зеркало из https://github.com/mozilla/gecko-dev.git
merge autoland to mozilla-central a=merge
This commit is contained in:
Коммит
cec6c3f714
|
@ -55,7 +55,6 @@ b2g/locales/en-US/b2g-l10n.js
|
|||
# browser/ exclusions
|
||||
browser/app/**
|
||||
browser/branding/**/firefox-branding.js
|
||||
browser/base/content/browser-social.js
|
||||
browser/base/content/nsContextMenu.js
|
||||
browser/base/content/sanitizeDialog.js
|
||||
browser/base/content/test/general/file_csp_block_all_mixedcontent.html
|
||||
|
@ -64,8 +63,8 @@ browser/base/content/newtab/**
|
|||
browser/components/downloads/**
|
||||
browser/components/sessionstore/**
|
||||
browser/components/tabview/**
|
||||
# generated files in cld2
|
||||
browser/components/translation/cld2/cld-worker.js
|
||||
# generated & special files in cld2
|
||||
browser/components/translation/cld2/**
|
||||
browser/extensions/pdfjs/content/build**
|
||||
browser/extensions/pdfjs/content/web**
|
||||
# generated or library files in pocket
|
||||
|
|
|
@ -110,8 +110,7 @@ exports.testPreferedOsLocale = function(assert) {
|
|||
prefs.set(PREF_SELECTED_LOCALE, "");
|
||||
prefs.set(PREF_ACCEPT_LANGUAGES, "");
|
||||
|
||||
let expectedLocale = Services.locale.getLocaleComponentForUserAgent().
|
||||
toLowerCase();
|
||||
let expectedLocale = Services.locale.getAppLocale().toLowerCase();
|
||||
let expectedLocaleList = [expectedLocale];
|
||||
|
||||
// Add default "en-us" fallback if the main language is not already en-us
|
||||
|
|
|
@ -1190,20 +1190,8 @@ pref("browser.newtabpage.directory.source", "https://tiles.services.mozilla.com/
|
|||
// endpoint to send newtab click and view pings
|
||||
pref("browser.newtabpage.directory.ping", "https://tiles.services.mozilla.com/v3/links/");
|
||||
|
||||
// activates the remote-hosted newtab page
|
||||
pref("browser.newtabpage.remote", false);
|
||||
|
||||
// remote newtab version targeted
|
||||
pref("browser.newtabpage.remote.version", "1");
|
||||
|
||||
// Toggles endpoints allowed for remote newtab communications
|
||||
pref("browser.newtabpage.remote.mode", "production");
|
||||
|
||||
// content-signature tests for remote newtab
|
||||
pref("browser.newtabpage.remote.content-signing-test", false);
|
||||
|
||||
// verification keys for remote-hosted newtab page
|
||||
pref("browser.newtabpage.remote.keys", "");
|
||||
// activates Activity Stream
|
||||
pref("browser.newtabpage.activity-stream.enabled", false);
|
||||
|
||||
// Enable the DOM fullscreen API.
|
||||
pref("full-screen-api.enabled", true);
|
||||
|
|
|
@ -297,6 +297,7 @@
|
|||
#endif
|
||||
<menuitem id="menu_readerModeItem"
|
||||
observes="View:ReaderView"
|
||||
key="key_toggleReaderMode"
|
||||
hidden="true"/>
|
||||
<menuitem id="menu_showAllTabs"
|
||||
hidden="true"
|
||||
|
|
|
@ -284,7 +284,7 @@
|
|||
<key id="key_fullScreen_old" key="&fullScreenCmd.macCommandKey;" command="View:FullScreen" modifiers="accel,shift"/>
|
||||
<key keycode="VK_F11" command="View:FullScreen"/>
|
||||
#endif
|
||||
<key id="toggleReaderMode" key="&toggleReaderMode.key;" command="View:ReaderView" modifiers="accel,alt" disabled="true"/>
|
||||
<key id="key_toggleReaderMode" key="&toggleReaderMode.key;" command="View:ReaderView" modifiers="accel,alt" disabled="true"/>
|
||||
<key key="&reloadCmd.commandkey;" command="Browser:Reload" modifiers="accel" id="key_reload"/>
|
||||
<key key="&reloadCmd.commandkey;" command="Browser:ReloadSkipCache" modifiers="accel,shift"/>
|
||||
<key id="key_viewSource" key="&pageSourceCmd.commandkey;" command="View:PageSource" modifiers="accel"/>
|
||||
|
|
|
@ -2,12 +2,17 @@
|
|||
* 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/. */
|
||||
|
||||
/* eslint-env mozilla/browser-window */
|
||||
/* eslint no-undef: "error" */
|
||||
/* global OpenGraphBuilder:false, DynamicResizeWatcher:false */
|
||||
|
||||
// the "exported" symbols
|
||||
var SocialUI,
|
||||
SocialShare,
|
||||
SocialActivationListener;
|
||||
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "OpenGraphBuilder", function() {
|
||||
let tmp = {};
|
||||
|
@ -21,6 +26,9 @@ XPCOMUtils.defineLazyGetter(this, "DynamicResizeWatcher", function() {
|
|||
return tmp.DynamicResizeWatcher;
|
||||
});
|
||||
|
||||
let messageManager = window.messageManager;
|
||||
let openUILinkIn = window.openUILinkIn;
|
||||
|
||||
SocialUI = {
|
||||
_initialized: false,
|
||||
|
||||
|
@ -67,16 +75,16 @@ SocialUI = {
|
|||
}
|
||||
},
|
||||
|
||||
_providersChanged: function() {
|
||||
_providersChanged() {
|
||||
SocialShare.populateProviderMenu();
|
||||
},
|
||||
|
||||
showLearnMore: function() {
|
||||
showLearnMore() {
|
||||
let url = Services.urlFormatter.formatURLPref("app.support.baseURL") + "social-api";
|
||||
openUILinkIn(url, "tab");
|
||||
},
|
||||
|
||||
closeSocialPanelForLinkTraversal: function (target, linkNode) {
|
||||
closeSocialPanelForLinkTraversal(target, linkNode) {
|
||||
// No need to close the panel if this traversal was not retargeted
|
||||
if (target == "" || target == "_self")
|
||||
return;
|
||||
|
@ -103,7 +111,7 @@ SocialUI = {
|
|||
// extrachrome is not restored during session restore, so we need
|
||||
// to check for the toolbar as well.
|
||||
let chromeless = docElem.getAttribute("chromehidden").includes("extrachrome") ||
|
||||
docElem.getAttribute('chromehidden').includes("toolbar");
|
||||
docElem.getAttribute("chromehidden").includes("toolbar");
|
||||
// This property is "fixed" for a window, so avoid doing the check above
|
||||
// multiple times...
|
||||
delete this._chromeless;
|
||||
|
@ -118,11 +126,11 @@ SocialUI = {
|
|||
return Social.providers.length > 0;
|
||||
},
|
||||
|
||||
canSharePage: function(aURI) {
|
||||
return (aURI && (aURI.schemeIs('http') || aURI.schemeIs('https')));
|
||||
canSharePage(aURI) {
|
||||
return (aURI && (aURI.schemeIs("http") || aURI.schemeIs("https")));
|
||||
},
|
||||
|
||||
onCustomizeEnd: function(aWindow) {
|
||||
onCustomizeEnd(aWindow) {
|
||||
if (aWindow != window)
|
||||
return;
|
||||
// customization mode gets buttons out of sync with command updating, fix
|
||||
|
@ -140,20 +148,20 @@ SocialUI = {
|
|||
|
||||
// called on tab/urlbar/location changes and after customization. Update
|
||||
// anything that is tab specific.
|
||||
updateState: function() {
|
||||
updateState() {
|
||||
goSetCommandEnabled("Social:PageShareable", this.canSharePage(gBrowser.currentURI));
|
||||
}
|
||||
}
|
||||
|
||||
// message manager handlers
|
||||
SocialActivationListener = {
|
||||
init: function() {
|
||||
init() {
|
||||
messageManager.addMessageListener("Social:Activation", this);
|
||||
},
|
||||
uninit: function() {
|
||||
uninit() {
|
||||
messageManager.removeMessageListener("Social:Activation", this);
|
||||
},
|
||||
receiveMessage: function(aMessage) {
|
||||
receiveMessage(aMessage) {
|
||||
let data = aMessage.json;
|
||||
let browser = aMessage.target;
|
||||
data.window = window;
|
||||
|
@ -185,8 +193,8 @@ SocialActivationListener = {
|
|||
// make this new provider the selected provider. If the panel hasn't
|
||||
// been opened, we need to make the frame first.
|
||||
SocialShare._createFrame();
|
||||
SocialShare.iframe.setAttribute('src', 'data:text/plain;charset=utf8,');
|
||||
SocialShare.iframe.setAttribute('origin', provider.origin);
|
||||
SocialShare.iframe.setAttribute("src", "data:text/plain;charset=utf8,");
|
||||
SocialShare.iframe.setAttribute("origin", provider.origin);
|
||||
// get the right button selected
|
||||
SocialShare.populateProviderMenu();
|
||||
if (SocialShare.panel.state == "open") {
|
||||
|
@ -229,7 +237,7 @@ SocialShare = {
|
|||
return this.panel.lastChild.firstChild;
|
||||
},
|
||||
|
||||
uninit: function () {
|
||||
uninit() {
|
||||
if (this.iframe) {
|
||||
let mm = this.messageManager;
|
||||
mm.removeMessageListener("PageVisibility:Show", this);
|
||||
|
@ -240,7 +248,7 @@ SocialShare = {
|
|||
}
|
||||
},
|
||||
|
||||
_createFrame: function() {
|
||||
_createFrame() {
|
||||
let panel = this.panel;
|
||||
if (this.iframe)
|
||||
return;
|
||||
|
@ -273,9 +281,9 @@ SocialShare = {
|
|||
return this.iframe.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader.messageManager;
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
receiveMessage(aMessage) {
|
||||
let iframe = this.iframe;
|
||||
switch(aMessage.name) {
|
||||
switch (aMessage.name) {
|
||||
case "PageVisibility:Show":
|
||||
SocialShare._dynamicResizer.start(iframe.parentNode, iframe);
|
||||
break;
|
||||
|
@ -288,7 +296,7 @@ SocialShare = {
|
|||
}
|
||||
},
|
||||
|
||||
handleEvent: function(event) {
|
||||
handleEvent(event) {
|
||||
switch (event.type) {
|
||||
case "load": {
|
||||
this.iframe.parentNode.removeAttribute("loading");
|
||||
|
@ -298,7 +306,7 @@ SocialShare = {
|
|||
}
|
||||
},
|
||||
|
||||
getSelectedProvider: function() {
|
||||
getSelectedProvider() {
|
||||
let provider;
|
||||
let lastProviderOrigin = this.iframe && this.iframe.getAttribute("origin");
|
||||
if (lastProviderOrigin) {
|
||||
|
@ -307,14 +315,14 @@ SocialShare = {
|
|||
return provider;
|
||||
},
|
||||
|
||||
createTooltip: function(event) {
|
||||
createTooltip(event) {
|
||||
let tt = event.target;
|
||||
let provider = Social._getProviderFromOrigin(tt.triggerNode.getAttribute("origin"));
|
||||
tt.firstChild.setAttribute("value", provider.name);
|
||||
tt.lastChild.setAttribute("value", provider.origin);
|
||||
},
|
||||
|
||||
populateProviderMenu: function() {
|
||||
populateProviderMenu() {
|
||||
if (!this.iframe)
|
||||
return;
|
||||
let providers = Social.providers.filter(p => p.shareURL);
|
||||
|
@ -359,16 +367,16 @@ SocialShare = {
|
|||
return widget.forWindow(window).node;
|
||||
},
|
||||
|
||||
_onclick: function() {
|
||||
_onclick() {
|
||||
Services.telemetry.getHistogramById("SOCIAL_PANEL_CLICKS").add(0);
|
||||
},
|
||||
|
||||
onShowing: function() {
|
||||
onShowing() {
|
||||
(this._currentAnchor || this.anchor).setAttribute("open", "true");
|
||||
this.iframe.addEventListener("click", this._onclick, true);
|
||||
},
|
||||
|
||||
onHidden: function() {
|
||||
onHidden() {
|
||||
(this._currentAnchor || this.anchor).removeAttribute("open");
|
||||
this._currentAnchor = null;
|
||||
this.iframe.docShellIsActive = false;
|
||||
|
@ -381,7 +389,7 @@ SocialShare = {
|
|||
this.iframe.purgeSessionHistory();
|
||||
},
|
||||
|
||||
sharePage: function(providerOrigin, graphData, target, anchor) {
|
||||
sharePage(providerOrigin, graphData, target, anchor) {
|
||||
// if providerOrigin is undefined, we use the last-used provider, or the
|
||||
// current/default provider. The provider selection in the share panel
|
||||
// will call sharePage with an origin for us to switch to.
|
||||
|
@ -393,8 +401,8 @@ SocialShare = {
|
|||
// in mozSocial API, or via nsContentMenu calls. If it is present, it MUST
|
||||
// define at least url. If it is undefined, we're sharing the current url in
|
||||
// the browser tab.
|
||||
let pageData = graphData ? graphData : this.currentShare;
|
||||
let sharedURI = pageData ? Services.io.newURI(pageData.url) :
|
||||
let sharedPageData = graphData || this.currentShare;
|
||||
let sharedURI = sharedPageData ? Services.io.newURI(sharedPageData.url) :
|
||||
gBrowser.currentURI;
|
||||
if (!SocialUI.canSharePage(sharedURI))
|
||||
return;
|
||||
|
@ -406,7 +414,7 @@ SocialShare = {
|
|||
// socialapi functionality. One tweak is that we shoot an event
|
||||
// containing the open graph data.
|
||||
let _dataFn;
|
||||
if (!pageData || sharedURI == gBrowser.currentURI) {
|
||||
if (!sharedPageData || sharedURI == gBrowser.currentURI) {
|
||||
browserMM.addMessageListener("PageMetadata:PageDataResult", _dataFn = (msg) => {
|
||||
browserMM.removeMessageListener("PageMetadata:PageDataResult", _dataFn);
|
||||
let pageData = msg.json;
|
||||
|
@ -422,16 +430,16 @@ SocialShare = {
|
|||
return;
|
||||
}
|
||||
// if this is a share of a selected item, get any microformats
|
||||
if (!pageData.microformats && target) {
|
||||
if (!sharedPageData.microformats && target) {
|
||||
browserMM.addMessageListener("PageMetadata:MicroformatsResult", _dataFn = (msg) => {
|
||||
browserMM.removeMessageListener("PageMetadata:MicroformatsResult", _dataFn);
|
||||
pageData.microformats = msg.data;
|
||||
this.sharePage(providerOrigin, pageData, target, anchor);
|
||||
sharedPageData.microformats = msg.data;
|
||||
this.sharePage(providerOrigin, sharedPageData, target, anchor);
|
||||
});
|
||||
browserMM.sendAsyncMessage("PageMetadata:GetMicroformats", null, { target });
|
||||
return;
|
||||
}
|
||||
this.currentShare = pageData;
|
||||
this.currentShare = sharedPageData;
|
||||
|
||||
let provider;
|
||||
if (providerOrigin)
|
||||
|
@ -448,7 +456,7 @@ SocialShare = {
|
|||
if (btn)
|
||||
btn.checked = true;
|
||||
|
||||
let shareEndpoint = OpenGraphBuilder.generateEndpointURL(provider.shareURL, pageData);
|
||||
let shareEndpoint = OpenGraphBuilder.generateEndpointURL(provider.shareURL, sharedPageData);
|
||||
|
||||
this._dynamicResizer.stop();
|
||||
let size = provider.getPageSize("share");
|
||||
|
@ -474,13 +482,12 @@ SocialShare = {
|
|||
iframe.purgeSessionHistory();
|
||||
|
||||
// always ensure that origin belongs to the endpoint
|
||||
let uri = Services.io.newURI(shareEndpoint);
|
||||
iframe.setAttribute("origin", provider.origin);
|
||||
iframe.setAttribute("src", shareEndpoint);
|
||||
this._openPanel(anchor);
|
||||
},
|
||||
|
||||
showDirectory: function(anchor) {
|
||||
showDirectory(anchor) {
|
||||
this._createFrame();
|
||||
let iframe = this.iframe;
|
||||
if (iframe.getAttribute("src") == "about:providerdirectory")
|
||||
|
@ -492,7 +499,7 @@ SocialShare = {
|
|||
this._openPanel(anchor);
|
||||
},
|
||||
|
||||
_openPanel: function(anchor) {
|
||||
_openPanel(anchor) {
|
||||
this._currentAnchor = anchor || this.anchor;
|
||||
anchor = document.getAnonymousElementByAttribute(this._currentAnchor, "class", "toolbarbutton-icon");
|
||||
this.panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, false);
|
||||
|
@ -500,4 +507,4 @@ SocialShare = {
|
|||
}
|
||||
};
|
||||
|
||||
})();
|
||||
}).call(this);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -451,11 +451,11 @@ toolbar:not(#TabsToolbar) > #personal-bookmarks {
|
|||
}
|
||||
%endif
|
||||
|
||||
#browser-bottombox[lwthemefooter="true"] {
|
||||
:root[lwthemefooter=true] #browser-bottombox:-moz-lwtheme {
|
||||
background-repeat: no-repeat;
|
||||
background-position: bottom left;
|
||||
background-color: var(--lwt-accent-color);
|
||||
background-image: var(--lwt-header-image);
|
||||
background-image: var(--lwt-footer-image);
|
||||
}
|
||||
|
||||
.menuitem-iconic-tooltip {
|
||||
|
|
|
@ -2540,11 +2540,8 @@ function URLBarSetURI(aURI) {
|
|||
} catch (e) {}
|
||||
|
||||
// Replace initial page URIs with an empty string
|
||||
// 1. only if there's no opener (bug 370555).
|
||||
// 2. if remote newtab is enabled and it's the default remote newtab page
|
||||
let defaultRemoteURL = gAboutNewTabService.remoteEnabled &&
|
||||
uri.spec === gAboutNewTabService.newTabURL;
|
||||
if ((gInitialPages.includes(uri.spec) || defaultRemoteURL) &&
|
||||
// only if there's no opener (bug 370555).
|
||||
if (gInitialPages.includes(uri.spec) &&
|
||||
checkEmptyPageOrigin(gBrowser.selectedBrowser, uri)) {
|
||||
value = "";
|
||||
} else {
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
#endif
|
||||
titlemenuseparator="&mainWindow.titlemodifiermenuseparator;"
|
||||
lightweightthemes="true"
|
||||
lightweightthemesfooter="browser-bottombox"
|
||||
windowtype="navigator:browser"
|
||||
macanimationtype="document"
|
||||
screenX="4" screenY="4"
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"extends": [
|
||||
"../../../../../testing/mochitest/browser.eslintrc.js"
|
||||
]
|
||||
};
|
|
@ -17,8 +17,9 @@ support-files =
|
|||
|
||||
[browser_extension_sideloading.js]
|
||||
[browser_extension_update_background.js]
|
||||
[browser_extension_update_interactive.js]
|
||||
[browser_permissions_addons_search.js]
|
||||
[browser_permissions_installTrigger.js]
|
||||
[browser_permissions_local_file.js]
|
||||
[browser_permissions_mozAddonManager.js]
|
||||
[browser_update_interactive.js]
|
||||
[browser_update_interactive_noprompt.js]
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
const {AddonManagerPrivate} = Cu.import("resource://gre/modules/AddonManager.jsm", {});
|
||||
|
||||
const ID = "update2@tests.mozilla.org";
|
||||
const ID_LEGACY = "legacy_update@tests.mozilla.org";
|
||||
|
||||
// Set some prefs that apply to all the tests in this file
|
||||
add_task(function* setup() {
|
||||
|
@ -134,43 +133,3 @@ function checkOne(win, addon) {
|
|||
// Test "Find Updates" with both auto-update settings
|
||||
add_task(() => interactiveUpdateTest(true, checkOne));
|
||||
add_task(() => interactiveUpdateTest(false, checkOne));
|
||||
|
||||
// Check that an update from a legacy extension to a webextensino
|
||||
// does not display a prompt
|
||||
add_task(async function() {
|
||||
await SpecialPowers.pushPrefEnv({set: [
|
||||
// Point updates to the local mochitest server
|
||||
["extensions.update.url", `${BASE}/browser_webext_update.json`],
|
||||
]});
|
||||
|
||||
// Navigate away to ensure that BrowserOpenAddonMgr() opens a new tab
|
||||
gBrowser.selectedBrowser.loadURI("about:robots");
|
||||
await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
|
||||
|
||||
// Install initial version of the test extension
|
||||
let addon = await promiseInstallAddon(`${BASE}/browser_legacy.xpi`);
|
||||
ok(addon, "Addon was installed");
|
||||
is(addon.version, "1.1", "Version 1 of the addon is installed");
|
||||
|
||||
// Go to Extensions in about:addons
|
||||
let win = await BrowserOpenAddonsMgr("addons://list/extension");
|
||||
|
||||
let sawPopup = false;
|
||||
PopupNotifications.panel.addEventListener("popupshown",
|
||||
() => sawPopup = true,
|
||||
{once: true});
|
||||
|
||||
// Trigger an update check, we should see the update get applied
|
||||
let updatePromise = promiseInstallEvent(addon, "onInstallEnded");
|
||||
win.gViewController.doCommand("cmd_findAllUpdates");
|
||||
await updatePromise;
|
||||
|
||||
addon = await AddonManager.getAddonByID(ID_LEGACY);
|
||||
is(addon.version, "2.0", "Should have upgraded");
|
||||
|
||||
ok(!sawPopup, "Should not have seen a permission notification");
|
||||
|
||||
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
addon.uninstall();
|
||||
await SpecialPowers.popPrefEnv();
|
||||
});
|
|
@ -0,0 +1,62 @@
|
|||
|
||||
// Set some prefs that apply to all the tests in this file
|
||||
add_task(function* setup() {
|
||||
yield SpecialPowers.pushPrefEnv({set: [
|
||||
// We don't have pre-pinned certificates for the local mochitest server
|
||||
["extensions.install.requireBuiltInCerts", false],
|
||||
["extensions.update.requireBuiltInCerts", false],
|
||||
|
||||
// Point updates to the local mochitest server
|
||||
["extensions.update.url", `${BASE}/browser_webext_update.json`],
|
||||
|
||||
// XXX remove this when prompts are enabled by default
|
||||
["extensions.webextPermissionPrompts", true],
|
||||
]});
|
||||
});
|
||||
|
||||
// Helper to test that an update of a given extension does not
|
||||
// generate any permission prompts.
|
||||
async function testUpdateNoPrompt(filename, id,
|
||||
initialVersion = "1.0", updateVersion = "2.0") {
|
||||
// Navigate away to ensure that BrowserOpenAddonMgr() opens a new tab
|
||||
gBrowser.selectedBrowser.loadURI("about:robots");
|
||||
await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
|
||||
|
||||
// Install initial version of the test extension
|
||||
let addon = await promiseInstallAddon(`${BASE}/${filename}`);
|
||||
ok(addon, "Addon was installed");
|
||||
is(addon.version, initialVersion, "Version 1 of the addon is installed");
|
||||
|
||||
// Go to Extensions in about:addons
|
||||
let win = await BrowserOpenAddonsMgr("addons://list/extension");
|
||||
|
||||
let sawPopup = false;
|
||||
function popupListener() {
|
||||
sawPopup = true;
|
||||
}
|
||||
PopupNotifications.panel.addEventListener("popupshown", popupListener);
|
||||
|
||||
// Trigger an update check, we should see the update get applied
|
||||
let updatePromise = promiseInstallEvent(addon, "onInstallEnded");
|
||||
win.gViewController.doCommand("cmd_findAllUpdates");
|
||||
await updatePromise;
|
||||
|
||||
addon = await AddonManager.getAddonByID(id);
|
||||
is(addon.version, updateVersion, "Should have upgraded");
|
||||
|
||||
ok(!sawPopup, "Should not have seen a permission notification");
|
||||
PopupNotifications.panel.removeEventListener("popupshown", popupListener);
|
||||
|
||||
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
addon.uninstall();
|
||||
}
|
||||
|
||||
// Test that we don't see a prompt when updating from a legacy
|
||||
// extension to a webextension.
|
||||
add_task(() => testUpdateNoPrompt("browser_legacy.xpi",
|
||||
"legacy_update@tests.mozilla.org", "1.1"));
|
||||
|
||||
// Test that we don't see a prompt when no new promptable permissions
|
||||
// are added.
|
||||
add_task(() => testUpdateNoPrompt("browser_webext_update_perms1.xpi",
|
||||
"update_perms@tests.mozilla.org"));
|
|
@ -149,16 +149,6 @@ AboutRedirector::NewChannel(nsIURI* aURI,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = aboutNewTabService->GetDefaultURL(url);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// if about:newtab points to an external resource we have to make sure
|
||||
// the content is signed and trusted
|
||||
bool remoteEnabled = false;
|
||||
rv = aboutNewTabService->GetRemoteEnabled(&remoteEnabled);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (remoteEnabled) {
|
||||
NS_ENSURE_ARG_POINTER(aLoadInfo);
|
||||
aLoadInfo->SetVerifySignedContent(true);
|
||||
}
|
||||
}
|
||||
// fall back to the specified url in the map
|
||||
if (url.IsEmpty()) {
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = { // eslint-disable-line no-undef
|
||||
"env": {
|
||||
"mozilla/browser-window": true,
|
||||
},
|
||||
|
||||
"plugins": [
|
||||
"mozilla",
|
||||
]
|
||||
};
|
|
@ -40,12 +40,14 @@ function isAncestorOrSelf(target, node) {
|
|||
// WeakMap[Extension -> BrowserAction]
|
||||
const browserActionMap = new WeakMap();
|
||||
|
||||
const browserAreas = {
|
||||
"navbar": CustomizableUI.AREA_NAVBAR,
|
||||
"menupanel": CustomizableUI.AREA_PANEL,
|
||||
"tabstrip": CustomizableUI.AREA_TABSTRIP,
|
||||
"personaltoolbar": CustomizableUI.AREA_BOOKMARKS,
|
||||
};
|
||||
XPCOMUtils.defineLazyGetter(this, "browserAreas", () => {
|
||||
return {
|
||||
"navbar": CustomizableUI.AREA_NAVBAR,
|
||||
"menupanel": CustomizableUI.AREA_PANEL,
|
||||
"tabstrip": CustomizableUI.AREA_TABSTRIP,
|
||||
"personaltoolbar": CustomizableUI.AREA_BOOKMARKS,
|
||||
};
|
||||
});
|
||||
|
||||
// Responsible for the browser_action section of the manifest as well
|
||||
// as the associated popup.
|
||||
|
|
|
@ -44,6 +44,13 @@ class ChildDevToolsPanel extends EventEmitter {
|
|||
if (view.viewType === "devtools_panel" &&
|
||||
view.devtoolsToolboxInfo.toolboxPanelId === this.id) {
|
||||
this._panelContext = view;
|
||||
|
||||
// Reset the cached _panelContext property when the view is closed.
|
||||
view.callOnClose({
|
||||
close: () => {
|
||||
this._panelContext = null;
|
||||
},
|
||||
});
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,11 +21,11 @@ extensions.registerSchemaAPI("devtools.network", "devtools_parent", (context) =>
|
|||
|
||||
let targetPromise = getDevToolsTargetForContext(context);
|
||||
targetPromise.then(target => {
|
||||
target.on("will-navigate", listener);
|
||||
target.on("navigate", listener);
|
||||
});
|
||||
return () => {
|
||||
targetPromise.then(target => {
|
||||
target.off("will-navigate", listener);
|
||||
target.off("navigate", listener);
|
||||
});
|
||||
};
|
||||
}).api(),
|
||||
|
|
|
@ -170,6 +170,12 @@ class ParentDevToolsPanel {
|
|||
unwatchExtensionProxyContextLoad();
|
||||
browser.remove();
|
||||
toolbox.off("select", this.onToolboxPanelSelect);
|
||||
|
||||
// If the panel has been disabled from the toolbox preferences,
|
||||
// we need to re-initialize the waitTopLevelContext Promise.
|
||||
this.waitTopLevelContext = new Promise(resolve => {
|
||||
this._resolveTopLevelContext = resolve;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -184,7 +190,6 @@ class ParentDevToolsPanel {
|
|||
if (!this.waitTopLevelContext || !this.panelAdded) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.visible && id === this.id) {
|
||||
// Wait that the panel is fully loaded and emit show.
|
||||
this.waitTopLevelContext.then(() => {
|
||||
|
@ -218,6 +223,8 @@ class ParentDevToolsPanel {
|
|||
|
||||
this.context = null;
|
||||
this.toolbox = null;
|
||||
this.waitTopLevelContext = null;
|
||||
this._resolveTopLevelContext = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ let initDevTools;
|
|||
global.getDevToolsTargetForContext = (context) => {
|
||||
return Task.spawn(function* asyncGetTabTarget() {
|
||||
if (context.devToolsTarget) {
|
||||
yield context.devToolsTarget.makeRemote();
|
||||
return context.devToolsTarget;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ Cu.import("resource://gre/modules/ExtensionUtils.jsm");
|
|||
|
||||
var {
|
||||
SingletonEventManager,
|
||||
ignoreEvent,
|
||||
} = ExtensionUtils;
|
||||
|
||||
// This function is pretty tightly tied to Extension.jsm.
|
||||
|
@ -214,7 +213,9 @@ extensions.registerSchemaAPI("tabs", "addon_parent", context => {
|
|||
};
|
||||
}).api(),
|
||||
|
||||
onReplaced: ignoreEvent(context, "tabs.onReplaced"),
|
||||
onReplaced: new SingletonEventManager(context, "tabs.onReplaced", fire => {
|
||||
return () => {};
|
||||
}).api(),
|
||||
|
||||
onMoved: new SingletonEventManager(context, "tabs.onMoved", fire => {
|
||||
// There are certain circumstances where we need to ignore a move event.
|
||||
|
|
|
@ -135,6 +135,56 @@ add_task(function* test_devtools_page_panels_create() {
|
|||
is(secondCycleResults.panelShown, 2, "panel.onShown listener has been called twice");
|
||||
is(secondCycleResults.panelHidden, 2, "panel.onHidden listener has been called twice");
|
||||
|
||||
// Turn off the addon devtools panel using the visibilityswitch.
|
||||
const waitToolVisibilityOff = new Promise(resolve => {
|
||||
toolbox.once("tool-unregistered", resolve);
|
||||
});
|
||||
|
||||
Services.prefs.setBoolPref(`devtools.webext-${panelId}.enabled`, false);
|
||||
gDevTools.emit("tool-unregistered", panelId);
|
||||
|
||||
yield waitToolVisibilityOff;
|
||||
|
||||
ok(toolbox.hasAdditionalTool(panelId),
|
||||
"The tool has not been removed on visibilityswitch set to false");
|
||||
|
||||
is(toolbox.visibleAdditionalTools.filter(tool => tool.id == panelId).length, 0,
|
||||
"The tool is not visible on visibilityswitch set to false");
|
||||
|
||||
// Turn on the addon devtools panel using the visibilityswitch.
|
||||
const waitToolVisibilityOn = new Promise(resolve => {
|
||||
toolbox.once("tool-registered", resolve);
|
||||
});
|
||||
|
||||
Services.prefs.setBoolPref(`devtools.webext-${panelId}.enabled`, true);
|
||||
gDevTools.emit("tool-registered", panelId);
|
||||
|
||||
yield waitToolVisibilityOn;
|
||||
|
||||
ok(toolbox.hasAdditionalTool(panelId),
|
||||
"The tool has been added on visibilityswitch set to true");
|
||||
is(toolbox.visibleAdditionalTools.filter(toolId => toolId == panelId).length, 1,
|
||||
"The tool is visible on visibilityswitch set to true");
|
||||
|
||||
// Test devtools panel is loaded correctly after being toggled and
|
||||
// devtools panel events has been fired as expected.
|
||||
yield gDevTools.showToolbox(target, panelId);
|
||||
yield extension.awaitMessage("devtools_panel_shown");
|
||||
info("Addon Devtools Panel shown - after visibilityswitch toggled");
|
||||
|
||||
info("Wait until the Addon Devtools Panel has been loaded - after visibilityswitch toggled");
|
||||
const panelTabIdAfterToggle = yield extension.awaitMessage("devtools_panel_inspectedWindow_tabId");
|
||||
is(panelTabIdAfterToggle, devtoolsPageTabId,
|
||||
"Got the same devtools.inspectedWindow.tabId from devtools panel after visibility toggled");
|
||||
|
||||
yield gDevTools.showToolbox(target, "webconsole");
|
||||
const toolToggledResults = yield extension.awaitMessage("devtools_panel_hidden");
|
||||
info("Addon Devtools Panel hidden - after visibilityswitch toggled");
|
||||
|
||||
is(toolToggledResults.panelCreated, 1, "devtools.panel.create callback has been called once");
|
||||
is(toolToggledResults.panelShown, 3, "panel.onShown listener has been called three times");
|
||||
is(toolToggledResults.panelHidden, 3, "panel.onHidden listener has been called three times");
|
||||
|
||||
yield gDevTools.closeToolbox(target);
|
||||
|
||||
yield target.destroy();
|
||||
|
|
|
@ -167,6 +167,12 @@ add_task(function* test_create_options() {
|
|||
add_task(function* test_urlbar_focus() {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
background() {
|
||||
browser.tabs.onUpdated.addListener(function onUpdated(_, info) {
|
||||
if (info.status === "complete") {
|
||||
browser.test.sendMessage("complete");
|
||||
browser.tabs.onUpdated.removeListener(onUpdated);
|
||||
}
|
||||
});
|
||||
browser.test.onMessage.addListener(async (cmd, ...args) => {
|
||||
const result = await browser.tabs[cmd](...args);
|
||||
browser.test.sendMessage("result", result);
|
||||
|
@ -178,7 +184,10 @@ add_task(function* test_urlbar_focus() {
|
|||
|
||||
// Test content is focused after opening a regular url
|
||||
extension.sendMessage("create", {url: "https://example.com"});
|
||||
const tab1 = yield extension.awaitMessage("result");
|
||||
const [tab1] = yield Promise.all([
|
||||
extension.awaitMessage("result"),
|
||||
extension.awaitMessage("complete"),
|
||||
]);
|
||||
|
||||
is(document.activeElement.tagName, "browser", "Content focused after opening a web page");
|
||||
|
||||
|
|
|
@ -17,17 +17,13 @@ XPCOMUtils.defineLazyGetter(this, "EventEmitter", function() {
|
|||
|
||||
// Supported prefs and data type
|
||||
const gPrefsMap = new Map([
|
||||
["browser.newtabpage.remote", "bool"],
|
||||
["browser.newtabpage.remote.mode", "str"],
|
||||
["browser.newtabpage.remote.version", "str"],
|
||||
["browser.newtabpage.activity-stream.enabled", "bool"],
|
||||
["browser.newtabpage.enabled", "bool"],
|
||||
["browser.newtabpage.enhanced", "bool"],
|
||||
["browser.newtabpage.introShown", "bool"],
|
||||
["browser.newtabpage.updateIntroShown", "bool"],
|
||||
["browser.newtabpage.pinned", "str"],
|
||||
["browser.newtabpage.blocked", "str"],
|
||||
["intl.locale.matchOS", "bool"],
|
||||
["general.useragent.locale", "localized"],
|
||||
["browser.search.hiddenOneOffs", "str"],
|
||||
]);
|
||||
|
||||
|
|
|
@ -242,4 +242,3 @@ let PlacesProvider = {
|
|||
// Kept only for backwards-compatibility
|
||||
XPCOMUtils.defineLazyGetter(PlacesProvider, "LinkChecker",
|
||||
() => NewTabUtils.linkChecker);
|
||||
|
||||
|
|
|
@ -4,9 +4,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
/* globals XPCOMUtils, NewTabPrefsProvider, Services,
|
||||
Locale, UpdateUtils, NewTabRemoteResources
|
||||
*/
|
||||
/* globals XPCOMUtils, NewTabPrefsProvider, Services */
|
||||
"use strict";
|
||||
|
||||
const {utils: Cu, interfaces: Ci} = Components;
|
||||
|
@ -14,53 +12,27 @@ const {utils: Cu, interfaces: Ci} = Components;
|
|||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
|
||||
"resource://gre/modules/UpdateUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NewTabPrefsProvider",
|
||||
"resource:///modules/NewTabPrefsProvider.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Locale",
|
||||
"resource://gre/modules/Locale.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NewTabRemoteResources",
|
||||
"resource:///modules/NewTabRemoteResources.jsm");
|
||||
|
||||
const LOCAL_NEWTAB_URL = "chrome://browser/content/newtab/newTab.xhtml";
|
||||
|
||||
const REMOTE_NEWTAB_PATH = "/newtab/v%VERSION%/%CHANNEL%/%LOCALE%/index.html";
|
||||
const ACTIVITY_STREAM_URL = "resource://activity-stream/data/content/activity-stream.html";
|
||||
|
||||
const ABOUT_URL = "about:newtab";
|
||||
|
||||
// Pref that tells if remote newtab is enabled
|
||||
const PREF_REMOTE_ENABLED = "browser.newtabpage.remote";
|
||||
|
||||
// Pref branch necesssary for testing
|
||||
const PREF_REMOTE_CS_TEST = "browser.newtabpage.remote.content-signing-test";
|
||||
|
||||
// The preference that tells whether to match the OS locale
|
||||
const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS";
|
||||
|
||||
// The preference that tells what locale the user selected
|
||||
const PREF_SELECTED_LOCALE = "general.useragent.locale";
|
||||
|
||||
// The preference that tells what remote mode is enabled.
|
||||
const PREF_REMOTE_MODE = "browser.newtabpage.remote.mode";
|
||||
|
||||
// The preference that tells which remote version is expected.
|
||||
const PREF_REMOTE_VERSION = "browser.newtabpage.remote.version";
|
||||
|
||||
const VALID_CHANNELS = new Set(["esr", "release", "beta", "aurora", "nightly"]);
|
||||
// Pref that tells if activity stream is enabled
|
||||
const PREF_ACTIVITY_STREAM_ENABLED = "browser.newtabpage.activity-stream.enabled";
|
||||
|
||||
function AboutNewTabService() {
|
||||
NewTabPrefsProvider.prefs.on(PREF_REMOTE_ENABLED, this._handleToggleEvent.bind(this));
|
||||
|
||||
this._updateRemoteMaybe = this._updateRemoteMaybe.bind(this);
|
||||
|
||||
// trigger remote change if needed, according to pref
|
||||
this.toggleRemote(Services.prefs.getBoolPref(PREF_REMOTE_ENABLED));
|
||||
NewTabPrefsProvider.prefs.on(PREF_ACTIVITY_STREAM_ENABLED, this._handleToggleEvent.bind(this));
|
||||
this.toggleActivityStream(Services.prefs.getBoolPref(PREF_ACTIVITY_STREAM_ENABLED));
|
||||
}
|
||||
|
||||
/*
|
||||
* A service that allows for the overriding, at runtime, of the newtab page's url.
|
||||
* Additionally, the service manages pref state between a remote and local newtab page.
|
||||
* Additionally, the service manages pref state between a activity stream, or the regular
|
||||
* about:newtab page.
|
||||
*
|
||||
* There is tight coupling with browser/about/AboutRedirector.cpp.
|
||||
*
|
||||
|
@ -77,7 +49,8 @@ function AboutNewTabService() {
|
|||
*
|
||||
* When the URL loaded is about:newtab, the default behavior, or when entered in the
|
||||
* URL bar, the redirector is hit. The service is then called to return either of
|
||||
* two URLs, a chrome or remote one, based on the browser.newtabpage.remote pref.
|
||||
* two URLs, a chrome or the activity stream one, based on the
|
||||
* browser.newtabpage.activity-stream.enabled pref.
|
||||
*
|
||||
* NOTE: "about:newtab" will always result in a default newtab page, and never an overridden URL.
|
||||
*
|
||||
|
@ -93,8 +66,7 @@ function AboutNewTabService() {
|
|||
AboutNewTabService.prototype = {
|
||||
|
||||
_newTabURL: ABOUT_URL,
|
||||
_remoteEnabled: false,
|
||||
_remoteURL: null,
|
||||
_activityStreamEnabled: false,
|
||||
_overridden: false,
|
||||
|
||||
classID: Components.ID("{dfcd2adc-7867-4d3a-ba70-17501f208142}"),
|
||||
|
@ -104,140 +76,60 @@ AboutNewTabService.prototype = {
|
|||
}],
|
||||
|
||||
_handleToggleEvent(prefName, stateEnabled, forceState) { // jshint unused:false
|
||||
if (this.toggleRemote(stateEnabled, forceState)) {
|
||||
if (this.toggleActivityStream(stateEnabled, forceState)) {
|
||||
Services.obs.notifyObservers(null, "newtab-url-changed", ABOUT_URL);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* React to changes to the remote newtab pref.
|
||||
* React to changes to the activity stream pref.
|
||||
*
|
||||
* If browser.newtabpage.remote is true, this will change the default URL to the
|
||||
* remote newtab page URL. If browser.newtabpage.remote is false, the default URL
|
||||
* If browser.newtabpage.activity-stream.enabled is true, this will change the default URL to the
|
||||
* activity stream page URL. If browser.newtabpage.activity-stream.enabled is false, the default URL
|
||||
* will be a local chrome URL.
|
||||
*
|
||||
* This will only act if there is a change of state and if not overridden.
|
||||
*
|
||||
* @returns {Boolean} Returns if there has been a state change
|
||||
*
|
||||
* @param {Boolean} stateEnabled remote state to set to
|
||||
* @param {Boolean} stateEnabled activity stream enabled state to set to
|
||||
* @param {Boolean} forceState force state change
|
||||
*/
|
||||
toggleRemote(stateEnabled, forceState) {
|
||||
toggleActivityStream(stateEnabled, forceState) {
|
||||
|
||||
if (!forceState && (this._overriden || stateEnabled === this._remoteEnabled)) {
|
||||
if (!forceState && (this.overridden || stateEnabled === this.activityStreamEnabled)) {
|
||||
// exit there is no change of state
|
||||
return false;
|
||||
}
|
||||
|
||||
let csTest = Services.prefs.getBoolPref(PREF_REMOTE_CS_TEST);
|
||||
if (stateEnabled) {
|
||||
if (!csTest) {
|
||||
this._remoteURL = this.generateRemoteURL();
|
||||
} else {
|
||||
this._remoteURL = this._newTabURL;
|
||||
}
|
||||
NewTabPrefsProvider.prefs.on(
|
||||
PREF_SELECTED_LOCALE,
|
||||
this._updateRemoteMaybe);
|
||||
NewTabPrefsProvider.prefs.on(
|
||||
PREF_MATCH_OS_LOCALE,
|
||||
this._updateRemoteMaybe);
|
||||
NewTabPrefsProvider.prefs.on(
|
||||
PREF_REMOTE_MODE,
|
||||
this._updateRemoteMaybe);
|
||||
NewTabPrefsProvider.prefs.on(
|
||||
PREF_REMOTE_VERSION,
|
||||
this._updateRemoteMaybe);
|
||||
this._remoteEnabled = true;
|
||||
this._activityStreamEnabled = true;
|
||||
} else {
|
||||
NewTabPrefsProvider.prefs.off(PREF_SELECTED_LOCALE, this._updateRemoteMaybe);
|
||||
NewTabPrefsProvider.prefs.off(PREF_MATCH_OS_LOCALE, this._updateRemoteMaybe);
|
||||
NewTabPrefsProvider.prefs.off(PREF_REMOTE_MODE, this._updateRemoteMaybe);
|
||||
NewTabPrefsProvider.prefs.off(PREF_REMOTE_VERSION, this._updateRemoteMaybe);
|
||||
this._remoteEnabled = false;
|
||||
}
|
||||
if (!csTest) {
|
||||
this._newTabURL = ABOUT_URL;
|
||||
this._activityStreamEnabled = false;
|
||||
}
|
||||
this._newtabURL = ABOUT_URL;
|
||||
return true;
|
||||
},
|
||||
|
||||
/*
|
||||
* Generate a default url based on remote mode, version, locale and update channel
|
||||
*/
|
||||
generateRemoteURL() {
|
||||
let releaseName = this.releaseFromUpdateChannel(UpdateUtils.UpdateChannel);
|
||||
let path = REMOTE_NEWTAB_PATH
|
||||
.replace("%VERSION%", this.remoteVersion)
|
||||
.replace("%LOCALE%", Locale.getLocale())
|
||||
.replace("%CHANNEL%", releaseName);
|
||||
let mode = Services.prefs.getCharPref(PREF_REMOTE_MODE);
|
||||
if (!(mode in NewTabRemoteResources.MODE_CHANNEL_MAP)) {
|
||||
mode = "production";
|
||||
}
|
||||
return NewTabRemoteResources.MODE_CHANNEL_MAP[mode].origin + path;
|
||||
},
|
||||
|
||||
/*
|
||||
* Returns the default URL.
|
||||
*
|
||||
* This URL only depends on the browser.newtabpage.remote pref. Overriding
|
||||
* This URL only depends on the browser.newtabpage.activity-stream.enabled pref. Overriding
|
||||
* the newtab page has no effect on the result of this function.
|
||||
*
|
||||
* The result is also the remote URL if this is in a test (PREF_REMOTE_CS_TEST)
|
||||
*
|
||||
* @returns {String} the default newtab URL, remote or local depending on browser.newtabpage.remote
|
||||
* @returns {String} the default newtab URL, activity-stream or regular depending on browser.newtabpage.activity-stream.enabled
|
||||
*/
|
||||
get defaultURL() {
|
||||
let csTest = Services.prefs.getBoolPref(PREF_REMOTE_CS_TEST);
|
||||
if (this._remoteEnabled || csTest) {
|
||||
return this._remoteURL;
|
||||
if (this.activityStreamEnabled) {
|
||||
return this.activityStreamURL;
|
||||
}
|
||||
return LOCAL_NEWTAB_URL;
|
||||
},
|
||||
|
||||
/*
|
||||
* Updates the remote location when the page is not overriden.
|
||||
*
|
||||
* Useful when there is a dependent pref change
|
||||
*/
|
||||
_updateRemoteMaybe() {
|
||||
if (!this._remoteEnabled || this._overridden) {
|
||||
return;
|
||||
}
|
||||
|
||||
let url = this.generateRemoteURL();
|
||||
if (url !== this._remoteURL) {
|
||||
this._remoteURL = url;
|
||||
Services.obs.notifyObservers(null, "newtab-url-changed",
|
||||
this._remoteURL);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the release name from an Update Channel name
|
||||
*
|
||||
* @returns {String} a release name based on the update channel. Defaults to nightly
|
||||
*/
|
||||
releaseFromUpdateChannel(channelName) {
|
||||
return VALID_CHANNELS.has(channelName) ? channelName : "nightly";
|
||||
},
|
||||
|
||||
get newTabURL() {
|
||||
return this._newTabURL;
|
||||
},
|
||||
|
||||
get remoteVersion() {
|
||||
return Services.prefs.getCharPref(PREF_REMOTE_VERSION);
|
||||
},
|
||||
|
||||
get remoteReleaseName() {
|
||||
return this.releaseFromUpdateChannel(UpdateUtils.UpdateChannel);
|
||||
},
|
||||
|
||||
set newTabURL(aNewTabURL) {
|
||||
let csTest = Services.prefs.getBoolPref(PREF_REMOTE_CS_TEST);
|
||||
aNewTabURL = aNewTabURL.trim();
|
||||
if (aNewTabURL === ABOUT_URL) {
|
||||
// avoid infinite redirects in case one sets the URL to about:newtab
|
||||
|
@ -246,25 +138,8 @@ AboutNewTabService.prototype = {
|
|||
} else if (aNewTabURL === "") {
|
||||
aNewTabURL = "about:blank";
|
||||
}
|
||||
let remoteURL = this.generateRemoteURL();
|
||||
let prefRemoteEnabled = Services.prefs.getBoolPref(PREF_REMOTE_ENABLED);
|
||||
let isResetLocal = !prefRemoteEnabled && aNewTabURL === LOCAL_NEWTAB_URL;
|
||||
let isResetRemote = prefRemoteEnabled && aNewTabURL === remoteURL;
|
||||
|
||||
if (isResetLocal || isResetRemote) {
|
||||
if (this._overriden && !csTest) {
|
||||
// only trigger a reset if previously overridden and this is no test
|
||||
this.resetNewTabURL();
|
||||
}
|
||||
return;
|
||||
}
|
||||
// turn off remote state if needed
|
||||
if (!csTest) {
|
||||
this.toggleRemote(false);
|
||||
} else {
|
||||
// if this is a test, we want the remoteURL to be set
|
||||
this._remoteURL = aNewTabURL;
|
||||
}
|
||||
this.toggleActivityStream(false);
|
||||
this._newTabURL = aNewTabURL;
|
||||
this._overridden = true;
|
||||
Services.obs.notifyObservers(null, "newtab-url-changed", this._newTabURL);
|
||||
|
@ -274,14 +149,18 @@ AboutNewTabService.prototype = {
|
|||
return this._overridden;
|
||||
},
|
||||
|
||||
get remoteEnabled() {
|
||||
return this._remoteEnabled;
|
||||
get activityStreamEnabled() {
|
||||
return this._activityStreamEnabled;
|
||||
},
|
||||
|
||||
get activityStreamURL() {
|
||||
return ACTIVITY_STREAM_URL;
|
||||
},
|
||||
|
||||
resetNewTabURL() {
|
||||
this._overridden = false;
|
||||
this._newTabURL = ABOUT_URL;
|
||||
this.toggleRemote(Services.prefs.getBoolPref(PREF_REMOTE_ENABLED), true);
|
||||
this.toggleActivityStream(Services.prefs.getBoolPref(PREF_ACTIVITY_STREAM_ENABLED), true);
|
||||
Services.obs.notifyObservers(null, "newtab-url-changed", this._newTabURL);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -19,7 +19,7 @@ interface nsIAboutNewTabService : nsISupports
|
|||
attribute ACString newTabURL;
|
||||
|
||||
/**
|
||||
* Returns the default URL (remote or local depending on pref)
|
||||
* Returns the default URL (local or activity stream depending on pref)
|
||||
*/
|
||||
attribute ACString defaultURL;
|
||||
|
||||
|
@ -29,31 +29,15 @@ interface nsIAboutNewTabService : nsISupports
|
|||
readonly attribute bool overridden;
|
||||
|
||||
/**
|
||||
* Returns true if the default resource is remotely hosted and isn't
|
||||
* Returns true if the default resource is activity stream and isn't
|
||||
* overridden
|
||||
*/
|
||||
readonly attribute bool remoteEnabled;
|
||||
|
||||
readonly attribute bool activityStreamEnabled;
|
||||
|
||||
/**
|
||||
* Returns the version of the remote newtab page expected
|
||||
*/
|
||||
readonly attribute ACString remoteVersion;
|
||||
|
||||
/**
|
||||
* Returns the expected channel for the remote the newtab page
|
||||
* Returns the activity stream resource URL for the newtab page
|
||||
*/
|
||||
readonly attribute ACString remoteReleaseName;
|
||||
|
||||
/**
|
||||
* Generates and returns the remote newtab page url
|
||||
*/
|
||||
ACString generateRemoteURL();
|
||||
|
||||
/**
|
||||
* Returns a remote new tab release name given an update channel name
|
||||
*/
|
||||
ACString releaseFromUpdateChannel(in ACString channelName);
|
||||
readonly attribute ACString activityStreamURL;
|
||||
|
||||
/**
|
||||
* Resets to the default resource and also resets the
|
||||
|
|
|
@ -2,15 +2,7 @@
|
|||
support-files =
|
||||
blue_page.html
|
||||
dummy_page.html
|
||||
newtabwebchannel_basic.html
|
||||
newtabmessages_places.html
|
||||
newtabmessages_prefs.html
|
||||
newtabmessages_preview.html
|
||||
newtabmessages_search.html
|
||||
|
||||
[browser_PreviewProvider.js]
|
||||
[browser_remotenewtab_pageloads.js]
|
||||
[browser_newtab_overrides.js]
|
||||
[browser_newtabmessages.js]
|
||||
skip-if = true # Bug 1271177, bug 1262719
|
||||
[browser_newtabwebchannel.js]
|
||||
|
|
|
@ -23,7 +23,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService",
|
|||
"nsIAboutNewTabService");
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
Services.prefs.setBoolPref("browser.newtabpage.remote", false);
|
||||
Services.prefs.setBoolPref("browser.newtabpage.activity-stream.enabled", false);
|
||||
aboutNewTabService.resetNewTabURL();
|
||||
});
|
||||
|
||||
|
|
|
@ -1,222 +0,0 @@
|
|||
/* globals Cu, XPCOMUtils, Preferences, is, registerCleanupFunction, NewTabWebChannel,
|
||||
PlacesTestUtils, NewTabMessages, ok, Services, PlacesUtils, NetUtil, Task */
|
||||
|
||||
"use strict";
|
||||
|
||||
Cu.import("resource://gre/modules/Preferences.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NewTabWebChannel",
|
||||
"resource:///modules/NewTabWebChannel.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NewTabMessages",
|
||||
"resource:///modules/NewTabMessages.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
|
||||
"resource://testing-common/PlacesTestUtils.jsm");
|
||||
|
||||
let setup = Task.async(function*() {
|
||||
Preferences.set("browser.newtabpage.enhanced", true);
|
||||
Preferences.set("browser.newtabpage.remote.mode", "test");
|
||||
Preferences.set("browser.newtabpage.remote", true);
|
||||
NewTabMessages.init();
|
||||
yield PlacesTestUtils.clearHistory();
|
||||
});
|
||||
|
||||
let cleanup = Task.async(function*() {
|
||||
NewTabMessages.uninit();
|
||||
Preferences.set("browser.newtabpage.remote", false);
|
||||
Preferences.set("browser.newtabpage.remote.mode", "production");
|
||||
});
|
||||
registerCleanupFunction(cleanup);
|
||||
|
||||
/*
|
||||
* Sanity tests for pref messages
|
||||
*/
|
||||
add_task(function* prefMessages_request() {
|
||||
yield setup();
|
||||
|
||||
let testURL = "https://example.com/browser/browser/components/newtab/tests/browser/newtabmessages_prefs.html";
|
||||
|
||||
let tabOptions = {
|
||||
gBrowser,
|
||||
url: testURL
|
||||
};
|
||||
|
||||
let prefResponseAck = new Promise(resolve => {
|
||||
NewTabWebChannel.once("responseAck", () => {
|
||||
ok(true, "a request response has been received");
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
yield BrowserTestUtils.withNewTab(tabOptions, function*() {
|
||||
yield prefResponseAck;
|
||||
let prefChangeAck = new Promise(resolve => {
|
||||
NewTabWebChannel.once("responseAck", () => {
|
||||
ok(true, "a change response has been received");
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
Preferences.set("browser.newtabpage.enhanced", false);
|
||||
yield prefChangeAck;
|
||||
});
|
||||
yield cleanup();
|
||||
});
|
||||
|
||||
/*
|
||||
* Sanity tests for preview messages
|
||||
*/
|
||||
add_task(function* previewMessages_request() {
|
||||
yield setup();
|
||||
var oldEnabledPref = Services.prefs.getBoolPref("browser.pagethumbnails.capturing_disabled");
|
||||
Services.prefs.setBoolPref("browser.pagethumbnails.capturing_disabled", false);
|
||||
|
||||
let testURL = "https://example.com/browser/browser/components/newtab/tests/browser/newtabmessages_preview.html";
|
||||
|
||||
let tabOptions = {
|
||||
gBrowser,
|
||||
url: testURL
|
||||
};
|
||||
|
||||
let previewResponseAck = new Promise(resolve => {
|
||||
NewTabWebChannel.once("responseAck", () => {
|
||||
ok(true, "a request response has been received");
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
yield BrowserTestUtils.withNewTab(tabOptions, function*() {
|
||||
yield previewResponseAck;
|
||||
});
|
||||
yield cleanup();
|
||||
Services.prefs.setBoolPref("browser.pagethumbnails.capturing_disabled", oldEnabledPref);
|
||||
});
|
||||
|
||||
/*
|
||||
* Sanity tests for places messages
|
||||
*/
|
||||
add_task(function* placesMessages_request() {
|
||||
yield setup();
|
||||
let testURL = "https://example.com/browser/browser/components/newtab/tests/browser/newtabmessages_places.html";
|
||||
|
||||
// url prefix for test history population
|
||||
const TEST_URL = "https://mozilla.com/";
|
||||
// time when the test starts execution
|
||||
const TIME_NOW = (new Date()).getTime();
|
||||
|
||||
// utility function to compute past timestamp
|
||||
function timeDaysAgo(numDays) {
|
||||
return TIME_NOW - (numDays * 24 * 60 * 60 * 1000);
|
||||
}
|
||||
|
||||
// utility function to make a visit for insertion into places db
|
||||
function makeVisit(index, daysAgo, isTyped, domain = TEST_URL) {
|
||||
let {
|
||||
TRANSITION_TYPED,
|
||||
TRANSITION_LINK
|
||||
} = PlacesUtils.history;
|
||||
|
||||
return {
|
||||
uri: NetUtil.newURI(`${domain}${index}`),
|
||||
visitDate: timeDaysAgo(daysAgo),
|
||||
transition: (isTyped) ? TRANSITION_TYPED : TRANSITION_LINK,
|
||||
};
|
||||
}
|
||||
|
||||
yield PlacesTestUtils.clearHistory();
|
||||
|
||||
// all four visits must come from different domains to avoid deduplication
|
||||
let visits = [
|
||||
makeVisit(0, 0, true, "http://bar.com/"), // frecency 200, today
|
||||
makeVisit(1, 0, true, "http://foo.com/"), // frecency 200, today
|
||||
makeVisit(2, 2, true, "http://buz.com/"), // frecency 200, 2 days ago
|
||||
makeVisit(3, 2, false, "http://aaa.com/"), // frecency 10, 2 days ago, transition
|
||||
];
|
||||
|
||||
yield PlacesTestUtils.addVisits(visits);
|
||||
|
||||
/** Test Begins **/
|
||||
|
||||
let tabOptions = {
|
||||
gBrowser,
|
||||
url: testURL
|
||||
};
|
||||
|
||||
let placesResponseAck = new Promise(resolve => {
|
||||
NewTabWebChannel.once("numItemsAck", (_, msg) => {
|
||||
ok(true, "a request response has been received");
|
||||
is(msg.data, visits.length + 1, "received an expected number of history items");
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
yield BrowserTestUtils.withNewTab(tabOptions, function*() {
|
||||
yield placesResponseAck;
|
||||
ok(true, "a change response has been received");
|
||||
let placesChangeAck = new Promise(resolve => {
|
||||
NewTabWebChannel.once("clearHistoryAck", (_, msg) => {
|
||||
is(msg.data, "clearHistory", "a clear history message has been received");
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
yield PlacesTestUtils.clearHistory();
|
||||
yield placesChangeAck;
|
||||
});
|
||||
yield cleanup();
|
||||
});
|
||||
|
||||
/*
|
||||
* Sanity tests for search messages
|
||||
*/
|
||||
add_task(function* searchMessages_request() {
|
||||
yield setup();
|
||||
let testURL = "https://example.com/browser/browser/components/newtab/tests/browser/newtabmessages_search.html";
|
||||
|
||||
// create dummy test engines
|
||||
Services.search.addEngineWithDetails("Engine1", "", "", "", "GET",
|
||||
"http://example.com/?q={searchTerms}");
|
||||
Services.search.addEngineWithDetails("Engine2", "", "", "", "GET",
|
||||
"http://example.com/?q={searchTerms}");
|
||||
|
||||
let tabOptions = {
|
||||
gBrowser,
|
||||
url: testURL
|
||||
};
|
||||
|
||||
let UIStringsResponseAck = new Promise(resolve => {
|
||||
NewTabWebChannel.once("UIStringsAck", (_, msg) => {
|
||||
ok(true, "a search request response for UI string has been received");
|
||||
ok(msg.data, "received the UI Strings");
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
let suggestionsResponseAck = new Promise(resolve => {
|
||||
NewTabWebChannel.once("suggestionsAck", (_, msg) => {
|
||||
ok(true, "a search request response for suggestions has been received");
|
||||
ok(msg.data, "received the suggestions");
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
let stateResponseAck = new Promise(resolve => {
|
||||
NewTabWebChannel.once("stateAck", (_, msg) => {
|
||||
ok(true, "a search request response for state has been received");
|
||||
ok(msg.data, "received a state object");
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
let currentEngineResponseAck = new Promise(resolve => {
|
||||
NewTabWebChannel.once("currentEngineAck", (_, msg) => {
|
||||
ok(true, "a search request response for current engine has been received");
|
||||
ok(msg.data, "received a current engine");
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
yield BrowserTestUtils.withNewTab(tabOptions, function*() {
|
||||
yield UIStringsResponseAck;
|
||||
yield suggestionsResponseAck;
|
||||
yield stateResponseAck;
|
||||
yield currentEngineResponseAck;
|
||||
});
|
||||
|
||||
cleanup();
|
||||
});
|
|
@ -1,251 +0,0 @@
|
|||
/* globals XPCOMUtils, Cu, Preferences, NewTabWebChannel, is, registerCleanupFunction */
|
||||
|
||||
"use strict";
|
||||
|
||||
Cu.import("resource://gre/modules/Preferences.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NewTabWebChannel",
|
||||
"resource:///modules/NewTabWebChannel.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NewTabMessages",
|
||||
"resource:///modules/NewTabMessages.jsm");
|
||||
|
||||
const TEST_URL = "https://example.com/browser/browser/components/newtab/tests/browser/newtabwebchannel_basic.html";
|
||||
const TEST_URL_2 = "http://mochi.test:8888/browser/browser/components/newtab/tests/browser/newtabwebchannel_basic.html";
|
||||
|
||||
function setup(mode = "test") {
|
||||
Preferences.set("browser.newtabpage.remote.mode", mode);
|
||||
Preferences.set("browser.newtabpage.remote", true);
|
||||
NewTabWebChannel.init();
|
||||
NewTabMessages.init();
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
NewTabMessages.uninit();
|
||||
NewTabWebChannel.uninit();
|
||||
Preferences.set("browser.newtabpage.remote", false);
|
||||
Preferences.set("browser.newtabpage.remote.mode", "production");
|
||||
}
|
||||
registerCleanupFunction(cleanup);
|
||||
|
||||
/*
|
||||
* Tests flow of messages from newtab to chrome and chrome to newtab
|
||||
*/
|
||||
add_task(function* open_webchannel_basic() {
|
||||
setup();
|
||||
|
||||
let tabOptions = {
|
||||
gBrowser,
|
||||
url: TEST_URL
|
||||
};
|
||||
|
||||
let messagePromise = new Promise(resolve => {
|
||||
NewTabWebChannel.once("foo", function(name, msg) {
|
||||
is(name, "foo", "Correct message type sent: foo");
|
||||
is(msg.data, "bar", "Correct data sent: bar");
|
||||
resolve(msg.target);
|
||||
});
|
||||
});
|
||||
|
||||
let replyPromise = new Promise(resolve => {
|
||||
NewTabWebChannel.once("reply", function(name, msg) {
|
||||
is(name, "reply", "Correct message type sent: reply");
|
||||
is(msg.data, "quuz", "Correct data sent: quuz");
|
||||
resolve(msg.target);
|
||||
});
|
||||
});
|
||||
|
||||
let unloadPromise = new Promise(resolve => {
|
||||
NewTabWebChannel.once("targetUnload", function(name) {
|
||||
is(name, "targetUnload", "Correct message type sent: targetUnload");
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
is(NewTabWebChannel.numBrowsers, 0, "Sanity check");
|
||||
yield BrowserTestUtils.withNewTab(tabOptions, function*(browser) {
|
||||
let target = yield messagePromise;
|
||||
is(NewTabWebChannel.numBrowsers, 1, "One target expected");
|
||||
is(target.browser, browser, "Same browser");
|
||||
NewTabWebChannel.send("respond", null, target);
|
||||
yield replyPromise;
|
||||
});
|
||||
|
||||
Cu.forceGC();
|
||||
is(NewTabWebChannel.numBrowsers, 0, "Sanity check");
|
||||
yield unloadPromise;
|
||||
cleanup();
|
||||
});
|
||||
|
||||
/*
|
||||
* Tests message broadcast reaches all open newtab pages
|
||||
*/
|
||||
add_task(function* webchannel_broadcast() {
|
||||
setup();
|
||||
|
||||
let countingMessagePromise = new Promise(resolve => {
|
||||
let count = 0;
|
||||
NewTabWebChannel.on("foo", function test_message(name, msg) {
|
||||
count += 1;
|
||||
if (count === 2) {
|
||||
NewTabWebChannel.off("foo", test_message);
|
||||
resolve(msg.target);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
let countingReplyPromise = new Promise(resolve => {
|
||||
let count = 0;
|
||||
NewTabWebChannel.on("reply", function test_message(name, msg) {
|
||||
count += 1;
|
||||
if (count === 2) {
|
||||
NewTabWebChannel.off("reply", test_message);
|
||||
resolve(msg.target);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
let countingUnloadPromise = new Promise(resolve => {
|
||||
let count = 0;
|
||||
NewTabWebChannel.on("targetUnload", function test_message() {
|
||||
count += 1;
|
||||
if (count === 2) {
|
||||
NewTabWebChannel.off("targetUnload", test_message);
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
let tabs = [];
|
||||
is(NewTabWebChannel.numBrowsers, 0, "Sanity check");
|
||||
tabs.push(yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL));
|
||||
tabs.push(yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL));
|
||||
|
||||
yield countingMessagePromise;
|
||||
is(NewTabWebChannel.numBrowsers, 2, "Two targets expected");
|
||||
|
||||
NewTabWebChannel.broadcast("respond", null);
|
||||
yield countingReplyPromise;
|
||||
|
||||
for (let tab of tabs) {
|
||||
yield BrowserTestUtils.removeTab(tab);
|
||||
}
|
||||
Cu.forceGC();
|
||||
|
||||
is(NewTabWebChannel.numBrowsers, 0, "Sanity check");
|
||||
yield countingUnloadPromise;
|
||||
cleanup();
|
||||
});
|
||||
|
||||
/*
|
||||
* Tests switching modes
|
||||
*/
|
||||
add_task(function* webchannel_switch() {
|
||||
setup();
|
||||
|
||||
function newMessagePromise() {
|
||||
return new Promise(resolve => {
|
||||
NewTabWebChannel.once("foo", function(name, msg) {
|
||||
resolve(msg.target);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
let replyCount = 0;
|
||||
function newReplyPromise() {
|
||||
return new Promise(resolve => {
|
||||
NewTabWebChannel.on("reply", function() {
|
||||
replyCount += 1;
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
let unloadPromise = new Promise(resolve => {
|
||||
NewTabWebChannel.once("targetUnload", function() {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
let unloadAllPromise = new Promise(resolve => {
|
||||
NewTabWebChannel.once("targetUnloadAll", function() {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
let tabs = [];
|
||||
let messagePromise;
|
||||
is(NewTabWebChannel.numBrowsers, 0, "Sanity check");
|
||||
|
||||
messagePromise = newMessagePromise();
|
||||
tabs.push(yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL));
|
||||
yield messagePromise;
|
||||
is(NewTabWebChannel.numBrowsers, 1, "Correct number of targets");
|
||||
|
||||
messagePromise = newMessagePromise();
|
||||
Preferences.set("browser.newtabpage.remote.mode", "test2");
|
||||
tabs.push(yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL_2));
|
||||
yield unloadAllPromise;
|
||||
yield messagePromise;
|
||||
is(NewTabWebChannel.numBrowsers, 1, "Correct number of targets");
|
||||
|
||||
NewTabWebChannel.broadcast("respond", null);
|
||||
yield newReplyPromise();
|
||||
is(replyCount, 1, "only current channel is listened to for replies");
|
||||
|
||||
const webchannelWhitelistPref = "webchannel.allowObject.urlWhitelist";
|
||||
let origWhitelist = Services.prefs.getCharPref(webchannelWhitelistPref);
|
||||
let newWhitelist = origWhitelist + " http://mochi.test:8888";
|
||||
Services.prefs.setCharPref(webchannelWhitelistPref, newWhitelist);
|
||||
try {
|
||||
NewTabWebChannel.broadcast("respond_object", null);
|
||||
yield newReplyPromise();
|
||||
} finally {
|
||||
Services.prefs.clearUserPref(webchannelWhitelistPref);
|
||||
}
|
||||
|
||||
for (let tab of tabs) {
|
||||
yield BrowserTestUtils.removeTab(tab);
|
||||
}
|
||||
|
||||
Cu.forceGC();
|
||||
is(NewTabWebChannel.numBrowsers, 0, "Sanity check");
|
||||
yield unloadPromise;
|
||||
cleanup();
|
||||
});
|
||||
|
||||
add_task(function* open_webchannel_reload() {
|
||||
setup();
|
||||
|
||||
let tabOptions = {
|
||||
gBrowser,
|
||||
url: TEST_URL
|
||||
};
|
||||
|
||||
let messagePromise = new Promise(resolve => {
|
||||
NewTabWebChannel.once("foo", function(name, msg) {
|
||||
is(name, "foo", "Correct message type sent: foo");
|
||||
is(msg.data, "bar", "Correct data sent: bar");
|
||||
resolve(msg.target);
|
||||
});
|
||||
});
|
||||
let unloadPromise = new Promise(resolve => {
|
||||
NewTabWebChannel.once("targetUnload", function() {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
is(NewTabWebChannel.numBrowsers, 0, "Sanity check");
|
||||
yield BrowserTestUtils.withNewTab(tabOptions, function*(browser) {
|
||||
let target = yield messagePromise;
|
||||
is(NewTabWebChannel.numBrowsers, 1, "One target expected");
|
||||
is(target.browser, browser, "Same browser");
|
||||
|
||||
browser.reload();
|
||||
});
|
||||
|
||||
Cu.forceGC();
|
||||
is(NewTabWebChannel.numBrowsers, 0, "Sanity check");
|
||||
yield unloadPromise;
|
||||
cleanup();
|
||||
});
|
|
@ -1,49 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<title>Newtab WebChannel test</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
window.addEventListener("WebChannelMessageToContent", function(e) {
|
||||
if (e.detail.message) {
|
||||
let reply;
|
||||
switch (e.detail.message.type) {
|
||||
case "RECEIVE_FRECENT":
|
||||
reply = new window.CustomEvent("WebChannelMessageToChrome", {
|
||||
detail: JSON.stringify({
|
||||
id: "newtab",
|
||||
message: JSON.stringify({type: "numItemsAck", data: e.detail.message.data.length}),
|
||||
})
|
||||
});
|
||||
window.dispatchEvent(reply);
|
||||
break;
|
||||
case "RECEIVE_PLACES_CHANGE":
|
||||
if (e.detail.message.data.type === "clearHistory") {
|
||||
reply = new window.CustomEvent("WebChannelMessageToChrome", {
|
||||
detail: JSON.stringify({
|
||||
id: "newtab",
|
||||
message: JSON.stringify({type: "clearHistoryAck", data: e.detail.message.data.type}),
|
||||
})
|
||||
});
|
||||
window.dispatchEvent(reply);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}, true);
|
||||
|
||||
document.onreadystatechange = function() {
|
||||
if (document.readyState === "complete") {
|
||||
let msg = new window.CustomEvent("WebChannelMessageToChrome", {
|
||||
detail: JSON.stringify({
|
||||
id: "newtab",
|
||||
message: JSON.stringify({type: "REQUEST_FRECENT"}),
|
||||
})
|
||||
});
|
||||
window.dispatchEvent(msg);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,32 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<title>Newtab WebChannel test</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
window.addEventListener("WebChannelMessageToContent", function(e) {
|
||||
if (e.detail.message && e.detail.message.type === "RECEIVE_PREFS") {
|
||||
let reply = new window.CustomEvent("WebChannelMessageToChrome", {
|
||||
detail: JSON.stringify({
|
||||
id: "newtab",
|
||||
message: JSON.stringify({type: "responseAck"}),
|
||||
})
|
||||
});
|
||||
window.dispatchEvent(reply);
|
||||
}
|
||||
}, true);
|
||||
|
||||
document.onreadystatechange = function() {
|
||||
let msg = new window.CustomEvent("WebChannelMessageToChrome", {
|
||||
detail: JSON.stringify({
|
||||
id: "newtab",
|
||||
message: JSON.stringify({type: "REQUEST_PREFS"}),
|
||||
})
|
||||
});
|
||||
window.dispatchEvent(msg);
|
||||
};
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,37 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<title>Newtab WebChannel test</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
let thumbURL = "https://example.com/browser/browser/components/newtab/tests/browser/blue_page.html";
|
||||
|
||||
window.addEventListener("WebChannelMessageToContent", function(e) {
|
||||
if (e.detail.message && e.detail.message.type === "RECEIVE_THUMB") {
|
||||
if (e.detail.message.data.imgData && e.detail.message.data.url === thumbURL) {
|
||||
let reply = new window.CustomEvent("WebChannelMessageToChrome", {
|
||||
detail: JSON.stringify({
|
||||
id: "newtab",
|
||||
message: JSON.stringify({type: "responseAck"}),
|
||||
})
|
||||
});
|
||||
window.dispatchEvent(reply);
|
||||
}
|
||||
}
|
||||
}, true);
|
||||
|
||||
document.onreadystatechange = function() {
|
||||
if (document.readyState === "complete") {
|
||||
let msg = new window.CustomEvent("WebChannelMessageToChrome", {
|
||||
detail: JSON.stringify({
|
||||
id: "newtab",
|
||||
message: JSON.stringify({type: "REQUEST_THUMB", data: thumbURL}),
|
||||
})
|
||||
});
|
||||
window.dispatchEvent(msg);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,113 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<title>Newtab WebChannel test</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
let suggestionsData = {
|
||||
engineName: "Engine1",
|
||||
searchString: "test",
|
||||
};
|
||||
let removeFormHistoryData = "test";
|
||||
let performSearchData = {
|
||||
engineName: "Engine1",
|
||||
healthReportKey: "1",
|
||||
searchPurpose: "d",
|
||||
searchString: "test",
|
||||
};
|
||||
let cycleEngineData = "Engine2";
|
||||
|
||||
window.addEventListener("WebChannelMessageToContent", function(e) {
|
||||
if (e.detail.message) {
|
||||
let reply;
|
||||
switch (e.detail.message.type) {
|
||||
case "RECEIVE_UISTRINGS":
|
||||
reply = new window.CustomEvent("WebChannelMessageToChrome", {
|
||||
detail: {
|
||||
id: "newtab",
|
||||
message: JSON.stringify({type: "UIStringsAck", data: e.detail.message.data}),
|
||||
}
|
||||
});
|
||||
window.dispatchEvent(reply);
|
||||
break;
|
||||
case "RECEIVE_SEARCH_SUGGESTIONS":
|
||||
reply = new window.CustomEvent("WebChannelMessageToChrome", {
|
||||
detail: {
|
||||
id: "newtab",
|
||||
message: JSON.stringify({type: "suggestionsAck", data: e.detail.message.data}),
|
||||
}
|
||||
});
|
||||
window.dispatchEvent(reply);
|
||||
break;
|
||||
case "RECEIVE_SEARCH_STATE":
|
||||
reply = new window.CustomEvent("WebChannelMessageToChrome", {
|
||||
detail: {
|
||||
id: "newtab",
|
||||
message: JSON.stringify({type: "stateAck", data: e.detail.message.data}),
|
||||
}
|
||||
});
|
||||
window.dispatchEvent(reply);
|
||||
break;
|
||||
case "RECEIVE_CURRENT_ENGINE":
|
||||
reply = new window.CustomEvent("WebChannelMessageToChrome", {
|
||||
detail: {
|
||||
id: "newtab",
|
||||
message: JSON.stringify({type: "currentEngineAck", data: e.detail.message.data}),
|
||||
}
|
||||
});
|
||||
window.dispatchEvent(reply);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}, true);
|
||||
|
||||
document.onreadystatechange = function() {
|
||||
if (document.readyState === "complete") {
|
||||
let msg = new window.CustomEvent("WebChannelMessageToChrome", {
|
||||
detail: {
|
||||
id: "newtab",
|
||||
message: JSON.stringify({type: "REQUEST_UISTRINGS"}),
|
||||
}
|
||||
});
|
||||
window.dispatchEvent(msg);
|
||||
msg = new window.CustomEvent("WebChannelMessageToChrome", {
|
||||
detail: {
|
||||
id: "newtab",
|
||||
message: JSON.stringify({type: "REQUEST_SEARCH_SUGGESTIONS", data: suggestionsData}),
|
||||
}
|
||||
});
|
||||
window.dispatchEvent(msg);
|
||||
msg = new window.CustomEvent("WebChannelMessageToChrome", {
|
||||
detail: {
|
||||
id: "newtab",
|
||||
message: JSON.stringify({type: "REQUEST_SEARCH_STATE"}),
|
||||
}
|
||||
});
|
||||
window.dispatchEvent(msg);
|
||||
msg = new window.CustomEvent("WebChannelMessageToChrome", {
|
||||
detail: {
|
||||
id: "newtab",
|
||||
message: JSON.stringify({type: "REQUEST_REMOVE_FORM_HISTORY", data: removeFormHistoryData}),
|
||||
}
|
||||
});
|
||||
window.dispatchEvent(msg);
|
||||
msg = new window.CustomEvent("WebChannelMessageToChrome", {
|
||||
detail: {
|
||||
id: "newtab",
|
||||
message: JSON.stringify({type: "REQUEST_PERFORM_SEARCH", data: performSearchData}),
|
||||
}
|
||||
});
|
||||
window.dispatchEvent(msg);
|
||||
msg = new window.CustomEvent("WebChannelMessageToChrome", {
|
||||
detail: {
|
||||
id: "newtab",
|
||||
message: JSON.stringify({type: "REQUEST_CYCLE_ENGINE", data: cycleEngineData}),
|
||||
}
|
||||
});
|
||||
window.dispatchEvent(msg);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,36 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<title>Newtab WebChannel test</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
document.onreadystatechange = function() {
|
||||
let msg = new window.CustomEvent("WebChannelMessageToChrome", {
|
||||
detail: JSON.stringify({
|
||||
id: "newtab",
|
||||
message: JSON.stringify({type: "foo", data: "bar"}),
|
||||
})
|
||||
});
|
||||
window.dispatchEvent(msg);
|
||||
};
|
||||
|
||||
window.addEventListener("WebChannelMessageToContent", function(e) {
|
||||
if (e.detail.message && e.detail.message.type.startsWith("respond")) {
|
||||
var detail = {
|
||||
id: "newtab",
|
||||
message: JSON.stringify({type: "reply", data: "quuz"}),
|
||||
};
|
||||
if (e.detail.message.type !== "respond_object") {
|
||||
detail = JSON.stringify(detail);
|
||||
}
|
||||
let reply = new window.CustomEvent("WebChannelMessageToChrome", {
|
||||
detail
|
||||
});
|
||||
window.dispatchEvent(reply);
|
||||
}
|
||||
}, true);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -18,17 +18,12 @@ XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService",
|
|||
"@mozilla.org/browser/aboutnewtab-service;1",
|
||||
"nsIAboutNewTabService");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Locale",
|
||||
"resource://gre/modules/Locale.jsm");
|
||||
|
||||
const DEFAULT_HREF = aboutNewTabService.generateRemoteURL();
|
||||
const DEFAULT_HREF = aboutNewTabService.activityStreamURL;
|
||||
const DEFAULT_CHROME_URL = "chrome://browser/content/newtab/newTab.xhtml";
|
||||
const DOWNLOADS_URL = "chrome://browser/content/downloads/contentAreaDownloadsView.xul";
|
||||
const DEFAULT_VERSION = aboutNewTabService.remoteVersion;
|
||||
|
||||
function cleanup() {
|
||||
Services.prefs.setBoolPref("browser.newtabpage.remote", false);
|
||||
Services.prefs.setCharPref("browser.newtabpage.remote.version", DEFAULT_VERSION);
|
||||
Services.prefs.setBoolPref("browser.newtabpage.activity-stream.enabled", false);
|
||||
aboutNewTabService.resetNewTabURL();
|
||||
NewTabPrefsProvider.prefs.uninit();
|
||||
}
|
||||
|
@ -38,10 +33,10 @@ do_register_cleanup(cleanup);
|
|||
/**
|
||||
* Test the overriding of the default URL
|
||||
*/
|
||||
add_task(function* test_override_remote_disabled() {
|
||||
add_task(function* test_override_activity_stream_disabled() {
|
||||
NewTabPrefsProvider.prefs.init();
|
||||
let notificationPromise;
|
||||
Services.prefs.setBoolPref("browser.newtabpage.remote", false);
|
||||
Services.prefs.setBoolPref("browser.newtabpage.activity-stream.enabled", false);
|
||||
|
||||
// tests default is the local newtab resource
|
||||
Assert.equal(aboutNewTabService.defaultURL, DEFAULT_CHROME_URL,
|
||||
|
@ -53,10 +48,10 @@ add_task(function* test_override_remote_disabled() {
|
|||
aboutNewTabService.newTabURL = url;
|
||||
yield notificationPromise;
|
||||
Assert.ok(aboutNewTabService.overridden, "Newtab URL should be overridden");
|
||||
Assert.ok(!aboutNewTabService.remoteEnabled, "Newtab remote should not be enabled");
|
||||
Assert.ok(!aboutNewTabService.activityStreamEnabled, "Newtab activity stream should not be enabled");
|
||||
Assert.equal(aboutNewTabService.newTabURL, url, "Newtab URL should be the custom URL");
|
||||
|
||||
// test reset with remote disabled
|
||||
// test reset with activity stream disabled
|
||||
notificationPromise = nextChangeNotificationPromise("about:newtab");
|
||||
aboutNewTabService.resetNewTabURL();
|
||||
yield notificationPromise;
|
||||
|
@ -73,19 +68,19 @@ add_task(function* test_override_remote_disabled() {
|
|||
cleanup();
|
||||
});
|
||||
|
||||
add_task(function* test_override_remote_enabled() {
|
||||
add_task(function* test_override_activity_stream_enabled() {
|
||||
NewTabPrefsProvider.prefs.init();
|
||||
let notificationPromise;
|
||||
// change newtab page to remote
|
||||
// change newtab page to activity stream
|
||||
notificationPromise = nextChangeNotificationPromise("about:newtab");
|
||||
Services.prefs.setBoolPref("browser.newtabpage.remote", true);
|
||||
Services.prefs.setBoolPref("browser.newtabpage.activity-stream.enabled", true);
|
||||
yield notificationPromise;
|
||||
let remoteHref = aboutNewTabService.generateRemoteURL();
|
||||
Assert.equal(aboutNewTabService.defaultURL, remoteHref, "Newtab URL should be the default remote URL");
|
||||
let activityStreamURL = aboutNewTabService.activityStreamURL;
|
||||
Assert.equal(aboutNewTabService.defaultURL, activityStreamURL, "Newtab URL should be the default activity stream URL");
|
||||
Assert.ok(!aboutNewTabService.overridden, "Newtab URL should not be overridden");
|
||||
Assert.ok(aboutNewTabService.remoteEnabled, "Newtab remote should be enabled");
|
||||
Assert.ok(aboutNewTabService.activityStreamEnabled, "Activity Stream should be enabled");
|
||||
|
||||
// change to local newtab page while remote is enabled
|
||||
// change to local newtab page while activity stream is enabled
|
||||
notificationPromise = nextChangeNotificationPromise(DEFAULT_CHROME_URL);
|
||||
aboutNewTabService.newTabURL = DEFAULT_CHROME_URL;
|
||||
yield notificationPromise;
|
||||
|
@ -94,7 +89,7 @@ add_task(function* test_override_remote_enabled() {
|
|||
Assert.equal(aboutNewTabService.defaultURL, DEFAULT_CHROME_URL,
|
||||
"Newtab URL defaultURL set to the default chrome URL");
|
||||
Assert.ok(aboutNewTabService.overridden, "Newtab URL should be overridden");
|
||||
Assert.ok(!aboutNewTabService.remoteEnabled, "Newtab remote should not be enabled");
|
||||
Assert.ok(!aboutNewTabService.activityStreamEnabled, "Activity Stream should not be enabled");
|
||||
|
||||
cleanup();
|
||||
});
|
||||
|
@ -107,46 +102,11 @@ add_task(function* test_updates() {
|
|||
* Simulates a "cold-boot" situation, with some pref already set before testing a series
|
||||
* of changes.
|
||||
*/
|
||||
Preferences.set("browser.newtabpage.remote", true);
|
||||
Preferences.set("browser.newtabpage.activity-stream.enabled", true);
|
||||
aboutNewTabService.resetNewTabURL(); // need to set manually because pref notifs are off
|
||||
let notificationPromise;
|
||||
let productionModeBaseUrl = "https://content.cdn.mozilla.net";
|
||||
let testModeBaseUrl = "https://example.com";
|
||||
let expectedPath = `/newtab` +
|
||||
`/v${aboutNewTabService.remoteVersion}` +
|
||||
`/${aboutNewTabService.remoteReleaseName}` +
|
||||
"/en-GB" +
|
||||
"/index.html";
|
||||
let expectedHref = productionModeBaseUrl + expectedPath;
|
||||
Preferences.set("intl.locale.matchOS", true);
|
||||
Preferences.set("general.useragent.locale", "en-GB");
|
||||
Preferences.set("browser.newtabpage.remote.mode", "production");
|
||||
NewTabPrefsProvider.prefs.init();
|
||||
|
||||
// test update checks for prefs
|
||||
notificationPromise = nextChangeNotificationPromise(
|
||||
expectedHref, "Remote href should be updated");
|
||||
Preferences.set("intl.locale.matchOS", false);
|
||||
yield notificationPromise;
|
||||
|
||||
notificationPromise = nextChangeNotificationPromise(
|
||||
DEFAULT_HREF, "Remote href changes back to default");
|
||||
Preferences.set("general.useragent.locale", "en-US");
|
||||
yield notificationPromise;
|
||||
|
||||
// test update fires when mode is changed
|
||||
expectedPath = expectedPath.replace("/en-GB/", "/en-US/");
|
||||
notificationPromise = nextChangeNotificationPromise(
|
||||
testModeBaseUrl + expectedPath, "Remote href changes back to origin of test mode");
|
||||
Preferences.set("browser.newtabpage.remote.mode", "test");
|
||||
yield notificationPromise;
|
||||
|
||||
// test invalid mode ends up pointing to production url
|
||||
notificationPromise = nextChangeNotificationPromise(
|
||||
DEFAULT_HREF, "Remote href changes back to production default");
|
||||
Preferences.set("browser.newtabpage.remote.mode", "invalid");
|
||||
yield notificationPromise;
|
||||
|
||||
// test update fires on override and reset
|
||||
let testURL = "https://example.com/";
|
||||
notificationPromise = nextChangeNotificationPromise(
|
||||
|
@ -158,19 +118,10 @@ add_task(function* test_updates() {
|
|||
notificationPromise = nextChangeNotificationPromise(
|
||||
"about:newtab", "a notification occurs on reset");
|
||||
aboutNewTabService.resetNewTabURL();
|
||||
Assert.ok(aboutNewTabService.remoteEnabled, "Newtab remote should be enabled");
|
||||
Assert.equal(aboutNewTabService.defaultURL, DEFAULT_HREF, "Default URL should be the remote page");
|
||||
Assert.ok(aboutNewTabService.activityStreamEnabled, "Activity Stream should be enabled");
|
||||
Assert.equal(aboutNewTabService.defaultURL, DEFAULT_HREF, "Default URL should be the activity stream page");
|
||||
yield notificationPromise;
|
||||
|
||||
// override to default URL from default URL
|
||||
notificationPromise = nextChangeNotificationPromise(
|
||||
testURL, "a notification only occurs for a change in overridden urls");
|
||||
aboutNewTabService.newTabURL = aboutNewTabService.generateRemoteURL();
|
||||
Assert.ok(aboutNewTabService.remoteEnabled, "Newtab remote should be enabled");
|
||||
aboutNewTabService.newTabURL = testURL;
|
||||
yield notificationPromise;
|
||||
Assert.ok(!aboutNewTabService.remoteEnabled, "Newtab remote should not be enabled");
|
||||
|
||||
// reset twice, only one notification for default URL
|
||||
notificationPromise = nextChangeNotificationPromise(
|
||||
"about:newtab", "reset occurs");
|
||||
|
@ -180,51 +131,6 @@ add_task(function* test_updates() {
|
|||
cleanup();
|
||||
});
|
||||
|
||||
/**
|
||||
* Verifies that releaseFromUpdateChannel
|
||||
* Returns the correct release names
|
||||
*/
|
||||
add_task(function* test_release_names() {
|
||||
let valid_channels = ["esr", "release", "beta", "aurora", "nightly"];
|
||||
let invalid_channels = new Set(["default", "invalid"]);
|
||||
|
||||
for (let channel of valid_channels) {
|
||||
Assert.equal(channel, aboutNewTabService.releaseFromUpdateChannel(channel),
|
||||
"release == channel name when valid");
|
||||
}
|
||||
|
||||
for (let channel of invalid_channels) {
|
||||
Assert.equal("nightly", aboutNewTabService.releaseFromUpdateChannel(channel),
|
||||
"release == nightly when invalid");
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Verifies that remote version updates changes the remote newtab url
|
||||
*/
|
||||
add_task(function* test_version_update() {
|
||||
NewTabPrefsProvider.prefs.init();
|
||||
|
||||
Services.prefs.setBoolPref("browser.newtabpage.remote", true);
|
||||
Assert.ok(aboutNewTabService.remoteEnabled, "remote mode enabled");
|
||||
|
||||
let productionModeBaseUrl = "https://content.cdn.mozilla.net";
|
||||
let version_incr = String(parseInt(DEFAULT_VERSION) + 1);
|
||||
let expectedPath = `/newtab` +
|
||||
`/v${version_incr}` +
|
||||
`/${aboutNewTabService.remoteReleaseName}` +
|
||||
`/${Locale.getLocale()}` +
|
||||
`/index.html`;
|
||||
let expectedHref = productionModeBaseUrl + expectedPath;
|
||||
|
||||
let notificationPromise;
|
||||
notificationPromise = nextChangeNotificationPromise(expectedHref);
|
||||
Preferences.set("browser.newtabpage.remote.version", version_incr);
|
||||
yield notificationPromise;
|
||||
|
||||
cleanup();
|
||||
});
|
||||
|
||||
function nextChangeNotificationPromise(aNewURL, testMessage) {
|
||||
return new Promise(resolve => {
|
||||
Services.obs.addObserver(function observer(aSubject, aTopic, aData) { // jshint unused:false
|
||||
|
|
|
@ -17,7 +17,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService",
|
|||
|
||||
add_task(function*() {
|
||||
let defaultURL = aboutNewTabService.newTabURL;
|
||||
Services.prefs.setBoolPref("browser.newtabpage.remote", false);
|
||||
Services.prefs.setBoolPref("browser.newtabpage.activity-stream.enabled", false);
|
||||
|
||||
Assert.equal(NewTabURL.get(), defaultURL, `Default newtab URL should be ${defaultURL}`);
|
||||
let url = "http://example.com/";
|
||||
|
@ -33,9 +33,9 @@ add_task(function*() {
|
|||
Assert.ok(!NewTabURL.overridden, "Newtab URL should not be overridden");
|
||||
Assert.equal(NewTabURL.get(), defaultURL, "Newtab URL should be the default");
|
||||
|
||||
// change newtab page to remote
|
||||
// change newtab page to activity stream
|
||||
NewTabPrefsProvider.prefs.init();
|
||||
Services.prefs.setBoolPref("browser.newtabpage.remote", true);
|
||||
Services.prefs.setBoolPref("browser.newtabpage.activity-stream.enabled", true);
|
||||
Assert.equal(NewTabURL.get(), "about:newtab", `Newtab URL should be about:newtab`);
|
||||
Assert.ok(!NewTabURL.overridden, "Newtab URL should not be overridden");
|
||||
NewTabPrefsProvider.prefs.uninit();
|
||||
|
|
|
@ -23,7 +23,8 @@ XPCOMUtils.defineLazyServiceGetter(this, "AlertsService", "@mozilla.org/alerts-s
|
|||
AsyncShutdown:false, AutoCompletePopup:false, BookmarkHTMLUtils:false,
|
||||
BookmarkJSONUtils:false, BrowserUITelemetry:false, BrowserUsageTelemetry:false,
|
||||
ContentClick:false, ContentPrefServiceParent:false, ContentSearch:false,
|
||||
DateTimePickerHelper:false, DirectoryLinksProvider:false, Feeds:false,
|
||||
DateTimePickerHelper:false, DirectoryLinksProvider:false,
|
||||
ExtensionsUI:false, Feeds:false,
|
||||
FileUtils:false, FormValidationHandler:false, Integration:false,
|
||||
LightweightThemeManager:false, LoginHelper:false, LoginManagerParent:false,
|
||||
NetUtil:false, NewTabMessages:false, NewTabUtils:false, OS:false,
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// This file spawns content tasks.
|
||||
/* eslint-env mozilla/frame-script */
|
||||
|
||||
const BASE_URL = "http://mochi.test:8888/browser/browser/components/originattributes/test/browser/";
|
||||
const BASE_DOMAIN = "mochi.test";
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"env": {
|
||||
// Everything in this directory is loaded alongside the places overlay.
|
||||
"mozilla/places-overlay": true
|
||||
},
|
||||
|
||||
"plugins": [
|
||||
"mozilla",
|
||||
]
|
||||
};
|
|
@ -57,6 +57,8 @@
|
|||
* been performed by the dialog.
|
||||
*/
|
||||
|
||||
/* import-globals-from editBookmarkOverlay.js */
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
|
||||
"resource://gre/modules/PrivateBrowsingUtils.jsm");
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* eslint-env mozilla/browser-window */
|
||||
|
||||
Components.utils.import("resource://gre/modules/AppConstants.jsm");
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
|
|
@ -286,9 +286,13 @@ var gEditItemOverlay = {
|
|||
// Note: since all controls are collapsed by default, we don't get the
|
||||
// default XUL dialog behavior, that selects the first control, so we set
|
||||
// the focus explicitly.
|
||||
// Note: If focusedElement === "preferred", this file expects gPrefService
|
||||
// to be defined in the global scope.
|
||||
let elt;
|
||||
if (focusedElement === "preferred") {
|
||||
/* eslint-disable no-undef */
|
||||
elt = this._element(gPrefService.getCharPref("browser.bookmarks.editDialog.firstEditField"));
|
||||
/* eslint-enable no-undef */
|
||||
} else if (focusedElement === "first") {
|
||||
elt = document.querySelector("textbox:not([collapsed=true])");
|
||||
}
|
||||
|
@ -899,7 +903,7 @@ var gEditItemOverlay = {
|
|||
|
||||
let tagsInField = this._getTagsArrayFromTagsInputField();
|
||||
let allTags = PlacesUtils.tagging.allTags;
|
||||
for (tag of allTags) {
|
||||
for (let tag of allTags) {
|
||||
let elt = document.createElement("listitem");
|
||||
elt.setAttribute("type", "checkbox");
|
||||
elt.setAttribute("label", tag);
|
||||
|
@ -1064,7 +1068,7 @@ var gEditItemOverlay = {
|
|||
// menulist has been changed, we need to update the label of its
|
||||
// representing element.
|
||||
let menupopup = this._folderMenuList.menupopup;
|
||||
for (menuitem of menupopup.childNodes) {
|
||||
for (let menuitem of menupopup.childNodes) {
|
||||
if ("folderId" in menuitem && menuitem.folderId == aItemId) {
|
||||
menuitem.label = aNewTitle;
|
||||
break;
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* import-globals-from editBookmarkOverlay.js */
|
||||
// Via downloadsViewOverlay.xul -> allDownloadsViewOverlay.xul
|
||||
/* import-globals-from ../../../../toolkit/content/contentAreaUtils.js */
|
||||
|
||||
Components.utils.import("resource://gre/modules/AppConstants.jsm");
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Components.utils.import("resource://gre/modules/TelemetryStopwatch.jsm");
|
||||
|
|
|
@ -44,8 +44,6 @@
|
|||
|
||||
<script type="application/javascript"
|
||||
src="chrome://browser/content/places/places.js"/>
|
||||
<script type="application/javascript"
|
||||
src="chrome://browser/content/utilityOverlay.js"/>
|
||||
<script type="application/javascript"
|
||||
src="chrome://browser/content/places/editBookmarkOverlay.js"/>
|
||||
|
||||
|
@ -89,7 +87,7 @@
|
|||
<!-- Instantiation Keys -->
|
||||
<key id="placesKey_close" key="&cmd.close.key;" modifiers="accel"
|
||||
oncommand="close();"/>
|
||||
|
||||
|
||||
<!-- Command Keys -->
|
||||
<key id="placesKey_find:all"
|
||||
command="OrganizerCommand_find:all"
|
||||
|
@ -375,7 +373,7 @@
|
|||
onkeypress="ContentTree.onKeyPress(event);"
|
||||
onopenflatcontainer="PlacesOrganizer.openFlatContainer(aContainer);">
|
||||
<treecols id="placeContentColumns" context="placesColumnsContext">
|
||||
<treecol label="&col.name.label;" id="placesContentTitle" anonid="title" flex="5" primary="true" ordinal="1"
|
||||
<treecol label="&col.name.label;" id="placesContentTitle" anonid="title" flex="5" primary="true" ordinal="1"
|
||||
persist="width hidden ordinal sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol label="&col.tags.label;" id="placesContentTags" anonid="tags" flex="2"
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
var Cc = Components.classes;
|
||||
var Ci = Components.interfaces;
|
||||
var Cr = Components.results;
|
||||
var Cu = Components.utils;
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Components.utils.import("resource://gre/modules/Task.jsm");
|
||||
|
@ -65,7 +66,7 @@
|
|||
oncommand="goDoPlacesCommand('placesCmd_new:folder');"/>
|
||||
<command id="placesCmd_new:separator"
|
||||
oncommand="goDoPlacesCommand('placesCmd_new:separator');"/>
|
||||
<command id="placesCmd_show:info"
|
||||
<command id="placesCmd_show:info"
|
||||
oncommand="goDoPlacesCommand('placesCmd_show:info');"/>
|
||||
<command id="placesCmd_rename"
|
||||
oncommand="goDoPlacesCommand('placesCmd_show:info');"
|
||||
|
@ -166,7 +167,7 @@
|
|||
<menuitem id="placesContext_cut"
|
||||
command="placesCmd_cut"
|
||||
label="&cutCmd.label;"
|
||||
accesskey="&cutCmd.accesskey;"
|
||||
accesskey="&cutCmd.accesskey;"
|
||||
closemenu="single"
|
||||
selection="bookmark|folder|separator|query"
|
||||
forcehideselection="tagChild|livemarkChild"/>
|
||||
|
@ -220,7 +221,7 @@
|
|||
<menuseparator id="placesContext_sortSeparator"/>
|
||||
<menuitem id="placesContext_show:info"
|
||||
command="placesCmd_show:info"
|
||||
label="&cmd.properties.label;"
|
||||
label="&cmd.properties.label;"
|
||||
accesskey="&cmd.properties.accesskey;"
|
||||
selection="bookmark|folder|query"
|
||||
forcehideselection="livemarkChild"/>
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* import-globals-from preferences.js */
|
||||
|
||||
// Load DownloadUtils module for convertByteUnits
|
||||
Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
|
||||
Components.utils.import("resource://gre/modules/LoadContextInfo.jsm");
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* import-globals-from preferences.js */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Constants & Enumeration Values
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* import-globals-from preferences.js */
|
||||
|
||||
Components.utils.import("resource://gre/modules/AppConstants.jsm");
|
||||
Components.utils.import("resource://gre/modules/ContextualIdentityService.jsm");
|
||||
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* import-globals-from preferences.js */
|
||||
/* import-globals-from ../../../../toolkit/mozapps/preferences/fontbuilder.js */
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "AlertsServiceDND", function() {
|
||||
try {
|
||||
let alertsService = Cc["@mozilla.org/alerts-service;1"]
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* import-globals-from preferences.js */
|
||||
|
||||
Components.utils.import("resource://gre/modules/Downloads.jsm");
|
||||
Components.utils.import("resource://gre/modules/FileUtils.jsm");
|
||||
Components.utils.import("resource://gre/modules/Task.jsm");
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
/* import-globals-from advanced.js */
|
||||
/* import-globals-from main.js */
|
||||
/* import-globals-from search.js */
|
||||
/* import-globals-from containers.js */
|
||||
/* import-globals-from content.js */
|
||||
/* import-globals-from privacy.js */
|
||||
/* import-globals-from applications.js */
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* import-globals-from preferences.js */
|
||||
|
||||
Components.utils.import("resource://gre/modules/AppConstants.jsm");
|
||||
Components.utils.import("resource://gre/modules/PluralForm.jsm");
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* import-globals-from preferences.js */
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
|
||||
"resource://gre/modules/PlacesUtils.jsm");
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* import-globals-from preferences.js */
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "LoginHelper",
|
||||
"resource://gre/modules/LoginHelper.jsm");
|
||||
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
- License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
- You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* import-globals-from ../../../base/content/utilityOverlay.js */
|
||||
/* import-globals-from preferences.js */
|
||||
|
||||
"use strict";
|
||||
|
||||
var gSubDialog = {
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* import-globals-from preferences.js */
|
||||
|
||||
Components.utils.import("resource://services-sync/main.js");
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// This file gets imported into the same scope as head.js.
|
||||
/* import-globals-from head.js */
|
||||
|
||||
function* runTestOnPrivacyPrefPane(testFunc) {
|
||||
info("runTestOnPrivacyPrefPane entered");
|
||||
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:preferences", true, true);
|
||||
|
|
|
@ -27,9 +27,9 @@
|
|||
<description>&settings.description;</description>
|
||||
<separator class="thin"/>
|
||||
|
||||
<hbox id="searchBoxContainer" align="center">
|
||||
<label accesskey="&search.accesskey;" control="searchBox">&search.label;</label>
|
||||
<textbox id="searchBox" type="search" flex="1"/>
|
||||
<hbox id="searchBoxContainer">
|
||||
<textbox id="searchBox" type="search" flex="1"
|
||||
placeholder="&searchPlaceHolder;" accesskey="&searchPlaceHolder.accesskey;"/>
|
||||
</hbox>
|
||||
<separator class="thin"/>
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
/* eslint-env mozilla/frame-script */
|
||||
|
||||
/**
|
||||
* Given some window in the parent process, ensure that
|
||||
* the nsIXULWindow has the CHROME_PRIVATE_WINDOW chromeFlag,
|
||||
|
|
|
@ -3,6 +3,12 @@
|
|||
- 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/. -->
|
||||
|
||||
<!-- This file is imported into the browser window. -->
|
||||
<!-- eslint-env mozilla/browser-window -->
|
||||
|
||||
<!-- XULCommandEvent is a specialised global. -->
|
||||
<!-- global XULCommandEvent -->
|
||||
|
||||
<!DOCTYPE bindings [
|
||||
<!ENTITY % searchBarDTD SYSTEM "chrome://browser/locale/searchbar.dtd" >
|
||||
%searchBarDTD;
|
||||
|
|
|
@ -4216,9 +4216,10 @@ var SessionStoreInternal = {
|
|||
_shouldSaveTab: function ssi_shouldSaveTab(aTabState) {
|
||||
// If the tab has one of the following transient about: history entry,
|
||||
// then we don't actually want to write this tab's data to disk.
|
||||
return aTabState.entries.length &&
|
||||
!(aTabState.entries[0].url == "about:printpreview" ||
|
||||
aTabState.entries[0].url == "about:privatebrowsing");
|
||||
return aTabState.userTypedValue ||
|
||||
(aTabState.entries.length &&
|
||||
!(aTabState.entries[0].url == "about:printpreview" ||
|
||||
aTabState.entries[0].url == "about:privatebrowsing"));
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -13,7 +13,7 @@ Cu.import("resource:///modules/syncedtabs/SyncedTabsDeckComponent.js");
|
|||
XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts",
|
||||
"resource://gre/modules/FxAccounts.jsm");
|
||||
|
||||
this.syncedTabsDeckComponent = new SyncedTabsDeckComponent({window, SyncedTabs, fxAccounts});
|
||||
var syncedTabsDeckComponent = new SyncedTabsDeckComponent({window, SyncedTabs, fxAccounts});
|
||||
|
||||
let onLoaded = () => {
|
||||
syncedTabsDeckComponent.init();
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<!-- eslint-env mozilla/browser-window -->
|
||||
|
||||
<!DOCTYPE bindings [
|
||||
<!ENTITY % notificationDTD SYSTEM "chrome://global/locale/notification.dtd">
|
||||
%notificationDTD;
|
||||
|
|
|
@ -326,6 +326,7 @@ if (typeof Mozilla == "undefined") {
|
|||
})();
|
||||
|
||||
// Make this library Require-able.
|
||||
/* eslint-env commonjs */
|
||||
if (typeof module !== "undefined" && module.exports) {
|
||||
module.exports = Mozilla.UITour;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
/* eslint-env mozilla/frame-script */
|
||||
|
||||
var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
const PREF_TEST_WHITELIST = "browser.uitour.testingOrigins";
|
||||
const UITOUR_PERMISSION = "uitour";
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
"use strict";
|
||||
|
||||
// This file spawns a content task.
|
||||
/* eslint-env mozilla/frame-script */
|
||||
|
||||
// This file expects these globals to be defined by the test case.
|
||||
/* global gTestTab:true, gContentAPI:true, gContentWindow:true, tests:false */
|
||||
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "UITour",
|
||||
|
|
|
@ -2,23 +2,25 @@ MOZ_AUTOMATION_BUILD_SYMBOLS=0
|
|||
MOZ_AUTOMATION_PACKAGE_TESTS=0
|
||||
MOZ_AUTOMATION_L10N_CHECK=0
|
||||
|
||||
# The toolchain installed on our OSX 10.7 build machines is too old to support
|
||||
# MachO LC_DATA_IN_CODE load command, which newer LLVM generates, so we need to
|
||||
# use a newer toolchain that we build.
|
||||
#
|
||||
# Unfortunately setting $PATH is not enough, because the build system hardcodes
|
||||
# the default values for some of the build tools, which we also need to
|
||||
# override below. The default value for host ar and host ranlib is also
|
||||
# hardcoded so we need to override those separately.
|
||||
CCTOOLS_DIR="$topsrcdir/cctools/bin"
|
||||
export PATH="$CCTOOLS_DIR:$PATH"
|
||||
export AR="$CCTOOLS_DIR/ar"
|
||||
export HOST_AR="$CCTOOLS_DIR/ar"
|
||||
export RANLIB="$CCTOOLS_DIR/ranlib"
|
||||
export HOST_RANLIB="$CCTOOLS_DIR/ranlib"
|
||||
export LIPO="$CCTOOLS_DIR/lipo"
|
||||
export OTOOL="$CCTOOLS_DIR/otool"
|
||||
export STRIP="$CCTOOLS_DIR/strip"
|
||||
if test `uname -s` = Darwin; then
|
||||
# The toolchain installed on our OSX 10.7 build machines is too old to support
|
||||
# MachO LC_DATA_IN_CODE load command, which newer LLVM generates, so we need to
|
||||
# use a newer toolchain that we build.
|
||||
#
|
||||
# Unfortunately setting $PATH is not enough, because the build system hardcodes
|
||||
# the default values for some of the build tools, which we also need to
|
||||
# override below. The default value for host ar and host ranlib is also
|
||||
# hardcoded so we need to override those separately.
|
||||
CCTOOLS_DIR="$topsrcdir/cctools/bin"
|
||||
export PATH="$CCTOOLS_DIR:$PATH"
|
||||
export AR="$CCTOOLS_DIR/ar"
|
||||
export HOST_AR="$CCTOOLS_DIR/ar"
|
||||
export RANLIB="$CCTOOLS_DIR/ranlib"
|
||||
export HOST_RANLIB="$CCTOOLS_DIR/ranlib"
|
||||
export LIPO="$CCTOOLS_DIR/lipo"
|
||||
export OTOOL="$CCTOOLS_DIR/otool"
|
||||
export STRIP="$CCTOOLS_DIR/strip"
|
||||
fi
|
||||
|
||||
. $topsrcdir/build/macosx/mozconfig.common
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
<!ENTITY hostCol.label "Site">
|
||||
<!ENTITY statusCol.label "Status">
|
||||
<!ENTITY usageCol.label "Storage">
|
||||
<!ENTITY search.label "Search:">
|
||||
<!ENTITY search.accesskey "S">
|
||||
<!ENTITY searchPlaceHolder "Search">
|
||||
<!ENTITY searchPlaceHolder.accesskey "S">
|
||||
<!ENTITY removeSelected.label "Remove Selected">
|
||||
<!ENTITY removeSelected.accesskey "r">
|
||||
<!ENTITY save.label "Save Changes">
|
||||
|
|
|
@ -194,7 +194,8 @@ var DirectoryLinksProvider = {
|
|||
} catch (e) {}
|
||||
|
||||
if (matchOS) {
|
||||
return Services.locale.getLocaleComponentForUserAgent();
|
||||
return Cc["@mozilla.org/intl/ospreferences;1"].
|
||||
getService(Ci.mozIOSPreferences).getSystemLocale();
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
|
@ -141,6 +141,12 @@ this.ExtensionsUI = {
|
|||
}
|
||||
|
||||
let strings = this._buildStrings(info);
|
||||
// If this is an update with no promptable permissions, just apply it
|
||||
if (info.type == "update" && strings.msgs.length == 0) {
|
||||
info.resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
this.showPermissionsPrompt(target, strings, info.icon).then(answer => {
|
||||
if (answer) {
|
||||
info.resolve();
|
||||
|
|
|
@ -88,7 +88,7 @@ var ReaderParent = {
|
|||
|
||||
let button = win.document.getElementById("reader-mode-button");
|
||||
let command = win.document.getElementById("View:ReaderView");
|
||||
let key = win.document.getElementById("toggleReaderMode");
|
||||
let key = win.document.getElementById("key_toggleReaderMode");
|
||||
if (browser.currentURI.spec.startsWith("about:reader")) {
|
||||
button.setAttribute("readeractive", true);
|
||||
button.hidden = false;
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
skin/classic/browser/aboutNetError.css (../shared/aboutNetError.css)
|
||||
skin/classic/browser/blockedSite.css (../shared/blockedSite.css)
|
||||
skin/classic/browser/error-pages.css (../shared/error-pages.css)
|
||||
skin/classic/browser/browser.inc.css (../shared/browser.inc.css)
|
||||
* skin/classic/browser/aboutProviderDirectory.css (../shared/aboutProviderDirectory.css)
|
||||
* skin/classic/browser/aboutSessionRestore.css (../shared/aboutSessionRestore.css)
|
||||
skin/classic/browser/aboutSocialError.css (../shared/aboutSocialError.css)
|
||||
|
|
|
@ -109,13 +109,6 @@ toolbar:-moz-lwtheme {
|
|||
margin-top: var(--space-above-tabbar);
|
||||
}
|
||||
|
||||
#main-window[customize-entered][tabsintitlebar]:not([inFullscreen]) #toolbar-menubar[customizing-dragovertarget].customization-target::before,
|
||||
#main-window[customize-entered][tabsintitlebar]:not([inFullscreen]) #TabsToolbar[customizing-dragovertarget].customization-target::before,
|
||||
#main-window[customize-entered][tabsintitlebar]:not([inFullscreen]) #toolbar-menubar.customization-target:hover::before,
|
||||
#main-window[customize-entered][tabsintitlebar]:not([inFullscreen]) #TabsToolbar.customization-target:hover::before {
|
||||
outline-color: CaptionText;
|
||||
}
|
||||
|
||||
#navigator-toolbox {
|
||||
-moz-appearance: none;
|
||||
background-color: transparent;
|
||||
|
|
|
@ -43,14 +43,11 @@ button {
|
|||
|
||||
.panel {
|
||||
max-width: 800px;
|
||||
margin-bottom: 35px;
|
||||
}
|
||||
|
||||
/* Targets */
|
||||
|
||||
.targets {
|
||||
margin-bottom: 35px;
|
||||
}
|
||||
|
||||
.target-list {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
|
|
@ -117,9 +117,13 @@ module.exports = createClass({
|
|||
render() {
|
||||
let { client, id } = this.props;
|
||||
let { debugDisabled, extensions: targets } = this.state;
|
||||
let name = Strings.GetStringFromName("extensions");
|
||||
let installedName = Strings.GetStringFromName("extensions");
|
||||
let temporaryName = Strings.GetStringFromName("temporaryExtensions");
|
||||
let targetClass = AddonTarget;
|
||||
|
||||
const installedTargets = targets.filter((target) => !target.temporarilyInstalled);
|
||||
const temporaryTargets = targets.filter((target) => target.temporarilyInstalled);
|
||||
|
||||
return dom.div({
|
||||
id: id + "-panel",
|
||||
className: "panel",
|
||||
|
@ -131,11 +135,21 @@ module.exports = createClass({
|
|||
name: Strings.GetStringFromName("addons")
|
||||
}),
|
||||
AddonsControls({ debugDisabled }),
|
||||
dom.div({ id: "temporary-addons" },
|
||||
TargetList({
|
||||
id: "temporary-extensions",
|
||||
name: temporaryName,
|
||||
targets: temporaryTargets,
|
||||
client,
|
||||
debugDisabled,
|
||||
targetClass,
|
||||
sort: true
|
||||
})),
|
||||
dom.div({ id: "addons" },
|
||||
TargetList({
|
||||
id: "extensions",
|
||||
name,
|
||||
targets,
|
||||
name: installedName,
|
||||
targets: installedTargets,
|
||||
client,
|
||||
debugDisabled,
|
||||
targetClass,
|
||||
|
|
|
@ -58,7 +58,8 @@ module.exports = createClass({
|
|||
// Only temporarily installed add-ons can be reloaded.
|
||||
const canBeReloaded = target.temporarilyInstalled;
|
||||
|
||||
return dom.li({ className: "target-container" },
|
||||
return dom.li(
|
||||
{ className: "target-container", "data-addon-id": target.addonID },
|
||||
dom.img({
|
||||
className: "target-icon",
|
||||
role: "presentation",
|
||||
|
|
|
@ -33,7 +33,7 @@ add_task(function* () {
|
|||
});
|
||||
|
||||
// Retrieve the DEBUG button for the addon
|
||||
let names = [...document.querySelectorAll("#addons .target-name")];
|
||||
let names = getInstalledAddonNames(document);
|
||||
let name = names.filter(element => element.textContent === ADDON_NAME)[0];
|
||||
ok(name, "Found the addon in the list");
|
||||
let targetElement = name.parentNode.parentNode;
|
||||
|
|
|
@ -31,7 +31,7 @@ function* tearDownAddon(addon) {
|
|||
}
|
||||
|
||||
function getReloadButton(document, addonName) {
|
||||
const names = [...document.querySelectorAll("#addons .target-name")];
|
||||
const names = getInstalledAddonNames(document);
|
||||
const name = names.filter(element => element.textContent === addonName)[0];
|
||||
ok(name, `Found ${addonName} add-on in the list`);
|
||||
const targetElement = name.parentNode.parentNode;
|
||||
|
@ -157,7 +157,7 @@ add_task(function* reloadButtonRefreshesMetadata() {
|
|||
const tempExt = new TempWebExt(ADDON_ID);
|
||||
tempExt.writeManifest(manifestBase);
|
||||
|
||||
const onAddonListUpdated = waitForMutation(getAddonList(document),
|
||||
const onAddonListUpdated = waitForMutation(getTemporaryAddonList(document),
|
||||
{ childList: true });
|
||||
const onInstalled = promiseAddonEvent("onInstalled");
|
||||
yield AddonManager.installTemporaryAddon(tempExt.sourceDir);
|
||||
|
@ -170,7 +170,7 @@ add_task(function* reloadButtonRefreshesMetadata() {
|
|||
|
||||
// Wait for the add-on list to be updated with the reloaded name.
|
||||
const onReInstall = promiseAddonEvent("onInstalled");
|
||||
const onAddonReloaded = waitForContentMutation(getAddonList(document));
|
||||
const onAddonReloaded = waitForContentMutation(getTemporaryAddonList(document));
|
||||
|
||||
const reloadButton = getReloadButton(document, manifestBase.name);
|
||||
reloadButton.click();
|
||||
|
@ -178,7 +178,7 @@ add_task(function* reloadButtonRefreshesMetadata() {
|
|||
yield onAddonReloaded;
|
||||
const [reloadedAddon] = yield onReInstall;
|
||||
// Make sure the name was updated correctly.
|
||||
const allAddons = [...document.querySelectorAll("#addons .target-name")]
|
||||
const allAddons = getInstalledAddonNames(document)
|
||||
.map(element => element.textContent);
|
||||
const nameWasUpdated = allAddons.some(name => name === newName);
|
||||
ok(nameWasUpdated, `New name appeared in reloaded add-ons: ${allAddons}`);
|
||||
|
|
|
@ -89,6 +89,37 @@ function getAddonList(document) {
|
|||
document.querySelector("#addons .targets");
|
||||
}
|
||||
|
||||
/**
|
||||
* Depending on whether there are temporary addons installed, return either a
|
||||
* target list element or its container.
|
||||
* @param {DOMDocument} document #temporary-addons section container document
|
||||
* @return {DOMNode} target list or container element
|
||||
*/
|
||||
function getTemporaryAddonList(document) {
|
||||
return document.querySelector("#temporary-addons .target-list") ||
|
||||
document.querySelector("#temporary-addons .targets");
|
||||
}
|
||||
|
||||
/**
|
||||
* Depending on whether the addon is installed, return either the addon list
|
||||
* element or throw an Error.
|
||||
* @param {DOMDocument} document addon section container document
|
||||
* @return {DOMNode} target list
|
||||
* @throws {Error} add-on not found error
|
||||
*/
|
||||
function getAddonListWithAddon(document, id) {
|
||||
const addon = document.querySelector(`[data-addon-id="${id}"]`);
|
||||
if (!addon) {
|
||||
throw new Error("couldn't find add-on by id");
|
||||
}
|
||||
return addon.closest(".target-list");
|
||||
}
|
||||
|
||||
function getInstalledAddonNames(document) {
|
||||
const selector = "#addons .target-name, #temporary-addons .target-name";
|
||||
return [...document.querySelectorAll(selector)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Depending on whether there are service workers installed, return either a
|
||||
* target list element or its container.
|
||||
|
@ -118,7 +149,7 @@ function* installAddon({document, path, name, isWebExtension}) {
|
|||
let file = getSupportsFile(path);
|
||||
MockFilePicker.setFiles([file.file]);
|
||||
|
||||
let addonList = getAddonList(document);
|
||||
let addonList = getTemporaryAddonList(document);
|
||||
let addonListMutation = waitForMutation(addonList, { childList: true });
|
||||
|
||||
let onAddonInstalled;
|
||||
|
@ -159,7 +190,7 @@ function* installAddon({document, path, name, isWebExtension}) {
|
|||
}
|
||||
|
||||
function* uninstallAddon({document, id, name}) {
|
||||
let addonList = getAddonList(document);
|
||||
let addonList = getAddonListWithAddon(document, id);
|
||||
let addonListMutation = waitForMutation(addonList, { childList: true });
|
||||
|
||||
// Now uninstall this addon
|
||||
|
@ -340,7 +371,7 @@ function* setupTestAboutDebuggingWebExtension(name, path) {
|
|||
});
|
||||
|
||||
// Retrieve the DEBUG button for the addon
|
||||
let names = [...document.querySelectorAll("#addons .target-name")];
|
||||
let names = getInstalledAddonNames(document);
|
||||
let nameEl = names.filter(element => element.textContent === name)[0];
|
||||
ok(name, "Found the addon in the list");
|
||||
let targetElement = nameEl.parentNode.parentNode;
|
||||
|
|
|
@ -76,7 +76,6 @@ ToolSidebar.prototype = {
|
|||
"devtools/client/shared/components/tabs/tabbar"));
|
||||
|
||||
let sidebar = Tabbar({
|
||||
toolbox: this._toolPanel._toolbox,
|
||||
showAllTabsMenu: true,
|
||||
onSelect: this.handleSelectionChange.bind(this),
|
||||
});
|
||||
|
|
|
@ -61,6 +61,10 @@ loadTemporaryAddon = Load Temporary Add-on
|
|||
# This string is displayed as a header above the list of loaded add-ons.
|
||||
extensions = Extensions
|
||||
|
||||
# LOCALIZATION NOTE (temporaryExtensions):
|
||||
# This string is displayed as a header above the list of temporarily loaded add-ons.
|
||||
temporaryExtensions = Temporary Extensions
|
||||
|
||||
# LOCALIZATION NOTE (selectAddonFromFile2):
|
||||
# This string is displayed as the title of the file picker that appears when
|
||||
# the user clicks the 'Load Temporary Add-on' button
|
||||
|
|
|
@ -82,11 +82,13 @@ const MonitorPanel = createClass({
|
|||
|
||||
componentWillUnmount() {
|
||||
MediaQueryList.removeListener(this.onLayoutChange);
|
||||
let { clientWidth, clientHeight } = findDOMNode(this.refs.networkDetailsPanel) || {};
|
||||
|
||||
let { clientWidth, clientHeight } = findDOMNode(this.refs.endPanel) || {};
|
||||
|
||||
if (this.state.isVerticalSpliter && clientWidth) {
|
||||
Prefs.networkDetailsWidth = clientWidth;
|
||||
} else if (clientHeight) {
|
||||
}
|
||||
if (!this.state.isVerticalSpliter && clientHeight) {
|
||||
Prefs.networkDetailsHeight = clientHeight;
|
||||
}
|
||||
},
|
||||
|
@ -110,11 +112,7 @@ const MonitorPanel = createClass({
|
|||
maxSize: "80%",
|
||||
splitterSize: "1px",
|
||||
startPanel: RequestList({ isEmpty }),
|
||||
endPanel: networkDetailsOpen ?
|
||||
NetworkDetailsPanel({
|
||||
ref: "networkDetailsPanel",
|
||||
toolbox: window.NetMonitorController._toolbox,
|
||||
}) : null,
|
||||
endPanel: networkDetailsOpen && NetworkDetailsPanel({ ref: "endPanel" }),
|
||||
endPanelControl: true,
|
||||
vert: this.state.isVerticalSpliter,
|
||||
}),
|
||||
|
|
|
@ -55,10 +55,7 @@ const RequestListContent = createClass({
|
|||
cloneSelectedRequest: () => dispatch(Actions.cloneSelectedRequest()),
|
||||
openStatistics: (open) => dispatch(Actions.openStatistics(open)),
|
||||
});
|
||||
this.tooltip = new HTMLTooltip(
|
||||
window.NetMonitorController._toolbox.doc,
|
||||
{ type: "arrow" }
|
||||
);
|
||||
this.tooltip = new HTMLTooltip(window.parent.document, { type: "arrow" });
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
|
|
|
@ -121,7 +121,7 @@ const Toolbar = createClass({
|
|||
title: TOOLBAR_CLEAR,
|
||||
onClick: clearRequests,
|
||||
}),
|
||||
div({ id: "requests-list-filter-buttons" }, buttons),
|
||||
div({ className: "requests-list-filter-buttons" }, buttons),
|
||||
),
|
||||
span({ className: "devtools-toolbar-group" },
|
||||
button({
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
const { TimelineFront } = require("devtools/shared/fronts/timeline");
|
||||
const { CurlUtils } = require("devtools/client/shared/curl");
|
||||
const { ACTIVITY_TYPE, EVENTS } = require("./constants");
|
||||
const { configureStore } = require("./store");
|
||||
const Actions = require("./actions/index");
|
||||
const {
|
||||
fetchHeaders,
|
||||
|
@ -22,7 +21,7 @@ const {
|
|||
getDisplayedRequestById,
|
||||
} = require("./selectors/index");
|
||||
|
||||
const gStore = window.gStore = configureStore();
|
||||
const gStore = window.gStore;
|
||||
|
||||
/**
|
||||
* Object defining the network monitor controller components.
|
||||
|
@ -312,7 +311,7 @@ var NetMonitorController = {
|
|||
* Open a given source in Debugger
|
||||
*/
|
||||
viewSourceInDebugger(sourceURL, sourceLine) {
|
||||
return this._toolbox.viewSourceInDebugger(sourceURL, sourceLine);
|
||||
return this.toolbox.viewSourceInDebugger(sourceURL, sourceLine);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -829,6 +828,7 @@ NetworkEventsHandler.prototype = {
|
|||
* Preliminary setup for the NetMonitorController object.
|
||||
*/
|
||||
NetMonitorController.NetworkEventsHandler = new NetworkEventsHandler();
|
||||
window.NetMonitorController = NetMonitorController;
|
||||
window.gNetwork = NetMonitorController.NetworkEventsHandler;
|
||||
|
||||
exports.NetMonitorController = NetMonitorController;
|
||||
|
|
|
@ -20,6 +20,12 @@ var Netmonitor = {
|
|||
const { createFactory } = require("devtools/client/shared/vendor/react");
|
||||
const { render } = require("devtools/client/shared/vendor/react-dom");
|
||||
const Provider = createFactory(require("devtools/client/shared/vendor/react-redux").Provider);
|
||||
const { configureStore } = require("./store");
|
||||
const store = window.gStore = configureStore();
|
||||
const { NetMonitorController } = require("./netmonitor-controller");
|
||||
NetMonitorController.toolbox = toolbox;
|
||||
NetMonitorController._target = toolbox.target;
|
||||
this.NetMonitorController = NetMonitorController;
|
||||
|
||||
// Components
|
||||
const NetworkMonitor = createFactory(require("./components/network-monitor"));
|
||||
|
@ -27,18 +33,11 @@ var Netmonitor = {
|
|||
// Inject EventEmitter into netmonitor window.
|
||||
EventEmitter.decorate(window);
|
||||
|
||||
window.NetMonitorController = require("./netmonitor-controller").NetMonitorController;
|
||||
window.NetMonitorController._toolbox = toolbox;
|
||||
window.NetMonitorController._target = tabTarget;
|
||||
|
||||
this.root = document.querySelector(".root");
|
||||
|
||||
render(Provider(
|
||||
{ store: window.gStore },
|
||||
NetworkMonitor(),
|
||||
), this.root);
|
||||
render(Provider({ store }, NetworkMonitor()), this.root);
|
||||
|
||||
return window.NetMonitorController.startupNetMonitor();
|
||||
return NetMonitorController.startupNetMonitor();
|
||||
},
|
||||
|
||||
destroy: () => {
|
||||
|
@ -47,6 +46,6 @@ var Netmonitor = {
|
|||
|
||||
unmountComponentAtNode(this.root);
|
||||
|
||||
return window.NetMonitorController.shutdownNetMonitor();
|
||||
return this.NetMonitorController.shutdownNetMonitor();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -5,9 +5,11 @@
|
|||
"use strict";
|
||||
|
||||
const I = require("devtools/client/shared/vendor/immutable");
|
||||
const { ADD_TIMING_MARKER,
|
||||
CLEAR_TIMING_MARKERS,
|
||||
CLEAR_REQUESTS } = require("../constants");
|
||||
const {
|
||||
ADD_TIMING_MARKER,
|
||||
CLEAR_TIMING_MARKERS,
|
||||
CLEAR_REQUESTS,
|
||||
} = require("../constants");
|
||||
|
||||
const TimingMarkers = I.Record({
|
||||
firstDocumentDOMContentLoadedTimestamp: -1,
|
||||
|
@ -15,14 +17,14 @@ const TimingMarkers = I.Record({
|
|||
});
|
||||
|
||||
function addTimingMarker(state, action) {
|
||||
if (action.marker.name == "document::DOMContentLoaded" &&
|
||||
state.firstDocumentDOMContentLoadedTimestamp == -1) {
|
||||
if (action.marker.name === "document::DOMContentLoaded" &&
|
||||
state.firstDocumentDOMContentLoadedTimestamp === -1) {
|
||||
return state.set("firstDocumentDOMContentLoadedTimestamp",
|
||||
action.marker.unixTime / 1000);
|
||||
}
|
||||
|
||||
if (action.marker.name == "document::Load" &&
|
||||
state.firstDocumentLoadTimestamp == -1) {
|
||||
if (action.marker.name === "document::Load" &&
|
||||
state.firstDocumentLoadTimestamp === -1) {
|
||||
return state.set("firstDocumentLoadTimestamp",
|
||||
action.marker.unixTime / 1000);
|
||||
}
|
||||
|
|
|
@ -179,7 +179,7 @@ RequestListContextMenu.prototype = {
|
|||
click: () => this.openStatistics(true)
|
||||
}));
|
||||
|
||||
menu.popup(screenX, screenY, window.NetMonitorController._toolbox);
|
||||
menu.popup(screenX, screenY, { doc: window.parent.document });
|
||||
return menu;
|
||||
},
|
||||
|
||||
|
|
|
@ -27,7 +27,6 @@ function NetworkDetailsPanel({
|
|||
cloneSelectedRequest,
|
||||
request,
|
||||
selectTab,
|
||||
toolbox,
|
||||
}) {
|
||||
if (!request) {
|
||||
return null;
|
||||
|
@ -40,7 +39,6 @@ function NetworkDetailsPanel({
|
|||
activeTabId,
|
||||
request,
|
||||
selectTab,
|
||||
toolbox,
|
||||
}) :
|
||||
CustomRequestPanel({
|
||||
cloneSelectedRequest,
|
||||
|
@ -58,7 +56,6 @@ NetworkDetailsPanel.propTypes = {
|
|||
open: PropTypes.bool,
|
||||
request: PropTypes.object,
|
||||
selectTab: PropTypes.func.isRequired,
|
||||
toolbox: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
module.exports = connect(
|
||||
|
|
|
@ -42,7 +42,6 @@ function TabboxPanel({
|
|||
cloneSelectedRequest,
|
||||
request,
|
||||
selectTab,
|
||||
toolbox,
|
||||
}) {
|
||||
if (!request) {
|
||||
return null;
|
||||
|
@ -54,7 +53,6 @@ function TabboxPanel({
|
|||
onSelect: selectTab,
|
||||
renderOnlySelected: true,
|
||||
showAllTabsMenu: true,
|
||||
toolbox,
|
||||
},
|
||||
TabPanel({
|
||||
id: "headers",
|
||||
|
@ -111,7 +109,6 @@ TabboxPanel.propTypes = {
|
|||
cloneSelectedRequest: PropTypes.func.isRequired,
|
||||
request: PropTypes.object,
|
||||
selectTab: PropTypes.func.isRequired,
|
||||
toolbox: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
module.exports = connect(
|
||||
|
|
|
@ -55,9 +55,7 @@ add_task(function* () {
|
|||
document.querySelectorAll(".request-list-item")[0]);
|
||||
|
||||
yield waitForClipboardPromise(function setup() {
|
||||
// Context menu is appending in XUL document, we must select it from
|
||||
// toolbox.doc
|
||||
monitor.toolbox.doc
|
||||
monitor.panelWin.parent.document
|
||||
.querySelector("#request-list-context-copy-as-curl").click();
|
||||
}, function validate(result) {
|
||||
if (typeof result !== "string") {
|
||||
|
|
|
@ -41,9 +41,7 @@ add_task(function* () {
|
|||
].join("\n");
|
||||
|
||||
yield waitForClipboardPromise(function setup() {
|
||||
// Context menu is appending in XUL document, we must select it from
|
||||
// toolbox.doc
|
||||
monitor.toolbox.doc
|
||||
monitor.panelWin.parent.document
|
||||
.querySelector("#request-list-context-copy-request-headers").click();
|
||||
}, function validate(result) {
|
||||
// Sometimes, a "Cookie" header is left over from other tests. Remove it:
|
||||
|
@ -66,9 +64,7 @@ add_task(function* () {
|
|||
document.querySelectorAll(".request-list-item")[0]);
|
||||
|
||||
yield waitForClipboardPromise(function setup() {
|
||||
// Context menu is appending in XUL document, we must select it from
|
||||
// _oolbox.doc
|
||||
monitor.toolbox.doc
|
||||
monitor.panelWin.parent.document
|
||||
.querySelector("#response-list-context-copy-response-headers").click();
|
||||
}, function validate(result) {
|
||||
// Fake the "Last-Modified" and "Date" headers because they will vary:
|
||||
|
|
|
@ -25,9 +25,7 @@ add_task(function* () {
|
|||
document.querySelectorAll(".request-list-item")[5]);
|
||||
|
||||
yield waitForClipboardPromise(function setup() {
|
||||
// Context menu is appending in XUL document, we must select it from
|
||||
// toolbox.doc
|
||||
monitor.toolbox.doc
|
||||
monitor.panelWin.parent.document
|
||||
.querySelector("#request-list-context-copy-image-as-data-uri").click();
|
||||
}, TEST_IMAGE_DATA_URI);
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ add_task(function* () {
|
|||
document.querySelectorAll(".request-list-item")[index]);
|
||||
EventUtils.sendMouseEvent({ type: "contextmenu" },
|
||||
document.querySelectorAll(".request-list-item")[index]);
|
||||
let copyUrlParamsNode = monitor.toolbox.doc
|
||||
let copyUrlParamsNode = monitor.panelWin.parent.document
|
||||
.querySelector("#request-list-context-copy-url-params");
|
||||
is(!!copyUrlParamsNode, !hidden,
|
||||
"The \"Copy URL Parameters\" context menu item should" + (hidden ? " " : " not ") +
|
||||
|
@ -75,7 +75,7 @@ add_task(function* () {
|
|||
EventUtils.sendMouseEvent({ type: "contextmenu" },
|
||||
document.querySelectorAll(".request-list-item")[index]);
|
||||
yield waitForClipboardPromise(function setup() {
|
||||
monitor.toolbox.doc
|
||||
monitor.panelWin.parent.document
|
||||
.querySelector("#request-list-context-copy-url-params").click();
|
||||
}, queryString);
|
||||
ok(true, "The url query string copied from the selected item is correct.");
|
||||
|
@ -86,7 +86,7 @@ add_task(function* () {
|
|||
document.querySelectorAll(".request-list-item")[index]);
|
||||
EventUtils.sendMouseEvent({ type: "contextmenu" },
|
||||
document.querySelectorAll(".request-list-item")[index]);
|
||||
let copyPostDataNode = monitor.toolbox.doc
|
||||
let copyPostDataNode = monitor.panelWin.parent.document
|
||||
.querySelector("#request-list-context-copy-post-data");
|
||||
is(!!copyPostDataNode, !hidden,
|
||||
"The \"Copy POST Data\" context menu item should" + (hidden ? " " : " not ") +
|
||||
|
@ -99,7 +99,7 @@ add_task(function* () {
|
|||
EventUtils.sendMouseEvent({ type: "contextmenu" },
|
||||
document.querySelectorAll(".request-list-item")[index]);
|
||||
yield waitForClipboardPromise(function setup() {
|
||||
monitor.toolbox.doc
|
||||
monitor.panelWin.parent.document
|
||||
.querySelector("#request-list-context-copy-post-data").click();
|
||||
}, postData);
|
||||
ok(true, "The post data string copied from the selected item is correct.");
|
||||
|
|
|
@ -27,9 +27,7 @@ add_task(function* () {
|
|||
document.querySelectorAll(".request-list-item")[3]);
|
||||
|
||||
yield waitForClipboardPromise(function setup() {
|
||||
// Context menu is appending in XUL document, we must select it from
|
||||
// toolbox.doc
|
||||
monitor.toolbox.doc
|
||||
monitor.panelWin.parent.document
|
||||
.querySelector("#request-list-context-copy-response").click();
|
||||
}, EXPECTED_RESULT);
|
||||
|
||||
|
|
|
@ -27,9 +27,7 @@ add_task(function* () {
|
|||
document.querySelectorAll(".request-list-item")[0]);
|
||||
|
||||
yield waitForClipboardPromise(function setup() {
|
||||
// Context menu is appending in XUL document, we must select it from
|
||||
// toolbox.doc
|
||||
monitor.toolbox.doc
|
||||
monitor.panelWin.parent.document
|
||||
.querySelector("#request-list-context-copy-image-as-data-uri").click();
|
||||
}, function check(text) {
|
||||
return text.startsWith("data:") && !/undefined/.test(text);
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче