1 /* import-globals-from common.js */
4 * Tests if the given child and grand child accessibles at the given point are
7 * @param aID [in] accessible identifier
8 * @param aX [in] x coordinate of the point relative accessible
9 * @param aY [in] y coordinate of the point relative accessible
10 * @param aChildID [in] expected child accessible
11 * @param aGrandChildID [in] expected child accessible
13 function testChildAtPoint(aID, aX, aY, aChildID, aGrandChildID) {
14 var child = getChildAtPoint(aID, aX, aY, false);
15 var expectedChild = getAccessible(aChildID);
18 "Wrong direct child accessible at the point (" +
24 isObject(child, expectedChild, msg);
26 var grandChild = getChildAtPoint(aID, aX, aY, true);
27 var expectedGrandChild = getAccessible(aGrandChildID);
30 "Wrong deepest child accessible at the point (" +
36 isObject(grandChild, expectedGrandChild, msg);
40 * Test if getChildAtPoint returns the given child and grand child accessibles
41 * at coordinates of child accessible (direct and deep hit test).
43 function hitTest(aContainerID, aChildID, aGrandChildID) {
44 var container = getAccessible(aContainerID);
45 var child = getAccessible(aChildID);
46 var grandChild = getAccessible(aGrandChildID);
48 var [x, y] = getBoundsForDOMElm(child);
50 var actualChild = container.getChildAtPoint(x + 1, y + 1);
54 "Wrong direct child of " + prettyName(aContainerID)
57 var actualGrandChild = container.getDeepestChildAtPoint(x + 1, y + 1);
61 "Wrong deepest child of " + prettyName(aContainerID)
66 * Test if getOffsetAtPoint returns the given text offset at given coordinates.
68 function testOffsetAtPoint(aHyperTextID, aX, aY, aCoordType, aExpectedOffset) {
69 var hyperText = getAccessible(aHyperTextID, [nsIAccessibleText]);
70 var offset = hyperText.getOffsetAtPoint(aX, aY, aCoordType);
74 "Wrong offset at given point (" +
79 prettyName(aHyperTextID)
84 * Zoom the given document.
86 function zoomDocument(aDocument, aZoom) {
87 SpecialPowers.setFullZoom(aDocument.defaultView, aZoom);
91 * Set the relative resolution of this document. This is what apz does.
92 * On non-mobile platforms you won't see a visible change.
94 function setResolution(aDocument, aZoom) {
95 var windowUtils = aDocument.defaultView.windowUtils;
97 windowUtils.setResolutionAndScaleTo(aZoom);
101 * Return child accessible at the given point.
103 * @param aIdentifier [in] accessible identifier
104 * @param aX [in] x coordinate of the point relative accessible
105 * @param aY [in] y coordinate of the point relative accessible
106 * @param aFindDeepestChild [in] points whether deepest or nearest child should
108 * @return the child accessible at the given point
110 function getChildAtPoint(aIdentifier, aX, aY, aFindDeepestChild) {
111 var acc = getAccessible(aIdentifier);
116 var [screenX, screenY] = getBoundsForDOMElm(acc.DOMNode);
118 var x = screenX + aX;
119 var y = screenY + aY;
122 if (aFindDeepestChild) {
123 return acc.getDeepestChildAtPoint(x, y);
125 return acc.getChildAtPoint(x, y);
132 * Test the accessible position.
134 function testPos(aID, aPoint) {
135 var [expectedX, expectedY] =
136 aPoint != undefined ? aPoint : getBoundsForDOMElm(aID);
138 var [x, y] = getBounds(aID);
139 is(x, expectedX, "Wrong x coordinate of " + prettyName(aID));
140 is(y, expectedY, "Wrong y coordinate of " + prettyName(aID));
144 * Test the accessible boundaries.
146 function testBounds(aID, aRect) {
147 var [expectedX, expectedY, expectedWidth, expectedHeight] =
148 aRect != undefined ? aRect : getBoundsForDOMElm(aID);
150 var [x, y, width, height] = getBounds(aID);
151 is(x, expectedX, "Wrong x coordinate of " + prettyName(aID));
152 is(y, expectedY, "Wrong y coordinate of " + prettyName(aID));
153 is(width, expectedWidth, "Wrong width of " + prettyName(aID));
154 is(height, expectedHeight, "Wrong height of " + prettyName(aID));
158 * Test text position at the given offset.
160 function testTextPos(aID, aOffset, aPoint, aCoordOrigin) {
161 var [expectedX, expectedY] = aPoint;
165 var hyperText = getAccessible(aID, [nsIAccessibleText]);
166 hyperText.getCharacterExtents(aOffset, xObj, yObj, {}, {}, aCoordOrigin);
170 "Wrong x coordinate at offset " + aOffset + " for " + prettyName(aID)
173 yObj.value - expectedY <= 2 && expectedY - yObj.value <= 2,
174 "Wrong y coordinate at offset " +
182 "The difference doesn't exceed 1."
187 * Test text bounds that is enclosed betwene the given offsets.
189 function testTextBounds(aID, aStartOffset, aEndOffset, aRect, aCoordOrigin) {
190 var [expectedX, expectedY, expectedWidth, expectedHeight] = aRect;
196 var hyperText = getAccessible(aID, [nsIAccessibleText]);
197 hyperText.getRangeExtents(
212 "Wrong x coordinate of text between offsets (" +
225 `y coord of text between offsets (${aStartOffset}, ${aEndOffset}) ` +
226 `for ${prettyName(aID)}`
231 "Wrong width of text between offsets (" +
242 isWithin(expectedWidth, widthObj.value, 1, msg);
244 // fails on some windows machines
253 `height of text between offsets (${aStartOffset}, ${aEndOffset}) ` +
254 `for ${prettyName(aID)}`
259 * Return the accessible coordinates relative to the screen in device pixels.
261 function getPos(aID) {
262 var accessible = getAccessible(aID);
265 accessible.getBounds(x, y, {}, {});
266 return [x.value, y.value];
270 * Return the accessible coordinates and size relative to the screen in device
271 * pixels. This methods also retrieves coordinates in CSS pixels and ensures that they
272 * match Dev pixels with a given device pixel ratio.
274 function getBounds(aID, aDPR = window.devicePixelRatio) {
275 const accessible = getAccessible(aID);
284 accessible.getBounds(x, y, width, height);
285 accessible.getBoundsInCSSPixels(xInCSS, yInCSS, widthInCSS, heightInCSS);
287 info(`DPR is: ${aDPR}`);
292 "X in CSS pixels is calculated correctly"
298 "Y in CSS pixels is calculated correctly"
304 "Width in CSS pixels is calculated correctly"
310 "Height in CSS pixels is calculated correctly"
313 return [x.value, y.value, width.value, height.value];
316 function getRangeExtents(aID, aStartOffset, aEndOffset, aCoordOrigin) {
317 var hyperText = getAccessible(aID, [nsIAccessibleText]);
322 hyperText.getRangeExtents(
331 return [x.value, y.value, width.value, height.value];
335 * Return DOM node coordinates relative the screen and its size in device
338 function getBoundsForDOMElm(aID) {
344 var elm = getNode(aID);
345 if (elm.localName == "area") {
346 var mapName = elm.parentNode.getAttribute("name");
347 var selector = "[usemap='#" + mapName + "']";
348 var img = elm.ownerDocument.querySelector(selector);
350 var areaCoords = elm.coords.split(",");
351 var areaX = parseInt(areaCoords[0]);
352 var areaY = parseInt(areaCoords[1]);
353 var areaWidth = parseInt(areaCoords[2]) - areaX;
354 var areaHeight = parseInt(areaCoords[3]) - areaY;
356 let rect = img.getBoundingClientRect();
357 x = rect.left + areaX;
358 y = rect.top + areaY;
362 let rect = elm.getBoundingClientRect();
366 height = rect.height;
369 var elmWindow = elm.ownerGlobal;
370 return CSSToDevicePixels(
372 x + elmWindow.mozInnerScreenX,
373 y + elmWindow.mozInnerScreenY,
379 function CSSToDevicePixels(aWindow, aX, aY, aWidth, aHeight) {
380 var ratio = aWindow.devicePixelRatio;
382 // CSS pixels and ratio can be not integer. Device pixels are always integer.
383 // Do our best and hope it works.
385 Math.round(aX * ratio),
386 Math.round(aY * ratio),
387 Math.round(aWidth * ratio),
388 Math.round(aHeight * ratio),