Editor: Merge Editor bug fixes ahead of 6.5 RC4.

This merges several high priority bug fixes for the editor ahead of WordPress 6.5:
- https://github.com/WordPress/gutenberg/pull/60180
- https://github.com/WordPress/gutenberg/pull/60093
- https://github.com/WordPress/gutenberg/pull/60071
- https://github.com/WordPress/gutenberg/pull/60130
- https://github.com/WordPress/gutenberg/pull/59959
- https://github.com/WordPress/gutenberg/pull/60167

Reviewed by jorbin, swissspidy.
Merges [57888] to the 6.5 branch.

Props youknowriad, annezazu, mcsf, jsnajdr, mmaattiiaass, get_dave, scruffian, mikachan, grantmkin, andraganescu, scruffian, antosguillamot, fabiankaegy, huzaifaalmesbah, krupajnanda, colorful-tones, liviopv, mamaduka, kim88, poena, peterwilsoncc, wildworks, swissspidy, desrosj, jorbin.
Fixes #60315.
Built from https://develop.svn.wordpress.org/branches/6.5@57891


git-svn-id: http://core.svn.wordpress.org/branches/6.5@57392 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Pascal Birchler 2024-03-28 08:31:19 +00:00
parent c94919702a
commit 11ea343fca
10 changed files with 86 additions and 21 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1472,6 +1472,14 @@ function block_core_navigation_update_ignore_hooked_blocks_meta( $post ) {
return $post;
}
/**
* Skip meta generation when consumers intentionally update specific Navigation fields
* and omit the content update.
*/
if ( ! isset( $post->post_content ) ) {
return $post;
}
/*
* We run the Block Hooks mechanism to inject the `metadata.ignoredHookedBlocks` attribute into
* all anchor blocks. For the root level, we create a mock Navigation and extract them from there.

View File

@ -74,10 +74,20 @@ const {
} = (0,interactivity_namespaceObject.getContext)();
if (type === 'submenu' &&
// Only open on hover if the overlay is closed.
Object.values(overlayOpenedBy || {}).filter(Boolean).length === 0) actions.openMenu('hover');
Object.values(overlayOpenedBy || {}).filter(Boolean).length === 0) {
actions.openMenu('hover');
}
},
closeMenuOnHover() {
actions.closeMenu('hover');
const {
type,
overlayOpenedBy
} = (0,interactivity_namespaceObject.getContext)();
if (type === 'submenu' &&
// Only close on hover if the overlay is closed.
Object.values(overlayOpenedBy || {}).filter(Boolean).length === 0) {
actions.closeMenu('hover');
}
},
openMenuOnClick() {
const ctx = (0,interactivity_namespaceObject.getContext)();

View File

@ -1 +1 @@
import*as e from"@wordpress/interactivity";var t={d:(e,n)=>{for(var o in n)t.o(n,o)&&!t.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:n[o]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const n=(e=>{var n={};return t.d(n,e),n})({getContext:()=>e.getContext,getElement:()=>e.getElement,store:()=>e.store}),o=["a[href]",'input:not([disabled]):not([type="hidden"]):not([aria-hidden])',"select:not([disabled]):not([aria-hidden])","textarea:not([disabled]):not([aria-hidden])","button:not([disabled]):not([aria-hidden])","[contenteditable]",'[tabindex]:not([tabindex^="-"])'];document.addEventListener("click",(()=>{}));const{state:l,actions:c}=(0,n.store)("core/navigation",{state:{get roleAttribute(){return"overlay"===(0,n.getContext)().type&&l.isMenuOpen?"dialog":null},get ariaModal(){return"overlay"===(0,n.getContext)().type&&l.isMenuOpen?"true":null},get ariaLabel(){const e=(0,n.getContext)();return"overlay"===e.type&&l.isMenuOpen?e.ariaLabel:null},get isMenuOpen(){return Object.values(l.menuOpenedBy).filter(Boolean).length>0},get menuOpenedBy(){const e=(0,n.getContext)();return"overlay"===e.type?e.overlayOpenedBy:e.submenuOpenedBy}},actions:{openMenuOnHover(){const{type:e,overlayOpenedBy:t}=(0,n.getContext)();"submenu"===e&&0===Object.values(t||{}).filter(Boolean).length&&c.openMenu("hover")},closeMenuOnHover(){c.closeMenu("hover")},openMenuOnClick(){const e=(0,n.getContext)(),{ref:t}=(0,n.getElement)();e.previousFocus=t,c.openMenu("click")},closeMenuOnClick(){c.closeMenu("click"),c.closeMenu("focus")},openMenuOnFocus(){c.openMenu("focus")},toggleMenuOnClick(){const e=(0,n.getContext)(),{ref:t}=(0,n.getElement)();window.document.activeElement!==t&&t.focus();const{menuOpenedBy:o}=l;o.click||o.focus?(c.closeMenu("click"),c.closeMenu("focus")):(e.previousFocus=t,c.openMenu("click"))},handleMenuKeydown(e){const{type:t,firstFocusableElement:o,lastFocusableElement:u}=(0,n.getContext)();if(l.menuOpenedBy.click){if("Escape"===e?.key)return c.closeMenu("click"),void c.closeMenu("focus");"overlay"===t&&"Tab"===e.key&&(e.shiftKey&&window.document.activeElement===o?(e.preventDefault(),u.focus()):e.shiftKey||window.document.activeElement!==u||(e.preventDefault(),o.focus()))}},handleMenuFocusout(e){const{modal:t}=(0,n.getContext)();(null===e.relatedTarget||!t?.contains(e.relatedTarget)&&e.target!==window.document.activeElement)&&(c.closeMenu("click"),c.closeMenu("focus"))},openMenu(e="click"){const{type:t}=(0,n.getContext)();l.menuOpenedBy[e]=!0,"overlay"===t&&document.documentElement.classList.add("has-modal-open")},closeMenu(e="click"){const t=(0,n.getContext)();l.menuOpenedBy[e]=!1,l.isMenuOpen||(t.modal?.contains(window.document.activeElement)&&t.previousFocus?.focus(),t.modal=null,t.previousFocus=null,"overlay"===t.type&&document.documentElement.classList.remove("has-modal-open"))}},callbacks:{initMenu(){const e=(0,n.getContext)(),{ref:t}=(0,n.getElement)();if(l.isMenuOpen){const n=t.querySelectorAll(o);e.modal=t,e.firstFocusableElement=n[0],e.lastFocusableElement=n[n.length-1]}},focusFirstElement(){const{ref:e}=(0,n.getElement)();if(l.isMenuOpen){const t=e.querySelectorAll(o);t?.[0]?.focus()}}}},{lock:!0});
import*as e from"@wordpress/interactivity";var t={d:(e,n)=>{for(var o in n)t.o(n,o)&&!t.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:n[o]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const n=(e=>{var n={};return t.d(n,e),n})({getContext:()=>e.getContext,getElement:()=>e.getElement,store:()=>e.store}),o=["a[href]",'input:not([disabled]):not([type="hidden"]):not([aria-hidden])',"select:not([disabled]):not([aria-hidden])","textarea:not([disabled]):not([aria-hidden])","button:not([disabled]):not([aria-hidden])","[contenteditable]",'[tabindex]:not([tabindex^="-"])'];document.addEventListener("click",(()=>{}));const{state:l,actions:c}=(0,n.store)("core/navigation",{state:{get roleAttribute(){return"overlay"===(0,n.getContext)().type&&l.isMenuOpen?"dialog":null},get ariaModal(){return"overlay"===(0,n.getContext)().type&&l.isMenuOpen?"true":null},get ariaLabel(){const e=(0,n.getContext)();return"overlay"===e.type&&l.isMenuOpen?e.ariaLabel:null},get isMenuOpen(){return Object.values(l.menuOpenedBy).filter(Boolean).length>0},get menuOpenedBy(){const e=(0,n.getContext)();return"overlay"===e.type?e.overlayOpenedBy:e.submenuOpenedBy}},actions:{openMenuOnHover(){const{type:e,overlayOpenedBy:t}=(0,n.getContext)();"submenu"===e&&0===Object.values(t||{}).filter(Boolean).length&&c.openMenu("hover")},closeMenuOnHover(){const{type:e,overlayOpenedBy:t}=(0,n.getContext)();"submenu"===e&&0===Object.values(t||{}).filter(Boolean).length&&c.closeMenu("hover")},openMenuOnClick(){const e=(0,n.getContext)(),{ref:t}=(0,n.getElement)();e.previousFocus=t,c.openMenu("click")},closeMenuOnClick(){c.closeMenu("click"),c.closeMenu("focus")},openMenuOnFocus(){c.openMenu("focus")},toggleMenuOnClick(){const e=(0,n.getContext)(),{ref:t}=(0,n.getElement)();window.document.activeElement!==t&&t.focus();const{menuOpenedBy:o}=l;o.click||o.focus?(c.closeMenu("click"),c.closeMenu("focus")):(e.previousFocus=t,c.openMenu("click"))},handleMenuKeydown(e){const{type:t,firstFocusableElement:o,lastFocusableElement:u}=(0,n.getContext)();if(l.menuOpenedBy.click){if("Escape"===e?.key)return c.closeMenu("click"),void c.closeMenu("focus");"overlay"===t&&"Tab"===e.key&&(e.shiftKey&&window.document.activeElement===o?(e.preventDefault(),u.focus()):e.shiftKey||window.document.activeElement!==u||(e.preventDefault(),o.focus()))}},handleMenuFocusout(e){const{modal:t}=(0,n.getContext)();(null===e.relatedTarget||!t?.contains(e.relatedTarget)&&e.target!==window.document.activeElement)&&(c.closeMenu("click"),c.closeMenu("focus"))},openMenu(e="click"){const{type:t}=(0,n.getContext)();l.menuOpenedBy[e]=!0,"overlay"===t&&document.documentElement.classList.add("has-modal-open")},closeMenu(e="click"){const t=(0,n.getContext)();l.menuOpenedBy[e]=!1,l.isMenuOpen||(t.modal?.contains(window.document.activeElement)&&t.previousFocus?.focus(),t.modal=null,t.previousFocus=null,"overlay"===t.type&&document.documentElement.classList.remove("has-modal-open"))}},callbacks:{initMenu(){const e=(0,n.getContext)(),{ref:t}=(0,n.getElement)();if(l.isMenuOpen){const n=t.querySelectorAll(o);e.modal=t,e.firstFocusableElement=n[0],e.lastFocusableElement=n[n.length-1]}},focusFirstElement(){const{ref:e}=(0,n.getElement)();if(l.isMenuOpen){const t=e.querySelectorAll(o);t?.[0]?.focus()}}}},{lock:!0});

View File

@ -49267,7 +49267,7 @@ const BlockSwitcher = ({
invalidBlocks: true
};
}
const rootClientId = getBlockRootClientId(clientIds);
const rootClientId = getBlockRootClientId(Array.isArray(clientIds) ? clientIds[0] : clientIds);
const [{
name: firstBlockName
}] = _blocks;

File diff suppressed because one or more lines are too long

View File

@ -26792,8 +26792,26 @@ function makeFontFacesFormData(font) {
}
}
async function batchInstallFontFaces(fontFamilyId, fontFacesData) {
const promises = fontFacesData.map(faceData => fetchInstallFontFace(fontFamilyId, faceData));
const responses = await Promise.allSettled(promises);
const responses = [];
/*
* Uses the same response format as Promise.allSettled, but executes requests in sequence to work
* around a race condition that can cause an error when the fonts directory doesn't exist yet.
*/
for (const faceData of fontFacesData) {
try {
const response = await fetchInstallFontFace(fontFamilyId, faceData);
responses.push({
status: 'fulfilled',
value: response
});
} catch (error) {
responses.push({
status: 'rejected',
reason: error
});
}
}
const results = {
errors: [],
successes: []
@ -27021,12 +27039,23 @@ function FontLibraryProvider({
// Library Fonts
const [modalTabOpen, setModalTabOpen] = (0,external_wp_element_namespaceObject.useState)(false);
const [libraryFontSelected, setLibraryFontSelected] = (0,external_wp_element_namespaceObject.useState)(null);
const baseThemeFonts = baseFontFamilies?.theme ? baseFontFamilies.theme.map(f => setUIValuesNeeded(f, {
source: 'theme'
})).sort((a, b) => a.name.localeCompare(b.name)) : [];
// Themes Fonts are the fonts defined in the global styles (database persisted theme.json data).
const themeFonts = fontFamilies?.theme ? fontFamilies.theme.map(f => setUIValuesNeeded(f, {
source: 'theme'
})).sort((a, b) => a.name.localeCompare(b.name)) : [];
const themeFontsSlugs = new Set(themeFonts.map(f => f.slug));
/*
* Base Theme Fonts are the fonts defined in the theme.json *file*.
*
* Uses the fonts from global styles + the ones from the theme.json file that hasn't repeated slugs.
* Avoids incosistencies with the fonts listed in the font library modal as base (unactivated).
* These inconsistencies can happen when the active theme fonts in global styles aren't defined in theme.json file as when a theme style variation is applied.
*/
const baseThemeFonts = baseFontFamilies?.theme ? themeFonts.concat(baseFontFamilies.theme.filter(f => !themeFontsSlugs.has(f.slug)).map(f => setUIValuesNeeded(f, {
source: 'theme'
})).sort((a, b) => a.name.localeCompare(b.name))) : [];
const customFonts = fontFamilies?.custom ? fontFamilies.custom.map(f => setUIValuesNeeded(f, {
source: 'custom'
})).sort((a, b) => a.name.localeCompare(b.name)) : [];
@ -27046,7 +27075,7 @@ function FontLibraryProvider({
setLibraryFontSelected(null);
return;
}
const fonts = font.source === 'theme' ? baseThemeFonts : baseCustomFonts;
const fonts = font.source === 'theme' ? themeFonts : baseCustomFonts;
// Tries to find the font in the installed fonts
const fontSelected = fonts.find(f => f.slug === font.slug);
@ -27127,8 +27156,10 @@ function FontLibraryProvider({
// Use the sucessfully installed font faces
// As well as any font faces that were already installed (those will be activated)
if (sucessfullyInstalledFontFaces?.length > 0 || alreadyInstalledFontFaces?.length > 0) {
fontFamilyToInstall.fontFace = [...sucessfullyInstalledFontFaces, ...alreadyInstalledFontFaces];
fontFamiliesToActivate.push(fontFamilyToInstall);
// Use font data from REST API not from client to ensure
// correct font information is used.
installedFontFamily.fontFace = [...sucessfullyInstalledFontFaces];
fontFamiliesToActivate.push(installedFontFamily);
}
// If it's a system font but was installed successfully, activate it.
@ -27200,14 +27231,30 @@ function FontLibraryProvider({
}
};
const activateCustomFontFamilies = fontsToAdd => {
// Merge the existing custom fonts with the new fonts.
// Removes the id from the families and faces to avoid saving that to global styles post content.
const fontsToActivate = fontsToAdd.map(({
id: _familyDbId,
fontFace,
...font
}) => ({
...font,
...(fontFace && fontFace.length > 0 ? {
fontFace: fontFace.map(({
id: _faceDbId,
...face
}) => face)
} : {})
}));
// Activate the fonts by set the new custom fonts array.
setFontFamilies({
...fontFamilies,
custom: mergeFontFamilies(fontFamilies?.custom, fontsToAdd)
// Merge the existing custom fonts with the new fonts.
custom: mergeFontFamilies(fontFamilies?.custom, fontsToActivate)
});
// Add custom fonts to the browser.
fontsToAdd.forEach(font => {
fontsToActivate.forEach(font => {
if (font.fontFace) {
font.fontFace.forEach(face => {
// Load font faces just in the iframe because they already are in the document.

File diff suppressed because one or more lines are too long

View File

@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
$wp_version = '6.5-RC3-57890';
$wp_version = '6.5-RC3-57891';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.