mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
merge fx-team to mozilla-central a=merge
This commit is contained in:
commit
25c15869e1
@ -142,7 +142,7 @@ var AnimationsController = {
|
||||
this.onNewNodeFront = this.onNewNodeFront.bind(this);
|
||||
this.onAnimationMutations = this.onAnimationMutations.bind(this);
|
||||
|
||||
let target = gToolbox.target;
|
||||
let target = gInspector.target;
|
||||
this.animationsFront = new AnimationsFront(target.client, target.form);
|
||||
|
||||
// Expose actor capabilities.
|
||||
|
@ -9,7 +9,7 @@ const osString = Services.appinfo.OS;
|
||||
|
||||
// Panels
|
||||
loader.lazyGetter(this, "OptionsPanel", () => require("devtools/client/framework/toolbox-options").OptionsPanel);
|
||||
loader.lazyGetter(this, "InspectorPanel", () => require("devtools/client/inspector/inspector-panel").InspectorPanel);
|
||||
loader.lazyGetter(this, "InspectorPanel", () => require("devtools/client/inspector/panel").InspectorPanel);
|
||||
loader.lazyGetter(this, "WebConsolePanel", () => require("devtools/client/webconsole/panel").WebConsolePanel);
|
||||
loader.lazyGetter(this, "DebuggerPanel", () => require("devtools/client/debugger/panel").DebuggerPanel);
|
||||
loader.lazyGetter(this, "StyleEditorPanel", () => require("devtools/client/styleeditor/styleeditor-panel").StyleEditorPanel);
|
||||
|
@ -7,7 +7,7 @@ const URL = "data:text/html;charset=utf8,test for textbox context menu";
|
||||
|
||||
add_task(function* () {
|
||||
let toolbox = yield openNewTabAndToolbox(URL, "inspector");
|
||||
let textboxContextMenu = toolbox.textboxContextMenuPopup;
|
||||
let textboxContextMenu = toolbox.textBoxContextMenuPopup;
|
||||
|
||||
emptyClipboard();
|
||||
|
||||
|
@ -137,7 +137,7 @@ function Toolbox(target, selectedTool, hostType, hostOptions) {
|
||||
this._saveSplitConsoleHeight = this._saveSplitConsoleHeight.bind(this);
|
||||
this._onFocus = this._onFocus.bind(this);
|
||||
this._showDevEditionPromo = this._showDevEditionPromo.bind(this);
|
||||
this._updateTextboxMenuItems = this._updateTextboxMenuItems.bind(this);
|
||||
this._updateTextBoxMenuItems = this._updateTextBoxMenuItems.bind(this);
|
||||
this._onBottomHostMinimized = this._onBottomHostMinimized.bind(this);
|
||||
this._onBottomHostMaximized = this._onBottomHostMaximized.bind(this);
|
||||
this._onToolSelectWhileMinimized = this._onToolSelectWhileMinimized.bind(this);
|
||||
@ -402,10 +402,10 @@ Toolbox.prototype = {
|
||||
let noautohideMenu = this.doc.getElementById("command-button-noautohide");
|
||||
noautohideMenu.addEventListener("click", this._toggleAutohide, true);
|
||||
|
||||
this.textboxContextMenuPopup =
|
||||
this.textBoxContextMenuPopup =
|
||||
this.doc.getElementById("toolbox-textbox-context-popup");
|
||||
this.textboxContextMenuPopup.addEventListener("popupshowing",
|
||||
this._updateTextboxMenuItems, true);
|
||||
this.textBoxContextMenuPopup.addEventListener("popupshowing",
|
||||
this._updateTextBoxMenuItems, true);
|
||||
|
||||
this.shortcuts = new KeyShortcuts({
|
||||
window: this.doc.defaultView
|
||||
@ -2096,10 +2096,10 @@ Toolbox.prototype = {
|
||||
this.closeButton.removeEventListener("click", this.destroy, true);
|
||||
this.closeButton = null;
|
||||
}
|
||||
if (this.textboxContextMenuPopup) {
|
||||
this.textboxContextMenuPopup.removeEventListener("popupshowing",
|
||||
this._updateTextboxMenuItems, true);
|
||||
this.textboxContextMenuPopup = null;
|
||||
if (this.textBoxContextMenuPopup) {
|
||||
this.textBoxContextMenuPopup.removeEventListener("popupshowing",
|
||||
this._updateTextBoxMenuItems, true);
|
||||
this.textBoxContextMenuPopup = null;
|
||||
}
|
||||
if (this.tabbar) {
|
||||
this.tabbar.removeEventListener("focus", this._onTabbarFocus, true);
|
||||
@ -2235,12 +2235,23 @@ Toolbox.prototype = {
|
||||
/**
|
||||
* Enable / disable necessary textbox menu items using globalOverlay.js.
|
||||
*/
|
||||
_updateTextboxMenuItems: function () {
|
||||
_updateTextBoxMenuItems: function () {
|
||||
let window = this.win;
|
||||
["cmd_undo", "cmd_delete", "cmd_cut",
|
||||
"cmd_copy", "cmd_paste", "cmd_selectAll"].forEach(window.goUpdateCommand);
|
||||
},
|
||||
|
||||
/**
|
||||
* Open the textbox context menu at given coordinates.
|
||||
* Panels in the toolbox can call this on contextmenu events with event.screenX/Y
|
||||
* instead of having to implement their own copy/paste/selectAll menu.
|
||||
* @param {Number} x
|
||||
* @param {Number} y
|
||||
*/
|
||||
openTextBoxContextMenu: function (x, y) {
|
||||
this.textBoxContextMenuPopup.openPopupAtScreen(x, y, true);
|
||||
},
|
||||
|
||||
/**
|
||||
* Connects to the SPS profiler when the developer tools are open. This is
|
||||
* necessary because of the WebConsole's `profile` and `profileEnd` methods.
|
||||
|
@ -341,10 +341,10 @@ BoxModelView.prototype = {
|
||||
*/
|
||||
trackReflows: function () {
|
||||
if (!this.reflowFront) {
|
||||
let toolbox = this.inspector.toolbox;
|
||||
if (toolbox.target.form.reflowActor) {
|
||||
this.reflowFront = ReflowFront(toolbox.target.client,
|
||||
toolbox.target.form);
|
||||
let { target } = this.inspector;
|
||||
if (target.form.reflowActor) {
|
||||
this.reflowFront = ReflowFront(target.client,
|
||||
target.form);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
@ -384,7 +384,6 @@ BoxModelView.prototype = {
|
||||
start: self => {
|
||||
self.elt.parentNode.classList.add("boxmodel-editing");
|
||||
},
|
||||
|
||||
change: value => {
|
||||
if (NUMERIC.test(value)) {
|
||||
value += "px";
|
||||
@ -404,7 +403,6 @@ BoxModelView.prototype = {
|
||||
|
||||
session.setProperties(properties).catch(e => console.error(e));
|
||||
},
|
||||
|
||||
done: (value, commit) => {
|
||||
editor.elt.parentNode.classList.remove("boxmodel-editing");
|
||||
if (!commit) {
|
||||
@ -413,6 +411,7 @@ BoxModelView.prototype = {
|
||||
}, e => console.error(e));
|
||||
}
|
||||
},
|
||||
contextMenu: this.inspector.onTextBoxContextMenu,
|
||||
cssProperties: this._cssProperties
|
||||
}, event);
|
||||
},
|
||||
@ -468,7 +467,7 @@ BoxModelView.prototype = {
|
||||
this.inspector.sidebar.off("computedview-selected", this.onNewNode);
|
||||
this.inspector.selection.off("new-node-front", this.onNewSelection);
|
||||
this.inspector.sidebar.off("select", this.onSidebarSelect);
|
||||
this.inspector._target.off("will-navigate", this.onWillNavigate);
|
||||
this.inspector.target.off("will-navigate", this.onWillNavigate);
|
||||
this.inspector.off("computed-view-filtered", this.onFilterComputedView);
|
||||
|
||||
this.inspector = null;
|
||||
@ -792,7 +791,7 @@ BoxModelView.prototype = {
|
||||
this.inspector.markup.on("node-hover", this.onMarkupViewNodeHover);
|
||||
|
||||
// Release the actor on will-navigate event
|
||||
this.inspector._target.once("will-navigate", this.onWillNavigate);
|
||||
this.inspector.target.once("will-navigate", this.onWillNavigate);
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -148,8 +148,6 @@ function CssComputedView(inspector, document, pageStyle) {
|
||||
this._onFilterStyles = this._onFilterStyles.bind(this);
|
||||
this._onClearSearch = this._onClearSearch.bind(this);
|
||||
this._onIncludeBrowserStyles = this._onIncludeBrowserStyles.bind(this);
|
||||
this._onFilterTextboxContextMenu =
|
||||
this._onFilterTextboxContextMenu.bind(this);
|
||||
|
||||
let doc = this.styleDocument;
|
||||
this.element = doc.getElementById("propertyContainer");
|
||||
@ -167,8 +165,7 @@ function CssComputedView(inspector, document, pageStyle) {
|
||||
this.element.addEventListener("copy", this._onCopy);
|
||||
this.element.addEventListener("contextmenu", this._onContextMenu);
|
||||
this.searchField.addEventListener("input", this._onFilterStyles);
|
||||
this.searchField.addEventListener("contextmenu",
|
||||
this._onFilterTextboxContextMenu);
|
||||
this.searchField.addEventListener("contextmenu", this.inspector.onTextBoxContextMenu);
|
||||
this.searchClearButton.addEventListener("click", this._onClearSearch);
|
||||
this.includeBrowserStylesCheckbox.addEventListener("input",
|
||||
this._onIncludeBrowserStyles);
|
||||
@ -546,19 +543,6 @@ CssComputedView.prototype = {
|
||||
}, filterTimeout);
|
||||
},
|
||||
|
||||
/**
|
||||
* Context menu handler for filter style search box.
|
||||
*/
|
||||
_onFilterTextboxContextMenu: function (event) {
|
||||
try {
|
||||
this.styleDocument.defaultView.focus();
|
||||
let contextmenu = this.inspector.toolbox.textboxContextMenuPopup;
|
||||
contextmenu.openPopupAtScreen(event.screenX, event.screenY, true);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when the user clicks on the clear button in the filter style search
|
||||
* box. Returns true if the search box is cleared and false otherwise.
|
||||
@ -654,8 +638,7 @@ CssComputedView.prototype = {
|
||||
* Focus the window on mousedown.
|
||||
*/
|
||||
focusWindow: function () {
|
||||
let win = this.styleDocument.defaultView;
|
||||
win.focus();
|
||||
this.styleWindow.focus();
|
||||
},
|
||||
|
||||
/**
|
||||
@ -692,7 +675,7 @@ CssComputedView.prototype = {
|
||||
*/
|
||||
copySelection: function () {
|
||||
try {
|
||||
let win = this.styleDocument.defaultView;
|
||||
let win = this.styleWindow;
|
||||
let text = win.getSelection().toString().trim();
|
||||
|
||||
// Tidy up block headings by moving CSS property names and their
|
||||
@ -758,7 +741,7 @@ CssComputedView.prototype = {
|
||||
this.element.removeEventListener("contextmenu", this._onContextMenu);
|
||||
this.searchField.removeEventListener("input", this._onFilterStyles);
|
||||
this.searchField.removeEventListener("contextmenu",
|
||||
this._onFilterTextboxContextMenu);
|
||||
this.inspector.onTextBoxContextMenu);
|
||||
this.searchClearButton.removeEventListener("click", this._onClearSearch);
|
||||
this.includeBrowserStylesCheckbox.removeEventListener("input",
|
||||
this._onIncludeBrowserStyles);
|
||||
|
@ -17,7 +17,7 @@ add_task(function* () {
|
||||
|
||||
let win = view.styleWindow;
|
||||
let searchField = view.searchField;
|
||||
let searchContextMenu = toolbox.textboxContextMenuPopup;
|
||||
let searchContextMenu = toolbox.textBoxContextMenuPopup;
|
||||
ok(searchContextMenu,
|
||||
"The search filter context menu is loaded in the computed view");
|
||||
|
||||
|
@ -32,9 +32,10 @@ FontInspector.prototype = {
|
||||
this.showAllLink = this.chromeDoc.getElementById("font-showall");
|
||||
this.showAllLink.addEventListener("click", this.showAll);
|
||||
this.previewTextChanged = this.previewTextChanged.bind(this);
|
||||
this.previewInput =
|
||||
this.chromeDoc.getElementById("font-preview-text-input");
|
||||
this.previewInput = this.chromeDoc.getElementById("font-preview-text-input");
|
||||
this.previewInput.addEventListener("input", this.previewTextChanged);
|
||||
this.previewInput.addEventListener("contextmenu",
|
||||
this.inspector.onTextBoxContextMenu);
|
||||
|
||||
// Listen for theme changes as the color of the previews depend on the theme
|
||||
gDevTools.on("theme-switched", this.onThemeChanged);
|
||||
@ -59,6 +60,8 @@ FontInspector.prototype = {
|
||||
this.inspector.selection.off("new-node-front", this.onNewNode);
|
||||
this.showAllLink.removeEventListener("click", this.showAll);
|
||||
this.previewInput.removeEventListener("input", this.previewTextChanged);
|
||||
this.previewInput.removeEventListener("contextmenu",
|
||||
this.inspector.onTextBoxContextMenu);
|
||||
|
||||
gDevTools.off("theme-switched", this.onThemeChanged);
|
||||
|
||||
|
@ -42,12 +42,9 @@ function InspectorSearch(inspector, input, clearBtn) {
|
||||
this._onKeyDown = this._onKeyDown.bind(this);
|
||||
this._onInput = this._onInput.bind(this);
|
||||
this._onClearSearch = this._onClearSearch.bind(this);
|
||||
this._onFilterTextboxContextMenu =
|
||||
this._onFilterTextboxContextMenu.bind(this);
|
||||
this.searchBox.addEventListener("keydown", this._onKeyDown, true);
|
||||
this.searchBox.addEventListener("input", this._onInput, true);
|
||||
this.searchBox.addEventListener("contextmenu",
|
||||
this._onFilterTextboxContextMenu);
|
||||
this.searchBox.addEventListener("contextmenu", this.inspector.onTextBoxContextMenu);
|
||||
this.searchClearButton.addEventListener("click", this._onClearSearch);
|
||||
|
||||
// For testing, we need to be able to wait for the most recent node request
|
||||
@ -69,7 +66,7 @@ InspectorSearch.prototype = {
|
||||
this.searchBox.removeEventListener("keydown", this._onKeyDown, true);
|
||||
this.searchBox.removeEventListener("input", this._onInput, true);
|
||||
this.searchBox.removeEventListener("contextmenu",
|
||||
this._onFilterTextboxContextMenu);
|
||||
this.inspector.onTextBoxContextMenu);
|
||||
this.searchClearButton.removeEventListener("click", this._onClearSearch);
|
||||
this.searchBox = null;
|
||||
this.searchClearButton = null;
|
||||
@ -136,18 +133,6 @@ InspectorSearch.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Context menu handler for filter search box.
|
||||
*/
|
||||
_onFilterTextboxContextMenu: function (event) {
|
||||
try {
|
||||
let contextmenu = this.inspector.toolbox.textboxContextMenuPopup;
|
||||
contextmenu.openPopupAtScreen(event.screenX, event.screenY, true);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
},
|
||||
|
||||
_onClearSearch: function () {
|
||||
this.searchBox.classList.remove("devtools-style-searchbox-no-match");
|
||||
this.searchBox.value = "";
|
||||
|
@ -4,8 +4,12 @@
|
||||
* 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/. */
|
||||
|
||||
/* global window */
|
||||
|
||||
"use strict";
|
||||
|
||||
var Cu = Components.utils;
|
||||
var { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
var Services = require("Services");
|
||||
var promise = require("promise");
|
||||
var defer = require("devtools/shared/defer");
|
||||
@ -81,11 +85,11 @@ const PORTRAIT_MODE_WIDTH = 700;
|
||||
* Fired when the stylesheet source links have been updated (when switching
|
||||
* to source-mapped files)
|
||||
*/
|
||||
function InspectorPanel(iframeWindow, toolbox) {
|
||||
function Inspector(toolbox) {
|
||||
this._toolbox = toolbox;
|
||||
this._target = toolbox.target;
|
||||
this.panelDoc = iframeWindow.document;
|
||||
this.panelWin = iframeWindow;
|
||||
this.panelDoc = window.document;
|
||||
this.panelWin = window;
|
||||
this.panelWin.inspector = this;
|
||||
|
||||
this.telemetry = new Telemetry();
|
||||
@ -96,6 +100,7 @@ function InspectorPanel(iframeWindow, toolbox) {
|
||||
this._onBeforeNavigate = this._onBeforeNavigate.bind(this);
|
||||
this.onNewRoot = this.onNewRoot.bind(this);
|
||||
this._onContextMenu = this._onContextMenu.bind(this);
|
||||
this.onTextBoxContextMenu = this.onTextBoxContextMenu.bind(this);
|
||||
this._updateSearchResultsLabel = this._updateSearchResultsLabel.bind(this);
|
||||
this.onNewSelection = this.onNewSelection.bind(this);
|
||||
this.onBeforeNewSelection = this.onBeforeNewSelection.bind(this);
|
||||
@ -112,13 +117,11 @@ function InspectorPanel(iframeWindow, toolbox) {
|
||||
EventEmitter.decorate(this);
|
||||
}
|
||||
|
||||
exports.InspectorPanel = InspectorPanel;
|
||||
|
||||
InspectorPanel.prototype = {
|
||||
Inspector.prototype = {
|
||||
/**
|
||||
* open is effectively an asynchronous constructor
|
||||
*/
|
||||
open: Task.async(function* () {
|
||||
init: Task.async(function* () {
|
||||
// Localize all the nodes containing a data-localization attribute.
|
||||
localizeMarkup(this.panelDoc);
|
||||
|
||||
@ -146,6 +149,10 @@ InspectorPanel.prototype = {
|
||||
return this._toolbox.selection;
|
||||
},
|
||||
|
||||
get highlighter() {
|
||||
return this._toolbox.highlighter;
|
||||
},
|
||||
|
||||
get isOuterHTMLEditable() {
|
||||
return this._target.client.traits.editOuterHTML;
|
||||
},
|
||||
@ -275,7 +282,7 @@ InspectorPanel.prototype = {
|
||||
},
|
||||
|
||||
_getPageStyle: function () {
|
||||
return this._toolbox.inspector.getPageStyle().then(pageStyle => {
|
||||
return this.inspector.getPageStyle().then(pageStyle => {
|
||||
this.pageStyle = pageStyle;
|
||||
}, this._handleRejectionIfNotDestroyed);
|
||||
},
|
||||
@ -441,8 +448,6 @@ InspectorPanel.prototype = {
|
||||
let SplitBox = this.React.createFactory(this.browserRequire(
|
||||
"devtools/client/shared/components/splitter/split-box"));
|
||||
|
||||
this.panelWin.addEventListener("resize", this.onPanelWindowResize, true);
|
||||
|
||||
let splitter = SplitBox({
|
||||
className: "inspector-sidebar-splitter",
|
||||
initialWidth: INITIAL_SIDEBAR_SIZE,
|
||||
@ -462,6 +467,8 @@ InspectorPanel.prototype = {
|
||||
this._splitter = this.ReactDOM.render(splitter,
|
||||
this.panelDoc.getElementById("inspector-splitter-box"));
|
||||
|
||||
this.panelWin.addEventListener("resize", this.onPanelWindowResize, true);
|
||||
|
||||
// Persist splitter state in preferences.
|
||||
this.sidebar.on("show", this.onSidebarShown);
|
||||
this.sidebar.on("hide", this.onSidebarHidden);
|
||||
@ -602,7 +609,7 @@ InspectorPanel.prototype = {
|
||||
|
||||
// Setup the eye-dropper icon if we're in an HTML document and we have actor support.
|
||||
if (this.selection.nodeFront && this.selection.nodeFront.isInHTMLDocument) {
|
||||
this.toolbox.target.actorHasMethod("inspector", "pickColorFromPage").then(value => {
|
||||
this.target.actorHasMethod("inspector", "pickColorFromPage").then(value => {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
@ -926,6 +933,17 @@ InspectorPanel.prototype = {
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* This is meant to be called by all the search, filter, inplace text boxes in the
|
||||
* inspector, and just calls through to the toolbox openTextBoxContextMenu helper.
|
||||
* @param {DOMEvent} e
|
||||
*/
|
||||
onTextBoxContextMenu: function (e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
this.toolbox.openTextBoxContextMenu(e.screenX, e.screenY);
|
||||
},
|
||||
|
||||
_openMenu: function ({ target, screenX = 0, screenY = 0 } = { }) {
|
||||
let markupContainer = this.markup.getContainer(this.selection.nodeFront);
|
||||
|
||||
@ -1273,7 +1291,7 @@ InspectorPanel.prototype = {
|
||||
this._markupFrame = doc.createElement("iframe");
|
||||
this._markupFrame.setAttribute("flex", "1");
|
||||
this._markupFrame.setAttribute("tooltip", "aHTMLTooltip");
|
||||
this._markupFrame.addEventListener("contextmenu", this._onContextMenu, true);
|
||||
this._markupFrame.addEventListener("contextmenu", this._onContextMenu);
|
||||
|
||||
// This is needed to enable tooltips inside the iframe document.
|
||||
this._markupFrame.addEventListener("load", this._onMarkupFrameLoad, true);
|
||||
@ -1302,7 +1320,7 @@ InspectorPanel.prototype = {
|
||||
|
||||
if (this._markupFrame) {
|
||||
this._markupFrame.removeEventListener("load", this._onMarkupFrameLoad, true);
|
||||
this._markupFrame.removeEventListener("contextmenu", this._onContextMenu, true);
|
||||
this._markupFrame.removeEventListener("contextmenu", this._onContextMenu);
|
||||
}
|
||||
|
||||
if (this.markup) {
|
||||
@ -1816,3 +1834,90 @@ InspectorPanel.prototype = {
|
||||
}, console.error);
|
||||
}
|
||||
};
|
||||
|
||||
// URL constructor doesn't support chrome: scheme
|
||||
let href = window.location.href.replace(/chrome:/, "http://");
|
||||
let url = new window.URL(href);
|
||||
|
||||
// Only use this method to attach the toolbox if some query parameters are given
|
||||
if (url.search.length > 1) {
|
||||
const { targetFromURL } = require("devtools/client/framework/target-from-url");
|
||||
const { attachThread } = require("devtools/client/framework/attach-thread");
|
||||
const { BrowserLoader } =
|
||||
Cu.import("resource://devtools/client/shared/browser-loader.js", {});
|
||||
|
||||
const { Selection } = require("devtools/client/framework/selection");
|
||||
const { InspectorFront } = require("devtools/shared/fronts/inspector");
|
||||
const { getHighlighterUtils } = require("devtools/client/framework/toolbox-highlighter-utils");
|
||||
|
||||
Task.spawn(function* () {
|
||||
let target = yield targetFromURL(url);
|
||||
|
||||
let notImplemented = function () {
|
||||
throw new Error("Not implemented in a tab");
|
||||
};
|
||||
let fakeToolbox = {
|
||||
target,
|
||||
hostType: "bottom",
|
||||
doc: window.document,
|
||||
win: window,
|
||||
on() {}, emit() {}, off() {},
|
||||
initInspector() {},
|
||||
browserRequire: BrowserLoader({
|
||||
window: window,
|
||||
useOnlyShared: true
|
||||
}).require,
|
||||
get React() {
|
||||
return this.browserRequire("devtools/client/shared/vendor/react");
|
||||
},
|
||||
get ReactDOM() {
|
||||
return this.browserRequire("devtools/client/shared/vendor/react-dom");
|
||||
},
|
||||
isToolRegistered() {
|
||||
return false;
|
||||
},
|
||||
currentToolId: "inspector",
|
||||
getCurrentPanel() {
|
||||
return "inspector";
|
||||
},
|
||||
get textboxContextMenuPopup() {
|
||||
notImplemented();
|
||||
},
|
||||
getPanel: notImplemented,
|
||||
openSplitConsole: notImplemented,
|
||||
viewCssSourceInStyleEditor: notImplemented,
|
||||
viewJsSourceInDebugger: notImplemented,
|
||||
viewSource: notImplemented,
|
||||
viewSourceInDebugger: notImplemented,
|
||||
viewSourceInStyleEditor: notImplemented,
|
||||
|
||||
// For attachThread:
|
||||
highlightTool() {},
|
||||
unhighlightTool() {},
|
||||
selectTool() {},
|
||||
raise() {},
|
||||
getNotificationBox() {}
|
||||
};
|
||||
|
||||
// attachThread also expect a toolbox as argument
|
||||
fakeToolbox.threadClient = yield attachThread(fakeToolbox);
|
||||
|
||||
let inspector = InspectorFront(target.client, target.form);
|
||||
let showAllAnonymousContent =
|
||||
Services.prefs.getBoolPref("devtools.inspector.showAllAnonymousContent");
|
||||
let walker = yield inspector.getWalker({ showAllAnonymousContent });
|
||||
let selection = new Selection(walker);
|
||||
let highlighter = yield inspector.getHighlighter(false);
|
||||
|
||||
fakeToolbox.inspector = inspector;
|
||||
fakeToolbox.walker = walker;
|
||||
fakeToolbox.selection = selection;
|
||||
fakeToolbox.highlighter = highlighter;
|
||||
fakeToolbox.highlighterUtils = getHighlighterUtils(fakeToolbox);
|
||||
|
||||
let inspectorUI = new Inspector(fakeToolbox);
|
||||
inspectorUI.init();
|
||||
}).then(null, e => {
|
||||
window.alert("Unable to start the inspector:" + e.message + "\n" + e.stack);
|
||||
});
|
||||
}
|
@ -25,6 +25,7 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<script type="application/javascript;version=1.8"
|
||||
src="chrome://devtools/content/shared/theme-switching.js"></script>
|
||||
<script type="application/javascript;version=1.8" src="inspector.js" defer="true"></script>
|
||||
</head>
|
||||
<body class="theme-body" role="application">
|
||||
<div class="inspector-responsive-container theme-body inspector">
|
||||
|
@ -84,8 +84,8 @@ const INSPECTOR_L10N = new LocalizationHelper("devtools/locale/inspector.propert
|
||||
* An iframe in which the caller has kindly loaded markup.xhtml.
|
||||
*/
|
||||
function MarkupView(inspector, frame, controllerWindow) {
|
||||
this._inspector = inspector;
|
||||
this.walker = this._inspector.walker;
|
||||
this.inspector = inspector;
|
||||
this.walker = this.inspector.walker;
|
||||
this._frame = frame;
|
||||
this.win = this._frame.contentWindow;
|
||||
this.doc = this._frame.contentDocument;
|
||||
@ -109,7 +109,7 @@ function MarkupView(inspector, frame, controllerWindow) {
|
||||
theme: "auto",
|
||||
};
|
||||
|
||||
this.popup = new AutocompletePopup(inspector._toolbox, options);
|
||||
this.popup = new AutocompletePopup(inspector.toolbox, options);
|
||||
|
||||
this.undo = new UndoStack();
|
||||
this.undo.installController(controllerWindow);
|
||||
@ -145,8 +145,8 @@ function MarkupView(inspector, frame, controllerWindow) {
|
||||
this._frame.addEventListener("focus", this._onFocus, false);
|
||||
this.walker.on("mutations", this._mutationObserver);
|
||||
this.walker.on("display-change", this._onDisplayChange);
|
||||
this._inspector.selection.on("new-node-front", this._onNewSelection);
|
||||
this._inspector.toolbox.on("picker-node-hovered", this._onToolboxPickerHover);
|
||||
this.inspector.selection.on("new-node-front", this._onNewSelection);
|
||||
this.toolbox.on("picker-node-hovered", this._onToolboxPickerHover);
|
||||
|
||||
this._onNewSelection();
|
||||
this._initTooltips();
|
||||
@ -168,6 +168,10 @@ MarkupView.prototype = {
|
||||
|
||||
_selectedContainer: null,
|
||||
|
||||
get toolbox() {
|
||||
return this.inspector.toolbox;
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle promise rejections for various asynchronous actions, and only log errors if
|
||||
* the markup view still exists.
|
||||
@ -181,9 +185,9 @@ MarkupView.prototype = {
|
||||
},
|
||||
|
||||
_initTooltips: function () {
|
||||
this.eventDetailsTooltip = new HTMLTooltip(this._inspector.toolbox,
|
||||
this.eventDetailsTooltip = new HTMLTooltip(this.toolbox,
|
||||
{type: "arrow"});
|
||||
this.imagePreviewTooltip = new HTMLTooltip(this._inspector.toolbox,
|
||||
this.imagePreviewTooltip = new HTMLTooltip(this.toolbox,
|
||||
{type: "arrow", useXulWrapper: "true"});
|
||||
this._enableImagePreviewTooltip();
|
||||
},
|
||||
@ -423,8 +427,7 @@ MarkupView.prototype = {
|
||||
* requests queued up
|
||||
*/
|
||||
_showBoxModel: function (nodeFront) {
|
||||
return this._inspector.toolbox.highlighterUtils
|
||||
.highlightNodeFront(nodeFront);
|
||||
return this.toolbox.highlighterUtils.highlightNodeFront(nodeFront);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -437,7 +440,7 @@ MarkupView.prototype = {
|
||||
* requests queued up
|
||||
*/
|
||||
_hideBoxModel: function (forceHide) {
|
||||
return this._inspector.toolbox.highlighterUtils.unhighlight(forceHide);
|
||||
return this.toolbox.highlighterUtils.unhighlight(forceHide);
|
||||
},
|
||||
|
||||
_briefBoxModelTimer: null,
|
||||
@ -551,14 +554,14 @@ MarkupView.prototype = {
|
||||
* highlighted.
|
||||
*/
|
||||
_shouldNewSelectionBeHighlighted: function () {
|
||||
let reason = this._inspector.selection.reason;
|
||||
let reason = this.inspector.selection.reason;
|
||||
let unwantedReasons = [
|
||||
"inspector-open",
|
||||
"navigateaway",
|
||||
"nodeselected",
|
||||
"test"
|
||||
];
|
||||
let isHighlight = this._hoveredNode === this._inspector.selection.nodeFront;
|
||||
let isHighlight = this._hoveredNode === this.inspector.selection.nodeFront;
|
||||
return !isHighlight && reason && unwantedReasons.indexOf(reason) === -1;
|
||||
},
|
||||
|
||||
@ -568,7 +571,7 @@ MarkupView.prototype = {
|
||||
* the view.
|
||||
*/
|
||||
_onNewSelection: function () {
|
||||
let selection = this._inspector.selection;
|
||||
let selection = this.inspector.selection;
|
||||
|
||||
this.htmlEditor.hide();
|
||||
if (this._hoveredNode && this._hoveredNode !== selection.nodeFront) {
|
||||
@ -581,7 +584,7 @@ MarkupView.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
let done = this._inspector.updating("markup-view");
|
||||
let done = this.inspector.updating("markup-view");
|
||||
let onShowBoxModel, onShow;
|
||||
|
||||
// Highlight the element briefly if needed.
|
||||
@ -611,7 +614,7 @@ MarkupView.prototype = {
|
||||
* on why the current node got selected.
|
||||
*/
|
||||
maybeNavigateToNewSelection: function () {
|
||||
let {reason, nodeFront} = this._inspector.selection;
|
||||
let {reason, nodeFront} = this.inspector.selection;
|
||||
|
||||
// The list of reasons that should lead to navigating to the node.
|
||||
let reasonsToNavigate = [
|
||||
@ -656,9 +659,9 @@ MarkupView.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
let selection = this._inspector.selection;
|
||||
let selection = this.inspector.selection;
|
||||
if (selection.isNode()) {
|
||||
this._inspector.copyOuterHTML();
|
||||
this.inspector.copyOuterHTML();
|
||||
}
|
||||
evt.stopPropagation();
|
||||
evt.preventDefault();
|
||||
@ -713,7 +716,7 @@ MarkupView.prototype = {
|
||||
}
|
||||
case "markupView.scrollInto.key": {
|
||||
let selection = this._selectedContainer.node;
|
||||
this._inspector.scrollNodeIntoView(selection);
|
||||
this.inspector.scrollNodeIntoView(selection);
|
||||
break;
|
||||
}
|
||||
// Generic keys
|
||||
@ -965,12 +968,12 @@ MarkupView.prototype = {
|
||||
this._elt.appendChild(container.elt);
|
||||
this._rootNode = node;
|
||||
} else if (nodeType == nodeConstants.ELEMENT_NODE && !isPseudoElement) {
|
||||
container = new MarkupElementContainer(this, node, this._inspector);
|
||||
container = new MarkupElementContainer(this, node, this.inspector);
|
||||
} else if (nodeType == nodeConstants.COMMENT_NODE ||
|
||||
nodeType == nodeConstants.TEXT_NODE) {
|
||||
container = new MarkupTextContainer(this, node, this._inspector);
|
||||
container = new MarkupTextContainer(this, node, this.inspector);
|
||||
} else {
|
||||
container = new MarkupReadOnlyContainer(this, node, this._inspector);
|
||||
container = new MarkupReadOnlyContainer(this, node, this.inspector);
|
||||
}
|
||||
|
||||
if (flashNode) {
|
||||
@ -982,7 +985,7 @@ MarkupView.prototype = {
|
||||
|
||||
this._updateChildren(container);
|
||||
|
||||
this._inspector.emit("container-created", container);
|
||||
this.inspector.emit("container-created", container);
|
||||
|
||||
return container;
|
||||
},
|
||||
@ -1039,7 +1042,7 @@ MarkupView.prototype = {
|
||||
return;
|
||||
}
|
||||
this._flashMutatedNodes(mutations);
|
||||
this._inspector.emit("markupmutation", mutations);
|
||||
this.inspector.emit("markupmutation", mutations);
|
||||
|
||||
// Since the htmlEditor is absolutely positioned, a mutation may change
|
||||
// the location in which it should be shown.
|
||||
@ -1277,13 +1280,13 @@ MarkupView.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
this._inspector.off("markupmutation", onMutations);
|
||||
this.inspector.off("markupmutation", onMutations);
|
||||
this._removedNodeObserver = null;
|
||||
|
||||
// Don't select the new node if the user has already changed the current
|
||||
// selection.
|
||||
if (this._inspector.selection.nodeFront === parentContainer.node ||
|
||||
(this._inspector.selection.nodeFront === removedNode && isHTMLTag)) {
|
||||
if (this.inspector.selection.nodeFront === parentContainer.node ||
|
||||
(this.inspector.selection.nodeFront === removedNode && isHTMLTag)) {
|
||||
let childContainers = parentContainer.getChildContainers();
|
||||
if (childContainers && childContainers[childIndex]) {
|
||||
this.markNodeAsSelected(childContainers[childIndex].node, reason);
|
||||
@ -1297,7 +1300,7 @@ MarkupView.prototype = {
|
||||
|
||||
// Start listening for mutations until we find a childList change that has
|
||||
// removedNode removed.
|
||||
this._inspector.on("markupmutation", onMutations);
|
||||
this.inspector.on("markupmutation", onMutations);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1307,7 +1310,7 @@ MarkupView.prototype = {
|
||||
*/
|
||||
cancelReselectOnRemoved: function () {
|
||||
if (this._removedNodeObserver) {
|
||||
this._inspector.off("markupmutation", this._removedNodeObserver);
|
||||
this.inspector.off("markupmutation", this._removedNodeObserver);
|
||||
this._removedNodeObserver = null;
|
||||
this.emit("canceledreselectonremoved");
|
||||
}
|
||||
@ -1479,8 +1482,8 @@ MarkupView.prototype = {
|
||||
}
|
||||
|
||||
// Change the current selection if needed.
|
||||
if (this._inspector.selection.nodeFront !== node) {
|
||||
this._inspector.selection.setNodeFront(node, reason || "nodeselected");
|
||||
if (this.inspector.selection.nodeFront !== node) {
|
||||
this.inspector.selection.setNodeFront(node, reason || "nodeselected");
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1526,7 +1529,7 @@ MarkupView.prototype = {
|
||||
*/
|
||||
_checkSelectionVisible: function (container) {
|
||||
let centered = null;
|
||||
let node = this._inspector.selection.nodeFront;
|
||||
let node = this.inspector.selection.nodeFront;
|
||||
while (node) {
|
||||
if (node.parentNode() === container.node) {
|
||||
centered = node;
|
||||
@ -1741,8 +1744,8 @@ MarkupView.prototype = {
|
||||
this._frame.removeEventListener("focus", this._onFocus, false);
|
||||
this.walker.off("mutations", this._mutationObserver);
|
||||
this.walker.off("display-change", this._onDisplayChange);
|
||||
this._inspector.selection.off("new-node-front", this._onNewSelection);
|
||||
this._inspector.toolbox.off("picker-node-hovered",
|
||||
this.inspector.selection.off("new-node-front", this._onNewSelection);
|
||||
this.toolbox.off("picker-node-hovered",
|
||||
this._onToolboxPickerHover);
|
||||
|
||||
this._prefObserver.off(ATTR_COLLAPSE_ENABLED_PREF,
|
||||
@ -2338,7 +2341,7 @@ MarkupContainer.prototype = {
|
||||
let type = target.dataset.type;
|
||||
// Make container tabbable descendants not tabbable (by default).
|
||||
this.canFocus = false;
|
||||
this.markup._inspector.followAttributeLink(type, link);
|
||||
this.markup.inspector.followAttributeLink(type, link);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2646,7 +2649,7 @@ MarkupElementContainer.prototype = Heritage.extend(MarkupContainer.prototype, {
|
||||
|
||||
let listenerInfo = yield this.node.getEventListenerInfo();
|
||||
|
||||
let toolbox = this.markup._inspector.toolbox;
|
||||
let toolbox = this.markup.toolbox;
|
||||
setEventTooltip(tooltip, listenerInfo, toolbox);
|
||||
// Disable the image preview tooltip while we display the event details
|
||||
this.markup._disableImagePreviewTooltip();
|
||||
@ -2912,7 +2915,8 @@ function TextEditor(container, node, templateId) {
|
||||
});
|
||||
});
|
||||
},
|
||||
cssProperties: getCssProperties(this.markup._inspector.toolbox)
|
||||
cssProperties: getCssProperties(this.markup.toolbox),
|
||||
contextMenu: this.markup.inspector.onTextBoxContextMenu
|
||||
});
|
||||
|
||||
this.update();
|
||||
@ -2966,7 +2970,7 @@ function ElementEditor(container, node) {
|
||||
this.markup = this.container.markup;
|
||||
this.template = this.markup.template.bind(this.markup);
|
||||
this.doc = this.markup.doc;
|
||||
this._cssProperties = getCssProperties(this.markup._inspector.toolbox);
|
||||
this._cssProperties = getCssProperties(this.markup.toolbox);
|
||||
|
||||
this.attrElements = new Map();
|
||||
this.animationTimers = {};
|
||||
@ -2994,6 +2998,7 @@ function ElementEditor(container, node) {
|
||||
trigger: "dblclick",
|
||||
stopOnReturn: true,
|
||||
done: this.onTagEdit.bind(this),
|
||||
contextMenu: this.markup.inspector.onTextBoxContextMenu,
|
||||
cssProperties: this._cssProperties
|
||||
});
|
||||
}
|
||||
@ -3021,6 +3026,7 @@ function ElementEditor(container, node) {
|
||||
undoMods.apply();
|
||||
});
|
||||
},
|
||||
contextMenu: this.markup.inspector.onTextBoxContextMenu,
|
||||
cssProperties: this._cssProperties
|
||||
});
|
||||
|
||||
@ -3262,6 +3268,7 @@ ElementEditor.prototype = {
|
||||
undoMods.apply();
|
||||
});
|
||||
},
|
||||
contextMenu: this.markup.inspector.onTextBoxContextMenu,
|
||||
cssProperties: this._cssProperties
|
||||
});
|
||||
|
||||
@ -3362,8 +3369,7 @@ ElementEditor.prototype = {
|
||||
// Only allow one refocus on attribute change at a time, so when there's
|
||||
// more than 1 request in parallel, the last one wins.
|
||||
if (this._editedAttributeObserver) {
|
||||
this.markup._inspector.off("markupmutation",
|
||||
this._editedAttributeObserver);
|
||||
this.markup.inspector.off("markupmutation", this._editedAttributeObserver);
|
||||
this._editedAttributeObserver = null;
|
||||
}
|
||||
|
||||
@ -3448,7 +3454,7 @@ ElementEditor.prototype = {
|
||||
|
||||
// Start listening for mutations until we find an attributes change
|
||||
// that modifies this attribute.
|
||||
this.markup._inspector.once("markupmutation", onMutations);
|
||||
this.markup.inspector.once("markupmutation", onMutations);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -15,7 +15,7 @@ add_task(function* () {
|
||||
assertMarkupViewIsLoaded();
|
||||
yield selectNode("#one", inspector);
|
||||
|
||||
let willNavigate = inspector.toolbox.target.once("will-navigate");
|
||||
let willNavigate = inspector.target.once("will-navigate");
|
||||
yield testActor.eval(`content.location = "${URL_2}"`);
|
||||
|
||||
info("Waiting for will-navigate");
|
||||
|
@ -14,9 +14,9 @@ DIRS += [
|
||||
DevToolsModules(
|
||||
'breadcrumbs.js',
|
||||
'inspector-commands.js',
|
||||
'inspector-panel.js',
|
||||
'inspector-search.js',
|
||||
'inspector.xhtml',
|
||||
'panel.js',
|
||||
'toolsidebar.js',
|
||||
)
|
||||
|
||||
|
19
devtools/client/inspector/panel.js
Normal file
19
devtools/client/inspector/panel.js
Normal file
@ -0,0 +1,19 @@
|
||||
/* 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";
|
||||
|
||||
function InspectorPanel(iframeWindow, toolbox) {
|
||||
this._inspector = new iframeWindow.Inspector(toolbox);
|
||||
}
|
||||
InspectorPanel.prototype = {
|
||||
open() {
|
||||
return this._inspector.init();
|
||||
},
|
||||
|
||||
destroy() {
|
||||
return this._inspector.destroy();
|
||||
}
|
||||
};
|
||||
exports.InspectorPanel = InspectorPanel;
|
@ -112,8 +112,6 @@ function CssRuleView(inspector, document, store, pageStyle) {
|
||||
this._onCopy = this._onCopy.bind(this);
|
||||
this._onFilterStyles = this._onFilterStyles.bind(this);
|
||||
this._onClearSearch = this._onClearSearch.bind(this);
|
||||
this._onFilterTextboxContextMenu =
|
||||
this._onFilterTextboxContextMenu.bind(this);
|
||||
this._onTogglePseudoClassPanel = this._onTogglePseudoClassPanel.bind(this);
|
||||
this._onTogglePseudoClass = this._onTogglePseudoClass.bind(this);
|
||||
|
||||
@ -140,8 +138,7 @@ function CssRuleView(inspector, document, store, pageStyle) {
|
||||
this.element.addEventListener("contextmenu", this._onContextMenu);
|
||||
this.addRuleButton.addEventListener("click", this._onAddRule);
|
||||
this.searchField.addEventListener("input", this._onFilterStyles);
|
||||
this.searchField.addEventListener("contextmenu",
|
||||
this._onFilterTextboxContextMenu);
|
||||
this.searchField.addEventListener("contextmenu", this.inspector.onTextBoxContextMenu);
|
||||
this.searchClearButton.addEventListener("click", this._onClearSearch);
|
||||
this.pseudoClassToggle.addEventListener("click",
|
||||
this._onTogglePseudoClassPanel);
|
||||
@ -470,7 +467,7 @@ CssRuleView.prototype = {
|
||||
_onAddRule: function () {
|
||||
let elementStyle = this._elementStyle;
|
||||
let element = elementStyle.element;
|
||||
let client = this.inspector.toolbox.target.client;
|
||||
let client = this.inspector.target.client;
|
||||
let pseudoClasses = element.pseudoClassLocks;
|
||||
|
||||
if (!client.traits.addNewRule) {
|
||||
@ -644,19 +641,6 @@ CssRuleView.prototype = {
|
||||
}, filterTimeout);
|
||||
},
|
||||
|
||||
/**
|
||||
* Context menu handler for filter style search box.
|
||||
*/
|
||||
_onFilterTextboxContextMenu: function (event) {
|
||||
try {
|
||||
this.styleWindow.focus();
|
||||
let contextmenu = this.inspector.toolbox.textboxContextMenuPopup;
|
||||
contextmenu.openPopupAtScreen(event.screenX, event.screenY, true);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when the user clicks on the clear button in the filter style search
|
||||
* box. Returns true if the search box is cleared and false otherwise.
|
||||
@ -699,7 +683,7 @@ CssRuleView.prototype = {
|
||||
this.addRuleButton.removeEventListener("click", this._onAddRule);
|
||||
this.searchField.removeEventListener("input", this._onFilterStyles);
|
||||
this.searchField.removeEventListener("contextmenu",
|
||||
this._onFilterTextboxContextMenu);
|
||||
this.inspector.onTextBoxContextMenu);
|
||||
this.searchClearButton.removeEventListener("click", this._onClearSearch);
|
||||
this.pseudoClassToggle.removeEventListener("click",
|
||||
this._onTogglePseudoClassPanel);
|
||||
|
@ -16,7 +16,7 @@ add_task(function* () {
|
||||
|
||||
let win = view.styleWindow;
|
||||
let searchField = view.searchField;
|
||||
let searchContextMenu = toolbox.textboxContextMenuPopup;
|
||||
let searchContextMenu = toolbox.textBoxContextMenuPopup;
|
||||
ok(searchContextMenu,
|
||||
"The search filter context menu is loaded in the rule view");
|
||||
|
||||
|
@ -87,7 +87,7 @@ RuleEditor.prototype = {
|
||||
|
||||
get isSelectorEditable() {
|
||||
let trait = this.isEditable &&
|
||||
this.toolbox.target.client.traits.selectorEditable &&
|
||||
this.ruleView.inspector.target.client.traits.selectorEditable &&
|
||||
this.rule.domRule.type !== ELEMENT_STYLE &&
|
||||
this.rule.domRule.type !== CSSRule.KEYFRAME_RULE;
|
||||
|
||||
@ -145,7 +145,8 @@ RuleEditor.prototype = {
|
||||
editableField({
|
||||
element: this.selectorText,
|
||||
done: this._onSelectorDone,
|
||||
cssProperties: this.rule.cssProperties
|
||||
cssProperties: this.rule.cssProperties,
|
||||
contextMenu: this.ruleView.inspector.onTextBoxContextMenu
|
||||
});
|
||||
}
|
||||
|
||||
@ -448,7 +449,8 @@ RuleEditor.prototype = {
|
||||
advanceChars: ":",
|
||||
contentType: InplaceEditor.CONTENT_TYPES.CSS_PROPERTY,
|
||||
popup: this.ruleView.popup,
|
||||
cssProperties: this.rule.cssProperties
|
||||
cssProperties: this.rule.cssProperties,
|
||||
contextMenu: this.ruleView.inspector.onTextBoxContextMenu
|
||||
});
|
||||
|
||||
// Auto-close the input if multiple rules get pasted into new property.
|
||||
|
@ -219,7 +219,8 @@ TextPropertyEditor.prototype = {
|
||||
advanceChars: ":",
|
||||
contentType: InplaceEditor.CONTENT_TYPES.CSS_PROPERTY,
|
||||
popup: this.popup,
|
||||
cssProperties: this.cssProperties
|
||||
cssProperties: this.cssProperties,
|
||||
contextMenu: this.ruleView.inspector.onTextBoxContextMenu
|
||||
});
|
||||
|
||||
// Auto blur name field on multiple CSS rules get pasted in.
|
||||
@ -289,7 +290,8 @@ TextPropertyEditor.prototype = {
|
||||
popup: this.popup,
|
||||
multiline: true,
|
||||
maxWidth: () => this.container.getBoundingClientRect().width,
|
||||
cssProperties: this.cssProperties
|
||||
cssProperties: this.cssProperties,
|
||||
contextMenu: this.ruleView.inspector.onTextBoxContextMenu
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -161,3 +161,4 @@ subsuite = clipboard
|
||||
[browser_inspector_search-navigation.js]
|
||||
[browser_inspector_sidebarstate.js]
|
||||
[browser_inspector_switch-to-inspector-on-pick.js]
|
||||
[browser_inspector_textbox-menu.js]
|
||||
|
@ -34,7 +34,7 @@ add_task(function* () {
|
||||
|
||||
info("Waiting for box mode to show.");
|
||||
let body = yield getNodeFront("body", inspector);
|
||||
yield toolbox.highlighter.showBoxModel(body);
|
||||
yield inspector.highlighter.showBoxModel(body);
|
||||
|
||||
info("Waiting for element picker to become active.");
|
||||
yield startPicker(toolbox);
|
||||
|
@ -27,11 +27,11 @@ const ELEMENTS = ["box-model-root",
|
||||
"box-model-infobar-dimensions"];
|
||||
|
||||
add_task(function* () {
|
||||
let {inspector, toolbox, testActor} = yield openInspectorForURL(TEST_URL);
|
||||
let {inspector, testActor} = yield openInspectorForURL(TEST_URL);
|
||||
|
||||
info("Show the box-model highlighter");
|
||||
let divFront = yield getNodeFront("div", inspector);
|
||||
yield toolbox.highlighter.showBoxModel(divFront);
|
||||
yield inspector.highlighter.showBoxModel(divFront);
|
||||
|
||||
for (let id of ELEMENTS) {
|
||||
let foundId = yield testActor.getHighlighterNodeAttribute(id, "id");
|
||||
@ -39,5 +39,5 @@ add_task(function* () {
|
||||
}
|
||||
|
||||
info("Hide the box-model highlighter");
|
||||
yield toolbox.highlighter.hideBoxModel();
|
||||
yield inspector.highlighter.hideBoxModel();
|
||||
});
|
||||
|
@ -11,7 +11,7 @@
|
||||
const TEST_URL = "data:text/html;charset=utf-8,<p>Select me!</p>";
|
||||
|
||||
add_task(function* () {
|
||||
let {toolbox, inspector, testActor} = yield openInspectorForURL(TEST_URL);
|
||||
let {inspector, testActor} = yield openInspectorForURL(TEST_URL);
|
||||
|
||||
info("hover over the <p> line in the markup-view so that it's the " +
|
||||
"currently hovered node");
|
||||
@ -24,7 +24,7 @@ add_task(function* () {
|
||||
|
||||
info("listen to the highlighter's hidden event");
|
||||
let onHidden = testActor.waitForHighlighterEvent("hidden",
|
||||
toolbox.highlighter);
|
||||
inspector.highlighter);
|
||||
info("mouse-leave the markup-view");
|
||||
yield mouseLeaveMarkupView(inspector);
|
||||
yield onHidden;
|
||||
|
@ -46,7 +46,7 @@ add_task(function* () {
|
||||
info("Key pressed. Waiting for element to be picked");
|
||||
testActor.synthesizeKey(args);
|
||||
return promise.all([
|
||||
toolbox.selection.once("new-node-front"),
|
||||
inspector.selection.once("new-node-front"),
|
||||
inspector.once("inspector-updated")
|
||||
]);
|
||||
}
|
||||
|
@ -185,7 +185,7 @@ const TEST_DATA = [
|
||||
];
|
||||
|
||||
add_task(function* () {
|
||||
let {inspector, toolbox, testActor} = yield openInspectorForURL(
|
||||
let {inspector, testActor} = yield openInspectorForURL(
|
||||
"data:text/html;charset=utf-8," + encodeURI(TEST_URL));
|
||||
|
||||
let divFront = yield getNodeFront("div", inspector);
|
||||
@ -194,11 +194,11 @@ add_task(function* () {
|
||||
info("Running test: " + desc);
|
||||
|
||||
info("Show the box-model highlighter with options " + options);
|
||||
yield toolbox.highlighter.showBoxModel(divFront, options);
|
||||
yield inspector.highlighter.showBoxModel(divFront, options);
|
||||
|
||||
yield checkHighlighter(testActor);
|
||||
|
||||
info("Hide the box-model highlighter");
|
||||
yield toolbox.highlighter.hideBoxModel();
|
||||
yield inspector.highlighter.hideBoxModel();
|
||||
}
|
||||
});
|
||||
|
@ -22,7 +22,7 @@ add_task(function* () {
|
||||
info("Key pressed. Waiting for element to be picked");
|
||||
testActor.synthesizeKey(msg);
|
||||
return promise.all([
|
||||
toolbox.selection.once("new-node-front"),
|
||||
inspector.selection.once("new-node-front"),
|
||||
inspector.once("inspector-updated")
|
||||
]);
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ add_task(function* () {
|
||||
let divFront = yield getNodeFront("div", inspector);
|
||||
|
||||
info("Waiting for highlighter to activate");
|
||||
yield inspector.toolbox.highlighter.showBoxModel(divFront);
|
||||
yield inspector.highlighter.showBoxModel(divFront);
|
||||
|
||||
let rect = yield testActor.getSimpleBorderRect();
|
||||
is(rect.width, 100, "The highlighter has the right width.");
|
||||
@ -31,5 +31,5 @@ add_task(function* () {
|
||||
is(rect.width, 200, "The highlighter has the right width after update");
|
||||
|
||||
info("Waiting for highlighter to hide");
|
||||
yield inspector.toolbox.highlighter.hideBoxModel();
|
||||
yield inspector.highlighter.hideBoxModel();
|
||||
});
|
||||
|
@ -89,9 +89,8 @@ function* testNavigate(inspector, testActor, ruleview) {
|
||||
}
|
||||
|
||||
function* showPickerOn(selector, inspector) {
|
||||
let highlighter = inspector.toolbox.highlighter;
|
||||
let nodeFront = yield getNodeFront(selector, inspector);
|
||||
yield highlighter.showBoxModel(nodeFront);
|
||||
yield inspector.highlighter.showBoxModel(nodeFront);
|
||||
}
|
||||
|
||||
function* assertPseudoAddedToNode(inspector, testActor, ruleview) {
|
||||
@ -119,7 +118,7 @@ function* assertPseudoAddedToNode(inspector, testActor, ruleview) {
|
||||
let value = yield testActor.getHighlighterNodeTextContent(
|
||||
"box-model-infobar-pseudo-classes");
|
||||
is(value, PSEUDO, "pseudo-class in infobar selector");
|
||||
yield inspector.toolbox.highlighter.hideBoxModel();
|
||||
yield inspector.highlighter.hideBoxModel();
|
||||
}
|
||||
|
||||
function* assertPseudoRemovedFromNode(testActor) {
|
||||
@ -145,5 +144,5 @@ function* assertPseudoRemovedFromView(inspector, testActor, ruleview) {
|
||||
let value = yield testActor.getHighlighterNodeTextContent(
|
||||
"box-model-infobar-pseudo-classes");
|
||||
is(value, "", "pseudo-class removed from infobar selector");
|
||||
yield inspector.toolbox.highlighter.hideBoxModel();
|
||||
yield inspector.highlighter.hideBoxModel();
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ add_task(function* () {
|
||||
yield selectNode("h1", inspector);
|
||||
|
||||
let win = inspector.panelWin;
|
||||
let searchContextMenu = toolbox.textboxContextMenuPopup;
|
||||
let searchContextMenu = toolbox.textBoxContextMenuPopup;
|
||||
ok(searchContextMenu,
|
||||
"The search filter context menu is loaded in the inspector");
|
||||
|
||||
|
@ -0,0 +1,90 @@
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
// Test that when right-clicking on various text boxes throughout the inspector does use
|
||||
// the toolbox's context menu (copy/cut/paste/selectAll/Undo).
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab(`data:text/html;charset=utf-8,
|
||||
<style>h1 { color: red; }</style>
|
||||
<h1 id="title">textbox context menu test</h1>`);
|
||||
let {toolbox, inspector} = yield openInspector();
|
||||
yield selectNode("h1", inspector);
|
||||
|
||||
info("Testing the markup-view tagname");
|
||||
let container = yield focusNode("h1", inspector);
|
||||
let tag = container.editor.tag;
|
||||
tag.focus();
|
||||
EventUtils.sendKey("return", inspector.panelWin);
|
||||
yield checkTextBox(inspector.markup.doc.activeElement, toolbox);
|
||||
|
||||
info("Testing the markup-view attribute");
|
||||
EventUtils.sendKey("tab", inspector.panelWin);
|
||||
yield checkTextBox(inspector.markup.doc.activeElement, toolbox);
|
||||
|
||||
info("Testing the markup-view new attribute");
|
||||
// It takes 2 tabs to focus the newAttr field, the first one just moves the cursor to
|
||||
// the end of the field.
|
||||
EventUtils.sendKey("tab", inspector.panelWin);
|
||||
EventUtils.sendKey("tab", inspector.panelWin);
|
||||
yield checkTextBox(inspector.markup.doc.activeElement, toolbox);
|
||||
|
||||
info("Testing the markup-view textcontent");
|
||||
EventUtils.sendKey("tab", inspector.panelWin);
|
||||
yield checkTextBox(inspector.markup.doc.activeElement, toolbox);
|
||||
// Blur this last markup-view field, since we're moving on to the rule-view next.
|
||||
EventUtils.sendKey("escape", inspector.panelWin);
|
||||
|
||||
info("Testing the rule-view selector");
|
||||
let ruleView = inspector.ruleview.view;
|
||||
let cssRuleEditor = getRuleViewRuleEditor(ruleView, 1);
|
||||
EventUtils.synthesizeMouse(cssRuleEditor.selectorText, 0, 0, {}, inspector.panelWin);
|
||||
yield checkTextBox(inspector.panelDoc.activeElement, toolbox);
|
||||
|
||||
info("Testing the rule-view property name");
|
||||
EventUtils.sendKey("tab", inspector.panelWin);
|
||||
yield checkTextBox(inspector.panelDoc.activeElement, toolbox);
|
||||
|
||||
info("Testing the rule-view property value");
|
||||
EventUtils.sendKey("tab", inspector.panelWin);
|
||||
yield checkTextBox(inspector.panelDoc.activeElement, toolbox);
|
||||
|
||||
info("Testing the rule-view new property");
|
||||
// Tabbing out of the value field triggers a ruleview-changed event that we need to wait
|
||||
// for.
|
||||
let onRuleViewChanged = once(ruleView, "ruleview-changed");
|
||||
EventUtils.sendKey("tab", inspector.panelWin);
|
||||
yield onRuleViewChanged;
|
||||
yield checkTextBox(inspector.panelDoc.activeElement, toolbox);
|
||||
|
||||
info("Switching to the computed-view");
|
||||
let onComputedViewReady = inspector.once("boxmodel-view-updated");
|
||||
selectComputedView(inspector);
|
||||
yield onComputedViewReady;
|
||||
|
||||
info("Testing the box-model region");
|
||||
let margin = inspector.panelDoc.querySelector(".boxmodel-margin.boxmodel-top > span");
|
||||
EventUtils.synthesizeMouseAtCenter(margin, {}, inspector.panelWin);
|
||||
yield checkTextBox(inspector.panelDoc.activeElement, toolbox);
|
||||
});
|
||||
|
||||
function* checkTextBox(textBox, {textBoxContextMenuPopup}) {
|
||||
is(textBoxContextMenuPopup.state, "closed", "The menu is closed");
|
||||
|
||||
info("Simulating context click on the textbox and expecting the menu to open");
|
||||
let onContextMenu = once(textBoxContextMenuPopup, "popupshown");
|
||||
EventUtils.synthesizeMouse(textBox, 2, 2, {type: "contextmenu", button: 2},
|
||||
textBox.ownerDocument.defaultView);
|
||||
yield onContextMenu;
|
||||
|
||||
is(textBoxContextMenuPopup.state, "open", "The menu is now visible");
|
||||
|
||||
info("Closing the menu");
|
||||
let onContextMenuHidden = once(textBoxContextMenuPopup, "popuphidden");
|
||||
textBoxContextMenuPopup.hidePopup();
|
||||
yield onContextMenuHidden;
|
||||
|
||||
is(textBoxContextMenuPopup.state, "closed", "The menu is closed again");
|
||||
}
|
@ -25,6 +25,7 @@ devtools.jar:
|
||||
content/shared/frame-script-utils.js (shared/frame-script-utils.js)
|
||||
content/styleeditor/styleeditor.xul (styleeditor/styleeditor.xul)
|
||||
content/storage/storage.xul (storage/storage.xul)
|
||||
content/inspector/inspector.js (inspector/inspector.js)
|
||||
content/inspector/fonts/fonts.js (inspector/fonts/fonts.js)
|
||||
content/inspector/markup/markup.xhtml (inspector/markup/markup.xhtml)
|
||||
content/animationinspector/animation-controller.js (animationinspector/animation-controller.js)
|
||||
|
@ -88,6 +88,8 @@ function isKeyIn(key, ...keys) {
|
||||
* This function is called before the editor has been torn down.
|
||||
* {Function} destroy:
|
||||
* Called when the editor is destroyed and has been torn down.
|
||||
* {Function} contextMenu:
|
||||
* Called when the user triggers a contextmenu event on the input.
|
||||
* {Object} advanceChars:
|
||||
* This can be either a string or a function.
|
||||
* If it is a string, then if any characters in it are typed,
|
||||
@ -222,6 +224,7 @@ function InplaceEditor(options, event) {
|
||||
this.cssProperties = options.cssProperties;
|
||||
this.change = options.change;
|
||||
this.done = options.done;
|
||||
this.contextMenu = options.contextMenu;
|
||||
this.destroy = options.destroy;
|
||||
this.initial = options.initial ? options.initial : this.elt.textContent;
|
||||
this.multiline = options.multiline || false;
|
||||
@ -249,6 +252,7 @@ function InplaceEditor(options, event) {
|
||||
this._onInput = this._onInput.bind(this);
|
||||
this._onKeyup = this._onKeyup.bind(this);
|
||||
this._onAutocompletePopupClick = this._onAutocompletePopupClick.bind(this);
|
||||
this._onContextMenu = this._onContextMenu.bind(this);
|
||||
|
||||
this._createInput();
|
||||
|
||||
@ -290,6 +294,7 @@ function InplaceEditor(options, event) {
|
||||
this.input.addEventListener("dblclick", this._stopEventPropagation, false);
|
||||
this.input.addEventListener("click", this._stopEventPropagation, false);
|
||||
this.input.addEventListener("mousedown", this._stopEventPropagation, false);
|
||||
this.input.addEventListener("contextmenu", this._onContextMenu, false);
|
||||
this.doc.defaultView.addEventListener("blur", this._onWindowBlur, false);
|
||||
|
||||
this.validate = options.validate;
|
||||
@ -349,11 +354,10 @@ InplaceEditor.prototype = {
|
||||
this.input.removeEventListener("keypress", this._onKeyPress, false);
|
||||
this.input.removeEventListener("keyup", this._onKeyup, false);
|
||||
this.input.removeEventListener("input", this._onInput, false);
|
||||
this.input.removeEventListener("dblclick", this._stopEventPropagation,
|
||||
false);
|
||||
this.input.removeEventListener("dblclick", this._stopEventPropagation, false);
|
||||
this.input.removeEventListener("click", this._stopEventPropagation, false);
|
||||
this.input.removeEventListener("mousedown", this._stopEventPropagation,
|
||||
false);
|
||||
this.input.removeEventListener("mousedown", this._stopEventPropagation, false);
|
||||
this.input.removeEventListener("contextmenu", this._onContextMenu, false);
|
||||
this.doc.defaultView.removeEventListener("blur", this._onWindowBlur, false);
|
||||
|
||||
this._stopAutosize();
|
||||
@ -1164,6 +1168,12 @@ InplaceEditor.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
_onContextMenu: function (event) {
|
||||
if (this.contextMenu) {
|
||||
this.contextMenu(event);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Open the autocomplete popup, adding a custom click handler and classname.
|
||||
*
|
||||
|
@ -741,7 +741,7 @@ Heritage.extend(SwatchBasedEditorTooltip.prototype, {
|
||||
this.spectrum.updateUI();
|
||||
}
|
||||
|
||||
let {target} = this.inspector.toolbox;
|
||||
let {target} = this.inspector;
|
||||
target.actorHasMethod("inspector", "pickColorFromPage").then(value => {
|
||||
let tooltipDoc = this.tooltip.doc;
|
||||
let eyeButton = tooltipDoc.querySelector("#eyedropper-button");
|
||||
|
@ -11,6 +11,14 @@
|
||||
--eyedropper-image: url(images/firebug/command-eyedropper.svg);
|
||||
}
|
||||
|
||||
:root.theme-light {
|
||||
--breadcrumbs-border-color: #f3f3f3;
|
||||
}
|
||||
|
||||
:root.theme-dark {
|
||||
--breadcrumbs-border-color: #454d5d;
|
||||
}
|
||||
|
||||
/* Make sure to hide scroll bars for the parent window */
|
||||
window {
|
||||
overflow: hidden;
|
||||
@ -117,6 +125,10 @@ window {
|
||||
padding: 0px;
|
||||
border-bottom-width: 0px;
|
||||
border-top-width: 1px;
|
||||
border-top-color: var(--breadcrumbs-border-color);
|
||||
/* Bug 1262668 - Use the same background as the body so the breadcrumbs toolbar doesn't
|
||||
get mistaken as a splitter */
|
||||
background-color: var(--theme-body-background);
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
|
@ -214,7 +214,7 @@
|
||||
|
||||
#breadcrumb-separator-after,
|
||||
#breadcrumb-separator-before:after {
|
||||
background: var(--theme-toolbar-background);
|
||||
background: var(--theme-body-background);
|
||||
}
|
||||
|
||||
/* This chevron arrow cannot be replicated easily in CSS, so we are using
|
||||
|
Loading…
Reference in New Issue
Block a user