Skip to content

Commit 50df70a

Browse files
authored
fix(get-background-color): scroll element into view horizontally (#1845)
* fix(get-background-color): scroll element into view horizontally * prevent infinite loop * comment
1 parent 754d56b commit 50df70a

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

lib/commons/color/get-background-color.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,21 @@ color.getBackgroundColor = function getBackgroundColor(
2525
const clientHeight = elm.getBoundingClientRect().height;
2626
const alignToTop = clientHeight - 2 >= window.innerHeight * 2;
2727
elm.scrollIntoView(alignToTop);
28+
29+
// ensure element is scrolled into view horizontally
30+
let center, scrollParent;
31+
do {
32+
const rect = elm.getBoundingClientRect();
33+
34+
// 'x' does not exist in IE11
35+
const x = 'x' in rect ? rect.x : rect.left;
36+
center = x + rect.width / 2;
37+
38+
if (center < 0) {
39+
scrollParent = getScrollParent(elm);
40+
scrollParent.scrollLeft = 0;
41+
}
42+
} while (center < 0 && scrollParent !== document.documentElement);
2843
}
2944

3045
let bgColors = [];
@@ -378,6 +393,36 @@ function contentOverlapping(targetElement, bgNode) {
378393
return false;
379394
}
380395

396+
/**
397+
* Return the scrolling parent element
398+
* @see https://stackoverflow.com/questions/35939886/find-first-scrollable-parent#42543908
399+
* @param {Element} element
400+
* @param {Boolean} includeHidden
401+
* @return {Element}
402+
*/
403+
function getScrollParent(element, includeHidden) {
404+
var style = getComputedStyle(element);
405+
var excludeStaticParent = style.position === 'absolute';
406+
var overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/;
407+
408+
if (style.position === 'fixed') {
409+
return document.documentElement;
410+
}
411+
for (var parent = element; (parent = parent.parentElement); ) {
412+
style = getComputedStyle(parent);
413+
if (excludeStaticParent && style.position === 'static') {
414+
continue;
415+
}
416+
if (
417+
overflowRegex.test(style.overflow + style.overflowY + style.overflowX)
418+
) {
419+
return parent;
420+
}
421+
}
422+
423+
return document.documentElement;
424+
}
425+
381426
/**
382427
* Determines whether an element has a fully opaque background, whether solid color or an image
383428
* @param {Element} node

test/commons/color/get-background-color.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,19 @@ describe('color.getBackgroundColor', function() {
646646
assert.notEqual(window.pageYOffset, 0);
647647
});
648648

649+
it('scrolls horizontally into view when scroll is enabled', function() {
650+
fixture.innerHTML =
651+
'<div style="width: 1000px;"><span id="target">long text to test scrolling</span></div>';
652+
var targetEl = fixture.querySelector('#target');
653+
var bgNodes = [];
654+
window.scroll(100, 0);
655+
656+
axe.testUtils.flatTreeSetup(fixture.firstChild);
657+
axe.commons.color.getBackgroundColor(targetEl, bgNodes, false);
658+
659+
assert.equal(document.documentElement.scrollLeft, 0);
660+
});
661+
649662
it('returns elements with negative z-index', function() {
650663
fixture.innerHTML =
651664
'<div id="sibling" ' +

0 commit comments

Comments
 (0)