merge autoland to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2017-03-06 10:51:51 +01:00
Родитель e844f7b79d d28fbf09bc
Коммит cec6c3f714
362 изменённых файлов: 6391 добавлений и 3874 удалений

Просмотреть файл

@ -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);

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше