Skip to content
This repository has been archived by the owner on Feb 25, 2023. It is now read-only.

Delay hide option #774

Merged
merged 5 commits into from
Sep 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions ext/bg/data/options-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@
"alphanumeric",
"autoHideResults",
"delay",
"hideDelay",
"length",
"modifier",
"deepDomScan",
Expand Down Expand Up @@ -360,6 +361,11 @@
"minimum": 0,
"default": 20
},
"hideDelay": {
"type": "number",
"minimum": 0,
"default": 0
},
"length": {
"type": "integer",
"minimum": 1,
Expand Down
2 changes: 2 additions & 0 deletions ext/bg/js/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,7 @@ class OptionsUtil {
// Options conditions converted to string representations.
// Added usePopupWindow.
// Updated handlebars templates to include "clipboard-image" definition.
// Added hideDelay.
for (const {conditionGroups} of options.profiles) {
for (const {conditions} of conditionGroups) {
for (const condition of conditions) {
Expand All @@ -487,6 +488,7 @@ class OptionsUtil {
}
for (const {options: profileOptions} of options.profiles) {
profileOptions.general.usePopupWindow = false;
profileOptions.scanning.hideDelay = 0;
}
await this._addFieldTemplatesToOptions(options, '/bg/data/anki-field-templates-upgrade-v4.handlebars');
return options;
Expand Down
12 changes: 10 additions & 2 deletions ext/bg/settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -415,8 +415,16 @@ <h3>Scanning Options</h3>
</div>

<div class="form-group options-advanced">
<label for="scan-delay">Scan delay <span class="label-light">(in milliseconds)</span></label>
<input type="number" min="0" id="scan-delay" class="form-control" data-setting="scanning.delay">
<div class="row">
<div class="col-xs-6">
<label for="scan-delay">Scan delay <span class="label-light">(in milliseconds)</span></label>
<input type="number" min="0" id="scan-delay" class="form-control" data-setting="scanning.delay">
</div>
<div class="col-xs-6">
<label for="scan-close-delay">Auto-hide delay <span class="label-light">(in milliseconds)</span></label>
<input type="number" min="0" id="scan-close-delay" class="form-control" data-setting="scanning.hideDelay">
</div>
</div>
</div>

<div class="form-group options-advanced">
Expand Down
64 changes: 55 additions & 9 deletions ext/fg/js/frontend.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ class Frontend {
this._popupFactory = popupFactory;
this._allowRootFramePopupProxy = allowRootFramePopupProxy;
this._popupCache = new Map();
this._popupEventListeners = new EventListenerCollection();
this._updatePopupToken = null;
this._clearSelectionTimer = null;
this._isPointerOverPopup = false;

this._runtimeMessageHandlers = new Map([
['requestFrontendReadyBroadcast', {async: false, handler: this._onMessageRequestFrontendReadyBroadcast.bind(this)}]
Expand Down Expand Up @@ -175,7 +178,7 @@ class Frontend {
}

_onApiClosePopup() {
this._textScanner.clearSelection(false);
this._clearSelection(false);
}

_onApiCopySelection() {
Expand Down Expand Up @@ -232,9 +235,11 @@ class Frontend {
}

_onClearSelection({passive}) {
this._stopClearSelectionDelayed();
if (this._popup !== null) {
this._popup.hide(!passive);
this._popup.clearAutoPlayTimer();
this._isPointerOverPopup = false;
}
this._updatePendingOptions();
}
Expand All @@ -249,24 +254,61 @@ class Frontend {
await this.updateOptions();
}

_onSearched({textScanner, type, definitions, sentence, input: {cause}, textSource, optionsContext, error}) {
_onSearched({type, definitions, sentence, input: {cause}, textSource, optionsContext, error}) {
const scanningOptions = this._options.scanning;

if (error !== null) {
if (yomichan.isExtensionUnloaded) {
if (textSource !== null && this._options.scanning.modifier !== 'none') {
if (textSource !== null && scanningOptions.modifier !== 'none') {
this._showExtensionUnloaded(textSource);
}
} else {
yomichan.logError(error);
}
} if (type !== null) {
this._stopClearSelectionDelayed();
const focus = (cause === 'mouse');
this._showContent(textSource, focus, definitions, type, sentence, optionsContext);
} else {
if (type !== null) {
const focus = (cause === 'mouse');
this._showContent(textSource, focus, definitions, type, sentence, optionsContext);
if (scanningOptions.autoHideResults) {
this._clearSelectionDelayed(scanningOptions.hideDelay, false);
}
}
}

_onPopupFramePointerOver() {
this._isPointerOverPopup = true;
this._stopClearSelectionDelayed();
}

_onPopupFramePointerOut() {
this._isPointerOverPopup = false;
}

_clearSelection(passive) {
this._stopClearSelectionDelayed();
this._textScanner.clearSelection(passive);
}

_clearSelectionDelayed(delay, restart, passive) {
if (!this._textScanner.hasSelection()) { return; }
if (delay > 0) {
if (this._clearSelectionTimer !== null && !restart) { return; } // Already running
this._stopClearSelectionDelayed();
this._clearSelectionTimer = setTimeout(() => {
this._clearSelectionTimer = null;
if (this._isPointerOverPopup) { return; }
this._clearSelection(passive);
}, delay);
} else {
this._clearSelection(passive);
}
}

if (type === null && this._options.scanning.autoHideResults) {
textScanner.clearSelection(false);
_stopClearSelectionDelayed() {
if (this._clearSelectionTimer !== null) {
clearTimeout(this._clearSelectionTimer);
this._clearSelectionTimer = null;
}
}

Expand Down Expand Up @@ -354,8 +396,12 @@ class Frontend {
this.setDisabledOverride(!this._options.scanning.enableOnSearchPage);
}

this._textScanner.clearSelection(true);
this._clearSelection(true);
this._popupEventListeners.removeAllEventListeners();
this._popup = popup;
this._popupEventListeners.on(popup, 'framePointerOver', this._onPopupFramePointerOver.bind(this));
this._popupEventListeners.on(popup, 'framePointerOut', this._onPopupFramePointerOut.bind(this));
this._isPointerOverPopup = false;
}

async _getDefaultPopup() {
Expand Down
10 changes: 10 additions & 0 deletions ext/fg/js/popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ class Popup extends EventDispatcher {
// Public functions

prepare() {
this._frame.addEventListener('mouseover', this._onFrameMouseOver.bind(this));
this._frame.addEventListener('mouseout', this._onFrameMouseOut.bind(this));
this._frame.addEventListener('mousedown', (e) => e.stopPropagation());
this._frame.addEventListener('scroll', (e) => e.stopPropagation());
this._frame.addEventListener('load', this._onFrameLoad.bind(this));
Expand Down Expand Up @@ -207,6 +209,14 @@ class Popup extends EventDispatcher {

// Private functions

_onFrameMouseOver() {
this.trigger('framePointerOver', {});
}

_onFrameMouseOut() {
this.trigger('framePointerOut', {});
}

_inject() {
let injectPromise = this._injectPromise;
if (injectPromise === null) {
Expand Down
4 changes: 4 additions & 0 deletions ext/mixed/js/text-scanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ class TextScanner extends EventDispatcher {
return clonedTextSource.text();
}

hasSelection() {
return (this._textSourceCurrent !== null);
}

clearSelection(passive) {
if (!this._canClearSelection) { return; }
if (this._textSourceCurrent !== null) {
Expand Down