Fix text selection during scanning (#1508)

* Move function

* Add _onSearchClick function

* Move _onSearchClick after event prevention

* Prevent search if selection is changed before a click occurs
This commit is contained in:
toasted-nutbread 2021-03-09 20:01:37 -05:00 committed by GitHub
parent c6f4144fda
commit 4f4990820e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -71,6 +71,11 @@ class TextScanner extends EventDispatcher {
this._enabledValue = false; this._enabledValue = false;
this._eventListeners = new EventListenerCollection(); this._eventListeners = new EventListenerCollection();
this._preventNextClickScan = false;
this._preventNextClickScanTimer = null;
this._preventNextClickScanTimerDuration = 50;
this._preventNextClickScanTimerCallback = this._onPreventNextClickScanTimeout.bind(this);
this._primaryTouchIdentifier = null; this._primaryTouchIdentifier = null;
this._preventNextContextMenu = false; this._preventNextContextMenu = false;
this._preventNextMouseDown = false; this._preventNextMouseDown = false;
@ -350,6 +355,30 @@ class TextScanner extends EventDispatcher {
return results; return results;
} }
_resetPreventNextClickScan() {
this._preventNextClickScan = false;
if (this._preventNextClickScanTimer !== null) { clearTimeout(this._preventNextClickScanTimer); }
this._preventNextClickScanTimer = setTimeout(this._preventNextClickScanTimerCallback, this._preventNextClickScanTimerDuration);
}
_onPreventNextClickScanTimeout() {
this._preventNextClickScanTimer = null;
}
_onSelectionChange() {
if (this._preventNextClickScanTimer !== null) { return; } // Ignore deselection that occurs at the start of the click
this._preventNextClickScan = true;
}
_onSearchClickMouseDown(e) {
if (e.button !== 0) { return; }
this._resetPreventNextClickScan();
}
_onSearchClickTouchStart() {
this._resetPreventNextClickScan();
}
_onMouseOver(e) { _onMouseOver(e) {
if (this._ignoreElements !== null && this._ignoreElements().includes(e.target)) { if (this._ignoreElements !== null && this._ignoreElements().includes(e.target)) {
this._scanTimerClear(); this._scanTimerClear();
@ -376,6 +405,7 @@ class TextScanner extends EventDispatcher {
switch (e.button) { switch (e.button) {
case 0: // Primary case 0: // Primary
if (this._searchOnClick) { this._resetPreventNextClickScan(); }
this._scanTimerClear(); this._scanTimerClear();
this.clearSelection(false); this.clearSelection(false);
break; break;
@ -394,19 +424,32 @@ class TextScanner extends EventDispatcher {
} }
_onClick(e) { _onClick(e) {
if (this._searchOnClick) {
const modifiers = DocumentUtil.getActiveModifiersAndButtons(e);
const modifierKeys = DocumentUtil.getActiveModifiers(e);
const inputInfo = this._createInputInfo(null, 'mouse', 'click', false, modifiers, modifierKeys);
this._searchAt(e.clientX, e.clientY, inputInfo);
}
if (this._preventNextClick) { if (this._preventNextClick) {
this._preventNextClick = false; this._preventNextClick = false;
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
return false; return false;
} }
if (this._searchOnClick) {
this._onSearchClick(e);
}
}
_onSearchClick(e) {
const preventNextClickScan = this._preventNextClickScan;
this._preventNextClickScan = false;
if (this._preventNextClickScanTimer !== null) {
clearTimeout(this._preventNextClickScanTimer);
this._preventNextClickScanTimer = null;
}
if (preventNextClickScan) { return; }
const modifiers = DocumentUtil.getActiveModifiersAndButtons(e);
const modifierKeys = DocumentUtil.getActiveModifiers(e);
const inputInfo = this._createInputInfo(null, 'mouse', 'click', false, modifiers, modifierKeys);
this._searchAt(e.clientX, e.clientY, inputInfo);
} }
_onAuxClick() { _onAuxClick() {
@ -687,6 +730,9 @@ class TextScanner extends EventDispatcher {
eventListenerInfos.push(...this._getTouchEventListeners()); eventListenerInfos.push(...this._getTouchEventListeners());
} }
} }
if (this._searchOnClick) {
eventListenerInfos.push(...this._getMouseClickOnlyEventListeners2());
}
for (const args of eventListenerInfos) { for (const args of eventListenerInfos) {
this._eventListeners.addEventListener(...args); this._eventListeners.addEventListener(...args);
@ -718,11 +764,6 @@ class TextScanner extends EventDispatcher {
]; ];
} }
_getMouseClickOnlyEventListeners() {
return [
[this._node, 'click', this._onClick.bind(this)]
];
}
_getTouchEventListeners() { _getTouchEventListeners() {
return [ return [
[this._node, 'auxclick', this._onAuxClick.bind(this)], [this._node, 'auxclick', this._onAuxClick.bind(this)],
@ -734,6 +775,26 @@ class TextScanner extends EventDispatcher {
]; ];
} }
_getMouseClickOnlyEventListeners() {
return [
[this._node, 'click', this._onClick.bind(this)]
];
}
_getMouseClickOnlyEventListeners2() {
const {documentElement} = document;
const entries = [
[document, 'selectionchange', this._onSelectionChange.bind(this)]
];
if (documentElement !== null) {
entries.push([documentElement, 'mousedown', this._onSearchClickMouseDown.bind(this)]);
if (this._touchInputEnabled) {
entries.push([documentElement, 'touchstart', this._onSearchClickTouchStart.bind(this)]);
}
}
return entries;
}
_getTouch(touchList, identifier) { _getTouch(touchList, identifier) {
for (const touch of touchList) { for (const touch of touchList) {
if (touch.identifier === identifier) { if (touch.identifier === identifier) {