Merge m-c to m-i

MozReview-Commit-ID: LUDPZ08eWBo
This commit is contained in:
Phil Ringnalda 2016-10-26 18:58:54 -07:00
commit 76f5d03bb6
320 changed files with 2867 additions and 16973 deletions

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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"

View File

@ -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">

View File

@ -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)

View File

@ -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");

View File

@ -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

View File

@ -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 });

View File

@ -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);
});

View File

@ -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);

View File

@ -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;
});

View File

@ -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");

View File

@ -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":

View File

@ -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>

View File

@ -11,6 +11,4 @@ DIRS += [
DevToolsModules(
'dom-panel.js',
'dom.html',
'main.js',
)

View File

@ -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.

View File

@ -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',

View File

@ -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");

View File

@ -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") {

View File

@ -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();

View File

@ -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;

View File

@ -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"))

View File

@ -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}`,

View File

@ -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;
}

View 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;

View File

@ -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");

View File

@ -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

View File

@ -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();
},
/**

View File

@ -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();
};

View File

@ -16,7 +16,6 @@ DevToolsModules(
'breadcrumbs.js',
'inspector-commands.js',
'inspector-search.js',
'inspector.xhtml',
'panel.js',
'toolsidebar.js',
)

View File

@ -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);

View File

@ -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);
});
/**

View File

@ -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)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -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',

View File

@ -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

View File

@ -16,7 +16,6 @@ DevToolsModules(
'app.js',
'constants.js',
'dominator-tree-lazy-children.js',
'initializer.js',
'models.js',
'panel.js',
'reducers.js',

View File

@ -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"

View File

@ -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",

View File

@ -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",

View File

@ -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"?>

View File

@ -9,5 +9,4 @@ DevToolsModules(
'file-picker.js',
'l10n.js',
'prompts.js',
'readdir.js',
)

View File

@ -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">

View File

@ -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);
},

View File

@ -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

View File

@ -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 {

View File

@ -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',

View File

@ -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">

View File

@ -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">

View File

@ -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) {

View File

@ -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;

View File

@ -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),

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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

View File

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 61 KiB

View File

Before

Width:  |  Height:  |  Size: 418 B

After

Width:  |  Height:  |  Size: 418 B

View File

@ -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

View File

Before

Width:  |  Height:  |  Size: 421 B

After

Width:  |  Height:  |  Size: 421 B

View File

Before

Width:  |  Height:  |  Size: 421 B

After

Width:  |  Height:  |  Size: 421 B

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -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

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 61 KiB

View File

@ -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);

View File

@ -10,5 +10,6 @@ DIRS += [
DevToolsModules(
'common.css',
'splitters.css',
'variables.css',
)

View File

@ -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,

View File

@ -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 {

View File

@ -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/. */

View File

@ -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;

View File

@ -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;

View File

@ -7,4 +7,4 @@
* specific path.
*/
@import url("chrome://devtools/skin/common.css");
@import url("resource://devtools/client/themes/common.css");

View File

@ -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 {

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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>

View File

@ -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();"

View File

@ -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)

View File

@ -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 ||

View File

@ -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");

View File

@ -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,

View File

@ -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>

View File

@ -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>

View File

@ -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]

View File

@ -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;
}

View File

@ -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>

View File

@ -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>

View File

@ -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);
}

View File

@ -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,

Some files were not shown because too many files have changed in this diff Show More