diff --git a/blocks/api/raw-handling/strip-attributes.js b/blocks/api/raw-handling/strip-attributes.js
index 6d5ade2f436c47..832f71c9e36d5f 100644
--- a/blocks/api/raw-handling/strip-attributes.js
+++ b/blocks/api/raw-handling/strip-attributes.js
@@ -6,7 +6,7 @@ const { ELEMENT_NODE } = window.Node;
/**
* Internal dependencies
*/
-import { isAttributeWhitelisted } from './utils';
+import { isAttributeWhitelisted, isClassWhitelisted } from './utils';
export default function( node ) {
if ( node.nodeType !== ELEMENT_NODE ) {
@@ -20,10 +20,27 @@ export default function( node ) {
const tag = node.nodeName.toLowerCase();
Array.from( node.attributes ).forEach( ( { name } ) => {
- if ( isAttributeWhitelisted( tag, name ) ) {
+ if ( name === 'class' || isAttributeWhitelisted( tag, name ) ) {
return;
}
node.removeAttribute( name );
} );
+
+ const oldClasses = node.getAttribute( 'class' );
+
+ if ( ! oldClasses ) {
+ return;
+ }
+
+ const newClasses = oldClasses
+ .split( ' ' )
+ .filter( ( name ) => name && isClassWhitelisted( tag, name ) )
+ .join( ' ' );
+
+ if ( newClasses.length ) {
+ node.setAttribute( 'class', newClasses );
+ } else {
+ node.removeAttribute( 'class' );
+ }
}
diff --git a/blocks/api/raw-handling/test/strip-attributes.js b/blocks/api/raw-handling/test/strip-attributes.js
index 43dc12511364df..a68469cb202f4f 100644
--- a/blocks/api/raw-handling/test/strip-attributes.js
+++ b/blocks/api/raw-handling/test/strip-attributes.js
@@ -29,4 +29,8 @@ describe( 'stripAttributes', () => {
it( 'should keep some attributes', () => {
equal( deepFilterHTML( 'test', [ stripAttributes ] ), 'test' );
} );
+
+ it( 'should keep some classes', () => {
+ equal( deepFilterHTML( '
', [ stripAttributes ] ), '
' );
+ } );
} );
diff --git a/blocks/api/raw-handling/utils.js b/blocks/api/raw-handling/utils.js
index 38689919f2c990..777c0796eaafb9 100644
--- a/blocks/api/raw-handling/utils.js
+++ b/blocks/api/raw-handling/utils.js
@@ -49,7 +49,7 @@ const inlineWrapperWhiteList = {
const whitelist = {
...inlineWhitelist,
...inlineWrapperWhiteList,
- img: { attributes: [ 'src', 'alt' ] },
+ img: { attributes: [ 'src', 'alt' ], classes: [ 'alignleft', 'aligncenter', 'alignright', 'alignnone' ] },
figure: {},
blockquote: {},
hr: {},
@@ -100,6 +100,14 @@ export function isInline( node, tagName ) {
return !! inlineWhitelist[ nodeName ] || isInlineForTag( nodeName, tagName );
}
+export function isClassWhitelisted( tag, name ) {
+ return (
+ whitelist[ tag ] &&
+ whitelist[ tag ].classes &&
+ whitelist[ tag ].classes.indexOf( name ) !== -1
+ );
+}
+
export function isInlineWrapper( node ) {
return !! inlineWrapperWhiteList[ node.nodeName.toLowerCase() ];
}
diff --git a/blocks/library/image/index.js b/blocks/library/image/index.js
index 4c94d5f26de71b..1148571aef77a0 100644
--- a/blocks/library/image/index.js
+++ b/blocks/library/image/index.js
@@ -9,7 +9,7 @@ import { createMediaFromFile } from '@wordpress/utils';
*/
import './style.scss';
import './editor.scss';
-import { registerBlockType, createBlock } from '../../api';
+import { registerBlockType, createBlock, getBlockAttributes, getBlockType } from '../../api';
import ImageBlock from './block';
registerBlockType( 'core/image', {
@@ -63,13 +63,22 @@ registerBlockType( 'core/image', {
from: [
{
type: 'raw',
- isMatch: ( node ) => {
+ isMatch( node ) {
const tag = node.nodeName.toLowerCase();
const hasText = !! node.textContent.trim();
const hasImage = node.querySelector( 'img' );
return tag === 'img' || ( hasImage && ! hasText ) || ( hasImage && tag === 'figure' );
},
+ transform( node ) {
+ const targetNode = node.parentNode.querySelector( 'figure,img' );
+ const matches = /align(left|center|right)/.exec( targetNode.className );
+ const align = matches ? matches[ 1 ] : undefined;
+ const blockType = getBlockType( 'core/image' );
+ const attributes = getBlockAttributes( blockType, targetNode.outerHTML, { align } );
+
+ return createBlock( 'core/image', attributes );
+ },
},
{
type: 'files',