feat(deploy): preflight + smoke-test + UAT checklist (phases 3.9.1–3.11)
Prepare the project for production deployment and final client
acceptance testing. Adds preflight fail-fast command, hardened FX rate
importer, currency seeder, deploy scripts, E2E smoke test, and the
43-item UAT checklist document with sign-off form.
Key changes:
- Phase 3.9.1 — hotfix (AddressBookEntry):
- Add $attributes defaults (use_count=0, is_default=false) so
instance values are populated right after create() without
refresh(). Resolves the red test
`it_increments_use_count_and_sets_last_used_at`.
- Phase 3.10 — deploy infrastructure (Laravel):
- Add `ifnex:preflight` command: fail-fast audit of production
environment (APP_ENV, APP_DEBUG, APP_KEY, IFNEX_API_KEY,
IFNEX_BRIDGE_API_KEY, ZARINPAL_SANDBOX, DB_CONNECTION, CORS,
currencies seeded, PHP extensions, storage writable). Exits 1
if any check fails; supports --skip-db for pre-migrate runs.
- Add `ifnex:import-fx-rates` command: replacement for
`ifnex:update-rates`. Fetches USD/AED from Exir.io + EUR/CNY
from FreeCurrencyAPI. Supports --auto-approve (cron use) and
--threshold (max change % for auto-approve). Logs critical on
HTTP failure. URL configurable via EXIR_API_URL env.
- Add `CurrencySeeder`: creates 5 base currencies (USD/AED/EUR/
CNY/IRR) with rate=0 (IRR=1). Idempotent — does not overwrite
real rates already set by admin or cron.
- Update `DatabaseSeeder`: skip super_admin with password
'password' in production (still created in local/testing).
- Fix `bootstrap/app.php`: remove dead `use ApiKeyAuth` import
(actual class is ApiKeyMiddleware). Latent fatal if api_key
alias was used.
- Add `config/ifnex.php` exir block + preflight config.
- Harden `.env.example`: MySQL default, EXIR_API_URL,
SANCTUM_STATEFUL_DOMAINS, APP_TIMEZONE, LOG_DAILY_DAYS, fix
duplicate CURRENCY_API_KEY.
- Phase 3.10 — deploy scripts (Linux):
- Add `scripts/deploy.sh`: idempotent 13-step deploy (composer
install → key:generate → preflight → migrate → seed → FX import
→ cache → chown). Fail-fast with set -e.
- Add `scripts/cron-exir-rates.sh`: daily cron wrapper for
`ifnex:import-fx-rates --source=all --auto-approve`.
- Phase 3.10.1 — preflight hotfix:
- Make expected DB connection configurable
(ifnex.preflight.expected_db_connection) instead of hardcoded
'mysql'. Prevents cascade test failure when tests would have to
mutate database.default to mysql in a sqlite test environment
(Unknown database ':memory:' → broken connection pool → 22
previously-green tests fail with "There is already an active
transaction").
- Rewrite IfnexPreflightTest to use config() rather than mutating
database.default.
- Phase 3.11 — UAT:
- Add `ifnex:smoke-test` command: E2E post-deploy automated test
(25+ checks: DB connection, core tables, currencies with
non-zero rates, countries count, roles, admin user, system
settings, storage writable, config/route cache, 4 API
endpoints: /up, /countries, /track/{invalid}, /customer/profile
without token).
- Add 9 feature tests for smoke-test (PASS + 6 FAIL + custom URL
+ 422/500 handling + auth bypass detection).
- Add `UAT-3.11.md`: 43-item Persian checklist for client
acceptance testing across 15 feature areas. Includes sign-off
form for both parties (client + VernaSoft).
- Update `CLIENT_DELIVERY.md` to record phases 3.10 and 3.11.
Tests:
- Total: 51 → 82 tests, 150 → 220+ assertions, all green.
- New: IfnexPreflightTest (9), IfnexImportFxRatesTest (9),
CurrencySeederTest (4), IfnexSmokeTestTest (9) = 31 new tests.
Documentation:
- DEPLOYMENT_HANDOFF.md §2.4: add CurrencySeeder + import-fx-rates.
- DEPLOYMENT_HANDOFF.md §2.8: update cron to use cron-exir-rates.sh.
- UAT-3.11.md: new 43-item client acceptance checklist + sign-off.
- CLIENT_DELIVERY.md: record phases 3.10 and 3.11 completion.
This commit is contained in:
parent
a4fc807160
commit
f1d5667fe8
@ -58,6 +58,102 @@ require_once ABSPATH . 'wp-admin/admin-header.php';
|
||||
<a href="contribute.php" class="nav-tab"><?php _e( 'Get Involved' ); ?></a>
|
||||
</nav>
|
||||
|
||||
<div class="about__section changelog has-subtle-background-color">
|
||||
<div class="column">
|
||||
<h2><?php _e( 'Maintenance and Security Releases' ); ?></h2>
|
||||
<p>
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s: WordPress version. */
|
||||
__( '<strong>Version %s</strong> addressed some security issues.' ),
|
||||
'7.1.4'
|
||||
);
|
||||
?>
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s: HelpHub URL. */
|
||||
__( 'For more information, see <a href="%s">the release notes</a>.' ),
|
||||
sprintf(
|
||||
/* translators: %s: WordPress version. */
|
||||
esc_url( __( 'https://wordpress.org/documentation/wordpress-version/version-%s/' ) ),
|
||||
sanitize_title( '7.1.4' )
|
||||
)
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
<p>
|
||||
<?php
|
||||
printf(
|
||||
/* translators: 1: WordPress version number, 2: Plural number of bugs. */
|
||||
_n(
|
||||
'<strong>Version %1$s</strong> addressed some security issues and fixed %2$s bug.',
|
||||
'<strong>Version %1$s</strong> addressed some security issues and fixed %2$s bugs.',
|
||||
4
|
||||
),
|
||||
'7.1.3',
|
||||
'4'
|
||||
);
|
||||
?>
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s: HelpHub URL. */
|
||||
__( 'For more information, see <a href="%s">the release notes</a>.' ),
|
||||
sprintf(
|
||||
/* translators: %s: WordPress version. */
|
||||
esc_url( __( 'https://wordpress.org/documentation/wordpress-version/version-%s/' ) ),
|
||||
sanitize_title( '7.1.3' )
|
||||
)
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
<p>
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s: WordPress version. */
|
||||
__( '<strong>Version %s</strong> addressed one security issue.' ),
|
||||
'7.1.2'
|
||||
);
|
||||
?>
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s: HelpHub URL. */
|
||||
__( 'For more information, see <a href="%s">the release notes</a>.' ),
|
||||
sprintf(
|
||||
/* translators: %s: WordPress version. */
|
||||
esc_url( __( 'https://wordpress.org/documentation/wordpress-version/version-%s/' ) ),
|
||||
sanitize_title( '7.1.2' )
|
||||
)
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
<p>
|
||||
<?php
|
||||
printf(
|
||||
/* translators: 1: WordPress version number, 2: Plural number of bugs. More than one security issue. */
|
||||
_n(
|
||||
'<strong>Version %1$s</strong> addressed some security issues and fixed %2$s bug.',
|
||||
'<strong>Version %1$s</strong> addressed some security issues and fixed %2$s bugs.',
|
||||
36
|
||||
),
|
||||
'7.1.1',
|
||||
number_format_i18n( 36 )
|
||||
);
|
||||
?>
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s: HelpHub URL. */
|
||||
__( 'For more information, see <a href="%s">the release notes</a>.' ),
|
||||
sprintf(
|
||||
/* translators: %s: WordPress version. */
|
||||
esc_url( __( 'https://wordpress.org/documentation/wordpress-version/version-%s/' ) ),
|
||||
sanitize_title( '7.1.1' )
|
||||
)
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="about__section">
|
||||
<div class="column is-left-padding-zero is-right-padding-zero">
|
||||
<h2><?php _e( 'Welcome to WordPress 7.1' ); ?></h2>
|
||||
|
||||
@ -1981,7 +1981,8 @@ div.action-links,
|
||||
|
||||
.plugins .active th.check-column,
|
||||
.plugins .active td.check-column,
|
||||
.plugin-update-tr.active td {
|
||||
.plugin-update-tr.active td,
|
||||
.plugins tr.paused td.check-column {
|
||||
border-right: 4px solid transparent;
|
||||
}
|
||||
|
||||
@ -1995,6 +1996,10 @@ div.action-links,
|
||||
border-right: 4px solid var(--wp-admin-theme-color);
|
||||
}
|
||||
|
||||
.plugins tr.active.paused {
|
||||
border-right: 4px solid #b32d2e;
|
||||
}
|
||||
|
||||
.wp-list-table .column-primary .toggle-row {
|
||||
display: block;
|
||||
}
|
||||
@ -2341,8 +2346,7 @@ div.action-links,
|
||||
|
||||
.plugins tr.active + tr.inactive th.check-column,
|
||||
.plugins tr.active + tr.inactive td.check-column,
|
||||
.plugins tr.active + tr.inactive td.column-description,
|
||||
.plugins .plugin-update-tr:before {
|
||||
.plugins tr.active + tr.inactive td.column-description {
|
||||
box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
@ -2352,13 +2356,8 @@ div.action-links,
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
/* mimic the checkbox th */
|
||||
.plugins .plugin-update-tr:before {
|
||||
content: "";
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
.plugins #the-list .plugin-update-tr .plugin-update {
|
||||
flex: 0 1 100%;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
@ -2366,12 +2365,6 @@ div.action-links,
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.plugins .active.update + .plugin-update-tr:before,
|
||||
.plugins .active.updated + .plugin-update-tr:before {
|
||||
background-color: rgba(var(--wp-admin-theme-color--rgb), 0.08);
|
||||
border-right: 4px solid var(--wp-admin-theme-color);
|
||||
}
|
||||
|
||||
.plugins .plugin-update-tr .update-message {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -1980,7 +1980,8 @@ div.action-links,
|
||||
|
||||
.plugins .active th.check-column,
|
||||
.plugins .active td.check-column,
|
||||
.plugin-update-tr.active td {
|
||||
.plugin-update-tr.active td,
|
||||
.plugins tr.paused td.check-column {
|
||||
border-left: 4px solid transparent;
|
||||
}
|
||||
|
||||
@ -1994,6 +1995,10 @@ div.action-links,
|
||||
border-left: 4px solid var(--wp-admin-theme-color);
|
||||
}
|
||||
|
||||
.plugins tr.active.paused {
|
||||
border-left: 4px solid #b32d2e;
|
||||
}
|
||||
|
||||
.wp-list-table .column-primary .toggle-row {
|
||||
display: block;
|
||||
}
|
||||
@ -2340,8 +2345,7 @@ div.action-links,
|
||||
|
||||
.plugins tr.active + tr.inactive th.check-column,
|
||||
.plugins tr.active + tr.inactive td.check-column,
|
||||
.plugins tr.active + tr.inactive td.column-description,
|
||||
.plugins .plugin-update-tr:before {
|
||||
.plugins tr.active + tr.inactive td.column-description {
|
||||
box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
@ -2351,13 +2355,8 @@ div.action-links,
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
/* mimic the checkbox th */
|
||||
.plugins .plugin-update-tr:before {
|
||||
content: "";
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
.plugins #the-list .plugin-update-tr .plugin-update {
|
||||
flex: 0 1 100%;
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
@ -2365,12 +2364,6 @@ div.action-links,
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.plugins .active.update + .plugin-update-tr:before,
|
||||
.plugins .active.updated + .plugin-update-tr:before {
|
||||
background-color: rgba(var(--wp-admin-theme-color--rgb), 0.08);
|
||||
border-left: 4px solid var(--wp-admin-theme-color);
|
||||
}
|
||||
|
||||
.plugins .plugin-update-tr .update-message {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -202,11 +202,23 @@ p {
|
||||
}
|
||||
|
||||
.login form .forgetmenot {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
/* Matches the height of the Log In button beside it, so the row centers on it. */
|
||||
min-height: 40px;
|
||||
font-weight: 400;
|
||||
float: right;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* Centering aligns margin boxes, so margins left from the inline layout would offset these. */
|
||||
.login form .forgetmenot input[type="checkbox"],
|
||||
.login form .forgetmenot label {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.login .button-primary {
|
||||
float: left;
|
||||
}
|
||||
|
||||
2
03_WordPress/wp-admin/css/login-rtl.min.css
vendored
2
03_WordPress/wp-admin/css/login-rtl.min.css
vendored
File diff suppressed because one or more lines are too long
@ -201,11 +201,23 @@ p {
|
||||
}
|
||||
|
||||
.login form .forgetmenot {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
/* Matches the height of the Log In button beside it, so the row centers on it. */
|
||||
min-height: 40px;
|
||||
font-weight: 400;
|
||||
float: left;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* Centering aligns margin boxes, so margins left from the inline layout would offset these. */
|
||||
.login form .forgetmenot input[type="checkbox"],
|
||||
.login form .forgetmenot label {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.login .button-primary {
|
||||
float: right;
|
||||
}
|
||||
|
||||
2
03_WordPress/wp-admin/css/login.min.css
vendored
2
03_WordPress/wp-admin/css/login.min.css
vendored
File diff suppressed because one or more lines are too long
@ -1804,7 +1804,7 @@ function wp_ajax_add_user( $action ) {
|
||||
'show-link' => sprintf(
|
||||
/* translators: %s: The new user. */
|
||||
__( 'User %s added' ),
|
||||
'<a href="#user-' . $user_id . '">' . $user_object->user_login . '</a>'
|
||||
'<a href="#user-' . $user_id . '">' . esc_html( $user_object->user_login ) . '</a>'
|
||||
),
|
||||
'role' => $role,
|
||||
),
|
||||
@ -2059,6 +2059,13 @@ function wp_ajax_menu_quick_search() {
|
||||
function wp_ajax_get_permalink() {
|
||||
check_ajax_referer( 'getpermalink', 'getpermalinknonce' );
|
||||
$post_id = isset( $_POST['post_id'] ) ? (int) $_POST['post_id'] : 0;
|
||||
if ( ! $post_id ) {
|
||||
// Bypass call to get_preview_post_link() for unspecified post ID.
|
||||
wp_die( '' );
|
||||
}
|
||||
if ( ! current_user_can( 'edit_post', $post_id ) ) {
|
||||
wp_die( -1 );
|
||||
}
|
||||
wp_die( get_preview_post_link( $post_id ) );
|
||||
}
|
||||
|
||||
@ -2070,8 +2077,15 @@ function wp_ajax_get_permalink() {
|
||||
function wp_ajax_sample_permalink() {
|
||||
check_ajax_referer( 'samplepermalink', 'samplepermalinknonce' );
|
||||
$post_id = isset( $_POST['post_id'] ) ? (int) $_POST['post_id'] : 0;
|
||||
$title = $_POST['new_title'] ?? '';
|
||||
$slug = $_POST['new_slug'] ?? null;
|
||||
if ( ! $post_id ) {
|
||||
// Bypass call to get_sample_permalink_html() for unspecified post ID.
|
||||
wp_die( '' );
|
||||
}
|
||||
if ( ! current_user_can( 'edit_post', $post_id ) ) {
|
||||
wp_die( -1 );
|
||||
}
|
||||
$title = $_POST['new_title'] ?? '';
|
||||
$slug = $_POST['new_slug'] ?? null;
|
||||
wp_die( get_sample_permalink_html( $post_id, $title, $slug ) );
|
||||
}
|
||||
|
||||
@ -4615,6 +4629,12 @@ function wp_ajax_activate_plugin() {
|
||||
wp_send_json_error( $status );
|
||||
}
|
||||
|
||||
// A network-only plugin is activated for the entire network.
|
||||
if ( is_multisite() && is_network_only_plugin( $status['plugin'] ) && ! current_user_can( 'manage_network_plugins' ) ) {
|
||||
$status['errorMessage'] = __( 'Sorry, you are not allowed to activate this plugin.' );
|
||||
wp_send_json_error( $status );
|
||||
}
|
||||
|
||||
if ( is_plugin_active( $status['plugin'] ) ) {
|
||||
$status['errorMessage'] = sprintf(
|
||||
/* translators: %s: Plugin name. */
|
||||
|
||||
@ -572,7 +572,7 @@ class Custom_Image_Header {
|
||||
$header_image_style .= 'height:' . $custom_header->height . 'px;';
|
||||
}
|
||||
?>
|
||||
<div id="headimg" style="<?php echo $header_image_style; ?>">
|
||||
<div id="headimg" style="<?php echo esc_attr( $header_image_style ); ?>">
|
||||
<?php
|
||||
if ( display_header_text() ) {
|
||||
$style = ' style="color:#' . get_header_textcolor() . ';"';
|
||||
@ -1184,8 +1184,8 @@ endif;
|
||||
'attachment_id' => $choice['attachment_id'],
|
||||
'url' => $choice['url'],
|
||||
'thumbnail_url' => $choice['url'],
|
||||
'height' => $choice['height'],
|
||||
'width' => $choice['width'],
|
||||
'height' => absint( $choice['height'] ),
|
||||
'width' => absint( $choice['width'] ),
|
||||
);
|
||||
|
||||
update_post_meta( $choice['attachment_id'], '_wp_attachment_is_custom_header', get_stylesheet() );
|
||||
@ -1216,7 +1216,13 @@ endif;
|
||||
}
|
||||
}
|
||||
|
||||
set_theme_mod( 'header_image', sanitize_url( $header_image_data['url'] ) );
|
||||
$header_image_data['url'] = sanitize_url( $header_image_data['url'] );
|
||||
|
||||
if ( isset( $header_image_data['thumbnail_url'] ) ) {
|
||||
$header_image_data['thumbnail_url'] = sanitize_url( $header_image_data['thumbnail_url'] );
|
||||
}
|
||||
|
||||
set_theme_mod( 'header_image', $header_image_data['url'] );
|
||||
set_theme_mod( 'header_image_data', $header_image_data );
|
||||
}
|
||||
|
||||
@ -1589,9 +1595,8 @@ endif;
|
||||
$alt_text_key = '_wp_attachment_image_alt';
|
||||
|
||||
foreach ( $header_images as &$header_image ) {
|
||||
$header_meta = get_post_meta( $header_image['attachment_id'] );
|
||||
$header_image['timestamp'] = $header_meta[ $timestamp_key ] ?? '';
|
||||
$header_image['alt_text'] = $header_meta[ $alt_text_key ] ?? '';
|
||||
$header_image['timestamp'] = get_post_meta( $header_image['attachment_id'], $timestamp_key, true );
|
||||
$header_image['alt_text'] = get_post_meta( $header_image['attachment_id'], $alt_text_key, true );
|
||||
}
|
||||
|
||||
return $header_images;
|
||||
|
||||
@ -240,7 +240,7 @@ class WP_MS_Users_List_Table extends WP_List_Table {
|
||||
<span class="screen-reader-text">
|
||||
<?php
|
||||
/* translators: Hidden accessibility text. %s: User login. */
|
||||
printf( __( 'Select %s' ), $user->user_login );
|
||||
printf( __( 'Select %s' ), esc_html( $user->user_login ) );
|
||||
?>
|
||||
</span>
|
||||
</label>
|
||||
@ -273,9 +273,9 @@ class WP_MS_Users_List_Table extends WP_List_Table {
|
||||
|
||||
if ( current_user_can( 'edit_user', $user->ID ) ) {
|
||||
$edit_link = esc_url( add_query_arg( 'wp_http_referer', urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ), get_edit_user_link( $user->ID ) ) );
|
||||
$edit = "<a href=\"{$edit_link}\">{$user->user_login}</a>";
|
||||
$edit = "<a href=\"{$edit_link}\">" . esc_html( $user->user_login ) . '</a>';
|
||||
} else {
|
||||
$edit = $user->user_login;
|
||||
$edit = esc_html( $user->user_login );
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@ -98,7 +98,7 @@ class WP_Privacy_Data_Export_Requests_List_Table extends WP_Privacy_Requests_Tab
|
||||
$row_actions['complete-request'] = $complete_request_markup;
|
||||
}
|
||||
|
||||
return sprintf( '<a href="%1$s">%2$s</a> %3$s', esc_url( 'mailto:' . $item->email ), $item->email, $this->row_actions( $row_actions ) );
|
||||
return sprintf( '<a href="%1$s">%2$s</a> %3$s', esc_url( 'mailto:' . $item->email ), esc_html( $item->email ), $this->row_actions( $row_actions ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -104,7 +104,7 @@ class WP_Privacy_Data_Removal_Requests_List_Table extends WP_Privacy_Requests_Ta
|
||||
$row_actions['complete-request'] = $complete_request_markup;
|
||||
}
|
||||
|
||||
return sprintf( '<a href="%1$s">%2$s</a> %3$s', esc_url( 'mailto:' . $item->email ), $item->email, $this->row_actions( $row_actions ) );
|
||||
return sprintf( '<a href="%1$s">%2$s</a> %3$s', esc_url( 'mailto:' . $item->email ), esc_html( $item->email ), $this->row_actions( $row_actions ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -425,7 +425,7 @@ abstract class WP_Privacy_Requests_Table extends WP_List_Table {
|
||||
'<label for="requester_%1$s"><span class="screen-reader-text">%2$s</span></label><span class="spinner"></span>',
|
||||
esc_attr( $item->ID ),
|
||||
/* translators: Hidden accessibility text. %s: Email address. */
|
||||
sprintf( __( 'Select %s' ), $item->email )
|
||||
sprintf( __( 'Select %s' ), esc_html( $item->email ) )
|
||||
);
|
||||
}
|
||||
|
||||
@ -551,7 +551,7 @@ abstract class WP_Privacy_Requests_Table extends WP_List_Table {
|
||||
* @return string Email column markup.
|
||||
*/
|
||||
public function column_email( $item ) {
|
||||
return sprintf( '<a href="%1$s">%2$s</a> %3$s', esc_url( 'mailto:' . $item->email ), $item->email, $this->row_actions( array() ) );
|
||||
return sprintf( '<a href="%1$s">%2$s</a> %3$s', esc_url( 'mailto:' . $item->email ), esc_html( $item->email ), $this->row_actions( array() ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -343,6 +343,21 @@ class WP_Upgrader {
|
||||
return $download_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an unpredictable name for the directory a package is unpacked into.
|
||||
*
|
||||
* @since 7.1.4
|
||||
*
|
||||
* @param string $package The full local path or URI of the package.
|
||||
* @return string The directory name, without a path.
|
||||
*/
|
||||
private function get_working_dir_name( $package ) {
|
||||
// Strip off any .tmp or .zip suffixes.
|
||||
$name = basename( basename( $package, '.tmp' ), '.zip' );
|
||||
|
||||
return $name . '-' . wp_generate_password( 16, false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpacks a compressed package file.
|
||||
*
|
||||
@ -366,16 +381,32 @@ class WP_Upgrader {
|
||||
|
||||
$upgrade_folder = $wp_filesystem->wp_content_dir() . 'upgrade/';
|
||||
|
||||
// Clean up contents of upgrade directory beforehand.
|
||||
// Clean up contents of upgrade directory beforehand, keeping its index.php.
|
||||
$upgrade_files = $wp_filesystem->dirlist( $upgrade_folder );
|
||||
if ( ! empty( $upgrade_files ) ) {
|
||||
foreach ( $upgrade_files as $file ) {
|
||||
if ( 'index.php' === $file['name'] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$wp_filesystem->delete( $upgrade_folder . $file['name'], true );
|
||||
}
|
||||
}
|
||||
|
||||
// We need a working directory - strip off any .tmp or .zip suffixes.
|
||||
$working_dir = $upgrade_folder . basename( basename( $package, '.tmp' ), '.zip' );
|
||||
/*
|
||||
* The upgrade directory is web-served. Keep it from being listed, as core does
|
||||
* for wp-content and its plugins and themes directories, so the name of the
|
||||
* working directory created below cannot be discovered from a directory index.
|
||||
*/
|
||||
if ( ! $wp_filesystem->is_dir( $upgrade_folder ) ) {
|
||||
$wp_filesystem->mkdir( $upgrade_folder, FS_CHMOD_DIR );
|
||||
}
|
||||
if ( ! $wp_filesystem->exists( $upgrade_folder . 'index.php' ) ) {
|
||||
$wp_filesystem->put_contents( $upgrade_folder . 'index.php', "<?php\n// Silence is golden.\n", FS_CHMOD_FILE );
|
||||
}
|
||||
|
||||
// We need a working directory.
|
||||
$working_dir = $upgrade_folder . $this->get_working_dir_name( $package );
|
||||
|
||||
// Clean up working directory.
|
||||
if ( $wp_filesystem->is_dir( $working_dir ) ) {
|
||||
|
||||
@ -468,10 +468,10 @@ class WP_Users_List_Table extends WP_List_Table {
|
||||
);
|
||||
|
||||
if ( current_user_can( 'edit_user', $user_object->ID ) ) {
|
||||
$edit = "<strong><a href=\"{$edit_link}\">{$user_object->user_login}</a>{$super_admin}</strong><br />";
|
||||
$edit = '<strong><a href="' . $edit_link . '">' . esc_html( $user_object->user_login ) . "</a>{$super_admin}</strong><br />";
|
||||
$actions['edit'] = '<a href="' . $edit_link . '">' . __( 'Edit' ) . '</a>';
|
||||
} else {
|
||||
$edit = "<strong>{$user_object->user_login}{$super_admin}</strong><br />";
|
||||
$edit = '<strong>' . esc_html( $user_object->user_login ) . "{$super_admin}</strong><br />";
|
||||
}
|
||||
|
||||
if ( ! is_multisite()
|
||||
@ -529,11 +529,11 @@ class WP_Users_List_Table extends WP_List_Table {
|
||||
$user_object->ID,
|
||||
$role_classes,
|
||||
/* translators: Hidden accessibility text. %s: User login. */
|
||||
sprintf( __( 'Select %s' ), $user_object->user_login )
|
||||
sprintf( __( 'Select %s' ), esc_html( $user_object->user_login ) )
|
||||
);
|
||||
|
||||
} else {
|
||||
$edit = "<strong>{$user_object->user_login}{$super_admin}</strong>";
|
||||
$edit = '<strong>' . esc_html( $user_object->user_login ) . "{$super_admin}</strong>";
|
||||
}
|
||||
|
||||
$avatar = get_avatar( $user_object->ID, 32 );
|
||||
|
||||
@ -183,11 +183,15 @@ function export_wp( $args = array() ) {
|
||||
)
|
||||
);
|
||||
|
||||
// Cast thumbnail IDs to integers to prevent second-order SQL injection via user-controlled meta values.
|
||||
$thumbnails_ids = array_filter( array_map( 'absint', $thumbnails_ids ) );
|
||||
|
||||
$additional_ids = array_merge( $additional_ids, $attachment_ids, $thumbnails_ids );
|
||||
}
|
||||
|
||||
// Merge the additional IDs back with the original post IDs after processing all posts
|
||||
$post_ids = array_unique( array_merge( $post_ids, $additional_ids ) );
|
||||
// Merge the additional IDs back with the original post IDs after processing all posts.
|
||||
// Cast to integers as defense-in-depth, since $additional_ids may include values sourced from postmeta.
|
||||
$post_ids = array_unique( array_map( 'absint', array_merge( $post_ids, $additional_ids ) ) );
|
||||
}
|
||||
|
||||
/*
|
||||
@ -597,8 +601,10 @@ function export_wp( $args = array() ) {
|
||||
|
||||
// Fetch 20 posts at a time rather than loading the entire table into memory.
|
||||
while ( $next_posts = array_splice( $post_ids, 0, 20 ) ) {
|
||||
$where = 'WHERE ID IN (' . implode( ',', $next_posts ) . ')';
|
||||
$posts = $wpdb->get_results( "SELECT * FROM {$wpdb->posts} $where" );
|
||||
// Re-sanitize immediately before use, as defense-in-depth against the IDs being interpolated directly into SQL below.
|
||||
$next_posts = array_map( 'absint', $next_posts );
|
||||
$where = 'WHERE ID IN (' . implode( ',', $next_posts ) . ')';
|
||||
$posts = $wpdb->get_results( "SELECT * FROM {$wpdb->posts} $where" );
|
||||
|
||||
// Begin Loop.
|
||||
foreach ( $posts as $post ) {
|
||||
|
||||
@ -1083,10 +1083,15 @@ function wp_read_image_metadata( $file ) {
|
||||
* @since 7.0.0
|
||||
*
|
||||
* @param string $file File path to the image.
|
||||
* @return string Embedded alternative text.
|
||||
* @return string Embedded alternative text, empty when there is no alt text or DOM extension is not installed.
|
||||
*/
|
||||
function wp_get_image_alttext( $file ) {
|
||||
$alt_text = '';
|
||||
$alt_text = '';
|
||||
|
||||
if ( ! class_exists( 'DOMDocument', false ) ) {
|
||||
return $alt_text;
|
||||
}
|
||||
|
||||
$img_contents = file_get_contents( $file );
|
||||
|
||||
if ( false === $img_contents ) {
|
||||
|
||||
@ -3370,7 +3370,7 @@ function attachment_submitbox_metadata() {
|
||||
<?php
|
||||
if ( $post->post_parent ) {
|
||||
$post_parent = get_post( $post->post_parent );
|
||||
if ( $post_parent ) {
|
||||
if ( $post_parent && current_user_can( 'read_post', $post_parent->ID ) ) {
|
||||
$uploaded_to_title = $post_parent->post_title ? $post_parent->post_title : __( '(no title)' );
|
||||
$uploaded_to_link = get_edit_post_link( $post->post_parent, 'raw' );
|
||||
?>
|
||||
|
||||
@ -889,7 +889,7 @@ function confirm_delete_users( $users ) {
|
||||
sprintf(
|
||||
/* translators: %s: User login. */
|
||||
__( 'Warning! User %s cannot be deleted.' ),
|
||||
$delete_user->user_login
|
||||
esc_html( $delete_user->user_login )
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -899,14 +899,14 @@ function confirm_delete_users( $users ) {
|
||||
sprintf(
|
||||
/* translators: %s: User login. */
|
||||
__( 'Warning! User cannot be deleted. The user %s is a network administrator.' ),
|
||||
'<em>' . $delete_user->user_login . '</em>'
|
||||
'<em>' . esc_html( $delete_user->user_login ) . '</em>'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
?>
|
||||
<tr>
|
||||
<th scope="row"><?php echo $delete_user->user_login; ?>
|
||||
<th scope="row"><?php echo esc_html( $delete_user->user_login ); ?>
|
||||
<?php echo '<input type="hidden" name="user[]" value="' . esc_attr( $user_id ) . '" />' . "\n"; ?>
|
||||
</th>
|
||||
<?php
|
||||
@ -919,7 +919,7 @@ function confirm_delete_users( $users ) {
|
||||
printf(
|
||||
/* translators: 1: User login, 2: User ID. */
|
||||
__( '%1$s (ID #%2$s): What should be done with the content owned by this user?' ),
|
||||
'<strong>' . $delete_user->user_login . '</strong>',
|
||||
'<strong>' . esc_html( $delete_user->user_login ) . '</strong>',
|
||||
$user_id
|
||||
);
|
||||
?>
|
||||
@ -1003,6 +1003,7 @@ function confirm_delete_users( $users ) {
|
||||
'include' => $blog_users,
|
||||
'show' => 'display_name_with_login',
|
||||
'id' => "reassign_user_{$details->userblog_id}_{$delete_user->ID}",
|
||||
'blog_id' => $details->userblog_id,
|
||||
)
|
||||
);
|
||||
?>
|
||||
|
||||
@ -598,11 +598,17 @@ function is_plugin_active_for_network( $plugin ) {
|
||||
* Checks for "Site Wide Only: true" for backward compatibility.
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @since 7.1.1 The `$plugin` path is normalized with `plugin_basename()` and `trim()`,
|
||||
* matching how `activate_plugin()` resolves it.
|
||||
*
|
||||
* @param string $plugin Path to the plugin file relative to the plugins directory.
|
||||
* @param string $plugin Path to the plugin file. Accepts a path relative to the plugins
|
||||
* directory, or an absolute path, with or without surrounding whitespace.
|
||||
* @return bool True if plugin is network only, false otherwise.
|
||||
*/
|
||||
function is_network_only_plugin( $plugin ) {
|
||||
// Normalize the path the same way activate_plugin() does, so both agree on the file.
|
||||
$plugin = plugin_basename( trim( $plugin ) );
|
||||
|
||||
$plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin );
|
||||
if ( $plugin_data ) {
|
||||
return $plugin_data['Network'];
|
||||
|
||||
@ -24,6 +24,20 @@ function _wp_translate_postdata( $update = false, $post_data = null ) {
|
||||
$post_data = &$_POST;
|
||||
}
|
||||
|
||||
/*
|
||||
* A raw `ID` on the create path (no `post_ID`) is an attempt to overwrite an
|
||||
* existing post while bypassing the per-post capability checks below, which only
|
||||
* run on the update path. Reject it outright: legitimate post creation never
|
||||
* carries an `ID`.
|
||||
*/
|
||||
if ( ! $update && ! empty( $post_data['ID'] ) ) {
|
||||
if ( 'page' === $post_data['post_type'] ) {
|
||||
return new WP_Error( 'edit_others_pages', __( 'Sorry, you are not allowed to edit pages as this user.' ) );
|
||||
} else {
|
||||
return new WP_Error( 'edit_others_posts', __( 'Sorry, you are not allowed to edit posts as this user.' ) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $update ) {
|
||||
$post_data['ID'] = (int) $post_data['post_ID'];
|
||||
}
|
||||
|
||||
@ -1545,8 +1545,9 @@ function update_core( $from, $to ) {
|
||||
/*
|
||||
* Don't copy wp-content, we'll deal with that below.
|
||||
* We also copy version.php last so failed updates report their old version.
|
||||
* Never copy a wp-config.php, which could have been written to the working directory.
|
||||
*/
|
||||
$skip = array( 'wp-content', 'wp-includes/version.php' );
|
||||
$skip = array( 'wp-content', 'wp-includes/version.php', 'wp-config.php' );
|
||||
$check_is_writable = array();
|
||||
|
||||
// Check to see which files don't really need updating - only available for 3.7 and higher.
|
||||
|
||||
@ -695,7 +695,7 @@ $('.contextual-help-tabs').on( 'click', 'a', function(e) {
|
||||
$('.contextual-help-tabs .active').removeClass('active');
|
||||
link.parent('li').addClass('active');
|
||||
|
||||
panel = $( link.attr('href') );
|
||||
panel = $( document ).find( link.attr('href') );
|
||||
|
||||
// Panels.
|
||||
$('.help-tab-content').not( panel ).removeClass('active').hide();
|
||||
|
||||
2
03_WordPress/wp-admin/js/common.min.js
vendored
2
03_WordPress/wp-admin/js/common.min.js
vendored
File diff suppressed because one or more lines are too long
@ -2082,9 +2082,9 @@ themes.RunInstaller = {
|
||||
self.view.collection.query( request );
|
||||
self.view.collection.trigger( 'update' );
|
||||
|
||||
// Open the theme preview.
|
||||
// Open the theme preview. The slug comes from the URL, so escape it.
|
||||
self.view.collection.once( 'query:success', function() {
|
||||
$( 'div[data-slug="' + slug + '"]' ).trigger( 'click' );
|
||||
$( 'div.theme[data-slug="' + $.escapeSelector( slug ) + '"]' ).trigger( 'click' );
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
2
03_WordPress/wp-admin/js/theme.min.js
vendored
2
03_WordPress/wp-admin/js/theme.min.js
vendored
File diff suppressed because one or more lines are too long
@ -557,7 +557,7 @@ switch ( $action ) {
|
||||
|
||||
?>
|
||||
<?php foreach ( $public_display as $id => $item ) : ?>
|
||||
<option <?php selected( $profile_user->display_name, $item ); ?>><?php echo $item; ?></option>
|
||||
<option <?php selected( $profile_user->display_name, $item ); ?>><?php echo esc_html( $item ); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</td>
|
||||
@ -790,7 +790,7 @@ switch ( $action ) {
|
||||
<p class="description">
|
||||
<?php
|
||||
/* translators: %s: User's display name. */
|
||||
printf( __( 'Log %s out of all locations.' ), $profile_user->display_name );
|
||||
printf( __( 'Log %s out of all locations.' ), esc_html( $profile_user->display_name ) );
|
||||
?>
|
||||
</p>
|
||||
</td>
|
||||
|
||||
@ -351,7 +351,7 @@ switch ( $wp_list_table->current_action() ) {
|
||||
/* translators: 1: User ID, 2: User login. */
|
||||
__( 'ID #%1$s: %2$s <strong>The current user will not be deleted.</strong>' ),
|
||||
$id,
|
||||
$user->user_login
|
||||
esc_html( $user->user_login )
|
||||
);
|
||||
echo "</li>\n";
|
||||
} else {
|
||||
@ -402,7 +402,7 @@ switch ( $wp_list_table->current_action() ) {
|
||||
printf(
|
||||
/* translators: 1: User login. 2: User ID */
|
||||
__( '%1$s (ID #%2$s): This user does not have any content.' ),
|
||||
'<strong>' . $user->user_login . '</strong>',
|
||||
'<strong>' . esc_html( $user->user_login ) . '</strong>',
|
||||
$id
|
||||
);
|
||||
?>
|
||||
@ -416,7 +416,7 @@ switch ( $wp_list_table->current_action() ) {
|
||||
printf(
|
||||
/* translators: 1: User login, 2: User ID. */
|
||||
__( '%1$s (ID #%2$s): What should be done with the content owned by this user?' ),
|
||||
'<strong>' . $user->user_login . '</strong>',
|
||||
'<strong>' . esc_html( $user->user_login ) . '</strong>',
|
||||
$id
|
||||
);
|
||||
?>
|
||||
@ -568,7 +568,7 @@ switch ( $wp_list_table->current_action() ) {
|
||||
/* translators: 1: User ID, 2: User login. */
|
||||
__( 'ID #%1$s: %2$s <strong>Sorry, you are not allowed to remove this user.</strong>' ),
|
||||
$id,
|
||||
$user->user_login
|
||||
esc_html( $user->user_login )
|
||||
);
|
||||
echo "</li>\n";
|
||||
} else {
|
||||
@ -581,7 +581,7 @@ switch ( $wp_list_table->current_action() ) {
|
||||
/* translators: 1: User ID, 2: User login. */
|
||||
__( 'ID #%1$s: %2$s' ),
|
||||
$id,
|
||||
$user->user_login
|
||||
esc_html( $user->user_login )
|
||||
);
|
||||
echo "</li>\n";
|
||||
|
||||
|
||||
@ -274,7 +274,7 @@ function wp_admin_bar_my_account_item( $wp_admin_bar ) {
|
||||
}
|
||||
|
||||
/* translators: %s: Current user's display name. */
|
||||
$howdy = sprintf( __( 'Howdy, %s' ), '<span class="display-name">' . wp_get_current_user()->display_name . '</span>' );
|
||||
$howdy = sprintf( __( 'Howdy, %s' ), '<span class="display-name">' . esc_html( wp_get_current_user()->display_name ) . '</span>' );
|
||||
|
||||
$avatar = get_avatar( $user_id, 28 );
|
||||
$wp_admin_bar->add_node(
|
||||
@ -323,10 +323,10 @@ function wp_admin_bar_my_account_menu( $wp_admin_bar ) {
|
||||
);
|
||||
|
||||
$user_info = get_avatar( $user_id, 64 );
|
||||
$user_info .= "<span class='display-name'>{$current_user->display_name}</span>";
|
||||
$user_info .= "<span class='display-name'>" . esc_html( $current_user->display_name ) . '</span>';
|
||||
|
||||
if ( $current_user->display_name !== $current_user->user_login ) {
|
||||
$user_info .= "<span class='username'>{$current_user->user_login}</span>";
|
||||
$user_info .= "<span class='username'>" . esc_html( $current_user->user_login ) . '</span>';
|
||||
}
|
||||
|
||||
if ( false !== $profile_url ) {
|
||||
|
||||
@ -104,7 +104,7 @@
|
||||
'wp-url',
|
||||
'wp-warning'
|
||||
),
|
||||
'version' => 'd3cbb2c45b145b27a5cf'
|
||||
'version' => '37e58da384b2558bd479'
|
||||
),
|
||||
'block-library.js' => array(
|
||||
'dependencies' => array(
|
||||
@ -150,19 +150,19 @@
|
||||
'import' => 'dynamic'
|
||||
)
|
||||
),
|
||||
'version' => '2e80403676c10cc0a473'
|
||||
'version' => '00e6e2a44788af201f35'
|
||||
),
|
||||
'block-serialization-default-parser.js' => array(
|
||||
'dependencies' => array(
|
||||
|
||||
),
|
||||
'version' => '4c6f3dd40077f7c17604'
|
||||
'version' => 'fc209395a022242d64aa'
|
||||
),
|
||||
'block-serialization-spec-parser.js' => array(
|
||||
'dependencies' => array(
|
||||
|
||||
),
|
||||
'version' => '7b0b496c3d48b1ef3f9e'
|
||||
'version' => '345804e2c9fb36e816cd'
|
||||
),
|
||||
'blocks.js' => array(
|
||||
'dependencies' => array(
|
||||
@ -402,7 +402,7 @@
|
||||
'import' => 'static'
|
||||
)
|
||||
),
|
||||
'version' => 'a7750dea8d5c880ddf33'
|
||||
'version' => 'a6cb1641d13f718c01bd'
|
||||
),
|
||||
'edit-site.js' => array(
|
||||
'dependencies' => array(
|
||||
@ -452,7 +452,7 @@
|
||||
'import' => 'static'
|
||||
)
|
||||
),
|
||||
'version' => '638e98d0061f4b9f1efb'
|
||||
'version' => '008f89f2cb2ad17a5947'
|
||||
),
|
||||
'edit-widgets.js' => array(
|
||||
'dependencies' => array(
|
||||
@ -543,7 +543,7 @@
|
||||
'import' => 'static'
|
||||
)
|
||||
),
|
||||
'version' => '2cd3b932f41a420d5904'
|
||||
'version' => 'af070cfff88093363220'
|
||||
),
|
||||
'element.js' => array(
|
||||
'dependencies' => array(
|
||||
@ -663,7 +663,7 @@
|
||||
'wp-url',
|
||||
'wp-warning'
|
||||
),
|
||||
'version' => 'b8bf604c1cc119e63ee6'
|
||||
'version' => '07c1c94f9b21baa97a96'
|
||||
),
|
||||
'notices.js' => array(
|
||||
'dependencies' => array(
|
||||
@ -881,7 +881,7 @@
|
||||
'import' => 'dynamic'
|
||||
)
|
||||
),
|
||||
'version' => 'f7174b0617bcd68e57c3'
|
||||
'version' => 'a2c026d433c295fd5145'
|
||||
),
|
||||
'url.js' => array(
|
||||
'dependencies' => array(
|
||||
|
||||
@ -64,7 +64,7 @@
|
||||
'import' => 'static'
|
||||
)
|
||||
),
|
||||
'version' => '25ee935fd6c67371d0f3'
|
||||
'version' => '25f29e3c6cc00370914b'
|
||||
),
|
||||
'block-library/navigation/view.js' => array(
|
||||
'dependencies' => array(
|
||||
@ -253,7 +253,7 @@
|
||||
'dependencies' => array(
|
||||
|
||||
),
|
||||
'version' => 'efaa5193bbad9c60ffd1'
|
||||
'version' => '6a43cba92ed701f32cd9'
|
||||
),
|
||||
'interactivity-router/full-page.js' => array(
|
||||
'dependencies' => array(
|
||||
@ -281,7 +281,7 @@
|
||||
'import' => 'static'
|
||||
)
|
||||
),
|
||||
'version' => 'a6e90b8896f83fb1b5dd'
|
||||
'version' => 'dea5032c2153d213c1ee'
|
||||
),
|
||||
'latex-to-mathml/index.js' => array(
|
||||
'dependencies' => array(
|
||||
@ -360,7 +360,7 @@
|
||||
'dependencies' => array(
|
||||
|
||||
),
|
||||
'version' => '685442d334b2d3e70832'
|
||||
'version' => '7e33cd8c4128731126e8'
|
||||
),
|
||||
'workflow/index.js' => array(
|
||||
'dependencies' => array(
|
||||
|
||||
@ -542,6 +542,16 @@ function wp_render_block_states_support( $block_content, $block ) {
|
||||
return $block_content;
|
||||
}
|
||||
|
||||
/*
|
||||
* Every CSS rule this function can produce is keyed off the block's `style`
|
||||
* attribute. Without it there is nothing to generate, so bail before doing
|
||||
* any of the lookups below — this runs for every block on every request.
|
||||
*/
|
||||
$style = $block['attrs']['style'] ?? array();
|
||||
if ( empty( $style ) || ! is_array( $style ) ) {
|
||||
return $block_content;
|
||||
}
|
||||
|
||||
$block_name = $block['blockName'];
|
||||
$block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block_name );
|
||||
if ( ! $block_type ) {
|
||||
@ -549,7 +559,6 @@ function wp_render_block_states_support( $block_content, $block ) {
|
||||
}
|
||||
|
||||
$supported_pseudo_states = WP_Theme_JSON::VALID_BLOCK_PSEUDO_SELECTORS[ $block_name ] ?? array();
|
||||
$style = $block['attrs']['style'] ?? array();
|
||||
$css_rules = array();
|
||||
$viewport_settings = wp_get_global_settings( array( 'viewport' ) );
|
||||
$responsive_media_queries = WP_Theme_JSON::get_viewport_media_queries( $viewport_settings );
|
||||
|
||||
@ -343,11 +343,22 @@ function _get_block_template_file( $template_type, $slug ) {
|
||||
);
|
||||
foreach ( $themes as $theme_slug => $theme_dir ) {
|
||||
$template_base_paths = get_block_theme_folders( $theme_slug );
|
||||
$file_path = $theme_dir . '/' . $template_base_paths[ $template_type ] . '/' . $slug . '.html';
|
||||
if ( file_exists( $file_path ) ) {
|
||||
$template_dir = $theme_dir . '/' . $template_base_paths[ $template_type ];
|
||||
$file_path = $template_dir . '/' . $slug . '.html';
|
||||
$template_file = realpath( $file_path );
|
||||
$template_root = realpath( $template_dir );
|
||||
|
||||
if (
|
||||
false !== $template_file &&
|
||||
false !== $template_root &&
|
||||
str_starts_with(
|
||||
wp_normalize_path( $template_file ),
|
||||
trailingslashit( wp_normalize_path( $template_root ) )
|
||||
)
|
||||
) {
|
||||
$new_template_item = array(
|
||||
'slug' => $slug,
|
||||
'path' => $file_path,
|
||||
'path' => $template_file,
|
||||
'theme' => $theme_slug,
|
||||
'type' => $template_type,
|
||||
);
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
.wp-block-accordion-panel[hidden] {
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
margin-block-start: 0;
|
||||
padding: 0 !important;
|
||||
}
|
||||
@ -1 +1 @@
|
||||
.wp-block-accordion-panel[hidden]{margin-block-start:0}
|
||||
.wp-block-accordion-panel[hidden]{border:none!important;box-shadow:none!important;margin-block-start:0;padding:0!important}
|
||||
@ -1,3 +1,6 @@
|
||||
.wp-block-accordion-panel[hidden] {
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
margin-block-start: 0;
|
||||
padding: 0 !important;
|
||||
}
|
||||
@ -1 +1 @@
|
||||
.wp-block-accordion-panel[hidden]{margin-block-start:0}
|
||||
.wp-block-accordion-panel[hidden]{border:none!important;box-shadow:none!important;margin-block-start:0;padding:0!important}
|
||||
@ -53,7 +53,7 @@ function render_block_core_categories( $attributes, $content, $block ) {
|
||||
$show_label = empty( $attributes['showLabel'] ) ? ' screen-reader-text' : '';
|
||||
$default_label = $taxonomy->label;
|
||||
$label_text = ! empty( $attributes['label'] ) ? wp_kses_post( $attributes['label'] ) : $default_label;
|
||||
$wrapper_markup = '<div %1$s><label class="wp-block-categories__label' . $show_label . '" for="' . esc_attr( $id ) . '">' . $label_text . '</label>%2$s</div>';
|
||||
$wrapper_markup = '<div %1$s><label class="wp-block-categories__label' . $show_label . '" for="' . esc_attr( $id ) . '">%3$s</label>%2$s</div>';
|
||||
$items_markup = wp_dropdown_categories( $args );
|
||||
$type = 'dropdown';
|
||||
|
||||
@ -69,6 +69,7 @@ function render_block_core_categories( $attributes, $content, $block ) {
|
||||
} else {
|
||||
$args['show_option_none'] = $taxonomy->labels->no_terms;
|
||||
|
||||
$label_text = '';
|
||||
$wrapper_markup = '<ul %1$s>%2$s</ul>';
|
||||
$items_markup = wp_list_categories( $args );
|
||||
$type = 'list';
|
||||
@ -87,7 +88,8 @@ function render_block_core_categories( $attributes, $content, $block ) {
|
||||
return sprintf(
|
||||
$wrapper_markup,
|
||||
$wrapper_attributes,
|
||||
$items_markup
|
||||
$items_markup,
|
||||
$label_text
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -25,7 +25,7 @@ function render_block_core_comments_pagination_next( $attributes, $content, $blo
|
||||
$comment_vars = build_comment_query_vars_from_block( $block );
|
||||
$max_page = ( new WP_Comment_Query( $comment_vars ) )->max_num_pages;
|
||||
$default_label = __( 'Newer Comments' );
|
||||
$label = isset( $attributes['label'] ) && ! empty( $attributes['label'] ) ? $attributes['label'] : $default_label;
|
||||
$label = ! empty( $attributes['label'] ) ? $attributes['label'] : $default_label;
|
||||
$pagination_arrow = get_comments_pagination_arrow( $block, 'next' );
|
||||
|
||||
$filter_link_attributes = static function () {
|
||||
@ -33,6 +33,8 @@ function render_block_core_comments_pagination_next( $attributes, $content, $blo
|
||||
};
|
||||
add_filter( 'next_comments_link_attributes', $filter_link_attributes );
|
||||
|
||||
// Escaping early as the pagination arrow usually returns HTML and shouldn't be escaped.
|
||||
$label = esc_html( $label );
|
||||
if ( $pagination_arrow ) {
|
||||
$label .= $pagination_arrow;
|
||||
}
|
||||
|
||||
@ -18,8 +18,11 @@
|
||||
*/
|
||||
function render_block_core_comments_pagination_previous( $attributes, $content, $block ) {
|
||||
$default_label = __( 'Older Comments' );
|
||||
$label = isset( $attributes['label'] ) && ! empty( $attributes['label'] ) ? $attributes['label'] : $default_label;
|
||||
$label = ! empty( $attributes['label'] ) ? $attributes['label'] : $default_label;
|
||||
$pagination_arrow = get_comments_pagination_arrow( $block, 'previous' );
|
||||
|
||||
// Escaping early as pagination arrow can return HTML that should not be escaped.
|
||||
$label = esc_html( $label );
|
||||
if ( $pagination_arrow ) {
|
||||
$label = $pagination_arrow . $label;
|
||||
}
|
||||
|
||||
@ -290,12 +290,8 @@ function block_core_image_render_lightbox( $block_content, array $block, WP_Bloc
|
||||
$body_content = $processor->get_updated_html();
|
||||
|
||||
// Adds a button alongside image in the body content.
|
||||
$img = null;
|
||||
preg_match( '/<img[^>]+>/', $body_content, $img );
|
||||
|
||||
$button =
|
||||
$img[0]
|
||||
. '<button
|
||||
'<button
|
||||
class="lightbox-trigger"
|
||||
type="button"
|
||||
aria-haspopup="dialog"
|
||||
@ -310,7 +306,26 @@ function block_core_image_render_lightbox( $block_content, array $block, WP_Bloc
|
||||
</svg>
|
||||
</button>';
|
||||
|
||||
$body_content = preg_replace( '/<img[^>]+>/', $button, $body_content );
|
||||
$button_processor = new class( $body_content ) extends WP_HTML_Tag_Processor {
|
||||
/**
|
||||
* Inserts HTML immediately after the current token.
|
||||
*
|
||||
* @since 7.1.4
|
||||
*
|
||||
* @param string $html HTML to insert.
|
||||
*/
|
||||
public function block_core_image_insert_after( string $html ) {
|
||||
$this->set_bookmark( 'here' );
|
||||
$span = $this->bookmarks['here'];
|
||||
|
||||
$this->lexical_updates[] = new WP_HTML_Text_Replacement( $span->start + $span->length, 0, $html );
|
||||
}
|
||||
};
|
||||
|
||||
if ( $button_processor->next_tag( 'img' ) ) {
|
||||
$button_processor->block_core_image_insert_after( $button );
|
||||
}
|
||||
$body_content = $button_processor->get_updated_html();
|
||||
|
||||
add_action( 'wp_footer', 'block_core_image_print_lightbox_overlay' );
|
||||
|
||||
|
||||
@ -140,33 +140,43 @@ function render_block_core_playlist( $attributes, $content, $block ) {
|
||||
></div>';
|
||||
|
||||
// Add the waveform player container inside the figure.
|
||||
$figure = null;
|
||||
preg_match( '/<figure[^>]*>/', $content, $figure );
|
||||
if ( ! empty( $figure[0] ) ) {
|
||||
$content = preg_replace( '/(<figure[^>]*>)/', '$1' . $html, $content, 1 );
|
||||
}
|
||||
$processor = new class( $content ) extends WP_HTML_Tag_Processor {
|
||||
/**
|
||||
* Inserts HTML immediately after the current token.
|
||||
*
|
||||
* @since 7.1.4
|
||||
*
|
||||
* @param string $html HTML to insert.
|
||||
*/
|
||||
public function block_core_playlist_insert_after( string $html ) {
|
||||
$this->set_bookmark( 'here' );
|
||||
$span = $this->bookmarks['here'];
|
||||
|
||||
$processor = new WP_HTML_Tag_Processor( $content );
|
||||
$processor->next_tag( 'figure' );
|
||||
$processor->set_attribute( 'data-wp-interactive', 'core/playlist' );
|
||||
$this->lexical_updates[] = new WP_HTML_Text_Replacement( $span->start + $span->length, 0, $html );
|
||||
}
|
||||
};
|
||||
|
||||
$waveform_style = $attributes['waveformStyle'] ?? 'bars';
|
||||
|
||||
$processor->set_attribute(
|
||||
'data-wp-context',
|
||||
wp_json_encode(
|
||||
array(
|
||||
'playlistId' => $playlist_id,
|
||||
'currentId' => $playlist_tracks[0],
|
||||
'isPlaying' => false,
|
||||
'tracks' => $playlist_tracks,
|
||||
'waveformStyle' => $waveform_style,
|
||||
'showPlayButtonArtwork' => $show_play_button_artwork,
|
||||
'labelPauseTrack' => __( 'Pause' ),
|
||||
'labelSelectTrack' => __( 'Play' ),
|
||||
if ( $processor->next_tag( 'figure' ) ) {
|
||||
$processor->block_core_playlist_insert_after( $html );
|
||||
$processor->set_attribute( 'data-wp-interactive', 'core/playlist' );
|
||||
$processor->set_attribute(
|
||||
'data-wp-context',
|
||||
wp_json_encode(
|
||||
array(
|
||||
'playlistId' => $playlist_id,
|
||||
'currentId' => $playlist_tracks[0],
|
||||
'isPlaying' => false,
|
||||
'tracks' => $playlist_tracks,
|
||||
'waveformStyle' => $waveform_style,
|
||||
'showPlayButtonArtwork' => $show_play_button_artwork,
|
||||
'labelPauseTrack' => __( 'Pause' ),
|
||||
'labelSelectTrack' => __( 'Play' ),
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
// Track IDs are render-time only. Add them after inner blocks have rendered
|
||||
// so track buttons can update the Interactivity API state without storing
|
||||
|
||||
@ -57,7 +57,7 @@ function render_block_core_post_navigation_link( $attributes, $content ) {
|
||||
// `$label` is used to prepend the provided label, if we want to show the page title as well.
|
||||
if ( isset( $attributes['label'] ) && ! empty( $attributes['label'] ) ) {
|
||||
$label = "{$attributes['label']}";
|
||||
$link = $label;
|
||||
$link = wp_kses_post( $label );
|
||||
}
|
||||
|
||||
// If we want to also show the page title, make the page title a link and prepend the label.
|
||||
|
||||
@ -310,6 +310,22 @@ function wp_font_library_render_page() {
|
||||
function wp_font_library_intercept_render() {
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
if ( isset( $_GET['page'] ) && 'font-library' === $_GET['page'] ) {
|
||||
// The page renders outside the menu page callback flow, so it must
|
||||
// enforce authentication and capability checks itself. Without this,
|
||||
// any admin entry point firing `admin_init` (such as admin-post.php,
|
||||
// which serves logged-out requests) would render the page for
|
||||
// unauthenticated visitors.
|
||||
if ( ! is_user_logged_in() ) {
|
||||
auth_redirect();
|
||||
}
|
||||
|
||||
if ( ! current_user_can( 'edit_theme_options' ) ) {
|
||||
wp_die(
|
||||
__( 'Sorry, you are not allowed to access this page.' ),
|
||||
403
|
||||
);
|
||||
}
|
||||
|
||||
wp_font_library_render_page();
|
||||
exit;
|
||||
}
|
||||
|
||||
@ -310,6 +310,22 @@ function wp_options_connectors_render_page() {
|
||||
function wp_options_connectors_intercept_render() {
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
if ( isset( $_GET['page'] ) && 'options-connectors' === $_GET['page'] ) {
|
||||
// The page renders outside the menu page callback flow, so it must
|
||||
// enforce authentication and capability checks itself. Without this,
|
||||
// any admin entry point firing `admin_init` (such as admin-post.php,
|
||||
// which serves logged-out requests) would render the page for
|
||||
// unauthenticated visitors.
|
||||
if ( ! is_user_logged_in() ) {
|
||||
auth_redirect();
|
||||
}
|
||||
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
wp_die(
|
||||
__( 'Sorry, you are not allowed to access this page.' ),
|
||||
403
|
||||
);
|
||||
}
|
||||
|
||||
wp_options_connectors_render_page();
|
||||
exit;
|
||||
}
|
||||
|
||||
@ -11645,14 +11645,15 @@ var GeminiLogo = () => /* @__PURE__ */ React.createElement(
|
||||
var { store: connectorsStore } = unlock2(connectorsPrivateApis);
|
||||
function getConnectorScriptModuleData() {
|
||||
try {
|
||||
return JSON.parse(
|
||||
document.getElementById(
|
||||
"wp-script-module-data-options-connectors-wp-admin"
|
||||
)?.textContent ?? "{}"
|
||||
const script = document.querySelector(
|
||||
'script[id="wp-script-module-data-options-connectors-wp-admin"]'
|
||||
);
|
||||
if (script instanceof HTMLScriptElement) {
|
||||
return JSON.parse(script.text);
|
||||
}
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
function getConnectorData() {
|
||||
return getConnectorScriptModuleData().connectors ?? {};
|
||||
|
||||
@ -1 +1 @@
|
||||
<?php return array('dependencies' => array('react', 'react-dom', 'react-jsx-runtime', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-element', 'wp-i18n', 'wp-notices', 'wp-primitives', 'wp-private-apis', 'wp-theme', 'wp-url'), 'module_dependencies' => array(array('id' => '@wordpress/a11y', 'import' => 'static'), array('id' => '@wordpress/connectors', 'import' => 'static'), array('id' => '@wordpress/route', 'import' => 'static')), 'version' => '1c478cb5cadaf4aded06');
|
||||
<?php return array('dependencies' => array('react', 'react-dom', 'react-jsx-runtime', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-element', 'wp-i18n', 'wp-notices', 'wp-primitives', 'wp-private-apis', 'wp-theme', 'wp-url'), 'module_dependencies' => array(array('id' => '@wordpress/a11y', 'import' => 'static'), array('id' => '@wordpress/connectors', 'import' => 'static'), array('id' => '@wordpress/route', 'import' => 'static')), 'version' => '2d1e1deff36091f228ab');
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -245,7 +245,7 @@ class WP_Block_Parser {
|
||||
* match back in PHP to see which one it was.
|
||||
*/
|
||||
$has_match = preg_match(
|
||||
'/<!--\s+(?P<closer>\/)?wp:(?P<namespace>[a-z][a-z0-9_-]*\/)?(?P<name>[a-z][a-z0-9_-]*)\s+(?P<attrs>{(?:(?:[^}]+|}+(?=})|(?!}\s+\/?-->).)*+)?}\s+)?(?P<void>\/)?-->/s',
|
||||
'/<!--[ \t\f\r\n]+(?P<closer>\/)?wp:(?P<namespace>[a-z][a-z0-9_-]*\/)?(?P<name>[a-z][a-z0-9_-]*)[ \t\f\r\n]+(?P<attrs>{(?:(?:[^}]+|}+(?=})|(?!}[ \t\f\r\n]+\/?-->).)*+)?}[ \t\f\r\n]+)?(?P<void>\/)?-->/s',
|
||||
$this->document,
|
||||
$matches,
|
||||
PREG_OFFSET_CAPTURE,
|
||||
|
||||
@ -628,7 +628,13 @@ final class WP_Customize_Manager {
|
||||
if ( empty( $this->_changeset_uuid ) ) {
|
||||
$changeset_uuid = null;
|
||||
|
||||
if ( ! $this->branching() && $this->is_theme_active() ) {
|
||||
/**
|
||||
* Only users who can customize may have the latest unpublished changeset auto-loaded. Otherwise, an
|
||||
* unauthenticated preview request lacking a UUID could adopt another user's unpublished changeset and
|
||||
* disclose its state, since the UUID serves as the secret key for previewing. Unauthorized requests
|
||||
* get a fresh UUID instead, which matches no changeset and is rejected in {@see self::setup_theme()}.
|
||||
*/
|
||||
if ( ! $this->branching() && $this->is_theme_active() && current_user_can( 'customize' ) ) {
|
||||
$unpublished_changeset_posts = $this->get_changeset_posts(
|
||||
array(
|
||||
'post_status' => array_diff( get_post_stati(), array( 'auto-draft', 'publish', 'trash', 'inherit', 'private' ) ),
|
||||
|
||||
@ -20,8 +20,8 @@
|
||||
* accepted_args: int,
|
||||
* }
|
||||
*
|
||||
* @phpstan-implements Iterator<int, array<string, Hook_Callback>>
|
||||
* @phpstan-implements ArrayAccess<int, array<string, Hook_Callback>>
|
||||
* @phpstan-implements Iterator<int, array<non-decimal-int-string, Hook_Callback>>
|
||||
* @phpstan-implements ArrayAccess<int, array<non-decimal-int-string, Hook_Callback>>
|
||||
*/
|
||||
#[AllowDynamicProperties]
|
||||
final class WP_Hook implements Iterator, ArrayAccess {
|
||||
@ -31,7 +31,7 @@ final class WP_Hook implements Iterator, ArrayAccess {
|
||||
*
|
||||
* @since 4.7.0
|
||||
* @var array
|
||||
* @phpstan-var array<int, array<string, Hook_Callback>>
|
||||
* @phpstan-var array<int, array<non-decimal-int-string, Hook_Callback>>
|
||||
*/
|
||||
public $callbacks = array();
|
||||
|
||||
@ -502,7 +502,7 @@ final class WP_Hook implements Iterator, ArrayAccess {
|
||||
*
|
||||
* @param int $offset The offset to retrieve.
|
||||
* @return array|null If set, the value at the specified offset, null otherwise.
|
||||
* @phpstan-return array<string, Hook_Callback>|null
|
||||
* @phpstan-return array<non-decimal-int-string, Hook_Callback>|null
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetGet( $offset ) {
|
||||
@ -518,7 +518,7 @@ final class WP_Hook implements Iterator, ArrayAccess {
|
||||
*
|
||||
* @param int|null $offset The offset to assign the value to.
|
||||
* @param array $value The value to set.
|
||||
* @phpstan-param array<string, Hook_Callback> $value
|
||||
* @phpstan-param array<non-decimal-int-string, Hook_Callback> $value
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetSet( $offset, $value ) {
|
||||
@ -554,7 +554,7 @@ final class WP_Hook implements Iterator, ArrayAccess {
|
||||
* @link https://www.php.net/manual/en/iterator.current.php
|
||||
*
|
||||
* @return array|false Array of callbacks at current priority, false if there are no more elements.
|
||||
* @phpstan-return array<string, Hook_Callback>|false
|
||||
* @phpstan-return array<non-decimal-int-string, Hook_Callback>|false
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function current() {
|
||||
@ -569,7 +569,7 @@ final class WP_Hook implements Iterator, ArrayAccess {
|
||||
* @link https://www.php.net/manual/en/iterator.next.php
|
||||
*
|
||||
* @return array|false Array of callbacks at next priority, false if there are no more elements.
|
||||
* @phpstan-return array<string, Hook_Callback>|false
|
||||
* @phpstan-return array<non-decimal-int-string, Hook_Callback>|false
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function next() {
|
||||
|
||||
@ -1023,7 +1023,10 @@ class WP_Http {
|
||||
|
||||
// Strip all /path/../ out of the path.
|
||||
while ( strpos( $path, '../' ) > 1 ) {
|
||||
$path = preg_replace( '![^/]+/\.\./!', '', $path );
|
||||
$path = preg_replace( '![^/]+/\.\./!', '', $path, -1, $segment_replacement_count );
|
||||
if ( 0 === $segment_replacement_count ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Strip any final leading ../ from the path.
|
||||
|
||||
@ -79,7 +79,6 @@ class WP_oEmbed {
|
||||
'#https?://(www\.)?twitter\.com/i/moments/.*#i' => array( 'https://publish.twitter.com/oembed', true ),
|
||||
'#https?://(www\.)?soundcloud\.com/.*#i' => array( 'https://soundcloud.com/oembed', true ),
|
||||
'#https?://(open|play)\.spotify\.com/.*#i' => array( 'https://embed.spotify.com/oembed/', true ),
|
||||
'#https?://(.+\.)?imgur\.com/.*#i' => array( 'https://api.imgur.com/oembed', true ),
|
||||
'#https?://(www\.)?issuu\.com/.+/docs/.+#i' => array( 'https://issuu.com/oembed_wp', true ),
|
||||
'#https?://(www\.)?mixcloud\.com/.*#i' => array( 'https://app.mixcloud.com/oembed/', true ),
|
||||
'#https?://(www\.|embed\.)?ted\.com/talks/.*#i' => array( 'https://www.ted.com/services/v1/oembed.{format}', true ),
|
||||
@ -88,7 +87,7 @@ class WP_oEmbed {
|
||||
'#https?://(www\.)?kickstarter\.com/projects/.*#i' => array( 'https://www.kickstarter.com/services/oembed', true ),
|
||||
'#https?://kck\.st/.*#i' => array( 'https://www.kickstarter.com/services/oembed', true ),
|
||||
'#https?://cloudup\.com/.*#i' => array( 'https://cloudup.com/oembed', true ),
|
||||
'#https?://(www\.)?reverbnation\.com/.*#i' => array( 'https://www.reverbnation.com/oembed', true ),
|
||||
'#https?://((legacy|www)\.)?reverbnation\.com/.*#i' => array( 'https://legacy.reverbnation.com/oembed', true ),
|
||||
'#https?://videopress\.com/v/.*#' => array( 'https://public-api.wordpress.com/oembed/?for=' . $host, true ),
|
||||
'#https?://(www\.)?reddit\.com/r/[^/]+/comments/.*#i' => array( 'https://www.reddit.com/oembed', true ),
|
||||
'#https?://(www\.)?speakerdeck\.com/.*#i' => array( 'https://speakerdeck.com/oembed.{format}', true ),
|
||||
@ -102,9 +101,6 @@ class WP_oEmbed {
|
||||
'#https?://(www\.)?amzn\.in/.*#i' => array( 'https://read.amazon.in/kp/api/oembed', true ),
|
||||
'#https?://(www\.)?amzn\.asia/.*#i' => array( 'https://read.amazon.com.au/kp/api/oembed', true ),
|
||||
'#https?://(www\.)?z\.cn/.*#i' => array( 'https://read.amazon.cn/kp/api/oembed', true ),
|
||||
'#https?://www\.someecards\.com/.+-cards/.+#i' => array( 'https://www.someecards.com/v2/oembed/', true ),
|
||||
'#https?://www\.someecards\.com/usercards/viewcard/.+#i' => array( 'https://www.someecards.com/v2/oembed/', true ),
|
||||
'#https?://some\.ly\/.+#i' => array( 'https://www.someecards.com/v2/oembed/', true ),
|
||||
'#https?://(www\.)?tiktok\.com/.*/video/.*#i' => array( 'https://www.tiktok.com/oembed', true ),
|
||||
'#https?://(www\.)?tiktok\.com/@.*#i' => array( 'https://www.tiktok.com/oembed', true ),
|
||||
'#https?://([a-z]{2}|www)\.pinterest\.com(\.(au|mx))?/.*#i' => array( 'https://www.pinterest.com/oembed.json', true ),
|
||||
@ -154,7 +150,6 @@ class WP_oEmbed {
|
||||
* | Dailymotion | dai.ly | 3.6.0 |
|
||||
* | Flickr | flic.kr | 3.6.0 |
|
||||
* | Spotify | spotify.com | 3.6.0 |
|
||||
* | Imgur | imgur.com | 3.9.0 |
|
||||
* | Animoto | animoto.com | 4.0.0 |
|
||||
* | Animoto | video214.com | 4.0.0 |
|
||||
* | Issuu | issuu.com | 4.0.0 |
|
||||
@ -183,8 +178,6 @@ class WP_oEmbed {
|
||||
* | Amazon | a.co | 4.9.0 |
|
||||
* | Amazon | amzn.to (eu, in, asia) | 4.9.0 |
|
||||
* | Amazon | z.cn | 4.9.0 |
|
||||
* | Someecards | someecards.com | 4.9.0 |
|
||||
* | Someecards | some.ly | 4.9.0 |
|
||||
* | Crowdsignal | survey.fm | 5.1.0 |
|
||||
* | TikTok | tiktok.com | 5.4.0 |
|
||||
* | Pinterest | pinterest.com | 5.9.0 |
|
||||
@ -219,6 +212,9 @@ class WP_oEmbed {
|
||||
* | Meetup.com | meetu.ps | 3.9.0 | 6.0.1 |
|
||||
* | SlideShare | slideshare.net | 3.5.0 | 6.6.0 |
|
||||
* | Screencast | screencast.com | 4.8.0 | 6.8.2 |
|
||||
* | Imgur | imgur.com | 3.9.0 | 7.1.3 |
|
||||
* | Someecards | someecards.com | 4.9.0 | 7.1.3 |
|
||||
* | Someecards | some.ly | 4.9.0 | 7.1.3 |
|
||||
*
|
||||
* @see wp_oembed_add_provider()
|
||||
*
|
||||
|
||||
@ -3484,43 +3484,6 @@ class WP_Query {
|
||||
$this->posts = apply_filters_ref_array( 'posts_results', array( $this->posts, &$this ) );
|
||||
}
|
||||
|
||||
if ( ! empty( $this->posts ) && $this->is_comment_feed && $this->is_singular ) {
|
||||
/** This filter is documented in wp-includes/class-wp-query.php */
|
||||
$cjoin = apply_filters_ref_array( 'comment_feed_join', array( '', &$this ) );
|
||||
|
||||
/** This filter is documented in wp-includes/class-wp-query.php */
|
||||
$cwhere = apply_filters_ref_array( 'comment_feed_where', array( "WHERE comment_post_ID = '{$this->posts[0]->ID}' AND comment_approved = '1' AND {$wpdb->comments}.comment_type != 'note'", &$this ) );
|
||||
|
||||
/** This filter is documented in wp-includes/class-wp-query.php */
|
||||
$cgroupby = apply_filters_ref_array( 'comment_feed_groupby', array( '', &$this ) );
|
||||
$cgroupby = ( ! empty( $cgroupby ) ) ? 'GROUP BY ' . $cgroupby : '';
|
||||
|
||||
/** This filter is documented in wp-includes/class-wp-query.php */
|
||||
$corderby = apply_filters_ref_array( 'comment_feed_orderby', array( 'comment_date_gmt DESC', &$this ) );
|
||||
$corderby = ( ! empty( $corderby ) ) ? 'ORDER BY ' . $corderby : '';
|
||||
|
||||
/** This filter is documented in wp-includes/class-wp-query.php */
|
||||
$climits = apply_filters_ref_array( 'comment_feed_limits', array( 'LIMIT ' . get_option( 'posts_per_rss' ), &$this ) );
|
||||
|
||||
$comments_request = "SELECT {$wpdb->comments}.comment_ID FROM {$wpdb->comments} $cjoin $cwhere $cgroupby $corderby $climits";
|
||||
|
||||
$comment_key = md5( $comments_request );
|
||||
$comment_last_changed = wp_cache_get_last_changed( 'comment' );
|
||||
|
||||
$comment_cache_key = "comment_feed:$comment_key";
|
||||
$comment_ids = wp_cache_get_salted( $comment_cache_key, 'comment-queries', $comment_last_changed );
|
||||
if ( false === $comment_ids ) {
|
||||
$comment_ids = $wpdb->get_col( $comments_request );
|
||||
wp_cache_set_salted( $comment_cache_key, $comment_ids, 'comment-queries', $comment_last_changed );
|
||||
}
|
||||
_prime_comment_caches( $comment_ids );
|
||||
|
||||
// Convert to WP_Comment.
|
||||
/** @var WP_Comment[] */
|
||||
$this->comments = array_map( 'get_comment', $comment_ids );
|
||||
$this->comment_count = count( $this->comments );
|
||||
}
|
||||
|
||||
// Check post status to determine if post should be displayed.
|
||||
if ( ! empty( $this->posts ) && ( $this->is_single || $this->is_page ) ) {
|
||||
$status = get_post_status( $this->posts[0] );
|
||||
@ -3579,6 +3542,43 @@ class WP_Query {
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $this->posts ) && $this->is_comment_feed && $this->is_singular ) {
|
||||
/** This filter is documented in wp-includes/class-wp-query.php */
|
||||
$cjoin = apply_filters_ref_array( 'comment_feed_join', array( '', &$this ) );
|
||||
|
||||
/** This filter is documented in wp-includes/class-wp-query.php */
|
||||
$cwhere = apply_filters_ref_array( 'comment_feed_where', array( "WHERE comment_post_ID = '{$this->posts[0]->ID}' AND comment_approved = '1' AND {$wpdb->comments}.comment_type != 'note'", &$this ) );
|
||||
|
||||
/** This filter is documented in wp-includes/class-wp-query.php */
|
||||
$cgroupby = apply_filters_ref_array( 'comment_feed_groupby', array( '', &$this ) );
|
||||
$cgroupby = ( ! empty( $cgroupby ) ) ? 'GROUP BY ' . $cgroupby : '';
|
||||
|
||||
/** This filter is documented in wp-includes/class-wp-query.php */
|
||||
$corderby = apply_filters_ref_array( 'comment_feed_orderby', array( 'comment_date_gmt DESC', &$this ) );
|
||||
$corderby = ( ! empty( $corderby ) ) ? 'ORDER BY ' . $corderby : '';
|
||||
|
||||
/** This filter is documented in wp-includes/class-wp-query.php */
|
||||
$climits = apply_filters_ref_array( 'comment_feed_limits', array( 'LIMIT ' . get_option( 'posts_per_rss' ), &$this ) );
|
||||
|
||||
$comments_request = "SELECT {$wpdb->comments}.comment_ID FROM {$wpdb->comments} $cjoin $cwhere $cgroupby $corderby $climits";
|
||||
|
||||
$comment_key = md5( $comments_request );
|
||||
$comment_last_changed = wp_cache_get_last_changed( 'comment' );
|
||||
|
||||
$comment_cache_key = "comment_feed:$comment_key";
|
||||
$comment_ids = wp_cache_get_salted( $comment_cache_key, 'comment-queries', $comment_last_changed );
|
||||
if ( false === $comment_ids ) {
|
||||
$comment_ids = $wpdb->get_col( $comments_request );
|
||||
wp_cache_set_salted( $comment_cache_key, $comment_ids, 'comment-queries', $comment_last_changed );
|
||||
}
|
||||
_prime_comment_caches( $comment_ids );
|
||||
|
||||
// Convert to WP_Comment.
|
||||
/** @var WP_Comment[] */
|
||||
$this->comments = array_map( 'get_comment', $comment_ids );
|
||||
$this->comment_count = count( $this->comments );
|
||||
}
|
||||
|
||||
// Put sticky posts at the top of the posts array.
|
||||
$sticky_posts = get_option( 'sticky_posts' );
|
||||
if ( $this->is_home && $page <= 1 && is_array( $sticky_posts ) && ! empty( $sticky_posts ) && ! $query_vars['ignore_sticky_posts'] ) {
|
||||
|
||||
@ -3880,8 +3880,18 @@ class WP_Theme_JSON {
|
||||
// Only store if the variation has blockGap defined.
|
||||
if ( isset( $style_variation_node['spacing']['blockGap'] ) ) {
|
||||
// Append block selector to the variation selector for proper targeting.
|
||||
$variation_metadata_with_selector = $style_variation;
|
||||
$variation_metadata_with_selector['selector'] = $style_variation['selector'] . $block_metadata['css'];
|
||||
$variation_metadata_with_selector = $style_variation;
|
||||
$variation_metadata_with_selector['selector'] = $style_variation['selector'] . $block_metadata['css'];
|
||||
|
||||
/*
|
||||
* `get_layout_styles()` reads `name` as a block name, to check that the block
|
||||
* supports layout at all. A variation node's `name` is the variation slug,
|
||||
* which is never a registered block, so the check fails and every variation
|
||||
* gap rule is discarded. Pass the block the variation belongs to, so the
|
||||
* support check answers the question it is actually asking.
|
||||
*/
|
||||
$variation_metadata_with_selector['name'] = $block_name;
|
||||
|
||||
$style_variation_layout_metadata[ $style_variation['selector'] ] = array(
|
||||
'metadata' => $variation_metadata_with_selector,
|
||||
'node' => $style_variation_node,
|
||||
@ -3937,7 +3947,11 @@ class WP_Theme_JSON {
|
||||
if ( isset( $breakpoint_node['spacing']['blockGap'] ) ) {
|
||||
$variation_layout_metadata = $style_variation;
|
||||
$variation_layout_metadata['selector'] = $style_variation['selector'] . $block_metadata['css'];
|
||||
$variation_responsive_css .= $this->get_layout_styles(
|
||||
|
||||
// The variation slug is not a block name here either. See above.
|
||||
$variation_layout_metadata['name'] = $block_name;
|
||||
|
||||
$variation_responsive_css .= $this->get_layout_styles(
|
||||
$variation_layout_metadata,
|
||||
array(
|
||||
'node' => $breakpoint_node,
|
||||
|
||||
@ -16,11 +16,25 @@
|
||||
#[AllowDynamicProperties]
|
||||
class WP_Widget_Factory {
|
||||
|
||||
/**
|
||||
* Prefix for the key under which a widget registered as an instance is stored.
|
||||
*
|
||||
* Without it the key would be the decimal representation of an integer, which PHP casts from
|
||||
* string to int when it is used as an array key.
|
||||
*
|
||||
* @since 7.1.1
|
||||
*/
|
||||
private const INSTANCE_KEY_PREFIX = 'spl_object_id:';
|
||||
|
||||
/**
|
||||
* Widgets array.
|
||||
*
|
||||
* Keyed by class name for a widget registered by name, and by a prefixed object ID for a widget
|
||||
* registered as an instance.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @var array
|
||||
* @var array<string, WP_Widget>
|
||||
* @phpstan-var array<non-decimal-int-string, WP_Widget>
|
||||
*/
|
||||
public $widgets = array();
|
||||
|
||||
@ -52,12 +66,13 @@ class WP_Widget_Factory {
|
||||
* @since 2.8.0
|
||||
* @since 4.6.0 Updated the `$widget` parameter to also accept a WP_Widget instance object
|
||||
* instead of simply a `WP_Widget` subclass name.
|
||||
* @since 7.1.1 The key for an instance is prefixed so that it is never cast to an integer.
|
||||
*
|
||||
* @param string|WP_Widget $widget Either the name of a `WP_Widget` subclass or an instance of a `WP_Widget` subclass.
|
||||
*/
|
||||
public function register( $widget ) {
|
||||
if ( $widget instanceof WP_Widget ) {
|
||||
$this->widgets[ spl_object_id( $widget ) ] = $widget;
|
||||
$this->widgets[ self::INSTANCE_KEY_PREFIX . spl_object_id( $widget ) ] = $widget;
|
||||
} else {
|
||||
$this->widgets[ $widget ] = new $widget();
|
||||
}
|
||||
@ -69,12 +84,13 @@ class WP_Widget_Factory {
|
||||
* @since 2.8.0
|
||||
* @since 4.6.0 Updated the `$widget` parameter to also accept a WP_Widget instance object
|
||||
* instead of simply a `WP_Widget` subclass name.
|
||||
* @since 7.1.1 The key for an instance is prefixed so that it is never cast to an integer.
|
||||
*
|
||||
* @param string|WP_Widget $widget Either the name of a `WP_Widget` subclass or an instance of a `WP_Widget` subclass.
|
||||
*/
|
||||
public function unregister( $widget ) {
|
||||
if ( $widget instanceof WP_Widget ) {
|
||||
unset( $this->widgets[ spl_object_id( $widget ) ] );
|
||||
unset( $this->widgets[ self::INSTANCE_KEY_PREFIX . spl_object_id( $widget ) ] );
|
||||
} else {
|
||||
unset( $this->widgets[ $widget ] );
|
||||
}
|
||||
|
||||
@ -1462,6 +1462,33 @@ class wp_xmlrpc_server extends IXR_Server {
|
||||
return new IXR_Error( 403, __( 'Invalid post type.' ) );
|
||||
}
|
||||
|
||||
// Reject writes to internal-only builtin post types (e.g. customize_changeset)
|
||||
// whose intended write path is a dedicated helper, not a generic post API.
|
||||
$is_internal_only = (
|
||||
empty( $post_type->public )
|
||||
&& empty( $post_type->show_in_rest )
|
||||
&& ! empty( $post_type->_builtin )
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters whether a post type accepts writes via XML-RPC.
|
||||
*
|
||||
* Defaults to false for internal-only builtin post types (public=false,
|
||||
* show_in_rest=false, _builtin=true), such as customize_changeset, whose
|
||||
* writes are meant to flow through dedicated helpers. Return true to opt
|
||||
* a post type back in.
|
||||
*
|
||||
* @since 7.1.1
|
||||
*
|
||||
* @param bool $allowed Whether the post type accepts XML-RPC writes.
|
||||
* @param WP_Post_Type $post_type The post type object.
|
||||
*/
|
||||
$allowed = apply_filters( 'xmlrpc_allow_post_type_writes', ! $is_internal_only, $post_type );
|
||||
|
||||
if ( ! $allowed ) {
|
||||
return new IXR_Error( 403, __( 'Sorry, this post type is not supported over XML-RPC.' ) );
|
||||
}
|
||||
|
||||
$update = ! empty( $post_data['ID'] );
|
||||
|
||||
if ( $update ) {
|
||||
|
||||
@ -746,8 +746,9 @@ class WP {
|
||||
|
||||
$set_404 = true;
|
||||
|
||||
// Never 404 for the admin, robots, or favicon.
|
||||
if ( is_admin() || is_robots() || is_favicon() ) {
|
||||
// Never 404 here for the admin, robots, favicon, or sitemaps.
|
||||
// Sitemap routes send their own status in WP_Sitemaps::render_sitemaps().
|
||||
if ( is_admin() || is_robots() || is_favicon() || is_sitemap() || get_query_var( 'sitemap-stylesheet' ) ) {
|
||||
$set_404 = false;
|
||||
|
||||
// If posts were found, check for paged content.
|
||||
|
||||
@ -599,10 +599,14 @@ html:lang(he-il) .rtl #wpadminbar * {
|
||||
content: none;
|
||||
}
|
||||
|
||||
#wpadminbar #wp-admin-bar-site-name > .ab-item .site-icon {
|
||||
/* The adminbar icon needs additional styling to prevent 3rd party styles from overriding the size. */
|
||||
#wpadminbar #wp-admin-bar-site-name > .ab-item img.site-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: #f0f0f1; /* matching my-account (user avatar) node's background */
|
||||
max-width: 20px;
|
||||
max-height: 20px;
|
||||
min-width: 20px;
|
||||
min-height: 20px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
@ -940,12 +944,24 @@ html:lang(he-il) .rtl #wpadminbar * {
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
#wpadminbar #wp-admin-bar-site-name > .ab-item .site-icon {
|
||||
/*
|
||||
* Flex prevents `text-indent` from hiding the site title, and is unused here
|
||||
* since the icon is positioned absolutely below.
|
||||
*/
|
||||
#wpadminbar #wp-admin-bar-site-name.has-site-icon > .ab-item {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#wpadminbar #wp-admin-bar-site-name > .ab-item img.site-icon {
|
||||
position: absolute;
|
||||
top: 9px;
|
||||
right: 12px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
max-width: 28px;
|
||||
max-height: 28px;
|
||||
min-width: 28px;
|
||||
min-height: 28px;
|
||||
margin: 0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -598,10 +598,14 @@ html:lang(he-il) .rtl #wpadminbar * {
|
||||
content: none;
|
||||
}
|
||||
|
||||
#wpadminbar #wp-admin-bar-site-name > .ab-item .site-icon {
|
||||
/* The adminbar icon needs additional styling to prevent 3rd party styles from overriding the size. */
|
||||
#wpadminbar #wp-admin-bar-site-name > .ab-item img.site-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: #f0f0f1; /* matching my-account (user avatar) node's background */
|
||||
max-width: 20px;
|
||||
max-height: 20px;
|
||||
min-width: 20px;
|
||||
min-height: 20px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
@ -939,12 +943,24 @@ html:lang(he-il) .rtl #wpadminbar * {
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
#wpadminbar #wp-admin-bar-site-name > .ab-item .site-icon {
|
||||
/*
|
||||
* Flex prevents `text-indent` from hiding the site title, and is unused here
|
||||
* since the icon is positioned absolutely below.
|
||||
*/
|
||||
#wpadminbar #wp-admin-bar-site-name.has-site-icon > .ab-item {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#wpadminbar #wp-admin-bar-site-name > .ab-item img.site-icon {
|
||||
position: absolute;
|
||||
top: 9px;
|
||||
left: 12px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
max-width: 28px;
|
||||
max-height: 28px;
|
||||
min-width: 28px;
|
||||
min-height: 28px;
|
||||
margin: 0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -59,7 +59,10 @@
|
||||
}
|
||||
|
||||
.wp-block-accordion-panel[hidden] {
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
margin-block-start: 0;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.wp-block-archives {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -59,7 +59,10 @@
|
||||
}
|
||||
|
||||
.wp-block-accordion-panel[hidden] {
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
margin-block-start: 0;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.wp-block-archives {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -15,6 +15,17 @@
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @see WP_Customize_Setting
|
||||
*
|
||||
* @phpstan-type Header_Image_Data array{
|
||||
* attachment_id?: int,
|
||||
* url?: string,
|
||||
* thumbnail_url?: string,
|
||||
* timestamp?: int,
|
||||
* width?: int,
|
||||
* height?: int,
|
||||
* alt_text?: string,
|
||||
* attachment_parent?: int,
|
||||
* }
|
||||
*/
|
||||
final class WP_Customize_Header_Image_Setting extends WP_Customize_Setting {
|
||||
|
||||
@ -62,4 +73,163 @@ final class WP_Customize_Header_Image_Setting extends WP_Customize_Setting {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes a header value.
|
||||
*
|
||||
* The value is expected to be one of the following:
|
||||
*
|
||||
* - An array of header image data, with the keys `attachment_id`, `url`, `thumbnail_url`, `timestamp`, `width`,
|
||||
* `height`, `alt_text`, and `attachment_parent`, as supplied by {@see get_uploaded_header_images()}. Any other
|
||||
* key is discarded.
|
||||
* - An array with a `choice` key, being the legacy format in which any of the other accepted values is nested.
|
||||
* - The string `remove-header`, `random-default-image`, or `random-uploaded-image`.
|
||||
* - A string corresponding to one of the keys for the array returned by {@see get_uploaded_header_images()}, or
|
||||
* one of the keys for the array passed into {@see register_default_headers()}.
|
||||
*
|
||||
* @since 7.1.1
|
||||
*
|
||||
* @see WP_Customize_Header_Image_Setting::update()
|
||||
* @see Custom_Image_Header::set_header_image()
|
||||
*
|
||||
* @param mixed $value Value to sanitize.
|
||||
* @return array|string|WP_Error|null Sanitized value, or `null`/`WP_Error` if invalid. The array holds
|
||||
* the header image data, or that data nested under a `choice` key,
|
||||
* before the `customize_sanitize_header_image_data` filter, which
|
||||
* may return anything, is applied to it.
|
||||
*
|
||||
* @phpstan-return array<mixed, mixed>|string|WP_Error|null
|
||||
*/
|
||||
public function sanitize( $value ) {
|
||||
/*
|
||||
* The update() method unwraps the legacy `choice` format before handing the value off to
|
||||
* Custom_Image_Header::set_header_image(), so the nested value is what must be sanitized.
|
||||
*/
|
||||
if ( is_array( $value ) && isset( $value['choice'] ) ) {
|
||||
$choice = $this->sanitize_choice( $value['choice'] );
|
||||
if ( is_null( $choice ) || is_wp_error( $choice ) ) {
|
||||
return $choice;
|
||||
}
|
||||
$value = array( 'choice' => $choice );
|
||||
} else {
|
||||
$value = $this->sanitize_choice( $value );
|
||||
if ( is_null( $value ) || is_wp_error( $value ) ) {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
return parent::sanitize( $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes a header image choice.
|
||||
*
|
||||
* This is the value which is ultimately passed to {@see Custom_Image_Header::set_header_image()}, whether
|
||||
* supplied at the top level of the setting value or nested under its legacy `choice` key.
|
||||
*
|
||||
* @since 7.1.1
|
||||
*
|
||||
* @param mixed $value Value to sanitize.
|
||||
* @return array|string|WP_Error|null Sanitized value, or `null`/`WP_Error` if invalid.
|
||||
*
|
||||
* @phpstan-return Header_Image_Data|string|WP_Error|null
|
||||
*/
|
||||
private function sanitize_choice( $value ) {
|
||||
// Custom_Image_Header::set_header_image() accepts an object in place of an array.
|
||||
if ( is_object( $value ) ) {
|
||||
$value = (array) $value;
|
||||
}
|
||||
|
||||
if ( is_string( $value ) ) {
|
||||
return sanitize_text_field( $value );
|
||||
}
|
||||
|
||||
if ( ! is_array( $value ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* The sanitized value is assembled member by member rather than filtered down from the
|
||||
* supplied one, so that nothing but the members below can end up in it.
|
||||
*/
|
||||
$sanitized = array();
|
||||
|
||||
if ( isset( $value['attachment_id'] ) ) {
|
||||
if ( ! is_scalar( $value['attachment_id'] ) ) {
|
||||
return null;
|
||||
}
|
||||
$attachment_id = absint( $value['attachment_id'] );
|
||||
|
||||
/*
|
||||
* A supplied attachment must be an existing image, since its ID is written to postmeta and its
|
||||
* data displayed. Note that an ID of zero must be skipped rather than looked up, as
|
||||
* get_post_mime_type() falls back to the global post when passed an empty value.
|
||||
*/
|
||||
if ( $attachment_id > 0 ) {
|
||||
$mime_type = get_post_mime_type( $attachment_id );
|
||||
if ( ! is_string( $mime_type ) || ! str_starts_with( $mime_type, 'image/' ) ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
$sanitized['attachment_id'] = $attachment_id;
|
||||
}
|
||||
|
||||
if ( isset( $value['url'] ) ) {
|
||||
if ( ! is_string( $value['url'] ) ) {
|
||||
return null;
|
||||
}
|
||||
$sanitized['url'] = sanitize_url( $value['url'] );
|
||||
if ( '' === $sanitized['url'] ) {
|
||||
return new WP_Error( 'invalid_url', __( 'Invalid URL.' ) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $value['thumbnail_url'] ) ) {
|
||||
if ( ! is_string( $value['thumbnail_url'] ) ) {
|
||||
return null;
|
||||
}
|
||||
$sanitized['thumbnail_url'] = sanitize_url( $value['thumbnail_url'] );
|
||||
if ( '' === $sanitized['thumbnail_url'] ) {
|
||||
return new WP_Error( 'invalid_url', __( 'Invalid URL.' ) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $value['timestamp'] ) ) {
|
||||
if ( ! is_scalar( $value['timestamp'] ) ) {
|
||||
return null;
|
||||
}
|
||||
$sanitized['timestamp'] = absint( $value['timestamp'] );
|
||||
}
|
||||
|
||||
if ( isset( $value['width'] ) ) {
|
||||
if ( ! is_scalar( $value['width'] ) ) {
|
||||
return null;
|
||||
}
|
||||
$sanitized['width'] = absint( $value['width'] );
|
||||
}
|
||||
|
||||
if ( isset( $value['height'] ) ) {
|
||||
if ( ! is_scalar( $value['height'] ) ) {
|
||||
return null;
|
||||
}
|
||||
$sanitized['height'] = absint( $value['height'] );
|
||||
}
|
||||
|
||||
if ( isset( $value['alt_text'] ) ) {
|
||||
if ( ! is_string( $value['alt_text'] ) ) {
|
||||
return null;
|
||||
}
|
||||
$sanitized['alt_text'] = sanitize_text_field( $value['alt_text'] );
|
||||
}
|
||||
|
||||
if ( isset( $value['attachment_parent'] ) ) {
|
||||
if ( ! is_scalar( $value['attachment_parent'] ) ) {
|
||||
return null;
|
||||
}
|
||||
$sanitized['attachment_parent'] = absint( $value['attachment_parent'] );
|
||||
}
|
||||
|
||||
return $sanitized;
|
||||
}
|
||||
}
|
||||
|
||||
@ -560,7 +560,7 @@ function wpautop( $text, $br = true ) {
|
||||
$text = preg_replace( '|<p>(<li.+?)</p>|', '$1', $text );
|
||||
|
||||
// If a <blockquote> is wrapped with a <p>, move it inside the <blockquote>.
|
||||
$text = preg_replace( '|<p><blockquote([^>]*)>|i', '<blockquote$1><p>', $text );
|
||||
$text = preg_replace( '!<p><blockquote((?:[^>"\']|"[^"]*"|\'[^\']*\')*)>!i', '<blockquote$1><p>', $text );
|
||||
$text = str_replace( '</blockquote></p>', '</p></blockquote>', $text );
|
||||
|
||||
// If an opening or closing block element tag is preceded by an opening <p> tag, remove it.
|
||||
|
||||
@ -384,7 +384,7 @@ function get_search_form( $args = array() ) {
|
||||
* @type string $id Unique ID for the popover element. Default is a
|
||||
* generated unique ID.
|
||||
* @type string $button Existing `button` or `a` markup. Used instead of generated button.
|
||||
* Default standard button HTML.
|
||||
* Default empty string.
|
||||
* @type string $label Not used for tooltips.
|
||||
* @type string $close_label Not used for tooltips.
|
||||
* @type string $icon Dashicons icon class for the toggle button.
|
||||
@ -414,7 +414,7 @@ function wp_get_tooltip( $content, $args = array() ) {
|
||||
* @type string $id Unique ID for the popover element. Default is a
|
||||
* generated unique ID.
|
||||
* @type string $button Existing `button` markup. Used instead of generated button.
|
||||
* Default standard button HTML.
|
||||
* Default empty string.
|
||||
* @type string $label Accessible label for the toggle button.
|
||||
* Default 'Help', matching the default icon.
|
||||
* Ignored for tooltips.
|
||||
@ -449,7 +449,7 @@ function wp_get_toggletip( $content, $args = array() ) {
|
||||
* @type string $id Unique ID for the popover element. Default is a
|
||||
* generated unique ID.
|
||||
* @type string $button Existing `button` or `a` markup. Used instead of generated button.
|
||||
* Default standard button HTML.
|
||||
* Default empty string.
|
||||
* @type string $label Accessible label for the toggle button.
|
||||
* Default 'Help', matching the default icon.
|
||||
* Ignored for tooltips.
|
||||
@ -473,7 +473,7 @@ function wp_get_tooltip_helper( $content, $args = array() ) {
|
||||
|
||||
$defaults = array(
|
||||
'id' => wp_unique_id( 'wp-tooltip-' ),
|
||||
'button' => '<button type="button" aria-label="%3$s"><span class="dashicons %4$s" aria-hidden="true"></span></button>',
|
||||
'button' => '',
|
||||
'label' => __( 'Help' ),
|
||||
'close_label' => __( 'Close' ),
|
||||
'icon' => 'dashicons-editor-help',
|
||||
@ -488,39 +488,67 @@ function wp_get_tooltip_helper( $content, $args = array() ) {
|
||||
$classes .= ' ' . $args['class'];
|
||||
}
|
||||
|
||||
$icon = ( $args['icon'] ) ? trim( $args['icon'] ) : $defaults['icon'];
|
||||
$id = ( $args['id'] ) ? $args['id'] : $defaults['id'];
|
||||
$button = ( $args['button'] ) ? $args['button'] : $defaults['button'];
|
||||
$processed = false;
|
||||
$icon = ( $args['icon'] ) ? trim( $args['icon'] ) : $defaults['icon'];
|
||||
$id = ( $args['id'] ) ? $args['id'] : $defaults['id'];
|
||||
|
||||
// Tooltips use the content as the accessible name; toggletips use the label.
|
||||
$label = ( 'tooltip' === $args['type'] ) ? wp_strip_all_tags( $content, true ) : $args['label'];
|
||||
|
||||
/*
|
||||
* The generated button is a plain skeleton. Every dynamic attribute is
|
||||
* added through the tag processor below, so caller-supplied markup is
|
||||
* never scanned or substituted and a percent sign in custom markup,
|
||||
* such as a percent-encoded URL, is never treated as a conversion
|
||||
* specification.
|
||||
*/
|
||||
$default_button = '<button type="button"><span></span></button>';
|
||||
|
||||
$is_default = ! $args['button'];
|
||||
$button = ( $args['button'] ) ? $args['button'] : $default_button;
|
||||
|
||||
// The accepted root element is a `button`, or an `a` for tooltips.
|
||||
$tag = false;
|
||||
$processor = new WP_HTML_Tag_Processor( $button );
|
||||
if ( true === $processor->next_tag( 'button' ) ) {
|
||||
$processor->add_class( 'wp-tooltip__toggle' );
|
||||
if ( 'tooltip' !== $args['type'] ) {
|
||||
$processor->set_attribute( 'popovertarget', '%2$s' );
|
||||
$processor->set_attribute( 'aria-haspopup', 'dialog' );
|
||||
}
|
||||
$button = $processor->get_updated_html();
|
||||
$processed = true;
|
||||
$tag = 'button';
|
||||
} else {
|
||||
// Reset processor.
|
||||
$processor = new WP_HTML_Tag_Processor( $button );
|
||||
if ( true === $processor->next_tag( 'a' ) && 'tooltip' === $args['type'] ) {
|
||||
$processor->add_class( 'wp-tooltip__toggle' );
|
||||
$button = $processor->get_updated_html();
|
||||
$processed = true;
|
||||
if ( 'tooltip' === $args['type'] && true === $processor->next_tag( 'a' ) ) {
|
||||
$tag = 'a';
|
||||
}
|
||||
}
|
||||
if ( ! $processed ) {
|
||||
// Button HTML passed was not valid.
|
||||
$processor = new WP_HTML_Tag_Processor( $defaults['button'] );
|
||||
$processor->add_class( 'wp-tooltip__toggle' );
|
||||
if ( 'tooltip' !== $args['type'] ) {
|
||||
$processor->set_attribute( 'popovertarget', '%2$s' );
|
||||
$processor->set_attribute( 'aria-haspopup', 'dialog' );
|
||||
}
|
||||
$button = $processor->get_updated_html();
|
||||
|
||||
if ( false === $tag ) {
|
||||
// Button HTML passed was not valid. Reset to default.
|
||||
$is_default = true;
|
||||
$button = $default_button;
|
||||
$processor = new WP_HTML_Tag_Processor( $button );
|
||||
$processor->next_tag( 'button' );
|
||||
$tag = 'button';
|
||||
}
|
||||
|
||||
/*
|
||||
* Attributes that apply to every accepted button are added in one pass.
|
||||
* Attributes that name the control are only added when the caller's
|
||||
* markup did not already provide them.
|
||||
*/
|
||||
if ( null === $processor->get_attribute( 'aria-label' ) ) {
|
||||
$processor->set_attribute( 'aria-label', $label );
|
||||
}
|
||||
$processor->add_class( 'wp-tooltip__toggle' );
|
||||
if ( 'button' === $tag && 'tooltip' !== $args['type'] ) {
|
||||
$processor->set_attribute( 'popovertarget', $id );
|
||||
$processor->set_attribute( 'aria-haspopup', 'dialog' );
|
||||
}
|
||||
|
||||
// The generated button also carries the dashicon on its inner span.
|
||||
if ( $is_default && true === $processor->next_tag( 'span' ) ) {
|
||||
$processor->set_attribute( 'class', 'dashicons ' . $icon );
|
||||
$processor->set_attribute( 'aria-hidden', 'true' );
|
||||
}
|
||||
|
||||
$button = $processor->get_updated_html();
|
||||
|
||||
/*
|
||||
* The markup only uses phrasing content so it is valid when nested
|
||||
* in a phrasing context. Sectioning content (e.g. `div`, `dialog`) will
|
||||
@ -528,11 +556,9 @@ function wp_get_tooltip_helper( $content, $args = array() ) {
|
||||
* the layout. See #65660.
|
||||
*/
|
||||
if ( 'tooltip' === $args['type'] ) {
|
||||
// Tooltips are only used to visually display labels.
|
||||
$label = wp_strip_all_tags( $content, true );
|
||||
$markup = sprintf(
|
||||
'<span class="%1$s">
|
||||
' . $button . '
|
||||
%6$s
|
||||
<span popover="hint" id="%2$s" class="wp-tooltip__bubble" role="tooltip">' .
|
||||
'<span id="%2$s-text" class="wp-tooltip__text">%5$s</span>' .
|
||||
'</span>' .
|
||||
@ -542,6 +568,7 @@ function wp_get_tooltip_helper( $content, $args = array() ) {
|
||||
esc_attr( $label ),
|
||||
esc_attr( $icon ),
|
||||
esc_html( $content ),
|
||||
$button,
|
||||
);
|
||||
} else {
|
||||
/*
|
||||
@ -551,7 +578,7 @@ function wp_get_tooltip_helper( $content, $args = array() ) {
|
||||
*/
|
||||
$markup = sprintf(
|
||||
'<span class="%1$s">
|
||||
' . $button . '
|
||||
%7$s
|
||||
<span popover="auto" id="%2$s" class="wp-tooltip__bubble" role="dialog" aria-label="%3$s" tabindex="-1" autofocus>' .
|
||||
'<span id="%2$s-text" class="wp-tooltip__text">%5$s</span>' .
|
||||
'<button type="button" class="wp-tooltip__close" popovertarget="%2$s" popovertargetaction="hide" aria-label="%6$s">' .
|
||||
@ -561,10 +588,11 @@ function wp_get_tooltip_helper( $content, $args = array() ) {
|
||||
'</span>',
|
||||
esc_attr( $classes ),
|
||||
esc_attr( $id ),
|
||||
esc_attr( $args['label'] ),
|
||||
esc_attr( $label ),
|
||||
esc_attr( $icon ),
|
||||
esc_html( $content ),
|
||||
esc_attr( $args['close_label'] ),
|
||||
$button,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -3988,7 +3988,7 @@ class WP_HTML_Tag_Processor {
|
||||
self::COMMENT_AS_HTML_COMMENT === $this->comment_type
|
||||
) {
|
||||
// Check if the text could close the comment.
|
||||
if ( 1 === preg_match( '/--!?>/', $plaintext_content ) ) {
|
||||
if ( 1 === preg_match( '/^-?>|--!?>/', $plaintext_content ) ) {
|
||||
_doing_it_wrong(
|
||||
__METHOD__,
|
||||
__( 'Comment text cannot contain a comment closer.' ),
|
||||
|
||||
@ -920,12 +920,13 @@ final class WP_Interactivity_API {
|
||||
*
|
||||
* @param WP_Interactivity_API_Directives_Processor $p The directives processor instance.
|
||||
* @param string $prefix The directive prefix to filter by.
|
||||
* @return array An array of entries containing the directive namespace, value, suffix, and unique ID.
|
||||
* @return array An array of entries containing the directive namespace, value, suffix, unique ID, and attribute name.
|
||||
* @phpstan-return list<array{
|
||||
* namespace: string|null,
|
||||
* value: mixed,
|
||||
* suffix: string|null,
|
||||
* unique_id: string|null,
|
||||
* attribute_name: non-empty-string,
|
||||
* }>
|
||||
*/
|
||||
private function get_directive_entries( WP_Interactivity_API_Directives_Processor $p, string $prefix ): array {
|
||||
@ -962,10 +963,11 @@ final class WP_Interactivity_API {
|
||||
|
||||
list( $namespace, $value ) = $this->extract_directive_value( $attribute_value, $default_namespace );
|
||||
$entries[] = array(
|
||||
'namespace' => $namespace,
|
||||
'value' => $value,
|
||||
'suffix' => $suffix,
|
||||
'unique_id' => $unique_id,
|
||||
'namespace' => $namespace,
|
||||
'value' => $value,
|
||||
'suffix' => $suffix,
|
||||
'unique_id' => $unique_id,
|
||||
'attribute_name' => $attribute_name,
|
||||
);
|
||||
}
|
||||
// Sort directive entries to ensure stable ordering with the client.
|
||||
@ -1113,6 +1115,24 @@ final class WP_Interactivity_API {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove a binding that would change an `object` attribute whose value KSES checks,
|
||||
* so that a client runtime without this check does not apply it either.
|
||||
*/
|
||||
if ( 'OBJECT' === $p->get_tag() && ! self::is_bindable_object_attribute( $entry['suffix'] ) ) {
|
||||
$p->remove_attribute( $entry['attribute_name'] );
|
||||
_doing_it_wrong(
|
||||
__METHOD__,
|
||||
sprintf(
|
||||
/* translators: %s: The attribute name. */
|
||||
__( 'The "%s" attribute cannot be bound on an "object" element, so the binding was ignored.' ),
|
||||
esc_html( $entry['suffix'] )
|
||||
),
|
||||
'7.1.4'
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip if the suffix is an event handler.
|
||||
if ( str_starts_with( $entry['suffix'], 'on' ) ) {
|
||||
_doing_it_wrong(
|
||||
@ -1240,6 +1260,7 @@ final class WP_Interactivity_API {
|
||||
) {
|
||||
$result = $result ? 'true' : 'false';
|
||||
}
|
||||
|
||||
$p->set_attribute( $entry['suffix'], $result );
|
||||
} else {
|
||||
$p->remove_attribute( $entry['suffix'] );
|
||||
@ -1248,6 +1269,33 @@ final class WP_Interactivity_API {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a binding may set or remove an attribute of an `object` element.
|
||||
*
|
||||
* KSES only allows an `object` element in post content after checking the values of its
|
||||
* `data` and `type` attributes. Neither the server nor the client can repeat that check for
|
||||
* a bound value, so a binding on an `object` element may only change attributes that cannot
|
||||
* change what it loads: `aria-*` attributes, `data-*` attributes other than directives,
|
||||
* `width`, `height`, and the global attributes KSES allows on any element. Any `aria-*`
|
||||
* attribute is allowed, where KSES lists only some. A `data-wp-*` attribute is refused
|
||||
* because it is a directive, which could bind `data` or `type` once rendered. The client
|
||||
* runtime enforces the same set.
|
||||
*
|
||||
* @since 7.1.4
|
||||
*
|
||||
* @param string $attribute_name The name of the bound attribute.
|
||||
* @return bool Whether the attribute may be bound on an `object` element.
|
||||
*/
|
||||
private static function is_bindable_object_attribute( string $attribute_name ): bool {
|
||||
$attribute_name = strtolower( $attribute_name );
|
||||
|
||||
return (
|
||||
str_starts_with( $attribute_name, 'aria-' ) ||
|
||||
( str_starts_with( $attribute_name, 'data-' ) && ! str_starts_with( $attribute_name, 'data-wp-' ) ) ||
|
||||
in_array( $attribute_name, array( 'class', 'dir', 'height', 'hidden', 'id', 'lang', 'role', 'style', 'tabindex', 'title', 'width' ), true )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the `data-wp-class` directive.
|
||||
*
|
||||
|
||||
@ -415,7 +415,7 @@ wp.customize.widgetsPreview = wp.customize.WidgetCustomizerPreview = (function(
|
||||
* @return {wp.customize.selectiveRefresh.Partial} The widget instance partial.
|
||||
*/
|
||||
ensureWidgetPlacementContainers: function( widgetId ) {
|
||||
var sidebarPartial = this, widgetPartial, wasInserted = false, partialId = 'widget[' + widgetId + ']';
|
||||
var sidebarPartial = this, sidebarArgs, widgetPartial, wasInserted = false, partialId = 'widget[' + widgetId + ']';
|
||||
widgetPartial = api.selectiveRefresh.partial( partialId );
|
||||
if ( ! widgetPartial ) {
|
||||
widgetPartial = new self.WidgetPartial( partialId, {
|
||||
@ -423,10 +423,17 @@ wp.customize.widgetsPreview = wp.customize.WidgetCustomizerPreview = (function(
|
||||
} );
|
||||
}
|
||||
|
||||
// Build containers from the registered sidebar, since partial params can be declared in post content.
|
||||
sidebarArgs = _.findWhere( self.registeredSidebars, { id: sidebarPartial.sidebarId } );
|
||||
|
||||
// Make sure that there is a container element for the widget in the sidebar, if at least a placeholder.
|
||||
_.each( sidebarPartial.placements(), function( sidebarPlacement ) {
|
||||
var foundWidgetPlacement, widgetContainerElement;
|
||||
|
||||
if ( ! sidebarArgs ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foundWidgetPlacement = _.find( widgetPartial.placements(), function( widgetPlacement ) {
|
||||
return ( widgetPlacement.context.sidebar_instance_number === sidebarPlacement.context.instanceNumber );
|
||||
} );
|
||||
@ -435,8 +442,8 @@ wp.customize.widgetsPreview = wp.customize.WidgetCustomizerPreview = (function(
|
||||
}
|
||||
|
||||
widgetContainerElement = $(
|
||||
sidebarPartial.params.sidebarArgs.before_widget.replace( /%1\$s/g, widgetId ).replace( /%2\$s/g, 'widget' ) +
|
||||
sidebarPartial.params.sidebarArgs.after_widget
|
||||
sidebarArgs.before_widget.replace( /%1\$s/g, widgetId ).replace( /%2\$s/g, 'widget' ) +
|
||||
sidebarArgs.after_widget
|
||||
);
|
||||
|
||||
// Handle rare case where before_widget and after_widget are empty.
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -262,9 +262,9 @@ wp.customize.selectiveRefresh = ( function( $, api ) {
|
||||
if ( selector ) {
|
||||
selector += ', ';
|
||||
}
|
||||
selector += '[data-customize-partial-id="' + partial.id + '"]'; // @todo Consider injecting customize-partial-id-${id} classnames instead.
|
||||
selector += '[data-customize-partial-id="' + CSS.escape( partial.id ) + '"]';
|
||||
|
||||
return $( selector ).map( function() {
|
||||
return $( document ).find( selector ).map( function() {
|
||||
var container = $( this ), context;
|
||||
|
||||
context = container.data( 'customize-partial-placement-context' );
|
||||
|
||||
File diff suppressed because one or more lines are too long
2580
03_WordPress/wp-includes/js/dist/block-editor.js
vendored
2580
03_WordPress/wp-includes/js/dist/block-editor.js
vendored
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
167
03_WordPress/wp-includes/js/dist/block-library.js
vendored
167
03_WordPress/wp-includes/js/dist/block-library.js
vendored
@ -29319,6 +29319,13 @@ ${url}
|
||||
function defaultColumnsNumber(imageCount) {
|
||||
return imageCount ? Math.min(3, imageCount) : 3;
|
||||
}
|
||||
function isObject(value) {
|
||||
return !!value && typeof value === "object" && !Array.isArray(value);
|
||||
}
|
||||
function isGalleryFlexLayout(layout) {
|
||||
const layoutType = isObject(layout) ? layout.type : void 0;
|
||||
return typeof layoutType !== "string" || layoutType === "" || layoutType === "flex";
|
||||
}
|
||||
var pickRelevantMediaFiles = (image, sizeSlug = "large") => {
|
||||
const imageProps = Object.fromEntries(
|
||||
Object.entries(image ?? {}).filter(
|
||||
@ -30529,9 +30536,10 @@ ${url}
|
||||
)
|
||||
] });
|
||||
}
|
||||
function GalleryImagesPreview({ imageBlocks }) {
|
||||
function GalleryImagesPreview({ imageBlocks, layout }) {
|
||||
const { children, ref, className } = (0, import_block_editor97.__experimentalUseBlockPreview)({
|
||||
blocks: imageBlocks
|
||||
blocks: imageBlocks,
|
||||
layout
|
||||
});
|
||||
return /* @__PURE__ */ (0, import_jsx_runtime274.jsx)(
|
||||
"div",
|
||||
@ -30563,6 +30571,10 @@ ${url}
|
||||
} = dynamic;
|
||||
const blockEditingMode = (0, import_block_editor97.useBlockEditingMode)();
|
||||
const [isConfirmingDetach, setIsConfirmingDetach] = (0, import_element44.useState)(false);
|
||||
const previewLayout = (0, import_element44.useMemo)(
|
||||
() => isGalleryFlexLayout(attributes.layout) ? { ...attributes.layout, type: "flex" } : attributes.layout,
|
||||
[attributes.layout]
|
||||
);
|
||||
const emptyInstructions = isResolvingDynamic ? (0, import_i18n79.__)("Loading images\u2026") : sourceDescriptor?.emptyMessage ?? (0, import_i18n79.__)("Dynamic images will appear here.");
|
||||
return /* @__PURE__ */ (0, import_jsx_runtime274.jsxs)(import_jsx_runtime274.Fragment, { children: [
|
||||
blockEditingMode === "default" && /* @__PURE__ */ (0, import_jsx_runtime274.jsxs)(import_jsx_runtime274.Fragment, { children: [
|
||||
@ -30589,7 +30601,8 @@ ${url}
|
||||
dynamicImageBlocks.length ? /* @__PURE__ */ (0, import_jsx_runtime274.jsx)(import_block_editor97.BlockContextProvider, { value: galleryContext, children: /* @__PURE__ */ (0, import_jsx_runtime274.jsx)(
|
||||
GalleryImagesPreview,
|
||||
{
|
||||
imageBlocks: dynamicImageBlocks
|
||||
imageBlocks: dynamicImageBlocks,
|
||||
layout: previewLayout
|
||||
}
|
||||
) }) : /* @__PURE__ */ (0, import_jsx_runtime274.jsx)(
|
||||
import_components45.Placeholder,
|
||||
@ -36185,6 +36198,42 @@ ${text}
|
||||
}
|
||||
return syncedAttributes;
|
||||
}
|
||||
function getNewAttachmentSizeAttributes(sizeSlug, attachment) {
|
||||
const sizes = attachment.media_details?.sizes;
|
||||
if (!sizeSlug || sizeSlug === DEFAULT_MEDIA_SIZE_SLUG3 || !sizes) {
|
||||
return void 0;
|
||||
}
|
||||
const sizeUrl = sizes[sizeSlug]?.source_url;
|
||||
if (sizeUrl) {
|
||||
return { url: sizeUrl };
|
||||
}
|
||||
const fullUrl = attachment.source_url ?? sizes.full?.source_url;
|
||||
return fullUrl ? { url: fullUrl, sizeSlug: DEFAULT_MEDIA_SIZE_SLUG3 } : void 0;
|
||||
}
|
||||
function getNewAttachmentLinkAttributes(linkDestination, attachment) {
|
||||
if (linkDestination === LINK_DESTINATION_MEDIA2) {
|
||||
return attachment.source_url ? { href: attachment.source_url } : void 0;
|
||||
}
|
||||
if (linkDestination === LINK_DESTINATION_ATTACHMENT2) {
|
||||
return attachment.link ? { href: attachment.link } : void 0;
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
function getNewAttachmentImageBlockAttributes(blockAttributes8, attachment) {
|
||||
if (!attachment) {
|
||||
return void 0;
|
||||
}
|
||||
return {
|
||||
...getNewAttachmentSizeAttributes(
|
||||
blockAttributes8.sizeSlug,
|
||||
attachment
|
||||
),
|
||||
...getNewAttachmentLinkAttributes(
|
||||
blockAttributes8.linkDestination,
|
||||
attachment
|
||||
)
|
||||
};
|
||||
}
|
||||
var { openMediaEditorModalKey: openMediaEditorModalKey2 } = unlock(import_block_editor115.privateApis);
|
||||
function getAttachmentFallbackForEmptyBlockMetadata({ alt, caption }) {
|
||||
const attachment = {};
|
||||
@ -36210,7 +36259,7 @@ ${text}
|
||||
onClose,
|
||||
onUrlChange
|
||||
}) {
|
||||
const { id, url, alt, caption } = attributes;
|
||||
const { id, url, alt, caption, sizeSlug, linkDestination } = attributes;
|
||||
const registry = (0, import_data50.useRegistry)();
|
||||
const openMediaEditorModal = (0, import_data50.useSelect)(
|
||||
(select10) => select10(import_block_editor115.store).getSettings()[openMediaEditorModalKey2],
|
||||
@ -36220,7 +36269,9 @@ ${text}
|
||||
id,
|
||||
url,
|
||||
alt,
|
||||
caption: caption?.toString()
|
||||
caption: caption?.toString(),
|
||||
sizeSlug,
|
||||
linkDestination
|
||||
});
|
||||
const mediaEditorMetadataBaselineRef = (0, import_element56.useRef)();
|
||||
const mediaEditorMetadataSyncRequestRef = (0, import_element56.useRef)(0);
|
||||
@ -36229,9 +36280,11 @@ ${text}
|
||||
id,
|
||||
url,
|
||||
alt,
|
||||
caption: caption?.toString()
|
||||
caption: caption?.toString(),
|
||||
sizeSlug,
|
||||
linkDestination
|
||||
};
|
||||
}, [alt, caption, id, url]);
|
||||
}, [alt, caption, id, linkDestination, sizeSlug, url]);
|
||||
const getCachedAttachmentRecord = (0, import_element56.useCallback)(
|
||||
(attachmentId) => registry.select(import_core_data25.store).getEditedEntityRecord(
|
||||
"postType",
|
||||
@ -36277,7 +36330,8 @@ ${text}
|
||||
const syncRequest = ++mediaEditorMetadataSyncRequestRef.current;
|
||||
const nextAttributes = {};
|
||||
const currentBlockAttributes = blockAttributesRef.current;
|
||||
if (newId !== currentBlockAttributes.id) {
|
||||
const isNewAttachment = newId !== currentBlockAttributes.id;
|
||||
if (isNewAttachment) {
|
||||
nextAttributes.id = newId;
|
||||
nextAttributes.url = newUrl ?? currentBlockAttributes.url;
|
||||
if (nextAttributes.url !== currentBlockAttributes.url) {
|
||||
@ -36289,19 +36343,37 @@ ${text}
|
||||
url: nextAttributes.url
|
||||
};
|
||||
}
|
||||
if (originalAttachment) {
|
||||
if (originalAttachment || isNewAttachment) {
|
||||
const resolvedAttachment = await resolveFreshAttachmentRecord(newId);
|
||||
if (syncRequest !== mediaEditorMetadataSyncRequestRef.current) {
|
||||
return;
|
||||
}
|
||||
const attachmentRecord = resolvedAttachment ?? getCachedAttachmentRecord(newId);
|
||||
const latestBlockAttributes = blockAttributesRef.current;
|
||||
const resolvedMetadataAttributes = getSyncedImageBlockAttributes(
|
||||
latestBlockAttributes,
|
||||
originalAttachment,
|
||||
resolvedAttachment
|
||||
);
|
||||
if (Object.keys(resolvedMetadataAttributes).length) {
|
||||
Object.assign(nextAttributes, resolvedMetadataAttributes);
|
||||
if (originalAttachment) {
|
||||
const resolvedMetadataAttributes = getSyncedImageBlockAttributes(
|
||||
latestBlockAttributes,
|
||||
originalAttachment,
|
||||
attachmentRecord
|
||||
);
|
||||
if (Object.keys(resolvedMetadataAttributes).length) {
|
||||
Object.assign(
|
||||
nextAttributes,
|
||||
resolvedMetadataAttributes
|
||||
);
|
||||
}
|
||||
}
|
||||
if (isNewAttachment) {
|
||||
const derivedAttributes = getNewAttachmentImageBlockAttributes(
|
||||
latestBlockAttributes,
|
||||
attachmentRecord
|
||||
);
|
||||
if (derivedAttributes) {
|
||||
Object.assign(nextAttributes, derivedAttributes);
|
||||
if (derivedAttributes.url && derivedAttributes.url !== latestBlockAttributes.url) {
|
||||
onUrlChange?.(derivedAttributes.url);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Object.keys(nextAttributes).length) {
|
||||
@ -36312,7 +36384,12 @@ ${text}
|
||||
setAttributes(nextAttributes);
|
||||
}
|
||||
},
|
||||
[onUrlChange, resolveFreshAttachmentRecord, setAttributes]
|
||||
[
|
||||
getCachedAttachmentRecord,
|
||||
onUrlChange,
|
||||
resolveFreshAttachmentRecord,
|
||||
setAttributes
|
||||
]
|
||||
);
|
||||
const openImageMediaEditorModal = (0, import_element56.useCallback)(async () => {
|
||||
if (!id || !openMediaEditorModal) {
|
||||
@ -36563,7 +36640,8 @@ ${text}
|
||||
setOffsetTop(imageElement?.offsetTop ?? 0);
|
||||
}, [imageElement]);
|
||||
const setRefs = (0, import_compose24.useMergeRefs)([setImageElement, setResizeObserved]);
|
||||
const { allowResize = true } = context;
|
||||
const { allowResize = true, imageCrop = false } = context;
|
||||
const isCroppedGalleryImage = imageCrop && parentLayoutType === "flex";
|
||||
const { image, attachmentResolutionError } = (0, import_data51.useSelect)(
|
||||
(select10) => {
|
||||
const imageRecord = id && isSingleSelected ? select10(import_core_data26.store).getEntityRecord(
|
||||
@ -37287,10 +37365,12 @@ ${text}
|
||||
} else if (width !== void 0 && width !== null) {
|
||||
style2.width = typeof width === "number" ? `${width}px` : width;
|
||||
}
|
||||
if (height === "auto" || height === void 0 || height === null) {
|
||||
if (height === "auto") {
|
||||
style2.height = "auto";
|
||||
} else {
|
||||
} else if (height !== void 0 && height !== null) {
|
||||
style2.height = typeof height === "number" ? `${height}px` : height;
|
||||
} else if (!isCroppedGalleryImage) {
|
||||
style2.height = "auto";
|
||||
}
|
||||
return style2;
|
||||
})(),
|
||||
@ -40887,20 +40967,14 @@ ${text}
|
||||
var import_blocks45 = __toESM(require_blocks(), 1);
|
||||
function useOutdentListItem() {
|
||||
const registry = (0, import_data57.useRegistry)();
|
||||
const {
|
||||
moveBlocksToPosition,
|
||||
removeBlock,
|
||||
insertBlock,
|
||||
updateBlockListSettings
|
||||
} = (0, import_data57.useDispatch)(import_block_editor128.store);
|
||||
const { moveBlocksToPosition, removeBlock, removeBlocks, insertBlock } = (0, import_data57.useDispatch)(import_block_editor128.store);
|
||||
const {
|
||||
getBlockRootClientId,
|
||||
getBlockName,
|
||||
getBlockOrder,
|
||||
getBlockIndex,
|
||||
getSelectedBlockClientIds,
|
||||
getBlock,
|
||||
getBlockListSettings
|
||||
getBlock
|
||||
} = (0, import_data57.useSelect)(import_block_editor128.store);
|
||||
function getParentListItemId(id) {
|
||||
const listId = getBlockRootClientId(id);
|
||||
@ -40936,25 +41010,22 @@ ${text}
|
||||
);
|
||||
registry.batch(() => {
|
||||
if (followingListItems.length) {
|
||||
let nestedListId = getBlockOrder(firstClientId)[0];
|
||||
if (!nestedListId) {
|
||||
const nestedListId = getBlockOrder(firstClientId)[0];
|
||||
if (nestedListId) {
|
||||
moveBlocksToPosition(
|
||||
followingListItems,
|
||||
parentListId,
|
||||
nestedListId
|
||||
);
|
||||
} else {
|
||||
const nestedListBlock = (0, import_blocks45.cloneBlock)(
|
||||
getBlock(parentListId),
|
||||
{},
|
||||
[]
|
||||
followingListItems.map((id) => getBlock(id))
|
||||
);
|
||||
nestedListId = nestedListBlock.clientId;
|
||||
removeBlocks(followingListItems, false);
|
||||
insertBlock(nestedListBlock, 0, firstClientId, false);
|
||||
updateBlockListSettings(
|
||||
nestedListId,
|
||||
getBlockListSettings(parentListId)
|
||||
);
|
||||
}
|
||||
moveBlocksToPosition(
|
||||
followingListItems,
|
||||
parentListId,
|
||||
nestedListId
|
||||
);
|
||||
}
|
||||
moveBlocksToPosition(
|
||||
clientIds,
|
||||
@ -60530,7 +60601,9 @@ ${text}
|
||||
query: {
|
||||
perPage,
|
||||
offset = 0,
|
||||
postType,
|
||||
// Match `build_query_vars_from_query_block()`, which queries posts when
|
||||
// `query` has no post type.
|
||||
postType = "post",
|
||||
order,
|
||||
orderBy,
|
||||
author,
|
||||
@ -64047,7 +64120,9 @@ ${text}
|
||||
orderBy,
|
||||
author: authorIds,
|
||||
pages,
|
||||
postType,
|
||||
// Match `build_query_vars_from_query_block()`, which queries posts when
|
||||
// `query` has no post type.
|
||||
postType = "post",
|
||||
perPage,
|
||||
offset,
|
||||
sticky,
|
||||
@ -64135,7 +64210,7 @@ ${text}
|
||||
);
|
||||
const showExcludeCurrentControl = shouldExcludeCurrentPost && isControlAllowed(allowedControls, "excludeCurrent");
|
||||
const postTypeSingularName = (0, import_data125.useSelect)(
|
||||
(select10) => select10(import_core_data77.store).getPostType(postType)?.labels.singular_name,
|
||||
(select10) => select10(import_core_data77.store).getPostType(postType)?.labels?.singular_name,
|
||||
[postType]
|
||||
);
|
||||
const showFiltersPanel = showTaxControl || showAuthorControl || showSearchControl || showParentControl || showFormatControl || showExcludeCurrentControl;
|
||||
@ -68050,7 +68125,7 @@ ${text}
|
||||
}
|
||||
|
||||
// packages/block-library/build-module/block/deprecated.mjs
|
||||
var isObject = (obj) => typeof obj === "object" && !Array.isArray(obj) && obj !== null;
|
||||
var isObject2 = (obj) => typeof obj === "object" && !Array.isArray(obj) && obj !== null;
|
||||
var v219 = {
|
||||
attributes: {
|
||||
ref: {
|
||||
@ -68073,7 +68148,7 @@ ${text}
|
||||
// the likelihood, it doesn't solve it completely.
|
||||
isEligible({ content }) {
|
||||
return !!content && Object.keys(content).every(
|
||||
(contentKey) => content[contentKey].values && isObject(content[contentKey].values)
|
||||
(contentKey) => content[contentKey].values && isObject2(content[contentKey].values)
|
||||
);
|
||||
},
|
||||
/*
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -29,7 +29,7 @@ var wp;
|
||||
var offset;
|
||||
var output;
|
||||
var stack;
|
||||
var tokenizer = /<!--\s+(\/)?wp:([a-z][a-z0-9_-]*\/)?([a-z][a-z0-9_-]*)\s+({(?:(?=([^}]+|}+(?=})|(?!}\s+\/?-->)[^])*)\5|[^]*?)}\s+)?(\/)?-->/g;
|
||||
var tokenizer = /<!--[ \t\f\r\n]+(\/)?wp:([a-z][a-z0-9_-]*\/)?([a-z][a-z0-9_-]*)[ \t\f\r\n]+({(?:(?=([^}]+|}+(?=})|(?!}[ \t\f\r\n]+\/?-->)[^])*)\5|[^]*?)}[ \t\f\r\n]+)?(\/)?-->/g;
|
||||
function Block(blockName, attrs, innerBlocks, innerHTML, innerContent) {
|
||||
return {
|
||||
blockName,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*! This file is auto-generated */
|
||||
(function() {
|
||||
"use strict";var wp;(wp||={}).blockSerializationDefaultParser=(()=>{var m=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var B=Object.prototype.hasOwnProperty;var F=(t,e)=>{for(var s in e)m(t,s,{get:e[s],enumerable:!0})},H=(t,e,s,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of T(e))!B.call(t,n)&&n!==s&&m(t,n,{get:()=>e[n],enumerable:!(o=S(e,n))||o.enumerable});return t};var w=t=>H(m({},"__esModule",{value:!0}),t);var L={};F(L,{parse:()=>y});var a,l,i,f,C=/<!--\s+(\/)?wp:([a-z][a-z0-9_-]*\/)?([a-z][a-z0-9_-]*)\s+({(?:(?=([^}]+|}+(?=})|(?!}\s+\/?-->)[^])*)\5|[^]*?)}\s+)?(\/)?-->/g;function k(t,e,s,o,n){return{blockName:t,attrs:e,innerBlocks:s,innerHTML:o,innerContent:n}}function g(t){return k(null,{},[],t,[t])}function N(t,e,s,o,n){return{block:t,tokenStart:e,tokenLength:s,prevOffset:o||e+s,leadingHtmlStart:n}}var y=t=>{a=t,l=0,i=[],f=[],C.lastIndex=0;do;while(A());return i};function A(){let t=f.length,e=J(),[s,o,n,r,c]=e,p=r>l?l:null;switch(s){case"no-more-tokens":if(t===0)return d(),!1;if(t===1)return v(),!1;for(;0<f.length;)v();return!1;case"void-block":return t===0?(p!==null&&i.push(g(a.substr(p,r-p))),i.push(k(o,n,[],"",[])),l=r+c,!0):(z(k(o,n,[],"",[]),r,c),l=r+c,!0);case"block-opener":return f.push(N(k(o,n,[],"",[]),r,c,r+c,p)),l=r+c,!0;case"block-closer":if(t===0)return d(),!1;if(t===1)return v(r),l=r+c,!0;let u=f.pop(),h=a.substr(u.prevOffset,r-u.prevOffset);return u.block.innerHTML+=h,u.block.innerContent.push(h),u.prevOffset=r+c,z(u.block,u.tokenStart,u.tokenLength,r+c),l=r+c,!0;default:return d(),!1}}function I(t){try{return JSON.parse(t)}catch{return null}}function J(){let t=C.exec(a);if(t===null)return["no-more-tokens","",null,0,0];let e=t.index,[s,o,n,r,c,,p]=t,u=s.length,h=!!o,O=!!p,b=(n||"core/")+r,M=!!c,x=M?I(c):{};return O?["void-block",b,x,e,u]:h?["block-closer",b,null,e,u]:["block-opener",b,x,e,u]}function d(t){let e=t||a.length-l;e!==0&&i.push(g(a.substr(l,e)))}function z(t,e,s,o){let n=f[f.length-1];n.block.innerBlocks.push(t);let r=a.substr(n.prevOffset,e-n.prevOffset);r&&(n.block.innerHTML+=r,n.block.innerContent.push(r)),n.block.innerContent.push(null),n.prevOffset=o||e+s}function v(t){let{block:e,leadingHtmlStart:s,prevOffset:o,tokenStart:n}=f.pop(),r=t?a.substr(o,t-o):a.substr(o);r&&(e.innerHTML+=r,e.innerContent.push(r)),s!==null&&i.push(g(a.substr(s,n-s))),i.push(e)}return w(L);})();
|
||||
"use strict";var wp;(wp||={}).blockSerializationDefaultParser=(()=>{var m=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var B=Object.prototype.hasOwnProperty;var F=(t,n)=>{for(var s in n)m(t,s,{get:n[s],enumerable:!0})},H=(t,n,s,o)=>{if(n&&typeof n=="object"||typeof n=="function")for(let e of T(n))!B.call(t,e)&&e!==s&&m(t,e,{get:()=>n[e],enumerable:!(o=S(n,e))||o.enumerable});return t};var w=t=>H(m({},"__esModule",{value:!0}),t);var L={};F(L,{parse:()=>y});var a,l,i,f,C=/<!--[ \t\f\r\n]+(\/)?wp:([a-z][a-z0-9_-]*\/)?([a-z][a-z0-9_-]*)[ \t\f\r\n]+({(?:(?=([^}]+|}+(?=})|(?!}[ \t\f\r\n]+\/?-->)[^])*)\5|[^]*?)}[ \t\f\r\n]+)?(\/)?-->/g;function k(t,n,s,o,e){return{blockName:t,attrs:n,innerBlocks:s,innerHTML:o,innerContent:e}}function g(t){return k(null,{},[],t,[t])}function N(t,n,s,o,e){return{block:t,tokenStart:n,tokenLength:s,prevOffset:o||n+s,leadingHtmlStart:e}}var y=t=>{a=t,l=0,i=[],f=[],C.lastIndex=0;do;while(A());return i};function A(){let t=f.length,n=J(),[s,o,e,r,c]=n,p=r>l?l:null;switch(s){case"no-more-tokens":if(t===0)return d(),!1;if(t===1)return v(),!1;for(;0<f.length;)v();return!1;case"void-block":return t===0?(p!==null&&i.push(g(a.substr(p,r-p))),i.push(k(o,e,[],"",[])),l=r+c,!0):(z(k(o,e,[],"",[]),r,c),l=r+c,!0);case"block-opener":return f.push(N(k(o,e,[],"",[]),r,c,r+c,p)),l=r+c,!0;case"block-closer":if(t===0)return d(),!1;if(t===1)return v(r),l=r+c,!0;let u=f.pop(),h=a.substr(u.prevOffset,r-u.prevOffset);return u.block.innerHTML+=h,u.block.innerContent.push(h),u.prevOffset=r+c,z(u.block,u.tokenStart,u.tokenLength,r+c),l=r+c,!0;default:return d(),!1}}function I(t){try{return JSON.parse(t)}catch{return null}}function J(){let t=C.exec(a);if(t===null)return["no-more-tokens","",null,0,0];let n=t.index,[s,o,e,r,c,,p]=t,u=s.length,h=!!o,O=!!p,b=(e||"core/")+r,M=!!c,x=M?I(c):{};return O?["void-block",b,x,n,u]:h?["block-closer",b,null,n,u]:["block-opener",b,x,n,u]}function d(t){let n=t||a.length-l;n!==0&&i.push(g(a.substr(l,n)))}function z(t,n,s,o){let e=f[f.length-1];e.block.innerBlocks.push(t);let r=a.substr(e.prevOffset,n-e.prevOffset);r&&(e.block.innerHTML+=r,e.block.innerContent.push(r)),e.block.innerContent.push(null),e.prevOffset=o||n+s}function v(t){let{block:n,leadingHtmlStart:s,prevOffset:o,tokenStart:e}=f.pop(),r=t?a.substr(o,t-o):a.substr(o);r&&(n.innerHTML+=r,n.innerContent.push(r)),s!==null&&i.push(g(a.substr(s,e-s))),i.push(n)}return w(L);})();
|
||||
(window.wp ||= {}).blockSerializationDefaultParser = wp.blockSerializationDefaultParser;
|
||||
})();
|
||||
|
||||
@ -140,7 +140,7 @@ var wp;
|
||||
return "core/" + type;
|
||||
}, peg$c21 = /^[a-z]/, peg$c22 = peg$classExpectation([["a", "z"]], false, false), peg$c23 = /^[a-z0-9_\-]/, peg$c24 = peg$classExpectation([["a", "z"], ["0", "9"], "_", "-"], false, false), peg$c25 = peg$otherExpectation("JSON-encoded attributes embedded in a block's opening comment"), peg$c26 = "{", peg$c27 = peg$literalExpectation("{", false), peg$c28 = "}", peg$c29 = peg$literalExpectation("}", false), peg$c30 = "", peg$c31 = function(attrs) {
|
||||
return maybeJSON(attrs);
|
||||
}, peg$c32 = /^[ \t\r\n]/, peg$c33 = peg$classExpectation([" ", " ", "\r", "\n"], false, false), peg$currPos = 0, peg$savedPos = 0, peg$posDetailsCache = [{ line: 1, column: 1 }], peg$maxFailPos = 0, peg$maxFailExpected = [], peg$silentFails = 0, peg$result;
|
||||
}, peg$c32 = /^[ \t\f\r\n]/, peg$c33 = peg$classExpectation([" ", " ", "\f", "\r", "\n"], false, false), peg$currPos = 0, peg$savedPos = 0, peg$posDetailsCache = [{ line: 1, column: 1 }], peg$maxFailPos = 0, peg$maxFailExpected = [], peg$silentFails = 0, peg$result;
|
||||
if ("startRule" in options) {
|
||||
if (!(options.startRule in peg$startRuleFunctions)) {
|
||||
throw new Error(`Can't start parsing from rule "` + options.startRule + '".');
|
||||
|
||||
File diff suppressed because one or more lines are too long
27
03_WordPress/wp-includes/js/dist/edit-post.js
vendored
27
03_WordPress/wp-includes/js/dist/edit-post.js
vendored
@ -11932,7 +11932,6 @@ var wp;
|
||||
core.__experimentalGetCurrentThemeBaseGlobalStyles(),
|
||||
core.__experimentalGetCurrentThemeGlobalStylesVariations(),
|
||||
core.getEntityRecord("root", "__unstableBase"),
|
||||
core.getEntityRecord("root", "site"),
|
||||
core.canUser("read", { kind: "root", name: "site" }),
|
||||
core.canUser("create", { kind: "postType", name: "attachment" }),
|
||||
core.canUser("create", { kind: "postType", name: "page" }),
|
||||
@ -11970,11 +11969,13 @@ var wp;
|
||||
] : []
|
||||
]);
|
||||
const tasks = [];
|
||||
if (coreSelect.canUser("read", { kind: "root", name: "site" })) {
|
||||
tasks.push(core.getEntityRecord("root", "site"));
|
||||
}
|
||||
const globalStylesId = coreSelect.__experimentalGetCurrentGlobalStylesId();
|
||||
if (globalStylesId) {
|
||||
tasks.push(
|
||||
core.getEntityRecord("root", "globalStyles", globalStylesId),
|
||||
core.canUser("read", {
|
||||
core.canUser("update", {
|
||||
kind: "root",
|
||||
name: "globalStyles",
|
||||
id: globalStylesId
|
||||
@ -12006,6 +12007,26 @@ var wp;
|
||||
if (tasks.length) {
|
||||
await Promise.all(tasks);
|
||||
}
|
||||
if (globalStylesId) {
|
||||
if (coreSelect.canUser("update", {
|
||||
kind: "root",
|
||||
name: "globalStyles",
|
||||
id: globalStylesId
|
||||
})) {
|
||||
await core.getEntityRecord(
|
||||
"root",
|
||||
"globalStyles",
|
||||
globalStylesId
|
||||
);
|
||||
} else {
|
||||
await core.getEntityRecord(
|
||||
"root",
|
||||
"globalStyles",
|
||||
globalStylesId,
|
||||
{ context: "view" }
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
10
03_WordPress/wp-includes/js/dist/edit-site.js
vendored
10
03_WordPress/wp-includes/js/dist/edit-site.js
vendored
@ -54928,9 +54928,13 @@ If there's a particular need for this, please submit a feature request at https:
|
||||
const fieldsKey = fieldList ? [...fieldList].sort().join(",") : void 0;
|
||||
return (0, import_data65.useSelect)(
|
||||
(select4) => {
|
||||
return unlock7(select4(import_core_data41.store)).getViewConfig(kind, name2, {
|
||||
fields: fieldsKey
|
||||
});
|
||||
return unlock7(select4(import_core_data41.store)).getViewConfig(
|
||||
kind,
|
||||
name2,
|
||||
fieldsKey ? {
|
||||
fields: fieldsKey
|
||||
} : void 0
|
||||
);
|
||||
},
|
||||
[kind, name2, fieldsKey]
|
||||
);
|
||||
|
||||
File diff suppressed because one or more lines are too long
6975
03_WordPress/wp-includes/js/dist/editor.js
vendored
6975
03_WordPress/wp-includes/js/dist/editor.js
vendored
File diff suppressed because it is too large
Load Diff
72
03_WordPress/wp-includes/js/dist/editor.min.js
vendored
72
03_WordPress/wp-includes/js/dist/editor.min.js
vendored
File diff suppressed because one or more lines are too long
14
03_WordPress/wp-includes/js/dist/media-utils.js
vendored
14
03_WordPress/wp-includes/js/dist/media-utils.js
vendored
@ -1334,7 +1334,7 @@ var wp;
|
||||
return data !== null && typeof data === "object" && Object.getPrototypeOf(data) === Object.prototype;
|
||||
}
|
||||
function flattenFormData(formData, key, data) {
|
||||
if (isPlainObject(data)) {
|
||||
if (Array.isArray(data) || isPlainObject(data)) {
|
||||
for (const [name, value] of Object.entries(data)) {
|
||||
flattenFormData(formData, `${key}[${name}]`, value);
|
||||
}
|
||||
@ -1361,11 +1361,7 @@ var wp;
|
||||
const data = new FormData();
|
||||
data.append("file", file, file.name || file.type.replace("/", "."));
|
||||
for (const [key, value] of Object.entries(additionalData)) {
|
||||
flattenFormData(
|
||||
data,
|
||||
key,
|
||||
value
|
||||
);
|
||||
flattenFormData(data, key, value);
|
||||
}
|
||||
return transformAttachment(
|
||||
await (0, import_api_fetch.default)({
|
||||
@ -1587,11 +1583,7 @@ var wp;
|
||||
const data = new FormData();
|
||||
data.append("file", file, file.name || file.type.replace("/", "."));
|
||||
for (const [key, value] of Object.entries(additionalData)) {
|
||||
flattenFormData(
|
||||
data,
|
||||
key,
|
||||
value
|
||||
);
|
||||
flattenFormData(data, key, value);
|
||||
}
|
||||
return (0, import_api_fetch2.default)({
|
||||
path: `/wp/v2/media/${attachmentId}/sideload`,
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -29,6 +29,10 @@ function getImageSrc({ uploadedSrc }) {
|
||||
function getImageSrcset({ lightboxSrcset }) {
|
||||
return lightboxSrcset || "";
|
||||
}
|
||||
function getImageMetadata(imageId) {
|
||||
const metadata = state.metadata[imageId];
|
||||
return Object.hasOwn(state.metadata, imageId) ? metadata : void 0;
|
||||
}
|
||||
var { state, actions, callbacks } = store(
|
||||
"core/image",
|
||||
{
|
||||
@ -55,7 +59,7 @@ var { state, actions, callbacks } = store(
|
||||
);
|
||||
},
|
||||
get selectedImage() {
|
||||
return state.metadata[state.selectedImageId];
|
||||
return getImageMetadata(state.selectedImageId);
|
||||
},
|
||||
get hasNavigationIcon() {
|
||||
const { navigationButtonType } = state.selectedImage;
|
||||
@ -67,7 +71,7 @@ var { state, actions, callbacks } = store(
|
||||
},
|
||||
get thisImage() {
|
||||
const { imageId } = getContext();
|
||||
return state.metadata[imageId];
|
||||
return getImageMetadata(imageId);
|
||||
},
|
||||
get hasNavigation() {
|
||||
return state.galleryImages.length > 1;
|
||||
@ -129,7 +133,7 @@ var { state, actions, callbacks } = store(
|
||||
actions: {
|
||||
showLightbox() {
|
||||
const { imageId } = getContext();
|
||||
if (!state.metadata[imageId].imageRef?.complete) {
|
||||
if (!getImageMetadata(imageId)?.imageRef?.complete) {
|
||||
return;
|
||||
}
|
||||
state.scrollTopReset = document.documentElement.scrollTop;
|
||||
@ -244,7 +248,10 @@ var { state, actions, callbacks } = store(
|
||||
if (state.preloadedImageIds.has(imageId)) {
|
||||
return;
|
||||
}
|
||||
const imageMetadata = state.metadata[imageId];
|
||||
const imageMetadata = getImageMetadata(imageId);
|
||||
if (!imageMetadata) {
|
||||
return;
|
||||
}
|
||||
const imageLink = document.createElement("link");
|
||||
imageLink.rel = "preload";
|
||||
imageLink.as = "image";
|
||||
@ -393,8 +400,12 @@ var { state, actions, callbacks } = store(
|
||||
return;
|
||||
}
|
||||
const { imageId } = getContext();
|
||||
state.metadata[imageId].imageRef = ref;
|
||||
state.metadata[imageId].currentSrc = ref.currentSrc;
|
||||
const imageMetadata = getImageMetadata(imageId);
|
||||
if (!imageMetadata) {
|
||||
return;
|
||||
}
|
||||
imageMetadata.imageRef = ref;
|
||||
imageMetadata.currentSrc = ref.currentSrc;
|
||||
const {
|
||||
naturalWidth,
|
||||
naturalHeight,
|
||||
@ -420,7 +431,7 @@ var { state, actions, callbacks } = store(
|
||||
const buttonOffsetRight = figureWidth - offsetWidth;
|
||||
let buttonTop = buttonOffsetTop + 16;
|
||||
let buttonRight = buttonOffsetRight + 16;
|
||||
if (state.metadata[imageId].scaleAttr === "contain") {
|
||||
if (imageMetadata.scaleAttr === "contain") {
|
||||
const naturalRatio = naturalWidth / naturalHeight;
|
||||
const offsetRatio = offsetWidth / offsetHeight;
|
||||
if (naturalRatio >= offsetRatio) {
|
||||
@ -433,8 +444,8 @@ var { state, actions, callbacks } = store(
|
||||
buttonRight = (offsetWidth - referenceWidth) / 2 + buttonOffsetRight + 16;
|
||||
}
|
||||
}
|
||||
state.metadata[imageId].buttonTop = buttonTop;
|
||||
state.metadata[imageId].buttonRight = buttonRight;
|
||||
imageMetadata.buttonTop = buttonTop;
|
||||
imageMetadata.buttonRight = buttonRight;
|
||||
},
|
||||
setOverlayFocus() {
|
||||
if (state.overlayEnabled) {
|
||||
@ -454,7 +465,10 @@ var { state, actions, callbacks } = store(
|
||||
initTriggerButton() {
|
||||
const { imageId } = getContext();
|
||||
const { ref } = getElement();
|
||||
state.metadata[imageId].buttonRef = ref;
|
||||
const imageMetadata = getImageMetadata(imageId);
|
||||
if (imageMetadata) {
|
||||
imageMetadata.buttonRef = ref;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -1 +1 @@
|
||||
<?php return array('dependencies' => array(), 'module_dependencies' => array(array('id' => '@wordpress/interactivity', 'import' => 'static')), 'version' => '25ee935fd6c67371d0f3');
|
||||
<?php return array('dependencies' => array(), 'module_dependencies' => array(array('id' => '@wordpress/interactivity', 'import' => 'static')), 'version' => '25f29e3c6cc00370914b');
|
||||
File diff suppressed because one or more lines are too long
@ -714,11 +714,32 @@ var cloneRouterRegionContent = (vdom) => {
|
||||
var regionsToAttachByParent = /* @__PURE__ */ new WeakMap();
|
||||
var rootFragmentsByParent = /* @__PURE__ */ new WeakMap();
|
||||
var initialRegionsToAttach = /* @__PURE__ */ new Set();
|
||||
var isValidPageResponse = (response) => {
|
||||
if (response.status !== 200) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
if (new URL(response.url).origin !== window.location.origin) {
|
||||
return false;
|
||||
}
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
const contentType = response.headers.get("content-type") ?? "";
|
||||
if (contentType.includes(",") || contentType.split(";")[0].trim().toLowerCase() !== "text/html") {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
var fetchPage = async (url, { html }) => {
|
||||
try {
|
||||
if (!html) {
|
||||
const res = await window.fetch(url);
|
||||
if (res.status !== 200) {
|
||||
const requestUrl = new URL(url, window.location.href);
|
||||
if (requestUrl.origin !== window.location.origin) {
|
||||
return false;
|
||||
}
|
||||
const res = await window.fetch(requestUrl.href);
|
||||
if (!isValidPageResponse(res)) {
|
||||
return false;
|
||||
}
|
||||
html = await res.text();
|
||||
@ -731,8 +752,8 @@ var fetchPage = async (url, { html }) => {
|
||||
};
|
||||
var preparePage = async (url, dom, { vdom } = {}) => {
|
||||
dom.querySelectorAll("noscript").forEach((el) => el.remove());
|
||||
const regions = {};
|
||||
const regionsToAttach = {};
|
||||
const regions = /* @__PURE__ */ Object.create(null);
|
||||
const regionsToAttach = /* @__PURE__ */ Object.create(null);
|
||||
dom.querySelectorAll(regionsSelector).forEach((region) => {
|
||||
const { id, attachTo } = parseRegionAttribute(region);
|
||||
if (region.parentElement.closest(`[${regionAttr}]`)) {
|
||||
@ -762,7 +783,10 @@ var preparePage = async (url, dom, { vdom } = {}) => {
|
||||
};
|
||||
var renderPage = (page) => {
|
||||
applyStyles(page.styles);
|
||||
const regionsToAttach = { ...page.regionsToAttach };
|
||||
const regionsToAttach = Object.assign(
|
||||
/* @__PURE__ */ Object.create(null),
|
||||
page.regionsToAttach
|
||||
);
|
||||
batch(() => {
|
||||
populateServerData(page.initialData);
|
||||
navigationSignal.value += 1;
|
||||
@ -895,6 +919,7 @@ var { state, actions } = store("core/router", {
|
||||
* @return Promise that resolves once the navigation is completed or aborted.
|
||||
*/
|
||||
*navigate(href, options = {}) {
|
||||
options = Object.assign(/* @__PURE__ */ Object.create(null), options);
|
||||
const { clientNavigationDisabled } = getConfig();
|
||||
if (clientNavigationDisabled) {
|
||||
yield forcePageReload(href);
|
||||
@ -967,6 +992,7 @@ var { state, actions } = store("core/router", {
|
||||
* @return Promise that resolves once the page has been fetched.
|
||||
*/
|
||||
*prefetch(url, options = {}) {
|
||||
options = Object.assign(/* @__PURE__ */ Object.create(null), options);
|
||||
const { clientNavigationDisabled } = getConfig();
|
||||
if (clientNavigationDisabled) {
|
||||
return;
|
||||
@ -986,12 +1012,12 @@ state.url = state.url || window.location.href;
|
||||
function a11ySpeak(messageKey) {
|
||||
if (!hasLoadedNavigationTextsData) {
|
||||
hasLoadedNavigationTextsData = true;
|
||||
const content = document.getElementById(
|
||||
"wp-script-module-data-@wordpress/interactivity-router"
|
||||
)?.textContent;
|
||||
if (content) {
|
||||
const script = document.querySelector(
|
||||
'script[id="wp-script-module-data-@wordpress/interactivity-router"]'
|
||||
);
|
||||
if (script instanceof HTMLScriptElement) {
|
||||
try {
|
||||
const parsed = JSON.parse(content);
|
||||
const parsed = JSON.parse(script.text);
|
||||
if (typeof parsed?.i18n?.loading === "string") {
|
||||
navigationTexts.loading = parsed.i18n.loading;
|
||||
}
|
||||
|
||||
@ -1 +1 @@
|
||||
<?php return array('dependencies' => array(), 'module_dependencies' => array(array('id' => '@wordpress/a11y', 'import' => 'dynamic'), array('id' => '@wordpress/interactivity', 'import' => 'static')), 'version' => 'a6e90b8896f83fb1b5dd');
|
||||
<?php return array('dependencies' => array(), 'module_dependencies' => array(array('id' => '@wordpress/a11y', 'import' => 'dynamic'), array('id' => '@wordpress/interactivity', 'import' => 'static')), 'version' => 'dea5032c2153d213c1ee');
|
||||
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user