@wordpress/block-library 9.40.2-next.v.202602241322.0 → 9.40.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/comment-reply-link/edit.cjs +2 -1
- package/build/comment-reply-link/edit.cjs.map +2 -2
- package/build/comments/edit/placeholder.cjs +2 -1
- package/build/comments/edit/placeholder.cjs.map +2 -2
- package/build/cover/edit/index.cjs +39 -26
- package/build/cover/edit/index.cjs.map +2 -2
- package/build/cover/embed-video-utils.cjs +8 -6
- package/build/cover/embed-video-utils.cjs.map +2 -2
- package/build/embed/embed-preview.cjs +2 -1
- package/build/embed/embed-preview.cjs.map +2 -2
- package/build/html/block.json +2 -1
- package/build/html/modal.cjs +147 -230
- package/build/html/modal.cjs.map +3 -3
- package/build/icon/block.json +3 -12
- package/build/image/image.cjs +1 -1
- package/build/image/image.cjs.map +2 -2
- package/build/latest-comments/deprecated.cjs +33 -0
- package/build/latest-comments/deprecated.cjs.map +2 -2
- package/build/navigation/edit/index.cjs +123 -119
- package/build/navigation/edit/index.cjs.map +3 -3
- package/build/navigation/edit/navigation-menu-selector.cjs +2 -1
- package/build/navigation/edit/navigation-menu-selector.cjs.map +2 -2
- package/build/navigation/view.cjs +9 -2
- package/build/navigation/view.cjs.map +2 -2
- package/build/navigation-link/edit.cjs +2 -1
- package/build/navigation-link/edit.cjs.map +2 -2
- package/build/navigation-link/shared/controls.cjs +29 -52
- package/build/navigation-link/shared/controls.cjs.map +3 -3
- package/build/navigation-link/shared/use-handle-link-change.cjs +19 -3
- package/build/navigation-link/shared/use-handle-link-change.cjs.map +3 -3
- package/build/navigation-link/shared/use-link-preview.cjs +8 -9
- package/build/navigation-link/shared/use-link-preview.cjs.map +2 -2
- package/build/navigation-submenu/edit.cjs +8 -22
- package/build/navigation-submenu/edit.cjs.map +2 -2
- package/build/nextpage/block.json +0 -1
- package/build/page-list-item/edit.cjs +6 -3
- package/build/page-list-item/edit.cjs.map +2 -2
- package/build/paragraph/edit.cjs +1 -1
- package/build/paragraph/edit.cjs.map +1 -1
- package/build/post-navigation-link/block.json +3 -1
- package/build/post-navigation-link/edit.cjs +36 -2
- package/build/post-navigation-link/edit.cjs.map +3 -3
- package/build/post-navigation-link/index.cjs +0 -2
- package/build/post-navigation-link/index.cjs.map +3 -3
- package/build/post-title/block.json +3 -1
- package/build/post-title/deprecated.cjs +1 -82
- package/build/post-title/deprecated.cjs.map +3 -3
- package/build/post-title/edit.cjs +36 -10
- package/build/post-title/edit.cjs.map +3 -3
- package/build/query-title/block.json +3 -1
- package/build/query-title/deprecated.cjs +1 -70
- package/build/query-title/deprecated.cjs.map +3 -3
- package/build/query-title/edit.cjs +35 -17
- package/build/query-title/edit.cjs.map +3 -3
- package/build/shortcode/block.json +2 -1
- package/build/site-tagline/block.json +4 -6
- package/build/site-tagline/deprecated.cjs +1 -66
- package/build/site-tagline/deprecated.cjs.map +3 -3
- package/build/site-tagline/edit.cjs +28 -14
- package/build/site-tagline/edit.cjs.map +3 -3
- package/build/site-title/block.json +3 -1
- package/build/site-title/deprecated.cjs +1 -79
- package/build/site-title/deprecated.cjs.map +3 -3
- package/build/site-title/edit.cjs +30 -14
- package/build/site-title/edit.cjs.map +3 -3
- package/build/tabs-menu-item/block.json +26 -1
- package/build/tabs-menu-item/controls.cjs +100 -2
- package/build/tabs-menu-item/controls.cjs.map +3 -3
- package/build/tabs-menu-item/edit.cjs +65 -6
- package/build/tabs-menu-item/edit.cjs.map +2 -2
- package/build/tabs-menu-item/save.cjs +15 -1
- package/build/tabs-menu-item/save.cjs.map +2 -2
- package/build-module/comment-reply-link/edit.mjs +3 -2
- package/build-module/comment-reply-link/edit.mjs.map +2 -2
- package/build-module/comments/edit/placeholder.mjs +3 -2
- package/build-module/comments/edit/placeholder.mjs.map +2 -2
- package/build-module/cover/edit/index.mjs +47 -29
- package/build-module/cover/edit/index.mjs.map +2 -2
- package/build-module/cover/embed-video-utils.mjs +7 -5
- package/build-module/cover/embed-video-utils.mjs.map +2 -2
- package/build-module/embed/embed-preview.mjs +2 -1
- package/build-module/embed/embed-preview.mjs.map +2 -2
- package/build-module/html/block.json +2 -1
- package/build-module/html/modal.mjs +149 -232
- package/build-module/html/modal.mjs.map +2 -2
- package/build-module/icon/block.json +3 -12
- package/build-module/image/image.mjs +1 -1
- package/build-module/image/image.mjs.map +2 -2
- package/build-module/latest-comments/deprecated.mjs +33 -0
- package/build-module/latest-comments/deprecated.mjs.map +2 -2
- package/build-module/navigation/edit/index.mjs +123 -119
- package/build-module/navigation/edit/index.mjs.map +2 -2
- package/build-module/navigation/edit/navigation-menu-selector.mjs +2 -1
- package/build-module/navigation/edit/navigation-menu-selector.mjs.map +2 -2
- package/build-module/navigation/view.mjs +9 -2
- package/build-module/navigation/view.mjs.map +2 -2
- package/build-module/navigation-link/edit.mjs +2 -1
- package/build-module/navigation-link/edit.mjs.map +2 -2
- package/build-module/navigation-link/shared/controls.mjs +29 -53
- package/build-module/navigation-link/shared/controls.mjs.map +2 -2
- package/build-module/navigation-link/shared/use-handle-link-change.mjs +19 -3
- package/build-module/navigation-link/shared/use-handle-link-change.mjs.map +2 -2
- package/build-module/navigation-link/shared/use-link-preview.mjs +8 -9
- package/build-module/navigation-link/shared/use-link-preview.mjs.map +2 -2
- package/build-module/navigation-submenu/edit.mjs +9 -23
- package/build-module/navigation-submenu/edit.mjs.map +2 -2
- package/build-module/nextpage/block.json +0 -1
- package/build-module/page-list-item/edit.mjs +6 -3
- package/build-module/page-list-item/edit.mjs.map +2 -2
- package/build-module/paragraph/edit.mjs +2 -2
- package/build-module/paragraph/edit.mjs.map +1 -1
- package/build-module/post-navigation-link/block.json +3 -1
- package/build-module/post-navigation-link/edit.mjs +30 -3
- package/build-module/post-navigation-link/edit.mjs.map +2 -2
- package/build-module/post-navigation-link/index.mjs +0 -2
- package/build-module/post-navigation-link/index.mjs.map +2 -2
- package/build-module/post-title/block.json +3 -1
- package/build-module/post-title/deprecated.mjs +1 -82
- package/build-module/post-title/deprecated.mjs.map +2 -2
- package/build-module/post-title/edit.mjs +27 -10
- package/build-module/post-title/edit.mjs.map +2 -2
- package/build-module/query-title/block.json +3 -1
- package/build-module/query-title/deprecated.mjs +1 -70
- package/build-module/query-title/deprecated.mjs.map +2 -2
- package/build-module/query-title/edit.mjs +36 -17
- package/build-module/query-title/edit.mjs.map +2 -2
- package/build-module/shortcode/block.json +2 -1
- package/build-module/site-tagline/block.json +4 -6
- package/build-module/site-tagline/deprecated.mjs +1 -66
- package/build-module/site-tagline/deprecated.mjs.map +2 -2
- package/build-module/site-tagline/edit.mjs +29 -14
- package/build-module/site-tagline/edit.mjs.map +2 -2
- package/build-module/site-title/block.json +3 -1
- package/build-module/site-title/deprecated.mjs +1 -79
- package/build-module/site-title/deprecated.mjs.map +2 -2
- package/build-module/site-title/edit.mjs +31 -14
- package/build-module/site-title/edit.mjs.map +2 -2
- package/build-module/tabs-menu-item/block.json +26 -1
- package/build-module/tabs-menu-item/controls.mjs +104 -3
- package/build-module/tabs-menu-item/controls.mjs.map +2 -2
- package/build-module/tabs-menu-item/edit.mjs +66 -6
- package/build-module/tabs-menu-item/edit.mjs.map +2 -2
- package/build-module/tabs-menu-item/save.mjs +15 -1
- package/build-module/tabs-menu-item/save.mjs.map +2 -2
- package/build-style/editor-rtl.css +30 -6
- package/build-style/editor.css +30 -6
- package/build-style/html/editor-rtl.css +10 -6
- package/build-style/html/editor.css +10 -6
- package/build-style/icon/editor-rtl.css +5 -0
- package/build-style/icon/editor.css +5 -0
- package/build-style/navigation/style-rtl.css +15 -1
- package/build-style/navigation/style.css +15 -1
- package/build-style/navigation-link/editor-rtl.css +10 -0
- package/build-style/navigation-link/editor.css +10 -0
- package/build-style/navigation-overlay-close/style-rtl.css +3 -3
- package/build-style/navigation-overlay-close/style.css +3 -3
- package/build-style/style-rtl.css +30 -7
- package/build-style/style.css +30 -7
- package/build-style/tabs-menu-item/editor-rtl.css +5 -0
- package/build-style/tabs-menu-item/editor.css +5 -0
- package/build-style/tabs-menu-item/style-rtl.css +12 -3
- package/build-style/tabs-menu-item/style.css +12 -3
- package/package.json +38 -38
- package/src/accordion-item/index.php +17 -5
- package/src/comment-reply-link/edit.js +5 -2
- package/src/comments/edit/placeholder.js +5 -2
- package/src/cover/edit/index.js +72 -35
- package/src/cover/embed-video-utils.js +9 -7
- package/src/cover/index.php +8 -0
- package/src/details/index.php +47 -0
- package/src/embed/embed-preview.js +6 -5
- package/src/html/block.json +2 -1
- package/src/html/editor.scss +15 -5
- package/src/html/modal.js +32 -99
- package/src/icon/block.json +3 -12
- package/src/icon/editor.scss +5 -0
- package/src/icon/index.php +3 -1
- package/src/image/image.js +14 -15
- package/src/image/index.php +7 -5
- package/src/latest-comments/deprecated.js +33 -0
- package/src/navigation/edit/index.js +134 -130
- package/src/navigation/edit/navigation-menu-selector.js +2 -1
- package/src/navigation/index.php +62 -9
- package/src/navigation/style.scss +17 -1
- package/src/navigation/view.js +14 -2
- package/src/navigation-link/edit.js +1 -0
- package/src/navigation-link/editor.scss +18 -0
- package/src/navigation-link/shared/controls.js +35 -62
- package/src/navigation-link/shared/test/controls.js +5 -5
- package/src/navigation-link/shared/test/use-handle-link-change.test.js +212 -0
- package/src/navigation-link/shared/test/use-link-preview.test.js +19 -1
- package/src/navigation-link/shared/use-handle-link-change.js +36 -9
- package/src/navigation-link/shared/use-link-preview.js +14 -15
- package/src/navigation-overlay-close/style.scss +3 -3
- package/src/navigation-submenu/edit.js +11 -28
- package/src/nextpage/block.json +0 -1
- package/src/page-list-item/edit.js +8 -7
- package/src/paragraph/edit.js +2 -2
- package/src/post-featured-image/index.php +4 -2
- package/src/post-navigation-link/block.json +3 -1
- package/src/post-navigation-link/edit.js +35 -2
- package/src/post-navigation-link/index.js +0 -2
- package/src/post-title/block.json +3 -1
- package/src/post-title/deprecated.js +1 -86
- package/src/post-title/edit.js +18 -2
- package/src/query-title/block.json +3 -1
- package/src/query-title/deprecated.js +1 -74
- package/src/query-title/edit.js +27 -11
- package/src/shortcode/block.json +2 -1
- package/src/site-tagline/block.json +4 -6
- package/src/site-tagline/deprecated.js +1 -70
- package/src/site-tagline/edit.js +22 -9
- package/src/site-title/block.json +3 -1
- package/src/site-title/deprecated.js +1 -83
- package/src/site-title/edit.js +22 -9
- package/src/tabs-menu-item/block.json +26 -1
- package/src/tabs-menu-item/controls.js +108 -0
- package/src/tabs-menu-item/edit.js +79 -6
- package/src/tabs-menu-item/editor.scss +6 -0
- package/src/tabs-menu-item/save.js +26 -1
- package/src/tabs-menu-item/style.scss +14 -3
- package/build/post-navigation-link/deprecated.cjs +0 -100
- package/build/post-navigation-link/deprecated.cjs.map +0 -7
- package/build-module/post-navigation-link/deprecated.mjs +0 -69
- package/build-module/post-navigation-link/deprecated.mjs.map +0 -7
- package/src/post-navigation-link/deprecated.js +0 -72
|
@@ -237,7 +237,7 @@ describe( 'Controls', () => {
|
|
|
237
237
|
|
|
238
238
|
render( <Controls { ...propsWithExternalLink } /> );
|
|
239
239
|
|
|
240
|
-
expect( screen.getByText( 'View
|
|
240
|
+
expect( screen.getByText( 'View' ) ).toBeVisible();
|
|
241
241
|
} );
|
|
242
242
|
|
|
243
243
|
it( 'shows "View page" for page links', () => {
|
|
@@ -253,7 +253,7 @@ describe( 'Controls', () => {
|
|
|
253
253
|
|
|
254
254
|
render( <Controls { ...propsWithPageLink } /> );
|
|
255
255
|
|
|
256
|
-
expect( screen.getByText( 'View
|
|
256
|
+
expect( screen.getByText( 'View' ) ).toBeVisible();
|
|
257
257
|
} );
|
|
258
258
|
|
|
259
259
|
it( 'shows "View post" for post links', () => {
|
|
@@ -269,7 +269,7 @@ describe( 'Controls', () => {
|
|
|
269
269
|
|
|
270
270
|
render( <Controls { ...propsWithPostLink } /> );
|
|
271
271
|
|
|
272
|
-
expect( screen.getByText( 'View
|
|
272
|
+
expect( screen.getByText( 'View' ) ).toBeVisible();
|
|
273
273
|
} );
|
|
274
274
|
|
|
275
275
|
it( 'shows "View category" for category links', () => {
|
|
@@ -285,7 +285,7 @@ describe( 'Controls', () => {
|
|
|
285
285
|
|
|
286
286
|
render( <Controls { ...propsWithCategoryLink } /> );
|
|
287
287
|
|
|
288
|
-
expect( screen.getByText( 'View
|
|
288
|
+
expect( screen.getByText( 'View' ) ).toBeVisible();
|
|
289
289
|
} );
|
|
290
290
|
|
|
291
291
|
it( 'shows "View link" for custom type links', () => {
|
|
@@ -301,7 +301,7 @@ describe( 'Controls', () => {
|
|
|
301
301
|
|
|
302
302
|
render( <Controls { ...propsWithCustomLink } /> );
|
|
303
303
|
|
|
304
|
-
expect( screen.getByText( 'View
|
|
304
|
+
expect( screen.getByText( 'View' ) ).toBeVisible();
|
|
305
305
|
} );
|
|
306
306
|
} );
|
|
307
307
|
} );
|
|
@@ -423,6 +423,51 @@ describe( 'useHandleLinkChange', () => {
|
|
|
423
423
|
} )
|
|
424
424
|
);
|
|
425
425
|
} );
|
|
426
|
+
|
|
427
|
+
it( 'should update text when editing text and changing a bound entity link to a custom URL in the link editing UI', () => {
|
|
428
|
+
useEntityBinding.mockReturnValue( {
|
|
429
|
+
hasUrlBinding: true,
|
|
430
|
+
createBinding: mockCreateBinding,
|
|
431
|
+
clearBinding: mockClearBinding,
|
|
432
|
+
} );
|
|
433
|
+
|
|
434
|
+
const attributes = {
|
|
435
|
+
id: 456,
|
|
436
|
+
url: 'https://example.com/my-page',
|
|
437
|
+
label: 'My Page',
|
|
438
|
+
kind: 'post-type',
|
|
439
|
+
type: 'page',
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
const { result } = renderHook( () =>
|
|
443
|
+
useHandleLinkChange( {
|
|
444
|
+
clientId,
|
|
445
|
+
attributes,
|
|
446
|
+
setAttributes: mockSetAttributes,
|
|
447
|
+
allowTextUpdate: true,
|
|
448
|
+
} )
|
|
449
|
+
);
|
|
450
|
+
|
|
451
|
+
const updatedLink = {
|
|
452
|
+
url: 'https://external-site.com',
|
|
453
|
+
title: 'Updated Navigation Text',
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
result.current( updatedLink );
|
|
457
|
+
|
|
458
|
+
expect( mockClearBinding ).toHaveBeenCalled();
|
|
459
|
+
expect( mockUpdateBlockAttributes ).toHaveBeenCalledWith(
|
|
460
|
+
clientId,
|
|
461
|
+
expect.objectContaining( {
|
|
462
|
+
url: 'https://external-site.com',
|
|
463
|
+
kind: 'custom',
|
|
464
|
+
type: 'custom',
|
|
465
|
+
id: undefined,
|
|
466
|
+
label: 'Updated Navigation Text',
|
|
467
|
+
} )
|
|
468
|
+
);
|
|
469
|
+
expect( updateAttributes ).not.toHaveBeenCalled();
|
|
470
|
+
} );
|
|
426
471
|
} );
|
|
427
472
|
|
|
428
473
|
describe( 'updating existing links', () => {
|
|
@@ -503,6 +548,87 @@ describe( 'useHandleLinkChange', () => {
|
|
|
503
548
|
);
|
|
504
549
|
} );
|
|
505
550
|
|
|
551
|
+
it( 'should preserve label when changing the link without editing text in the link editing UI', () => {
|
|
552
|
+
const attributes = {
|
|
553
|
+
id: 123,
|
|
554
|
+
url: 'https://example.com/page',
|
|
555
|
+
label: 'Custom Label',
|
|
556
|
+
kind: 'post-type',
|
|
557
|
+
type: 'page',
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
const { result } = renderHook( () =>
|
|
561
|
+
useHandleLinkChange( {
|
|
562
|
+
clientId,
|
|
563
|
+
attributes,
|
|
564
|
+
setAttributes: mockSetAttributes,
|
|
565
|
+
allowTextUpdate: true,
|
|
566
|
+
} )
|
|
567
|
+
);
|
|
568
|
+
|
|
569
|
+
const updatedLink = {
|
|
570
|
+
id: 456,
|
|
571
|
+
url: 'https://example.com/new-page',
|
|
572
|
+
title: 'Custom Label',
|
|
573
|
+
kind: 'post-type',
|
|
574
|
+
type: 'page',
|
|
575
|
+
};
|
|
576
|
+
|
|
577
|
+
result.current( updatedLink );
|
|
578
|
+
|
|
579
|
+
expect( updateAttributes ).toHaveBeenCalledWith(
|
|
580
|
+
expect.not.objectContaining( {
|
|
581
|
+
title: 'Custom Label',
|
|
582
|
+
} ),
|
|
583
|
+
mockSetAttributes,
|
|
584
|
+
attributes
|
|
585
|
+
);
|
|
586
|
+
expect( mockUpdateBlockAttributes ).not.toHaveBeenCalled();
|
|
587
|
+
} );
|
|
588
|
+
|
|
589
|
+
it( 'should include title when editing text and changing the entity link in the link editing UI', () => {
|
|
590
|
+
const attributes = {
|
|
591
|
+
id: 123,
|
|
592
|
+
url: 'https://example.com/page',
|
|
593
|
+
label: 'Sample Page',
|
|
594
|
+
kind: 'post-type',
|
|
595
|
+
type: 'page',
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
const { result } = renderHook( () =>
|
|
599
|
+
useHandleLinkChange( {
|
|
600
|
+
clientId,
|
|
601
|
+
attributes,
|
|
602
|
+
setAttributes: mockSetAttributes,
|
|
603
|
+
allowTextUpdate: true,
|
|
604
|
+
} )
|
|
605
|
+
);
|
|
606
|
+
|
|
607
|
+
const updatedLink = {
|
|
608
|
+
id: 456,
|
|
609
|
+
url: 'https://example.com/new-page',
|
|
610
|
+
title: 'Updated Navigation Text',
|
|
611
|
+
kind: 'post-type',
|
|
612
|
+
type: 'page',
|
|
613
|
+
};
|
|
614
|
+
|
|
615
|
+
result.current( updatedLink );
|
|
616
|
+
|
|
617
|
+
expect( updateAttributes ).toHaveBeenCalledWith(
|
|
618
|
+
expect.objectContaining( {
|
|
619
|
+
title: 'Updated Navigation Text',
|
|
620
|
+
} ),
|
|
621
|
+
mockSetAttributes,
|
|
622
|
+
attributes
|
|
623
|
+
);
|
|
624
|
+
expect( mockUpdateBlockAttributes ).toHaveBeenCalledWith(
|
|
625
|
+
clientId,
|
|
626
|
+
{
|
|
627
|
+
label: 'Updated Navigation Text',
|
|
628
|
+
}
|
|
629
|
+
);
|
|
630
|
+
} );
|
|
631
|
+
|
|
506
632
|
it( 'should include title when creating link without existing label', () => {
|
|
507
633
|
const attributes = {};
|
|
508
634
|
|
|
@@ -606,6 +732,92 @@ describe( 'useHandleLinkChange', () => {
|
|
|
606
732
|
);
|
|
607
733
|
} );
|
|
608
734
|
|
|
735
|
+
it( 'should include title when editing text for the same existing entity link', () => {
|
|
736
|
+
const attributes = {
|
|
737
|
+
id: 123,
|
|
738
|
+
url: 'https://example.com/page',
|
|
739
|
+
label: 'Sample Page',
|
|
740
|
+
kind: 'post-type',
|
|
741
|
+
type: 'page',
|
|
742
|
+
};
|
|
743
|
+
|
|
744
|
+
const { result } = renderHook( () =>
|
|
745
|
+
useHandleLinkChange( {
|
|
746
|
+
clientId,
|
|
747
|
+
attributes,
|
|
748
|
+
setAttributes: mockSetAttributes,
|
|
749
|
+
allowTextUpdate: true,
|
|
750
|
+
} )
|
|
751
|
+
);
|
|
752
|
+
|
|
753
|
+
const updatedLink = {
|
|
754
|
+
id: 123,
|
|
755
|
+
url: 'https://example.com/page',
|
|
756
|
+
title: 'Updated Sample Page',
|
|
757
|
+
kind: 'post-type',
|
|
758
|
+
type: 'page',
|
|
759
|
+
};
|
|
760
|
+
|
|
761
|
+
result.current( updatedLink );
|
|
762
|
+
|
|
763
|
+
expect( updateAttributes ).toHaveBeenCalledWith(
|
|
764
|
+
expect.objectContaining( {
|
|
765
|
+
title: 'Updated Sample Page',
|
|
766
|
+
} ),
|
|
767
|
+
mockSetAttributes,
|
|
768
|
+
attributes
|
|
769
|
+
);
|
|
770
|
+
expect( mockUpdateBlockAttributes ).toHaveBeenCalledWith(
|
|
771
|
+
clientId,
|
|
772
|
+
{
|
|
773
|
+
label: 'Updated Sample Page',
|
|
774
|
+
}
|
|
775
|
+
);
|
|
776
|
+
} );
|
|
777
|
+
|
|
778
|
+
it( 'should clear text when the inline link editing UI title is emptied', () => {
|
|
779
|
+
const attributes = {
|
|
780
|
+
id: 123,
|
|
781
|
+
url: 'https://example.com/page',
|
|
782
|
+
label: 'Sample Page',
|
|
783
|
+
kind: 'post-type',
|
|
784
|
+
type: 'page',
|
|
785
|
+
};
|
|
786
|
+
|
|
787
|
+
const { result } = renderHook( () =>
|
|
788
|
+
useHandleLinkChange( {
|
|
789
|
+
clientId,
|
|
790
|
+
attributes,
|
|
791
|
+
setAttributes: mockSetAttributes,
|
|
792
|
+
allowTextUpdate: true,
|
|
793
|
+
} )
|
|
794
|
+
);
|
|
795
|
+
|
|
796
|
+
const updatedLink = {
|
|
797
|
+
id: 123,
|
|
798
|
+
url: 'https://example.com/page',
|
|
799
|
+
title: '',
|
|
800
|
+
kind: 'post-type',
|
|
801
|
+
type: 'page',
|
|
802
|
+
};
|
|
803
|
+
|
|
804
|
+
result.current( updatedLink );
|
|
805
|
+
|
|
806
|
+
expect( updateAttributes ).toHaveBeenCalledWith(
|
|
807
|
+
expect.objectContaining( {
|
|
808
|
+
title: '',
|
|
809
|
+
} ),
|
|
810
|
+
mockSetAttributes,
|
|
811
|
+
attributes
|
|
812
|
+
);
|
|
813
|
+
expect( mockUpdateBlockAttributes ).toHaveBeenCalledWith(
|
|
814
|
+
clientId,
|
|
815
|
+
{
|
|
816
|
+
label: '',
|
|
817
|
+
}
|
|
818
|
+
);
|
|
819
|
+
} );
|
|
820
|
+
|
|
609
821
|
it( 'should update custom link to another custom link', () => {
|
|
610
822
|
updateAttributes.mockImplementation( ( attrs ) => ( {
|
|
611
823
|
isEntityLink: false,
|
|
@@ -92,10 +92,28 @@ describe( 'computeDisplayUrl', () => {
|
|
|
92
92
|
it( 'should treat same-origin URLs as internal', () => {
|
|
93
93
|
const result = computeDisplayUrl( {
|
|
94
94
|
linkUrl: 'https://example.com/my-page',
|
|
95
|
-
|
|
95
|
+
homeUrl: 'https://example.com',
|
|
96
96
|
} );
|
|
97
97
|
expect( result.isExternal ).toBe( false );
|
|
98
98
|
} );
|
|
99
|
+
|
|
100
|
+
it( 'should treat same-origin URLs as internal when homeUrl includes a path', () => {
|
|
101
|
+
const result = computeDisplayUrl( {
|
|
102
|
+
linkUrl: 'https://example.com/my-page',
|
|
103
|
+
homeUrl: 'https://example.com/blog',
|
|
104
|
+
} );
|
|
105
|
+
expect( result.isExternal ).toBe( false );
|
|
106
|
+
expect( result.displayUrl ).toBe( '/my-page' );
|
|
107
|
+
} );
|
|
108
|
+
|
|
109
|
+
it( 'should treat http and https to same host as internal (compare by host, not origin)', () => {
|
|
110
|
+
const result = computeDisplayUrl( {
|
|
111
|
+
linkUrl: 'http://example.com/my-page',
|
|
112
|
+
homeUrl: 'https://example.com',
|
|
113
|
+
} );
|
|
114
|
+
expect( result.isExternal ).toBe( false );
|
|
115
|
+
expect( result.displayUrl ).toBe( '/my-page' );
|
|
116
|
+
} );
|
|
99
117
|
} );
|
|
100
118
|
|
|
101
119
|
describe( 'special protocols and edge cases', () => {
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
import { useCallback } from '@wordpress/element';
|
|
5
5
|
import { useDispatch } from '@wordpress/data';
|
|
6
6
|
import { store as blockEditorStore } from '@wordpress/block-editor';
|
|
7
|
+
import { __unstableStripHTML as stripHTML } from '@wordpress/dom';
|
|
8
|
+
import { escapeHTML } from '@wordpress/escape-html';
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* Internal dependencies
|
|
@@ -16,13 +18,19 @@ import { useEntityBinding } from './use-entity-binding';
|
|
|
16
18
|
* Manages the transition between entity links and custom links,
|
|
17
19
|
* including proper binding creation and cleanup.
|
|
18
20
|
*
|
|
19
|
-
* @param {Object} options
|
|
20
|
-
* @param {string} options.clientId
|
|
21
|
-
* @param {Object} options.attributes
|
|
22
|
-
* @param {Function} options.setAttributes
|
|
21
|
+
* @param {Object} options - Configuration options
|
|
22
|
+
* @param {string} options.clientId - Block client ID
|
|
23
|
+
* @param {Object} options.attributes - Current block attributes
|
|
24
|
+
* @param {Function} options.setAttributes - Standard setAttribute function
|
|
25
|
+
* @param {boolean} options.allowTextUpdate - Whether this control can update the link text
|
|
23
26
|
* @return {Function} Callback function to handle link changes
|
|
24
27
|
*/
|
|
25
|
-
export function useHandleLinkChange( {
|
|
28
|
+
export function useHandleLinkChange( {
|
|
29
|
+
clientId,
|
|
30
|
+
attributes,
|
|
31
|
+
setAttributes,
|
|
32
|
+
allowTextUpdate = false,
|
|
33
|
+
} ) {
|
|
26
34
|
const { updateBlockAttributes } = useDispatch( blockEditorStore );
|
|
27
35
|
const { hasUrlBinding, createBinding, clearBinding } = useEntityBinding( {
|
|
28
36
|
clientId,
|
|
@@ -42,12 +50,25 @@ export function useHandleLinkChange( { clientId, attributes, setAttributes } ) {
|
|
|
42
50
|
id: updatedLink.id,
|
|
43
51
|
};
|
|
44
52
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
53
|
+
const currentText = attributes.label
|
|
54
|
+
? stripHTML( attributes.label )
|
|
55
|
+
: '';
|
|
56
|
+
const updatedText = updatedLink.title ?? '';
|
|
57
|
+
const hasTextUpdate =
|
|
58
|
+
allowTextUpdate &&
|
|
59
|
+
updatedLink.title !== undefined &&
|
|
60
|
+
updatedText !== currentText;
|
|
61
|
+
const textUpdateAttributes = hasTextUpdate
|
|
62
|
+
? { label: escapeHTML( updatedText ) }
|
|
63
|
+
: {};
|
|
64
|
+
|
|
65
|
+
if (
|
|
66
|
+
! attributes.label ||
|
|
67
|
+
attributes.label === '' ||
|
|
68
|
+
hasTextUpdate
|
|
69
|
+
) {
|
|
48
70
|
attrs.title = updatedLink.title;
|
|
49
71
|
}
|
|
50
|
-
|
|
51
72
|
// Check if transitioning from entity to custom link
|
|
52
73
|
const willBeCustomLink = ! updatedLink.id && hasUrlBinding;
|
|
53
74
|
|
|
@@ -62,6 +83,7 @@ export function useHandleLinkChange( { clientId, attributes, setAttributes } ) {
|
|
|
62
83
|
kind: 'custom',
|
|
63
84
|
type: 'custom',
|
|
64
85
|
id: undefined,
|
|
86
|
+
...textUpdateAttributes,
|
|
65
87
|
} );
|
|
66
88
|
} else {
|
|
67
89
|
// Normal flow for entity links or unbound custom links
|
|
@@ -76,10 +98,15 @@ export function useHandleLinkChange( { clientId, attributes, setAttributes } ) {
|
|
|
76
98
|
} else {
|
|
77
99
|
clearBinding();
|
|
78
100
|
}
|
|
101
|
+
|
|
102
|
+
if ( Object.keys( textUpdateAttributes ).length ) {
|
|
103
|
+
updateBlockAttributes( clientId, textUpdateAttributes );
|
|
104
|
+
}
|
|
79
105
|
}
|
|
80
106
|
},
|
|
81
107
|
[
|
|
82
108
|
attributes,
|
|
109
|
+
allowTextUpdate,
|
|
83
110
|
clientId,
|
|
84
111
|
hasUrlBinding,
|
|
85
112
|
createBinding,
|
|
@@ -31,10 +31,10 @@ function capitalize( str ) {
|
|
|
31
31
|
*
|
|
32
32
|
* @param {Object} options - Parameters object
|
|
33
33
|
* @param {string} options.linkUrl - The URL to process
|
|
34
|
-
* @param {string} options.
|
|
34
|
+
* @param {string} options.homeUrl - The WordPress site URL (required for internal/external detection)
|
|
35
35
|
* @return {Object} Object with displayUrl and isExternal flag
|
|
36
36
|
*/
|
|
37
|
-
export function computeDisplayUrl( { linkUrl,
|
|
37
|
+
export function computeDisplayUrl( { linkUrl, homeUrl } = {} ) {
|
|
38
38
|
if ( ! linkUrl ) {
|
|
39
39
|
return { displayUrl: '', isExternal: false };
|
|
40
40
|
}
|
|
@@ -51,9 +51,10 @@ export function computeDisplayUrl( { linkUrl, siteUrl } = {} ) {
|
|
|
51
51
|
// This must happen before trusting the type attribute
|
|
52
52
|
try {
|
|
53
53
|
const parsedUrl = new URL( linkUrl );
|
|
54
|
-
//
|
|
55
|
-
const
|
|
56
|
-
|
|
54
|
+
// Compare by host (not origin) so http/https to same site both count as internal
|
|
55
|
+
const siteHost = new URL( homeUrl ).host;
|
|
56
|
+
|
|
57
|
+
if ( parsedUrl.host === siteHost ) {
|
|
57
58
|
// Show only the pathname (and search/hash if present)
|
|
58
59
|
let path = parsedUrl.pathname + parsedUrl.search + parsedUrl.hash;
|
|
59
60
|
// Remove trailing slash
|
|
@@ -62,12 +63,11 @@ export function computeDisplayUrl( { linkUrl, siteUrl } = {} ) {
|
|
|
62
63
|
}
|
|
63
64
|
displayUrl = path;
|
|
64
65
|
} else {
|
|
65
|
-
// Different
|
|
66
|
+
// Different host - this is an external link
|
|
66
67
|
isExternal = true;
|
|
67
68
|
}
|
|
68
69
|
} catch ( e ) {
|
|
69
|
-
// URL parsing failed -
|
|
70
|
-
// Since we already checked for relative paths and hash links above, treat as external
|
|
70
|
+
// URL parsing failed - treat as external (e.g. no homeUrl, or URL without protocol)
|
|
71
71
|
isExternal = true;
|
|
72
72
|
}
|
|
73
73
|
|
|
@@ -174,13 +174,12 @@ export function useLinkPreview( {
|
|
|
174
174
|
hasBinding,
|
|
175
175
|
isEntityAvailable,
|
|
176
176
|
} ) {
|
|
177
|
-
// Get the WordPress
|
|
178
|
-
const
|
|
179
|
-
|
|
177
|
+
// Get the WordPress homepage URL from settings
|
|
178
|
+
const homeUrl = useSelect( ( select ) => {
|
|
179
|
+
return select( coreDataStore ).getEntityRecord(
|
|
180
180
|
'root',
|
|
181
|
-
'
|
|
182
|
-
);
|
|
183
|
-
return siteEntity?.url;
|
|
181
|
+
'__unstableBase'
|
|
182
|
+
)?.home;
|
|
184
183
|
}, [] );
|
|
185
184
|
|
|
186
185
|
const title =
|
|
@@ -194,7 +193,7 @@ export function useLinkPreview( {
|
|
|
194
193
|
// Compute display URL and external flag
|
|
195
194
|
const { displayUrl, isExternal } = computeDisplayUrl( {
|
|
196
195
|
linkUrl: url,
|
|
197
|
-
|
|
196
|
+
homeUrl,
|
|
198
197
|
} );
|
|
199
198
|
|
|
200
199
|
const image = useSelect(
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
align-items: center;
|
|
4
4
|
justify-content: center;
|
|
5
5
|
gap: 0.5em;
|
|
6
|
-
padding: 0
|
|
6
|
+
padding: 0;
|
|
7
7
|
border: none;
|
|
8
8
|
background: transparent;
|
|
9
9
|
cursor: pointer;
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
svg {
|
|
17
|
-
width:
|
|
18
|
-
height:
|
|
17
|
+
width: 24px;
|
|
18
|
+
height: 24px;
|
|
19
19
|
fill: currentColor;
|
|
20
20
|
display: block;
|
|
21
21
|
flex-shrink: 0;
|
|
@@ -35,8 +35,8 @@ import { ItemSubmenuIcon } from './icons';
|
|
|
35
35
|
import {
|
|
36
36
|
Controls,
|
|
37
37
|
LinkUI,
|
|
38
|
-
updateAttributes,
|
|
39
38
|
useEntityBinding,
|
|
39
|
+
useHandleLinkChange,
|
|
40
40
|
useIsInvalidLink,
|
|
41
41
|
InvalidDraftDisplay,
|
|
42
42
|
useEnableLinkStatusValidation,
|
|
@@ -92,15 +92,17 @@ export default function NavigationSubmenuEdit( {
|
|
|
92
92
|
blockEditingMode !== 'default' ? true : submenuVisibility === 'click';
|
|
93
93
|
|
|
94
94
|
// URL binding logic
|
|
95
|
-
const {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
95
|
+
const { hasUrlBinding, isBoundEntityAvailable, entityRecord } =
|
|
96
|
+
useEntityBinding( {
|
|
97
|
+
clientId,
|
|
98
|
+
attributes,
|
|
99
|
+
} );
|
|
100
|
+
|
|
101
|
+
const handleLinkChange = useHandleLinkChange( {
|
|
102
102
|
clientId,
|
|
103
103
|
attributes,
|
|
104
|
+
setAttributes,
|
|
105
|
+
allowTextUpdate: true,
|
|
104
106
|
} );
|
|
105
107
|
|
|
106
108
|
const { __unstableMarkNextChangeAsNotPersistent, replaceBlock } =
|
|
@@ -398,26 +400,7 @@ export default function NavigationSubmenuEdit( {
|
|
|
398
400
|
setAttributes( { url: '' } );
|
|
399
401
|
speak( __( 'Link removed.' ), 'assertive' );
|
|
400
402
|
} }
|
|
401
|
-
onChange={
|
|
402
|
-
// updateAttributes determines the final state and returns metadata
|
|
403
|
-
const {
|
|
404
|
-
isEntityLink,
|
|
405
|
-
attributes: updatedAttributes,
|
|
406
|
-
} = updateAttributes(
|
|
407
|
-
updatedValue,
|
|
408
|
-
setAttributes,
|
|
409
|
-
attributes
|
|
410
|
-
);
|
|
411
|
-
|
|
412
|
-
// Handle URL binding based on the final computed state
|
|
413
|
-
// Only create bindings for entity links (posts, pages, taxonomies)
|
|
414
|
-
// Never create bindings for custom links (manual URLs)
|
|
415
|
-
if ( isEntityLink ) {
|
|
416
|
-
createBinding( updatedAttributes );
|
|
417
|
-
} else {
|
|
418
|
-
clearBinding();
|
|
419
|
-
}
|
|
420
|
-
} }
|
|
403
|
+
onChange={ handleLinkChange }
|
|
421
404
|
/>
|
|
422
405
|
) }
|
|
423
406
|
</ParentElement>
|
package/src/nextpage/block.json
CHANGED
|
@@ -8,7 +8,6 @@ import clsx from 'clsx';
|
|
|
8
8
|
import { useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor';
|
|
9
9
|
import { useSelect } from '@wordpress/data';
|
|
10
10
|
import { store as coreStore } from '@wordpress/core-data';
|
|
11
|
-
import { RawHTML } from '@wordpress/element';
|
|
12
11
|
import { safeHTML } from '@wordpress/dom';
|
|
13
12
|
|
|
14
13
|
/**
|
|
@@ -78,9 +77,10 @@ export default function PageListItemEdit( { context, attributes } ) {
|
|
|
78
77
|
type="button"
|
|
79
78
|
className="wp-block-navigation-item__content wp-block-navigation-submenu__toggle"
|
|
80
79
|
aria-expanded="false"
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
80
|
+
dangerouslySetInnerHTML={ {
|
|
81
|
+
__html: safeHTML( label ),
|
|
82
|
+
} }
|
|
83
|
+
/>
|
|
84
84
|
<span className="wp-block-page-list__submenu-icon wp-block-navigation__submenu-icon">
|
|
85
85
|
<ItemSubmenuIcon />
|
|
86
86
|
</span>
|
|
@@ -91,9 +91,10 @@ export default function PageListItemEdit( { context, attributes } ) {
|
|
|
91
91
|
'wp-block-navigation-item__content': isNavigationChild,
|
|
92
92
|
} ) }
|
|
93
93
|
href={ link }
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
dangerouslySetInnerHTML={ {
|
|
95
|
+
__html: safeHTML( title ),
|
|
96
|
+
} }
|
|
97
|
+
/>
|
|
97
98
|
) }
|
|
98
99
|
{ hasChildren && (
|
|
99
100
|
<>
|
package/src/paragraph/edit.js
CHANGED
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
useBlockEditingMode,
|
|
22
22
|
} from '@wordpress/block-editor';
|
|
23
23
|
import { getBlockSupport } from '@wordpress/blocks';
|
|
24
|
-
import {
|
|
24
|
+
import { formatLTR } from '@wordpress/icons';
|
|
25
25
|
/**
|
|
26
26
|
* Internal dependencies
|
|
27
27
|
*/
|
|
@@ -32,7 +32,7 @@ function ParagraphRTLControl( { direction, setDirection } ) {
|
|
|
32
32
|
return (
|
|
33
33
|
isRTL() && (
|
|
34
34
|
<ToolbarButton
|
|
35
|
-
icon={
|
|
35
|
+
icon={ formatLTR }
|
|
36
36
|
title={ _x( 'Left to right', 'editor button' ) }
|
|
37
37
|
isActive={ direction === 'ltr' }
|
|
38
38
|
onClick={ () => {
|
|
@@ -166,8 +166,10 @@ function get_block_core_post_featured_image_overlay_element_markup( $attributes
|
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
// Apply overlay and gradient classes.
|
|
169
|
-
$
|
|
170
|
-
|
|
169
|
+
if ( $has_dim_background ) {
|
|
170
|
+
$class_names[] = 'has-background-dim';
|
|
171
|
+
$class_names[] = "has-background-dim-{$attributes['dimRatio']}";
|
|
172
|
+
}
|
|
171
173
|
|
|
172
174
|
if ( $has_solid_overlay ) {
|
|
173
175
|
$class_names[] = "has-{$attributes['overlayColor']}-background-color";
|
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
"description": "Displays the next or previous post link that is adjacent to the current post.",
|
|
8
8
|
"textdomain": "default",
|
|
9
9
|
"attributes": {
|
|
10
|
+
"textAlign": {
|
|
11
|
+
"type": "string"
|
|
12
|
+
},
|
|
10
13
|
"type": {
|
|
11
14
|
"type": "string",
|
|
12
15
|
"default": "next"
|
|
@@ -43,7 +46,6 @@
|
|
|
43
46
|
"typography": {
|
|
44
47
|
"fontSize": true,
|
|
45
48
|
"lineHeight": true,
|
|
46
|
-
"textAlign": true,
|
|
47
49
|
"__experimentalFontFamily": true,
|
|
48
50
|
"__experimentalFontWeight": true,
|
|
49
51
|
"__experimentalFontStyle": true,
|