Skip to content

Commit

Permalink
Represent Editable value as array tree
Browse files Browse the repository at this point in the history
  • Loading branch information
aduth committed Dec 18, 2017
1 parent 600cb2a commit 20da270
Show file tree
Hide file tree
Showing 16 changed files with 508 additions and 323 deletions.
2 changes: 1 addition & 1 deletion blocks/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ export {
hasBlockSupport,
isReusableBlock,
} from './registration';

export { nodeListToTree } from './matchers';
63 changes: 55 additions & 8 deletions blocks/api/matchers.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,61 @@
/**
* WordPress dependencies
*/
import { createElement } from '@wordpress/element';

/**
* External dependencies
*/
import { nodeListToReact, nodeToReact } from 'dom-react';
export { attr, prop, html, text, query } from 'hpq';

export function buildTree( type, attributes, ...children ) {
children = children.map( ( child ) => {
if ( 'boolean' === typeof child ) {
child = null;
}

if ( null === child || undefined === child ) {
child = '';
} else if ( 'number' === typeof child ) {
child = String( child );
}

if ( 'string' === typeof child ) {
return child;
}

return buildTree( child );
} );

return [ type, attributes, children ];
}

export function nodeListToTree( nodeList, createElement ) {
return [ ...nodeList ].map( ( node ) => nodeToTree( node, createElement ) );
}

export function elementAsArray( type, attributes, children ) {
return [ type, attributes, children ];
}

export function nodeToTree( node, createElement = elementAsArray ) {
if ( ! node ) {
return null;
}

if ( node.nodeType === 3 ) {
return node.nodeValue;
}

if ( node.nodeType !== 1 ) {
return null;
}

const type = node.nodeName.toLowerCase();
const attributes = [ ...node.attributes ].reduce( ( result, { name, value } ) => {
result[ name ] = value;
return result;
}, {} );
const children = nodeListToTree( node.childNodes );

return createElement( type, attributes, children );
}

export const children = ( selector ) => {
return ( domNode ) => {
let match = domNode;
Expand All @@ -18,7 +65,7 @@ export const children = ( selector ) => {
}

if ( match ) {
return nodeListToReact( match.childNodes || [], createElement );
return nodeListToTree( match.childNodes );
}

return [];
Expand All @@ -33,6 +80,6 @@ export const node = ( selector ) => {
match = domNode.querySelector( selector );
}

return nodeToReact( match, createElement );
return nodeToTree( match );
};
};
42 changes: 29 additions & 13 deletions blocks/editable/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
defer,
noop,
} from 'lodash';
import { nodeListToReact } from 'dom-react';
import 'element-closest';

/**
Expand All @@ -28,7 +27,7 @@ import { Slot, Fill } from '@wordpress/components';
* Internal dependencies
*/
import './style.scss';
import { rawHandler } from '../api';
import { rawHandler, nodeListToTree } from '../api';
import FormatToolbar from './format-toolbar';
import TinyMCE from './tinymce';
import { pickAriaProps } from './aria';
Expand All @@ -37,6 +36,23 @@ import { EVENTS } from './constants';

const { BACKSPACE, DELETE, ENTER } = keycodes;

function toElement( value ) {
if ( ! value ) {
return null;
}

if ( ! Array.isArray( value ) ) {
return value;
}

const [ type, attributes, children ] = value;
if ( ! attributes || attributes.constructor !== Object ) {
return value.map( toElement );
}

return createElement( type, attributes, children.map( toElement ) );
}

