68 lines
1.7 KiB
JavaScript
68 lines
1.7 KiB
JavaScript
/**
|
|
* External dependencies
|
|
*/
|
|
import { h } from 'preact';
|
|
|
|
export const hydratedIslands = new WeakSet();
|
|
|
|
// Recursive function that transfoms a DOM tree into vDOM.
|
|
export function toVdom( node ) {
|
|
const props = {};
|
|
const { attributes, childNodes } = node;
|
|
const wpDirectives = {};
|
|
let hasWpDirectives = false;
|
|
let ignore = false;
|
|
let island = false;
|
|
|
|
if ( node.nodeType === 3 ) return node.data;
|
|
if ( node.nodeType === 4 ) {
|
|
node.replaceWith( new Text( node.nodeValue ) );
|
|
return node.nodeValue;
|
|
}
|
|
|
|
for ( let i = 0; i < attributes.length; i++ ) {
|
|
const n = attributes[ i ].name;
|
|
if ( n[ 0 ] === 'w' && n[ 1 ] === 'p' && n[ 2 ] === '-' && n[ 3 ] ) {
|
|
if ( n === 'wp-ignore' ) {
|
|
ignore = true;
|
|
} else if ( n === 'wp-island' ) {
|
|
island = true;
|
|
} else {
|
|
hasWpDirectives = true;
|
|
let val = attributes[ i ].value;
|
|
try {
|
|
val = JSON.parse( val );
|
|
} catch ( e ) {}
|
|
const [ , prefix, suffix ] = /wp-([^:]+):?(.*)$/.exec( n );
|
|
wpDirectives[ prefix ] = wpDirectives[ prefix ] || {};
|
|
wpDirectives[ prefix ][ suffix || 'default' ] = val;
|
|
}
|
|
} else if ( n === 'ref' ) {
|
|
continue;
|
|
} else {
|
|
props[ n ] = attributes[ i ].value;
|
|
}
|
|
}
|
|
|
|
if ( ignore && ! island )
|
|
return h( node.localName, {
|
|
dangerouslySetInnerHTML: { __html: node.innerHTML },
|
|
} );
|
|
if ( island ) hydratedIslands.add( node );
|
|
|
|
if ( hasWpDirectives ) props.wp = wpDirectives;
|
|
|
|
const children = [];
|
|
for ( let i = 0; i < childNodes.length; i++ ) {
|
|
const child = childNodes[ i ];
|
|
if ( child.nodeType === 8 || child.nodeType === 7 ) {
|
|
child.remove();
|
|
i--;
|
|
} else {
|
|
children.push( toVdom( child ) );
|
|
}
|
|
}
|
|
|
|
return h( node.localName, props, children );
|
|
}
|