src/chunkify.js
/**
 * Omit including containers for text nodes that are for image captions or
 * superscripts. Build list of text nodes first, then remove ones that are
 * omitted (consider weak set), and then concatenate for synthesis followed
 * by iteration. Chunk up nodes by language, queue of stuff to read informed
 * by subsequent element to know pause.
 *
 * @param {Object}          args                        - Arguments
 * @param {Element}         args.containerElement       - Container element.
 * @param {string|Function} args.chunkRootIncludeFilter - CSS selector or function which is used to find chunk root elements.
 * @param {string|Function} args.chunkLeafExcludeFilter - CSS selector or function which is used to exclude text node parent elements inside chunk roots.
 * @returns {Chunk[]} Chunks.
 */
Omit including containers for text nodes that are for image captions or
superscripts. Build list of text nodes first, then remove ones that are
omitted (consider weak set), and then concatenate for synthesis followed
by iteration. Chunk up nodes by language, queue of stuff to read informed
by subsequent element to know pause.

@param {Object}          args                        - Arguments
@param {Element}         args.containerElement       - Container element.
@param {string|Function} args.chunkRootIncludeFilter - CSS selector or function which is used to find chunk root elements.
@param {string|Function} args.chunkLeafExcludeFilter - CSS selector or function which is used to exclude text node parent elements inside chunk roots.
@returns {Chunk[]} Chunks.
Omit including containers for text nodes that are for image captions or superscripts . Build list of text nodes first then remove ones that are omitted ( consider weak set ) and then concatenate for synthesis followed by iteration . Chunk up nodes by language queue of stuff to read informed by subsequent element to know pause . @param { Object } args - Arguments @param { Element } args . containerElement - Container element . @param { string|Function } args . chunkRootIncludeFilter - CSS selector or function which is used to find chunk root elements . @param { string|Function } args . chunkLeafExcludeFilter - CSS selector or function which is used to exclude text node parent elements inside chunk roots . @returns { Chunk [] } Chunks .
function chunkify( {
	containerElement,
	chunkRootIncludeFilter = DEFAULT_ROOT_WHITELIST_SELECTOR,
	chunkLeafExcludeFilter = DEFAULT_LEAF_BLACKLIST_SELECTOR,
} ) {
	let rootIncludeFilter = chunkRootIncludeFilter;
	let leafExcludeFilter = chunkLeafExcludeFilter;
	if ( 'string' === typeof rootIncludeFilter ) {
		const rootIncludeSelector = rootIncludeFilter;
		rootIncludeFilter = ( element ) => element.matches( rootIncludeSelector );
	}
	if ( 'string' === typeof leafExcludeFilter ) {
		const leafExcludeSelector = leafExcludeFilter;
		leafExcludeFilter = ( element ) => element.matches( leafExcludeSelector );
	}
	const chunks = [];
	const rootElementStack = [];
	const addChunkNode = ( textNode, language ) => {
		if ( ! /\w/.test( textNode.nodeValue ) ) {
			return;
		}
		const root = rootElementStack[ rootElementStack.length - 1 ];
		if ( ! root ) {
			return;
		}
		let currentChunk = chunks[ chunks.length - 1 ];
		if ( ! currentChunk || currentChunk.language !== language || root !== currentChunk.root ) {
			currentChunk = {
				language,
				nodes: [],
				root,
			};
			chunks.push( currentChunk );
		}
		currentChunk.nodes.push( textNode );
	};
	const processElement = ( element ) => {
		const elementLanguage = findLanguage( element );
		const isRootChunkElement = rootIncludeFilter( element );
		if ( isRootChunkElement ) {
			rootElementStack.push( element );
		}
		for ( const childNode of element.childNodes ) {
			switch ( childNode.nodeType ) {
				case Node.ELEMENT_NODE:
					if ( ! leafExcludeFilter( childNode ) ) {
						processElement( childNode );
					}
					break;
				case Node.TEXT_NODE:
					if ( 0 !== rootElementStack.length ) {
						addChunkNode( childNode, elementLanguage );
					}
					break;
				default:
					break;
			}
		}
		if ( isRootChunkElement ) {
			rootElementStack.pop();
		}
	};
	processElement( containerElement );
	return chunks;
}
function chunkify ( { containerElement , chunkRootIncludeFilter = DEFAULT_ROOT_WHITELIST_SELECTOR , chunkLeafExcludeFilter = DEFAULT_LEAF_BLACKLIST_SELECTOR , } ) { let rootIncludeFilter = chunkRootIncludeFilter ; let leafExcludeFilter = chunkLeafExcludeFilter ; if ( 'string' === typeof rootIncludeFilter ) { const rootIncludeSelector = rootIncludeFilter ; rootIncludeFilter = ( element ) => element . matches ( rootIncludeSelector ) ; } if ( 'string' === typeof leafExcludeFilter ) { const leafExcludeSelector = leafExcludeFilter ; leafExcludeFilter = ( element ) => element . matches ( leafExcludeSelector ) ; } const chunks = [ ] ; const rootElementStack = [ ] ; const addChunkNode = ( textNode , language ) => { if ( ! / \w / . test ( textNode . nodeValue ) ) { return ; } const root = rootElementStack [ rootElementStack . length - 1 ] ; if ( ! root ) { return ; } let currentChunk = chunks [ chunks . length - 1 ] ; if ( ! currentChunk || currentChunk . language !== language || root !== currentChunk . root ) { currentChunk = { language , nodes : [ ] , root , } ; chunks . push ( currentChunk ) ; } currentChunk . nodes . push ( textNode ) ; } ; const processElement = ( element ) => { const elementLanguage = findLanguage ( element ) ; const isRootChunkElement = rootIncludeFilter ( element ) ; if ( isRootChunkElement ) { rootElementStack . push ( element ) ; } for ( const childNode of element . childNodes ) { switch ( childNode . nodeType ) { case Node . ELEMENT_NODE : if ( ! leafExcludeFilter ( childNode ) ) { processElement ( childNode ) ; } break ; case Node . TEXT_NODE : if ( 0 !== rootElementStack . length ) { addChunkNode ( childNode , elementLanguage ) ; } break ; default : break ; } } if ( isRootChunkElement ) { rootElementStack . pop ( ) ; } } ; processElement ( containerElement ) ; return chunks ; }
Omit including containers for text nodes that are for image captions or
 superscripts.
Omit including containers for text nodes that are for image captions or superscripts .
// Make sure filters are functions when selector strings are supplied. /**
	 * Chunks.
	 *
	 * @type {Chunk[]}
	 */ /**
	 * Root element stack.
	 *
	 * @type {Element[]}
	 */ /**
	 * Add chunk text node.
	 *
	 * @param {Node}   textNode - Text node.
	 * @param {string} language - Language.
	 * @returns {void}
	 */ // Skip nodes that don't contain words. /**
	 * Process element.
	 *
	 * @param {Element} element - DOM Element.
	 * @returns {void}
	 */