@wordpress/block-editor 9.3.0 → 9.4.0
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/CHANGELOG.md +2 -0
- package/build/components/block-pattern-setup/index.js +3 -9
- package/build/components/block-pattern-setup/index.js.map +1 -1
- package/build/components/block-pattern-setup/setup-toolbar.js +3 -8
- package/build/components/block-pattern-setup/setup-toolbar.js.map +1 -1
- package/build/components/block-preview/auto.js +21 -5
- package/build/components/block-preview/auto.js.map +1 -1
- package/build/components/block-settings-menu/block-edit-visually-button.js +70 -0
- package/build/components/block-settings-menu/block-edit-visually-button.js.map +1 -0
- package/build/components/block-settings-menu/block-settings-dropdown.js +1 -1
- package/build/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
- package/build/components/block-settings-menu/index.js +6 -2
- package/build/components/block-settings-menu/index.js.map +1 -1
- package/build/components/block-settings-menu-controls/index.js +4 -1
- package/build/components/block-settings-menu-controls/index.js.map +1 -1
- package/build/components/block-title/use-block-display-title.js +3 -10
- package/build/components/block-title/use-block-display-title.js.map +1 -1
- package/build/components/colors-gradients/dropdown.js +2 -1
- package/build/components/colors-gradients/dropdown.js.map +1 -1
- package/build/components/duotone/components.js +145 -0
- package/build/components/duotone/components.js.map +1 -0
- package/build/components/duotone/index.js +40 -0
- package/build/components/duotone/index.js.map +1 -0
- package/build/components/duotone/utils.js +38 -0
- package/build/components/duotone/utils.js.map +1 -0
- package/build/components/duotone-control/index.js +17 -5
- package/build/components/duotone-control/index.js.map +1 -1
- package/build/components/index.js +14 -0
- package/build/components/index.js.map +1 -1
- package/build/components/inserter/index.js +3 -3
- package/build/components/inserter/index.js.map +1 -1
- package/build/components/media-placeholder/index.js +1 -0
- package/build/components/media-placeholder/index.js.map +1 -1
- package/build/components/media-placeholder/index.native.js +4 -4
- package/build/components/media-placeholder/index.native.js.map +1 -1
- package/build/components/media-replace-flow/index.js +3 -7
- package/build/components/media-replace-flow/index.js.map +1 -1
- package/build/components/publish-date-time-picker/index.js +3 -0
- package/build/components/publish-date-time-picker/index.js.map +1 -1
- package/build/components/rich-text/use-input-rules.js +4 -13
- package/build/components/rich-text/use-input-rules.js.map +1 -1
- package/build/components/rich-text/use-paste-handler.js +20 -5
- package/build/components/rich-text/use-paste-handler.js.map +1 -1
- package/build/elements/index.js +11 -3
- package/build/elements/index.js.map +1 -1
- package/build/hooks/aria-label.js +71 -0
- package/build/hooks/aria-label.js.map +1 -0
- package/build/hooks/duotone.js +33 -160
- package/build/hooks/duotone.js.map +1 -1
- package/build/hooks/index.js +3 -7
- package/build/hooks/index.js.map +1 -1
- package/build/hooks/layout.js +6 -4
- package/build/hooks/layout.js.map +1 -1
- package/build/index.js +0 -7
- package/build/index.js.map +1 -1
- package/build/layouts/flex.js +2 -2
- package/build/layouts/flex.js.map +1 -1
- package/build/store/actions.js +10 -14
- package/build/store/actions.js.map +1 -1
- package/build/store/reducer.js +18 -9
- package/build/store/reducer.js.map +1 -1
- package/build/utils/selection.js +34 -0
- package/build/utils/selection.js.map +1 -0
- package/build-module/components/block-pattern-setup/index.js +3 -9
- package/build-module/components/block-pattern-setup/index.js.map +1 -1
- package/build-module/components/block-pattern-setup/setup-toolbar.js +3 -8
- package/build-module/components/block-pattern-setup/setup-toolbar.js.map +1 -1
- package/build-module/components/block-preview/auto.js +20 -5
- package/build-module/components/block-preview/auto.js.map +1 -1
- package/build-module/components/block-settings-menu/block-edit-visually-button.js +56 -0
- package/build-module/components/block-settings-menu/block-edit-visually-button.js.map +1 -0
- package/build-module/components/block-settings-menu/block-settings-dropdown.js +2 -4
- package/build-module/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
- package/build-module/components/block-settings-menu/index.js +6 -3
- package/build-module/components/block-settings-menu/index.js.map +1 -1
- package/build-module/components/block-settings-menu-controls/index.js +5 -2
- package/build-module/components/block-settings-menu-controls/index.js.map +1 -1
- package/build-module/components/block-title/use-block-display-title.js +3 -9
- package/build-module/components/block-title/use-block-display-title.js.map +1 -1
- package/build-module/components/colors-gradients/dropdown.js +2 -1
- package/build-module/components/colors-gradients/dropdown.js.map +1 -1
- package/build-module/components/duotone/components.js +130 -0
- package/build-module/components/duotone/components.js.map +1 -0
- package/build-module/components/duotone/index.js +3 -0
- package/build-module/components/duotone/index.js.map +1 -0
- package/build-module/components/duotone/utils.js +30 -0
- package/build-module/components/duotone/utils.js.map +1 -0
- package/build-module/components/duotone-control/index.js +18 -6
- package/build-module/components/duotone-control/index.js.map +1 -1
- package/build-module/components/index.js +1 -0
- package/build-module/components/index.js.map +1 -1
- package/build-module/components/inserter/index.js +3 -2
- package/build-module/components/inserter/index.js.map +1 -1
- package/build-module/components/media-placeholder/index.js +1 -0
- package/build-module/components/media-placeholder/index.js.map +1 -1
- package/build-module/components/media-placeholder/index.native.js +5 -3
- package/build-module/components/media-placeholder/index.native.js.map +1 -1
- package/build-module/components/media-replace-flow/index.js +3 -6
- package/build-module/components/media-replace-flow/index.js.map +1 -1
- package/build-module/components/publish-date-time-picker/index.js +2 -0
- package/build-module/components/publish-date-time-picker/index.js.map +1 -1
- package/build-module/components/rich-text/use-input-rules.js +3 -11
- package/build-module/components/rich-text/use-input-rules.js.map +1 -1
- package/build-module/components/rich-text/use-paste-handler.js +20 -5
- package/build-module/components/rich-text/use-paste-handler.js.map +1 -1
- package/build-module/elements/index.js +7 -1
- package/build-module/elements/index.js.map +1 -1
- package/build-module/hooks/aria-label.js +59 -0
- package/build-module/hooks/aria-label.js.map +1 -0
- package/build-module/hooks/duotone.js +22 -140
- package/build-module/hooks/duotone.js.map +1 -1
- package/build-module/hooks/index.js +1 -1
- package/build-module/hooks/index.js.map +1 -1
- package/build-module/hooks/layout.js +6 -4
- package/build-module/hooks/layout.js.map +1 -1
- package/build-module/index.js +1 -1
- package/build-module/index.js.map +1 -1
- package/build-module/layouts/flex.js +2 -2
- package/build-module/layouts/flex.js.map +1 -1
- package/build-module/store/actions.js +6 -11
- package/build-module/store/actions.js.map +1 -1
- package/build-module/store/reducer.js +19 -10
- package/build-module/store/reducer.js.map +1 -1
- package/build-module/utils/selection.js +24 -0
- package/build-module/utils/selection.js.map +1 -0
- package/build-style/style-rtl.css +5 -1
- package/build-style/style.css +5 -1
- package/package.json +28 -28
- package/src/components/block-draggable/test/helpers.native.js +3 -3
- package/src/components/block-list/style.scss +1 -1
- package/src/components/block-pattern-setup/index.js +2 -10
- package/src/components/block-pattern-setup/setup-toolbar.js +2 -9
- package/src/components/block-preview/auto.js +17 -3
- package/src/components/block-settings-menu/block-edit-visually-button.js +52 -0
- package/src/components/block-settings-menu/block-settings-dropdown.js +3 -2
- package/src/components/block-settings-menu/index.js +15 -11
- package/src/components/block-settings-menu-controls/index.js +3 -2
- package/src/components/block-title/use-block-display-title.js +9 -7
- package/src/components/colors-gradients/dropdown.js +1 -0
- package/src/components/duotone/components.js +133 -0
- package/src/components/duotone/index.js +7 -0
- package/src/components/duotone/utils.js +25 -0
- package/src/components/duotone-control/index.js +12 -7
- package/src/components/duotone-control/style.scss +5 -0
- package/src/components/index.js +1 -0
- package/src/components/inserter/index.js +3 -5
- package/src/components/link-control/test/fixtures/index.js +3 -4
- package/src/components/link-control/test/index.js +58 -69
- package/src/components/media-placeholder/index.js +1 -0
- package/src/components/media-placeholder/index.native.js +9 -5
- package/src/components/media-replace-flow/index.js +2 -8
- package/src/components/media-upload/README.md +8 -0
- package/src/components/publish-date-time-picker/index.js +2 -0
- package/src/components/responsive-block-control/README.md +3 -1
- package/src/components/responsive-block-control/test/index.js +1 -2
- package/src/components/rich-text/use-input-rules.js +6 -15
- package/src/components/rich-text/use-paste-handler.js +17 -5
- package/src/elements/index.js +8 -1
- package/src/elements/test/index.js +18 -0
- package/src/hooks/aria-label.js +67 -0
- package/src/hooks/duotone.js +18 -139
- package/src/hooks/index.js +1 -1
- package/src/hooks/layout.js +20 -9
- package/src/index.js +0 -1
- package/src/layouts/flex.js +2 -2
- package/src/store/actions.js +8 -21
- package/src/store/reducer.js +21 -9
- package/src/store/test/reducer.js +138 -10
- package/src/store/test/selectors.js +3 -6
- package/src/utils/selection.js +26 -0
- package/src/utils/test/selection.js +39 -0
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
import { render, unmountComponentAtNode } from 'react-dom';
|
|
5
5
|
import { act, Simulate } from 'react-dom/test-utils';
|
|
6
6
|
import { queryByText, queryByRole } from '@testing-library/react';
|
|
7
|
-
import { default as lodash, first, last, nth, uniqueId } from 'lodash';
|
|
8
7
|
/**
|
|
9
8
|
* WordPress dependencies
|
|
10
9
|
*/
|
|
@@ -18,13 +17,20 @@ import { useSelect } from '@wordpress/data';
|
|
|
18
17
|
* Internal dependencies
|
|
19
18
|
*/
|
|
20
19
|
import LinkControl from '../';
|
|
21
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
fauxEntitySuggestions,
|
|
22
|
+
fetchFauxEntitySuggestions,
|
|
23
|
+
uniqueId,
|
|
24
|
+
} from './fixtures';
|
|
22
25
|
|
|
23
26
|
// Mock debounce() so that it runs instantly.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
jest.mock( 'lodash', () => ( {
|
|
28
|
+
...jest.requireActual( 'lodash' ),
|
|
29
|
+
debounce: ( fn ) => {
|
|
30
|
+
fn.cancel = jest.fn();
|
|
31
|
+
return fn;
|
|
32
|
+
},
|
|
33
|
+
} ) );
|
|
28
34
|
|
|
29
35
|
const mockFetchSearchSuggestions = jest.fn();
|
|
30
36
|
|
|
@@ -357,7 +363,7 @@ describe( 'Searching for a link', () => {
|
|
|
357
363
|
|
|
358
364
|
it( 'should display only search suggestions when current input value is not URL-like', async () => {
|
|
359
365
|
const searchTerm = 'Hello world';
|
|
360
|
-
const firstFauxSuggestion =
|
|
366
|
+
const firstFauxSuggestion = fauxEntitySuggestions[ 0 ];
|
|
361
367
|
|
|
362
368
|
act( () => {
|
|
363
369
|
render( <LinkControl />, container );
|
|
@@ -377,9 +383,9 @@ describe( 'Searching for a link', () => {
|
|
|
377
383
|
|
|
378
384
|
const searchResultElements = getSearchResults();
|
|
379
385
|
|
|
380
|
-
const firstSearchResultItemHTML =
|
|
381
|
-
|
|
382
|
-
|
|
386
|
+
const firstSearchResultItemHTML = searchResultElements[ 0 ].innerHTML;
|
|
387
|
+
const lastSearchResultItemHTML =
|
|
388
|
+
searchResultElements[ searchResultElements.length - 1 ].innerHTML;
|
|
383
389
|
|
|
384
390
|
expect( searchResultElements ).toHaveLength(
|
|
385
391
|
fauxEntitySuggestions.length
|
|
@@ -502,7 +508,8 @@ describe( 'Searching for a link', () => {
|
|
|
502
508
|
const searchResultElements = getSearchResults();
|
|
503
509
|
|
|
504
510
|
const lastSearchResultItemHTML =
|
|
505
|
-
|
|
511
|
+
searchResultElements[ searchResultElements.length - 1 ]
|
|
512
|
+
.innerHTML;
|
|
506
513
|
const additionalDefaultFallbackURLSuggestionLength = 1;
|
|
507
514
|
|
|
508
515
|
// We should see a search result for each of the expect search suggestions
|
|
@@ -974,11 +981,9 @@ describe( 'Creating Entities (eg: Posts, Pages)', () => {
|
|
|
974
981
|
'[role="listbox"] [role="option"]'
|
|
975
982
|
);
|
|
976
983
|
|
|
977
|
-
const createButton =
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
)
|
|
981
|
-
);
|
|
984
|
+
const createButton = Array.from( searchResultElements ).filter(
|
|
985
|
+
( result ) => result.innerHTML.includes( 'Create:' )
|
|
986
|
+
)[ 0 ];
|
|
982
987
|
|
|
983
988
|
expect( createButton ).not.toBeNull();
|
|
984
989
|
expect( createButton.innerHTML ).toEqual(
|
|
@@ -1071,11 +1076,9 @@ describe( 'Creating Entities (eg: Posts, Pages)', () => {
|
|
|
1071
1076
|
'[role="listbox"] [role="option"]'
|
|
1072
1077
|
);
|
|
1073
1078
|
|
|
1074
|
-
const createButton =
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
)
|
|
1078
|
-
);
|
|
1079
|
+
const createButton = Array.from( searchResultElements ).filter(
|
|
1080
|
+
( result ) => result.innerHTML.includes( 'Create:' )
|
|
1081
|
+
)[ 0 ];
|
|
1079
1082
|
|
|
1080
1083
|
await act( async () => {
|
|
1081
1084
|
Simulate.click( createButton );
|
|
@@ -1143,11 +1146,9 @@ describe( 'Creating Entities (eg: Posts, Pages)', () => {
|
|
|
1143
1146
|
const searchResultElements = container.querySelectorAll(
|
|
1144
1147
|
'[role="listbox"] [role="option"]'
|
|
1145
1148
|
);
|
|
1146
|
-
const createButton =
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
)
|
|
1150
|
-
);
|
|
1149
|
+
const createButton = Array.from( searchResultElements ).filter(
|
|
1150
|
+
( result ) => result.innerHTML.includes( 'Create:' )
|
|
1151
|
+
)[ 0 ];
|
|
1151
1152
|
|
|
1152
1153
|
// Step down into the search results, highlighting the first result item.
|
|
1153
1154
|
act( () => {
|
|
@@ -1210,11 +1211,9 @@ describe( 'Creating Entities (eg: Posts, Pages)', () => {
|
|
|
1210
1211
|
'[role="listbox"] [role="option"]'
|
|
1211
1212
|
);
|
|
1212
1213
|
|
|
1213
|
-
const createButton =
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
)
|
|
1217
|
-
);
|
|
1214
|
+
const createButton = Array.from( searchResultElements ).filter(
|
|
1215
|
+
( result ) => result.innerHTML.includes( 'Custom suggestion text' )
|
|
1216
|
+
)[ 0 ];
|
|
1218
1217
|
|
|
1219
1218
|
expect( createButton ).not.toBeNull();
|
|
1220
1219
|
} );
|
|
@@ -1241,11 +1240,9 @@ describe( 'Creating Entities (eg: Posts, Pages)', () => {
|
|
|
1241
1240
|
const searchResultElements = container.querySelectorAll(
|
|
1242
1241
|
'[role="listbox"] [role="option"]'
|
|
1243
1242
|
);
|
|
1244
|
-
const createButton =
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
)
|
|
1248
|
-
);
|
|
1243
|
+
const createButton = Array.from( searchResultElements ).filter(
|
|
1244
|
+
( result ) => result.innerHTML.includes( 'Create:' )
|
|
1245
|
+
)[ 0 ];
|
|
1249
1246
|
|
|
1250
1247
|
// Verify input has no value.
|
|
1251
1248
|
expect( searchInput.value ).toBe( '' );
|
|
@@ -1275,11 +1272,9 @@ describe( 'Creating Entities (eg: Posts, Pages)', () => {
|
|
|
1275
1272
|
const searchResultElements = container.querySelectorAll(
|
|
1276
1273
|
'[role="listbox"] [role="option"]'
|
|
1277
1274
|
);
|
|
1278
|
-
const createButton =
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
)
|
|
1282
|
-
);
|
|
1275
|
+
const createButton = Array.from( searchResultElements ).filter(
|
|
1276
|
+
( result ) => result.innerHTML.includes( 'New page' )
|
|
1277
|
+
)[ 0 ];
|
|
1283
1278
|
|
|
1284
1279
|
// Verify input has no value.
|
|
1285
1280
|
expect( searchInput.value ).toBe( '' );
|
|
@@ -1321,11 +1316,9 @@ describe( 'Creating Entities (eg: Posts, Pages)', () => {
|
|
|
1321
1316
|
'[role="listbox"] [role="option"]'
|
|
1322
1317
|
);
|
|
1323
1318
|
|
|
1324
|
-
const createButton =
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
)
|
|
1328
|
-
);
|
|
1319
|
+
const createButton = Array.from( searchResultElements ).filter(
|
|
1320
|
+
( result ) => result.innerHTML.includes( 'New page' )
|
|
1321
|
+
)[ 0 ];
|
|
1329
1322
|
|
|
1330
1323
|
expect( createButton ).toBeFalsy(); // Shouldn't exist!
|
|
1331
1324
|
}
|
|
@@ -1366,11 +1359,9 @@ describe( 'Creating Entities (eg: Posts, Pages)', () => {
|
|
|
1366
1359
|
let searchResultElements = container.querySelectorAll(
|
|
1367
1360
|
'[role="listbox"] [role="option"]'
|
|
1368
1361
|
);
|
|
1369
|
-
let createButton =
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
)
|
|
1373
|
-
);
|
|
1362
|
+
let createButton = Array.from( searchResultElements ).filter(
|
|
1363
|
+
( result ) => result.innerHTML.includes( 'Create:' )
|
|
1364
|
+
)[ 0 ];
|
|
1374
1365
|
|
|
1375
1366
|
await act( async () => {
|
|
1376
1367
|
Simulate.click( createButton );
|
|
@@ -1407,18 +1398,16 @@ describe( 'Creating Entities (eg: Posts, Pages)', () => {
|
|
|
1407
1398
|
searchResultElements = container.querySelectorAll(
|
|
1408
1399
|
'[role="listbox"] [role="option"]'
|
|
1409
1400
|
);
|
|
1410
|
-
createButton =
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
)
|
|
1414
|
-
);
|
|
1401
|
+
createButton = Array.from( searchResultElements ).filter(
|
|
1402
|
+
( result ) => result.innerHTML.includes( 'New page' )
|
|
1403
|
+
)[ 0 ];
|
|
1415
1404
|
} );
|
|
1416
1405
|
} );
|
|
1417
1406
|
} );
|
|
1418
1407
|
|
|
1419
1408
|
describe( 'Selecting links', () => {
|
|
1420
1409
|
it( 'should display a selected link corresponding to the provided "currentLink" prop', () => {
|
|
1421
|
-
const selectedLink =
|
|
1410
|
+
const selectedLink = fauxEntitySuggestions[ 0 ];
|
|
1422
1411
|
|
|
1423
1412
|
const LinkControlConsumer = () => {
|
|
1424
1413
|
const [ link ] = useState( selectedLink );
|
|
@@ -1447,7 +1436,7 @@ describe( 'Selecting links', () => {
|
|
|
1447
1436
|
} );
|
|
1448
1437
|
|
|
1449
1438
|
it( 'should hide "selected" link UI and display search UI prepopulated with previously selected link title when "Change" button is clicked', () => {
|
|
1450
|
-
const selectedLink =
|
|
1439
|
+
const selectedLink = fauxEntitySuggestions[ 0 ];
|
|
1451
1440
|
|
|
1452
1441
|
const LinkControlConsumer = () => {
|
|
1453
1442
|
const [ link, setLink ] = useState( selectedLink );
|
|
@@ -1484,7 +1473,7 @@ describe( 'Selecting links', () => {
|
|
|
1484
1473
|
|
|
1485
1474
|
describe( 'Selection using mouse click', () => {
|
|
1486
1475
|
it.each( [
|
|
1487
|
-
[ 'entity', 'hello world',
|
|
1476
|
+
[ 'entity', 'hello world', fauxEntitySuggestions[ 0 ] ], // Entity search.
|
|
1488
1477
|
[
|
|
1489
1478
|
'url',
|
|
1490
1479
|
'https://www.wordpress.org',
|
|
@@ -1528,7 +1517,7 @@ describe( 'Selecting links', () => {
|
|
|
1528
1517
|
|
|
1529
1518
|
const searchResultElements = getSearchResults();
|
|
1530
1519
|
|
|
1531
|
-
const firstSearchSuggestion =
|
|
1520
|
+
const firstSearchSuggestion = searchResultElements[ 0 ];
|
|
1532
1521
|
|
|
1533
1522
|
// Simulate selecting the first of the search suggestions.
|
|
1534
1523
|
act( () => {
|
|
@@ -1557,7 +1546,7 @@ describe( 'Selecting links', () => {
|
|
|
1557
1546
|
|
|
1558
1547
|
describe( 'Selection using keyboard', () => {
|
|
1559
1548
|
it.each( [
|
|
1560
|
-
[ 'entity', 'hello world',
|
|
1549
|
+
[ 'entity', 'hello world', fauxEntitySuggestions[ 0 ] ], // Entity search.
|
|
1561
1550
|
[
|
|
1562
1551
|
'url',
|
|
1563
1552
|
'https://www.wordpress.org',
|
|
@@ -1607,8 +1596,8 @@ describe( 'Selecting links', () => {
|
|
|
1607
1596
|
|
|
1608
1597
|
const searchResultElements = getSearchResults();
|
|
1609
1598
|
|
|
1610
|
-
const firstSearchSuggestion =
|
|
1611
|
-
const secondSearchSuggestion =
|
|
1599
|
+
const firstSearchSuggestion = searchResultElements[ 0 ];
|
|
1600
|
+
const secondSearchSuggestion = searchResultElements[ 1 ];
|
|
1612
1601
|
|
|
1613
1602
|
let selectedSearchResultElement = container.querySelector(
|
|
1614
1603
|
'[role="option"][aria-selected="true"]'
|
|
@@ -1711,8 +1700,8 @@ describe( 'Selecting links', () => {
|
|
|
1711
1700
|
|
|
1712
1701
|
const searchResultElements = getSearchResults();
|
|
1713
1702
|
|
|
1714
|
-
const firstSearchSuggestion =
|
|
1715
|
-
const secondSearchSuggestion =
|
|
1703
|
+
const firstSearchSuggestion = searchResultElements[ 0 ];
|
|
1704
|
+
const secondSearchSuggestion = searchResultElements[ 1 ];
|
|
1716
1705
|
|
|
1717
1706
|
let selectedSearchResultElement = container.querySelector(
|
|
1718
1707
|
'[role="option"][aria-selected="true"]'
|
|
@@ -1758,7 +1747,7 @@ describe( 'Selecting links', () => {
|
|
|
1758
1747
|
|
|
1759
1748
|
describe( 'Addition Settings UI', () => {
|
|
1760
1749
|
it( 'should display "New Tab" setting (in "off" mode) by default when a link is selected', async () => {
|
|
1761
|
-
const selectedLink =
|
|
1750
|
+
const selectedLink = fauxEntitySuggestions[ 0 ];
|
|
1762
1751
|
const expectedSettingText = 'Open in new tab';
|
|
1763
1752
|
|
|
1764
1753
|
const LinkControlConsumer = () => {
|
|
@@ -1791,7 +1780,7 @@ describe( 'Addition Settings UI', () => {
|
|
|
1791
1780
|
} );
|
|
1792
1781
|
|
|
1793
1782
|
it( 'should display a setting control with correct default state for each of the custom settings provided', async () => {
|
|
1794
|
-
const selectedLink =
|
|
1783
|
+
const selectedLink = fauxEntitySuggestions[ 0 ];
|
|
1795
1784
|
|
|
1796
1785
|
const customSettings = [
|
|
1797
1786
|
{
|
|
@@ -2266,7 +2255,7 @@ describe( 'Rich link previews', () => {
|
|
|
2266
2255
|
} );
|
|
2267
2256
|
|
|
2268
2257
|
describe( 'Controlling link title text', () => {
|
|
2269
|
-
const selectedLink =
|
|
2258
|
+
const selectedLink = fauxEntitySuggestions[ 0 ];
|
|
2270
2259
|
|
|
2271
2260
|
it( 'should not show a means to alter the link title text by default', async () => {
|
|
2272
2261
|
act( () => {
|
|
@@ -2285,7 +2274,7 @@ describe( 'Controlling link title text', () => {
|
|
|
2285
2274
|
'should not show the link title text input when the URL is `%s`',
|
|
2286
2275
|
async ( urlValue ) => {
|
|
2287
2276
|
const selectedLinkWithoutURL = {
|
|
2288
|
-
...
|
|
2277
|
+
...fauxEntitySuggestions[ 0 ],
|
|
2289
2278
|
url: urlValue,
|
|
2290
2279
|
};
|
|
2291
2280
|
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
4
|
import { View, Text, TouchableWithoutFeedback } from 'react-native';
|
|
5
|
-
import { uniqWith } from 'lodash';
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* WordPress dependencies
|
|
@@ -23,12 +22,17 @@ import { Icon, plusCircleFilled } from '@wordpress/icons';
|
|
|
23
22
|
*/
|
|
24
23
|
import styles from './styles.scss';
|
|
25
24
|
|
|
25
|
+
const isMediaEqual = ( media1, media2 ) =>
|
|
26
|
+
media1.id === media2.id || media1.url === media2.url;
|
|
27
|
+
|
|
26
28
|
// Remove duplicates after gallery append.
|
|
27
29
|
const dedupMedia = ( media ) =>
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
media.reduce(
|
|
31
|
+
( dedupedMedia, mediaItem ) =>
|
|
32
|
+
dedupedMedia.some( ( item ) => isMediaEqual( item, mediaItem ) )
|
|
33
|
+
? dedupedMedia
|
|
34
|
+
: [ ...dedupedMedia, mediaItem ],
|
|
35
|
+
[]
|
|
32
36
|
);
|
|
33
37
|
|
|
34
38
|
function MediaPlaceholder( props ) {
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* External dependencies
|
|
3
|
-
*/
|
|
4
|
-
import { uniqueId } from 'lodash';
|
|
5
|
-
|
|
6
1
|
/**
|
|
7
2
|
* WordPress dependencies
|
|
8
3
|
*/
|
|
@@ -38,6 +33,7 @@ import LinkControl from '../link-control';
|
|
|
38
33
|
import { store as blockEditorStore } from '../../store';
|
|
39
34
|
|
|
40
35
|
const noop = () => {};
|
|
36
|
+
let uniqueId = 0;
|
|
41
37
|
|
|
42
38
|
const MediaReplaceFlow = ( {
|
|
43
39
|
mediaURL,
|
|
@@ -64,9 +60,7 @@ const MediaReplaceFlow = ( {
|
|
|
64
60
|
return select( blockEditorStore ).getSettings().mediaUpload;
|
|
65
61
|
}, [] );
|
|
66
62
|
const editMediaButtonRef = useRef();
|
|
67
|
-
const errorNoticeID = uniqueId
|
|
68
|
-
'block-editor/media-replace-flow/error-notice/'
|
|
69
|
-
);
|
|
63
|
+
const errorNoticeID = `block-editor/media-replace-flow/error-notice/${ ++uniqueId }`;
|
|
70
64
|
|
|
71
65
|
const onUploadError = ( message ) => {
|
|
72
66
|
const safeMessage = stripHTML( message );
|
|
@@ -64,6 +64,14 @@ If allowedTypes is unset all mime types should be allowed.
|
|
|
64
64
|
- Required: No
|
|
65
65
|
- Platform: Web | Mobile
|
|
66
66
|
|
|
67
|
+
### mode
|
|
68
|
+
|
|
69
|
+
Value of Frame content default mode like 'browse', 'upload' etc.
|
|
70
|
+
|
|
71
|
+
- Type: `String`
|
|
72
|
+
- Required: No
|
|
73
|
+
- Default: false
|
|
74
|
+
- Platform: Web
|
|
67
75
|
### multiple
|
|
68
76
|
|
|
69
77
|
Whether to allow multiple selections or not.
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { DateTimePicker } from '@wordpress/components';
|
|
5
5
|
import { __ } from '@wordpress/i18n';
|
|
6
6
|
import { forwardRef } from '@wordpress/element';
|
|
7
|
+
import { __experimentalGetSettings as getSettings } from '@wordpress/date';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Internal dependencies
|
|
@@ -27,6 +28,7 @@ function PublishDateTimePicker(
|
|
|
27
28
|
onClose={ onClose }
|
|
28
29
|
/>
|
|
29
30
|
<DateTimePicker
|
|
31
|
+
startOfWeek={ getSettings().l10n.startOfWeek }
|
|
30
32
|
__nextRemoveHelpButton
|
|
31
33
|
__nextRemoveResetButton
|
|
32
34
|
onChange={ onChange }
|
|
@@ -171,8 +171,10 @@ const renderDefaultControl = ( labelComponent, viewport ) => {
|
|
|
171
171
|
An optional render function (prop) used to render the controls for the _responsive_ settings. If not provided, by default, responsive controls will be _automatically_ rendered using the component returned by the `renderDefaultControl` prop. For _complete_ control over the output of the responsive controls, you may return a component here and it will be rendered when the control group is in "responsive" mode.
|
|
172
172
|
|
|
173
173
|
```jsx
|
|
174
|
+
let uniqueId = 0;
|
|
175
|
+
|
|
174
176
|
const renderResponsiveControls = ( viewports ) => {
|
|
175
|
-
const inputId = uniqueId
|
|
177
|
+
const inputId = ++uniqueId;
|
|
176
178
|
|
|
177
179
|
return viewports.map( ( { id, label } ) => {
|
|
178
180
|
return (
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { render, unmountComponentAtNode } from 'react-dom';
|
|
5
5
|
import { act, Simulate } from 'react-dom/test-utils';
|
|
6
|
-
import { uniqueId } from 'lodash';
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
8
|
* WordPress dependencies
|
|
@@ -31,7 +30,7 @@ afterEach( () => {
|
|
|
31
30
|
container = null;
|
|
32
31
|
} );
|
|
33
32
|
|
|
34
|
-
const inputId =
|
|
33
|
+
const inputId = 'input-12345678';
|
|
35
34
|
|
|
36
35
|
const sizeOptions = [
|
|
37
36
|
{
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* External dependencies
|
|
3
|
-
*/
|
|
4
|
-
import { findKey } from 'lodash';
|
|
5
|
-
|
|
6
1
|
/**
|
|
7
2
|
* WordPress dependencies
|
|
8
3
|
*/
|
|
@@ -17,21 +12,17 @@ import { useDispatch } from '@wordpress/data';
|
|
|
17
12
|
*/
|
|
18
13
|
import { store as blockEditorStore } from '../../store';
|
|
19
14
|
import { preventEventDiscovery } from './prevent-event-discovery';
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const START_OF_SELECTED_AREA = '\u0086';
|
|
15
|
+
import {
|
|
16
|
+
retrieveSelectedAttribute,
|
|
17
|
+
START_OF_SELECTED_AREA,
|
|
18
|
+
} from '../../utils/selection';
|
|
25
19
|
|
|
26
20
|
function findSelection( blocks ) {
|
|
27
21
|
let i = blocks.length;
|
|
28
22
|
|
|
29
23
|
while ( i-- ) {
|
|
30
|
-
const attributeKey =
|
|
31
|
-
blocks[ i ].attributes
|
|
32
|
-
( v ) =>
|
|
33
|
-
typeof v === 'string' &&
|
|
34
|
-
v.indexOf( START_OF_SELECTED_AREA ) !== -1
|
|
24
|
+
const attributeKey = retrieveSelectedAttribute(
|
|
25
|
+
blocks[ i ].attributes
|
|
35
26
|
);
|
|
36
27
|
|
|
37
28
|
if ( attributeKey ) {
|
|
@@ -254,17 +254,29 @@ export function usePasteHandler( props ) {
|
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
/**
|
|
257
|
-
* Normalizes a given string of HTML to remove the Windows
|
|
258
|
-
* and any preceeding and trailing
|
|
257
|
+
* Normalizes a given string of HTML to remove the Windows-specific "Fragment"
|
|
258
|
+
* comments and any preceeding and trailing content.
|
|
259
259
|
*
|
|
260
260
|
* @param {string} html the html to be normalized
|
|
261
261
|
* @return {string} the normalized html
|
|
262
262
|
*/
|
|
263
263
|
function removeWindowsFragments( html ) {
|
|
264
|
-
const
|
|
265
|
-
const
|
|
264
|
+
const startStr = '<!--StartFragment-->';
|
|
265
|
+
const startIdx = html.indexOf( startStr );
|
|
266
|
+
if ( startIdx > -1 ) {
|
|
267
|
+
html = html.substring( startIdx + startStr.length );
|
|
268
|
+
} else {
|
|
269
|
+
// No point looking for EndFragment
|
|
270
|
+
return html;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const endStr = '<!--EndFragment-->';
|
|
274
|
+
const endIdx = html.indexOf( endStr );
|
|
275
|
+
if ( endIdx > -1 ) {
|
|
276
|
+
html = html.substring( 0, endIdx );
|
|
277
|
+
}
|
|
266
278
|
|
|
267
|
-
return html
|
|
279
|
+
return html;
|
|
268
280
|
}
|
|
269
281
|
|
|
270
282
|
/**
|
package/src/elements/index.js
CHANGED
|
@@ -1 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
const ELEMENT_CLASS_NAMES = {
|
|
2
|
+
button: 'wp-element-button',
|
|
3
|
+
caption: 'wp-element-caption',
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
export const __experimentalGetElementClassName = ( element ) => {
|
|
7
|
+
return ELEMENT_CLASS_NAMES[ element ] ? ELEMENT_CLASS_NAMES[ element ] : '';
|
|
8
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { __experimentalGetElementClassName } from '@wordpress/block-editor';
|
|
5
|
+
|
|
6
|
+
describe( 'element class names', () => {
|
|
7
|
+
it( 'should return the correct class name for button', () => {
|
|
8
|
+
expect( __experimentalGetElementClassName( 'button' ) ).toEqual(
|
|
9
|
+
'wp-element-button'
|
|
10
|
+
);
|
|
11
|
+
} );
|
|
12
|
+
|
|
13
|
+
it( 'should return an empty string for an unknown element', () => {
|
|
14
|
+
expect(
|
|
15
|
+
__experimentalGetElementClassName( 'unknown-element' )
|
|
16
|
+
).toEqual( '' );
|
|
17
|
+
} );
|
|
18
|
+
} );
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { addFilter } from '@wordpress/hooks';
|
|
5
|
+
import { hasBlockSupport } from '@wordpress/blocks';
|
|
6
|
+
|
|
7
|
+
const ARIA_LABEL_SCHEMA = {
|
|
8
|
+
type: 'string',
|
|
9
|
+
source: 'attribute',
|
|
10
|
+
attribute: 'aria-label',
|
|
11
|
+
selector: '*',
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Filters registered block settings, extending attributes with ariaLabel using aria-label
|
|
16
|
+
* of the first node.
|
|
17
|
+
*
|
|
18
|
+
* @param {Object} settings Original block settings.
|
|
19
|
+
*
|
|
20
|
+
* @return {Object} Filtered block settings.
|
|
21
|
+
*/
|
|
22
|
+
export function addAttribute( settings ) {
|
|
23
|
+
// Allow blocks to specify their own attribute definition with default values if needed.
|
|
24
|
+
if ( settings?.attributes?.ariaLabel?.type ) {
|
|
25
|
+
return settings;
|
|
26
|
+
}
|
|
27
|
+
if ( hasBlockSupport( settings, 'ariaLabel' ) ) {
|
|
28
|
+
// Gracefully handle if settings.attributes is undefined.
|
|
29
|
+
settings.attributes = {
|
|
30
|
+
...settings.attributes,
|
|
31
|
+
ariaLabel: ARIA_LABEL_SCHEMA,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return settings;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Override props assigned to save component to inject aria-label, if block
|
|
40
|
+
* supports ariaLabel. This is only applied if the block's save result is an
|
|
41
|
+
* element and not a markup string.
|
|
42
|
+
*
|
|
43
|
+
* @param {Object} extraProps Additional props applied to save element.
|
|
44
|
+
* @param {Object} blockType Block type.
|
|
45
|
+
* @param {Object} attributes Current block attributes.
|
|
46
|
+
*
|
|
47
|
+
* @return {Object} Filtered props applied to save element.
|
|
48
|
+
*/
|
|
49
|
+
export function addSaveProps( extraProps, blockType, attributes ) {
|
|
50
|
+
if ( hasBlockSupport( blockType, 'ariaLabel' ) ) {
|
|
51
|
+
extraProps[ 'aria-label' ] =
|
|
52
|
+
attributes.ariaLabel === '' ? null : attributes.ariaLabel;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return extraProps;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
addFilter(
|
|
59
|
+
'blocks.registerBlockType',
|
|
60
|
+
'core/ariaLabel/attribute',
|
|
61
|
+
addAttribute
|
|
62
|
+
);
|
|
63
|
+
addFilter(
|
|
64
|
+
'blocks.getSaveContent.extraProps',
|
|
65
|
+
'core/ariaLabel/save-props',
|
|
66
|
+
addSaveProps
|
|
67
|
+
);
|