diff options
| author | Alex Yatskov <alex@foosoft.net> | 2016-07-24 21:18:17 -0700 | 
|---|---|---|
| committer | Alex Yatskov <alex@foosoft.net> | 2016-07-24 21:18:17 -0700 | 
| commit | 19cc8fda335f27229753038709f3765090e169e8 (patch) | |
| tree | 49ee07eb15e84c78eca7e07ac81aa88a2c453f08 /ext/fg/js | |
| parent | 871acf7c2d75b349e55b761d5513223cf716464e (diff) | |
Better range handling.
Diffstat (limited to 'ext/fg/js')
| -rw-r--r-- | ext/fg/js/client.js | 4 | ||||
| -rw-r--r-- | ext/fg/js/source-image.js | 8 | ||||
| -rw-r--r-- | ext/fg/js/source-input.js | 8 | ||||
| -rw-r--r-- | ext/fg/js/source-range.js | 68 | 
4 files changed, 68 insertions, 20 deletions
| diff --git a/ext/fg/js/client.js b/ext/fg/js/client.js index bb0d3749..9806b96a 100644 --- a/ext/fg/js/client.js +++ b/ext/fg/js/client.js @@ -110,13 +110,13 @@ class Client {              return;          } -        textSource.setLength(this.options.scanLength); +        textSource.setEndOffset(this.options.scanLength);          bgFindTerm(textSource.text(), ({definitions, length}) => {              if (length === 0) {                  this.hidePopup();              } else {                  const sequence = ++this.sequence; -                textSource.setLength(length); +                textSource.setEndOffset(length);                  bgRenderText(                      {definitions, root: this.fgRoot, options: this.options, sequence}, diff --git a/ext/fg/js/source-image.js b/ext/fg/js/source-image.js index bbc0ba46..319f25fe 100644 --- a/ext/fg/js/source-image.js +++ b/ext/fg/js/source-image.js @@ -32,8 +32,14 @@ class TextSourceImage {          return this.img.getAttribute('alt') || '';      } -    setLength(length) { +    setStartOffset(length) { +        // NOP +        return 0; +    } + +    setEndOffset(length) {          this.length = length; +        return length;      }      containsPoint(point) { diff --git a/ext/fg/js/source-input.js b/ext/fg/js/source-input.js index 0bea977b..9f5a76a0 100644 --- a/ext/fg/js/source-input.js +++ b/ext/fg/js/source-input.js @@ -32,8 +32,14 @@ class TextSourceInput {          return this.input.nodeName === 'BUTTON' ? this.input.innerHTML : this.input.value;      } -    setLength(length) { +    setStartOffset(length) { +        // NOP +        return 0; +    } + +    setEndOffset(length) {          this.length = length; +        return length;      }      containsPoint(point) { diff --git a/ext/fg/js/source-range.js b/ext/fg/js/source-range.js index e09ec33a..fbab45f9 100644 --- a/ext/fg/js/source-range.js +++ b/ext/fg/js/source-range.js @@ -26,9 +26,16 @@ class TextSourceRange {          return this.rng.toString();      } -    setLength(length) { -        const end = TextSourceRange.seekEnd(this.rng.startContainer, this.rng.startOffset + length); +    setEndOffset(length) { +        const end = TextSourceRange.seekForward(this.rng.startContainer, this.rng.startOffset + length);          this.rng.setEnd(end.node, end.offset); +        return length - end.length; +    } + +    setStartOffset(length) { +        const start = TextSourceRange.seekBackward(this.rng.startContainer, length + (this.rng.startContainer.length - this.rng.startOffset)); +        this.rng.setStart(start.node, start.offset); +        return length - start.length;      }      containsPoint(point) { @@ -67,37 +74,66 @@ class TextSourceRange {          return other.rng && other.rng.compareBoundaryPoints(Range.START_TO_START, this.rng) == 0;      } -    static seekEnd(node, length) { +    static seekForward(node, length) {          const state = {node, offset: 0, length}; +        if (!TextSourceRange.seekForwardHelper(node, state)) { +            return state; +        } -        if (!TextSourceRange.seekEndRecurse(node, state)) { -            return {node: state.node, offset: state.offset}; +        for (let current = node; current !== null; current = current.parentElement) { +            for (let sibling = current.nextSibling; sibling !== null; sibling = sibling.nextSibling) { +                if (!TextSourceRange.seekForwardHelper(sibling, state)) { +                    return state; +                } +            }          } -        for (let sibling = node.nextSibling; sibling !== null; sibling = sibling.nextSibling) { -            if (!TextSourceRange.seekEndRecurse(sibling, state)) { -                return {node: state.node, offset: state.offset}; +        return state; +    } + +    static seekForwardHelper(node, state) { +        if (node.nodeType === 3) { +            const consumed = Math.min(node.length, state.length); +            state.node = node; +            state.offset = consumed; +            state.length -= consumed; +        } else { +            for (let i = 0; i < node.childNodes.length; ++i) { +                if (!TextSourceRange.seekForwardHelper(node.childNodes[i], state)) { +                    break; +                }              }          } -        for (let sibling = node.parentElement.nextSibling; sibling !== null; sibling = sibling.nextSibling) { -            if (!TextSourceRange.seekEndRecurse(sibling, state)) { -                return {node: state.node, offset: state.offset}; +        return state.length > 0; +    } + +    static seekBackward(node, length) { +        const state = {node, offset: node.length, length}; +        if (!TextSourceRange.seekBackwardHelper(node, state)) { +            return state; +        } + +        for (let current = node; current !== null; current = current.parentElement) { +            for (let sibling = current.previousSibling; sibling !== null; sibling = sibling.previousSibling) { +                if (!TextSourceRange.seekBackwardHelper(sibling, state)) { +                    return state; +                }              }          } -        return {node: state.node, offset: state.offset}; +        return state;      } -    static seekEndRecurse(node, state) { +    static seekBackwardHelper(node, state) {          if (node.nodeType === 3) {              const consumed = Math.min(node.length, state.length);              state.node = node; -            state.offset = consumed; +            state.offset = node.length - consumed;              state.length -= consumed;          } else { -            for (let i = 0; i < node.childNodes.length; ++i) { -                if (!TextSourceRange.seekEndRecurse(node.childNodes[i], state)) { +            for (let i = node.childNodes.length - 1; i >= 0; --i) { +                if (!TextSourceRange.seekBackwardHelper(node.childNodes[i], state)) {                      break;                  }              } |