1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/accessible/tests/mochitest/layout.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,259 @@ 1.4 +/** 1.5 + * Tests if the given child and grand child accessibles at the given point are 1.6 + * expected. 1.7 + * 1.8 + * @param aID [in] accessible identifier 1.9 + * @param aX [in] x coordinate of the point relative accessible 1.10 + * @param aY [in] y coordinate of the point relative accessible 1.11 + * @param aChildID [in] expected child accessible 1.12 + * @param aGrandChildID [in] expected child accessible 1.13 + */ 1.14 +function testChildAtPoint(aID, aX, aY, aChildID, aGrandChildID) 1.15 +{ 1.16 + var child = getChildAtPoint(aID, aX, aY, false); 1.17 + var expectedChild = getAccessible(aChildID); 1.18 + 1.19 + var msg = "Wrong direct child accessible at the point (" + aX + ", " + aY + 1.20 + ") of " + prettyName(aID); 1.21 + isObject(child, expectedChild, msg); 1.22 + 1.23 + var grandChild = getChildAtPoint(aID, aX, aY, true); 1.24 + var expectedGrandChild = getAccessible(aGrandChildID); 1.25 + 1.26 + msg = "Wrong deepest child accessible at the point (" + aX + ", " + aY + 1.27 + ") of " + prettyName(aID); 1.28 + isObject(grandChild, expectedGrandChild, msg); 1.29 +} 1.30 + 1.31 +/** 1.32 + * Test if getChildAtPoint returns the given child and grand child accessibles 1.33 + * at coordinates of child accessible (direct and deep hit test). 1.34 + */ 1.35 +function hitTest(aContainerID, aChildID, aGrandChildID) 1.36 +{ 1.37 + var container = getAccessible(aContainerID); 1.38 + var child = getAccessible(aChildID); 1.39 + var grandChild = getAccessible(aGrandChildID); 1.40 + 1.41 + var [x, y] = getBoundsForDOMElm(child); 1.42 + 1.43 + var actualChild = container.getChildAtPoint(x + 1, y + 1); 1.44 + isObject(actualChild, child, 1.45 + "Wrong direct child of " + prettyName(aContainerID)); 1.46 + 1.47 + var actualGrandChild = container.getDeepestChildAtPoint(x + 1, y + 1); 1.48 + isObject(actualGrandChild, grandChild, 1.49 + "Wrong deepest child of " + prettyName(aContainerID)); 1.50 +} 1.51 + 1.52 +/** 1.53 + * Test if getOffsetAtPoint returns the given text offset at given coordinates. 1.54 + */ 1.55 +function testOffsetAtPoint(aHyperTextID, aX, aY, aCoordType, aExpectedOffset) 1.56 +{ 1.57 + var hyperText = getAccessible(aHyperTextID, [nsIAccessibleText]); 1.58 + var offset = hyperText.getOffsetAtPoint(aX, aY, aCoordType); 1.59 + is(offset, aExpectedOffset, 1.60 + "Wrong offset at given point (" + aX + ", " + aY + ") for " + 1.61 + prettyName(aHyperTextID)); 1.62 +} 1.63 + 1.64 +/** 1.65 + * Zoom the given document. 1.66 + */ 1.67 +function zoomDocument(aDocument, aZoom) 1.68 +{ 1.69 + var docShell = aDocument.defaultView. 1.70 + QueryInterface(Components.interfaces.nsIInterfaceRequestor). 1.71 + getInterface(Components.interfaces.nsIWebNavigation). 1.72 + QueryInterface(Components.interfaces.nsIDocShell); 1.73 + var docViewer = docShell.contentViewer. 1.74 + QueryInterface(Components.interfaces.nsIMarkupDocumentViewer); 1.75 + 1.76 + docViewer.fullZoom = aZoom; 1.77 +} 1.78 + 1.79 +/** 1.80 + * Return child accessible at the given point. 1.81 + * 1.82 + * @param aIdentifier [in] accessible identifier 1.83 + * @param aX [in] x coordinate of the point relative accessible 1.84 + * @param aY [in] y coordinate of the point relative accessible 1.85 + * @param aFindDeepestChild [in] points whether deepest or nearest child should 1.86 + * be returned 1.87 + * @return the child accessible at the given point 1.88 + */ 1.89 +function getChildAtPoint(aIdentifier, aX, aY, aFindDeepestChild) 1.90 +{ 1.91 + var acc = getAccessible(aIdentifier); 1.92 + if (!acc) 1.93 + return; 1.94 + 1.95 + var [screenX, screenY] = getBoundsForDOMElm(acc.DOMNode); 1.96 + 1.97 + var x = screenX + aX; 1.98 + var y = screenY + aY; 1.99 + 1.100 + try { 1.101 + if (aFindDeepestChild) 1.102 + return acc.getDeepestChildAtPoint(x, y); 1.103 + return acc.getChildAtPoint(x, y); 1.104 + } catch (e) { } 1.105 + 1.106 + return null; 1.107 +} 1.108 + 1.109 +/** 1.110 + * Test the accessible position. 1.111 + */ 1.112 +function testPos(aID, aPoint) 1.113 +{ 1.114 + var [expectedX, expectedY] = 1.115 + (aPoint != undefined) ? aPoint : getBoundsForDOMElm(aID); 1.116 + 1.117 + var [x, y] = getBounds(aID); 1.118 + is(x, expectedX, "Wrong x coordinate of " + prettyName(aID)); 1.119 + is(y, expectedY, "Wrong y coordinate of " + prettyName(aID)); 1.120 +} 1.121 + 1.122 +/** 1.123 + * Test the accessible boundaries. 1.124 + */ 1.125 +function testBounds(aID, aRect) 1.126 +{ 1.127 + var [expectedX, expectedY, expectedWidth, expectedHeight] = 1.128 + (aRect != undefined) ? aRect : getBoundsForDOMElm(aID); 1.129 + 1.130 + var [x, y, width, height] = getBounds(aID); 1.131 + is(x, expectedX, "Wrong x coordinate of " + prettyName(aID)); 1.132 + is(y, expectedY, "Wrong y coordinate of " + prettyName(aID)); 1.133 + is(width, expectedWidth, "Wrong width of " + prettyName(aID)); 1.134 + is(height, expectedHeight, "Wrong height of " + prettyName(aID)); 1.135 +} 1.136 + 1.137 +/** 1.138 + * Test text position at the given offset. 1.139 + */ 1.140 +function testTextPos(aID, aOffset, aPoint, aCoordOrigin) 1.141 +{ 1.142 + var [expectedX, expectedY] = aPoint; 1.143 + 1.144 + var xObj = {}, yObj = {}; 1.145 + var hyperText = getAccessible(aID, [nsIAccessibleText]); 1.146 + hyperText.getCharacterExtents(aOffset, xObj, yObj, {}, {}, aCoordOrigin); 1.147 + is(xObj.value, expectedX, 1.148 + "Wrong x coordinate at offset " + aOffset + " for " + prettyName(aID)); 1.149 + ok(yObj.value - expectedY < 2 && expectedY - yObj.value < 2, 1.150 + "Wrong y coordinate at offset " + aOffset + " for " + prettyName(aID) + 1.151 + " - got " + yObj.value + ", expected " + expectedY + 1.152 + "The difference doesn't exceed 1."); 1.153 +} 1.154 + 1.155 +/** 1.156 + * Test text bounds that is enclosed betwene the given offsets. 1.157 + */ 1.158 +function testTextBounds(aID, aStartOffset, aEndOffset, aRect, aCoordOrigin) 1.159 +{ 1.160 + var [expectedX, expectedY, expectedWidth, expectedHeight] = aRect; 1.161 + 1.162 + var xObj = {}, yObj = {}, widthObj = {}, heightObj = {}; 1.163 + var hyperText = getAccessible(aID, [nsIAccessibleText]); 1.164 + hyperText.getRangeExtents(aStartOffset, aEndOffset, 1.165 + xObj, yObj, widthObj, heightObj, aCoordOrigin); 1.166 + is(xObj.value, expectedX, 1.167 + "Wrong x coordinate of text between offsets (" + aStartOffset + ", " + 1.168 + aEndOffset + ") for " + prettyName(aID)); 1.169 + is(yObj.value, expectedY, 1.170 + "Wrong y coordinate of text between offsets (" + aStartOffset + ", " + 1.171 + aEndOffset + ") for " + prettyName(aID)); 1.172 + 1.173 + var msg = "Wrong width of text between offsets (" + aStartOffset + ", " + 1.174 + aEndOffset + ") for " + prettyName(aID); 1.175 + if (widthObj.value == expectedWidth) 1.176 + ok(true, msg); 1.177 + else 1.178 + todo(false, msg); // fails on some windows machines 1.179 + 1.180 + is(heightObj.value, expectedHeight, 1.181 + "Wrong height of text between offsets (" + aStartOffset + ", " + 1.182 + aEndOffset + ") for " + prettyName(aID)); 1.183 +} 1.184 + 1.185 +/** 1.186 + * Return the accessible coordinates relative to the screen in device pixels. 1.187 + */ 1.188 +function getPos(aID) 1.189 +{ 1.190 + var accessible = getAccessible(aID); 1.191 + var x = {}, y = {}; 1.192 + accessible.getBounds(x, y, {}, {}); 1.193 + return [x.value, y.value]; 1.194 +} 1.195 + 1.196 +/** 1.197 + * Return the accessible coordinates and size relative to the screen in device 1.198 + * pixels. 1.199 + */ 1.200 +function getBounds(aID) 1.201 +{ 1.202 + var accessible = getAccessible(aID); 1.203 + var x = {}, y = {}, width = {}, height = {}; 1.204 + accessible.getBounds(x, y, width, height); 1.205 + return [x.value, y.value, width.value, height.value]; 1.206 +} 1.207 + 1.208 +/** 1.209 + * Return DOM node coordinates relative the screen and its size in device 1.210 + * pixels. 1.211 + */ 1.212 +function getBoundsForDOMElm(aID) 1.213 +{ 1.214 + var x = 0, y = 0, width = 0, height = 0; 1.215 + 1.216 + var elm = getNode(aID); 1.217 + if (elm.localName == "area") { 1.218 + var mapName = elm.parentNode.getAttribute("name"); 1.219 + var selector = "[usemap='#" + mapName + "']"; 1.220 + var img = elm.ownerDocument.querySelector(selector); 1.221 + 1.222 + var areaCoords = elm.coords.split(","); 1.223 + var areaX = parseInt(areaCoords[0]); 1.224 + var areaY = parseInt(areaCoords[1]); 1.225 + var areaWidth = parseInt(areaCoords[2]) - areaX; 1.226 + var areaHeight = parseInt(areaCoords[3]) - areaY; 1.227 + 1.228 + var rect = img.getBoundingClientRect(); 1.229 + x = rect.left + areaX; 1.230 + y = rect.top + areaY; 1.231 + width = areaWidth; 1.232 + height = areaHeight; 1.233 + } 1.234 + else { 1.235 + var rect = elm.getBoundingClientRect(); 1.236 + x = rect.left; 1.237 + y = rect.top; 1.238 + width = rect.width; 1.239 + height = rect.height; 1.240 + } 1.241 + 1.242 + var elmWindow = elm.ownerDocument.defaultView; 1.243 + return CSSToDevicePixels(elmWindow, 1.244 + x + elmWindow.mozInnerScreenX, 1.245 + y + elmWindow.mozInnerScreenY, 1.246 + width, 1.247 + height); 1.248 +} 1.249 + 1.250 +function CSSToDevicePixels(aWindow, aX, aY, aWidth, aHeight) 1.251 +{ 1.252 + var winUtil = aWindow. 1.253 + QueryInterface(Components.interfaces.nsIInterfaceRequestor). 1.254 + getInterface(Components.interfaces.nsIDOMWindowUtils); 1.255 + 1.256 + var ratio = winUtil.screenPixelsPerCSSPixel; 1.257 + 1.258 + // CSS pixels and ratio can be not integer. Device pixels are always integer. 1.259 + // Do our best and hope it works. 1.260 + return [ Math.round(aX * ratio), Math.round(aY * ratio), 1.261 + Math.round(aWidth * ratio), Math.round(aHeight * ratio) ]; 1.262 +}