Backed out 14 changesets (bug 1508660, bug 1508656, bug 1504185) for browser_target_cached-front.js perma failures CLOSED TREE

Backed out changeset 08e5ae4312b3 (bug 1508660)
Backed out changeset 01b687bb0b75 (bug 1504185)
Backed out changeset 140374b098aa (bug 1504185)
Backed out changeset caafdc0ea4c7 (bug 1508656)
Backed out changeset 8b98b777aec2 (bug 1508656)
Backed out changeset f1905a2f9b6c (bug 1508656)
Backed out changeset 8b01632f9e3d (bug 1508656)
Backed out changeset eb4c893d451e (bug 1508656)
Backed out changeset 70db61618160 (bug 1508656)
Backed out changeset dff79b73c7fe (bug 1508660)
Backed out changeset b3518d5285be (bug 1508660)
Backed out changeset 94a957b9ba90 (bug 1508660)
Backed out changeset 773938f18269 (bug 1508660)
Backed out changeset 4eca8fce0a47 (bug 1508660)
This commit is contained in:
Ciure Andrei 2018-12-17 17:15:23 +02:00
Родитель bb324b9dad
Коммит 2540abfecb
40 изменённых файлов: 318 добавлений и 369 удалений

Просмотреть файл

@ -44,28 +44,23 @@ class AccessibilityStartup {
// We must call a method on an accessibility front here (such as getWalker), in
// oreder to be able to check actor's backward compatibility via actorHasMethod.
// See targe.js@getActorDescription for more information.
try {
this._walker = await this._accessibility.getWalker();
this._walker = await this._accessibility.getWalker();
this._supports = {};
// Only works with FF61+ targets
this._supports.enableDisable =
await this.target.actorHasMethod("accessibility", "enable");
this._supports = {};
// Only works with FF61+ targets
this._supports.enableDisable =
await this.target.actorHasMethod("accessibility", "enable");
if (this._supports.enableDisable) {
([ this._supports.relations, this._supports.snapshot ] = await Promise.all([
this.target.actorHasMethod("accessible", "getRelations"),
this.target.actorHasMethod("accessible", "snapshot"),
]));
if (this._supports.enableDisable) {
([ this._supports.relations, this._supports.snapshot ] = await Promise.all([
this.target.actorHasMethod("accessible", "getRelations"),
this.target.actorHasMethod("accessible", "snapshot"),
]));
await this._accessibility.bootstrap();
}
return true;
} catch (e) {
// toolbox may be destroyed during this step.
return false;
await this._accessibility.bootstrap();
}
return true;
}
/**

Просмотреть файл

@ -85,7 +85,7 @@ Tools.inspector = {
preventClosingOnKey: true,
onkey: function(panel, toolbox) {
toolbox.inspector.nodePicker.togglePicker();
toolbox.highlighterUtils.togglePicker();
},
isTargetSupported: function(target) {
@ -582,9 +582,8 @@ function createHighlightButton(highlighterName, id) {
description: l10n(`toolbox.buttons.${id}`),
isTargetSupported: target => !target.chrome,
async onClick(event, toolbox) {
await toolbox.initInspector();
const highlighter =
await toolbox.inspector.getOrCreateHighlighterByType(highlighterName);
await toolbox.highlighterUtils.getOrCreateHighlighterByType(highlighterName);
if (highlighter.isShown()) {
return highlighter.hide();
}
@ -594,17 +593,7 @@ function createHighlightButton(highlighterName, id) {
return highlighter.show({});
},
isChecked(toolbox) {
// if the inspector doesn't exist, then the highlighter has not yet been connected
// to the front end.
const inspectorFront = toolbox.target.getCachedFront("inspector");
if (!inspectorFront) {
// initialize the inspector front asyncronously. There is a potential for buggy
// behavior here, but we need to change how the buttons get data (have them
// consume data from reducers rather than writing our own version) in order to
// fix this properly.
return false;
}
const highlighter = inspectorFront.getKnownHighlighter(highlighterName);
const highlighter = toolbox.highlighterUtils.getKnownHighlighter(highlighterName);
return highlighter && highlighter.isShown();
},
};

Просмотреть файл

@ -28,6 +28,7 @@ DevToolsModules(
'target-from-url.js',
'target.js',
'toolbox-context-menu.js',
'toolbox-highlighter-utils.js',
'toolbox-host-manager.js',
'toolbox-hosts.js',
'toolbox-options.js',

Просмотреть файл

@ -391,31 +391,18 @@ Target.prototype = {
// Get a Front for a target-scoped actor.
// i.e. an actor served by RootActor.listTabs or RootActorActor.getTab requests
async getFront(typeName) {
getFront(typeName) {
let front = this.fronts.get(typeName);
// the front might have been destroyed and no longer have an actor ID
if (front && front.actorID || front && typeof front.then === "function") {
return front;
}
front = getFront(this.client, typeName, this.form);
this.fronts.set(typeName, front);
// replace the placeholder with the instance of the front once it has loaded
front = await front;
this.emit(typeName, front);
this.fronts.set(typeName, front);
return front;
},
getCachedFront(typeName) {
// do not wait for async fronts;
const front = this.fronts.get(typeName);
// ensure that the front is a front, and not async front
if (front && front.actorID) {
return front;
}
return null;
},
get client() {
return this._client;
},

Просмотреть файл

@ -76,7 +76,6 @@ skip-if = os == 'win' || debug # Bug 1282269, 1448084
[browser_source_map-reload.js]
[browser_source_map-late-script.js]
[browser_target_from_url.js]
[browser_target_cached-front.js]
[browser_target_events.js]
[browser_target_remote.js]
[browser_target_support.js]

Просмотреть файл

@ -98,12 +98,12 @@ add_task(async function() {
async function inspectorShouldBeOpenAndHighlighting(inspector) {
is(toolbox.currentToolId, "inspector", "Correct tool has been loaded");
await toolbox.inspector.nodePicker.once("picker-started");
await toolbox.once("picker-started");
ok(true, "picker-started event received, highlighter started");
inspector.synthesizeKey();
await toolbox.inspector.nodePicker.once("picker-stopped");
await toolbox.once("picker-stopped");
ok(true, "picker-stopped event received, highlighter stopped");
}

Просмотреть файл

@ -1,24 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
add_task(async function() {
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
const target = await TargetFactory.forTab(gBrowser.selectedTab);
await target.attach();
info("Cached front when getFront has not been called");
let getCachedFront = target.getCachedFront("accessibility");
ok(!getCachedFront, "no front exists");
info("Cached front when getFront has been called but has not finished");
const asyncFront = target.getFront("accessibility");
getCachedFront = target.getCachedFront("accessibility");
ok(!getCachedFront, "no front exists");
info("Cached front when getFront has been called and has finished");
const front = await asyncFront;
getCachedFront = target.getCachedFront("accessibility");
is(getCachedFront, front, "front is the same as async front");
});

Просмотреть файл

@ -0,0 +1,214 @@
/* 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";
const promise = require("promise");
/**
* Client-side highlighter shared module.
* To be used by toolbox panels that need to highlight DOM elements.
*
* Highlighting and selecting elements is common enough that it needs to be at
* toolbox level, accessible by any panel that needs it.
* That's why the toolbox is the one that initializes the inspector and
* highlighter. It's also why the API returned by this module needs a reference
* to the toolbox which should be set once only.
*/
/**
* Get the highighterUtils instance for a given toolbox.
* This should be done once only by the toolbox itself and stored there so that
* panels can get it from there. That's because the API returned has a stateful
* scope that would be different for another instance returned by this function.
*
* @param {Toolbox} toolbox
* @return {Object} the highlighterUtils public API
*/
exports.getHighlighterUtils = function(toolbox) {
if (!toolbox) {
throw new Error("Missing or invalid toolbox passed to getHighlighterUtils");
}
// Exported API properties will go here
const exported = {};
// Is the highlighter currently in pick mode
let isPicking = false;
/**
* Release this utils, nullifying the references to the toolbox
*/
exported.release = function() {
toolbox = null;
};
/**
* Make a function that initializes the inspector before it runs.
* Since the init of the inspector is asynchronous, the return value will be
* produced by Task.async and the argument should be a generator
* @param {Function*} generator A generator function
* @return {Function} A function
*/
let isInspectorInitialized = false;
const requireInspector = generator => {
return async function(...args) {
if (!isInspectorInitialized) {
await toolbox.initInspector();
isInspectorInitialized = true;
}
return generator.apply(null, args);
};
};
/**
* Start/stop the element picker on the debuggee target.
* @param {Boolean} doFocus - Optionally focus the content area once the picker is
* activated.
* @return A promise that resolves when done
*/
exported.togglePicker = function(doFocus) {
if (isPicking) {
return cancelPicker();
}
return startPicker(doFocus);
};
/**
* Start the element picker on the debuggee target.
* This will request the inspector actor to start listening for mouse events
* on the target page to highlight the hovered/picked element.
* Depending on the server-side capabilities, this may fire events when nodes
* are hovered.
* @param {Boolean} doFocus - Optionally focus the content area once the picker is
* activated.
* @return A promise that resolves when the picker has started or immediately
* if it is already started
*/
const startPicker = exported.startPicker =
requireInspector(async function(doFocus = false) {
if (isPicking) {
return;
}
isPicking = true;
toolbox.pickerButton.isChecked = true;
await toolbox.selectTool("inspector", "inspect_dom");
toolbox.on("select", cancelPicker);
toolbox.walker.on("picker-node-hovered", onPickerNodeHovered);
toolbox.walker.on("picker-node-picked", onPickerNodePicked);
toolbox.walker.on("picker-node-previewed", onPickerNodePreviewed);
toolbox.walker.on("picker-node-canceled", onPickerNodeCanceled);
await toolbox.highlighter.pick(doFocus);
toolbox.emit("picker-started");
});
/**
* Stop the element picker. Note that the picker is automatically stopped when
* an element is picked
* @return A promise that resolves when the picker has stopped or immediately
* if it is already stopped
*/
const stopPicker = exported.stopPicker = requireInspector(async function() {
if (!isPicking) {
return;
}
isPicking = false;
toolbox.pickerButton.isChecked = false;
await toolbox.highlighter.cancelPick();
toolbox.walker.off("picker-node-hovered", onPickerNodeHovered);
toolbox.walker.off("picker-node-picked", onPickerNodePicked);
toolbox.walker.off("picker-node-previewed", onPickerNodePreviewed);
toolbox.walker.off("picker-node-canceled", onPickerNodeCanceled);
toolbox.off("select", cancelPicker);
toolbox.emit("picker-stopped");
});
/**
* Stop the picker, but also emit an event that the picker was canceled.
*/
const cancelPicker = exported.cancelPicker = async function() {
await stopPicker();
toolbox.emit("picker-canceled");
};
/**
* When a node is hovered by the mouse when the highlighter is in picker mode
* @param {Object} data Information about the node being hovered
*/
function onPickerNodeHovered(data) {
toolbox.emit("picker-node-hovered", data.node);
}
/**
* When a node has been picked while the highlighter is in picker mode
* @param {Object} data Information about the picked node
*/
function onPickerNodePicked(data) {
toolbox.selection.setNodeFront(data.node, { reason: "picker-node-picked" });
stopPicker();
}
/**
* When a node has been shift-clicked (previewed) while the highlighter is in
* picker mode
* @param {Object} data Information about the picked node
*/
function onPickerNodePreviewed(data) {
toolbox.selection.setNodeFront(data.node, { reason: "picker-node-previewed" });
}
/**
* When the picker is canceled, stop the picker, and make sure the toolbox
* gets the focus.
*/
function onPickerNodeCanceled() {
cancelPicker();
toolbox.win.focus();
}
/**
* If the main, box-model, highlighter isn't enough, or if multiple highlighters
* are needed in parallel, this method can be used to return a new instance of a
* highlighter actor, given a type.
* The type of the highlighter passed must be known by the server.
* The highlighter actor returned will have the show(nodeFront) and hide()
* methods and needs to be released by the consumer when not needed anymore.
* @return Promise a promise that resolves to the highlighter
*/
exported.getHighlighterByType = requireInspector(async function(typeName) {
const highlighter = await toolbox.inspector.getHighlighterByType(typeName);
return highlighter || promise.reject("The target doesn't support " +
`creating highlighters by types or ${typeName} is unknown`);
});
/**
* Similar to getHighlighterByType, however it automatically memoizes and
* destroys highlighters with the inspector, instead of having to be manually
* managed by consumers.
* The type of the highlighter passed must be known by the server.
* The highlighter actor returned will have the show(nodeFront) and hide()
* methods and needs to be released by the consumer when not needed anymore.
* @return Promise a promise that resolves to the highlighter
*/
exported.getOrCreateHighlighterByType = requireInspector(async function(typeName) {
const highlighter = await toolbox.inspector.getOrCreateHighlighterByType(typeName);
return highlighter || promise.reject("The target doesn't support " +
`creating highlighters by types or ${typeName} is unknown`);
});
exported.getKnownHighlighter = function(typeName) {
return toolbox.inspector && toolbox.inspector.getKnownHighlighter(typeName);
};
// Return the public API
return exported;
};

Просмотреть файл

@ -38,6 +38,8 @@ const L10N = new LocalizationHelper("devtools/client/locales/toolbox.properties"
loader.lazyRequireGetter(this, "AppConstants",
"resource://gre/modules/AppConstants.jsm", true);
loader.lazyRequireGetter(this, "getHighlighterUtils",
"devtools/client/framework/toolbox-highlighter-utils", true);
loader.lazyRequireGetter(this, "flags",
"devtools/shared/flags");
loader.lazyRequireGetter(this, "KeyShortcuts",
@ -134,6 +136,7 @@ function Toolbox(target, selectedTool, hostType, contentWindow, frameId,
this._splitConsoleOnKeypress = this._splitConsoleOnKeypress.bind(this);
this.closeToolbox = this.closeToolbox.bind(this);
this.destroy = this.destroy.bind(this);
this.highlighterUtils = getHighlighterUtils(this);
this._highlighterReady = this._highlighterReady.bind(this);
this._highlighterHidden = this._highlighterHidden.bind(this);
this._applyCacheSettings = this._applyCacheSettings.bind(this);
@ -149,10 +152,8 @@ function Toolbox(target, selectedTool, hostType, contentWindow, frameId,
this._onToolbarArrowKeypress = this._onToolbarArrowKeypress.bind(this);
this._onPickerClick = this._onPickerClick.bind(this);
this._onPickerKeypress = this._onPickerKeypress.bind(this);
this._onPickerStarting = this._onPickerStarting.bind(this);
this._onPickerStarted = this._onPickerStarted.bind(this);
this._onPickerStopped = this._onPickerStopped.bind(this);
this._onPickerCanceled = this._onPickerCanceled.bind(this);
this._onInspectObject = this._onInspectObject.bind(this);
this._onNewSelectedNodeFront = this._onNewSelectedNodeFront.bind(this);
this._onToolSelected = this._onToolSelected.bind(this);
@ -192,6 +193,9 @@ function Toolbox(target, selectedTool, hostType, contentWindow, frameId,
gDevTools.on("tool-registered", this._toolRegistered);
gDevTools.on("tool-unregistered", this._toolUnregistered);
this.on("picker-started", this._onPickerStarted);
this.on("picker-stopped", this._onPickerStopped);
/**
* Get text direction for the current locale direction.
*
@ -371,6 +375,8 @@ Toolbox.prototype = {
/**
* Get the toolbox highlighter front. Note that it may not always have been
* initialized first. Use `initInspector()` if needed.
* Consider using highlighterUtils instead, it exposes the highlighter API in
* a useful way for the toolbox panels
*/
get highlighter() {
return this._highlighter;
@ -1267,7 +1273,7 @@ Toolbox.prototype = {
* Note: Toggle picker can be overwritten by panel other than the inspector to
* allow for custom picker behaviour.
*/
_onPickerClick: async function() {
_onPickerClick: function() {
const focus = this.hostType === Toolbox.HostType.BOTTOM ||
this.hostType === Toolbox.HostType.LEFT ||
this.hostType === Toolbox.HostType.RIGHT;
@ -1275,10 +1281,7 @@ Toolbox.prototype = {
if (currentPanel.togglePicker) {
currentPanel.togglePicker(focus);
} else {
if (!this.inspector) {
await this.initInspector();
}
this.inspector.nodePicker.togglePicker(focus);
this.highlighterUtils.togglePicker(focus);
}
},
@ -1292,35 +1295,19 @@ Toolbox.prototype = {
if (currentPanel.cancelPicker) {
currentPanel.cancelPicker();
} else {
this.inspector.nodePicker.cancel();
this.highlighterUtils.cancelPicker();
}
// Stop the console from toggling.
event.stopImmediatePropagation();
}
},
_onPickerStarting: async function() {
this.pickerButton.isChecked = true;
await this.selectTool("inspector", "inspect_dom");
this.on("select", this.inspector.nodePicker.stop);
},
_onPickerStarted: async function() {
_onPickerStarted: function() {
this.doc.addEventListener("keypress", this._onPickerKeypress, true);
},
_onPickerStopped: function() {
this.off("select", this.inspector.nodePicker.stop);
this.doc.removeEventListener("keypress", this._onPickerKeypress, true);
this.pickerButton.isChecked = false;
},
/**
* When the picker is canceled, make sure the toolbox
* gets the focus.
*/
_onPickerCanceled: function() {
this.win.focus();
},
/**
@ -2721,10 +2708,6 @@ Toolbox.prototype = {
this._highlighter = this.inspector.highlighter;
this._selection = this.inspector.selection;
this.inspector.nodePicker.on("picker-starting", this._onPickerStarting);
this.inspector.nodePicker.on("picker-started", this._onPickerStarted);
this.inspector.nodePicker.on("picker-stopped", this._onPickerStopped);
this.inspector.nodePicker.on("picker-node-canceled", this._onPickerCanceled);
this.walker.on("highlighter-ready", this._highlighterReady);
this.walker.on("highlighter-hide", this._highlighterHidden);
this._selection.on("new-node-front", this._onNewSelectedNodeFront);
@ -2977,6 +2960,7 @@ Toolbox.prototype = {
}
const target = this._target;
this._target = null;
this.highlighterUtils.release();
target.off("close", this.destroy);
return target.destroy();
}, console.error).then(() => {

Просмотреть файл

@ -141,8 +141,8 @@ class AnimationInspector {
this.provider = provider;
this.inspector.sidebar.on("select", this.onSidebarSelectionChanged);
this.inspector.inspector.nodePicker.on("picker-started", this.onElementPickerStarted);
this.inspector.inspector.nodePicker.on("picker-stopped", this.onElementPickerStopped);
this.inspector.toolbox.on("picker-started", this.onElementPickerStarted);
this.inspector.toolbox.on("picker-stopped", this.onElementPickerStopped);
this.inspector.toolbox.on("select", this.onSidebarSelectionChanged);
}
@ -165,12 +165,8 @@ class AnimationInspector {
this.inspector.selection.off("new-node-front", this.update);
this.inspector.sidebar.off("select", this.onSidebarSelectionChanged);
this.inspector.toolbox.off("inspector-sidebar-resized", this.onSidebarResized);
this.inspector.inspector.nodePicker.off(
"picker-started", this.onElementPickerStarted
);
this.inspector.inspector.nodePicker.off(
"picker-stopped", this.onElementPickerStopped
);
this.inspector.toolbox.off("picker-started", this.onElementPickerStarted);
this.inspector.toolbox.off("picker-stopped", this.onElementPickerStopped);
this.inspector.toolbox.off("select", this.onSidebarSelectionChanged);
this.animationsFrontPromise.then(front => {
@ -652,7 +648,7 @@ class AnimationInspector {
}
toggleElementPicker() {
this.inspector.inspector.nodePicker.togglePicker();
this.inspector.toolbox.highlighterUtils.togglePicker();
}
async update() {

Просмотреть файл

@ -207,12 +207,12 @@ BoxModel.prototype = {
* geometry editor enabled state.
*/
onHideGeometryEditor() {
const { markup, selection, inspector } = this.inspector;
const { markup, selection, toolbox } = this.inspector;
this.highlighters.hideGeometryEditor();
this.store.dispatch(updateGeometryEditorEnabled(false));
inspector.nodePicker.off("picker-started", this.onHideGeometryEditor);
toolbox.off("picker-started", this.onHideGeometryEditor);
selection.off("new-node-front", this.onHideGeometryEditor);
markup.off("leave", this.onMarkupViewLeave);
markup.off("node-hover", this.onMarkupViewNodeHover);
@ -365,7 +365,7 @@ BoxModel.prototype = {
* toggle button is clicked.
*/
onToggleGeometryEditor() {
const { markup, selection, inspector } = this.inspector;
const { markup, selection, toolbox } = this.inspector;
const nodeFront = this.inspector.selection.nodeFront;
const state = this.store.getState();
const enabled = !state.boxModel.geometryEditorEnabled;
@ -375,13 +375,13 @@ BoxModel.prototype = {
if (enabled) {
// Hide completely the geometry editor if the picker is clicked or a new node front
inspector.nodePicker.on("picker-started", this.onHideGeometryEditor);
toolbox.on("picker-started", this.onHideGeometryEditor);
selection.on("new-node-front", this.onHideGeometryEditor);
// Temporary hide the geometry editor
markup.on("leave", this.onMarkupViewLeave);
markup.on("node-hover", this.onMarkupViewNodeHover);
} else {
inspector.nodePicker.off("picker-started", this.onHideGeometryEditor);
toolbox.off("picker-started", this.onHideGeometryEditor);
selection.off("new-node-front", this.onHideGeometryEditor);
markup.off("leave", this.onMarkupViewLeave);
markup.off("node-hover", this.onMarkupViewNodeHover);

Просмотреть файл

@ -54,7 +54,7 @@ class ChangesView {
}
this.changesFrontPromise = new Promise(async resolve => {
const target = this.inspector.target;
const front = await target.getFront("changes");
const front = target.getFront("changes");
this.onChangesFront(front);
resolve(front);
});

Просмотреть файл

@ -752,7 +752,7 @@ class FontInspector {
async onToggleFontHighlight(font, show, isForCurrentElement = true) {
if (!this.fontsHighlighter) {
try {
this.fontsHighlighter = await this.inspector.inspector
this.fontsHighlighter = await this.inspector.toolbox.highlighterUtils
.getHighlighterByType("FontsHighlighter");
} catch (e) {
// When connecting to an older server or when debugging a XUL document, the

Просмотреть файл

@ -121,12 +121,8 @@ function MarkupView(inspector, frame, controllerWindow) {
this.walker.on("mutations", this._mutationObserver);
this.win.addEventListener("copy", this._onCopy);
this.win.addEventListener("mouseup", this._onMouseUp);
this.inspector.inspector.nodePicker.on(
"picker-node-canceled", this._onToolboxPickerCanceled
);
this.inspector.inspector.nodePicker.on(
"picker-node-hovered", this._onToolboxPickerHover
);
this.toolbox.on("picker-canceled", this._onToolboxPickerCanceled);
this.toolbox.on("picker-node-hovered", this._onToolboxPickerHover);
if (flags.testing) {
// In tests, we start listening immediately to avoid having to simulate a mousemove.
@ -1953,9 +1949,7 @@ MarkupView.prototype = {
this._elt.removeEventListener("mouseout", this._onMouseOut);
this._frame.removeEventListener("focus", this._onFocus);
this.inspector.selection.off("new-node-front", this._onNewSelection);
this.inspector.inspector.nodePicker.off(
"picker-node-hovered", this._onToolboxPickerHover
);
this.toolbox.off("picker-node-hovered", this._onToolboxPickerHover);
this.walker.off("display-change", this._onDisplayChange);
this.walker.off("mutations", this._mutationObserver);
this.win.removeEventListener("copy", this._onCopy);

Просмотреть файл

@ -262,8 +262,8 @@ CssRuleView.prototype = {
}
try {
const front = this.inspector.inspector;
const h = await front.getHighlighterByType("SelectorHighlighter");
const utils = this.inspector.toolbox.highlighterUtils;
const h = await utils.getHighlighterByType("SelectorHighlighter");
this.selectorHighlighter = h;
return h;
} catch (e) {

Просмотреть файл

@ -12,7 +12,7 @@ add_task(async function() {
await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
const {view, toolbox} = await openRuleView();
const pickerStopped = toolbox.inspector.nodePicker.once("picker-stopped");
const pickerStopped = toolbox.once("picker-stopped");
await startPicker(toolbox);

Просмотреть файл

@ -28,7 +28,7 @@ class HighlightersOverlay {
*/
constructor(inspector) {
this.inspector = inspector;
this.inspectorFront = this.inspector.inspector;
this.highlighterUtils = this.inspector.toolbox.highlighterUtils;
this.store = this.inspector.store;
this.telemetry = inspector.telemetry;
this.maxGridHighlighters =
@ -779,7 +779,7 @@ class HighlightersOverlay {
let highlighter;
try {
highlighter = await this.inspectorFront.getHighlighterByType(type);
highlighter = await this.highlighterUtils.getHighlighterByType(type);
} catch (e) {
this._handleRejection(e);
}
@ -812,7 +812,7 @@ class HighlightersOverlay {
highlighter = this.extraGridHighlighterPool.pop();
} else {
try {
highlighter = await this.inspectorFront.getHighlighterByType(
highlighter = await this.highlighterUtils.getHighlighterByType(
"CssGridHighlighter");
} catch (e) {
this._handleRejection(e);
@ -1240,7 +1240,7 @@ class HighlightersOverlay {
this._lastHovered = null;
this.inspector = null;
this.inspectorFront = null;
this.highlighterUtils = null;
this.state = null;
this.store = null;

Просмотреть файл

@ -60,11 +60,11 @@ add_task(async function() {
await testActor.isNodeCorrectlyHighlighted(iframeBodySelector, is);
info("Waiting for the element picker to deactivate.");
await inspector.inspector.nodePicker.stop();
await inspector.toolbox.highlighterUtils.stopPicker();
function moveMouseOver(selector, x, y) {
info("Waiting for element " + selector + " to be highlighted");
testActor.synthesizeMouse({selector, x, y, options: {type: "mousemove"}});
return inspector.inspector.nodePicker.once("picker-node-hovered");
return inspector.toolbox.once("picker-node-hovered");
}
});

Просмотреть файл

@ -31,7 +31,7 @@ add_task(async function() {
function cancelPickerByShortcut() {
info("Key pressed. Waiting for picker to be canceled.");
testActor.synthesizeKey({key: "VK_ESCAPE", options: {}});
return inspector.inspector.nodePicker.once("picker-node-canceled");
return inspector.toolbox.once("picker-canceled");
}
function moveMouseOver(selector) {

Просмотреть файл

@ -51,7 +51,7 @@ add_task(async function() {
"Breadcrumbs have 9 items.");
info("Waiting for element picker to deactivate.");
await inspector.inspector.nodePicker.stop();
await inspector.toolbox.highlighterUtils.stopPicker();
function moveMouseOver(selector) {
info("Waiting for element " + selector + " to be highlighted");
@ -59,6 +59,6 @@ add_task(async function() {
selector: selector,
options: {type: "mousemove"},
center: true,
}).then(() => inspector.inspector.nodePicker.once("picker-node-hovered"));
}).then(() => inspector.toolbox.once("picker-node-hovered"));
}
});

Просмотреть файл

@ -9,7 +9,7 @@
const TEST_URL = URL_ROOT + "doc_inspector_highlighter_dom.html";
add_task(async function() {
const {toolbox, testActor} = await openInspectorForURL(TEST_URL);
const {inspector, toolbox, testActor} = await openInspectorForURL(TEST_URL);
await startPicker(toolbox);
@ -44,12 +44,12 @@ add_task(async function() {
info("First child selection test Passed.");
info("Stopping the picker");
await toolbox.inspector.nodePicker.stop();
await toolbox.highlighterUtils.stopPicker();
function doKeyHover(args) {
info("Key pressed. Waiting for element to be highlighted/hovered");
testActor.synthesizeKey(args);
return toolbox.inspector.nodePicker.once("picker-node-hovered");
return inspector.toolbox.once("picker-node-hovered");
}
function moveMouseOver(selector) {
@ -59,6 +59,6 @@ add_task(async function() {
center: true,
selector: selector,
});
return toolbox.inspector.nodePicker.once("picker-node-hovered");
return inspector.toolbox.once("picker-node-hovered");
}
});

Просмотреть файл

@ -9,7 +9,7 @@
const TEST_URL = URL_ROOT + "doc_inspector_highlighter_dom.html";
add_task(async function() {
const {toolbox, testActor} = await openInspectorForURL(TEST_URL);
const {inspector, toolbox, testActor} = await openInspectorForURL(TEST_URL);
await startPicker(toolbox);
@ -40,12 +40,12 @@ add_task(async function() {
info("Previously chosen child is remembered. Passed.");
info("Stopping the picker");
await toolbox.inspector.nodePicker.stop();
await toolbox.highlighterUtils.stopPicker();
function doKeyHover(args) {
info("Key pressed. Waiting for element to be highlighted/hovered");
const onHighlighterReady = toolbox.once("highlighter-ready");
const onPickerNodeHovered = toolbox.inspector.nodePicker.once("picker-node-hovered");
const onPickerNodeHovered = inspector.toolbox.once("picker-node-hovered");
testActor.synthesizeKey(args);
return promise.all([onHighlighterReady, onPickerNodeHovered]);
}
@ -53,7 +53,7 @@ add_task(async function() {
function moveMouseOver(selector) {
info("Waiting for element " + selector + " to be highlighted");
const onHighlighterReady = toolbox.once("highlighter-ready");
const onPickerNodeHovered = toolbox.inspector.nodePicker.once("picker-node-hovered");
const onPickerNodeHovered = inspector.toolbox.once("picker-node-hovered");
testActor.synthesizeMouse({
options: {type: "mousemove"},
center: true,

Просмотреть файл

@ -48,21 +48,20 @@ add_task(async function() {
return promise.all([
inspector.selection.once("new-node-front"),
inspector.once("inspector-updated"),
inspector.inspector.nodePicker.once("picker-stopped"),
inspector.toolbox.once("picker-stopped"),
]);
}
function doKeyStop(args) {
info("Key pressed. Waiting for picker to be canceled");
testActor.synthesizeKey(args);
return inspector.inspector.nodePicker.once("picker-stopped");
return inspector.toolbox.once("picker-stopped");
}
function moveMouseOver(selector) {
info("Waiting for element " + selector + " to be highlighted");
const onHighlighterReady = toolbox.once("highlighter-ready");
const onPickerNodeHovered =
inspector.inspector.nodePicker.once("picker-node-hovered");
const onPickerNodeHovered = inspector.toolbox.once("picker-node-hovered");
testActor.synthesizeMouse({
options: {type: "mousemove"},
center: true,

Просмотреть файл

@ -15,7 +15,7 @@ add_task(async function() {
await startPicker(toolbox);
info("Start using the picker by hovering over nodes");
const onHover = toolbox.inspector.nodePicker.once("picker-node-hovered");
const onHover = toolbox.once("picker-node-hovered");
testActor.synthesizeMouse({
options: {type: "mousemove"},
center: true,
@ -24,7 +24,7 @@ add_task(async function() {
await onHover;
info("Press escape and wait for the picker to stop");
const onPickerStopped = toolbox.inspector.nodePicker.once("picker-node-canceled");
const onPickerStopped = toolbox.once("picker-stopped");
testActor.synthesizeKey({
key: "VK_ESCAPE",
options: {},

Просмотреть файл

@ -34,6 +34,6 @@ add_task(async function() {
center: true,
selector: selector,
});
return inspector.inspector.nodePicker.once("picker-node-hovered");
return inspector.toolbox.once("picker-node-hovered");
}
});

Просмотреть файл

@ -39,5 +39,5 @@ add_task(async function() {
ok(isVisible, "Inspector is highlighting after iframe nav.");
info("Stopping element picker.");
await toolbox.inspector.nodePicker.stop();
await toolbox.highlighterUtils.stopPicker();
});

Просмотреть файл

@ -12,7 +12,7 @@ const TEST_URI = "data:text/html;charset=UTF-8," +
add_task(async function() {
const { toolbox } = await openInspectorForURL(TEST_URI);
const pickerStopped = toolbox.inspector.nodePicker.once("picker-stopped");
const pickerStopped = toolbox.once("picker-stopped");
info("Starting the inspector picker");
await startPicker(toolbox);

Просмотреть файл

@ -67,7 +67,7 @@ add_task(async function() {
await startPickerAndAssertSwitchToInspector(toolbox);
info("Stoppping element picker.");
await toolbox.inspector.nodePicker.stop();
await toolbox.highlighterUtils.stopPicker();
checkResults();
});

Просмотреть файл

@ -68,7 +68,7 @@ var navigateTo = async function(inspector, url) {
var startPicker = async function(toolbox, skipFocus) {
info("Start the element picker");
toolbox.win.focus();
await toolbox.inspector.nodePicker.start();
await toolbox.highlighterUtils.startPicker();
if (!skipFocus) {
// By default make sure the content window is focused since the picker may not focus
// the content window by default.
@ -121,7 +121,7 @@ function pickElement(inspector, testActor, selector, x, y) {
*/
function hoverElement(inspector, testActor, selector, x, y) {
info("Waiting for element " + selector + " to be hovered");
const onHovered = inspector.inspector.nodePicker.once("picker-node-hovered");
const onHovered = inspector.toolbox.once("picker-node-hovered");
testActor.synthesizeMouse({selector, x, y, options: {type: "mousemove"}});
return onHovered;
}

Просмотреть файл

@ -169,7 +169,7 @@ class SwatchColorPickerTooltip extends SwatchBasedEditorTooltip {
telemetry.getHistogramById(TELEMETRY_PICKER_EYEDROPPER_OPEN_COUNT).add(true);
// cancelling picker(if it is already selected) on opening eye-dropper
inspector.nodePicker.cancel();
toolbox.highlighterUtils.cancelPicker();
// pickColorFromPage will focus the content document. If the devtools are in a
// separate window, the colorpicker tooltip will be closed before pickColorFromPage

Просмотреть файл

@ -33,9 +33,9 @@ class StoragePanel {
/**
* open is effectively an asynchronous constructor
*/
async open() {
open() {
this.target.on("close", this.destroy);
this._front = await this.target.getFront("storage");
this._front = this.target.getFront("storage");
this.UI = new StorageUI(this._front, this._target,
this._panelWin, this._toolbox);

Просмотреть файл

@ -129,9 +129,11 @@ StyleEditorUI.prototype = {
await toolbox.initInspector();
this._walker = toolbox.walker;
const hUtils = toolbox.highlighterUtils;
try {
this._highlighter =
await toolbox.inspector.getHighlighterByType(SELECTOR_HIGHLIGHTER_TYPE);
await hUtils.getHighlighterByType(SELECTOR_HIGHLIGHTER_TYPE);
} catch (e) {
// The selectorHighlighter can't always be instantiated, for example
// it doesn't work with XUL windows (until bug 1094959 gets fixed);

Просмотреть файл

@ -963,14 +963,13 @@ function isReverseSearchInputFocused(hud) {
*/
async function selectNodeWithPicker(toolbox, testActor, selector) {
const inspector = toolbox.getPanel("inspector");
const inspectorFront = inspector.inspector;
const onPickerStarted = inspectorFront.nodePicker.once("picker-started");
inspectorFront.nodePicker.start();
const onPickerStarted = inspector.toolbox.once("picker-started");
inspector.toolbox.highlighterUtils.startPicker();
await onPickerStarted;
info(`Picker mode started, now clicking on "${selector}" to select that node`);
const onPickerStopped = inspectorFront.nodePicker.once("picker-stopped");
const onPickerStopped = toolbox.once("picker-stopped");
const onInspectorUpdated = inspector.once("inspector-updated");
testActor.synthesizeMouse({

Просмотреть файл

@ -20,7 +20,15 @@ But there can be a wide variety of highlighters. In particular, highlighters are
Highlighters run on the debuggee side, not on the toolbox side. This is so that it's possible to highlight elements on a remote device for instance. This means you need to go through the [Remote Debugging Protocol](protocol.md) to use a highlighter.
Since the box-model highlighter (HighlighterFront) is the most used type of highlighter (for instance it's displayed when you move your mouse over nodes in the inspector), the HighlighterFront provides a custom set of methods to interact with it:
### The highlighter utils
The easiest way to access the highlighters from toolbox-side DevTools code is by using the highlighter utils, which is conveniently available on the toolbox object. Here is how you can access the utils:
```js
let hUtils = toolbox.highlighterUtils;
```
Since the box-model highlighter is the most used type of highlighter (for instance it's displayed when you move your mouse over nodes in the inspector), the utils provides a set of methods to interact with it:
| Method | Description |
|------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
@ -30,15 +38,7 @@ Since the box-model highlighter (HighlighterFront) is the most used type of high
| `highlightDomValueGrip(valueGrip)` | Display the box-model highlighter on a given node, represented by a debugger object value grip. |
| `unhighlight()` | Hide the box-model highlighter. |
Not all methods that are related to highlighters are present on the HighlighterFront. The
`highlightDomValueGrip` method also requires the WalkerFront in order to transform a Grip into a
NodeFront. Therefore, methods that access other Fronts are available on the InspectorFront.
| Method | Description |
|------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `highlightDomValueGrip(valueGrip)` | Display the box-model highlighter on a given node, represented by a debugger object value grip. |
But the box-model highlighter isn't the only type of highlighter, so the InspectorFront also provides the following method:
But the box-model highlighter isn't the only type of highlighter, so the highlighter utils provides the following method:
| Method | Description |
|----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
@ -46,7 +46,7 @@ But the box-model highlighter isn't the only type of highlighter, so the Inspect
### The highlighter API
When getting a highlighter via `toolbox.inspector.getHighlighterByType(typeName)`, the right type of highlighter will be instantiated on the server-side and will be wrapped into a `CustomHighlighterActor` and that's what will be returned to the caller. This means that all types of highlighters share the same following API:
When getting a highlighter via `toolbox.highlighterUtils.getHighlighterByType(typeName)`, the right type of highlighter will be instantiated on the server-side and will be wrapped into a `CustomHighlighterActor` and that's what will be returned to the caller. This means that all types of highlighters share the same following API:
| Method | Description |
|------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

Просмотреть файл

@ -91,3 +91,8 @@ We don't just have 1 highlighter, we have a framework for highlighters:
- a (chrome-only) platform API to inject markup in a native-anonymous node in content (that works on all targets)
- a number of specific highlighter implementations (css transform, rect, selector, geometry, rulers, ...)
- a CustomHighlighterActor to get instances of specific highlighters
The entry point is toolbox-highlighter-utils.js:
- get it with toolbox.highlighterUtils
- use this to easily highlight any node in the page (with the usual box model highlighter),
- also use this to instantiate an other specific highlighter

Просмотреть файл

@ -15,7 +15,6 @@ class HighlighterFront extends FrontClassWithSpec(highlighterSpec) {
super(client, form);
this.isNodeFrontHighlighted = false;
this.isPicking = false;
}
// Update the object given a form representation off the wire.
@ -25,37 +24,13 @@ class HighlighterFront extends FrontClassWithSpec(highlighterSpec) {
this.traits = json.traits || {};
}
/**
* Start the element picker on the debuggee target.
* @param {Boolean} doFocus - Optionally focus the content area once the picker is
* activated.
* @return promise that resolves when the picker has started or immediately
* if it is already started
*/
pick(doFocus) {
if (this.isPicking) {
return null;
}
this.isPicking = true;
if (doFocus && super.pickAndFocus) {
return super.pickAndFocus();
}
return super.pick();
}
/**
* Stop the element picker.
* @return promise that resolves when the picker has stopped or immediately
* if it is already stopped
*/
cancelPick() {
if (!this.isPicking) {
return Promise.resolve();
}
this.isPicking = false;
return super.cancelPick();
}
/**
* Show the box model highlighter on a node in the content page.
* The node needs to be a NodeFront, as defined by the inspector actor

Просмотреть файл

@ -5,7 +5,6 @@
const Telemetry = require("devtools/client/shared/telemetry");
const telemetry = new Telemetry();
const { NodePicker } = require("devtools/shared/fronts/inspector/node-picker");
const TELEMETRY_EYEDROPPER_OPENED = "DEVTOOLS_EYEDROPPER_OPENED_COUNT";
const TELEMETRY_EYEDROPPER_OPENED_MENU = "DEVTOOLS_MENU_EYEDROPPER_OPENED_COUNT";
const SHOW_ALL_ANONYMOUS_CONTENT_PREF = "devtools.inspector.showAllAnonymousContent";
@ -458,7 +457,6 @@ class InspectorFront extends FrontClassWithSpec(inspectorSpec) {
]);
this.selection = new Selection(this.walker);
this.nodePicker = new NodePicker(this.highlighter, this.walker, this.selection);
}
async _getWalker() {
@ -501,17 +499,6 @@ class InspectorFront extends FrontClassWithSpec(inspectorSpec) {
}
}
async getHighlighterByType(typeName) {
let highlighter = null;
try {
highlighter = await super.getHighlighterByType(typeName);
} catch (_) {
throw new Error("The target doesn't support " +
`creating highlighters by types or ${typeName} is unknown`);
}
return highlighter;
}
getKnownHighlighter(type) {
return this._highlighters.get(type);
}

Просмотреть файл

@ -1,10 +0,0 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
DevToolsModules(
'node-picker.js',
)

Просмотреть файл

@ -1,142 +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";
loader.lazyRequireGetter(this, "EventEmitter", "devtools/shared/event-emitter");
/**
* Client-side NodePicker module.
* To be used by inspector front when it needs to select DOM elements.
*/
/**
* Get the NodePicker instance for an inspector front.
* The NodePicker wraps the highlighter so that it can interact with the
* walkerFront and selection api. The nodeFront is stateless, with the
* HighlighterFront managing it's own state.
*
* @param {highlighter} highlighterFront
* @param {walker} walkerFront
* @param {selection} selection api
* @return {Object} the NodePicker public API
*/
class NodePicker extends EventEmitter {
constructor(highlighter, walker, selection) {
super();
this.highlighter = highlighter;
this.walker = walker;
this.selection = selection;
this.cancel = this.cancel.bind(this);
this.start = this.start.bind(this);
this.stop = this.stop.bind(this);
this.togglePicker = this.togglePicker.bind(this);
this._onHovered = this._onHovered.bind(this);
this._onPicked = this._onPicked.bind(this);
this._onPreviewed = this._onPreviewed.bind(this);
this._onCanceled = this._onCanceled.bind(this);
}
/**
* Start/stop the element picker on the debuggee target.
* @param {Boolean} doFocus - Optionally focus the content area once the picker is
* activated.
* @return Promise that resolves when done
*/
togglePicker(doFocus) {
if (this.highlighter.isPicking) {
return this.stop();
}
return this.start(doFocus);
}
/**
* Start the element picker on the debuggee target.
* This will request the inspector actor to start listening for mouse events
* on the target page to highlight the hovered/picked element.
* Depending on the server-side capabilities, this may fire events when nodes
* are hovered.
* @param {Boolean} doFocus - Optionally focus the content area once the picker is
* activated.
* @return Promise that resolves when the picker has started or immediately
* if it is already started
*/
async start(doFocus) {
if (this.highlighter.isPicking) {
return null;
}
this.emit("picker-starting");
this.walker.on("picker-node-hovered", this._onHovered);
this.walker.on("picker-node-picked", this._onPicked);
this.walker.on("picker-node-previewed", this._onPreviewed);
this.walker.on("picker-node-canceled", this._onCanceled);
const picked = await this.highlighter.pick(doFocus);
this.emit("picker-started");
return picked;
}
/**
* Stop the element picker. Note that the picker is automatically stopped when
* an element is picked
* @return Promise that resolves when the picker has stopped or immediately
* if it is already stopped
*/
async stop() {
if (!this.highlighter.isPicking) {
return;
}
await this.highlighter.cancelPick();
this.walker.off("picker-node-hovered", this._onHovered);
this.walker.off("picker-node-picked", this._onPicked);
this.walker.off("picker-node-previewed", this._onPreviewed);
this.walker.off("picker-node-canceled", this._onCanceled);
this.emit("picker-stopped");
}
/**
* Stop the picker, but also emit an event that the picker was canceled.
*/
async cancel() {
await this.stop();
this.emit("picker-node-canceled");
}
/**
* When a node is hovered by the mouse when the highlighter is in picker mode
* @param {Object} data Information about the node being hovered
*/
_onHovered(data) {
this.emit("picker-node-hovered", data.node);
}
/**
* When a node has been picked while the highlighter is in picker mode
* @param {Object} data Information about the picked node
*/
_onPicked(data) {
this.selection.setNodeFront(data.node, { reason: "picker-node-picked" });
return this.stop();
}
/**
* When a node has been shift-clicked (previewed) while the highlighter is in
* picker mode
* @param {Object} data Information about the picked node
*/
_onPreviewed(data) {
this.selection.setNodeFront(data.node, { reason: "picker-node-previewed" });
}
/**
* When the picker is canceled, stop the picker, and make sure the toolbox
* gets the focus.
*/
_onCanceled() {
return this.cancel();
}
}
exports.NodePicker = NodePicker;

Просмотреть файл

@ -6,7 +6,6 @@
DIRS += [
'addon',
'inspector',
'targets',
]