ckeditor5-image-upload-base64
Version:
The development environment of CKEditor 5 – the best browser-based rich text editor.
90 lines (71 loc) • 2.5 kB
JavaScript
/**
* @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/
/**
* @module watchdog/utils/getsubnodes
*/
/* globals EventTarget, Event */
export default function getSubNodes( head, excludedProperties = new Set() ) {
const nodes = [ head ];
// @if CK_DEBUG_WATCHDOG // const prevNodeMap = new Map();
// Nodes are stored to prevent infinite looping.
const subNodes = new Set();
while ( nodes.length > 0 ) {
const node = nodes.shift();
if ( subNodes.has( node ) || shouldNodeBeSkipped( node ) || excludedProperties.has( node ) ) {
continue;
}
subNodes.add( node );
// Handle arrays, maps, sets, custom collections that implements `[ Symbol.iterator ]()`, etc.
if ( node[ Symbol.iterator ] ) {
// The custom editor iterators might cause some problems if the editor is crashed.
try {
for ( const n of node ) {
nodes.push( n );
// @if CK_DEBUG_WATCHDOG // if ( !prevNodeMap.has( n ) ) {
// @if CK_DEBUG_WATCHDOG // prevNodeMap.set( n, node );
// @if CK_DEBUG_WATCHDOG // }
}
} catch ( err ) {
// Do not log errors for broken structures
// since we are in the error handling process already.
// eslint-disable-line no-empty
}
} else {
for ( const key in node ) {
// We share a reference via the protobuf library within the editors,
// hence the shared value should be skipped. Although, it's not a perfect
// solution since new places like that might occur in the future.
if ( key === 'defaultValue' ) {
continue;
}
nodes.push( node[ key ] );
// @if CK_DEBUG_WATCHDOG // if ( !prevNodeMap.has( node[ key ] ) ) {
// @if CK_DEBUG_WATCHDOG // prevNodeMap.set( node[ key ], node );
// @if CK_DEBUG_WATCHDOG // }
}
}
}
// @if CK_DEBUG_WATCHDOG // return { subNodes, prevNodeMap };
return subNodes;
}
function shouldNodeBeSkipped( node ) {
const type = Object.prototype.toString.call( node );
const typeOfNode = typeof node;
return (
typeOfNode === 'number' ||
typeOfNode === 'boolean' ||
typeOfNode === 'string' ||
typeOfNode === 'symbol' ||
typeOfNode === 'function' ||
type === '[object Date]' ||
type === '[object RegExp]' ||
type === '[object Module]' ||
node === undefined ||
node === null ||
// Skip native DOM objects, e.g. Window, nodes, events, etc.
node instanceof EventTarget ||
node instanceof Event
);
}