Bug 1336198 - Part 7: Refactor box model logic into box-model.js. r=jdescottes
MozReview-Commit-ID: C4DMNTYoTU
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/boxmodel/box-model.js
@@ -0,0 +1,285 @@
+/* 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 { Task } = require("devtools/shared/task");
+const { getCssProperties } = require("devtools/shared/fronts/css-properties");
+const { ReflowFront } = require("devtools/shared/fronts/reflow");
+
+const { InplaceEditor } = require("devtools/client/shared/inplace-editor");
+
+const { updateLayout } = require("./actions/box-model");
+
+const EditingSession = require("./utils/editing-session");
+
+const NUMERIC = /^-?[\d\.]+$/;
+
+/**
+ * A singleton instance of the box model controllers.
+ *
+ * @param {Inspector} inspector
+ * An instance of the Inspector currently loaded in the toolbox.
+ * @param {Window} window
+ * The document window of the toolbox.
+ */
+function BoxModel(inspector, window) {
+ this.document = window.document;
+ this.inspector = inspector;
+ this.store = inspector.store;
+
+ this.updateBoxModel = this.updateBoxModel.bind(this);
+
+ this.onHideBoxModelHighlighter = this.onHideBoxModelHighlighter.bind(this);
+ this.onNewSelection = this.onNewSelection.bind(this);
+ this.onShowBoxModelEditor = this.onShowBoxModelEditor.bind(this);
+ this.onShowBoxModelHighlighter = this.onShowBoxModelHighlighter.bind(this);
+ this.onSidebarSelect = this.onSidebarSelect.bind(this);
+
+ this.inspector.selection.on("new-node-front", this.onNewSelection);
+ this.inspector.sidebar.on("select", this.onSidebarSelect);
+}
+
+BoxModel.prototype = {
+
+ /**
+ * Destruction function called when the inspector is destroyed. Removes event listeners
+ * and cleans up references.
+ */
+ destroy() {
+ this.inspector.selection.off("new-node-front", this.onNewSelection);
+ this.inspector.sidebar.off("select", this.onSidebarSelect);
+
+ if (this.reflowFront) {
+ this.untrackReflows();
+ this.reflowFront.destroy();
+ this.reflowFront = null;
+ }
+
+ this.document = null;
+ this.inspector = null;
+ this.walker = null;
+ },
+
+ /**
+ * Returns an object containing the box model's handler functions used in the box
+ * model's React component props.
+ */
+ getComponentProps() {
+ return {
+ onHideBoxModelHighlighter: this.onHideBoxModelHighlighter,
+ onShowBoxModelEditor: this.onShowBoxModelEditor,
+ onShowBoxModelHighlighter: this.onShowBoxModelHighlighter,
+ };
+ },
+
+ /**
+ * Returns true if the layout panel is visible, and false otherwise.
+ */
+ isPanelVisible() {
+ return this.inspector.toolbox.currentToolId === "inspector" &&
+ this.inspector.sidebar &&
+ this.inspector.sidebar.getCurrentTabID() === "layoutview";
+ },
+
+ /**
+ * Returns true if the layout panel is visible and the current node is valid to
+ * be displayed in the view.
+ */
+ isPanelVisibleAndNodeValid() {
+ return this.isPanelVisible() &&
+ this.inspector.selection.isConnected() &&
+ this.inspector.selection.isElementNode();
+ },
+
+ /**
+ * Starts listening to reflows in the current tab.
+ */
+ trackReflows() {
+ if (!this.reflowFront) {
+ let { target } = this.inspector;
+ if (target.form.reflowActor) {
+ this.reflowFront = ReflowFront(target.client,
+ target.form);
+ } else {
+ return;
+ }
+ }
+
+ this.reflowFront.on("reflows", this.updateBoxModel);
+ this.reflowFront.start();
+ },
+
+ /**
+ * Stops listening to reflows in the current tab.
+ */
+ untrackReflows() {
+ if (!this.reflowFront) {
+ return;
+ }
+
+ this.reflowFront.off("reflows", this.updateBoxModel);
+ this.reflowFront.stop();
+ },
+
+ /**
+ * Updates the box model panel by dispatching the new layout data.
+ */
+ updateBoxModel() {
+ let lastRequest = Task.spawn((function* () {
+ if (!(this.isPanelVisible() &&
+ this.inspector.selection.isConnected() &&
+ this.inspector.selection.isElementNode())) {
+ return null;
+ }
+
+ let node = this.inspector.selection.nodeFront;
+ let layout = yield this.inspector.pageStyle.getLayout(node, {
+ autoMargins: true,
+ });
+ let styleEntries = yield this.inspector.pageStyle.getApplied(node, {});
+ this.elementRules = styleEntries.map(e => e.rule);
+
+ // Update the redux store with the latest layout properties and update the box
+ // model view.
+ this.store.dispatch(updateLayout(layout));
+
+ // If a subsequent request has been made, wait for that one instead.
+ if (this._lastRequest != lastRequest) {
+ return this._lastRequest;
+ }
+
+ this._lastRequest = null;
+
+ this.inspector.emit("boxmodel-view-updated");
+ return null;
+ }).bind(this)).catch(console.error);
+
+ this._lastRequest = lastRequest;
+ },
+
+ /**
+ * Selection 'new-node-front' event handler.
+ */
+ onNewSelection: function () {
+ if (!this.isPanelVisibleAndNodeValid()) {
+ return;
+ }
+
+ this.updateBoxModel();
+ },
+
+ /**
+ * Hides the box-model highlighter on the currently selected element.
+ */
+ onHideBoxModelHighlighter() {
+ let toolbox = this.inspector.toolbox;
+ toolbox.highlighterUtils.unhighlight();
+ },
+
+ /**
+ * Shows the inplace editor when a box model editable value is clicked on the
+ * box model panel.
+ *
+ * @param {DOMNode} element
+ * The element that was clicked.
+ * @param {Event} event
+ * The event object.
+ * @param {String} property
+ * The name of the property.
+ */
+ onShowBoxModelEditor(element, event, property) {
+ let session = new EditingSession({
+ inspector: this.inspector,
+ doc: this.document,
+ elementRules: this.elementRules,
+ });
+ let initialValue = session.getProperty(property);
+
+ let editor = new InplaceEditor({
+ element: element,
+ initial: initialValue,
+ contentType: InplaceEditor.CONTENT_TYPES.CSS_VALUE,
+ property: {
+ name: property
+ },
+ start: self => {
+ self.elt.parentNode.classList.add("boxmodel-editing");
+ },
+ change: value => {
+ if (NUMERIC.test(value)) {
+ value += "px";
+ }
+
+ let properties = [
+ { name: property, value: value }
+ ];
+
+ if (property.substring(0, 7) == "border-") {
+ let bprop = property.substring(0, property.length - 5) + "style";
+ let style = session.getProperty(bprop);
+ if (!style || style == "none" || style == "hidden") {
+ properties.push({ name: bprop, value: "solid" });
+ }
+ }
+
+ session.setProperties(properties).catch(e => console.error(e));
+ },
+ done: (value, commit) => {
+ editor.elt.parentNode.classList.remove("boxmodel-editing");
+ if (!commit) {
+ session.revert().then(() => {
+ session.destroy();
+ }, e => console.error(e));
+ return;
+ }
+
+ let node = this.inspector.selection.nodeFront;
+ this.inspector.pageStyle.getLayout(node, {
+ autoMargins: true,
+ }).then(layout => {
+ this.store.dispatch(updateLayout(layout));
+ }, e => console.error(e));
+ },
+ contextMenu: this.inspector.onTextBoxContextMenu,
+ cssProperties: getCssProperties(this.inspector.toolbox)
+ }, event);
+ },
+
+ /**
+ * Shows the box-model highlighter on the currently selected element.
+ *
+ * @param {Object} options
+ * Options passed to the highlighter actor.
+ */
+ onShowBoxModelHighlighter(options = {}) {
+ let toolbox = this.inspector.toolbox;
+ let nodeFront = this.inspector.selection.nodeFront;
+
+ toolbox.highlighterUtils.highlightNodeFront(nodeFront, options);
+ },
+
+ /**
+ * Handler for the inspector sidebar select event. Starts listening for
+ * "grid-layout-changed" if the layout panel is visible. Otherwise, stop
+ * listening for grid layout changes. Finally, refresh the layout view if
+ * it is visible.
+ */
+ onSidebarSelect() {
+ if (!this.isPanelVisible()) {
+ this.untrackReflows();
+ return;
+ }
+
+ if (this.inspector.selection.isConnected() &&
+ this.inspector.selection.isElementNode()) {
+ this.trackReflows();
+ }
+
+ this.updateBoxModel();
+ },
+
+};
+
+module.exports = BoxModel;
--- a/devtools/client/inspector/boxmodel/moz.build
+++ b/devtools/client/inspector/boxmodel/moz.build
@@ -7,10 +7,11 @@
DIRS += [
'actions',
'components',
'reducers',
'utils',
]
DevToolsModules(
+ 'box-model.js',
'types.js',
)
--- a/devtools/client/inspector/inspector.js
+++ b/devtools/client/inspector/inspector.js
@@ -18,16 +18,17 @@ var {Task} = require("devtools/shared/ta
const {initCssProperties} = require("devtools/shared/fronts/css-properties");
const nodeConstants = require("devtools/shared/dom-node-constants");
const Telemetry = require("devtools/client/shared/telemetry");
const Menu = require("devtools/client/framework/menu");
const MenuItem = require("devtools/client/framework/menu-item");
const {HTMLBreadcrumbs} = require("devtools/client/inspector/breadcrumbs");
+const BoxModelView = require("devtools/client/inspector/boxmodel/box-model");
const {ComputedViewTool} = require("devtools/client/inspector/computed/computed");
const {FontInspector} = require("devtools/client/inspector/fonts/fonts");
const {InspectorSearch} = require("devtools/client/inspector/inspector-search");
const {RuleViewTool} = require("devtools/client/inspector/rules/rules");
const HighlightersOverlay = require("devtools/client/inspector/shared/highlighters-overlay");
const {ToolSidebar} = require("devtools/client/inspector/toolsidebar");
const MarkupView = require("devtools/client/inspector/markup/markup");
const {CommandUtils} = require("devtools/client/shared/developer-toolbar");
@@ -568,16 +569,17 @@ Inspector.prototype = {
this.sidebar.addExistingTab(
"computedview",
INSPECTOR_L10N.getStr("inspector.sidebar.computedViewTitle"),
defaultTab == "computedview");
this.ruleview = new RuleViewTool(this, this.panelWin);
this.computedview = new ComputedViewTool(this, this.panelWin);
+ this.boxmodelview = new BoxModelView(this, this.panelWin);
if (Services.prefs.getBoolPref("devtools.layoutview.enabled")) {
const LayoutView = this.browserRequire("devtools/client/inspector/layout/layout");
this.layoutview = new LayoutView(this, this.panelWin);
}
if (this.target.form.animationsActor) {
this.sidebar.addFrameTab(
--- a/devtools/client/inspector/layout/components/App.js
+++ b/devtools/client/inspector/layout/components/App.js
@@ -6,19 +6,20 @@
const { addons, createClass, createFactory, DOM: dom, PropTypes } =
require("devtools/client/shared/vendor/react");
const { connect } = require("devtools/client/shared/vendor/react-redux");
const { LocalizationHelper } = require("devtools/shared/l10n");
const Accordion = createFactory(require("./Accordion"));
-const BoxModel = createFactory(require("./BoxModel"));
const Grid = createFactory(require("./Grid"));
+const BoxModel = createFactory(require("devtools/client/inspector/boxmodel/components/BoxModel"));
+
const Types = require("../types");
const { getStr } = require("../utils/l10n");
const BOXMODEL_STRINGS_URI = "devtools/client/locales/boxmodel.properties";
const BOXMODEL_L10N = new LocalizationHelper(BOXMODEL_STRINGS_URI);
const App = createClass({
--- a/devtools/client/inspector/layout/layout.js
+++ b/devtools/client/inspector/layout/layout.js
@@ -1,47 +1,38 @@
/* 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 Services = require("Services");
const { Task } = require("devtools/shared/task");
-const { getCssProperties } = require("devtools/shared/fronts/css-properties");
-const { ReflowFront } = require("devtools/shared/fronts/reflow");
-const { InplaceEditor } = require("devtools/client/shared/inplace-editor");
const { createFactory, createElement } = require("devtools/client/shared/vendor/react");
const { Provider } = require("devtools/client/shared/vendor/react-redux");
const SwatchColorPickerTooltip = require("devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip");
const {
- updateLayout,
-} = require("./actions/box-model");
-const {
updateGridColor,
updateGridHighlighted,
updateGrids,
} = require("./actions/grids");
const {
updateShowGridLineNumbers,
updateShowInfiniteLines,
} = require("./actions/highlighter-settings");
const App = createFactory(require("./components/App"));
-const EditingSession = require("./utils/editing-session");
-
const { LocalizationHelper } = require("devtools/shared/l10n");
const INSPECTOR_L10N =
new LocalizationHelper("devtools/client/locales/inspector.properties");
-const NUMERIC = /^-?[\d\.]+$/;
const SHOW_GRID_LINE_NUMBERS = "devtools.gridinspector.showGridLineNumbers";
const SHOW_INFINITE_LINES_PREF = "devtools.gridinspector.showInfiniteLines";
// Default grid colors.
const GRID_COLORS = [
"#05E4EE",
"#BB9DFF",
"#FFB53B",
@@ -54,44 +45,46 @@ const GRID_COLORS = [
function LayoutView(inspector, window) {
this.document = window.document;
this.highlighters = inspector.highlighters;
this.inspector = inspector;
this.store = inspector.store;
this.walker = this.inspector.walker;
- this.updateBoxModel = this.updateBoxModel.bind(this);
-
this.onGridLayoutChange = this.onGridLayoutChange.bind(this);
this.onHighlighterChange = this.onHighlighterChange.bind(this);
- this.onNewSelection = this.onNewSelection.bind(this);
this.onSidebarSelect = this.onSidebarSelect.bind(this);
this.init();
}
LayoutView.prototype = {
/**
* Initializes the layout view by fetching the LayoutFront from the walker, creating
* the redux store and adding the view into the inspector sidebar.
*/
init: Task.async(function* () {
if (!this.inspector) {
return;
}
+ let {
+ onHideBoxModelHighlighter,
+ onShowBoxModelEditor,
+ onShowBoxModelHighlighter,
+ } = this.inspector.boxmodelview.getComponentProps();
+
this.layoutInspector = yield this.inspector.walker.getLayoutInspector();
this.loadHighlighterSettings();
this.highlighters.on("grid-highlighter-hidden", this.onHighlighterChange);
this.highlighters.on("grid-highlighter-shown", this.onHighlighterChange);
- this.inspector.selection.on("new-node-front", this.onNewSelection);
this.inspector.sidebar.on("select", this.onSidebarSelect);
// Create a shared SwatchColorPicker instance to be reused by all GridItem components.
this.swatchColorPickerTooltip = new SwatchColorPickerTooltip(
this.inspector.toolbox.doc,
this.inspector,
{
supportsCssColor4ColorFunction: () => false
@@ -107,23 +100,20 @@ LayoutView.prototype = {
},
/**
* Shows the box model properties under the box model if true, otherwise, hidden by
* default.
*/
showBoxModelProperties: true,
- /**
- * Hides the box-model highlighter on the currently selected element.
- */
- onHideBoxModelHighlighter: () => {
- let toolbox = this.inspector.toolbox;
- toolbox.highlighterUtils.unhighlight();
- },
+ onHideBoxModelHighlighter: () => onHideBoxModelHighlighter(),
+ onShowBoxModelEditor: (element, event, property) =>
+ onShowBoxModelEditor(element, event, property),
+ onShowBoxModelHighlighter: (options = {}) => onShowBoxModelHighlighter(options),
/**
* Handler for a change in the grid overlay color picker for a grid container.
*
* @param {NodeFront} node
* The NodeFront of the grid container element for which the grid color is
* being updated.
* @param {String} color
@@ -139,98 +129,16 @@ LayoutView.prototype = {
if (grid.nodeFront === node && grid.highlighted) {
let highlighterSettings = this.getGridHighlighterSettings(node);
this.highlighters.showGridHighlighter(node, highlighterSettings);
}
}
},
/**
- * Shows the inplace editor when a box model editable value is clicked on the
- * box model panel.
- *
- * @param {DOMNode} element
- * The element that was clicked.
- * @param {Event} event
- * The event object.
- * @param {String} property
- * The name of the property.
- */
- onShowBoxModelEditor: (element, event, property) => {
- let session = new EditingSession({
- inspector: this.inspector,
- doc: this.document,
- elementRules: this.elementRules,
- });
- let initialValue = session.getProperty(property);
-
- let editor = new InplaceEditor({
- element: element,
- initial: initialValue,
- contentType: InplaceEditor.CONTENT_TYPES.CSS_VALUE,
- property: {
- name: property
- },
- start: self => {
- self.elt.parentNode.classList.add("boxmodel-editing");
- },
- change: value => {
- if (NUMERIC.test(value)) {
- value += "px";
- }
-
- let properties = [
- { name: property, value: value }
- ];
-
- if (property.substring(0, 7) == "border-") {
- let bprop = property.substring(0, property.length - 5) + "style";
- let style = session.getProperty(bprop);
- if (!style || style == "none" || style == "hidden") {
- properties.push({ name: bprop, value: "solid" });
- }
- }
-
- session.setProperties(properties).catch(e => console.error(e));
- },
- done: (value, commit) => {
- editor.elt.parentNode.classList.remove("boxmodel-editing");
- if (!commit) {
- session.revert().then(() => {
- session.destroy();
- }, e => console.error(e));
- return;
- }
-
- let node = this.inspector.selection.nodeFront;
- this.inspector.pageStyle.getLayout(node, {
- autoMargins: true,
- }).then(layout => {
- this.store.dispatch(updateLayout(layout));
- }, e => console.error(e));
- },
- contextMenu: this.inspector.onTextBoxContextMenu,
- cssProperties: getCssProperties(this.inspector.toolbox)
- }, event);
- },
-
- /**
- * Shows the box-model highlighter on the currently selected element.
- *
- * @param {Object} options
- * Options passed to the highlighter actor.
- */
- onShowBoxModelHighlighter: (options = {}) => {
- let toolbox = this.inspector.toolbox;
- let nodeFront = this.inspector.selection.nodeFront;
-
- toolbox.highlighterUtils.highlightNodeFront(nodeFront, options);
- },
-
- /**
* Handler for a change in the input checkboxes in the GridList component.
* Toggles on/off the grid highlighter for the provided grid container element.
*
* @param {NodeFront} node
* The NodeFront of the grid container element for which the grid
* highlighter is toggled on/off for.
*/
onToggleGridHighlighter: node => {
@@ -304,26 +212,19 @@ LayoutView.prototype = {
/**
* Destruction function called when the inspector is destroyed. Removes event listeners
* and cleans up references.
*/
destroy() {
this.highlighters.off("grid-highlighter-hidden", this.onHighlighterChange);
this.highlighters.off("grid-highlighter-shown", this.onHighlighterChange);
- this.inspector.selection.off("new-node-front", this.onNewSelection);
this.inspector.sidebar.off("select", this.onSidebarSelect);
this.layoutInspector.off("grid-layout-changed", this.onGridLayoutChange);
- if (this.reflowFront) {
- this.untrackReflows();
- this.reflowFront.destroy();
- this.reflowFront = null;
- }
-
this.document = null;
this.inspector = null;
this.layoutInspector = null;
this.store = null;
this.walker = null;
},
/**
@@ -368,105 +269,29 @@ LayoutView.prototype = {
*/
isPanelVisible() {
return this.inspector.toolbox.currentToolId === "inspector" &&
this.inspector.sidebar &&
this.inspector.sidebar.getCurrentTabID() === "layoutview";
},
/**
- * Returns true if the layout panel is visible and the current node is valid to
- * be displayed in the view.
- */
- isPanelVisibleAndNodeValid() {
- return this.isPanelVisible() &&
- this.inspector.selection.isConnected() &&
- this.inspector.selection.isElementNode();
- },
-
- /**
* Load the grid highligher display settings into the store from the stored preferences.
*/
loadHighlighterSettings() {
let { dispatch } = this.store;
let showGridLineNumbers = Services.prefs.getBoolPref(SHOW_GRID_LINE_NUMBERS);
let showInfinteLines = Services.prefs.getBoolPref(SHOW_INFINITE_LINES_PREF);
dispatch(updateShowGridLineNumbers(showGridLineNumbers));
dispatch(updateShowInfiniteLines(showInfinteLines));
},
/**
- * Starts listening to reflows in the current tab.
- */
- trackReflows() {
- if (!this.reflowFront) {
- let { target } = this.inspector;
- if (target.form.reflowActor) {
- this.reflowFront = ReflowFront(target.client,
- target.form);
- } else {
- return;
- }
- }
-
- this.reflowFront.on("reflows", this.updateBoxModel);
- this.reflowFront.start();
- },
-
- /**
- * Stops listening to reflows in the current tab.
- */
- untrackReflows() {
- if (!this.reflowFront) {
- return;
- }
-
- this.reflowFront.off("reflows", this.updateBoxModel);
- this.reflowFront.stop();
- },
-
- /**
- * Updates the box model panel by dispatching the new layout data.
- */
- updateBoxModel() {
- let lastRequest = Task.spawn((function* () {
- if (!(this.isPanelVisible() &&
- this.inspector.selection.isConnected() &&
- this.inspector.selection.isElementNode())) {
- return null;
- }
-
- let node = this.inspector.selection.nodeFront;
- let layout = yield this.inspector.pageStyle.getLayout(node, {
- autoMargins: true,
- });
- let styleEntries = yield this.inspector.pageStyle.getApplied(node, {});
- this.elementRules = styleEntries.map(e => e.rule);
-
- // Update the redux store with the latest layout properties and update the box
- // model view.
- this.store.dispatch(updateLayout(layout));
-
- // If a subsequent request has been made, wait for that one instead.
- if (this._lastRequest != lastRequest) {
- return this._lastRequest;
- }
-
- this._lastRequest = null;
-
- this.inspector.emit("boxmodel-view-updated");
- return null;
- }).bind(this)).catch(console.error);
-
- this._lastRequest = lastRequest;
- },
-
- /**
* Updates the grid panel by dispatching the new grid data. This is called when the
* layout view becomes visible or the view needs to be updated with new grid data.
*
* @param {Array|null} gridFronts
* Optional array of all GridFront in the current page.
*/
updateGridPanel: Task.async(function* (gridFronts) {
// Stop refreshing if the inspector or store is already destroyed.
@@ -522,44 +347,26 @@ LayoutView.prototype = {
* is shown for.
*/
onHighlighterChange(event, nodeFront) {
let highlighted = event === "grid-highlighter-shown";
this.store.dispatch(updateGridHighlighted(nodeFront, highlighted));
},
/**
- * Selection 'new-node-front' event handler.
- */
- onNewSelection: function () {
- if (!this.isPanelVisibleAndNodeValid()) {
- return;
- }
-
- this.updateBoxModel();
- },
-
- /**
* Handler for the inspector sidebar select event. Starts listening for
* "grid-layout-changed" if the layout panel is visible. Otherwise, stop
* listening for grid layout changes. Finally, refresh the layout view if
* it is visible.
*/
onSidebarSelect() {
if (!this.isPanelVisible()) {
this.layoutInspector.off("grid-layout-changed", this.onGridLayoutChange);
- this.untrackReflows();
return;
}
- if (this.inspector.selection.isConnected() &&
- this.inspector.selection.isElementNode()) {
- this.trackReflows();
- }
-
this.layoutInspector.on("grid-layout-changed", this.onGridLayoutChange);
- this.updateBoxModel();
this.updateGridPanel();
},
};
module.exports = LayoutView;
--- a/devtools/client/shared/browser-loader.js
+++ b/devtools/client/shared/browser-loader.js
@@ -7,16 +7,17 @@ var Cu = Components.utils;
const loaders = Cu.import("resource://gre/modules/commonjs/toolkit/loader.js", {});
const { devtools } = Cu.import("resource://devtools/shared/Loader.jsm", {});
const { joinURI } = devtools.require("devtools/shared/path");
const { assert } = devtools.require("devtools/shared/DevToolsUtils");
const Services = devtools.require("Services");
const { AppConstants } = devtools.require("resource://gre/modules/AppConstants.jsm");
const BROWSER_BASED_DIRS = [
+ "resource://devtools/client/inspector/boxmodel",
"resource://devtools/client/inspector/layout",
"resource://devtools/client/jsonview",
"resource://devtools/client/shared/vendor",
"resource://devtools/client/shared/redux",
];
const COMMON_LIBRARY_DIRS = [
"resource://devtools/client/shared/vendor",