diff --git a/packages/block-editor/src/components/iframe/index.js b/packages/block-editor/src/components/iframe/index.js index d089925b3846a..f06f140e02849 100644 --- a/packages/block-editor/src/components/iframe/index.js +++ b/packages/block-editor/src/components/iframe/index.js @@ -49,6 +49,19 @@ function styleSheetsCompat( doc ) { return; } + // Generally, ignore inline styles. We add inline styles belonging to a + // stylesheet later, which may or may not match the selectors. + if ( ownerNode.tagName !== 'LINK' ) { + return; + } + + // Don't try to add the reset styles, which were removed as a dependency + // from `edit-blocks` for the iframe since we don't need to reset admin + // styles. + if ( ownerNode.id === 'wp-reset-editor-styles-css' ) { + return; + } + const isMatch = Array.from( cssRules ).find( ( { selectorText } ) => selectorText && @@ -62,9 +75,17 @@ function styleSheetsCompat( doc ) { `Stylesheet ${ ownerNode.id } was not properly added. For blocks, use the block API's style (https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#style) or editorStyle (https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#editor-style). For themes, use add_editor_style (https://developer.wordpress.org/block-editor/how-to-guides/themes/theme-support/#editor-styles).`, - ownerNode + ownerNode.outerHTML ); doc.head.appendChild( ownerNode.cloneNode( true ) ); + + // Add inline styles belonging to the stylesheet. + const inlineCssId = ownerNode.id.replace( '-css', '-inline-css' ); + const inlineCssElement = document.getElementById( inlineCssId ); + + if ( inlineCssElement ) { + doc.head.appendChild( inlineCssElement.cloneNode( true ) ); + } } } ); } @@ -232,12 +253,23 @@ function Iframe( { contentRef, children, head, ...props }, ref ) { head = ( <> - { styles.map( ( { tagName, href, id, rel, media }, index ) => { - const TagName = tagName.toLowerCase(); - return ( - - ); - } ) } + { styles.map( + ( { tagName, href, id, rel, media, textContent } ) => { + const TagName = tagName.toLowerCase(); + + if ( TagName === 'style' ) { + return ( + + { textContent } + + ); + } + + return ( + + ); + } + ) } { head } ); diff --git a/packages/e2e-tests/plugins/iframed-inline-styles.php b/packages/e2e-tests/plugins/iframed-inline-styles.php new file mode 100644 index 0000000000000..f54c8eb83e623 --- /dev/null +++ b/packages/e2e-tests/plugins/iframed-inline-styles.php @@ -0,0 +1,52 @@ + { + const { createElement: el } = element; + const { registerBlockType } = blocks; + const { useBlockProps } = blockEditor; + + registerBlockType( 'test/iframed-inline-styles', { + apiVersion: 2, + edit: function Edit() { + return el( 'div', useBlockProps(), 'Edit' ); + }, + save: function Save() { + return el( 'div', useBlockProps.save(), 'Save' ); + }, + } ); +} )( window ); diff --git a/packages/e2e-tests/plugins/iframed-inline-styles/style.css b/packages/e2e-tests/plugins/iframed-inline-styles/style.css new file mode 100644 index 0000000000000..23ddfa8529081 --- /dev/null +++ b/packages/e2e-tests/plugins/iframed-inline-styles/style.css @@ -0,0 +1,9 @@ +/** + * The following styles get applied both on the front of your site and in the + * editor. + */ +.wp-block-test-iframed-inline-styles { + background-color: #21759b; + color: #fff; + padding: 2px; +} diff --git a/packages/e2e-tests/plugins/iframed-masonry-block/editor.js b/packages/e2e-tests/plugins/iframed-masonry-block/editor.js index a6d2697fe3930..2833815c0a1ae 100644 --- a/packages/e2e-tests/plugins/iframed-masonry-block/editor.js +++ b/packages/e2e-tests/plugins/iframed-masonry-block/editor.js @@ -28,7 +28,7 @@ el( 'div', { className: 'grid-item' } ), el( 'div', { className: 'grid-item' } ), el( 'div', { className: 'grid-item grid-item--height2' } ), - ] + ]; registerBlockType( 'test/iframed-masonry-block', { edit: function Edit() { diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-inline-styles.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-inline-styles.test.js.snap new file mode 100644 index 0000000000000..46d3e807bff83 --- /dev/null +++ b/packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-inline-styles.test.js.snap @@ -0,0 +1,7 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`iframed inline styles should load inline styles in iframe 1`] = ` +" +
Save
+" +`; diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-masonry-block.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-masonry-block.test.js.snap index 1c0d56386164f..0033b3aff44d1 100644 --- a/packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-masonry-block.test.js.snap +++ b/packages/e2e-tests/specs/editor/plugins/__snapshots__/iframed-masonry-block.test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`changing image size should load script and dependencies in iframe 1`] = ` +exports[`iframed masonry block should load script and dependencies in iframe 1`] = ` "
" diff --git a/packages/e2e-tests/specs/editor/plugins/iframed-inline-styles.test.js b/packages/e2e-tests/specs/editor/plugins/iframed-inline-styles.test.js new file mode 100644 index 0000000000000..e8f8a83a8c1f9 --- /dev/null +++ b/packages/e2e-tests/specs/editor/plugins/iframed-inline-styles.test.js @@ -0,0 +1,69 @@ +/** + * WordPress dependencies + */ +import { + activatePlugin, + createNewPost, + deactivatePlugin, + insertBlock, + getEditedPostContent, + openDocumentSettingsSidebar, + clickButton, + canvas, +} from '@wordpress/e2e-test-utils'; + +async function getComputedStyle( context, property ) { + return await context.evaluate( ( prop ) => { + const container = document.querySelector( + '.wp-block-test-iframed-inline-styles' + ); + return window.getComputedStyle( container )[ prop ]; + }, property ); +} + +describe( 'iframed inline styles', () => { + beforeEach( async () => { + await activatePlugin( 'gutenberg-test-iframed-inline-styles' ); + await createNewPost( { postType: 'page' } ); + } ); + + afterEach( async () => { + await deactivatePlugin( 'gutenberg-test-iframed-inline-styles' ); + } ); + + it( 'should load inline styles in iframe', async () => { + await insertBlock( 'Iframed Inline Styles' ); + + expect( await getEditedPostContent() ).toMatchSnapshot(); + expect( await getComputedStyle( page, 'padding' ) ).toBe( '20px' ); + expect( await getComputedStyle( page, 'border-width' ) ).toBe( '2px' ); + + await openDocumentSettingsSidebar(); + await clickButton( 'Page' ); + await clickButton( 'Template' ); + await clickButton( 'New' ); + await page.keyboard.press( 'Tab' ); + await page.keyboard.press( 'Tab' ); + await page.keyboard.type( 'Iframed Test' ); + await clickButton( 'Create' ); + await page.waitForSelector( 'iframe[name="editor-canvas"]' ); + await canvas().waitForSelector( + '.wp-block-test-iframed-inline-styles' + ); + + // Inline styles of properly enqueued stylesheet should load. + expect( await getComputedStyle( canvas(), 'padding' ) ).toBe( '20px' ); + + // Inline styles of stylesheet loaded with the compatibility layer + // should load. + expect( await getComputedStyle( canvas(), 'border-width' ) ).toBe( + '2px' + ); + + expect( console ).toHaveErrored( + `Stylesheet iframed-inline-styles-compat-style-css was not properly added. +For blocks, use the block API's style (https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#style) or editorStyle (https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#editor-style). +For themes, use add_editor_style (https://developer.wordpress.org/block-editor/how-to-guides/themes/theme-support/#editor-styles). ` + ); + } ); +} ); diff --git a/packages/e2e-tests/specs/editor/plugins/iframed-masonry-block.test.js b/packages/e2e-tests/specs/editor/plugins/iframed-masonry-block.test.js index 5c12f2abb1b6a..7877442e5695e 100644 --- a/packages/e2e-tests/specs/editor/plugins/iframed-masonry-block.test.js +++ b/packages/e2e-tests/specs/editor/plugins/iframed-masonry-block.test.js @@ -26,7 +26,7 @@ async function didMasonryLoadCorrectly( context ) { } ); } -describe( 'changing image size', () => { +describe( 'iframed masonry block', () => { beforeEach( async () => { await activatePlugin( 'gutenberg-test-iframed-masonry-block' ); await createNewPost( { postType: 'page' } );