diff --git a/packages/slate-react/src/plugins/debug/debug-batch-events.js b/packages/slate-react/src/plugins/debug/debug-batch-events.js new file mode 100644 index 000000000..d9f9df849 --- /dev/null +++ b/packages/slate-react/src/plugins/debug/debug-batch-events.js @@ -0,0 +1,111 @@ +import Debug from 'debug' +import EVENT_HANDLERS from '../../constants/event-handlers' +import stringifyEvent from './stringify-event' + +/** + * Constants + */ + +const INTERVAL = 2000 + +/** + * Debug events function. + * + * @type {Function} + */ + +const debug = Debug('slate:batch-events') + +/** + * A plugin that sends short easy to digest debug info about each event to + * browser. + * + * @return {Object} + */ + +function DebugBatchEventsPlugin() { + /** + * When the batch started + * + * @type {Date} + */ + + let startDate = null + + /** + * The timeoutId used to cancel the timeout + * + * @type {Any} + */ + + let timeoutId = null + + /** + * An array of events not yet dumped with `debug` + * + * @type {Array} + */ + + const events = [] + + /** + * Send all events to debug + * + * Note: Formatted so it can easily be cut and pasted as text for analysis or + * documentation. + */ + + function dumpEvents() { + debug(`\n${events.join('\n')}`) + events.length = 0 + } + + /** + * Push an event on to the Array of events for debugging in a batch + * + * @param {Event} event + */ + + function pushEvent(event) { + if (events.length === 0) { + startDate = new Date() + } + + const s = stringifyEvent(event) + const now = new Date() + events.push(`- ${now - startDate} - ${s}`) + clearTimeout(timeoutId) + timeoutId = setTimeout(dumpEvents, INTERVAL) + } + + /** + * Plugin Object + * + * @type {Object} + */ + + const plugin = {} + + for (const eventName of EVENT_HANDLERS) { + plugin[eventName] = function(event, editor, next) { + pushEvent(event) + next() + } + } + + /** + * Return the plugin. + * + * @type {Object} + */ + + return plugin +} + +/** + * Export. + * + * @type {Function} + */ + +export default DebugBatchEventsPlugin diff --git a/packages/slate-react/src/plugins/debug/debug-events.js b/packages/slate-react/src/plugins/debug/debug-events.js new file mode 100644 index 000000000..6eb00f0de --- /dev/null +++ b/packages/slate-react/src/plugins/debug/debug-events.js @@ -0,0 +1,52 @@ +import Debug from 'debug' +import EVENT_HANDLERS from '../../constants/event-handlers' +import stringifyEvent from './stringify-event' + +/** + * Debug events function. + * + * @type {Function} + */ + +const debug = Debug('slate:events') + +/** + * A plugin that sends short easy to digest debug info about each event to + * browser. + * + * @return {Object} + */ + +function DebugEventsPlugin() { + /** + * Plugin Object + * + * @type {Object} + */ + + const plugin = {} + + for (const eventName of EVENT_HANDLERS) { + plugin[eventName] = function(event, editor, next) { + const s = stringifyEvent(event) + debug(s) + next() + } + } + + /** + * Return the plugin. + * + * @type {Object} + */ + + return plugin +} + +/** + * Export. + * + * @type {Function} + */ + +export default DebugEventsPlugin diff --git a/packages/slate-react/src/plugins/debug/index.js b/packages/slate-react/src/plugins/debug/index.js deleted file mode 100644 index 1b6aee4d8..000000000 --- a/packages/slate-react/src/plugins/debug/index.js +++ /dev/null @@ -1,64 +0,0 @@ -import Debug from 'debug' - -/** - * A plugin that adds the "before" browser-specific logic to the editor. - * - * @return {Object} - */ - -function DebugPlugin(namespace) { - /** - * Debug. - * - * @type {Function} - */ - - const debug = Debug(namespace) - - const events = [ - 'onBeforeInput', - 'onBlur', - 'onClick', - 'onCompositionEnd', - 'onCompositionStart', - 'onCopy', - 'onCut', - 'onDragEnd', - 'onDragEnter', - 'onDragExit', - 'onDragLeave', - 'onDragOver', - 'onDragStart', - 'onDrop', - 'onFocus', - 'onInput', - 'onKeyDown', - 'onPaste', - 'onSelect', - ] - - const plugin = {} - - for (const eventName of events) { - plugin[eventName] = function(event, editor, next) { - debug(eventName, { event }) - next() - } - } - - /** - * Return the plugin. - * - * @type {Object} - */ - - return plugin -} - -/** - * Export. - * - * @type {Function} - */ - -export default DebugPlugin diff --git a/packages/slate-react/src/plugins/debug/stringify-event.js b/packages/slate-react/src/plugins/debug/stringify-event.js new file mode 100644 index 000000000..c6ea658a8 --- /dev/null +++ b/packages/slate-react/src/plugins/debug/stringify-event.js @@ -0,0 +1,21 @@ +/** + * Takes a React Synthetic Event or a DOM Event and turns it into a String that + * is easy to log. It's succinct and keeps info to a bare minimum. + * + * @param {Event} event + */ + +export default function stringifyEvent(event) { + const e = event.nativeEvent || event + + switch (e.type) { + case 'keydown': + return `${e.type} ${JSON.stringify(e.key)}` + case 'input': + case 'beforeinput': + case 'textInput': + return `${e.type}:${e.inputType} ${JSON.stringify(e.data)}` + default: + return e.type + } +} diff --git a/packages/slate-react/src/plugins/react/index.js b/packages/slate-react/src/plugins/react/index.js index b70bdc9ec..346c4dd6c 100644 --- a/packages/slate-react/src/plugins/react/index.js +++ b/packages/slate-react/src/plugins/react/index.js @@ -1,3 +1,4 @@ +import Debug from 'debug' import PlaceholderPlugin from 'slate-react-placeholder' import EditorPropsPlugin from './editor-props' @@ -6,6 +7,8 @@ import CommandsPlugin from './commands' import QueriesPlugin from './queries' import DOMPlugin from '../dom' import RestoreDOMPlugin from './restore-dom' +import DebugEventsPlugin from '../debug/debug-events' +import DebugBatchEventsPlugin from '../debug/debug-batch-events' /** * A plugin that adds the React-specific rendering logic to the editor. @@ -16,6 +19,12 @@ import RestoreDOMPlugin from './restore-dom' function ReactPlugin(options = {}) { const { placeholder = '', plugins = [] } = options + const debugEventsPlugin = Debug.enabled('slate:events') + ? DebugEventsPlugin(options) + : null + const debugBatchEventsPlugin = Debug.enabled('slate:batch-events') + ? DebugBatchEventsPlugin(options) + : null const renderingPlugin = RenderingPlugin(options) const commandsPlugin = CommandsPlugin(options) const queriesPlugin = QueriesPlugin(options) @@ -34,6 +43,8 @@ function ReactPlugin(options = {}) { }) return [ + debugEventsPlugin, + debugBatchEventsPlugin, domPlugin, restoreDomPlugin, placeholderPlugin,