Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cherry-picked commits for WordPress 6.4 Beta 2 #54914

Merged
merged 37 commits into from
Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
cd9fc99
Fix the install of system fonts from a font collection (#54713)
matiasbenedetto Sep 27, 2023
3ada010
Fix set upload dir test (#54762)
matiasbenedetto Sep 27, 2023
121a1be
Site Editor: Prevent unintended actions on the classic theme (#54422)
t-hamano Sep 27, 2023
592aed1
Patterns: Fix back navigation after pattern creation (#54852)
aaronrobertshaw Sep 27, 2023
d4583eb
Patterns: Fix category control width in site editor (#54853)
aaronrobertshaw Sep 27, 2023
0de93a9
Patterns: Allow non-user patterns under Standard filter (#54756)
aaronrobertshaw Sep 27, 2023
8351350
Performance Tests: Separate page setup from test (#53808)
WunderBart Sep 21, 2023
bcd11e4
Performance Tests: Support legacy selector for expanded elements (#54…
WunderBart Sep 21, 2023
ff67ea7
Paragraph: Make 'aria-label' consistent with other blocks (#54687)
Mamaduka Sep 21, 2023
9dea2a3
Move lightbox render function to filter (#54670)
artemiomorales Sep 25, 2023
c20f4a1
syntax refactor repace strpos with str_contains (#54832)
matiasbenedetto Sep 27, 2023
87c2691
Font Library: avoid deprected error in test (#54802)
matiasbenedetto Sep 27, 2023
1271ebb
Fix the ShortcutProvider usage (#54851)
youknowriad Sep 27, 2023
1ad31d0
Image: Ensure `false` values are preserved in memory when defined in …
artemiomorales Sep 27, 2023
1b53e1b
Use "Not synced" in place of "Standard" nomenclature for patterns (#5…
richtabor Sep 27, 2023
949b28c
Format Library: Try to fix highlight popover jumping (#54736)
t-hamano Sep 27, 2023
23ad86f
Move mime-type collection generation to a function that can be tested…
pbking Sep 27, 2023
78d3141
Ensure lightbox toggle is shown if block-level setting exists (#54878)
artemiomorales Sep 27, 2023
3375dbc
Block Editor: Update strings in blocks 'RenameModal' component (#54887)
Mamaduka Sep 27, 2023
9949351
Footnotes: Add aria-label to return links (#54843)
alexstine Sep 28, 2023
83cb042
Font Library: Changed the OTF mime type expected value to be what PHP…
pbking Sep 28, 2023
0d63803
Image: Fix layout shift when lightbox is opened and closed (#53026)
cbravobernal Sep 28, 2023
75cb40f
Font Library: move font uploads to a new tab (#54655)
madhusudhand Sep 28, 2023
c35b6d0
Block custom CSS: Fix incorrect CSS when multiple root selectors (#53…
t-hamano Sep 29, 2023
7b19836
Add new e2e test for creating a pattern (#54855)
kevin940726 Sep 27, 2023
458a73d
Use list role instead of listbox for patterns (#54884)
kevin940726 Sep 28, 2023
ccf7656
Popover: Fix the styles for components that use emotion within popove…
youknowriad Sep 29, 2023
507d0e9
Footnotes: use core’s meta revisioning if available (#52988)
adamsilverstein Sep 29, 2023
7525413
Remove base url from link control search results (#54553)
getdave Sep 21, 2023
614f768
[Site Editor]: Update copy of using the default template in a page (…
ntsekouras Sep 22, 2023
b5596e4
Remove overflow: hidden from the entity title h1 in the site editor s…
ramonjd Sep 25, 2023
34fa64a
Site Editor: Avoid same key warnings in template parts area listings …
Mamaduka Sep 28, 2023
9836669
Fix ToolSelector popover variant (#54840)
richtabor Sep 29, 2023
fd167db
Font Library: refactor endpoint permissions (#54829)
matiasbenedetto Sep 29, 2023
c4ffd4a
Don’t use TypeScript files in scripts package (#54856)
swissspidy Sep 27, 2023
3e6d894
Fix Search Block not updating in Nav block (#54823)
getdave Sep 27, 2023
59fff9f
Remove word-wrap property (#54866)
getdave Sep 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion lib/block-supports/behaviors.php
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,9 @@ function gutenberg_render_behaviors_support_lightbox( $block_content, $block ) {
data-wp-bind--aria-modal="context.core.image.lightboxEnabled"
data-wp-effect="effects.core.image.initLightbox"
data-wp-on--keydown="actions.core.image.handleKeydown"
data-wp-on--mousewheel="actions.core.image.hideLightbox"
data-wp-on--touchstart="actions.core.image.handleTouchStart"
data-wp-on--touchmove="actions.core.image.handleTouchMove"
data-wp-on--touchend="actions.core.image.handleTouchEnd"
data-wp-on--click="actions.core.image.hideLightbox"
>
<button type="button" aria-label="$close_button_label" style="fill: $close_button_color" class="close-button" data-wp-on--click="actions.core.image.hideLightbox">
Expand Down
20 changes: 17 additions & 3 deletions lib/class-wp-theme-json-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -1145,9 +1145,23 @@ protected function process_blocks_custom_css( $css, $selector ) {
// Split CSS nested rules.
$parts = explode( '&', $css );
foreach ( $parts as $part ) {
$processed_css .= ( ! str_contains( $part, '{' ) )
? trim( $selector ) . '{' . trim( $part ) . '}' // If the part doesn't contain braces, it applies to the root level.
: trim( $selector . $part ); // Prepend the selector, which effectively replaces the "&" character.
$is_root_css = ( ! str_contains( $part, '{' ) );
if ( $is_root_css ) {
// If the part doesn't contain braces, it applies to the root level.
$processed_css .= trim( $selector ) . '{' . trim( $part ) . '}';
} else {
// If the part contains braces, it's a nested CSS rule.
$part = explode( '{', str_replace( '}', '', $part ) );
if ( count( $part ) !== 2 ) {
continue;
}
$nested_selector = $part[0];
$css_value = $part[1];
$part_selector = str_starts_with( $nested_selector, ' ' )
? static::scope_selector( $selector, $nested_selector )
: static::append_to_selector( $selector, $nested_selector );
$processed_css .= $part_selector . '{' . trim( $css_value ) . '}';
}
}
return $processed_css;
}
Expand Down
250 changes: 250 additions & 0 deletions lib/compat/plugin/footnotes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
<?php
/**
* Compatibility shim for the footnotes bloct to enable test passing while awaiting the tested code to be merged to core.
*
* See https://github.com/WordPress/gutenberg/pull/52988.
*
* Once merged, this shim can be removed.
*
* @package gutenberg
*/

/**
* Remove footnote revision hooks when plugin is running on a version of core that already supports meta revisions.
*/
if ( function_exists( 'wp_post_revision_meta_keys' ) ) {
if ( has_action( 'rest_after_insert_post', 'wp_add_footnotes_revisions_to_post_meta' ) ) {
remove_action( 'rest_after_insert_post', 'wp_add_footnotes_revisions_to_post_meta' );
}
if ( has_action( 'rest_after_insert_page', 'wp_add_footnotes_revisions_to_post_meta' ) ) {
remove_action( 'rest_after_insert_page', 'wp_add_footnotes_revisions_to_post_meta' );
}
if ( has_action( 'wp_after_insert_post', 'wp_save_footnotes_meta' ) ) {
remove_action( 'wp_after_insert_post', 'wp_save_footnotes_meta' );
}
if ( has_action( '_wp_put_post_revision', 'wp_keep_footnotes_revision_id' ) ) {
remove_action( '_wp_put_post_revision', 'wp_keep_footnotes_revision_id' );
}
if ( has_action( 'wp_restore_post_revision', 'wp_restore_footnotes_from_revision' ) ) {
remove_action( 'wp_restore_post_revision', 'wp_restore_footnotes_from_revision' );
}
if ( has_action( 'wp_creating_autosave', '_wp_rest_api_autosave_meta' ) ) {
remove_action( 'wp_creating_autosave', '_wp_rest_api_autosave_meta' );
}
if ( has_action( '_wp_put_post_revision', '_wp_rest_api_autosave_meta' ) ) {
remove_action( '_wp_put_post_revision', '_wp_rest_api_autosave_meta' );
}
if ( has_filter( 'rest_pre_insert_post', '_wp_rest_api_force_autosave_difference' ) ) {
remove_filter( 'rest_pre_insert_post', '_wp_rest_api_force_autosave_difference' );
}
} else {
/**
* For versions of core that don't support meta revisions, use hooks to add.
*/
if ( ! function_exists( 'wp_save_footnotes_meta' ) ) {
/**
* Saves the footnotes meta value to the revision.
*
* @since 6.3.0
* @since 6.4.0 Core added post meta revisions, so this is no longer needed.
*
* @param int $revision_id The revision ID.
*/
function wp_save_footnotes_meta( $revision_id ) {
$post_id = wp_is_post_revision( $revision_id );

if ( $post_id ) {
$footnotes = get_post_meta( $post_id, 'footnotes', true );

if ( $footnotes ) {
// Can't use update_post_meta() because it doesn't allow revisions.
update_metadata( 'post', $revision_id, 'footnotes', wp_slash( $footnotes ) );
}
}
}
if ( ! function_exists( 'wp_post_revision_meta_keys' ) ) {
add_action( 'wp_after_insert_post', 'wp_save_footnotes_meta' );
}
}

if ( ! function_exists( 'wp_keep_footnotes_revision_id' ) ) {
/**
* Keeps track of the revision ID for "rest_after_insert_{$post_type}".
*
* @since 6.3.0
* @since 6.4.0 Core added post meta revisions, so this is no longer needed.
*
* @global int $wp_temporary_footnote_revision_id The footnote revision ID.
*
* @param int $revision_id The revision ID.
*/
function wp_keep_footnotes_revision_id( $revision_id ) {
global $wp_temporary_footnote_revision_id;
$wp_temporary_footnote_revision_id = $revision_id;
}
if ( ! function_exists( 'wp_post_revision_meta_keys' ) ) {
add_action( '_wp_put_post_revision', 'wp_keep_footnotes_revision_id' );
}
}

if ( ! function_exists( 'wp_add_footnotes_revisions_to_post_meta' ) ) {

/**
* This is a specific fix for the REST API. The REST API doesn't update
* the post and post meta in one go (through `meta_input`). While it
* does fix the `wp_after_insert_post` hook to be called correctly after
* updating meta, it does NOT fix hooks such as post_updated and
* save_post, which are normally also fired after post meta is updated
* in `wp_insert_post()`. Unfortunately, `wp_save_post_revision` is
* added to the `post_updated` action, which means the meta is not
* available at the time, so we have to add it afterwards through the
* `"rest_after_insert_{$post_type}"` action.
*
* @since 6.3.0
* @since 6.4.0 Core added post meta revisions, so this is no longer needed.
*
* @global int $wp_temporary_footnote_revision_id The footnote revision ID.
*
* @param WP_Post $post The post object.
*/
function wp_add_footnotes_revisions_to_post_meta( $post ) {
global $wp_temporary_footnote_revision_id;

if ( $wp_temporary_footnote_revision_id ) {
$revision = get_post( $wp_temporary_footnote_revision_id );

if ( ! $revision ) {
return;
}

$post_id = $revision->post_parent;

// Just making sure we're updating the right revision.
if ( $post->ID === $post_id ) {
$footnotes = get_post_meta( $post_id, 'footnotes', true );

if ( $footnotes ) {
// Can't use update_post_meta() because it doesn't allow revisions.
update_metadata( 'post', $wp_temporary_footnote_revision_id, 'footnotes', wp_slash( $footnotes ) );
}
}
}
}

if ( ! function_exists( 'wp_post_revision_meta_keys' ) ) {
add_action( 'rest_after_insert_post', 'wp_add_footnotes_revisions_to_post_meta' );
add_action( 'rest_after_insert_page', 'wp_add_footnotes_revisions_to_post_meta' );
}
}

if ( ! function_exists( 'wp_restore_footnotes_from_revision' ) ) {

/**
* Restores the footnotes meta value from the revision.
*
* @since 6.3.0
* @since 6.4.0 Core added post meta revisions, so this is no longer needed.
*
* @param int $post_id The post ID.
* @param int $revision_id The revision ID.
*/
function wp_restore_footnotes_from_revision( $post_id, $revision_id ) {
$footnotes = get_post_meta( $revision_id, 'footnotes', true );

if ( $footnotes ) {
update_post_meta( $post_id, 'footnotes', wp_slash( $footnotes ) );
} else {
delete_post_meta( $post_id, 'footnotes' );
}
}
if ( ! function_exists( 'wp_post_revision_meta_keys' ) ) {
add_action( 'wp_restore_post_revision', 'wp_restore_footnotes_from_revision', 10, 2 );
}
}

if ( ! function_exists( '_wp_rest_api_autosave_meta' ) ) {

/**
* The REST API autosave endpoint doesn't save meta, so we can use the
* `wp_creating_autosave` when it updates an exiting autosave, and
* `_wp_put_post_revision` when it creates a new autosave.
*
* @since 6.3.0
* @since 6.4.0 Core added post meta revisions, so this is no longer needed.
*
* @param int|array $autosave The autosave ID or array.
*/
function _wp_rest_api_autosave_meta( $autosave ) {
// Ensure it's a REST API request.
if ( ! defined( 'REST_REQUEST' ) || ! REST_REQUEST ) {
return;
}

$body = rest_get_server()->get_raw_data();
$body = json_decode( $body, true );

if ( ! isset( $body['meta']['footnotes'] ) ) {
return;
}

// `wp_creating_autosave` passes the array,
// `_wp_put_post_revision` passes the ID.
$id = is_int( $autosave ) ? $autosave : $autosave['ID'];

if ( ! $id ) {
return;
}

// Can't use update_post_meta() because it doesn't allow revisions.
update_metadata( 'post', $id, 'footnotes', wp_slash( $body['meta']['footnotes'] ) );
}

if ( ! function_exists( 'wp_post_revision_meta_keys' ) ) {
// See https://github.com/WordPress/wordpress-develop/blob/2103cb9966e57d452c94218bbc3171579b536a40/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php#L391C1-L391C1.
add_action( 'wp_creating_autosave', '_wp_rest_api_autosave_meta' );
// See https://github.com/WordPress/wordpress-develop/blob/2103cb9966e57d452c94218bbc3171579b536a40/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php#L398.
// Then https://github.com/WordPress/wordpress-develop/blob/2103cb9966e57d452c94218bbc3171579b536a40/src/wp-includes/revision.php#L367.
add_action( '_wp_put_post_revision', '_wp_rest_api_autosave_meta' );
}
}

if ( ! function_exists( '_wp_rest_api_force_autosave_difference' ) ) {

/**
* This is a workaround for the autosave endpoint returning early if the
* revision field are equal. The problem is that "footnotes" is not real
* revision post field, so there's nothing to compare against.
*
* This trick sets the "footnotes" field (value doesn't matter), which will
* cause the autosave endpoint to always update the latest revision. That should
* be fine, it should be ok to update the revision even if nothing changed. Of
* course, this is temporary fix.
*
* @since 6.3.0
* @since 6.4.0 Core added post meta revisions, so this is no longer needed.
*
* @param WP_Post $prepared_post The prepared post object.
* @param WP_REST_Request $request The request object.
*
* See https://github.com/WordPress/wordpress-develop/blob/2103cb9966e57d452c94218bbc3171579b536a40/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php#L365-L384.
* See https://github.com/WordPress/wordpress-develop/blob/2103cb9966e57d452c94218bbc3171579b536a40/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php#L219.
*/
function _wp_rest_api_force_autosave_difference( $prepared_post, $request ) {
// We only want to be altering POST requests.
if ( $request->get_method() !== 'POST' ) {
return $prepared_post;
}

// Only alter requests for the '/autosaves' route.
if ( substr( $request->get_route(), -strlen( '/autosaves' ) ) !== '/autosaves' ) {
return $prepared_post;
}

$prepared_post->footnotes = '[]';
return $prepared_post;
}
if ( ! function_exists( 'wp_post_revision_meta_keys' ) ) {
add_filter( 'rest_pre_insert_post', '_wp_rest_api_force_autosave_difference', 10, 2 );
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public function get_config() {
*/
public function get_data() {
// If the src is a URL, fetch the data from the URL.
if ( false !== strpos( $this->config['src'], 'http' ) && false !== strpos( $this->config['src'], '://' ) ) {
if ( str_contains( $this->config['src'], 'http' ) && str_contains( $this->config['src'], '://' ) ) {
if ( ! wp_http_validate_url( $this->config['src'] ) ) {
return new WP_Error( 'font_collection_read_error', __( 'Invalid URL for Font Collection data.', 'gutenberg' ) );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,9 @@ public static function merge_fonts_data( $font1, $font2 ) {
* @return bool True if the file has a font MIME type, false otherwise.
*/
public static function has_font_mime_type( $filepath ) {
$filetype = wp_check_filetype( $filepath, WP_Font_Library::ALLOWED_FONT_MIME_TYPES );
$allowed_mime_types = WP_Font_Library::get_expected_font_mime_types_per_php_version();
$filetype = wp_check_filetype( $filepath, $allowed_mime_types );

return in_array( $filetype['type'], WP_Font_Library::ALLOWED_FONT_MIME_TYPES, true );
return in_array( $filetype['type'], $allowed_mime_types, true );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ private function get_upload_overrides( $filename ) {
// Seems mime type for files that are not images cannot be tested.
// See wp_check_filetype_and_ext().
'test_type' => true,
'mimes' => WP_Font_Library::ALLOWED_FONT_MIME_TYPES,
'mimes' => WP_Font_Library::get_expected_font_mime_types_per_php_version(),
'unique_filename_callback' => static function () use ( $filename ) {
// Keep the original filename.
return $filename;
Expand Down
30 changes: 22 additions & 8 deletions lib/experimental/fonts/font-library/class-wp-font-library.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,28 @@
*/
class WP_Font_Library {

const PHP_7_TTF_MIME_TYPE = PHP_VERSION_ID >= 70300 ? 'application/font-sfnt' : 'application/x-font-ttf';
/**
* Provide the expected mime-type value for font files per-PHP release. Due to differences in the values returned these values differ between PHP versions.
*
* This is necessary until a collection of valid mime-types per-file extension can be provided to 'upload_mimes' filter.
*
* @since 6.4.0
*
* @param array $php_version_id The version of PHP to provide mime types for. The default is the current PHP version.
*
* @return Array A collection of mime types keyed by file extension.
*/
public static function get_expected_font_mime_types_per_php_version( $php_version_id = PHP_VERSION_ID ) {

const ALLOWED_FONT_MIME_TYPES = array(
'otf' => 'font/otf',
'ttf' => PHP_VERSION_ID >= 70400 ? 'font/sfnt' : self::PHP_7_TTF_MIME_TYPE,
'woff' => PHP_VERSION_ID >= 80100 ? 'font/woff' : 'application/font-woff',
'woff2' => PHP_VERSION_ID >= 80100 ? 'font/woff2' : 'application/font-woff2',
);
$php_7_ttf_mime_type = $php_version_id >= 70300 ? 'application/font-sfnt' : 'application/x-font-ttf';

return array(
'otf' => 'application/vnd.ms-opentype',
'ttf' => $php_version_id >= 70400 ? 'font/sfnt' : $php_7_ttf_mime_type,
'woff' => $php_version_id >= 80100 ? 'font/woff' : 'application/font-woff',
'woff2' => $php_version_id >= 80100 ? 'font/woff2' : 'application/font-woff2',
);
}

/**
* Font collections.
Expand Down Expand Up @@ -130,6 +144,6 @@ public static function set_upload_dir( $defaults ) {
* @return array Modified upload directory.
*/
public static function set_allowed_mime_types( $mime_types ) {
return array_merge( $mime_types, self::ALLOWED_FONT_MIME_TYPES );
return array_merge( $mime_types, self::get_expected_font_mime_types_per_php_version() );
}
}
Loading
Loading