diff --git a/packages/block-library/src/image/index.js b/packages/block-library/src/image/index.js index 0a5ca7618c4aa..65bd1df8f1dc2 100644 --- a/packages/block-library/src/image/index.js +++ b/packages/block-library/src/image/index.js @@ -111,6 +111,21 @@ const schema = { }, }; +function getFirstAnchorAttributeFormHTML( html, attributeName ) { + const { body } = document.implementation.createHTMLDocument( '' ); + + body.innerHTML = html; + + const { firstElementChild } = body; + + if ( + firstElementChild && + firstElementChild.nodeName === 'A' + ) { + return firstElementChild.getAttribute( attributeName ) || undefined; + } +} + export const settings = { title: __( 'Image' ), @@ -185,27 +200,28 @@ export const settings = { }, caption: { shortcode: ( attributes, { shortcode } ) => { - const { content } = shortcode; - return content.replace( /\s*]*>\s/, '' ); + const { body } = document.implementation.createHTMLDocument( '' ); + + body.innerHTML = shortcode.content; + body.removeChild( body.firstElementChild ); + + return body.innerHTML.trim(); }, }, href: { - type: 'string', - source: 'attribute', - attribute: 'href', - selector: 'a', + shortcode: ( attributes, { shortcode } ) => { + return getFirstAnchorAttributeFormHTML( shortcode.content, 'href' ); + }, }, rel: { - type: 'string', - source: 'attribute', - attribute: 'rel', - selector: 'a', + shortcode: ( attributes, { shortcode } ) => { + return getFirstAnchorAttributeFormHTML( shortcode.content, 'rel' ); + }, }, linkClass: { - type: 'string', - source: 'attribute', - attribute: 'class', - selector: 'a', + shortcode: ( attributes, { shortcode } ) => { + return getFirstAnchorAttributeFormHTML( shortcode.content, 'class' ); + }, }, id: { type: 'number', diff --git a/test/integration/__snapshots__/blocks-raw-handling.spec.js.snap b/test/integration/__snapshots__/blocks-raw-handling.spec.js.snap index 320b201a836e3..9d8761f906216 100644 --- a/test/integration/__snapshots__/blocks-raw-handling.spec.js.snap +++ b/test/integration/__snapshots__/blocks-raw-handling.spec.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Blocks raw handling rawHandler should convert HTML post to blocks with minimal content changes 1`] = ` +exports[`rawHandler should convert HTML post to blocks with minimal content changes 1`] = ` "

Howdy

@@ -54,3 +54,21 @@ exports[`Blocks raw handling rawHandler should convert HTML post to blocks with

Heading

Text.

" `; + +exports[`rawHandler should convert a caption shortcode 1`] = ` +" +
\\"\\"
test
+" +`; + +exports[`rawHandler should convert a caption shortcode with caption 1`] = ` +" +
\\"\\"
test
+" +`; + +exports[`rawHandler should convert a caption shortcode with link 1`] = ` +" +
\\"Bell
Bell on wharf in San Francisco
+" +`; diff --git a/test/integration/blocks-raw-handling.spec.js b/test/integration/blocks-raw-handling.spec.js index b0997d3b757d9..3f0e951026537 100644 --- a/test/integration/blocks-raw-handling.spec.js +++ b/test/integration/blocks-raw-handling.spec.js @@ -155,11 +155,26 @@ describe( 'Blocks raw handling', () => { } ); } ); } ); +} ); - describe( 'rawHandler', () => { - it( 'should convert HTML post to blocks with minimal content changes', () => { - const HTML = readFile( path.join( __dirname, 'fixtures/wordpress-convert.html' ) ); - expect( serialize( rawHandler( { HTML } ) ) ).toMatchSnapshot(); - } ); +describe( 'rawHandler', () => { + it( 'should convert HTML post to blocks with minimal content changes', () => { + const HTML = readFile( path.join( __dirname, 'fixtures/wordpress-convert.html' ) ); + expect( serialize( rawHandler( { HTML } ) ) ).toMatchSnapshot(); + } ); + + it( 'should convert a caption shortcode', () => { + const HTML = readFile( path.join( __dirname, 'fixtures/shortcode-caption.html' ) ); + expect( serialize( rawHandler( { HTML } ) ) ).toMatchSnapshot(); + } ); + + it( 'should convert a caption shortcode with link', () => { + const HTML = readFile( path.join( __dirname, 'fixtures/shortcode-caption-with-link.html' ) ); + expect( serialize( rawHandler( { HTML } ) ) ).toMatchSnapshot(); + } ); + + it( 'should convert a caption shortcode with caption', () => { + const HTML = readFile( path.join( __dirname, 'fixtures/shortcode-caption-with-caption-link.html' ) ); + expect( serialize( rawHandler( { HTML } ) ) ).toMatchSnapshot(); } ); } ); diff --git a/test/integration/fixtures/caption-shortcode-out.html b/test/integration/fixtures/caption-shortcode-out.html deleted file mode 100644 index 2027b65d2feae..0000000000000 --- a/test/integration/fixtures/caption-shortcode-out.html +++ /dev/null @@ -1,3 +0,0 @@ - -
test
- diff --git a/test/integration/fixtures/shortcode-caption-with-caption-link.html b/test/integration/fixtures/shortcode-caption-with-caption-link.html new file mode 100644 index 0000000000000..4eb0f6c4f0c1f --- /dev/null +++ b/test/integration/fixtures/shortcode-caption-with-caption-link.html @@ -0,0 +1 @@ +

[caption id="attachment_122" align="alignnone" width="300"] test[/caption]

diff --git a/test/integration/fixtures/shortcode-caption-with-link.html b/test/integration/fixtures/shortcode-caption-with-link.html new file mode 100644 index 0000000000000..3405b7ac1ecf0 --- /dev/null +++ b/test/integration/fixtures/shortcode-caption-with-link.html @@ -0,0 +1 @@ +[caption id="attachment_754" align="alignnone" width="604"]Bell on Wharf Bell on wharf in San Francisco[/caption] diff --git a/test/integration/fixtures/caption-shortcode-in.html b/test/integration/fixtures/shortcode-caption.html similarity index 100% rename from test/integration/fixtures/caption-shortcode-in.html rename to test/integration/fixtures/shortcode-caption.html