diff options
| -rw-r--r-- | content_scripts/link_hints.coffee | 2 | ||||
| -rw-r--r-- | content_scripts/vimium_frontend.coffee | 2 | ||||
| -rw-r--r-- | lib/dom_utils.coffee | 14 | ||||
| -rw-r--r-- | tests/dom_tests/dom_utils_test.coffee | 28 |
4 files changed, 25 insertions, 21 deletions
diff --git a/content_scripts/link_hints.coffee b/content_scripts/link_hints.coffee index 51e5df35..3fa6f20f 100644 --- a/content_scripts/link_hints.coffee +++ b/content_scripts/link_hints.coffee @@ -197,7 +197,7 @@ LinkHints = isClickable = onlyHasTabIndex = true if isClickable - clientRect = DomUtils.getVisibleClientRect element + clientRect = DomUtils.getVisibleClientRect element, true if clientRect != null visibleElements.push {element: element, rect: clientRect, secondClassCitizen: onlyHasTabIndex} diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index e7aea163..967e1e1e 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -395,7 +395,7 @@ extend window, visibleInputs = for i in [0...resultSet.snapshotLength] by 1 element = resultSet.snapshotItem i - rect = DomUtils.getVisibleClientRect element + rect = DomUtils.getVisibleClientRect element, true continue if rect == null { element: element, rect: rect } diff --git a/lib/dom_utils.coffee b/lib/dom_utils.coffee index e0ab09e2..30b9f68c 100644 --- a/lib/dom_utils.coffee +++ b/lib/dom_utils.coffee @@ -55,21 +55,25 @@ DomUtils = # # Returns the first visible clientRect of an element if it exists. Otherwise it returns null. # - getVisibleClientRect: (element) -> + # WARNING: If testChildren = true then the rects of visible (eg. floated) children may be returned instead. + # This is used for LinkHints and focusInput, **BUT IS UNSUITABLE FOR MOST OTHER PURPOSES**. + # + getVisibleClientRect: (element, testChildren = false) -> # Note: this call will be expensive if we modify the DOM in between calls. clientRects = (Rect.copy clientRect for clientRect in element.getClientRects()) for clientRect in clientRects - # If the link has zero dimensions, it may be wrapping visible - # but floated elements. Check for this. - if (clientRect.width == 0 || clientRect.height == 0) + # If the link has zero dimensions, it may be wrapping visible but floated elements. Check for this. + if (clientRect.width == 0 or clientRect.height == 0) and testChildren for child in element.children computedStyle = window.getComputedStyle(child, null) # Ignore child elements which are not floated and not absolutely positioned for parent elements with # zero width/height + # NOTE(mrmr1993): This ignores floated/absolutely positioned descendants nested within inline + # children. continue if (computedStyle.getPropertyValue('float') == 'none' && computedStyle.getPropertyValue('position') != 'absolute') - childClientRect = @getVisibleClientRect(child) + childClientRect = @getVisibleClientRect child, true continue if childClientRect == null or childClientRect.width < 3 or childClientRect.height < 3 return childClientRect diff --git a/tests/dom_tests/dom_utils_test.coffee b/tests/dom_tests/dom_utils_test.coffee index ad8bde3c..e98dc958 100644 --- a/tests/dom_tests/dom_utils_test.coffee +++ b/tests/dom_tests/dom_utils_test.coffee @@ -4,19 +4,19 @@ context "Check visibility", document.getElementById("test-div").innerHTML = """ <div id='foo'>test</div> """ - assert.isTrue (DomUtils.getVisibleClientRect document.getElementById 'foo') != null + assert.isTrue (DomUtils.getVisibleClientRect (document.getElementById 'foo'), true) != null should "detect display:none links as hidden", -> document.getElementById("test-div").innerHTML = """ <a id='foo' style='display:none'>test</a> """ - assert.equal null, DomUtils.getVisibleClientRect document.getElementById 'foo' + assert.equal null, (DomUtils.getVisibleClientRect (document.getElementById 'foo'), true) should "detect visibility:hidden links as hidden", -> document.getElementById("test-div").innerHTML = """ <a id='foo' style='visibility:hidden'>test</a> """ - assert.equal null, DomUtils.getVisibleClientRect document.getElementById 'foo' + assert.equal null, (DomUtils.getVisibleClientRect (document.getElementById 'foo'), true) should "detect elements nested in display:none elements as hidden", -> document.getElementById("test-div").innerHTML = """ @@ -24,7 +24,7 @@ context "Check visibility", <a id='foo'>test</a> </div> """ - assert.equal null, DomUtils.getVisibleClientRect document.getElementById 'foo' + assert.equal null, (DomUtils.getVisibleClientRect (document.getElementById 'foo'), true) should "detect links nested in visibility:hidden elements as hidden", -> document.getElementById("test-div").innerHTML = """ @@ -32,23 +32,23 @@ context "Check visibility", <a id='foo'>test</a> </div> """ - assert.equal null, DomUtils.getVisibleClientRect document.getElementById 'foo' + assert.equal null, (DomUtils.getVisibleClientRect (document.getElementById 'foo'), true) should "detect links outside viewport as hidden", -> document.getElementById("test-div").innerHTML = """ <a id='foo' style='position:absolute;top:-2000px'>test</a> <a id='bar' style='position:absolute;left:2000px'>test</a> """ - assert.equal null, DomUtils.getVisibleClientRect document.getElementById 'foo' - assert.equal null, DomUtils.getVisibleClientRect document.getElementById 'bar' + assert.equal null, (DomUtils.getVisibleClientRect (document.getElementById 'foo'), true) + assert.equal null, (DomUtils.getVisibleClientRect (document.getElementById 'bar'), true) should "detect links only partially outside viewport as visible", -> document.getElementById("test-div").innerHTML = """ <a id='foo' style='position:absolute;top:-10px'>test</a> <a id='bar' style='position:absolute;left:-10px'>test</a> """ - assert.isTrue (DomUtils.getVisibleClientRect document.getElementById 'foo') != null - assert.isTrue (DomUtils.getVisibleClientRect document.getElementById 'bar') != null + assert.isTrue (DomUtils.getVisibleClientRect (document.getElementById 'foo'), true) != null + assert.isTrue (DomUtils.getVisibleClientRect (document.getElementById 'bar'), true) != null should "detect links that contain only floated / absolutely-positioned divs as visible", -> document.getElementById("test-div").innerHTML = """ @@ -56,14 +56,14 @@ context "Check visibility", <div style='float:left'>test</div> </a> """ - assert.isTrue (DomUtils.getVisibleClientRect document.getElementById 'foo') != null + assert.isTrue (DomUtils.getVisibleClientRect (document.getElementById 'foo'), true) != null document.getElementById("test-div").innerHTML = """ <a id='foo'> <div style='position:absolute;top:0;left:0'>test</div> </a> """ - assert.isTrue (DomUtils.getVisibleClientRect document.getElementById 'foo') != null + assert.isTrue (DomUtils.getVisibleClientRect (document.getElementById 'foo'), true) != null should "detect links that contain only invisible floated divs as invisible", -> document.getElementById("test-div").innerHTML = """ @@ -71,7 +71,7 @@ context "Check visibility", <div style='float:left;visibility:hidden'>test</div> </a> """ - assert.equal null, DomUtils.getVisibleClientRect document.getElementById 'foo' + assert.equal null, (DomUtils.getVisibleClientRect (document.getElementById 'foo'), true) should "detect links inside opacity:0 elements as visible", -> # XXX This is an expected failure. See issue #16. @@ -80,7 +80,7 @@ context "Check visibility", <a id='foo'>test</a> </div> """ - assert.isTrue (DomUtils.getVisibleClientRect document.getElementById 'foo') != null + assert.isTrue (DomUtils.getVisibleClientRect (document.getElementById 'foo'), true) != null should "Detect links within SVGs as visible", -> # XXX this is an expected failure @@ -91,4 +91,4 @@ context "Check visibility", </a> </svg> """ - assert.equal null, DomUtils.getVisibleClientRect document.getElementById 'foo' + assert.equal null, (DomUtils.getVisibleClientRect (document.getElementById 'foo'), true) |
