From 3896832e3119ebe235d27b8af91b4402fd80b922 Mon Sep 17 00:00:00 2001 From: Simon Lydell Date: Tue, 18 Oct 2016 17:09:57 +0200 Subject: [PATCH] Improve full page scrolling adjustment on some pages On medium.com, there is a fixed footer. However, it is not `position: fixed;` like fixed element usually are. Instead, it's `position: absolute;` (and the page scroll is inside an adjacent element instead of on ``). This commit allows elements with `position: absolute;` to as headers and footers as well. --- extension/lib/utils.coffee | 5 ----- extension/lib/viewport.coffee | 20 ++++++++++++++------ 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/extension/lib/utils.coffee b/extension/lib/utils.coffee index ed55100..484265a 100644 --- a/extension/lib/utils.coffee +++ b/extension/lib/utils.coffee @@ -465,10 +465,6 @@ isDetached = (element) -> isNonEmptyTextNode = (node) -> return node.nodeType == 3 and node.data.trim() != '' -isPositionFixed = (element) -> - computedStyle = element.ownerGlobal.getComputedStyle(element) - return computedStyle?.getPropertyValue('position') == 'fixed' - querySelectorAllDeep = (window, selector) -> elements = Array.from(window.document.querySelectorAll(selector)) for frame in window.frames @@ -773,7 +769,6 @@ module.exports = { insertText isDetached isNonEmptyTextNode - isPositionFixed querySelectorAllDeep selectAllSubstringMatches selectElement diff --git a/extension/lib/viewport.coffee b/extension/lib/viewport.coffee index 151c69f..c820311 100644 --- a/extension/lib/viewport.coffee +++ b/extension/lib/viewport.coffee @@ -23,6 +23,14 @@ utils = require('./utils') MINIMUM_EDGE_DISTANCE = 4 +getPosition = (element) -> + computedStyle = element.ownerGlobal.getComputedStyle(element) + return computedStyle?.getPropertyValue('position') + +isFixed = (element) -> getPosition(element) == 'fixed' + +isFixedOrAbsolute = (element) -> getPosition(element) in ['fixed', 'absolute'] + adjustRectToViewport = (rect, viewport) -> # The right and bottom values are subtracted by 1 because # `document.elementFromPoint(right, bottom)` does not return the element @@ -145,7 +153,7 @@ getFirstVisibleText = (window, viewport) -> continue unless isInsideViewport(rect, viewport) if element.contentWindow and - not utils.checkElementOrAncestor(element, utils.isPositionFixed) + not utils.checkElementOrAncestor(element, isFixed) {viewport: frameViewport} = getFrameViewport(element, viewport) ? {} continue unless frameViewport result = getFirstVisibleText(element.contentWindow, frameViewport) @@ -156,7 +164,7 @@ getFirstVisibleText = (window, viewport) -> Array.filter(element.childNodes, utils.isNonEmptyTextNode) continue if nonEmptyTextNodes.length == 0 - continue if utils.checkElementOrAncestor(element, utils.isPositionFixed) + continue if utils.checkElementOrAncestor(element, isFixed) for textNode in nonEmptyTextNodes offset = getFirstVisibleNonWhitespaceOffset(textNode, viewport) @@ -188,15 +196,15 @@ getFixedHeaderAndFooter = (window) -> for candidate in candidates rect = candidate.getBoundingClientRect() continue unless rect.height <= maxHeight and rect.width >= minWidth - # Checking for `position: fixed;` is the absolutely most expensive - # operation, so that is done last. + # Checking for `position: fixed;` or `position: absolute;` is the absolutely + # most expensive operation, so that is done last. switch when rect.top <= headerBottom and rect.bottom > headerBottom and - utils.isPositionFixed(candidate) + isFixedOrAbsolute(candidate) header = candidate headerBottom = rect.bottom when rect.bottom >= footerTop and rect.top < footerTop and - utils.isPositionFixed(candidate) + isFixedOrAbsolute(candidate) footer = candidate footerTop = rect.top -- 2.39.3