UNPKG

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
/** * @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 ); }