@wordpress/block-editor 15.13.2-next.v.202602241322.0 → 15.13.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/components/block-bindings/attribute-control.cjs +5 -2
- package/build/components/block-bindings/attribute-control.cjs.map +2 -2
- package/build/components/block-inspector/edit-contents.cjs +5 -4
- package/build/components/block-inspector/edit-contents.cjs.map +2 -2
- package/build/components/block-list/block-html.cjs +6 -2
- package/build/components/block-list/block-html.cjs.map +2 -2
- package/build/components/block-list/block.cjs +9 -1
- package/build/components/block-list/block.cjs.map +2 -2
- package/build/components/block-list/use-block-props/index.cjs +10 -1
- package/build/components/block-list/use-block-props/index.cjs.map +2 -2
- package/build/components/block-settings-menu-controls/index.cjs +1 -0
- package/build/components/block-settings-menu-controls/index.cjs.map +2 -2
- package/build/components/block-styles/index.cjs +7 -1
- package/build/components/block-styles/index.cjs.map +3 -3
- package/build/components/block-switcher/block-transformations-menu.cjs +2 -0
- package/build/components/block-switcher/block-transformations-menu.cjs.map +2 -2
- package/build/components/block-switcher/block-variation-transformations.cjs +2 -0
- package/build/components/block-switcher/block-variation-transformations.cjs.map +2 -2
- package/build/components/block-toolbar/block-toolbar-icon.cjs +1 -1
- package/build/components/block-toolbar/block-toolbar-icon.cjs.map +2 -2
- package/build/components/block-toolbar/index.cjs +8 -4
- package/build/components/block-toolbar/index.cjs.map +2 -2
- package/build/components/block-tools/index.cjs +4 -3
- package/build/components/block-tools/index.cjs.map +2 -2
- package/build/components/block-variation-transforms/index.cjs +11 -5
- package/build/components/block-variation-transforms/index.cjs.map +2 -2
- package/build/components/block-visibility/modal.cjs +2 -2
- package/build/components/block-visibility/modal.cjs.map +1 -1
- package/build/components/block-visibility/use-block-visibility.cjs +4 -3
- package/build/components/block-visibility/use-block-visibility.cjs.map +2 -2
- package/build/components/block-visibility/viewport-visibility-info.cjs +6 -1
- package/build/components/block-visibility/viewport-visibility-info.cjs.map +2 -2
- package/build/components/dimensions-tool/scale-tool.cjs +2 -2
- package/build/components/dimensions-tool/scale-tool.cjs.map +2 -2
- package/build/components/iframe/index.cjs +1 -3
- package/build/components/iframe/index.cjs.map +2 -2
- package/build/components/iframe/use-scale-canvas.cjs +0 -1
- package/build/components/iframe/use-scale-canvas.cjs.map +2 -2
- package/build/components/inspector-controls-tabs/use-inspector-controls-tabs.cjs +8 -4
- package/build/components/inspector-controls-tabs/use-inspector-controls-tabs.cjs.map +2 -2
- package/build/components/link-picker/link-preview.cjs +2 -1
- package/build/components/link-picker/link-preview.cjs.map +3 -3
- package/build/components/provider/index.cjs +23 -7
- package/build/components/provider/index.cjs.map +2 -2
- package/build/components/provider/use-media-upload-settings.cjs +1 -0
- package/build/components/provider/use-media-upload-settings.cjs.map +2 -2
- package/build/components/writing-flow/use-arrow-nav.cjs +1 -1
- package/build/components/writing-flow/use-arrow-nav.cjs.map +2 -2
- package/build/hooks/auto-inspector-controls.cjs +26 -2
- package/build/hooks/auto-inspector-controls.cjs.map +3 -3
- package/build/hooks/cross-origin-isolation.cjs +9 -75
- package/build/hooks/cross-origin-isolation.cjs.map +2 -2
- package/build/hooks/custom-css.cjs +26 -0
- package/build/hooks/custom-css.cjs.map +3 -3
- package/build/private-apis.cjs +1 -0
- package/build/private-apis.cjs.map +2 -2
- package/build/store/actions.cjs +0 -8
- package/build/store/actions.cjs.map +2 -2
- package/build/store/private-keys.cjs +3 -0
- package/build/store/private-keys.cjs.map +2 -2
- package/build/store/private-selectors.cjs +4 -3
- package/build/store/private-selectors.cjs.map +2 -2
- package/build/store/reducer.cjs +78 -74
- package/build/store/reducer.cjs.map +2 -2
- package/build/store/selectors.cjs +16 -14
- package/build/store/selectors.cjs.map +2 -2
- package/build-module/components/block-bindings/attribute-control.mjs +5 -2
- package/build-module/components/block-bindings/attribute-control.mjs.map +2 -2
- package/build-module/components/block-inspector/edit-contents.mjs +5 -4
- package/build-module/components/block-inspector/edit-contents.mjs.map +2 -2
- package/build-module/components/block-list/block-html.mjs +7 -3
- package/build-module/components/block-list/block-html.mjs.map +2 -2
- package/build-module/components/block-list/block.mjs +10 -2
- package/build-module/components/block-list/block.mjs.map +2 -2
- package/build-module/components/block-list/use-block-props/index.mjs +11 -2
- package/build-module/components/block-list/use-block-props/index.mjs.map +2 -2
- package/build-module/components/block-settings-menu-controls/index.mjs +1 -0
- package/build-module/components/block-settings-menu-controls/index.mjs.map +2 -2
- package/build-module/components/block-styles/index.mjs +7 -1
- package/build-module/components/block-styles/index.mjs.map +2 -2
- package/build-module/components/block-switcher/block-transformations-menu.mjs +2 -0
- package/build-module/components/block-switcher/block-transformations-menu.mjs.map +2 -2
- package/build-module/components/block-switcher/block-variation-transformations.mjs +2 -0
- package/build-module/components/block-switcher/block-variation-transformations.mjs.map +2 -2
- package/build-module/components/block-toolbar/block-toolbar-icon.mjs +1 -1
- package/build-module/components/block-toolbar/block-toolbar-icon.mjs.map +2 -2
- package/build-module/components/block-toolbar/index.mjs +8 -4
- package/build-module/components/block-toolbar/index.mjs.map +2 -2
- package/build-module/components/block-tools/index.mjs +4 -3
- package/build-module/components/block-tools/index.mjs.map +2 -2
- package/build-module/components/block-variation-transforms/index.mjs +11 -5
- package/build-module/components/block-variation-transforms/index.mjs.map +2 -2
- package/build-module/components/block-visibility/modal.mjs +2 -2
- package/build-module/components/block-visibility/modal.mjs.map +1 -1
- package/build-module/components/block-visibility/use-block-visibility.mjs +4 -3
- package/build-module/components/block-visibility/use-block-visibility.mjs.map +2 -2
- package/build-module/components/block-visibility/viewport-visibility-info.mjs +6 -1
- package/build-module/components/block-visibility/viewport-visibility-info.mjs.map +2 -2
- package/build-module/components/dimensions-tool/scale-tool.mjs +2 -2
- package/build-module/components/dimensions-tool/scale-tool.mjs.map +2 -2
- package/build-module/components/iframe/index.mjs +2 -9
- package/build-module/components/iframe/index.mjs.map +2 -2
- package/build-module/components/iframe/use-scale-canvas.mjs +0 -1
- package/build-module/components/iframe/use-scale-canvas.mjs.map +2 -2
- package/build-module/components/inspector-controls-tabs/use-inspector-controls-tabs.mjs +8 -4
- package/build-module/components/inspector-controls-tabs/use-inspector-controls-tabs.mjs.map +2 -2
- package/build-module/components/link-picker/link-preview.mjs +2 -1
- package/build-module/components/link-picker/link-preview.mjs.map +2 -2
- package/build-module/components/provider/index.mjs +23 -7
- package/build-module/components/provider/index.mjs.map +2 -2
- package/build-module/components/provider/use-media-upload-settings.mjs +1 -0
- package/build-module/components/provider/use-media-upload-settings.mjs.map +2 -2
- package/build-module/components/writing-flow/use-arrow-nav.mjs +1 -1
- package/build-module/components/writing-flow/use-arrow-nav.mjs.map +2 -2
- package/build-module/hooks/auto-inspector-controls.mjs +28 -4
- package/build-module/hooks/auto-inspector-controls.mjs.map +2 -2
- package/build-module/hooks/cross-origin-isolation.mjs +9 -75
- package/build-module/hooks/cross-origin-isolation.mjs.map +2 -2
- package/build-module/hooks/custom-css.mjs +28 -2
- package/build-module/hooks/custom-css.mjs.map +2 -2
- package/build-module/private-apis.mjs +3 -1
- package/build-module/private-apis.mjs.map +2 -2
- package/build-module/store/actions.mjs +0 -8
- package/build-module/store/actions.mjs.map +2 -2
- package/build-module/store/private-keys.mjs +2 -0
- package/build-module/store/private-keys.mjs.map +2 -2
- package/build-module/store/private-selectors.mjs +4 -3
- package/build-module/store/private-selectors.mjs.map +2 -2
- package/build-module/store/reducer.mjs +78 -73
- package/build-module/store/reducer.mjs.map +2 -2
- package/build-module/store/selectors.mjs +16 -14
- package/build-module/store/selectors.mjs.map +2 -2
- package/build-style/content-rtl.css +25 -0
- package/build-style/content.css +25 -0
- package/build-style/style-rtl.css +3 -0
- package/build-style/style.css +3 -0
- package/package.json +39 -39
- package/src/components/block-bindings/attribute-control.js +8 -3
- package/src/components/block-inspector/edit-contents.js +5 -3
- package/src/components/block-list/block-html.js +13 -3
- package/src/components/block-list/block.js +10 -1
- package/src/components/block-list/content.scss +35 -0
- package/src/components/block-list/use-block-props/index.js +11 -1
- package/src/components/block-settings-menu-controls/index.js +1 -0
- package/src/components/block-styles/index.js +7 -1
- package/src/components/block-switcher/block-transformations-menu.js +2 -0
- package/src/components/block-switcher/block-variation-transformations.js +2 -0
- package/src/components/block-toolbar/block-toolbar-icon.js +6 -1
- package/src/components/block-toolbar/index.js +7 -2
- package/src/components/block-tools/index.js +11 -4
- package/src/components/block-tools/style.scss +5 -0
- package/src/components/block-variation-transforms/index.js +41 -36
- package/src/components/block-visibility/use-block-visibility.js +4 -2
- package/src/components/block-visibility/viewport-visibility-info.js +8 -1
- package/src/components/dimensions-tool/scale-tool.js +2 -2
- package/src/components/iframe/index.js +2 -12
- package/src/components/iframe/use-scale-canvas.js +0 -1
- package/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js +9 -5
- package/src/components/link-picker/link-preview.js +2 -1
- package/src/components/provider/index.js +49 -6
- package/src/components/provider/use-media-upload-settings.js +1 -0
- package/src/components/writing-flow/use-arrow-nav.js +9 -2
- package/src/hooks/auto-inspector-controls.js +31 -4
- package/src/hooks/cross-origin-isolation.js +10 -109
- package/src/hooks/custom-css.js +36 -2
- package/src/hooks/test/cross-origin-isolation.js +15 -42
- package/src/private-apis.js +2 -0
- package/src/store/actions.js +0 -8
- package/src/store/private-keys.js +1 -0
- package/src/store/private-selectors.js +6 -3
- package/src/store/reducer.js +119 -97
- package/src/store/selectors.js +59 -22
- package/src/store/test/private-selectors.js +67 -34
- package/src/store/test/reducer.js +545 -57
- package/src/store/test/selectors.js +611 -53
|
@@ -146,41 +146,46 @@ function VariationsToggleGroupControl( {
|
|
|
146
146
|
|
|
147
147
|
function __experimentalBlockVariationTransforms( { blockClientId } ) {
|
|
148
148
|
const { updateBlockAttributes } = useDispatch( blockEditorStore );
|
|
149
|
-
const {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
149
|
+
const {
|
|
150
|
+
activeBlockVariation,
|
|
151
|
+
variations,
|
|
152
|
+
canEdit,
|
|
153
|
+
isContentOnly,
|
|
154
|
+
isSection,
|
|
155
|
+
} = useSelect(
|
|
156
|
+
( select ) => {
|
|
157
|
+
const { getActiveBlockVariation, getBlockVariations } =
|
|
158
|
+
select( blocksStore );
|
|
159
|
+
|
|
160
|
+
const {
|
|
161
|
+
getBlockName,
|
|
162
|
+
getBlockAttributes,
|
|
163
|
+
getBlockEditingMode,
|
|
164
|
+
isSectionBlock,
|
|
165
|
+
} = unlock( select( blockEditorStore ) );
|
|
166
|
+
const { canEditBlock } = select( blockEditorStore );
|
|
167
|
+
|
|
168
|
+
const name = blockClientId && getBlockName( blockClientId );
|
|
169
|
+
|
|
170
|
+
const { hasContentRoleAttribute } = unlock( select( blocksStore ) );
|
|
171
|
+
const isContentBlock = hasContentRoleAttribute( name );
|
|
172
|
+
|
|
173
|
+
return {
|
|
174
|
+
activeBlockVariation: getActiveBlockVariation(
|
|
175
|
+
name,
|
|
176
|
+
getBlockAttributes( blockClientId ),
|
|
177
|
+
'transform'
|
|
178
|
+
),
|
|
179
|
+
variations: name && getBlockVariations( name, 'transform' ),
|
|
180
|
+
canEdit: canEditBlock( blockClientId ),
|
|
181
|
+
isContentOnly:
|
|
182
|
+
getBlockEditingMode( blockClientId ) === 'contentOnly' &&
|
|
183
|
+
! isContentBlock,
|
|
184
|
+
isSection: isSectionBlock( blockClientId ),
|
|
185
|
+
};
|
|
186
|
+
},
|
|
187
|
+
[ blockClientId ]
|
|
188
|
+
);
|
|
184
189
|
|
|
185
190
|
const selectedValue = activeBlockVariation?.name;
|
|
186
191
|
|
|
@@ -205,7 +210,7 @@ function __experimentalBlockVariationTransforms( { blockClientId } ) {
|
|
|
205
210
|
} );
|
|
206
211
|
};
|
|
207
212
|
|
|
208
|
-
if ( ! variations?.length || isContentOnly || isSection ) {
|
|
213
|
+
if ( ! variations?.length || ! canEdit || isContentOnly || isSection ) {
|
|
209
214
|
return null;
|
|
210
215
|
}
|
|
211
216
|
|
|
@@ -14,16 +14,18 @@ import { BLOCK_VISIBILITY_VIEWPORTS } from './constants';
|
|
|
14
14
|
* @param {Object} options Parameters to avoid extra store subscriptions.
|
|
15
15
|
* @param {Object|boolean} options.blockVisibility Block visibility metadata.
|
|
16
16
|
* @param {string} options.deviceType Current device type ('desktop', 'tablet', 'mobile').
|
|
17
|
+
* @param {Window?} options.view Window instance in which to perform viewport matching
|
|
17
18
|
* @return {Object} Object with `isBlockCurrentlyHidden` (boolean) and `currentViewport` (string) properties.
|
|
18
19
|
*/
|
|
19
20
|
export default function useBlockVisibility( options = {} ) {
|
|
20
21
|
const {
|
|
21
22
|
blockVisibility = undefined,
|
|
22
23
|
deviceType = BLOCK_VISIBILITY_VIEWPORTS.desktop.key,
|
|
24
|
+
view = window,
|
|
23
25
|
} = options;
|
|
24
26
|
|
|
25
|
-
const isLargerThanMobile = useViewportMatch( 'mobile', '>=' ); // >= 480px
|
|
26
|
-
const isLargerThanTablet = useViewportMatch( 'medium', '>=' ); // >= 782px
|
|
27
|
+
const isLargerThanMobile = useViewportMatch( 'mobile', '>=', view ); // >= 480px
|
|
28
|
+
const isLargerThanTablet = useViewportMatch( 'medium', '>=', view ); // >= 782px
|
|
27
29
|
|
|
28
30
|
/*
|
|
29
31
|
* Priority:
|
|
@@ -17,6 +17,7 @@ import { unseen } from '@wordpress/icons';
|
|
|
17
17
|
import { unlock } from '../../lock-unlock';
|
|
18
18
|
import { store as blockEditorStore } from '../../store';
|
|
19
19
|
import useBlockVisibility from './use-block-visibility';
|
|
20
|
+
import { useBlockElement } from '../block-list/use-block-props/use-block-refs';
|
|
20
21
|
import { deviceTypeKey } from '../../store/private-keys';
|
|
21
22
|
import { BLOCK_VISIBILITY_VIEWPORTS } from './constants';
|
|
22
23
|
|
|
@@ -56,10 +57,16 @@ export default function ViewportVisibilityInfo( { clientId } ) {
|
|
|
56
57
|
[ clientId ]
|
|
57
58
|
);
|
|
58
59
|
|
|
59
|
-
//
|
|
60
|
+
// Get the block's DOM element to derive the canvas iframe window,
|
|
61
|
+
// so viewport detection matches the actual block rendering context.
|
|
62
|
+
const blockElement = useBlockElement( clientId );
|
|
63
|
+
const rawCanvasView = blockElement?.ownerDocument?.defaultView;
|
|
64
|
+
const canvasView = rawCanvasView === null ? undefined : rawCanvasView;
|
|
65
|
+
|
|
60
66
|
const { isBlockCurrentlyHidden, currentViewport } = useBlockVisibility( {
|
|
61
67
|
blockVisibility: currentBlockVisibility,
|
|
62
68
|
deviceType: selectedDeviceType,
|
|
69
|
+
view: canvasView,
|
|
63
70
|
} );
|
|
64
71
|
|
|
65
72
|
/*
|
|
@@ -98,14 +98,14 @@ export default function ScaleTool( {
|
|
|
98
98
|
|
|
99
99
|
return (
|
|
100
100
|
<ToolsPanelItem
|
|
101
|
-
label={
|
|
101
|
+
label={ _x( 'Scale', 'Image scaling options' ) }
|
|
102
102
|
isShownByDefault={ isShownByDefault }
|
|
103
103
|
hasValue={ () => displayValue !== defaultValue }
|
|
104
104
|
onDeselect={ () => onChange( defaultValue ) }
|
|
105
105
|
panelId={ panelId }
|
|
106
106
|
>
|
|
107
107
|
<ToggleGroupControl
|
|
108
|
-
label={
|
|
108
|
+
label={ _x( 'Scale', 'Image scaling options' ) }
|
|
109
109
|
isBlock
|
|
110
110
|
help={ scaleHelp[ displayValue ] }
|
|
111
111
|
value={ displayValue }
|
|
@@ -8,12 +8,7 @@ import clsx from 'clsx';
|
|
|
8
8
|
*/
|
|
9
9
|
import { useState, createPortal, forwardRef } from '@wordpress/element';
|
|
10
10
|
import { __ } from '@wordpress/i18n';
|
|
11
|
-
import {
|
|
12
|
-
useMergeRefs,
|
|
13
|
-
useRefEffect,
|
|
14
|
-
useDisabled,
|
|
15
|
-
useViewportMatch,
|
|
16
|
-
} from '@wordpress/compose';
|
|
11
|
+
import { useMergeRefs, useRefEffect, useDisabled } from '@wordpress/compose';
|
|
17
12
|
import { __experimentalStyleProvider as StyleProvider } from '@wordpress/components';
|
|
18
13
|
import { useSelect } from '@wordpress/data';
|
|
19
14
|
|
|
@@ -25,8 +20,6 @@ import { getCompatibilityStyles } from './get-compatibility-styles';
|
|
|
25
20
|
import { useScaleCanvas } from './use-scale-canvas';
|
|
26
21
|
import { store as blockEditorStore } from '../../store';
|
|
27
22
|
|
|
28
|
-
const ViewportWidthProvider = useViewportMatch.__experimentalWidthProvider;
|
|
29
|
-
|
|
30
23
|
function bubbleEvent( event, Constructor, frame ) {
|
|
31
24
|
const init = {};
|
|
32
25
|
|
|
@@ -274,7 +267,6 @@ function Iframe( {
|
|
|
274
267
|
const {
|
|
275
268
|
contentResizeListener,
|
|
276
269
|
containerResizeListener,
|
|
277
|
-
containerWidth,
|
|
278
270
|
isZoomedOut,
|
|
279
271
|
scaleContainerWidth,
|
|
280
272
|
} = useScaleCanvas( {
|
|
@@ -355,9 +347,7 @@ function Iframe( {
|
|
|
355
347
|
>
|
|
356
348
|
{ contentResizeListener }
|
|
357
349
|
<StyleProvider document={ iframeDocument }>
|
|
358
|
-
|
|
359
|
-
{ children }
|
|
360
|
-
</ViewportWidthProvider>
|
|
350
|
+
{ children }
|
|
361
351
|
</StyleProvider>
|
|
362
352
|
</body>,
|
|
363
353
|
iframeDocument.documentElement
|
|
@@ -111,14 +111,18 @@ export default function useInspectorControlsTabs(
|
|
|
111
111
|
tabs.push( TAB_SETTINGS );
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
|
|
114
|
+
const { tabSettings, isPreviewMode } = useSelect( ( select ) => {
|
|
115
|
+
const settings = select( blockEditorStore ).getSettings();
|
|
116
|
+
return {
|
|
117
|
+
tabSettings: settings.blockInspectorTabs,
|
|
118
|
+
isPreviewMode: settings.isPreviewMode,
|
|
119
|
+
};
|
|
120
|
+
}, [] );
|
|
121
|
+
|
|
122
|
+
if ( ! isPreviewMode && ( hasBlockStyles || hasStyleFills ) ) {
|
|
115
123
|
tabs.push( TAB_STYLES );
|
|
116
124
|
}
|
|
117
125
|
|
|
118
|
-
const tabSettings = useSelect( ( select ) => {
|
|
119
|
-
return select( blockEditorStore ).getSettings().blockInspectorTabs;
|
|
120
|
-
}, [] );
|
|
121
|
-
|
|
122
126
|
const showTabs = getShowTabs( blockName, tabSettings );
|
|
123
127
|
return showTabs ? tabs : EMPTY_ARRAY;
|
|
124
128
|
}
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
privateApis as componentsPrivateApis,
|
|
10
10
|
} from '@wordpress/components';
|
|
11
11
|
import { Icon, chevronDown } from '@wordpress/icons';
|
|
12
|
+
import { __unstableStripHTML as stripHTML } from '@wordpress/dom';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Internal dependencies
|
|
@@ -50,7 +51,7 @@ export function LinkPreview( { title, url, image, badges } ) {
|
|
|
50
51
|
numberOfLines={ 1 }
|
|
51
52
|
className="link-preview-button__title"
|
|
52
53
|
>
|
|
53
|
-
{ title }
|
|
54
|
+
{ stripHTML( title ) }
|
|
54
55
|
</Truncate>
|
|
55
56
|
{ url && (
|
|
56
57
|
<Truncate
|
|
@@ -20,6 +20,7 @@ import { BlockRefsProvider } from './block-refs-provider';
|
|
|
20
20
|
import { unlock } from '../../lock-unlock';
|
|
21
21
|
import KeyboardShortcuts from '../keyboard-shortcuts';
|
|
22
22
|
import useMediaUploadSettings from './use-media-upload-settings';
|
|
23
|
+
import { mediaUploadOnSuccessKey } from '../../store/private-keys';
|
|
23
24
|
import { SelectionContext } from './selection-context';
|
|
24
25
|
|
|
25
26
|
/** @typedef {import('@wordpress/data').WPDataRegistry} WPDataRegistry */
|
|
@@ -89,6 +90,7 @@ function shouldEnableClientSideMediaProcessing() {
|
|
|
89
90
|
* or when adding a file to the editor via drag & drop.
|
|
90
91
|
*
|
|
91
92
|
* @param {WPDataRegistry} registry
|
|
93
|
+
* @param {Object} settings Block editor settings.
|
|
92
94
|
* @param {Object} $3 Parameters object passed to the function.
|
|
93
95
|
* @param {Array} $3.allowedTypes Array with the types of media that can be uploaded, if unset all types are allowed.
|
|
94
96
|
* @param {Object} $3.additionalData Additional data to include in the request.
|
|
@@ -100,6 +102,7 @@ function shouldEnableClientSideMediaProcessing() {
|
|
|
100
102
|
*/
|
|
101
103
|
function mediaUpload(
|
|
102
104
|
registry,
|
|
105
|
+
settings,
|
|
103
106
|
{
|
|
104
107
|
allowedTypes,
|
|
105
108
|
additionalData = {},
|
|
@@ -113,9 +116,13 @@ function mediaUpload(
|
|
|
113
116
|
void registry.dispatch( uploadStore ).addItems( {
|
|
114
117
|
files: Array.from( filesList ),
|
|
115
118
|
onChange: onFileChange,
|
|
116
|
-
onSuccess
|
|
119
|
+
onSuccess: ( attachments ) => {
|
|
120
|
+
settings?.[ mediaUploadOnSuccessKey ]?.( attachments );
|
|
121
|
+
onSuccess?.( attachments );
|
|
122
|
+
},
|
|
117
123
|
onBatchSuccess,
|
|
118
|
-
onError: (
|
|
124
|
+
onError: ( error ) =>
|
|
125
|
+
onError( typeof error === 'string' ? error : error?.message ?? '' ),
|
|
119
126
|
additionalData,
|
|
120
127
|
allowedTypes,
|
|
121
128
|
} );
|
|
@@ -146,16 +153,38 @@ export const ExperimentalBlockEditorProvider = withRegistryProvider(
|
|
|
146
153
|
const isClientSideMediaEnabled =
|
|
147
154
|
shouldEnableClientSideMediaProcessing();
|
|
148
155
|
|
|
156
|
+
// Nested providers (e.g. from useBlockPreview) inherit settings
|
|
157
|
+
// where mediaUpload has already been replaced with the
|
|
158
|
+
// interceptor. Detect this so we skip the replacement and
|
|
159
|
+
// MediaUploadProvider for them — see the longer comment below.
|
|
160
|
+
const isMediaUploadIntercepted =
|
|
161
|
+
!! _settings?.mediaUpload?.__isMediaUploadInterceptor;
|
|
162
|
+
|
|
149
163
|
const settings = useMemo( () => {
|
|
150
|
-
if (
|
|
164
|
+
if (
|
|
165
|
+
isClientSideMediaEnabled &&
|
|
166
|
+
_settings?.mediaUpload &&
|
|
167
|
+
! isMediaUploadIntercepted
|
|
168
|
+
) {
|
|
151
169
|
// Create a new object so that the original props.settings.mediaUpload is not modified.
|
|
170
|
+
const interceptor = mediaUpload.bind(
|
|
171
|
+
null,
|
|
172
|
+
registry,
|
|
173
|
+
_settings
|
|
174
|
+
);
|
|
175
|
+
interceptor.__isMediaUploadInterceptor = true;
|
|
152
176
|
return {
|
|
153
177
|
..._settings,
|
|
154
|
-
mediaUpload:
|
|
178
|
+
mediaUpload: interceptor,
|
|
155
179
|
};
|
|
156
180
|
}
|
|
157
181
|
return _settings;
|
|
158
|
-
}, [
|
|
182
|
+
}, [
|
|
183
|
+
_settings,
|
|
184
|
+
registry,
|
|
185
|
+
isClientSideMediaEnabled,
|
|
186
|
+
isMediaUploadIntercepted,
|
|
187
|
+
] );
|
|
159
188
|
|
|
160
189
|
const { __experimentalUpdateSettings } = unlock(
|
|
161
190
|
useDispatch( blockEditorStore )
|
|
@@ -215,7 +244,21 @@ export const ExperimentalBlockEditorProvider = withRegistryProvider(
|
|
|
215
244
|
</SelectionContext.Provider>
|
|
216
245
|
);
|
|
217
246
|
|
|
218
|
-
|
|
247
|
+
// MediaUploadProvider writes the mediaUpload function from
|
|
248
|
+
// _settings into the shared upload-media store so the store can
|
|
249
|
+
// hand files off to the server. useMediaUploadSettings extracts
|
|
250
|
+
// mediaUpload from the original _settings prop — *before* the
|
|
251
|
+
// interceptor replacement above — so the store receives the
|
|
252
|
+
// real server-side upload function.
|
|
253
|
+
//
|
|
254
|
+
// Only the first (outermost) provider should do this.
|
|
255
|
+
// Nested providers (e.g. from useBlockPreview in
|
|
256
|
+
// core/post-template) inherit settings that already contain
|
|
257
|
+
// the interceptor, so their MediaUploadProvider would
|
|
258
|
+
// overwrite the store's server-side function with the
|
|
259
|
+
// interceptor, causing uploads to loop instead of reaching
|
|
260
|
+
// the server.
|
|
261
|
+
if ( isClientSideMediaEnabled && ! isMediaUploadIntercepted ) {
|
|
219
262
|
return (
|
|
220
263
|
<MediaUploadProvider
|
|
221
264
|
settings={ mediaUploadSettings }
|
|
@@ -15,6 +15,7 @@ function useMediaUploadSettings( settings = {} ) {
|
|
|
15
15
|
() => ( {
|
|
16
16
|
mediaUpload: settings.mediaUpload,
|
|
17
17
|
mediaSideload: settings.mediaSideload,
|
|
18
|
+
mediaFinalize: settings.mediaFinalize,
|
|
18
19
|
maxUploadFileSize: settings.maxUploadFileSize,
|
|
19
20
|
allowedMimeTypes: settings.allowedMimeTypes,
|
|
20
21
|
allImageSizes: settings.allImageSizes,
|
|
@@ -115,9 +115,16 @@ export function getClosestTabbable(
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
function isTabCandidate( node ) {
|
|
118
|
-
// If it's a block
|
|
119
|
-
// there are better
|
|
118
|
+
// If it's a block wrapper (not itself a contenteditable editing surface)
|
|
119
|
+
// and there are nested focusable nodes, skip because there are better
|
|
120
|
+
// candidates. We must not skip contenteditable nodes that happen to
|
|
121
|
+
// contain links or other focusable inline elements, since those are the
|
|
122
|
+
// correct navigation targets.
|
|
123
|
+
//
|
|
124
|
+
// See https://github.com/WordPress/gutenberg/pull/77474
|
|
125
|
+
// TODO: Consider fixing focus.tabbable
|
|
120
126
|
if (
|
|
127
|
+
node.contentEditable !== 'true' &&
|
|
121
128
|
getBlockClientId( node ) &&
|
|
122
129
|
focus.focusable
|
|
123
130
|
.find( node )
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
-
import { getBlockType } from '@wordpress/blocks';
|
|
4
|
+
import { getBlockType, store as blocksStore } from '@wordpress/blocks';
|
|
5
5
|
import { PanelBody } from '@wordpress/components';
|
|
6
6
|
import { useSelect } from '@wordpress/data';
|
|
7
7
|
import { DataForm } from '@wordpress/dataviews';
|
|
8
|
-
import { useMemo } from '@wordpress/element';
|
|
8
|
+
import { useContext, useMemo } from '@wordpress/element';
|
|
9
9
|
import { __ } from '@wordpress/i18n';
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -14,6 +14,8 @@ import { __ } from '@wordpress/i18n';
|
|
|
14
14
|
import InspectorControls from '../components/inspector-controls';
|
|
15
15
|
import { useBlockEditingMode } from '../components/block-editing-mode';
|
|
16
16
|
import { store as blockEditorStore } from '../store';
|
|
17
|
+
import { unlock } from '../lock-unlock';
|
|
18
|
+
import BlockContext from '../components/block-context';
|
|
17
19
|
import { generateFieldsFromAttributes } from './generate-fields-from-attributes';
|
|
18
20
|
|
|
19
21
|
/**
|
|
@@ -45,9 +47,34 @@ function hasAutoGenerateControl( blockTypeAttributes ) {
|
|
|
45
47
|
function AutoRegisterControls( { name, clientId, setAttributes } ) {
|
|
46
48
|
const blockEditingMode = useBlockEditingMode();
|
|
47
49
|
|
|
50
|
+
const blockContext = useContext( BlockContext );
|
|
51
|
+
|
|
48
52
|
const attributes = useSelect(
|
|
49
|
-
( select ) =>
|
|
50
|
-
|
|
53
|
+
( select ) => {
|
|
54
|
+
const _attributes =
|
|
55
|
+
select( blockEditorStore ).getBlockAttributes( clientId );
|
|
56
|
+
if ( ! _attributes?.metadata?.bindings ) {
|
|
57
|
+
return _attributes;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const { getBlockBindingsSource } = unlock( select( blocksStore ) );
|
|
61
|
+
return Object.entries( _attributes.metadata.bindings ).reduce(
|
|
62
|
+
( acc, [ attribute, binding ] ) => {
|
|
63
|
+
const source = getBlockBindingsSource( binding.source );
|
|
64
|
+
if ( ! source ) {
|
|
65
|
+
return acc;
|
|
66
|
+
}
|
|
67
|
+
const values = source.getValues( {
|
|
68
|
+
select,
|
|
69
|
+
context: blockContext,
|
|
70
|
+
bindings: { [ attribute ]: binding },
|
|
71
|
+
} );
|
|
72
|
+
return { ...acc, ...values };
|
|
73
|
+
},
|
|
74
|
+
_attributes
|
|
75
|
+
);
|
|
76
|
+
},
|
|
77
|
+
[ blockContext, clientId ]
|
|
51
78
|
);
|
|
52
79
|
|
|
53
80
|
const blockType = getBlockType( name );
|
|
@@ -1,34 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*/
|
|
4
|
-
import { addFilter } from '@wordpress/hooks';
|
|
5
|
-
import { createHigherOrderComponent } from '@wordpress/compose';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Adds crossorigin and credentialless attributes to elements as needed.
|
|
2
|
+
* Adds crossorigin="anonymous" to an element if missing.
|
|
9
3
|
*
|
|
10
4
|
* @param {Element} el The element to modify.
|
|
11
5
|
*/
|
|
12
|
-
function
|
|
13
|
-
// Add the crossorigin attribute if missing.
|
|
6
|
+
function addCrossOriginAttribute( el ) {
|
|
14
7
|
if ( ! el.hasAttribute( 'crossorigin' ) ) {
|
|
15
8
|
el.setAttribute( 'crossorigin', 'anonymous' );
|
|
16
9
|
}
|
|
17
|
-
|
|
18
|
-
// For iframes, add the credentialless attribute.
|
|
19
|
-
if ( el.nodeName === 'IFRAME' && ! el.hasAttribute( 'credentialless' ) ) {
|
|
20
|
-
// Do not modify the iframed editor canvas.
|
|
21
|
-
if ( el.getAttribute( 'src' )?.startsWith( 'blob:' ) ) {
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
el.setAttribute( 'credentialless', '' );
|
|
26
|
-
|
|
27
|
-
// Reload the iframe to ensure the new attribute is taken into account.
|
|
28
|
-
const origSrc = el.getAttribute( 'src' ) || '';
|
|
29
|
-
el.setAttribute( 'src', '' );
|
|
30
|
-
el.setAttribute( 'src', origSrc );
|
|
31
|
-
}
|
|
32
10
|
}
|
|
33
11
|
|
|
34
12
|
// Only add the mutation observer if the site is cross-origin isolated.
|
|
@@ -49,59 +27,18 @@ if ( window.crossOriginIsolated ) {
|
|
|
49
27
|
return;
|
|
50
28
|
}
|
|
51
29
|
|
|
52
|
-
el.querySelectorAll(
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
addCrossOriginAttributes( v );
|
|
56
|
-
} );
|
|
57
|
-
|
|
58
|
-
if ( el.nodeName === 'IFRAME' ) {
|
|
59
|
-
const iframeNode = el;
|
|
60
|
-
|
|
61
|
-
/*
|
|
62
|
-
* Sandboxed iframes should not get modified. For example embedding a tweet served in a sandboxed
|
|
63
|
-
* iframe, the tweet itself would not be modified.
|
|
64
|
-
*/
|
|
65
|
-
const isEmbedSandboxIframe =
|
|
66
|
-
iframeNode.classList.contains(
|
|
67
|
-
'components-sandbox'
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
if ( ! isEmbedSandboxIframe ) {
|
|
71
|
-
iframeNode.addEventListener( 'load', () => {
|
|
72
|
-
try {
|
|
73
|
-
if (
|
|
74
|
-
iframeNode.contentDocument &&
|
|
75
|
-
iframeNode.contentDocument.body
|
|
76
|
-
) {
|
|
77
|
-
observer.observe(
|
|
78
|
-
iframeNode.contentDocument,
|
|
79
|
-
{
|
|
80
|
-
childList: true,
|
|
81
|
-
attributes: true,
|
|
82
|
-
subtree: true,
|
|
83
|
-
}
|
|
84
|
-
);
|
|
85
|
-
}
|
|
86
|
-
} catch ( e ) {
|
|
87
|
-
// Iframe may be cross-origin or otherwise inaccessible.
|
|
88
|
-
// Silently ignore these cases.
|
|
89
|
-
}
|
|
90
|
-
} );
|
|
30
|
+
el.querySelectorAll( 'source,script,video,link' ).forEach(
|
|
31
|
+
( v ) => {
|
|
32
|
+
addCrossOriginAttribute( v );
|
|
91
33
|
}
|
|
92
|
-
|
|
34
|
+
);
|
|
93
35
|
|
|
94
36
|
if (
|
|
95
|
-
[
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
'SCRIPT',
|
|
99
|
-
'VIDEO',
|
|
100
|
-
'LINK',
|
|
101
|
-
'IFRAME',
|
|
102
|
-
].includes( el.nodeName )
|
|
37
|
+
[ 'SOURCE', 'SCRIPT', 'VIDEO', 'LINK' ].includes(
|
|
38
|
+
el.nodeName
|
|
39
|
+
)
|
|
103
40
|
) {
|
|
104
|
-
|
|
41
|
+
addCrossOriginAttribute( el );
|
|
105
42
|
}
|
|
106
43
|
} );
|
|
107
44
|
} );
|
|
@@ -134,39 +71,3 @@ if ( window.crossOriginIsolated ) {
|
|
|
134
71
|
|
|
135
72
|
startObservingBody();
|
|
136
73
|
}
|
|
137
|
-
|
|
138
|
-
// Only apply the embed preview filter when cross-origin isolated.
|
|
139
|
-
if ( window.crossOriginIsolated ) {
|
|
140
|
-
const supportsCredentialless =
|
|
141
|
-
'credentialless' in window.HTMLIFrameElement.prototype;
|
|
142
|
-
|
|
143
|
-
const disableEmbedPreviews = createHigherOrderComponent(
|
|
144
|
-
( BlockEdit ) =>
|
|
145
|
-
function DisableEmbedPreviews( props ) {
|
|
146
|
-
if ( 'core/embed' !== props.name ) {
|
|
147
|
-
return <BlockEdit { ...props } />;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// List of embeds that do not support a preview is from packages/block-library/src/embed/variations.js.
|
|
151
|
-
const previewable =
|
|
152
|
-
supportsCredentialless &&
|
|
153
|
-
! [ 'facebook', 'smugmug' ].includes(
|
|
154
|
-
props.attributes.providerNameSlug
|
|
155
|
-
);
|
|
156
|
-
|
|
157
|
-
return (
|
|
158
|
-
<BlockEdit
|
|
159
|
-
{ ...props }
|
|
160
|
-
attributes={ { ...props.attributes, previewable } }
|
|
161
|
-
/>
|
|
162
|
-
);
|
|
163
|
-
},
|
|
164
|
-
'withDisabledEmbedPreview'
|
|
165
|
-
);
|
|
166
|
-
|
|
167
|
-
addFilter(
|
|
168
|
-
'editor.BlockEdit',
|
|
169
|
-
'media-experiments/disable-embed-previews',
|
|
170
|
-
disableEmbedPreviews
|
|
171
|
-
);
|
|
172
|
-
}
|
package/src/hooks/custom-css.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
-
import { useMemo } from '@wordpress/element';
|
|
5
|
-
import { useSelect } from '@wordpress/data';
|
|
4
|
+
import { useEffect, useMemo } from '@wordpress/element';
|
|
5
|
+
import { useDispatch, useSelect } from '@wordpress/data';
|
|
6
6
|
import { useInstanceId } from '@wordpress/compose';
|
|
7
7
|
import { getBlockType, hasBlockSupport } from '@wordpress/blocks';
|
|
8
8
|
import { __, sprintf } from '@wordpress/i18n';
|
|
9
9
|
import { processCSSNesting } from '@wordpress/global-styles-engine';
|
|
10
|
+
import { useBlockEditingMode } from '../components/block-editing-mode';
|
|
11
|
+
import { store as noticesStore } from '@wordpress/notices';
|
|
10
12
|
|
|
11
13
|
/**
|
|
12
14
|
* Internal dependencies
|
|
@@ -33,6 +35,11 @@ const EMPTY_STYLE = {};
|
|
|
33
35
|
* @param {Object} props.style Block style attribute.
|
|
34
36
|
*/
|
|
35
37
|
function CustomCSSControl( { blockName, setAttributes, style } ) {
|
|
38
|
+
const blockEditingMode = useBlockEditingMode();
|
|
39
|
+
|
|
40
|
+
if ( blockEditingMode !== 'default' ) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
36
43
|
const blockType = getBlockType( blockName );
|
|
37
44
|
|
|
38
45
|
function onChange( newStyle ) {
|
|
@@ -63,6 +70,8 @@ function CustomCSSControl( { blockName, setAttributes, style } ) {
|
|
|
63
70
|
);
|
|
64
71
|
}
|
|
65
72
|
|
|
73
|
+
const CUSTOM_CSS_WARNING_NOTICE_ID = 'custom-css-edit-warning';
|
|
74
|
+
|
|
66
75
|
function CustomCSSEdit( { clientId, name, setAttributes } ) {
|
|
67
76
|
const { style, canEditCSS } = useSelect(
|
|
68
77
|
( select ) => {
|
|
@@ -107,6 +116,31 @@ function useBlockProps( { style } ) {
|
|
|
107
116
|
customCSS.trim().length > 0 &&
|
|
108
117
|
validateCSS( customCSS );
|
|
109
118
|
|
|
119
|
+
const canEditCSS = useSelect(
|
|
120
|
+
( select ) => select( blockEditorStore ).getSettings().canEditCSS,
|
|
121
|
+
[]
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
const { createWarningNotice } = useDispatch( noticesStore );
|
|
125
|
+
|
|
126
|
+
// Show a warning notice when the user lacks edit_css and a block has
|
|
127
|
+
// custom CSS. The fixed notice ID ensures only one notice is shown
|
|
128
|
+
// regardless of how many blocks have CSS.
|
|
129
|
+
const hasCustomCSS = !! customCSS?.trim();
|
|
130
|
+
useEffect( () => {
|
|
131
|
+
if ( ! canEditCSS && hasCustomCSS ) {
|
|
132
|
+
createWarningNotice(
|
|
133
|
+
__(
|
|
134
|
+
'This post contains blocks with custom CSS. You do not have permission to edit CSS. If you save this post, the custom CSS will be removed.'
|
|
135
|
+
),
|
|
136
|
+
{
|
|
137
|
+
id: CUSTOM_CSS_WARNING_NOTICE_ID,
|
|
138
|
+
isDismissible: true,
|
|
139
|
+
}
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
}, [ canEditCSS, hasCustomCSS, createWarningNotice ] );
|
|
143
|
+
|
|
110
144
|
const customCSSIdentifier = useInstanceId(
|
|
111
145
|
CUSTOM_CSS_INSTANCE_REFERENCE,
|
|
112
146
|
'wp-custom-css'
|