mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 00:35:44 +00:00
Bug 1578242 - Make the inspector use the TargetList. r=gl,pbro
Differential Revision: https://phabricator.services.mozilla.com/D48859 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
0cff796747
commit
27c69caaec
@ -359,7 +359,7 @@ Toolbox.prototype = {
|
||||
|
||||
get nodePicker() {
|
||||
if (!this._nodePicker) {
|
||||
this._nodePicker = new NodePicker(this.target, this.selection);
|
||||
this._nodePicker = new NodePicker(this.targetList, this.selection);
|
||||
this._nodePicker.on("picker-starting", this._onPickerStarting);
|
||||
this._nodePicker.on("picker-started", this._onPickerStarted);
|
||||
this._nodePicker.on("picker-stopped", this._onPickerStopped);
|
||||
|
@ -372,7 +372,7 @@ class FontInspector {
|
||||
return [];
|
||||
}
|
||||
|
||||
const inspectorFronts = await this.inspector.inspectorFront.getAllInspectorFronts();
|
||||
const inspectorFronts = await this.inspector.getAllInspectorFronts();
|
||||
|
||||
let allFonts = [];
|
||||
for (const { pageStyle } of inspectorFronts) {
|
||||
|
@ -153,7 +153,7 @@ class GridInspector {
|
||||
* @return {Array} The list of LayoutActor fronts
|
||||
*/
|
||||
async getLayoutFronts() {
|
||||
const inspectorFronts = await this.inspector.inspectorFront.getAllInspectorFronts();
|
||||
const inspectorFronts = await this.inspector.getAllInspectorFronts();
|
||||
|
||||
const layoutFronts = [];
|
||||
for (const { walker } of inspectorFronts) {
|
||||
|
@ -513,7 +513,7 @@ SelectorAutocompleter.prototype = {
|
||||
query += "*";
|
||||
}
|
||||
|
||||
this._lastQuery = this.inspector.inspectorFront
|
||||
this._lastQuery = this.inspector
|
||||
// Get all inspectors where we want suggestions from.
|
||||
.getAllInspectorFronts()
|
||||
.then(inspectors => {
|
||||
|
@ -176,6 +176,8 @@ function Inspector(toolbox) {
|
||||
this._handleRejectionIfNotDestroyed = this._handleRejectionIfNotDestroyed.bind(
|
||||
this
|
||||
);
|
||||
this._onTargetAvailable = this._onTargetAvailable.bind(this);
|
||||
this._onTargetDestroyed = this._onTargetDestroyed.bind(this);
|
||||
this._onBeforeNavigate = this._onBeforeNavigate.bind(this);
|
||||
this._onMarkupFrameLoad = this._onMarkupFrameLoad.bind(this);
|
||||
this._updateSearchResultsLabel = this._updateSearchResultsLabel.bind(this);
|
||||
@ -220,17 +222,11 @@ Inspector.prototype = {
|
||||
this.currentTarget.threadFront.on("resumed", this.handleThreadResumed);
|
||||
}
|
||||
|
||||
await this.initInspectorFront();
|
||||
|
||||
this.currentTarget.on("will-navigate", this._onBeforeNavigate);
|
||||
|
||||
await Promise.all([
|
||||
this._getCssProperties(),
|
||||
this._getPageStyle(),
|
||||
this._getDefaultSelection(),
|
||||
this._getAccessibilityFront(),
|
||||
this._getChangesFront(),
|
||||
]);
|
||||
await this.toolbox.targetList.watchTargets(
|
||||
[this.toolbox.targetList.TYPES.FRAME],
|
||||
this._onTargetAvailable,
|
||||
this._onTargetDestroyed
|
||||
);
|
||||
|
||||
// Store the URL of the target page prior to navigation in order to ensure
|
||||
// telemetry counts in the Grid Inspector are not double counted on reload.
|
||||
@ -243,8 +239,56 @@ Inspector.prototype = {
|
||||
return this._deferredOpen();
|
||||
},
|
||||
|
||||
async initInspectorFront() {
|
||||
this.inspectorFront = await this.currentTarget.getFront("inspector");
|
||||
async _onTargetAvailable(type, targetFront, isTopLevel) {
|
||||
// Ignore all targets but the top level one
|
||||
if (!isTopLevel) {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.initInspectorFront(targetFront);
|
||||
|
||||
targetFront.on("will-navigate", this._onBeforeNavigate);
|
||||
|
||||
await Promise.all([
|
||||
this._getCssProperties(),
|
||||
this._getPageStyle(),
|
||||
this._getDefaultSelection(),
|
||||
this._getAccessibilityFront(),
|
||||
this._getChangesFront(),
|
||||
]);
|
||||
this.reflowTracker = new ReflowTracker(this.currentTarget);
|
||||
|
||||
// When we navigate to another process and switch to a new
|
||||
// target and the inspector is already ready, we want to
|
||||
// update the markup view accordingly. So force a new-root event.
|
||||
// For the initial panel startup, the initial top level target
|
||||
// update the markup view from _deferredOpen.
|
||||
// We might want to followup here in order to share the same
|
||||
// codepath between the initial top level target and the next
|
||||
// one we switch to. i.e. extract from deferredOpen code
|
||||
// which has to be called only once on inspector startup.
|
||||
// Then move the rest to onNewRoot and always call onNewRoot from here.
|
||||
if (this.isReady) {
|
||||
this.onNewRoot();
|
||||
}
|
||||
},
|
||||
|
||||
_onTargetDestroyed(type, targetFront, isTopLevel) {
|
||||
// Ignore all targets but the top level one
|
||||
if (!isTopLevel) {
|
||||
return;
|
||||
}
|
||||
targetFront.off("will-navigate", this._onBeforeNavigate);
|
||||
|
||||
this._defaultNode = null;
|
||||
this.selection.setNodeFront(null);
|
||||
|
||||
this.reflowTracker.destroy();
|
||||
this.reflowTracker = null;
|
||||
},
|
||||
|
||||
async initInspectorFront(targetFront) {
|
||||
this.inspectorFront = await targetFront.getFront("inspector");
|
||||
this.highlighter = this.inspectorFront.highlighter;
|
||||
this.walker = this.inspectorFront.walker;
|
||||
},
|
||||
@ -253,6 +297,20 @@ Inspector.prototype = {
|
||||
return this._toolbox;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the list of InspectorFront instances that correspond to all of the inspectable
|
||||
* targets in remote frames nested within the document inspected here, as well as the
|
||||
* current InspectorFront instance.
|
||||
*
|
||||
* @return {Array} The list of InspectorFront instances.
|
||||
*/
|
||||
async getAllInspectorFronts() {
|
||||
return this.toolbox.targetList.getAllFronts(
|
||||
this.toolbox.targetList.TYPES.FRAME,
|
||||
"inspector"
|
||||
);
|
||||
},
|
||||
|
||||
get highlighters() {
|
||||
if (!this._highlighters) {
|
||||
this._highlighters = new HighlightersOverlay(this);
|
||||
@ -503,10 +561,10 @@ Inspector.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Target getter.
|
||||
* Top level target front getter.
|
||||
*/
|
||||
get currentTarget() {
|
||||
return this._target;
|
||||
return this.toolbox.targetList.targetFront;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1418,7 +1476,7 @@ Inspector.prototype = {
|
||||
|
||||
this._selectionCssSelectors = {
|
||||
selectors: cssSelectors,
|
||||
url: this._target.url,
|
||||
url: this.currentTarget.url,
|
||||
};
|
||||
},
|
||||
|
||||
@ -1429,7 +1487,7 @@ Inspector.prototype = {
|
||||
get selectionCssSelectors() {
|
||||
if (
|
||||
this._selectionCssSelectors &&
|
||||
this._selectionCssSelectors.url === this._target.url
|
||||
this._selectionCssSelectors.url === this.currentTarget.url
|
||||
) {
|
||||
return this._selectionCssSelectors.selectors;
|
||||
}
|
||||
@ -1671,10 +1729,15 @@ Inspector.prototype = {
|
||||
this.teardownToolbar();
|
||||
|
||||
this.breadcrumbs.destroy();
|
||||
this.reflowTracker.destroy();
|
||||
this.styleChangeTracker.destroy();
|
||||
this.searchboxShortcuts.destroy();
|
||||
|
||||
this.toolbox.targetList.unwatchTargets(
|
||||
[this.toolbox.targetList.TYPES.FRAME],
|
||||
this._onTargetAvailable,
|
||||
this._onTargetDestroyed
|
||||
);
|
||||
|
||||
this._is3PaneModeChromeEnabled = null;
|
||||
this._is3PaneModeEnabled = null;
|
||||
this._markupBox = null;
|
||||
|
@ -400,7 +400,7 @@ MarkupView.prototype = {
|
||||
|
||||
init: async function() {
|
||||
try {
|
||||
this.inspectorFronts = await this.inspector.inspectorFront.getAllInspectorFronts();
|
||||
this.inspectorFronts = await this.inspector.getAllInspectorFronts();
|
||||
} catch (e) {
|
||||
// This call might fail if called asynchrously after the toolbox is finished
|
||||
// closing.
|
||||
|
@ -17,16 +17,16 @@ loader.lazyRequireGetter(this, "EventEmitter", "devtools/shared/event-emitter");
|
||||
* walkerFront and selection api. The nodeFront is stateless, with the
|
||||
* HighlighterFront managing it's own state.
|
||||
*
|
||||
* @param {Target} target
|
||||
* The target the toolbox will debug
|
||||
* @param {TargetList} targetList
|
||||
* The TargetList component referencing all the targets to be debugged
|
||||
* @param {Selection} selection
|
||||
* The global Selection object
|
||||
*/
|
||||
class NodePicker extends EventEmitter {
|
||||
constructor(target, selection) {
|
||||
constructor(targetList, selection) {
|
||||
super();
|
||||
|
||||
this.target = target;
|
||||
this.targetList = targetList;
|
||||
this.selection = selection;
|
||||
|
||||
// Whether or not the node picker is active.
|
||||
@ -80,8 +80,10 @@ class NodePicker extends EventEmitter {
|
||||
|
||||
// Get all the inspector fronts where the picker should start, and cache them locally
|
||||
// so we can stop the picker when needed for the same list of inspector fronts.
|
||||
const inspectorFront = await this.target.getFront("inspector");
|
||||
this._currentInspectorFronts = await inspectorFront.getAllInspectorFronts();
|
||||
this._currentInspectorFronts = await this.targetList.getAllFronts(
|
||||
this.targetList.TYPES.FRAME,
|
||||
"inspector"
|
||||
);
|
||||
|
||||
for (const { walker, highlighter } of this._currentInspectorFronts) {
|
||||
walker.on("picker-node-hovered", this._onHovered);
|
||||
|
@ -24,7 +24,8 @@ function ReflowTracker(target) {
|
||||
|
||||
ReflowTracker.prototype = {
|
||||
destroy() {
|
||||
if (this.reflowFront) {
|
||||
// Ensure that the front isn't yet destroyed
|
||||
if (this.reflowFront && this.reflowFront.actorID) {
|
||||
this.stopTracking();
|
||||
this.reflowFront.destroy();
|
||||
this.reflowFront = null;
|
||||
|
@ -33,7 +33,7 @@ class InspectorStyleChangeTracker {
|
||||
try {
|
||||
// TODO: Bug 1588868 - Get all the inspector fronts whenever targets changes or
|
||||
// are added or removed.
|
||||
this.inspectorFronts = await this.inspector.inspectorFront.getAllInspectorFronts();
|
||||
this.inspectorFronts = await this.inspector.getAllInspectorFronts();
|
||||
} catch (e) {
|
||||
// This call might fail if called asynchrously after the toolbox is finished
|
||||
// closing.
|
||||
|
@ -19,7 +19,6 @@ const TELEMETRY_EYEDROPPER_OPENED_MENU =
|
||||
const SHOW_ALL_ANONYMOUS_CONTENT_PREF =
|
||||
"devtools.inspector.showAllAnonymousContent";
|
||||
const SHOW_UA_SHADOW_ROOTS_PREF = "devtools.inspector.showUserAgentShadowRoots";
|
||||
const BROWSER_FISSION_ENABLED_PREF = "devtools.browsertoolbox.fission";
|
||||
const CONTENT_FISSION_ENABLED_PREF = "devtools.contenttoolbox.fission";
|
||||
const USE_NEW_BOX_MODEL_HIGHLIGHTER_PREF =
|
||||
"devtools.inspector.use-new-box-model-highlighter";
|
||||
@ -50,16 +49,6 @@ class InspectorFront extends FrontClassWithSpec(inspectorSpec) {
|
||||
]);
|
||||
}
|
||||
|
||||
get isBrowserFissionEnabled() {
|
||||
if (this._isBrowserFissionEnabled === undefined) {
|
||||
this._isBrowserFissionEnabled = Services.prefs.getBoolPref(
|
||||
BROWSER_FISSION_ENABLED_PREF
|
||||
);
|
||||
}
|
||||
|
||||
return this._isBrowserFissionEnabled;
|
||||
}
|
||||
|
||||
get isContentFissionEnabled() {
|
||||
if (this._isContentFissionEnabled === undefined) {
|
||||
this._isContentFissionEnabled = Services.prefs.getBoolPref(
|
||||
@ -81,6 +70,11 @@ class InspectorFront extends FrontClassWithSpec(inspectorSpec) {
|
||||
showAllAnonymousContent,
|
||||
showUserAgentShadowRoots,
|
||||
});
|
||||
|
||||
// We need to reparent the RootNode of remote iframe Walkers
|
||||
// so that their parent is the NodeFront of the <iframe>
|
||||
// element, coming from another process/target/WalkerFront.
|
||||
await this.walker.reparentRemoteFrame();
|
||||
}
|
||||
|
||||
async _getHighlighter() {
|
||||
@ -151,48 +145,6 @@ class InspectorFront extends FrontClassWithSpec(inspectorSpec) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of InspectorFront instances that correspond to all of the inspectable
|
||||
* targets in remote frames nested within the document inspected here.
|
||||
*
|
||||
* Note that this only returns a non-empty array if the used from the Browser Toolbox
|
||||
* and with the FISSION_ENABLED pref on.
|
||||
*
|
||||
* @return {Array} The list of InspectorFront instances.
|
||||
*/
|
||||
async getChildInspectors() {
|
||||
const childInspectors = [];
|
||||
const target = this.targetFront;
|
||||
|
||||
// this line can be removed when we are ready for fission frames
|
||||
if (this.isBrowserFissionEnabled && target.chrome && !target.isAddon) {
|
||||
const { frames } = await target.listRemoteFrames();
|
||||
// attempt to get targets and filter by targets that could connect
|
||||
for (const descriptor of frames) {
|
||||
const remoteTarget = await descriptor.getTarget();
|
||||
if (remoteTarget) {
|
||||
// get inspector
|
||||
const remoteInspectorFront = await remoteTarget.getFront("inspector");
|
||||
await remoteInspectorFront.walker.reparentRemoteFrame();
|
||||
childInspectors.push(remoteInspectorFront);
|
||||
}
|
||||
}
|
||||
}
|
||||
return childInspectors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of InspectorFront instances that correspond to all of the inspectable
|
||||
* targets in remote frames nested within the document inspected here, as well as the
|
||||
* current InspectorFront instance.
|
||||
*
|
||||
* @return {Array} The list of InspectorFront instances.
|
||||
*/
|
||||
async getAllInspectorFronts() {
|
||||
const remoteInspectors = await this.getChildInspectors();
|
||||
return [this, ...remoteInspectors];
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a node grip, return a NodeFront on the right context.
|
||||
*
|
||||
|
@ -454,10 +454,33 @@ class WalkerFront extends FrontClassWithSpec(walkerSpec) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that the RootNode of this Walker has the right parent NodeFront.
|
||||
*
|
||||
* This method does nothing if we are on the top level target's WalkerFront,
|
||||
* as the RootNode won't have any parent.
|
||||
*
|
||||
* Otherwise, if we are in an iframe's WalkerFront, we would expect the parent
|
||||
* of the RootNode (i.e. the NodeFront for the document loaded within the iframe)
|
||||
* to be the <iframe>'s NodeFront. Because of fission, the two NodeFront may refer
|
||||
* to DOM Element running in distinct processes and so the NodeFront comes from
|
||||
* two distinct Targets and two distinct WalkerFront.
|
||||
* This is why we need this manual "reparent" code to do the glue between the
|
||||
* two documents.
|
||||
*/
|
||||
async reparentRemoteFrame() {
|
||||
// Get the parent target, which most likely runs in another process
|
||||
const descriptorFront = this.targetFront.descriptorFront;
|
||||
// If we are on the top target, descriptorFront will be the RootFront
|
||||
// and won't have the getParentTarget method.
|
||||
if (!descriptorFront.getParentTarget) {
|
||||
return;
|
||||
}
|
||||
const parentTarget = await descriptorFront.getParentTarget();
|
||||
// Don't reparent if we are on the top target
|
||||
if (parentTarget == this.targetFront) {
|
||||
return;
|
||||
}
|
||||
// Get the NodeFront for the embedder element
|
||||
// i.e. the <iframe> element which is hosting the document that
|
||||
const parentWalker = (await parentTarget.getFront("inspector")).walker;
|
||||
|
Loading…
Reference in New Issue
Block a user