diff options
Diffstat (limited to 'ext/fg/js')
| -rw-r--r-- | ext/fg/js/source.js | 101 | 
1 files changed, 65 insertions, 36 deletions
| diff --git a/ext/fg/js/source.js b/ext/fg/js/source.js index 07006cc9..fa4706f2 100644 --- a/ext/fg/js/source.js +++ b/ext/fg/js/source.js @@ -358,13 +358,32 @@ class TextSourceRange {   */  class TextSourceElement { -    constructor(element, content='') { -        this.element = element; -        this.content = content; +    constructor(element, fullContent=null, startOffset=0, endOffset=0) { +        this._element = element; +        this._fullContent = (typeof fullContent === 'string' ? fullContent : TextSourceElement.getElementContent(element)); +        this._startOffset = startOffset; +        this._endOffset = endOffset; +        this._content = this._fullContent.substring(this._startOffset, this._endOffset); +    } + +    get element() { +        return this._element; +    } + +    get fullContent() { +        return this._fullContent; +    } + +    get startOffset() { +        return this._startOffset; +    } + +    get endOffset() { +        return this._endOffset;      }      clone() { -        return new TextSourceElement(this.element, this.content); +        return new TextSourceElement(this._element, this._fullContent, this._startOffset, this._endOffset);      }      cleanup() { @@ -372,44 +391,32 @@ class TextSourceElement {      }      text() { -        return this.content; +        return this._content;      } -    setEndOffset(length) { -        switch (this.element.nodeName.toUpperCase()) { -            case 'BUTTON': -                this.content = this.element.textContent; -                break; -            case 'IMG': -                this.content = this.element.getAttribute('alt'); -                break; -            default: -                this.content = this.element.value; -                break; -        } - -        let consumed = 0; -        let content = ''; -        for (const currentChar of this.content || '') { -            if (consumed >= length) { -                break; -            } else if (!currentChar.match(IGNORE_TEXT_PATTERN)) { -                consumed++; -                content += currentChar; -            } +    setEndOffset(length, fromEnd=false) { +        if (fromEnd) { +            const delta = Math.min(this._fullContent.length - this._endOffset, length); +            this._endOffset += delta; +            this._content = this._fullContent.substring(this._startOffset, this._endOffset); +            return delta; +        } else { +            const delta = Math.min(this._fullContent.length - this._startOffset, length); +            this._endOffset = this._startOffset + delta; +            this._content = this._fullContent.substring(this._startOffset, this._endOffset); +            return delta;          } - -        this.content = content; - -        return this.content.length;      } -    setStartOffset() { -        return 0; +    setStartOffset(length) { +        const delta = Math.min(this._startOffset, length); +        this._startOffset -= delta; +        this._content = this._fullContent.substring(this._startOffset, this._endOffset); +        return delta;      }      getRect() { -        return this.element.getBoundingClientRect(); +        return this._element.getBoundingClientRect();      }      getWritingMode() { @@ -429,8 +436,30 @@ class TextSourceElement {              typeof other === 'object' &&              other !== null &&              other instanceof TextSourceElement && -            other.element === this.element && -            other.content === this.content +            this._element === other.element && +            this._fullContent === other.fullContent && +            this._startOffset === other.startOffset && +            this._endOffset === other.endOffset          );      } + +    static getElementContent(element) { +        let content; +        switch (element.nodeName.toUpperCase()) { +            case 'BUTTON': +                content = element.textContent; +                break; +            case 'IMG': +                content = element.getAttribute('alt') || ''; +                break; +            default: +                content = `${element.value}`; +                break; +        } + +        // Remove zero-width non-joiner +        content = content.replace(/\u200c/g, ''); + +        return content; +    }  } |