diff options
| author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2019-08-25 21:13:17 -0400 | 
|---|---|---|
| committer | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2019-09-02 19:33:52 -0400 | 
| commit | 71471d08e56f1a2431e67d0439724cc52a1ea73e (patch) | |
| tree | e6562c5418195c4254026f3a34c41bea2500c1a7 /ext | |
| parent | 3491affcf13ef10b78714d4955da6ee9aeb11457 (diff) | |
Add option to enable/disable scanning of source expressions in popups
Diffstat (limited to 'ext')
| -rw-r--r-- | ext/bg/js/options.js | 1 | ||||
| -rw-r--r-- | ext/bg/js/settings.js | 2 | ||||
| -rw-r--r-- | ext/bg/settings.html | 4 | ||||
| -rw-r--r-- | ext/fg/js/frontend.js | 86 | ||||
| -rw-r--r-- | ext/fg/js/popup-nested.js | 4 | 
5 files changed, 89 insertions, 8 deletions
| diff --git a/ext/bg/js/options.js b/ext/bg/js/options.js index 1b2d5e1a..df95aae9 100644 --- a/ext/bg/js/options.js +++ b/ext/bg/js/options.js @@ -221,6 +221,7 @@ function optionsSetDefaults(options) {              modifier: 'shift',              deepDomScan: false,              popupNestingMaxDepth: 0, +            enableOnPopupExpressions: false,              enableOnSearchPage: true          }, diff --git a/ext/bg/js/settings.js b/ext/bg/js/settings.js index 5472c7bd..83f4528c 100644 --- a/ext/bg/js/settings.js +++ b/ext/bg/js/settings.js @@ -48,6 +48,7 @@ async function formRead() {      optionsNew.scanning.alphanumeric = $('#search-alphanumeric').prop('checked');      optionsNew.scanning.autoHideResults = $('#auto-hide-results').prop('checked');      optionsNew.scanning.deepDomScan = $('#deep-dom-scan').prop('checked'); +    optionsNew.scanning.enableOnPopupExpressions = $('#enable-scanning-of-popup-expressions').prop('checked');      optionsNew.scanning.enableOnSearchPage = $('#enable-scanning-on-search-page').prop('checked');      optionsNew.scanning.delay = parseInt($('#scan-delay').val(), 10);      optionsNew.scanning.length = parseInt($('#scan-length').val(), 10); @@ -191,6 +192,7 @@ async function onReady() {      $('#search-alphanumeric').prop('checked', options.scanning.alphanumeric);      $('#auto-hide-results').prop('checked', options.scanning.autoHideResults);      $('#deep-dom-scan').prop('checked', options.scanning.deepDomScan); +    $('#enable-scanning-of-popup-expressions').prop('checked', options.scanning.enableOnPopupExpressions);      $('#enable-scanning-on-search-page').prop('checked', options.scanning.enableOnSearchPage);      $('#scan-delay').val(options.scanning.delay);      $('#scan-length').val(options.scanning.length); diff --git a/ext/bg/settings.html b/ext/bg/settings.html index 0005efa6..85b7ee5f 100644 --- a/ext/bg/settings.html +++ b/ext/bg/settings.html @@ -192,6 +192,10 @@                      <label><input type="checkbox" id="auto-hide-results"> Automatically hide results</label>                  </div> +                <div class="checkbox options-advanced"> +                    <label><input type="checkbox" id="enable-scanning-of-popup-expressions"> Enable scanning of popup expressions</label> +                </div> +                  <div class="checkbox">                      <label><input type="checkbox" id="enable-scanning-on-search-page"> Enable scanning on search page</label>                  </div> diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 3605dffd..f59ea318 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -18,7 +18,7 @@  class Frontend { -    constructor(popup) { +    constructor(popup, ignoreNodes) {          this.popup = popup;          this.popupTimer = null;          this.mouseDownLeft = false; @@ -26,6 +26,7 @@ class Frontend {          this.textSourceLast = null;          this.pendingLookup = false;          this.options = null; +        this.ignoreNodes = (Array.isArray(ignoreNodes) && ignoreNodes.length > 0 ? ignoreNodes.join(',') : null);          this.primaryTouchIdentifier = null;          this.contextMenuChecking = false; @@ -39,10 +40,10 @@ class Frontend {      static create() {          const initializationData = window.frontendInitializationData;          const isNested = (initializationData !== null && typeof initializationData === 'object'); -        const {id, parentFrameId} = initializationData || {}; +        const {id, parentFrameId, ignoreNodes} = isNested ? initializationData : {};          const popup = isNested ? new PopupProxy(id, parentFrameId) : PopupProxyHost.instance.createPopup(null); -        const frontend = new Frontend(popup); +        const frontend = new Frontend(popup, ignoreNodes);          frontend.prepare();          return frontend;      } @@ -337,9 +338,14 @@ class Frontend {      }      async searchTerms(textSource, focus) { -        textSource.setEndOffset(this.options.scanning.length); +        this.setTextSourceScanLength(textSource, this.options.scanning.length); -        const {definitions, length} = await apiTermsFind(textSource.text()); +        const searchText = textSource.text(); +        if (searchText.length === 0) { +            return; +        } + +        const {definitions, length} = await apiTermsFind(searchText);          if (definitions.length === 0) {              return false;          } @@ -365,9 +371,14 @@ class Frontend {      }      async searchKanji(textSource, focus) { -        textSource.setEndOffset(1); +        this.setTextSourceScanLength(textSource, 1); -        const definitions = await apiKanjiFind(textSource.text()); +        const searchText = textSource.text(); +        if (searchText.length === 0) { +            return; +        } + +        const definitions = await apiKanjiFind(searchText);          if (definitions.length === 0) {              return false;          } @@ -493,6 +504,67 @@ class Frontend {          }          return false;      } + +    setTextSourceScanLength(textSource, length) { +        textSource.setEndOffset(length); +        if (this.ignoreNodes === null || !textSource.range) { +            return; +        } + +        length = textSource.text().length; +        while (textSource.range && length > 0) { +            const nodes = Frontend.getNodesInRange(textSource.range); +            if (Frontend.isValidScanningNodeList(nodes, this.ignoreNodes)) { +                break; +            } +            --length; +            textSource.setEndOffset(length); +        } +    } + +    static getNodesInRange(range) { +        const end = range.endContainer; +        const nodes = []; +        for (let node = range.startContainer; node !== null; node = Frontend.getNextNode(node)) { +            nodes.push(node); +            if (node === end) { break; } +        } +        return nodes; +    } + +    static getNextNode(node) { +        let next = node.firstChild; +        if (next === null) { +            while (true) { +                next = node.nextSibling; +                if (next !== null) { break; } + +                next = node.parentNode; +                if (node === null) { break; } + +                node = next; +            } +        } +        return next; +    } + +    static isValidScanningNodeList(nodeList, selector) { +        for (const node of nodeList) { +            if (!Frontend.isValidScanningNode(node, selector)) { +                return false; +            } +        } +        return true; +    } + +    static isValidScanningNode(node, selector) { +        for (; node !== null; node = node.parentNode) { +            if (node.nodeType === Node.ELEMENT_NODE) { +                return !node.matches(selector); +            } +        } +        return true; +    }  }  window.yomichan_frontend = Frontend.create(); diff --git a/ext/fg/js/popup-nested.js b/ext/fg/js/popup-nested.js index ad235cc6..e0376bb2 100644 --- a/ext/fg/js/popup-nested.js +++ b/ext/fg/js/popup-nested.js @@ -32,7 +32,9 @@ async function popupNestedInitialize(id, depth, parentFrameId) {          return;      } -    window.frontendInitializationData = {id, depth, parentFrameId}; +    const ignoreNodes = options.scanning.enableOnPopupExpressions ? [] : [ '.expression', '.expression *' ]; + +    window.frontendInitializationData = {id, depth, parentFrameId, ignoreNodes};      const scriptSrcs = [          '/fg/js/frontend-api-sender.js', |