зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 5 changesets (bug 1738915, bug 1739061, bug 1730148) for causing mochitest failures on browser_resources_document_events.js CLOSED TREE DONTBUILD
Backed out changeset 24c1a120bb77 (bug 1739061) Backed out changeset eb9953fd3252 (bug 1738915) Backed out changeset 9bd72db885eb (bug 1730148) Backed out changeset 819078e24fa6 (bug 1730148) Backed out changeset a0e706688adc (bug 1730148)
This commit is contained in:
Родитель
91f08a1fbe
Коммит
e72368c08e
|
@ -80,15 +80,26 @@ add_task(async function testWebExtensionsToolboxWebConsole() {
|
|||
const browserActionEl = window.document.getElementById(browserActionId);
|
||||
ok(browserActionEl, "Got the browserAction button from the browser UI");
|
||||
|
||||
// Create a promise that will resolve when popup.html appears in the list of
|
||||
// frames known by the toolbox.
|
||||
const popupFramePromise = new Promise(resolve => {
|
||||
const listener = data => {
|
||||
if (data.frames.some(({ url }) => url && url.endsWith("popup.html"))) {
|
||||
toolbox.target.off("frame-update", listener);
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
toolbox.target.on("frame-update", listener);
|
||||
});
|
||||
|
||||
info("Show the web extension popup");
|
||||
browserActionEl.click();
|
||||
|
||||
info("Wait until the frames list button is displayed");
|
||||
const btn = await waitFor(() =>
|
||||
toolbox.doc.getElementById("command-button-frames")
|
||||
);
|
||||
info("Wait until popup.html appears in the frames list menu button");
|
||||
await popupFramePromise;
|
||||
|
||||
info("Clicking the frame list button");
|
||||
const btn = toolbox.doc.getElementById("command-button-frames");
|
||||
btn.click();
|
||||
|
||||
const menuList = toolbox.doc.getElementById("toolbox-frame-menu");
|
||||
|
|
|
@ -61,16 +61,6 @@ DomPanel.prototype = {
|
|||
|
||||
this._toolbox.on("select", this.onPanelVisibilityChange);
|
||||
|
||||
// onTargetAvailable is mandatory when calling watchTargets
|
||||
this._onTargetAvailable = () => {};
|
||||
this._onTargetSelected = this._onTargetSelected.bind(this);
|
||||
await this._commands.targetCommand.watchTargets(
|
||||
[this._commands.targetCommand.TYPES.FRAME],
|
||||
this._onTargetAvailable,
|
||||
null,
|
||||
this._onTargetSelected
|
||||
);
|
||||
|
||||
this.onResourceAvailable = this.onResourceAvailable.bind(this);
|
||||
await this._commands.resourceCommand.watchResources(
|
||||
[this._commands.resourceCommand.TYPES.DOCUMENT_EVENT],
|
||||
|
@ -102,12 +92,6 @@ DomPanel.prototype = {
|
|||
}
|
||||
this._destroyed = true;
|
||||
|
||||
this._commands.targetCommand.unwatchTargets(
|
||||
[this._commands.targetCommand.TYPES.FRAME],
|
||||
this._onTargetAvailable,
|
||||
null,
|
||||
this._onTargetSelected
|
||||
);
|
||||
this._commands.resourceCommand.unwatchResources(
|
||||
[this._commands.resourceCommand.TYPES.DOCUMENT_EVENT],
|
||||
{ onAvailable: this.onResourceAvailable }
|
||||
|
@ -139,22 +123,15 @@ DomPanel.prototype = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Make sure the panel is refreshed, either when navigation occurs or when a frame is
|
||||
* selected in the iframe picker.
|
||||
* Make sure the panel is refreshed when navigation occurs.
|
||||
* The panel is refreshed immediately if it's currently selected or lazily when the user
|
||||
* actually selects it.
|
||||
*/
|
||||
forceRefresh: function() {
|
||||
onTabNavigated: function() {
|
||||
this.shouldRefresh = true;
|
||||
// This will end up calling scriptCommand execute method to retrieve the `window` grip
|
||||
// on targetCommand.selectedTargetFront.
|
||||
this.refresh();
|
||||
},
|
||||
|
||||
_onTargetSelected: function({ targetFront }) {
|
||||
this.forceRefresh();
|
||||
},
|
||||
|
||||
onResourceAvailable: function(resources) {
|
||||
for (const resource of resources) {
|
||||
// Only consider top level document, and ignore remote iframes top document
|
||||
|
@ -164,7 +141,7 @@ DomPanel.prototype = {
|
|||
resource.name === "dom-complete" &&
|
||||
resource.targetFront.isTopLevel
|
||||
) {
|
||||
this.forceRefresh();
|
||||
this.onTabNavigated();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -12,7 +12,6 @@ support-files =
|
|||
[browser_dom_array.js]
|
||||
[browser_dom_basic.js]
|
||||
[browser_dom_fission_target_switching.js]
|
||||
[browser_dom_iframe_picker.js]
|
||||
[browser_dom_nodes_highlight.js]
|
||||
[browser_dom_nodes_select.js]
|
||||
[browser_dom_refresh.js]
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Check that the DOM panel works as expected when a specific frame is selected in the
|
||||
// iframe picker.
|
||||
|
||||
const TEST_URL = `https://example.com/document-builder.sjs?html=
|
||||
<h1>top_level</h1>
|
||||
<iframe src="https://example.org/document-builder.sjs?html=in_iframe"></iframe>`;
|
||||
|
||||
add_task(async function() {
|
||||
const { panel } = await addTestTab(TEST_URL);
|
||||
const toolbox = panel._toolbox;
|
||||
|
||||
info("Wait until the iframe picker button is visible");
|
||||
try {
|
||||
await waitFor(() => toolbox.doc.getElementById("command-button-frames"));
|
||||
} catch (e) {
|
||||
if (isFissionEnabled() && !isEveryFrameTargetEnabled()) {
|
||||
ok(
|
||||
true,
|
||||
"Remote frames are not displayed in iframe picker if Fission is enabled but EFT is not"
|
||||
);
|
||||
return;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
info("Check `document` property when no specific frame is focused");
|
||||
let documentPropertyValue = getDocumentPropertyValue(panel);
|
||||
|
||||
ok(
|
||||
documentPropertyValue.startsWith("HTMLDocument https://example.com"),
|
||||
`Got expected "document" value (${documentPropertyValue})`
|
||||
);
|
||||
|
||||
info(
|
||||
"Select the frame in the iframe picker and check that the document property is updated"
|
||||
);
|
||||
// Wait for the DOM panel to refresh.
|
||||
const store = getReduxStoreFromPanel(panel);
|
||||
let onPropertiesFetched = waitForDispatch(store, "FETCH_PROPERTIES");
|
||||
|
||||
const exampleOrgFrame = toolbox.doc.querySelector(
|
||||
"#toolbox-frame-menu .menuitem:last-child .command"
|
||||
);
|
||||
|
||||
exampleOrgFrame.click();
|
||||
await onPropertiesFetched;
|
||||
|
||||
documentPropertyValue = getDocumentPropertyValue(panel);
|
||||
ok(
|
||||
documentPropertyValue.startsWith("HTMLDocument https://example.org"),
|
||||
`Got expected "document" value (${documentPropertyValue})`
|
||||
);
|
||||
|
||||
info(
|
||||
"Select the top-level frame and check that the document property is updated"
|
||||
);
|
||||
onPropertiesFetched = waitForDispatch(store, "FETCH_PROPERTIES");
|
||||
|
||||
const exampleComFrame = toolbox.doc.querySelector(
|
||||
"#toolbox-frame-menu .menuitem:first-child .command"
|
||||
);
|
||||
exampleComFrame.click();
|
||||
await onPropertiesFetched;
|
||||
|
||||
documentPropertyValue = getDocumentPropertyValue(panel);
|
||||
ok(
|
||||
documentPropertyValue.startsWith("HTMLDocument https://example.com"),
|
||||
`Got expected "document" value (${documentPropertyValue})`
|
||||
);
|
||||
});
|
||||
|
||||
function getDocumentPropertyValue(panel) {
|
||||
return getRowByLabel(panel, "document").querySelector("td.treeValueCell")
|
||||
.textContent;
|
||||
}
|
|
@ -128,6 +128,7 @@ class ToolboxToolbar extends Component {
|
|||
this.hideMenu = this.hideMenu.bind(this);
|
||||
this.createFrameList = this.createFrameList.bind(this);
|
||||
this.highlightFrame = this.highlightFrame.bind(this);
|
||||
this.clickFrameButton = this.clickFrameButton.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
@ -310,12 +311,17 @@ class ToolboxToolbar extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
highlightFrame(id) {
|
||||
clickFrameButton(event) {
|
||||
const { toolbox } = this.props;
|
||||
toolbox.onSelectFrame(event.target.id);
|
||||
}
|
||||
|
||||
highlightFrame(id) {
|
||||
if (!id) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { toolbox } = this.props;
|
||||
toolbox.onHighlightFrame(id);
|
||||
}
|
||||
|
||||
|
@ -330,21 +336,15 @@ class ToolboxToolbar extends Component {
|
|||
const label = toolbox.target.isWebExtension
|
||||
? toolbox.target.getExtensionPathName(frame.url)
|
||||
: getUnicodeUrl(frame.url);
|
||||
|
||||
const item = MenuItem({
|
||||
id: frame.id.toString(),
|
||||
key: "toolbox-frame-key-" + frame.id,
|
||||
label,
|
||||
checked: frame.id === toolbox.selectedFrameId,
|
||||
onClick: () => toolbox.onIframePickerFrameSelected(frame.id),
|
||||
});
|
||||
|
||||
// Always put the top level frame at the top
|
||||
if (frame.isTopLevel) {
|
||||
items.unshift(item);
|
||||
} else {
|
||||
items.push(item);
|
||||
}
|
||||
items.push(
|
||||
MenuItem({
|
||||
id: frame.id.toString(),
|
||||
key: "toolbox-frame-key-" + frame.id,
|
||||
label,
|
||||
checked: frame.id === toolbox.selectedFrameId,
|
||||
onClick: this.clickFrameButton,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
return MenuList(
|
||||
|
|
|
@ -103,6 +103,7 @@ skip-if =
|
|||
[browser_toolbox_error_count.js]
|
||||
[browser_toolbox_fission_navigation.js]
|
||||
[browser_toolbox_frames_list.js]
|
||||
fail-if = fission # Bug 1608054
|
||||
[browser_toolbox_getpanelwhenready.js]
|
||||
[browser_toolbox_highlight.js]
|
||||
[browser_toolbox_hosts.js]
|
||||
|
|
|
@ -55,26 +55,11 @@ add_task(async function() {
|
|||
});
|
||||
|
||||
info("Check that the content of the frames list was updated");
|
||||
try {
|
||||
await checkFramesList(toolbox, [
|
||||
TEST_COM_URL,
|
||||
"https://example.com/document-builder.sjs?html=example.com iframe",
|
||||
"https://example.org/document-builder.sjs?html=example.org iframe",
|
||||
]);
|
||||
|
||||
// If Fission is enabled and EFT is not, we shouldn't hit this line as `checkFramesList`
|
||||
// should throw (as remote frames are only displayed when EFT is enabled).
|
||||
ok(
|
||||
!isFissionEnabled() || isEveryFrameTargetEnabled(),
|
||||
"iframe picker should only display remote frames when EFT is enabled"
|
||||
);
|
||||
} catch (e) {
|
||||
ok(
|
||||
isFissionEnabled() && !isEveryFrameTargetEnabled(),
|
||||
"iframe picker displays remote frames only when EFT is enabled"
|
||||
);
|
||||
return;
|
||||
}
|
||||
await checkFramesList(toolbox, [
|
||||
TEST_COM_URL,
|
||||
"https://example.com/document-builder.sjs?html=example.com iframe",
|
||||
"https://example.org/document-builder.sjs?html=example.org iframe",
|
||||
]);
|
||||
|
||||
info("Reload and check that the frames list is cleared");
|
||||
await reloadBrowser();
|
||||
|
@ -127,8 +112,7 @@ function getFramesButton(toolbox) {
|
|||
|
||||
async function checkFramesList(toolbox, expectedFrames) {
|
||||
const frames = await waitFor(() => {
|
||||
// items might be added in the list before their url is known, so exclude empty items.
|
||||
const f = getFramesLabels(toolbox).filter(t => t !== "");
|
||||
const f = getFramesLabels(toolbox);
|
||||
if (f.length !== expectedFrames.length) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -100,10 +100,7 @@ add_task(async function() {
|
|||
info("Select the iframe");
|
||||
iframeBtn.click();
|
||||
|
||||
// will-navigate isn't emitted in the targetCommand-based iframe picker.
|
||||
if (!isEveryFrameTargetEnabled()) {
|
||||
await willNavigate;
|
||||
}
|
||||
await willNavigate;
|
||||
await onInspectorReloaded;
|
||||
// wait a bit more in case an eventual title update would happen later
|
||||
await wait(1000);
|
||||
|
|
|
@ -321,7 +321,6 @@ function Toolbox(
|
|||
this.togglePaintFlashing = this.togglePaintFlashing.bind(this);
|
||||
this._onTargetAvailable = this._onTargetAvailable.bind(this);
|
||||
this._onTargetDestroyed = this._onTargetDestroyed.bind(this);
|
||||
this._onTargetSelected = this._onTargetSelected.bind(this);
|
||||
this._onResourceAvailable = this._onResourceAvailable.bind(this);
|
||||
this._onResourceUpdated = this._onResourceUpdated.bind(this);
|
||||
|
||||
|
@ -701,9 +700,7 @@ Toolbox.prototype = {
|
|||
|
||||
// Attach to a new top-level target.
|
||||
// For now, register these event listeners only on the top level target
|
||||
if (!targetFront.targetForm.ignoreSubFrames) {
|
||||
targetFront.on("frame-update", this._updateFrames);
|
||||
}
|
||||
targetFront.on("frame-update", this._updateFrames);
|
||||
const consoleFront = await targetFront.getFront("console");
|
||||
consoleFront.on("inspectObject", this._onInspectObject);
|
||||
}
|
||||
|
@ -728,25 +725,6 @@ Toolbox.prototype = {
|
|||
}
|
||||
await this.initPerformance();
|
||||
}
|
||||
|
||||
if (targetFront.targetForm.ignoreSubFrames) {
|
||||
this._updateFrames({
|
||||
frames: [
|
||||
{
|
||||
id: targetFront.actorID,
|
||||
targetFront,
|
||||
url: targetFront.url,
|
||||
title: targetFront.title,
|
||||
isTopLevel: targetFront.isTopLevel,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
async _onTargetSelected({ targetFront }) {
|
||||
this._updateFrames({ selected: targetFront.actorID });
|
||||
this.selectTarget(targetFront.actorID);
|
||||
},
|
||||
|
||||
_onTargetDestroyed({ targetFront }) {
|
||||
|
@ -771,17 +749,6 @@ Toolbox.prototype = {
|
|||
if (this.hostType !== Toolbox.HostType.PAGE) {
|
||||
this.store.dispatch(unregisterTarget(targetFront));
|
||||
}
|
||||
|
||||
if (targetFront.targetForm.ignoreSubFrames) {
|
||||
this._updateFrames({
|
||||
frames: [
|
||||
{
|
||||
id: targetFront.actorID,
|
||||
destroy: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_onTargetThreadFrontResumeWrongOrder() {
|
||||
|
@ -902,8 +869,7 @@ Toolbox.prototype = {
|
|||
await this.commands.targetCommand.watchTargets(
|
||||
this.commands.targetCommand.ALL_TYPES,
|
||||
this._onTargetAvailable,
|
||||
this._onTargetDestroyed,
|
||||
this._onTargetSelected
|
||||
this._onTargetDestroyed
|
||||
);
|
||||
|
||||
const onResourcesWatched = this.resourceCommand.watchResources(
|
||||
|
@ -2329,7 +2295,7 @@ Toolbox.prototype = {
|
|||
this.frameButton.isVisible = isVisible;
|
||||
|
||||
if (isVisible) {
|
||||
this.frameButton.isChecked = !selectedFrame.isTopLevel;
|
||||
this.frameButton.isChecked = selectedFrame.parentID != null;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -3258,22 +3224,14 @@ Toolbox.prototype = {
|
|||
},
|
||||
|
||||
_listFrames: async function(event) {
|
||||
if (
|
||||
!this.target.getTrait("frames") ||
|
||||
this.target.targetForm.ignoreSubFrames
|
||||
) {
|
||||
// We are not targetting a regular WindowGlobalTargetActor (it can be either an
|
||||
// addon or browser toolbox actor), or EFT is enabled.
|
||||
if (!this.target.getTrait("frames")) {
|
||||
// We are not targetting a regular WindowGlobalTargetActor
|
||||
// it can be either an addon or browser toolbox actor
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
try {
|
||||
const { frames } = await this.target.listFrames();
|
||||
|
||||
// @backward-compat { version 95 } frame.isTopLevel was added in 95.
|
||||
for (const frame of frames) {
|
||||
frame.isTopLevel = !frame.parentID;
|
||||
}
|
||||
this._updateFrames({ frames });
|
||||
} catch (e) {
|
||||
console.error("Error while listing frames", e);
|
||||
|
@ -3281,96 +3239,48 @@ Toolbox.prototype = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Called by the iframe picker when the user selected a frame.
|
||||
*
|
||||
* @param {String} frameIdOrTargetActorId
|
||||
* Select a frame by sending 'switchToFrame' packet to the backend.
|
||||
*/
|
||||
onIframePickerFrameSelected: function(frameIdOrTargetActorId) {
|
||||
if (!this.frameMap.has(frameIdOrTargetActorId)) {
|
||||
console.error(
|
||||
`Can't focus on frame "${frameIdOrTargetActorId}", it is not a known frame`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const frameInfo = this.frameMap.get(frameIdOrTargetActorId);
|
||||
// If there is no targetFront in the frameData, this means EFT is not enabled.
|
||||
// Send packet to the backend to select specified frame and wait for 'frameUpdate'
|
||||
// event packet to update the UI.
|
||||
if (!frameInfo.targetFront) {
|
||||
this.target.switchToFrame({ windowId: frameIdOrTargetActorId });
|
||||
return;
|
||||
}
|
||||
|
||||
// Here, EFT is enabled, so we want to focus the toolbox on the specific targetFront
|
||||
// that was selected by the user. This will trigger this._onTargetSelected which will
|
||||
// take care of updating the iframe picker state.
|
||||
this.commands.targetCommand.selectTarget(frameInfo.targetFront);
|
||||
onSelectFrame: function(frameId) {
|
||||
// Send packet to the backend to select specified frame and
|
||||
// wait for 'frameUpdate' event packet to update the UI.
|
||||
this.target.switchToFrame({ windowId: frameId });
|
||||
},
|
||||
|
||||
/**
|
||||
* Highlight a frame in the page
|
||||
*
|
||||
* @param {String} frameIdOrTargetActorId
|
||||
*/
|
||||
onHighlightFrame: async function(frameIdOrTargetActorId) {
|
||||
// Only enable frame highlighting when the top level document is targeted
|
||||
if (!this.rootFrameSelected) {
|
||||
return;
|
||||
}
|
||||
|
||||
const frameInfo = this.frameMap.get(frameIdOrTargetActorId);
|
||||
if (!frameInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
let nodeFront;
|
||||
if (frameInfo.targetFront) {
|
||||
const inspectorFront = await frameInfo.targetFront.getFront("inspector");
|
||||
nodeFront = await inspectorFront.walker.documentElement();
|
||||
} else {
|
||||
const inspectorFront = await this.target.getFront("inspector");
|
||||
nodeFront = await inspectorFront.walker.getNodeActorFromWindowID(
|
||||
frameIdOrTargetActorId
|
||||
);
|
||||
}
|
||||
onHighlightFrame: async function(frameId) {
|
||||
const inspectorFront = await this.target.getFront("inspector");
|
||||
const highlighter = this.getHighlighter();
|
||||
return highlighter.highlight(nodeFront);
|
||||
|
||||
// Only enable frame highlighting when the top level document is targeted
|
||||
if (this.rootFrameSelected) {
|
||||
const nodeFront = await inspectorFront.walker.getNodeActorFromWindowID(
|
||||
frameId
|
||||
);
|
||||
return highlighter.highlight(nodeFront);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Handles changes in document frames.
|
||||
* A handler for 'frameUpdate' packets received from the backend.
|
||||
* Following properties might be set on the packet:
|
||||
*
|
||||
* @param {Object} data
|
||||
* @param {Boolean} data.destroyAll: All frames have been destroyed.
|
||||
* @param {Number} data.selected: A frame has been selected
|
||||
* @param {Object} data.frameData: Some frame data were updated
|
||||
* @param {String} data.frameData.url: new frame URL (it might have been blank or about:blank)
|
||||
* @param {String} data.frameData.title: new frame title
|
||||
* @param {Number|String} data.frameData.id: frame ID / targetFront actorID when EFT is enabled.
|
||||
* @param {Array<Object>} data.frames: List of frames. Every frame can have:
|
||||
* @param {Number|String} data.frames[].id: frame ID / targetFront actorID when EFT is enabled.
|
||||
* @param {String} data.frames[].url: frame URL
|
||||
* @param {String} data.frames[].title: frame title
|
||||
* @param {Boolean} data.frames[].destroy: Set to true if destroyed
|
||||
* @param {Boolean} data.frames[].isTopLevel: true for top level window
|
||||
* destroyAll {Boolean}: All frames have been destroyed.
|
||||
* selected {Number}: A frame has been selected
|
||||
* frames {Array}: list of frames. Every frame can have:
|
||||
* id {Number}: frame ID
|
||||
* url {String}: frame URL
|
||||
* title {String}: frame title
|
||||
* destroy {Boolean}: Set to true if destroyed
|
||||
* parentID {Number}: ID of the parent frame (not set
|
||||
* for top level window)
|
||||
*/
|
||||
_updateFrames: function(data) {
|
||||
// At the moment, frames `id` can either be outerWindowID (a Number),
|
||||
// or a targetActorID (a String).
|
||||
// In order to have the same type of data as a key of `frameMap`, we transform any
|
||||
// outerWindowID into a string.
|
||||
// This can be removed once EFT is enabled by default
|
||||
if (data.selected) {
|
||||
data.selected = data.selected.toString();
|
||||
} else if (data.frameData) {
|
||||
data.frameData.id = data.frameData.id.toString();
|
||||
} else if (data.frames) {
|
||||
data.frames.forEach(frame => {
|
||||
if (frame.id) {
|
||||
frame.id = frame.id.toString();
|
||||
}
|
||||
});
|
||||
// We may receive this event before the toolbox is ready.
|
||||
if (!this.isReady) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Store (synchronize) data about all existing frames on the backend
|
||||
|
@ -3379,20 +3289,6 @@ Toolbox.prototype = {
|
|||
this.selectedFrameId = null;
|
||||
} else if (data.selected) {
|
||||
this.selectedFrameId = data.selected;
|
||||
} else if (data.frameData && this.frameMap.has(data.frameData.id)) {
|
||||
const existingFrameData = this.frameMap.get(data.frameData.id);
|
||||
if (
|
||||
existingFrameData.title == data.frameData.title &&
|
||||
existingFrameData.url == data.frameData.url
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.frameMap.set(data.frameData.id, {
|
||||
...existingFrameData,
|
||||
url: data.frameData.url,
|
||||
title: data.frameData.title,
|
||||
});
|
||||
} else if (data.frames) {
|
||||
data.frames.forEach(frame => {
|
||||
if (frame.destroy) {
|
||||
|
@ -3413,10 +3309,13 @@ Toolbox.prototype = {
|
|||
// frames in case of the BrowserToolbox.
|
||||
if (!this.selectedFrameId) {
|
||||
const frames = [...this.frameMap.values()];
|
||||
const topFrames = frames.filter(frame => frame.isTopLevel);
|
||||
const topFrames = frames.filter(frame => !frame.parentID);
|
||||
this.selectedFrameId = topFrames.length ? topFrames[0].id : null;
|
||||
}
|
||||
|
||||
// We may need to hide/show the frames button now.
|
||||
this.updateFrameButton();
|
||||
|
||||
// Debounce the update to avoid unnecessary flickering/rendering.
|
||||
if (!this.debouncedToolbarUpdate) {
|
||||
this.debouncedToolbarUpdate = debounce(
|
||||
|
@ -3432,35 +3331,37 @@ Toolbox.prototype = {
|
|||
);
|
||||
}
|
||||
|
||||
const updateUiElements = () => {
|
||||
// We may need to hide/show the frames button now.
|
||||
this.updateFrameButton();
|
||||
|
||||
if (this.debouncedToolbarUpdate) {
|
||||
this.debouncedToolbarUpdate();
|
||||
}
|
||||
};
|
||||
|
||||
// This may have been called before the toolbox is ready (= the dom elements for
|
||||
// the iframe picker don't exist yet).
|
||||
if (!this.isReady) {
|
||||
this.once("ready").then(() => updateUiElements);
|
||||
} else {
|
||||
updateUiElements();
|
||||
if (this.debouncedToolbarUpdate) {
|
||||
this.debouncedToolbarUpdate();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a 0-based selected frame depth.
|
||||
*
|
||||
* For example, if the root frame is selected, the returned value is 0. For a sub-frame
|
||||
* of the root document, the returned value is 1, and so on.
|
||||
*/
|
||||
get selectedFrameDepth() {
|
||||
// If the frame switcher is disabled, we won't have a selected frame ID.
|
||||
// In this case, we're always showing the root frame.
|
||||
if (!this.selectedFrameId) {
|
||||
return 0;
|
||||
}
|
||||
let depth = 0;
|
||||
let frame = this.frameMap.get(this.selectedFrameId);
|
||||
while (frame) {
|
||||
depth++;
|
||||
frame = this.frameMap.get(frame.parentID);
|
||||
}
|
||||
return depth - 1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns whether a root frame (with no parent frame) is selected.
|
||||
*/
|
||||
get rootFrameSelected() {
|
||||
// If the frame switcher is disabled, we won't have a selected frame ID.
|
||||
// In this case, we're always showing the root frame.
|
||||
if (!this.selectedFrameId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return this.frameMap.get(this.selectedFrameId).isTopLevel;
|
||||
return this.selectedFrameDepth == 0;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -3958,8 +3859,7 @@ Toolbox.prototype = {
|
|||
this.commands.targetCommand.unwatchTargets(
|
||||
this.commands.targetCommand.ALL_TYPES,
|
||||
this._onTargetAvailable,
|
||||
this._onTargetDestroyed,
|
||||
this._onTargetSelected
|
||||
this._onTargetDestroyed
|
||||
);
|
||||
this.resourceCommand.unwatchResources(
|
||||
[
|
||||
|
@ -4577,21 +4477,13 @@ Toolbox.prototype = {
|
|||
// the "newer" event.
|
||||
resource.name === "dom-interactive"
|
||||
) {
|
||||
// the targetFront title and url are updated on dom-interactive, so delay refreshing
|
||||
// the targetFront title and url are update on dom-interactive, so delay refreshing
|
||||
// the host title a bit in order for the event listener in targetCommand to be
|
||||
// executed.
|
||||
setTimeout(() => {
|
||||
// Update the EvaluationContext selector so url/title of targets can be updated
|
||||
this.store.dispatch(refreshTargets());
|
||||
|
||||
this._updateFrames({
|
||||
frameData: {
|
||||
id: resource.targetFront.actorID,
|
||||
url: resource.targetFront.url,
|
||||
title: resource.targetFront.title,
|
||||
},
|
||||
});
|
||||
|
||||
if (resource.targetFront.isTopLevel) {
|
||||
this._refreshHostTitle();
|
||||
this._setDebugTargetData();
|
||||
|
|
|
@ -58,9 +58,7 @@ class WindowGlobalTargetFront extends TargetMixin(
|
|||
* Event listener for `frameUpdate` event.
|
||||
*/
|
||||
_onFrameUpdate(packet) {
|
||||
// @backward-compat { version 96 } isTopLevel was added on the server in 96, so we
|
||||
// can simply send `packet` when 96 hits release.
|
||||
this.emit("frame-update", { ...packet, isTopLevel: !packet.parentID });
|
||||
this.emit("frame-update", packet);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -159,7 +159,6 @@ function Inspector(toolbox, commands) {
|
|||
);
|
||||
this._onTargetAvailable = this._onTargetAvailable.bind(this);
|
||||
this._onTargetDestroyed = this._onTargetDestroyed.bind(this);
|
||||
this._onTargetSelected = this._onTargetSelected.bind(this);
|
||||
this._onWillNavigate = this._onWillNavigate.bind(this);
|
||||
this._updateSearchResultsLabel = this._updateSearchResultsLabel.bind(this);
|
||||
|
||||
|
@ -209,8 +208,7 @@ Inspector.prototype = {
|
|||
await this.commands.targetCommand.watchTargets(
|
||||
[this.commands.targetCommand.TYPES.FRAME],
|
||||
this._onTargetAvailable,
|
||||
this._onTargetDestroyed,
|
||||
this._onTargetSelected
|
||||
this._onTargetDestroyed
|
||||
);
|
||||
|
||||
await this.toolbox.resourceCommand.watchResources(
|
||||
|
@ -277,30 +275,6 @@ Inspector.prototype = {
|
|||
]);
|
||||
},
|
||||
|
||||
async _onTargetSelected({ targetFront }) {
|
||||
// We don't use this.highlighters since it creates a HighlightersOverlay if it wasn't
|
||||
// the case yet.
|
||||
if (this._highlighters) {
|
||||
this._highlighters.hideAllHighlighters();
|
||||
}
|
||||
await this.initInspectorFront(targetFront);
|
||||
|
||||
// the target might have been destroyed when reloading quickly,
|
||||
// while waiting for inspector front initialization
|
||||
if (targetFront.isDestroyed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { walker } = await targetFront.getFront("inspector");
|
||||
const rootNodeFront = await walker.getRootNode();
|
||||
// When a given target is focused, don't try to reset the selection
|
||||
this.selectionCssSelectors = [];
|
||||
this._defaultNode = null;
|
||||
|
||||
// onRootNodeAvailable will take care of populating the markup view
|
||||
await this.onRootNodeAvailable(rootNodeFront);
|
||||
},
|
||||
|
||||
_onTargetDestroyed({ targetFront }) {
|
||||
// Ignore all targets but the top level one
|
||||
if (!targetFront.isTopLevel) {
|
||||
|
@ -557,7 +531,7 @@ Inspector.prototype = {
|
|||
this._defaultNode = null;
|
||||
this.selection.setNodeFront(null);
|
||||
if (this._highlighters) {
|
||||
this._highlighters.hideAllHighlighters();
|
||||
this._highlighters.onWillNavigate();
|
||||
}
|
||||
this._destroyMarkup();
|
||||
this._pendingSelectionUnique = null;
|
||||
|
@ -592,7 +566,7 @@ Inspector.prototype = {
|
|||
return null;
|
||||
}
|
||||
|
||||
const walker = rootNodeFront.walkerFront;
|
||||
const walker = this.walker;
|
||||
const cssSelectors = this.selectionCssSelectors;
|
||||
// Try to find a default node using three strategies:
|
||||
const defaultNodeSelectors = [
|
||||
|
@ -1729,8 +1703,7 @@ Inspector.prototype = {
|
|||
this.commands.targetCommand.unwatchTargets(
|
||||
[this.commands.targetCommand.TYPES.FRAME],
|
||||
this._onTargetAvailable,
|
||||
this._onTargetDestroyed,
|
||||
this._onTargetSelected
|
||||
this._onTargetDestroyed
|
||||
);
|
||||
const { resourceCommand } = this.toolbox;
|
||||
resourceCommand.unwatchResources(
|
||||
|
|
|
@ -2329,22 +2329,7 @@ MarkupView.prototype = {
|
|||
* of the markup-view tree, and not from the perspective of the actual DOM.
|
||||
*/
|
||||
_getParentInTree: function(node) {
|
||||
const parent = node.parentOrHost();
|
||||
if (!parent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// If the parent node belongs to a different target while the node's target is the
|
||||
// one selected by the user in the iframe picker, we don't want to go further up.
|
||||
if (
|
||||
node.targetFront !== parent.targetFront &&
|
||||
node.targetFront ==
|
||||
this.inspector.commands.targetCommand.selectedTargetFront
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return parent;
|
||||
return node.parentOrHost();
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -164,7 +164,6 @@ skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32
|
|||
[browser_rules_search-filter_escape-keypress.js]
|
||||
[browser_rules_select-and-copy-styles.js]
|
||||
skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
|
||||
[browser_rules_selector-highlighter-iframe-picker.js]
|
||||
[browser_rules_selector-highlighter-on-navigate.js]
|
||||
[browser_rules_selector-highlighter_01.js]
|
||||
[browser_rules_selector-highlighter_02.js]
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that the selector highlighter works when selecting frames in the iframe picker
|
||||
|
||||
const TEST_URI = `
|
||||
<style type="text/css">
|
||||
body {
|
||||
background: red;
|
||||
}
|
||||
</style>
|
||||
<h1>Test the selector highlighter</h1>
|
||||
<iframe src="data:text/html,<meta charset=utf8><style>h2 {background: yellow;}</style><h2>In iframe</h2>">
|
||||
`;
|
||||
|
||||
add_task(async function() {
|
||||
await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
const { inspector, toolbox, view } = await openRuleView();
|
||||
|
||||
info("Clicking on a selector icon");
|
||||
const { highlighter, isShown } = await clickSelectorIcon(view, "body");
|
||||
|
||||
ok(highlighter, "The selector highlighter instance was created");
|
||||
ok(isShown, "The selector highlighter was shown");
|
||||
|
||||
// Open frame menu and wait till it's available on the screen.
|
||||
const panel = toolbox.doc.getElementById("command-button-frames-panel");
|
||||
const btn = toolbox.doc.getElementById("command-button-frames");
|
||||
btn.click();
|
||||
ok(panel, "popup panel has created.");
|
||||
await waitUntil(() => panel.classList.contains("tooltip-visible"));
|
||||
|
||||
// Verify that the menu is populated.
|
||||
const menuList = toolbox.doc.getElementById("toolbox-frame-menu");
|
||||
const frames = Array.from(menuList.querySelectorAll(".command"));
|
||||
|
||||
const onNewRoot = inspector.once("new-root");
|
||||
frames[1].click();
|
||||
await onNewRoot;
|
||||
|
||||
const activeHighlighter = inspector.highlighters.getActiveHighlighter(
|
||||
inspector.highlighters.TYPES.SELECTOR
|
||||
);
|
||||
ok(
|
||||
!activeHighlighter,
|
||||
"No selector highlighter is active after selecting a frame"
|
||||
);
|
||||
});
|
|
@ -180,7 +180,7 @@ class HighlightersOverlay {
|
|||
|
||||
this.onMouseMove = this.onMouseMove.bind(this);
|
||||
this.onMouseOut = this.onMouseOut.bind(this);
|
||||
this.hideAllHighlighters = this.hideAllHighlighters.bind(this);
|
||||
this.onWillNavigate = this.onWillNavigate.bind(this);
|
||||
this.hideFlexboxHighlighter = this.hideFlexboxHighlighter.bind(this);
|
||||
this.hideGridHighlighter = this.hideGridHighlighter.bind(this);
|
||||
this.hideShapesHighlighter = this.hideShapesHighlighter.bind(this);
|
||||
|
@ -557,7 +557,7 @@ class HighlightersOverlay {
|
|||
|
||||
if (this._pendingHighlighters.get(type) !== id) {
|
||||
return;
|
||||
} else if (skipShow || nodeFront.isDestroyed()) {
|
||||
} else if (skipShow) {
|
||||
this._pendingHighlighters.delete(type);
|
||||
return;
|
||||
}
|
||||
|
@ -1837,11 +1837,9 @@ class HighlightersOverlay {
|
|||
}
|
||||
|
||||
/**
|
||||
* Hides any visible highlighter and clear internal state. This should be called to
|
||||
* have a clean slate, for example when the page navigates or when a given frame is
|
||||
* selected in the iframe picker.
|
||||
* Clear saved highlighter shown properties on will-navigate.
|
||||
*/
|
||||
async hideAllHighlighters() {
|
||||
async onWillNavigate() {
|
||||
this.destroyEditors();
|
||||
|
||||
// Hide any visible highlighters and clear any timers set to autohide highlighters.
|
||||
|
|
|
@ -15,7 +15,11 @@ const TEST_URI =
|
|||
add_task(async function() {
|
||||
info("Enable command-button-frames preference setting");
|
||||
Services.prefs.setBoolPref("devtools.command-button-frames.enabled", true);
|
||||
const { inspector, toolbox } = await openInspectorForURL(TEST_URI);
|
||||
const {
|
||||
inspector,
|
||||
toolbox,
|
||||
highlighterTestFront,
|
||||
} = await openInspectorForURL(TEST_URI);
|
||||
|
||||
await assertMarkupViewAsTree(
|
||||
`
|
||||
|
@ -40,12 +44,7 @@ add_task(async function() {
|
|||
|
||||
info("Check highlighting is correct after switching iframe context");
|
||||
await selectAndHighlightNode("#inner", inspector);
|
||||
|
||||
const nodeFront = await getNodeFront("#inner", inspector);
|
||||
const iframeHighlighterTestFront = await getHighlighterTestFront(toolbox, {
|
||||
target: nodeFront.targetFront,
|
||||
});
|
||||
const isHighlightCorrect = await iframeHighlighterTestFront.assertHighlightedNode(
|
||||
const isHighlightCorrect = await highlighterTestFront.assertHighlightedNode(
|
||||
"#inner"
|
||||
);
|
||||
ok(isHighlightCorrect, "The selected node is properly highlighted.");
|
||||
|
|
|
@ -113,11 +113,7 @@ add_task(async function() {
|
|||
function getOnInspectorReadyAfterNavigation(inspector) {
|
||||
const promises = [inspector.once("reloaded")];
|
||||
|
||||
if (
|
||||
isFissionEnabled() ||
|
||||
isServerTargetSwitchingEnabled() ||
|
||||
isEveryFrameTargetEnabled()
|
||||
) {
|
||||
if (isFissionEnabled() || isServerTargetSwitchingEnabled()) {
|
||||
// the inspector is initializing the accessibility front in onTargetAvailable, so we
|
||||
// need to wait for the target to be processed, otherwise we may end up with pending
|
||||
// promises failures.
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
// Test frame selection switching at toolbox level when using the inspector
|
||||
// Test frame selection switching at toolbox level
|
||||
// when using the inspector
|
||||
|
||||
const FrameURL =
|
||||
"data:text/html;charset=UTF-8," +
|
||||
|
@ -14,6 +15,8 @@ const URL =
|
|||
encodeURI('<iframe src="' + FrameURL + '"></iframe><div id="top">top</div>');
|
||||
|
||||
add_task(async function() {
|
||||
Services.prefs.setBoolPref("devtools.command-button-frames.enabled", true);
|
||||
|
||||
const { inspector, toolbox } = await openInspectorForURL(URL);
|
||||
|
||||
// Verify we are on the top level document
|
||||
|
@ -38,9 +41,11 @@ add_task(async function() {
|
|||
ok(panel, "popup panel has created.");
|
||||
await waitUntil(() => panel.classList.contains("tooltip-visible"));
|
||||
|
||||
// Verify that the menu is populated.
|
||||
// Verify that the menu is popuplated.
|
||||
const menuList = toolbox.doc.getElementById("toolbox-frame-menu");
|
||||
const frames = Array.from(menuList.querySelectorAll(".command"));
|
||||
const frames = Array.prototype.slice.call(
|
||||
menuList.querySelectorAll(".command")
|
||||
);
|
||||
is(frames.length, 2, "We have both frames in the menu");
|
||||
|
||||
frames.sort(function(a, b) {
|
||||
|
@ -78,17 +83,17 @@ add_task(async function() {
|
|||
|
||||
// Only select the iframe after we are able to select an element from the top
|
||||
// level document.
|
||||
let newRoot = inspector.once("new-root");
|
||||
const newRoot = inspector.once("new-root");
|
||||
await selectNode("#top", inspector);
|
||||
info("Select the iframe");
|
||||
frames[0].click();
|
||||
|
||||
if (!isEveryFrameTargetEnabled()) {
|
||||
await willNavigate;
|
||||
}
|
||||
await willNavigate;
|
||||
await newRoot;
|
||||
|
||||
info("The iframe is selected, check that the markup view was updated");
|
||||
info("Navigation to the iframe is done, the inspector should be back up");
|
||||
|
||||
// Verify we are on page one
|
||||
await assertMarkupViewAsTree(
|
||||
`
|
||||
body
|
||||
|
@ -96,25 +101,13 @@ add_task(async function() {
|
|||
"body",
|
||||
inspector
|
||||
);
|
||||
|
||||
// On page 2 load, verify we have the right content
|
||||
assertMarkupViewIsLoaded(inspector);
|
||||
|
||||
info(
|
||||
"Remove the iframe and check that the inspector gets updated to show the top level frame markup"
|
||||
);
|
||||
newRoot = inspector.once("new-root");
|
||||
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async function() {
|
||||
content.document.querySelector("iframe").remove();
|
||||
});
|
||||
await newRoot;
|
||||
await selectNode("#frame", inspector);
|
||||
|
||||
await assertMarkupViewAsTree(
|
||||
`
|
||||
body
|
||||
div id="top"`,
|
||||
"body",
|
||||
inspector
|
||||
);
|
||||
assertMarkupViewIsLoaded(inspector);
|
||||
Services.prefs.clearUserPref("devtools.command-button-frames.enabled");
|
||||
});
|
||||
|
||||
function assertMarkupViewIsLoaded(inspector) {
|
||||
|
|
|
@ -116,11 +116,14 @@ skip-if = os != 'mac' # The tested ctrl+key shortcuts are OSX only
|
|||
[browser_jsterm_editor_toolbar.js]
|
||||
[browser_jsterm_error_docs.js]
|
||||
[browser_jsterm_error_outside_valid_range.js]
|
||||
[browser_jsterm_evaluation_context_selector_iframe_picker.js]
|
||||
[browser_jsterm_evaluation_context_selector_pause_in_debugger.js]
|
||||
skip-if = !fission # context selector is only visible when fission is enabled.
|
||||
[browser_jsterm_evaluation_context_selector_targets_update.js]
|
||||
skip-if = !fission # context selector is only visible when fission is enabled.
|
||||
[browser_jsterm_evaluation_context_selector_inspector.js]
|
||||
skip-if = !fission # context selector is only visible when fission is enabled.
|
||||
[browser_jsterm_evaluation_context_selector.js]
|
||||
skip-if = !fission # context selector is only visible when fission is enabled.
|
||||
[browser_jsterm_file_load_save_keyboard_shortcut.js]
|
||||
[browser_jsterm_focus_reload.js]
|
||||
[browser_jsterm_helper_clear.js]
|
||||
|
@ -150,6 +153,7 @@ skip-if = (os == "win" && processor == "aarch64") # disabled on aarch64 due to 1
|
|||
[browser_jsterm_screenshot_command_file.js]
|
||||
[browser_jsterm_screenshot_command_fixed_header.js]
|
||||
[browser_jsterm_screenshot_command_selector.js]
|
||||
skip-if = !fission # context selector is only visible when fission is enabled.
|
||||
[browser_jsterm_screenshot_command_warnings.js]
|
||||
skip-if = (os == "win" && os_version == "6.1") # Getting the clipboard image dimensions throws an exception
|
||||
[browser_jsterm_selfxss.js]
|
||||
|
|
|
@ -22,15 +22,6 @@ add_task(async function() {
|
|||
".webconsole-evaluation-selector-button"
|
||||
);
|
||||
|
||||
if (!isFissionEnabled() && !isEveryFrameTargetEnabled()) {
|
||||
is(
|
||||
evaluationContextSelectorButton,
|
||||
null,
|
||||
"context selector is only displayed when Fission or EFT is enabled"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
ok(
|
||||
evaluationContextSelectorButton,
|
||||
"The evaluation context selector is visible"
|
||||
|
|
|
@ -1,128 +0,0 @@
|
|||
/* 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 evaluation context selector reacts as expected when using the Toolbox
|
||||
// iframe picker.
|
||||
|
||||
const TEST_URI = `https://example.com/document-builder.sjs?html=${encodeURIComponent(`
|
||||
<html>
|
||||
<h1>example.com</h1>
|
||||
<iframe src="https://example.org/document-builder.sjs?html=example.org"></iframe>
|
||||
<iframe src="https://example.net/document-builder.sjs?html=example.net"></iframe>
|
||||
</html>
|
||||
`)}`;
|
||||
|
||||
add_task(async function() {
|
||||
// Enable the context selector and the frames button.
|
||||
await pushPref("devtools.contenttoolbox.webconsole.input.context", true);
|
||||
await pushPref("devtools.command-button-frames.enabled", true);
|
||||
|
||||
const hud = await openNewTabAndConsole(TEST_URI);
|
||||
|
||||
info("Wait until the iframe picker button is displayed");
|
||||
try {
|
||||
await waitFor(() => getFramesButton(hud.toolbox));
|
||||
ok(
|
||||
!isFissionEnabled() || isEveryFrameTargetEnabled(),
|
||||
"iframe picker should only display remote frames when EFT is enabled"
|
||||
);
|
||||
} catch (e) {
|
||||
if (isFissionEnabled() && !isEveryFrameTargetEnabled()) {
|
||||
ok(true, "iframe picker displays remote frames only when EFT is enabled");
|
||||
return;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
const evaluationContextSelectorButton = hud.ui.outputNode.querySelector(
|
||||
".webconsole-evaluation-selector-button"
|
||||
);
|
||||
await executeAndWaitForMessage(
|
||||
hud,
|
||||
"document.location.host",
|
||||
`"example.com"`,
|
||||
".result"
|
||||
);
|
||||
ok(true, "The expression was evaluated in the example.com document.");
|
||||
|
||||
info("Select the example.org iframe");
|
||||
selectFrameInIframePicker(hud.toolbox, "https://example.org");
|
||||
try {
|
||||
await waitFor(() =>
|
||||
evaluationContextSelectorButton.innerText.includes("example.org")
|
||||
);
|
||||
if (!isEveryFrameTargetEnabled()) {
|
||||
todo(
|
||||
true,
|
||||
"context selector should only reacts to iframe picker when EFT is enabled"
|
||||
);
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
if (!isEveryFrameTargetEnabled()) {
|
||||
todo(
|
||||
false,
|
||||
"context selector only reacts to iframe picker when EFT is enabled"
|
||||
);
|
||||
return;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
ok(true, "The context was set to the example.org document");
|
||||
|
||||
await executeAndWaitForMessage(
|
||||
hud,
|
||||
"document.location.host",
|
||||
`"example.org"`,
|
||||
".result"
|
||||
);
|
||||
ok(true, "The expression was evaluated in the example.org document.");
|
||||
|
||||
info("Select the example.net iframe");
|
||||
selectFrameInIframePicker(hud.toolbox, "https://example.net");
|
||||
await waitFor(() =>
|
||||
evaluationContextSelectorButton.innerText.includes("example.net")
|
||||
);
|
||||
ok(true, "The context was set to the example.net document");
|
||||
|
||||
await executeAndWaitForMessage(
|
||||
hud,
|
||||
"document.location.host",
|
||||
`"example.net"`,
|
||||
".result"
|
||||
);
|
||||
ok(true, "The expression was evaluated in the example.net document.");
|
||||
|
||||
info("Select the Top frame");
|
||||
selectFrameInIframePicker(hud.toolbox, "https://example.com");
|
||||
await waitFor(() =>
|
||||
evaluationContextSelectorButton.innerText.includes("Top")
|
||||
);
|
||||
ok(true, "The context was set to the example.com document");
|
||||
|
||||
await executeAndWaitForMessage(
|
||||
hud,
|
||||
"document.location.host",
|
||||
`"example.com"`,
|
||||
".result"
|
||||
);
|
||||
ok(true, "The expression was evaluated in the example.com document.");
|
||||
});
|
||||
|
||||
function getFramesButton(toolbox) {
|
||||
return toolbox.doc.getElementById("command-button-frames");
|
||||
}
|
||||
|
||||
function selectFrameInIframePicker(toolbox, host) {
|
||||
const commandItem = Array.from(
|
||||
toolbox.doc.querySelectorAll("#toolbox-frame-menu .command .label")
|
||||
).find(label => label.textContent.startsWith(host));
|
||||
if (!commandItem) {
|
||||
throw new Error(`Couldn't find any frame starting with "${host}"`);
|
||||
}
|
||||
|
||||
commandItem.click();
|
||||
}
|
|
@ -31,15 +31,6 @@ add_task(async function() {
|
|||
".webconsole-evaluation-selector-button"
|
||||
);
|
||||
|
||||
if (!isFissionEnabled() && !isEveryFrameTargetEnabled()) {
|
||||
is(
|
||||
evaluationContextSelectorButton,
|
||||
null,
|
||||
"context selector is only displayed when Fission or EFT is enabled"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
setInputValue(hud, "document.location.host");
|
||||
await waitForEagerEvaluationResult(hud, `"example.com"`);
|
||||
|
||||
|
|
|
@ -43,16 +43,6 @@ add_task(async function() {
|
|||
const evaluationContextSelectorButton = hud.ui.outputNode.querySelector(
|
||||
".webconsole-evaluation-selector-button"
|
||||
);
|
||||
|
||||
if (!isFissionEnabled() && !isEveryFrameTargetEnabled()) {
|
||||
is(
|
||||
evaluationContextSelectorButton,
|
||||
null,
|
||||
"context selector is only displayed when Fission or EFT is enabled"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
await waitFor(
|
||||
() => evaluationContextSelectorButton.innerText.includes("example.org"),
|
||||
"The context selector wasn't updated"
|
||||
|
|
|
@ -22,15 +22,6 @@ add_task(async function() {
|
|||
".webconsole-evaluation-selector-button"
|
||||
);
|
||||
|
||||
if (!isFissionEnabled() && !isEveryFrameTargetEnabled()) {
|
||||
is(
|
||||
evaluationContextSelectorButton,
|
||||
null,
|
||||
"context selector is only displayed when Fission or EFT is enabled"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
is(
|
||||
evaluationContextSelectorButton.innerText,
|
||||
"Top",
|
||||
|
|
|
@ -72,16 +72,6 @@ add_task(async function() {
|
|||
const evaluationContextSelectorButton = hud.ui.outputNode.querySelector(
|
||||
".webconsole-evaluation-selector-button"
|
||||
);
|
||||
|
||||
if (!isFissionEnabled() && !isEveryFrameTargetEnabled()) {
|
||||
is(
|
||||
evaluationContextSelectorButton,
|
||||
null,
|
||||
"context selector is only displayed when Fission or EFT is enabled"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const remoteIframeUrl = await SpecialPowers.spawn(
|
||||
gBrowser.selectedBrowser,
|
||||
[],
|
||||
|
|
|
@ -57,12 +57,9 @@ class DocumentEventWatcher {
|
|||
// make the payload bigger for events where we either don't have a title yet,
|
||||
// or where we already had a chance to get the title.
|
||||
title: name === "dom-interactive" ? targetActor.title : undefined,
|
||||
// only send `url` on dom loading and dom-interactive so we don't make the
|
||||
// payload bigger for other events
|
||||
url:
|
||||
name === "dom-loading" || name === "dom-interactive"
|
||||
? targetActor.url
|
||||
: undefined,
|
||||
// only send `url` on dom loading so we don't make the payload bigger for
|
||||
// other events
|
||||
url: name === "dom-loading" ? targetActor.url : undefined,
|
||||
// only send `newURI` on will navigate so we don't make the payload bigger for
|
||||
// other events
|
||||
newURI: name === "will-navigate" ? newURI : null,
|
||||
|
|
|
@ -585,7 +585,6 @@ const windowGlobalTargetPrototype = {
|
|||
innerWindowId,
|
||||
topInnerWindowId: this.browsingContext.topWindowContext.innerWindowId,
|
||||
isTopLevelTarget: this.isTopLevelTarget,
|
||||
ignoreSubFrames: this.ignoreSubFrames,
|
||||
traits: {
|
||||
// @backward-compat { version 64 } Exposes a new trait to help identify
|
||||
// BrowsingContextActor's inherited actors from the client side.
|
||||
|
@ -995,7 +994,6 @@ const windowGlobalTargetPrototype = {
|
|||
return {
|
||||
id,
|
||||
parentID,
|
||||
isTopLevel: window == this.originalWindow && this.isTopLevelTarget,
|
||||
url: window.location.href,
|
||||
title: window.document.title,
|
||||
};
|
||||
|
|
|
@ -49,7 +49,7 @@ class ScriptCommand {
|
|||
selectedTargetFront,
|
||||
} = options;
|
||||
|
||||
let targetFront = this._commands.targetCommand.selectedTargetFront;
|
||||
let targetFront = this._commands.targetCommand.targetFront;
|
||||
|
||||
const selectedActor =
|
||||
selectedObjectActor || selectedNodeActor || frameActor;
|
||||
|
|
|
@ -23,7 +23,6 @@ const {
|
|||
} = require("devtools/shared/commands/target/legacy-target-watchers/legacy-workers-watcher");
|
||||
|
||||
class TargetCommand extends EventEmitter {
|
||||
#selectedTargetFront;
|
||||
/**
|
||||
* This class helps managing, iterating over and listening for Targets.
|
||||
*
|
||||
|
@ -79,14 +78,12 @@ class TargetCommand extends EventEmitter {
|
|||
// time watchTargets is called.
|
||||
this._pendingWatchTargetInitialization = new Map();
|
||||
|
||||
// Listeners for target creation, destruction and selection
|
||||
// Listeners for target creation and destruction
|
||||
this._createListeners = new EventEmitter();
|
||||
this._destroyListeners = new EventEmitter();
|
||||
this._selectListeners = new EventEmitter();
|
||||
|
||||
this._onTargetAvailable = this._onTargetAvailable.bind(this);
|
||||
this._onTargetDestroyed = this._onTargetDestroyed.bind(this);
|
||||
this._onTargetSelected = this._onTargetSelected.bind(this);
|
||||
|
||||
this.legacyImplementation = {
|
||||
process: new LegacyProcessesWatcher(
|
||||
|
@ -133,10 +130,6 @@ class TargetCommand extends EventEmitter {
|
|||
this._onResourceAvailable = this._onResourceAvailable.bind(this);
|
||||
}
|
||||
|
||||
get selectedTargetFront() {
|
||||
return this.#selectedTargetFront || this.targetFront;
|
||||
}
|
||||
|
||||
// Called whenever a new Target front is available.
|
||||
// Either because a target was already available as we started calling startListening
|
||||
// or if it has just been created
|
||||
|
@ -178,7 +171,6 @@ class TargetCommand extends EventEmitter {
|
|||
// Update the reference to the memoized top level target
|
||||
this.targetFront = targetFront;
|
||||
this.descriptorFront.setTarget(targetFront);
|
||||
this.#selectedTargetFront = null;
|
||||
|
||||
if (isFirstTarget && this.isServerTargetSwitchingEnabled()) {
|
||||
this._gotFirstTopLevelTarget = true;
|
||||
|
@ -305,17 +297,6 @@ class TargetCommand extends EventEmitter {
|
|||
});
|
||||
this._targets.delete(targetFront);
|
||||
|
||||
// If the destroyed target was the selected one, we need to do some cleanup
|
||||
if (this.#selectedTargetFront == targetFront) {
|
||||
// If we're doing a targetSwitch, simply nullify #selectedTargetFront
|
||||
if (isTargetSwitching) {
|
||||
this.#selectedTargetFront = null;
|
||||
} else {
|
||||
// Otherwise we want to select the top level target
|
||||
this.selectTarget(this.targetFront);
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldDestroyTargetFront) {
|
||||
// When calling targetFront.destroy(), we will first call TargetFrontMixin.destroy,
|
||||
// which will try to call `detach` RDP method.
|
||||
|
@ -329,23 +310,6 @@ class TargetCommand extends EventEmitter {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {TargetFront} targetFront
|
||||
*/
|
||||
async _onTargetSelected(targetFront) {
|
||||
if (this.#selectedTargetFront == targetFront) {
|
||||
// Target is already selected, we can bail out.
|
||||
return;
|
||||
}
|
||||
|
||||
this.#selectedTargetFront = targetFront;
|
||||
const targetType = this.getTargetType(targetFront);
|
||||
await this._selectListeners.emitAsync(targetType, {
|
||||
targetFront,
|
||||
});
|
||||
}
|
||||
|
||||
_setListening(type, value) {
|
||||
if (value) {
|
||||
this._listenersStarted.add(type);
|
||||
|
@ -628,19 +592,15 @@ class TargetCommand extends EventEmitter {
|
|||
* The type of target to listen for. Constant of TargetCommand.TYPES.
|
||||
* @param {Function} onAvailable
|
||||
* Callback fired when a target has been just created or was already available.
|
||||
* The function is called with a single object argument containing the following properties:
|
||||
* The function is called with the following arguments:
|
||||
* - {TargetFront} targetFront: The target Front
|
||||
* - {Boolean} isTargetSwitching: Is this target relates to a navigation and
|
||||
* this replaced a previously available target, this flag will be true
|
||||
* @param {Function} onDestroy
|
||||
* Callback fired in case of target front destruction.
|
||||
* The function is called with the same arguments than onAvailable.
|
||||
* @param {Function} onSelect.
|
||||
* Callback fired when a given target is selected from the iframe picker
|
||||
* The function is called with a single object argument containing the following properties:
|
||||
* - {TargetFront} targetFront: The target Front
|
||||
*/
|
||||
async watchTargets(types, onAvailable, onDestroy, onSelect) {
|
||||
async watchTargets(types, onAvailable, onDestroy) {
|
||||
if (typeof onAvailable != "function") {
|
||||
throw new Error(
|
||||
"TargetCommand.watchTargets expects a function as second argument"
|
||||
|
@ -710,9 +670,6 @@ class TargetCommand extends EventEmitter {
|
|||
if (onDestroy) {
|
||||
this._destroyListeners.on(type, onDestroy);
|
||||
}
|
||||
if (onSelect) {
|
||||
this._selectListeners.on(type, onSelect);
|
||||
}
|
||||
}
|
||||
|
||||
await Promise.all(promises);
|
||||
|
@ -723,7 +680,7 @@ class TargetCommand extends EventEmitter {
|
|||
* Stop listening for the creation and/or destruction of a given type of target fronts.
|
||||
* See `watchTargets()` for documentation of the arguments.
|
||||
*/
|
||||
unwatchTargets(types, onAvailable, onDestroy, onSelect) {
|
||||
unwatchTargets(types, onAvailable, onDestroy) {
|
||||
if (typeof onAvailable != "function") {
|
||||
throw new Error(
|
||||
"TargetCommand.unwatchTargets expects a function as second argument"
|
||||
|
@ -741,9 +698,6 @@ class TargetCommand extends EventEmitter {
|
|||
if (onDestroy) {
|
||||
this._destroyListeners.off(type, onDestroy);
|
||||
}
|
||||
if (onSelect) {
|
||||
this._selectListeners.off(type, onSelect);
|
||||
}
|
||||
}
|
||||
this._pendingWatchTargetInitialization.delete(onAvailable);
|
||||
}
|
||||
|
@ -877,16 +831,6 @@ class TargetCommand extends EventEmitter {
|
|||
await this._onTargetAvailable(newTarget);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the user selects a frame in the iframe picker.
|
||||
*
|
||||
* @param {WindowGlobalTargetFront} targetFront
|
||||
* The target front we want the toolbox to focus on.
|
||||
*/
|
||||
selectTarget(targetFront) {
|
||||
return this._onTargetSelected(targetFront);
|
||||
}
|
||||
|
||||
isTargetRegistered(targetFront) {
|
||||
return this._targets.has(targetFront);
|
||||
}
|
||||
|
@ -910,9 +854,7 @@ class TargetCommand extends EventEmitter {
|
|||
this.stopListening();
|
||||
this._createListeners.off();
|
||||
this._destroyListeners.off();
|
||||
this._selectListeners.off();
|
||||
|
||||
this.#selectedTargetFront = null;
|
||||
this._isDestroyed = true;
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче