diff --git a/devtools/client/responsive.html/docs/browser-swap.md b/devtools/client/responsive.html/docs/browser-swap.md
index f4f8322cb4..75055ad4ef 100644
--- a/devtools/client/responsive.html/docs/browser-swap.md
+++ b/devtools/client/responsive.html/docs/browser-swap.md
@@ -96,8 +96,11 @@ browsers are swapped.
Browser attributes `gBrowser.swapBrowsersAndCloseOther` transfers between
browsers:
+* `usercontextid`
+
Tab attributes `gBrowser.swapBrowsersAndCloseOther` transfers between tabs:
+* `usercontextid`
* `muted`
* `soundplaying`
* `busy`
diff --git a/devtools/client/responsive.html/manager.js b/devtools/client/responsive.html/manager.js
index 97ef8ad6dc..a3fbed3661 100644
--- a/devtools/client/responsive.html/manager.js
+++ b/devtools/client/responsive.html/manager.js
@@ -76,6 +76,11 @@ const ResponsiveUIManager = exports.ResponsiveUIManager = {
this.showRemoteOnlyNotification(window, tab, options);
return promise.reject(new Error("RDM only available for remote tabs."));
}
+ // Remove this once we support this case in bug 1306975.
+ if (tab.linkedBrowser.hasAttribute("usercontextid")) {
+ this.showNoContainerTabsNotification(window, tab, options);
+ return promise.reject(new Error("RDM not available for container tabs."));
+ }
if (!this.isActiveForTab(tab)) {
this.initMenuCheckListenerFor(window);
@@ -213,7 +218,16 @@ const ResponsiveUIManager = exports.ResponsiveUIManager = {
}
}),
- showRemoteOnlyNotification(window, tab, { command } = {}) {
+ showRemoteOnlyNotification(window, tab, options) {
+ this.showErrorNotification(window, tab, options, getStr("responsive.remoteOnly"));
+ },
+
+ showNoContainerTabsNotification(window, tab, options) {
+ this.showErrorNotification(window, tab, options,
+ getStr("responsive.noContainerTabs"));
+ },
+
+ showErrorNotification(window, tab, { command } = {}, msg) {
// Default to using the browser's per-tab notification box
let nbox = window.gBrowser.getNotificationBox(tab.linkedBrowser);
diff --git a/devtools/client/styleeditor/test/browser.ini b/devtools/client/styleeditor/test/browser.ini
index ba935e1ddf..4a84d45e66 100644
--- a/devtools/client/styleeditor/test/browser.ini
+++ b/devtools/client/styleeditor/test/browser.ini
@@ -77,6 +77,7 @@ support-files =
[browser_styleeditor_init.js]
[browser_styleeditor_inline_friendly_names.js]
[browser_styleeditor_loading.js]
+[browser_styleeditor_loading_with_containers.js]
[browser_styleeditor_media_sidebar.js]
[browser_styleeditor_media_sidebar_links.js]
skip-if = e10s && debug # Bug 1252201 - Docshell leak on debug e10s
diff --git a/devtools/client/styleeditor/test/browser_styleeditor_loading_with_containers.js b/devtools/client/styleeditor/test/browser_styleeditor_loading_with_containers.js
new file mode 100644
index 0000000000..a00628c8b8
--- /dev/null
+++ b/devtools/client/styleeditor/test/browser_styleeditor_loading_with_containers.js
@@ -0,0 +1,63 @@
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Test that the stylesheets can be loaded correctly with containers
+// (bug 1282660).
+
+const TESTCASE_URI = TEST_BASE_HTTP + "simple.html";
+const EXPECTED_SHEETS = [
+ {
+ sheetIndex: 0,
+ name: /^simple.css$/,
+ rules: 1,
+ active: true
+ }, {
+ sheetIndex: 1,
+ name: /^<.*>$/,
+ rules: 3,
+ active: false
+ }
+];
+
+add_task(function* () {
+ // Using the personal container.
+ let userContextId = 1;
+ let { tab } = yield* openTabInUserContext(TESTCASE_URI, userContextId);
+ let { ui } = yield openStyleEditor(tab);
+
+ is(ui.editors.length, 2, "The UI contains two style sheets.");
+ checkSheet(ui.editors[0], EXPECTED_SHEETS[0]);
+ checkSheet(ui.editors[1], EXPECTED_SHEETS[1]);
+});
+
+function* openTabInUserContext(uri, userContextId) {
+ // Open the tab in the correct userContextId.
+ let tab = gBrowser.addTab(uri, {userContextId});
+
+ // Select tab and make sure its browser is focused.
+ gBrowser.selectedTab = tab;
+ tab.ownerDocument.defaultView.focus();
+
+ let browser = gBrowser.getBrowserForTab(tab);
+ yield BrowserTestUtils.browserLoaded(browser);
+ return {tab, browser};
+}
+
+function checkSheet(editor, expected) {
+ is(editor.styleSheet.styleSheetIndex, expected.sheetIndex,
+ "Style sheet has correct index.");
+
+ let summary = editor.summary;
+ let name = summary.querySelector(".stylesheet-name > label")
+ .getAttribute("value");
+ ok(expected.name.test(name), "The name '" + name + "' is correct.");
+
+ let ruleCount = summary.querySelector(".stylesheet-rule-count").textContent;
+ is(parseInt(ruleCount, 10), expected.rules, "the rule count is correct");
+
+ is(summary.classList.contains("splitview-active"), expected.active,
+ "The active status for this sheet is correct.");
+}
diff --git a/devtools/client/webconsole/new-console-output/test/fixtures/stubs/consoleApi.js b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/consoleApi.js
index d9662c4fdc..26e95fe39f 100644
--- a/devtools/client/webconsole/new-console-output/test/fixtures/stubs/consoleApi.js
+++ b/devtools/client/webconsole/new-console-output/test/fixtures/stubs/consoleApi.js
@@ -657,7 +657,8 @@ stubPackets.set("console.log('foobar', 'test')", {
"appId": 0,
"firstPartyDomain": "",
"inIsolatedMozBrowser": false,
- "privateBrowsingId": 0
+ "privateBrowsingId": 0,
+ "userContextId": 0
},
"private": false,
"styles": [],
@@ -689,7 +690,8 @@ stubPackets.set("console.log(undefined)", {
"appId": 0,
"firstPartyDomain": "",
"inIsolatedMozBrowser": false,
- "privateBrowsingId": 0
+ "privateBrowsingId": 0,
+ "userContextId": 0
},
"private": false,
"styles": [],
@@ -719,7 +721,8 @@ stubPackets.set("console.warn('danger, will robinson!')", {
"appId": 0,
"firstPartyDomain": "",
"inIsolatedMozBrowser": false,
- "privateBrowsingId": 0
+ "privateBrowsingId": 0,
+ "userContextId": 0
},
"private": false,
"styles": [],
@@ -751,7 +754,8 @@ stubPackets.set("console.log(NaN)", {
"appId": 0,
"firstPartyDomain": "",
"inIsolatedMozBrowser": false,
- "privateBrowsingId": 0
+ "privateBrowsingId": 0,
+ "userContextId": 0
},
"private": false,
"styles": [],
@@ -783,7 +787,8 @@ stubPackets.set("console.log(null)", {
"appId": 0,
"firstPartyDomain": "",
"inIsolatedMozBrowser": false,
- "privateBrowsingId": 0
+ "privateBrowsingId": 0,
+ "userContextId": 0
},
"private": false,
"styles": [],
@@ -813,7 +818,8 @@ stubPackets.set("console.log('鼬')", {
"appId": 0,
"firstPartyDomain": "",
"inIsolatedMozBrowser": false,
- "privateBrowsingId": 0
+ "privateBrowsingId": 0,
+ "userContextId": 0
},
"private": false,
"styles": [],
@@ -841,7 +847,8 @@ stubPackets.set("console.clear()", {
"appId": 0,
"firstPartyDomain": "",
"inIsolatedMozBrowser": false,
- "privateBrowsingId": 0
+ "privateBrowsingId": 0,
+ "userContextId": 0
},
"private": false,
"timeStamp": 1477086275587,
@@ -874,7 +881,8 @@ stubPackets.set("console.count('bar')", {
"appId": 0,
"firstPartyDomain": "",
"inIsolatedMozBrowser": false,
- "privateBrowsingId": 0
+ "privateBrowsingId": 0,
+ "userContextId": 0
},
"private": false,
"timeStamp": 1477086277812,
@@ -925,7 +933,8 @@ stubPackets.set("console.assert(false, {message: 'foobar'})", {
"appId": 0,
"firstPartyDomain": "",
"inIsolatedMozBrowser": false,
- "privateBrowsingId": 0
+ "privateBrowsingId": 0,
+ "userContextId": 0
},
"private": false,
"styles": [],
@@ -964,7 +973,8 @@ stubPackets.set("console.log('hello \nfrom \rthe \"string world!')", {
"appId": 0,
"firstPartyDomain": "",
"inIsolatedMozBrowser": false,
- "privateBrowsingId": 0
+ "privateBrowsingId": 0,
+ "userContextId": 0
},
"private": false,
"styles": [],
@@ -994,7 +1004,8 @@ stubPackets.set("console.log('úṇĩçödê țĕșť')", {
"appId": 0,
"firstPartyDomain": "",
"inIsolatedMozBrowser": false,
- "privateBrowsingId": 0
+ "privateBrowsingId": 0,
+ "userContextId": 0
},
"private": false,
"styles": [],
@@ -1036,7 +1047,8 @@ stubPackets.set("console.dirxml(window)", {
"appId": 0,
"firstPartyDomain": "",
"inIsolatedMozBrowser": false,
- "privateBrowsingId": 0
+ "privateBrowsingId": 0,
+ "userContextId": 0
},
"private": false,
"timeStamp": 1477086285483,
@@ -1064,7 +1076,8 @@ stubPackets.set("console.trace()", {
"appId": 0,
"firstPartyDomain": "",
"inIsolatedMozBrowser": false,
- "privateBrowsingId": 0
+ "privateBrowsingId": 0,
+ "userContextId": 0
},
"private": false,
"timeStamp": 1477086287286,
@@ -1117,7 +1130,8 @@ stubPackets.set("console.time('bar')", {
"appId": 0,
"firstPartyDomain": "",
"inIsolatedMozBrowser": false,
- "privateBrowsingId": 0
+ "privateBrowsingId": 0,
+ "userContextId": 0
},
"private": false,
"timeStamp": 1477086289137,
@@ -1150,7 +1164,8 @@ stubPackets.set("console.timeEnd('bar')", {
"appId": 0,
"firstPartyDomain": "",
"inIsolatedMozBrowser": false,
- "privateBrowsingId": 0
+ "privateBrowsingId": 0,
+ "userContextId": 0
},
"private": false,
"timeStamp": 1477086289138,
@@ -1183,7 +1198,8 @@ stubPackets.set("console.table('bar')", {
"appId": 0,
"firstPartyDomain": "",
"inIsolatedMozBrowser": false,
- "privateBrowsingId": 0
+ "privateBrowsingId": 0,
+ "userContextId": 0
},
"private": false,
"timeStamp": 1477086290984,
@@ -1230,7 +1246,8 @@ stubPackets.set("console.table(['a', 'b', 'c'])", {
"appId": 0,
"firstPartyDomain": "",
"inIsolatedMozBrowser": false,
- "privateBrowsingId": 0
+ "privateBrowsingId": 0,
+ "userContextId": 0
},
"private": false,
"timeStamp": 1477086292762,
@@ -1260,7 +1277,8 @@ stubPackets.set("console.group('bar')", {
"appId": 0,
"firstPartyDomain": "",
"inIsolatedMozBrowser": false,
- "privateBrowsingId": 0
+ "privateBrowsingId": 0,
+ "userContextId": 0
},
"private": false,
"timeStamp": 1477086294628,
@@ -1290,7 +1308,8 @@ stubPackets.set("console.groupEnd('bar')", {
"appId": 0,
"firstPartyDomain": "",
"inIsolatedMozBrowser": false,
- "privateBrowsingId": 0
+ "privateBrowsingId": 0,
+ "userContextId": 0
},
"private": false,
"timeStamp": 1477086294630,
@@ -1320,7 +1339,8 @@ stubPackets.set("console.groupCollapsed('foo')", {
"appId": 0,
"firstPartyDomain": "",
"inIsolatedMozBrowser": false,
- "privateBrowsingId": 0
+ "privateBrowsingId": 0,
+ "userContextId": 0
},
"private": false,
"timeStamp": 1477086296567,
@@ -1350,7 +1370,8 @@ stubPackets.set("console.groupEnd('foo')", {
"appId": 0,
"firstPartyDomain": "",
"inIsolatedMozBrowser": false,
- "privateBrowsingId": 0
+ "privateBrowsingId": 0,
+ "userContextId": 0
},
"private": false,
"timeStamp": 1477086296570,
@@ -1378,7 +1399,8 @@ stubPackets.set("console.group()", {
"appId": 0,
"firstPartyDomain": "",
"inIsolatedMozBrowser": false,
- "privateBrowsingId": 0
+ "privateBrowsingId": 0,
+ "userContextId": 0
},
"private": false,
"timeStamp": 1477086298462,
@@ -1406,7 +1428,8 @@ stubPackets.set("console.groupEnd()", {
"appId": 0,
"firstPartyDomain": "",
"inIsolatedMozBrowser": false,
- "privateBrowsingId": 0
+ "privateBrowsingId": 0,
+ "userContextId": 0
},
"private": false,
"timeStamp": 1477086298464,
@@ -1437,7 +1460,8 @@ stubPackets.set("console.log(%cfoobar)", {
"appId": 0,
"firstPartyDomain": "",
"inIsolatedMozBrowser": false,
- "privateBrowsingId": 0
+ "privateBrowsingId": 0,
+ "userContextId": 0
},
"private": false,
"styles": [
diff --git a/devtools/server/actors/stylesheets.js b/devtools/server/actors/stylesheets.js
index f484a59765..7fcbca8c48 100644
--- a/devtools/server/actors/stylesheets.js
+++ b/devtools/server/actors/stylesheets.js
@@ -451,10 +451,21 @@ var StyleSheetActor = protocol.ActorClassWithSpec(styleSheetSpec, {
let options = {
loadFromCache: true,
policy: Ci.nsIContentPolicy.TYPE_INTERNAL_STYLESHEET,
- window: this.window,
charset: this._getCSSCharset()
};
+ // Bug 1282660 - We use the system principal to load the default internal
+ // stylesheets instead of the content principal since such stylesheets
+ // require system principal to load. At meanwhile, we strip the loadGroup
+ // for preventing the assertion of the userContextId mismatching.
+ // The default internal stylesheets load from the 'resource:' URL.
+ // Bug 1287607, 1291321 - 'chrome' and 'file' protocols should also be handled in the
+ // same way.
+ if (!/^(chrome|file|resource):\/\//.test(this.href)) {
+ options.window = this.window;
+ options.principal = this.document.nodePrincipal;
+ }
+
return fetch(this.href, options).then(({ content }) => {
this.text = content;
return content;