From 96cb419ccbfd82f563957c542d2957f9fc936d48 Mon Sep 17 00:00:00 2001 From: Sunny Hirai Date: Wed, 22 May 2019 18:21:20 -0700 Subject: [PATCH] Second attempt at Debug Mutations (#2823) * Add debug-mutations * Fix linting * Add debug-mutations to o core plugins * Fix debug output * Add comment about debug statement * Add comment explaining the building of debug output object --- .../src/plugins/debug/debug-mutations.js | 77 +++++++++++++++++++ .../slate-react/src/plugins/react/index.js | 5 ++ 2 files changed, 82 insertions(+) create mode 100644 packages/slate-react/src/plugins/debug/debug-mutations.js diff --git a/packages/slate-react/src/plugins/debug/debug-mutations.js b/packages/slate-react/src/plugins/debug/debug-mutations.js new file mode 100644 index 000000000..aad6e0c0b --- /dev/null +++ b/packages/slate-react/src/plugins/debug/debug-mutations.js @@ -0,0 +1,77 @@ +import Debug from 'debug' + +/** + * Debug mutations function. + * + * @type {Function} + */ + +const debug = Debug('slate:mutations') + +/** + * Properties on a MutationRecord + * + * @type {Object} + */ + +const MUTATION_PROPERTIES = [ + 'type', + 'oldValue', + 'target', + 'addedNodes', + 'removedNodes', + 'attributeName', + 'attributeNamespace', + 'nextSibling', + 'previousSibling', +] + +/** + * A plugin that sends short easy to digest debug info about each dom mutation + * to browser. + * + * More information about mutations here: + * + * + * + * + * @param {Object} options + */ + +function DebugMutationsPlugin({ editor }) { + const observer = new window.MutationObserver(mutations => { + const array = Array.from(mutations).map(mutationRecord => { + const object = {} + + // Only add properties that provide meaningful values to the object + // to make the debug info easier to read + MUTATION_PROPERTIES.forEach(key => { + const value = mutationRecord[key] + if (value == null) return + if (value instanceof window.NodeList && value.length === 0) return + object[key] = value + }) + + return object + }) + + // The first argument must not be the array as `debug` renders the first + // argument in a different way than the rest + debug(`${array.length} Mutations`, ...array) + }) + + // `findDOMNode` does not exist until later so we use `setTimeout` + setTimeout(() => { + const rootEl = editor.findDOMNode([]) + + observer.observe(rootEl, { + childList: true, + characterData: true, + attributes: true, + subtree: true, + characterDataOldValue: true, + }) + }) +} + +export default DebugMutationsPlugin diff --git a/packages/slate-react/src/plugins/react/index.js b/packages/slate-react/src/plugins/react/index.js index 346c4dd6c..4fd912db2 100644 --- a/packages/slate-react/src/plugins/react/index.js +++ b/packages/slate-react/src/plugins/react/index.js @@ -9,6 +9,7 @@ import DOMPlugin from '../dom' import RestoreDOMPlugin from './restore-dom' import DebugEventsPlugin from '../debug/debug-events' import DebugBatchEventsPlugin from '../debug/debug-batch-events' +import DebugMutationsPlugin from '../debug/debug-mutations' /** * A plugin that adds the React-specific rendering logic to the editor. @@ -25,6 +26,9 @@ function ReactPlugin(options = {}) { const debugBatchEventsPlugin = Debug.enabled('slate:batch-events') ? DebugBatchEventsPlugin(options) : null + const debugMutationsPlugin = Debug.enabled('slate:mutations') + ? DebugMutationsPlugin(options) + : null const renderingPlugin = RenderingPlugin(options) const commandsPlugin = CommandsPlugin(options) const queriesPlugin = QueriesPlugin(options) @@ -45,6 +49,7 @@ function ReactPlugin(options = {}) { return [ debugEventsPlugin, debugBatchEventsPlugin, + debugMutationsPlugin, domPlugin, restoreDomPlugin, placeholderPlugin,