From f269276b0521bbada41ca81cd6aadece89089e17 Mon Sep 17 00:00:00 2001 From: Jason Chen Date: Mon, 3 Jul 2017 23:49:02 -0700 Subject: [PATCH] implement and use selectionchange related #1522 --- core/emitter.js | 28 ++++++++++++++++++++++++++++ core/selection.js | 10 +++------- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/core/emitter.js b/core/emitter.js index 2a959623f5..e5bfd8843b 100644 --- a/core/emitter.js +++ b/core/emitter.js @@ -3,10 +3,23 @@ import logger from './logger'; let debug = logger('quill:events'); +const EVENTS = ['selectionchange']; + +EVENTS.forEach(function(eventName) { + document.addEventListener(eventName, (...args) => { + document.querySelectorAll('.ql-container').forEach((node) => { + // TODO use WeakMap + if (node.__quill && node.__quill.emitter) { + node.__quill.emitter.handleDOM(...args); + } + }); + }); +}); class Emitter extends EventEmitter { constructor() { super(); + this.listeners = {}; this.on('error', debug.error); } @@ -14,6 +27,21 @@ class Emitter extends EventEmitter { debug.log.apply(debug, arguments); super.emit.apply(this, arguments); } + + handleDOM(...args) { + (this.listeners[event.type] || []).forEach(function({ node, handler }) { + if (event.target === node) { + handler(...args); + } + }); + } + + listenDOM(eventName, node, handler) { + if (!this.listeners[eventName]) { + this.listeners[eventName] = []; + } + this.listeners[eventName].push({ node, handler }) + } } Emitter.events = { diff --git a/core/selection.js b/core/selection.js index a5fb6ae80f..aa743c4714 100644 --- a/core/selection.js +++ b/core/selection.js @@ -31,13 +31,6 @@ class Selection { this.cursor = Parchment.create('cursor', this); // savedRange is last non-null range this.lastRange = this.savedRange = new Range(0, 0); - ['keyup', 'mouseup', 'mouseleave', 'touchend', 'touchleave', 'focus', 'blur'].forEach((eventName) => { - this.root.addEventListener(eventName, () => { - // When range used to be a selection and user click within the selection, - // the range now being a cursor has not updated yet without setTimeout - setTimeout(this.update.bind(this, Emitter.sources.USER), 100); - }); - }); this.root.addEventListener('click', (e) => { const blot = Parchment.find(e.target, true); const selectedNode = document.querySelector('.ql-embed-selected'); @@ -51,6 +44,9 @@ class Selection { e.stopPropagation(); } }); + this.emitter.listenDOM('selectionchange', document, () => { + this.update(Emitter.sources.USER); + }); this.emitter.on(Emitter.events.EDITOR_CHANGE, (type, delta) => { if (type === Emitter.events.TEXT_CHANGE && delta.length() > 0) { this.update(Emitter.sources.SILENT);