2012-11-30 12:07:59 +04:00
|
|
|
/* 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";
|
|
|
|
|
2018-03-14 19:31:12 +03:00
|
|
|
const EventEmitter = require("devtools/shared/event-emitter");
|
2015-08-26 16:05:13 +03:00
|
|
|
const promise = require("promise");
|
2016-02-27 15:51:10 +03:00
|
|
|
const Services = require("Services");
|
2012-11-30 12:07:59 +04:00
|
|
|
|
2017-04-27 17:05:31 +03:00
|
|
|
loader.lazyRequireGetter(
|
|
|
|
this,
|
|
|
|
"gDevToolsBrowser",
|
|
|
|
"devtools/client/framework/devtools-browser",
|
|
|
|
true
|
|
|
|
);
|
2015-12-03 17:42:35 +03:00
|
|
|
|
2019-12-12 16:17:10 +03:00
|
|
|
loader.lazyRequireGetter(
|
|
|
|
this,
|
|
|
|
"PrivateBrowsingUtils",
|
|
|
|
"resource://gre/modules/PrivateBrowsingUtils.jsm",
|
|
|
|
true
|
|
|
|
);
|
|
|
|
|
2015-03-27 20:35:32 +03:00
|
|
|
/* A host should always allow this much space for the page to be displayed.
|
|
|
|
* There is also a min-height on the browser, but we still don't want to set
|
|
|
|
* frame.height to be larger than that, since it can cause problems with
|
|
|
|
* resizing the toolbox and panel layout. */
|
2015-06-01 17:39:41 +03:00
|
|
|
const MIN_PAGE_SIZE = 25;
|
2015-03-27 20:35:32 +03:00
|
|
|
|
2020-01-27 19:07:37 +03:00
|
|
|
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
|
|
|
|
2012-11-30 12:07:59 +04:00
|
|
|
/**
|
|
|
|
* A toolbox host represents an object that contains a toolbox (e.g. the
|
|
|
|
* sidebar or a separate window). Any host object should implement the
|
|
|
|
* following functions:
|
|
|
|
*
|
2020-01-20 17:00:02 +03:00
|
|
|
* create() - create the UI
|
2012-11-30 12:07:59 +04:00
|
|
|
* destroy() - destroy the host's UI
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Host object for the dock on the bottom of the browser
|
|
|
|
*/
|
|
|
|
function BottomHost(hostTab) {
|
|
|
|
this.hostTab = hostTab;
|
|
|
|
|
2012-12-14 11:05:00 +04:00
|
|
|
EventEmitter.decorate(this);
|
2012-11-30 12:07:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
BottomHost.prototype = {
|
|
|
|
type: "bottom",
|
|
|
|
|
|
|
|
heightPref: "devtools.toolbox.footer.height",
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a box at the bottom of the host tab.
|
|
|
|
*/
|
2018-03-12 21:24:38 +03:00
|
|
|
create: async function() {
|
2017-04-27 17:05:31 +03:00
|
|
|
await gDevToolsBrowser.loadBrowserStyleSheet(this.hostTab.ownerGlobal);
|
2012-12-13 17:03:55 +04:00
|
|
|
|
2018-06-01 13:36:09 +03:00
|
|
|
const gBrowser = this.hostTab.ownerDocument.defaultView.gBrowser;
|
|
|
|
const ownerDocument = gBrowser.ownerDocument;
|
2018-11-08 18:31:37 +03:00
|
|
|
this._browserContainer = gBrowser.getBrowserContainer(
|
|
|
|
this.hostTab.linkedBrowser
|
|
|
|
);
|
2012-11-30 12:07:59 +04:00
|
|
|
|
2018-08-25 03:16:27 +03:00
|
|
|
this._splitter = ownerDocument.createXULElement("splitter");
|
2012-11-30 12:07:59 +04:00
|
|
|
this._splitter.setAttribute("class", "devtools-horizontal-splitter");
|
2016-07-07 18:38:27 +03:00
|
|
|
// Avoid resizing notification containers
|
|
|
|
this._splitter.setAttribute("resizebefore", "flex");
|
2012-11-30 12:07:59 +04:00
|
|
|
|
2019-04-10 04:04:37 +03:00
|
|
|
this.frame = createDevToolsFrame(
|
|
|
|
ownerDocument,
|
|
|
|
"devtools-toolbox-bottom-iframe"
|
|
|
|
);
|
2015-03-25 22:01:00 +03:00
|
|
|
this.frame.height = Math.min(
|
|
|
|
Services.prefs.getIntPref(this.heightPref),
|
2018-11-08 18:31:37 +03:00
|
|
|
this._browserContainer.clientHeight - MIN_PAGE_SIZE
|
2015-03-25 22:01:00 +03:00
|
|
|
);
|
2012-11-30 12:07:59 +04:00
|
|
|
|
2018-11-08 18:31:37 +03:00
|
|
|
this._browserContainer.appendChild(this._splitter);
|
|
|
|
this._browserContainer.appendChild(this.frame);
|
2012-11-30 12:07:59 +04:00
|
|
|
|
2020-01-08 15:58:55 +03:00
|
|
|
focusTab(this.hostTab);
|
|
|
|
return this.frame;
|
2012-11-30 12:07:59 +04:00
|
|
|
},
|
|
|
|
|
2013-01-09 13:32:35 +04:00
|
|
|
/**
|
|
|
|
* Raise the host.
|
|
|
|
*/
|
2018-03-12 21:24:38 +03:00
|
|
|
raise: function() {
|
2013-01-09 13:32:35 +04:00
|
|
|
focusTab(this.hostTab);
|
|
|
|
},
|
|
|
|
|
2013-02-26 16:40:19 +04:00
|
|
|
/**
|
|
|
|
* Set the toolbox title.
|
2015-06-08 17:03:49 +03:00
|
|
|
* Nothing to do for this host type.
|
2013-02-26 16:40:19 +04:00
|
|
|
*/
|
2018-03-12 21:24:38 +03:00
|
|
|
setTitle: function() {},
|
2013-02-26 16:40:19 +04:00
|
|
|
|
2012-11-30 12:07:59 +04:00
|
|
|
/**
|
|
|
|
* Destroy the bottom dock.
|
|
|
|
*/
|
2018-03-12 21:24:38 +03:00
|
|
|
destroy: function() {
|
2012-12-13 17:03:55 +04:00
|
|
|
if (!this._destroyed) {
|
|
|
|
this._destroyed = true;
|
|
|
|
|
|
|
|
Services.prefs.setIntPref(this.heightPref, this.frame.height);
|
2018-11-08 18:31:37 +03:00
|
|
|
this._browserContainer.removeChild(this._splitter);
|
|
|
|
this._browserContainer.removeChild(this.frame);
|
2016-09-12 13:21:40 +03:00
|
|
|
this.frame = null;
|
2018-11-08 18:31:37 +03:00
|
|
|
this._browserContainer = null;
|
2016-09-12 13:21:40 +03:00
|
|
|
this._splitter = null;
|
2012-11-30 12:07:59 +04:00
|
|
|
}
|
|
|
|
|
2013-07-11 11:12:20 +04:00
|
|
|
return promise.resolve(null);
|
2012-11-30 12:07:59 +04:00
|
|
|
},
|
2015-06-08 17:03:49 +03:00
|
|
|
};
|
2012-11-30 12:07:59 +04:00
|
|
|
|
|
|
|
/**
|
2018-06-07 19:45:53 +03:00
|
|
|
* Base Host object for the in-browser sidebar
|
2012-11-30 12:07:59 +04:00
|
|
|
*/
|
2018-06-07 19:45:53 +03:00
|
|
|
class SidebarHost {
|
2018-06-08 07:18:54 +03:00
|
|
|
constructor(hostTab, type) {
|
2018-06-07 19:45:53 +03:00
|
|
|
this.hostTab = hostTab;
|
2018-06-08 07:18:54 +03:00
|
|
|
this.type = type;
|
2018-06-07 19:45:53 +03:00
|
|
|
this.widthPref = "devtools.toolbox.sidebar.width";
|
2012-11-30 12:07:59 +04:00
|
|
|
|
2018-06-07 19:45:53 +03:00
|
|
|
EventEmitter.decorate(this);
|
|
|
|
}
|
2012-11-30 12:07:59 +04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a box in the sidebar of the host tab.
|
|
|
|
*/
|
2018-06-07 19:45:53 +03:00
|
|
|
async create() {
|
2017-04-27 17:05:31 +03:00
|
|
|
await gDevToolsBrowser.loadBrowserStyleSheet(this.hostTab.ownerGlobal);
|
2018-06-01 13:36:09 +03:00
|
|
|
const gBrowser = this.hostTab.ownerDocument.defaultView.gBrowser;
|
|
|
|
const ownerDocument = gBrowser.ownerDocument;
|
2018-11-08 18:31:37 +03:00
|
|
|
this._browserContainer = gBrowser.getBrowserContainer(
|
|
|
|
this.hostTab.linkedBrowser
|
|
|
|
);
|
|
|
|
this._browserPanel = gBrowser.getPanel(this.hostTab.linkedBrowser);
|
2012-11-30 12:07:59 +04:00
|
|
|
|
2018-08-25 03:16:27 +03:00
|
|
|
this._splitter = ownerDocument.createXULElement("splitter");
|
2012-11-30 12:07:59 +04:00
|
|
|
this._splitter.setAttribute("class", "devtools-side-splitter");
|
|
|
|
|
2019-04-10 04:04:37 +03:00
|
|
|
this.frame = createDevToolsFrame(
|
|
|
|
ownerDocument,
|
|
|
|
"devtools-toolbox-side-iframe"
|
|
|
|
);
|
2015-03-25 22:01:00 +03:00
|
|
|
this.frame.width = Math.min(
|
|
|
|
Services.prefs.getIntPref(this.widthPref),
|
2018-11-08 18:31:37 +03:00
|
|
|
this._browserPanel.clientWidth - MIN_PAGE_SIZE
|
2015-03-25 22:01:00 +03:00
|
|
|
);
|
|
|
|
|
2018-08-24 03:09:34 +03:00
|
|
|
// We should consider the direction when changing the dock position.
|
|
|
|
const topWindow = this.hostTab.ownerDocument.defaultView.top;
|
|
|
|
const topDoc = topWindow.document.documentElement;
|
|
|
|
const isLTR = topWindow.getComputedStyle(topDoc).direction === "ltr";
|
|
|
|
|
|
|
|
if ((isLTR && this.type == "right") || (!isLTR && this.type == "left")) {
|
2018-11-08 18:31:37 +03:00
|
|
|
this._browserPanel.appendChild(this._splitter);
|
|
|
|
this._browserPanel.appendChild(this.frame);
|
2018-06-07 19:45:53 +03:00
|
|
|
} else {
|
2018-11-08 18:31:37 +03:00
|
|
|
this._browserPanel.insertBefore(this.frame, this._browserContainer);
|
|
|
|
this._browserPanel.insertBefore(this._splitter, this._browserContainer);
|
2018-06-07 19:45:53 +03:00
|
|
|
}
|
2012-11-30 12:07:59 +04:00
|
|
|
|
2020-01-08 15:58:55 +03:00
|
|
|
focusTab(this.hostTab);
|
|
|
|
return this.frame;
|
2018-06-07 19:45:53 +03:00
|
|
|
}
|
2012-11-30 12:07:59 +04:00
|
|
|
|
2013-01-09 13:32:35 +04:00
|
|
|
/**
|
|
|
|
* Raise the host.
|
|
|
|
*/
|
2018-06-07 19:45:53 +03:00
|
|
|
raise() {
|
2013-01-09 13:32:35 +04:00
|
|
|
focusTab(this.hostTab);
|
2018-06-07 19:45:53 +03:00
|
|
|
}
|
2013-01-09 13:32:35 +04:00
|
|
|
|
2013-02-26 16:40:19 +04:00
|
|
|
/**
|
|
|
|
* Set the toolbox title.
|
2015-06-08 17:03:49 +03:00
|
|
|
* Nothing to do for this host type.
|
2013-02-26 16:40:19 +04:00
|
|
|
*/
|
2018-06-07 19:45:53 +03:00
|
|
|
setTitle() {}
|
2013-02-26 16:40:19 +04:00
|
|
|
|
2012-11-30 12:07:59 +04:00
|
|
|
/**
|
|
|
|
* Destroy the sidebar.
|
|
|
|
*/
|
2018-06-07 19:45:53 +03:00
|
|
|
destroy() {
|
2012-12-13 17:03:55 +04:00
|
|
|
if (!this._destroyed) {
|
|
|
|
this._destroyed = true;
|
2012-11-30 12:07:59 +04:00
|
|
|
|
2012-12-13 17:03:55 +04:00
|
|
|
Services.prefs.setIntPref(this.widthPref, this.frame.width);
|
2018-11-08 18:31:37 +03:00
|
|
|
this._browserPanel.removeChild(this._splitter);
|
|
|
|
this._browserPanel.removeChild(this.frame);
|
2012-12-13 17:03:55 +04:00
|
|
|
}
|
|
|
|
|
2013-07-11 11:12:20 +04:00
|
|
|
return promise.resolve(null);
|
2012-11-30 12:07:59 +04:00
|
|
|
}
|
2018-06-07 19:45:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Host object for the in-browser left sidebar
|
|
|
|
*/
|
|
|
|
class LeftHost extends SidebarHost {
|
|
|
|
constructor(hostTab) {
|
|
|
|
super(hostTab, "left");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Host object for the in-browser right sidebar
|
|
|
|
*/
|
|
|
|
class RightHost extends SidebarHost {
|
|
|
|
constructor(hostTab) {
|
|
|
|
super(hostTab, "right");
|
|
|
|
}
|
|
|
|
}
|
2012-11-30 12:07:59 +04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Host object for the toolbox in a separate window
|
|
|
|
*/
|
2019-12-12 16:17:10 +03:00
|
|
|
function WindowHost(hostTab) {
|
2012-11-30 12:07:59 +04:00
|
|
|
this._boundUnload = this._boundUnload.bind(this);
|
2019-12-12 16:17:10 +03:00
|
|
|
this.hostTab = hostTab;
|
2012-12-14 11:05:00 +04:00
|
|
|
EventEmitter.decorate(this);
|
2012-11-30 12:07:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
WindowHost.prototype = {
|
|
|
|
type: "window",
|
|
|
|
|
2019-11-14 02:44:19 +03:00
|
|
|
WINDOW_URL: "chrome://devtools/content/framework/toolbox-window.xhtml",
|
2012-11-30 12:07:59 +04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a new xul window to contain the toolbox.
|
|
|
|
*/
|
2018-03-12 21:24:38 +03:00
|
|
|
create: function() {
|
2018-07-03 09:16:31 +03:00
|
|
|
return new Promise(resolve => {
|
2019-12-12 16:17:10 +03:00
|
|
|
let flags = "chrome,centerscreen,resizable,dialog=no";
|
|
|
|
|
|
|
|
// If we are debugging a tab which is in a Private window, we must also
|
|
|
|
// set the private flag on the DevTools host window. Otherwise switching
|
|
|
|
// hosts between docked and window modes can fail due to incompatible
|
|
|
|
// docshell origin attributes. See 1581093.
|
|
|
|
if (
|
|
|
|
this.hostTab &&
|
|
|
|
PrivateBrowsingUtils.isWindowPrivate(this.hostTab.ownerGlobal)
|
|
|
|
) {
|
|
|
|
flags += ",private";
|
|
|
|
}
|
|
|
|
|
2018-07-03 09:16:31 +03:00
|
|
|
const win = Services.ww.openWindow(
|
|
|
|
null,
|
|
|
|
this.WINDOW_URL,
|
|
|
|
"_blank",
|
|
|
|
flags,
|
|
|
|
null
|
|
|
|
);
|
2012-12-13 17:03:55 +04:00
|
|
|
|
2018-07-03 09:16:31 +03:00
|
|
|
const frameLoad = () => {
|
|
|
|
win.removeEventListener("load", frameLoad, true);
|
|
|
|
win.focus();
|
|
|
|
|
2019-04-10 04:04:38 +03:00
|
|
|
this.frame = createDevToolsFrame(
|
|
|
|
win.document,
|
|
|
|
"devtools-toolbox-window-iframe"
|
|
|
|
);
|
|
|
|
win.document
|
|
|
|
.getElementById("devtools-toolbox-window")
|
|
|
|
.appendChild(this.frame);
|
|
|
|
|
|
|
|
// The forceOwnRefreshDriver attribute is set to avoid Windows only issues with
|
|
|
|
// CSS transitions when switching from docked to window hosts.
|
|
|
|
// Added in Bug 832920, should be reviewed in Bug 1542468.
|
|
|
|
this.frame.setAttribute("forceOwnRefreshDriver", "");
|
2018-07-03 09:16:31 +03:00
|
|
|
resolve(this.frame);
|
|
|
|
};
|
2012-11-30 12:07:59 +04:00
|
|
|
|
2018-07-03 09:16:31 +03:00
|
|
|
win.addEventListener("load", frameLoad, true);
|
|
|
|
win.addEventListener("unload", this._boundUnload);
|
2012-12-13 17:03:55 +04:00
|
|
|
|
2018-07-03 09:16:31 +03:00
|
|
|
this._window = win;
|
|
|
|
});
|
2012-11-30 12:07:59 +04:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Catch the user closing the window.
|
|
|
|
*/
|
2018-03-12 21:24:38 +03:00
|
|
|
_boundUnload: function(event) {
|
2012-11-30 12:07:59 +04:00
|
|
|
if (event.target.location != this.WINDOW_URL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this._window.removeEventListener("unload", this._boundUnload);
|
|
|
|
|
|
|
|
this.emit("window-closed");
|
|
|
|
},
|
|
|
|
|
2013-01-09 13:32:35 +04:00
|
|
|
/**
|
|
|
|
* Raise the host.
|
|
|
|
*/
|
2018-03-12 21:24:38 +03:00
|
|
|
raise: function() {
|
2013-01-09 13:32:35 +04:00
|
|
|
this._window.focus();
|
|
|
|
},
|
|
|
|
|
2013-02-26 16:40:19 +04:00
|
|
|
/**
|
|
|
|
* Set the toolbox title.
|
|
|
|
*/
|
2018-03-12 21:24:38 +03:00
|
|
|
setTitle: function(title) {
|
2013-02-26 16:40:19 +04:00
|
|
|
this._window.document.title = title;
|
|
|
|
},
|
|
|
|
|
2012-11-30 12:07:59 +04:00
|
|
|
/**
|
|
|
|
* Destroy the window.
|
|
|
|
*/
|
2018-03-12 21:24:38 +03:00
|
|
|
destroy: function() {
|
2012-12-13 17:03:55 +04:00
|
|
|
if (!this._destroyed) {
|
|
|
|
this._destroyed = true;
|
|
|
|
|
|
|
|
this._window.removeEventListener("unload", this._boundUnload);
|
|
|
|
this._window.close();
|
|
|
|
}
|
|
|
|
|
2013-07-11 11:12:20 +04:00
|
|
|
return promise.resolve(null);
|
2012-11-30 12:07:59 +04:00
|
|
|
},
|
2013-12-02 12:28:01 +04:00
|
|
|
};
|
2012-11-30 12:07:59 +04:00
|
|
|
|
2013-11-16 06:47:00 +04:00
|
|
|
/**
|
2020-01-08 14:28:12 +03:00
|
|
|
* Host object for the Browser Toolbox
|
2013-11-16 06:47:00 +04:00
|
|
|
*/
|
2020-01-08 14:28:12 +03:00
|
|
|
function BrowserToolboxHost(hostTab, options) {
|
2020-01-08 15:58:55 +03:00
|
|
|
this.doc = options.doc;
|
2013-11-16 06:47:00 +04:00
|
|
|
EventEmitter.decorate(this);
|
|
|
|
}
|
|
|
|
|
2020-01-08 14:28:12 +03:00
|
|
|
BrowserToolboxHost.prototype = {
|
|
|
|
type: "browsertoolbox",
|
2013-11-16 06:47:00 +04:00
|
|
|
|
2020-01-08 15:58:55 +03:00
|
|
|
create: async function() {
|
|
|
|
this.frame = createDevToolsFrame(
|
|
|
|
this.doc,
|
|
|
|
"devtools-toolbox-browsertoolbox-iframe"
|
|
|
|
);
|
2013-11-16 06:47:00 +04:00
|
|
|
|
2020-01-08 15:58:55 +03:00
|
|
|
this.doc.body.appendChild(this.frame);
|
|
|
|
|
|
|
|
return this.frame;
|
2013-11-16 06:47:00 +04:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Raise the host.
|
|
|
|
*/
|
2018-03-12 21:24:38 +03:00
|
|
|
raise: function() {
|
2020-01-08 15:58:55 +03:00
|
|
|
this.doc.defaultView.focus();
|
2013-11-16 06:47:00 +04:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the toolbox title.
|
|
|
|
*/
|
2018-03-12 21:24:38 +03:00
|
|
|
setTitle: function(title) {
|
2020-01-08 15:58:55 +03:00
|
|
|
this.doc.title = title;
|
2013-11-16 06:47:00 +04:00
|
|
|
},
|
|
|
|
|
2020-01-08 15:58:55 +03:00
|
|
|
// Do nothing. The BrowserToolbox is destroyed by quitting the application.
|
2018-03-12 21:24:38 +03:00
|
|
|
destroy: function() {
|
2013-11-16 06:47:00 +04:00
|
|
|
return promise.resolve(null);
|
|
|
|
},
|
2015-06-08 17:03:49 +03:00
|
|
|
};
|
2013-11-16 06:47:00 +04:00
|
|
|
|
2019-01-31 21:08:19 +03:00
|
|
|
/**
|
|
|
|
* Host object for the toolbox as a page.
|
|
|
|
* This is typically used by `about:debugging`, when opening toolbox in a new tab,
|
|
|
|
* via `about:devtools-toolbox` URLs.
|
|
|
|
* The `iframe` ends up being the tab's browser element.
|
|
|
|
*/
|
|
|
|
function PageHost(hostTab, options) {
|
|
|
|
this.frame = options.customIframe;
|
|
|
|
}
|
|
|
|
|
|
|
|
PageHost.prototype = {
|
|
|
|
type: "page",
|
|
|
|
|
|
|
|
create: function() {
|
|
|
|
return promise.resolve(this.frame);
|
|
|
|
},
|
|
|
|
|
|
|
|
// Do nothing.
|
|
|
|
raise: function() {},
|
|
|
|
|
|
|
|
// Do nothing.
|
|
|
|
setTitle: function(title) {},
|
|
|
|
|
|
|
|
// Do nothing.
|
|
|
|
destroy: function() {
|
|
|
|
return promise.resolve(null);
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2012-11-30 12:07:59 +04:00
|
|
|
/**
|
|
|
|
* Switch to the given tab in a browser and focus the browser window
|
|
|
|
*/
|
|
|
|
function focusTab(tab) {
|
2018-06-01 13:36:09 +03:00
|
|
|
const browserWindow = tab.ownerDocument.defaultView;
|
2012-11-30 12:07:59 +04:00
|
|
|
browserWindow.focus();
|
|
|
|
browserWindow.gBrowser.selectedTab = tab;
|
|
|
|
}
|
2018-06-07 19:45:53 +03:00
|
|
|
|
2019-04-10 04:04:37 +03:00
|
|
|
/**
|
|
|
|
* Create an iframe that can be used to load DevTools via about:devtools-toolbox.
|
|
|
|
*/
|
|
|
|
function createDevToolsFrame(doc, className) {
|
2020-01-14 17:45:41 +03:00
|
|
|
const frame = doc.createXULElement("browser");
|
|
|
|
frame.setAttribute("type", "content");
|
2019-10-07 22:35:07 +03:00
|
|
|
frame.flex = 1; // Required to be able to shrink when the window shrinks
|
|
|
|
frame.className = className;
|
2020-01-27 19:07:37 +03:00
|
|
|
|
|
|
|
const inXULDocument = doc.documentElement.namespaceURI === XUL_NS;
|
|
|
|
if (inXULDocument) {
|
|
|
|
// When the toolbox frame is loaded in a XUL document, tooltips rely on a
|
|
|
|
// special XUL <tooltip id="aHTMLTooltip"> element.
|
|
|
|
// This attribute should not be set when the frame is loaded in a HTML
|
|
|
|
// document (for instance: Browser Toolbox).
|
|
|
|
frame.tooltip = "aHTMLTooltip";
|
|
|
|
}
|
2019-04-10 04:04:37 +03:00
|
|
|
return frame;
|
|
|
|
}
|
|
|
|
|
2018-06-07 19:45:53 +03:00
|
|
|
exports.Hosts = {
|
|
|
|
bottom: BottomHost,
|
|
|
|
left: LeftHost,
|
|
|
|
right: RightHost,
|
|
|
|
window: WindowHost,
|
2020-01-08 14:28:12 +03:00
|
|
|
browsertoolbox: BrowserToolboxHost,
|
2019-01-31 21:08:19 +03:00
|
|
|
page: PageHost,
|
2018-06-07 19:45:53 +03:00
|
|
|
};
|