diff options
| author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2022-05-18 21:43:19 -0400 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-05-18 21:43:19 -0400 | 
| commit | 6e239638bb7f89353f0dd2c67600966aeec726f2 (patch) | |
| tree | f143028136d7f4c09c624d8e5a98b60c55b75fe3 /ext/js | |
| parent | a33a00f5ae410d0ae9a50cbe6b9331864d638b25 (diff) | |
DOMTextScanner updates (#2146)
* JSDoc updates
* Move function
* Simplify
* Refactor return type
* Refactor getElementSeekInfo return type
Diffstat (limited to 'ext/js')
| -rw-r--r-- | ext/js/dom/dom-text-scanner.js | 142 | 
1 files changed, 69 insertions, 73 deletions
| diff --git a/ext/js/dom/dom-text-scanner.js b/ext/js/dom/dom-text-scanner.js index a81d6b4f..fff08825 100644 --- a/ext/js/dom/dom-text-scanner.js +++ b/ext/js/dom/dom-text-scanner.js @@ -44,7 +44,7 @@ class DOMTextScanner {      /**       * Gets the current node being scanned. -     * @returns A DOM Node. +     * @type {Node}       */      get node() {          return this._node; @@ -53,7 +53,7 @@ class DOMTextScanner {      /**       * Gets the current offset corresponding to the node being scanned.       * This value is only applicable for text nodes. -     * @returns An integer. +     * @type {number}       */      get offset() {          return this._offset; @@ -62,7 +62,7 @@ class DOMTextScanner {      /**       * Gets the remaining number of characters that weren't scanned in the last seek() call.       * This value is usually 0 unless the end of the document was reached. -     * @returns An integer. +     * @type {number}       */      get remainder() {          return this._remainder; @@ -70,7 +70,7 @@ class DOMTextScanner {      /**       * Gets the accumulated content string resulting from calls to seek(). -     * @returns A string. +     * @type {string}       */      get content() {          return this._content; @@ -78,11 +78,11 @@ class DOMTextScanner {      /**       * Seeks a given length in the document and accumulates the text content. -     * @param length A positive or negative integer corresponding to how many characters +     * @param {number} length A positive or negative integer corresponding to how many characters       *   should be added to content. Content is only added to the accumulation string,       *   never removed, so mixing seek calls with differently signed length values       *   may give unexpected results. -     * @returns this +     * @returns {DOMTextScanner} this       */      seek(length) {          const forward = (length >= 0); @@ -114,7 +114,7 @@ class DOMTextScanner {              } else if (nodeType === ELEMENT_NODE) {                  lastNode = node;                  this._offset = 0; -                [enterable, newlines] = DOMTextScanner.getElementSeekInfo(node); +                ({enterable, newlines} = DOMTextScanner.getElementSeekInfo(node));                  if (newlines > this._newlines && generateLayoutContent) {                      this._newlines = newlines;                  } @@ -125,7 +125,7 @@ class DOMTextScanner {              for (const exitedNode of exitedNodes) {                  if (exitedNode.nodeType !== ELEMENT_NODE) { continue; } -                newlines = DOMTextScanner.getElementSeekInfo(exitedNode)[1]; +                ({newlines} = DOMTextScanner.getElementSeekInfo(exitedNode));                  if (newlines > this._newlines && generateLayoutContent) {                      this._newlines = newlines;                  } @@ -144,18 +144,14 @@ class DOMTextScanner {      /**       * Seeks forward in a text node. -     * @param textNode The text node to use. -     * @param resetOffset Whether or not the text offset should be reset. -     * @returns true if scanning should continue, or false if the scan length has been reached. +     * @param {Text} textNode The text node to use. +     * @param {boolean} resetOffset Whether or not the text offset should be reset. +     * @returns {boolean} `true` if scanning should continue, or `false` if the scan length has been reached.       */      _seekTextNodeForward(textNode, resetOffset) {          const nodeValue = textNode.nodeValue;          const nodeValueLength = nodeValue.length; -        const [preserveNewlines, preserveWhitespace] = ( -            this._forcePreserveWhitespace ? -            [true, true] : -            DOMTextScanner.getWhitespaceSettings(textNode) -        ); +        const {preserveNewlines, preserveWhitespace} = this._getWhitespaceSettings(textNode);          let lineHasWhitespace = this._lineHasWhitespace;          let lineHasContent = this._lineHasContent; @@ -234,18 +230,14 @@ class DOMTextScanner {       * - offset is decremented before getting the character.       * - offset is reverted by incrementing instead of decrementing.       * - content string is prepended instead of appended. -     * @param textNode The text node to use. -     * @param resetOffset Whether or not the text offset should be reset. -     * @returns true if scanning should continue, or false if the scan length has been reached. +     * @param {Text} textNode The text node to use. +     * @param {boolean} resetOffset Whether or not the text offset should be reset. +     * @returns {boolean} `true` if scanning should continue, or `false` if the scan length has been reached.       */      _seekTextNodeBackward(textNode, resetOffset) {          const nodeValue = textNode.nodeValue;          const nodeValueLength = nodeValue.length; -        const [preserveNewlines, preserveWhitespace] = ( -            this._forcePreserveWhitespace ? -            [true, true] : -            DOMTextScanner.getWhitespaceSettings(textNode) -        ); +        const {preserveNewlines, preserveWhitespace} = this._getWhitespaceSettings(textNode);          let lineHasWhitespace = this._lineHasWhitespace;          let lineHasContent = this._lineHasContent; @@ -315,15 +307,41 @@ class DOMTextScanner {          return (remainder > 0);      } +    /** +     * Gets information about how whitespace characters are treated. +     * @param {Text} textNode The text node to check. +     * @returns {{preserveNewlines: boolean, preserveWhitespace: boolean}} Information about the whitespace. +     *   The value of `preserveNewlines` indicates whether or not newline characters are treated as line breaks. +     *   The value of `preserveWhitespace` indicates whether or not sequences of whitespace characters are collapsed. +     */ +    _getWhitespaceSettings(textNode) { +        if (this._forcePreserveWhitespace) { +            return {preserveNewlines: true, preserveWhitespace: true}; +        } +        const element = DOMTextScanner.getParentElement(textNode); +        if (element !== null) { +            const style = window.getComputedStyle(element); +            switch (style.whiteSpace) { +                case 'pre': +                case 'pre-wrap': +                case 'break-spaces': +                    return {preserveNewlines: true, preserveWhitespace: true}; +                case 'pre-line': +                    return {preserveNewlines: true, preserveWhitespace: false}; +            } +        } +        return {preserveNewlines: false, preserveWhitespace: false}; +    } +      // Static helpers      /**       * Gets the next node in the document for a specified scanning direction. -     * @param node The current DOM Node. -     * @param forward Whether to scan forward in the document or backward. -     * @param visitChildren Whether the children of the current node should be visited. -     * @param exitedNodes An array which stores nodes which were exited. -     * @returns The next node in the document, or null if there is no next node. +     * @param {Node} node The current DOM Node. +     * @param {boolean} forward Whether to scan forward in the document or backward. +     * @param {boolean} visitChildren Whether the children of the current node should be visited. +     * @param {Node[]} exitedNodes An array which stores nodes which were exited. +     * @returns {?Node} The next node in the document, or `null` if there is no next node.       */      static getNextNode(node, forward, visitChildren, exitedNodes) {          let next = visitChildren ? (forward ? node.firstChild : node.lastChild) : null; @@ -345,8 +363,8 @@ class DOMTextScanner {      /**       * Gets the parent element of a given Node. -     * @param node The node to check. -     * @returns The parent element if one exists, otherwise null. +     * @param {Node} node The node to check. +     * @returns {?Node} The parent element if one exists, otherwise `null`.       */      static getParentElement(node) {          while (node !== null && node.nodeType !== Node.ELEMENT_NODE) { @@ -359,8 +377,8 @@ class DOMTextScanner {       * Gets the parent <ruby> element of a given node, if one exists. For efficiency purposes,       * this only checks the immediate parent elements and does not check all ancestors, so       * there are cases where the node may be in a ruby element but it is not returned. -     * @param node The node to check. -     * @returns A <ruby> node if the input node is contained in one, otherwise null. +     * @param {Node} node The node to check. +     * @returns {?HTMLElement} A <ruby> node if the input node is contained in one, otherwise `null`.       */      static getParentRubyElement(node) {          node = DOMTextScanner.getParentElement(node); @@ -374,9 +392,10 @@ class DOMTextScanner {      }      /** -     * @returns [enterable: boolean, newlines: integer] -     *   The enterable value indicates whether the content of this node should be entered. -     *   The newlines value corresponds to the number of newline characters that should be added. +     * Gets seek information about an element. +     * @returns {{enterable: boolean, newlines: number}} The seek information. +     *   The `enterable` value indicates whether the content of this node should be entered. +     *   The `newlines` value corresponds to the number of newline characters that should be added.       *     1 newline corresponds to a simple new line in the layout.       *     2 newlines corresponds to a significant visual distinction since the previous content.       */ @@ -387,9 +406,9 @@ class DOMTextScanner {              case 'RT':              case 'SCRIPT':              case 'STYLE': -                return [false, 0]; +                return {enterable: false, newlines: 0};              case 'BR': -                return [false, 1]; +                return {enterable: false, newlines: 1};              case 'TEXTAREA':              case 'INPUT':              case 'BUTTON': @@ -418,36 +437,13 @@ class DOMTextScanner {              }          } -        return [enterable, newlines]; -    } - -    /** -     * Gets information about how whitespace characters are treated. -     * @param textNode The Text node to check. -     * @returns [preserveNewlines: boolean, preserveWhitespace: boolean] -     *   The value of preserveNewlines indicates whether or not newline characters are treated as line breaks. -     *   The value of preserveWhitespace indicates whether or not sequences of whitespace characters are collapsed. -     */ -    static getWhitespaceSettings(textNode) { -        const element = DOMTextScanner.getParentElement(textNode); -        if (element !== null) { -            const style = window.getComputedStyle(element); -            switch (style.whiteSpace) { -                case 'pre': -                case 'pre-wrap': -                case 'break-spaces': -                    return [true, true]; -                case 'pre-line': -                    return [true, false]; -            } -        } -        return [false, false]; +        return {enterable, newlines};      }      /**       * Gets attributes for the specified character. -     * @param character A string containing a single character. -     * @returns An integer representing the attributes of the character. +     * @param {string} character A string containing a single character. +     * @returns {number} An integer representing the attributes of the character.       *   0: Character should be ignored.       *   1: Character is collapsible whitespace.       *   2: Character should be added to the content. @@ -472,9 +468,9 @@ class DOMTextScanner {      /**       * Checks whether a given style is visible or not. -     * This function does not check style.display === 'none'. -     * @param style An object implementing the CSSStyleDeclaration interface. -     * @returns true if the style should result in an element being visible, otherwise false. +     * This function does not check `style.display === 'none'`. +     * @param {CSSStyleDeclaration} style An object implementing the CSSStyleDeclaration interface. +     * @returns {boolean} `true` if the style should result in an element being visible, otherwise `false`.       */      static isStyleVisible(style) {          return !( @@ -493,8 +489,8 @@ class DOMTextScanner {      /**       * Checks whether a given style is selectable or not. -     * @param style An object implementing the CSSStyleDeclaration interface. -     * @returns true if the style is selectable, otherwise false. +     * @param {CSSStyleDeclaration} style An object implementing the CSSStyleDeclaration interface. +     * @returns {boolean} `true` if the style is selectable, otherwise `false`.       */      static isStyleSelectable(style) {          return !( @@ -507,8 +503,8 @@ class DOMTextScanner {      /**       * Checks whether a CSS color is transparent or not. -     * @param cssColor A CSS color string, expected to be encoded in rgb(a) form. -     * @returns true if the color is transparent, otherwise false. +     * @param {string} cssColor A CSS color string, expected to be encoded in rgb(a) form. +     * @returns {false} `true` if the color is transparent, otherwise `false`.       */      static isCSSColorTransparent(cssColor) {          return ( @@ -520,8 +516,8 @@ class DOMTextScanner {      /**       * Checks whether a CSS display value will cause a layout change for text. -     * @param cssDisplay A CSS string corresponding to the value of the display property. -     * @returns true if the layout is changed by this value, otherwise false. +     * @param {string} cssDisplay A CSS string corresponding to the value of the display property. +     * @returns {boolean} `true` if the layout is changed by this value, otherwise `false`.       */      static doesCSSDisplayChangeLayout(cssDisplay) {          let pos = cssDisplay.indexOf(' '); |