зеркало из https://github.com/mozilla/gecko-dev.git
Merge autoland to mozilla-central. a=merge
This commit is contained in:
Коммит
a40ef31fc9
|
@ -30,7 +30,7 @@ rev = "77a7f5eb12a8d93f2bd71bd4d844405e06743365"
|
|||
[source."https://github.com/mozilla-spidermonkey/jsparagus"]
|
||||
git = "https://github.com/mozilla-spidermonkey/jsparagus"
|
||||
replace-with = "vendored-sources"
|
||||
rev = "9871d65530f5fc0e3d953efbf40b51e9c56c6d2a"
|
||||
rev = "ce731ef6014c41b1691a9be3480fbc43e5e9a396"
|
||||
|
||||
[source."https://github.com/kvark/spirv_cross"]
|
||||
branch = "wgpu3"
|
||||
|
|
|
@ -2367,7 +2367,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "jsparagus"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=9871d65530f5fc0e3d953efbf40b51e9c56c6d2a#9871d65530f5fc0e3d953efbf40b51e9c56c6d2a"
|
||||
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=ce731ef6014c41b1691a9be3480fbc43e5e9a396#ce731ef6014c41b1691a9be3480fbc43e5e9a396"
|
||||
dependencies = [
|
||||
"jsparagus-ast",
|
||||
"jsparagus-emitter",
|
||||
|
@ -2380,7 +2380,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "jsparagus-ast"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=9871d65530f5fc0e3d953efbf40b51e9c56c6d2a#9871d65530f5fc0e3d953efbf40b51e9c56c6d2a"
|
||||
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=ce731ef6014c41b1691a9be3480fbc43e5e9a396#ce731ef6014c41b1691a9be3480fbc43e5e9a396"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"indexmap",
|
||||
|
@ -2391,7 +2391,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "jsparagus-emitter"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=9871d65530f5fc0e3d953efbf40b51e9c56c6d2a#9871d65530f5fc0e3d953efbf40b51e9c56c6d2a"
|
||||
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=ce731ef6014c41b1691a9be3480fbc43e5e9a396#ce731ef6014c41b1691a9be3480fbc43e5e9a396"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"byteorder",
|
||||
|
@ -2403,7 +2403,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "jsparagus-generated-parser"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=9871d65530f5fc0e3d953efbf40b51e9c56c6d2a#9871d65530f5fc0e3d953efbf40b51e9c56c6d2a"
|
||||
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=ce731ef6014c41b1691a9be3480fbc43e5e9a396#ce731ef6014c41b1691a9be3480fbc43e5e9a396"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"jsparagus-ast",
|
||||
|
@ -2413,12 +2413,12 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "jsparagus-json-log"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=9871d65530f5fc0e3d953efbf40b51e9c56c6d2a#9871d65530f5fc0e3d953efbf40b51e9c56c6d2a"
|
||||
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=ce731ef6014c41b1691a9be3480fbc43e5e9a396#ce731ef6014c41b1691a9be3480fbc43e5e9a396"
|
||||
|
||||
[[package]]
|
||||
name = "jsparagus-parser"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=9871d65530f5fc0e3d953efbf40b51e9c56c6d2a#9871d65530f5fc0e3d953efbf40b51e9c56c6d2a"
|
||||
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=ce731ef6014c41b1691a9be3480fbc43e5e9a396#ce731ef6014c41b1691a9be3480fbc43e5e9a396"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"jsparagus-ast",
|
||||
|
@ -2430,7 +2430,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "jsparagus-scope"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=9871d65530f5fc0e3d953efbf40b51e9c56c6d2a#9871d65530f5fc0e3d953efbf40b51e9c56c6d2a"
|
||||
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=ce731ef6014c41b1691a9be3480fbc43e5e9a396#ce731ef6014c41b1691a9be3480fbc43e5e9a396"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"jsparagus-ast",
|
||||
|
|
|
@ -12,4 +12,5 @@ skip-if = os == "android"
|
|||
[browser_test_general.js]
|
||||
[browser_test_shadowroot.js]
|
||||
[browser_test_zoom_text.js]
|
||||
skip-if = (os == "linux" && bits == 64 && debug && fission) #Bug 1630208
|
||||
[browser_test_zoom.js]
|
||||
|
|
|
@ -57,7 +57,6 @@
|
|||
window.messageManager.addMessageListener("contextmenu", this);
|
||||
|
||||
if (gMultiProcessBrowser) {
|
||||
messageManager.addMessageListener("DOMTitleChanged", this);
|
||||
messageManager.addMessageListener("DOMWindowClose", this);
|
||||
messageManager.addMessageListener("Browser:Init", this);
|
||||
} else {
|
||||
|
@ -5128,17 +5127,6 @@
|
|||
let browser = aMessage.target;
|
||||
|
||||
switch (aMessage.name) {
|
||||
case "DOMTitleChanged": {
|
||||
let tab = this.getTabForBrowser(browser);
|
||||
if (!tab || tab.hasAttribute("pending")) {
|
||||
return undefined;
|
||||
}
|
||||
let titleChanged = this.setTabTitle(tab);
|
||||
if (titleChanged && !tab.selected && !tab.hasAttribute("busy")) {
|
||||
tab.setAttribute("titlechanged", "true");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "contextmenu": {
|
||||
openContextMenu(aMessage);
|
||||
break;
|
||||
|
@ -5293,8 +5281,6 @@
|
|||
window.removeEventListener("framefocusrequested", this);
|
||||
|
||||
if (gMultiProcessBrowser) {
|
||||
let messageManager = window.getGroupMessageManager("browsers");
|
||||
messageManager.removeMessageListener("DOMTitleChanged", this);
|
||||
window.messageManager.removeMessageListener("contextmenu", this);
|
||||
|
||||
if (this._switcher) {
|
||||
|
@ -5354,6 +5340,29 @@
|
|||
}
|
||||
});
|
||||
|
||||
this.addEventListener("pagetitlechanged", event => {
|
||||
let browser = event.target;
|
||||
let tab = this.getTabForBrowser(browser);
|
||||
if (!tab || tab.hasAttribute("pending")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore empty title changes on internal pages. This prevents the title
|
||||
// from changing while Fluent is populating the (initially-empty) title
|
||||
// element.
|
||||
if (
|
||||
!browser.contentTitle &&
|
||||
browser.contentPrincipal.isSystemPrincipal
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
let titleChanged = this.setTabTitle(tab);
|
||||
if (titleChanged && !tab.selected && !tab.hasAttribute("busy")) {
|
||||
tab.setAttribute("titlechanged", "true");
|
||||
}
|
||||
});
|
||||
|
||||
this.addEventListener(
|
||||
"DOMWillOpenModalDialog",
|
||||
event => {
|
||||
|
@ -5441,47 +5450,6 @@
|
|||
true
|
||||
);
|
||||
|
||||
this.addEventListener("DOMTitleChanged", event => {
|
||||
if (!event.isTrusted) {
|
||||
return;
|
||||
}
|
||||
|
||||
var contentWin = event.target.defaultView;
|
||||
if (contentWin != contentWin.top) {
|
||||
return;
|
||||
}
|
||||
|
||||
let browser = contentWin.docShell.chromeEventHandler;
|
||||
var tab = this.getTabForBrowser(browser);
|
||||
if (!tab || tab.hasAttribute("pending")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!browser.docShell) {
|
||||
return;
|
||||
}
|
||||
// Ensure `docShell.document` (an nsIWebNavigation idl prop) is there:
|
||||
browser.docShell.QueryInterface(Ci.nsIWebNavigation);
|
||||
if (event.target != browser.docShell.document) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore empty title changes on internal pages. This prevents the title
|
||||
// from changing while Fluent is populating the (initially-empty) title
|
||||
// element.
|
||||
if (
|
||||
!browser.contentTitle &&
|
||||
browser.contentPrincipal.isSystemPrincipal
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
var titleChanged = this.setTabTitle(tab);
|
||||
if (titleChanged && !tab.selected && !tab.hasAttribute("busy")) {
|
||||
tab.setAttribute("titlechanged", "true");
|
||||
}
|
||||
});
|
||||
|
||||
let onTabCrashed = event => {
|
||||
if (!event.isTrusted || !event.isTopFrame) {
|
||||
return;
|
||||
|
|
|
@ -14,4 +14,4 @@ skip-if = (fission && os == 'linux' && bits == 64 && os_version == '18.04') # b
|
|||
[browser_fullscreen_window_open.js]
|
||||
skip-if = debug && os == 'mac' # Bug 1568570
|
||||
[browser_fullscreen_window_focus.js]
|
||||
skip-if = debug && (os == 'mac' || ( fission && os == "linux" && os_version == "18.04")) # Bug 1568570, 1618386
|
||||
skip-if = os == 'mac' || (debug && fission && os == "linux" && os_version == "18.04") # Bug 1568570, 1618386
|
||||
|
|
|
@ -64,12 +64,20 @@ XPCOMUtils.defineLazyServiceGetter(
|
|||
|
||||
const PREF_PDFJS_ISDEFAULT_CACHE_STATE = "pdfjs.enabledCache.state";
|
||||
|
||||
/**
|
||||
* Fission-compatible JSProcess implementations.
|
||||
* Each actor options object takes the form of a ProcessActorOptions dictionary.
|
||||
* Detailed documentation of these options is in dom/docs/Fission.rst,
|
||||
* available at https://firefox-source-docs.mozilla.org/dom/Fission.html#jsprocessactor
|
||||
*/
|
||||
let JSPROCESSACTORS = {};
|
||||
|
||||
/**
|
||||
* Fission-compatible JSWindowActor implementations.
|
||||
* Detailed documentation of these is in dom/docs/Fission.rst,
|
||||
* available at https://firefox-source-docs.mozilla.org/dom/Fission.html#jswindowactor
|
||||
*/
|
||||
let ACTORS = {
|
||||
let JSWINDOWACTORS = {
|
||||
AboutLogins: {
|
||||
parent: {
|
||||
moduleURI: "resource:///actors/AboutLoginsParent.jsm",
|
||||
|
@ -1176,7 +1184,8 @@ BrowserGlue.prototype = {
|
|||
os.addObserver(this, "handlersvc-store-initialized");
|
||||
os.addObserver(this, "shield-init-complete");
|
||||
|
||||
ActorManagerParent.addActors(ACTORS);
|
||||
ActorManagerParent.addJSProcessActors(JSPROCESSACTORS);
|
||||
ActorManagerParent.addJSWindowActors(JSWINDOWACTORS);
|
||||
ActorManagerParent.addLegacyActors(LEGACY_ACTORS);
|
||||
ActorManagerParent.flush();
|
||||
|
||||
|
|
|
@ -723,6 +723,10 @@
|
|||
<label class="PanelUI-profiler-recording-label">Recording…</label>
|
||||
<spacer flex="1" />
|
||||
</hbox>
|
||||
<description id="PanelUI-profiler-locked">
|
||||
The profiler is currently disabled, most likely due to a Private Browsing
|
||||
window being open.
|
||||
</description>
|
||||
<hbox id="PanelUI-profiler-inactive" class="PanelUI-profiler-buttons">
|
||||
<spacer flex="1" />
|
||||
<vbox>
|
||||
|
@ -986,7 +990,7 @@
|
|||
</html:div>
|
||||
</toolbaritem>
|
||||
</vbox>
|
||||
<toolbarbutton class="subviewbutton panel-subview-footer"
|
||||
<toolbarbutton class="subviewbutton panel-subview-footer"
|
||||
onclick="ToolbarPanelHub.toggleWhatsNewPref(event)">
|
||||
<checkbox id="panelMenu-toggleWhatsNew"
|
||||
class="panelMenu-toggleWhatsNew-checkbox"
|
||||
|
|
|
@ -172,13 +172,13 @@ class BasePopup {
|
|||
// popup was closed externally, there will be no message manager here, so
|
||||
// just replace our receiveMessage method with a stub.
|
||||
if (mm) {
|
||||
mm.removeMessageListener("DOMTitleChanged", this);
|
||||
mm.removeMessageListener("Extension:BrowserBackgroundChanged", this);
|
||||
mm.removeMessageListener("Extension:BrowserContentLoaded", this);
|
||||
mm.removeMessageListener("Extension:BrowserResized", this);
|
||||
} else if (finalize) {
|
||||
this.receiveMessage = () => {};
|
||||
}
|
||||
browser.removeEventListener("pagetitlechanged", this);
|
||||
browser.removeEventListener("DOMWindowClose", this);
|
||||
}
|
||||
|
||||
|
@ -211,10 +211,6 @@ class BasePopup {
|
|||
|
||||
receiveMessage({ name, data }) {
|
||||
switch (name) {
|
||||
case "DOMTitleChanged":
|
||||
this.viewNode.setAttribute("aria-label", this.browser.contentTitle);
|
||||
break;
|
||||
|
||||
case "Extension:BrowserBackgroundChanged":
|
||||
this.setBackground(data.background);
|
||||
break;
|
||||
|
@ -260,6 +256,10 @@ class BasePopup {
|
|||
}
|
||||
break;
|
||||
|
||||
case "pagetitlechanged":
|
||||
this.viewNode.setAttribute("aria-label", this.browser.contentTitle);
|
||||
break;
|
||||
|
||||
case "DOMWindowClose":
|
||||
this.closePopup();
|
||||
break;
|
||||
|
@ -324,10 +324,10 @@ class BasePopup {
|
|||
|
||||
let setupBrowser = browser => {
|
||||
let mm = browser.messageManager;
|
||||
mm.addMessageListener("DOMTitleChanged", this);
|
||||
mm.addMessageListener("Extension:BrowserBackgroundChanged", this);
|
||||
mm.addMessageListener("Extension:BrowserContentLoaded", this);
|
||||
mm.addMessageListener("Extension:BrowserResized", this);
|
||||
browser.addEventListener("pagetitlechanged", this);
|
||||
browser.addEventListener("DOMWindowClose", this);
|
||||
return browser;
|
||||
};
|
||||
|
|
|
@ -286,7 +286,9 @@ add_task(async function test_onProviderResultsRequested() {
|
|||
query: "test",
|
||||
engine: "Test engine",
|
||||
suggestion: undefined,
|
||||
tailPrefix: undefined,
|
||||
tail: undefined,
|
||||
tailOffsetIndex: -1,
|
||||
keyword: undefined,
|
||||
isSearchHistory: false,
|
||||
icon: "",
|
||||
|
|
|
@ -16,10 +16,7 @@ add_task(async function test_movePendingTabToNewWindow() {
|
|||
];
|
||||
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["browser.sessionstore.restore_on_demand", true],
|
||||
["toolkit.cosmeticAnimations.enabled", false],
|
||||
],
|
||||
set: [["browser.sessionstore.restore_on_demand", true]],
|
||||
});
|
||||
|
||||
let state = {
|
||||
|
|
|
@ -17,7 +17,6 @@ const PAGE_2 =
|
|||
add_task(async function setup() {
|
||||
await pushPrefs(
|
||||
["dom.ipc.processCount", 1],
|
||||
["toolkit.cosmeticAnimations.enabled", false],
|
||||
["browser.sessionstore.restore_on_demand", false]
|
||||
);
|
||||
});
|
||||
|
|
|
@ -30,7 +30,11 @@ add_task(async function() {
|
|||
}
|
||||
}
|
||||
tab.addEventListener("TabAttrModified", TabAttrModifiedListener);
|
||||
return () => {
|
||||
return async () => {
|
||||
await BrowserTestUtils.waitForCondition(
|
||||
() => seenLabels.length == expectedLabels.length,
|
||||
"saw " + seenLabels.length + " TabAttrModified events"
|
||||
);
|
||||
tab.removeEventListener("TabAttrModified", TabAttrModifiedListener);
|
||||
is(
|
||||
JSON.stringify(seenLabels),
|
||||
|
@ -95,11 +99,11 @@ add_task(async function() {
|
|||
gBrowser.selectedTab = tab2;
|
||||
await browserLoadedPromise;
|
||||
ok(!tab2.hasAttribute("pending"), "second tab isn't pending anymore");
|
||||
await finishObservingLabelChanges();
|
||||
ok(
|
||||
document.title.startsWith(ABOUT_ROBOTS_TITLE),
|
||||
"title bar displays content title"
|
||||
);
|
||||
finishObservingLabelChanges();
|
||||
|
||||
info("selecting the third tab");
|
||||
finishObservingLabelChanges = observeLabelChanges(tab3, [
|
||||
|
@ -114,11 +118,11 @@ add_task(async function() {
|
|||
gBrowser.selectedTab = tab3;
|
||||
await browserLoadedPromise;
|
||||
ok(!tab3.hasAttribute("pending"), "third tab isn't pending anymore");
|
||||
await finishObservingLabelChanges();
|
||||
ok(
|
||||
document.title.startsWith(REMOTE_TITLE),
|
||||
"title bar displays content title"
|
||||
);
|
||||
finishObservingLabelChanges();
|
||||
|
||||
info("selecting the fourth tab");
|
||||
finishObservingLabelChanges = observeLabelChanges(tab4, [NO_TITLE_URL]);
|
||||
|
@ -130,12 +134,12 @@ add_task(async function() {
|
|||
gBrowser.selectedTab = tab4;
|
||||
await browserLoadedPromise;
|
||||
ok(!tab4.hasAttribute("pending"), "fourth tab isn't pending anymore");
|
||||
await finishObservingLabelChanges();
|
||||
is(
|
||||
document.title,
|
||||
document.getElementById("bundle_brand").getString("brandFullName"),
|
||||
"title bar doesn't display content title since page doesn't have one"
|
||||
);
|
||||
finishObservingLabelChanges();
|
||||
|
||||
info("restoring the modified browser state");
|
||||
gBrowser.selectedTab = tab3;
|
||||
|
@ -172,7 +176,7 @@ add_task(async function() {
|
|||
);
|
||||
await tabContentRestored;
|
||||
ok(!tab1.hasAttribute("pending"), "first tab isn't pending anymore");
|
||||
finishObservingLabelChanges();
|
||||
await finishObservingLabelChanges();
|
||||
|
||||
await promiseBrowserState(BACKUP_STATE);
|
||||
});
|
||||
|
|
|
@ -369,6 +369,19 @@ class ProviderSearchSuggestions extends UrlbarProvider {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (suggestion.entry.tail && suggestion.entry.tailOffsetIndex < 0) {
|
||||
Cu.reportError(
|
||||
`Error in tail suggestion parsing. Value: ${suggestion.entry.value}, tail: ${suggestion.entry.tail}.`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
let tail, tailPrefix;
|
||||
if (UrlbarPrefs.get("richSuggestions.tail")) {
|
||||
tail = suggestion.entry.tail;
|
||||
tailPrefix = suggestion.entry.matchPrefix;
|
||||
}
|
||||
|
||||
try {
|
||||
results.push(
|
||||
new UrlbarResult(
|
||||
|
@ -380,14 +393,9 @@ class ProviderSearchSuggestions extends UrlbarProvider {
|
|||
suggestion.entry.value,
|
||||
UrlbarUtils.HIGHLIGHT.SUGGESTED,
|
||||
],
|
||||
tail: [
|
||||
UrlbarPrefs.get("richSuggestions.tail") &&
|
||||
suggestion.entry.matchPrefix &&
|
||||
suggestion.entry.tail
|
||||
? suggestion.entry.matchPrefix + suggestion.entry.tail
|
||||
: undefined,
|
||||
UrlbarUtils.HIGHLIGHT.SUGGESTED,
|
||||
],
|
||||
tailPrefix,
|
||||
tail: [tail, UrlbarUtils.HIGHLIGHT.SUGGESTED],
|
||||
tailOffsetIndex: suggestion.entry.tailOffsetIndex,
|
||||
keyword: [alias ? alias : undefined, UrlbarUtils.HIGHLIGHT.TYPED],
|
||||
query: [searchString.trim(), UrlbarUtils.HIGHLIGHT.NONE],
|
||||
isSearchHistory: false,
|
||||
|
|
|
@ -209,7 +209,9 @@ function makeUrlbarResult(tokens, info) {
|
|||
UrlbarUtils.HIGHLIGHT.SUGGESTED,
|
||||
],
|
||||
// For test interoperabilty with UrlbarProviderSearchSuggestions.
|
||||
tailPrefix: undefined,
|
||||
tail: undefined,
|
||||
tailOffsetIndex: -1,
|
||||
keyword: [action.params.alias, UrlbarUtils.HIGHLIGHT.TYPED],
|
||||
query: [
|
||||
action.params.searchQuery.trim(),
|
||||
|
|
|
@ -128,7 +128,7 @@ class UrlbarResult {
|
|||
case UrlbarUtils.KEYWORD_OFFER.HIDE:
|
||||
return ["", []];
|
||||
}
|
||||
if (this.payload.tail) {
|
||||
if (this.payload.tail && this.payload.tailOffsetIndex >= 0) {
|
||||
return [this.payload.tail, this.payloadHighlights.tail];
|
||||
} else if (this.payload.suggestion) {
|
||||
return [this.payload.suggestion, this.payloadHighlights.suggestion];
|
||||
|
|
|
@ -645,6 +645,12 @@ UrlbarUtils.RESULT_PAYLOAD_SCHEMA = {
|
|||
tail: {
|
||||
type: "string",
|
||||
},
|
||||
tailPrefix: {
|
||||
type: "string",
|
||||
},
|
||||
tailOffsetIndex: {
|
||||
type: "number",
|
||||
},
|
||||
title: {
|
||||
type: "string",
|
||||
},
|
||||
|
|
|
@ -46,7 +46,26 @@ class UrlbarValueFormatter {
|
|||
return this.urlbarInput.querySelector("#urlbar-scheme");
|
||||
}
|
||||
|
||||
update() {
|
||||
async update() {
|
||||
// _getUrlMetaData does URI fixup, which depends on the search service, so
|
||||
// make sure it's initialized. It can be uninitialized here on session
|
||||
// restore. Skip this if the service is already initialized in order to
|
||||
// avoid the async call in the common case. However, we can't access
|
||||
// Service.search before first paint (delayed startup) because there's a
|
||||
// performance test that prohibits it, so first bail if delayed startup
|
||||
// isn't finished.
|
||||
if (!this.window.gBrowserInit.delayedStartupFinished) {
|
||||
return;
|
||||
}
|
||||
if (!Services.search.isInitialized) {
|
||||
let instance = (this._updateInstance = {});
|
||||
await Services.search.init();
|
||||
if (this._updateInstance != instance) {
|
||||
return;
|
||||
}
|
||||
delete this._updateInstance;
|
||||
}
|
||||
|
||||
// Cleanup that must be done in any case, even if there's no value.
|
||||
this.urlbarInput.removeAttribute("domaindir");
|
||||
this.scheme.value = "";
|
||||
|
|
|
@ -759,6 +759,24 @@ class UrlbarView {
|
|||
typeIcon.className = "urlbarView-type-icon";
|
||||
noWrap.appendChild(typeIcon);
|
||||
|
||||
let tailPrefix = this._createElement("span");
|
||||
tailPrefix.className = "urlbarView-tail-prefix";
|
||||
noWrap.appendChild(tailPrefix);
|
||||
item._elements.set("tailPrefix", tailPrefix);
|
||||
// tailPrefix holds text only for alignment purposes so it should never be
|
||||
// read to screen readers.
|
||||
tailPrefix.toggleAttribute("aria-hidden", true);
|
||||
|
||||
let tailPrefixStr = this._createElement("span");
|
||||
tailPrefixStr.className = "urlbarView-tail-prefix-string";
|
||||
tailPrefix.appendChild(tailPrefixStr);
|
||||
item._elements.set("tailPrefixStr", tailPrefixStr);
|
||||
|
||||
let tailPrefixChar = this._createElement("span");
|
||||
tailPrefixChar.className = "urlbarView-tail-prefix-char";
|
||||
tailPrefix.appendChild(tailPrefixChar);
|
||||
item._elements.set("tailPrefixChar", tailPrefixChar);
|
||||
|
||||
let title = this._createElement("span");
|
||||
title.className = "urlbarView-title";
|
||||
noWrap.appendChild(title);
|
||||
|
@ -896,6 +914,16 @@ class UrlbarView {
|
|||
result.title,
|
||||
result.titleHighlights
|
||||
);
|
||||
|
||||
if (result.payload.tail && result.payload.tailOffsetIndex >= 0) {
|
||||
this._fillTailSuggestionPrefix(item, result);
|
||||
title.setAttribute("aria-label", result.payload.suggestion);
|
||||
item.toggleAttribute("tail-suggestion", true);
|
||||
} else {
|
||||
item.removeAttribute("tail-suggestion");
|
||||
title.removeAttribute("aria-label");
|
||||
}
|
||||
|
||||
title._tooltip = result.title;
|
||||
if (title.hasAttribute("overflow")) {
|
||||
title.setAttribute("title", title._tooltip);
|
||||
|
@ -1325,6 +1353,25 @@ class UrlbarView {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds markup for a tail suggestion prefix to a row.
|
||||
* @param {Node} item
|
||||
* The node for the result row.
|
||||
* @param {UrlbarResult} result
|
||||
* A UrlbarResult representing a tail suggestion.
|
||||
*/
|
||||
_fillTailSuggestionPrefix(item, result) {
|
||||
let tailPrefixStrNode = item._elements.get("tailPrefixStr");
|
||||
let tailPrefixStr = result.payload.suggestion.substring(
|
||||
0,
|
||||
result.payload.tailOffsetIndex
|
||||
);
|
||||
tailPrefixStrNode.textContent = tailPrefixStr;
|
||||
|
||||
let tailPrefixCharNode = item._elements.get("tailPrefixChar");
|
||||
tailPrefixCharNode.textContent = result.payload.tailPrefix;
|
||||
}
|
||||
|
||||
_enableOrDisableOneOffSearches(enable = true) {
|
||||
if (enable) {
|
||||
this.oneOffSearchButtons.telemetryOrigin = "urlbar";
|
||||
|
|
|
@ -303,7 +303,9 @@ function makeSearchResult(
|
|||
queryContext,
|
||||
{
|
||||
suggestion,
|
||||
tailPrefix,
|
||||
tail,
|
||||
tailOffsetIndex,
|
||||
engineName,
|
||||
alias,
|
||||
query,
|
||||
|
@ -323,13 +325,24 @@ function makeSearchResult(
|
|||
}
|
||||
}
|
||||
|
||||
// Tail suggestion common cases, handled here to reduce verbosity in tests.
|
||||
if (tail && !tailPrefix) {
|
||||
tailPrefix = "… ";
|
||||
}
|
||||
|
||||
if (!tailOffsetIndex) {
|
||||
tailOffsetIndex = tail ? suggestion.indexOf(tail) : -1;
|
||||
}
|
||||
|
||||
let result = new UrlbarResult(
|
||||
UrlbarUtils.RESULT_TYPE.SEARCH,
|
||||
UrlbarUtils.RESULT_SOURCE.SEARCH,
|
||||
...UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
|
||||
engine: [engineName, UrlbarUtils.HIGHLIGHT.TYPED],
|
||||
suggestion: [suggestion, UrlbarUtils.HIGHLIGHT.SUGGESTED],
|
||||
tailPrefix,
|
||||
tail: [tail, UrlbarUtils.HIGHLIGHT.SUGGESTED],
|
||||
tailOffsetIndex,
|
||||
keyword: [alias, UrlbarUtils.HIGHLIGHT.TYPED],
|
||||
// Check against undefined so consumers can pass in the empty string.
|
||||
query: [
|
||||
|
|
|
@ -136,12 +136,12 @@ add_task(async function basic_tail() {
|
|||
makeSearchResult(context, {
|
||||
engineName: ENGINE_NAME,
|
||||
suggestion: query + "oronto",
|
||||
tail: "… toronto",
|
||||
tail: "toronto",
|
||||
}),
|
||||
makeSearchResult(context, {
|
||||
engineName: ENGINE_NAME,
|
||||
suggestion: query + "unisia",
|
||||
tail: "… tunisia",
|
||||
tail: "tunisia",
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
@ -188,12 +188,12 @@ add_task(async function mixed_results() {
|
|||
makeSearchResult(context, {
|
||||
engineName: ENGINE_NAME,
|
||||
suggestion: query + "oronto",
|
||||
tail: "… toronto",
|
||||
tail: "toronto",
|
||||
}),
|
||||
makeSearchResult(context, {
|
||||
engineName: ENGINE_NAME,
|
||||
suggestion: query + "unisia",
|
||||
tail: "… tunisia",
|
||||
tail: "tunisia",
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
@ -222,7 +222,7 @@ add_task(async function dedupe_local() {
|
|||
makeSearchResult(context, {
|
||||
engineName: ENGINE_NAME,
|
||||
suggestion: query + "unisia",
|
||||
tail: "… tunisia",
|
||||
tail: "tunisia",
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
@ -246,7 +246,7 @@ add_task(async function limit_results() {
|
|||
makeSearchResult(context, {
|
||||
engineName: ENGINE_NAME,
|
||||
suggestion: query + "oronto",
|
||||
tail: "… toronto",
|
||||
tail: "toronto",
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
|
|
@ -24,8 +24,12 @@ var PdfJsTelemetry = {
|
|||
onViewerIsUsed() {
|
||||
Services.telemetry.scalarAdd("pdf.viewer.used", 1);
|
||||
},
|
||||
onFallback() {
|
||||
onFallback(featureId) {
|
||||
Services.telemetry.scalarAdd("pdf.viewer.fallback_shown", 1);
|
||||
let histogram = Services.telemetry.getHistogramById(
|
||||
"PDF_VIEWER_FALLBACK_REASON"
|
||||
);
|
||||
histogram.add(featureId ?? "unknown");
|
||||
},
|
||||
onDocumentSize(size) {
|
||||
let histogram = Services.telemetry.getHistogramById(
|
||||
|
|
|
@ -496,7 +496,7 @@ class ChromeActions {
|
|||
} else {
|
||||
message = getLocalizedString(strings, "unsupported_feature");
|
||||
}
|
||||
PdfJsTelemetry.onFallback();
|
||||
PdfJsTelemetry.onFallback(featureId);
|
||||
PdfjsContentUtils.displayWarning(
|
||||
domWindow,
|
||||
message,
|
||||
|
|
|
@ -204,20 +204,6 @@ const AVAILABLE_INJECTIONS = [
|
|||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "bug1568256",
|
||||
platform: "android",
|
||||
domain: "zertifikate.commerzbank.de",
|
||||
bug: "1568256",
|
||||
contentScripts: {
|
||||
matches: ["*://*.zertifikate.commerzbank.de/webforms/mobile/*"],
|
||||
css: [
|
||||
{
|
||||
file: "injections/css/bug1568256-zertifikate.commerzbank.de-flex.css",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "bug1568908",
|
||||
platform: "desktop",
|
||||
|
@ -439,6 +425,20 @@ const AVAILABLE_INJECTIONS = [
|
|||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "bug1633796",
|
||||
platform: "android",
|
||||
domain: "www.laposte.fr",
|
||||
bug: "1633796",
|
||||
contentScripts: {
|
||||
matches: ["https://www.laposte.fr/*"],
|
||||
css: [
|
||||
{
|
||||
file: "injections/css/bug1633796-www-la-poste-fr-placeholder-fix.css",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
module.exports = AVAILABLE_INJECTIONS;
|
||||
|
|
|
@ -28,6 +28,9 @@ let AVAILABLE_PIP_OVERRIDES;
|
|||
// Laracasts
|
||||
"https://*.laracasts.com/*": TOGGLE_POLICIES.ONE_QUARTER,
|
||||
|
||||
// Netflix
|
||||
"https://*.netflix.com/browse": TOGGLE_POLICIES.HIDDEN,
|
||||
|
||||
// Twitch
|
||||
"https://*.twitch.tv/*": TOGGLE_POLICIES.ONE_QUARTER,
|
||||
"https://*.twitch.tech/*": TOGGLE_POLICIES.ONE_QUARTER,
|
||||
|
|
|
@ -34,30 +34,6 @@ const AVAILABLE_UA_OVERRIDES = [
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Bug 1563839 - rolb.santanderbank.com - Build UA override
|
||||
* WebCompat issue #33462 - https://webcompat.com/issues/33462
|
||||
*
|
||||
* santanderbank expects UA to have 'like Gecko', otherwise it runs
|
||||
* xmlDoc.onload whose support has been dropped. It results in missing labels in forms
|
||||
* and some other issues. Adding 'like Gecko' fixes those issues.
|
||||
*/
|
||||
id: "bug1563839",
|
||||
platform: "all",
|
||||
domain: "rolb.santanderbank.com",
|
||||
bug: "1563839",
|
||||
config: {
|
||||
matches: [
|
||||
"*://*.santander.co.uk/*",
|
||||
"*://bob.santanderbank.com/*",
|
||||
"*://rolb.santanderbank.com/*",
|
||||
],
|
||||
uaTransformer: originalUA => {
|
||||
return originalUA.replace("Gecko", "like Gecko");
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Bug 1577519 - att.tv - Create a UA override for att.tv for playback on desktop
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
/**
|
||||
* zertifikate.commerzbank.de - clickable elements on the page are collapsed
|
||||
* Bug #1568256 - https://bugzilla.mozilla.org/show_bug.cgi?id=1568256
|
||||
* WebCompat issue #9102 - https://webcompat.com/issues/9102
|
||||
*
|
||||
* Affected elements have display:-webkit-box and display:flex applied, however,
|
||||
* listed in wrong order, so display:-webkit-box is becoming the final say.
|
||||
* Adding display: flex for those elements fixes the issue
|
||||
*/
|
||||
.x-layout-box {
|
||||
display: flex !important;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
* www.laposte.fr - Account credentials overlap placeholder text
|
||||
* Bug #1633796 - https://bugzilla.mozilla.org/show_bug.cgi?id=1633796
|
||||
* WebCompat issue #52274 - https://webcompat.com/issues/52274
|
||||
*
|
||||
* The login form for www.laposte.fr uses a positioned label as
|
||||
* placeholder text, and relies on focus to move it. However, Firefox
|
||||
* does not currently support unprefixed :read-only, so the entire
|
||||
* rule is discarded. Until https://bugzilla.mozilla.org/show_bug.cgi?id=312971
|
||||
* ships, we can work around this by rewriting the rule.
|
||||
*/
|
||||
|
||||
.flottingLabel .group input:focus ~ label,
|
||||
.flottingLabel .group input:valid ~ label,
|
||||
.flottingLabel .group input:-moz-read-only ~ label,
|
||||
.flottingLabel .group input.flatpickr-input ~ label,
|
||||
.flottingLabel .group input:disabled ~ label {
|
||||
color: #606060;
|
||||
font-size: 0.625em;
|
||||
top: 0;
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
"manifest_version": 2,
|
||||
"name": "Web Compat",
|
||||
"description": "Urgent post-release fixes for web compatibility.",
|
||||
"version": "10.1.2",
|
||||
"version": "11.0.0",
|
||||
|
||||
"applications": {
|
||||
"gecko": {
|
||||
|
|
|
@ -45,7 +45,6 @@ FINAL_TARGET_FILES.features['webcompat@mozilla.org']['injections']['css'] += [
|
|||
'injections/css/bug0000000-testbed-css-injection.css',
|
||||
'injections/css/bug1561371-mail.google.com-allow-horizontal-scrolling.css',
|
||||
'injections/css/bug1567610-dns.google.com-moz-fit-content.css',
|
||||
'injections/css/bug1568256-zertifikate.commerzbank.de-flex.css',
|
||||
'injections/css/bug1568908-console.cloud.google.com-scrollbar-fix.css',
|
||||
'injections/css/bug1570119-teamcoco.com-scrollbar-width.css',
|
||||
'injections/css/bug1570328-developer-apple.com-transform-scale.css',
|
||||
|
@ -58,6 +57,7 @@ FINAL_TARGET_FILES.features['webcompat@mozilla.org']['injections']['css'] += [
|
|||
'injections/css/bug1610344-directv.com.co-hide-unsupported-message.css',
|
||||
'injections/css/bug1631960-websube.ckbogazici.com.tr-table-row-fix.css',
|
||||
'injections/css/bug1632019-everyman.co-gallery-width-fix.css',
|
||||
'injections/css/bug1633796-www-la-poste-fr-placeholder-fix.css',
|
||||
]
|
||||
|
||||
FINAL_TARGET_FILES.features['webcompat@mozilla.org']['injections']['js'] += [
|
||||
|
|
|
@ -950,8 +950,7 @@ var gPermissionObject = {
|
|||
],
|
||||
getDefault() {
|
||||
if (
|
||||
Services.prefs.getIntPref("network.cookie.cookieBehavior") ==
|
||||
Ci.nsICookieService.BEHAVIOR_REJECT
|
||||
Services.cookies.cookieBehavior == Ci.nsICookieService.BEHAVIOR_REJECT
|
||||
) {
|
||||
return SitePermissions.BLOCK;
|
||||
}
|
||||
|
|
|
@ -1877,7 +1877,7 @@ panelview[mainview] #PanelUI-whatsNew-content {
|
|||
margin-inline-start: -80px;
|
||||
}
|
||||
|
||||
/* These checkbox styles have been pulled from `common.inc.css` and
|
||||
/* These checkbox styles have been pulled from `common.inc.css` and
|
||||
duplicated here to ensure they apply correctly. See
|
||||
https://searchfox.org/mozilla-central/rev/7908ce29657cfd623993046bd8e38664e1c0b28e/toolkit/themes/shared/in-content/common.inc.css#559 */
|
||||
#PanelUI-whatsNew checkbox {
|
||||
|
@ -2328,3 +2328,13 @@ panelview[mainview] #PanelUI-whatsNew-content {
|
|||
#PanelUI-profiler-presets[disabled="true"]::part(label-box) {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the specificity of `#PanelUI-profiler description`
|
||||
*/
|
||||
description#PanelUI-profiler-locked {
|
||||
padding: 16px;
|
||||
line-height: 1.5;
|
||||
/* Make sure this description is wider than the header's */
|
||||
max-width: 310px;
|
||||
}
|
||||
|
|
|
@ -365,6 +365,25 @@
|
|||
flex-shrink: 1;
|
||||
}
|
||||
|
||||
/* Tail suggestions */
|
||||
.urlbarView-tail-prefix {
|
||||
display: none;
|
||||
justify-content: flex-end;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.urlbarView-row[tail-suggestion] > .urlbarView-row-inner > .urlbarView-no-wrap > .urlbarView-tail-prefix {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.urlbarView-tail-prefix > .urlbarView-tail-prefix-string {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.urlbarView-tail-prefix > .urlbarView-tail-prefix-char {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
/* Title separator */
|
||||
|
||||
.urlbarView-title-separator::before {
|
||||
|
|
|
@ -34,7 +34,8 @@
|
|||
#include "prnetdb.h"
|
||||
#include "nsIURIFixup.h"
|
||||
#include "mozilla/dom/StorageUtils.h"
|
||||
|
||||
#include "mozilla/ContentBlocking.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIURIMutator.h"
|
||||
|
||||
#include "json/json.h"
|
||||
|
@ -689,6 +690,24 @@ BasePrincipal::GetPrefLightCacheKey(nsIURI* aURI, bool aWithCredentials,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
BasePrincipal::HasFirstpartyStorageAccess(mozIDOMWindow* aCheckWindow,
|
||||
uint32_t* aRejectedReason,
|
||||
bool* aOutAllowed) {
|
||||
*aRejectedReason = 0;
|
||||
*aOutAllowed = false;
|
||||
|
||||
nsPIDOMWindowInner* win = nsPIDOMWindowInner::From(aCheckWindow);
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = GetURI(getter_AddRefs(uri));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
*aOutAllowed =
|
||||
ContentBlocking::ShouldAllowAccessFor(win, uri, aRejectedReason);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
BasePrincipal::GetIsNullPrincipal(bool* aResult) {
|
||||
*aResult = Kind() == eNullPrincipal;
|
||||
|
|
|
@ -152,6 +152,9 @@ class BasePrincipal : public nsJSPrincipals {
|
|||
bool* aRes) override;
|
||||
NS_IMETHOD GetPrefLightCacheKey(nsIURI* aURI, bool aWithCredentials,
|
||||
nsACString& _retval) override;
|
||||
NS_IMETHOD HasFirstpartyStorageAccess(mozIDOMWindow* aCheckWindow,
|
||||
uint32_t* aRejectedReason,
|
||||
bool* aOutAllowed) override;
|
||||
NS_IMETHOD GetAsciiHost(nsACString& aAsciiHost) override;
|
||||
NS_IMETHOD GetLocalStorageQuotaKey(nsACString& aRes) override;
|
||||
NS_IMETHOD AllowsRelaxStrictFileOriginPolicy(nsIURI* aURI,
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include "nsIAboutModule.idl"
|
||||
#include "nsIReferrerInfo.idl"
|
||||
interface nsIChannel;
|
||||
|
||||
#include "mozIDOMWindow.idl"
|
||||
|
||||
%{C++
|
||||
struct JSPrincipals;
|
||||
|
@ -330,6 +330,14 @@ interface nsIPrincipal : nsISerializable
|
|||
ACString getPrefLightCacheKey(in nsIURI aURI ,in bool aWithCredentials);
|
||||
|
||||
|
||||
/*
|
||||
* Checks if the Principals URI has first party storage access
|
||||
* when loaded inside the provided 3rd party resource window.
|
||||
* See also: ContentBlocking::ShouldAllowAccessFor
|
||||
*/
|
||||
bool hasFirstpartyStorageAccess(in mozIDOMWindow aWindow, out uint32_t rejectedReason);
|
||||
|
||||
|
||||
/*
|
||||
* Returns a Key for the LocalStorage Manager, used to
|
||||
* check the Principals Origin Storage usage.
|
||||
|
|
|
@ -95,6 +95,7 @@ included_inclnames_to_ignore = set([
|
|||
'unicode/uchar.h', # ICU
|
||||
'unicode/uclean.h', # ICU
|
||||
'unicode/ucol.h', # ICU
|
||||
'unicode/ucurr.h', # ICU
|
||||
'unicode/udat.h', # ICU
|
||||
'unicode/udata.h', # ICU
|
||||
'unicode/udatpg.h', # ICU
|
||||
|
@ -103,7 +104,9 @@ included_inclnames_to_ignore = set([
|
|||
'unicode/ufieldpositer.h', # ICU
|
||||
'unicode/uformattedvalue.h', # ICU
|
||||
'unicode/ulistformatter.h', # ICU
|
||||
'unicode/uldnames.h', # ICU
|
||||
'unicode/uloc.h', # ICU
|
||||
'unicode/umachine.h', # ICU
|
||||
'unicode/uniset.h', # ICU
|
||||
'unicode/unistr.h', # ICU
|
||||
'unicode/unorm2.h', # ICU
|
||||
|
|
Двоичный файл не отображается.
|
@ -1308,13 +1308,16 @@ if CONFIG['MOZ_SYSTEM_ICU']:
|
|||
'unicode/uchar.h',
|
||||
'unicode/uclean.h',
|
||||
'unicode/ucol.h',
|
||||
'unicode/ucurr.h',
|
||||
'unicode/udat.h',
|
||||
'unicode/udata.h',
|
||||
'unicode/udatpg.h',
|
||||
'unicode/udisplaycontext.h',
|
||||
'unicode/uldnames.h',
|
||||
'unicode/ulistformatter.h',
|
||||
'unicode/uenum.h',
|
||||
'unicode/uformattedvalue.h',
|
||||
'unicode/umachine.h',
|
||||
'unicode/uniset.h',
|
||||
'unicode/unistr.h',
|
||||
'unicode/unorm.h',
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
}
|
||||
|
||||
.inline-preview-outer {
|
||||
padding: 1px 0;
|
||||
background-color: var(--theme-inline-preview-background);
|
||||
border: 1px solid var(--theme-inline-preview-border-color);
|
||||
border-radius: 3px;
|
||||
|
|
|
@ -40,4 +40,10 @@ add_task(async function() {
|
|||
const newLoc = await service.originalPositionFor(JS_URL, GENERATED_LINE);
|
||||
is(newLoc.sourceUrl, ORIGINAL_URL, "check mapped URL");
|
||||
is(newLoc.line, ORIGINAL_LINE, "check mapped line number");
|
||||
|
||||
// See Bug 1637793 and Bug 1621337.
|
||||
// Ideally the debugger should only resolve when the worker targets have been
|
||||
// retrieved, which should be fixed by Bug 1621337 or a followup.
|
||||
info("Wait for all pending requests to settle on the DevToolsClient");
|
||||
await toolbox.target.client.waitForRequestsToSettle();
|
||||
});
|
||||
|
|
|
@ -20,6 +20,12 @@ async function viewSource() {
|
|||
|
||||
assertSelectedLocationInDebugger(debuggerPanel, 2, undefined);
|
||||
|
||||
// See Bug 1637793 and Bug 1621337.
|
||||
// Ideally the debugger should only resolve when the worker targets have been
|
||||
// retrieved, which should be fixed by Bug 1621337 or a followup.
|
||||
info("Wait for all pending requests to settle on the DevToolsClient");
|
||||
await toolbox.target.client.waitForRequestsToSettle();
|
||||
|
||||
await closeToolboxAndTab(toolbox);
|
||||
finish();
|
||||
}
|
||||
|
|
|
@ -54,4 +54,10 @@ add_task(async function() {
|
|||
loaders,
|
||||
panelName: "debugger",
|
||||
});
|
||||
|
||||
// See Bug 1637793 and Bug 1621337.
|
||||
// Ideally the debugger should only resolve when the worker targets have been
|
||||
// retrieved, which should be fixed by Bug 1621337 or a followup.
|
||||
info("Wait for all pending requests to settle on the DevToolsClient");
|
||||
await toolbox.target.client.waitForRequestsToSettle();
|
||||
});
|
||||
|
|
|
@ -241,6 +241,8 @@ devtools.jar:
|
|||
content/netmonitor/src/assets/styles/StatusCode.css (netmonitor/src/assets/styles/StatusCode.css)
|
||||
content/netmonitor/src/assets/styles/websockets.css (netmonitor/src/assets/styles/websockets.css)
|
||||
content/netmonitor/src/assets/styles/search.css (netmonitor/src/assets/styles/search.css)
|
||||
content/netmonitor/src/assets/styles/UrlPreview.css (netmonitor/src/assets/styles/UrlPreview.css)
|
||||
content/netmonitor/src/assets/styles/HeadersPanel.css (netmonitor/src/assets/styles/HeadersPanel.css)
|
||||
|
||||
# Application panel
|
||||
content/application/index.html (application/index.html)
|
||||
|
|
|
@ -265,13 +265,13 @@ networkMenu.sizeUnavailable=—
|
|||
networkMenu.sizeUnavailable.title=Transferred size is not available
|
||||
|
||||
# LOCALIZATION NOTE (networkMenu.sizeCached): This is the label displayed
|
||||
# in the network menu specifying the transfer or a request is
|
||||
# in the network menu and the headers panel specifying the transfer or a request is
|
||||
# cached.
|
||||
networkMenu.sizeCached=cached
|
||||
|
||||
# LOCALIZATION NOTE (networkMenu.sizeServiceWorker): This is the label displayed
|
||||
# in the network menu specifying the transferred of a request computed
|
||||
# by a service worker.
|
||||
# in the network menu and the headers panel specifying the transferred of a request
|
||||
# computed by a service worker.
|
||||
networkMenu.sizeServiceWorker=service worker
|
||||
|
||||
# LOCALIZATION NOTE (networkMenu.blocked2): This is a generic message for a
|
||||
|
@ -629,8 +629,8 @@ netmonitor.toolbar.duration=Duration
|
|||
netmonitor.toolbar.latency=Latency
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.toolbar.transferred): This is the label displayed
|
||||
# in the network table toolbar, above the "transferred" column, which is the
|
||||
# compressed / encoded size.
|
||||
# in the network table toolbar, above the "transferred" column and in general
|
||||
# section of the headers panel, which is the compressed / encoded size.
|
||||
netmonitor.toolbar.transferred=Transferred
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.toolbar.contentSize): This is the label displayed
|
||||
|
@ -1009,33 +1009,38 @@ netmonitor.toolbar.responseHeaders=Response Headers
|
|||
# block url toolbar button.
|
||||
netmonitor.headers.toolbar.block=Block
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.summary.url): This is the label displayed
|
||||
# in the network details headers tab identifying the URL.
|
||||
netmonitor.summary.url=Request URL:
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.summary.method): This is the label displayed
|
||||
# in the network details headers tab identifying the method.
|
||||
netmonitor.summary.method=Request Method:
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.summary.address): This is the label displayed
|
||||
# LOCALIZATION NOTE (netmonitor.headers.address): This is the label displayed
|
||||
# in the network details headers tab identifying the remote address.
|
||||
netmonitor.summary.address=Remote Address:
|
||||
netmonitor.headers.address=Address
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.summary.status): This is the label displayed
|
||||
# LOCALIZATION NOTE (netmonitor.headers.status): This is the label displayed
|
||||
# in the network details headers tab identifying the status code.
|
||||
netmonitor.summary.status=Status Code:
|
||||
netmonitor.headers.status=Status
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.summary.version): This is the label displayed
|
||||
# LOCALIZATION NOTE (netmonitor.headers.size): This is the label displayed
|
||||
# in the network details headers tab identifying the size.
|
||||
netmonitor.headers.size=Size
|
||||
|
||||
# LOCALIZATION NOTE (networkMenu.headers.sizeDetails): This label is displayed
|
||||
# in the network details headers tab providing the size details.
|
||||
# %1$S is the transferred size, %2$S is the size.
|
||||
netmonitor.headers.sizeDetails=%1$S (%2$S size)
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.headers.version): This is the label displayed
|
||||
# in the network details headers tab identifying the http version.
|
||||
netmonitor.summary.version=Version:
|
||||
netmonitor.headers.version=Version
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.summary.learnMore): This is the label displayed
|
||||
# in the network details headers tab, with a link to external documentation.
|
||||
netmonitor.summary.learnMore=Learn more about status code
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.summary.referrerPolicy): This is the label displayed
|
||||
# LOCALIZATION NOTE (netmonitor.headers.referrer): This is the label displayed
|
||||
# in the network details headers tab identifying the referrer policy.
|
||||
netmonitor.summary.referrerPolicy=Referrer Policy:
|
||||
netmonitor.headers.referrer=Referrer
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.headers.contentBlocking): This is the label displayed
|
||||
# in the network details headers tab identifying the content blocking mode.
|
||||
netmonitor.headers.contentBlocking=Blocking
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.summary.editAndResend): This is the label displayed
|
||||
# on the button in the headers tab that opens a form to edit and resend the currently
|
||||
|
@ -1166,6 +1171,10 @@ netmonitor.security.certificate=Certificate:
|
|||
# in the Network monitor panel as a tooltip for tracking resource icon.
|
||||
netmonitor.trackingResource.tooltip=This URL matches a known tracker and it would be blocked with Content Blocking enabled.
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.trackingResource.enhancedTrackingProtection): This is
|
||||
# the label used in the Network monitor panel for showing enhanced tracking protection.
|
||||
netmonitor.trackingResource.enhancedTrackingProtection=Enhanced Tracking Protection
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.context.copy): This is the label displayed
|
||||
# for the copy sub-menu in the context menu for a request
|
||||
netmonitor.context.copy=Copy
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
# 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/.
|
||||
|
||||
### These strings are used inside the Storage Inspector.
|
||||
|
||||
# Hint shown when the selected storage host does not contain any data
|
||||
storage-table-empty-text = No data present for selected host
|
||||
|
||||
# Hint shown when the cookies storage type is selected. Clicking the link will open
|
||||
# https://developer.mozilla.org/docs/Tools/Storage_Inspector/Cookies
|
||||
storage-table-type-cookies-hint = View and edit cookies by selecting a host. <a data-l10n-name="learn-more-link">Learn more</a>
|
||||
|
||||
# Hint shown when the local storage type is selected. Clicking the link will open
|
||||
# https://developer.mozilla.org/docs/Tools/Storage_Inspector/Local_Storage_Session_Storage
|
||||
storage-table-type-localstorage-hint = View and edit the local storage by selecting a host. <a data-l10n-name="learn-more-link">Learn more</a>
|
||||
|
||||
# Hint shown when the session storage type is selected. Clicking the link will open
|
||||
# https://developer.mozilla.org/docs/Tools/Storage_Inspector/Local_Storage_Session_Storage
|
||||
storage-table-type-sessionstorage-hint = View and edit the session storage by selecting a host. <a data-l10n-name="learn-more-link">Learn more</a>
|
||||
|
||||
# Hint shown when the IndexedDB storage type is selected. Clicking the link will open
|
||||
# https://developer.mozilla.org/docs/Tools/Storage_Inspector/IndexedDB
|
||||
storage-table-type-indexeddb-hint = View and delete IndexedDB entries by selecting a database. <a data-l10n-name="learn-more-link">Learn more</a>
|
||||
|
||||
# Hint shown when the cache storage type is selected. Clicking the link will open
|
||||
# https://developer.mozilla.org/docs/Tools/Storage_Inspector/Cache_Storage
|
||||
storage-table-type-cache-hint = View and delete the cache storage entries by selecting a storage. <a data-l10n-name="learn-more-link">Learn more</a>
|
||||
|
||||
# Hint shown when the extension storage type is selected. Clicking the link will open
|
||||
# https://developer.mozilla.org/docs/Tools/Storage_Inspector/Extension_Storage
|
||||
storage-table-type-extensionstorage-hint = View and edit the extension storage by selecting a host. <a data-l10n-name="learn-more-link">Learn more</a>
|
|
@ -13,11 +13,6 @@
|
|||
# Key shortcut used to focus the filter box on top of the data view
|
||||
storage.filter.key=CmdOrCtrl+F
|
||||
|
||||
# LOCALIZATION NOTE (table.emptyText):
|
||||
# This string is displayed when there are no rows in the Storage Table for the
|
||||
# selected host.
|
||||
table.emptyText=No data present for selected host
|
||||
|
||||
# LOCALIZATION NOTE (tree.labels.*):
|
||||
# These strings are the labels for Storage type groups present in the Storage
|
||||
# Tree, like cookies, local storage etc.
|
||||
|
|
|
@ -0,0 +1,220 @@
|
|||
/* 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/. */
|
||||
|
||||
/* Headers tabpanel */
|
||||
|
||||
.network-monitor .headers-panel-container {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.network-monitor .headers-panel-container .panel-container {
|
||||
position: absolute;
|
||||
top: calc(var(--theme-toolbar-height) + 1px);
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.network-monitor .headers-panel-container .devtools-button {
|
||||
padding: 2px;
|
||||
}
|
||||
.network-monitor .headers-panel-container .devtools-dropdown-button {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.network-monitor .headers-panel-container .devtools-button:not(:hover) {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.network-monitor .headers-overview {
|
||||
border-bottom: 1px solid var(--theme-splitter-color);
|
||||
}
|
||||
|
||||
.network-monitor .headers-overview .summary {
|
||||
padding: 10px 20px;
|
||||
}
|
||||
|
||||
.network-monitor .headers-summary,
|
||||
.network-monitor .response-summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.network-monitor .raw-headers-toggle {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.network-monitor .accordion-header-label {
|
||||
color: var(--theme-icon-dimmed-color)
|
||||
}
|
||||
|
||||
.network-monitor .raw-headers-toggle .headers-summary-label {
|
||||
color: var(--theme-toolbar-color);
|
||||
}
|
||||
|
||||
.network-monitor .raw-headers-toggle-input > input {
|
||||
display: inline-block;
|
||||
width: 2em;
|
||||
vertical-align: bottom;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.network-monitor .properties-view .tree-container .treeTable .treeValueCell .devtools-checkbox-toggle {
|
||||
margin-block: 2px;
|
||||
}
|
||||
|
||||
.network-monitor .properties-view .raw-headers-container .raw-headers {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
padding: 2px 12px;
|
||||
white-space: pre;
|
||||
overflow-wrap: normal;
|
||||
overflow-x: auto;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.network-monitor .accordion-item .treeTable .objectBox-string {
|
||||
color: var(--theme-body-color);
|
||||
}
|
||||
|
||||
.network-monitor .accordion-item .treeTable tr.treeRow.selected .objectBox-string {
|
||||
color: var(--theme-selection-color);
|
||||
}
|
||||
|
||||
.network-monitor .properties-view .raw-headers-container td {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.network-monitor .properties-view .raw-headers-container textarea {
|
||||
width: 100%;
|
||||
font-family: var(--monospace-font-family);
|
||||
font-size: var(--theme-body-font-size);
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.theme-light .network-monitor .properties-view textarea {
|
||||
background-color: white;
|
||||
border: 1px solid var(--grey-25);
|
||||
color: var(--grey-90);
|
||||
}
|
||||
|
||||
.theme-dark .network-monitor .properties-view textarea {
|
||||
background-color: var(--grey-70);
|
||||
border: 1px solid var(--grey-85);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.network-monitor .properties-view .raw-headers .tabpanel-summary-label {
|
||||
padding: 0 0 4px;
|
||||
}
|
||||
|
||||
.headers-summary .textbox-input {
|
||||
margin-inline-end: 2px;
|
||||
}
|
||||
|
||||
.network-monitor .headers-summary .status-text {
|
||||
width: auto !important;
|
||||
margin-inline-start: 4px;
|
||||
}
|
||||
|
||||
/* Status codes */
|
||||
|
||||
.headers-overview .summary .status .status-code {
|
||||
display: inline;
|
||||
margin-right: 5px;
|
||||
background-color: transparent;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.headers-overview .summary .status[data-code^="1"] {
|
||||
color: var(--status-code-color-1xx);
|
||||
}
|
||||
|
||||
.headers-overview .summary .status[data-code^="2"] {
|
||||
color: var(--status-code-color-2xx);
|
||||
}
|
||||
|
||||
.headers-overview .summary .status[data-code^="3"] {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.headers-overview .summary .status[data-code^="4"] {
|
||||
color: var(--status-code-color-4xx);
|
||||
}
|
||||
|
||||
.headers-overview .summary .status[data-code^="5"] {
|
||||
color: var(--status-code-color-5xx);
|
||||
}
|
||||
|
||||
/* Non-standard status codes are styled like 5XX */
|
||||
.headers-overview .summary .status[data-code^="0"],
|
||||
.headers-overview .summary .status[data-code^="6"],
|
||||
.headers-overview .summary .status[data-code^="7"],
|
||||
.headers-overview .summary .status[data-code^="8"],
|
||||
.headers-overview .summary .status[data-code^="9"] {
|
||||
color: var(--status-code-color-5xx);
|
||||
}
|
||||
|
||||
/* Summary tabpanel */
|
||||
|
||||
.network-monitor .tabpanel-summary-container {
|
||||
flex-wrap: wrap;
|
||||
padding: 1px;
|
||||
padding-inline-start: 4px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.network-monitor .tabpanel-summary-container .tracking-resource {
|
||||
margin-inline: -2px 2px;
|
||||
vertical-align: text-bottom;
|
||||
fill: var(--theme-icon-color);
|
||||
}
|
||||
|
||||
.network-monitor .tabpanel-summary-label {
|
||||
display: inline-block;
|
||||
padding-inline-end: 3px;
|
||||
min-width: 70px;
|
||||
color: var(--theme-icon-dimmed-color);
|
||||
}
|
||||
|
||||
.network-monitor .tabpanel-summary-value {
|
||||
color: inherit;
|
||||
padding-inline-start: 3px;
|
||||
}
|
||||
|
||||
.network-monitor .tabpanel-summary-value strong {
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
.theme-dark .network-monitor .tabpanel-summary-value {
|
||||
color: var(--theme-selection-color);
|
||||
}
|
||||
|
||||
.network-monitor .tracking-protection {
|
||||
color: var(--theme-icon-dimmed-color);
|
||||
margin-left: 47px;
|
||||
}
|
||||
|
||||
.network-monitor .tracking-protection .learn-more-link:not(:hover)::before {
|
||||
color: var(--theme-icon-dimmed-color);
|
||||
}
|
||||
|
||||
.theme-dark .network-monitor .edit-and-resend-button {
|
||||
background-color: var(--toolbarbutton-background);
|
||||
color: var(--theme-selection-color);
|
||||
}
|
||||
|
||||
.network-monitor .headers-summary-label,
|
||||
.network-monitor .tree-container .objectBox {
|
||||
white-space: nowrap;
|
||||
}
|
|
@ -385,7 +385,6 @@
|
|||
width: auto !important;
|
||||
margin-inline-start: 4px;
|
||||
}
|
||||
|
||||
/* Params and Response error messages */
|
||||
|
||||
.network-monitor .request-error-header,
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
/* 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/. */
|
||||
|
||||
/* Url Preview */
|
||||
|
||||
.url-preview {
|
||||
border-bottom: 1px solid var(--theme-splitter-color);
|
||||
padding: 6px 4px;
|
||||
}
|
||||
|
||||
.url-preview .properties-view,
|
||||
.url-preview .tree-container,
|
||||
.url-preview .treeTable {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.url-preview .properties-view {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.url-preview tbody:focus {
|
||||
outline: none;
|
||||
}
|
||||
.url-preview td.splitter {
|
||||
/* This makes sure that the column spans the width of the
|
||||
side bar so the contained horizontal splitter is visible */
|
||||
width: 100vw !important;
|
||||
}
|
||||
|
||||
.url-preview .horizontal-splitter {
|
||||
border-bottom: 1px solid var(--theme-splitter-color);
|
||||
margin: 6px 7px 6px 20px;
|
||||
}
|
||||
|
||||
.url-preview .url {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.url-preview .treeTable .treeRow:not(.selected):hover {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.url-preview .treeTable tr.treeRow:first-child .treeLabelCell::after {
|
||||
content: "";
|
||||
}
|
||||
.url-preview .treeTable .treeLabelCell {
|
||||
--tree-label-cell-indent: 0 !important;
|
||||
}
|
||||
/* Indent the array params */
|
||||
.url-preview .treeTable .treeRow[aria-level="4"] .treeLabelCell {
|
||||
text-indent: 15px;
|
||||
}
|
||||
|
||||
.url-preview .treeTable .treeLabel[data-level="1"] {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
/* Collapsed url */
|
||||
.url-preview tr.treeRow:first-child .treeLabelCell {
|
||||
font-weight: bold;
|
||||
color: var(--theme-icon-dimmed-color);
|
||||
}
|
||||
|
||||
.url-preview tr.treeRow .treeLabelCell {
|
||||
float: left;
|
||||
margin-right: -15px;
|
||||
padding: 0;
|
||||
|
||||
}
|
||||
.url-preview tr.treeRow .treeValueCell {
|
||||
display: inline;
|
||||
word-break: break-all;
|
||||
max-width: none;
|
||||
box-decoration-break: clone;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.url-preview .treeTable .treeValueCell {
|
||||
color: var(--theme-body-color);
|
||||
}
|
||||
|
||||
.url-preview .url-scheme,
|
||||
.url-preview .url-chars {
|
||||
color: var(--theme-icon-dimmed-color);
|
||||
}
|
||||
|
||||
.url-preview .url-params-name {
|
||||
color: var(--theme-highlight-blue);
|
||||
}
|
|
@ -26,6 +26,8 @@
|
|||
@import "chrome://devtools/content/netmonitor/src/assets/styles/StatusCode.css";
|
||||
@import "chrome://devtools/content/netmonitor/src/assets/styles/websockets.css";
|
||||
@import "chrome://devtools/content/netmonitor/src/assets/styles/search.css";
|
||||
@import "chrome://devtools/content/netmonitor/src/assets/styles/UrlPreview.css";
|
||||
@import "chrome://devtools/content/netmonitor/src/assets/styles/HeadersPanel.css";
|
||||
|
||||
/* General */
|
||||
|
||||
|
|
|
@ -0,0 +1,199 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
const {
|
||||
Component,
|
||||
createFactory,
|
||||
} = require("devtools/client/shared/vendor/react");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
|
||||
const PropertiesView = createFactory(
|
||||
require("devtools/client/netmonitor/src/components/request-details/PropertiesView")
|
||||
);
|
||||
|
||||
const {
|
||||
parseQueryString,
|
||||
} = require("devtools/client/netmonitor/src/utils/request-utils");
|
||||
|
||||
const TreeRow = createFactory(
|
||||
require("devtools/client/shared/components/tree/TreeRow")
|
||||
);
|
||||
|
||||
loader.lazyGetter(this, "MODE", function() {
|
||||
return require("devtools/client/shared/components/reps/reps").MODE;
|
||||
});
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
|
||||
const { div, span, tr, td } = dom;
|
||||
|
||||
/**
|
||||
* Url Preview Component
|
||||
* This component is used to render urls. Its show both compact and destructured views
|
||||
* of the url. Its takes a url and the http method as properties.
|
||||
*
|
||||
* Example Url:
|
||||
* https://foo.com/bla?x=123&y=456&z=789&a=foo&a=bar
|
||||
*
|
||||
* Structure:
|
||||
* {
|
||||
* GET : {
|
||||
* "scheme" : "https",
|
||||
* "host" : "foo.com",
|
||||
* "filename" : "bla",
|
||||
* "query" : {
|
||||
* "x": "123",
|
||||
* "y": "456",
|
||||
* "z": "789",
|
||||
* "a": {
|
||||
* "0": foo,
|
||||
* "1": bar
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
class UrlPreview extends Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
url: PropTypes.string,
|
||||
method: PropTypes.string,
|
||||
};
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.parseUrl = this.parseUrl.bind(this);
|
||||
this.renderValue = this.renderValue.bind(this);
|
||||
}
|
||||
|
||||
renderRow(props) {
|
||||
const {
|
||||
member: { name },
|
||||
} = props;
|
||||
if (name == "query") {
|
||||
return tr(
|
||||
{ key: name, className: "treeRow stringRow" },
|
||||
td(
|
||||
{ colSpan: 2, className: "splitter" },
|
||||
div({ className: "horizontal-splitter" })
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const customProps = { ...props };
|
||||
customProps.member.selected = false;
|
||||
return TreeRow(customProps);
|
||||
}
|
||||
|
||||
renderValue(props) {
|
||||
const {
|
||||
member: { level, open },
|
||||
value,
|
||||
} = props;
|
||||
if (level == 0) {
|
||||
if (open) {
|
||||
return "";
|
||||
}
|
||||
const { scheme, host, filename, query } = value;
|
||||
const queryParamNames = query ? Object.keys(query) : [];
|
||||
// render collapsed url
|
||||
return div(
|
||||
{ key: "url", className: "url" },
|
||||
span({ key: "url-scheme", className: "url-scheme" }, `${scheme}://`),
|
||||
span({ key: "url-host", className: "url-host" }, `${host}`),
|
||||
span({ key: "url-filename", className: "url-filename" }, `${filename}`),
|
||||
!!queryParamNames.length &&
|
||||
span({ key: "url-ques", className: "url-chars" }, "?"),
|
||||
queryParamNames.map((name, index) => {
|
||||
return span(
|
||||
{ key: `url-params-${name}`, className: "url-params" },
|
||||
span(
|
||||
{ key: "url-params-name", className: "url-params-name" },
|
||||
`${name}`
|
||||
),
|
||||
span({ key: "url-chars-equals", className: "url-chars" }, "="),
|
||||
span(
|
||||
{ key: "url-params-value", className: "url-params-value" },
|
||||
`${query[name]}`
|
||||
),
|
||||
queryParamNames.length - 1 !== index &&
|
||||
span({ key: "url-amp", className: "url-chars" }, "&")
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
if (typeof value !== "string") {
|
||||
// the query node would be an object
|
||||
if (level == 0) {
|
||||
return "";
|
||||
}
|
||||
// for arrays
|
||||
return "[...]";
|
||||
}
|
||||
// Show query params values with quotes
|
||||
return level == 1 ? value : `"${value}"`;
|
||||
}
|
||||
|
||||
parseUrl(url) {
|
||||
const { method } = this.props;
|
||||
const { host, protocol, pathname, search } = new URL(url);
|
||||
|
||||
const urlObject = {
|
||||
[method]: {
|
||||
scheme: protocol.replace(":", ""),
|
||||
host: host,
|
||||
filename: pathname,
|
||||
},
|
||||
};
|
||||
|
||||
const expandedNodes = new Set();
|
||||
// make sure the query node is always expanded
|
||||
expandedNodes.add(`/${method}/query`);
|
||||
|
||||
// check and add query parameters
|
||||
if (search.length) {
|
||||
const params = parseQueryString(search);
|
||||
urlObject[method].query = params.reduce((map, obj) => {
|
||||
const value = map[obj.name];
|
||||
if (value || value === "") {
|
||||
if (typeof value !== "object") {
|
||||
expandedNodes.add(`/${method}/query/${obj.name}`);
|
||||
map[obj.name] = [value];
|
||||
}
|
||||
map[obj.name].push(obj.value);
|
||||
} else {
|
||||
map[obj.name] = obj.value;
|
||||
}
|
||||
return map;
|
||||
}, {});
|
||||
}
|
||||
|
||||
return {
|
||||
urlObject,
|
||||
expandedNodes,
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const { url } = this.props;
|
||||
const { urlObject, expandedNodes } = this.parseUrl(url);
|
||||
|
||||
return div(
|
||||
{ className: "url-preview" },
|
||||
PropertiesView({
|
||||
object: urlObject,
|
||||
useQuotes: true,
|
||||
defaultSelectFirstNode: false,
|
||||
mode: MODE.TINY,
|
||||
expandedNodes,
|
||||
renderRow: this.renderRow,
|
||||
renderValue: this.renderValue,
|
||||
enableInput: false,
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = UrlPreview;
|
|
@ -6,4 +6,5 @@ DevToolsModules(
|
|||
'HtmlPreview.js',
|
||||
'ImagePreview.js',
|
||||
'SourcePreview.js',
|
||||
'UrlPreview.js'
|
||||
)
|
||||
|
|
|
@ -21,7 +21,6 @@ const {
|
|||
const { L10N } = require("devtools/client/netmonitor/src/utils/l10n");
|
||||
const {
|
||||
getHeadersURL,
|
||||
getHTTPStatusCodeURL,
|
||||
getTrackingProtectionURL,
|
||||
} = require("devtools/client/netmonitor/src/utils/mdn-utils");
|
||||
const {
|
||||
|
@ -45,6 +44,9 @@ const SearchBox = createFactory(
|
|||
const Accordion = createFactory(
|
||||
require("devtools/client/shared/components/Accordion")
|
||||
);
|
||||
const UrlPreview = createFactory(
|
||||
require("devtools/client/netmonitor/src/components/previews/UrlPreview")
|
||||
);
|
||||
const StatusCode = createFactory(
|
||||
require("devtools/client/netmonitor/src/components/StatusCode")
|
||||
);
|
||||
|
@ -70,7 +72,7 @@ loader.lazyRequireGetter(
|
|||
true
|
||||
);
|
||||
|
||||
const { button, div, input, label, span, textarea, tr, td } = dom;
|
||||
const { div, input, label, span, textarea, tr, td, button } = dom;
|
||||
|
||||
const RESEND = L10N.getStr("netmonitor.context.resend.label");
|
||||
const EDIT_AND_RESEND = L10N.getStr("netmonitor.summary.editAndResend");
|
||||
|
@ -80,14 +82,17 @@ const HEADERS_FILTER_TEXT = L10N.getStr("headersFilterText");
|
|||
const REQUEST_HEADERS = L10N.getStr("requestHeaders");
|
||||
const REQUEST_HEADERS_FROM_UPLOAD = L10N.getStr("requestHeadersFromUpload");
|
||||
const RESPONSE_HEADERS = L10N.getStr("responseHeaders");
|
||||
const SUMMARY_ADDRESS = L10N.getStr("netmonitor.summary.address");
|
||||
const SUMMARY_METHOD = L10N.getStr("netmonitor.summary.method");
|
||||
const SUMMARY_URL = L10N.getStr("netmonitor.summary.url");
|
||||
const SUMMARY_STATUS = L10N.getStr("netmonitor.summary.status");
|
||||
const SUMMARY_VERSION = L10N.getStr("netmonitor.summary.version");
|
||||
const HEADERS_ADDRESS = L10N.getStr("netmonitor.headers.address");
|
||||
const HEADERS_STATUS = L10N.getStr("netmonitor.headers.status");
|
||||
const HEADERS_VERSION = L10N.getStr("netmonitor.headers.version");
|
||||
const HEADERS_TRANSFERRED = L10N.getStr("netmonitor.toolbar.transferred");
|
||||
const SUMMARY_STATUS_LEARN_MORE = L10N.getStr("netmonitor.summary.learnMore");
|
||||
const SUMMARY_REFERRER_POLICY = L10N.getStr(
|
||||
"netmonitor.summary.referrerPolicy"
|
||||
const HEADERS_REFERRER = L10N.getStr("netmonitor.headers.referrer");
|
||||
const HEADERS_CONTENT_BLOCKING = L10N.getStr(
|
||||
"netmonitor.headers.contentBlocking"
|
||||
);
|
||||
const HEADERS_ETP = L10N.getStr(
|
||||
"netmonitor.trackingResource.enhancedTrackingProtection"
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -260,20 +265,11 @@ class HeadersPanel extends Component {
|
|||
key: summaryLabel,
|
||||
className: "tabpanel-summary-container headers-summary",
|
||||
},
|
||||
div(
|
||||
{ className: "tabpanel-summary-labelvalue" },
|
||||
span(
|
||||
{ className: "tabpanel-summary-label headers-summary-label" },
|
||||
summaryLabel
|
||||
),
|
||||
span(
|
||||
{
|
||||
className:
|
||||
"tabpanel-summary-value textbox-input devtools-monospace",
|
||||
},
|
||||
value
|
||||
)
|
||||
)
|
||||
span(
|
||||
{ className: "tabpanel-summary-label headers-summary-label" },
|
||||
summaryLabel
|
||||
),
|
||||
span({ className: "tabpanel-summary-value" }, value)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -517,6 +513,8 @@ class HeadersPanel extends Component {
|
|||
urlDetails,
|
||||
referrerPolicy,
|
||||
isThirdPartyTrackingResource,
|
||||
contentSize,
|
||||
transferredSize,
|
||||
},
|
||||
openRequestBlockingAndAddUrl,
|
||||
} = this.props;
|
||||
|
@ -526,7 +524,6 @@ class HeadersPanel extends Component {
|
|||
rawUploadHeadersOpened,
|
||||
filterText,
|
||||
} = this.state;
|
||||
const item = { fromCache, fromServiceWorker, status, statusText };
|
||||
|
||||
if (
|
||||
(!requestHeaders || !requestHeaders.headers.length) &&
|
||||
|
@ -634,100 +631,90 @@ class HeadersPanel extends Component {
|
|||
});
|
||||
}
|
||||
|
||||
// not showing #hash in url
|
||||
const summaryUrl = urlDetails.url
|
||||
? this.renderSummary(SUMMARY_URL, urlDetails.url.split("#")[0])
|
||||
: null;
|
||||
|
||||
const summaryMethod = method
|
||||
? this.renderSummary(SUMMARY_METHOD, method)
|
||||
: null;
|
||||
|
||||
const summaryAddress = remoteAddress
|
||||
? this.renderSummary(
|
||||
SUMMARY_ADDRESS,
|
||||
HEADERS_ADDRESS,
|
||||
getFormattedIPAndPort(remoteAddress, remotePort)
|
||||
)
|
||||
: null;
|
||||
|
||||
const sizeText = L10N.getFormatStrWithNumbers(
|
||||
"netmonitor.headers.sizeDetails",
|
||||
getFormattedSize(transferredSize),
|
||||
getFormattedSize(contentSize)
|
||||
);
|
||||
|
||||
const summarySize = this.renderSummary(HEADERS_TRANSFERRED, sizeText);
|
||||
|
||||
let summaryStatus;
|
||||
|
||||
if (status) {
|
||||
const statusCodeDocURL = getHTTPStatusCodeURL(status.toString());
|
||||
const inputWidth = statusText.length + 1;
|
||||
|
||||
summaryStatus = div(
|
||||
{
|
||||
key: "headers-summary",
|
||||
className: "tabpanel-summary-container headers-summary",
|
||||
},
|
||||
div(
|
||||
span(
|
||||
{
|
||||
className: "tabpanel-summary-label headers-summary-label",
|
||||
},
|
||||
SUMMARY_STATUS
|
||||
HEADERS_STATUS
|
||||
),
|
||||
StatusCode({ item }),
|
||||
input({
|
||||
className:
|
||||
"tabpanel-summary-value textbox-input devtools-monospace" +
|
||||
" status-text",
|
||||
readOnly: true,
|
||||
value: `${statusText}`,
|
||||
size: `${inputWidth}`,
|
||||
}),
|
||||
statusCodeDocURL
|
||||
? MDNLink({
|
||||
url: statusCodeDocURL,
|
||||
title: SUMMARY_STATUS_LEARN_MORE,
|
||||
})
|
||||
: span({
|
||||
className: "headers-summary learn-more-link",
|
||||
})
|
||||
span(
|
||||
{
|
||||
className: "tabpanel-summary-value status",
|
||||
"data-code": status,
|
||||
},
|
||||
StatusCode({
|
||||
item: { fromCache, fromServiceWorker, status, statusText },
|
||||
}),
|
||||
statusText
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
let trackingProtectionStatus;
|
||||
|
||||
let trackingProtectionDetails = "";
|
||||
if (isThirdPartyTrackingResource) {
|
||||
const trackingProtectionDocURL = getTrackingProtectionURL();
|
||||
|
||||
trackingProtectionStatus = div(
|
||||
{
|
||||
key: "tracking-protection",
|
||||
className: "tabpanel-summary-container tracking-protection",
|
||||
},
|
||||
div({
|
||||
className: "tracking-resource",
|
||||
}),
|
||||
L10N.getStr("netmonitor.trackingResource.tooltip"),
|
||||
trackingProtectionDocURL
|
||||
? MDNLink({
|
||||
url: trackingProtectionDocURL,
|
||||
title: SUMMARY_STATUS_LEARN_MORE,
|
||||
})
|
||||
: span({
|
||||
className: "headers-summary learn-more-link",
|
||||
})
|
||||
trackingProtectionStatus = this.renderSummary(
|
||||
HEADERS_CONTENT_BLOCKING,
|
||||
div(null, span({ className: "tracking-resource" }), HEADERS_ETP)
|
||||
);
|
||||
trackingProtectionDetails = this.renderSummary(
|
||||
"",
|
||||
div(
|
||||
{
|
||||
key: "tracking-protection",
|
||||
className: "tabpanel-summary-value tracking-protection",
|
||||
},
|
||||
L10N.getStr("netmonitor.trackingResource.tooltip"),
|
||||
trackingProtectionDocURL
|
||||
? MDNLink({
|
||||
url: trackingProtectionDocURL,
|
||||
title: SUMMARY_STATUS_LEARN_MORE,
|
||||
})
|
||||
: span({ className: "headers-summary learn-more-link" })
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const summaryVersion = httpVersion
|
||||
? this.renderSummary(SUMMARY_VERSION, httpVersion)
|
||||
? this.renderSummary(HEADERS_VERSION, httpVersion)
|
||||
: null;
|
||||
|
||||
const summaryReferrerPolicy = referrerPolicy
|
||||
? this.renderSummary(SUMMARY_REFERRER_POLICY, referrerPolicy)
|
||||
? this.renderSummary(HEADERS_REFERRER, referrerPolicy)
|
||||
: null;
|
||||
|
||||
const summaryItems = [
|
||||
summaryUrl,
|
||||
trackingProtectionStatus,
|
||||
summaryMethod,
|
||||
summaryAddress,
|
||||
summaryStatus,
|
||||
summaryAddress,
|
||||
summaryVersion,
|
||||
summarySize,
|
||||
summaryReferrerPolicy,
|
||||
trackingProtectionStatus,
|
||||
trackingProtectionDetails,
|
||||
].filter(summaryItem => summaryItem !== null);
|
||||
|
||||
return div(
|
||||
|
@ -763,7 +750,11 @@ class HeadersPanel extends Component {
|
|||
),
|
||||
div(
|
||||
{ className: "panel-container" },
|
||||
div({ className: "headers-overview" }, summaryItems),
|
||||
div(
|
||||
{ className: "headers-overview" },
|
||||
UrlPreview({ url: urlDetails.url, method }),
|
||||
div({ className: "summary" }, summaryItems)
|
||||
),
|
||||
Accordion({ items })
|
||||
)
|
||||
);
|
||||
|
|
|
@ -19,20 +19,21 @@ add_task(async function() {
|
|||
// Execute request.
|
||||
await performRequests(monitor, tab, 1);
|
||||
|
||||
// Wait until the tab panel summary is displayed
|
||||
const wait = waitUntil(
|
||||
() => document.querySelectorAll(".tabpanel-summary-label")[0]
|
||||
// Wait until the url preview ihas loaded
|
||||
const wait = waitUntil(() =>
|
||||
document.querySelector("#headers-panel .url-preview")
|
||||
);
|
||||
|
||||
EventUtils.sendMouseEvent(
|
||||
{ type: "mousedown" },
|
||||
document.querySelectorAll(".request-list-item")[0]
|
||||
);
|
||||
|
||||
await wait;
|
||||
|
||||
const requestURL = document.querySelectorAll(".tabpanel-summary-value")[0];
|
||||
|
||||
const requestURL = document.querySelector("#headers-panel .url-preview .url");
|
||||
is(
|
||||
requestURL.textContent.endsWith("foo+%23+bar"),
|
||||
requestURL.textContent.endsWith("foo # bar"),
|
||||
true,
|
||||
"\"Request URL\" containing '#' is correctly decoded."
|
||||
);
|
||||
|
|
|
@ -29,7 +29,7 @@ add_task(async function() {
|
|||
);
|
||||
await wait;
|
||||
|
||||
const referrerPolicyIndex = 5;
|
||||
const referrerPolicyIndex = 4;
|
||||
const referrerPolicyHeader = document.querySelectorAll(
|
||||
".tabpanel-summary-label"
|
||||
)[referrerPolicyIndex];
|
||||
|
@ -38,7 +38,7 @@ add_task(async function() {
|
|||
)[referrerPolicyIndex];
|
||||
|
||||
is(
|
||||
referrerPolicyHeader.textContent === "Referrer Policy:",
|
||||
referrerPolicyHeader.textContent === "Referrer",
|
||||
true,
|
||||
'"Referrer Policy" header is displayed in the header panel.'
|
||||
);
|
||||
|
|
|
@ -87,7 +87,7 @@ add_task(async function() {
|
|||
const tabEl = document.querySelectorAll(
|
||||
".network-details-bar .tabs-menu a"
|
||||
)[0];
|
||||
const tabpanel = document.querySelector(".network-details-bar .tab-panel");
|
||||
const tabpanel = document.querySelector("#headers-panel");
|
||||
|
||||
is(
|
||||
tabEl.getAttribute("aria-selected"),
|
||||
|
@ -96,19 +96,20 @@ add_task(async function() {
|
|||
);
|
||||
// Request URL
|
||||
is(
|
||||
tabpanel.querySelectorAll(".tabpanel-summary-value")[0].innerText,
|
||||
tabpanel.querySelector(".url-preview .url").innerText,
|
||||
SIMPLE_SJS,
|
||||
"The url summary value is incorrect."
|
||||
);
|
||||
|
||||
// Request method
|
||||
is(
|
||||
tabpanel.querySelectorAll(".tabpanel-summary-value")[1].innerText,
|
||||
tabpanel.querySelectorAll(".treeLabel")[0].innerText,
|
||||
"GET",
|
||||
"The method summary value is incorrect."
|
||||
);
|
||||
// Remote address
|
||||
is(
|
||||
tabpanel.querySelectorAll(".tabpanel-summary-value")[2].innerText,
|
||||
tabpanel.querySelectorAll(".tabpanel-summary-value")[1].innerText,
|
||||
"127.0.0.1:8888",
|
||||
"The remote address summary value is incorrect."
|
||||
);
|
||||
|
@ -119,13 +120,13 @@ add_task(async function() {
|
|||
"The status summary code is incorrect."
|
||||
);
|
||||
is(
|
||||
tabpanel.querySelector(".status-text").getAttribute("value"),
|
||||
tabpanel.querySelector(".status").childNodes[1].textContent,
|
||||
"Och Aye",
|
||||
"The status summary value is incorrect."
|
||||
);
|
||||
// Version
|
||||
is(
|
||||
tabpanel.querySelectorAll(".tabpanel-summary-value")[4].innerText,
|
||||
tabpanel.querySelectorAll(".tabpanel-summary-value")[2].innerText,
|
||||
"HTTP/1.1",
|
||||
"The HTTP version is incorrect."
|
||||
);
|
||||
|
@ -139,7 +140,7 @@ add_task(async function() {
|
|||
);
|
||||
|
||||
is(
|
||||
tabpanel.querySelectorAll(".treeLabelCell").length,
|
||||
tabpanel.querySelectorAll(".accordion .treeLabelCell").length,
|
||||
23,
|
||||
"There should be 23 header values displayed in this tabpanel."
|
||||
);
|
||||
|
|
|
@ -172,35 +172,31 @@ add_task(async function() {
|
|||
document.querySelectorAll(".request-list-item")[index]
|
||||
);
|
||||
|
||||
// wait till all the summary section is loaded
|
||||
await waitUntil(() =>
|
||||
document.querySelector(
|
||||
"#headers-panel .tabpanel-summary-value.textbox-input"
|
||||
)
|
||||
document.querySelector("#headers-panel .tabpanel-summary-value")
|
||||
);
|
||||
|
||||
const panel = document.querySelector("#headers-panel");
|
||||
const summaryValues = panel.querySelectorAll(
|
||||
".tabpanel-summary-value.textbox-input"
|
||||
);
|
||||
const {
|
||||
method,
|
||||
correctUri,
|
||||
details: { status, statusText },
|
||||
} = data;
|
||||
|
||||
const statusCode = panel.querySelector(".status-code");
|
||||
const statusTextInput = panel.querySelector(".status-text");
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mouseover" }, statusCode);
|
||||
await waitUntil(() => statusCode.title);
|
||||
|
||||
is(
|
||||
summaryValues[0].textContent,
|
||||
panel.querySelector(".url-preview .url").textContent,
|
||||
correctUri,
|
||||
"The url summary value is incorrect."
|
||||
);
|
||||
is(
|
||||
summaryValues[1].textContent,
|
||||
panel.querySelectorAll(".treeLabel")[0].textContent,
|
||||
method,
|
||||
"The method summary value is incorrect."
|
||||
"The method value is incorrect."
|
||||
);
|
||||
is(
|
||||
statusCode.dataset.code,
|
||||
|
@ -212,11 +208,6 @@ add_task(async function() {
|
|||
status + " " + statusText,
|
||||
"The status summary value is incorrect."
|
||||
);
|
||||
is(
|
||||
statusTextInput.value,
|
||||
statusText,
|
||||
"The status text value is incorrect."
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -62,6 +62,7 @@ function selectElementsInPanelview(panelview) {
|
|||
window: /** @type {ChromeWindow} */ (document.defaultView),
|
||||
inactive: getElementById("PanelUI-profiler-inactive"),
|
||||
active: getElementById("PanelUI-profiler-active"),
|
||||
locked: getElementById("PanelUI-profiler-locked"),
|
||||
presetDescription: getElementById("PanelUI-profiler-content-description"),
|
||||
presetCustom: getElementById("PanelUI-profiler-content-custom"),
|
||||
presetsCustomButton: getElementById(
|
||||
|
@ -133,25 +134,48 @@ function createViewControllers(state, elements) {
|
|||
PanelMultiView.forNode(elements.panelview).descriptionHeightWorkaround();
|
||||
},
|
||||
|
||||
updateProfilerActive() {
|
||||
updateProfilerState() {
|
||||
const { Services } = lazy.Services();
|
||||
const isProfilerActive = Services.profiler.IsActive();
|
||||
elements.inactive.setAttribute(
|
||||
"hidden",
|
||||
isProfilerActive ? "true" : "false"
|
||||
);
|
||||
elements.active.setAttribute(
|
||||
"hidden",
|
||||
isProfilerActive ? "false" : "true"
|
||||
);
|
||||
elements.settingsSection.setAttribute(
|
||||
"hidden",
|
||||
isProfilerActive ? "true" : "false"
|
||||
);
|
||||
elements.contentRecording.setAttribute(
|
||||
"hidden",
|
||||
isProfilerActive ? "false" : "true"
|
||||
);
|
||||
/**
|
||||
* Convert two boolean values into a "profilerState" enum.
|
||||
*
|
||||
* @type {"active" | "inactive" | "locked"}
|
||||
*/
|
||||
let profilerState = Services.profiler.IsActive() ? "active" : "inactive";
|
||||
if (!Services.profiler.CanProfile()) {
|
||||
// In private browsing mode, the profiler is locked.
|
||||
profilerState = "locked";
|
||||
}
|
||||
|
||||
switch (profilerState) {
|
||||
case "active":
|
||||
elements.inactive.setAttribute("hidden", "true");
|
||||
elements.active.setAttribute("hidden", "false");
|
||||
elements.settingsSection.setAttribute("hidden", "true");
|
||||
elements.contentRecording.setAttribute("hidden", "false");
|
||||
elements.locked.setAttribute("hidden", "true");
|
||||
break;
|
||||
case "inactive":
|
||||
elements.inactive.setAttribute("hidden", "false");
|
||||
elements.active.setAttribute("hidden", "true");
|
||||
elements.settingsSection.setAttribute("hidden", "false");
|
||||
elements.contentRecording.setAttribute("hidden", "true");
|
||||
elements.locked.setAttribute("hidden", "true");
|
||||
break;
|
||||
case "locked": {
|
||||
elements.inactive.setAttribute("hidden", "true");
|
||||
elements.active.setAttribute("hidden", "true");
|
||||
elements.settingsSection.setAttribute("hidden", "true");
|
||||
elements.contentRecording.setAttribute("hidden", "true");
|
||||
elements.locked.setAttribute("hidden", "false");
|
||||
// This works around XULElement height issues.
|
||||
const { height } = elements.locked.getBoundingClientRect();
|
||||
elements.locked.style.height = `${height}px`;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new Error("Unhandled profiler state.");
|
||||
}
|
||||
},
|
||||
|
||||
createPresetsList() {
|
||||
|
@ -217,7 +241,7 @@ function initializePopup(state, elements, view) {
|
|||
// the size of the container. It needs to wait a second before the bounding box
|
||||
// returns an actual size.
|
||||
view.updateInfoCollapse();
|
||||
view.updateProfilerActive();
|
||||
view.updateProfilerState();
|
||||
view.updatePresets();
|
||||
|
||||
// XUL <description> elements don't vertically size correctly, this is
|
||||
|
@ -319,12 +343,20 @@ function addPopupEventHandlers(state, elements, view) {
|
|||
|
||||
// Update the view when the profiler starts/stops.
|
||||
const { Services } = lazy.Services();
|
||||
Services.obs.addObserver(view.updateProfilerActive, "profiler-started");
|
||||
Services.obs.addObserver(view.updateProfilerActive, "profiler-stopped");
|
||||
state.cleanup.push(() => {
|
||||
Services.obs.removeObserver(view.updateProfilerActive, "profiler-started");
|
||||
Services.obs.removeObserver(view.updateProfilerActive, "profiler-stopped");
|
||||
});
|
||||
|
||||
// These are all events that can affect the current state of the profiler.
|
||||
const events = [
|
||||
"profiler-started",
|
||||
"profiler-stopped",
|
||||
"chrome-document-global-created", // This is potentially a private browser.
|
||||
"last-pb-context-exited",
|
||||
];
|
||||
for (const event of events) {
|
||||
Services.obs.addObserver(view.updateProfilerState, event);
|
||||
state.cleanup.push(() => {
|
||||
Services.obs.removeObserver(view.updateProfilerState, event);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Provide an exports object for the JSM to be properly read by TypeScript.
|
||||
|
|
|
@ -27,3 +27,4 @@ support-files =
|
|||
[browser_webchannel-enable-menu-button.js]
|
||||
[browser_popup-record-capture.js]
|
||||
[browser_popup-record-discard.js]
|
||||
[browser_popup-private-browsing.js]
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
add_task(async function test() {
|
||||
info(
|
||||
"Test that the profiler popup gets disabled when a private browsing window is open."
|
||||
);
|
||||
await makeSureProfilerPopupIsEnabled();
|
||||
await toggleOpenProfilerPopup();
|
||||
|
||||
const getRecordingButton = () =>
|
||||
getElementByLabel(document, "Start Recording");
|
||||
const getDisabledMessage = () =>
|
||||
getElementFromDocumentByText(
|
||||
document,
|
||||
"The profiler is currently disabled"
|
||||
);
|
||||
|
||||
ok(await getRecordingButton(), "The start recording button is available");
|
||||
|
||||
info("Open a private browsing window.");
|
||||
const privateWindow = await BrowserTestUtils.openNewBrowserWindow({
|
||||
private: true,
|
||||
});
|
||||
|
||||
info("Switch back to the main window and open the popup again.");
|
||||
window.focus();
|
||||
await toggleOpenProfilerPopup();
|
||||
|
||||
ok(await getDisabledMessage(), "The disabled message is displayed.");
|
||||
|
||||
info("Close the private window");
|
||||
await BrowserTestUtils.closeWindow(privateWindow);
|
||||
|
||||
info("Make sure the first window is focused, and open the popup back up.");
|
||||
window.focus();
|
||||
await toggleOpenProfilerPopup();
|
||||
|
||||
ok(
|
||||
await getRecordingButton(),
|
||||
"The start recording button is available once again."
|
||||
);
|
||||
});
|
|
@ -29,7 +29,6 @@ const SWAPPED_BROWSER_STATE = [
|
|||
"_securityUI",
|
||||
"_documentURI",
|
||||
"_documentContentType",
|
||||
"_contentTitle",
|
||||
"_characterSet",
|
||||
"_contentPrincipal",
|
||||
"_isSyntheticDocument",
|
||||
|
@ -102,7 +101,6 @@ function tunnelToInnerBrowser(outer, inner) {
|
|||
if (webProgress?.isTopLevel) {
|
||||
inner._documentURI = outer._documentURI;
|
||||
inner._documentContentType = outer._documentContentType;
|
||||
inner._contentTitle = outer._contentTitle;
|
||||
inner._characterSet = outer._characterSet;
|
||||
inner._contentPrincipal = outer._contentPrincipal;
|
||||
inner._isSyntheticDocument = outer._isSyntheticDocument;
|
||||
|
@ -457,7 +455,6 @@ MessageManagerTunnel.prototype = {
|
|||
// Messages sent to browser.js
|
||||
"PageStyle:StyleSheets",
|
||||
// Messages sent to browser.js
|
||||
"DOMTitleChanged",
|
||||
"InPermitUnload",
|
||||
"PermitUnload",
|
||||
// Messages sent to SessionStore.jsm
|
||||
|
|
|
@ -21,10 +21,13 @@ add_task(async function() {
|
|||
col4: "Column 4",
|
||||
},
|
||||
uniqueId: "col1",
|
||||
emptyText: "This is dummy empty text",
|
||||
emptyText: "dummy-text",
|
||||
highlightUpdated: true,
|
||||
removableColumns: true,
|
||||
firstColumn: "col4",
|
||||
l10n: {
|
||||
setAttributes: function() {},
|
||||
},
|
||||
});
|
||||
|
||||
startTests(doc, table);
|
||||
|
|
|
@ -29,9 +29,12 @@ function test() {
|
|||
col4: "Column 4",
|
||||
},
|
||||
uniqueId: "col1",
|
||||
emptyText: "This is dummy empty text",
|
||||
emptyText: "dummy-text",
|
||||
highlightUpdated: true,
|
||||
removableColumns: true,
|
||||
l10n: {
|
||||
setAttributes: function() {},
|
||||
},
|
||||
});
|
||||
startTests();
|
||||
});
|
||||
|
|
|
@ -33,6 +33,9 @@ function test() {
|
|||
highlightUpdated: true,
|
||||
removableColumns: true,
|
||||
wrapTextInElements: true,
|
||||
l10n: {
|
||||
setAttributes: function() {},
|
||||
},
|
||||
});
|
||||
startTests();
|
||||
});
|
||||
|
|
|
@ -63,7 +63,8 @@ Object.defineProperty(this, "EVENTS", {
|
|||
* entry in the table. Default: name.
|
||||
* - wrapTextInElements: Don't ever use 'value' attribute on labels.
|
||||
* Default: false.
|
||||
* - emptyText: text to display when no entries in the table to display.
|
||||
* - emptyText: Localization ID for the text to display when there are
|
||||
* no entries in the table to display.
|
||||
* - highlightUpdated: true to highlight the changed/added row.
|
||||
* - removableColumns: Whether columns are removeable. If set to false,
|
||||
* the context menu in the headers will not appear.
|
||||
|
@ -87,6 +88,7 @@ function TableWidget(node, options = {}) {
|
|||
firstColumn,
|
||||
wrapTextInElements,
|
||||
cellContextMenuId,
|
||||
l10n,
|
||||
} = options;
|
||||
this.emptyText = emptyText || "";
|
||||
this.uniqueId = uniqueId || "name";
|
||||
|
@ -95,6 +97,7 @@ function TableWidget(node, options = {}) {
|
|||
this.highlightUpdated = highlightUpdated || false;
|
||||
this.removableColumns = removableColumns !== false;
|
||||
this.cellContextMenuId = cellContextMenuId;
|
||||
this.l10n = l10n;
|
||||
|
||||
this.tbody = this.document.createXULElement("hbox");
|
||||
this.tbody.className = "table-widget-body theme-body";
|
||||
|
@ -104,10 +107,11 @@ function TableWidget(node, options = {}) {
|
|||
this.afterScroll = this.afterScroll.bind(this);
|
||||
this.tbody.addEventListener("scroll", this.onScroll.bind(this));
|
||||
|
||||
this.placeholder = this.document.createXULElement("label");
|
||||
// Prepare placeholder
|
||||
this.placeholder = this.document.createElement("div");
|
||||
this.placeholder.className = "plain table-widget-empty-text";
|
||||
this.placeholder.setAttribute("flex", "1");
|
||||
this._parent.appendChild(this.placeholder);
|
||||
this.setPlaceholder(this.emptyText);
|
||||
|
||||
this.items = new Map();
|
||||
this.columns = new Map();
|
||||
|
@ -121,8 +125,6 @@ function TableWidget(node, options = {}) {
|
|||
|
||||
if (initialColumns) {
|
||||
this.setColumns(initialColumns, uniqueId);
|
||||
} else if (this.emptyText) {
|
||||
this.setPlaceholderText(this.emptyText);
|
||||
}
|
||||
|
||||
this.bindSelectedRow = id => {
|
||||
|
@ -656,10 +658,30 @@ TableWidget.prototype = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Sets the text to be shown when the table is empty.
|
||||
* Sets the localization ID of the description to be shown when the table is empty.
|
||||
*
|
||||
* @param {String} l10nID
|
||||
* The ID of the localization string.
|
||||
* @param {String} learnMoreURL
|
||||
* A URL referring to a website with further information related to
|
||||
* the data shown in the table widget.
|
||||
*/
|
||||
setPlaceholderText: function(text) {
|
||||
this.placeholder.setAttribute("value", text);
|
||||
setPlaceholder: function(l10nID, learnMoreURL) {
|
||||
if (learnMoreURL) {
|
||||
let placeholderLink = this.placeholder.firstElementChild;
|
||||
if (!placeholderLink) {
|
||||
placeholderLink = this.document.createElement("a");
|
||||
placeholderLink.setAttribute("target", "_blank");
|
||||
placeholderLink.setAttribute("data-l10n-name", "learn-more-link");
|
||||
this.placeholder.appendChild(placeholderLink);
|
||||
}
|
||||
placeholderLink.setAttribute("href", learnMoreURL);
|
||||
} else {
|
||||
// Remove link element if no learn more URL is given
|
||||
this.placeholder.firstElementChild?.remove();
|
||||
}
|
||||
|
||||
this.l10n.setAttributes(this.placeholder, l10nID);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -955,7 +977,7 @@ TableWidget.prototype = {
|
|||
column.clear();
|
||||
}
|
||||
this.tbody.setAttribute("empty", "empty");
|
||||
this.setPlaceholderText(this.emptyText);
|
||||
this.setPlaceholder(this.emptyText);
|
||||
|
||||
this.selectedRow = null;
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
<script src="chrome://devtools/content/shared/theme-switching.js"/>
|
||||
<script src="chrome://global/content/globalOverlay.js"/>
|
||||
|
||||
<html:link rel="localization" href="devtools/client/storage.ftl"/>
|
||||
|
||||
<popupset id="storagePopupSet">
|
||||
<menupopup id="storage-tree-popup">
|
||||
<menuitem id="storage-tree-popup-delete-all"
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
|
||||
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
|
||||
|
||||
DIRS += [
|
||||
'utils',
|
||||
]
|
||||
|
||||
DevToolsModules(
|
||||
'panel.js',
|
||||
'ui.js',
|
||||
|
|
|
@ -92,5 +92,6 @@ fail-if = fission
|
|||
[browser_storage_sidebar_toggle.js]
|
||||
fail-if = fission
|
||||
[browser_storage_sidebar_update.js]
|
||||
[browser_storage_type_descriptions.js]
|
||||
[browser_storage_values.js]
|
||||
[browser_storage_webext_storage_local.js]
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
/* 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/. */
|
||||
|
||||
// Basic test to assert that the descriptions for the different storage types
|
||||
// are correctly displayed and the links referring to pages with further
|
||||
// information are set.
|
||||
|
||||
"use strict";
|
||||
|
||||
const getStorageTypeURL = require("devtools/client/storage/utils/mdn-utils");
|
||||
|
||||
const storeItems = [
|
||||
"Cache",
|
||||
"cookies",
|
||||
"indexedDB",
|
||||
"localStorage",
|
||||
"sessionStorage",
|
||||
];
|
||||
|
||||
/**
|
||||
* Test that the desired number of tree items are present
|
||||
*/
|
||||
function testTree() {
|
||||
const doc = gPanelWindow.document;
|
||||
for (const type of storeItems) {
|
||||
ok(
|
||||
doc.querySelector(`[data-id='${JSON.stringify([type])}']`),
|
||||
`Tree item ${type} should be present in the storage tree`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that description is shown for each of the tree items
|
||||
*/
|
||||
const testDescriptions = async function() {
|
||||
const doc = gPanelWindow.document;
|
||||
const win = doc.defaultView;
|
||||
// Expand all nodes so that the synthesized click event actually works
|
||||
gUI.tree.expandAll();
|
||||
|
||||
// Click the tree items and wait for the content to be updated
|
||||
for (const type of storeItems) {
|
||||
await selectTreeItem([type]);
|
||||
|
||||
// Check whether the table is hidden
|
||||
is(
|
||||
win.getComputedStyle(doc.querySelector(".table-widget-body")).display,
|
||||
"none",
|
||||
"Table must be hidden"
|
||||
);
|
||||
|
||||
// Check whether the description shown
|
||||
is(
|
||||
win.getComputedStyle(doc.querySelector(".table-widget-empty-text"))
|
||||
.display,
|
||||
"block",
|
||||
"Description for the type must be shown"
|
||||
);
|
||||
|
||||
// Check learn more link
|
||||
const learnMoreLink = doc.querySelector(".table-widget-empty-text > a");
|
||||
ok(learnMoreLink, "There is a [Learn more] link");
|
||||
const expectedURL =
|
||||
getStorageTypeURL(type) +
|
||||
"?utm_source=devtools&utm_medium=storage-inspector";
|
||||
is(
|
||||
learnMoreLink.href,
|
||||
expectedURL,
|
||||
`Learn more link refers to ${expectedURL}`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
add_task(async function() {
|
||||
await openTabAndSetupStorage(MAIN_DOMAIN + "storage-empty-objectstores.html");
|
||||
|
||||
testTree();
|
||||
await testDescriptions();
|
||||
await finishTests();
|
||||
});
|
|
@ -545,9 +545,16 @@ async function selectTreeItem(ids) {
|
|||
|
||||
// The item exists but is not selected... select it.
|
||||
info(`Selecting "${ids}".`);
|
||||
const updated = gUI.once("store-objects-updated");
|
||||
gUI.tree.selectedItem = ids;
|
||||
await updated;
|
||||
if (ids.length > 1) {
|
||||
const updated = gUI.once("store-objects-updated");
|
||||
gUI.tree.selectedItem = ids;
|
||||
await updated;
|
||||
} else {
|
||||
// If the length of the IDs array is 1, a storage type
|
||||
// gets selected and no 'store-objects-updated' event
|
||||
// will be fired in that case.
|
||||
gUI.tree.selectedItem = ids;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,6 +10,7 @@ const KeyShortcuts = require("devtools/client/shared/key-shortcuts");
|
|||
const { parseItemValue } = require("devtools/shared/storage/utils");
|
||||
const { KeyCodes } = require("devtools/client/shared/keycodes");
|
||||
const { getUnicodeHostname } = require("devtools/client/shared/unicode-url");
|
||||
const getStorageTypeURL = require("devtools/client/storage/utils/mdn-utils");
|
||||
|
||||
// GUID to be used as a separator in compound keys. This must match the same
|
||||
// constant in devtools/server/actors/storage.js,
|
||||
|
@ -131,9 +132,10 @@ class StorageUI {
|
|||
|
||||
const tableNode = this._panelDoc.getElementById("storage-table");
|
||||
this.table = new TableWidget(tableNode, {
|
||||
emptyText: L10N.getStr("table.emptyText"),
|
||||
emptyText: "storage-table-empty-text",
|
||||
highlightUpdated: true,
|
||||
cellContextMenuId: "storage-table-popup",
|
||||
l10n: this._panelDoc.l10n,
|
||||
});
|
||||
|
||||
this.updateObjectSidebar = this.updateObjectSidebar.bind(this);
|
||||
|
@ -1049,6 +1051,33 @@ class StorageUI {
|
|||
|
||||
let names = null;
|
||||
if (!host) {
|
||||
let storageTypeHintL10nId = "";
|
||||
switch (type) {
|
||||
case "Cache":
|
||||
storageTypeHintL10nId = "storage-table-type-cache-hint";
|
||||
break;
|
||||
case "cookies":
|
||||
storageTypeHintL10nId = "storage-table-type-cookies-hint";
|
||||
break;
|
||||
case "extensionStorage":
|
||||
storageTypeHintL10nId = "storage-table-type-extensionstorage-hint";
|
||||
break;
|
||||
case "localStorage":
|
||||
storageTypeHintL10nId = "storage-table-type-localstorage-hint";
|
||||
break;
|
||||
case "indexedDB":
|
||||
storageTypeHintL10nId = "storage-table-type-indexeddb-hint";
|
||||
break;
|
||||
case "sessionStorage":
|
||||
storageTypeHintL10nId = "storage-table-type-sessionstorage-hint";
|
||||
break;
|
||||
}
|
||||
this.table.setPlaceholder(
|
||||
storageTypeHintL10nId,
|
||||
getStorageTypeURL(this.table.datatype) +
|
||||
"?utm_source=devtools&utm_medium=storage-inspector"
|
||||
);
|
||||
|
||||
// If selected item has no host then reset table headers
|
||||
await this.clearHeaders();
|
||||
return;
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {
|
||||
FluentL10n,
|
||||
} = require("devtools/client/shared/fluent-l10n/fluent-l10n");
|
||||
|
||||
// exports a singleton, which will be used across all storage panel modules
|
||||
exports.l10n = new FluentL10n();
|
|
@ -0,0 +1,34 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const MDN_BASE_URL = "https://developer.mozilla.org/Tools/Storage_Inspector/";
|
||||
|
||||
/**
|
||||
* Get the MDN URL for the specified storage type.
|
||||
*
|
||||
* @param {string} type Type of the storage.
|
||||
*
|
||||
* @return {string} The MDN URL for the storage type, or null if not available.
|
||||
*/
|
||||
function getStorageTypeURL(type) {
|
||||
switch (type) {
|
||||
case "cookies":
|
||||
return `${MDN_BASE_URL}Cookies`;
|
||||
case "localStorage":
|
||||
case "sessionStorage":
|
||||
return `${MDN_BASE_URL}Local_storage_Session_storage`;
|
||||
case "indexedDB":
|
||||
return `${MDN_BASE_URL}IndexedDB`;
|
||||
case "Cache":
|
||||
return `${MDN_BASE_URL}Cache_Storage`;
|
||||
case "extensionStorage":
|
||||
return `${MDN_BASE_URL}Extension_storage`;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = getStorageTypeURL;
|
|
@ -0,0 +1,8 @@
|
|||
# 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/.
|
||||
|
||||
DevToolsModules(
|
||||
'l10n.js',
|
||||
'mdn-utils.js',
|
||||
)
|
|
@ -339,7 +339,6 @@ checkbox:-moz-focusring {
|
|||
margin: 0 3px;
|
||||
transition: opacity 0.05s ease-in-out;
|
||||
color: var(--theme-icon-color);
|
||||
direction: ltr;
|
||||
font-size: 11px;
|
||||
-moz-context-properties: fill;
|
||||
fill: currentColor;
|
||||
|
|
|
@ -750,6 +750,7 @@
|
|||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: 600;
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
#print-simulation-toggle::before {
|
||||
|
|
|
@ -2,6 +2,15 @@
|
|||
* 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/. */
|
||||
|
||||
/*
|
||||
* Global styles
|
||||
*/
|
||||
a {
|
||||
color: var(--theme-highlight-blue);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Storage Host Tree */
|
||||
|
||||
#storage-tree {
|
||||
|
@ -23,8 +32,13 @@
|
|||
outline: 0;
|
||||
}
|
||||
|
||||
/* Storage Table */
|
||||
|
||||
/* Let the component gain focus when a click hits an empty area */
|
||||
#storage-table {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
-moz-user-focus: normal;
|
||||
}
|
||||
|
||||
|
|
|
@ -570,12 +570,13 @@
|
|||
}
|
||||
|
||||
.table-widget-body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.table-widget-body,
|
||||
.table-widget-empty-text {
|
||||
background-color: var(--theme-body-background);
|
||||
.table-widget-body[empty="empty"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Column Headers */
|
||||
|
@ -674,9 +675,7 @@
|
|||
|
||||
.table-widget-empty-text {
|
||||
display: none;
|
||||
text-align: center;
|
||||
font-size: large;
|
||||
margin-top: -20px !important;
|
||||
}
|
||||
|
||||
.table-widget-body:empty + .table-widget-empty-text:not([value=""]),
|
||||
|
|
|
@ -46,7 +46,7 @@ async function registerWatcher(watcher, watchedBrowsingContextID) {
|
|||
watchers.set(prefix, watcher);
|
||||
if (watchers.size == 1) {
|
||||
// Register the JSWindowActor pair "DevToolsFrame" only once we register our first WindowGlobal Watcher
|
||||
ActorManagerParent.addActors({
|
||||
ActorManagerParent.addJSWindowActors({
|
||||
DevToolsFrame: {
|
||||
parent: {
|
||||
moduleURI:
|
||||
|
|
|
@ -51,11 +51,6 @@ loader.lazyImporter(
|
|||
"AddonManager",
|
||||
"resource://gre/modules/AddonManager.jsm"
|
||||
);
|
||||
loader.lazyImporter(
|
||||
this,
|
||||
"AppConstants",
|
||||
"resource://gre/modules/AppConstants.jsm"
|
||||
);
|
||||
|
||||
/**
|
||||
* Browser-specific actors.
|
||||
|
@ -178,15 +173,6 @@ exports.createRootActor = function createRootActor(connection) {
|
|||
* conservative approach of simply searching the entire table for actors that
|
||||
* belong to the closing XUL window, rather than trying to somehow track which
|
||||
* XUL window each tab belongs to.
|
||||
*
|
||||
* - Title changes:
|
||||
*
|
||||
* For tabs living in the child process, we listen for DOMTitleChange message
|
||||
* via the top-level window's message manager.
|
||||
* But as these messages aren't sent for tabs loaded in the parent process,
|
||||
* we also listen for TabAttrModified event, which is fired only on Firefox
|
||||
* desktop.
|
||||
* Also, we listen DOMTitleChange event on Android document.
|
||||
*/
|
||||
function BrowserTabList(connection) {
|
||||
this._connection = connection;
|
||||
|
@ -231,7 +217,7 @@ function BrowserTabList(connection) {
|
|||
/* True if we're testing, and should throw if consistency checks fail. */
|
||||
this._testing = false;
|
||||
|
||||
this._onAndroidDocumentEvent = this._onAndroidDocumentEvent.bind(this);
|
||||
this._onPageTitleChangedEvent = this._onPageTitleChangedEvent.bind(this);
|
||||
}
|
||||
|
||||
BrowserTabList.prototype.constructor = BrowserTabList;
|
||||
|
@ -487,33 +473,14 @@ BrowserTabList.prototype._checkListening = function() {
|
|||
);
|
||||
|
||||
/*
|
||||
* We also listen for title changed from the child process.
|
||||
* This allows listening for title changes from OOP tabs.
|
||||
* OOP tabs are running browser-child.js frame script which sends DOMTitleChanged
|
||||
* events through the message manager.
|
||||
* We also listen for title changed events on the browser.
|
||||
*/
|
||||
this._listenForMessagesIf(
|
||||
this._listenForEventsIf(
|
||||
this._onListChanged && this._mustNotify,
|
||||
"_listeningForTitleChange",
|
||||
["DOMTitleChanged"]
|
||||
["pagetitlechanged"],
|
||||
this._onPageTitleChangedEvent
|
||||
);
|
||||
|
||||
/*
|
||||
* We also listen for title changed event on Android document.
|
||||
* Android document events are used for single process Gecko View and Firefox for
|
||||
* Android. They do no execute browser-child.js because of single process, instead
|
||||
* DOMTitleChanged events are emitted on the top level document.
|
||||
* Also, Multi process Gecko View is not covered by here since that receives title
|
||||
* updates via DOMTitleChanged messages.
|
||||
*/
|
||||
if (AppConstants.platform === "android") {
|
||||
this._listenForEventsIf(
|
||||
this._onListChanged && this._mustNotify,
|
||||
"_listeningForAndroidDocument",
|
||||
["DOMTitleChanged"],
|
||||
this._onAndroidDocumentEvent
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -547,40 +514,11 @@ BrowserTabList.prototype._listenForEventsIf = function(
|
|||
};
|
||||
|
||||
/*
|
||||
* Add or remove message listeners for all XUL windows.
|
||||
*
|
||||
* @param shouldListen boolean
|
||||
* True if we should add message listeners; false if we should remove them.
|
||||
* @param guard string
|
||||
* The name of a guard property of 'this', indicating whether we're
|
||||
* already listening for those messages.
|
||||
* @param messageNames array of strings
|
||||
* An array of message names.
|
||||
* Event listener for pagetitlechanged event.
|
||||
*/
|
||||
BrowserTabList.prototype._listenForMessagesIf = function(
|
||||
shouldListen,
|
||||
guard,
|
||||
messageNames
|
||||
) {
|
||||
if (!shouldListen !== !this[guard]) {
|
||||
const op = shouldListen ? "addMessageListener" : "removeMessageListener";
|
||||
for (const win of Services.wm.getEnumerator(
|
||||
DevToolsServer.chromeWindowType
|
||||
)) {
|
||||
for (const name of messageNames) {
|
||||
win.messageManager[op](name, this);
|
||||
}
|
||||
}
|
||||
this[guard] = shouldListen;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* This function assumes to be used as a event listener for Android document.
|
||||
*/
|
||||
BrowserTabList.prototype._onAndroidDocumentEvent = function(event) {
|
||||
BrowserTabList.prototype._onPageTitleChangedEvent = function(event) {
|
||||
switch (event.type) {
|
||||
case "DOMTitleChanged": {
|
||||
case "pagetitlechanged": {
|
||||
const window = event.currentTarget.ownerGlobal;
|
||||
this._onDOMTitleChanged(window.browser);
|
||||
break;
|
||||
|
@ -588,21 +526,6 @@ BrowserTabList.prototype._onAndroidDocumentEvent = function(event) {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Implement nsIMessageListener.
|
||||
*/
|
||||
BrowserTabList.prototype.receiveMessage = DevToolsUtils.makeInfallible(function(
|
||||
message
|
||||
) {
|
||||
const browser = message.target;
|
||||
switch (message.name) {
|
||||
case "DOMTitleChanged": {
|
||||
this._onDOMTitleChanged(browser);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Handle "DOMTitleChanged" event.
|
||||
*/
|
||||
|
@ -623,8 +546,7 @@ BrowserTabList.prototype.handleEvent = DevToolsUtils.makeInfallible(function(
|
|||
event
|
||||
) {
|
||||
// If event target has `linkedBrowser`, the event target can be assumed <tab> element.
|
||||
// Else (in Android case), because event target is assumed <browser> element,
|
||||
// use the target as it is.
|
||||
// Else, event target is assumed <browser> element, use the target as it is.
|
||||
const browser = event.target.linkedBrowser || event.target;
|
||||
switch (event.type) {
|
||||
case "TabOpen":
|
||||
|
|
|
@ -305,7 +305,7 @@ class DevToolsFrameChild extends JSWindowActorChild {
|
|||
}
|
||||
|
||||
handleEvent({ type }) {
|
||||
// DOMWindowCreated is registered from FrameWatcher via `ActorManagerParent.addActors`
|
||||
// DOMWindowCreated is registered from FrameWatcher via `ActorManagerParent.addJSWindowActors`
|
||||
// as a DOM event to be listened to and so is fired by JS Window Actor code platform code.
|
||||
if (type == "DOMWindowCreated") {
|
||||
this.instantiate();
|
||||
|
|
|
@ -404,6 +404,9 @@ void BrowsingContext::SetDocShell(nsIDocShell* aDocShell) {
|
|||
mDocShell = aDocShell;
|
||||
mDanglingRemoteOuterProxies = !mIsInProcess;
|
||||
mIsInProcess = true;
|
||||
if (mChildSessionHistory) {
|
||||
mChildSessionHistory->SetIsInProcess(true);
|
||||
}
|
||||
}
|
||||
|
||||
// This class implements a callback that will return the remote window proxy for
|
||||
|
@ -517,6 +520,10 @@ void BrowsingContext::Attach(bool aFromIPC, ContentParent* aOriginProcess) {
|
|||
PopupBlocker::RegisterOpenPopupSpam();
|
||||
}
|
||||
|
||||
if (IsTop() && GetHasSessionHistory()) {
|
||||
CreateChildSHistory();
|
||||
}
|
||||
|
||||
if (XRE_IsContentProcess() && !aFromIPC) {
|
||||
// Send attach to our parent if we need to.
|
||||
ContentChild::GetSingleton()->SendCreateBrowsingContext(
|
||||
|
@ -626,6 +633,11 @@ void BrowsingContext::PrepareForProcessChange() {
|
|||
// different process now. This may need to change in the future with
|
||||
// Cross-Process BFCache.
|
||||
mDocShell = nullptr;
|
||||
if (mChildSessionHistory) {
|
||||
// This can be removed once session history is stored exclusively in the
|
||||
// parent process.
|
||||
mChildSessionHistory->SetIsInProcess(false);
|
||||
}
|
||||
|
||||
if (!mWindowProxy) {
|
||||
return;
|
||||
|
@ -1318,14 +1330,16 @@ nsresult BrowsingContext::SetOriginAttributes(const OriginAttributes& aAttrs) {
|
|||
void BrowsingContext::AssertCoherentLoadContext() {
|
||||
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
|
||||
// LoadContext should generally match our opener or parent.
|
||||
if (RefPtr<BrowsingContext> opener = GetOpener()) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(opener->mType == mType);
|
||||
MOZ_DIAGNOSTIC_ASSERT(opener->mGroup == mGroup);
|
||||
MOZ_DIAGNOSTIC_ASSERT(opener->mUseRemoteTabs == mUseRemoteTabs);
|
||||
MOZ_DIAGNOSTIC_ASSERT(opener->mUseRemoteSubframes == mUseRemoteSubframes);
|
||||
MOZ_DIAGNOSTIC_ASSERT(opener->mPrivateBrowsingId == mPrivateBrowsingId);
|
||||
MOZ_DIAGNOSTIC_ASSERT(
|
||||
opener->mOriginAttributes.EqualsIgnoringFPD(mOriginAttributes));
|
||||
if (IsContent()) {
|
||||
if (RefPtr<BrowsingContext> opener = GetOpener()) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(opener->mType == mType);
|
||||
MOZ_DIAGNOSTIC_ASSERT(opener->mGroup == mGroup);
|
||||
MOZ_DIAGNOSTIC_ASSERT(opener->mUseRemoteTabs == mUseRemoteTabs);
|
||||
MOZ_DIAGNOSTIC_ASSERT(opener->mUseRemoteSubframes == mUseRemoteSubframes);
|
||||
MOZ_DIAGNOSTIC_ASSERT(opener->mPrivateBrowsingId == mPrivateBrowsingId);
|
||||
MOZ_DIAGNOSTIC_ASSERT(
|
||||
opener->mOriginAttributes.EqualsIgnoringFPD(mOriginAttributes));
|
||||
}
|
||||
}
|
||||
if (RefPtr<BrowsingContext> parent = GetParent()) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(parent->mType == mType);
|
||||
|
@ -1386,16 +1400,16 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(BrowsingContext)
|
|||
tmp->mFields.SetWithoutSyncing<IDX_IsPopupSpam>(false);
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocShell, mParentWindow, mGroup,
|
||||
mEmbedderElement, mWindowContexts,
|
||||
mCurrentWindowContext, mSessionStorageManager)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(
|
||||
mDocShell, mParentWindow, mGroup, mEmbedderElement, mWindowContexts,
|
||||
mCurrentWindowContext, mSessionStorageManager, mChildSessionHistory)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(BrowsingContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(
|
||||
mDocShell, mParentWindow, mGroup, mEmbedderElement, mWindowContexts,
|
||||
mCurrentWindowContext, mSessionStorageManager)
|
||||
mCurrentWindowContext, mSessionStorageManager, mChildSessionHistory)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
class RemoteLocationProxy
|
||||
|
@ -2199,6 +2213,51 @@ void BrowsingContext::AddDeprioritizedLoadRunner(nsIRunnable* aRunner) {
|
|||
EventQueuePriority::Idle);
|
||||
}
|
||||
|
||||
void BrowsingContext::InitSessionHistory() {
|
||||
MOZ_ASSERT(!IsDiscarded());
|
||||
MOZ_ASSERT(IsTop());
|
||||
MOZ_ASSERT(EverAttached());
|
||||
|
||||
if (!GetHasSessionHistory()) {
|
||||
SetHasSessionHistory(true);
|
||||
|
||||
// If the top browsing context (this one) is loaded in this process then we
|
||||
// also create the session history implementation for the child process.
|
||||
// This can be removed once session history is stored exclusively in the
|
||||
// parent process.
|
||||
mChildSessionHistory->SetIsInProcess(mDocShell);
|
||||
}
|
||||
}
|
||||
|
||||
ChildSHistory* BrowsingContext::GetChildSessionHistory() {
|
||||
// For now we're checking that the session history object for the child
|
||||
// process is available before returning the ChildSHistory object, because
|
||||
// it is the actual implementation that ChildSHistory forwards to. This can
|
||||
// be removed once session history is stored exclusively in the parent
|
||||
// process.
|
||||
return mChildSessionHistory && mChildSessionHistory->IsInProcess()
|
||||
? mChildSessionHistory.get()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
void BrowsingContext::CreateChildSHistory() {
|
||||
MOZ_ASSERT(IsTop());
|
||||
|
||||
// Because session history is global in a browsing context tree, every process
|
||||
// that has access to a browsing context tree needs access to its session
|
||||
// history. That is why we create the ChildSHistory object in every process
|
||||
// where we have access to this browsing context (which is the top one).
|
||||
mChildSessionHistory = new ChildSHistory(this);
|
||||
}
|
||||
|
||||
void BrowsingContext::DidSet(FieldIndex<IDX_HasSessionHistory>,
|
||||
bool aOldValue) {
|
||||
MOZ_ASSERT(GetHasSessionHistory() || !aOldValue,
|
||||
"We don't support turning off session history.");
|
||||
|
||||
CreateChildSHistory();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
|
||||
namespace ipc {
|
||||
|
|
|
@ -61,6 +61,7 @@ namespace dom {
|
|||
class BrowsingContent;
|
||||
class BrowsingContextGroup;
|
||||
class CanonicalBrowsingContext;
|
||||
class ChildSHistory;
|
||||
class ContentParent;
|
||||
class Element;
|
||||
template <typename>
|
||||
|
@ -132,7 +133,11 @@ class WindowProxyHolder;
|
|||
FIELD(WatchedByDevToolsInternal, bool) \
|
||||
FIELD(TextZoom, float) \
|
||||
/* See nsIRequest for possible flags. */ \
|
||||
FIELD(DefaultLoadFlags, uint32_t)
|
||||
FIELD(DefaultLoadFlags, uint32_t) \
|
||||
/* Signals that session history is enabled for this browsing context tree. \
|
||||
* This is only ever set to true on the top BC, so consumers need to get \
|
||||
* the value from the top BC! */ \
|
||||
FIELD(HasSessionHistory, bool)
|
||||
|
||||
// BrowsingContext, in this context, is the cross process replicated
|
||||
// environment in which information about documents is stored. In
|
||||
|
@ -597,6 +602,13 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
|
|||
const OriginAttributes& OriginAttributesRef() { return mOriginAttributes; }
|
||||
nsresult SetOriginAttributes(const OriginAttributes& aAttrs);
|
||||
|
||||
// This should only be called on the top browsing context.
|
||||
void InitSessionHistory();
|
||||
|
||||
// This will only ever return a non-null value if called on the top browsing
|
||||
// context.
|
||||
ChildSHistory* GetChildSessionHistory();
|
||||
|
||||
protected:
|
||||
virtual ~BrowsingContext();
|
||||
BrowsingContext(WindowContext* aParentWindow, BrowsingContextGroup* aGroup,
|
||||
|
@ -737,6 +749,8 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
|
|||
bool CanSet(FieldIndex<IDX_UseGlobalHistory>, const bool& aUseGlobalHistory,
|
||||
ContentParent* aSource);
|
||||
|
||||
void DidSet(FieldIndex<IDX_HasSessionHistory>, bool aOldValue);
|
||||
|
||||
template <size_t I, typename T>
|
||||
bool CanSet(FieldIndex<I>, const T&, ContentParent*) {
|
||||
return true;
|
||||
|
@ -761,6 +775,8 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
|
|||
// process.
|
||||
bool CheckOnlyEmbedderCanSet(ContentParent* aSource);
|
||||
|
||||
void CreateChildSHistory();
|
||||
|
||||
// Type of BrowsingContent
|
||||
const Type mType;
|
||||
|
||||
|
@ -855,7 +871,8 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
|
|||
|
||||
mozilla::LinkedList<DeprioritizedLoadRunner> mDeprioritizedLoadRunner;
|
||||
|
||||
RefPtr<dom::SessionStorageManager> mSessionStorageManager;
|
||||
RefPtr<SessionStorageManager> mSessionStorageManager;
|
||||
RefPtr<ChildSHistory> mChildSessionHistory;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -423,10 +423,6 @@ nsDocShell::~nsDocShell() {
|
|||
|
||||
Destroy();
|
||||
|
||||
if (mSessionHistory) {
|
||||
mSessionHistory->LegacySHistory()->ClearRootBrowsingContext();
|
||||
}
|
||||
|
||||
if (mContentViewer) {
|
||||
mContentViewer->Close(nullptr);
|
||||
mContentViewer->Destroy();
|
||||
|
@ -544,7 +540,7 @@ void nsDocShell::DestroyChildren() {
|
|||
|
||||
NS_IMPL_CYCLE_COLLECTION_WEAK_PTR_INHERITED(nsDocShell, nsDocLoader,
|
||||
mScriptGlobal, mInitialClientSource,
|
||||
mSessionHistory, mBrowsingContext,
|
||||
mBrowsingContext,
|
||||
mChromeEventHandler)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsDocShell, nsDocLoader)
|
||||
|
@ -2955,8 +2951,8 @@ nsresult nsDocShell::AddChildSHEntryInternal(nsISHEntry* aCloneRef,
|
|||
uint32_t aLoadType,
|
||||
bool aCloneChildren) {
|
||||
nsresult rv = NS_OK;
|
||||
if (mSessionHistory) {
|
||||
rv = mSessionHistory->LegacySHistory()->AddChildSHEntryHelper(
|
||||
if (GetSessionHistory()) {
|
||||
rv = GetSessionHistory()->LegacySHistory()->AddChildSHEntryHelper(
|
||||
aCloneRef, aNewEntry, mBrowsingContext, aCloneChildren);
|
||||
} else {
|
||||
/* Just pass this along */
|
||||
|
@ -3010,13 +3006,8 @@ nsresult nsDocShell::AddChildSHEntryToParent(nsISHEntry* aNewEntry,
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::RemoveFromSessionHistory() {
|
||||
nsCOMPtr<nsIDocShellTreeItem> root;
|
||||
GetInProcessSameTypeRootTreeItem(getter_AddRefs(root));
|
||||
nsCOMPtr<nsIWebNavigation> rootAsWebnav = do_QueryInterface(root);
|
||||
if (!rootAsWebnav) {
|
||||
return NS_OK;
|
||||
}
|
||||
RefPtr<ChildSHistory> sessionHistory = rootAsWebnav->GetSessionHistory();
|
||||
RefPtr<ChildSHistory> sessionHistory =
|
||||
mBrowsingContext->Top()->GetChildSessionHistory();
|
||||
if (!sessionHistory) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -3957,6 +3948,8 @@ nsDocShell::Reload(uint32_t aReloadFlags) {
|
|||
doc->GetSrcdocData(srcdoc);
|
||||
flags |= INTERNAL_LOAD_FLAGS_IS_SRCDOC;
|
||||
baseURI = doc->GetBaseURI();
|
||||
} else {
|
||||
srcdoc = VoidString();
|
||||
}
|
||||
nsCOMPtr<nsIChannel> chan = doc->GetChannel();
|
||||
if (chan) {
|
||||
|
@ -4081,26 +4074,10 @@ nsDocShell::GetCurrentURI(nsIURI** aURI) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::InitSessionHistory() {
|
||||
MOZ_ASSERT(!mIsBeingDestroyed);
|
||||
|
||||
// Make sure that we are the root DocShell, and set a handle to root docshell
|
||||
// in the session history.
|
||||
nsCOMPtr<nsIDocShellTreeItem> root;
|
||||
GetInProcessSameTypeRootTreeItem(getter_AddRefs(root));
|
||||
if (root != this) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mSessionHistory = new ChildSHistory(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetSessionHistoryXPCOM(nsISupports** aSessionHistory) {
|
||||
NS_ENSURE_ARG_POINTER(aSessionHistory);
|
||||
RefPtr<ChildSHistory> shistory = mSessionHistory;
|
||||
RefPtr<ChildSHistory> shistory = GetSessionHistory();
|
||||
shistory.forget(aSessionHistory);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -4321,12 +4298,11 @@ nsDocShell::Destroy() {
|
|||
mScriptGlobal = nullptr;
|
||||
}
|
||||
|
||||
if (mSessionHistory) {
|
||||
if (GetSessionHistory()) {
|
||||
// We want to destroy these content viewers now rather than
|
||||
// letting their destruction wait for the session history
|
||||
// entries to get garbage collected. (Bug 488394)
|
||||
mSessionHistory->EvictLocalContentViewers();
|
||||
mSessionHistory = nullptr;
|
||||
GetSessionHistory()->EvictLocalContentViewers();
|
||||
}
|
||||
|
||||
if (mWillChangeProcess) {
|
||||
|
@ -7520,13 +7496,13 @@ nsresult nsDocShell::CreateContentViewer(const nsACString& aContentType,
|
|||
|
||||
// Be sure to have a correct mLSHE, it may have been cleared by
|
||||
// EndPageLoad. See bug 302115.
|
||||
if (mSessionHistory && !mLSHE) {
|
||||
int32_t idx = mSessionHistory->LegacySHistory()->GetRequestedIndex();
|
||||
ChildSHistory* shistory = GetSessionHistory();
|
||||
if (shistory && !mLSHE) {
|
||||
int32_t idx = shistory->LegacySHistory()->GetRequestedIndex();
|
||||
if (idx == -1) {
|
||||
idx = mSessionHistory->Index();
|
||||
idx = shistory->Index();
|
||||
}
|
||||
mSessionHistory->LegacySHistory()->GetEntryAtIndex(idx,
|
||||
getter_AddRefs(mLSHE));
|
||||
shistory->LegacySHistory()->GetEntryAtIndex(idx, getter_AddRefs(mLSHE));
|
||||
}
|
||||
|
||||
mLoadType = LOAD_ERROR_PAGE;
|
||||
|
@ -8446,11 +8422,11 @@ nsresult nsDocShell::HandleSameDocumentNavigation(
|
|||
/* Set the title for the SH entry for this target url. so that
|
||||
* SH menus in go/back/forward buttons won't be empty for this.
|
||||
*/
|
||||
if (mSessionHistory) {
|
||||
int32_t index = mSessionHistory->Index();
|
||||
ChildSHistory* shistory = GetSessionHistory();
|
||||
if (shistory) {
|
||||
int32_t index = shistory->Index();
|
||||
nsCOMPtr<nsISHEntry> shEntry;
|
||||
mSessionHistory->LegacySHistory()->GetEntryAtIndex(index,
|
||||
getter_AddRefs(shEntry));
|
||||
shistory->LegacySHistory()->GetEntryAtIndex(index, getter_AddRefs(shEntry));
|
||||
NS_ENSURE_TRUE(shEntry, NS_ERROR_FAILURE);
|
||||
shEntry->SetTitle(mTitle);
|
||||
}
|
||||
|
@ -10095,12 +10071,9 @@ bool nsDocShell::OnNewURI(nsIURI* aURI, nsIChannel* aChannel,
|
|||
(IsForceReloadType(aLoadType) && IsFrame()));
|
||||
|
||||
// Create SH Entry (mLSHE) only if there is a SessionHistory object in the
|
||||
// current frame or in the root docshell.
|
||||
RefPtr<ChildSHistory> rootSH = mSessionHistory;
|
||||
if (!rootSH) {
|
||||
// Get the handle to SH from the root docshell
|
||||
rootSH = GetRootSessionHistory();
|
||||
}
|
||||
// in the root browsing context.
|
||||
RefPtr<ChildSHistory> rootSH =
|
||||
mBrowsingContext->Top()->GetChildSessionHistory();
|
||||
if (!rootSH) {
|
||||
updateSHistory = false;
|
||||
updateGHistory = false; // XXX Why global history too?
|
||||
|
@ -10203,11 +10176,11 @@ bool nsDocShell::OnNewURI(nsIURI* aURI, nsIChannel* aChannel,
|
|||
aPrincipalToInherit, aStoragePrincipalToInherit,
|
||||
aCsp, aCloneSHChildren, getter_AddRefs(mLSHE));
|
||||
}
|
||||
} else if (mSessionHistory && mLSHE && mURIResultedInDocument) {
|
||||
} else if (GetSessionHistory() && mLSHE && mURIResultedInDocument) {
|
||||
// Even if we don't add anything to SHistory, ensure the current index
|
||||
// points to the same SHEntry as our mLSHE.
|
||||
|
||||
mSessionHistory->LegacySHistory()->EnsureCorrectEntryAtCurrIndex(mLSHE);
|
||||
GetSessionHistory()->LegacySHistory()->EnsureCorrectEntryAtCurrIndex(mLSHE);
|
||||
}
|
||||
|
||||
// If this is a POST request, we do not want to include this in global
|
||||
|
@ -10846,11 +10819,11 @@ nsresult nsDocShell::AddToSessionHistory(
|
|||
loadReplace, referrerInfo, srcdoc, srcdocEntry, baseURI,
|
||||
saveLayoutState, expired);
|
||||
|
||||
if (root == static_cast<nsIDocShellTreeItem*>(this) && mSessionHistory) {
|
||||
if (root == static_cast<nsIDocShellTreeItem*>(this) && GetSessionHistory()) {
|
||||
bool shouldPersist = ShouldAddToSessionHistory(aURI, aChannel);
|
||||
Maybe<int32_t> previousEntryIndex;
|
||||
Maybe<int32_t> loadedEntryIndex;
|
||||
rv = mSessionHistory->LegacySHistory()->AddToRootSessionHistory(
|
||||
rv = GetSessionHistory()->LegacySHistory()->AddToRootSessionHistory(
|
||||
aCloneChildren, mOSHE, mBrowsingContext, entry, mLoadType,
|
||||
shouldPersist, &previousEntryIndex, &loadedEntryIndex);
|
||||
|
||||
|
@ -12259,9 +12232,9 @@ nsDocShell::ResumeRedirectedLoad(uint64_t aIdentifier, int32_t aHistoryIndex) {
|
|||
|
||||
// If we're performing a history load, locate the correct history entry,
|
||||
// and set the relevant bits on our loadState.
|
||||
if (aHistoryIndex >= 0 && self->mSessionHistory) {
|
||||
if (aHistoryIndex >= 0 && self->GetSessionHistory()) {
|
||||
nsCOMPtr<nsISHistory> legacySHistory =
|
||||
self->mSessionHistory->LegacySHistory();
|
||||
self->GetSessionHistory()->LegacySHistory();
|
||||
|
||||
nsCOMPtr<nsISHEntry> entry;
|
||||
nsresult rv = legacySHistory->GetEntryAtIndex(aHistoryIndex,
|
||||
|
|
|
@ -662,6 +662,10 @@ class nsDocShell final : public nsDocLoader,
|
|||
void SetHistoryEntryAndUpdateBC(const Maybe<nsISHEntry*>& aLSHE,
|
||||
const Maybe<nsISHEntry*>& aOSHE);
|
||||
|
||||
mozilla::dom::ChildSHistory* GetSessionHistory() {
|
||||
return mBrowsingContext->GetChildSessionHistory();
|
||||
}
|
||||
|
||||
//
|
||||
// URI Load
|
||||
//
|
||||
|
|
|
@ -987,12 +987,6 @@ interface nsIDocShell : nsIDocShellTreeItem
|
|||
|
||||
Array<float> getColorMatrix();
|
||||
|
||||
/**
|
||||
* Initialize session history for this docshell. The docshell must be the root
|
||||
* docshell.
|
||||
*/
|
||||
void initSessionHistory();
|
||||
|
||||
%{C++
|
||||
/**
|
||||
* These methods call nsDocShell::GetHTMLEditorInternal() and
|
||||
|
|
|
@ -20,23 +20,30 @@
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
static already_AddRefed<nsISHistory> CreateSHistory(nsDocShell* aDocShell) {
|
||||
if (XRE_IsContentProcess() && StaticPrefs::fission_sessionHistoryInParent()) {
|
||||
return do_AddRef(static_cast<SHistoryChild*>(
|
||||
ContentChild::GetSingleton()->SendPSHistoryConstructor(
|
||||
aDocShell->GetBrowsingContext())));
|
||||
ChildSHistory::ChildSHistory(BrowsingContext* aBrowsingContext)
|
||||
: mBrowsingContext(aBrowsingContext) {}
|
||||
|
||||
void ChildSHistory::SetIsInProcess(bool aIsInProcess) {
|
||||
if (!aIsInProcess) {
|
||||
mHistory = nullptr;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISHistory> history =
|
||||
new nsSHistory(aDocShell->GetBrowsingContext(), aDocShell->HistoryID());
|
||||
return history.forget();
|
||||
if (mHistory) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (XRE_IsContentProcess() && StaticPrefs::fission_sessionHistoryInParent()) {
|
||||
mHistory = do_AddRef(static_cast<SHistoryChild*>(
|
||||
ContentChild::GetSingleton()->SendPSHistoryConstructor(
|
||||
mBrowsingContext)));
|
||||
return;
|
||||
}
|
||||
|
||||
mHistory = new nsSHistory(mBrowsingContext);
|
||||
}
|
||||
|
||||
ChildSHistory::ChildSHistory(nsDocShell* aDocShell)
|
||||
: mDocShell(aDocShell), mHistory(CreateSHistory(aDocShell)) {}
|
||||
|
||||
ChildSHistory::~ChildSHistory() {}
|
||||
|
||||
int32_t ChildSHistory::Count() { return mHistory->GetCount(); }
|
||||
|
||||
int32_t ChildSHistory::Index() {
|
||||
|
@ -87,7 +94,10 @@ void ChildSHistory::EvictLocalContentViewers() {
|
|||
mHistory->EvictAllContentViewers();
|
||||
}
|
||||
|
||||
nsISHistory* ChildSHistory::LegacySHistory() { return mHistory; }
|
||||
nsISHistory* ChildSHistory::LegacySHistory() {
|
||||
MOZ_RELEASE_ASSERT(mHistory);
|
||||
return mHistory;
|
||||
}
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ChildSHistory)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
|
@ -97,7 +107,7 @@ NS_INTERFACE_MAP_END
|
|||
NS_IMPL_CYCLE_COLLECTING_ADDREF(ChildSHistory)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(ChildSHistory)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ChildSHistory, mDocShell, mHistory)
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ChildSHistory, mBrowsingContext, mHistory)
|
||||
|
||||
JSObject* ChildSHistory::WrapObject(JSContext* cx,
|
||||
JS::Handle<JSObject*> aGivenProto) {
|
||||
|
@ -105,14 +115,7 @@ JSObject* ChildSHistory::WrapObject(JSContext* cx,
|
|||
}
|
||||
|
||||
nsISupports* ChildSHistory::GetParentObject() const {
|
||||
// We want to get the BrowserChildMessageManager, which is the
|
||||
// messageManager on mDocShell.
|
||||
RefPtr<ContentFrameMessageManager> mm;
|
||||
if (mDocShell) {
|
||||
mm = mDocShell->GetMessageManager();
|
||||
}
|
||||
// else we must be unlinked... can that happen here?
|
||||
return ToSupports(mm);
|
||||
return xpc::NativeGlobal(xpc::PrivilegedJunkScope());
|
||||
}
|
||||
|
||||
already_AddRefed<nsISHEntry> CreateSHEntryForDocShell(nsISHistory* aSHistory) {
|
||||
|
|
|
@ -25,16 +25,14 @@
|
|||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/LinkedList.h"
|
||||
|
||||
class nsSHistory;
|
||||
class nsDocShell;
|
||||
class nsISHEntry;
|
||||
class nsISHistory;
|
||||
class nsIWebNavigation;
|
||||
class nsIGlobalObject;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class BrowsingContext;
|
||||
|
||||
class ChildSHistory : public nsISupports, public nsWrapperCache {
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
|
@ -43,7 +41,13 @@ class ChildSHistory : public nsISupports, public nsWrapperCache {
|
|||
JSObject* WrapObject(JSContext* cx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
explicit ChildSHistory(nsDocShell* aDocShell);
|
||||
explicit ChildSHistory(BrowsingContext* aBrowsingContext);
|
||||
|
||||
// Create or destroy the session history implementation in the child process.
|
||||
// This can be removed once session history is stored exclusively in the
|
||||
// parent process.
|
||||
void SetIsInProcess(bool aIsInProcess);
|
||||
bool IsInProcess() { return !!mHistory; }
|
||||
|
||||
int32_t Count();
|
||||
int32_t Index();
|
||||
|
@ -72,7 +76,7 @@ class ChildSHistory : public nsISupports, public nsWrapperCache {
|
|||
nsISHistory* LegacySHistory();
|
||||
|
||||
private:
|
||||
virtual ~ChildSHistory();
|
||||
virtual ~ChildSHistory() = default;
|
||||
|
||||
class PendingAsyncHistoryNavigation
|
||||
: public Runnable,
|
||||
|
@ -96,7 +100,7 @@ class ChildSHistory : public nsISupports, public nsWrapperCache {
|
|||
int32_t mOffset;
|
||||
};
|
||||
|
||||
RefPtr<nsDocShell> mDocShell;
|
||||
RefPtr<BrowsingContext> mBrowsingContext;
|
||||
nsCOMPtr<nsISHistory> mHistory;
|
||||
mozilla::LinkedList<PendingAsyncHistoryNavigation> mPendingNavigations;
|
||||
};
|
||||
|
|
|
@ -215,9 +215,6 @@ SHistoryChild::AddEntry(nsISHEntry* aEntry, bool aPersist) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(void)
|
||||
SHistoryChild::ClearRootBrowsingContext() { mRootDocShell = nullptr; }
|
||||
|
||||
NS_IMETHODIMP
|
||||
SHistoryChild::UpdateIndex(void) {
|
||||
return SendUpdateIndex() ? NS_OK : NS_ERROR_FAILURE;
|
||||
|
|
|
@ -21,9 +21,8 @@ namespace mozilla {
|
|||
namespace dom {
|
||||
|
||||
LegacySHistory::LegacySHistory(SHistoryParent* aSHistoryParent,
|
||||
CanonicalBrowsingContext* aRootBC,
|
||||
const nsID& aDocShellID)
|
||||
: nsSHistory(aRootBC, aDocShellID), mSHistoryParent(aSHistoryParent) {
|
||||
CanonicalBrowsingContext* aRootBC)
|
||||
: nsSHistory(aRootBC), mSHistoryParent(aSHistoryParent) {
|
||||
mIsRemote = true;
|
||||
aRootBC->SetSessionHistory(this);
|
||||
}
|
||||
|
@ -47,7 +46,7 @@ static void FillInLoadResult(
|
|||
}
|
||||
|
||||
SHistoryParent::SHistoryParent(CanonicalBrowsingContext* aContext)
|
||||
: mHistory(new LegacySHistory(this, aContext, nsID())) {}
|
||||
: mHistory(new LegacySHistory(this, aContext)) {}
|
||||
|
||||
SHistoryParent::~SHistoryParent() { mHistory->mSHistoryParent = nullptr; }
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ class LegacySHistory final : public nsSHistory {
|
|||
|
||||
public:
|
||||
LegacySHistory(SHistoryParent* aSHistoryParent,
|
||||
CanonicalBrowsingContext* aRootBC, const nsID& aDocShellID);
|
||||
CanonicalBrowsingContext* aRootBC);
|
||||
|
||||
NS_IMETHOD CreateEntry(nsISHEntry** aEntry) override;
|
||||
using nsSHistory::ReloadCurrentEntry;
|
||||
|
|
|
@ -150,13 +150,6 @@ interface nsISHistory: nsISupports
|
|||
*/
|
||||
void addEntry(in nsISHEntry aEntry, in boolean aPersist);
|
||||
|
||||
/**
|
||||
* Clear the reference to the toplevel browsing context object that this
|
||||
* SHistory object belongs to.
|
||||
*/
|
||||
[noscript, notxpcom]
|
||||
void ClearRootBrowsingContext();
|
||||
|
||||
/**
|
||||
* Update the index maintained by sessionHistory
|
||||
*/
|
||||
|
|
|
@ -204,12 +204,12 @@ void nsSHistory::EvictContentViewerForEntry(nsISHEntry* aEntry) {
|
|||
}
|
||||
}
|
||||
|
||||
nsSHistory::nsSHistory(BrowsingContext* aRootBC, const nsID& aRootDocShellID)
|
||||
nsSHistory::nsSHistory(BrowsingContext* aRootBC)
|
||||
: mRootBC(aRootBC),
|
||||
mIsRemote(false),
|
||||
mIndex(-1),
|
||||
mRequestedIndex(-1),
|
||||
mRootDocShellID(aRootDocShellID) {
|
||||
mRootDocShellID(aRootBC->GetHistoryID()) {
|
||||
// Add this new SHistory object to the list
|
||||
gSHistoryList.insertBack(this);
|
||||
|
||||
|
@ -805,9 +805,6 @@ nsresult nsSHistory::AddEntry(nsISHEntry* aSHEntry, bool aPersist,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(void)
|
||||
nsSHistory::ClearRootBrowsingContext() { mRootBC = nullptr; }
|
||||
|
||||
/* Get size of the history list */
|
||||
NS_IMETHODIMP
|
||||
nsSHistory::GetCount(int32_t* aResult) {
|
||||
|
|
|
@ -70,7 +70,7 @@ class nsSHistory : public mozilla::LinkedListElement<nsSHistory>,
|
|||
nsTArray<EntriesAndBrowsingContextData>* entriesToUpdate;
|
||||
};
|
||||
|
||||
nsSHistory(mozilla::dom::BrowsingContext* aRootBC, const nsID& aDocShellID);
|
||||
explicit nsSHistory(mozilla::dom::BrowsingContext* aRootBC);
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISHISTORY
|
||||
|
||||
|
|
|
@ -16184,7 +16184,9 @@ nsICookieJarSettings* Document::CookieJarSettings() {
|
|||
inProcessParent->CookieJarSettings()->GetCookieBehavior(),
|
||||
mozilla::net::CookieJarSettings::Cast(
|
||||
inProcessParent->CookieJarSettings())
|
||||
->GetFirstPartyDomain())
|
||||
->GetFirstPartyDomain(),
|
||||
inProcessParent->CookieJarSettings()
|
||||
->GetIsFirstPartyIsolated())
|
||||
: net::CookieJarSettings::Create();
|
||||
|
||||
if (auto* wgc = GetWindowGlobalChild()) {
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
#include "nsRFPService.h"
|
||||
#include "nsStringStream.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsICookieManager.h"
|
||||
#include "nsICookieService.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsStreamUtils.h"
|
||||
|
@ -507,7 +508,7 @@ StorageManager* Navigator::Storage() {
|
|||
}
|
||||
|
||||
bool Navigator::CookieEnabled() {
|
||||
bool cookieEnabled = (StaticPrefs::network_cookie_cookieBehavior() !=
|
||||
bool cookieEnabled = (nsICookieManager::GetCookieBehavior() !=
|
||||
nsICookieService::BEHAVIOR_REJECT);
|
||||
|
||||
// Check whether an exception overrides the global cookie behavior
|
||||
|
@ -522,19 +523,16 @@ bool Navigator::CookieEnabled() {
|
|||
return cookieEnabled;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> contentURI;
|
||||
BasePrincipal::Cast(doc->NodePrincipal())->GetURI(getter_AddRefs(contentURI));
|
||||
|
||||
if (!contentURI) {
|
||||
uint32_t rejectedReason = 0;
|
||||
bool granted = false;
|
||||
nsresult rv = doc->NodePrincipal()->HasFirstpartyStorageAccess(
|
||||
mWindow, &rejectedReason, &granted);
|
||||
if (NS_FAILED(rv)) {
|
||||
// Not a content, so technically can't set cookies, but let's
|
||||
// just return the default value.
|
||||
return cookieEnabled;
|
||||
}
|
||||
|
||||
uint32_t rejectedReason = 0;
|
||||
bool granted = ContentBlocking::ShouldAllowAccessFor(mWindow, contentURI,
|
||||
&rejectedReason);
|
||||
|
||||
ContentBlockingNotifier::OnDecision(
|
||||
mWindow,
|
||||
granted ? ContentBlockingNotifier::BlockingDecision::eAllow
|
||||
|
|
|
@ -2132,8 +2132,7 @@ nsresult nsFrameLoader::MaybeCreateDocShell() {
|
|||
if (mIsTopLevelContent && mOwnerContent->IsXULElement(nsGkAtoms::browser) &&
|
||||
!mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::disablehistory)) {
|
||||
// XXX(nika): Set this up more explicitly?
|
||||
nsresult rv = docShell->InitSessionHistory();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mPendingBrowsingContext->InitSessionHistory();
|
||||
}
|
||||
|
||||
// Apply sandbox flags even if our owner is not an iframe, as this copies
|
||||
|
|
|
@ -7101,13 +7101,13 @@ void nsGlobalWindowInner::FireOnNewGlobalObject() {
|
|||
#endif
|
||||
|
||||
already_AddRefed<Promise> nsGlobalWindowInner::CreateImageBitmap(
|
||||
JSContext* aCx, const ImageBitmapSource& aImage, ErrorResult& aRv) {
|
||||
const ImageBitmapSource& aImage, ErrorResult& aRv) {
|
||||
return ImageBitmap::Create(this, aImage, Nothing(), aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<Promise> nsGlobalWindowInner::CreateImageBitmap(
|
||||
JSContext* aCx, const ImageBitmapSource& aImage, int32_t aSx, int32_t aSy,
|
||||
int32_t aSw, int32_t aSh, ErrorResult& aRv) {
|
||||
const ImageBitmapSource& aImage, int32_t aSx, int32_t aSy, int32_t aSw,
|
||||
int32_t aSh, ErrorResult& aRv) {
|
||||
return ImageBitmap::Create(this, aImage,
|
||||
Some(gfx::IntRect(aSx, aSy, aSw, aSh)), aRv);
|
||||
}
|
||||
|
|
|
@ -873,13 +873,11 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
|||
mozilla::ErrorResult& aError);
|
||||
|
||||
already_AddRefed<mozilla::dom::Promise> CreateImageBitmap(
|
||||
JSContext* aCx, const mozilla::dom::ImageBitmapSource& aImage,
|
||||
mozilla::ErrorResult& aRv);
|
||||
const mozilla::dom::ImageBitmapSource& aImage, mozilla::ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<mozilla::dom::Promise> CreateImageBitmap(
|
||||
JSContext* aCx, const mozilla::dom::ImageBitmapSource& aImage,
|
||||
int32_t aSx, int32_t aSy, int32_t aSw, int32_t aSh,
|
||||
mozilla::ErrorResult& aRv);
|
||||
const mozilla::dom::ImageBitmapSource& aImage, int32_t aSx, int32_t aSy,
|
||||
int32_t aSw, int32_t aSh, mozilla::ErrorResult& aRv);
|
||||
|
||||
// ChromeWindow bits. Do NOT call these unless your window is in
|
||||
// fact chrome.
|
||||
|
|
|
@ -32,13 +32,9 @@
|
|||
# cannot be prefable, and must ensure that they disallow
|
||||
# XPConnect wrapping. Always false for callback interfaces.
|
||||
# Defaults to true for non-callback descriptors.
|
||||
#
|
||||
# The following fields are either a string, an array (defaults to an empty
|
||||
# array) or a dictionary with three possible keys (all, getterOnly and
|
||||
# setterOnly) each having such an array as the value
|
||||
#
|
||||
# * implicitJSContext - attributes and methods specified in the .webidl file
|
||||
# that require a JSContext as the first argument
|
||||
# * implicitJSContext - Llist of names of attributes and methods specified in
|
||||
# the .webidl file that require a JSContext as the first
|
||||
# argument.
|
||||
#
|
||||
# The value for an interface is a dictionary which specifies the
|
||||
# descriptor to use when generating that interface's binding.
|
||||
|
@ -119,10 +115,6 @@ DOMInterfaces = {
|
|||
'concrete': True,
|
||||
},
|
||||
|
||||
'Clipboard' : {
|
||||
'implicitJSContext' : ['write', 'writeText', 'read', 'readText'],
|
||||
},
|
||||
|
||||
'ClonedErrorHolder': {
|
||||
'wrapperCache': False
|
||||
},
|
||||
|
@ -213,10 +205,6 @@ DOMInterfaces = {
|
|||
'implicitJSContext': [ 'filename', 'lineNumber', 'stack' ],
|
||||
},
|
||||
|
||||
'DOMLocalization': {
|
||||
'implicitJSContext': [ 'getAttributes' ],
|
||||
},
|
||||
|
||||
'DOMMatrixReadOnly': {
|
||||
'headerFile': 'mozilla/dom/DOMMatrix.h',
|
||||
},
|
||||
|
@ -234,7 +222,6 @@ DOMInterfaces = {
|
|||
},
|
||||
|
||||
'DOMRequest': {
|
||||
'implicitJSContext': [ 'then' ],
|
||||
'concrete': True,
|
||||
},
|
||||
|
||||
|
@ -480,10 +467,6 @@ DOMInterfaces = {
|
|||
'wrapperCache': False,
|
||||
},
|
||||
|
||||
'MediaKeys' : {
|
||||
'implicitJSContext': [ 'createSession']
|
||||
},
|
||||
|
||||
'MediaStream': {
|
||||
'headerFile': 'DOMMediaStream.h',
|
||||
'nativeType': 'mozilla::DOMMediaStream'
|
||||
|
@ -1011,10 +994,6 @@ DOMInterfaces = {
|
|||
'wrapperCache': False
|
||||
},
|
||||
|
||||
'TCPSocket': {
|
||||
'implicitJSContext': ['send']
|
||||
},
|
||||
|
||||
'TouchList': {
|
||||
'headerFile': 'mozilla/dom/TouchEvent.h',
|
||||
},
|
||||
|
@ -1048,10 +1027,6 @@ DOMInterfaces = {
|
|||
'nativeType': 'mozilla::dom::TextTrackRegion',
|
||||
},
|
||||
|
||||
'WebAuthentication': {
|
||||
'implicitJSContext': 'makeCredential',
|
||||
},
|
||||
|
||||
'WebExtensionContentScript': {
|
||||
'nativeType': 'mozilla::extensions::WebExtensionContentScript',
|
||||
},
|
||||
|
@ -1469,7 +1444,6 @@ DOMInterfaces = {
|
|||
'nativeType': 'nsGlobalWindowInner',
|
||||
'headerFile': 'nsGlobalWindow.h',
|
||||
'implicitJSContext': [
|
||||
'createImageBitmap',
|
||||
'requestIdleCallback'
|
||||
],
|
||||
},
|
||||
|
@ -1491,13 +1465,13 @@ DOMInterfaces = {
|
|||
'WorkerDebuggerGlobalScope': {
|
||||
'headerFile': 'mozilla/dom/WorkerScope.h',
|
||||
'implicitJSContext': [
|
||||
'dump', 'global', 'reportError', 'setConsoleEventHandler',
|
||||
'dump', 'reportError', 'setConsoleEventHandler',
|
||||
],
|
||||
},
|
||||
|
||||
'WorkerGlobalScope': {
|
||||
'headerFile': 'mozilla/dom/WorkerScope.h',
|
||||
'implicitJSContext': [ 'createImageBitmap', 'importScripts' ],
|
||||
'implicitJSContext': [ 'importScripts' ],
|
||||
},
|
||||
|
||||
'Worklet': {
|
||||
|
@ -1506,10 +1480,6 @@ DOMInterfaces = {
|
|||
'implicitJSContext': [ 'addModule' ],
|
||||
},
|
||||
|
||||
'XMLHttpRequest': {
|
||||
'implicitJSContext': [ 'send'],
|
||||
},
|
||||
|
||||
'XMLSerializer': {
|
||||
'nativeType': 'nsDOMSerializer',
|
||||
'wrapperCache': False
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче