178 lines
4.8 KiB
JavaScript
178 lines
4.8 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
import { Assert } from "resource://testing-common/Assert.sys.mjs";
|
|
|
|
import { CommonUtils } from "chrome://mochitests/content/browser/accessible/tests/browser/Common.sys.mjs";
|
|
|
|
export const Layout = {
|
|
/**
|
|
* Zoom the given document.
|
|
*/
|
|
zoomDocument(doc, zoom) {
|
|
const bc = BrowsingContext.getFromWindow(doc.defaultView);
|
|
// To mirror the behaviour of the UI, we set the zoom
|
|
// value on the top level browsing context. This value automatically
|
|
// propagates down to iframes.
|
|
bc.top.fullZoom = zoom;
|
|
},
|
|
|
|
/**
|
|
* Set the relative resolution of this document. This is what apz does.
|
|
* On non-mobile platforms you won't see a visible change.
|
|
*/
|
|
setResolution(doc, zoom) {
|
|
const windowUtils = doc.defaultView.windowUtils;
|
|
windowUtils.setResolutionAndScaleTo(zoom);
|
|
},
|
|
|
|
/**
|
|
* Assert.is() function checking the expected value is within the range.
|
|
*/
|
|
isWithin(expected, got, within, msg) {
|
|
if (Math.abs(got - expected) <= within) {
|
|
Assert.ok(true, `${msg} - Got ${got}`);
|
|
} else {
|
|
Assert.ok(
|
|
false,
|
|
`${msg} - Got ${got}, expected ${expected} with error of ${within}`
|
|
);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Return the accessible coordinates relative to the screen in device pixels.
|
|
*/
|
|
getPos(id) {
|
|
const accessible = CommonUtils.getAccessible(id);
|
|
const x = {};
|
|
const y = {};
|
|
accessible.getBounds(x, y, {}, {});
|
|
|
|
return [x.value, y.value];
|
|
},
|
|
|
|
/**
|
|
* Return the accessible coordinates and size relative to the screen in device
|
|
* pixels. This methods also retrieves coordinates in CSS pixels and ensures that they
|
|
* match Dev pixels with a given device pixel ratio.
|
|
*/
|
|
getBounds(id, dpr) {
|
|
const accessible = CommonUtils.getAccessible(id);
|
|
const x = {};
|
|
const y = {};
|
|
const width = {};
|
|
const height = {};
|
|
const xInCSS = {};
|
|
const yInCSS = {};
|
|
const widthInCSS = {};
|
|
const heightInCSS = {};
|
|
accessible.getBounds(x, y, width, height);
|
|
accessible.getBoundsInCSSPixels(xInCSS, yInCSS, widthInCSS, heightInCSS);
|
|
|
|
this.isWithin(
|
|
x.value / dpr,
|
|
xInCSS.value,
|
|
1,
|
|
"X in CSS pixels is calculated correctly"
|
|
);
|
|
this.isWithin(
|
|
y.value / dpr,
|
|
yInCSS.value,
|
|
1,
|
|
"Y in CSS pixels is calculated correctly"
|
|
);
|
|
this.isWithin(
|
|
width.value / dpr,
|
|
widthInCSS.value,
|
|
1,
|
|
"Width in CSS pixels is calculated correctly"
|
|
);
|
|
this.isWithin(
|
|
height.value / dpr,
|
|
heightInCSS.value,
|
|
1,
|
|
"Height in CSS pixels is calculated correctly"
|
|
);
|
|
|
|
return [x.value, y.value, width.value, height.value];
|
|
},
|
|
|
|
getRangeExtents(id, startOffset, endOffset, coordOrigin) {
|
|
const hyperText = CommonUtils.getAccessible(id, [Ci.nsIAccessibleText]);
|
|
const x = {};
|
|
const y = {};
|
|
const width = {};
|
|
const height = {};
|
|
hyperText.getRangeExtents(
|
|
startOffset,
|
|
endOffset,
|
|
x,
|
|
y,
|
|
width,
|
|
height,
|
|
coordOrigin
|
|
);
|
|
|
|
return [x.value, y.value, width.value, height.value];
|
|
},
|
|
|
|
CSSToDevicePixels(win, x, y, width, height) {
|
|
const ratio = win.devicePixelRatio;
|
|
|
|
// CSS pixels and ratio can be not integer. Device pixels are always integer.
|
|
// Do our best and hope it works.
|
|
return [
|
|
Math.round(x * ratio),
|
|
Math.round(y * ratio),
|
|
Math.round(width * ratio),
|
|
Math.round(height * ratio),
|
|
];
|
|
},
|
|
|
|
/**
|
|
* Return DOM node coordinates relative the screen and its size in device
|
|
* pixels.
|
|
*/
|
|
getBoundsForDOMElm(id, doc) {
|
|
let x = 0;
|
|
let y = 0;
|
|
let width = 0;
|
|
let height = 0;
|
|
|
|
const elm = CommonUtils.getNode(id, doc);
|
|
const elmWindow = elm.ownerGlobal;
|
|
if (elm.localName == "area") {
|
|
const mapName = elm.parentNode.getAttribute("name");
|
|
const selector = `[usemap="#${mapName}"]`;
|
|
const img = elm.ownerDocument.querySelector(selector);
|
|
|
|
const areaCoords = elm.coords.split(",");
|
|
const areaX = parseInt(areaCoords[0], 10);
|
|
const areaY = parseInt(areaCoords[1], 10);
|
|
const areaWidth = parseInt(areaCoords[2], 10) - areaX;
|
|
const areaHeight = parseInt(areaCoords[3], 10) - areaY;
|
|
|
|
const rect = img.getBoundingClientRect();
|
|
x = rect.left + areaX;
|
|
y = rect.top + areaY;
|
|
width = areaWidth;
|
|
height = areaHeight;
|
|
} else {
|
|
const rect = elm.getBoundingClientRect();
|
|
x = rect.left;
|
|
y = rect.top;
|
|
width = rect.width;
|
|
height = rect.height;
|
|
}
|
|
|
|
return this.CSSToDevicePixels(
|
|
elmWindow,
|
|
x + elmWindow.mozInnerScreenX,
|
|
y + elmWindow.mozInnerScreenY,
|
|
width,
|
|
height
|
|
);
|
|
},
|
|
};
|