accessible/tests/mochitest/layout.js

changeset 0
6474c204b198
     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 +}

mercurial