function createTinyMCEElement( type, props, ...children ) {
if ( props[ 'data-mce-bogus' ] === 'all' ) {
return null;
Expand All @@ -46,11 +62,11 @@ function createTinyMCEElement( type, props, ...children ) {
return children;
}

return createElement(
return [
type,
omitBy( props, ( value, key ) => key.indexOf( 'data-mce-' ) === 0 ),
...children
);
children,
];
}

function isLinkBoundary( fragment ) {
Expand Down Expand Up @@ -559,8 +575,8 @@ export default class Editable extends Component {
const index = dom.nodeIndex( selectedNode );
const beforeNodes = childNodes.slice( 0, index );
const afterNodes = childNodes.slice( index + 1 );
const beforeElement = nodeListToReact( beforeNodes, createTinyMCEElement );
const afterElement = nodeListToReact( afterNodes, createTinyMCEElement );
const beforeElement = nodeListToTree( beforeNodes, createTinyMCEElement );
const afterElement = nodeListToTree( afterNodes, createTinyMCEElement );

this.setContent( beforeElement );
this.props.onSplit( beforeElement, afterElement );
Expand Down Expand Up @@ -614,8 +630,8 @@ export default class Editable extends Component {
const beforeFragment = beforeRange.extractContents();
const afterFragment = afterRange.extractContents();

const beforeElement = nodeListToReact( beforeFragment.childNodes, createTinyMCEElement );
const afterElement = isLinkBoundary( afterFragment ) ? [] : nodeListToReact( afterFragment.childNodes, createTinyMCEElement );
const beforeElement = nodeListToTree( beforeFragment.childNodes, createTinyMCEElement );
const afterElement = isLinkBoundary( afterFragment ) ? [] : nodeListToTree( afterFragment.childNodes, createTinyMCEElement );

this.setContent( beforeElement );
this.props.onSplit( beforeElement, afterElement, ...blocks );
Expand Down Expand Up @@ -668,8 +684,8 @@ export default class Editable extends Component {
this.setContent( this.props.value );

this.props.onSplit(
nodeListToReact( before, createTinyMCEElement ),
nodeListToReact( after, createTinyMCEElement )
nodeListToTree( before, createTinyMCEElement ),
nodeListToTree( after, createTinyMCEElement )
);
}

Expand Down Expand Up @@ -709,7 +725,7 @@ export default class Editable extends Component {
}

getContent() {
return nodeListToReact( this.editor.getBody().childNodes || [], createTinyMCEElement );
return nodeListToTree( this.editor.getBody().childNodes || [], createTinyMCEElement );
}

updateFocus() {
Expand Down Expand Up @@ -862,7 +878,7 @@ export default class Editable extends Component {
getSettings={ this.getSettings }
onSetup={ this.onSetup }
style={ style }
defaultValue={ value }
defaultValue={ toElement( value ) }
isPlaceholderVisible={ isPlaceholderVisible }
aria-label={ placeholder }
{ ...ariaProps }
Expand Down
8 changes: 2 additions & 6 deletions blocks/library/pullquote/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,7 @@ registerBlockType( 'core/pullquote', {

return (
<blockquote className={ `align${ align }` }>
{ value && value.map( ( paragraph, i ) =>
<p key={ i }>{ paragraph.children && paragraph.children.props.children }</p>
) }
{ value.map( ( paragraph ) => paragraph.children ) }
{ citation && citation.length > 0 && (
<cite>{ citation }</cite>
) }
Expand All @@ -145,9 +143,7 @@ registerBlockType( 'core/pullquote', {

return (
<blockquote className={ `align${ align }` }>
{ value && value.map( ( paragraph, i ) =>
<p key={ i }>{ paragraph.children && paragraph.children.props.children }</p>
) }
{ value.map( ( paragraph ) => paragraph.children ) }
{ citation && citation.length > 0 && (
<footer>{ citation }</footer>
) }
Expand Down
8 changes: 2 additions & 6 deletions blocks/library/quote/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,7 @@ registerBlockType( 'core/quote', {
className={ style === 2 ? 'is-large' : '' }
style={ { textAlign: align ? align : null } }
>
{ value.map( ( paragraph, i ) => (
<p key={ i }>{ paragraph.children && paragraph.children.props.children }</p>
) ) }
{ value.map( ( paragraph ) => paragraph.children ) }
{ citation && citation.length > 0 && (
<cite>{ citation }</cite>
) }
Expand All @@ -267,9 +265,7 @@ registerBlockType( 'core/quote', {
className={ `blocks-quote-style-${ style }` }
style={ { textAlign: align ? align : null } }
>
{ value.map( ( paragraph, i ) => (
<p key={ i }>{ paragraph.children && paragraph.children.props.children }</p>
) ) }
{ value.map( ( paragraph ) => paragraph.children ) }
{ citation && citation.length > 0 && (
<footer>{ citation }</footer>
) }
Expand Down
11 changes: 7 additions & 4 deletions blocks/test/fixtures/core__heading__h2-em.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
"attributes": {
"content": [
"The ",
{
"type": "em",
"children": "Inserter"
},
[
"em",
{},
[
"Inserter"
]
],
" Tool"
],
"nodeName": "H2"
Expand Down
75 changes: 47 additions & 28 deletions blocks/test/fixtures/core__list__ul.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,56 @@
"attributes": {
"nodeName": "UL",
"values": [
{
"type": "li",
"children": "Text & Headings"
},
{
"type": "li",
"children": "Images & Videos"
},
{
"type": "li",
"children": "Galleries"
},
{
"type": "li",
"children": "Embeds, like YouTube, Tweets, or other WordPress posts."
},
{
"type": "li",
"children": "Layout blocks, like Buttons, Hero Images, Separators, etc."
},
{
"type": "li",
"children": [
[
"li",
{},
[
"Text & Headings"
]
],
[
"li",
{},
[
"Images & Videos"
]
],
[
"li",
{},
[
"Galleries"
]
],
[
"li",
{},
[
"Embeds, like YouTube, Tweets, or other WordPress posts."
]
],
[
"li",
{},
[
"Layout blocks, like Buttons, Hero Images, Separators, etc."
]
],
[
"li",
{},
[
"And ",
{
"type": "em",
"children": "Lists"
},
[
"em",
{},
[
"Lists"
]
],
" like this one of course :)"
]
}
]
]
},
"originalContent": "<ul><li>Text & Headings</li><li>Images & Videos</li><li>Galleries</li><li>Embeds, like YouTube, Tweets, or other WordPress posts.</li><li>Layout blocks, like Buttons, Hero Images, Separators, etc.</li><li>And <em>Lists</em> like this one of course :)</li></ul>"
Expand Down
19 changes: 12 additions & 7 deletions blocks/test/fixtures/core__preformatted.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,19 @@
"attributes": {
"content": [
"Some ",
{
"type": "em",
"children": "preformatted"
},
[
"em",
{},
[
"preformatted"
]
],
" text...",
{
"type": "br"
},
[
"br",
{},
[]
],
"And more!"
]
},
Expand Down
17 changes: 7 additions & 10 deletions blocks/test/fixtures/core__pullquote.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,13 @@
"attributes": {
"value": [
{
"children": {
"type": "p",
"key": null,
"ref": null,
"props": {
"children": "Testing pullquote block..."
},
"_owner": null,
"_store": {}
}
"children": [
"p",
{},
[
"Testing pullquote block..."
]
]
}
],
"citation": [
Expand Down
Loading

0 comments on commit 20da270

Please sign in to comment.