From 9ee8e7b607b34d6ee841bc36e0b10646d1f8d7de Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Fri, 7 Jan 2022 08:54:23 -0500 Subject: [PATCH] Improve element picker/zapper's handling of shadow roots Related issue: - https://github.com/uBlockOrigin/uBlock-issues/issues/1850 --- src/js/scriptlets/epicker.js | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/js/scriptlets/epicker.js b/src/js/scriptlets/epicker.js index 879b83eae..ace009de4 100644 --- a/src/js/scriptlets/epicker.js +++ b/src/js/scriptlets/epicker.js @@ -83,17 +83,18 @@ const getElementBoundingClientRect = function(elem) { if ( rect.width !== 0 && rect.height !== 0 ) { return rect; } + if ( elem.shadowRoot instanceof DocumentFragment ) { + return getElementBoundingClientRect(elem.shadowRoot); + } let left = rect.left, - right = rect.right, + right = left + rect.width, top = rect.top, - bottom = rect.bottom; + bottom = top + rect.height; for ( const child of elem.children ) { rect = getElementBoundingClientRect(child); - if ( rect.width === 0 || rect.height === 0 ) { - continue; - } + if ( rect.width === 0 || rect.height === 0 ) { continue; } if ( rect.left < left ) { left = rect.left; } if ( rect.right > right ) { right = rect.right; } if ( rect.top < top ) { top = rect.top; } @@ -101,8 +102,10 @@ const getElementBoundingClientRect = function(elem) { } return { + bottom, height: bottom - top, left, + right, top, width: right - left }; @@ -940,20 +943,22 @@ const zapElementAtPoint = function(mx, my, options) { if ( elemToRemove instanceof Element === false ) { return; } - const getStyleValue = function(elem, prop) { + const getStyleValue = (elem, prop) => { const style = window.getComputedStyle(elem); return style ? style[prop] : ''; }; // Heuristic to detect scroll-locking: remove such lock when detected. - let maybeScrollLocked = false; - let elem = elemToRemove; - do { - maybeScrollLocked = - parseInt(getStyleValue(elem, 'zIndex'), 10) >= 1000 || - getStyleValue(elem, 'position') === 'fixed'; - elem = elem.parentElement; - } while ( elem !== null && maybeScrollLocked === false ); + let maybeScrollLocked = elemToRemove.shadowRoot instanceof DocumentFragment; + if ( maybeScrollLocked === false ) { + let elem = elemToRemove; + do { + maybeScrollLocked = + parseInt(getStyleValue(elem, 'zIndex'), 10) >= 1000 || + getStyleValue(elem, 'position') === 'fixed'; + elem = elem.parentElement; + } while ( elem !== null && maybeScrollLocked === false ); + } if ( maybeScrollLocked ) { const doc = document; if ( getStyleValue(doc.body, 'overflowY') === 'hidden' ) {