Merge m-c to m-i
MozReview-Commit-ID: LUDPZ08eWBo
2
CLOBBER
@ -22,4 +22,4 @@
|
||||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
Bug 1306438 and bug 1304815 - Rust update and related changes require clobber
|
||||
Bug 1311178 - File removals in devtools on OS X
|
||||
|
@ -33,11 +33,6 @@ var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptS
|
||||
|
||||
var permissionSpecificChecker = {};
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this,
|
||||
"TelephonyService",
|
||||
"@mozilla.org/telephony/telephonyservice;1",
|
||||
"nsITelephonyService");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
|
||||
"resource://gre/modules/SystemAppProxy.jsm");
|
||||
|
||||
@ -454,22 +449,6 @@ ContentPermissionPrompt.prototype = {
|
||||
permissionSpecificChecker["audio-capture"] = function(request) {
|
||||
let forbid = false;
|
||||
|
||||
try {
|
||||
// nsITelephonyService.enumerateCalls is synchronous.
|
||||
TelephonyService.enumerateCalls({
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsITelephonyListener]),
|
||||
enumerateCallStateComplete: function() {},
|
||||
enumerateCallState: function(callInfo) {
|
||||
if (callInfo.callState == Ci.nsITelephonyService.CALL_STATE_CONNECTED) {
|
||||
forbid = true;
|
||||
}
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
// No restriction if Telephony service doesn't exist.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (forbid) {
|
||||
request.cancel();
|
||||
}
|
||||
|
@ -193,7 +193,6 @@
|
||||
@RESPATH@/components/dom_mobilemessage.xpt
|
||||
@RESPATH@/components/dom_storage.xpt
|
||||
@RESPATH@/components/dom_stylesheets.xpt
|
||||
@RESPATH@/components/dom_telephony.xpt
|
||||
@RESPATH@/components/dom_threads.xpt
|
||||
@RESPATH@/components/dom_traversal.xpt
|
||||
@RESPATH@/components/dom_tv.xpt
|
||||
@ -468,13 +467,7 @@
|
||||
@RESPATH@/components/StkCmdFactory.manifest
|
||||
@RESPATH@/components/RILSystemMessengerHelper.js
|
||||
@RESPATH@/components/RILSystemMessengerHelper.manifest
|
||||
@RESPATH@/components/TelephonyAudioService.js
|
||||
@RESPATH@/components/TelephonyAudioService.manifest
|
||||
@RESPATH@/components/USSDReceivedWrapper.js
|
||||
@RESPATH@/components/USSDReceivedWrapper.manifest
|
||||
#ifndef DISABLE_MOZ_RIL_GEOLOC
|
||||
@RESPATH@/components/TelephonyService.js
|
||||
@RESPATH@/components/TelephonyService.manifest
|
||||
#endif
|
||||
#endif // MOZ_WIDGET_GONK && MOZ_B2G_RIL
|
||||
|
||||
|
@ -1127,11 +1127,7 @@ pref("services.sync.prefs.sync.xpinstall.whitelist.required", true);
|
||||
// user's tabs and bookmarks. Note this pref is also synced.
|
||||
pref("services.sync.syncedTabs.showRemoteIcons", true);
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
pref("services.sync.sendTabToDevice.enabled", true);
|
||||
#else
|
||||
pref("services.sync.sendTabToDevice.enabled", false);
|
||||
#endif
|
||||
|
||||
// Developer edition preferences
|
||||
#ifdef MOZ_DEV_EDITION
|
||||
@ -1543,10 +1539,10 @@ pref("webchannel.allowObject.urlWhitelist", "https://accounts.firefox.com https:
|
||||
// Whether or not the browser should scan for unsubmitted
|
||||
// crash reports, and then show a notification for submitting
|
||||
// those reports.
|
||||
#ifdef RELEASE_OR_BETA
|
||||
pref("browser.crashReports.unsubmittedCheck.enabled", false);
|
||||
#else
|
||||
#ifdef EARLY_BETA_OR_EARLIER
|
||||
pref("browser.crashReports.unsubmittedCheck.enabled", true);
|
||||
#else
|
||||
pref("browser.crashReports.unsubmittedCheck.enabled", false);
|
||||
#endif
|
||||
|
||||
// chancesUntilSuppress is how many times we'll show the unsubmitted
|
||||
|
@ -398,9 +398,11 @@ function findChildShell(aDocument, aDocShell, aSoughtURI) {
|
||||
var gPopupBlockerObserver = {
|
||||
_reportButton: null,
|
||||
|
||||
onReportButtonClick: function (aEvent)
|
||||
onReportButtonMousedown: function (aEvent)
|
||||
{
|
||||
if (aEvent.button != 0 || aEvent.target != this._reportButton)
|
||||
// If this method is called on the same event tick as the popup gets
|
||||
// hidden, do nothing to avoid re-opening the popup.
|
||||
if (aEvent.button != 0 || aEvent.target != this._reportButton || this.isPopupHidingTick)
|
||||
return;
|
||||
|
||||
document.getElementById("blockedPopupOptions")
|
||||
@ -598,6 +600,9 @@ var gPopupBlockerObserver = {
|
||||
if (aEvent.target.anchorNode.id == "page-report-button")
|
||||
aEvent.target.anchorNode.removeAttribute("open");
|
||||
|
||||
this.isPopupHidingTick = true;
|
||||
setTimeout(() => this.isPopupHidingTick = false, 0);
|
||||
|
||||
let item = aEvent.target.lastChild;
|
||||
while (item && item.getAttribute("observes") != "blockedPopupsSeparator") {
|
||||
let next = item.previousSibling;
|
||||
|
@ -766,7 +766,7 @@
|
||||
class="urlbar-icon"
|
||||
hidden="true"
|
||||
tooltiptext="&pageReportIcon.tooltip;"
|
||||
onclick="gPopupBlockerObserver.onReportButtonClick(event);"/>
|
||||
onmousedown="gPopupBlockerObserver.onReportButtonMousedown(event);"/>
|
||||
<image id="reader-mode-button"
|
||||
class="urlbar-icon"
|
||||
hidden="true"
|
||||
|
@ -417,6 +417,7 @@
|
||||
<label id="security-technical-shortform" class="fieldValue"/>
|
||||
<description id="security-technical-longform1" class="fieldLabel"/>
|
||||
<description id="security-technical-longform2" class="fieldLabel"/>
|
||||
<description id="security-technical-certificate-transparency" class="fieldLabel"/>
|
||||
</vbox>
|
||||
</groupbox>
|
||||
<hbox pack="end">
|
||||
|
@ -65,7 +65,8 @@ var security = {
|
||||
isBroken : isBroken,
|
||||
isMixed : isMixed,
|
||||
isEV : isEV,
|
||||
cert : cert
|
||||
cert : cert,
|
||||
certificateTransparency : undefined
|
||||
};
|
||||
|
||||
var version;
|
||||
@ -95,6 +96,27 @@ var security = {
|
||||
break;
|
||||
}
|
||||
|
||||
// Select status text to display for Certificate Transparency.
|
||||
switch (status.certificateTransparencyStatus) {
|
||||
case nsISSLStatus.CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE:
|
||||
// CT compliance checks were not performed,
|
||||
// do not display any status text.
|
||||
retval.certificateTransparency = null;
|
||||
break;
|
||||
case nsISSLStatus.CERTIFICATE_TRANSPARENCY_NONE:
|
||||
retval.certificateTransparency = "None";
|
||||
break;
|
||||
case nsISSLStatus.CERTIFICATE_TRANSPARENCY_OK:
|
||||
retval.certificateTransparency = "OK";
|
||||
break;
|
||||
case nsISSLStatus.CERTIFICATE_TRANSPARENCY_UNKNOWN_LOG:
|
||||
retval.certificateTransparency = "UnknownLog";
|
||||
break;
|
||||
case nsISSLStatus.CERTIFICATE_TRANSPARENCY_INVALID:
|
||||
retval.certificateTransparency = "Invalid";
|
||||
break;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
return {
|
||||
@ -106,7 +128,8 @@ var security = {
|
||||
isBroken : isBroken,
|
||||
isMixed : isMixed,
|
||||
isEV : isEV,
|
||||
cert : null
|
||||
cert : null,
|
||||
certificateTransparency : null
|
||||
};
|
||||
},
|
||||
|
||||
@ -283,6 +306,16 @@ function securityOnLoad(uri, windowInfo) {
|
||||
setText("security-technical-shortform", hdr);
|
||||
setText("security-technical-longform1", msg1);
|
||||
setText("security-technical-longform2", msg2);
|
||||
|
||||
const ctStatus =
|
||||
document.getElementById("security-technical-certificate-transparency");
|
||||
if (info.certificateTransparency) {
|
||||
ctStatus.hidden = false;
|
||||
ctStatus.value = pkiBundle.getString(
|
||||
"pageInfo_CertificateTransparency_" + info.certificateTransparency);
|
||||
} else {
|
||||
ctStatus.hidden = true;
|
||||
}
|
||||
}
|
||||
|
||||
function setText(id, value)
|
||||
|
@ -53,11 +53,6 @@ let allowedImageReferences = [
|
||||
{file: "chrome://devtools/skin/images/dock-bottom-maximize@2x.png",
|
||||
from: "chrome://devtools/skin/toolbox.css",
|
||||
isFromDevTools: true},
|
||||
|
||||
// Bug 1302708
|
||||
{file: "chrome/devtools/modules/devtools/client/themes/images/filter.svg",
|
||||
from: "chrome/devtools/modules/devtools/client/themes/common.css",
|
||||
isFromDevTools: true},
|
||||
];
|
||||
|
||||
var moduleLocation = gTestPath.replace(/\/[^\/]*$/i, "/parsingTestHelpers.jsm");
|
||||
|
@ -210,7 +210,6 @@
|
||||
@RESPATH@/components/dom_sidebar.xpt
|
||||
@RESPATH@/components/dom_storage.xpt
|
||||
@RESPATH@/components/dom_stylesheets.xpt
|
||||
@RESPATH@/components/dom_telephony.xpt
|
||||
@RESPATH@/components/dom_traversal.xpt
|
||||
#ifdef MOZ_WEBSPEECH
|
||||
@RESPATH@/components/dom_webspeechrecognition.xpt
|
||||
|
@ -55,7 +55,7 @@ module.exports = createClass({
|
||||
}
|
||||
tab.icon = prePath + "/favicon.ico";
|
||||
} else {
|
||||
tab.icon = "chrome://devtools/skin/images/tabs-icon.svg";
|
||||
tab.icon = "chrome://devtools/skin/images/globe.svg";
|
||||
}
|
||||
});
|
||||
this.setState({ tabs });
|
||||
|
@ -37,6 +37,5 @@ var test = Task.async(function* () {
|
||||
is(packet.frame.where.line, 3,
|
||||
"Should have stopped at line 3 (debugger statement), not line 2 (other tab's breakpoint)");
|
||||
|
||||
yield teardown(panel1);
|
||||
yield resumeDebuggerThenCloseAndFinish(panel2);
|
||||
});
|
||||
|
@ -84,7 +84,7 @@ function getHost(host) {
|
||||
|
||||
function resizeToolboxWindow(panel, host) {
|
||||
let sizeOption = host.split(":")[1];
|
||||
let win = panel._toolbox._host._window;
|
||||
let win = panel._toolbox.win.parent;
|
||||
|
||||
// should be the same value as BREAKPOINT_SMALL_WINDOW_WIDTH in debugger-view.js
|
||||
let breakpoint = 850;
|
||||
@ -101,7 +101,7 @@ function resizeToolboxWindow(panel, host) {
|
||||
function resizeAndWaitForLayoutChange(panel, width) {
|
||||
info("Updating toolbox window width to " + width);
|
||||
|
||||
let win = panel._toolbox._host._window;
|
||||
let win = panel._toolbox.win.parent;
|
||||
let gDebugger = panel.panelWin;
|
||||
|
||||
win.resizeTo(width, window.screen.availHeight);
|
||||
|
@ -9,137 +9,112 @@
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
|
||||
|
||||
var gTab, gPanel, gDebugger;
|
||||
var gFocusedWindow, gToolbox, gToolboxTab;
|
||||
|
||||
function test() {
|
||||
add_task(function *() {
|
||||
let options = {
|
||||
source: TAB_URL,
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gToolbox = gPanel._toolbox;
|
||||
gToolboxTab = gToolbox.doc.getElementById("toolbox-tab-jsdebugger");
|
||||
let [tab,, panel] = yield initDebugger(TAB_URL, options);
|
||||
let panelWin = panel.panelWin;
|
||||
let toolbox = panel._toolbox;
|
||||
let toolboxTab = toolbox.doc.getElementById("toolbox-tab-jsdebugger");
|
||||
|
||||
performTest();
|
||||
});
|
||||
}
|
||||
let newTab = yield addTab(TAB_URL);
|
||||
isnot(newTab, tab,
|
||||
"The newly added tab is different from the debugger's tab.");
|
||||
is(gBrowser.selectedTab, newTab,
|
||||
"Debugger's tab is not the selected tab.");
|
||||
|
||||
function performTest() {
|
||||
addTab(TAB_URL).then(aTab => {
|
||||
isnot(aTab, gTab,
|
||||
"The newly added tab is different from the debugger's tab.");
|
||||
is(gBrowser.selectedTab, aTab,
|
||||
"Debugger's tab is not the selected tab.");
|
||||
info("Run tests against bottom host.");
|
||||
yield testPause();
|
||||
yield testResume();
|
||||
|
||||
gFocusedWindow = window;
|
||||
testPause();
|
||||
});
|
||||
}
|
||||
// testResume selected the console, select back the debugger.
|
||||
yield toolbox.selectTool("jsdebugger");
|
||||
|
||||
function focusMainWindow() {
|
||||
// Make sure toolbox is not focused.
|
||||
window.addEventListener("focus", onFocus, true);
|
||||
info("Focusing main window.");
|
||||
info("Switching to a toolbox window host.");
|
||||
yield toolbox.switchHost(Toolbox.HostType.WINDOW);
|
||||
|
||||
// Execute soon to avoid any race conditions between toolbox and main window
|
||||
// getting focused.
|
||||
executeSoon(() => {
|
||||
window.focus();
|
||||
});
|
||||
}
|
||||
info("Run tests against window host.");
|
||||
yield testPause();
|
||||
yield testResume();
|
||||
|
||||
function onFocus() {
|
||||
window.removeEventListener("focus", onFocus, true);
|
||||
info("Main window focused.");
|
||||
info("Cleanup after the test.");
|
||||
yield toolbox.switchHost(Toolbox.HostType.BOTTOM);
|
||||
yield closeDebuggerAndFinish(panel);
|
||||
|
||||
gFocusedWindow = window;
|
||||
testPause();
|
||||
}
|
||||
function* testPause() {
|
||||
is(panelWin.gThreadClient.paused, false,
|
||||
"Should be running after starting the test.");
|
||||
|
||||
function testPause() {
|
||||
is(gDebugger.gThreadClient.paused, false,
|
||||
"Should be running after starting the test.");
|
||||
|
||||
is(gFocusedWindow, window,
|
||||
"Main window is the top level window before pause.");
|
||||
|
||||
if (gToolbox.hostType == Toolbox.HostType.WINDOW) {
|
||||
gToolbox._host._window.addEventListener("focus", function onFocus() {
|
||||
gToolbox._host._window.removeEventListener("focus", onFocus, true);
|
||||
gFocusedWindow = gToolbox._host._window;
|
||||
}, true);
|
||||
}
|
||||
|
||||
gDebugger.gThreadClient.addOneTimeListener("paused", () => {
|
||||
if (gToolbox.hostType == Toolbox.HostType.WINDOW) {
|
||||
is(gFocusedWindow, gToolbox._host._window,
|
||||
"Toolbox window is the top level window on pause.");
|
||||
let onFocus, onTabSelect;
|
||||
if (toolbox.hostType == Toolbox.HostType.WINDOW) {
|
||||
onFocus = new Promise(done => {
|
||||
toolbox.win.parent.addEventListener("focus", function onFocus() {
|
||||
toolbox.win.parent.removeEventListener("focus", onFocus, true);
|
||||
done();
|
||||
}, true);
|
||||
});
|
||||
} else {
|
||||
is(gBrowser.selectedTab, gTab,
|
||||
onTabSelect = new Promise(done => {
|
||||
tab.parentNode.addEventListener("TabSelect", function listener({type}) {
|
||||
tab.parentNode.removeEventListener(type, listener);
|
||||
done();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
let onPaused = waitForPause(panelWin.gThreadClient);
|
||||
|
||||
// Evaluate a script to fully pause the debugger
|
||||
evalInTab(tab, "debugger;");
|
||||
|
||||
yield onPaused;
|
||||
yield onFocus;
|
||||
yield onTabSelect;
|
||||
|
||||
if (toolbox.hostType != Toolbox.HostType.WINDOW) {
|
||||
is(gBrowser.selectedTab, tab,
|
||||
"Debugger's tab got selected.");
|
||||
}
|
||||
gToolbox.selectTool("webconsole").then(() => {
|
||||
ok(gToolboxTab.hasAttribute("highlighted") &&
|
||||
gToolboxTab.getAttribute("highlighted") == "true",
|
||||
"The highlighted class is present");
|
||||
ok(!gToolboxTab.hasAttribute("selected") ||
|
||||
gToolboxTab.getAttribute("selected") != "true",
|
||||
"The tab is not selected");
|
||||
}).then(() => gToolbox.selectTool("jsdebugger")).then(() => {
|
||||
ok(gToolboxTab.hasAttribute("highlighted") &&
|
||||
gToolboxTab.getAttribute("highlighted") == "true",
|
||||
"The highlighted class is present");
|
||||
ok(gToolboxTab.hasAttribute("selected") &&
|
||||
gToolboxTab.getAttribute("selected") == "true",
|
||||
"...and the tab is selected, so the glow will not be present.");
|
||||
}).then(testResume);
|
||||
});
|
||||
|
||||
// Evaluate a script to fully pause the debugger
|
||||
evalInTab(gTab, "debugger;");
|
||||
}
|
||||
|
||||
function testResume() {
|
||||
gDebugger.gThreadClient.addOneTimeListener("resumed", () => {
|
||||
gToolbox.selectTool("webconsole").then(() => {
|
||||
ok(!gToolboxTab.hasAttribute("highlighted") ||
|
||||
gToolboxTab.getAttribute("highlighted") != "true",
|
||||
"The highlighted class is not present now after the resume");
|
||||
ok(!gToolboxTab.hasAttribute("selected") ||
|
||||
gToolboxTab.getAttribute("selected") != "true",
|
||||
"The tab is not selected");
|
||||
}).then(maybeEndTest);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
gDebugger.document.getElementById("resume"),
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
function maybeEndTest() {
|
||||
if (gToolbox.hostType == Toolbox.HostType.BOTTOM) {
|
||||
info("Switching to a toolbox window host.");
|
||||
gToolbox.switchHost(Toolbox.HostType.WINDOW).then(focusMainWindow);
|
||||
} else {
|
||||
info("Switching to main window host.");
|
||||
gToolbox.switchHost(Toolbox.HostType.BOTTOM).then(() => closeDebuggerAndFinish(gPanel));
|
||||
yield toolbox.selectTool("webconsole");
|
||||
ok(toolboxTab.hasAttribute("highlighted") &&
|
||||
toolboxTab.getAttribute("highlighted") == "true",
|
||||
"The highlighted class is present");
|
||||
ok(!toolboxTab.hasAttribute("selected") ||
|
||||
toolboxTab.getAttribute("selected") != "true",
|
||||
"The tab is not selected");
|
||||
yield toolbox.selectTool("jsdebugger");
|
||||
ok(toolboxTab.hasAttribute("highlighted") &&
|
||||
toolboxTab.getAttribute("highlighted") == "true",
|
||||
"The highlighted class is present");
|
||||
ok(toolboxTab.hasAttribute("selected") &&
|
||||
toolboxTab.getAttribute("selected") == "true",
|
||||
"...and the tab is selected, so the glow will not be present.");
|
||||
}
|
||||
}
|
||||
|
||||
function* testResume() {
|
||||
let onPaused = waitForEvent(panelWin.gThreadClient, "resumed");
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
panelWin.document.getElementById("resume"),
|
||||
panelWin);
|
||||
|
||||
yield onPaused;
|
||||
|
||||
yield toolbox.selectTool("webconsole");
|
||||
ok(!toolboxTab.hasAttribute("highlighted") ||
|
||||
toolboxTab.getAttribute("highlighted") != "true",
|
||||
"The highlighted class is not present now after the resume");
|
||||
ok(!toolboxTab.hasAttribute("selected") ||
|
||||
toolboxTab.getAttribute("selected") != "true",
|
||||
"The tab is not selected");
|
||||
}
|
||||
});
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
// Revert to the default toolbox host, so that the following tests proceed
|
||||
// normally and not inside a non-default host.
|
||||
Services.prefs.setCharPref("devtools.toolbox.host", Toolbox.HostType.BOTTOM);
|
||||
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
|
||||
gFocusedWindow = null;
|
||||
gToolbox = null;
|
||||
gToolboxTab = null;
|
||||
});
|
||||
|
@ -34,8 +34,17 @@ add_task(function* () {
|
||||
"jsdebugger",
|
||||
Toolbox.HostType.WINDOW);
|
||||
|
||||
is(toolbox._host.type, "window", "correct host");
|
||||
ok(toolbox._host._window.document.title.includes(WORKER_URL),
|
||||
is(toolbox.hostType, "window", "correct host");
|
||||
|
||||
yield new Promise(done => {
|
||||
toolbox.win.parent.addEventListener("message", function onmessage(event) {
|
||||
if (event.data.name == "set-host-title") {
|
||||
toolbox.win.parent.removeEventListener("message", onmessage);
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
ok(toolbox.win.parent.document.title.includes(WORKER_URL),
|
||||
"worker URL in host title");
|
||||
|
||||
let toolTabs = toolbox.doc.querySelectorAll(".devtools-tab");
|
||||
|
@ -751,6 +751,9 @@ AddonDebugger.prototype = {
|
||||
}),
|
||||
|
||||
_onMessage: function (event) {
|
||||
if (typeof(event.data) !== "string") {
|
||||
return;
|
||||
}
|
||||
let json = JSON.parse(event.data);
|
||||
switch (json.name) {
|
||||
case "toolbox-title":
|
||||
|
@ -10,7 +10,6 @@
|
||||
<link href="resource://devtools/client/dom/content/dom-view.css" rel="stylesheet" />
|
||||
<link href="resource://devtools/client/jsonview/css/toolbar.css" rel="stylesheet" />
|
||||
<link href="resource://devtools/client/shared/components/tree/tree-view.css" rel="stylesheet" />
|
||||
<link href="resource://devtools/client/dom/content/components/search-box.css" rel="stylesheet" />
|
||||
|
||||
<script type="text/javascript;version=1.8"
|
||||
src="chrome://devtools/content/shared/theme-switching.js"></script>
|
||||
|
@ -11,6 +11,4 @@ DIRS += [
|
||||
|
||||
DevToolsModules(
|
||||
'dom-panel.js',
|
||||
'dom.html',
|
||||
'main.js',
|
||||
)
|
||||
|
@ -10,6 +10,7 @@ const defer = require("devtools/shared/defer");
|
||||
|
||||
// Load gDevToolsBrowser toolbox lazily as they need gDevTools to be fully initialized
|
||||
loader.lazyRequireGetter(this, "Toolbox", "devtools/client/framework/toolbox", true);
|
||||
loader.lazyRequireGetter(this, "ToolboxHostManager", "devtools/client/framework/toolbox-host-manager", true);
|
||||
loader.lazyRequireGetter(this, "gDevToolsBrowser", "devtools/client/framework/devtools-browser", true);
|
||||
|
||||
const {defaultTools: DefaultTools, defaultThemes: DefaultThemes} =
|
||||
@ -18,6 +19,7 @@ const EventEmitter = require("devtools/shared/event-emitter");
|
||||
const {JsonView} = require("devtools/client/jsonview/main");
|
||||
const AboutDevTools = require("devtools/client/framework/about-devtools-toolbox");
|
||||
const {when: unload} = require("sdk/system/unload");
|
||||
const {Task} = require("devtools/shared/task");
|
||||
|
||||
const FORBIDDEN_IDS = new Set(["toolbox", ""]);
|
||||
const MAX_ORDINAL = 99;
|
||||
@ -397,35 +399,27 @@ DevTools.prototype = {
|
||||
* @return {Toolbox} toolbox
|
||||
* The toolbox that was opened
|
||||
*/
|
||||
showToolbox: function (target, toolId, hostType, hostOptions) {
|
||||
let deferred = defer();
|
||||
|
||||
showToolbox: Task.async(function* (target, toolId, hostType, hostOptions) {
|
||||
let toolbox = this._toolboxes.get(target);
|
||||
if (toolbox) {
|
||||
|
||||
let hostPromise = (hostType != null && toolbox.hostType != hostType) ?
|
||||
toolbox.switchHost(hostType) :
|
||||
promise.resolve(null);
|
||||
|
||||
if (toolId != null && toolbox.currentToolId != toolId) {
|
||||
hostPromise = hostPromise.then(function () {
|
||||
return toolbox.selectTool(toolId);
|
||||
});
|
||||
if (hostType != null && toolbox.hostType != hostType) {
|
||||
yield toolbox.switchHost(hostType);
|
||||
}
|
||||
|
||||
return hostPromise.then(function () {
|
||||
toolbox.raise();
|
||||
return toolbox;
|
||||
});
|
||||
}
|
||||
else {
|
||||
// No toolbox for target, create one
|
||||
toolbox = new Toolbox(target, toolId, hostType, hostOptions);
|
||||
if (toolId != null && toolbox.currentToolId != toolId) {
|
||||
yield toolbox.selectTool(toolId);
|
||||
}
|
||||
|
||||
toolbox.raise();
|
||||
} else {
|
||||
let manager = new ToolboxHostManager(target, hostType, hostOptions);
|
||||
|
||||
toolbox = yield manager.create(toolId);
|
||||
this._toolboxes.set(target, toolbox);
|
||||
|
||||
this.emit("toolbox-created", toolbox);
|
||||
|
||||
this._toolboxes.set(target, toolbox);
|
||||
|
||||
toolbox.once("destroy", () => {
|
||||
this.emit("toolbox-destroy", target);
|
||||
});
|
||||
@ -435,16 +429,12 @@ DevTools.prototype = {
|
||||
this.emit("toolbox-destroyed", target);
|
||||
});
|
||||
|
||||
// If toolId was passed in, it will already be selected before the
|
||||
// open promise resolves.
|
||||
toolbox.open().then(() => {
|
||||
deferred.resolve(toolbox);
|
||||
this.emit("toolbox-ready", toolbox);
|
||||
});
|
||||
yield toolbox.open();
|
||||
this.emit("toolbox-ready", toolbox);
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
return toolbox;
|
||||
}),
|
||||
|
||||
/**
|
||||
* Return the toolbox for a given target.
|
||||
|
@ -25,6 +25,7 @@ DevToolsModules(
|
||||
'target-from-url.js',
|
||||
'target.js',
|
||||
'toolbox-highlighter-utils.js',
|
||||
'toolbox-host-manager.js',
|
||||
'toolbox-hosts.js',
|
||||
'toolbox-options.js',
|
||||
'toolbox.js',
|
||||
|
@ -71,7 +71,7 @@ function runTests1(aTab) {
|
||||
|
||||
gDevTools.showToolbox(target, toolId1).then(function (toolbox) {
|
||||
is(toolbox.target, target, "toolbox target is correct");
|
||||
is(toolbox._host.hostTab, gBrowser.selectedTab, "toolbox host is correct");
|
||||
is(toolbox.target.tab, gBrowser.selectedTab, "targeted tab is correct");
|
||||
|
||||
ok(events["init"], "init event fired");
|
||||
ok(events["ready"], "ready event fired");
|
||||
@ -139,7 +139,7 @@ function runTests2() {
|
||||
|
||||
gDevTools.showToolbox(target, toolId2).then(function (toolbox) {
|
||||
is(toolbox.target, target, "toolbox target is correct");
|
||||
is(toolbox._host.hostTab, gBrowser.selectedTab, "toolbox host is correct");
|
||||
is(toolbox.target.tab, gBrowser.selectedTab, "targeted tab is correct");
|
||||
|
||||
ok(events["init"], "init event fired");
|
||||
ok(events["build"], "build event fired");
|
||||
|
@ -24,6 +24,9 @@ function test() {
|
||||
});
|
||||
|
||||
function onMessage(event) {
|
||||
if (typeof(event.data) !== "string") {
|
||||
return;
|
||||
}
|
||||
info("onMessage: " + event.data);
|
||||
let json = JSON.parse(event.data);
|
||||
if (json.name == "toolbox-close") {
|
||||
|
@ -42,12 +42,12 @@ function testWindowHost() {
|
||||
// Need to wait for focus as otherwise window.focus() is overridden by
|
||||
// toolbox window getting focused first on Linux and Mac.
|
||||
let onToolboxFocus = () => {
|
||||
toolbox._host._window.removeEventListener("focus", onToolboxFocus, true);
|
||||
toolbox.win.parent.removeEventListener("focus", onToolboxFocus, true);
|
||||
info("focusing main window.");
|
||||
window.focus();
|
||||
};
|
||||
// Need to wait for toolbox window to get focus.
|
||||
toolbox._host._window.addEventListener("focus", onToolboxFocus, true);
|
||||
toolbox.win.parent.addEventListener("focus", onToolboxFocus, true);
|
||||
}
|
||||
|
||||
function onFocus() {
|
||||
@ -56,11 +56,11 @@ function onFocus() {
|
||||
|
||||
// Check if toolbox window got focus.
|
||||
let onToolboxFocusAgain = () => {
|
||||
toolbox._host._window.removeEventListener("focus", onToolboxFocusAgain, false);
|
||||
toolbox.win.parent.removeEventListener("focus", onToolboxFocusAgain, false);
|
||||
ok(true, "Toolbox window is the focused window after calling toolbox.raise()");
|
||||
cleanup();
|
||||
};
|
||||
toolbox._host._window.addEventListener("focus", onToolboxFocusAgain, false);
|
||||
toolbox.win.parent.addEventListener("focus", onToolboxFocusAgain, false);
|
||||
|
||||
// Now raise toolbox.
|
||||
toolbox.raise();
|
||||
|
@ -82,7 +82,7 @@ function* testToggleDetachedToolbox(tab, key, modifiers) {
|
||||
|
||||
info("Verify windowed toolbox is focused instead of closed when using " +
|
||||
"toggle key from the main window");
|
||||
let toolboxWindow = toolbox._host._window;
|
||||
let toolboxWindow = toolbox.win.top;
|
||||
let onToolboxWindowFocus = once(toolboxWindow, "focus", true);
|
||||
EventUtils.synthesizeKey(key, modifiers);
|
||||
yield onToolboxWindowFocus;
|
||||
|
@ -28,28 +28,35 @@ function test() {
|
||||
.then(() => toolbox.selectTool(TOOL_ID_1))
|
||||
|
||||
// undock toolbox and check title
|
||||
.then(() => toolbox.switchHost(Toolbox.HostType.WINDOW))
|
||||
.then(() => {
|
||||
// We have to first switch the host in order to spawn the new top level window
|
||||
// on which we are going to listen from title change event
|
||||
return toolbox.switchHost(Toolbox.HostType.WINDOW)
|
||||
.then(() => waitForTitleChange(toolbox));
|
||||
})
|
||||
.then(checkTitle.bind(null, NAME_1, URL_1, "toolbox undocked"))
|
||||
|
||||
// switch to different tool and check title
|
||||
.then(() => toolbox.selectTool(TOOL_ID_2))
|
||||
.then(() => {
|
||||
let onTitleChanged = waitForTitleChange(toolbox);
|
||||
toolbox.selectTool(TOOL_ID_2);
|
||||
return onTitleChanged;
|
||||
})
|
||||
.then(checkTitle.bind(null, NAME_1, URL_1, "tool changed"))
|
||||
|
||||
// navigate to different local url and check title
|
||||
.then(function () {
|
||||
let deferred = defer();
|
||||
target.once("navigate", () => deferred.resolve());
|
||||
let onTitleChanged = waitForTitleChange(toolbox);
|
||||
gBrowser.loadURI(URL_2);
|
||||
return deferred.promise;
|
||||
return onTitleChanged;
|
||||
})
|
||||
.then(checkTitle.bind(null, NAME_2, URL_2, "url changed"))
|
||||
|
||||
// navigate to a real url and check title
|
||||
.then(() => {
|
||||
let deferred = defer();
|
||||
target.once("navigate", () => deferred.resolve());
|
||||
let onTitleChanged = waitForTitleChange(toolbox);
|
||||
gBrowser.loadURI(URL_3);
|
||||
return deferred.promise;
|
||||
return onTitleChanged;
|
||||
})
|
||||
.then(checkTitle.bind(null, NAME_3, URL_3, "url changed"))
|
||||
|
||||
@ -66,7 +73,11 @@ function test() {
|
||||
return gDevTools.showToolbox(target, null, Toolbox.HostType.WINDOW);
|
||||
})
|
||||
.then(function (aToolbox) { toolbox = aToolbox; })
|
||||
.then(() => toolbox.selectTool(TOOL_ID_1))
|
||||
.then(() => {
|
||||
let onTitleChanged = waitForTitleChange(toolbox);
|
||||
toolbox.selectTool(TOOL_ID_1);
|
||||
return onTitleChanged;
|
||||
})
|
||||
.then(checkTitle.bind(null, NAME_3, URL_3,
|
||||
"toolbox destroyed and recreated"))
|
||||
|
||||
|
@ -25,8 +25,14 @@ add_task(function* () {
|
||||
let toolbox = yield gDevTools.showToolbox(target, null,
|
||||
Toolbox.HostType.BOTTOM);
|
||||
|
||||
let onTitleChanged = waitForTitleChange(toolbox);
|
||||
yield toolbox.selectTool("inspector");
|
||||
yield onTitleChanged;
|
||||
|
||||
yield toolbox.switchHost(Toolbox.HostType.WINDOW);
|
||||
// Wait for title change event *after* switch host, in order to listen
|
||||
// for the event on the WINDOW host window, which only exists after switchHost
|
||||
yield waitForTitleChange(toolbox);
|
||||
|
||||
is(getTitle(), `Developer Tools - Page title - ${URL}`,
|
||||
"Devtools title correct after switching to detached window host");
|
||||
@ -56,6 +62,8 @@ add_task(function* () {
|
||||
// Listen to will-navigate to check if the view is empty
|
||||
let willNavigate = toolbox.target.once("will-navigate");
|
||||
|
||||
onTitleChanged = waitForTitleChange(toolbox);
|
||||
|
||||
// Only select the iframe after we are able to select an element from the top
|
||||
// level document.
|
||||
let newRoot = toolbox.getPanel("inspector").once("new-root");
|
||||
@ -64,6 +72,7 @@ add_task(function* () {
|
||||
|
||||
yield willNavigate;
|
||||
yield newRoot;
|
||||
yield onTitleChanged;
|
||||
|
||||
info("Navigation to the iframe is done, the inspector should be back up");
|
||||
is(getTitle(), `Developer Tools - Page title - ${URL}`,
|
||||
|
@ -580,3 +580,17 @@ function emptyClipboard() {
|
||||
function isWindows() {
|
||||
return Services.appinfo.OS === "WINNT";
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for a given toolbox to get its title updated.
|
||||
*/
|
||||
function waitForTitleChange(toolbox) {
|
||||
let deferred = defer();
|
||||
toolbox.win.parent.addEventListener("message", function onmessage(event) {
|
||||
if (event.data.name == "set-host-title") {
|
||||
toolbox.win.parent.removeEventListener("message", onmessage);
|
||||
deferred.resolve();
|
||||
}
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
244
devtools/client/framework/toolbox-host-manager.js
Normal file
@ -0,0 +1,244 @@
|
||||
const Services = require("Services");
|
||||
const {Ci} = require("chrome");
|
||||
const {LocalizationHelper} = require("devtools/shared/l10n");
|
||||
const L10N = new LocalizationHelper("devtools/locale/toolbox.properties");
|
||||
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
||||
const {Task} = require("devtools/shared/task");
|
||||
|
||||
loader.lazyRequireGetter(this, "Toolbox", "devtools/client/framework/toolbox", true);
|
||||
loader.lazyRequireGetter(this, "Hosts", "devtools/client/framework/toolbox-hosts", true);
|
||||
|
||||
/**
|
||||
* Implement a wrapper on the chrome side to setup a Toolbox within Firefox UI.
|
||||
*
|
||||
* This component handles iframe creation within Firefox, in which we are loading
|
||||
* the toolbox document. Then both the chrome and the toolbox document communicate
|
||||
* via "message" events.
|
||||
*
|
||||
* Messages sent by the toolbox to the chrome:
|
||||
* - switch-host:
|
||||
* Order to display the toolbox in another host (side, bottom, window, or the
|
||||
* previously used one)
|
||||
* - toggle-minimize-mode:
|
||||
* When using the bottom host, the toolbox can be miximized to only display
|
||||
* the tool titles
|
||||
* - maximize-host:
|
||||
* When using the bottom host in minimized mode, revert back to regular mode
|
||||
* in order to see tool titles and the tools
|
||||
* - raise-host:
|
||||
* Focus the tools
|
||||
* - set-host-title:
|
||||
* When using the window host, update the window title
|
||||
*
|
||||
* Messages sent by the chrome to the toolbox:
|
||||
* - host-minimized:
|
||||
* The bottom host is done minimizing (after animation end)
|
||||
* - host-maximized:
|
||||
* The bottom host is done switching back to regular mode (after animation
|
||||
* end)
|
||||
* - switched-host:
|
||||
* The `switch-host` command sent by the toolbox is done
|
||||
*/
|
||||
|
||||
const LAST_HOST = "devtools.toolbox.host";
|
||||
const PREVIOUS_HOST = "devtools.toolbox.previousHost";
|
||||
let ID_COUNTER = 1;
|
||||
|
||||
function ToolboxHostManager(target, hostType, hostOptions) {
|
||||
this.target = target;
|
||||
|
||||
this.frameId = ID_COUNTER++;
|
||||
|
||||
if (!hostType) {
|
||||
hostType = Services.prefs.getCharPref(LAST_HOST);
|
||||
}
|
||||
this.onHostMinimized = this.onHostMinimized.bind(this);
|
||||
this.onHostMaximized = this.onHostMaximized.bind(this);
|
||||
this.host = this.createHost(hostType, hostOptions);
|
||||
this.hostType = hostType;
|
||||
}
|
||||
|
||||
ToolboxHostManager.prototype = {
|
||||
create: Task.async(function* (toolId) {
|
||||
yield this.host.create();
|
||||
|
||||
this.host.frame.setAttribute("aria-label", L10N.getStr("toolbox.label"));
|
||||
this.host.frame.ownerDocument.defaultView.addEventListener("message", this);
|
||||
// We have to listen on capture as no event fires on bubble
|
||||
this.host.frame.addEventListener("unload", this, true);
|
||||
|
||||
let toolbox = new Toolbox(this.target, toolId, this.host.type, this.host.frame.contentWindow, this.frameId);
|
||||
|
||||
// Prevent reloading the toolbox when loading the tools in a tab (e.g. from about:debugging)
|
||||
if (!this.host.frame.contentWindow.location.href.startsWith("about:devtools-toolbox")) {
|
||||
this.host.frame.setAttribute("src", "about:devtools-toolbox");
|
||||
}
|
||||
|
||||
return toolbox;
|
||||
}),
|
||||
|
||||
handleEvent(event) {
|
||||
switch(event.type) {
|
||||
case "message":
|
||||
this.onMessage(event);
|
||||
break;
|
||||
case "unload":
|
||||
// On unload, host iframe already lost its contentWindow attribute, so
|
||||
// we can only compare against locations. Here we filter two very
|
||||
// different cases: preliminary about:blank document as well as iframes
|
||||
// like tool iframes.
|
||||
if (!event.target.location.href.startsWith("about:devtools-toolbox")) {
|
||||
break;
|
||||
}
|
||||
// Don't destroy the host during unload event (esp., don't remove the
|
||||
// iframe from DOM!). Otherwise the unload event for the toolbox
|
||||
// document doesn't fire within the toolbox *document*! This is
|
||||
// the unload event that fires on the toolbox *iframe*.
|
||||
DevToolsUtils.executeSoon(() => {
|
||||
this.destroy();
|
||||
});
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
onMessage(event) {
|
||||
if (!event.data) {
|
||||
return;
|
||||
}
|
||||
// Toolbox document is still chrome and disallow identifying message
|
||||
// origin via event.source as it is null. So use a custom id.
|
||||
if (event.data.frameId != this.frameId) {
|
||||
return;
|
||||
}
|
||||
switch (event.data.name) {
|
||||
case "switch-host":
|
||||
this.switchHost(event.data.hostType);
|
||||
break;
|
||||
case "maximize-host":
|
||||
this.host.maximize();
|
||||
break;
|
||||
case "raise-host":
|
||||
this.host.raise();
|
||||
break;
|
||||
case "toggle-minimize-mode":
|
||||
this.host.toggleMinimizeMode(event.data.toolbarHeight);
|
||||
break;
|
||||
case "set-host-title":
|
||||
this.host.setTitle(event.data.title);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
postMessage(data) {
|
||||
let window = this.host.frame.contentWindow;
|
||||
window.postMessage(data, "*");
|
||||
},
|
||||
|
||||
destroy() {
|
||||
this.destroyHost();
|
||||
this.host = null;
|
||||
this.hostType = null;
|
||||
this.target = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a host object based on the given host type.
|
||||
*
|
||||
* Warning: bottom and sidebar hosts require that the toolbox target provides
|
||||
* a reference to the attached tab. Not all Targets have a tab property -
|
||||
* make sure you correctly mix and match hosts and targets.
|
||||
*
|
||||
* @param {string} hostType
|
||||
* The host type of the new host object
|
||||
*
|
||||
* @return {Host} host
|
||||
* The created host object
|
||||
*/
|
||||
createHost(hostType, options) {
|
||||
if (!Hosts[hostType]) {
|
||||
throw new Error("Unknown hostType: " + hostType);
|
||||
}
|
||||
|
||||
let newHost = new Hosts[hostType](this.target.tab, options);
|
||||
// Update the label and icon when the state changes.
|
||||
newHost.on("minimized", this.onHostMinimized);
|
||||
newHost.on("maximized", this.onHostMaximized);
|
||||
return newHost;
|
||||
},
|
||||
|
||||
onHostMinimized() {
|
||||
this.postMessage({
|
||||
name: "host-minimized"
|
||||
});
|
||||
},
|
||||
|
||||
onHostMaximized() {
|
||||
this.postMessage({
|
||||
name: "host-maximized"
|
||||
});
|
||||
},
|
||||
|
||||
switchHost: Task.async(function* (hostType) {
|
||||
if (hostType == "previous") {
|
||||
// Switch to the last used host for the toolbox UI.
|
||||
// This is determined by the devtools.toolbox.previousHost pref.
|
||||
hostType = Services.prefs.getCharPref(PREVIOUS_HOST);
|
||||
|
||||
// Handle the case where the previous host happens to match the current
|
||||
// host. If so, switch to bottom if it's not already used, and side if not.
|
||||
if (hostType === this.hostType) {
|
||||
if (hostType === Toolbox.HostType.BOTTOM) {
|
||||
hostType = Toolbox.HostType.SIDE;
|
||||
} else {
|
||||
hostType = Toolbox.HostType.BOTTOM;
|
||||
}
|
||||
}
|
||||
}
|
||||
let iframe = this.host.frame;
|
||||
let newHost = this.createHost(hostType);
|
||||
let newIframe = yield newHost.create();
|
||||
// change toolbox document's parent to the new host
|
||||
newIframe.swapFrameLoaders(iframe);
|
||||
|
||||
this.destroyHost();
|
||||
|
||||
if (this.hostType != Toolbox.HostType.CUSTOM) {
|
||||
Services.prefs.setCharPref(PREVIOUS_HOST, this.hostType);
|
||||
}
|
||||
|
||||
this.host = newHost;
|
||||
this.hostType = hostType;
|
||||
this.host.setTitle(this.host.frame.contentWindow.document.title);
|
||||
this.host.frame.ownerDocument.defaultView.addEventListener("message", this);
|
||||
this.host.frame.addEventListener("unload", this, true);
|
||||
|
||||
if (hostType != Toolbox.HostType.CUSTOM) {
|
||||
Services.prefs.setCharPref(LAST_HOST, hostType);
|
||||
}
|
||||
|
||||
// Tell the toolbox the host changed
|
||||
this.postMessage({
|
||||
name: "switched-host",
|
||||
hostType
|
||||
});
|
||||
}),
|
||||
|
||||
/**
|
||||
* Destroy the current host, and remove event listeners from its frame.
|
||||
*
|
||||
* @return {promise} to be resolved when the host is destroyed.
|
||||
*/
|
||||
destroyHost() {
|
||||
// When Firefox toplevel is closed, the frame may already be detached and
|
||||
// the top level document gone
|
||||
if (this.host.frame.ownerDocument.defaultView) {
|
||||
this.host.frame.ownerDocument.defaultView.removeEventListener("message", this);
|
||||
}
|
||||
this.host.frame.removeEventListener("unload", this, true);
|
||||
|
||||
this.host.off("minimized", this.onHostMinimized);
|
||||
this.host.off("maximized", this.onHostMaximized);
|
||||
return this.host.destroy();
|
||||
}
|
||||
};
|
||||
exports.ToolboxHostManager = ToolboxHostManager;
|
@ -256,7 +256,10 @@ OptionsPanel.prototype = {
|
||||
|
||||
setupThemeList: function () {
|
||||
let themeBox = this.panelDoc.getElementById("devtools-theme-box");
|
||||
themeBox.innerHTML = "";
|
||||
let themeLabels = themeBox.querySelectorAll("label");
|
||||
for (let label of themeLabels) {
|
||||
label.remove();
|
||||
}
|
||||
|
||||
let createThemeOption = theme => {
|
||||
let inputLabel = this.panelDoc.createElement("label");
|
||||
|
@ -40,8 +40,6 @@ loader.lazyRequireGetter(this, "CommandUtils",
|
||||
"devtools/client/shared/developer-toolbar", true);
|
||||
loader.lazyRequireGetter(this, "getHighlighterUtils",
|
||||
"devtools/client/framework/toolbox-highlighter-utils", true);
|
||||
loader.lazyRequireGetter(this, "Hosts",
|
||||
"devtools/client/framework/toolbox-hosts", true);
|
||||
loader.lazyRequireGetter(this, "Selection",
|
||||
"devtools/client/framework/selection", true);
|
||||
loader.lazyRequireGetter(this, "InspectorFront",
|
||||
@ -80,12 +78,17 @@ loader.lazyGetter(this, "registerHarOverlay", () => {
|
||||
* Tool to select initially
|
||||
* @param {Toolbox.HostType} hostType
|
||||
* Type of host that will host the toolbox (e.g. sidebar, window)
|
||||
* @param {object} hostOptions
|
||||
* Options for host specifically
|
||||
* @param {DOMWindow} contentWindow
|
||||
* The window object of the toolbox document
|
||||
* @param {string} frameId
|
||||
* A unique identifier to differentiate toolbox documents from the
|
||||
* chrome codebase when passing DOM messages
|
||||
*/
|
||||
function Toolbox(target, selectedTool, hostType, hostOptions) {
|
||||
function Toolbox(target, selectedTool, hostType, contentWindow, frameId) {
|
||||
this._target = target;
|
||||
this._win = null;
|
||||
this._win = contentWindow;
|
||||
this.frameId = frameId;
|
||||
|
||||
this._toolPanels = new Map();
|
||||
this._telemetry = new Telemetry();
|
||||
if (Services.prefs.getBoolPref("devtools.sourcemap.locations.enabled")) {
|
||||
@ -113,6 +116,7 @@ function Toolbox(target, selectedTool, hostType, hostOptions) {
|
||||
this._prefChanged = this._prefChanged.bind(this);
|
||||
this._saveSplitConsoleHeight = this._saveSplitConsoleHeight.bind(this);
|
||||
this._onFocus = this._onFocus.bind(this);
|
||||
this._onBrowserMessage = this._onBrowserMessage.bind(this);
|
||||
this._showDevEditionPromo = this._showDevEditionPromo.bind(this);
|
||||
this._updateTextBoxMenuItems = this._updateTextBoxMenuItems.bind(this);
|
||||
this._onBottomHostMinimized = this._onBottomHostMinimized.bind(this);
|
||||
@ -130,16 +134,12 @@ function Toolbox(target, selectedTool, hostType, hostOptions) {
|
||||
|
||||
this._target.on("close", this.destroy);
|
||||
|
||||
if (!hostType) {
|
||||
hostType = Services.prefs.getCharPref(this._prefs.LAST_HOST);
|
||||
}
|
||||
if (!selectedTool) {
|
||||
selectedTool = Services.prefs.getCharPref(this._prefs.LAST_TOOL);
|
||||
}
|
||||
this._defaultToolId = selectedTool;
|
||||
|
||||
this._hostOptions = hostOptions;
|
||||
this._host = this._createHost(hostType, hostOptions);
|
||||
this._hostType = hostType;
|
||||
|
||||
EventEmitter.decorate(this);
|
||||
|
||||
@ -174,10 +174,8 @@ Toolbox.prototype = {
|
||||
_URL: "about:devtools-toolbox",
|
||||
|
||||
_prefs: {
|
||||
LAST_HOST: "devtools.toolbox.host",
|
||||
LAST_TOOL: "devtools.toolbox.selectedTool",
|
||||
SIDE_ENABLED: "devtools.toolbox.sideEnabled",
|
||||
PREVIOUS_HOST: "devtools.toolbox.previousHost"
|
||||
},
|
||||
|
||||
currentToolId: null,
|
||||
@ -254,7 +252,7 @@ Toolbox.prototype = {
|
||||
* tab. See HostType for more details.
|
||||
*/
|
||||
get hostType() {
|
||||
return this._host.type;
|
||||
return this._hostType;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -337,27 +335,18 @@ Toolbox.prototype = {
|
||||
*/
|
||||
open: function () {
|
||||
return Task.spawn(function* () {
|
||||
let iframe = yield this._host.create();
|
||||
this._win = iframe.contentWindow;
|
||||
|
||||
let domReady = defer();
|
||||
|
||||
// Prevent reloading the document when the toolbox is opened in a tab
|
||||
let location = iframe.contentWindow.location.href;
|
||||
if (!location.startsWith(this._URL)) {
|
||||
iframe.setAttribute("src", this._URL);
|
||||
} else {
|
||||
// Update the URL so that onceDOMReady watch for the right url.
|
||||
this._URL = location;
|
||||
}
|
||||
|
||||
this.browserRequire = BrowserLoader({
|
||||
window: this.doc.defaultView,
|
||||
useOnlyShared: true
|
||||
}).require;
|
||||
|
||||
iframe.setAttribute("aria-label", L10N.getStr("toolbox.label"));
|
||||
let domHelper = new DOMHelpers(iframe.contentWindow);
|
||||
if (this.win.location.href.startsWith(this._URL)) {
|
||||
// Update the URL so that onceDOMReady watch for the right url.
|
||||
this._URL = this.win.location.href;
|
||||
}
|
||||
|
||||
let domReady = defer();
|
||||
let domHelper = new DOMHelpers(this.win);
|
||||
domHelper.onceDOMReady(() => {
|
||||
domReady.resolve();
|
||||
}, this._URL);
|
||||
@ -610,6 +599,7 @@ Toolbox.prototype = {
|
||||
this.doc.addEventListener("keypress", this._splitConsoleOnKeypress, false);
|
||||
this.doc.addEventListener("focus", this._onFocus, true);
|
||||
this.win.addEventListener("unload", this.destroy);
|
||||
this.win.addEventListener("message", this._onBrowserMessage, true);
|
||||
},
|
||||
|
||||
_removeHostListeners: function () {
|
||||
@ -618,6 +608,29 @@ Toolbox.prototype = {
|
||||
this.doc.removeEventListener("keypress", this._splitConsoleOnKeypress, false);
|
||||
this.doc.removeEventListener("focus", this._onFocus, true);
|
||||
this.win.removeEventListener("unload", this.destroy);
|
||||
this.win.removeEventListener("message", this._onBrowserMessage, true);
|
||||
}
|
||||
},
|
||||
|
||||
// Called whenever the chrome send a message
|
||||
_onBrowserMessage: function (event) {
|
||||
if (!event.data) {
|
||||
return;
|
||||
}
|
||||
switch (event.data.name) {
|
||||
case "switched-host":
|
||||
this._onSwitchedHost(event.data);
|
||||
break;
|
||||
case "host-minimized":
|
||||
if (this.hostType == Toolbox.HostType.BOTTOM) {
|
||||
this._onBottomHostMinimized();
|
||||
}
|
||||
break;
|
||||
case "host-maximized":
|
||||
if (this.hostType == Toolbox.HostType.BOTTOM) {
|
||||
this._onBottomHostMaximized();
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
@ -781,9 +794,6 @@ Toolbox.prototype = {
|
||||
// Show the button in its maximized state.
|
||||
this._onBottomHostMaximized();
|
||||
|
||||
// Update the label and icon when the state changes.
|
||||
this._host.on("minimized", this._onBottomHostMinimized);
|
||||
this._host.on("maximized", this._onBottomHostMaximized);
|
||||
// Maximize again when a tool gets selected.
|
||||
this.on("before-select", this._onToolSelectWhileMinimized);
|
||||
// Maximize and stop listening before the host type changes.
|
||||
@ -842,14 +852,27 @@ Toolbox.prototype = {
|
||||
},
|
||||
|
||||
_onToolSelectWhileMinimized: function () {
|
||||
this._host.maximize();
|
||||
this.postMessage({
|
||||
name: "maximize-host"
|
||||
});
|
||||
},
|
||||
|
||||
postMessage: function (msg) {
|
||||
// We sometime try to send messages in middle of destroy(), where the
|
||||
// toolbox iframe may already be detached and no longer have a parent.
|
||||
if (this.win.parent) {
|
||||
// Toolbox document is still chrome and disallow identifying message
|
||||
// origin via event.source as it is null. So use a custom id.
|
||||
msg.frameId = this.frameId;
|
||||
this.win.parent.postMessage(msg, "*");
|
||||
}
|
||||
},
|
||||
|
||||
_onBottomHostWillChange: function () {
|
||||
this._host.maximize();
|
||||
this.postMessage({
|
||||
name: "maximize-host"
|
||||
});
|
||||
|
||||
this._host.off("minimized", this._onBottomHostMinimized);
|
||||
this._host.off("maximized", this._onBottomHostMaximized);
|
||||
this.off("before-select", this._onToolSelectWhileMinimized);
|
||||
},
|
||||
|
||||
@ -862,7 +885,10 @@ Toolbox.prototype = {
|
||||
// tabbar is still visible.
|
||||
let toolbarHeight = this.tabbar.getBoxQuads({box: "content"})[0].bounds
|
||||
.height;
|
||||
this._host.toggleMinimizeMode(toolbarHeight);
|
||||
this.postMessage({
|
||||
name: "toggle-minimize-mode",
|
||||
toolbarHeight
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1625,7 +1651,9 @@ Toolbox.prototype = {
|
||||
* Raise the toolbox host.
|
||||
*/
|
||||
raise: function () {
|
||||
this._host.raise();
|
||||
this.postMessage({
|
||||
name: "raise-host"
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1639,7 +1667,10 @@ Toolbox.prototype = {
|
||||
} else {
|
||||
title = L10N.getFormatStr("toolbox.titleTemplate1", this.target.url);
|
||||
}
|
||||
this._host.setTitle(title);
|
||||
this.postMessage({
|
||||
name: "set-host-title",
|
||||
title
|
||||
});
|
||||
},
|
||||
|
||||
// Returns an instance of the preference actor
|
||||
@ -1817,48 +1848,11 @@ Toolbox.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a host object based on the given host type.
|
||||
*
|
||||
* Warning: some hosts require that the toolbox target provides a reference to
|
||||
* the attached tab. Not all Targets have a tab property - make sure you
|
||||
* correctly mix and match hosts and targets.
|
||||
*
|
||||
* @param {string} hostType
|
||||
* The host type of the new host object
|
||||
*
|
||||
* @return {Host} host
|
||||
* The created host object
|
||||
*/
|
||||
_createHost: function (hostType, options) {
|
||||
if (!Hosts[hostType]) {
|
||||
throw new Error("Unknown hostType: " + hostType);
|
||||
}
|
||||
|
||||
// clean up the toolbox if its window is closed
|
||||
let newHost = new Hosts[hostType](this.target.tab, options);
|
||||
newHost.on("window-closed", this.destroy);
|
||||
return newHost;
|
||||
},
|
||||
|
||||
/**
|
||||
* Switch to the last used host for the toolbox UI.
|
||||
* This is determined by the devtools.toolbox.previousHost pref.
|
||||
*/
|
||||
switchToPreviousHost: function () {
|
||||
let hostType = Services.prefs.getCharPref(this._prefs.PREVIOUS_HOST);
|
||||
|
||||
// Handle the case where the previous host happens to match the current
|
||||
// host. If so, switch to bottom if it's not already used, and side if not.
|
||||
if (hostType === this.hostType) {
|
||||
if (hostType === Toolbox.HostType.BOTTOM) {
|
||||
hostType = Toolbox.HostType.SIDE;
|
||||
} else {
|
||||
hostType = Toolbox.HostType.BOTTOM;
|
||||
}
|
||||
}
|
||||
|
||||
return this.switchHost(hostType);
|
||||
return this.switchHost("previous");
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1875,39 +1869,33 @@ Toolbox.prototype = {
|
||||
|
||||
this.emit("host-will-change", hostType);
|
||||
|
||||
// If we call swapFrameLoaders() when a tool if focused it leaves the
|
||||
// browser in a state where it thinks that the tool is focused but in
|
||||
// reality the content area is focused. Blurring the tool before calling
|
||||
// swapFrameLoaders() works around this issue.
|
||||
// ToolboxHostManager is going to call swapFrameLoaders which mess up with
|
||||
// focus. We have to blur before calling it in order to be able to restore
|
||||
// the focus after, in _onSwitchedHost.
|
||||
this.focusTool(this.currentToolId, false);
|
||||
|
||||
let newHost = this._createHost(hostType);
|
||||
return newHost.create().then(iframe => {
|
||||
// change toolbox document's parent to the new host
|
||||
iframe.QueryInterface(Ci.nsIFrameLoaderOwner);
|
||||
iframe.swapFrameLoaders(this._host.frame);
|
||||
|
||||
this._host.off("window-closed", this.destroy);
|
||||
this.destroyHost();
|
||||
|
||||
let prevHostType = this._host.type;
|
||||
this._host = newHost;
|
||||
|
||||
if (this.hostType != Toolbox.HostType.CUSTOM) {
|
||||
Services.prefs.setCharPref(this._prefs.LAST_HOST, this._host.type);
|
||||
Services.prefs.setCharPref(this._prefs.PREVIOUS_HOST, prevHostType);
|
||||
}
|
||||
|
||||
this._buildDockButtons();
|
||||
this._addKeysToWindow();
|
||||
|
||||
// Focus the tool to make sure keyboard shortcuts work straight away.
|
||||
this.focusTool(this.currentToolId, true);
|
||||
|
||||
this.emit("host-changed");
|
||||
|
||||
this._telemetry.log(HOST_HISTOGRAM, this._getTelemetryHostId());
|
||||
// Host code on the chrome side will send back a message once the host
|
||||
// switched
|
||||
this.postMessage({
|
||||
name: "switch-host",
|
||||
hostType
|
||||
});
|
||||
|
||||
return this.once("host-changed");
|
||||
},
|
||||
|
||||
_onSwitchedHost: function ({ hostType }) {
|
||||
this._hostType = hostType;
|
||||
|
||||
this._buildDockButtons();
|
||||
this._addKeysToWindow();
|
||||
|
||||
// We blurred the tools at start of switchHost, but also when clicking on
|
||||
// host switching button. We now have to restore the focus.
|
||||
this.focusTool(this.currentToolId, true);
|
||||
|
||||
this.emit("host-changed");
|
||||
this._telemetry.log(HOST_HISTOGRAM, this._getTelemetryHostId());
|
||||
},
|
||||
|
||||
/**
|
||||
@ -2079,16 +2067,6 @@ Toolbox.prototype = {
|
||||
return this.notificationBox;
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroy the current host, and remove event listeners from its frame.
|
||||
*
|
||||
* @return {promise} to be resolved when the host is destroyed.
|
||||
*/
|
||||
destroyHost: function () {
|
||||
this._removeHostListeners();
|
||||
return this._host.destroy();
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove all UI elements, detach from target and clear up
|
||||
*/
|
||||
@ -2196,11 +2174,19 @@ Toolbox.prototype = {
|
||||
// then destroying the host, successfully or not) before destroying the
|
||||
// target.
|
||||
deferred.resolve(settleAll(outstanding)
|
||||
.catch(console.error)
|
||||
.then(() => this.destroyHost())
|
||||
.catch(console.error)
|
||||
.then(() => {
|
||||
this._win = null;
|
||||
this._removeHostListeners();
|
||||
|
||||
// `location` may already be null if the toolbox document is already
|
||||
// in process of destruction. Otherwise if it is still around, ensure
|
||||
// releasing toolbox document and triggering cleanup thanks to unload
|
||||
// event. We do that precisely here, before nullifying the target as
|
||||
// various cleanup code depends on the target attribute to be still
|
||||
// defined.
|
||||
if (win.location) {
|
||||
win.location.replace("about:blank");
|
||||
}
|
||||
|
||||
// Targets need to be notified that the toolbox is being torn down.
|
||||
// This is done after other destruction tasks since it may tear down
|
||||
@ -2220,6 +2206,7 @@ Toolbox.prototype = {
|
||||
// Free _host after the call to destroyed in order to let a chance
|
||||
// to destroyed listeners to still query toolbox attributes
|
||||
this._host = null;
|
||||
this._win = null;
|
||||
this._toolPanels.clear();
|
||||
|
||||
// Force GC to prevent long GC pauses when running tests and to free up
|
||||
|
@ -939,6 +939,9 @@ PropertyView.prototype = {
|
||||
});
|
||||
this.shortcuts.on("F1", (name, event) => {
|
||||
this.mdnLinkClick(event);
|
||||
// Prevent opening the options panel
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
});
|
||||
this.shortcuts.on("Return", (name, event) => this.onMatchedToggle(event));
|
||||
this.shortcuts.on("Space", (name, event) => this.onMatchedToggle(event));
|
||||
@ -1170,8 +1173,6 @@ PropertyView.prototype = {
|
||||
let browserWin = inspector.target.tab.ownerDocument.defaultView;
|
||||
browserWin.openUILinkIn(this.link, "tab");
|
||||
}
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -73,7 +73,7 @@ function checkHelpLinkKeybinding(view) {
|
||||
let def = defer();
|
||||
|
||||
let propView = getFirstVisiblePropertyView(view);
|
||||
propView.mdnLinkClick = function () {
|
||||
propView.mdnLinkClick = function (event) {
|
||||
ok(true, "Pressing F1 opened the MDN link");
|
||||
def.resolve();
|
||||
};
|
||||
|
@ -16,7 +16,6 @@ DevToolsModules(
|
||||
'breadcrumbs.js',
|
||||
'inspector-commands.js',
|
||||
'inspector-search.js',
|
||||
'inspector.xhtml',
|
||||
'panel.js',
|
||||
'toolsidebar.js',
|
||||
)
|
||||
|
@ -43,7 +43,7 @@ add_task(function* () {
|
||||
inspector.breadcrumbs.arrowScrollBox.scrollBehavior = "instant";
|
||||
|
||||
yield toolbox.switchHost(Toolbox.HostType.WINDOW);
|
||||
let hostWindow = toolbox._host._window;
|
||||
let hostWindow = toolbox.win.parent;
|
||||
let originalWidth = hostWindow.outerWidth;
|
||||
let originalHeight = hostWindow.outerHeight;
|
||||
hostWindow.resizeTo(640, 300);
|
||||
|
@ -11,7 +11,7 @@ add_task(function* () {
|
||||
let { inspector, toolbox } = yield openInspectorForURL(
|
||||
"data:text/html;charset=utf-8,<h1>foo</h1><span>bar</span>", "window");
|
||||
|
||||
let hostWindow = toolbox._host._window;
|
||||
let hostWindow = toolbox.win.parent;
|
||||
let originalWidth = hostWindow.outerWidth;
|
||||
let originalHeight = hostWindow.outerHeight;
|
||||
|
||||
@ -45,7 +45,7 @@ add_task(function* () {
|
||||
ok(splitter.classList.contains("horz"), "Splitter is in horizontal mode");
|
||||
|
||||
info("Restore original window size");
|
||||
toolbox._host._window.resizeTo(originalWidth, originalHeight);
|
||||
toolbox.win.parent.resizeTo(originalWidth, originalHeight);
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -25,7 +25,6 @@ devtools.jar:
|
||||
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)
|
||||
content/animationinspector/animation-panel.js (animationinspector/animation-panel.js)
|
||||
@ -110,7 +109,6 @@ devtools.jar:
|
||||
content/commandline/commandlinetooltip.xhtml (commandline/commandlinetooltip.xhtml)
|
||||
content/framework/toolbox-window.xul (framework/toolbox-window.xul)
|
||||
content/framework/toolbox-options.xhtml (framework/toolbox-options.xhtml)
|
||||
content/framework/toolbox-options.js (framework/toolbox-options.js)
|
||||
content/framework/toolbox.xul (framework/toolbox.xul)
|
||||
content/framework/toolbox-init.js (framework/toolbox-init.js)
|
||||
content/framework/options-panel.css (framework/options-panel.css)
|
||||
@ -134,19 +132,15 @@ devtools.jar:
|
||||
content/responsive.html/index.xhtml (responsive.html/index.xhtml)
|
||||
content/responsive.html/index.js (responsive.html/index.js)
|
||||
content/dom/dom.html (dom/dom.html)
|
||||
content/dom/content/dom-view.css (dom/content/dom-view.css)
|
||||
content/dom/main.js (dom/main.js)
|
||||
% skin devtools classic/1.0 %skin/
|
||||
skin/devtools-browser.css (themes/devtools-browser.css)
|
||||
skin/common.css (themes/common.css)
|
||||
skin/splitters.css (themes/splitters.css)
|
||||
skin/dark-theme.css (themes/dark-theme.css)
|
||||
skin/light-theme.css (themes/light-theme.css)
|
||||
skin/firebug-theme.css (themes/firebug-theme.css)
|
||||
skin/toolbars.css (themes/toolbars.css)
|
||||
skin/toolbox.css (themes/toolbox.css)
|
||||
skin/tooltips.css (themes/tooltips.css)
|
||||
skin/variables.css (themes/variables.css)
|
||||
skin/images/add.svg (themes/images/add.svg)
|
||||
skin/images/filters.svg (themes/images/filters.svg)
|
||||
skin/images/filter-swatch.svg (themes/images/filter-swatch.svg)
|
||||
@ -161,7 +155,6 @@ devtools.jar:
|
||||
skin/images/filetypes/dir-close.svg (themes/images/filetypes/dir-close.svg)
|
||||
skin/images/filetypes/dir-open.svg (themes/images/filetypes/dir-open.svg)
|
||||
skin/images/filetypes/globe.svg (themes/images/filetypes/globe.svg)
|
||||
skin/images/filetypes/store.svg (themes/images/filetypes/store.svg)
|
||||
skin/images/commandline-icon.svg (themes/images/commandline-icon.svg)
|
||||
skin/images/alerticon-warning.png (themes/images/alerticon-warning.png)
|
||||
skin/images/alerticon-warning@2x.png (themes/images/alerticon-warning@2x.png)
|
||||
@ -170,7 +163,6 @@ devtools.jar:
|
||||
skin/images/command-paintflashing.svg (themes/images/command-paintflashing.svg)
|
||||
skin/images/command-screenshot.svg (themes/images/command-screenshot.svg)
|
||||
skin/images/command-responsivemode.svg (themes/images/command-responsivemode.svg)
|
||||
skin/images/command-scratchpad.svg (themes/images/command-scratchpad.svg)
|
||||
skin/images/command-pick.svg (themes/images/command-pick.svg)
|
||||
skin/images/command-frames.svg (themes/images/command-frames.svg)
|
||||
skin/images/command-console.svg (themes/images/command-console.svg)
|
||||
@ -193,7 +185,6 @@ devtools.jar:
|
||||
skin/dom.css (themes/dom.css)
|
||||
skin/performance.css (themes/performance.css)
|
||||
skin/memory.css (themes/memory.css)
|
||||
skin/promisedebugger.css (themes/promisedebugger.css)
|
||||
skin/scratchpad.css (themes/scratchpad.css)
|
||||
skin/shadereditor.css (themes/shadereditor.css)
|
||||
skin/storage.css (themes/storage.css)
|
||||
@ -205,11 +196,11 @@ devtools.jar:
|
||||
skin/jit-optimizations.css (themes/jit-optimizations.css)
|
||||
skin/images/filter.svg (themes/images/filter.svg)
|
||||
skin/images/search.svg (themes/images/search.svg)
|
||||
skin/images/itemToggle.svg (themes/images/itemToggle.svg)
|
||||
skin/images/itemArrow-dark-rtl.svg (themes/images/itemArrow-dark-rtl.svg)
|
||||
skin/images/itemArrow-dark-ltr.svg (themes/images/itemArrow-dark-ltr.svg)
|
||||
skin/images/itemArrow-rtl.svg (themes/images/itemArrow-rtl.svg)
|
||||
skin/images/itemArrow-ltr.svg (themes/images/itemArrow-ltr.svg)
|
||||
skin/images/item-toggle.svg (themes/images/item-toggle.svg)
|
||||
skin/images/item-arrow-dark-rtl.svg (themes/images/item-arrow-dark-rtl.svg)
|
||||
skin/images/item-arrow-dark-ltr.svg (themes/images/item-arrow-dark-ltr.svg)
|
||||
skin/images/item-arrow-rtl.svg (themes/images/item-arrow-rtl.svg)
|
||||
skin/images/item-arrow-ltr.svg (themes/images/item-arrow-ltr.svg)
|
||||
skin/images/noise.png (themes/images/noise.png)
|
||||
skin/images/dropmarker.svg (themes/images/dropmarker.svg)
|
||||
skin/boxmodel.css (themes/boxmodel.css)
|
||||
@ -221,8 +212,6 @@ devtools.jar:
|
||||
skin/images/debugger-step-in.svg (themes/images/debugger-step-in.svg)
|
||||
skin/images/debugger-step-out.svg (themes/images/debugger-step-out.svg)
|
||||
skin/images/debugger-step-over.svg (themes/images/debugger-step-over.svg)
|
||||
skin/images/debugger-blackbox.svg (themes/images/debugger-blackbox.svg)
|
||||
skin/images/debugger-prettyprint.svg (themes/images/debugger-prettyprint.svg)
|
||||
skin/images/debugger-toggleBreakpoints.svg (themes/images/debugger-toggleBreakpoints.svg)
|
||||
skin/images/tracer-icon.png (themes/images/tracer-icon.png)
|
||||
skin/images/tracer-icon@2x.png (themes/images/tracer-icon@2x.png)
|
||||
@ -266,7 +255,7 @@ devtools.jar:
|
||||
skin/images/debugging-devices.svg (themes/images/debugging-devices.svg)
|
||||
skin/images/debugging-tabs.svg (themes/images/debugging-tabs.svg)
|
||||
skin/images/debugging-workers.svg (themes/images/debugging-workers.svg)
|
||||
skin/images/tabs-icon.svg (themes/images/tabs-icon.svg)
|
||||
skin/images/globe.svg (themes/images/globe.svg)
|
||||
skin/images/tool-options.svg (themes/images/tool-options.svg)
|
||||
skin/images/tool-webconsole.svg (themes/images/tool-webconsole.svg)
|
||||
skin/images/tool-canvas.svg (themes/images/tool-canvas.svg)
|
||||
@ -317,7 +306,6 @@ devtools.jar:
|
||||
skin/images/reload.svg (themes/images/reload.svg)
|
||||
skin/images/security-state-broken.svg (themes/images/security-state-broken.svg)
|
||||
skin/images/security-state-insecure.svg (themes/images/security-state-insecure.svg)
|
||||
skin/images/security-state-local.svg (themes/images/security-state-local.svg)
|
||||
skin/images/security-state-secure.svg (themes/images/security-state-secure.svg)
|
||||
skin/images/security-state-weak.svg (themes/images/security-state-weak.svg)
|
||||
skin/images/diff.svg (themes/images/diff.svg)
|
||||
|
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 2.0 KiB |
@ -4,15 +4,11 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
DevToolsModules(
|
||||
'controls.png',
|
||||
'controls@2x.png',
|
||||
'general.css',
|
||||
'headers-panel.css',
|
||||
'json-panel.css',
|
||||
'main.css',
|
||||
'read-only-prop.svg',
|
||||
'search-box.css',
|
||||
'search.svg',
|
||||
'text-panel.css',
|
||||
|
@ -1,32 +0,0 @@
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs>
|
||||
<linearGradient id="c">
|
||||
<stop offset="0" stop-color="#787878"/>
|
||||
<stop offset="1" stop-color="#b4b4b4"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="d">
|
||||
<stop offset="0" stop-color="#505050"/>
|
||||
<stop offset="1" stop-color="#787878"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="a">
|
||||
<stop offset="0" stop-color="#c8c8c8"/>
|
||||
<stop offset="1" stop-color="#dcdcdc"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="b">
|
||||
<stop offset="0" stop-color="#a0a0a0"/>
|
||||
<stop offset="1" stop-color="#c8c8c8"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="e" x1="8.637" x2="6.34" y1="4.311" y2=".583" xlink:href="#a" gradientUnits="userSpaceOnUse" gradientTransform="matrix(.6 0 0 .7 .9 1)"/>
|
||||
<linearGradient id="f" x1="7.188" x2="4.956" y1="5.078" y2="1.392" xlink:href="#b" gradientUnits="userSpaceOnUse" gradientTransform="matrix(.6 0 0 .7 .9 1)"/>
|
||||
<linearGradient id="g" x1="11.377" x2="4.559" y1="1052.085" y2="1040.666" xlink:href="#a" gradientUnits="userSpaceOnUse" gradientTransform="matrix(.6 0 0 .6 1 -609.4)"/>
|
||||
<linearGradient id="h" x1="8.842" x2="1.917" y1="1053.385" y2="1041.923" xlink:href="#b" gradientUnits="userSpaceOnUse" gradientTransform="matrix(.6 0 0 .6 1 -609.4)"/>
|
||||
<linearGradient id="i" x1="8.54" x2="6.608" y1="12.498" y2="7.825" xlink:href="#d" gradientUnits="userSpaceOnUse" gradientTransform="matrix(.7 0 0 .7 .3 .3)"/>
|
||||
<linearGradient id="j" x1="9.392" x2="7.402" y1="12.116" y2="7.414" xlink:href="#c" gradientUnits="userSpaceOnUse" gradientTransform="matrix(.7 0 0 .7 .3 .3)"/>
|
||||
</defs>
|
||||
<path fill="url(#e)" stroke="url(#f)" stroke-width=".504" d="M6 1.215c-1.632 0-2.945 1.286-2.99 2.904.113-.02.237-.046.356-.046h.938C4.386 3.194 5.1 2.42 6 2.42c.9 0 1.614.774 1.696 1.654h.938c.12 0 .243.026.357.045C8.946 2.5 7.633 1.214 6 1.214z" stroke-linejoin="round" transform="matrix(1.2 0 0 1.2 -1.1 -1.1)"/>
|
||||
<rect width="9.571" height="6.72" x="1.214" y="4.065" fill="url(#g)" stroke="url(#h)" stroke-width=".504" rx="1.679" ry="1.679" stroke-linejoin="round" transform="matrix(1.2 0 0 1.2 -1.1 -1.1)"/>
|
||||
<path fill="url(#i)" stroke="url(#j)" stroke-width=".336" d="M6 5.504c-.67 0-1.205.535-1.205 1.206 0 .562.375 1.023.893 1.162v1.475h.625V7.872c.517-.14.892-.6.892-1.162 0-.67-.534-1.206-1.205-1.206z" stroke-linejoin="round" transform="matrix(1.2 0 0 1.2 -1.1 -1.1)"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 2.6 KiB |
@ -16,7 +16,6 @@ DevToolsModules(
|
||||
'app.js',
|
||||
'constants.js',
|
||||
'dominator-tree-lazy-children.js',
|
||||
'initializer.js',
|
||||
'models.js',
|
||||
'panel.js',
|
||||
'reducers.js',
|
||||
|
@ -22,9 +22,8 @@
|
||||
|
||||
<vbox id="network-inspector-view" flex="1">
|
||||
<hbox id="netmonitor-toolbar" class="devtools-toolbar">
|
||||
<toolbarbutton id="requests-menu-clear-button"
|
||||
class="devtools-toolbarbutton devtools-clear-icon"
|
||||
data-localization="tooltiptext=netmonitor.toolbar.clear"/>
|
||||
<html:div xmlns="http://www.w3.org/1999/xhtml"
|
||||
id="react-clear-button-hook"/>
|
||||
<html:div xmlns="http://www.w3.org/1999/xhtml"
|
||||
id="react-filter-buttons-hook"/>
|
||||
<spacer id="requests-menu-spacer"
|
||||
|
@ -154,7 +154,6 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
|
||||
|
||||
this.requestsMenuSortEvent = getKeyWithEvent(this.sortBy.bind(this));
|
||||
this.requestsMenuSortKeyboardEvent = getKeyWithEvent(this.sortBy.bind(this), true);
|
||||
this.reqeustsMenuClearEvent = this.clear.bind(this);
|
||||
this._onContextMenu = this._onContextMenu.bind(this);
|
||||
this._onContextNewTabCommand = this.openRequestInTab.bind(this);
|
||||
this._onContextCopyUrlCommand = this.copyUrl.bind(this);
|
||||
@ -187,8 +186,6 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
|
||||
this.requestsMenuSortEvent, false);
|
||||
$("#toolbar-labels").addEventListener("keydown",
|
||||
this.requestsMenuSortKeyboardEvent, false);
|
||||
$("#requests-menu-clear-button").addEventListener("click",
|
||||
this.reqeustsMenuClearEvent, false);
|
||||
$("#toggle-raw-headers").addEventListener("click",
|
||||
this.toggleRawHeadersEvent, false);
|
||||
$("#requests-menu-contents").addEventListener("scroll", this._onScroll, true);
|
||||
@ -269,8 +266,6 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
|
||||
this.requestsMenuSortEvent, false);
|
||||
$("#toolbar-labels").removeEventListener("keydown",
|
||||
this.requestsMenuSortKeyboardEvent, false);
|
||||
$("#requests-menu-clear-button").removeEventListener("click",
|
||||
this.reqeustsMenuClearEvent, false);
|
||||
this.freetextFilterBox.removeEventListener("input",
|
||||
this.requestsFreetextFilterEvent, false);
|
||||
this.freetextFilterBox.removeEventListener("command",
|
||||
|
@ -1,10 +1,14 @@
|
||||
/* globals dumpn, $, NetMonitorView */
|
||||
"use strict";
|
||||
|
||||
const { createFactory } = require("devtools/client/shared/vendor/react");
|
||||
const { createFactory, DOM } = require("devtools/client/shared/vendor/react");
|
||||
const ReactDOM = require("devtools/client/shared/vendor/react-dom");
|
||||
const Provider = createFactory(require("devtools/client/shared/vendor/react-redux").Provider);
|
||||
const FilterButtons = createFactory(require("./components/filter-buttons"));
|
||||
const { L10N } = require("./l10n");
|
||||
|
||||
// Shortcuts
|
||||
const { button } = DOM;
|
||||
|
||||
/**
|
||||
* Functions handling the toolbar view: expand/collapse button etc.
|
||||
@ -22,8 +26,20 @@ ToolbarView.prototype = {
|
||||
initialize: function (store) {
|
||||
dumpn("Initializing the ToolbarView");
|
||||
|
||||
this._clearContainerNode = $("#react-clear-button-hook");
|
||||
this._filterContainerNode = $("#react-filter-buttons-hook");
|
||||
|
||||
// clear button
|
||||
ReactDOM.render(button({
|
||||
id: "requests-menu-clear-button",
|
||||
className: "devtools-button devtools-clear-icon",
|
||||
title: L10N.getStr("netmonitor.toolbar.clear"),
|
||||
onClick: () => {
|
||||
NetMonitorView.RequestsMenu.clear();
|
||||
}
|
||||
}), this._clearContainerNode);
|
||||
|
||||
// filter button
|
||||
ReactDOM.render(Provider(
|
||||
{ store },
|
||||
FilterButtons()
|
||||
@ -40,6 +56,7 @@ ToolbarView.prototype = {
|
||||
destroy: function () {
|
||||
dumpn("Destroying the ToolbarView");
|
||||
|
||||
ReactDOM.unmountComponentAtNode(this._clearContainerNode);
|
||||
ReactDOM.unmountComponentAtNode(this._filterContainerNode);
|
||||
|
||||
this._detailsPaneToggleButton.removeEventListener("mousedown",
|
||||
|
@ -5,7 +5,7 @@
|
||||
<?xml-stylesheet href="chrome://devtools/skin/light-theme.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://devtools/skin/projecteditor/projecteditor.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://devtools/content/debugger/debugger.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://devtools/skin/common.css" type="text/css"?>
|
||||
<?xml-stylesheet href="resource://devtools/client/themes/common.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://devtools/skin/markup.css" type="text/css"?>
|
||||
|
||||
<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
|
||||
|
@ -9,5 +9,4 @@ DevToolsModules(
|
||||
'file-picker.js',
|
||||
'l10n.js',
|
||||
'prompts.js',
|
||||
'readdir.js',
|
||||
)
|
||||
|
@ -12,7 +12,6 @@
|
||||
<head>
|
||||
<title>&title;</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<link rel="stylesheet" href="chrome://devtools/skin/promisedebugger.css" type="text/css"/>
|
||||
<script type="application/javascript;version=1.8" src="chrome://devtools/content/shared/theme-switching.js"/>
|
||||
</head>
|
||||
<body class="devtools-monospace" role="application">
|
||||
|
@ -9,6 +9,10 @@ const Services = require("Services");
|
||||
const { Task } = require("devtools/shared/task");
|
||||
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
||||
const { BrowserElementWebNavigation } = require("./web-navigation");
|
||||
const { getStack } = require("devtools/shared/platform/stack");
|
||||
|
||||
// A symbol used to hold onto the frame loader from the outer browser while tunneling.
|
||||
const FRAME_LOADER = Symbol("devtools/responsive/frame-loader");
|
||||
|
||||
function debug(msg) {
|
||||
// console.log(msg);
|
||||
@ -77,6 +81,34 @@ function tunnelToInnerBrowser(outer, inner) {
|
||||
throw new Error("The inner browser must be remote.");
|
||||
}
|
||||
|
||||
// Various browser methods access the `frameLoader` property, including:
|
||||
// * `saveBrowser` from contentAreaUtils.js
|
||||
// * `docShellIsActive` from remote-browser.xml
|
||||
// * `hasContentOpener` from remote-browser.xml
|
||||
// * `preserveLayers` from remote-browser.xml
|
||||
// * `receiveMessage` from SessionStore.jsm
|
||||
// In general, these methods are interested in the `frameLoader` for the content,
|
||||
// so we redirect them to the inner browser's `frameLoader`.
|
||||
outer[FRAME_LOADER] = outer.frameLoader;
|
||||
Object.defineProperty(outer, "frameLoader", {
|
||||
get() {
|
||||
let stack = getStack();
|
||||
// One exception is `receiveMessage` from SessionStore.jsm. SessionStore
|
||||
// expects data updates to come in as messages targeted to a <xul:browser>.
|
||||
// In addition, it verifies[1] correctness by checking that the received
|
||||
// message's `targetFrameLoader` property matches the `frameLoader` of the
|
||||
// <xul:browser>. To keep SessionStore functioning as expected, we give it the
|
||||
// outer `frameLoader` as if nothing has changed.
|
||||
// [1]: https://dxr.mozilla.org/mozilla-central/rev/b1b18f25c0ea69d9ee57c4198d577dfcd0129ce1/browser/components/sessionstore/SessionStore.jsm#716
|
||||
if (stack.caller.filename.endsWith("SessionStore.jsm")) {
|
||||
return outer[FRAME_LOADER];
|
||||
}
|
||||
return inner.frameLoader;
|
||||
},
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
});
|
||||
|
||||
// The `permanentKey` property on a <xul:browser> is used to index into various maps
|
||||
// held by the session store. When you swap content around with
|
||||
// `_swapBrowserDocShells`, these keys are also swapped so they follow the content.
|
||||
@ -152,35 +184,6 @@ function tunnelToInnerBrowser(outer, inner) {
|
||||
outer[property] = inner[property];
|
||||
}
|
||||
|
||||
// Wants to access the content's `frameLoader`, so we'll redirect it to
|
||||
// inner browser.
|
||||
Object.defineProperty(outer, "hasContentOpener", {
|
||||
get() {
|
||||
return inner.frameLoader.tabParent.hasContentOpener;
|
||||
},
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
});
|
||||
|
||||
// Wants to access the content's `frameLoader`, so we'll redirect it to
|
||||
// inner browser.
|
||||
Object.defineProperty(outer, "docShellIsActive", {
|
||||
get() {
|
||||
return inner.frameLoader.tabParent.docShellIsActive;
|
||||
},
|
||||
set(value) {
|
||||
inner.frameLoader.tabParent.docShellIsActive = value;
|
||||
},
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
});
|
||||
|
||||
// Wants to access the content's `frameLoader`, so we'll redirect it to
|
||||
// inner browser.
|
||||
outer.preserveLayers = value => {
|
||||
inner.frameLoader.tabParent.preserveLayers(value);
|
||||
};
|
||||
|
||||
// Expose `PopupNotifications` on the content's owner global.
|
||||
// This is used by PermissionUI.jsm for permission doorhangers.
|
||||
// Note: This pollutes the responsive.html tool UI's global.
|
||||
@ -253,13 +256,6 @@ function tunnelToInnerBrowser(outer, inner) {
|
||||
outer.destroy();
|
||||
outer.style.MozBinding = "";
|
||||
|
||||
// Reset overridden XBL properties and methods. Deleting the override
|
||||
// means it will fallback to the original XBL binding definitions which
|
||||
// are on the prototype.
|
||||
delete outer.hasContentOpener;
|
||||
delete outer.docShellIsActive;
|
||||
delete outer.preserveLayers;
|
||||
|
||||
// Reset @remote since this is now back to a regular, non-remote browser
|
||||
outer.setAttribute("remote", "false");
|
||||
|
||||
@ -273,6 +269,12 @@ function tunnelToInnerBrowser(outer, inner) {
|
||||
mmTunnel.destroy();
|
||||
mmTunnel = null;
|
||||
|
||||
// Reset overridden XBL properties and methods. Deleting the override
|
||||
// means it will fallback to the original XBL binding definitions which
|
||||
// are on the prototype.
|
||||
delete outer.frameLoader;
|
||||
delete outer[FRAME_LOADER];
|
||||
|
||||
// Invalidate outer's permanentKey so that SessionStore stops associating
|
||||
// things that happen to the outer browser with the content inside in the
|
||||
// inner browser.
|
||||
@ -296,7 +298,7 @@ function copyPermanentKey(outer, inner) {
|
||||
// no direct mechanism to do so. As a workaround, we wait until the one errant message
|
||||
// has gone by, and then we copy the permanentKey after that, since the permanentKey is
|
||||
// what SessionStore uses to identify each browser.
|
||||
let outerMM = outer.frameLoader.messageManager;
|
||||
let outerMM = outer[FRAME_LOADER].messageManager;
|
||||
let onHistoryEntry = message => {
|
||||
let history = message.data.data.history;
|
||||
if (!history || !history.entries) {
|
||||
@ -427,17 +429,17 @@ MessageManagerTunnel.prototype = {
|
||||
],
|
||||
|
||||
get outerParentMM() {
|
||||
if (!this.outer.frameLoader) {
|
||||
if (!this.outer[FRAME_LOADER]) {
|
||||
return null;
|
||||
}
|
||||
return this.outer.frameLoader.messageManager;
|
||||
return this.outer[FRAME_LOADER].messageManager;
|
||||
},
|
||||
|
||||
get outerChildMM() {
|
||||
// This is only possible because we require the outer browser to be
|
||||
// non-remote, so we're able to reach into its window and use the child
|
||||
// side message manager there.
|
||||
let docShell = this.outer.frameLoader.docShell;
|
||||
let docShell = this.outer[FRAME_LOADER].docShell;
|
||||
return docShell.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIContentFrameMessageManager);
|
||||
},
|
||||
|
@ -59,10 +59,9 @@ exports.items = [
|
||||
}
|
||||
},
|
||||
offChange: function (aTarget, aChangeHandler) {
|
||||
if (aTarget.tab) {
|
||||
ResponsiveUIManager.off("on", aChangeHandler);
|
||||
ResponsiveUIManager.off("off", aChangeHandler);
|
||||
}
|
||||
// Do not check for target.tab as it may already be null during destroy
|
||||
ResponsiveUIManager.off("on", aChangeHandler);
|
||||
ResponsiveUIManager.off("off", aChangeHandler);
|
||||
},
|
||||
},
|
||||
exec: gcli_cmd_resize
|
||||
|
@ -9,7 +9,7 @@ Basic tests for the HSplitBox component.
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript "src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
|
||||
<link rel="stylesheet" href="chrome://devtools/skin/splitters.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="resource://devtools/client/themes/splitters.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="chrome://devtools/skin/components-h-split-box.css" type="text/css"/>
|
||||
<style>
|
||||
html {
|
||||
|
@ -30,7 +30,6 @@ DevToolsModules(
|
||||
'doorhanger.js',
|
||||
'file-watcher-worker.js',
|
||||
'file-watcher.js',
|
||||
'frame-script-utils.js',
|
||||
'getjson.js',
|
||||
'inplace-editor.js',
|
||||
'Jsbeautify.jsm',
|
||||
@ -47,7 +46,6 @@ DevToolsModules(
|
||||
'SplitView.jsm',
|
||||
'suggestion-picker.js',
|
||||
'telemetry.js',
|
||||
'theme-switching.js',
|
||||
'theme.js',
|
||||
'undo.js',
|
||||
'view-source.js',
|
||||
|
@ -11,7 +11,7 @@
|
||||
const HTML_NS = "http://www.w3.org/1999/xhtml";
|
||||
const TEST_URI = `data:text/xml;charset=UTF-8,<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin/global.css"?>
|
||||
<?xml-stylesheet href="chrome://devtools/skin/variables.css"?>
|
||||
<?xml-stylesheet href="resource://devtools/client/themes/variables.css"?>
|
||||
<?xml-stylesheet href="chrome://devtools/skin/tooltips.css"?>
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
class="theme-light" title="Tooltip hover test">
|
||||
|
@ -11,7 +11,7 @@ loadHelperScript("helper_inplace_editor.js");
|
||||
|
||||
const TEST_URI = `data:text/xml;charset=UTF-8,<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin/global.css"?>
|
||||
<?xml-stylesheet href="chrome://devtools/skin/common.css"?>
|
||||
<?xml-stylesheet href="resource://devtools/client/themes/common.css"?>
|
||||
<?xml-stylesheet href="chrome://devtools/skin/tooltips.css"?>
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Tooltip test">
|
||||
|
@ -22,14 +22,26 @@ add_task(function* () {
|
||||
info("Clearing the browser cache");
|
||||
cache.clear();
|
||||
|
||||
let { ui } = yield openStyleEditorForURL(TEST_URL, win);
|
||||
let { toolbox, ui } = yield openStyleEditorForURL(TEST_URL, win);
|
||||
|
||||
is(ui.editors.length, 1, "The style editor contains one sheet.");
|
||||
let editor = ui.editors[0];
|
||||
|
||||
yield editor.getSourceEditor();
|
||||
yield checkDiskCacheFor(TEST_HOST);
|
||||
|
||||
yield toolbox.destroy();
|
||||
|
||||
let onUnload = new Promise(done => {
|
||||
win.addEventListener("unload", function listener(event) {
|
||||
if (event.target == win.document) {
|
||||
win.removeEventListener("unload", listener);
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
win.close();
|
||||
yield onUnload;
|
||||
});
|
||||
|
||||
function checkDiskCacheFor(host) {
|
||||
|
@ -21,7 +21,7 @@ add_task(function* () {
|
||||
let editor = yield ui.editors[0].getSourceEditor();
|
||||
let originalSourceEditor = editor.sourceEditor;
|
||||
|
||||
let hostWindow = toolbox._host._window;
|
||||
let hostWindow = toolbox.win.parent;
|
||||
let originalWidth = hostWindow.outerWidth;
|
||||
let originalHeight = hostWindow.outerHeight;
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
* 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/. */
|
||||
|
||||
@import url("splitters.css");
|
||||
@import url("resource://devtools/client/themes/splitters.css");
|
||||
|
||||
:root {
|
||||
font: message-box;
|
||||
@ -554,7 +554,7 @@ checkbox:-moz-focusring {
|
||||
}
|
||||
|
||||
.devtools-filterinput {
|
||||
background-image: url(images/filter.svg#filterinput);
|
||||
background-image: url(chrome://devtools/skin/images/filter.svg#filterinput);
|
||||
}
|
||||
|
||||
.devtools-searchinput:-moz-locale-dir(rtl),
|
||||
|
@ -3,8 +3,8 @@
|
||||
* 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/. */
|
||||
|
||||
@import url(variables.css);
|
||||
@import url(common.css);
|
||||
@import url(resource://devtools/client/themes/variables.css);
|
||||
@import url(resource://devtools/client/themes/common.css);
|
||||
@import url(toolbars.css);
|
||||
@import url(tooltips.css);
|
||||
|
||||
|
@ -95,7 +95,7 @@
|
||||
}
|
||||
|
||||
#black-box {
|
||||
list-style-image: url(images/debugger-blackbox.svg);
|
||||
list-style-image: url(images/item-toggle.svg);
|
||||
}
|
||||
|
||||
.theme-firebug #black-box {
|
||||
@ -103,7 +103,7 @@
|
||||
}
|
||||
|
||||
#pretty-print {
|
||||
list-style-image: url(images/debugger-prettyprint.svg);
|
||||
list-style-image: url(images/tool-styleeditor.svg);
|
||||
}
|
||||
|
||||
.theme-firebug #pretty-print {
|
||||
@ -150,7 +150,7 @@
|
||||
#black-boxed-message-button > .button-box > .button-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-image: url(images/debugger-blackbox.svg);
|
||||
background-image: url(images/item-toggle.svg);
|
||||
background-position: 0 0;
|
||||
background-size: cover;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* 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/. */
|
||||
|
||||
@import url("splitters.css");
|
||||
@import url("resource://devtools/client/themes/splitters.css");
|
||||
|
||||
/* Bottom-docked toolbox minimize transition */
|
||||
.devtools-toolbox-bottom-iframe {
|
||||
@ -24,4 +24,3 @@
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,8 @@
|
||||
* 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/. */
|
||||
|
||||
@import url(variables.css);
|
||||
@import url(common.css);
|
||||
@import url(resource://devtools/client/themes/variables.css);
|
||||
@import url(resource://devtools/client/themes/common.css);
|
||||
@import url(light-theme.css);
|
||||
|
||||
:root {
|
||||
|
@ -1,7 +0,0 @@
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="#0b0b0b">
|
||||
<path d="M5 1.5a.5.5 0 0 0-1 0v2a.5.5 0 0 0 1 0v-2zM8.5 3.5v-2a.5.5 0 0 0-1 0v2a.5.5 0 0 0 1 0zM12 3.5v-2a.5.5 0 1 0-1 0v2a.5.5 0 1 0 1 0zM5 7h4a.5.5 0 0 0 0-1H5a.5.5 0 0 0 0 1zM5 11h2a.5.5 0 1 0 0-1H5a.5.5 0 1 0 0 1zM6 9h5a.5.5 0 1 0 0-1H6a.5.5 0 0 0 0 1z"/>
|
||||
<path d="M3 3.996v9.008c0-.003 0-.004.002-.004h9.996c-.001 0 .002-.003.002.004V3.996c0 .003 0 .004-.002.004H3.002C3.003 4 3 4.003 3 3.996zm-1 0C2 3.446 2.456 3 3.002 3h9.996A.998.998 0 0 1 14 3.996v9.008c0 .55-.456.996-1.002.996H3.002A.998.998 0 0 1 2 13.004V3.996z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 851 B |
@ -1,6 +0,0 @@
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="#0b0b0b">
|
||||
<path d="M5.5 2C3.565 2 2.806 3.12 3.065 4.587c.239 1.346.117 1.76-.435 2.39l-.054.06c-.252.288-.39.474-.523.74L1.94 8l.112.224c.132.265.27.45.523.739l.054.06c.552.63.674 1.044.435 2.39C2.802 12.904 3.527 14 5.5 14a.5.5 0 1 0 0-1c-1.291 0-1.614-.487-1.45-1.413.292-1.65.081-2.37-.669-3.223l-.053-.06c-.2-.229-.296-.357-.38-.528v.448c.084-.17.18-.299.38-.528l.053-.06c.75-.854.961-1.573.67-3.223C3.89 3.515 4.24 3 5.5 3a.5.5 0 1 0 0-1zM10.5 3c1.26 0 1.609.515 1.45 1.413-.292 1.65-.081 2.37.669 3.223l.053.06c.2.229.296.357.38.528v-.448c-.084.17-.18.299-.38.528l-.053.06c-.75.854-.961 1.573-.67 3.223.165.926-.158 1.413-1.449 1.413a.5.5 0 1 0 0 1c1.973 0 2.698-1.096 2.435-2.587-.239-1.346-.117-1.76.435-2.39l.054-.06c.252-.288.39-.474.523-.74L14.06 8l-.112-.224c-.132-.265-.27-.45-.523-.739l-.054-.06c-.552-.63-.674-1.044-.435-2.39C13.194 3.12 12.435 2 10.5 2a.5.5 0 0 0 0 1z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.2 KiB |
@ -1,7 +0,0 @@
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="#0b0b0b">
|
||||
<path d="M7.5 7.556c3.006 0 5.5-1.136 5.5-2.778C13 3.136 10.506 2 7.5 2S2 3.136 2 4.778C2 6.42 4.494 7.556 7.5 7.556zm0-1c-2.517 0-4.5-.903-4.5-1.778S4.983 3 7.5 3s4.5.903 4.5 1.778-1.983 1.778-4.5 1.778zM7.5 14.445c3.006 0 5.5-1.137 5.5-2.778 0-.878-.595-1.606-1.657-2.081-.244-.11-.473-.107-.778-.033-.056.014-.565.158-.765.205-.626.148-1.342.231-2.3.231-.973 0-1.683-.082-2.273-.225a18.574 18.574 0 0 1-.673-.193c-.277-.076-.479-.089-.707-.005l-.035.014C2.638 10.064 2 10.756 2 11.667c0 1.641 2.494 2.778 5.5 2.778zm0-1c-2.517 0-4.5-.904-4.5-1.778 0-.432.354-.816 1.194-1.163h-.002c-.012.005.003.006.097.032-.056-.016.474.144.702.2.669.162 1.458.253 2.509.253 1.035 0 1.828-.092 2.53-.257.228-.054.74-.2.77-.207a.756.756 0 0 1 .134-.027c.734.329 1.066.735 1.066 1.169 0 .874-1.983 1.778-4.5 1.778z"/>
|
||||
<path d="M7.5 10.945c3.006 0 5.5-1.137 5.5-2.778 0-.873-.62-1.601-1.693-2.082-.244-.109-.472-.106-.773-.032-.051.013-.551.158-.75.206-.615.147-1.326.23-2.284.23-.973 0-1.68-.082-2.265-.225a17.077 17.077 0 0 1-.66-.19c-.27-.076-.467-.092-.692-.015l-.054.02C2.65 6.568 2 7.259 2 8.168c0 1.641 2.494 2.778 5.5 2.778zm0-1C4.983 9.945 3 9.04 3 8.167c0-.426.364-.813 1.21-1.163l-.003.001c-.011.004.005.005.099.032-.079-.022.465.143.69.198.665.163 1.452.254 2.504.254 1.036 0 1.825-.092 2.517-.258.228-.054.733-.2.758-.207a.766.766 0 0 1 .124-.026c.748.335 1.101.75 1.101 1.169 0 .874-1.983 1.778-4.5 1.778z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 418 B After Width: | Height: | Size: 418 B |
@ -1,7 +1,7 @@
|
||||
<!-- 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/. -->
|
||||
<svg width="7" xmlns="http://www.w3.org/2000/svg" height="12" viewBox="0 0 7 12">
|
||||
<path fill="#181d20" d="M0,11.6 0,.4 5.5,6z"/>
|
||||
<path fill="#000" d="M1,0 0,0 0,.4 5.5,6 0,11.6 0,12 1,12 7,6z"/>
|
||||
</svg>
|
||||
<!-- 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/. -->
|
||||
<svg width="7" xmlns="http://www.w3.org/2000/svg" height="12" viewBox="0 0 7 12">
|
||||
<path fill="#181d20" d="M0,11.6 0,.4 5.5,6z"/>
|
||||
<path fill="#000" d="M1,0 0,0 0,.4 5.5,6 0,11.6 0,12 1,12 7,6z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 425 B After Width: | Height: | Size: 418 B |
Before Width: | Height: | Size: 421 B After Width: | Height: | Size: 421 B |
Before Width: | Height: | Size: 421 B After Width: | Height: | Size: 421 B |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
@ -1,7 +0,0 @@
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="#0b0b0b">
|
||||
<circle cx="8" cy="8.5" r="1.5"/>
|
||||
<path d="M15.498 8.28l-.001-.03v-.002-.004l-.002-.018-.004-.031c0-.002 0-.002 0 0l-.004-.035.006.082c-.037-.296-.133-.501-.28-.661-.4-.522-.915-1.042-1.562-1.604-1.36-1.182-2.74-1.975-4.178-2.309a6.544 6.544 0 0 0-2.755-.042c-.78.153-1.565.462-2.369.91C3.252 5.147 2.207 6 1.252 7.035c-.216.233-.36.398-.499.577-.338.437-.338 1 0 1.437.428.552.941 1.072 1.59 1.635 1.359 1.181 2.739 1.975 4.177 2.308.907.21 1.829.223 2.756.043.78-.153 1.564-.462 2.369-.91 1.097-.612 2.141-1.464 3.097-2.499.217-.235.36-.398.498-.578.12-.128.216-.334.248-.554 0 .01 0 .01-.008.04l.013-.079-.001.011.003-.031.001-.017v.005l.001-.02v.008l.002-.03.001-.05-.001-.044v-.004-.004zm-.954.045v.007l.001.004V8.33v.012l-.001.01v-.005-.005l.002-.015-.001.008c-.002.014-.002.014 0 0l-.007.084c.003-.057-.004-.041-.014-.031-.143.182-.27.327-.468.543-.89.963-1.856 1.752-2.86 2.311-.724.404-1.419.677-2.095.81a5.63 5.63 0 0 1-2.374-.036c-1.273-.295-2.523-1.014-3.774-2.101-.604-.525-1.075-1.001-1.457-1.496-.054-.07-.054-.107 0-.177.117-.152.244-.298.442-.512.89-.963 1.856-1.752 2.86-2.311.724-.404 1.419-.678 2.095-.81a5.631 5.631 0 0 1 2.374.036c1.272.295 2.523 1.014 3.774 2.101.603.524 1.074 1 1.457 1.496.035.041.043.057.046.076 0 .01 0 .01.008.043l-.009-.047.003.02-.002-.013v-.008.016c0-.004 0-.004 0 0v-.004z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 61 KiB |
@ -3,8 +3,8 @@
|
||||
* 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/. */
|
||||
|
||||
@import url(variables.css);
|
||||
@import url(common.css);
|
||||
@import url(resource://devtools/client/themes/variables.css);
|
||||
@import url(resource://devtools/client/themes/common.css);
|
||||
@import url(toolbars.css);
|
||||
@import url(tooltips.css);
|
||||
|
||||
|
@ -10,5 +10,6 @@ DIRS += [
|
||||
|
||||
DevToolsModules(
|
||||
'common.css',
|
||||
'splitters.css',
|
||||
'variables.css',
|
||||
)
|
||||
|
@ -7,6 +7,10 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#react-clear-button-hook {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collapsed details pane needs to be truly hidden to prevent both accessibility
|
||||
* tools and keyboard from accessing its contents.
|
||||
@ -289,7 +293,7 @@
|
||||
}
|
||||
|
||||
.security-state-local {
|
||||
list-style-image: url(chrome://devtools/skin/images/security-state-local.svg);
|
||||
list-style-image: url(chrome://devtools/skin/images/globe.svg);
|
||||
}
|
||||
|
||||
.requests-menu-type,
|
||||
|
@ -58,7 +58,7 @@
|
||||
}
|
||||
|
||||
#filter-button {
|
||||
list-style-image: url(images/filter.svg);
|
||||
list-style-image: url(chrome://devtools/skin/images/filter.svg);
|
||||
}
|
||||
|
||||
#performance-filter-menupopup > menuitem .menu-iconic-left::after {
|
||||
|
@ -1,3 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
@ -309,7 +309,7 @@
|
||||
}
|
||||
|
||||
.ruleview-overridden-rule-filter {
|
||||
background-image: url(images/filter.svg#filterinput);
|
||||
background-image: url(chrome://devtools/skin/images/filter.svg#filterinput);
|
||||
background-size: 11px 11px;
|
||||
margin-inline-start: 5px;
|
||||
display: inline-block;
|
||||
|
@ -44,7 +44,7 @@
|
||||
|
||||
.side-menu-widget-item-checkbox .checkbox-check {
|
||||
-moz-appearance: none;
|
||||
background-image: url(images/itemToggle.svg);
|
||||
background-image: url(images/item-toggle.svg);
|
||||
background-color: transparent;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
|
@ -7,4 +7,4 @@
|
||||
* specific path.
|
||||
*/
|
||||
|
||||
@import url("chrome://devtools/skin/common.css");
|
||||
@import url("resource://devtools/client/themes/common.css");
|
||||
|
@ -4,12 +4,12 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
.theme-dark {
|
||||
--sidemenu-selected-arrow: url(images/itemArrow-dark-ltr.svg);
|
||||
--sidemenu-selected-arrow-rtl: url(images/itemArrow-dark-rtl.svg);
|
||||
--sidemenu-selected-arrow: url(images/item-arrow-dark-ltr.svg);
|
||||
--sidemenu-selected-arrow-rtl: url(images/item-arrow-dark-rtl.svg);
|
||||
}
|
||||
.theme-light {
|
||||
--sidemenu-selected-arrow: url(images/itemArrow-ltr.svg);
|
||||
--sidemenu-selected-arrow-rtl: url(images/itemArrow-rtl.svg);
|
||||
--sidemenu-selected-arrow: url(images/item-arrow-ltr.svg);
|
||||
--sidemenu-selected-arrow-rtl: url(images/item-arrow-rtl.svg);
|
||||
}
|
||||
|
||||
.splitview-nav-container .devtools-throbber {
|
||||
|
@ -15,7 +15,7 @@
|
||||
}
|
||||
|
||||
#storage-tree .tree-widget-item[type="store"]:after {
|
||||
background-image: url(chrome://devtools/skin/images/filetypes/store.svg);
|
||||
background-image: url(chrome://devtools/skin/images/tool-storage.svg);
|
||||
background-size: 18px 18px;
|
||||
background-position: -1px 0;
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ li.error > .stylesheet-info > .stylesheet-more > .stylesheet-error-message {
|
||||
cursor: pointer;
|
||||
padding: 8px 0;
|
||||
margin: 0 8px;
|
||||
background-image: url(images/itemToggle.svg);
|
||||
background-image: url(images/item-toggle.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-clip: content-box;
|
||||
background-position: center;
|
||||
|
@ -11,11 +11,11 @@
|
||||
--searchbox-border-color: #ffbf00;
|
||||
--searcbox-no-match-background-color: #ffe5e5;
|
||||
--searcbox-no-match-border-color: #e52e2e;
|
||||
--magnifying-glass-image: url(images/search.svg);
|
||||
--filter-image: url(images/filter.svg);
|
||||
--tool-options-image: url(images/tool-options.svg);
|
||||
--magnifying-glass-image: url(chrome://devtools/skin/images/search.svg);
|
||||
--filter-image: url(chrome://devtools/skin/images/filter.svg);
|
||||
--tool-options-image: url(chrome://devtools/skin/images/tool-options.svg);
|
||||
--icon-filter: none;
|
||||
--checked-icon-filter: url(images/filters.svg#checked-icon-state);
|
||||
--checked-icon-filter: url(chrome://devtools/skin/images/filters.svg#checked-icon-state);
|
||||
--toolbar-button-border-color: rgba(170, 170, 170, .5);
|
||||
}
|
||||
|
||||
@ -26,17 +26,17 @@
|
||||
--searchbox-border-color: #d99f2b;
|
||||
--searcbox-no-match-background-color: #402325;
|
||||
--searcbox-no-match-border-color: #cc3d3d;
|
||||
--magnifying-glass-image: url(images/search.svg);
|
||||
--filter-image: url(images/filter.svg);
|
||||
--tool-options-image: url(images/tool-options.svg);
|
||||
--magnifying-glass-image: url(chrome://devtools/skin/images/search.svg);
|
||||
--filter-image: url(chrome://devtools/skin/images/filter.svg);
|
||||
--tool-options-image: url(chrome://devtools/skin/images/tool-options.svg);
|
||||
--icon-filter: invert(1);
|
||||
--checked-icon-filter: url(images/filters.svg#dark-theme-checked-icon-state);
|
||||
--checked-icon-filter: url(chrome://devtools/skin/images/filters.svg#dark-theme-checked-icon-state);
|
||||
--toolbar-button-border-color: rgba(0, 0, 0, .4);
|
||||
}
|
||||
|
||||
.theme-firebug {
|
||||
--magnifying-glass-image: url(images/search.svg);
|
||||
--tool-options-image: url(images/firebug/tool-options.svg);
|
||||
--magnifying-glass-image: url(chrome://devtools/skin/images/search.svg);
|
||||
--tool-options-image: url(chrome://devtools/skin/images/firebug/tool-options.svg);
|
||||
--icon-filter: none;
|
||||
--checked-icon-filter: none;
|
||||
--toolbar-button-border-color: rgba(170, 170, 170, .5);
|
||||
|
@ -12,7 +12,7 @@
|
||||
--command-paintflashing-image: url(images/command-paintflashing.svg);
|
||||
--command-screenshot-image: url(images/command-screenshot.svg);
|
||||
--command-responsive-image: url(images/command-responsivemode.svg);
|
||||
--command-scratchpad-image: url(images/command-scratchpad.svg);
|
||||
--command-scratchpad-image: url(images/tool-scratchpad.svg);
|
||||
--command-pick-image: url(images/command-pick.svg);
|
||||
--command-frames-image: url(images/command-frames.svg);
|
||||
--command-splitconsole-image: url(images/command-console.svg);
|
||||
|
@ -6,8 +6,8 @@
|
||||
.theme-dark {
|
||||
--table-splitter-color: rgba(255,255,255,0.15);
|
||||
--table-zebra-background: rgba(255,255,255,0.05);
|
||||
--sidemenu-selected-arrow: url(images/itemArrow-dark-ltr.svg);
|
||||
--sidemenu-selected-arrow-rtl: url(images/itemArrow-dark-rtl.svg);
|
||||
--sidemenu-selected-arrow: url(images/item-arrow-dark-ltr.svg);
|
||||
--sidemenu-selected-arrow-rtl: url(images/item-arrow-dark-rtl.svg);
|
||||
--delete-icon: url(chrome://devtools/skin/images/vview-delete.png);
|
||||
--delete-icon-2x: url(chrome://devtools/skin/images/vview-delete@2x.png);
|
||||
}
|
||||
@ -15,8 +15,8 @@
|
||||
.theme-light {
|
||||
--table-splitter-color: rgba(0,0,0,0.15);
|
||||
--table-zebra-background: rgba(0,0,0,0.05);
|
||||
--sidemenu-selected-arrow: url(images/itemArrow-ltr.svg);
|
||||
--sidemenu-selected-arrow-rtl: url(images/itemArrow-rtl.svg);
|
||||
--sidemenu-selected-arrow: url(images/item-arrow-ltr.svg);
|
||||
--sidemenu-selected-arrow-rtl: url(images/item-arrow-rtl.svg);
|
||||
--delete-icon: url(chrome://devtools/skin/images/vview-delete.png);
|
||||
--delete-icon-2x: url(chrome://devtools/skin/images/vview-delete@2x.png);
|
||||
}
|
||||
@ -24,8 +24,8 @@
|
||||
.theme-firebug {
|
||||
--table-splitter-color: rgba(0,0,0,0.15);
|
||||
--table-zebra-background: rgba(0,0,0,0.05);
|
||||
--sidemenu-selected-arrow: url(images/itemArrow-ltr.svg);
|
||||
--sidemenu-selected-arrow-rtl: url(images/itemArrow-rtl.svg);
|
||||
--sidemenu-selected-arrow: url(images/item-arrow-ltr.svg);
|
||||
--sidemenu-selected-arrow-rtl: url(images/item-arrow-rtl.svg);
|
||||
--delete-icon: url(chrome://devtools/skin/images/firebug/close.svg);
|
||||
--delete-icon-2x: url(chrome://devtools/skin/images/firebug/close.svg);
|
||||
}
|
||||
|
@ -96,5 +96,5 @@ function onExpandClosure(results) {
|
||||
|
||||
gVariablesView.window.focus();
|
||||
gJSTerm.once("sidebar-closed", finishTest);
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {});
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, gVariablesView.window);
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
<head>
|
||||
<meta charset="utf8"/>
|
||||
<link rel="stylesheet" href="chrome://webide/skin/deck.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="chrome://devtools/skin/common.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="resource://devtools/client/themes/common.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="chrome://webide/skin/logs.css" type="text/css"/>
|
||||
<script type="application/javascript;version=1.8" src="chrome://devtools/content/shared/theme-switching.js"></script>
|
||||
<script type="application/javascript;version=1.8" src="logs.js"></script>
|
||||
|
@ -12,7 +12,7 @@
|
||||
<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/global.css"?>
|
||||
<?xml-stylesheet href="chrome://devtools/skin/common.css"?>
|
||||
<?xml-stylesheet href="resource://devtools/client/themes/common.css"?>
|
||||
<?xml-stylesheet href="chrome://webide/skin/webide.css"?>
|
||||
|
||||
<window id="webide" onclose="return UI.canCloseProject();"
|
||||
|
@ -718,6 +718,15 @@ Animation::AnimationTimeToTimeStamp(const StickyTimeDuration& aTime) const
|
||||
return result;
|
||||
}
|
||||
|
||||
TimeStamp
|
||||
Animation::ElapsedTimeToTimeStamp(
|
||||
const StickyTimeDuration& aElapsedTime) const
|
||||
{
|
||||
return AnimationTimeToTimeStamp(aElapsedTime +
|
||||
mEffect->SpecifiedTiming().mDelay);
|
||||
}
|
||||
|
||||
|
||||
// https://w3c.github.io/web-animations/#silently-set-the-current-time
|
||||
void
|
||||
Animation::SilentlySetCurrentTime(const TimeDuration& aSeekTime)
|
||||
|
@ -255,6 +255,10 @@ public:
|
||||
*/
|
||||
TimeStamp AnimationTimeToTimeStamp(const StickyTimeDuration& aTime) const;
|
||||
|
||||
// Converts an AnimationEvent's elapsedTime value to an equivalent TimeStamp
|
||||
// that can be used to sort events by when they occurred.
|
||||
TimeStamp ElapsedTimeToTimeStamp(const StickyTimeDuration& aElapsedTime) const;
|
||||
|
||||
bool IsPausedOrPausing() const
|
||||
{
|
||||
return PlayState() == AnimationPlayState::Paused ||
|
||||
|
@ -64,9 +64,7 @@ function ensureElementRemoval(aElement) {
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
const OMTAPrefKey = 'layers.offmainthreadcomposition.async-animations';
|
||||
var omtaEnabled = SpecialPowers.DOMWindowUtils.layerManagerRemote &&
|
||||
SpecialPowers.getBoolPref(OMTAPrefKey);
|
||||
var omtaEnabled = isOMTAEnabled();
|
||||
|
||||
var isAndroid = !!navigator.userAgent.includes("Android");
|
||||
|
||||
|
@ -50,9 +50,7 @@ div {
|
||||
/** Test for bug 1045994 - Add a chrome-only property to inspect if an
|
||||
animation is running on the compositor or not **/
|
||||
|
||||
const OMTAPrefKey = 'layers.offmainthreadcomposition.async-animations';
|
||||
var omtaEnabled = SpecialPowers.DOMWindowUtils.layerManagerRemote &&
|
||||
SpecialPowers.getBoolPref(OMTAPrefKey);
|
||||
var omtaEnabled = isOMTAEnabled();
|
||||
|
||||
function assert_animation_is_running_on_compositor(animation, desc) {
|
||||
assert_equals(animation.isRunningOnCompositor, omtaEnabled,
|
||||
|
@ -0,0 +1,223 @@
|
||||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>Tests for CSS-Transition events</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-transitions-2/#transition-events">
|
||||
<script src="../testcommon.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Helper class to record the elapsedTime member of each event.
|
||||
* The EventWatcher class in testharness.js allows us to wait on
|
||||
* multiple events in a certain order but only records the event
|
||||
* parameters of the most recent event.
|
||||
*/
|
||||
function TransitionEventHandler(target) {
|
||||
this.target = target;
|
||||
this.target.ontransitionrun = function(evt) {
|
||||
this.transitionrun = evt.elapsedTime;
|
||||
}.bind(this);
|
||||
this.target.ontransitionstart = function(evt) {
|
||||
this.transitionstart = evt.elapsedTime;
|
||||
}.bind(this);
|
||||
this.target.ontransitionend = function(evt) {
|
||||
this.transitionend = evt.elapsedTime;
|
||||
}.bind(this);
|
||||
}
|
||||
|
||||
TransitionEventHandler.prototype.clear = function() {
|
||||
this.transitionrun = undefined;
|
||||
this.transitionstart = undefined;
|
||||
this.transitionend = undefined;
|
||||
};
|
||||
|
||||
function setupTransition(t, transitionStyle) {
|
||||
var div, watcher, handler, transition;
|
||||
transitionStyle = transitionStyle || 'transition: margin-left 100s 100s';
|
||||
div = addDiv(t, { style: transitionStyle });
|
||||
watcher = new EventWatcher(t, div, [ 'transitionrun',
|
||||
'transitionstart',
|
||||
'transitionend' ]);
|
||||
handler = new TransitionEventHandler(div);
|
||||
flushComputedStyle(div);
|
||||
|
||||
div.style.marginLeft = '100px';
|
||||
flushComputedStyle(div);
|
||||
|
||||
transition = div.getAnimations()[0];
|
||||
|
||||
return [transition, watcher, handler];
|
||||
}
|
||||
|
||||
// On the next frame (i.e. when events are queued), whether or not the
|
||||
// transition is still pending depends on the implementation.
|
||||
promise_test(function(t) {
|
||||
var [transition, watcher, handler] = setupTransition(t);
|
||||
return watcher.wait_for('transitionrun').then(function(evt) {
|
||||
assert_equals(evt.elapsedTime, 0.0);
|
||||
});
|
||||
}, 'Idle -> Pending or Before');
|
||||
|
||||
promise_test(function(t) {
|
||||
var [transition, watcher, handler] = setupTransition(t);
|
||||
// Force the transition to leave the idle phase
|
||||
transition.startTime = document.timeline.currentTime;
|
||||
return watcher.wait_for('transitionrun').then(function(evt) {
|
||||
assert_equals(evt.elapsedTime, 0.0);
|
||||
});
|
||||
}, 'Idle -> Before');
|
||||
|
||||
promise_test(function(t) {
|
||||
var [transition, watcher, handler] = setupTransition(t);
|
||||
// Seek to Active phase.
|
||||
transition.currentTime = 100 * MS_PER_SEC;
|
||||
transition.pause();
|
||||
return watcher.wait_for([ 'transitionrun',
|
||||
'transitionstart' ]).then(function(evt) {
|
||||
assert_equals(handler.transitionrun, 0.0);
|
||||
assert_equals(handler.transitionstart, 0.0);
|
||||
});
|
||||
}, 'Idle or Pending -> Active');
|
||||
|
||||
promise_test(function(t) {
|
||||
var [transition, watcher, handler] = setupTransition(t);
|
||||
// Seek to After phase.
|
||||
transition.finish();
|
||||
return watcher.wait_for([ 'transitionrun',
|
||||
'transitionstart',
|
||||
'transitionend' ]).then(function(evt) {
|
||||
assert_equals(handler.transitionrun, 0.0);
|
||||
assert_equals(handler.transitionstart, 0.0);
|
||||
assert_equals(handler.transitionend, 100.0);
|
||||
});
|
||||
}, 'Idle or Pending -> After');
|
||||
|
||||
promise_test(function(t) {
|
||||
var [transition, watcher, handler] = setupTransition(t);
|
||||
|
||||
return Promise.all([ watcher.wait_for('transitionrun'),
|
||||
transition.ready ]).then(function() {
|
||||
transition.currentTime = 100 * MS_PER_SEC;
|
||||
return watcher.wait_for('transitionstart');
|
||||
}).then(function() {
|
||||
assert_equals(handler.transitionstart, 0.0);
|
||||
});
|
||||
}, 'Before -> Active');
|
||||
|
||||
promise_test(function(t) {
|
||||
var [transition, watcher, handler] = setupTransition(t);
|
||||
return Promise.all([ watcher.wait_for('transitionrun'),
|
||||
transition.ready ]).then(function() {
|
||||
// Seek to After phase.
|
||||
transition.currentTime = 200 * MS_PER_SEC;
|
||||
return watcher.wait_for([ 'transitionstart', 'transitionend' ]);
|
||||
}).then(function(evt) {
|
||||
assert_equals(handler.transitionstart, 0.0);
|
||||
assert_equals(handler.transitionend, 100.0);
|
||||
});
|
||||
}, 'Before -> After');
|
||||
|
||||
promise_test(function(t) {
|
||||
var [transition, watcher, handler] = setupTransition(t);
|
||||
// Seek to Active phase.
|
||||
transition.currentTime = 100 * MS_PER_SEC;
|
||||
return watcher.wait_for([ 'transitionrun',
|
||||
'transitionstart' ]).then(function(evt) {
|
||||
// Seek to Before phase.
|
||||
transition.currentTime = 0;
|
||||
return watcher.wait_for('transitionend');
|
||||
}).then(function(evt) {
|
||||
assert_equals(evt.elapsedTime, 0.0);
|
||||
});
|
||||
}, 'Active -> Before');
|
||||
|
||||
promise_test(function(t) {
|
||||
var [transition, watcher, handler] = setupTransition(t);
|
||||
// Seek to Active phase.
|
||||
transition.currentTime = 100 * MS_PER_SEC;
|
||||
return watcher.wait_for([ 'transitionrun',
|
||||
'transitionstart' ]).then(function(evt) {
|
||||
// Seek to After phase.
|
||||
transition.currentTime = 200 * MS_PER_SEC;
|
||||
return watcher.wait_for('transitionend');
|
||||
}).then(function(evt) {
|
||||
assert_equals(evt.elapsedTime, 100.0);
|
||||
});
|
||||
}, 'Active -> After');
|
||||
|
||||
promise_test(function(t) {
|
||||
var [transition, watcher, handler] = setupTransition(t);
|
||||
// Seek to After phase.
|
||||
transition.finish();
|
||||
return watcher.wait_for([ 'transitionrun',
|
||||
'transitionstart',
|
||||
'transitionend' ]).then(function(evt) {
|
||||
// Seek to Before phase.
|
||||
transition.currentTime = 0;
|
||||
return watcher.wait_for([ 'transitionstart', 'transitionend' ]);
|
||||
}).then(function(evt) {
|
||||
assert_equals(handler.transitionstart, 100.0);
|
||||
assert_equals(handler.transitionend, 0.0);
|
||||
});
|
||||
}, 'After -> Before');
|
||||
|
||||
promise_test(function(t) {
|
||||
var [transition, watcher, handler] = setupTransition(t);
|
||||
// Seek to After phase.
|
||||
transition.finish();
|
||||
return watcher.wait_for([ 'transitionrun',
|
||||
'transitionstart',
|
||||
'transitionend' ]).then(function(evt) {
|
||||
// Seek to Active phase.
|
||||
transition.currentTime = 100 * MS_PER_SEC;
|
||||
return watcher.wait_for('transitionstart');
|
||||
}).then(function(evt) {
|
||||
assert_equals(evt.elapsedTime, 100.0);
|
||||
});
|
||||
}, 'After -> Active');
|
||||
|
||||
promise_test(function(t) {
|
||||
var [transition, watcher, handler] =
|
||||
setupTransition(t, 'transition: margin-left 100s -50s');
|
||||
|
||||
return watcher.wait_for([ 'transitionrun',
|
||||
'transitionstart' ]).then(function() {
|
||||
assert_equals(handler.transitionrun, 50.0);
|
||||
assert_equals(handler.transitionstart, 50.0);
|
||||
transition.finish();
|
||||
return watcher.wait_for('transitionend');
|
||||
}).then(function(evt) {
|
||||
assert_equals(evt.elapsedTime, 100.0);
|
||||
});
|
||||
}, 'Calculating the interval start and end time with negative start delay.');
|
||||
|
||||
promise_test(function(t) {
|
||||
var [transition, watcher, handler] = setupTransition(t);
|
||||
|
||||
return watcher.wait_for('transitionrun').then(function(evt) {
|
||||
// We can't set the end delay via generated effect timing.
|
||||
// Because CSS-Transition use the AnimationEffectTimingReadOnly.
|
||||
transition.effect = new KeyframeEffect(handler.target,
|
||||
{ marginleft: [ '0px', '100px' ]},
|
||||
{ duration: 100 * MS_PER_SEC,
|
||||
endDelay: -50 * MS_PER_SEC });
|
||||
// Seek to Before and play.
|
||||
transition.cancel();
|
||||
transition.play();
|
||||
return watcher.wait_for('transitionstart');
|
||||
}).then(function() {
|
||||
assert_equals(handler.transitionstart, 0.0);
|
||||
|
||||
// Seek to After phase.
|
||||
transition.finish();
|
||||
return watcher.wait_for('transitionend');
|
||||
}).then(function(evt) {
|
||||
assert_equals(evt.elapsedTime, 50.0);
|
||||
});
|
||||
}, 'Calculating the interval start and end time with negative end delay.');
|
||||
|
||||
done();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
'use strict';
|
||||
setup({explicit_done: true});
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{ "set": [["dom.animations-api.core.enabled", true]]},
|
||||
function() {
|
||||
window.open("file_csstransition-events.html");
|
||||
});
|
||||
</script>
|
@ -28,6 +28,7 @@ support-files =
|
||||
css-transitions/file_animation-pausing.html
|
||||
css-transitions/file_animation-ready.html
|
||||
css-transitions/file_animation-starttime.html
|
||||
css-transitions/file_csstransition-events.html
|
||||
css-transitions/file_csstransition-transitionproperty.html
|
||||
css-transitions/file_document-get-animations.html
|
||||
css-transitions/file_effect-target.html
|
||||
@ -46,6 +47,7 @@ support-files =
|
||||
mozilla/file_spacing_property_order.html
|
||||
mozilla/file_spacing_transform.html
|
||||
mozilla/file_transform_limits.html
|
||||
mozilla/file_transition_finish_on_compositor.html
|
||||
mozilla/file_underlying-discrete-value.html
|
||||
mozilla/file_set-easing.html
|
||||
style/file_animation-seeking-with-current-time.html
|
||||
@ -80,6 +82,7 @@ skip-if = buildapp == 'mulet'
|
||||
[css-transitions/test_animation-pausing.html]
|
||||
[css-transitions/test_animation-ready.html]
|
||||
[css-transitions/test_animation-starttime.html]
|
||||
[css-transitions/test_csstransition-events.html]
|
||||
[css-transitions/test_csstransition-transitionproperty.html]
|
||||
[css-transitions/test_document-get-animations.html]
|
||||
[css-transitions/test_effect-target.html]
|
||||
@ -103,6 +106,8 @@ skip-if = (toolkit == 'gonk' && debug)
|
||||
[mozilla/test_spacing_property_order.html]
|
||||
[mozilla/test_spacing_transform.html]
|
||||
[mozilla/test_transform_limits.html]
|
||||
[mozilla/test_transition_finish_on_compositor.html]
|
||||
skip-if = toolkit == 'android'
|
||||
[mozilla/test_underlying-discrete-value.html]
|
||||
[style/test_animation-seeking-with-current-time.html]
|
||||
[style/test_animation-seeking-with-start-time.html]
|
||||
|
@ -81,10 +81,7 @@ async_test(function(t) {
|
||||
// us through a different code path.
|
||||
async_test(function(t) {
|
||||
// This test only applies to compositor animations
|
||||
const OMTAPrefKey = 'layers.offmainthreadcomposition.async-animations';
|
||||
var omtaEnabled = SpecialPowers.DOMWindowUtils.layerManagerRemote &&
|
||||
opener.SpecialPowers.getBoolPref(OMTAPrefKey);
|
||||
if (!omtaEnabled) {
|
||||
if (!isOMTAEnabled()) {
|
||||
t.done();
|
||||
return;
|
||||
}
|
||||
|
@ -0,0 +1,67 @@
|
||||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<script src="../testcommon.js"></script>
|
||||
<script src="/tests/SimpleTest/paint_listener.js"></script>
|
||||
<style>
|
||||
div {
|
||||
/* Element needs geometry to be eligible for layerization */
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: white;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
function waitForPaints() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
waitForAllPaintsFlushed(resolve);
|
||||
});
|
||||
}
|
||||
|
||||
promise_test(t => {
|
||||
// This test only applies to compositor animations
|
||||
if (!isOMTAEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var div = addDiv(t, { style: 'transition: transform 50ms; ' +
|
||||
'transform: translateX(0px)' });
|
||||
getComputedStyle(div).transform;
|
||||
|
||||
div.style.transform = 'translateX(100px)';
|
||||
|
||||
var timeBeforeStart = window.performance.now();
|
||||
return waitForPaints().then(() => {
|
||||
// If it took over 50ms to paint the transition, we have no luck
|
||||
// to test it. This situation will happen if GC runs while waiting for the
|
||||
// paint.
|
||||
if (window.performance.now() - timeBeforeStart >= 50) {
|
||||
return;
|
||||
}
|
||||
|
||||
var transform =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
|
||||
assert_not_equals(transform, '',
|
||||
'The transition style is applied on the compositor');
|
||||
|
||||
// Generate artificial busyness on the main thread for 100ms.
|
||||
var timeAtStart = window.performance.now();
|
||||
while (window.performance.now() - timeAtStart < 100) {}
|
||||
|
||||
// Now the transition on the compositor should finish but stay at the final
|
||||
// position because there was no chance to pull the transition back from
|
||||
// the compositor.
|
||||
transform =
|
||||
SpecialPowers.DOMWindowUtils.getOMTAStyle(div, 'transform');
|
||||
assert_equals(transform, 'matrix(1, 0, 0, 1, 100, 0)',
|
||||
'The final transition style is still applied on the ' +
|
||||
'compositor');
|
||||
});
|
||||
}, 'Transition on the compositor keeps the final style while the main thread ' +
|
||||
'is busy even if the transition finished on the compositor');
|
||||
|
||||
done();
|
||||
</script>
|
||||
</body>
|
@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
'use strict';
|
||||
setup({explicit_done: true});
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{ "set": [["dom.animations-api.core.enabled", true]]},
|
||||
function() {
|
||||
window.open("file_transition_finish_on_compositor.html");
|
||||
});
|
||||
</script>
|
@ -206,3 +206,11 @@ function setupSynchronousObserver(t, target, subtree) {
|
||||
return observer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if off-main-thread animations.
|
||||
*/
|
||||
function isOMTAEnabled() {
|
||||
const OMTAPrefKey = 'layers.offmainthreadcomposition.async-animations';
|
||||
return SpecialPowers.DOMWindowUtils.layerManagerRemote &&
|
||||
SpecialPowers.getBoolPref(OMTAPrefKey);
|
||||
}
|
||||
|
@ -121,11 +121,6 @@ this.PermissionsTable = { geolocation: {
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
telephony: {
|
||||
app: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
browser: {
|
||||
app: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
|