diff options
Diffstat (limited to 'accessible/tests/mochitest/layout.js')
-rw-r--r-- | accessible/tests/mochitest/layout.js | 258 |
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) ]; +} |