/* 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/. */ "use strict"; // Test that the original position of a relative positioned node is correct // even when zooming. const TEST_URL = URL_ROOT + "doc_inspector_highlighter-geometry_01.html"; const ID = "geometry-editor-"; const { TYPES } = ChromeUtils.importESModule( "resource://devtools/shared/highlighters.mjs" ); const HIGHLIGHTER_TYPE = TYPES.GEOMETRY; const TESTS = { ".absolute-all-4": { desc: "Check absolute positioned element's parentOffset highlight", sides: ["top", "right", "bottom", "left"], }, ".relative": { desc: "Check relative positioned element original offset highlight", sides: ["top", "left"], }, }; add_task(async function () { const inspector = await openInspectorForURL(TEST_URL); const helper = await getHighlighterHelperFor(HIGHLIGHTER_TYPE)(inspector); helper.prefix = ID; const { finalize } = helper; for (const selector in TESTS) { await executeTest(inspector, helper, selector, TESTS[selector]); } await finalize(); }); async function executeTest(inspector, helper, selector, data) { const { show, hide } = helper; info("Showing the highlighter"); await show(selector); info(data.desc); await checkOffsetParentSame(helper, selector, data.sides); setContentPageZoomLevel(1.2); await reflowContentPage(); await checkOffsetParentSame(helper, selector, data.sides); info("Hiding the highlighter and resetting zoom"); setContentPageZoomLevel(1); await hide(); } // Check that the offsetParent element does not move around, // when the target element itself is being moved. async function checkOffsetParentSame({ getElementAttribute }, selector, sides) { const expectedOffsetParent = splitPointsIntoCoordinates( await getElementAttribute("offset-parent", "points") ); const expectedArrowStartPos = await checkArrowStartingPos( getElementAttribute, expectedOffsetParent, sides ); // Setting both to 0px would disable the offsetParent highlighter and not update points. await setContentPageElementAttribute(selector, "style", "top:1px; left:1px;"); await reflowContentPage(); const actualOffsetParent = splitPointsIntoCoordinates( await getElementAttribute("offset-parent", "points") ); const actualArrowStartPos = await checkArrowStartingPos( getElementAttribute, actualOffsetParent, sides ); await removeContentPageElementAttribute(selector, "style"); for (let i = 0; i < 4; i++) { for (let j = 0; j < 2; j++) { is( actualOffsetParent[i][j], expectedOffsetParent[i][j], `Coordinate ${j + 1}/2 of point ${ i + 1 }/4 is the same after repositioning.` ); } } for (let i = 0; i < expectedArrowStartPos.length; i++) { is( actualArrowStartPos[i], expectedArrowStartPos[i], `Start position of arrow-${sides[i]} is the same after repositioning.` ); } } // Check that the arrow starts at the boundary of the offsetParent. // This also returns the start coordinate along the relevant axis. async function checkArrowStartingPos( getElementAttribute, offsetParentPoints, sides ) { // offsetParentPoints is a number[][]. offsetParentPoints = offsetParentPoints.flat(); const result = []; for (const side of sides) { // The only attribute that must not change is the start position of the arrow. // Cross-axis and end position could change when the target element is moved. const axis = side === "top" || side === "bottom" ? "y" : "x"; // We have to round because floating point arithmetics are not consistent. // (They are consistent enough, they just vary in their 10^(-5)) const arrowPos = Math.round( parseFloat(await getElementAttribute("arrow-" + side, axis + "1")) ); ok( offsetParentPoints.includes(arrowPos), `arrow-${side} starts at offset parent` ); result.push(arrowPos); } return result; } // Splits the value of the points attribute into coordinates. function splitPointsIntoCoordinates(points) { const result = []; for (const coord of points.split(" ")) { // We have to round (see above). result.push(coord.split(",").map(s => Math.round(parseFloat(s)))); } return result; }