Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(commons/dom/createGrid): only add the visible, non-overflow areas of an element to the grid #4101

Merged
merged 3 commits into from
Jul 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions lib/commons/dom/create-grid.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { getNodeFromTree, getScroll, isShadowRoot } from '../../core/utils';
import constants from '../../core/constants';
import cache from '../../core/base/cache';
import assert from '../../core/utils/assert';
import getOverflowHiddenAncestors from './get-overflow-hidden-ancestors';
import { getIntersectionRect } from '../math';

const ROOT_LEVEL = 0;
const DEFAULT_LEVEL = 0.1;
Expand Down Expand Up @@ -392,11 +394,22 @@ function findScrollRegionParent(vNode, parentVNode) {
* @param {VirtualNode}
*/
function addNodeToGrid(grid, vNode) {
vNode.clientRects.forEach(rect => {
const overflowHiddenNodes = getOverflowHiddenAncestors(vNode);

vNode.clientRects.forEach(clientRect => {
// ignore any rects that are outside the bounds of overflow hidden ancestors
const visibleRect = overflowHiddenNodes.reduce((rect, overflowNode) => {
return rect && getIntersectionRect(rect, overflowNode.boundingClientRect);
}, clientRect);

if (!visibleRect) {
return;
}

// save a reference to where this element is in the grid so we
// can find it even if it's in a subgrid
vNode._grid ??= grid;
const gridRect = grid.getGridPositionOfRect(rect);
const gridRect = grid.getGridPositionOfRect(visibleRect);
grid.loopGridPosition(gridRect, gridCell => {
if (!gridCell.includes(vNode)) {
gridCell.push(vNode);
Expand Down
18 changes: 18 additions & 0 deletions test/commons/dom/create-grid.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,24 @@ describe('create-grid', () => {
]);
});

it('only adds the visible non-overflow area of large elements', () => {
const vNode = queryFixture(`
<div style="overflow: hidden; width: 300px; height: 300px;">
<span id="target" style="display: inline-block; width: 1000px; height: 1000px;">' +
'Hello world</span>
</div>
`);
createGrid();

const positions = findPositions(vNode._grid, vNode);
assert.deepEqual(positions, [
{ col: 0, row: 0 },
{ col: 1, row: 0 },
{ col: 0, row: 1 },
{ col: 1, row: 1 }
]);
});

describe('stackingOrder', () => {
it('adds stacking context information', () => {
fixture = fixtureSetup('<span>Hello world</span>');
Expand Down
45 changes: 45 additions & 0 deletions test/integration/full/contrast/memory.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Test Page</title>
<link
rel="stylesheet"
type="text/css"
href="/node_modules/mocha/mocha.css"
/>
<script src="/node_modules/mocha/mocha.js"></script>
<script src="/node_modules/chai/chai.js"></script>
<script src="/axe.js"></script>
<script>
mocha.setup({
timeout: 2000,
ui: 'bdd'
});
var assert = chai.assert;
</script>
<script src="/test/integration/no-ui-reporter.js"></script>
<style>
* {
box-sizing: border-box;
}
html,
body {
padding: 0;
margin: 0;
height: 100%;
background: #fff;
color: #000;
}
</style>
</head>
<body>
<div id="fixture">
<div style="overflow: hidden; width: 200px; height: 200px">
<!-- browsers each have their own CSS size limit so this number (which should be greater than the limit) will be capped to that -->
<div style="width: 1e9px; height: 1e9px">Hello World</div>
</div>
</div>
<script src="memory.js"></script>
<script src="/test/integration/adapter.js"></script>
</body>
</html>
18 changes: 18 additions & 0 deletions test/integration/full/contrast/memory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
Since we can't easily test for memory issue we'll assume that if this test doesn't time out then the memory issue isn't a problem
*/
describe('color-contrast memory test', () => {
describe('violations', () => {
it('should find none', done => {
axe.run(
'#fixture',
{ runOnly: { type: 'rule', values: ['color-contrast'] } },
(err, results) => {
assert.isNull(err);
assert.lengthOf(results.violations, 0);
done();
}
);
});
});
});