diff options
| author | Alex Yatskov <alex@foosoft.net> | 2017-05-25 23:06:10 -0700 | 
|---|---|---|
| committer | Alex Yatskov <alex@foosoft.net> | 2017-05-25 23:06:10 -0700 | 
| commit | 16baf9a400ac11a1c4f53ba6665db03a900511e0 (patch) | |
| tree | 685096179093f112a9263f15d3cf081f50e9634d /ext/fg/js | |
| parent | 1cdf496824709b4e4579d700c333e832d790925e (diff) | |
| parent | 618a3cb319c247c7196b1b83389d5f43241ab0c6 (diff) | |
Merge branch 'master' into firefox-amo
Diffstat (limited to 'ext/fg/js')
| -rw-r--r-- | ext/fg/js/driver.js | 21 | ||||
| -rw-r--r-- | ext/fg/js/source-element.js | 33 | ||||
| -rw-r--r-- | ext/fg/js/source-range.js | 90 | ||||
| -rw-r--r-- | ext/fg/js/util.js | 22 | 
4 files changed, 102 insertions, 64 deletions
| diff --git a/ext/fg/js/driver.js b/ext/fg/js/driver.js index e94a4ac2..b0cc4613 100644 --- a/ext/fg/js/driver.js +++ b/ext/fg/js/driver.js @@ -70,15 +70,22 @@ window.driver = new class {              return;          } -        if (this.options.scanning.requireShift && !e.shiftKey && !(this.mouseDownMiddle && this.options.scanning.middleMouse)) { +        const mouseScan = this.mouseDownMiddle && this.options.scanning.middleMouse; +        const keyScan = +            this.options.scanning.modifier === 'alt' && e.altKey || +            this.options.scanning.modifier === 'ctrl' && e.ctrlKey || +            this.options.scanning.modifier === 'shift' && e.shiftKey || +            this.options.scanning.modifier === 'none'; + +        if (!keyScan && !mouseScan) {              return;          }          const searchFunc = () => this.searchAt(this.lastMousePos); -        if (this.options.scanning.requireShift) { -            searchFunc(); -        } else { +        if (this.options.scanning.modifier === 'none') {              this.popupTimerSet(searchFunc); +        } else { +            searchFunc();          }      } @@ -142,8 +149,9 @@ window.driver = new class {              return;          } -        const textSource = docRangeFromPoint(point, this.options.scanning.imposter); +        const textSource = docRangeFromPoint(point);          if (!textSource || !textSource.containsPoint(point)) { +            docImposterDestroy();              return;          } @@ -159,6 +167,7 @@ window.driver = new class {          }).catch(error => {              this.handleError(error, textSource);          }).then(() => { +            docImposterDestroy();              this.pendingLookup = false;          });      } @@ -230,7 +239,7 @@ window.driver = new class {      handleError(error, textSource) {          if (window.orphaned) { -            if (textSource && this.options.scanning.requireShift) { +            if (textSource && this.options.scanning.modifier !== 'none') {                  this.popup.showOrphaned(textSource.getRect(), this.options);              }          } else { diff --git a/ext/fg/js/source-element.js b/ext/fg/js/source-element.js index 69fbc5ab..a8101382 100644 --- a/ext/fg/js/source-element.js +++ b/ext/fg/js/source-element.js @@ -18,41 +18,42 @@  class TextSourceElement { -    constructor(element, length=-1) { +    constructor(element, content='') {          this.element = element; -        this.length = length; +        this.content = content;      }      clone() { -        return new TextSourceElement(this.element, this.length); +        return new TextSourceElement(this.element, this.content);      }      text() { -        const text = this.textRaw(); -        return this.length < 0 ? text : text.substring(0, this.length); +        return this.content;      } -    textRaw() { +    setEndOffset(length) {          switch (this.element.nodeName) {              case 'BUTTON': -                return this.element.innerHTML; +                this.content = this.element.innerHTML; +                break;              case 'IMG': -                return this.element.getAttribute('alt'); +                this.content = this.element.getAttribute('alt'); +                break;              default: -                return this.element.value || ''; +                this.content = this.element.value; +                break;          } + +        this.content = this.content || ''; +        this.content = this.content.substring(0, length); + +        return this.content.length;      }      setStartOffset(length) { -        // NOP          return 0;      } -    setEndOffset(length) { -        this.length = length; -        return length; -    } -      containsPoint(point) {          const rect = this.getRect();          return point.x >= rect.left && point.x <= rect.right; @@ -71,6 +72,6 @@ class TextSourceElement {      }      equals(other) { -        return other.element && other.textRaw() === this.textRaw(); +        return other.element === this.element && other.content === this.content;      }  } diff --git a/ext/fg/js/source-range.js b/ext/fg/js/source-range.js index 6d445f54..fa73b0a4 100644 --- a/ext/fg/js/source-range.js +++ b/ext/fg/js/source-range.js @@ -18,30 +18,31 @@  class TextSourceRange { -    constructor(range) { -        this.rng = range; +    constructor(range, content='') { +        this.range = range; +        this.content = content;      }      clone() { -        return new TextSourceRange(this.rng.cloneRange()); +        return new TextSourceRange(this.range.cloneRange(), this.content);      }      text() { -        return this.rng.toString(); +        return this.content;      }      setEndOffset(length) { -        const lengthAdj = length + this.rng.startOffset; -        const state = TextSourceRange.seekForward(this.rng.startContainer, lengthAdj); -        this.rng.setEnd(state.node, state.offset); -        return length - state.length; +        const state = TextSourceRange.seekForward(this.range.startContainer, this.range.startOffset, length); +        this.range.setEnd(state.node, state.offset); +        this.content = state.content; +        return length - state.remainder;      }      setStartOffset(length) { -        const lengthAdj = length + (this.rng.startContainer.length - this.rng.startOffset); -        const state = TextSourceRange.seekBackward(this.rng.startContainer, lengthAdj); -        this.rng.setStart(state.node, state.offset); -        return length - state.length; +        const state = TextSourceRange.seekBackward(this.range.startContainer, this.range.startOffset, length); +        this.range.setStart(state.node, state.offset); +        this.content = state.content; +        return length - state.remainder;      }      containsPoint(point) { @@ -50,11 +51,11 @@ class TextSourceRange {      }      getRect() { -        return this.rng.getBoundingClientRect(); +        return this.range.getBoundingClientRect();      }      getPaddedRect() { -        const range = this.rng.cloneRange(); +        const range = this.range.cloneRange();          const startOffset = range.startOffset;          const endOffset = range.endOffset;          const node = range.startContainer; @@ -68,7 +69,7 @@ class TextSourceRange {      select() {          const selection = window.getSelection();          selection.removeAllRanges(); -        selection.addRange(this.rng); +        selection.addRange(this.range);      }      deselect() { @@ -77,11 +78,30 @@ class TextSourceRange {      }      equals(other) { -        return other.rng && other.rng.compareBoundaryPoints(Range.START_TO_START, this.rng) === 0; +        return other.range && other.range.compareBoundaryPoints(Range.START_TO_START, this.range) === 0;      } -    static seekForward(node, length) { -        const state = {node, length, offset: 0}; +    static shouldEnter(node) { +        if (node.nodeType !== 1) { +            return false; +        } + +        const skip = ['RT', 'SCRIPT', 'STYLE']; +        if (skip.includes(node.nodeName)) { +            return false; +        } + +        const style = window.getComputedStyle(node); +        const hidden = +            style.visibility === 'hidden' || +            style.display === 'none' || +            parseFloat(style.fontSize) === 0; + +        return !hidden; +    } + +    static seekForward(node, offset, length) { +        const state = {node, offset, remainder: length, content: ''};          if (!TextSourceRange.seekForwardHelper(node, state)) {              return state;          } @@ -98,12 +118,15 @@ class TextSourceRange {      }      static seekForwardHelper(node, state) { -        if (node.nodeType === 3) { -            const consumed = Math.min(node.length, state.length); +        if (node.nodeType === 3 && node.parentElement && TextSourceRange.shouldEnter(node.parentElement)) { +            const offset = state.node === node ? state.offset : 0; +            const remaining = node.length - offset; +            const consumed = Math.min(remaining, state.remainder); +            state.content = state.content + node.nodeValue.substring(offset, offset + consumed);              state.node = node; -            state.offset = consumed; -            state.length -= consumed; -        } else { +            state.offset = offset + consumed; +            state.remainder -= consumed; +        } else if (TextSourceRange.shouldEnter(node)) {              for (let i = 0; i < node.childNodes.length; ++i) {                  if (!TextSourceRange.seekForwardHelper(node.childNodes[i], state)) {                      break; @@ -111,11 +134,11 @@ class TextSourceRange {              }          } -        return state.length > 0; +        return state.remainder > 0;      } -    static seekBackward(node, length) { -        const state = {node, length, offset: node.length}; +    static seekBackward(node, offset, length) { +        const state = {node, offset, remainder: length, content: ''};          if (!TextSourceRange.seekBackwardHelper(node, state)) {              return state;          } @@ -132,12 +155,15 @@ class TextSourceRange {      }      static seekBackwardHelper(node, state) { -        if (node.nodeType === 3) { -            const consumed = Math.min(node.length, state.length); +        if (node.nodeType === 3 && node.parentElement && TextSourceRange.shouldEnter(node.parentElement)) { +            const offset = state.node === node ? state.offset : node.length; +            const remaining = offset; +            const consumed = Math.min(remaining, state.remainder); +            state.content = node.nodeValue.substring(offset - consumed, offset) + state.content;              state.node = node; -            state.offset = node.length - consumed; -            state.length -= consumed; -        } else { +            state.offset = offset - consumed; +            state.remainder -= consumed; +        } else if (TextSourceRange.shouldEnter(node)) {              for (let i = node.childNodes.length - 1; i >= 0; --i) {                  if (!TextSourceRange.seekBackwardHelper(node.childNodes[i], state)) {                      break; @@ -145,6 +171,6 @@ class TextSourceRange {              }          } -        return state.length > 0; +        return state.remainder > 0;      }  } diff --git a/ext/fg/js/util.js b/ext/fg/js/util.js index e5705ffd..c6270ce6 100644 --- a/ext/fg/js/util.js +++ b/ext/fg/js/util.js @@ -112,18 +112,12 @@ function docImposterDestroy() {      }  } -function docImposterHide() { -    for (const element of document.getElementsByClassName('yomichan-imposter')) { -        element.style.visibility = 'hidden'; -    } -} - -function docRangeFromPoint(point, imposter) { +function docRangeFromPoint(point) {      const element = document.elementFromPoint(point.x, point.y);      if (element !== null) {          if (element.nodeName === 'IMG' || element.nodeName === 'BUTTON') {              return new TextSourceElement(element); -        } else if (imposter && (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA')) { +        } else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {              docImposterCreate(element);          }      } @@ -144,11 +138,9 @@ function docRangeFromPoint(point, imposter) {      const range = document.caretRangeFromPoint(point.x, point.y);      if (range !== null) { -        docImposterHide();          return new TextSourceRange(range);      } -    docImposterDestroy();      return null;  } @@ -168,6 +160,11 @@ function docSentenceExtract(source, extent) {      for (let i = position; i >= startPos; --i) {          const c = content[i]; +        if (c === '\n') { +            startPos = i + 1; +            break; +        } +          if (quoteStack.length === 0 && (terminators.includes(c) || c in quotesFwd)) {              startPos = i + 1;              break; @@ -186,6 +183,11 @@ function docSentenceExtract(source, extent) {      for (let i = position; i <= endPos; ++i) {          const c = content[i]; +        if (c === '\n') { +            endPos = i + 1; +            break; +        } +          if (quoteStack.length === 0) {              if (terminators.includes(c)) {                  endPos = i + 1; |