mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 02:14:43 +00:00
Merge mozilla-central to mozilla-inbound
This commit is contained in:
commit
41ba400533
1
.hgtags
1
.hgtags
@ -131,3 +131,4 @@ d98f20c25feeac4dd7ebbd1c022957df1ef58af4 FIREFOX_AURORA_49_BASE
|
||||
fc69febcbf6c0dcc4b3dfc7a346d8d348798a65f FIREFOX_AURORA_51_BASE
|
||||
1196bf3032e1bce1fb07a01fd9082a767426c5fb FIREFOX_AURORA_52_BASE
|
||||
f80dc9fc34680105b714a49b4704bb843f5f7004 FIREFOX_AURORA_53_BASE
|
||||
6583496f169cd8a13c531ed16e98e8bf313eda8e FIREFOX_AURORA_54_BASE
|
||||
|
2
CLOBBER
2
CLOBBER
@ -22,4 +22,4 @@
|
||||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
Bug 1343432 - jemalloc update needs a clobber
|
||||
Merge day clobber
|
@ -29,7 +29,6 @@
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
#include "nsXPCOMStrings.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsIPersistentProperties2.h"
|
||||
|
||||
|
@ -169,6 +169,8 @@ pref("extensions.dss.switchPending", false); // Non-dynamic switch pending af
|
||||
pref("extensions.{972ce4c6-7e08-4474-a285-3208198ce6fd}.name", "chrome://browser/locale/browser.properties");
|
||||
pref("extensions.{972ce4c6-7e08-4474-a285-3208198ce6fd}.description", "chrome://browser/locale/browser.properties");
|
||||
|
||||
pref("extensions.webextensions.themes.icons.buttons", "back,forward,reload,stop,bookmark_star,bookmark_menu,downloads,home,app_menu,cut,copy,paste,new_window,new_private_window,save_page,print,history,full_screen,find,options,addons,developer,synced_tabs,open_file,sidebars,share_page,subscribe,text_encoding,email_link,forget,pocket");
|
||||
|
||||
pref("lightweightThemes.update.enabled", true);
|
||||
pref("lightweightThemes.getMoreURL", "https://addons.mozilla.org/%LOCALE%/firefox/themes");
|
||||
pref("lightweightThemes.recommendedThemes", "[{\"id\":\"recommended-1\",\"homepageURL\":\"https://addons.mozilla.org/firefox/addon/a-web-browser-renaissance/\",\"headerURL\":\"resource:///chrome/browser/content/browser/defaultthemes/1.header.jpg\",\"footerURL\":\"resource:///chrome/browser/content/browser/defaultthemes/1.footer.jpg\",\"textcolor\":\"#000000\",\"accentcolor\":\"#f2d9b1\",\"iconURL\":\"resource:///chrome/browser/content/browser/defaultthemes/1.icon.jpg\",\"previewURL\":\"resource:///chrome/browser/content/browser/defaultthemes/1.preview.jpg\",\"author\":\"Sean.Martell\",\"version\":\"0\"},{\"id\":\"recommended-2\",\"homepageURL\":\"https://addons.mozilla.org/firefox/addon/space-fantasy/\",\"headerURL\":\"resource:///chrome/browser/content/browser/defaultthemes/2.header.jpg\",\"footerURL\":\"resource:///chrome/browser/content/browser/defaultthemes/2.footer.jpg\",\"textcolor\":\"#ffffff\",\"accentcolor\":\"#d9d9d9\",\"iconURL\":\"resource:///chrome/browser/content/browser/defaultthemes/2.icon.jpg\",\"previewURL\":\"resource:///chrome/browser/content/browser/defaultthemes/2.preview.jpg\",\"author\":\"fx5800p\",\"version\":\"1.0\"},{\"id\":\"recommended-4\",\"homepageURL\":\"https://addons.mozilla.org/firefox/addon/pastel-gradient/\",\"headerURL\":\"resource:///chrome/browser/content/browser/defaultthemes/4.header.png\",\"footerURL\":\"resource:///chrome/browser/content/browser/defaultthemes/4.footer.png\",\"textcolor\":\"#000000\",\"accentcolor\":\"#000000\",\"iconURL\":\"resource:///chrome/browser/content/browser/defaultthemes/4.icon.png\",\"previewURL\":\"resource:///chrome/browser/content/browser/defaultthemes/4.preview.png\",\"author\":\"darrinhenein\",\"version\":\"1.0\"}]");
|
||||
@ -1247,19 +1249,15 @@ pref("dom.debug.propagate_gesture_events_through_content", false);
|
||||
|
||||
// All the Geolocation preferences are here.
|
||||
//
|
||||
// The request URL of the GeoLocation backend.
|
||||
#ifdef RELEASE_OR_BETA
|
||||
|
||||
// Geolocation preferences for the RELEASE channel.
|
||||
// Some of these prefs are specified even though they are redundant; they are
|
||||
// here for clarity and end-user experiments.
|
||||
#ifdef RELEASE
|
||||
pref("geo.wifi.uri", "https://www.googleapis.com/geolocation/v1/geolocate?key=%GOOGLE_API_KEY%");
|
||||
#else
|
||||
pref("geo.wifi.uri", "https://location.services.mozilla.com/v1/geolocate?key=%MOZILLA_API_KEY%");
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#ifdef RELEASE_OR_BETA
|
||||
pref("geo.provider.use_corelocation", false);
|
||||
#else
|
||||
pref("geo.provider.use_corelocation", true);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
@ -1267,13 +1265,28 @@ pref("geo.provider.ms-windows-location", false);
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
#ifdef MOZ_GPSD
|
||||
#ifdef RELEASE_OR_BETA
|
||||
pref("geo.provider.use_gpsd", false);
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
// Geolocation preferences for Nightly/Aurora/Beta.
|
||||
pref("geo.wifi.uri", "https://location.services.mozilla.com/v1/geolocate?key=%MOZILLA_API_KEY%");
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
pref("geo.provider.use_corelocation", true);
|
||||
#endif
|
||||
|
||||
// The native Windows location provider is only enabled in Nightly and likely to
|
||||
// be unstable. Set to false if things are really broken.
|
||||
#if defined(XP_WIN) && defined(NIGHTLY_BUILD)
|
||||
pref("geo.provider.ms-windows-location", true);
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_WIDGET_GTK) && defined(MOZ_GPSD)
|
||||
pref("geo.provider.use_gpsd", true);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// We keep allowing non-HTTPS geo requests on all the release
|
||||
|
@ -3,6 +3,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
if (AppConstants.MOZ_SERVICES_CLOUDSYNC) {
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "CloudSync",
|
||||
@ -40,8 +41,6 @@ var gSyncUI = {
|
||||
_syncAnimationTimer: 0,
|
||||
|
||||
init() {
|
||||
Cu.import("resource://services-common/stringbundle.js");
|
||||
|
||||
// Proceed to set up the UI if Sync has already started up.
|
||||
// Otherwise we'll do it when Sync is firing up.
|
||||
if (this.weaveService.ready) {
|
||||
@ -224,8 +223,9 @@ var gSyncUI = {
|
||||
},
|
||||
|
||||
_getAppName() {
|
||||
let brand = new StringBundle("chrome://branding/locale/brand.properties");
|
||||
return brand.get("brandShortName");
|
||||
let brand = Services.strings.createBundle(
|
||||
"chrome://branding/locale/brand.properties");
|
||||
return brand.GetStringFromName("brandShortName");
|
||||
},
|
||||
|
||||
// Commands
|
||||
@ -475,9 +475,8 @@ var gSyncUI = {
|
||||
XPCOMUtils.defineLazyGetter(gSyncUI, "_stringBundle", function() {
|
||||
// XXXzpao these strings should probably be moved from /services to /browser... (bug 583381)
|
||||
// but for now just make it work
|
||||
return Cc["@mozilla.org/intl/stringbundle;1"].
|
||||
getService(Ci.nsIStringBundleService).
|
||||
createBundle("chrome://weave/locale/services/sync.properties");
|
||||
return Services.strings.createBundle(
|
||||
"chrome://weave/locale/services/sync.properties");
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(gSyncUI, "log", function() {
|
||||
|
@ -1264,3 +1264,5 @@ toolbarpaletteitem[place="palette"][hidden] {
|
||||
opacity: 0.65;
|
||||
-moz-window-shadow: none;
|
||||
}
|
||||
|
||||
%include theme-vars.inc.css
|
||||
|
@ -829,6 +829,8 @@ function gKeywordURIFixup({ target: browser, data: fixupInfo }) {
|
||||
return;
|
||||
}
|
||||
|
||||
let contentPrincipal = browser.contentPrincipal;
|
||||
|
||||
// At this point we're still only just about to load this URI.
|
||||
// When the async DNS lookup comes back, we may be in any of these states:
|
||||
// 1) still on the previous URI, waiting for the preferredURI (keyword
|
||||
@ -931,7 +933,8 @@ function gKeywordURIFixup({ target: browser, data: fixupInfo }) {
|
||||
};
|
||||
|
||||
try {
|
||||
gDNSService.asyncResolve(hostName, 0, onLookupComplete, Services.tm.mainThread);
|
||||
gDNSService.asyncResolve(hostName, 0, onLookupComplete, Services.tm.mainThread,
|
||||
contentPrincipal.originAttributes);
|
||||
} catch (ex) {
|
||||
// Do nothing if the URL is invalid (we don't want to show a notification in that case).
|
||||
if (ex.result != Cr.NS_ERROR_UNKNOWN_HOST) {
|
||||
@ -6721,6 +6724,12 @@ var gIdentityHandler = {
|
||||
*/
|
||||
_state: 0,
|
||||
|
||||
/**
|
||||
* This flag gets set if the identity popup was opened by a keypress,
|
||||
* to be able to focus it on the popupshown event.
|
||||
*/
|
||||
_popupTriggeredByKeyboard: false,
|
||||
|
||||
get _isBroken() {
|
||||
return this._state & Ci.nsIWebProgressListener.STATE_IS_BROKEN;
|
||||
},
|
||||
@ -6855,6 +6864,10 @@ var gIdentityHandler = {
|
||||
delete this._permissionReloadHint;
|
||||
return this._permissionReloadHint = document.getElementById("identity-popup-permission-reload-hint");
|
||||
},
|
||||
get _popupExpander() {
|
||||
delete this._popupExpander;
|
||||
return this._popupExpander = document.getElementById("identity-popup-security-expander");
|
||||
},
|
||||
get _permissionAnchors() {
|
||||
delete this._permissionAnchors;
|
||||
let permissionAnchors = {};
|
||||
@ -6876,10 +6889,18 @@ var gIdentityHandler = {
|
||||
|
||||
toggleSubView(name, anchor) {
|
||||
let view = this._identityPopupMultiView;
|
||||
let id = `identity-popup-${name}View`;
|
||||
let subView = document.getElementById(id);
|
||||
|
||||
// Listen for the subview showing or hiding to change
|
||||
// the tooltip on the expander button.
|
||||
subView.addEventListener("ViewShowing", this);
|
||||
subView.addEventListener("ViewHiding", this);
|
||||
|
||||
if (view.showingSubView) {
|
||||
view.showMainView();
|
||||
} else {
|
||||
view.showSubView(`identity-popup-${name}View`, anchor);
|
||||
view.showSubView(id, anchor);
|
||||
}
|
||||
|
||||
// If an element is focused that's not the anchor, clear the focus.
|
||||
@ -7188,6 +7209,9 @@ var gIdentityHandler = {
|
||||
this._identityPopupInsecureLoginFormsLearnMore
|
||||
.setAttribute("href", baseURL + "insecure-password");
|
||||
|
||||
// The expander switches its tooltip when toggled, change it to the default.
|
||||
this._popupExpander.tooltipText = gNavigatorBundle.getString("identity.showDetails.tooltip");
|
||||
|
||||
// Determine connection security information.
|
||||
let connection = "not-secure";
|
||||
if (this._isSecureInternalUI) {
|
||||
@ -7361,6 +7385,8 @@ var gIdentityHandler = {
|
||||
return;
|
||||
}
|
||||
|
||||
this._popupTriggeredByKeyboard = event.type == "keypress";
|
||||
|
||||
// Make sure that the display:none style we set in xul is removed now that
|
||||
// the popup is actually needed
|
||||
this._identityPopup.hidden = false;
|
||||
@ -7380,10 +7406,12 @@ var gIdentityHandler = {
|
||||
|
||||
onPopupShown(event) {
|
||||
if (event.target == this._identityPopup) {
|
||||
// Move focus to the next available element in the identity popup.
|
||||
// This is required by role=alertdialog and fixes an issue where
|
||||
// an already open panel would steal focus from the identity popup.
|
||||
document.commandDispatcher.advanceFocusIntoSubtree(this._identityPopup);
|
||||
if (this._popupTriggeredByKeyboard) {
|
||||
// Move focus to the next available element in the identity popup.
|
||||
// This is required by role=alertdialog and fixes an issue where
|
||||
// an already open panel would steal focus from the identity popup.
|
||||
document.commandDispatcher.advanceFocusIntoSubtree(this._identityPopup);
|
||||
}
|
||||
|
||||
window.addEventListener("focus", this, true);
|
||||
}
|
||||
@ -7397,6 +7425,16 @@ var gIdentityHandler = {
|
||||
},
|
||||
|
||||
handleEvent(event) {
|
||||
// If the subview is shown or hidden, change the tooltip on the expander button.
|
||||
if (event.type == "ViewShowing") {
|
||||
this._popupExpander.tooltipText = gNavigatorBundle.getString("identity.hideDetails.tooltip");
|
||||
return;
|
||||
}
|
||||
if (event.type == "ViewHiding") {
|
||||
this._popupExpander.tooltipText = gNavigatorBundle.getString("identity.showDetails.tooltip");
|
||||
return;
|
||||
}
|
||||
|
||||
let elem = document.activeElement;
|
||||
let position = elem.compareDocumentPosition(this._identityPopup);
|
||||
|
||||
|
@ -97,10 +97,15 @@ browser[pending] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
browser[pendingtabchild],
|
||||
browser[pendingpaint] {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
tabbrowser[pendingtabchild] {
|
||||
background-color: #ffffff !important;
|
||||
}
|
||||
|
||||
tabbrowser[pendingpaint] {
|
||||
background-image: url(chrome://browser/skin/tabbrowser/pendingpaint.png);
|
||||
background-repeat: no-repeat;
|
||||
|
@ -3723,6 +3723,7 @@
|
||||
|
||||
visibleTab: this.selectedTab, // Tab that's on screen.
|
||||
spinnerTab: null, // Tab showing a spinner.
|
||||
blankTab: null, // Tab showing blank.
|
||||
originalTab: this.selectedTab, // Tab that we started on.
|
||||
|
||||
tabbrowser: this, // Reference to gBrowser.
|
||||
@ -3732,6 +3733,12 @@
|
||||
// Map from tabs to STATE_* (below).
|
||||
tabState: new Map(),
|
||||
|
||||
// Holds a collection of <xul:browser>'s for this tabbrowser
|
||||
// that we cannot force paint since their TabChild's haven't
|
||||
// been constructed yet. Instead, we show blank tabs for them
|
||||
// when attempting to switch to them.
|
||||
pendingTabChild: new WeakSet(),
|
||||
|
||||
// True if we're in the midst of switching tabs.
|
||||
switchInProgress: false,
|
||||
|
||||
@ -3827,6 +3834,7 @@
|
||||
window.addEventListener("sizemodechange", this);
|
||||
window.addEventListener("SwapDocShells", this, true);
|
||||
window.addEventListener("EndSwapDocShells", this, true);
|
||||
window.addEventListener("MozTabChildNotReady", this, true);
|
||||
if (!this.minimized) {
|
||||
this.setTabState(this.requestedTab, this.STATE_LOADED);
|
||||
}
|
||||
@ -3849,6 +3857,7 @@
|
||||
window.removeEventListener("sizemodechange", this);
|
||||
window.removeEventListener("SwapDocShells", this, true);
|
||||
window.removeEventListener("EndSwapDocShells", this, true);
|
||||
window.removeEventListener("MozTabChildNotReady", this, true);
|
||||
|
||||
this.tabbrowser._switcher = null;
|
||||
|
||||
@ -3864,6 +3873,7 @@
|
||||
this.assert(this.tabbrowser._switcher);
|
||||
this.assert(this.tabbrowser._switcher === this);
|
||||
this.assert(!this.spinnerTab);
|
||||
this.assert(!this.blankTab);
|
||||
this.assert(!this.loadTimer);
|
||||
this.assert(!this.loadingTab);
|
||||
this.assert(this.lastVisibleTab === this.requestedTab);
|
||||
@ -3894,20 +3904,45 @@
|
||||
// This function is called after all the main state changes to
|
||||
// make sure we display the right tab.
|
||||
updateDisplay() {
|
||||
let requestedTabState = this.getTabState(this.requestedTab);
|
||||
|
||||
let shouldBeBlank =
|
||||
this.pendingTabChild.has(this.requestedTab.linkedBrowser) &&
|
||||
requestedTabState == this.STATE_LOADING;
|
||||
|
||||
// Figure out which tab we actually want visible right now.
|
||||
let showTab = null;
|
||||
if (this.getTabState(this.requestedTab) != this.STATE_LOADED &&
|
||||
this.lastVisibleTab && this.loadTimer) {
|
||||
if (requestedTabState != this.STATE_LOADED &&
|
||||
this.lastVisibleTab && this.loadTimer && !shouldBeBlank) {
|
||||
// If we can't show the requestedTab, and lastVisibleTab is
|
||||
// available, show it.
|
||||
showTab = this.lastVisibleTab;
|
||||
} else {
|
||||
// Show the requested tab. If it's not available, we'll show the spinner.
|
||||
// Show the requested tab. If it's not available, we'll show the spinner or a blank tab.
|
||||
showTab = this.requestedTab;
|
||||
}
|
||||
|
||||
// First, let's deal with blank tabs, which we show instead
|
||||
// of the spinner when the tab is not currently set up
|
||||
// properly in the content process.
|
||||
if (!shouldBeBlank && this.blankTab) {
|
||||
this.tabbrowser.removeAttribute("pendingtabchild");
|
||||
this.blankTab.linkedBrowser.removeAttribute("pendingtabchild");
|
||||
this.blankTab = null;
|
||||
} else if (shouldBeBlank && this.blankTab !== showTab) {
|
||||
if (this.blankTab) {
|
||||
this.blankTab.linkedBrowser.removeAttribute("pendingtabchild");
|
||||
}
|
||||
this.blankTab = showTab;
|
||||
this.tabbrowser.setAttribute("pendingtabchild", "true");
|
||||
this.blankTab.linkedBrowser.setAttribute("pendingtabchild", "true");
|
||||
}
|
||||
|
||||
// Show or hide the spinner as needed.
|
||||
let needSpinner = this.getTabState(showTab) != this.STATE_LOADED && !this.minimized;
|
||||
let needSpinner = this.getTabState(showTab) != this.STATE_LOADED &&
|
||||
!this.minimized &&
|
||||
!shouldBeBlank;
|
||||
|
||||
if (!needSpinner && this.spinnerTab) {
|
||||
this.spinnerHidden();
|
||||
this.tabbrowser.removeAttribute("pendingpaint");
|
||||
@ -3992,6 +4027,9 @@
|
||||
if (this.lastVisibleTab && !this.lastVisibleTab.linkedBrowser) {
|
||||
this.lastVisibleTab = null;
|
||||
}
|
||||
if (this.blankTab && !this.blankTab.linkedBrowser) {
|
||||
this.blankTab = null;
|
||||
}
|
||||
if (this.spinnerTab && !this.spinnerTab.linkedBrowser) {
|
||||
this.spinnerHidden();
|
||||
this.spinnerTab = null;
|
||||
@ -4104,8 +4142,9 @@
|
||||
|
||||
// Fires when the layers become available for a tab.
|
||||
onLayersReady(browser) {
|
||||
this.pendingTabChild.delete(browser);
|
||||
let tab = this.tabbrowser.getTabForBrowser(browser);
|
||||
this.logState(`onLayersReady(${tab._tPos})`);
|
||||
this.logState(`onLayersReady(${tab._tPos}, ${browser.isRemoteBrowser})`);
|
||||
|
||||
this.assert(this.getTabState(tab) == this.STATE_LOADING ||
|
||||
this.getTabState(tab) == this.STATE_LOADED);
|
||||
@ -4130,6 +4169,7 @@
|
||||
|
||||
// Called when we're done clearing the layers for a tab.
|
||||
onLayersCleared(browser) {
|
||||
this.pendingTabChild.delete(browser);
|
||||
let tab = this.tabbrowser.getTabForBrowser(browser);
|
||||
if (tab) {
|
||||
this.logState(`onLayersCleared(${tab._tPos})`);
|
||||
@ -4150,6 +4190,15 @@
|
||||
} else if (this.getTabState(tab) == this.STATE_UNLOADING) {
|
||||
this.onLayersCleared(tab.linkedBrowser);
|
||||
}
|
||||
} else if (this.getTabState(tab) == this.STATE_LOADED) {
|
||||
// A tab just changed from non-remote to remote, which means
|
||||
// that it's gone back into the STATE_LOADING state until
|
||||
// it sends up a layer tree. We also add the browser to
|
||||
// the pendingTabChild set since this browser is unlikely
|
||||
// to have its TabChild set up right away, and we want to
|
||||
// make it appear "blank" instead of showing a spinner for it.
|
||||
this.pendingTabChild.add(tab.linkedBrowser);
|
||||
this.setTabState(tab, this.STATE_LOADING);
|
||||
}
|
||||
},
|
||||
|
||||
@ -4196,9 +4245,18 @@
|
||||
|
||||
let otherTabbrowser = otherBrowser.ownerGlobal.gBrowser;
|
||||
let otherState;
|
||||
let pendingTabChild = false;
|
||||
if (otherTabbrowser && otherTabbrowser._switcher) {
|
||||
let otherTab = otherTabbrowser.getTabForBrowser(otherBrowser);
|
||||
otherState = otherTabbrowser._switcher.getTabState(otherTab);
|
||||
let otherSwitcher = otherTabbrowser._switcher;
|
||||
otherState = otherSwitcher.getTabState(otherTab);
|
||||
pendingTabChild = otherSwitcher.pendingTabChild.has(otherBrowser);
|
||||
|
||||
if (pendingTabChild) {
|
||||
this.assert(otherState == this.STATE_LOADING);
|
||||
}
|
||||
|
||||
otherSwitcher.pendingTabChild.delete(otherBrowser);
|
||||
} else {
|
||||
otherState = (otherBrowser.docShellIsActive
|
||||
? this.STATE_LOADED
|
||||
@ -4208,7 +4266,10 @@
|
||||
if (!this.swapMap) {
|
||||
this.swapMap = new WeakMap();
|
||||
}
|
||||
this.swapMap.set(otherBrowser, otherState);
|
||||
this.swapMap.set(otherBrowser, {
|
||||
state: otherState,
|
||||
pendingTabChild,
|
||||
});
|
||||
},
|
||||
|
||||
onEndSwapDocShells(ourBrowser, otherBrowser) {
|
||||
@ -4227,12 +4288,17 @@
|
||||
}
|
||||
this.loadingTab = null;
|
||||
|
||||
let otherState = this.swapMap.get(otherBrowser);
|
||||
let { state: otherState, pendingTabChild } =
|
||||
this.swapMap.get(otherBrowser);
|
||||
|
||||
this.swapMap.delete(otherBrowser);
|
||||
|
||||
let ourTab = this.tabbrowser.getTabForBrowser(ourBrowser);
|
||||
if (ourTab) {
|
||||
this.setTabStateNoAction(ourTab, otherState);
|
||||
if (pendingTabChild) {
|
||||
this.pendingTabChild.add(ourTab.linkedBrowser);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -4247,6 +4313,28 @@
|
||||
this.setTabState(tab, this.STATE_LOADING);
|
||||
},
|
||||
|
||||
// The tab for this browser isn't currently set
|
||||
// up in the content process, so we have no chance
|
||||
// of painting it right away. We'll paint a blank
|
||||
// tab instead.
|
||||
onTabChildNotReady(browser) {
|
||||
this.assert(browser.isRemoteBrowser);
|
||||
|
||||
let tab = this.tabbrowser.getTabForBrowser(browser);
|
||||
|
||||
this.assert(this.getTabState(tab) == this.STATE_LOADING);
|
||||
|
||||
this.logState(`onTabChildNotReady(${tab._tPos})`);
|
||||
this.pendingTabChild.add(browser);
|
||||
this.maybeFinishTabSwitch();
|
||||
|
||||
if (this.loadingTab === tab) {
|
||||
this.clearTimer(this.loadTimer);
|
||||
this.loadTimer = null;
|
||||
this.loadingTab = null;
|
||||
}
|
||||
},
|
||||
|
||||
// Called when the user asks to switch to a given tab.
|
||||
requestTab(tab) {
|
||||
if (tab === this.requestedTab) {
|
||||
@ -4302,6 +4390,8 @@
|
||||
this.onSwapDocShells(event.originalTarget, event.detail);
|
||||
} else if (event.type == "EndSwapDocShells") {
|
||||
this.onEndSwapDocShells(event.originalTarget, event.detail);
|
||||
} else if (event.type == "MozTabChildNotReady") {
|
||||
this.onTabChildNotReady(event.originalTarget);
|
||||
}
|
||||
|
||||
this.postActions();
|
||||
@ -4328,7 +4418,8 @@
|
||||
*/
|
||||
maybeFinishTabSwitch() {
|
||||
if (this.switchInProgress && this.requestedTab &&
|
||||
this.getTabState(this.requestedTab) == this.STATE_LOADED) {
|
||||
(this.getTabState(this.requestedTab) == this.STATE_LOADED ||
|
||||
this.requestedTab === this.blankTab)) {
|
||||
// After this point the tab has switched from the content thread's point of view.
|
||||
// The changes will be visible after the next refresh driver tick + composite.
|
||||
let time = TelemetryStopwatch.timeElapsed("FX_TAB_SWITCH_TOTAL_E10S_MS", window);
|
||||
@ -4419,6 +4510,7 @@
|
||||
if (tab === this.lastVisibleTab) accum += "V";
|
||||
if (tab === this.loadingTab) accum += "L";
|
||||
if (tab === this.requestedTab) accum += "R";
|
||||
if (tab === this.blankTab) accum += "B";
|
||||
if (state == this.STATE_LOADED) accum += "(+)";
|
||||
if (state == this.STATE_LOADING) accum += "(+?)";
|
||||
if (state == this.STATE_UNLOADED) accum += "(-)";
|
||||
|
@ -192,9 +192,11 @@ add_task(function* checkAllTheProperties() {
|
||||
ok(uris.length, `Found ${uris.length} .properties files to scan for misused characters`);
|
||||
|
||||
for (let uri of uris) {
|
||||
let bundle = new StringBundle(uri.spec);
|
||||
let entities = bundle.getAll();
|
||||
for (let entity of entities) {
|
||||
let bundle = Services.strings.createBundle(uri.spec);
|
||||
let enumerator = bundle.getSimpleEnumeration();
|
||||
|
||||
while (enumerator.hasMoreElements()) {
|
||||
let entity = enumerator.getNext().QueryInterface(Ci.nsIPropertyElement);
|
||||
testForErrors(uri.spec, entity.key, entity.value);
|
||||
}
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ support-files =
|
||||
[browser_identity_UI.js]
|
||||
[browser_identityBlock_focus.js]
|
||||
support-files = ../general/permissions.html
|
||||
[browser_identityPopup_focus.js]
|
||||
[browser_insecureLoginForms.js]
|
||||
support-files =
|
||||
insecure_opener.html
|
||||
|
@ -0,0 +1,27 @@
|
||||
/* Tests the focus behavior of the identity popup. */
|
||||
|
||||
// Access the identity popup via mouseclick. Focus should not be moved inside.
|
||||
add_task(function* testIdentityPopupFocusClick() {
|
||||
yield SpecialPowers.pushPrefEnv({"set": [["accessibility.tabfocus", 7]]});
|
||||
yield BrowserTestUtils.withNewTab("https://example.com", function*() {
|
||||
let shown = BrowserTestUtils.waitForEvent(gIdentityHandler._identityPopup, "popupshown");
|
||||
EventUtils.synthesizeMouseAtCenter(gIdentityHandler._identityBox, {});
|
||||
yield shown;
|
||||
isnot(Services.focus.focusedElement, document.getElementById("identity-popup-security-expander"));
|
||||
});
|
||||
});
|
||||
|
||||
// Access the identity popup via keyboard. Focus should be moved inside.
|
||||
add_task(function* testIdentityPopupFocusKeyboard() {
|
||||
yield SpecialPowers.pushPrefEnv({"set": [["accessibility.tabfocus", 7]]});
|
||||
yield BrowserTestUtils.withNewTab("https://example.com", function*() {
|
||||
let focused = BrowserTestUtils.waitForEvent(gIdentityHandler._identityBox, "focus");
|
||||
gIdentityHandler._identityBox.focus();
|
||||
yield focused;
|
||||
let shown = BrowserTestUtils.waitForEvent(gIdentityHandler._identityPopup, "popupshown");
|
||||
EventUtils.synthesizeKey(" ", {});
|
||||
yield shown;
|
||||
is(Services.focus.focusedElement, document.getElementById("identity-popup-security-expander"));
|
||||
});
|
||||
});
|
||||
|
@ -85,7 +85,15 @@ function* testProbe(aProbe) {
|
||||
|
||||
add_task(function* setup() {
|
||||
yield SpecialPowers.pushPrefEnv({
|
||||
set: [["dom.ipc.processCount", 1]]
|
||||
set: [
|
||||
["dom.ipc.processCount", 1],
|
||||
// We can interrupt JS to paint now, which is great for
|
||||
// users, but bad for testing spinners. We temporarily
|
||||
// disable that feature for this test so that we can
|
||||
// easily get ourselves into a predictable tab spinner
|
||||
// state.
|
||||
["browser.tabs.remote.force-paint", false],
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -172,6 +172,8 @@ add_task(function* () {
|
||||
yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
|
||||
});
|
||||
|
||||
hookExtensionsTelemetry();
|
||||
|
||||
let changePromise = new Promise(resolve => {
|
||||
ExtensionsUI.on("change", function listener() {
|
||||
ExtensionsUI.off("change", listener);
|
||||
@ -327,6 +329,9 @@ add_task(function* () {
|
||||
addon4 = yield AddonManager.getAddonByID(ID4);
|
||||
is(addon4.userDisabled, false, "Addon 4 should be enabled");
|
||||
|
||||
// We should have recorded 1 cancelled followed by 3 accepted sideloads.
|
||||
expectTelemetry(["sideloadRejected", "sideloadAccepted", "sideloadAccepted", "sideloadAccepted"]);
|
||||
|
||||
isnot(menuButton.getAttribute("badge-status"), "addon-alert", "Should no longer have addon alert badge");
|
||||
|
||||
yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
|
@ -52,6 +52,8 @@ add_task(function* setup() {
|
||||
});
|
||||
});
|
||||
|
||||
hookExtensionsTelemetry();
|
||||
|
||||
// Helper function to test background updates.
|
||||
function* backgroundUpdateTest(url, id, checkIconFn) {
|
||||
yield SpecialPowers.pushPrefEnv({set: [
|
||||
@ -163,6 +165,9 @@ function* backgroundUpdateTest(url, id, checkIconFn) {
|
||||
|
||||
is(getBadgeStatus(), "", "Addon alert badge should be gone");
|
||||
|
||||
// Should have recorded 1 canceled followed by 1 accepted update.
|
||||
expectTelemetry(["updateRejected", "updateAccepted"]);
|
||||
|
||||
addon.uninstall();
|
||||
yield SpecialPowers.popPrefEnv();
|
||||
}
|
||||
|
@ -39,4 +39,4 @@ async function installSearch(filename) {
|
||||
EventUtils.synthesizeMouseAtCenter(button, {}, win);
|
||||
}
|
||||
|
||||
add_task(() => testInstallMethod(installSearch));
|
||||
add_task(() => testInstallMethod(installSearch, "installAmo"));
|
||||
|
@ -11,4 +11,4 @@ async function installTrigger(filename) {
|
||||
});
|
||||
}
|
||||
|
||||
add_task(() => testInstallMethod(installTrigger));
|
||||
add_task(() => testInstallMethod(installTrigger, "installAmo"));
|
||||
|
@ -20,4 +20,4 @@ async function installFile(filename) {
|
||||
contentWin.gViewController.doCommand("cmd_installFromFile");
|
||||
}
|
||||
|
||||
add_task(() => testInstallMethod(installFile));
|
||||
add_task(() => testInstallMethod(installFile, "installLocal"));
|
||||
|
@ -11,4 +11,4 @@ async function installMozAM(filename) {
|
||||
});
|
||||
}
|
||||
|
||||
add_task(() => testInstallMethod(installMozAM));
|
||||
add_task(() => testInstallMethod(installMozAM, "installAmo"));
|
||||
|
@ -2,6 +2,8 @@
|
||||
const BASE = getRootDirectory(gTestPath)
|
||||
.replace("chrome://mochitests/content/", "https://example.com/");
|
||||
|
||||
Cu.import("resource:///modules/ExtensionsUI.jsm");
|
||||
|
||||
/**
|
||||
* Wait for the given PopupNotification to display
|
||||
*
|
||||
@ -201,10 +203,13 @@ function checkNotification(panel, checkIcon, permissions) {
|
||||
* Callable that takes the name of an xpi file to install and
|
||||
* starts to install it. Should return a Promise that resolves
|
||||
* when the install is finished or rejects if the install is canceled.
|
||||
* @param {string} telemetryBase
|
||||
* If supplied, the base type for telemetry events that should be
|
||||
* recorded for this install method.
|
||||
*
|
||||
* @returns {Promise}
|
||||
*/
|
||||
async function testInstallMethod(installFn) {
|
||||
async function testInstallMethod(installFn, telemetryBase) {
|
||||
const PERMS_XPI = "browser_webext_permissions.xpi";
|
||||
const NO_PERMS_XPI = "browser_webext_nopermissions.xpi";
|
||||
const ID = "permissions@test.mozilla.org";
|
||||
@ -217,6 +222,10 @@ async function testInstallMethod(installFn) {
|
||||
["extensions.webextPermissionPrompts", true],
|
||||
]});
|
||||
|
||||
if (telemetryBase !== undefined) {
|
||||
hookExtensionsTelemetry();
|
||||
}
|
||||
|
||||
let testURI = makeURI("https://example.com/");
|
||||
Services.perms.add(testURI, "install", Services.perms.ALLOW_ACTION);
|
||||
registerCleanupFunction(() => Services.perms.remove(testURI, "install"));
|
||||
@ -316,6 +325,12 @@ async function testInstallMethod(installFn) {
|
||||
// the extension to clean up.)
|
||||
await runOnce(PERMS_XPI, false);
|
||||
|
||||
if (telemetryBase !== undefined) {
|
||||
// Should see 2 canceled installs followed by 1 successful install
|
||||
// for this method.
|
||||
expectTelemetry([`${telemetryBase}Rejected`, `${telemetryBase}Rejected`, `${telemetryBase}Accepted`]);
|
||||
}
|
||||
|
||||
await SpecialPowers.popPrefEnv();
|
||||
}
|
||||
|
||||
@ -347,3 +362,21 @@ add_task(async function() {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
let collectedTelemetry = [];
|
||||
function hookExtensionsTelemetry() {
|
||||
let originalHistogram = ExtensionsUI.histogram;
|
||||
ExtensionsUI.histogram = {
|
||||
add(value) { collectedTelemetry.push(value); },
|
||||
};
|
||||
registerCleanupFunction(() => {
|
||||
is(collectedTelemetry.length, 0, "No unexamined telemetry after test is finished");
|
||||
ExtensionsUI.histogram = originalHistogram;
|
||||
});
|
||||
}
|
||||
|
||||
function expectTelemetry(values) {
|
||||
Assert.deepEqual(values, collectedTelemetry);
|
||||
collectedTelemetry = [];
|
||||
}
|
||||
|
||||
|
166
browser/base/content/theme-vars.inc.css
Normal file
166
browser/base/content/theme-vars.inc.css
Normal file
@ -0,0 +1,166 @@
|
||||
%if 0
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
%endif
|
||||
|
||||
:root[lwthemeicons~="--back-icon"] #back-button:-moz-lwtheme {
|
||||
list-style-image: var(--back-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--forward-icon"] #forward-button:-moz-lwtheme {
|
||||
list-style-image: var(--forward-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--reload-icon"] #urlbar-reload-button:-moz-lwtheme {
|
||||
list-style-image: var(--reload-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--stop-icon"] #urlbar-stop-button:-moz-lwtheme {
|
||||
list-style-image: var(--stop-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--bookmark_star-icon"] #bookmarks-menu-button:-moz-lwtheme {
|
||||
list-style-image: var(--bookmark_star-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--bookmark_menu-icon"] #bookmarks-menu-button[cui-areatype='toolbar'] > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon:-moz-lwtheme {
|
||||
list-style-image: var(--bookmark_menu-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--downloads-icon"] #downloads-button:-moz-lwtheme {
|
||||
list-style-image: var(--downloads-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--home-icon"] #home-button:-moz-lwtheme {
|
||||
list-style-image: var(--home-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--app_menu-icon"] #PanelUI-menu-button:-moz-lwtheme {
|
||||
list-style-image: var(--app_menu-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--cut-icon"] #cut-button:-moz-lwtheme {
|
||||
list-style-image: var(--cut-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--copy-icon"] #copy-button:-moz-lwtheme {
|
||||
list-style-image: var(--copy-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--paste-icon"] #paste-button:-moz-lwtheme {
|
||||
list-style-image: var(--paste-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--new_window-icon"] #new-window-button:-moz-lwtheme {
|
||||
list-style-image: var(--new_window-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--new_private_window-icon"] #privatebrowsing-button:-moz-lwtheme {
|
||||
list-style-image: var(--new_private_window-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--save_page-icon"] #save-page-button:-moz-lwtheme {
|
||||
list-style-image: var(--save_page-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--print-icon"] #print-button:-moz-lwtheme {
|
||||
list-style-image: var(--print-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--history-icon"] #history-panelmenu:-moz-lwtheme {
|
||||
list-style-image: var(--history-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--full_screen-icon"] #fullscreen-button:-moz-lwtheme {
|
||||
list-style-image: var(--full_screen-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--find-icon"] #find-button:-moz-lwtheme {
|
||||
list-style-image: var(--find-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--options-icon"] #preferences-button:-moz-lwtheme {
|
||||
list-style-image: var(--options-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--addons-icon"] #add-ons-button:-moz-lwtheme {
|
||||
list-style-image: var(--addons-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--developer-icon"] #developer-button:-moz-lwtheme {
|
||||
list-style-image: var(--developer-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--synced_tabs-icon"] #sync-button:-moz-lwtheme {
|
||||
list-style-image: var(--synced_tabs-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--open_file-icon"] #open-file-button:-moz-lwtheme {
|
||||
list-style-image: var(--open_file-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--sidebars-icon"] #sidebar-button:-moz-lwtheme {
|
||||
list-style-image: var(--sidebars-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--share_page-icon"] #social-share-button:-moz-lwtheme {
|
||||
list-style-image: var(--share_page-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--subscribe-icon"] #feed-button:-moz-lwtheme {
|
||||
list-style-image: var(--subscribe-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--text_encoding-icon"] #characterencoding-button:-moz-lwtheme {
|
||||
list-style-image: var(--text_encoding-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--email_link-icon"] #email-link-button:-moz-lwtheme {
|
||||
list-style-image: var(--email_link-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--forget-icon"] #panic-button:-moz-lwtheme {
|
||||
list-style-image: var(--forget-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--pocket-icon"] #pocket-button:-moz-lwtheme {
|
||||
list-style-image: var(--pocket-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--back-icon"] #back-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--forward-icon"] #forward-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--bookmark_star-icon"] #bookmarks-menu-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--bookmark_menu-icon"] #bookmarks-menu-button[cui-areatype='toolbar'] > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--downloads-icon"] #downloads-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--home-icon"] #home-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--app_menu-icon"] #PanelUI-menu-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--cut-icon"] #cut-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--copy-icon"] #copy-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--paste-icon"] #paste-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--new_window-icon"] #new-window-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--new_private_window-icon"] #privatebrowsing-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--save_page-icon"] #save-page-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--print-icon"] #print-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--history-icon"] #history-panelmenu:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--full_screen-icon"] #fullscreen-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--find-icon"] #find-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--options-icon"] #preferences-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--addons-icon"] #add-ons-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--developer-icon"] #developer-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--synced_tabs-icon"] #sync-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--open_file-icon"] #open-file-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--sidebars-icon"] #sidebar-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--share_page-icon"] #social-share-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--subscribe-icon"] #feed-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--text_encoding-icon"] #characterencoding-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--email_link-icon"] #email-link-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--forget-icon"] #panic-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--pocket-icon"] #pocket-button:-moz-lwtheme {
|
||||
-moz-image-region: rect(0, 18px, 18px, 0) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--reload-icon"] #urlbar-reload-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--stop-icon"] #urlbar-stop-button:-moz-lwtheme {
|
||||
-moz-image-region: rect(0, 14px, 14px, 0) !important;
|
||||
}
|
@ -8,8 +8,6 @@ Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService",
|
||||
"@mozilla.org/browser/aboutnewtab-service;1",
|
||||
"nsIAboutNewTabService");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
|
||||
"resource://gre/modules/Preferences.jsm");
|
||||
|
||||
// Bug 1320736 tracks creating a generic precedence manager for handling
|
||||
// multiple addons modifying the same properties, and bug 1330494 has been filed
|
||||
@ -19,85 +17,32 @@ XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
|
||||
let overrides = {
|
||||
// A queue of extensions in line to override the newtab page (sorted oldest to newest).
|
||||
newtab: [],
|
||||
// A queue of extensions in line to override the home page (sorted oldest to newest).
|
||||
home: [],
|
||||
};
|
||||
|
||||
/**
|
||||
* Resets the specified page to its default value.
|
||||
*
|
||||
* @param {string} page The page to override. Accepted values are "newtab" and "home".
|
||||
*/
|
||||
function resetPage(page) {
|
||||
switch (page) {
|
||||
case "newtab":
|
||||
aboutNewTabService.resetNewTabURL();
|
||||
break;
|
||||
case "home":
|
||||
Preferences.reset("browser.startup.homepage");
|
||||
break;
|
||||
default:
|
||||
throw new Error("Unrecognized override type");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the specified page to the specified URL.
|
||||
*
|
||||
* @param {string} page The page to override. Accepted values are "newtab" and "home".
|
||||
* @param {string} url The resolved URL to use for the page override.
|
||||
*/
|
||||
function overridePage(page, url) {
|
||||
switch (page) {
|
||||
case "newtab":
|
||||
aboutNewTabService.newTabURL = url;
|
||||
break;
|
||||
case "home":
|
||||
Preferences.set("browser.startup.homepage", url);
|
||||
break;
|
||||
default:
|
||||
throw new Error("Unrecognized override type");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the page to the URL specified by the extension next in line. If no extensions
|
||||
* are in line, the page is reset to its default value.
|
||||
*
|
||||
* @param {string} page The page to override.
|
||||
*/
|
||||
function updatePage(page) {
|
||||
if (overrides[page].length) {
|
||||
overridePage(page, overrides[page][0].url);
|
||||
} else {
|
||||
resetPage(page);
|
||||
}
|
||||
}
|
||||
|
||||
/* eslint-disable mozilla/balanced-listeners */
|
||||
extensions.on("manifest_chrome_url_overrides", (type, directive, extension, manifest) => {
|
||||
if (Object.keys(overrides).length > 1) {
|
||||
extension.manifestError("Extensions can override only one page.");
|
||||
}
|
||||
if (manifest.chrome_url_overrides.newtab) {
|
||||
let newtab = manifest.chrome_url_overrides.newtab;
|
||||
let url = extension.baseURI.resolve(newtab);
|
||||
|
||||
for (let page of Object.keys(overrides)) {
|
||||
if (manifest.chrome_url_overrides[page]) {
|
||||
let relativeURL = manifest.chrome_url_overrides[page];
|
||||
let url = extension.baseURI.resolve(relativeURL);
|
||||
// Store the extension ID instead of a hard reference to the extension.
|
||||
overrides[page].push({id: extension.id, url});
|
||||
updatePage(page);
|
||||
break;
|
||||
// Only set the newtab URL if no other extension is overriding it.
|
||||
if (!overrides.newtab.length) {
|
||||
aboutNewTabService.newTabURL = url;
|
||||
}
|
||||
|
||||
overrides.newtab.push({id: extension.id, url});
|
||||
}
|
||||
});
|
||||
|
||||
extensions.on("shutdown", (type, extension) => {
|
||||
for (let page of Object.keys(overrides)) {
|
||||
let i = overrides[page].findIndex(o => o.id === extension.id);
|
||||
if (i !== -1) {
|
||||
overrides[page].splice(i, 1);
|
||||
updatePage(page);
|
||||
let i = overrides.newtab.findIndex(o => o.id === extension.id);
|
||||
if (i !== -1) {
|
||||
overrides.newtab.splice(i, 1);
|
||||
|
||||
if (overrides.newtab.length) {
|
||||
aboutNewTabService.newTabURL = overrides.newtab[0].url;
|
||||
} else {
|
||||
aboutNewTabService.resetNewTabURL();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -14,11 +14,6 @@
|
||||
"optional": true,
|
||||
"preprocess": "localize"
|
||||
},
|
||||
"home": {
|
||||
"$ref": "ExtensionURL",
|
||||
"optional": true,
|
||||
"preprocess": "localize"
|
||||
},
|
||||
"bookmarks": {
|
||||
"unsupported": true,
|
||||
"$ref": "ExtensionURL",
|
||||
|
@ -116,9 +116,8 @@ support-files =
|
||||
[browser_ext_tabs_update.js]
|
||||
[browser_ext_tabs_zoom.js]
|
||||
[browser_ext_tabs_update_url.js]
|
||||
[browser_ext_themes_icons.js]
|
||||
[browser_ext_topwindowid.js]
|
||||
[browser_ext_url_overrides_all.js]
|
||||
[browser_ext_url_overrides_home.js]
|
||||
[browser_ext_url_overrides_newtab.js]
|
||||
[browser_ext_webRequest.js]
|
||||
[browser_ext_webNavigation_frameId0.js]
|
||||
|
@ -7,8 +7,7 @@ add_task(function* () {
|
||||
"http://mochi.test:8888/browser/browser/components/extensions/test/browser/context.html");
|
||||
|
||||
let encodedImageData = "iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAC4klEQVRYhdWXLWzbQBSADQtDAwsHC1tUhUxqfL67lk2tdn+OJg0ODU0rLByqgqINBY6tmlbn7LMTJ5FaFVVBk1G0oUGjG2jT2Y7jxmmcbU/6iJ+f36fz+e5sGP9riCGm9hB37RG+scd4Yo/wsDXCZyIE2xuXsce4bY+wXkAsQtzYmExrfFgvkJkRbkzo1ehoxx5iXcgI/9iYUGt8WH9MqDXEcmNChmEYrRCf2SHWeYgQx3x0tLNRIeKQLTtEFyJEep4NTuhk8BC+yMrwEE3+iozo42d8gK7FAOkMsRiiN8QhW2ttSK5QTfRRV4QoymVeJMvPvDp7gCZigD613MN6yRFA3SWarow9QB9LCfG+NeF9qCtjAKOSQjCqVKhfVsiHEQ+grgx/lRGqUihAc1uL8EFD+KCRO+GrF4J61phcoRoPoEzkYhZYpykh5sMb7kOdIeY+jHKur4QI4Feh4AFX1nVeLxrAvQchGsBz5ls6wa2QdwcvIcE2863bTH79KOvsz/uUYJsp+J0pSzNlDckVqqVGUAF+n6uS7txcOl6wot4JVy70ufDLy4pWLUQVPE81pRI0mGe9oxLMHSeohHvMs/STUNaUK6vDPCvOyxMFDx4achehRDJmHnydnkPww5OFfLxrGIZBFDyYl4LpMzlTQFIP6AQx86w2UeYBccFpJrcKv5L9eGDtUAU6RIELqsB74uynjy/UBRF1gS5BTFxwQT1wTiXoUg9MH7m/3NZRRoi5IJytUbMgzv4Wc832+oQkiKgEehmyMkkpKsFkQV11QsRJL5rJYBLItQgRaUZEmnoZXsomz3vGiWw+I9KMF9SVFOqZEemZekli1jN3U/UOqhHHvC6oWWGElhfSpGdOk6+O9prdwvtLj5BjRsQxdRnot+Zeifpy/2/0stktKTRNLmbk0mwXyl8253fyojj+8rxOHNAhjjm5n0/5OOCGOKBzkrMO0Z75lvSAzKlrF32Z/3z8BqLAn+yMV7VhAAAAAElFTkSuQmCC";
|
||||
let decodedImageData = atob(encodedImageData);
|
||||
const IMAGE_ARRAYBUFFER = Uint8Array.from(decodedImageData, byte => byte.charCodeAt(0)).buffer;
|
||||
const IMAGE_ARRAYBUFFER = imageBufferFromDataURI(encodedImageData);
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
|
@ -0,0 +1,275 @@
|
||||
"use strict";
|
||||
|
||||
const ENCODED_IMAGE_DATA = "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgNjQgNjQiPjxwYXRoIGQ9Im01NS45IDMyLjFsLTIyLjctMTQuOWMwIDAgMTIuOS0xNy40IDE5LjQtMTQuOSAzLjEgMS4xIDUuNCAyNS4xIDMuMyAyOS44IiBmaWxsPSIjM2U0MzQ3Ii8+PHBhdGggZD0ibTU0LjkgMzMuOWwtOS00LjFjMCAwLTUuMy0xNCA2LjEtMjQuMSAyLjQgMiA1LjEgMjUgMi45IDI4LjIiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJtOC4xIDMyLjFsMjIuNi0xNC45YzAgMC0xMi45LTE3LjQtMTkuNC0xNC45LTMgMS4xLTUuMyAyNS4xLTMuMiAyOS44IiBmaWxsPSIjM2U0MzQ3Ii8+PHBhdGggZD0ibTkuMSAzMy45bDktNC4xYzAgMCA1LjMtMTQtNi4xLTI0LjEtMi40IDItNS4xIDI1LTIuOSAyOC4yIiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTMyLDEzQzE4LjksMTMsMiwzMy42LDIsNDUuNEMyMC41LDQ1LjQsMTkuNyw2MiwzMiw2MnMxMS41LTE2LjYsMzAtMTYuNkM2MiwzMy42LDQ1LjEsMTMsMzIsMTN6IiBmaWxsPSIjZmY4NzM2Ii8+PGcgZmlsbD0iI2ZmZiI+PHBhdGggZD0iTTMyLDU2LjJjMCw1LjEsOS42LDQuMiw5LjUtMi45YzYuNy05LjQsMTkuOS04LjcsMTkuOS04LjdDMzkuNiwzMi40LDMyLDU2LjIsMzIsNTYuMnoiLz48cGF0aCBkPSJNMzIsNTYuMmMwLDUuMS05LjYsNC4yLTkuNS0yLjlDMTUuOCw0NCwyLjYsNDQuNywyLjYsNDQuN0MyNC40LDMyLjQsMzIsNTYuMiwzMiw1Ni4yeiIvPjwvZz48ZyBmaWxsPSIjZmY4NzM2Ij48cGF0aCBkPSJtNTMuNCAxOC41Yy00IC43LTQuOSA2LjMtNC45IDYuM2w2IDUuM2MtMi4zLTUuOS0xLjEtMTEuNi0xLjEtMTEuNiIvPjxwYXRoIGQ9Im01MS4xIDEzLjVjLTQuNCAzLjktNS4xIDguNy01LjEgOC43bDYgNS4zYy0yLjQtNS44LS45LTE0LS45LTE0Ii8+PHBhdGggZD0ibTEwLjYgMTguNWM0IC43IDQuOSA2LjMgNC45IDYuM2wtNiA1LjNjMi4zLTUuOSAxLjEtMTEuNiAxLjEtMTEuNiIvPjxwYXRoIGQ9Im0xMi45IDEzLjVjNC40IDMuOSA1LjEgOC43IDUuMSA4LjdsLTYgNS4zYzIuNC01LjguOS0xNCAuOS0xNCIvPjwvZz48cGF0aCBkPSJtNTIuOCAzMS4xYy01LjctMS44LTEwLjktMy40LTEzLjguOS0yLjQgMy43LjcgOS40LjcgOS40IDExLjIgMS4yIDEzLjEtMTAuMyAxMy4xLTEwLjMiIGZpbGw9IiMzZTQzNDciLz48ZWxsaXBzZSBjeD0iNDMiIGN5PSIzNi4zIiByeD0iNC4yIiByeT0iNC4xIiBmaWxsPSIjZDVmZjgzIi8+PGcgZmlsbD0iIzNlNDM0NyI+PGVsbGlwc2UgY3g9IjQzIiBjeT0iMzYuMyIgcng9IjIuNyIgcnk9IjIuNyIvPjxwYXRoIGQ9Im0xMS4yIDMxLjFjNS43LTEuOCAxMC45LTMuNCAxMy43LjkgMi40IDMuNy0uNyA5LjQtLjcgOS40LTExLjEgMS4yLTEzLTEwLjMtMTMtMTAuMyIvPjwvZz48ZWxsaXBzZSBjeD0iMjEiIGN5PSIzNi4zIiByeD0iNC4yIiByeT0iNC4xIiBmaWxsPSIjZDVmZjgzIi8+PGcgZmlsbD0iIzNlNDM0NyI+PGVsbGlwc2UgY3g9IjIxIiBjeT0iMzYuMyIgcng9IjIuNyIgcnk9IjIuNyIvPjxwYXRoIGQ9Im00MS4yIDQ3LjljLS43LTIuMy0xLjgtNC40LTMtNi41IDEuMSAyLjEgMiA0LjMgMi41IDYuNi41IDIuMy43IDQuNyAwIDYuOC0uNCAxLTEgMi0xLjggMi42LS44LjYtMS44IDEtMi43IDEtLjkgMC0xLjktLjMtMi41LTEtLjYtLjctLjktMS42LS44LTIuNmwtLjkuMmgtLjljMCAxLS4yIDEuOS0uOCAyLjYtLjYuNy0xLjUgMS0yLjUgMS0uOSAwLTEuOS0uNC0yLjctMS0uOC0uNi0xLjQtMS42LTEuOC0yLjYtLjgtMi4xLS42LTQuNiAwLTYuOC41LTIuMyAxLjUtNC41IDIuNS02LjYtMS4yIDItMi4zIDQuMS0zIDYuNS0uNyAyLjMtMS4xIDQuOC0uNCA3LjMuMyAxLjIgMSAyLjQgMS45IDMuMy45LjkgMi4xIDEuNCAzLjQgMS41IDEuMi4xIDIuNi0uMiAzLjctMS4yLjMtLjIuNS0uNS43LS44LjIuMy40LjYuNy44IDEgMSAyLjQgMS4zIDMuNyAxLjIgMS4zLS4xIDIuNC0uNyAzLjQtMS41LjktLjkgMS42LTIgMS45LTMuMy41LTIuNi4xLTUuMi0uNi03LjUiLz48cGF0aCBkPSJtMzcuNiA1MC4zYy0xLjEtMS4xLTQuNS0xLjItNS42LTEuMi0xIDAtNC41LjEtNS42IDEuMi0uOC44LS4yIDIuOCAxLjkgNC41IDEuMyAxLjEgMi42IDEuNCAzLjYgMS40IDEgMCAyLjMtLjMgMy42LTEuNCAyLjMtMS43IDIuOS0zLjcgMi4xLTQuNSIvPjwvZz48L3N2Zz4=";
|
||||
|
||||
/**
|
||||
* Verifies that the button uses the expected icon.
|
||||
*
|
||||
* @param {string} selector The CSS selector used to find the button
|
||||
* within the DOM.
|
||||
* @param {boolean} shouldHaveCustomStyling True if the button should
|
||||
* have custom styling, False otherwise.
|
||||
* @param {string} message The message that is printed to the console
|
||||
* by the verifyFn.
|
||||
*/
|
||||
function verifyButtonProperties(selector, shouldHaveCustomStyling, message) {
|
||||
try {
|
||||
let element;
|
||||
// This selector is different than the others because it's the only
|
||||
// toolbarbutton that we ship by default that has type="menu-button",
|
||||
// which don't place a unique ID on the associated dropmarker-icon.
|
||||
if (selector == "#bookmarks-menu-button > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon") {
|
||||
if (message.includes("panel")) {
|
||||
// The dropmarker isn't shown in the menupanel.
|
||||
return;
|
||||
}
|
||||
element = document.querySelector("#bookmarks-menu-button");
|
||||
element = document.getAnonymousElementByAttribute(element, "class", "toolbarbutton-menubutton-dropmarker");
|
||||
element = document.getAnonymousElementByAttribute(element, "class", "dropmarker-icon");
|
||||
} else {
|
||||
element = document.querySelector(selector);
|
||||
}
|
||||
|
||||
let listStyleImage = getComputedStyle(element).listStyleImage;
|
||||
info(`listStyleImage for fox.svg is ${listStyleImage}`);
|
||||
is(listStyleImage.includes("fox.svg"), shouldHaveCustomStyling, message);
|
||||
} catch (ex) {
|
||||
ok(false, `Unable to verify ${selector}: ${ex}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the button uses default styling.
|
||||
*
|
||||
* @param {string} selector The CSS selector used to find the button
|
||||
* within the DOM.
|
||||
* @param {string} message The message that is printed to the console
|
||||
* by the verifyFn.
|
||||
*/
|
||||
function verifyButtonWithoutCustomStyling(selector, message) {
|
||||
verifyButtonProperties(selector, false, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the button uses non-default styling.
|
||||
*
|
||||
* @param {string} selector The CSS selector used to find the button
|
||||
* within the DOM.
|
||||
* @param {string} message The message that is printed to the console
|
||||
* by the verifyFn.
|
||||
*/
|
||||
function verifyButtonWithCustomStyling(selector, message) {
|
||||
verifyButtonProperties(selector, true, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loops through all of the buttons to confirm that they are styled
|
||||
* as expected (either with or without custom styling).
|
||||
*
|
||||
* @param {object} icons Array of an array that specifies which buttons should
|
||||
* have custom icons.
|
||||
* @param {object} iconInfo An array of arrays that maps API names to
|
||||
* CSS selectors.
|
||||
* @param {string} area The name of the area that the button resides in.
|
||||
*/
|
||||
function checkButtons(icons, iconInfo, area) {
|
||||
for (let button of iconInfo) {
|
||||
let iconInfo = icons.find(arr => arr[0] == button[0]);
|
||||
if (iconInfo[1]) {
|
||||
verifyButtonWithCustomStyling(button[1],
|
||||
`The ${button[1]} should have it's icon customized in the ${area}`);
|
||||
} else {
|
||||
verifyButtonWithoutCustomStyling(button[1],
|
||||
`The ${button[1]} should not have it's icon customized in the ${area}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function* runTestWithIcons(icons) {
|
||||
const FRAME_COLOR = [71, 105, 91];
|
||||
const TAB_TEXT_COLOR = [207, 221, 192, .9];
|
||||
let manifest = {
|
||||
"theme": {
|
||||
"images": {
|
||||
"theme_frame": "fox.svg",
|
||||
},
|
||||
"colors": {
|
||||
"frame": FRAME_COLOR,
|
||||
"tab_text": TAB_TEXT_COLOR,
|
||||
},
|
||||
"icons": {},
|
||||
},
|
||||
};
|
||||
let files = {
|
||||
"fox.svg": imageBufferFromDataURI(ENCODED_IMAGE_DATA),
|
||||
};
|
||||
|
||||
// Each item in this array has the following setup:
|
||||
// At position 0: The name that is used in the theme manifest.
|
||||
// At position 1: The CSS selector for the button in the DOM.
|
||||
// At position 2: The CustomizableUI name for the widget, only defined
|
||||
// if customizable.
|
||||
const ICON_INFO = [
|
||||
["back", "#back-button"],
|
||||
["forward", "#forward-button"],
|
||||
["reload", "#urlbar-reload-button"],
|
||||
["stop", "#urlbar-stop-button"],
|
||||
["bookmark_star", "#bookmarks-menu-button", "bookmarks-menu-button"],
|
||||
["bookmark_menu", "#bookmarks-menu-button > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon"],
|
||||
["downloads", "#downloads-button", "downloads-button"],
|
||||
["home", "#home-button", "home-button"],
|
||||
["app_menu", "#PanelUI-menu-button"],
|
||||
["cut", "#cut-button", "edit-controls"],
|
||||
["copy", "#copy-button"],
|
||||
["paste", "#paste-button"],
|
||||
["new_window", "#new-window-button", "new-window-button"],
|
||||
["new_private_window", "#privatebrowsing-button", "privatebrowsing-button"],
|
||||
["save_page", "#save-page-button", "save-page-button"],
|
||||
["print", "#print-button", "print-button"],
|
||||
["history", "#history-panelmenu", "history-panelmenu"],
|
||||
["full_screen", "#fullscreen-button", "fullscreen-button"],
|
||||
["find", "#find-button", "find-button"],
|
||||
["options", "#preferences-button", "preferences-button"],
|
||||
["addons", "#add-ons-button", "add-ons-button"],
|
||||
["developer", "#developer-button", "developer-button"],
|
||||
["synced_tabs", "#sync-button", "sync-button"],
|
||||
["open_file", "#open-file-button", "open-file-button"],
|
||||
["sidebars", "#sidebar-button", "sidebar-button"],
|
||||
["share_page", "#social-share-button", "social-share-button"],
|
||||
["subscribe", "#feed-button", "feed-button"],
|
||||
["text_encoding", "#characterencoding-button", "characterencoding-button"],
|
||||
["email_link", "#email-link-button", "email-link-button"],
|
||||
["forget", "#panic-button", "panic-button"],
|
||||
["pocket", "#pocket-button", "pocket-button"],
|
||||
];
|
||||
|
||||
window.maximize();
|
||||
|
||||
for (let button of ICON_INFO) {
|
||||
if (button[2]) {
|
||||
CustomizableUI.addWidgetToArea(button[2], CustomizableUI.AREA_NAVBAR);
|
||||
}
|
||||
|
||||
verifyButtonWithoutCustomStyling(button[1],
|
||||
`The ${button[1]} should not have it's icon customized when the test starts`);
|
||||
|
||||
let iconInfo = icons.find(arr => arr[0] == button[0]);
|
||||
manifest.theme.icons[button[0]] = iconInfo[1];
|
||||
}
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({manifest, files});
|
||||
|
||||
yield extension.startup();
|
||||
|
||||
checkButtons(icons, ICON_INFO, "toolbar");
|
||||
|
||||
for (let button of ICON_INFO) {
|
||||
if (button[2]) {
|
||||
CustomizableUI.addWidgetToArea(button[2], CustomizableUI.AREA_PANEL);
|
||||
}
|
||||
}
|
||||
|
||||
yield PanelUI.show();
|
||||
|
||||
checkButtons(icons, ICON_INFO, "panel");
|
||||
|
||||
yield PanelUI.hide();
|
||||
|
||||
yield extension.unload();
|
||||
|
||||
for (let button of ICON_INFO) {
|
||||
verifyButtonWithoutCustomStyling(button[1],
|
||||
`The ${button[1]} should not have it's icon customized when the theme is unloaded`);
|
||||
}
|
||||
}
|
||||
|
||||
add_task(function* setup() {
|
||||
yield SpecialPowers.pushPrefEnv({
|
||||
set: [["extensions.webextensions.themes.enabled", true],
|
||||
["extensions.webextensions.themes.icons.enabled", true]],
|
||||
});
|
||||
});
|
||||
|
||||
add_task(function* test_all_icons() {
|
||||
let icons = [
|
||||
["back", "fox.svg"],
|
||||
["forward", "fox.svg"],
|
||||
["reload", "fox.svg"],
|
||||
["stop", "fox.svg"],
|
||||
["bookmark_star", "fox.svg"],
|
||||
["bookmark_menu", "fox.svg"],
|
||||
["downloads", "fox.svg"],
|
||||
["home", "fox.svg"],
|
||||
["app_menu", "fox.svg"],
|
||||
["cut", "fox.svg"],
|
||||
["copy", "fox.svg"],
|
||||
["paste", "fox.svg"],
|
||||
["new_window", "fox.svg"],
|
||||
["new_private_window", "fox.svg"],
|
||||
["save_page", "fox.svg"],
|
||||
["print", "fox.svg"],
|
||||
["history", "fox.svg"],
|
||||
["full_screen", "fox.svg"],
|
||||
["find", "fox.svg"],
|
||||
["options", "fox.svg"],
|
||||
["addons", "fox.svg"],
|
||||
["developer", "fox.svg"],
|
||||
["synced_tabs", "fox.svg"],
|
||||
["open_file", "fox.svg"],
|
||||
["sidebars", "fox.svg"],
|
||||
["share_page", "fox.svg"],
|
||||
["subscribe", "fox.svg"],
|
||||
["text_encoding", "fox.svg"],
|
||||
["email_link", "fox.svg"],
|
||||
["forget", "fox.svg"],
|
||||
["pocket", "fox.svg"],
|
||||
];
|
||||
yield runTestWithIcons(icons);
|
||||
});
|
||||
|
||||
add_task(function* teardown() {
|
||||
CustomizableUI.reset();
|
||||
window.restore();
|
||||
});
|
||||
|
||||
add_task(function* test_some_icons() {
|
||||
let icons = [
|
||||
["back", ""],
|
||||
["forward", ""],
|
||||
["reload", "fox.svg"],
|
||||
["stop", ""],
|
||||
["bookmark_star", ""],
|
||||
["bookmark_menu", ""],
|
||||
["downloads", ""],
|
||||
["home", "fox.svg"],
|
||||
["app_menu", "fox.svg"],
|
||||
["cut", ""],
|
||||
["copy", ""],
|
||||
["paste", ""],
|
||||
["new_window", ""],
|
||||
["new_private_window", ""],
|
||||
["save_page", ""],
|
||||
["print", ""],
|
||||
["history", ""],
|
||||
["full_screen", ""],
|
||||
["find", ""],
|
||||
["options", ""],
|
||||
["addons", ""],
|
||||
["developer", ""],
|
||||
["synced_tabs", ""],
|
||||
["open_file", ""],
|
||||
["sidebars", ""],
|
||||
["share_page", ""],
|
||||
["subscribe", ""],
|
||||
["text_encoding", ""],
|
||||
["email_link", ""],
|
||||
["forget", ""],
|
||||
["pocket", "fox.svg"],
|
||||
];
|
||||
yield runTestWithIcons(icons);
|
||||
});
|
||||
|
||||
add_task(function* teardown() {
|
||||
CustomizableUI.reset();
|
||||
window.restore();
|
||||
});
|
@ -1,97 +0,0 @@
|
||||
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set sts=2 sw=2 et tw=80: */
|
||||
|
||||
"use strict";
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService",
|
||||
"@mozilla.org/browser/aboutnewtab-service;1",
|
||||
"nsIAboutNewTabService");
|
||||
|
||||
const NEWTAB_URI = "webext-newtab.html";
|
||||
const HOME_URI = "webext-home.html";
|
||||
|
||||
add_task(function* test_extensions_overriding_different_pages() {
|
||||
let defaultHomePage = Preferences.get("browser.startup.homepage");
|
||||
let defaultNewtabPage = aboutNewTabService.newTabURL;
|
||||
|
||||
is(Preferences.get("browser.startup.homepage"), defaultHomePage,
|
||||
`Default home url should be ${defaultHomePage}`);
|
||||
is(aboutNewTabService.newTabURL, defaultNewtabPage,
|
||||
`Default newtab url should be ${defaultNewtabPage}`);
|
||||
|
||||
let ext1 = ExtensionTestUtils.loadExtension({
|
||||
manifest: {"chrome_url_overrides": {}},
|
||||
});
|
||||
|
||||
let ext2 = ExtensionTestUtils.loadExtension({
|
||||
manifest: {"chrome_url_overrides": {newtab: NEWTAB_URI}},
|
||||
});
|
||||
|
||||
let ext3 = ExtensionTestUtils.loadExtension({
|
||||
manifest: {"chrome_url_overrides": {home: HOME_URI}},
|
||||
});
|
||||
|
||||
yield ext1.startup();
|
||||
|
||||
is(aboutNewTabService.newTabURL, defaultNewtabPage,
|
||||
`Default newtab url should still be ${defaultNewtabPage}`);
|
||||
is(Preferences.get("browser.startup.homepage"), defaultHomePage,
|
||||
`Default home url should be ${defaultHomePage}`);
|
||||
|
||||
yield ext2.startup();
|
||||
|
||||
ok(aboutNewTabService.newTabURL.endsWith(NEWTAB_URI),
|
||||
"Newtab url should be overriden by the second extension.");
|
||||
is(Preferences.get("browser.startup.homepage"), defaultHomePage,
|
||||
`Default home url should be ${defaultHomePage}`);
|
||||
|
||||
yield ext1.unload();
|
||||
|
||||
ok(aboutNewTabService.newTabURL.endsWith(NEWTAB_URI),
|
||||
"Newtab url should still be overriden by the second extension.");
|
||||
is(Preferences.get("browser.startup.homepage"), defaultHomePage,
|
||||
`Default home url should be ${defaultHomePage}`);
|
||||
|
||||
yield ext3.startup();
|
||||
|
||||
ok(aboutNewTabService.newTabURL.endsWith(NEWTAB_URI),
|
||||
"Newtab url should still be overriden by the second extension.");
|
||||
ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI),
|
||||
"Home url should be overriden by the third extension.");
|
||||
|
||||
yield ext2.unload();
|
||||
|
||||
is(aboutNewTabService.newTabURL, defaultNewtabPage,
|
||||
`Newtab url should be reset to ${defaultNewtabPage}`);
|
||||
ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI),
|
||||
"Home url should still be overriden by the third extension.");
|
||||
|
||||
yield ext3.unload();
|
||||
|
||||
is(aboutNewTabService.newTabURL, defaultNewtabPage,
|
||||
`Newtab url should be reset to ${defaultNewtabPage}`);
|
||||
is(Preferences.get("browser.startup.homepage"), defaultHomePage,
|
||||
`Home url should be reset to ${defaultHomePage}`);
|
||||
});
|
||||
|
||||
add_task(function* test_extensions_with_multiple_overrides() {
|
||||
let ext = ExtensionTestUtils.loadExtension({
|
||||
manifest: {"chrome_url_overrides": {
|
||||
newtab: NEWTAB_URI,
|
||||
home: HOME_URI,
|
||||
}},
|
||||
});
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
let waitForConsole = new Promise(resolve => {
|
||||
SimpleTest.monitorConsole(resolve, [{
|
||||
message: /Extensions can override only one page./,
|
||||
}]);
|
||||
});
|
||||
|
||||
yield ext.startup();
|
||||
yield ext.unload();
|
||||
|
||||
SimpleTest.endMonitorConsole();
|
||||
yield waitForConsole;
|
||||
});
|
@ -1,74 +0,0 @@
|
||||
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set sts=2 sw=2 et tw=80: */
|
||||
|
||||
"use strict";
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
|
||||
"resource://gre/modules/Preferences.jsm");
|
||||
|
||||
const HOME_URI_1 = "webext-home-1.html";
|
||||
const HOME_URI_2 = "webext-home-2.html";
|
||||
const HOME_URI_3 = "webext-home-3.html";
|
||||
|
||||
add_task(function* test_multiple_extensions_overriding_newtab_page() {
|
||||
let defaultHomePage = Preferences.get("browser.startup.homepage");
|
||||
|
||||
is(Preferences.get("browser.startup.homepage"), defaultHomePage,
|
||||
`Default home url should be ${defaultHomePage}`);
|
||||
|
||||
let ext1 = ExtensionTestUtils.loadExtension({
|
||||
manifest: {"chrome_url_overrides": {}},
|
||||
});
|
||||
|
||||
let ext2 = ExtensionTestUtils.loadExtension({
|
||||
manifest: {"chrome_url_overrides": {home: HOME_URI_1}},
|
||||
});
|
||||
|
||||
let ext3 = ExtensionTestUtils.loadExtension({
|
||||
manifest: {"chrome_url_overrides": {home: HOME_URI_2}},
|
||||
});
|
||||
|
||||
let ext4 = ExtensionTestUtils.loadExtension({
|
||||
manifest: {"chrome_url_overrides": {home: HOME_URI_3}},
|
||||
});
|
||||
|
||||
yield ext1.startup();
|
||||
|
||||
is(Preferences.get("browser.startup.homepage"), defaultHomePage,
|
||||
`Default home url should still be ${defaultHomePage}`);
|
||||
|
||||
yield ext2.startup();
|
||||
|
||||
ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_1),
|
||||
"Home url should be overriden by the second extension.");
|
||||
|
||||
yield ext1.unload();
|
||||
|
||||
ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_1),
|
||||
"Home url should still be overriden by the second extension.");
|
||||
|
||||
yield ext3.startup();
|
||||
|
||||
ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_1),
|
||||
"Home url should still be overriden by the second extension.");
|
||||
|
||||
yield ext2.unload();
|
||||
|
||||
ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_2),
|
||||
"Home url should be overriden by the third extension.");
|
||||
|
||||
yield ext4.startup();
|
||||
|
||||
ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_2),
|
||||
"Home url should be overriden by the third extension.");
|
||||
|
||||
yield ext4.unload();
|
||||
|
||||
ok(Preferences.get("browser.startup.homepage").endsWith(HOME_URI_2),
|
||||
"Home url should be overriden by the third extension.");
|
||||
|
||||
yield ext3.unload();
|
||||
|
||||
is(Preferences.get("browser.startup.homepage"), defaultHomePage,
|
||||
`Home url should be reset to ${defaultHomePage}`);
|
||||
});
|
@ -76,11 +76,11 @@ add_task(function* test_sending_message_from_newtab_page() {
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
"chrome_url_overrides": {
|
||||
newtab: NEWTAB_URI_1,
|
||||
newtab: NEWTAB_URI_2,
|
||||
},
|
||||
},
|
||||
files: {
|
||||
[NEWTAB_URI_1]: `
|
||||
[NEWTAB_URI_2]: `
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<meta charset="utf-8"/></head>
|
||||
|
@ -12,7 +12,8 @@
|
||||
* openExtensionContextMenu closeExtensionContextMenu
|
||||
* openActionContextMenu openSubmenu closeActionContextMenu
|
||||
* openTabContextMenu closeTabContextMenu
|
||||
* imageBuffer getListStyleImage getPanelForNode
|
||||
* imageBuffer imageBufferFromDataURI
|
||||
* getListStyleImage getPanelForNode
|
||||
* awaitExtensionPanel awaitPopupResize
|
||||
* promiseContentDimensions alterContent
|
||||
*/
|
||||
@ -64,8 +65,13 @@ var focusWindow = Task.async(function* focusWindow(win) {
|
||||
yield promise;
|
||||
});
|
||||
|
||||
function imageBufferFromDataURI(encodedImageData) {
|
||||
let decodedImageData = atob(encodedImageData);
|
||||
return Uint8Array.from(decodedImageData, byte => byte.charCodeAt(0)).buffer;
|
||||
}
|
||||
|
||||
let img = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==";
|
||||
var imageBuffer = Uint8Array.from(atob(img), byte => byte.charCodeAt(0)).buffer;
|
||||
var imageBuffer = imageBufferFromDataURI(img);
|
||||
|
||||
function getListStyleImage(button) {
|
||||
let style = button.ownerGlobal.getComputedStyle(button);
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "nsFeedSniffer.h"
|
||||
|
||||
#include "mozilla/Unused.h"
|
||||
|
||||
#include "nsNetCID.h"
|
||||
#include "nsXPCOM.h"
|
||||
@ -57,8 +58,8 @@ nsFeedSniffer::ConvertEncodedData(nsIRequest* request,
|
||||
return NS_ERROR_NO_INTERFACE;
|
||||
|
||||
nsAutoCString contentEncoding;
|
||||
httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Content-Encoding"),
|
||||
contentEncoding);
|
||||
mozilla::Unused << httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Content-Encoding"),
|
||||
contentEncoding);
|
||||
if (!contentEncoding.IsEmpty()) {
|
||||
nsCOMPtr<nsIStreamConverterService> converterService(do_GetService(NS_STREAMCONVERTERSERVICE_CONTRACTID));
|
||||
if (converterService) {
|
||||
@ -213,7 +214,7 @@ nsFeedSniffer::GetMIMETypeFromContent(nsIRequest* request,
|
||||
|
||||
// Check that this is a GET request, since you can't subscribe to a POST...
|
||||
nsAutoCString method;
|
||||
channel->GetRequestMethod(method);
|
||||
mozilla::Unused << channel->GetRequestMethod(method);
|
||||
if (!method.EqualsLiteral("GET")) {
|
||||
sniffedType.Truncate();
|
||||
return NS_OK;
|
||||
@ -265,8 +266,10 @@ nsFeedSniffer::GetMIMETypeFromContent(nsIRequest* request,
|
||||
|
||||
// set the feed header as a response header, since we have good metadata
|
||||
// telling us that the feed is supposed to be RSS or Atom
|
||||
channel->SetResponseHeader(NS_LITERAL_CSTRING("X-Moz-Is-Feed"),
|
||||
NS_LITERAL_CSTRING("1"), false);
|
||||
mozilla::DebugOnly<nsresult> rv =
|
||||
channel->SetResponseHeader(NS_LITERAL_CSTRING("X-Moz-Is-Feed"),
|
||||
NS_LITERAL_CSTRING("1"), false);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
sniffedType.AssignLiteral(TYPE_MAYBE_FEED);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -313,7 +313,7 @@ var PlacesOrganizer = {
|
||||
// The command execution function will take care of seeing if the
|
||||
// selection is a folder or a different container type, and will
|
||||
// load its contents in tabs.
|
||||
PlacesUIUtils.openContainerNodeInTabs(selectedNode, aEvent, this._places);
|
||||
PlacesUIUtils.openContainerNodeInTabs(node, aEvent, this._places);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -39,6 +39,7 @@ support-files =
|
||||
[browser_library_downloads.js]
|
||||
[browser_library_infoBox.js]
|
||||
[browser_library_left_pane_fixnames.js]
|
||||
[browser_library_left_pane_middleclick.js]
|
||||
[browser_library_left_pane_select_hierarchy.js]
|
||||
[browser_library_middleclick.js]
|
||||
[browser_library_open_leak.js]
|
||||
|
@ -0,0 +1,196 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* 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/. */
|
||||
|
||||
/**
|
||||
* Tests middle-clicking items in the Library.
|
||||
*/
|
||||
|
||||
const ENABLE_HISTORY_PREF = "places.history.enabled";
|
||||
|
||||
var gLibrary = null;
|
||||
var gTests = [];
|
||||
var gCurrentTest = null;
|
||||
|
||||
// Listener for TabOpen and tabs progress.
|
||||
var gTabsListener = {
|
||||
_loadedURIs: [],
|
||||
_openTabsCount: 0,
|
||||
|
||||
handleEvent(aEvent) {
|
||||
if (aEvent.type != "TabOpen")
|
||||
return;
|
||||
|
||||
if (++this._openTabsCount == gCurrentTest.URIs.length) {
|
||||
is(gBrowser.tabs.length, gCurrentTest.URIs.length + 1,
|
||||
"We have opened " + gCurrentTest.URIs.length + " new tab(s)");
|
||||
}
|
||||
|
||||
var tab = aEvent.target;
|
||||
is(tab.ownerGlobal, window,
|
||||
"Tab has been opened in current browser window");
|
||||
},
|
||||
|
||||
onLocationChange(aBrowser, aWebProgress, aRequest, aLocationURI,
|
||||
aFlags) {
|
||||
var spec = aLocationURI.spec;
|
||||
ok(true, spec);
|
||||
// When a new tab is opened, location is first set to "about:blank", so
|
||||
// we can ignore those calls.
|
||||
// Ignore multiple notifications for the same URI too.
|
||||
if (spec == "about:blank" || this._loadedURIs.includes(spec))
|
||||
return;
|
||||
|
||||
ok(gCurrentTest.URIs.includes(spec),
|
||||
"Opened URI found in list: " + spec);
|
||||
|
||||
if (gCurrentTest.URIs.includes(spec))
|
||||
this._loadedURIs.push(spec);
|
||||
|
||||
if (this._loadedURIs.length == gCurrentTest.URIs.length) {
|
||||
// We have correctly opened all URIs.
|
||||
|
||||
// Reset arrays.
|
||||
this._loadedURIs.length = 0;
|
||||
|
||||
this._openTabsCount = 0;
|
||||
|
||||
executeSoon(function() {
|
||||
// Close all tabs.
|
||||
while (gBrowser.tabs.length > 1)
|
||||
gBrowser.removeCurrentTab();
|
||||
|
||||
// Test finished. This will move to the next one.
|
||||
waitForFocus(gCurrentTest.finish, gBrowser.ownerGlobal);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Open a folder in tabs.
|
||||
|
||||
gTests.push({
|
||||
desc: "Open a folder in tabs.",
|
||||
URIs: ["about:buildconfig", "about:"],
|
||||
_folderId: -1,
|
||||
|
||||
setup() {
|
||||
var bs = PlacesUtils.bookmarks;
|
||||
// Create a new folder.
|
||||
var folderId = bs.createFolder(bs.unfiledBookmarksFolder,
|
||||
"Folder",
|
||||
bs.DEFAULT_INDEX);
|
||||
this._folderId = folderId;
|
||||
|
||||
// Add bookmarks in folder.
|
||||
this.URIs.forEach(function(aURI) {
|
||||
bs.insertBookmark(folderId,
|
||||
PlacesUtils._uri(aURI),
|
||||
bs.DEFAULT_INDEX,
|
||||
"Title");
|
||||
});
|
||||
|
||||
// Select unsorted bookmarks root in the left pane.
|
||||
gLibrary.PlacesOrganizer.selectLeftPaneQuery("UnfiledBookmarks");
|
||||
isnot(gLibrary.PlacesOrganizer._places.selectedNode, null,
|
||||
"We correctly have selection in the Library left pane");
|
||||
// Get our bookmark in the right pane.
|
||||
var folderNode = gLibrary.ContentTree.view.view.nodeForTreeIndex(0);
|
||||
is(folderNode.title, "Folder", "Found folder in the right pane");
|
||||
},
|
||||
|
||||
finish() {
|
||||
setTimeout(runNextTest, 0);
|
||||
},
|
||||
|
||||
cleanup() {
|
||||
PlacesUtils.bookmarks.removeItem(this._folderId);
|
||||
}
|
||||
});
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
// Sanity checks.
|
||||
ok(PlacesUtils, "PlacesUtils in context");
|
||||
ok(PlacesUIUtils, "PlacesUIUtils in context");
|
||||
|
||||
// Add tabs listeners.
|
||||
gBrowser.tabContainer.addEventListener("TabOpen", gTabsListener);
|
||||
gBrowser.addTabsProgressListener(gTabsListener);
|
||||
|
||||
// Temporary disable history, so we won't record pages navigation.
|
||||
gPrefService.setBoolPref(ENABLE_HISTORY_PREF, false);
|
||||
|
||||
// Open Library window.
|
||||
openLibrary(function(library) {
|
||||
gLibrary = library;
|
||||
// Kick off tests.
|
||||
runNextTest();
|
||||
});
|
||||
}
|
||||
|
||||
function runNextTest() {
|
||||
// Cleanup from previous test.
|
||||
if (gCurrentTest)
|
||||
gCurrentTest.cleanup();
|
||||
|
||||
if (gTests.length > 0) {
|
||||
// Goto next test.
|
||||
gCurrentTest = gTests.shift();
|
||||
info("Start of test: " + gCurrentTest.desc);
|
||||
// Test setup will set Library so that the bookmark to be opened is the
|
||||
// first node in the content (right pane) tree.
|
||||
gCurrentTest.setup();
|
||||
|
||||
gLibrary.focus();
|
||||
waitForFocus(function() {
|
||||
// Open the "Other Bookmarks" folder.
|
||||
gLibrary.PlacesOrganizer.selectLeftPaneQuery("UnfiledBookmarks");
|
||||
gLibrary.PlacesOrganizer._places.selectedNode.containerOpen = true;
|
||||
// Now middle-click on the bookmark contained with it.
|
||||
let bookmarkedNode = gLibrary.PlacesOrganizer._places.selectedNode.getChild(0);
|
||||
mouseEventOnCell(gLibrary.PlacesOrganizer._places,
|
||||
gLibrary.PlacesOrganizer._places.view.treeIndexForNode(bookmarkedNode),
|
||||
0,
|
||||
{ button: 1 });
|
||||
}, gLibrary);
|
||||
} else {
|
||||
// No more tests.
|
||||
|
||||
// We must close "Other Bookmarks" ready for other tests.
|
||||
gLibrary.PlacesOrganizer.selectLeftPaneQuery("UnfiledBookmarks");
|
||||
gLibrary.PlacesOrganizer._places.selectedNode.containerOpen = false;
|
||||
|
||||
// Close Library window.
|
||||
gLibrary.close();
|
||||
|
||||
// Remove tabs listeners.
|
||||
gBrowser.tabContainer.removeEventListener("TabOpen", gTabsListener);
|
||||
gBrowser.removeTabsProgressListener(gTabsListener);
|
||||
|
||||
// Restore history.
|
||||
try {
|
||||
gPrefService.clearUserPref(ENABLE_HISTORY_PREF);
|
||||
} catch (ex) {}
|
||||
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
function mouseEventOnCell(aTree, aRowIndex, aColumnIndex, aEventDetails) {
|
||||
var selection = aTree.view.selection;
|
||||
selection.select(aRowIndex);
|
||||
aTree.treeBoxObject.ensureRowIsVisible(aRowIndex);
|
||||
var column = aTree.columns[aColumnIndex];
|
||||
|
||||
// get cell coordinates
|
||||
var rect = aTree.treeBoxObject.getCoordsForCellItem(aRowIndex, column, "text");
|
||||
|
||||
EventUtils.synthesizeMouse(aTree.body, rect.x, rect.y,
|
||||
aEventDetails, gLibrary);
|
||||
}
|
@ -20,7 +20,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "PageStyle",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ScrollPosition",
|
||||
"resource://gre/modules/ScrollPosition.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SessionHistory",
|
||||
"resource:///modules/sessionstore/SessionHistory.jsm");
|
||||
"resource://gre/modules/sessionstore/SessionHistory.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SessionStorage",
|
||||
"resource:///modules/sessionstore/SessionStorage.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Utils",
|
||||
|
@ -28,7 +28,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "PageStyle",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ScrollPosition",
|
||||
"resource://gre/modules/ScrollPosition.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SessionHistory",
|
||||
"resource:///modules/sessionstore/SessionHistory.jsm");
|
||||
"resource://gre/modules/sessionstore/SessionHistory.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SessionStorage",
|
||||
"resource:///modules/sessionstore/SessionStorage.jsm");
|
||||
|
||||
|
@ -33,7 +33,6 @@ EXTRA_JS_MODULES.sessionstore = [
|
||||
'RunState.jsm',
|
||||
'SessionCookies.jsm',
|
||||
'SessionFile.jsm',
|
||||
'SessionHistory.jsm',
|
||||
'SessionMigration.jsm',
|
||||
'SessionSaver.jsm',
|
||||
'SessionStorage.jsm',
|
||||
|
@ -1 +1 @@
|
||||
54.0a1
|
||||
55.0a1
|
||||
|
@ -1 +1 @@
|
||||
54.0a1
|
||||
55.0a1
|
||||
|
@ -443,6 +443,8 @@ identity.identified.verified_by_you=You have added a security exception for this
|
||||
identity.identified.state_and_country=%S, %S
|
||||
|
||||
identity.icon.tooltip=Show site information
|
||||
identity.showDetails.tooltip=Show connection details
|
||||
identity.hideDetails.tooltip=Hide connection details
|
||||
|
||||
trackingProtection.intro.title=How Tracking Protection works
|
||||
# LOCALIZATION NOTE (trackingProtection.intro.description2):
|
||||
|
@ -195,7 +195,7 @@ var DirectoryLinksProvider = {
|
||||
|
||||
if (matchOS) {
|
||||
return Cc["@mozilla.org/intl/ospreferences;1"].
|
||||
getService(Ci.mozIOSPreferences).getSystemLocale();
|
||||
getService(Ci.mozIOSPreferences).systemLocale;
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -33,8 +33,11 @@ this.ExtensionsUI = {
|
||||
sideloaded: new Set(),
|
||||
updates: new Set(),
|
||||
sideloadListener: null,
|
||||
histogram: null,
|
||||
|
||||
init() {
|
||||
this.histogram = Services.telemetry.getHistogramById("EXTENSION_INSTALL_PROMPT_RESULT");
|
||||
|
||||
Services.obs.addObserver(this, "webextension-permission-prompt", false);
|
||||
Services.obs.addObserver(this, "webextension-update-permissions", false);
|
||||
Services.obs.addObserver(this, "webextension-install-notify", false);
|
||||
@ -88,13 +91,13 @@ this.ExtensionsUI = {
|
||||
});
|
||||
},
|
||||
|
||||
showAddonsManager(browser, strings, icon) {
|
||||
showAddonsManager(browser, strings, icon, histkey) {
|
||||
let global = browser.selectedBrowser.ownerGlobal;
|
||||
return global.BrowserOpenAddonsMgr("addons://list/extension").then(aomWin => {
|
||||
let aomBrowser = aomWin.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDocShell)
|
||||
.chromeEventHandler;
|
||||
return this.showPermissionsPrompt(aomBrowser, strings, icon);
|
||||
return this.showPermissionsPrompt(aomBrowser, strings, icon, histkey);
|
||||
});
|
||||
},
|
||||
|
||||
@ -108,13 +111,14 @@ this.ExtensionsUI = {
|
||||
permissions: addon.userPermissions,
|
||||
type: "sideload",
|
||||
});
|
||||
this.showAddonsManager(browser, strings, addon.iconURL).then(answer => {
|
||||
addon.userDisabled = !answer;
|
||||
});
|
||||
this.showAddonsManager(browser, strings, addon.iconURL, "sideload")
|
||||
.then(answer => {
|
||||
addon.userDisabled = !answer;
|
||||
});
|
||||
},
|
||||
|
||||
showUpdate(browser, info) {
|
||||
this.showAddonsManager(browser, info.strings, info.addon.iconURL)
|
||||
this.showAddonsManager(browser, info.strings, info.addon.iconURL, "update")
|
||||
.then(answer => {
|
||||
if (answer) {
|
||||
info.resolve();
|
||||
@ -147,13 +151,27 @@ this.ExtensionsUI = {
|
||||
return;
|
||||
}
|
||||
|
||||
this.showPermissionsPrompt(target, strings, info.icon).then(answer => {
|
||||
if (answer) {
|
||||
info.resolve();
|
||||
} else {
|
||||
info.reject();
|
||||
}
|
||||
});
|
||||
let histkey;
|
||||
if (info.type == "sideload") {
|
||||
histkey = "sideload";
|
||||
} else if (info.type == "update") {
|
||||
histkey = "update";
|
||||
} else if (info.source == "AMO") {
|
||||
histkey = "installAmo";
|
||||
} else if (info.source == "local") {
|
||||
histkey = "installLocal";
|
||||
} else {
|
||||
histkey = "installWeb";
|
||||
}
|
||||
|
||||
this.showPermissionsPrompt(target, strings, info.icon, histkey)
|
||||
.then(answer => {
|
||||
if (answer) {
|
||||
info.resolve();
|
||||
} else {
|
||||
info.reject();
|
||||
}
|
||||
});
|
||||
} else if (topic == "webextension-update-permissions") {
|
||||
let info = subject.wrappedJSObject;
|
||||
info.type = "update";
|
||||
@ -307,7 +325,7 @@ this.ExtensionsUI = {
|
||||
return result;
|
||||
},
|
||||
|
||||
showPermissionsPrompt(browser, strings, icon) {
|
||||
showPermissionsPrompt(browser, strings, icon, histkey) {
|
||||
function eventCallback(topic) {
|
||||
if (topic == "showing") {
|
||||
let doc = this.browser.ownerDocument;
|
||||
@ -349,13 +367,19 @@ this.ExtensionsUI = {
|
||||
let action = {
|
||||
label: strings.acceptText,
|
||||
accessKey: strings.acceptKey,
|
||||
callback: () => resolve(true),
|
||||
callback: () => {
|
||||
this.histogram.add(histkey + "Accepted");
|
||||
resolve(true);
|
||||
},
|
||||
};
|
||||
let secondaryActions = [
|
||||
{
|
||||
label: strings.cancelText,
|
||||
accessKey: strings.cancelKey,
|
||||
callback: () => resolve(false),
|
||||
callback: () => {
|
||||
this.histogram.add(histkey + "Rejected");
|
||||
resolve(false);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -804,6 +804,7 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton {
|
||||
}
|
||||
|
||||
.fxaSyncIllustration {
|
||||
width: 180px;
|
||||
height: var(--panel-ui-sync-illustration-height);
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" width="320" height="280" viewBox="0 0 320 280" xmlns:xlink="http://www.w3.org/1999/xlink" >
|
||||
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" viewBox="0 0 320 280" xmlns:xlink="http://www.w3.org/1999/xlink" >
|
||||
<style>
|
||||
#blueFill:target ~ use,
|
||||
#blueFill:target ~ g {
|
||||
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.7 KiB |
@ -64,7 +64,6 @@
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsJSUtils.h"
|
||||
#include "nsILoadInfo.h"
|
||||
#include "nsXPCOMStrings.h"
|
||||
|
||||
// This should be probably defined on some other place... but I couldn't find it
|
||||
#define WEBAPPS_PERM_NAME "webapps-manage"
|
||||
|
@ -10,4 +10,4 @@
|
||||
# hardcoded milestones in the tree from these two files.
|
||||
#--------------------------------------------------------
|
||||
|
||||
54.0a1
|
||||
55.0a1
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
const { interfaces: Ci, utils: Cu } = Components;
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
const kDebuggerPrefs = [
|
||||
"devtools.debugger.remote-enabled",
|
||||
"devtools.chrome.enabled"
|
||||
@ -124,9 +124,28 @@ DevToolsStartup.prototype = {
|
||||
if (!this._isRemoteDebuggingEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
let devtoolsThreadResumed = false;
|
||||
let pauseOnStartup = cmdLine.handleFlag("wait-for-jsdebugger", false);
|
||||
if (pauseOnStartup) {
|
||||
let observe = function (subject, topic, data) {
|
||||
devtoolsThreadResumed = true;
|
||||
Services.obs.removeObserver(observe, "devtools-thread-resumed");
|
||||
};
|
||||
Services.obs.addObserver(observe, "devtools-thread-resumed", false);
|
||||
}
|
||||
|
||||
const { BrowserToolboxProcess } = Cu.import("resource://devtools/client/framework/ToolboxProcess.jsm", {});
|
||||
BrowserToolboxProcess.init();
|
||||
|
||||
if (pauseOnStartup) {
|
||||
// Spin the event loop until the debugger connects.
|
||||
let thread = Cc["@mozilla.org/thread-manager;1"].getService().currentThread;
|
||||
while (!devtoolsThreadResumed) {
|
||||
thread.processNextEvent(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (cmdLine.state == Ci.nsICommandLine.STATE_REMOTE_AUTO) {
|
||||
cmdLine.preventDefault = true;
|
||||
}
|
||||
@ -203,6 +222,9 @@ DevToolsStartup.prototype = {
|
||||
/* eslint-disable max-len */
|
||||
helpInfo: " --jsconsole Open the Browser Console.\n" +
|
||||
" --jsdebugger Open the Browser Toolbox.\n" +
|
||||
" --wait-for-jsdebugger Spin event loop until JS debugger connects.\n" +
|
||||
" Enables debugging (some) application startup code paths.\n" +
|
||||
" Only has an effect when `--jsdebugger` is also supplied.\n" +
|
||||
" --devtools Open DevTools on initial load.\n" +
|
||||
" --start-debugger-server [ws:][ <port> | <path> ] Start the debugger server on\n" +
|
||||
" a TCP port or Unix domain socket path. Defaults to TCP port\n" +
|
||||
|
@ -60,13 +60,15 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
createFactories,
|
||||
parseURLEncodedText,
|
||||
parseURLParams,
|
||||
getSelectableInInspectorGrips
|
||||
getSelectableInInspectorGrips,
|
||||
maybeEscapePropertyName
|
||||
} = __webpack_require__(4);
|
||||
|
||||
module.exports = {
|
||||
REPS,
|
||||
MODE,
|
||||
createFactories,
|
||||
maybeEscapePropertyName,
|
||||
parseURLEncodedText,
|
||||
parseURLParams,
|
||||
getSelectableInInspectorGrips
|
||||
@ -354,6 +356,29 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
}) + "\"";
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape a property name, if needed. "Escaping" in this context
|
||||
* means surrounding the property name with quotes.
|
||||
*
|
||||
* @param {String}
|
||||
* name the property name
|
||||
* @return {String} either the input, or the input surrounded by
|
||||
* quotes, properly quoted in JS syntax.
|
||||
*/
|
||||
function maybeEscapePropertyName(name) {
|
||||
// Quote the property name if it needs quoting. This particular
|
||||
// test is an approximation; see
|
||||
// https://mathiasbynens.be/notes/javascript-properties. However,
|
||||
// the full solution requires a fair amount of Unicode data, and so
|
||||
// let's defer that until either it's important, or the \p regexp
|
||||
// syntax lands, see
|
||||
// https://github.com/tc39/proposal-regexp-unicode-property-escapes.
|
||||
if (!/^\w+$/.test(name)) {
|
||||
name = escapeString(name);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
function cropMultipleLines(text, limit) {
|
||||
return escapeNewLines(cropString(text, limit));
|
||||
}
|
||||
@ -587,7 +612,8 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
parseURLEncodedText,
|
||||
getFileName,
|
||||
getURLDisplayString,
|
||||
getSelectableInInspectorGrips
|
||||
getSelectableInInspectorGrips,
|
||||
maybeEscapePropertyName
|
||||
};
|
||||
|
||||
/***/ },
|
||||
@ -978,9 +1004,9 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
return x === y.toString();
|
||||
}
|
||||
|
||||
let props = Object.getOwnPropertyNames(array);
|
||||
for (let i = 0; i < props.length; i++) {
|
||||
let p = props[i];
|
||||
let propsArray = Object.getOwnPropertyNames(array);
|
||||
for (let i = 0; i < propsArray.length; i++) {
|
||||
let p = propsArray[i];
|
||||
|
||||
// Valid indexes are skipped
|
||||
if (isInteger(p)) {
|
||||
@ -1268,6 +1294,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
const React = __webpack_require__(3);
|
||||
const {
|
||||
createFactories,
|
||||
maybeEscapePropertyName,
|
||||
wrapRender
|
||||
} = __webpack_require__(4);
|
||||
const { MODE } = __webpack_require__(1);
|
||||
@ -1295,7 +1322,11 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
attachedActorIds: React.PropTypes.array,
|
||||
onDOMNodeMouseOver: React.PropTypes.func,
|
||||
onDOMNodeMouseOut: React.PropTypes.func,
|
||||
onInspectIconClick: React.PropTypes.func
|
||||
onInspectIconClick: React.PropTypes.func,
|
||||
// Normally a PropRep will quote a property name that isn't valid
|
||||
// when unquoted; but this flag can be used to suppress the
|
||||
// quoting.
|
||||
suppressQuotes: React.PropTypes.bool
|
||||
},
|
||||
|
||||
render: wrapRender(function () {
|
||||
@ -1305,14 +1336,18 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
name,
|
||||
mode,
|
||||
equal,
|
||||
delim
|
||||
delim,
|
||||
suppressQuotes
|
||||
} = this.props;
|
||||
|
||||
let key;
|
||||
// The key can be a simple string, for plain objects,
|
||||
// or another object for maps and weakmaps.
|
||||
if (typeof this.props.name === "string") {
|
||||
key = span({ "className": "nodeName" }, this.props.name);
|
||||
if (typeof name === "string") {
|
||||
if (!suppressQuotes) {
|
||||
name = maybeEscapePropertyName(name);
|
||||
}
|
||||
key = span({ "className": "nodeName" }, name);
|
||||
} else {
|
||||
key = Rep(Object.assign({}, this.props, {
|
||||
object: name,
|
||||
@ -1424,19 +1459,24 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
}
|
||||
|
||||
const truncate = Object.keys(properties).length > max;
|
||||
let props = this.getProps(properties, indexes, truncate);
|
||||
// The server synthesizes some property names for a Proxy, like
|
||||
// <target> and <handler>; we don't want to quote these because,
|
||||
// as synthetic properties, they appear more natural when
|
||||
// unquoted.
|
||||
const suppressQuotes = object.class === "Proxy";
|
||||
let propsArray = this.getProps(properties, indexes, truncate, suppressQuotes);
|
||||
if (truncate) {
|
||||
// There are some undisplayed props. Then display "more...".
|
||||
let objectLink = this.props.objectLink || span;
|
||||
|
||||
props.push(Caption({
|
||||
propsArray.push(Caption({
|
||||
object: objectLink({
|
||||
object: object
|
||||
}, `${propertiesLength - max} more…`)
|
||||
}));
|
||||
}
|
||||
|
||||
return props;
|
||||
return propsArray;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1445,10 +1485,12 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
* @param {Object} properties Props object.
|
||||
* @param {Array} indexes Indexes of props.
|
||||
* @param {Boolean} truncate true if the grip will be truncated.
|
||||
* @param {Boolean} suppressQuotes true if we should suppress quotes
|
||||
* on property names.
|
||||
* @return {Array} Props.
|
||||
*/
|
||||
getProps: function (properties, indexes, truncate) {
|
||||
let props = [];
|
||||
getProps: function (properties, indexes, truncate, suppressQuotes) {
|
||||
let propsArray = [];
|
||||
|
||||
// Make indexes ordered by ascending.
|
||||
indexes.sort(function (a, b) {
|
||||
@ -1459,7 +1501,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
let name = Object.keys(properties)[i];
|
||||
let value = this.getPropValue(properties[name]);
|
||||
|
||||
props.push(PropRep(Object.assign({}, this.props, {
|
||||
propsArray.push(PropRep(Object.assign({}, this.props, {
|
||||
mode: MODE.TINY,
|
||||
name: name,
|
||||
object: value,
|
||||
@ -1467,11 +1509,12 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
delim: i !== indexes.length - 1 || truncate ? ", " : "",
|
||||
defaultRep: Grip,
|
||||
// Do not propagate title to properties reps
|
||||
title: undefined
|
||||
title: undefined,
|
||||
suppressQuotes
|
||||
})));
|
||||
});
|
||||
|
||||
return props;
|
||||
return propsArray;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1530,7 +1573,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
|
||||
render: wrapRender(function () {
|
||||
let object = this.props.object;
|
||||
let props = this.safePropIterator(object, this.props.mode === MODE.LONG ? 10 : 3);
|
||||
let propsArray = this.safePropIterator(object, this.props.mode === MODE.LONG ? 10 : 3);
|
||||
|
||||
let objectLink = this.props.objectLink || span;
|
||||
if (this.props.mode === MODE.TINY) {
|
||||
@ -1543,7 +1586,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
return span({ className: "objectBox objectBox-object" }, this.getTitle(object), objectLink({
|
||||
className: "objectLeftBrace",
|
||||
object: object
|
||||
}, " { "), ...props, objectLink({
|
||||
}, " { "), ...propsArray, objectLink({
|
||||
className: "objectRightBrace",
|
||||
object: object
|
||||
}, " }"));
|
||||
@ -2114,7 +2157,8 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
name: `<${key}>`,
|
||||
object,
|
||||
equal: ": ",
|
||||
delim: i < keys.length - 1 ? ", " : ""
|
||||
delim: i < keys.length - 1 ? ", " : "",
|
||||
suppressQuotes: true
|
||||
}));
|
||||
});
|
||||
},
|
||||
@ -2136,11 +2180,11 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
}, " }"));
|
||||
}
|
||||
|
||||
const props = this.getProps(promiseState);
|
||||
const propsArray = this.getProps(promiseState);
|
||||
return span({ className: "objectBox objectBox-object" }, this.getTitle(object), objectLink({
|
||||
className: "objectLeftBrace",
|
||||
object: object
|
||||
}, " { "), ...props, objectLink({
|
||||
}, " { "), ...propsArray, objectLink({
|
||||
className: "objectRightBrace",
|
||||
object: object
|
||||
}, " }"));
|
||||
@ -2456,7 +2500,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
draggable: false,
|
||||
// TODO: Localize this with "openNodeInInspector" when Bug 1317038 lands
|
||||
title: "Click to select the node in the inspector",
|
||||
onClick: () => onInspectIconClick(object)
|
||||
onClick: e => onInspectIconClick(object, e)
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -2747,7 +2791,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
draggable: false,
|
||||
// TODO: Localize this with "openNodeInInspector" when Bug 1317038 lands
|
||||
title: "Click to select the node in the inspector",
|
||||
onClick: () => onInspectIconClick(grip)
|
||||
onClick: e => onInspectIconClick(grip, e)
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -3404,7 +3448,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
|
||||
render: wrapRender(function () {
|
||||
let object = this.props.object;
|
||||
let props = this.safeEntriesIterator(object, this.props.mode === MODE.LONG ? 10 : 3);
|
||||
let propsArray = this.safeEntriesIterator(object, this.props.mode === MODE.LONG ? 10 : 3);
|
||||
|
||||
let objectLink = this.props.objectLink || span;
|
||||
if (this.props.mode === MODE.TINY) {
|
||||
@ -3417,7 +3461,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||
return span({ className: "objectBox objectBox-object" }, this.getTitle(object), objectLink({
|
||||
className: "objectLeftBrace",
|
||||
object: object
|
||||
}, " { "), props, objectLink({
|
||||
}, " { "), propsArray, objectLink({
|
||||
className: "objectRightBrace",
|
||||
object: object
|
||||
}, " }"));
|
||||
|
@ -14,8 +14,8 @@ Test ArrayRep rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
"use strict";
|
||||
/* import-globals-from head.js */
|
||||
|
||||
|
@ -14,8 +14,8 @@ Test Attribute rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
window.onload = Task.async(function* () {
|
||||
try {
|
||||
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
|
@ -14,8 +14,8 @@ Test comment-node rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
"use strict";
|
||||
|
||||
window.onload = Task.async(function* () {
|
||||
|
@ -14,8 +14,8 @@ Test DateTime rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
window.onload = Task.async(function* () {
|
||||
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { Rep, DateTime } = REPS;
|
||||
|
@ -14,8 +14,8 @@ Test Document rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
window.onload = Task.async(function* () {
|
||||
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { Rep, Document } = REPS;
|
||||
|
@ -14,8 +14,8 @@ Test Element node rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
"use strict";
|
||||
|
||||
window.onload = Task.async(function* () {
|
||||
@ -233,8 +233,11 @@ window.onload = Task.async(function* () {
|
||||
const attachedActorIds = getStubAttachedActorIds(grips);
|
||||
|
||||
let inspectIconClickedValue = null;
|
||||
let onInspectIconClick = (object) => {
|
||||
let inspectIconClickedEvent = null;
|
||||
|
||||
let onInspectIconClick = (object, event) => {
|
||||
inspectIconClickedValue = object;
|
||||
inspectIconClickedEvent = event;
|
||||
};
|
||||
|
||||
const renderedComponentWithoutInspectIcon = renderComponent(ElementNode.rep, {
|
||||
@ -265,6 +268,8 @@ window.onload = Task.async(function* () {
|
||||
|
||||
is(inspectIconClickedValue, grips[0],
|
||||
"onInspectIconClick is called with expected value when inspect icon is clicked");
|
||||
ok(inspectIconClickedEvent !== null && inspectIconClickedEvent.type === "click",
|
||||
"onInspectIconClick forwarded the original event to the callback");
|
||||
}
|
||||
|
||||
function getGripStub(name) {
|
||||
|
@ -14,8 +14,8 @@ Test Error rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
"use strict";
|
||||
|
||||
window.onload = Task.async(function* () {
|
||||
|
@ -14,8 +14,8 @@ Test Event rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
window.onload = Task.async(function* () {
|
||||
const {
|
||||
REPS,
|
||||
|
@ -14,8 +14,8 @@ Test fallback for rep rendering when a rep fails to render.
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
window.onload = Task.async(function* () {
|
||||
try {
|
||||
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
|
@ -14,8 +14,8 @@ Test Func rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
window.onload = Task.async(function* () {
|
||||
const { REPS, MODE } = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { Rep, Func } = REPS;
|
||||
|
@ -14,8 +14,8 @@ Test GripArray rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
window.onload = Task.async(function* () {
|
||||
const {
|
||||
REPS,
|
||||
|
@ -14,8 +14,8 @@ Test GripMap rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
"use strict";
|
||||
|
||||
window.onload = Task.async(function* () {
|
||||
@ -156,7 +156,7 @@ window.onload = Task.async(function* () {
|
||||
// `new Map([["key-a","value-a"], ["key-b","value-b"], ["key-c","value-c"]])`
|
||||
const testName = "testMaxEntries";
|
||||
|
||||
const defaultOutput = `Map { key-a: "value-a", key-b: "value-b", key-c: "value-c" }`;
|
||||
const defaultOutput = `Map { "key-a": "value-a", "key-b": "value-b", "key-c": "value-c" }`;
|
||||
|
||||
const modeTests = [
|
||||
{
|
||||
@ -186,10 +186,10 @@ window.onload = Task.async(function* () {
|
||||
const testName = "testMoreThanMaxEntries";
|
||||
|
||||
const defaultOutput =
|
||||
`Map { key-0: "value-0", key-1: "value-1", key-2: "value-2", 98 more… }`;
|
||||
`Map { "key-0": "value-0", "key-1": "value-1", "key-2": "value-2", 98 more… }`;
|
||||
|
||||
// Generate string with 101 entries, which is the max limit for 'long' mode.
|
||||
let longString = Array.from({length: 10}).map((_, i) => `key-${i}: "value-${i}"`);
|
||||
let longString = Array.from({length: 10}).map((_, i) => `"key-${i}": "value-${i}"`);
|
||||
const longOutput = `Map { ${longString.join(", ")}, 91 more… }`;
|
||||
|
||||
const modeTests = [
|
||||
@ -220,9 +220,9 @@ window.onload = Task.async(function* () {
|
||||
const testName = "testUninterestingEntries";
|
||||
|
||||
const defaultOutput =
|
||||
`Map { key-a: null, key-c: "value-c", key-d: 4, 1 more… }`;
|
||||
`Map { "key-a": null, "key-c": "value-c", "key-d": 4, 1 more… }`;
|
||||
const longOutput =
|
||||
`Map { key-a: null, key-b: undefined, key-c: "value-c", key-d: 4 }`;
|
||||
`Map { "key-a": null, "key-b": undefined, "key-c": "value-c", "key-d": 4 }`;
|
||||
|
||||
const modeTests = [
|
||||
{
|
||||
|
@ -14,8 +14,8 @@ Test grip rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
window.onload = Task.async(function* () {
|
||||
const {
|
||||
REPS,
|
||||
|
@ -14,8 +14,8 @@ Test Infinity rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
"use strict";
|
||||
|
||||
window.onload = Task.async(function* () {
|
||||
|
@ -14,8 +14,8 @@ Test LongString rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
window.onload = Task.async(function* () {
|
||||
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { Rep, LongStringRep } = REPS;
|
||||
|
@ -14,8 +14,8 @@ Test NaN rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
"use strict";
|
||||
|
||||
window.onload = Task.async(function* () {
|
||||
|
@ -14,8 +14,8 @@ Test Null rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
window.onload = Task.async(function* () {
|
||||
try {
|
||||
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
|
@ -14,8 +14,8 @@ Test Number rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
window.onload = Task.async(function* () {
|
||||
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { Rep, Number } = REPS;
|
||||
|
@ -14,8 +14,8 @@ Test ObjectWithText rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
window.onload = Task.async(function* () {
|
||||
try {
|
||||
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
|
@ -14,8 +14,8 @@ Test ObjectWithURL rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
window.onload = Task.async(function* () {
|
||||
try {
|
||||
let ReactDOM = browserRequire("devtools/client/shared/vendor/react-dom");
|
||||
|
@ -14,8 +14,8 @@ Test Obj rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
window.onload = Task.async(function* () {
|
||||
const { REPS, MODE } = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { Rep, Obj } = REPS;
|
||||
@ -30,6 +30,9 @@ window.onload = Task.async(function* () {
|
||||
yield testMoreThanMaxProps();
|
||||
yield testUninterestingProps();
|
||||
|
||||
// Test that unusual property names are escaped.
|
||||
yield testEscapedPropertyNames();
|
||||
|
||||
// Test that properties are rendered as expected by PropRep
|
||||
yield testNested();
|
||||
|
||||
@ -159,6 +162,32 @@ window.onload = Task.async(function* () {
|
||||
testRepRenderModes(modeTests, "testUninterestingProps", componentUnderTest, stub);
|
||||
}
|
||||
|
||||
function testEscapedPropertyNames() {
|
||||
const stub = {"":1, "quote-this":2, noquotes:3};
|
||||
const defaultOutput = `Object { "": 1, "quote-this": 2, noquotes: 3 }`;
|
||||
|
||||
const modeTests = [
|
||||
{
|
||||
mode: undefined,
|
||||
expectedOutput: defaultOutput,
|
||||
},
|
||||
{
|
||||
mode: MODE.TINY,
|
||||
expectedOutput: `Object`,
|
||||
},
|
||||
{
|
||||
mode: MODE.SHORT,
|
||||
expectedOutput: defaultOutput,
|
||||
},
|
||||
{
|
||||
mode: MODE.LONG,
|
||||
expectedOutput: defaultOutput,
|
||||
}
|
||||
];
|
||||
|
||||
testRepRenderModes(modeTests, "testEscapedPropertyNames", componentUnderTest, stub);
|
||||
}
|
||||
|
||||
function testNested() {
|
||||
const stub = {
|
||||
objProp: {
|
||||
|
@ -14,8 +14,8 @@ Test Promise rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
"use strict";
|
||||
|
||||
window.onload = Task.async(function* () {
|
||||
|
@ -14,8 +14,8 @@ Test RegExp rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
window.onload = Task.async(function* () {
|
||||
try {
|
||||
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
|
@ -14,8 +14,8 @@ Test String rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
window.onload = Task.async(function* () {
|
||||
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
let { Rep, StringRep } = REPS;
|
||||
|
@ -14,8 +14,8 @@ Test Stylesheet rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
window.onload = Task.async(function* () {
|
||||
try {
|
||||
const { REPS } = browserRequire("devtools/client/shared/components/reps/reps");
|
||||
|
@ -14,8 +14,8 @@ Test Symbol rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
"use strict";
|
||||
/* import-globals-from head.js */
|
||||
|
||||
|
@ -14,8 +14,8 @@ Test text-node rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
"use strict";
|
||||
|
||||
window.onload = Task.async(function* () {
|
||||
@ -172,8 +172,11 @@ window.onload = Task.async(function* () {
|
||||
const attachedActorIds = getStubAttachedActorIds(grips);
|
||||
|
||||
let inspectIconClickedValue = null;
|
||||
let onInspectIconClick = (object) => {
|
||||
let inspectIconClickedEvent = null;
|
||||
|
||||
let onInspectIconClick = (object, event) => {
|
||||
inspectIconClickedValue = object;
|
||||
inspectIconClickedEvent = event;
|
||||
};
|
||||
|
||||
const renderedComponentWithoutInspectIcon = renderComponent(TextNode.rep, {
|
||||
@ -196,6 +199,8 @@ window.onload = Task.async(function* () {
|
||||
|
||||
is(inspectIconClickedValue, grips[0],
|
||||
"onInspectIconClick is called with expected value when inspect icon is clicked");
|
||||
ok(inspectIconClickedEvent !== null && inspectIconClickedEvent.type === "click",
|
||||
"onInspectIconClick forwarded the original event to the callback");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
@ -14,8 +14,8 @@ Test undefined rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
window.onload = Task.async(function* () {
|
||||
try {
|
||||
let ReactDOM = browserRequire("devtools/client/shared/vendor/react-dom");
|
||||
|
@ -14,8 +14,8 @@ Test window rep
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="head.js" type="application/javascript"></script>
|
||||
<script type="application/javascript">
|
||||
<script src="head.js" type="application/javascript;version=1.8"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
window.onload = Task.async(function* () {
|
||||
try {
|
||||
let ReactDOM = browserRequire("devtools/client/shared/vendor/react-dom");
|
||||
|
@ -50,7 +50,18 @@ function ChromeActor(connection) {
|
||||
if (!window) {
|
||||
window = Services.wm.getMostRecentWindow(null);
|
||||
}
|
||||
// On xpcshell, there is no window/docshell
|
||||
|
||||
// We really want _some_ window at least, so fallback to the hidden window if
|
||||
// there's nothing else (such as during early startup).
|
||||
if (!window) {
|
||||
try {
|
||||
window = Services.appShell.hiddenDOMWindow;
|
||||
} catch (e) {
|
||||
// On XPCShell, the above line will throw.
|
||||
}
|
||||
}
|
||||
|
||||
// On XPCShell, there is no window/docshell
|
||||
let docShell = window ? window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDocShell)
|
||||
: null;
|
||||
|
@ -1020,8 +1020,8 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
|
||||
|
||||
let packet = this._resumed();
|
||||
this._popThreadPause();
|
||||
// Tell anyone who cares of the resume (as of now, that's the xpcshell
|
||||
// harness)
|
||||
// Tell anyone who cares of the resume (as of now, that's the xpcshell harness and
|
||||
// devtools-startup.js when handling the --wait-for-jsdebugger flag)
|
||||
if (Services.obs) {
|
||||
Services.obs.notifyObservers(this, "devtools-thread-resumed", null);
|
||||
}
|
||||
|
@ -3223,6 +3223,7 @@ exports.CSS_PROPERTIES = {
|
||||
"dialog",
|
||||
"difference",
|
||||
"disabled",
|
||||
"distribute",
|
||||
"dotted",
|
||||
"double",
|
||||
"drag",
|
||||
@ -3283,6 +3284,8 @@ exports.CSS_PROPERTIES = {
|
||||
"inline-table",
|
||||
"inset",
|
||||
"inside",
|
||||
"inter-character",
|
||||
"inter-word",
|
||||
"intersect",
|
||||
"isolate",
|
||||
"italic",
|
||||
@ -8812,6 +8815,23 @@ exports.CSS_PROPERTIES = {
|
||||
"unset"
|
||||
]
|
||||
},
|
||||
"text-justify": {
|
||||
"isInherited": true,
|
||||
"subproperties": [
|
||||
"text-justify"
|
||||
],
|
||||
"supports": [],
|
||||
"values": [
|
||||
"auto",
|
||||
"distribute",
|
||||
"inherit",
|
||||
"initial",
|
||||
"inter-character",
|
||||
"inter-word",
|
||||
"none",
|
||||
"unset"
|
||||
]
|
||||
},
|
||||
"text-orientation": {
|
||||
"isInherited": true,
|
||||
"subproperties": [
|
||||
|
@ -428,8 +428,8 @@ nsDSURIContentListener::CheckFrameOptions(nsIRequest* aRequest)
|
||||
}
|
||||
|
||||
nsAutoCString xfoHeaderCValue;
|
||||
httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("X-Frame-Options"),
|
||||
xfoHeaderCValue);
|
||||
Unused << httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("X-Frame-Options"),
|
||||
xfoHeaderCValue);
|
||||
NS_ConvertUTF8toUTF16 xfoHeaderValue(xfoHeaderCValue);
|
||||
|
||||
// if no header value, there's nothing to do.
|
||||
|
@ -541,24 +541,31 @@ SendPing(void* aClosure, nsIContent* aContent, nsIURI* aURI,
|
||||
|
||||
// This is needed in order for 3rd-party cookie blocking to work.
|
||||
nsCOMPtr<nsIHttpChannelInternal> httpInternal = do_QueryInterface(httpChan);
|
||||
nsresult rv;
|
||||
if (httpInternal) {
|
||||
httpInternal->SetDocumentURI(doc->GetDocumentURI());
|
||||
rv = httpInternal->SetDocumentURI(doc->GetDocumentURI());
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
|
||||
httpChan->SetRequestMethod(NS_LITERAL_CSTRING("POST"));
|
||||
rv = httpChan->SetRequestMethod(NS_LITERAL_CSTRING("POST"));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
// Remove extraneous request headers (to reduce request size)
|
||||
httpChan->SetRequestHeader(NS_LITERAL_CSTRING("accept"),
|
||||
EmptyCString(), false);
|
||||
httpChan->SetRequestHeader(NS_LITERAL_CSTRING("accept-language"),
|
||||
EmptyCString(), false);
|
||||
httpChan->SetRequestHeader(NS_LITERAL_CSTRING("accept-encoding"),
|
||||
EmptyCString(), false);
|
||||
rv = httpChan->SetRequestHeader(NS_LITERAL_CSTRING("accept"),
|
||||
EmptyCString(), false);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
rv = httpChan->SetRequestHeader(NS_LITERAL_CSTRING("accept-language"),
|
||||
EmptyCString(), false);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
rv = httpChan->SetRequestHeader(NS_LITERAL_CSTRING("accept-encoding"),
|
||||
EmptyCString(), false);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
// Always send a Ping-To header.
|
||||
nsAutoCString pingTo;
|
||||
if (NS_SUCCEEDED(info->target->GetSpec(pingTo))) {
|
||||
httpChan->SetRequestHeader(NS_LITERAL_CSTRING("Ping-To"), pingTo, false);
|
||||
rv = httpChan->SetRequestHeader(NS_LITERAL_CSTRING("Ping-To"), pingTo, false);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIScriptSecurityManager> sm =
|
||||
@ -567,7 +574,7 @@ SendPing(void* aClosure, nsIContent* aContent, nsIURI* aURI,
|
||||
if (sm && info->referrer) {
|
||||
bool referrerIsSecure;
|
||||
uint32_t flags = nsIProtocolHandler::URI_SAFE_TO_LOAD_IN_SECURE_CONTEXT;
|
||||
nsresult rv = NS_URIChainHasFlags(info->referrer, flags, &referrerIsSecure);
|
||||
rv = NS_URIChainHasFlags(info->referrer, flags, &referrerIsSecure);
|
||||
|
||||
// Default to sending less data if NS_URIChainHasFlags() fails.
|
||||
referrerIsSecure = NS_FAILED(rv) || referrerIsSecure;
|
||||
@ -582,8 +589,9 @@ SendPing(void* aClosure, nsIContent* aContent, nsIURI* aURI,
|
||||
if (sameOrigin || !referrerIsSecure) {
|
||||
nsAutoCString pingFrom;
|
||||
if (NS_SUCCEEDED(info->referrer->GetSpec(pingFrom))) {
|
||||
httpChan->SetRequestHeader(NS_LITERAL_CSTRING("Ping-From"), pingFrom,
|
||||
false);
|
||||
rv = httpChan->SetRequestHeader(NS_LITERAL_CSTRING("Ping-From"),
|
||||
pingFrom, false);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
}
|
||||
|
||||
@ -591,7 +599,8 @@ SendPing(void* aClosure, nsIContent* aContent, nsIURI* aURI,
|
||||
// over an encrypted connection and its address does not have the same
|
||||
// origin as "ping URL", send a referrer.
|
||||
if (!sameOrigin && !referrerIsSecure) {
|
||||
httpChan->SetReferrerWithPolicy(info->referrer, info->referrerPolicy);
|
||||
rv = httpChan->SetReferrerWithPolicy(info->referrer, info->referrerPolicy);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
}
|
||||
|
||||
@ -7505,7 +7514,7 @@ nsDocShell::OnRedirectStateChange(nsIChannel* aOldChannel,
|
||||
uint32_t responseStatus = 0;
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aOldChannel);
|
||||
if (httpChannel) {
|
||||
(void)httpChannel->GetResponseStatus(&responseStatus);
|
||||
Unused << httpChannel->GetResponseStatus(&responseStatus);
|
||||
}
|
||||
|
||||
// Add visit N -1 => N
|
||||
@ -11150,16 +11159,20 @@ nsDocShell::DoURILoad(nsIURI* aURI,
|
||||
do_QueryInterface(channel));
|
||||
if (httpChannelInternal) {
|
||||
if (aForceAllowCookies) {
|
||||
httpChannelInternal->SetThirdPartyFlags(
|
||||
rv = httpChannelInternal->SetThirdPartyFlags(
|
||||
nsIHttpChannelInternal::THIRD_PARTY_FORCE_ALLOW);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
if (aFirstParty) {
|
||||
httpChannelInternal->SetDocumentURI(aURI);
|
||||
rv = httpChannelInternal->SetDocumentURI(aURI);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
} else {
|
||||
httpChannelInternal->SetDocumentURI(aReferrerURI);
|
||||
rv = httpChannelInternal->SetDocumentURI(aReferrerURI);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
httpChannelInternal->SetRedirectMode(
|
||||
rv = httpChannelInternal->SetRedirectMode(
|
||||
nsIHttpChannelInternal::REDIRECT_MODE_MANUAL);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWritablePropertyBag2> props(do_QueryInterface(channel));
|
||||
@ -11240,7 +11253,8 @@ nsDocShell::DoURILoad(nsIURI* aURI,
|
||||
// Set the referrer explicitly
|
||||
if (aReferrerURI && aSendReferrer) {
|
||||
// Referrer is currenly only set for link clicks here.
|
||||
httpChannel->SetReferrerWithPolicy(aReferrerURI, aReferrerPolicy);
|
||||
rv = httpChannel->SetReferrerWithPolicy(aReferrerURI, aReferrerPolicy);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
}
|
||||
|
||||
@ -12332,8 +12346,10 @@ nsDocShell::AddToSessionHistory(nsIURI* aURI, nsIChannel* aChannel,
|
||||
uint32_t loadFlags;
|
||||
aChannel->GetLoadFlags(&loadFlags);
|
||||
loadReplace = loadFlags & nsIChannel::LOAD_REPLACE;
|
||||
httpChannel->GetReferrer(getter_AddRefs(referrerURI));
|
||||
httpChannel->GetReferrerPolicy(&referrerPolicy);
|
||||
rv = httpChannel->GetReferrer(getter_AddRefs(referrerURI));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
rv = httpChannel->GetReferrerPolicy(&referrerPolicy);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
discardLayoutState = ShouldDiscardLayoutState(httpChannel);
|
||||
}
|
||||
@ -12975,7 +12991,7 @@ nsDocShell::ShouldDiscardLayoutState(nsIHttpChannel* aChannel)
|
||||
|
||||
// figure out if SH should be saving layout state
|
||||
bool noStore = false;
|
||||
aChannel->IsNoStoreResponse(&noStore);
|
||||
Unused << aChannel->IsNoStoreResponse(&noStore);
|
||||
return noStore;
|
||||
}
|
||||
|
||||
@ -13047,7 +13063,7 @@ nsDocShell::ChannelIsPost(nsIChannel* aChannel)
|
||||
}
|
||||
|
||||
nsAutoCString method;
|
||||
httpChannel->GetRequestMethod(method);
|
||||
Unused << httpChannel->GetRequestMethod(method);
|
||||
return method.EqualsLiteral("POST");
|
||||
}
|
||||
|
||||
|
@ -224,7 +224,7 @@ void
|
||||
Element::UpdateState(bool aNotify)
|
||||
{
|
||||
EventStates oldState = mState;
|
||||
mState = IntrinsicState() | (oldState & ESM_MANAGED_STATES);
|
||||
mState = IntrinsicState() | (oldState & EXTERNALLY_MANAGED_STATES);
|
||||
if (aNotify) {
|
||||
EventStates changedStates = oldState ^ mState;
|
||||
if (!changedStates.IsEmpty()) {
|
||||
|
@ -515,24 +515,39 @@ private:
|
||||
EventStates StyleStateFromLocks() const;
|
||||
|
||||
protected:
|
||||
// Methods for the ESM to manage state bits. These will handle
|
||||
// setting up script blockers when they notify, so no need to do it
|
||||
// in the callers unless desired.
|
||||
// Methods for the ESM, nsGlobalWindow and focus manager to manage state bits.
|
||||
// These will handle setting up script blockers when they notify, so no need
|
||||
// to do it in the callers unless desired. States passed here must only be
|
||||
// those in EXTERNALLY_MANAGED_STATES.
|
||||
virtual void AddStates(EventStates aStates)
|
||||
{
|
||||
NS_PRECONDITION(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES),
|
||||
"Should only be adding ESM-managed states here");
|
||||
"Should only be adding externally-managed states here");
|
||||
AddStatesSilently(aStates);
|
||||
NotifyStateChange(aStates);
|
||||
}
|
||||
virtual void RemoveStates(EventStates aStates)
|
||||
{
|
||||
NS_PRECONDITION(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES),
|
||||
"Should only be removing ESM-managed states here");
|
||||
"Should only be removing externally-managed states here");
|
||||
RemoveStatesSilently(aStates);
|
||||
NotifyStateChange(aStates);
|
||||
}
|
||||
public:
|
||||
// Public methods to manage state bits in MANUALLY_MANAGED_STATES.
|
||||
void AddManuallyManagedStates(EventStates aStates)
|
||||
{
|
||||
MOZ_ASSERT(MANUALLY_MANAGED_STATES.HasAllStates(aStates),
|
||||
"Should only be adding manually-managed states here");
|
||||
AddStates(aStates);
|
||||
}
|
||||
void RemoveManuallyManagedStates(EventStates aStates)
|
||||
{
|
||||
MOZ_ASSERT(MANUALLY_MANAGED_STATES.HasAllStates(aStates),
|
||||
"Should only be removing manually-managed states here");
|
||||
RemoveStates(aStates);
|
||||
}
|
||||
|
||||
virtual void UpdateEditableState(bool aNotify) override;
|
||||
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
|
@ -995,18 +995,22 @@ EventSourceImpl::SetupHttpChannel()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(!IsShutDown());
|
||||
mHttpChannel->SetRequestMethod(NS_LITERAL_CSTRING("GET"));
|
||||
DebugOnly<nsresult> rv =
|
||||
mHttpChannel->SetRequestMethod(NS_LITERAL_CSTRING("GET"));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
/* set the http request headers */
|
||||
|
||||
mHttpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
|
||||
rv = mHttpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
|
||||
NS_LITERAL_CSTRING(TEXT_EVENT_STREAM), false);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
// LOAD_BYPASS_CACHE already adds the Cache-Control: no-cache header
|
||||
|
||||
if (!mLastEventID.IsEmpty()) {
|
||||
mHttpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Last-Event-ID"),
|
||||
rv = mHttpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Last-Event-ID"),
|
||||
NS_ConvertUTF16toUTF8(mLastEventID), false);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1349,7 +1349,8 @@ Navigator::SendBeaconInternal(const nsAString& aUrl,
|
||||
aRv.Throw(NS_ERROR_DOM_BAD_URI);
|
||||
return false;
|
||||
}
|
||||
httpChannel->SetReferrer(documentURI);
|
||||
rv = httpChannel->SetReferrer(documentURI);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
nsCOMPtr<nsIInputStream> in;
|
||||
nsAutoCString contentTypeWithCharset;
|
||||
@ -1379,7 +1380,8 @@ Navigator::SendBeaconInternal(const nsAString& aUrl,
|
||||
NS_LITERAL_CSTRING("POST"),
|
||||
false);
|
||||
} else {
|
||||
httpChannel->SetRequestMethod(NS_LITERAL_CSTRING("POST"));
|
||||
rv = httpChannel->SetRequestMethod(NS_LITERAL_CSTRING("POST"));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(channel);
|
||||
|
@ -894,7 +894,8 @@ nsContentSink::PrefetchDNS(const nsAString &aHref)
|
||||
}
|
||||
|
||||
if (!hostname.IsEmpty() && nsHTMLDNSPrefetch::IsAllowed(mDocument)) {
|
||||
nsHTMLDNSPrefetch::PrefetchLow(hostname);
|
||||
nsHTMLDNSPrefetch::PrefetchLow(hostname,
|
||||
mDocument->NodePrincipal()->OriginAttributesRef());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4094,6 +4094,70 @@ nsDOMWindowUtils::IsTimeoutTracking(uint32_t aTimeoutId, bool* aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
struct StateTableEntry
|
||||
{
|
||||
const char* mStateString;
|
||||
EventStates mState;
|
||||
};
|
||||
|
||||
static constexpr StateTableEntry kManuallyManagedStates[] = {
|
||||
// none yet; but for example: { "highlight", NS_EVENT_STATE_HIGHLIGHT },
|
||||
{ nullptr, EventStates() },
|
||||
};
|
||||
|
||||
static_assert(!kManuallyManagedStates[ArrayLength(kManuallyManagedStates) - 1]
|
||||
.mStateString,
|
||||
"last kManuallyManagedStates entry must be a sentinel with "
|
||||
"mStateString == nullptr");
|
||||
|
||||
static EventStates
|
||||
GetEventStateForString(const nsAString& aStateString)
|
||||
{
|
||||
for (const StateTableEntry* entry = kManuallyManagedStates;
|
||||
entry->mStateString; ++entry) {
|
||||
if (aStateString.EqualsASCII(entry->mStateString)) {
|
||||
return entry->mState;
|
||||
}
|
||||
}
|
||||
return EventStates();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::AddManuallyManagedState(nsIDOMElement* aElement,
|
||||
const nsAString& aStateString)
|
||||
{
|
||||
nsCOMPtr<Element> element = do_QueryInterface(aElement);
|
||||
if (!element) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
EventStates state = GetEventStateForString(aStateString);
|
||||
if (state.IsEmpty()) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
element->AddManuallyManagedStates(state);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::RemoveManuallyManagedState(nsIDOMElement* aElement,
|
||||
const nsAString& aStateString)
|
||||
{
|
||||
nsCOMPtr<Element> element = do_QueryInterface(aElement);
|
||||
if (!element) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
EventStates state = GetEventStateForString(aStateString);
|
||||
if (state.IsEmpty()) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
element->RemoveManuallyManagedStates(state);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsTranslationNodeList)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_ENTRY(nsITranslationNodeList)
|
||||
|
@ -2638,11 +2638,11 @@ nsDocument::InitCSP(nsIChannel* aChannel)
|
||||
}
|
||||
|
||||
if (httpChannel) {
|
||||
httpChannel->GetResponseHeader(
|
||||
Unused << httpChannel->GetResponseHeader(
|
||||
NS_LITERAL_CSTRING("content-security-policy"),
|
||||
tCspHeaderValue);
|
||||
|
||||
httpChannel->GetResponseHeader(
|
||||
Unused << httpChannel->GetResponseHeader(
|
||||
NS_LITERAL_CSTRING("content-security-policy-report-only"),
|
||||
tCspROHeaderValue);
|
||||
}
|
||||
@ -4796,7 +4796,8 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
|
||||
do_QueryInterface(GetChannel());
|
||||
if (internalChannel) {
|
||||
nsCOMArray<nsISecurityConsoleMessage> messages;
|
||||
internalChannel->TakeAllSecurityMessages(messages);
|
||||
DebugOnly<nsresult> rv = internalChannel->TakeAllSecurityMessages(messages);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
SendToConsole(messages);
|
||||
}
|
||||
|
||||
|
@ -1132,6 +1132,7 @@ GK_ATOM(scrollbarUpTop, "scrollbar-up-top")
|
||||
GK_ATOM(scrollbox, "scrollbox")
|
||||
GK_ATOM(scrollcorner, "scrollcorner")
|
||||
GK_ATOM(scrolling, "scrolling")
|
||||
GK_ATOM(scrollPosition, "scroll-position")
|
||||
GK_ATOM(section, "section")
|
||||
GK_ATOM(select, "select")
|
||||
GK_ATOM(selectable, "selectable")
|
||||
|
@ -2599,8 +2599,9 @@ nsObjectLoadingContent::OpenChannel()
|
||||
// Referrer
|
||||
nsCOMPtr<nsIHttpChannel> httpChan(do_QueryInterface(chan));
|
||||
if (httpChan) {
|
||||
httpChan->SetReferrerWithPolicy(doc->GetDocumentURI(),
|
||||
doc->GetReferrerPolicy());
|
||||
rv = httpChan->SetReferrerWithPolicy(doc->GetDocumentURI(),
|
||||
doc->GetReferrerPolicy());
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
// Set the initiator type
|
||||
nsCOMPtr<nsITimedChannel> timedChannel(do_QueryInterface(httpChan));
|
||||
|
@ -1298,15 +1298,18 @@ nsScriptLoader::StartLoad(nsScriptLoadRequest *aRequest)
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
|
||||
if (httpChannel) {
|
||||
// HTTP content negotation has little value in this context.
|
||||
httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
|
||||
NS_LITERAL_CSTRING("*/*"),
|
||||
false);
|
||||
httpChannel->SetReferrerWithPolicy(mDocument->GetDocumentURI(),
|
||||
aRequest->mReferrerPolicy);
|
||||
rv = httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
|
||||
NS_LITERAL_CSTRING("*/*"),
|
||||
false);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
rv = httpChannel->SetReferrerWithPolicy(mDocument->GetDocumentURI(),
|
||||
aRequest->mReferrerPolicy);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
nsCOMPtr<nsIHttpChannelInternal> internalChannel(do_QueryInterface(httpChannel));
|
||||
if (internalChannel) {
|
||||
internalChannel->SetIntegrityMetadata(aRequest->mIntegrity.GetIntegrityString());
|
||||
rv = internalChannel->SetIntegrityMetadata(aRequest->mIntegrity.GetIntegrityString());
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,15 +143,17 @@ nsSyncLoader::LoadDocument(nsIChannel* aChannel,
|
||||
mChannel = aChannel;
|
||||
nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(mChannel);
|
||||
if (http) {
|
||||
http->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
|
||||
NS_LITERAL_CSTRING("text/xml,application/xml,application/xhtml+xml,*/*;q=0.1"),
|
||||
false);
|
||||
rv = http->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
|
||||
NS_LITERAL_CSTRING("text/xml,application/xml,application/xhtml+xml,*/*;q=0.1"),
|
||||
false);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
|
||||
if (loadInfo) {
|
||||
nsCOMPtr<nsIURI> loaderUri;
|
||||
loadInfo->TriggeringPrincipal()->GetURI(getter_AddRefs(loaderUri));
|
||||
if (loaderUri) {
|
||||
http->SetReferrerWithPolicy(loaderUri, aReferrerPolicy);
|
||||
rv = http->SetReferrerWithPolicy(loaderUri, aReferrerPolicy);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -314,12 +314,34 @@ private:
|
||||
|
||||
#define DIRECTION_STATES (NS_EVENT_STATE_LTR | NS_EVENT_STATE_RTL)
|
||||
|
||||
#define ESM_MANAGED_STATES (NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS | \
|
||||
NS_EVENT_STATE_HOVER | NS_EVENT_STATE_DRAGOVER | \
|
||||
NS_EVENT_STATE_URLTARGET | NS_EVENT_STATE_FOCUSRING | \
|
||||
NS_EVENT_STATE_FULL_SCREEN | NS_EVENT_STATE_UNRESOLVED | \
|
||||
NS_EVENT_STATE_FOCUS_WITHIN)
|
||||
// Event states that can be added and removed through
|
||||
// Element::{Add,Remove}ManuallyManagedStates.
|
||||
//
|
||||
// Take care when manually managing state bits. You are responsible for
|
||||
// setting or clearing the bit when an Element is added or removed from a
|
||||
// document (e.g. in BindToTree and UnbindFromTree), if that is an
|
||||
// appropriate thing to do for your state bit.
|
||||
#define MANUALLY_MANAGED_STATES ( \
|
||||
mozilla::EventStates() /* none so far */ \
|
||||
)
|
||||
|
||||
#define INTRINSIC_STATES (~ESM_MANAGED_STATES)
|
||||
// Event states that are managed externally to an element (by the
|
||||
// EventStateManager, or by other code). As opposed to those in
|
||||
// INTRINSIC_STATES, which are are computed by the element itself
|
||||
// and returned from Element::IntrinsicState.
|
||||
#define EXTERNALLY_MANAGED_STATES ( \
|
||||
MANUALLY_MANAGED_STATES | \
|
||||
NS_EVENT_STATE_ACTIVE | \
|
||||
NS_EVENT_STATE_DRAGOVER | \
|
||||
NS_EVENT_STATE_FOCUS | \
|
||||
NS_EVENT_STATE_FOCUSRING | \
|
||||
NS_EVENT_STATE_FOCUS_WITHIN | \
|
||||
NS_EVENT_STATE_FULL_SCREEN | \
|
||||
NS_EVENT_STATE_HOVER | \
|
||||
NS_EVENT_STATE_UNRESOLVED | \
|
||||
NS_EVENT_STATE_URLTARGET \
|
||||
)
|
||||
|
||||
#define INTRINSIC_STATES (~EXTERNALLY_MANAGED_STATES)
|
||||
|
||||
#endif // mozilla_EventStates_h_
|
||||
|
@ -298,11 +298,15 @@ FetchDriver::HttpFetch()
|
||||
|
||||
// Conversion between enumerations is safe due to static asserts in
|
||||
// dom/workers/ServiceWorkerManager.cpp
|
||||
internalChan->SetCorsMode(static_cast<uint32_t>(mRequest->Mode()));
|
||||
internalChan->SetRedirectMode(static_cast<uint32_t>(mRequest->GetRedirectMode()));
|
||||
rv = internalChan->SetCorsMode(static_cast<uint32_t>(mRequest->Mode()));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
rv = internalChan->SetRedirectMode(static_cast<uint32_t>(mRequest->GetRedirectMode()));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
mRequest->MaybeSkipCacheIfPerformingRevalidation();
|
||||
internalChan->SetFetchCacheMode(static_cast<uint32_t>(mRequest->GetCacheMode()));
|
||||
internalChan->SetIntegrityMetadata(mRequest->GetIntegrity());
|
||||
rv = internalChan->SetFetchCacheMode(static_cast<uint32_t>(mRequest->GetCacheMode()));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
rv = internalChan->SetIntegrityMetadata(mRequest->GetIntegrity());
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
|
||||
// Step 5. Proxy authentication will be handled by Necko.
|
||||
@ -451,7 +455,8 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest,
|
||||
|
||||
if (httpChannel) {
|
||||
uint32_t responseStatus;
|
||||
httpChannel->GetResponseStatus(&responseStatus);
|
||||
rv = httpChannel->GetResponseStatus(&responseStatus);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
if (mozilla::net::nsHttpChannel::IsRedirectStatus(responseStatus)) {
|
||||
if (mRequest->GetRedirectMode() == RequestRedirect::Error) {
|
||||
@ -464,7 +469,8 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest,
|
||||
}
|
||||
|
||||
nsAutoCString statusText;
|
||||
httpChannel->GetResponseStatusText(statusText);
|
||||
rv = httpChannel->GetResponseStatusText(statusText);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
response = new InternalResponse(responseStatus, statusText);
|
||||
|
||||
@ -739,8 +745,8 @@ FetchDriver::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
|
||||
nsCOMPtr<nsIHttpChannel> oldHttpChannel = do_QueryInterface(aOldChannel);
|
||||
nsAutoCString tRPHeaderCValue;
|
||||
if (oldHttpChannel) {
|
||||
oldHttpChannel->GetResponseHeader(NS_LITERAL_CSTRING("referrer-policy"),
|
||||
tRPHeaderCValue);
|
||||
Unused << oldHttpChannel->GetResponseHeader(NS_LITERAL_CSTRING("referrer-policy"),
|
||||
tRPHeaderCValue);
|
||||
}
|
||||
|
||||
// "HTTP-redirect fetch": step 14 "Append locationURL to request's URL list."
|
||||
@ -836,24 +842,32 @@ FetchDriver::SetRequestHeaders(nsIHttpChannel* aChannel) const
|
||||
hasAccept = true;
|
||||
}
|
||||
if (headers[i].mValue.IsEmpty()) {
|
||||
aChannel->SetEmptyRequestHeader(headers[i].mName);
|
||||
DebugOnly<nsresult> rv = aChannel->SetEmptyRequestHeader(headers[i].mName);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
} else {
|
||||
aChannel->SetRequestHeader(headers[i].mName, headers[i].mValue, false /* merge */);
|
||||
DebugOnly<nsresult> rv =
|
||||
aChannel->SetRequestHeader(headers[i].mName, headers[i].mValue,
|
||||
false /* merge */);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasAccept) {
|
||||
aChannel->SetRequestHeader(NS_LITERAL_CSTRING("accept"),
|
||||
NS_LITERAL_CSTRING("*/*"),
|
||||
false /* merge */);
|
||||
DebugOnly<nsresult> rv =
|
||||
aChannel->SetRequestHeader(NS_LITERAL_CSTRING("accept"),
|
||||
NS_LITERAL_CSTRING("*/*"),
|
||||
false /* merge */);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
|
||||
if (mRequest->ForceOriginHeader()) {
|
||||
nsAutoString origin;
|
||||
if (NS_SUCCEEDED(nsContentUtils::GetUTFOrigin(mPrincipal, origin))) {
|
||||
aChannel->SetRequestHeader(NS_LITERAL_CSTRING("origin"),
|
||||
NS_ConvertUTF16toUTF8(origin),
|
||||
false /* merge */);
|
||||
DebugOnly<nsresult> rv =
|
||||
aChannel->SetRequestHeader(NS_LITERAL_CSTRING("origin"),
|
||||
NS_ConvertUTF16toUTF8(origin),
|
||||
false /* merge */);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ FetchUtil::SetRequestReferrer(nsIPrincipal* aPrincipal,
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> referrerURI;
|
||||
aChannel->GetReferrer(getter_AddRefs(referrerURI));
|
||||
Unused << aChannel->GetReferrer(getter_AddRefs(referrerURI));
|
||||
|
||||
// Step 8 https://fetch.spec.whatwg.org/#main-fetch
|
||||
// If request’s referrer is not "no-referrer", set request’s referrer to
|
||||
|
@ -355,7 +355,10 @@ InternalHeaders::FillResponseHeaders(nsIRequest* aRequest)
|
||||
}
|
||||
|
||||
RefPtr<FillHeaders> visitor = new FillHeaders(this);
|
||||
httpChannel->VisitResponseHeaders(visitor);
|
||||
nsresult rv = httpChannel->VisitResponseHeaders(visitor);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("failed to fill headers");
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -291,7 +291,9 @@ HttpServer::TransportProvider::MaybeNotify()
|
||||
RefPtr<TransportProvider> self = this;
|
||||
nsCOMPtr<nsIRunnable> event = NS_NewRunnableFunction([self, this] ()
|
||||
{
|
||||
mListener->OnTransportAvailable(mTransport, mInput, mOutput);
|
||||
DebugOnly<nsresult> rv = mListener->OnTransportAvailable(mTransport,
|
||||
mInput, mOutput);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
});
|
||||
NS_DispatchToCurrentThread(event);
|
||||
}
|
||||
|
@ -693,15 +693,6 @@ nsresult nsGeolocationService::Init()
|
||||
mProvider = new AndroidLocationProvider();
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// GonkGPSGeolocationProvider can be started at boot up time for initialization reasons.
|
||||
// do_getService gets hold of the already initialized component and starts
|
||||
// processing location requests immediately.
|
||||
// do_Createinstance will create multiple instances of the provider which is not right.
|
||||
// bug 993041
|
||||
mProvider = do_GetService(GONK_GPS_GEOLOCATION_PROVIDER_CONTRACTID);
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
#ifdef MOZ_GPSD
|
||||
if (Preferences::GetBool("geo.provider.use_gpsd", false)) {
|
||||
@ -733,11 +724,11 @@ nsresult nsGeolocationService::Init()
|
||||
// "geo.provider.testing" is always set for all plain and browser chrome
|
||||
// mochitests, and also for xpcshell tests.
|
||||
if (!mProvider || Preferences::GetBool("geo.provider.testing", false)) {
|
||||
nsCOMPtr<nsIGeolocationProvider> geo_net_provider =
|
||||
nsCOMPtr<nsIGeolocationProvider> geoTestProvider =
|
||||
do_GetService(NS_GEOLOCATION_PROVIDER_CONTRACTID);
|
||||
|
||||
if (geo_net_provider) {
|
||||
mProvider = geo_net_provider;
|
||||
if (geoTestProvider) {
|
||||
mProvider = geoTestProvider;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include "nsError.h"
|
||||
#include "nsNodeInfoManager.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsXPCOMStrings.h"
|
||||
#include "xpcpublic.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsIThreadInternal.h"
|
||||
@ -517,7 +516,7 @@ HTMLMediaElement::MediaLoadListener::OnStartRequest(nsIRequest* aRequest,
|
||||
if (hc && NS_SUCCEEDED(hc->GetRequestSucceeded(&succeeded)) && !succeeded) {
|
||||
element->NotifyLoadError();
|
||||
uint32_t responseStatus = 0;
|
||||
hc->GetResponseStatus(&responseStatus);
|
||||
Unused << hc->GetResponseStatus(&responseStatus);
|
||||
nsAutoString code;
|
||||
code.AppendInt(responseStatus);
|
||||
nsAutoString src;
|
||||
@ -1169,9 +1168,10 @@ public:
|
||||
// Use a byte range request from the start of the resource.
|
||||
// This enables us to detect if the stream supports byte range
|
||||
// requests, and therefore seeking, early.
|
||||
hc->SetRequestHeader(NS_LITERAL_CSTRING("Range"),
|
||||
NS_LITERAL_CSTRING("bytes=0-"),
|
||||
false);
|
||||
rv = hc->SetRequestHeader(NS_LITERAL_CSTRING("Range"),
|
||||
NS_LITERAL_CSTRING("bytes=0-"),
|
||||
false);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
aElement->SetRequestHeaders(hc);
|
||||
}
|
||||
|
||||
@ -6455,12 +6455,15 @@ void HTMLMediaElement::SetRequestHeaders(nsIHttpChannel* aChannel)
|
||||
// and a length spec in the container are not present either) and from seeking.
|
||||
// So, disable the standard "Accept-Encoding: gzip,deflate" that we usually send.
|
||||
// See bug 614760.
|
||||
aChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept-Encoding"),
|
||||
EmptyCString(), false);
|
||||
DebugOnly<nsresult> rv =
|
||||
aChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept-Encoding"),
|
||||
EmptyCString(), false);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
// Set the Referer header
|
||||
aChannel->SetReferrerWithPolicy(OwnerDoc()->GetDocumentURI(),
|
||||
OwnerDoc()->GetReferrerPolicy());
|
||||
rv = aChannel->SetReferrerWithPolicy(OwnerDoc()->GetDocumentURI(),
|
||||
OwnerDoc()->GetReferrerPolicy());
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
|
||||
void HTMLMediaElement::FireTimeUpdate(bool aPeriodic)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user