summaryrefslogtreecommitdiffstats
path: root/accessible/tests/mochitest/layout.js
diff options
context:
space:
mode:
Diffstat (limited to 'accessible/tests/mochitest/layout.js')
-rw-r--r--accessible/tests/mochitest/layout.js258
1 files changed, 258 insertions, 0 deletions
diff --git a/accessible/tests/mochitest/layout.js b/accessible/tests/mochitest/layout.js
new file mode 100644
index 000000000..e1fb14670
--- /dev/null
+++ b/accessible/tests/mochitest/layout.js
@@ -0,0 +1,258 @@
+/**
+ * Tests if the given child and grand child accessibles at the given point are
+ * expected.
+ *
+ * @param aID [in] accessible identifier
+ * @param aX [in] x coordinate of the point relative accessible
+ * @param aY [in] y coordinate of the point relative accessible
+ * @param aChildID [in] expected child accessible
+ * @param aGrandChildID [in] expected child accessible
+ */
+function testChildAtPoint(aID, aX, aY, aChildID, aGrandChildID)
+{
+ var child = getChildAtPoint(aID, aX, aY, false);
+ var expectedChild = getAccessible(aChildID);
+
+ var msg = "Wrong direct child accessible at the point (" + aX + ", " + aY +
+ ") of " + prettyName(aID);
+ isObject(child, expectedChild, msg);
+
+ var grandChild = getChildAtPoint(aID, aX, aY, true);
+ var expectedGrandChild = getAccessible(aGrandChildID);
+
+ msg = "Wrong deepest child accessible at the point (" + aX + ", " + aY +
+ ") of " + prettyName(aID);
+ isObject(grandChild, expectedGrandChild, msg);
+}
+
+/**
+ * Test if getChildAtPoint returns the given child and grand child accessibles
+ * at coordinates of child accessible (direct and deep hit test).
+ */
+function hitTest(aContainerID, aChildID, aGrandChildID)
+{
+ var container = getAccessible(aContainerID);
+ var child = getAccessible(aChildID);
+ var grandChild = getAccessible(aGrandChildID);
+
+ var [x, y] = getBoundsForDOMElm(child);
+
+ var actualChild = container.getChildAtPoint(x + 1, y + 1);
+ isObject(actualChild, child,
+ "Wrong direct child of " + prettyName(aContainerID));
+
+ var actualGrandChild = container.getDeepestChildAtPoint(x + 1, y + 1);
+ isObject(actualGrandChild, grandChild,
+ "Wrong deepest child of " + prettyName(aContainerID));
+}
+
+/**
+ * Test if getOffsetAtPoint returns the given text offset at given coordinates.
+ */
+function testOffsetAtPoint(aHyperTextID, aX, aY, aCoordType, aExpectedOffset)
+{
+ var hyperText = getAccessible(aHyperTextID, [nsIAccessibleText]);
+ var offset = hyperText.getOffsetAtPoint(aX, aY, aCoordType);
+ is(offset, aExpectedOffset,
+ "Wrong offset at given point (" + aX + ", " + aY + ") for " +
+ prettyName(aHyperTextID));
+}
+
+/**
+ * Zoom the given document.
+ */
+function zoomDocument(aDocument, aZoom)
+{
+ var docShell = aDocument.defaultView.
+ QueryInterface(Components.interfaces.nsIInterfaceRequestor).
+ getInterface(Components.interfaces.nsIWebNavigation).
+ QueryInterface(Components.interfaces.nsIDocShell);
+ var docViewer = docShell.contentViewer;
+
+ docViewer.fullZoom = aZoom;
+}
+
+/**
+ * Return child accessible at the given point.
+ *
+ * @param aIdentifier [in] accessible identifier
+ * @param aX [in] x coordinate of the point relative accessible
+ * @param aY [in] y coordinate of the point relative accessible
+ * @param aFindDeepestChild [in] points whether deepest or nearest child should
+ * be returned
+ * @return the child accessible at the given point
+ */
+function getChildAtPoint(aIdentifier, aX, aY, aFindDeepestChild)
+{
+ var acc = getAccessible(aIdentifier);
+ if (!acc)
+ return;
+
+ var [screenX, screenY] = getBoundsForDOMElm(acc.DOMNode);
+
+ var x = screenX + aX;
+ var y = screenY + aY;
+
+ try {
+ if (aFindDeepestChild)
+ return acc.getDeepestChildAtPoint(x, y);
+ return acc.getChildAtPoint(x, y);
+ } catch (e) { }
+
+ return null;
+}
+
+/**
+ * Test the accessible position.
+ */
+function testPos(aID, aPoint)
+{
+ var [expectedX, expectedY] =
+ (aPoint != undefined) ? aPoint : getBoundsForDOMElm(aID);
+
+ var [x, y] = getBounds(aID);
+ is(x, expectedX, "Wrong x coordinate of " + prettyName(aID));
+ is(y, expectedY, "Wrong y coordinate of " + prettyName(aID));
+}
+
+/**
+ * Test the accessible boundaries.
+ */
+function testBounds(aID, aRect)
+{
+ var [expectedX, expectedY, expectedWidth, expectedHeight] =
+ (aRect != undefined) ? aRect : getBoundsForDOMElm(aID);
+
+ var [x, y, width, height] = getBounds(aID);
+ is(x, expectedX, "Wrong x coordinate of " + prettyName(aID));
+ is(y, expectedY, "Wrong y coordinate of " + prettyName(aID));
+ is(width, expectedWidth, "Wrong width of " + prettyName(aID));
+ is(height, expectedHeight, "Wrong height of " + prettyName(aID));
+}
+
+/**
+ * Test text position at the given offset.
+ */
+function testTextPos(aID, aOffset, aPoint, aCoordOrigin)
+{
+ var [expectedX, expectedY] = aPoint;
+
+ var xObj = {}, yObj = {};
+ var hyperText = getAccessible(aID, [nsIAccessibleText]);
+ hyperText.getCharacterExtents(aOffset, xObj, yObj, {}, {}, aCoordOrigin);
+ is(xObj.value, expectedX,
+ "Wrong x coordinate at offset " + aOffset + " for " + prettyName(aID));
+ ok(yObj.value - expectedY < 2 && expectedY - yObj.value < 2,
+ "Wrong y coordinate at offset " + aOffset + " for " + prettyName(aID) +
+ " - got " + yObj.value + ", expected " + expectedY +
+ "The difference doesn't exceed 1.");
+}
+
+/**
+ * Test text bounds that is enclosed betwene the given offsets.
+ */
+function testTextBounds(aID, aStartOffset, aEndOffset, aRect, aCoordOrigin)
+{
+ var [expectedX, expectedY, expectedWidth, expectedHeight] = aRect;
+
+ var xObj = {}, yObj = {}, widthObj = {}, heightObj = {};
+ var hyperText = getAccessible(aID, [nsIAccessibleText]);
+ hyperText.getRangeExtents(aStartOffset, aEndOffset,
+ xObj, yObj, widthObj, heightObj, aCoordOrigin);
+ is(xObj.value, expectedX,
+ "Wrong x coordinate of text between offsets (" + aStartOffset + ", " +
+ aEndOffset + ") for " + prettyName(aID));
+ is(yObj.value, expectedY,
+ "Wrong y coordinate of text between offsets (" + aStartOffset + ", " +
+ aEndOffset + ") for " + prettyName(aID));
+
+ var msg = "Wrong width of text between offsets (" + aStartOffset + ", " +
+ aEndOffset + ") for " + prettyName(aID);
+ if (widthObj.value == expectedWidth)
+ ok(true, msg);
+ else
+ todo(false, msg); // fails on some windows machines
+
+ is(heightObj.value, expectedHeight,
+ "Wrong height of text between offsets (" + aStartOffset + ", " +
+ aEndOffset + ") for " + prettyName(aID));
+}
+
+/**
+ * Return the accessible coordinates relative to the screen in device pixels.
+ */
+function getPos(aID)
+{
+ var accessible = getAccessible(aID);
+ var x = {}, y = {};
+ accessible.getBounds(x, y, {}, {});
+ return [x.value, y.value];
+}
+
+/**
+ * Return the accessible coordinates and size relative to the screen in device
+ * pixels.
+ */
+function getBounds(aID)
+{
+ var accessible = getAccessible(aID);
+ var x = {}, y = {}, width = {}, height = {};
+ accessible.getBounds(x, y, width, height);
+ return [x.value, y.value, width.value, height.value];
+}
+
+/**
+ * Return DOM node coordinates relative the screen and its size in device
+ * pixels.
+ */
+function getBoundsForDOMElm(aID)
+{
+ var x = 0, y = 0, width = 0, height = 0;
+
+ var elm = getNode(aID);
+ if (elm.localName == "area") {
+ var mapName = elm.parentNode.getAttribute("name");
+ var selector = "[usemap='#" + mapName + "']";
+ var img = elm.ownerDocument.querySelector(selector);
+
+ var areaCoords = elm.coords.split(",");
+ var areaX = parseInt(areaCoords[0]);
+ var areaY = parseInt(areaCoords[1]);
+ var areaWidth = parseInt(areaCoords[2]) - areaX;
+ var areaHeight = parseInt(areaCoords[3]) - areaY;
+
+ var rect = img.getBoundingClientRect();
+ x = rect.left + areaX;
+ y = rect.top + areaY;
+ width = areaWidth;
+ height = areaHeight;
+ }
+ else {
+ var rect = elm.getBoundingClientRect();
+ x = rect.left;
+ y = rect.top;
+ width = rect.width;
+ height = rect.height;
+ }
+
+ var elmWindow = elm.ownerDocument.defaultView;
+ return CSSToDevicePixels(elmWindow,
+ x + elmWindow.mozInnerScreenX,
+ y + elmWindow.mozInnerScreenY,
+ width,
+ height);
+}
+
+function CSSToDevicePixels(aWindow, aX, aY, aWidth, aHeight)
+{
+ var winUtil = aWindow.
+ QueryInterface(Components.interfaces.nsIInterfaceRequestor).
+ getInterface(Components.interfaces.nsIDOMWindowUtils);
+
+ var ratio = winUtil.screenPixelsPerCSSPixel;
+
+ // CSS pixels and ratio can be not integer. Device pixels are always integer.
+ // Do our best and hope it works.
+ return [ Math.round(aX * ratio), Math.round(aY * ratio),
+ Math.round(aWidth * ratio), Math.round(aHeight * ratio) ];
+}