/* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ /* eslint no-unused-vars: [2, {"vars": "local"}] */ "use strict"; // Import the inspector's head.js first (which itself imports shared-head.js). Services.scriptloader.loadSubScript( "chrome://mochitests/content/browser/devtools/client/inspector/test/head.js", this ); Services.prefs.setIntPref("devtools.toolbox.footer.height", 350); registerCleanupFunction(() => { Services.prefs.clearUserPref("devtools.toolbox.footer.height"); }); /** * Is the given node visible in the page (rendered in the frame tree). * @param {DOMNode} * @return {Boolean} */ function isNodeVisible(node) { return !!node.getClientRects().length; } /** * Wait for the boxmodel-view-updated event. * * @param {InspectorPanel} inspector * The instance of InspectorPanel currently loaded in the toolbox. * @param {Boolean} waitForSelectionUpdate * Should the boxmodel-view-updated event come from a new selection. * @return {Promise} a promise */ async function waitForUpdate(inspector, waitForSelectionUpdate) { /** * While the highlighter is visible (mouse over the fields of the box model editor), * reflow events are prevented; see ReflowActor -> setIgnoreLayoutChanges() * The box model view updates in response to reflow events. * To ensure reflow events are fired, hide the highlighter. */ await inspector.highlighters.hideHighlighterType( inspector.highlighters.TYPES.BOXMODEL ); return new Promise(resolve => { inspector.on("boxmodel-view-updated", function onUpdate(reasons) { // Wait for another update event if we are waiting for a selection related event. if (waitForSelectionUpdate && !reasons.includes("new-selection")) { return; } inspector.off("boxmodel-view-updated", onUpdate); resolve(); }); }); } /** * Wait for both boxmode-view-updated and markuploaded events. * * @return {Promise} a promise that resolves when both events have been received. */ function waitForMarkupLoaded(inspector) { return Promise.all([ waitForUpdate(inspector), inspector.once("markuploaded"), ]); } function getStyle(browser, selector, propertyName) { return SpecialPowers.spawn( browser, [selector, propertyName], async function (_selector, _propertyName) { return content.document .querySelector(_selector) .style.getPropertyValue(_propertyName); } ); } function setStyle(browser, selector, propertyName, value) { return SpecialPowers.spawn( browser, [selector, propertyName, value], async function (_selector, _propertyName, _value) { content.document.querySelector(_selector).style[_propertyName] = _value; } ); } /** * The box model doesn't participate in the inspector's update mechanism, so simply * calling the default selectNode isn't enough to guarantee that the box model view has * finished updating. We also need to wait for the "boxmodel-view-updated" event. */ var _selectNode = selectNode; selectNode = async function (node, inspector, reason) { const onUpdate = waitForUpdate(inspector, true); await _selectNode(node, inspector, reason); await onUpdate; }; /** * Wait until the provided element's text content matches the provided text. * Based on the waitFor helper, see documentation in * devtools/client/shared/test/shared-head.js * * @param {DOMNode} element * The element to check. * @param {String} expectedText * The text that is expected to be set as textContent of the element. */ async function waitForElementTextContent(element, expectedText) { await waitFor( () => element.textContent === expectedText, `Couldn't get "${expectedText}" as the text content of the given element` ); ok(true, `Found the expected text (${expectedText}) for the given element`); }