From ba01c66d6456aa2f4c08336d6e5062bef9e5f595 Mon Sep 17 00:00:00 2001 From: Simon Lydell Date: Thu, 2 Jun 2016 17:15:39 +0200 Subject: [PATCH] Drastically speed up `find_from_top_of_viewport` - Don't recurse into children of elements when looking for visible text nodes; we'll get to them anyway since we iterate over every element of the page. - Don't bother checking text nodes that we already know are whitespace only. Fixes #747. --- extension/lib/viewport.coffee | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/extension/lib/viewport.coffee b/extension/lib/viewport.coffee index 5591141..dd315a0 100644 --- a/extension/lib/viewport.coffee +++ b/extension/lib/viewport.coffee @@ -98,15 +98,21 @@ getFirstNonWhitespace = (element) -> viewport = getWindowViewport(window) for node in element.childNodes then switch node.nodeType when 3 # TextNode. - firstVisibleOffset = getFirstVisibleOffset(node, viewport) - if firstVisibleOffset? - offset = node.data.slice(firstVisibleOffset).search(/\S/) - return [node, firstVisibleOffset + offset] if offset >= 0 + continue unless /\S/.test(node.data) + offset = getFirstVisibleNonWhitespaceOffset(node, viewport) + return [node, offset] if offset >= 0 when 1 # Element. result = getFirstNonWhitespace(node) return result if result return null +getFirstVisibleNonWhitespaceOffset = (textNode, viewport) -> + firstVisibleOffset = getFirstVisibleOffset(textNode, viewport) + if firstVisibleOffset? + offset = textNode.data.slice(firstVisibleOffset).search(/\S/) + return firstVisibleOffset + offset if offset >= 0 + return -1 + getFirstVisibleOffset = (textNode, viewport) -> {length} = textNode.data return null if length == 0 @@ -146,12 +152,15 @@ getFirstVisibleText = (window, viewport) -> return result if result continue - continue unless Array.some(element.childNodes, utils.isNonEmptyTextNode) + nonEmptyTextNodes = + Array.filter(element.childNodes, utils.isNonEmptyTextNode) + continue if nonEmptyTextNodes.length == 0 continue if utils.checkElementOrAncestor(element, utils.isPositionFixed) - result = getFirstNonWhitespace(element) - return result if result + for textNode in nonEmptyTextNodes + offset = getFirstVisibleNonWhitespaceOffset(textNode, viewport) + return [textNode, offset] if offset >= 0 return null @@ -291,6 +300,7 @@ module.exports = { adjustRectToViewport getAllRangesInsideViewport getFirstNonWhitespace + getFirstVisibleNonWhitespaceOffset getFirstVisibleOffset getFirstVisibleRange getFirstVisibleText -- 2.39.3