зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1595979 - add hittest b-c tests (general, shadowroot, zoom). Fix an e10s bug where must prune check was done on the parent side instead of deferring to childAtPoint method. r=Jamie
Differential Revision: https://phabricator.services.mozilla.com/D69823 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
bf4f49a410
Коммит
fa747c2765
|
@ -1610,7 +1610,7 @@ mozilla::ipc::IPCResult DocAccessibleChild::RecvChildAtPoint(
|
|||
*aResultDoc = nullptr;
|
||||
*aResultID = 0;
|
||||
Accessible* acc = IdToAccessible(aID);
|
||||
if (acc && !acc->IsDefunct() && !nsAccUtils::MustPrune(acc)) {
|
||||
if (acc && !acc->IsDefunct()) {
|
||||
int32_t x = aX;
|
||||
int32_t y = aY;
|
||||
Accessible* result = acc->ChildAtPoint(
|
||||
|
|
|
@ -78,25 +78,25 @@ const Layout = {
|
|||
x.value / dpr,
|
||||
xInCSS.value,
|
||||
1,
|
||||
"Heights in CSS pixels is calculated correctly"
|
||||
"X in CSS pixels is calculated correctly"
|
||||
);
|
||||
this.isWithin(
|
||||
y.value / dpr,
|
||||
yInCSS.value,
|
||||
1,
|
||||
"Heights in CSS pixels is calculated correctly"
|
||||
"Y in CSS pixels is calculated correctly"
|
||||
);
|
||||
this.isWithin(
|
||||
width.value / dpr,
|
||||
widthInCSS.value,
|
||||
1,
|
||||
"Heights in CSS pixels is calculated correctly"
|
||||
"Width in CSS pixels is calculated correctly"
|
||||
);
|
||||
this.isWithin(
|
||||
height.value / dpr,
|
||||
heightInCSS.value,
|
||||
1,
|
||||
"Heights in CSS pixels is calculated correctly"
|
||||
"Height in CSS pixels is calculated correctly"
|
||||
);
|
||||
|
||||
return [x.value, y.value, width.value, height.value];
|
||||
|
|
|
@ -4,7 +4,11 @@ support-files =
|
|||
!/accessible/tests/browser/shared-head.js
|
||||
!/accessible/tests/browser/*.jsm
|
||||
!/accessible/tests/mochitest/*.js
|
||||
!/accessible/tests/mochitest/letters.gif
|
||||
|
||||
[browser_test_browser.js]
|
||||
[browser_test_canvas_hitregion.js]
|
||||
skip-if = os == "android"
|
||||
[browser_test_general.js]
|
||||
[browser_test_shadowroot.js]
|
||||
[browser_test_zoom.js]
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
async function runTests(browser, accDoc) {
|
||||
await waitForImageMap(browser, accDoc);
|
||||
const dpr = await getContentDPR(browser);
|
||||
|
||||
info("Not specific case, child and deepchild testing.");
|
||||
testChildAtPoint(
|
||||
dpr,
|
||||
3,
|
||||
3,
|
||||
findAccessibleChildByID(accDoc, "list"),
|
||||
findAccessibleChildByID(accDoc, "listitem"),
|
||||
findAccessibleChildByID(accDoc, "inner").firstChild
|
||||
);
|
||||
todo(
|
||||
false,
|
||||
"Bug 746974 - children must match on all platforms. On Windows, " +
|
||||
"ChildAtPoint with eDeepestChild is incorrectly ignoring MustPrune " +
|
||||
"for the graphic."
|
||||
);
|
||||
|
||||
info(
|
||||
"::MustPrune case (in this case childAtPoint doesn't look inside a " +
|
||||
"textbox), point is inside of textbox."
|
||||
);
|
||||
const txt = findAccessibleChildByID(accDoc, "txt");
|
||||
testChildAtPoint(dpr, 1, 1, txt, txt, txt);
|
||||
|
||||
info(
|
||||
"::MustPrune case, point is outside of textbox accessible but is in document."
|
||||
);
|
||||
testChildAtPoint(dpr, -1, -1, txt, null, null);
|
||||
|
||||
info("::MustPrune case, point is outside of root accessible.");
|
||||
testChildAtPoint(dpr, -10000, -10000, txt, null, null);
|
||||
|
||||
info("Not specific case, point is inside of btn accessible.");
|
||||
const btn = findAccessibleChildByID(accDoc, "btn");
|
||||
testChildAtPoint(dpr, 1, 1, btn, btn, btn);
|
||||
|
||||
info("Not specific case, point is outside of btn accessible.");
|
||||
testChildAtPoint(dpr, -1, -1, btn, null, null);
|
||||
|
||||
info(
|
||||
"Out of flow accessible testing, do not return out of flow accessible " +
|
||||
"because it's not a child of the accessible even though visually it is."
|
||||
);
|
||||
await invokeContentTask(browser, [], () => {
|
||||
const { CommonUtils } = ChromeUtils.import(
|
||||
"chrome://mochitests/content/browser/accessible/tests/browser/Common.jsm"
|
||||
);
|
||||
|
||||
const doc = content.document;
|
||||
const rectArea = CommonUtils.getNode("area", doc).getBoundingClientRect();
|
||||
const outOfFlow = CommonUtils.getNode("outofflow", doc);
|
||||
outOfFlow.style.left = rectArea.left + "px";
|
||||
outOfFlow.style.top = rectArea.top + "px";
|
||||
});
|
||||
|
||||
const area = findAccessibleChildByID(accDoc, "area");
|
||||
testChildAtPoint(dpr, 1, 1, area, area, area);
|
||||
|
||||
info("Test image maps. Their children are not in the layout tree.");
|
||||
const imgmap = findAccessibleChildByID(accDoc, "imgmap");
|
||||
const theLetterA = imgmap.firstChild;
|
||||
await hitTest(browser, imgmap, theLetterA, theLetterA);
|
||||
await hitTest(
|
||||
browser,
|
||||
findAccessibleChildByID(accDoc, "container"),
|
||||
imgmap,
|
||||
theLetterA
|
||||
);
|
||||
|
||||
info("hit testing for element contained by zero-width element");
|
||||
const container2Input = findAccessibleChildByID(accDoc, "container2_input");
|
||||
await hitTest(
|
||||
browser,
|
||||
findAccessibleChildByID(accDoc, "container2"),
|
||||
container2Input,
|
||||
container2Input
|
||||
);
|
||||
}
|
||||
|
||||
addAccessibleTask(
|
||||
`
|
||||
<div role="list" id="list">
|
||||
<div role="listitem" id="listitem"><span title="foo" id="inner">inner</span>item</div>
|
||||
</div>
|
||||
|
||||
<span role="button">button1</span><span role="button" id="btn">button2</span>
|
||||
|
||||
<span role="textbox">textbox1</span><span role="textbox" id="txt">textbox2</span>
|
||||
|
||||
<div id="outofflow" style="width: 10px; height: 10px; position: absolute; left: 0px; top: 0px; background-color: yellow;">
|
||||
</div>
|
||||
<div id="area" style="width: 100px; height: 100px; background-color: blue;"></div>
|
||||
|
||||
<map name="atoz_map">
|
||||
<area id="thelettera" href="http://www.bbc.co.uk/radio4/atoz/index.shtml#a"
|
||||
coords="0,0,15,15" alt="thelettera" shape="rect"/>
|
||||
</map>
|
||||
|
||||
<div id="container">
|
||||
<img id="imgmap" width="447" height="15" usemap="#atoz_map" src="http://example.com/a11y/accessible/tests/mochitest/letters.gif"/>
|
||||
</div>
|
||||
|
||||
<div id="container2" style="width: 0px">
|
||||
<input id="container2_input">
|
||||
</div>
|
||||
`,
|
||||
runTests,
|
||||
{
|
||||
iframe: true,
|
||||
remoteIframe: true,
|
||||
// Ensure that all hittest elements are in view.
|
||||
iframeAttrs: { style: "width: 600px; height: 600px;" },
|
||||
}
|
||||
);
|
|
@ -0,0 +1,61 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
async function runTests(browser, accDoc) {
|
||||
const dpr = await getContentDPR(browser);
|
||||
let componentAcc = findAccessibleChildByID(accDoc, "component1");
|
||||
testChildAtPoint(
|
||||
dpr,
|
||||
1,
|
||||
1,
|
||||
componentAcc,
|
||||
componentAcc.firstChild,
|
||||
componentAcc.firstChild
|
||||
);
|
||||
|
||||
componentAcc = findAccessibleChildByID(accDoc, "component2");
|
||||
testChildAtPoint(
|
||||
dpr,
|
||||
1,
|
||||
1,
|
||||
componentAcc,
|
||||
componentAcc.firstChild,
|
||||
componentAcc.firstChild
|
||||
);
|
||||
}
|
||||
|
||||
addAccessibleTask(
|
||||
`
|
||||
<div role="group" class="components" id="component1" style="display: inline-block;">
|
||||
<!--
|
||||
<div role="button" id="component-child"
|
||||
style="width: 100px; height: 100px; background-color: pink;">
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
<div role="group" class="components" id="component2" style="display: inline-block;">
|
||||
<!--
|
||||
<button>Hello world</button>
|
||||
-->
|
||||
</div>
|
||||
<script>
|
||||
// This routine adds the comment children of each 'component' to its
|
||||
// shadow root.
|
||||
var components = document.querySelectorAll(".components");
|
||||
for (var i = 0; i < components.length; i++) {
|
||||
var component = components[i];
|
||||
var shadow = component.attachShadow({mode: "open"});
|
||||
for (var child = component.firstChild; child; child = child.nextSibling) {
|
||||
if (child.nodeType === 8)
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
shadow.innerHTML = child.data;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
`,
|
||||
runTests,
|
||||
{ iframe: true, remoteIframe: true }
|
||||
);
|
|
@ -0,0 +1,38 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
async function runTests(browser, accDoc) {
|
||||
if (Services.appinfo.OS !== "Darwin") {
|
||||
const p1 = findAccessibleChildByID(accDoc, "p1");
|
||||
const p2 = findAccessibleChildByID(accDoc, "p2");
|
||||
await hitTest(browser, accDoc, p1, p1.firstChild);
|
||||
await hitTest(browser, accDoc, p2, p2.firstChild);
|
||||
|
||||
await invokeContentTask(browser, [], () => {
|
||||
const { Layout } = ChromeUtils.import(
|
||||
"chrome://mochitests/content/browser/accessible/tests/browser/Layout.jsm"
|
||||
);
|
||||
|
||||
Layout.zoomDocument(content.document, 2.0);
|
||||
content.document.body.offsetTop; // getBounds doesn't flush layout on its own.
|
||||
});
|
||||
|
||||
await hitTest(browser, accDoc, p1, p1.firstChild);
|
||||
await hitTest(browser, accDoc, p2, p2.firstChild);
|
||||
} else {
|
||||
todo(
|
||||
false,
|
||||
"Bug 746974 - deepest child must be correct on all platforms, disabling on Mac!"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
addAccessibleTask(`<p id="p1">para 1</p><p id="p2">para 2</p>`, runTests, {
|
||||
iframe: true,
|
||||
remoteIframe: true,
|
||||
// Ensure that all hittest elements are in view.
|
||||
iframeAttrs: { style: "left: 100px; top: 100px;" },
|
||||
});
|
|
@ -28,3 +28,62 @@ const { CommonUtils } = ChromeUtils.import(
|
|||
const { Layout } = ChromeUtils.import(
|
||||
"chrome://mochitests/content/browser/accessible/tests/browser/Layout.jsm"
|
||||
);
|
||||
|
||||
function getChildAtPoint(container, x, y, findDeepestChild) {
|
||||
try {
|
||||
return findDeepestChild
|
||||
? container.getDeepestChildAtPoint(x, y)
|
||||
: container.getChildAtPoint(x, y);
|
||||
} catch (e) {
|
||||
// Failed to get child at point.
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function testChildAtPoint(dpr, x, y, container, child, grandChild) {
|
||||
const [containerX, containerY] = Layout.getBounds(container, dpr);
|
||||
x += containerX;
|
||||
y += containerY;
|
||||
|
||||
CommonUtils.isObject(
|
||||
getChildAtPoint(container, x, y, false),
|
||||
child,
|
||||
`Wrong direct child accessible at the point (${x}, ${y}) of ${CommonUtils.prettyName(
|
||||
container
|
||||
)}`
|
||||
);
|
||||
|
||||
CommonUtils.isObject(
|
||||
getChildAtPoint(container, x, y, true),
|
||||
grandChild,
|
||||
`Wrong deepest child accessible at the point (${x}, ${y}) of ${CommonUtils.prettyName(
|
||||
container
|
||||
)}`
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if getChildAtPoint returns the given child and grand child accessibles
|
||||
* at coordinates of child accessible (direct and deep hit test).
|
||||
*/
|
||||
async function hitTest(browser, container, child, grandChild) {
|
||||
const [childX, childY] = await getContentBoundsForDOMElm(
|
||||
browser,
|
||||
getAccessibleDOMNodeID(child)
|
||||
);
|
||||
const x = childX + 1;
|
||||
const y = childY + 1;
|
||||
|
||||
CommonUtils.isObject(
|
||||
getChildAtPoint(container, x, y, false),
|
||||
child,
|
||||
`Wrong direct child of ${prettyName(container)}`
|
||||
);
|
||||
|
||||
CommonUtils.isObject(
|
||||
getChildAtPoint(container, x, y, true),
|
||||
grandChild,
|
||||
`Wrong deepest child of ${prettyName(container)}`
|
||||
);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче