diff --git a/accessible/base/MarkupMap.h b/accessible/base/MarkupMap.h index 5ba1a06e6926..7e16f5d28b8a 100644 --- a/accessible/base/MarkupMap.h +++ b/accessible/base/MarkupMap.h @@ -95,6 +95,10 @@ MARKUPMAP(h6, New_HyperText, roles::HEADING) +MARKUPMAP(input, + New_HTMLInput, + 0) + MARKUPMAP(label, New_HTMLLabel, roles::LABEL) diff --git a/accessible/base/nsAccessibilityService.cpp b/accessible/base/nsAccessibilityService.cpp index efccd31627de..59b003abea0b 100644 --- a/accessible/base/nsAccessibilityService.cpp +++ b/accessible/base/nsAccessibilityService.cpp @@ -195,6 +195,19 @@ New_HTMLDefinition(nsIContent* aContent, Accessible* aContext) static Accessible* New_HTMLLabel(nsIContent* aContent, Accessible* aContext) { return new HTMLLabelAccessible(aContent, aContext->Document()); } +static Accessible* New_HTMLInput(nsIContent* aContent, Accessible* aContext) +{ + if (aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type, + nsGkAtoms::checkbox, eIgnoreCase)) { + return new HTMLCheckboxAccessible(aContent, aContext->Document()); + } + if (aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type, + nsGkAtoms::radio, eIgnoreCase)) { + return new HTMLRadioButtonAccessible(aContent, aContext->Document()); + } + return nullptr; +} + static Accessible* New_HTMLOutput(nsIContent* aContent, Accessible* aContext) { return new HTMLOutputAccessible(aContent, aContext->Document()); } diff --git a/accessible/tests/mochitest/events/test_scroll.xul b/accessible/tests/mochitest/events/test_scroll.xul index e33161376328..1b597cdb3f00 100644 --- a/accessible/tests/mochitest/events/test_scroll.xul +++ b/accessible/tests/mochitest/events/test_scroll.xul @@ -64,7 +64,13 @@ this.invoke = function loadTabInBackground_invoke() { - tabBrowser().loadOneTab(aURL, null, "", null, true); + tabBrowser().loadOneTab(aURL, { + referrerURI: null, + charset: "", + postData: null, + inBackground: true, + triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), + }); } this.getID = function loadTabInBackground_getID() diff --git a/accessible/tests/mochitest/relations/test_embeds.xul b/accessible/tests/mochitest/relations/test_embeds.xul index 0cb6d6c6517d..07f8cb56180e 100644 --- a/accessible/tests/mochitest/relations/test_embeds.xul +++ b/accessible/tests/mochitest/relations/test_embeds.xul @@ -56,7 +56,13 @@ { this.invoke = function loadOneTab_invoke() { - tabBrowser().loadOneTab(aURI, null, null, null, false); + tabBrowser().loadOneTab(aURI, { + referrerURI: null, + charset: null, + postData: null, + inBackground: false, + triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), + }); } this.eventSeq = [ diff --git a/accessible/tests/mochitest/states/test_visibility.html b/accessible/tests/mochitest/states/test_visibility.html index 83e9d7c6ef7b..a3e5ffafbabf 100644 --- a/accessible/tests/mochitest/states/test_visibility.html +++ b/accessible/tests/mochitest/states/test_visibility.html @@ -53,7 +53,13 @@ this.invoke = function addTabInvoker_invoke() { - tabBrowser().loadOneTab(aURL, null, "", null, false); + tabBrowser().loadOneTab(aURL, { + referrerURI: null, + charset: "", + postData: null, + inBackground: false, + triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), + }); } this.finalCheck = function addTabInvoker_finalCheck() diff --git a/browser/base/content/browser-social.js b/browser/base/content/browser-social.js index 51bc989d58f4..79ec281ab1e9 100644 --- a/browser/base/content/browser-social.js +++ b/browser/base/content/browser-social.js @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* eslint-env mozilla/browser-window */ -/* global OpenGraphBuilder:false, DynamicResizeWatcher:false */ +/* global OpenGraphBuilder:false, DynamicResizeWatcher:false, Utils:false*/ // the "exported" symbols var SocialUI, @@ -25,6 +25,12 @@ XPCOMUtils.defineLazyGetter(this, "DynamicResizeWatcher", function() { return tmp.DynamicResizeWatcher; }); +XPCOMUtils.defineLazyGetter(this, "Utils", function() { + let tmp = {}; + Cu.import("resource://gre/modules/sessionstore/Utils.jsm", tmp); + return tmp.Utils; +}); + let messageManager = window.messageManager; let openUILinkIn = window.openUILinkIn; @@ -203,7 +209,11 @@ SocialActivationListener = { if (provider.postActivationURL) { // if activated from an open share panel, we load the landing page in // a background tab - gBrowser.loadOneTab(provider.postActivationURL, {inBackground: SocialShare.panel.state == "open"}); + let triggeringPrincipal = Utils.deserializePrincipal(aMessage.data.triggeringPrincipal); + gBrowser.loadOneTab(provider.postActivationURL, { + inBackground: SocialShare.panel.state == "open", + triggeringPrincipal, + }); } }); }, options); diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index de1f21c97065..9efb75df6a7a 100755 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -2291,11 +2291,14 @@ function delayedOpenWindow(chrome, flags, href, postData) { the URI kicked off before becoming the active content area. */ function delayedOpenTab(aUrl, aReferrer, aCharset, aPostData, aAllowThirdPartyFixup) { gBrowser.loadOneTab(aUrl, { - referrerURI: aReferrer, - charset: aCharset, - postData: aPostData, - inBackground: false, - allowThirdPartyFixup: aAllowThirdPartyFixup}); + referrerURI: aReferrer, + charset: aCharset, + postData: aPostData, + inBackground: false, + allowThirdPartyFixup: aAllowThirdPartyFixup, + // Bug 1367168: only use systemPrincipal till we can remove that function + triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), + }); } var gLastOpenDirectory = { @@ -2603,7 +2606,8 @@ function BrowserViewSourceOfDocument(aArgsOrDocument) { relatedToCurrent: true, inBackground: false, preferredRemoteType, - sameProcessAsFrameLoader: args.browser ? args.browser.frameLoader : null + sameProcessAsFrameLoader: args.browser ? args.browser.frameLoader : null, + triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), }); args.viewSourceBrowser = tabBrowser.getBrowserForTab(tab); top.gViewSourceUtils.viewSourceInBrowser(args); @@ -3412,7 +3416,8 @@ var PrintPreviewListener = { return gBrowser.loadOneTab("about:printpreview", { inBackground: true, preferredRemoteType, - sameProcessAsFrameLoader: browser.frameLoader + sameProcessAsFrameLoader: browser.frameLoader, + triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), }); }, getPrintPreviewBrowser() { @@ -3437,7 +3442,8 @@ var PrintPreviewListener = { let browser = this.getSourceBrowser(); this._simplifyPageTab = gBrowser.loadOneTab("about:printpreview", { inBackground: true, - sameProcessAsFrameLoader: browser.frameLoader + sameProcessAsFrameLoader: browser.frameLoader, + triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), }); return this.getSimplifiedSourceBrowser(); }, diff --git a/browser/base/content/content.js b/browser/base/content/content.js index 7b494e53c4e6..d52c0cb8d243 100644 --- a/browser/base/content/content.js +++ b/browser/base/content/content.js @@ -41,6 +41,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "PageMetadata", "resource://gre/modules/PageMetadata.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "PlacesUIUtils", "resource:///modules/PlacesUIUtils.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "Utils", + "resource://gre/modules/sessionstore/Utils.jsm"); XPCOMUtils.defineLazyGetter(this, "PageMenuChild", function() { let tmp = {}; Cu.import("resource://gre/modules/PageMenu.jsm", tmp); @@ -808,7 +810,8 @@ addEventListener("ActivateSocialFeature", function(aEvent) { sendAsyncMessage("Social:Activation", { url: ownerDocument.location.href, origin: ownerDocument.nodePrincipal.origin, - manifest: data + manifest: data, + triggeringPrincipal: Utils.serializePrincipal(ownerDocument.nodePrincipal), }); }, true, true); diff --git a/browser/base/content/nsContextMenu.js b/browser/base/content/nsContextMenu.js index 8fe21b6a6d1f..53bc215617d1 100644 --- a/browser/base/content/nsContextMenu.js +++ b/browser/base/content/nsContextMenu.js @@ -1179,7 +1179,8 @@ nsContextMenu.prototype = { } let tab = tabBrowser.loadOneTab("about:blank", { relatedToCurrent: true, - inBackground: false + inBackground: false, + triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), }); return tabBrowser.getBrowserForTab(tab); } diff --git a/browser/base/content/tab-content.js b/browser/base/content/tab-content.js index a4623b53180f..92861d38eb57 100644 --- a/browser/base/content/tab-content.js +++ b/browser/base/content/tab-content.js @@ -16,6 +16,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "E10SUtils", "resource:///modules/E10SUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils", "resource://gre/modules/BrowserUtils.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "Utils", + "resource://gre/modules/sessionstore/Utils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils", "resource://gre/modules/PrivateBrowsingUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "AboutReader", @@ -657,7 +659,7 @@ let PrerenderContentHandler = { } }, - startPrerenderingDocument(aHref, aReferrer) { + startPrerenderingDocument(aHref, aReferrer, aTriggeringPrincipal) { // XXX: Make this constant a pref if (this._pending.length >= 2) { return; @@ -668,6 +670,7 @@ let PrerenderContentHandler = { href: aHref.spec, referrer: aReferrer ? aReferrer.spec : null, id, + triggeringPrincipal: Utils.serializePrincipal(aTriggeringPrincipal), }); this._pending.push({ @@ -729,9 +732,9 @@ var WebBrowserChrome = { return true; }, - startPrerenderingDocument(aHref, aReferrer) { + startPrerenderingDocument(aHref, aReferrer, aTriggeringPrincipal) { if (PrerenderContentHandler.initialized) { - PrerenderContentHandler.startPrerenderingDocument(aHref, aReferrer); + PrerenderContentHandler.startPrerenderingDocument(aHref, aReferrer, aTriggeringPrincipal); } }, diff --git a/browser/base/content/tabbrowser.xml b/browser/base/content/tabbrowser.xml index ffada3bbb236..0f785f062cb2 100644 --- a/browser/base/content/tabbrowser.xml +++ b/browser/base/content/tabbrowser.xml @@ -5222,6 +5222,7 @@ allowThirdPartyFixup: true, relatedToCurrent: true, isPrerendered: true, + triggeringPrincipal: Utils.deserializePrincipal(data.triggeringPrincipal), }); let partialSHistory = newTab.linkedBrowser.frameLoader.partialSHistory; groupedSHistory.addPrerenderingPartialSHistory(partialSHistory, data.id); diff --git a/browser/base/content/test/performance/browser.ini b/browser/base/content/test/performance/browser.ini index acb6c701e2d4..ae9cce17f73b 100644 --- a/browser/base/content/test/performance/browser.ini +++ b/browser/base/content/test/performance/browser.ini @@ -1,6 +1,7 @@ [DEFAULT] support-files = head.js +[browser_startup.js] [browser_tabclose_reflows.js] [browser_tabopen_reflows.js] [browser_toolbariconcolor_restyles.js] diff --git a/browser/base/content/test/performance/browser_startup.js b/browser/base/content/test/performance/browser_startup.js new file mode 100644 index 000000000000..bf14c1720de9 --- /dev/null +++ b/browser/base/content/test/performance/browser_startup.js @@ -0,0 +1,135 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/* This test records at which phase of startup the JS components and modules + * are first loaded. + * If you made changes that cause this test to fail, it's likely because you + * are loading more JS code during startup. + * Most code has no reason to run off of the app-startup notification + * (this is very early, before we have selected the user profile, so + * preferences aren't accessible yet). + * If your code isn't strictly required to show the first browser window, + * it shouldn't be loaded before we are done with first paint. + * Finally, if your code isn't really needed during startup, it should not be + * loaded before we have started handling user events. + */ + +"use strict"; + +const startupPhases = { + // For app-startup, we have a whitelist of acceptable JS files. + // Anything loaded during app-startup must have a compelling reason + // to run before we have even selected the user profile. + // Consider loading your code after first paint instead, + // eg. from nsBrowserGlue.js' _onFirstWindowLoaded method). + "before profile selection": {whitelist: { + components: new Set([ + "nsBrowserGlue.js", + "MainProcessSingleton.js", + + // Bugs to fix: The following components shouldn't be initialized that early. + "WebContentConverter.js", + "nsSessionStartup.js", + "PushComponents.js", + ]), + modules: new Set([ + "resource://gre/modules/AppConstants.jsm", + "resource://gre/modules/XPCOMUtils.jsm", + "resource://gre/modules/Services.jsm", + + // Bugs to fix: Probably loaded too early, needs investigation. + "resource://gre/modules/Log.jsm", + "resource://gre/modules/AsyncPrefs.jsm", + "resource://gre/modules/RemotePageManager.jsm", + "resource://gre/modules/TelemetryStopwatch.jsm", + "resource://gre/modules/PrivateBrowsingUtils.jsm", + "resource://gre/modules/Promise.jsm" + ]) + }}, + + // For the following phases of startup we have only a black list for now + + // We are at this phase after creating the first browser window (ie. after final-ui-startup). + "before opening first browser window": {blacklist: { + components: new Set([ + "nsSearchService.js", + ]) + }}, + + // We reach this phase right after showing the first browser window. + // This means that anything already loaded at this point has been loaded + // before first paint and delayed it. + "before first paint": {}, + + // We are at this phase once we are ready to handle user events. + // Anything loaded at this phase or before gets in the way of the user + // interacting with the first browser window. + "before handling user events": {}, +} + +function test() { + if (!AppConstants.NIGHTLY_BUILD && !AppConstants.DEBUG) { + ok(!("@mozilla.org/test/startuprecorder;1" in Cc), + "the startup recorder component shouldn't exist in this non-nightly non-debug build."); + return; + } + + let data = Cc["@mozilla.org/test/startuprecorder;1"].getService().wrappedJSObject.data; + // Keep only the file name for components, as the path is an absolute file + // URL rather than a resource:// URL like for modules. + for (let phase in data) { + data[phase].components = + data[phase].components.map(f => f.replace(/.*\//, "")) + .filter(c => c != "startupRecorder.js"); + } + + // This block only adds debug output to help find the next bugs to file, + // it doesn't contribute to the actual test. + SimpleTest.requestCompleteLog(); + let previous; + for (let phase in data) { + for (let scriptType in data[phase]) { + for (let f of data[phase][scriptType]) { + // phases are ordered, so if a script wasn't loaded yet at the immediate + // previous phase, it wasn't loaded during any of the previous phases + // either, and is new in the current phase. + if (!previous || !data[previous][scriptType].includes(f)) + info(`${scriptType} loaded ${phase}: ${f}`); + } + } + previous = phase; + } + + for (let phase in startupPhases) { + let loadedList = data[phase]; + let whitelist = startupPhases[phase].whitelist || null; + if (whitelist) { + for (let scriptType in loadedList) { + loadedList[scriptType] = loadedList[scriptType].filter(c => { + if (!whitelist[scriptType].has(c)) + return true; + whitelist[scriptType].delete(c); + return false; + }); + is(loadedList[scriptType].length, 0, + `should have no unexpected ${scriptType} loaded ${phase}`); + for (let script of loadedList[scriptType]) { + ok(false, `unexpected ${scriptType}: ${script}`); + } + is(whitelist[scriptType].size, 0, + `all ${scriptType} whitelist entries should have been used`); + for (let script of whitelist[scriptType]) { + ok(false, `unused ${scriptType} whitelist entry: ${script}`); + } + } + } + let blacklist = startupPhases[phase].blacklist || null; + if (blacklist) { + for (let scriptType in blacklist) { + for (let file of blacklist[scriptType]) { + ok(!loadedList[scriptType].includes(file), `${file} is not allowed ${phase}`); + } + } + } + } +} diff --git a/browser/base/content/usercontext-briefcase.svg b/browser/base/content/usercontext-briefcase.svg new file mode 100644 index 000000000000..d38a745f9e7a --- /dev/null +++ b/browser/base/content/usercontext-briefcase.svg @@ -0,0 +1,9 @@ + + + + + diff --git a/browser/base/content/usercontext-cart.svg b/browser/base/content/usercontext-cart.svg new file mode 100644 index 000000000000..aedff937e890 --- /dev/null +++ b/browser/base/content/usercontext-cart.svg @@ -0,0 +1,9 @@ + + + + + diff --git a/browser/base/content/usercontext-circle.svg b/browser/base/content/usercontext-circle.svg new file mode 100644 index 000000000000..24bd6dc6014b --- /dev/null +++ b/browser/base/content/usercontext-circle.svg @@ -0,0 +1,8 @@ + + + + + diff --git a/browser/base/content/usercontext-dollar.svg b/browser/base/content/usercontext-dollar.svg new file mode 100644 index 000000000000..c96faa8d51ae --- /dev/null +++ b/browser/base/content/usercontext-dollar.svg @@ -0,0 +1,8 @@ + + + + + diff --git a/browser/base/content/usercontext-fingerprint.svg b/browser/base/content/usercontext-fingerprint.svg new file mode 100644 index 000000000000..58dd78cd097a --- /dev/null +++ b/browser/base/content/usercontext-fingerprint.svg @@ -0,0 +1,8 @@ + + + + + diff --git a/browser/base/content/usercontext.svg b/browser/base/content/usercontext.svg deleted file mode 100644 index 705f80bfdd15..000000000000 --- a/browser/base/content/usercontext.svg +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - diff --git a/browser/base/jar.mn b/browser/base/jar.mn index c7e6ae67a687..c6b43595f249 100644 --- a/browser/base/jar.mn +++ b/browser/base/jar.mn @@ -138,7 +138,11 @@ browser.jar: content/browser/tabbrowser.xml (content/tabbrowser.xml) * content/browser/urlbarBindings.xml (content/urlbarBindings.xml) content/browser/utilityOverlay.js (content/utilityOverlay.js) - content/browser/usercontext.svg (content/usercontext.svg) + content/browser/usercontext-briefcase.svg (content/usercontext-briefcase.svg) + content/browser/usercontext-cart.svg (content/usercontext-cart.svg) + content/browser/usercontext-circle.svg (content/usercontext-circle.svg) + content/browser/usercontext-dollar.svg (content/usercontext-dollar.svg) + content/browser/usercontext-fingerprint.svg (content/usercontext-fingerprint.svg) content/browser/web-panels.js (content/web-panels.js) * content/browser/web-panels.xul (content/web-panels.xul) content/browser/webext-panels.js (content/webext-panels.js) diff --git a/browser/components/contextualidentity/content/usercontext.css b/browser/components/contextualidentity/content/usercontext.css index 4ef99ad5c6ff..e1e55fd2c0ec 100644 --- a/browser/components/contextualidentity/content/usercontext.css +++ b/browser/components/contextualidentity/content/usercontext.css @@ -39,23 +39,23 @@ } [data-identity-icon="fingerprint"] { - --identity-icon: url("chrome://browser/content/usercontext.svg#fingerprint"); + --identity-icon: url("chrome://browser/content/usercontext-fingerprint.svg"); } [data-identity-icon="briefcase"] { - --identity-icon: url("chrome://browser/content/usercontext.svg#briefcase"); + --identity-icon: url("chrome://browser/content/usercontext-briefcase.svg"); } [data-identity-icon="dollar"] { - --identity-icon: url("chrome://browser/content/usercontext.svg#dollar"); + --identity-icon: url("chrome://browser/content/usercontext-dollar.svg"); } [data-identity-icon="cart"] { - --identity-icon: url("chrome://browser/content/usercontext.svg#cart"); + --identity-icon: url("chrome://browser/content/usercontext-cart.svg"); } [data-identity-icon="circle"] { - --identity-icon: url("chrome://browser/content/usercontext.svg#circle"); + --identity-icon: url("chrome://browser/content/usercontext-circle.svg"); } #userContext-indicator { @@ -83,7 +83,7 @@ .subviewbutton[usercontextid] > .toolbarbutton-icon, #userContext-indicator { background-image: var(--identity-icon); - filter: url(chrome://global/skin/filters.svg#fill); + -moz-context-properties: fill; fill: var(--identity-icon-color); background-size: contain; background-repeat: no-repeat; diff --git a/browser/components/customizableui/CustomizeMode.jsm b/browser/components/customizableui/CustomizeMode.jsm index e22e2f16e2f4..0d85ab2bf412 100644 --- a/browser/components/customizableui/CustomizeMode.jsm +++ b/browser/components/customizableui/CustomizeMode.jsm @@ -218,10 +218,12 @@ CustomizeMode.prototype = { } if (!gTab) { - this.setTab(this.browser.loadOneTab("about:blank", - { inBackground: false, - forceNotRemote: true, - skipAnimation: true })); + this.setTab(this.browser.loadOneTab("about:blank", { + inBackground: false, + forceNotRemote: true, + skipAnimation: true, + triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), + })); return; } if (!gTab.selected) { diff --git a/browser/components/moz.build b/browser/components/moz.build index 9f816dd38b08..81757f5468f9 100644 --- a/browser/components/moz.build +++ b/browser/components/moz.build @@ -66,6 +66,8 @@ EXTRA_PP_COMPONENTS += [ EXTRA_COMPONENTS += [ 'nsBrowserContentHandler.js', 'nsBrowserGlue.js', + 'tests/startupRecorder.js', + 'tests/testComponents.manifest', ] EXTRA_JS_MODULES += [ diff --git a/browser/components/tests/startupRecorder.js b/browser/components/tests/startupRecorder.js new file mode 100644 index 000000000000..ef07417451c1 --- /dev/null +++ b/browser/components/tests/startupRecorder.js @@ -0,0 +1,71 @@ +/* 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/. */ + +const {classes: Cc, utils: Cu, interfaces: Ci} = Components; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource://gre/modules/Services.jsm"); + +/** + * The startupRecorder component observes notifications at various stages of + * startup and records the set of JS components and modules that were already + * loaded at each of these points. + * The records are meant to be used by startup tests in + * browser/base/content/test/performance + * This component only exists in nightly and debug builds, it doesn't ship in + * our release builds. + */ +function startupRecorder() { + this.wrappedJSObject = this; + this.loader = Cc["@mozilla.org/moz/jsloader;1"].getService(Ci.xpcIJSModuleLoader); + this.data = {}; +} +startupRecorder.prototype = { + classID: Components.ID("{11c095b2-e42e-4bdf-9dd0-aed87595f6a4}"), + + QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]), + + record(name) { + this.data[name] = { + components: this.loader.loadedComponents(), + modules: this.loader.loadedModules() + }; + }, + + observe(subject, topic, data) { + + if (topic == "app-startup") { + // We can't ensure our observer will be called first or last, so the list of + // topics we observe here should avoid the topics used to trigger things + // during startup (eg. the topics observed by nsBrowserGlue.js). + let topics = [ + "profile-do-change", // This catches stuff loaded during app-startup + "toplevel-window-ready", // Catches stuff from final-ui-startup + "widget-first-paint", + "sessionstore-windows-restored", + ]; + for (let t of topics) + Services.obs.addObserver(this, t); + return; + } + + Services.obs.removeObserver(this, topic); + + if (topic == "sessionstore-windows-restored") { + // We use idleDispatch here to record the set of loaded scripts after we + // are fully done with startup and ready to react to user events. + Services.tm.mainThread.idleDispatch( + this.record.bind(this, "before handling user events")); + } else { + const topicsToNames = { + "profile-do-change": "before profile selection", + "toplevel-window-ready": "before opening first browser window", + "widget-first-paint": "before first paint", + }; + this.record(topicsToNames[topic]); + } + } +}; + +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([startupRecorder]); diff --git a/browser/components/tests/testComponents.manifest b/browser/components/tests/testComponents.manifest new file mode 100644 index 000000000000..efd8bc959686 --- /dev/null +++ b/browser/components/tests/testComponents.manifest @@ -0,0 +1,5 @@ +# This component restricts its registration for the app-startup category +# to the browser app so it doesn't get loaded in xpcshell. +component {11c095b2-e42e-4bdf-9dd0-aed87595f6a4} startupRecorder.js +contract @mozilla.org/test/startuprecorder;1 {11c095b2-e42e-4bdf-9dd0-aed87595f6a4} +category app-startup startupRecorder service,@mozilla.org/test/startuprecorder;1 application={ec8030f7-c20a-464f-9b0e-13a3a9e97384} diff --git a/browser/extensions/webcompat-reporter/content/WebCompatReporter.jsm b/browser/extensions/webcompat-reporter/content/WebCompatReporter.jsm index 02f45e136354..054d28d72a18 100644 --- a/browser/extensions/webcompat-reporter/content/WebCompatReporter.jsm +++ b/browser/extensions/webcompat-reporter/content/WebCompatReporter.jsm @@ -121,7 +121,7 @@ let WebCompatReporter = { let tab = gBrowser.loadOneTab( `${WebCompatReporter.endpoint}?url=${encodeURIComponent(tabData.url)}&src=desktop-reporter`, - {inBackground: false}); + {inBackground: false, triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()}); // If we successfully got a screenshot blob, add a listener to know when // the new tab is loaded before sending it over. diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index 48f0abddf9ed..528226de41c1 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -568,6 +568,11 @@ @RESPATH@/components/TestInterfaceJSMaplike.js #endif +#if defined(MOZ_DEBUG) || defined(NIGHTLY_BUILD) +@RESPATH@/browser/components/testComponents.manifest +@RESPATH@/browser/components/startupRecorder.js +#endif + ; [Extensions] @RESPATH@/components/extensions-toolkit.manifest @RESPATH@/browser/components/extensions-browser.manifest diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 20a9bf6cb780..9327f37dab40 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -11018,6 +11018,28 @@ nsDocShell::DoURILoad(nsIURI* aURI, new LoadInfo(loadingPrincipal, aTriggeringPrincipal, loadingNode, securityFlags, aContentPolicyType); + if (aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT) { + enum TopLevelDataState { + DATA_NAVIGATED = 0, + DATA_TYPED = 1, + NO_DATA = 2, + }; + bool isDataURI = (NS_SUCCEEDED(aURI->SchemeIs("data", &isDataURI)) && isDataURI); + if (isDataURI) { + // In all cases where the toplevel document is navigated to a data: URI + // the triggeringPrincipal is a CodeBasePrincipal. In all other cases + // e.g. typing a data: URL into the URL-Bar or also clicking a bookmark + // uses a SystemPrincipal as the triggeringPrincipal. + if (aTriggeringPrincipal->GetIsCodebasePrincipal()) { + Telemetry::Accumulate(Telemetry::DOCUMENT_DATA_URI_LOADS, DATA_NAVIGATED); + } else { + Telemetry::Accumulate(Telemetry::DOCUMENT_DATA_URI_LOADS, DATA_TYPED); + } + } else { + Telemetry::Accumulate(Telemetry::DOCUMENT_DATA_URI_LOADS, NO_DATA); + } + } + if (aPrincipalToInherit) { loadInfo->SetPrincipalToInherit(aPrincipalToInherit); } diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index 9002ac268d88..55ec73df344d 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -4009,6 +4009,11 @@ Element::RegisteredIntersectionObservers() return &slots->mRegisteredIntersectionObservers; } +enum nsPreviousIntersectionThreshold { + eUninitialized = -2, + eNonIntersecting = -1 +}; + void Element::RegisterIntersectionObserver(DOMIntersectionObserver* aObserver) { @@ -4017,7 +4022,13 @@ Element::RegisterIntersectionObserver(DOMIntersectionObserver* aObserver) if (observers->Contains(aObserver)) { return; } - RegisteredIntersectionObservers()->Put(aObserver, -1); + + // Value can be: + // -2: Makes sure next calculated threshold always differs, leading to a + // notification task being scheduled. + // -1: Non-intersecting. + // >= 0: Intersecting, valid index of aObserver->mThresholds. + RegisteredIntersectionObservers()->Put(aObserver, eUninitialized); } void diff --git a/dom/base/nsContentSink.h b/dom/base/nsContentSink.h index ae5c5e92eab7..b35cc61a9090 100644 --- a/dom/base/nsContentSink.h +++ b/dom/base/nsContentSink.h @@ -73,9 +73,6 @@ extern mozilla::LazyLogModule gContentSinkLogModuleInfo; //---------------------------------------------------------------------- -// 1/2 second fudge factor for window creation -#define NS_DELAY_FOR_WINDOW_CREATION 500000 - class nsContentSink : public nsICSSLoaderObserver, public nsSupportsWeakReference, public nsStubDocumentObserver, diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 3cf56a224a50..5117805aa518 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -3145,7 +3145,7 @@ nsIDocument::PrerenderHref(nsIURI* aHref) tabChild->GetWebBrowserChrome(getter_AddRefs(wbc3)); NS_ENSURE_TRUE(wbc3, false); - rv = wbc3->StartPrerenderingDocument(aHref, referrer); + rv = wbc3->StartPrerenderingDocument(aHref, referrer, NodePrincipal()); NS_ENSURE_SUCCESS(rv, false); return true; @@ -12338,7 +12338,8 @@ nsIDocument::DocAddSizeOfExcludingThis(nsWindowSizes* aWindowSizes) const &aWindowSizes->mLayoutPresShellSize, &aWindowSizes->mLayoutStyleSetsSize, &aWindowSizes->mLayoutTextRunsSize, - &aWindowSizes->mLayoutPresContextSize); + &aWindowSizes->mLayoutPresContextSize, + &aWindowSizes->mLayoutFramePropertiesSize); } aWindowSizes->mPropertyTablesSize += diff --git a/dom/base/nsFrameLoader.cpp b/dom/base/nsFrameLoader.cpp index 333f55b3cc74..fe1fbcbab757 100644 --- a/dom/base/nsFrameLoader.cpp +++ b/dom/base/nsFrameLoader.cpp @@ -178,7 +178,6 @@ nsFrameLoader::nsFrameLoader(Element* aOwner, nsPIDOMWindowOuter* aOpener, bool , mClipSubdocument(true) , mClampScrollPosition(true) , mObservingOwnerContent(false) - , mVisible(true) { mRemoteFrame = ShouldUseRemoteProcess(); MOZ_ASSERT(!mRemoteFrame || !aOpener, @@ -3495,29 +3494,6 @@ nsFrameLoader::Print(uint64_t aOuterWindowID, return NS_OK; } -/* [infallible] */ NS_IMETHODIMP -nsFrameLoader::SetVisible(bool aVisible) -{ - if (mVisible == aVisible) { - return NS_OK; - } - - mVisible = aVisible; - nsCOMPtr os = services::GetObserverService(); - if (os) { - os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, this), - "frameloader-visible-changed", nullptr); - } - return NS_OK; -} - -/* [infallible] */ NS_IMETHODIMP -nsFrameLoader::GetVisible(bool* aVisible) -{ - *aVisible = mVisible; - return NS_OK; -} - NS_IMETHODIMP nsFrameLoader::GetTabParent(nsITabParent** aTabParent) { diff --git a/dom/base/nsFrameLoader.h b/dom/base/nsFrameLoader.h index 26177e7a9f3f..fc3dcd0df582 100644 --- a/dom/base/nsFrameLoader.h +++ b/dom/base/nsFrameLoader.h @@ -375,10 +375,6 @@ private: bool mClampScrollPosition : 1; bool mObservingOwnerContent : 1; - // Backs nsIFrameLoader::{Get,Set}Visible. Visibility state here relates to - // whether this frameloader's