MozReview-Commit-ID: HlYQkwnswIh

--HG--
rename : gfx/layers/ipc/CompositorVsyncScheduler.h => gfx/layers/ipc/CompositorVsyncSchedulerOwner.h
rename : layout/style/test/test_flexbox_min_size_auto.html => layout/style/test/test_computed_style_min_size_auto.html
rename : config/external/nss/moz.build => security/moz.build
rename : config/external/nss/nss.symbols => security/nss.symbols
rename : testing/marionette/components/marionettecomponent.js => testing/marionette/components/marionette.js
rename : testing/web-platform/tests/XMLHttpRequest/event-upload-progress-crossorigin.sub.htm => testing/web-platform/tests/XMLHttpRequest/event-upload-progress-crossorigin.htm
rename : testing/web-platform/tests/XMLHttpRequest/send-non-same-origin.sub.htm => testing/web-platform/tests/XMLHttpRequest/send-non-same-origin.htm
rename : testing/web-platform/tests/html/browsers/history/the-location-interface/security_location_0.sub.htm => testing/web-platform/tests/html/browsers/history/the-location-interface/security_location_0.htm
rename : testing/web-platform/tests/html/browsers/the-window-object/security-window/window-security.sub.html => testing/web-platform/tests/html/browsers/the-window-object/security-window/window-security.html
rename : testing/web-platform/tests/html/browsers/windows/nested-browsing-contexts/frameElement.sub.html => testing/web-platform/tests/html/browsers/windows/nested-browsing-contexts/frameElement.html
rename : testing/web-platform/tests/html/browsers/windows/targeting-cross-origin-nested-browsing-contexts.sub.html => testing/web-platform/tests/html/browsers/windows/targeting-cross-origin-nested-browsing-contexts.html
rename : testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Document.currentScript.sub.html => testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Document.currentScript.html
rename : testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_href_specified.sub.html => testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_href_specified.html
rename : toolkit/components/places/tests/cpp/mock_Link.h => toolkit/components/places/tests/gtest/mock_Link.h
rename : toolkit/components/places/tests/cpp/moz.build => toolkit/components/places/tests/gtest/moz.build
rename : toolkit/components/places/tests/cpp/places_test_harness.h => toolkit/components/places/tests/gtest/places_test_harness.h
rename : toolkit/components/places/tests/cpp/places_test_harness_tail.h => toolkit/components/places/tests/gtest/places_test_harness_tail.h
rename : toolkit/components/places/tests/cpp/test_IHistory.cpp => toolkit/components/places/tests/gtest/test_IHistory.cpp
rename : browser/themes/shared/filters.svg => toolkit/themes/shared/filters.svg
rename : browser/themes/shared/downloads/menubutton-dropmarker.svg => toolkit/themes/shared/icons/menubutton-dropmarker.svg
extra : amend_source : b446cd55619aa09f6d48941ab201fb796738d217
This commit is contained in:
Kartikaya Gupta 2016-11-21 10:24:00 -05:00
Родитель 0bf678e8d3 59bb309e38
Коммит d654e9aa16
1713 изменённых файлов: 181811 добавлений и 122451 удалений

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

@ -175,7 +175,7 @@ endif
tup:
$(call BUILDSTATUS,TIERS make tup)
$(call BUILDSTATUS,TIER_START make)
$(MAKE) install-manifests buildid.h source-repo.h
$(MAKE) buildid.h source-repo.h
$(call BUILDSTATUS,TIER_FINISH make)
$(call BUILDSTATUS,TIER_START tup)
@$(TUP) $(if $(findstring s,$(filter-out --%,$(MAKEFLAGS))),,--verbose)

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

@ -3296,17 +3296,6 @@ module.exports={
"_retval": "longstring"
}
}
},
{
"name": "getRawPermissionsTable",
"request": {
"type": "getRawPermissionsTable"
},
"response": {
"value": {
"_retval": "json"
}
}
}
],
"events": {}

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

@ -281,6 +281,15 @@ exports.testValidateMapWithMissingKeyAndThrown = function (assert) {
assert.deepEqual(val, { baz: "foo" });
};
function forEachEnabled() {
try {
eval(`for each (var x in {}) {}`);
} catch (e) {
return false;
}
return true;
}
exports.testAddIterator = function testAddIterator (assert) {
let obj = {};
let keys = ["foo", "bar", "baz"];
@ -303,14 +312,17 @@ exports.testAddIterator = function testAddIterator (assert) {
for (let i = 0; i < keys.length; i++)
assert.equal(keysItr[i], keys[i], "the key is correct");
let valsItr = [];
for each (let val in obj)
valsItr.push(val);
assert.equal(valsItr.length, vals.length,
"the vals iterator returns the correct number of items");
for (let i = 0; i < vals.length; i++)
assert.equal(valsItr[i], vals[i], "the val is correct");
if (forEachEnabled()) {
eval(`
let valsItr = [];
for each (let val in obj)
valsItr.push(val);
assert.equal(valsItr.length, vals.length,
"the vals iterator returns the correct number of items");
for (let i = 0; i < vals.length; i++)
assert.equal(valsItr[i], vals[i], "the val is correct");
`);
}
};
require("sdk/test").run(exports);

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

@ -423,9 +423,9 @@ exports["test Object Tag"] = createProxyTest("", function (helper) {
helper.createWorker(
'new ' + function ContentScriptScope() {
// <object>, <embed> and other tags return typeof 'function'
// <object>, <embed> and other tags return typeof 'object'
let flash = document.createElement("object");
assert(typeof flash == "function", "<object> is typeof 'function'");
assert(typeof flash == "object", "<object> is typeof 'function'");
assert(flash.toString().match(/\[object HTMLObjectElement.*\]/), "<object> is HTMLObjectElement");
assert("setAttribute" in flash, "<object> has a setAttribute method");
done();

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

@ -500,9 +500,6 @@ pref("app.update.socket.maxErrors", 20);
// Enable update logging for now, to diagnose growing pains in the
// field.
pref("app.update.log", true);
// SystemUpdate API
pref("dom.system_update.active", "@mozilla.org/updates/update-prompt;1");
#else
// Explicitly disable the shutdown watchdog. It's enabled by default.
// When the updater is disabled, we want to know about shutdown hangs.
@ -939,9 +936,6 @@ pref("identity.fxaccounts.skipDeviceRegistration", true);
// Enable mapped array buffer.
pref("dom.mapped_arraybuffer.enabled", true);
// SystemUpdate API
pref("dom.system_update.enabled", true);
// UDPSocket API
pref("dom.udpsocket.enabled", true);

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

@ -9,13 +9,6 @@ contract @mozilla.org/system-alerts-service;1 {fe33c107-82a4-41d6-8c64-5353267e0
component {8c719f03-afe0-4aac-91ff-6c215895d467} ContentPermissionPrompt.js
contract @mozilla.org/content-permission/prompt;1 {8c719f03-afe0-4aac-91ff-6c215895d467}
#ifdef MOZ_UPDATER
# UpdatePrompt.js
component {88b3eb21-d072-4e3b-886d-f89d8c49fe59} UpdatePrompt.js
contract @mozilla.org/updates/update-prompt;1 {88b3eb21-d072-4e3b-886d-f89d8c49fe59}
category system-update-provider MozillaProvider @mozilla.org/updates/update-prompt;1,{88b3eb21-d072-4e3b-886d-f89d8c49fe59}
#endif
#ifdef MOZ_B2G
# DirectoryProvider.js
component {9181eb7c-6f87-11e1-90b1-4f59d80dd2e5} DirectoryProvider.js

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

@ -24,7 +24,6 @@ const ALLOW_MULTIPLE_REQUESTS = ["audio-capture", "video-capture"];
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/PermissionsTable.jsm");
var permissionManager = Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager);
var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
@ -67,56 +66,6 @@ function buildDefaultChoices(aTypesInfo) {
return choices;
}
/**
* aTypesInfo is an array of {permission, access, action, deny} which keeps
* the information of each permission. This arrary is initialized in
* ContentPermissionPrompt.prompt and used among functions.
*
* aTypesInfo[].permission : permission name
* aTypesInfo[].access : permission name + request.access
* aTypesInfo[].action : the default action of this permission
* aTypesInfo[].deny : true if security manager denied this app's origin
* principal.
* Note:
* aTypesInfo[].permission will be sent to prompt only when
* aTypesInfo[].action is PROMPT_ACTION and aTypesInfo[].deny is false.
*/
function rememberPermission(aTypesInfo, aPrincipal, aSession)
{
function convertPermToAllow(aPerm, aPrincipal)
{
let type =
permissionManager.testExactPermissionFromPrincipal(aPrincipal, aPerm);
if (shouldPrompt(aPerm, type)) {
debug("add " + aPerm + " to permission manager with ALLOW_ACTION");
if (!aSession) {
permissionManager.addFromPrincipal(aPrincipal,
aPerm,
Ci.nsIPermissionManager.ALLOW_ACTION);
} else if (PERMISSION_NO_SESSION.indexOf(aPerm) < 0) {
permissionManager.addFromPrincipal(aPrincipal,
aPerm,
Ci.nsIPermissionManager.ALLOW_ACTION,
Ci.nsIPermissionManager.EXPIRE_SESSION, 0);
}
}
}
for (let i in aTypesInfo) {
// Expand the permission to see if we have multiple access properties
// to convert
let perm = aTypesInfo[i].permission;
let access = PermissionsTable[perm].access;
if (access) {
for (let idx in access) {
convertPermToAllow(perm + "-" + access[idx], aPrincipal);
}
} else {
convertPermToAllow(perm, aPrincipal);
}
}
}
function ContentPermissionPrompt() {}
ContentPermissionPrompt.prototype = {
@ -296,7 +245,6 @@ ContentPermissionPrompt.prototype = {
this.sendToBrowserWindow("permission-prompt", request, typesInfo,
function(type, remember, choices) {
if (type == "permission-allow") {
rememberPermission(typesInfo, request.principal, !remember);
if (callback) {
callback();
}

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

@ -1,783 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
* vim: sw=2 ts=8 et :
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
const Cr = Components.results;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/AppConstants.jsm");
const VERBOSE = 1;
var log =
VERBOSE ?
function log_dump(msg) { dump("UpdatePrompt: "+ msg +"\n"); } :
function log_noop(msg) { };
const PREF_APPLY_PROMPT_TIMEOUT = "b2g.update.apply-prompt-timeout";
const PREF_APPLY_IDLE_TIMEOUT = "b2g.update.apply-idle-timeout";
const PREF_DOWNLOAD_WATCHDOG_TIMEOUT = "b2g.update.download-watchdog-timeout";
const PREF_DOWNLOAD_WATCHDOG_MAX_RETRIES = "b2g.update.download-watchdog-max-retries";
const NETWORK_ERROR_OFFLINE = 111;
const HTTP_ERROR_OFFSET = 1000;
const STATE_DOWNLOADING = 'downloading';
XPCOMUtils.defineLazyServiceGetter(Services, "aus",
"@mozilla.org/updates/update-service;1",
"nsIApplicationUpdateService");
XPCOMUtils.defineLazyServiceGetter(Services, "um",
"@mozilla.org/updates/update-manager;1",
"nsIUpdateManager");
XPCOMUtils.defineLazyServiceGetter(Services, "idle",
"@mozilla.org/widget/idleservice;1",
"nsIIdleService");
XPCOMUtils.defineLazyServiceGetter(Services, "settings",
"@mozilla.org/settingsService;1",
"nsISettingsService");
XPCOMUtils.defineLazyServiceGetter(Services, 'env',
'@mozilla.org/process/environment;1',
'nsIEnvironment');
function useSettings() {
// When we're running in the real phone, then we can use settings.
// But when we're running as part of xpcshell, there is no settings database
// and trying to use settings in this scenario causes lots of weird
// assertions at shutdown time.
if (typeof useSettings.result === "undefined") {
useSettings.result = !Services.env.get("XPCSHELL_TEST_PROFILE_DIR");
}
return useSettings.result;
}
XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
"resource://gre/modules/SystemAppProxy.jsm");
function UpdateCheckListener(updatePrompt) {
this._updatePrompt = updatePrompt;
}
UpdateCheckListener.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIUpdateCheckListener]),
_updatePrompt: null,
onCheckComplete: function UCL_onCheckComplete(request, updates, updateCount) {
if (Services.um.activeUpdate) {
// We're actively downloading an update, that's the update the user should
// see, even if a newer update is available.
this._updatePrompt.setUpdateStatus("active-update");
this._updatePrompt.showUpdateAvailable(Services.um.activeUpdate);
return;
}
if (updateCount == 0) {
this._updatePrompt.setUpdateStatus("no-updates");
if (this._updatePrompt._systemUpdateListener) {
this._updatePrompt._systemUpdateListener.onError("no-updates");
}
return;
}
let update = Services.aus.selectUpdate(updates, updateCount);
if (!update) {
this._updatePrompt.setUpdateStatus("already-latest-version");
if (this._updatePrompt._systemUpdateListener) {
this._updatePrompt._systemUpdateListener.onError("already-latest-version");
}
return;
}
this._updatePrompt.setUpdateStatus("check-complete");
this._updatePrompt.showUpdateAvailable(update);
},
onError: function UCL_onError(request, update) {
// nsIUpdate uses a signed integer for errorCode while any platform errors
// require all 32 bits.
let errorCode = update.errorCode >>> 0;
let isNSError = (errorCode >>> 31) == 1;
let errorMsg = "check-error-";
if (errorCode == NETWORK_ERROR_OFFLINE) {
errorMsg = "retry-when-online";
this._updatePrompt.setUpdateStatus(errorMsg);
} else if (isNSError) {
errorMsg = "check-error-" + errorCode;
this._updatePrompt.setUpdateStatus(errorMsg);
} else if (errorCode > HTTP_ERROR_OFFSET) {
let httpErrorCode = errorCode - HTTP_ERROR_OFFSET;
errorMsg = "check-error-http-" + httpErrorCode;
this._updatePrompt.setUpdateStatus(errorMsg);
}
if (this._updatePrompt._systemUpdateListener) {
this._updatePrompt._systemUpdateListener.onError(errorMsg);
}
Services.aus.QueryInterface(Ci.nsIUpdateCheckListener);
Services.aus.onError(request, update);
}
};
function UpdatePrompt() {
this.wrappedJSObject = this;
this._updateCheckListener = new UpdateCheckListener(this);
}
UpdatePrompt.prototype = {
classID: Components.ID("{88b3eb21-d072-4e3b-886d-f89d8c49fe59}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIUpdatePrompt,
Ci.nsIUpdateCheckListener,
Ci.nsIRequestObserver,
Ci.nsIProgressEventSink,
Ci.nsIObserver,
Ci.nsISystemUpdateProvider]),
_xpcom_factory: XPCOMUtils.generateSingletonFactory(UpdatePrompt),
_update: null,
_applyPromptTimer: null,
_waitingForIdle: false,
_updateCheckListner: null,
_systemUpdateListener: null,
_availableParameters: {
"deviceinfo.last_updated": null,
"gecko.updateStatus": null,
"app.update.channel": null,
"app.update.interval": null,
"app.update.url": null,
},
_pendingUpdateAvailablePackageInfo: null,
_isPendingUpdateReady: false,
_updateErrorQueue: [ ],
_receivedUpdatePromptReady: false,
// nsISystemUpdateProvider
checkForUpdate: function() {
this.forceUpdateCheck();
},
startDownload: function() {
this.downloadUpdate(this._update);
},
stopDownload: function() {
this.handleDownloadCancel();
},
applyUpdate: function() {
this.handleApplyPromptResult({result: "restart"});
},
setParameter: function(aName, aValue) {
if (!this._availableParameters.hasOwnProperty(aName)) {
return false;
}
this._availableParameters[aName] = aValue;
switch (aName) {
case "app.update.channel":
case "app.update.url":
Services.prefs.setCharPref(aName, aValue);
break;
case "app.update.interval":
Services.prefs.setIntPref(aName, parseInt(aValue, 10));
break;
}
return true;
},
getParameter: function(aName) {
if (!this._availableParameters.hasOwnProperty(aName)) {
return null;
}
return this._availableParameters[aName];
},
setListener: function(aListener) {
this._systemUpdateListener = aListener;
// If an update is available or ready, trigger the event right away at this point.
if (this._pendingUpdateAvailablePackageInfo) {
this._systemUpdateListener.onUpdateAvailable(this._pendingUpdateAvailablePackageInfo.type,
this._pendingUpdateAvailablePackageInfo.version,
this._pendingUpdateAvailablePackageInfo.description,
this._pendingUpdateAvailablePackageInfo.buildDate,
this._pendingUpdateAvailablePackageInfo.size);
// Set null when the listener is attached.
this._pendingUpdateAvailablePackageInfo = null;
}
if (this._isPendingUpdateReady) {
this._systemUpdateListener.onUpdateReady();
this._isPendingUpdateReady = false;
}
},
unsetListener: function(aListener) {
this._systemUpdateListener = null;
},
get applyPromptTimeout() {
return Services.prefs.getIntPref(PREF_APPLY_PROMPT_TIMEOUT);
},
get applyIdleTimeout() {
return Services.prefs.getIntPref(PREF_APPLY_IDLE_TIMEOUT);
},
handleContentStart: function UP_handleContentStart() {
SystemAppProxy.addEventListener("mozContentEvent", this);
},
// nsIUpdatePrompt
// FIXME/bug 737601: we should have users opt-in to downloading
// updates when on a billed pipe. Initially, opt-in for 3g, but
// that doesn't cover all cases.
checkForUpdates: function UP_checkForUpdates() { },
showUpdateAvailable: function UP_showUpdateAvailable(aUpdate) {
let packageInfo = {};
packageInfo.version = aUpdate.displayVersion;
packageInfo.description = aUpdate.statusText;
packageInfo.buildDate = aUpdate.buildID;
let patch = aUpdate.selectedPatch;
if (!patch && aUpdate.patchCount > 0) {
// For now we just check the first patch to get size information if a
// patch hasn't been selected yet.
patch = aUpdate.getPatchAt(0);
}
if (patch) {
packageInfo.size = patch.size;
packageInfo.type = patch.type;
} else {
log("Warning: no patches available in update");
}
this._pendingUpdateAvailablePackageInfo = packageInfo;
if (this._systemUpdateListener) {
this._systemUpdateListener.onUpdateAvailable(packageInfo.type,
packageInfo.version,
packageInfo.description,
packageInfo.buildDate,
packageInfo.size);
// Set null since the event is fired.
this._pendingUpdateAvailablePackageInfo = null;
}
if (!this.sendUpdateEvent("update-available", aUpdate)) {
log("Unable to prompt for available update, forcing download");
this.downloadUpdate(aUpdate);
}
},
showUpdateDownloaded: function UP_showUpdateDownloaded(aUpdate, aBackground) {
if (this._systemUpdateListener) {
this._systemUpdateListener.onUpdateReady();
} else {
this._isPendingUpdateReady = true;
}
// The update has been downloaded and staged. We send the update-downloaded
// event right away. After the user has been idle for a while, we send the
// update-prompt-restart event, increasing the chances that we can apply the
// update quietly without user intervention.
this.sendUpdateEvent("update-downloaded", aUpdate);
if (Services.idle.idleTime >= this.applyIdleTimeout) {
this.showApplyPrompt(aUpdate);
return;
}
let applyIdleTimeoutSeconds = this.applyIdleTimeout / 1000;
// We haven't been idle long enough, so register an observer
log("Update is ready to apply, registering idle timeout of " +
applyIdleTimeoutSeconds + " seconds before prompting.");
this._update = aUpdate;
this.waitForIdle();
},
storeUpdateError: function UP_storeUpdateError(aUpdate) {
log("Storing update error for later use");
this._updateErrorQueue.push(aUpdate);
},
sendStoredUpdateError: function UP_sendStoredUpdateError() {
log("Sending stored update error");
this._updateErrorQueue.forEach(aUpdate => {
this.sendUpdateEvent("update-error", aUpdate);
});
this._updateErrorQueue = [ ];
},
showUpdateError: function UP_showUpdateError(aUpdate) {
log("Update error, state: " + aUpdate.state + ", errorCode: " +
aUpdate.errorCode);
if (this._systemUpdateListener) {
this._systemUpdateListener.onError("update-error: " + aUpdate.errorCode + " " + aUpdate.statusText);
}
if (!this._receivedUpdatePromptReady) {
this.storeUpdateError(aUpdate);
} else {
this.sendUpdateEvent("update-error", aUpdate);
}
this.setUpdateStatus(aUpdate.statusText);
},
showUpdateHistory: function UP_showUpdateHistory(aParent) { },
showUpdateInstalled: function UP_showUpdateInstalled() {
this.setParameter("deviceinfo.last_updated", Date.now());
if (useSettings()) {
let lock = Services.settings.createLock();
lock.set("deviceinfo.last_updated", Date.now(), null, null);
}
},
// Custom functions
waitForIdle: function UP_waitForIdle() {
if (this._waitingForIdle) {
return;
}
this._waitingForIdle = true;
Services.idle.addIdleObserver(this, this.applyIdleTimeout / 1000);
Services.obs.addObserver(this, "quit-application", false);
},
setUpdateStatus: function UP_setUpdateStatus(aStatus) {
this.setParameter("gecko.updateStatus", aStatus);
if (useSettings()) {
log("Setting gecko.updateStatus: " + aStatus);
let lock = Services.settings.createLock();
lock.set("gecko.updateStatus", aStatus, null);
}
},
showApplyPrompt: function UP_showApplyPrompt(aUpdate) {
// Notify update package is ready to apply
if (this._systemUpdateListener) {
this._systemUpdateListener.onUpdateReady();
} else {
// Set the flag to true and fire the onUpdateReady event when the listener is attached.
this._isPendingUpdateReady = true;
}
if (!this.sendUpdateEvent("update-prompt-apply", aUpdate)) {
log("Unable to prompt, forcing restart");
this.restartProcess();
return;
}
if (AppConstants.MOZ_B2G_RIL) {
let window = Services.wm.getMostRecentWindow("navigator:browser");
let pinReq = window.navigator.mozIccManager.getCardLock("pin");
pinReq.onsuccess = function(e) {
if (e.target.result.enabled) {
// The SIM is pin locked. Don't use a fallback timer. This means that
// the user has to press Install to apply the update. If we use the
// timer, and the timer reboots the phone, then the phone will be
// unusable until the SIM is unlocked.
log("SIM is pin locked. Not starting fallback timer.");
} else {
// This means that no pin lock is enabled, so we go ahead and start
// the fallback timer.
this._applyPromptTimer = this.createTimer(this.applyPromptTimeout);
}
}.bind(this);
pinReq.onerror = function(e) {
this._applyPromptTimer = this.createTimer(this.applyPromptTimeout);
}.bind(this);
} else {
// Schedule a fallback timeout in case the UI is unable to respond or show
// a prompt for some reason.
this._applyPromptTimer = this.createTimer(this.applyPromptTimeout);
}
},
_copyProperties: ["appVersion", "buildID", "detailsURL", "displayVersion",
"errorCode", "isOSUpdate", "platformVersion",
"previousAppVersion", "state", "statusText"],
sendUpdateEvent: function UP_sendUpdateEvent(aType, aUpdate) {
let detail = {};
for (let property of this._copyProperties) {
detail[property] = aUpdate[property];
}
let patch = aUpdate.selectedPatch;
if (!patch && aUpdate.patchCount > 0) {
// For now we just check the first patch to get size information if a
// patch hasn't been selected yet.
patch = aUpdate.getPatchAt(0);
}
if (patch) {
detail.size = patch.size;
detail.updateType = patch.type;
} else {
log("Warning: no patches available in update");
}
this._update = aUpdate;
return this.sendChromeEvent(aType, detail);
},
sendChromeEvent: function UP_sendChromeEvent(aType, aDetail) {
let detail = aDetail || {};
detail.type = aType;
let sent = SystemAppProxy.dispatchEvent(detail);
if (!sent) {
log("Warning: Couldn't send update event " + aType +
": no content browser. Will send again when content becomes available.");
return false;
}
return true;
},
handleAvailableResult: function UP_handleAvailableResult(aDetail) {
// If the user doesn't choose "download", the updater will implicitly call
// showUpdateAvailable again after a certain period of time
switch (aDetail.result) {
case "download":
this.downloadUpdate(this._update);
break;
}
},
handleApplyPromptResult: function UP_handleApplyPromptResult(aDetail) {
if (this._applyPromptTimer) {
this._applyPromptTimer.cancel();
this._applyPromptTimer = null;
}
switch (aDetail.result) {
// Battery not okay, do not wait for idle to re-prompt
case "low-battery":
break;
case "wait":
// Wait until the user is idle before prompting to apply the update
this.waitForIdle();
break;
case "restart":
this.finishUpdate();
this._update = null;
break;
}
},
downloadUpdate: function UP_downloadUpdate(aUpdate) {
if (!aUpdate) {
aUpdate = Services.um.activeUpdate;
if (!aUpdate) {
log("No active update found to download");
return;
}
}
let status = Services.aus.downloadUpdate(aUpdate, true);
if (status == STATE_DOWNLOADING) {
Services.aus.addDownloadListener(this);
return;
}
// If the update has already been downloaded and applied, then
// Services.aus.downloadUpdate will return immediately and not
// call showUpdateDownloaded, so we detect this.
if (aUpdate.state == "applied" && aUpdate.errorCode == 0) {
this.showUpdateDownloaded(aUpdate, true);
return;
}
log("Error downloading update " + aUpdate.name + ": " + aUpdate.errorCode);
let errorCode = aUpdate.errorCode >>> 0;
if (errorCode == Cr.NS_ERROR_FILE_TOO_BIG) {
aUpdate.statusText = "file-too-big";
}
this.showUpdateError(aUpdate);
},
handleDownloadCancel: function UP_handleDownloadCancel() {
log("Pausing download");
Services.aus.pauseDownload();
},
finishUpdate: function UP_finishUpdate() {
if (!this._update.isOSUpdate) {
// Standard gecko+gaia updates will just need to restart the process
this.restartProcess();
return;
}
try {
Services.aus.applyOsUpdate(this._update);
}
catch (e) {
this._update.errorCode = Cr.NS_ERROR_FAILURE;
this.showUpdateError(this._update);
}
},
restartProcess: function UP_restartProcess() {
log("Update downloaded, restarting to apply it");
let callbackAfterSet = function() {
if (AppConstants.platform !== "gonk") {
let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"]
.getService(Ci.nsIAppStartup);
appStartup.quit(appStartup.eForceQuit | appStartup.eRestart);
} else {
// NB: on Gonk, we rely on the system process manager to restart us.
let pmService = Cc["@mozilla.org/power/powermanagerservice;1"]
.getService(Ci.nsIPowerManagerService);
pmService.restart();
}
}
if (useSettings()) {
// Save current os version in deviceinfo.previous_os
let lock = Services.settings.createLock({
handle: callbackAfterSet,
handleAbort: function(error) {
log("Abort callback when trying to set previous_os: " + error);
callbackAfterSet();
}
});
lock.get("deviceinfo.os", {
handle: function(name, value) {
log("Set previous_os to: " + value);
lock.set("deviceinfo.previous_os", value, null, null);
}
});
}
},
forceUpdateCheck: function UP_forceUpdateCheck() {
log("Forcing update check");
let checker = Cc["@mozilla.org/updates/update-checker;1"]
.createInstance(Ci.nsIUpdateChecker);
checker.checkForUpdates(this._updateCheckListener, true);
},
handleEvent: function UP_handleEvent(evt) {
if (evt.type !== "mozContentEvent") {
return;
}
let detail = evt.detail;
if (!detail) {
return;
}
switch (detail.type) {
case "force-update-check":
this.forceUpdateCheck();
break;
case "update-available-result":
this.handleAvailableResult(detail);
// If we started the apply prompt timer, this means that we're waiting
// for the user to press Later or Install Now. In this situation we
// don't want to clear this._update, becuase handleApplyPromptResult
// needs it.
if (this._applyPromptTimer == null && !this._waitingForIdle) {
this._update = null;
}
break;
case "update-download-cancel":
this.handleDownloadCancel();
break;
case "update-prompt-apply-result":
this.handleApplyPromptResult(detail);
break;
case "update-prompt-ready":
this._receivedUpdatePromptReady = true;
this.sendStoredUpdateError();
break;
}
},
// nsIObserver
observe: function UP_observe(aSubject, aTopic, aData) {
switch (aTopic) {
case "idle":
this._waitingForIdle = false;
this.showApplyPrompt(this._update);
// Fall through
case "quit-application":
Services.idle.removeIdleObserver(this, this.applyIdleTimeout / 1000);
Services.obs.removeObserver(this, "quit-application");
break;
}
},
// nsITimerCallback
notify: function UP_notify(aTimer) {
if (aTimer == this._applyPromptTimer) {
log("Timed out waiting for result, restarting");
this._applyPromptTimer = null;
this.finishUpdate();
this._update = null;
return;
}
if (aTimer == this._watchdogTimer) {
log("Download watchdog fired");
this._watchdogTimer = null;
this._autoRestartDownload = true;
Services.aus.pauseDownload();
return;
}
},
createTimer: function UP_createTimer(aTimeoutMs) {
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
timer.initWithCallback(this, aTimeoutMs, timer.TYPE_ONE_SHOT);
return timer;
},
// nsIRequestObserver
_startedSent: false,
_watchdogTimer: null,
_autoRestartDownload: false,
_autoRestartCount: 0,
startWatchdogTimer: function UP_startWatchdogTimer() {
let watchdogTimeout = 120000; // 120 seconds
try {
watchdogTimeout = Services.prefs.getIntPref(PREF_DOWNLOAD_WATCHDOG_TIMEOUT);
} catch (e) {
// This means that the preference doesn't exist. watchdogTimeout will
// retain its default assigned above.
}
if (watchdogTimeout <= 0) {
// 0 implies don't bother using the watchdog timer at all.
this._watchdogTimer = null;
return;
}
if (this._watchdogTimer) {
this._watchdogTimer.cancel();
} else {
this._watchdogTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
}
this._watchdogTimer.initWithCallback(this, watchdogTimeout,
Ci.nsITimer.TYPE_ONE_SHOT);
},
stopWatchdogTimer: function UP_stopWatchdogTimer() {
if (this._watchdogTimer) {
this._watchdogTimer.cancel();
this._watchdogTimer = null;
}
},
touchWatchdogTimer: function UP_touchWatchdogTimer() {
this.startWatchdogTimer();
},
onStartRequest: function UP_onStartRequest(aRequest, aContext) {
// Wait until onProgress to send the update-download-started event, in case
// this request turns out to fail for some reason
this._startedSent = false;
this.startWatchdogTimer();
},
onStopRequest: function UP_onStopRequest(aRequest, aContext, aStatusCode) {
this.stopWatchdogTimer();
Services.aus.removeDownloadListener(this);
let paused = !Components.isSuccessCode(aStatusCode);
if (!paused) {
// The download was successful, no need to restart
this._autoRestartDownload = false;
}
if (this._autoRestartDownload) {
this._autoRestartDownload = false;
let watchdogMaxRetries = Services.prefs.getIntPref(PREF_DOWNLOAD_WATCHDOG_MAX_RETRIES);
this._autoRestartCount++;
if (this._autoRestartCount > watchdogMaxRetries) {
log("Download - retry count exceeded - error");
// We exceeded the max retries. Treat the download like an error,
// which will give the user a chance to restart manually later.
this._autoRestartCount = 0;
if (Services.um.activeUpdate) {
this.showUpdateError(Services.um.activeUpdate);
}
return;
}
log("Download - restarting download - attempt " + this._autoRestartCount);
this.downloadUpdate(null);
return;
}
this._autoRestartCount = 0;
this.sendChromeEvent("update-download-stopped", {
paused: paused
});
},
// nsIProgressEventSink
onProgress: function UP_onProgress(aRequest, aContext, aProgress,
aProgressMax) {
if (this._systemUpdateListener) {
this._systemUpdateListener.onProgress(aProgress, aProgressMax);
}
if (aProgress == aProgressMax) {
// The update.mar validation done by onStopRequest may take
// a while before the onStopRequest callback is made, so stop
// the timer now.
this.stopWatchdogTimer();
} else {
this.touchWatchdogTimer();
}
if (!this._startedSent) {
this.sendChromeEvent("update-download-started", {
total: aProgressMax
});
this._startedSent = true;
}
this.sendChromeEvent("update-download-progress", {
progress: aProgress,
total: aProgressMax
});
},
onStatus: function UP_onStatus(aRequest, aUpdate, aStatus, aStatusArg) { }
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([UpdatePrompt]);

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

@ -41,11 +41,6 @@ if CONFIG['MOZ_B2G']:
'RecoveryService.js',
]
if CONFIG['MOZ_UPDATER']:
EXTRA_COMPONENTS += [
'UpdatePrompt.js',
]
EXTRA_JS_MODULES += [
'AboutServiceWorkers.jsm',
'ActivityChannel.jsm',

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

@ -774,14 +774,11 @@ bin/libfreebl_32int64_3.so
#if defined(ENABLE_MARIONETTE) || !defined(MOZ_WIDGET_GONK)
@RESPATH@/chrome/marionette@JAREXT@
@RESPATH@/chrome/marionette.manifest
@RESPATH@/components/MarionetteComponents.manifest
@RESPATH@/components/marionettecomponent.js
@RESPATH@/components/marionette.manifest
@RESPATH@/components/marionette.js
#endif
@RESPATH@/components/AlertsService.js
@RESPATH@/components/ContentPermissionPrompt.js
#ifdef MOZ_UPDATER
@RESPATH@/components/UpdatePrompt.js
#endif
@RESPATH@/components/DirectoryProvider.js
@RESPATH@/components/ProcessGlobal.js
@RESPATH@/components/OMAContentHandler.js

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -88,10 +88,20 @@ const gXPInstallObserver = {
const anchorID = "addons-notification-icon";
// Make notifications persist a minimum of 30 seconds
// Make notifications persistent
var options = {
displayURI: installInfo.originatingURI,
timeout: Date.now() + 30000,
persistent: true,
};
let acceptInstallation = () => {
for (let install of installInfo.installs)
install.install();
installInfo = null;
Services.telemetry
.getHistogramById("SECURITY_UI")
.add(Ci.nsISecurityUITelemetry.WARNING_CONFIRM_ADDON_INSTALL_CLICK_THROUGH);
};
let cancelInstallation = () => {
@ -105,8 +115,6 @@ const gXPInstallObserver = {
}
}
this.acceptInstallation = null;
showNextConfirmation();
};
@ -142,16 +150,6 @@ const gXPInstallObserver = {
addonList.appendChild(container);
}
this.acceptInstallation = () => {
for (let install of installInfo.installs)
install.install();
installInfo = null;
Services.telemetry
.getHistogramById("SECURITY_UI")
.add(Ci.nsISecurityUITelemetry.WARNING_CONFIRM_ADDON_INSTALL_CLICK_THROUGH);
};
break;
}
};
@ -187,13 +185,17 @@ const gXPInstallObserver = {
messageString = messageString.replace("#1", brandShortName);
messageString = messageString.replace("#2", installInfo.installs.length);
let cancelButton = document.getElementById("addon-install-confirmation-cancel");
cancelButton.label = gNavigatorBundle.getString("addonInstall.cancelButton.label");
cancelButton.accessKey = gNavigatorBundle.getString("addonInstall.cancelButton.accesskey");
let action = {
label: gNavigatorBundle.getString("addonInstall.acceptButton.label"),
accessKey: gNavigatorBundle.getString("addonInstall.acceptButton.accesskey"),
callback: acceptInstallation,
};
let acceptButton = document.getElementById("addon-install-confirmation-accept");
acceptButton.label = gNavigatorBundle.getString("addonInstall.acceptButton.label");
acceptButton.accessKey = gNavigatorBundle.getString("addonInstall.acceptButton.accesskey");
let secondaryAction = {
label: gNavigatorBundle.getString("addonInstall.cancelButton.label"),
accessKey: gNavigatorBundle.getString("addonInstall.cancelButton.accesskey"),
callback: () => {},
};
if (height) {
notification.style.minHeight = height + "px";
@ -205,8 +207,8 @@ const gXPInstallObserver = {
}
let popup = PopupNotifications.show(browser, "addon-install-confirmation",
messageString, anchorID, null, null,
options);
messageString, anchorID, action,
[secondaryAction], options);
removeNotificationOnEnd(popup, installInfo.installs);
@ -230,9 +232,10 @@ const gXPInstallObserver = {
var brandShortName = brandBundle.getString("brandShortName");
var notificationID = aTopic;
// Make notifications persist a minimum of 30 seconds
// Make notifications persistent
var options = {
displayURI: installInfo.originatingURI,
persistent: true,
timeout: Date.now() + 30000,
};
@ -305,29 +308,46 @@ const gXPInstallObserver = {
options.installs = installInfo.installs;
options.contentWindow = browser.contentWindow;
options.sourceURI = browser.currentURI;
options.eventCallback = (aEvent) => {
options.eventCallback = function(aEvent) {
switch (aEvent) {
case "shown":
let notificationElement = [...this.owner.panel.childNodes]
.find(n => n.notification == this);
if (notificationElement) {
if (Preferences.get("xpinstall.customConfirmationUI", false)) {
notificationElement.setAttribute("mainactiondisabled", "true");
} else {
notificationElement.button.hidden = true;
}
}
break;
case "removed":
options.contentWindow = null;
options.sourceURI = null;
break;
}
};
action = {
label: gNavigatorBundle.getString("addonInstall.acceptButton.label"),
accessKey: gNavigatorBundle.getString("addonInstall.acceptButton.accesskey"),
callback: () => {},
};
let secondaryAction = {
label: gNavigatorBundle.getString("addonInstall.cancelButton.label"),
accessKey: gNavigatorBundle.getString("addonInstall.cancelButton.accesskey"),
callback: () => {
for (let install of installInfo.installs) {
if (install.state != AddonManager.STATE_CANCELLED) {
install.cancel();
}
}
},
};
let notification = PopupNotifications.show(browser, notificationID, messageString,
anchorID, null, null, options);
anchorID, action,
[secondaryAction], options);
notification._startTime = Date.now();
let cancelButton = document.getElementById("addon-progress-cancel");
cancelButton.label = gNavigatorBundle.getString("addonInstall.cancelButton.label");
cancelButton.accessKey = gNavigatorBundle.getString("addonInstall.cancelButton.accesskey");
let acceptButton = document.getElementById("addon-progress-accept");
if (Preferences.get("xpinstall.customConfirmationUI", false)) {
acceptButton.label = gNavigatorBundle.getString("addonInstall.acceptButton.label");
acceptButton.accessKey = gNavigatorBundle.getString("addonInstall.acceptButton.accesskey");
} else {
acceptButton.hidden = true;
}
break; }
case "addon-install-failed": {
// TODO This isn't terribly ideal for the multiple failure case
@ -567,7 +587,7 @@ var LightWeightThemeWebInstaller = {
};
let options = {
timeout: Date.now() + 30000
persistent: true
};
PopupNotifications.show(gBrowser.selectedBrowser, "addon-theme-change",

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

@ -278,6 +278,7 @@ var gPluginHandler = {
let options = {
dismissed: !showNow,
persistent: showNow,
eventCallback: this._clickToPlayNotificationEventCallback,
primaryPlugin: primaryPluginPermission,
pluginData: pluginData,

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

@ -5970,8 +5970,12 @@ var OfflineApps = {
warnQuotaKB / 1024 ]);
let anchorID = "indexedDB-notification-icon";
let options = {
persistent: true,
hideClose: true,
};
PopupNotifications.show(browser, "offline-app-usage", message,
anchorID, mainAction);
anchorID, mainAction, null, options);
// Now that we've warned once, prevent the warning from showing up
// again.
@ -6030,8 +6034,8 @@ var OfflineApps = {
]);
} else {
let mainAction = {
label: gNavigatorBundle.getString("offlineApps.allow"),
accessKey: gNavigatorBundle.getString("offlineApps.allowAccessKey"),
label: gNavigatorBundle.getString("offlineApps.allowStoring.label"),
accessKey: gNavigatorBundle.getString("offlineApps.allowStoring.accesskey"),
callback: function() {
for (let [ciBrowser, ciDocId, ciUri] of notification.options.controlledItems) {
OfflineApps.allowSite(ciBrowser, ciDocId, ciUri);
@ -6039,18 +6043,20 @@ var OfflineApps = {
}
};
let secondaryActions = [{
label: gNavigatorBundle.getString("offlineApps.never"),
accessKey: gNavigatorBundle.getString("offlineApps.neverAccessKey"),
label: gNavigatorBundle.getString("offlineApps.dontAllow.label"),
accessKey: gNavigatorBundle.getString("offlineApps.dontAllow.accesskey"),
callback: function() {
for (let [, , ciUri] of notification.options.controlledItems) {
OfflineApps.disallowSite(ciUri);
}
}
}];
let message = gNavigatorBundle.getFormattedString("offlineApps.available",
let message = gNavigatorBundle.getFormattedString("offlineApps.available2",
[host]);
let anchorID = "indexedDB-notification-icon";
let options = {
persistent: true,
hideClose: true,
controlledItems : [[Cu.getWeakReference(browser), docId, uri]]
};
notification = PopupNotifications.show(browser, notificationID, message,
@ -6132,28 +6138,23 @@ var IndexedDBPromptHelper = {
return;
}
var host = browser.currentURI.asciiHost;
// Get the host name if available or the file path otherwise.
var host = browser.currentURI.asciiHost || browser.currentURI.path;
var message;
var responseTopic;
if (topic == this._permissionsPrompt) {
message = gNavigatorBundle.getFormattedString("offlineApps.available",
message = gNavigatorBundle.getFormattedString("offlineApps.available2",
[ host ]);
responseTopic = this._permissionsResponse;
}
const hiddenTimeoutDuration = 30000; // 30 seconds
const firstTimeoutDuration = 300000; // 5 minutes
var timeoutId;
var observer = requestor.getInterface(Ci.nsIObserver);
var mainAction = {
label: gNavigatorBundle.getString("offlineApps.allow"),
accessKey: gNavigatorBundle.getString("offlineApps.allowAccessKey"),
label: gNavigatorBundle.getString("offlineApps.allowStoring.label"),
accessKey: gNavigatorBundle.getString("offlineApps.allowStoring.accesskey"),
callback: function() {
clearTimeout(timeoutId);
observer.observe(null, responseTopic,
Ci.nsIPermissionManager.ALLOW_ACTION);
}
@ -6161,64 +6162,21 @@ var IndexedDBPromptHelper = {
var secondaryActions = [
{
label: gNavigatorBundle.getString("offlineApps.never"),
accessKey: gNavigatorBundle.getString("offlineApps.neverAccessKey"),
label: gNavigatorBundle.getString("offlineApps.dontAllow.label"),
accessKey: gNavigatorBundle.getString("offlineApps.dontAllow.accesskey"),
callback: function() {
clearTimeout(timeoutId);
observer.observe(null, responseTopic,
Ci.nsIPermissionManager.DENY_ACTION);
}
}
];
// This will be set to the result of PopupNotifications.show().
var notification;
function timeoutNotification() {
// Remove the notification.
if (notification) {
notification.remove();
}
// Clear all of our timeout stuff. We may be called directly, not just
// when the timeout actually elapses.
clearTimeout(timeoutId);
// And tell the page that the popup timed out.
observer.observe(null, responseTopic,
Ci.nsIPermissionManager.UNKNOWN_ACTION);
}
var options = {
eventCallback: function(state) {
// Don't do anything if the timeout has not been set yet.
if (!timeoutId) {
return;
}
// If the popup is being dismissed start the short timeout.
if (state == "dismissed") {
clearTimeout(timeoutId);
timeoutId = setTimeout(timeoutNotification, hiddenTimeoutDuration);
return;
}
// If the popup is being re-shown then clear the timeout allowing
// unlimited waiting.
if (state == "shown") {
clearTimeout(timeoutId);
}
}
};
notification = PopupNotifications.show(browser, topic, message,
this._notificationIcon, mainAction,
secondaryActions, options);
// Set the timeoutId after the popup has been created, and use the long
// timeout value. If the user doesn't notice the popup after this amount of
// time then it is most likely not visible and we want to alert the page.
timeoutId = setTimeout(timeoutNotification, firstTimeoutDuration);
PopupNotifications.show(browser, topic, message,
this._notificationIcon, mainAction,
secondaryActions, {
persistent: true,
hideClose: true,
});
}
};

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

@ -22,7 +22,7 @@
<label id="webRTC-selectWindow-label"
control="webRTC-selectWindow-menulist"/>
<menulist id="webRTC-selectWindow-menulist"
oncommand="webrtcUI.updateMainActionLabel(this);">
oncommand="webrtcUI.updateWarningLabel(this);">
<menupopup id="webRTC-selectWindow-menupopup"/>
</menulist>
<description id="webRTC-all-windows-shared" hidden="true">&getUserMedia.allWindowsShared.message;</description>
@ -66,16 +66,8 @@
<progressmeter id="addon-progress-notification-progressmeter"/>
<label id="addon-progress-notification-progresstext" crop="end"/>
</popupnotificationcontent>
<button id="addon-progress-cancel"
oncommand="this.parentNode.cancel();"/>
<button id="addon-progress-accept" disabled="true"/>
</popupnotification>
<popupnotification id="addon-install-confirmation-notification" hidden="true">
<popupnotificationcontent id="addon-install-confirmation-content" orient="vertical"/>
<button id="addon-install-confirmation-cancel"
oncommand="PopupNotifications.getNotification('addon-install-confirmation').remove();"/>
<button id="addon-install-confirmation-accept"
oncommand="gXPInstallObserver.acceptInstallation();
PopupNotifications.getNotification('addon-install-confirmation').remove();"/>
</popupnotification>

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

@ -2860,7 +2860,14 @@
this.mIsBusy = true;
}
this._swapBrowserDocShells(aOurTab, otherBrowser);
this._swapBrowserDocShells(aOurTab, otherBrowser, Ci.nsIBrowser.SWAP_DEFAULT);
}
// Unregister the previously opened URI
if (otherBrowser.registeredOpenURI) {
this._unifiedComplete.unregisterOpenPage(otherBrowser.registeredOpenURI,
otherBrowser.getAttribute("usercontextid") || 0);
delete otherBrowser.registeredOpenURI;
}
// Handle findbar data (if any)
@ -2893,9 +2900,21 @@
</body>
</method>
<method name="swapBrowsers">
<parameter name="aOurTab"/>
<parameter name="aOtherBrowser"/>
<parameter name="aFlags"/>
<body>
<![CDATA[
this._swapBrowserDocShells(aOurTab, aOtherBrowser, aFlags);
]]>
</body>
</method>
<method name="_swapBrowserDocShells">
<parameter name="aOurTab"/>
<parameter name="aOtherBrowser"/>
<parameter name="aFlags"/>
<body>
<![CDATA[
// Unhook our progress listener
@ -2937,15 +2956,17 @@
remoteBrowser._outerWindowIDBrowserMap.set(aOtherBrowser.outerWindowID, aOtherBrowser);
}
// Swap permanentKey properties.
let ourPermanentKey = ourBrowser.permanentKey;
ourBrowser.permanentKey = aOtherBrowser.permanentKey;
aOtherBrowser.permanentKey = ourPermanentKey;
aOurTab.permanentKey = ourBrowser.permanentKey;
if (remoteBrowser) {
let otherTab = remoteBrowser.getTabForBrowser(aOtherBrowser);
if (otherTab) {
otherTab.permanentKey = aOtherBrowser.permanentKey;
if (!(aFlags & Ci.nsIBrowser.SWAP_KEEP_PERMANENT_KEY)) {
// Swap permanentKey properties.
let ourPermanentKey = ourBrowser.permanentKey;
ourBrowser.permanentKey = aOtherBrowser.permanentKey;
aOtherBrowser.permanentKey = ourPermanentKey;
aOurTab.permanentKey = ourBrowser.permanentKey;
if (remoteBrowser) {
let otherTab = remoteBrowser.getTabForBrowser(aOtherBrowser);
if (otherTab) {
otherTab.permanentKey = aOtherBrowser.permanentKey;
}
}
}
@ -2965,18 +2986,16 @@
<parameter name="aOtherBrowser"/>
<body>
<![CDATA[
// If the current URI is registered as open remove it from the list.
if (aOurBrowser.registeredOpenURI) {
this._unifiedComplete.unregisterOpenPage(aOurBrowser.registeredOpenURI,
aOurBrowser.getAttribute("usercontextid") || 0);
delete aOurBrowser.registeredOpenURI;
}
// If the other/new URI is registered as open then copy it over.
// Swap the registeredOpenURI properties of the two browsers
let tmp = aOurBrowser.registeredOpenURI;
delete aOurBrowser.registeredOpenURI;
if (aOtherBrowser.registeredOpenURI) {
aOurBrowser.registeredOpenURI = aOtherBrowser.registeredOpenURI;
delete aOtherBrowser.registeredOpenURI;
}
if (tmp) {
aOtherBrowser.registeredOpenURI = tmp;
}
]]>
</body>
</method>

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

@ -329,9 +329,10 @@ var gTests = [
yield setSignedInUser();
let tab = yield promiseNewTabLoadEvent("about:accounts");
// sign the user out - the tab should have action=signin
let loadPromise = promiseOneMessage(tab, "test:document:load");
yield signOut();
// wait for the new load.
yield promiseOneMessage(tab, "test:document:load");
yield loadPromise;
is(tab.linkedBrowser.contentDocument.location.href, "about:accounts?action=signin");
}
},
@ -435,12 +436,11 @@ function promiseNewTabLoadEvent(aUrl)
let browser = tab.linkedBrowser;
let mm = browser.messageManager;
// give it an e10s-friendly content script to help with our tests.
mm.loadFrameScript(CHROME_BASE + "content_aboutAccounts.js", true);
// give it an e10s-friendly content script to help with our tests,
// and wait for it to tell us about the load.
return promiseOneMessage(tab, "test:document:load").then(
() => tab
);
let promise = promiseOneMessage(tab, "test:document:load");
mm.loadFrameScript(CHROME_BASE + "content_aboutAccounts.js", true);
return promise.then(() => tab);
}
// Returns a promise which is resolved with the iframe's URL after a new
@ -451,13 +451,13 @@ function promiseNewTabWithIframeLoadEvent(aUrl) {
let browser = tab.linkedBrowser;
let mm = browser.messageManager;
// give it an e10s-friendly content script to help with our tests.
mm.loadFrameScript(CHROME_BASE + "content_aboutAccounts.js", true);
// give it an e10s-friendly content script to help with our tests,
// and wait for it to tell us about the iframe load.
mm.addMessageListener("test:iframe:load", function onFrameLoad(message) {
mm.removeMessageListener("test:iframe:load", onFrameLoad);
deferred.resolve([tab, message.data.url]);
});
mm.loadFrameScript(CHROME_BASE + "content_aboutAccounts.js", true);
return deferred.promise;
}

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

@ -78,6 +78,8 @@ function waitForProgressNotification(aPanelOpen = false, aExpectedCount = 1) {
let nodes = Array.from(PopupNotifications.panel.childNodes);
let notification = nodes.find(n => n.id == notificationId + "-notification");
ok(notification, `Should have seen the right notification`);
ok(notification.button.hasAttribute("disabled"),
"The install button should be disabled");
}
return PopupNotifications.panel;
@ -116,13 +118,13 @@ function waitForNotification(aId, aExpectedCount = 1) {
yield observerPromise;
yield panelEventPromise;
info("Saw a notification");
info("Saw a " + aId + " notification");
ok(PopupNotifications.isPanelOpen, "Panel should be open");
is(PopupNotifications.panel.childNodes.length, aExpectedCount, "Should be the right number of notifications");
if (PopupNotifications.panel.childNodes.length) {
let nodes = Array.from(PopupNotifications.panel.childNodes);
let notification = nodes.find(n => n.id == aId + "-notification");
ok(notification, `Should have seen the right notification`);
ok(notification, "Should have seen the " + aId + " notification");
}
return PopupNotifications.panel;
@ -142,8 +144,8 @@ function waitForNotificationClose() {
function waitForInstallDialog() {
return Task.spawn(function* () {
if (Preferences.get("xpinstall.customConfirmationUI", false)) {
yield waitForNotification("addon-install-confirmation");
return;
let panel = yield waitForNotification("addon-install-confirmation");
return panel.childNodes[0];
}
info("Waiting for install dialog");
@ -176,7 +178,7 @@ function waitForInstallDialog() {
let button = domwindow.document.documentElement.getButton("accept");
button.disabled = false;
return;
return null;
});
}
@ -187,18 +189,18 @@ function removeTab() {
]);
}
function acceptInstallDialog() {
function acceptInstallDialog(installDialog) {
if (Preferences.get("xpinstall.customConfirmationUI", false)) {
document.getElementById("addon-install-confirmation-accept").click();
installDialog.button.click();
} else {
let win = Services.wm.getMostRecentWindow("Addons:Install");
win.document.documentElement.acceptDialog();
}
}
function cancelInstallDialog() {
function cancelInstallDialog(installDialog) {
if (Preferences.get("xpinstall.customConfirmationUI", false)) {
document.getElementById("addon-install-confirmation-cancel").click();
installDialog.secondaryButton.click();
} else {
let win = Services.wm.getMostRecentWindow("Addons:Install");
win.document.documentElement.cancelDialog();
@ -293,10 +295,10 @@ function test_blockedInstall() {
ok(PopupNotifications.isPanelOpen, "Notification should still be open");
notification = panel.childNodes[0];
is(notification.id, "addon-progress-notification", "Should have seen the progress notification");
yield dialogPromise;
let installDialog = yield dialogPromise;
notificationPromise = waitForNotification("addon-install-restart");
acceptInstallDialog();
acceptInstallDialog(installDialog);
panel = yield notificationPromise;
notification = panel.childNodes[0];
@ -328,14 +330,14 @@ function test_whitelistedInstall() {
BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?"
+ triggers).then(newTab => tab = newTab);
yield progressPromise;
yield dialogPromise;
let installDialog = yield dialogPromise;
yield BrowserTestUtils.waitForCondition(() => !!tab, "tab should be present");
is(gBrowser.selectedTab, tab,
"tab selected in response to the addon-install-confirmation notification");
let notificationPromise = waitForNotification("addon-install-restart");
acceptInstallDialog();
acceptInstallDialog(installDialog);
let panel = yield notificationPromise;
let notification = panel.childNodes[0];
@ -440,10 +442,10 @@ function test_restartless() {
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
yield progressPromise;
yield dialogPromise;
let installDialog = yield dialogPromise;
let notificationPromise = waitForNotification("addon-install-complete");
acceptInstallDialog();
acceptInstallDialog(installDialog);
let panel = yield notificationPromise;
let notification = panel.childNodes[0];
@ -482,10 +484,10 @@ function test_multiple() {
}));
BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
let panel = yield progressPromise;
yield dialogPromise;
let installDialog = yield dialogPromise;
let notificationPromise = waitForNotification("addon-install-restart");
acceptInstallDialog();
acceptInstallDialog(installDialog);
yield notificationPromise;
let notification = panel.childNodes[0];
@ -512,7 +514,9 @@ function test_multiple() {
function test_sequential() {
return Task.spawn(function* () {
// This test is only relevant if using the new doorhanger UI
if (!Preferences.get("xpinstall.customConfirmationUI", false)) {
// TODO: this subtest is disabled until multiple notification prompts are
// reworked in bug 1188152
if (true || !Preferences.get("xpinstall.customConfirmationUI", false)) {
return;
}
let pm = Services.perms;
@ -525,7 +529,7 @@ function test_sequential() {
}));
BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
yield progressPromise;
yield dialogPromise;
let installDialog = yield dialogPromise;
// Should see the right add-on
let container = document.getElementById("addon-install-confirmation-content");
@ -564,7 +568,7 @@ function test_sequential() {
is(container.childNodes.length, 1, "Should be one item listed");
is(container.childNodes[0].firstChild.getAttribute("value"), "XPI Test", "Should have the right add-on");
cancelInstallDialog();
cancelInstallDialog(installDialog);
ok(PopupNotifications.isPanelOpen, "Panel should still be open");
is(PopupNotifications.panel.childNodes.length, 1, "Should be the right number of notifications");
@ -577,7 +581,7 @@ function test_sequential() {
Services.perms.remove(makeURI("http://example.com"), "install");
let closePromise = waitForNotificationClose();
cancelInstallDialog();
cancelInstallDialog(installDialog);
yield closePromise;
yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
@ -603,7 +607,7 @@ function test_someUnverified() {
}));
BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
yield progressPromise;
yield dialogPromise;
let installDialog = yield dialogPromise;
let notification = document.getElementById("addon-install-confirmation-notification");
let message = notification.getAttribute("label");
@ -620,7 +624,7 @@ function test_someUnverified() {
is(container.childNodes[1].childNodes.length, 1, "Shouldn't have the unverified marker");
let notificationPromise = waitForNotification("addon-install-restart");
acceptInstallDialog();
acceptInstallDialog(installDialog);
yield notificationPromise;
let [addon, theme] = yield new Promise(resolve => {
@ -660,7 +664,7 @@ function test_allUnverified() {
}));
BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
yield progressPromise;
yield dialogPromise;
let installDialog = yield dialogPromise;
let notification = document.getElementById("addon-install-confirmation-notification");
let message = notification.getAttribute("label");
@ -672,7 +676,7 @@ function test_allUnverified() {
is(container.childNodes[0].childNodes.length, 1, "Shouldn't have the unverified marker");
let notificationPromise = waitForNotification("addon-install-complete");
acceptInstallDialog();
acceptInstallDialog(installDialog);
yield notificationPromise;
let addon = yield new Promise(resolve => {
@ -695,10 +699,10 @@ function test_url() {
yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
gBrowser.loadURI(TESTROOT + "amosigned.xpi");
yield progressPromise;
yield dialogPromise;
let installDialog = yield dialogPromise;
let notificationPromise = waitForNotification("addon-install-restart");
acceptInstallDialog();
acceptInstallDialog(installDialog);
let panel = yield notificationPromise;
let notification = panel.childNodes[0];
@ -863,10 +867,10 @@ function test_reload() {
}));
BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
yield progressPromise;
yield dialogPromise;
let installDialog = yield dialogPromise;
let notificationPromise = waitForNotification("addon-install-restart");
acceptInstallDialog();
acceptInstallDialog(installDialog);
let panel = yield notificationPromise;
let notification = panel.childNodes[0];
@ -906,10 +910,10 @@ function test_theme() {
}));
BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
yield progressPromise;
yield dialogPromise;
let installDialog = yield dialogPromise;
let notificationPromise = waitForNotification("addon-install-restart");
acceptInstallDialog();
acceptInstallDialog(installDialog);
let panel = yield notificationPromise;
let notification = panel.childNodes[0];
@ -986,11 +990,11 @@ function test_renotifyInstalled() {
}));
BrowserTestUtils.openNewForegroundTab(gBrowser, TESTROOT + "installtrigger.html?" + triggers);
yield progressPromise;
yield dialogPromise;
let installDialog = yield dialogPromise;
// Wait for the complete notification
let notificationPromise = waitForNotification("addon-install-restart");
acceptInstallDialog();
acceptInstallDialog(installDialog);
let panel = yield notificationPromise;
let closePromise = waitForNotificationClose();
@ -1005,13 +1009,13 @@ function test_renotifyInstalled() {
dialogPromise = waitForInstallDialog();
gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
yield progressPromise;
yield dialogPromise;
installDialog = yield dialogPromise;
info("Timeouts after this probably mean bug 589954 regressed");
// Wait for the complete notification
notificationPromise = waitForNotification("addon-install-restart");
acceptInstallDialog();
acceptInstallDialog(installDialog);
yield notificationPromise;
let installs = yield getInstalls();
@ -1046,7 +1050,6 @@ function test_cancel() {
is(PopupNotifications.panel.childNodes.length, 1, "Should be only one notification");
notification = panel.childNodes[0];
is(notification.id, "addon-progress-notification", "Should have seen the progress notification");
let button = document.getElementById("addon-progress-cancel");
// Cancel the download
let install = notification.notification.options.installs[0];
@ -1058,7 +1061,7 @@ function test_cancel() {
}
});
});
EventUtils.synthesizeMouseAtCenter(button, {});
EventUtils.synthesizeMouseAtCenter(notification.secondaryButton, {});
yield cancelledPromise;
yield new Promise(resolve => executeSoon(resolve));

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

@ -12,6 +12,8 @@ skip-if = (os == "linux" && (debug || asan))
skip-if = (os == "linux" && (debug || asan))
[browser_popupNotification_4.js]
skip-if = (os == "linux" && (debug || asan))
[browser_popupNotification_5.js]
skip-if = (os == "linux" && (debug || asan))
[browser_popupNotification_checkbox.js]
skip-if = (os == "linux" && (debug || asan))
[browser_reshow_in_background.js]

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

@ -47,6 +47,50 @@ var tests = [
ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
}
},
{ id: "Test#2b",
run: function() {
this.notifyObj = new BasicNotification(this.id);
this.notifyObj.secondaryActions.push({
label: "Extra Secondary Action",
accessKey: "E",
callback: () => this.extraSecondaryActionClicked = true,
});
showNotification(this.notifyObj);
},
onShown: function(popup) {
checkPopup(popup, this.notifyObj);
triggerSecondaryCommand(popup, 1);
},
onHidden: function(popup) {
ok(this.extraSecondaryActionClicked, "extra secondary action was clicked");
ok(!this.notifyObj.dismissalCallbackTriggered, "dismissal callback wasn't triggered");
ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
}
},
{ id: "Test#2c",
run: function() {
this.notifyObj = new BasicNotification(this.id);
this.notifyObj.secondaryActions.push({
label: "Extra Secondary Action",
accessKey: "E",
callback: () => ok(false, "unexpected callback invocation"),
}, {
label: "Other Extra Secondary Action",
accessKey: "O",
callback: () => this.extraSecondaryActionClicked = true,
});
showNotification(this.notifyObj);
},
onShown: function(popup) {
checkPopup(popup, this.notifyObj);
triggerSecondaryCommand(popup, 2);
},
onHidden: function(popup) {
ok(this.extraSecondaryActionClicked, "extra secondary action was clicked");
ok(!this.notifyObj.dismissalCallbackTriggered, "dismissal callback wasn't triggered");
ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
}
},
{ id: "Test#3",
run: function() {
this.notifyObj = new BasicNotification(this.id);

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

@ -187,22 +187,6 @@ var tests = [
goNext();
}
},
// Test notification "Not Now" menu item
{ id: "Test#8",
run: function() {
this.notifyObj = new BasicNotification(this.id);
this.notification = showNotification(this.notifyObj);
},
onShown: function(popup) {
checkPopup(popup, this.notifyObj);
triggerSecondaryCommand(popup, 1);
},
onHidden: function(popup) {
ok(this.notifyObj.dismissalCallbackTriggered, "dismissal callback triggered");
this.notification.remove();
ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
}
},
// Test notification close button
{ id: "Test#9",
run: function() {

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

@ -160,23 +160,6 @@ var tests = [
goNext();
}
},
// the hideNotNow option
{ id: "Test#7",
run: function() {
this.notifyObj = new BasicNotification(this.id);
this.notifyObj.options.hideNotNow = true;
this.notifyObj.mainAction.dismiss = true;
this.notification = showNotification(this.notifyObj);
},
onShown: function(popup) {
// checkPopup verifies that the Not Now item is hidden, and that no separator is added.
checkPopup(popup, this.notifyObj);
triggerMainCommand(popup);
},
onHidden: function(popup) {
this.notification.remove();
}
},
// the main action callback can keep the notification.
{ id: "Test#8",
run: function() {
@ -227,68 +210,5 @@ var tests = [
notification.remove();
goNext();
}
},
// panel updates should fire the showing and shown callbacks again.
{ id: "Test#11",
run: function() {
this.notifyObj = new BasicNotification(this.id);
this.notification = showNotification(this.notifyObj);
},
onShown: function(popup) {
checkPopup(popup, this.notifyObj);
this.notifyObj.showingCallbackTriggered = false;
this.notifyObj.shownCallbackTriggered = false;
// Force an update of the panel. This is typically called
// automatically when receiving 'activate' or 'TabSelect' events,
// but from a setTimeout, which is inconvenient for the test.
PopupNotifications._update();
checkPopup(popup, this.notifyObj);
this.notification.remove();
},
onHidden: function() { }
},
// A first dismissed notification shouldn't stop _update from showing a second notification
{ id: "Test#12",
run: function() {
this.notifyObj1 = new BasicNotification(this.id);
this.notifyObj1.id += "_1";
this.notifyObj1.anchorID = "default-notification-icon";
this.notifyObj1.options.dismissed = true;
this.notification1 = showNotification(this.notifyObj1);
this.notifyObj2 = new BasicNotification(this.id);
this.notifyObj2.id += "_2";
this.notifyObj2.anchorID = "geo-notification-icon";
this.notifyObj2.options.dismissed = true;
this.notification2 = showNotification(this.notifyObj2);
this.notification2.dismissed = false;
PopupNotifications._update();
},
onShown: function(popup) {
checkPopup(popup, this.notifyObj2);
this.notification1.remove();
this.notification2.remove();
},
onHidden: function(popup) { }
},
// The anchor icon should be shown for notifications in background windows.
{ id: "Test#13",
run: function() {
let notifyObj = new BasicNotification(this.id);
notifyObj.options.dismissed = true;
let win = gBrowser.replaceTabWithWindow(gBrowser.addTab("about:blank"));
whenDelayedStartupFinished(win, function() {
showNotification(notifyObj);
let anchor = document.getElementById("default-notification-icon");
is(anchor.getAttribute("showing"), "true", "the anchor is shown");
win.close();
goNext();
});
}
}
];

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

@ -0,0 +1,265 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
function test() {
waitForExplicitFinish();
ok(PopupNotifications, "PopupNotifications object exists");
ok(PopupNotifications.panel, "PopupNotifications panel exists");
setup();
goNext();
}
var gNotification;
var tests = [
// panel updates should fire the showing and shown callbacks again.
{ id: "Test#1",
run: function() {
this.notifyObj = new BasicNotification(this.id);
this.notification = showNotification(this.notifyObj);
},
onShown: function(popup) {
checkPopup(popup, this.notifyObj);
this.notifyObj.showingCallbackTriggered = false;
this.notifyObj.shownCallbackTriggered = false;
// Force an update of the panel. This is typically called
// automatically when receiving 'activate' or 'TabSelect' events,
// but from a setTimeout, which is inconvenient for the test.
PopupNotifications._update();
checkPopup(popup, this.notifyObj);
this.notification.remove();
},
onHidden: function() { }
},
// A first dismissed notification shouldn't stop _update from showing a second notification
{ id: "Test#2",
run: function() {
this.notifyObj1 = new BasicNotification(this.id);
this.notifyObj1.id += "_1";
this.notifyObj1.anchorID = "default-notification-icon";
this.notifyObj1.options.dismissed = true;
this.notification1 = showNotification(this.notifyObj1);
this.notifyObj2 = new BasicNotification(this.id);
this.notifyObj2.id += "_2";
this.notifyObj2.anchorID = "geo-notification-icon";
this.notifyObj2.options.dismissed = true;
this.notification2 = showNotification(this.notifyObj2);
this.notification2.dismissed = false;
PopupNotifications._update();
},
onShown: function(popup) {
checkPopup(popup, this.notifyObj2);
this.notification1.remove();
this.notification2.remove();
},
onHidden: function(popup) { }
},
// The anchor icon should be shown for notifications in background windows.
{ id: "Test#3",
run: function() {
let notifyObj = new BasicNotification(this.id);
notifyObj.options.dismissed = true;
let win = gBrowser.replaceTabWithWindow(gBrowser.addTab("about:blank"));
whenDelayedStartupFinished(win, function() {
showNotification(notifyObj);
let anchor = document.getElementById("default-notification-icon");
is(anchor.getAttribute("showing"), "true", "the anchor is shown");
win.close();
goNext();
});
}
},
// Test that persistent doesn't allow the notification to persist after
// navigation.
{ id: "Test#4",
run: function* () {
this.oldSelectedTab = gBrowser.selectedTab;
gBrowser.selectedTab = gBrowser.addTab("about:blank");
yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
this.notifyObj = new BasicNotification(this.id);
this.notifyObj.addOptions({
persistent: true
});
this.notification = showNotification(this.notifyObj);
},
onShown: function* (popup) {
this.complete = false;
yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.org/");
yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
// This code should not be executed.
ok(false, "Should have removed the notification after navigation");
// Properly dismiss and cleanup in case the unthinkable happens.
this.complete = true;
triggerSecondaryCommand(popup, 0);
},
onHidden: function(popup) {
ok(!this.complete, "Should have hidden the notification after navigation");
this.notification.remove();
gBrowser.removeTab(gBrowser.selectedTab);
gBrowser.selectedTab = this.oldSelectedTab;
}
},
// Test that persistent allows the notification to persist until explicitly
// dismissed.
{ id: "Test#5",
run: function* () {
this.oldSelectedTab = gBrowser.selectedTab;
gBrowser.selectedTab = gBrowser.addTab("about:blank");
yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
this.notifyObj = new BasicNotification(this.id);
this.notifyObj.addOptions({
persistent: true
});
this.notification = showNotification(this.notifyObj);
},
onShown: function* (popup) {
this.complete = false;
// Notification should persist after attempt to dismiss by clicking on the
// content area.
let browser = gBrowser.selectedBrowser;
yield BrowserTestUtils.synthesizeMouseAtCenter("body", {}, browser)
// Notification should be hidden after dismissal via Don't Allow.
this.complete = true;
triggerSecondaryCommand(popup, 0);
},
onHidden: function(popup) {
ok(this.complete, "Should have hidden the notification after clicking Not Now");
this.notification.remove();
gBrowser.removeTab(gBrowser.selectedTab);
gBrowser.selectedTab = this.oldSelectedTab;
}
},
// Test that persistent panels are still open after switching to another tab
// and back.
{ id: "Test#6a",
run: function* () {
this.notifyObj = new BasicNotification(this.id);
this.notifyObj.options.persistent = true;
gNotification = showNotification(this.notifyObj);
},
onShown: function* (popup) {
this.oldSelectedTab = gBrowser.selectedTab;
gBrowser.selectedTab = gBrowser.addTab("about:blank");
info("Waiting for the new tab to load.");
yield promiseTabLoadEvent(gBrowser.selectedTab, "http://example.com/");
},
onHidden: function(popup) {
ok(true, "Should have hidden the notification after tab switch");
gBrowser.removeTab(gBrowser.selectedTab);
gBrowser.selectedTab = this.oldSelectedTab;
}
},
// Second part of the previous test that compensates for the limitation in
// runNextTest that expects a single onShown/onHidden invocation per test.
{ id: "Test#6b",
run: function* () {
let id = PopupNotifications.panel.firstChild.getAttribute("popupid");
ok(id.endsWith("Test#6a"), "Should have found the notification from Test6a");
ok(PopupNotifications.isPanelOpen, "Should have shown the popup again after getting back to the tab");
gNotification.remove();
gNotification = null;
goNext();
}
},
// Test that persistent panels are still open after switching to another
// window and back.
{ id: "Test#7",
run: function* () {
this.oldSelectedTab = gBrowser.selectedTab;
gBrowser.selectedTab = gBrowser.addTab("about:blank");
let notifyObj = new BasicNotification(this.id);
notifyObj.options.persistent = true;
this.notification = showNotification(notifyObj);
let win = gBrowser.replaceTabWithWindow(gBrowser.addTab("about:blank"));
whenDelayedStartupFinished(win, () => {
ok(notifyObj.shownCallbackTriggered, "Should have triggered the shown callback");
let anchor = win.document.getElementById("default-notification-icon");
win.PopupNotifications._reshowNotifications(anchor);
ok(win.PopupNotifications.panel.childNodes.length == 0,
"no notification displayed in new window");
ok(PopupNotifications.isPanelOpen, "Should be still showing the popup in the first window");
win.close();
let id = PopupNotifications.panel.firstChild.getAttribute("popupid");
ok(id.endsWith("Test#7"), "Should have found the notification from Test7");
ok(PopupNotifications.isPanelOpen, "Should have shown the popup again after getting back to the window");
this.notification.remove();
gBrowser.removeTab(gBrowser.selectedTab);
gBrowser.selectedTab = this.oldSelectedTab;
goNext();
});
}
},
// Test that only the first persistent notification is shown on update
{ id: "Test#8",
run: function() {
this.notifyObj1 = new BasicNotification(this.id);
this.notifyObj1.id += "_1";
this.notifyObj1.anchorID = "default-notification-icon";
this.notifyObj1.options.persistent = true;
this.notification1 = showNotification(this.notifyObj1);
this.notifyObj2 = new BasicNotification(this.id);
this.notifyObj2.id += "_2";
this.notifyObj2.anchorID = "geo-notification-icon";
this.notifyObj2.options.persistent = true;
this.notification2 = showNotification(this.notifyObj2);
PopupNotifications._update();
},
onShown: function(popup) {
checkPopup(popup, this.notifyObj1);
this.notification1.remove();
this.notification2.remove();
},
onHidden: function(popup) { }
},
// Test that persistent notifications are shown stacked by anchor on update
{ id: "Test#9",
run: function() {
this.notifyObj1 = new BasicNotification(this.id);
this.notifyObj1.id += "_1";
this.notifyObj1.anchorID = "default-notification-icon";
this.notifyObj1.options.persistent = true;
this.notification1 = showNotification(this.notifyObj1);
this.notifyObj2 = new BasicNotification(this.id);
this.notifyObj2.id += "_2";
this.notifyObj2.anchorID = "geo-notification-icon";
this.notifyObj2.options.persistent = true;
this.notification2 = showNotification(this.notifyObj2);
this.notifyObj3 = new BasicNotification(this.id);
this.notifyObj3.id += "_3";
this.notifyObj3.anchorID = "default-notification-icon";
this.notifyObj3.options.persistent = true;
this.notification3 = showNotification(this.notifyObj3);
PopupNotifications._update();
},
onShown: function(popup) {
let notifications = popup.childNodes;
is(notifications.length, 2, "two notifications displayed");
let [notification1, notification2] = notifications;
is(notification1.id, this.notifyObj1.id + "-notification", "id 1 matches");
is(notification2.id, this.notifyObj3.id + "-notification", "id 2 matches");
this.notification1.remove();
this.notification2.remove();
this.notification3.remove();
},
onHidden: function(popup) { }
},
];

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

@ -213,25 +213,24 @@ function checkPopup(popup, notifyObj) {
is(notification.getAttribute("buttonaccesskey"),
notifyObj.mainAction.accessKey, "main action accesskey matches");
}
let actualSecondaryActions =
if (notifyObj.secondaryActions && notifyObj.secondaryActions.length > 0) {
let secondaryAction = notifyObj.secondaryActions[0];
is(notification.getAttribute("secondarybuttonlabel"), secondaryAction.label,
"secondary action label matches");
is(notification.getAttribute("secondarybuttonaccesskey"),
secondaryAction.accessKey, "secondary action accesskey matches");
}
// Additional secondary actions appear as menu items.
let actualExtraSecondaryActions =
Array.filter(notification.childNodes, child => child.nodeName == "menuitem");
let secondaryActions = notifyObj.secondaryActions || [];
let actualSecondaryActionsCount = actualSecondaryActions.length;
if (notifyObj.options.hideNotNow) {
is(notification.getAttribute("hidenotnow"), "true", "'Not Now' item hidden");
if (secondaryActions.length)
is(notification.lastChild.tagName, "menuitem", "no menuseparator");
}
else if (secondaryActions.length) {
is(notification.lastChild.tagName, "menuseparator", "menuseparator exists");
}
is(actualSecondaryActionsCount, secondaryActions.length,
actualSecondaryActions.length + " secondary actions");
secondaryActions.forEach(function(a, i) {
is(actualSecondaryActions[i].getAttribute("label"), a.label,
"label for secondary action " + i + " matches");
is(actualSecondaryActions[i].getAttribute("accesskey"), a.accessKey,
"accessKey for secondary action " + i + " matches");
let extraSecondaryActions = notifyObj.secondaryActions ? notifyObj.secondaryActions.slice(1) : [];
is(actualExtraSecondaryActions.length, extraSecondaryActions.length,
"number of extra secondary actions matches");
extraSecondaryActions.forEach(function(a, i) {
is(actualExtraSecondaryActions[i].getAttribute("label"), a.label,
"label for extra secondary action " + i + " matches");
is(actualExtraSecondaryActions[i].getAttribute("accesskey"), a.accessKey,
"accessKey for extra secondary action " + i + " matches");
});
}
@ -263,8 +262,7 @@ function triggerMainCommand(popup) {
ok(notifications.length > 0, "at least one notification displayed");
let notification = notifications[0];
info("Triggering main command for notification " + notification.id);
// 20, 10 so that the inner button is hit
EventUtils.synthesizeMouse(notification.button, 20, 10, {});
EventUtils.synthesizeMouseAtCenter(notification.button, {});
}
function triggerSecondaryCommand(popup, index) {
@ -272,17 +270,21 @@ function triggerSecondaryCommand(popup, index) {
ok(notifications.length > 0, "at least one notification displayed");
let notification = notifications[0];
info("Triggering secondary command for notification " + notification.id);
// Cancel the arrow panel slide-in transition (bug 767133) such that
// it won't interfere with us interacting with the dropdown.
document.getAnonymousNodes(popup)[0].style.transition = "none";
notification.button.focus();
if (index == 0) {
EventUtils.synthesizeMouseAtCenter(notification.secondaryButton, {});
return;
}
// Extra secondary actions appear in a menu.
notification.secondaryButton.nextSibling.nextSibling.focus();
popup.addEventListener("popupshown", function handle() {
popup.removeEventListener("popupshown", handle, false);
info("Command popup open for notification " + notification.id);
// Press down until the desired command is selected
for (let i = 0; i <= index; i++) {
// Press down until the desired command is selected. Decrease index by one
// since the secondary action was handled above.
for (let i = 0; i <= index - 1; i++) {
EventUtils.synthesizeKey("VK_DOWN", {});
}
// Activate

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

@ -111,32 +111,44 @@ function clickAddonRemoveButton(tab, aCallback) {
}
function activateOneProvider(manifest, finishActivation, aCallback) {
info("activating provider " + manifest.name);
let panel = document.getElementById("servicesInstall-notification");
BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown").then(() => {
ok(!panel.hidden, "servicesInstall-notification panel opened");
if (finishActivation)
panel.button.click();
else
panel.closebutton.click();
});
BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden").then(() => {
ok(panel.hidden, "servicesInstall-notification panel hidden");
if (!finishActivation) {
ok(panel.hidden, "activation panel is not showing");
executeSoon(aCallback);
} else {
waitForProviderLoad(manifest.origin).then(() => {
checkSocialUI();
executeSoon(aCallback);
});
}
});
Task.spawn(function* () {
info("activating provider " + manifest.name);
// the test will continue as the popup events fire...
activateProvider(manifest.origin, function() {
info("waiting on activation panel to open/close...");
});
// Wait for the helper callback and the popup shown event in any order.
let popupShown = BrowserTestUtils.waitForEvent(PopupNotifications.panel,
"popupshown");
yield new Promise(resolve => activateProvider(manifest.origin, resolve));
yield popupShown;
info("servicesInstall-notification panel opened");
// Start waiting for the activation event before the click on the button.
let providerLoaded = finishActivation ?
waitForProviderLoad(manifest.origin) : null;
let popupHidden = BrowserTestUtils.waitForEvent(PopupNotifications.panel,
"popuphidden");
// We need to wait for PopupNotifications.jsm to place the element.
let notification;
yield BrowserTestUtils.waitForCondition(
() => (notification = PopupNotifications.panel.childNodes[0]));
is(notification.id, "servicesInstall-notification");
if (finishActivation) {
notification.button.click();
} else {
notification.closebutton.click();
}
yield providerLoaded;
yield popupHidden;
info("servicesInstall-notification panel hidden");
if (finishActivation) {
checkSocialUI();
}
}).then(() => executeSoon(aCallback)).catch(ex => ok(false, ex));
}
var gTestDomains = ["https://example.com", "https://test1.example.com", "https://test2.example.com"];

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

@ -474,7 +474,7 @@ var gTests = [
},
{
desc: "'Always Allow' ignored and not shown on http pages",
desc: "'Always Allow' disabled on http pages",
run: function* checkNoAlwaysOnHttp() {
// Load an http page instead of the https version.
let browser = gBrowser.selectedBrowser;
@ -494,16 +494,16 @@ var gTests = [
yield promise;
yield expectObserverCalled("getUserMedia:request");
// Ensure that the 'Always Allow' action isn't shown.
let alwaysLabel = gNavigatorBundle.getString("getUserMedia.always.label");
ok(!!alwaysLabel, "found the 'Always Allow' localized label");
let labels = [];
// Ensure that checking the 'Remember this decision' checkbox disables
// 'Allow'.
let notification = PopupNotifications.panel.firstChild;
for (let node of notification.childNodes) {
if (node.localName == "menuitem")
labels.push(node.getAttribute("label"));
}
is(labels.indexOf(alwaysLabel), -1, "The 'Always Allow' item isn't shown");
let checkbox = notification.checkbox;
ok(!!checkbox, "checkbox is present");
ok(!checkbox.checked, "checkbox is not checked");
checkbox.click();
ok(checkbox.checked, "checkbox now checked");
ok(notification.button.disabled, "Allow button is disabled");
ok(!notification.hasAttribute("warninghidden"), "warning message is shown");
// Cleanup.
yield closeStream(true);

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

@ -305,22 +305,17 @@ const kActionNever = 3;
function activateSecondaryAction(aAction) {
let notification = PopupNotifications.panel.firstChild;
notification.button.focus();
let popup = notification.menupopup;
popup.addEventListener("popupshown", function() {
popup.removeEventListener("popupshown", arguments.callee, false);
// Press 'down' as many time as needed to select the requested action.
while (aAction--)
EventUtils.synthesizeKey("VK_DOWN", {});
// Activate
EventUtils.synthesizeKey("VK_RETURN", {});
}, false);
// One down event to open the popup
EventUtils.synthesizeKey("VK_DOWN",
{ altKey: !navigator.platform.includes("Mac") });
switch (aAction) {
case kActionNever:
notification.checkbox.setAttribute("checked", true); // fallthrough
case kActionDeny:
notification.secondaryButton.click();
break;
case kActionAlways:
notification.checkbox.setAttribute("checked", true);
notification.button.click();
break;
}
}
function getMediaCaptureState() {

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

@ -83,7 +83,7 @@
.subviewbutton[usercontextid] > .toolbarbutton-icon,
#userContext-indicator {
background-image: var(--identity-icon);
filter: url(chrome://browser/skin/filters.svg#fill);
filter: url(chrome://global/skin/filters.svg#fill);
fill: var(--identity-icon-color);
background-size: contain;
background-repeat: no-repeat;

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

@ -87,8 +87,9 @@ add_task(function* testBrowserActionDisabled() {
},
},
background() {
browser.browserAction.disable();
background: async function() {
await browser.browserAction.disable();
browser.test.sendMessage("browserAction-disabled");
},
files: {
@ -101,6 +102,8 @@ add_task(function* testBrowserActionDisabled() {
yield extension.startup();
yield extension.awaitMessage("browserAction-disabled");
const {GlobalManager, Management: {global: {browserActionFor}}} = Cu.import("resource://gre/modules/Extension.jsm", {});
let ext = GlobalManager.extensionMap.get(extension.id);
@ -108,6 +111,9 @@ add_task(function* testBrowserActionDisabled() {
let widget = getBrowserActionWidget(extension).forWindow(window);
is(widget.node.getAttribute("disabled"), "true", "Button is disabled");
is(browserAction.pendingPopup, null, "Have no pending popup prior to click");
// Test canceled click.
EventUtils.synthesizeMouseAtCenter(widget.node, {type: "mousedown", button: 0}, window);

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

@ -104,8 +104,6 @@ add_task(function* testWindowCreate() {
promiseTabUpdated("http://example.org/"),
]);
await new Promise(resolve => setTimeout(resolve, 0));
window = await browser.windows.create({url: ["http://example.com/", "http://example.org/"]});
await readyPromise;

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

@ -84,6 +84,8 @@ add_task(function* testWindowsEvents() {
let win2Id = yield extension.awaitMessage("window-created");
info(`Window 2 ID: ${win2Id}`);
win2.focus();
winId = yield extension.awaitMessage(`window-focus-changed`);
is(winId, win2Id, "Got focus change event for the correct window ID.");

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

@ -23,12 +23,10 @@ var {CustomizableUI} = Cu.import("resource:///modules/CustomizableUI.jsm");
// copied to the sub-directory "test-oop-extensions", which we detect here, and
// use to select our configuration.
if (gTestPath.includes("test-oop-extensions")) {
add_task(() => {
return SpecialPowers.pushPrefEnv({set: [
["dom.ipc.processCount", 1],
["extensions.webextensions.remote", true],
]});
});
SpecialPowers.pushPrefEnv({set: [
["dom.ipc.processCount", 1],
["extensions.webextensions.remote", true],
]});
}
// Bug 1239884: Our tests occasionally hit a long GC pause at unpredictable

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

@ -2854,8 +2854,8 @@ var E10SAccessibilityCheck = {
let options = {
popupIconURL: "chrome://browser/skin/e10s-64@2x.png",
learnMoreURL: Services.urlFormatter.formatURLPref("app.support.e10sAccessibilityUrl"),
persistent: true,
persistWhileVisible: true,
hideNotNow: true,
};
notification =

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

@ -141,7 +141,17 @@ var gEditItemOverlay = {
yield PlacesUtils.keywords.fetch({ url: this._paneInfo.uri.spec },
e => entries.push(e));
if (entries.length > 0) {
this._keyword = newKeyword = entries[0].keyword;
// We show an existing keyword if either POST data was not provided, or
// if the POST data is the same.
let existingKeyword = entries[0].keyword;
let postData = this._paneInfo.postData;
if (postData) {
let sameEntry = entries.find(e => e.postData === postData);
existingKeyword = sameEntry ? sameEntry.keyword : "";
}
if (existingKeyword) {
this._keyword = newKeyword = existingKeyword;
}
}
}
this._initTextField(this._keywordField, newKeyword);

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

@ -8,7 +8,7 @@ add_task(function* () {
url: TEST_URL,
}, function* (browser) {
// We must wait for the context menu code to build metadata.
yield openContextMenuForContentSelector(browser, 'form > input[name="search"]');
yield openContextMenuForContentSelector(browser, '#form1 > input[name="search"]');
yield withBookmarksDialog(true, AddKeywordForSearchField, function* (dialogWin) {
let acceptBtn = dialogWin.document.documentElement.getButton("accept");
@ -47,6 +47,61 @@ add_task(function* () {
});
});
add_task(function* reopen_same_field() {
yield PlacesUtils.keywords.insert({
url: TEST_URL,
keyword: "kw",
postData: "accenti%3D%E0%E8%EC%F2%F9&search%3D%25s"
});
registerCleanupFunction(function* () {
yield PlacesUtils.keywords.remove("kw");
});
// Reopening on the same input field should show the existing keyword.
yield BrowserTestUtils.withNewTab({
gBrowser,
url: TEST_URL,
}, function* (browser) {
// We must wait for the context menu code to build metadata.
yield openContextMenuForContentSelector(browser, '#form1 > input[name="search"]');
yield withBookmarksDialog(true, AddKeywordForSearchField, function* (dialogWin) {
let acceptBtn = dialogWin.document.documentElement.getButton("accept");
ok(acceptBtn.disabled, "Accept button is disabled");
let elt = dialogWin.document.getElementById("editBMPanel_keywordField");
is(elt.value, "kw");
});
});
});
add_task(function* open_other_field() {
yield PlacesUtils.keywords.insert({
url: TEST_URL,
keyword: "kw2",
postData: "search%3D%25s"
});
registerCleanupFunction(function* () {
yield PlacesUtils.keywords.remove("kw2");
});
// Reopening on another field of the same page that has different postData
// should not show the existing keyword.
yield BrowserTestUtils.withNewTab({
gBrowser,
url: TEST_URL,
}, function* (browser) {
// We must wait for the context menu code to build metadata.
yield openContextMenuForContentSelector(browser, '#form2 > input[name="search"]');
yield withBookmarksDialog(true, AddKeywordForSearchField, function* (dialogWin) {
let acceptBtn = dialogWin.document.documentElement.getButton("accept");
ok(acceptBtn.disabled, "Accept button is disabled");
let elt = dialogWin.document.getElementById("editBMPanel_keywordField");
is(elt.value, "");
});
});
});
function getPostDataString(stream) {
let sis = Cc["@mozilla.org/scriptableinputstream;1"]
.createInstance(Ci.nsIScriptableInputStream);

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

@ -5,9 +5,13 @@
<meta http-equiv="Content-Type" content="text/html;charset=windows-1252">
</head>
<body>
<form method="POST" action="keyword_form.html">
<form id="form1" method="POST" action="keyword_form.html">
<input type="hidden" name="accenti" value="àèìòù">
<input type="text" name="search">
</form>
<form id="form2" method="POST" action="keyword_form.html">
<input type="hidden" name="accenti" value="ùòìèà">
<input type="text" name="search">
</form>
</body>
</html>

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

@ -24,9 +24,9 @@ add_task(function* test() {
if (aPrivateMode) {
// Make sure the notification is correctly displayed without a remember control
is(notification.secondaryActions.length, 0, "Secondary actions shouldn't exist (always/never remember)");
ok(!notification.options.checkbox.show, "Secondary actions should exist (always/never remember)");
} else {
ok(notification.secondaryActions.length > 1, "Secondary actions should exist (always/never remember)");
ok(notification.options.checkbox.show, "Secondary actions should exist (always/never remember)");
}
notification.remove();

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

@ -30,8 +30,8 @@ this.SessionHistory = Object.freeze({
return SessionHistoryInternal.isEmpty(docShell);
},
collect: function (docShell) {
return SessionHistoryInternal.collect(docShell);
collect: function (docShell, aFromIdx = -1) {
return SessionHistoryInternal.collect(docShell, aFromIdx);
},
restore: function (docShell, tabData) {
@ -69,11 +69,15 @@ var SessionHistoryInternal = {
*
* @param docShell
* The docShell that owns the session history.
* @param aFromIdx
* The starting local index to collect the history from.
* @return An object reprereseting a partial global history update.
*/
collect: function (docShell) {
collect: function (docShell, aFromIdx = -1) {
let loadContext = docShell.QueryInterface(Ci.nsILoadContext);
let webNavigation = docShell.QueryInterface(Ci.nsIWebNavigation);
let history = webNavigation.sessionHistory.QueryInterface(Ci.nsISHistoryInternal);
let ihistory = history.QueryInterface(Ci.nsISHistory);
let data = {entries: [], userContextId: loadContext.originAttributes.userContextId };
@ -107,6 +111,23 @@ var SessionHistoryInternal = {
}
}
// Check if we should discard some of the entries which didn't change
if (aFromIdx > -1) {
data.entries.splice(0, aFromIdx + 1);
}
// Transform the entries from local to global index space.
data.index += ihistory.globalIndexOffset;
data.fromIdx = aFromIdx + ihistory.globalIndexOffset;
// If we are not the most recent partialSHistory in our groupedSHistory, we
// need to make certain that we don't replace the entries from the following
// SHistories - so we replace only the number of entries which our SHistory
// takes up.
if (ihistory.globalIndexOffset + ihistory.count < ihistory.globalCount) {
data.toIdx = data.fromIdx + ihistory.count;
}
return data;
},

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

@ -971,6 +971,18 @@ var SessionStoreInternal = {
this.resetEpoch(target);
}
break;
case "BrowserWillChangeProcess":
let promise = TabStateFlusher.flush(target);
target.frameLoader.addProcessChangeBlockingPromise(promise);
break;
case "BrowserChangedProcess":
let newEpoch = 1 + Math.max(this.getCurrentEpoch(target),
this.getCurrentEpoch(aEvent.otherBrowser));
this.setCurrentEpoch(target, newEpoch);
target.messageManager.sendAsyncMessage("SessionStore:becomeActiveProcess", {
epoch: newEpoch
});
break;
default:
throw new Error(`unhandled event ${aEvent.type}?`);
}
@ -1037,6 +1049,8 @@ var SessionStoreInternal = {
// Keep track of a browser's latest frameLoader.
aWindow.gBrowser.addEventListener("XULFrameLoaderCreated", this);
aWindow.gBrowser.addEventListener("BrowserChangedProcess", this);
aWindow.gBrowser.addEventListener("BrowserWillChangeProcess", this);
},
/**
@ -1291,6 +1305,8 @@ var SessionStoreInternal = {
}, this);
aWindow.gBrowser.removeEventListener("XULFrameLoaderCreated", this);
aWindow.gBrowser.removeEventListener("BrowserChangedProcess", this);
aWindow.gBrowser.removeEventListener("BrowserWillChangeProcess", this);
let winData = this._windows[aWindow.__SSi];
@ -4412,6 +4428,14 @@ var SessionStoreInternal = {
return next;
},
/**
* Manually set the epoch to a given value.
*/
setCurrentEpoch(aBrowser, aEpoch) {
this._browserEpochs.set(aBrowser.permanentKey, aEpoch);
return aEpoch;
},
/**
* Returns the current epoch for the given <browser>. If we haven't assigned
* a new epoch this will default to zero for new tabs.

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

@ -113,15 +113,19 @@ var TabStateCacheInternal = {
}
let history = data.history;
let toIdx = history.entries.length;
if ("toIdx" in change) {
toIdx = Math.min(toIdx, change.toIdx + 1);
}
for (let key of Object.keys(change)) {
if (key == "entries") {
if (change.fromIdx != kLastIndex) {
history.entries.splice(change.fromIdx + 1);
while (change.entries.length) {
history.entries.push(change.entries.shift());
}
let start = change.fromIdx + 1;
history.entries.splice.apply(
history.entries, [start, toIdx - start].concat(change.entries));
}
} else if (key != "fromIndex") {
} else if (key != "fromIdx" && key != "toIdx") {
history[key] = change[key];
}
}

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

@ -114,6 +114,7 @@ var MessageListener = {
"SessionStore:restoreTabContent",
"SessionStore:resetRestore",
"SessionStore:flush",
"SessionStore:becomeActiveProcess",
],
init: function () {
@ -148,6 +149,18 @@ var MessageListener = {
case "SessionStore:flush":
this.flush(data);
break;
case "SessionStore:becomeActiveProcess":
let shistory = docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory;
// Check if we are at the end of the current session history, if we are,
// it is safe for us to collect and transmit our session history, so
// transmit all of it. Otherwise, we only want to transmit our index changes,
// so collect from kLastIndex.
if (shistory.globalCount - shistory.globalIndexOffset == shistory.count) {
SessionHistoryListener.collect();
} else {
SessionHistoryListener.collectFrom(kLastIndex);
}
break;
default:
debug("received unknown message '" + name + "'");
break;
@ -255,9 +268,12 @@ var SessionHistoryListener = {
},
collect: function () {
this._fromIdx = kNoIndex;
// We want to send down a historychange even for full collects in case our
// session history is a partial session history, in which case we don't have
// enough information for a full update. collectFrom(-1) tells the collect
// function to collect all data avaliable in this process.
if (docShell) {
MessageQueue.push("history", () => SessionHistory.collect(docShell));
this.collectFrom(-1);
}
},
@ -286,15 +302,7 @@ var SessionHistoryListener = {
return null;
}
let history = SessionHistory.collect(docShell);
if (kLastIndex == idx) {
history.entries = [];
} else {
history.entries.splice(0, this._fromIdx + 1);
}
history.fromIdx = this._fromIdx;
let history = SessionHistory.collect(docShell, this._fromIdx);
this._fromIdx = kNoIndex;
return history;
});

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

@ -238,3 +238,5 @@ run-if = e10s && crashreporter
[browser_undoCloseById.js]
skip-if = debug
[browser_docshell_uuid_consistency.js]
[browser_grouped_session_store.js]
skip-if = !e10s # GroupedSHistory is e10s-only

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

@ -0,0 +1,135 @@
add_task(function* () {
const URIs = [
"data:text/html,1",
"data:text/html,2",
"data:text/html,3",
"data:text/html,4",
"data:text/html,5",
];
const {TabStateCache} = Cu.import("resource:///modules/sessionstore/TabStateCache.jsm", {});
const {TabStateFlusher} = Cu.import("resource:///modules/sessionstore/TabStateFlusher.jsm", {});
yield SpecialPowers.pushPrefEnv({
set: [["browser.groupedhistory.enabled", true]]
});
// Check that the data stored in the TabStateCache is correct for the current state.
function* validate(browser, length, index) {
yield TabStateFlusher.flush(browser);
let {history} = TabStateCache.get(browser);
is(history.entries.length, length, "Lengths match");
for (let i = 0; i < length; ++i) {
is(history.entries[i].url, URIs[i], "URI at index " + i + " matches");
}
is(history.index, index, "Index matches");
yield ContentTask.spawn(browser, [index, length], function* ([index, length]) {
let webNav = content.window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation);
is(webNav.canGoForward, index < length, "canGoForward is correct");
is(webNav.canGoBack, index > 1, "canGoBack is correct");
});
}
// Wait for a process change and then fulfil the promise.
function awaitProcessChange(browser) {
return new Promise(resolve => {
browser.addEventListener("BrowserChangedProcess", function bcp(e) {
browser.removeEventListener("BrowserChangedProcess", bcp);
ok(true, "The browser changed process!");
resolve();
});
});
}
// Order of events:
// Load [0], load [1], prerender [2], load [2], load [3]
// Back [2], Back [1], Forward [2], Back [0], Forward [3]
// Prerender [4], Back [0], Forward [2], Load [3'], Back [0].
yield BrowserTestUtils.withNewTab({ gBrowser, url: URIs[0] }, function* (browser1) {
yield* validate(browser1, 1, 1);
browser1.loadURI(URIs[1], null, null);
yield BrowserTestUtils.browserLoaded(browser1);
yield* validate(browser1, 2, 2);
// Create a new hidden prerendered tab to swap to.
let tab2 = gBrowser.loadOneTab(URIs[2], {
referrerPolicy: Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT,
allowThirdPartyFixup: true,
relatedToCurrent: true,
isPrerendered: true,
});
yield BrowserTestUtils.browserLoaded(tab2.linkedBrowser);
browser1.frameLoader.appendPartialSessionHistoryAndSwap(
tab2.linkedBrowser.frameLoader);
yield awaitProcessChange(browser1);
yield* validate(browser1, 3, 3);
browser1.loadURI(URIs[3], null, null);
yield BrowserTestUtils.browserLoaded(browser1);
yield* validate(browser1, 4, 4);
// In process navigate back.
let p = BrowserTestUtils.waitForContentEvent(browser1, "pageshow");
browser1.goBack();
yield p;
yield* validate(browser1, 4, 3);
// Cross process navigate back.
browser1.goBack();
yield awaitProcessChange(browser1);
yield* validate(browser1, 4, 2);
// Cross process navigate forward.
browser1.goForward();
yield awaitProcessChange(browser1);
yield* validate(browser1, 4, 3);
// Navigate across process to a page which was not recently loaded.
browser1.gotoIndex(0);
yield awaitProcessChange(browser1);
yield* validate(browser1, 4, 1);
// Navigate across process to a page which was not recently loaded in the other direction.
browser1.gotoIndex(3);
yield awaitProcessChange(browser1);
yield* validate(browser1, 4, 4);
// Create a new hidden prerendered tab to swap to
let tab3 = gBrowser.loadOneTab(URIs[4], {
referrerPolicy: Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT,
allowThirdPartyFixup: true,
relatedToCurrent: true,
isPrerendered: true,
});
yield BrowserTestUtils.browserLoaded(tab3.linkedBrowser);
browser1.frameLoader.appendPartialSessionHistoryAndSwap(
tab3.linkedBrowser.frameLoader);
yield awaitProcessChange(browser1);
yield* validate(browser1, 5, 5);
browser1.gotoIndex(0);
yield awaitProcessChange(browser1);
yield* validate(browser1, 5, 1);
browser1.gotoIndex(2);
yield awaitProcessChange(browser1);
yield* validate(browser1, 5, 3);
// Load a new page and make sure it throws out all of the following entries.
URIs[3] = "data:text/html,NEW";
browser1.loadURI(URIs[3]);
yield BrowserTestUtils.browserLoaded(browser1);
yield* validate(browser1, 4, 4);
browser1.gotoIndex(0);
yield awaitProcessChange(browser1);
yield* validate(browser1, 4, 1);
// XXX: This will be removed automatically by the owning tab closing in the
// future, but this is not supported yet.
gBrowser.removeTab(tab2);
gBrowser.removeTab(tab3);
});
});

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

@ -0,0 +1,3 @@
. "$topsrcdir/browser/config/mozconfigs/linux64/nightly"
ac_add_options --enable-stylo

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

@ -0,0 +1,3 @@
. "$topsrcdir/browser/config/mozconfigs/linux64/debug"
ac_add_options --enable-stylo

2
browser/extensions/flyweb/bootstrap.js поставляемый
Просмотреть файл

@ -158,7 +158,7 @@ const FlyWebPermissionPromptIntegration = (base) => ({
notificationIcon.setAttribute("aria-label",
"View the publish-server request");
notificationIcon.style.filter =
"url('chrome://browser/skin/filters.svg#fill')";
"url('chrome://global/skin/filters.svg#fill')";
notificationIcon.style.fill = "currentcolor";
notificationIcon.style.opacity = "0.4";
notificationPopupBox.appendChild(notificationIcon);

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

@ -1,3 +1,3 @@
This is the pdf.js project output, https://github.com/mozilla/pdf.js
Current extension version is: 1.6.315
Current extension version is: 1.6.329

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

@ -93,6 +93,7 @@ function initializeDefaultPreferences() {
"useOnlyCssZoom": false,
"externalLinkTarget": 0,
"enhanceTextSelection": false,
"renderer": "canvas",
"renderInteractiveForms": false,
"disablePageLabels": false
}

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

@ -51,6 +51,7 @@ var DEFAULT_PREFERENCES =
"useOnlyCssZoom": false,
"externalLinkTarget": 0,
"enhanceTextSelection": false,
"renderer": "canvas",
"renderInteractiveForms": false,
"disablePageLabels": false
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -375,6 +375,9 @@ if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('FIREFOX || MOZCENTRAL')) {
}
var networkManager = this._manager;
if (!networkManager.isHttp) {
return false;
}
var fullRequestXhrId = this._fullRequestId;
var fullRequestXhr = networkManager.getRequestXhr(fullRequestXhrId);
if (fullRequestXhr.getResponseHeader('Accept-Ranges') !== 'bytes') {

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

@ -5,6 +5,7 @@
(function(window) {
var gLanguage = '';
var gExternalLocalizerServices = null;
var gReadyState = 'loading';
// fetch an l10n objects
function getL10nData(key) {
@ -99,6 +100,8 @@
translateFragment();
gReadyState = 'complete';
// fire a 'localized' DOM event
var evtObject = document.createEvent('Event');
evtObject.initEvent('localized', false, false);
@ -135,6 +138,8 @@
return (rtlList.indexOf(shortCode) >= 0) ? 'rtl' : 'ltr';
},
getReadyState: function() { return gReadyState; },
setExternalLocalizerServices: function (externalLocalizerServices) {
gExternalLocalizerServices = externalLocalizerServices;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -76,7 +76,6 @@ PresentationPermissionPrompt.prototype = {
},
get popupOptions() {
return {
hideNotNow: true,
removeOnDismissal: true,
popupIconURL: kNotificationPopupIcon, // Icon shown on prompt content
eventCallback: (aTopic, aNewBrowser) => {
@ -127,7 +126,7 @@ PresentationPermissionPrompt.prototype = {
notificationIcon.setAttribute("role", "button");
notificationIcon.setAttribute("tooltiptext",
GetString("presentation.urlbar.tooltiptext"));
notificationIcon.style.filter = "url('chrome://browser/skin/filters.svg#fill')";
notificationIcon.style.filter = "url('chrome://global/skin/filters.svg#fill')";
notificationIcon.style.fill = "currentcolor";
notificationIcon.style.opacity = "0.4";
notificationPopupBox.appendChild(notificationIcon);
@ -162,7 +161,7 @@ PresentationPermissionPrompt.prototype = {
this._isResponded = true;
this.request.cancel(Cr.NS_ERROR_NOT_AVAILABLE);
},
dismiss: true, // For hideNotNow.
dismiss: true,
}];
},
// PRIVATE APIs

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

@ -527,8 +527,8 @@
@RESPATH@/chrome/marionette@JAREXT@
@RESPATH@/chrome/marionette.manifest
@RESPATH@/components/MarionetteComponents.manifest
@RESPATH@/components/marionettecomponent.js
@RESPATH@/components/marionette.manifest
@RESPATH@/components/marionette.js
#ifdef MOZ_WEBSPEECH
@RESPATH@/components/dom_webspeechsynth.xpt

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

@ -315,13 +315,11 @@ newWindowButton.tooltip=Open a new window (%S)
newTabButton.tooltip=Open a new tab (%S)
# Offline web applications
offlineApps.available=This website (%S) is asking to store data on your computer for offline use.
offlineApps.allow=Allow
offlineApps.allowAccessKey=A
offlineApps.never=Never for This Site
offlineApps.neverAccessKey=e
offlineApps.notNow=Not Now
offlineApps.notNowAccessKey=N
offlineApps.available2=Will you allow %S to store data on your computer?
offlineApps.allowStoring.label=Allow Storing Data
offlineApps.allowStoring.accesskey=A
offlineApps.dontAllow.label=Dont Allow
offlineApps.dontAllow.accesskey=n
offlineApps.usage=This website (%S) is now storing more than %SMB of data on your computer for offline use.
offlineApps.manageUsage=Show settings
@ -368,24 +366,21 @@ puAlertText=Click here for details
# Geolocation UI
# LOCALIZATION NOTE (geolocation.shareLocation geolocation.alwaysShareLocation geolocation.neverShareLocation):
# If you're having trouble with the word Share, please use Allow and Block in your language.
geolocation.shareLocation=Share Location
geolocation.shareLocation.accesskey=a
geolocation.alwaysShareLocation=Always Share Location
geolocation.alwaysShareLocation.accesskey=A
geolocation.neverShareLocation=Never Share Location
geolocation.neverShareLocation.accesskey=N
geolocation.shareWithSite2=Would you like to share your location with this site?
geolocation.shareWithFile2=Would you like to share your location with this file?
geolocation.allowLocation=Allow Location Access
geolocation.allowLocation.accesskey=A
geolocation.dontAllowLocation=Dont Allow
geolocation.dontAllowLocation.accesskey=n
geolocation.shareWithSite3=Will you allow %S to access your location?
geolocation.shareWithFile3=Will you allow this local file to access your location?
geolocation.remember=Remember this decision
webNotifications.receiveForSession=Receive for this session
webNotifications.receiveForSession.accesskey=s
webNotifications.alwaysReceive=Always Receive Notifications
webNotifications.alwaysReceive.accesskey=A
webNotifications.neverShow=Always Block Notifications
webNotifications.neverShow.accesskey=N
webNotifications.receiveFromSite=Would you like to receive notifications from this site?
webNotifications.remember=Remember this decision
webNotifications.rememberForSession=Remember decision for this session
webNotifications.allow=Allow Notifications
webNotifications.allow.accesskey=A
webNotifications.dontAllow=Dont Allow
webNotifications.dontAllow.accesskey=n
webNotifications.receiveFromSite2=Will you allow %S to send notifications?
# LOCALIZATION NOTE (webNotifications.upgradeTitle): When using native notifications on OS X, the title may be truncated around 32 characters.
webNotifications.upgradeTitle=Upgraded notifications
# LOCALIZATION NOTE (webNotifications.upgradeBody): When using native notifications on OS X, the body may be truncated around 100 characters in some views.
@ -473,19 +468,19 @@ social.error.closeSidebar.accesskey=C
# LOCALIZATION NOTE: %1$S is the label for the toolbar button, %2$S is the associated badge numbering that the social provider may provide.
social.aria.toolbarButtonBadgeText=%1$S (%2$S)
# LOCALIZATION NOTE (getUserMedia.shareCamera.message, getUserMedia.shareMicrophone.message,
# getUserMedia.shareScreen.message, getUserMedia.shareCameraAndMicrophone.message,
# getUserMedia.shareScreenAndMicrophone.message, getUserMedia.shareCameraAndAudioCapture.message,
# getUserMedia.shareAudioCapture.message, getUserMedia.shareScreenAndAudioCapture.message):
# LOCALIZATION NOTE (getUserMedia.shareCamera2.message, getUserMedia.shareMicrophone2.message,
# getUserMedia.shareScreen2.message, getUserMedia.shareCameraAndMicrophone2.message,
# getUserMedia.shareScreenAndMicrophone2.message, getUserMedia.shareCameraAndAudioCapture2.message,
# getUserMedia.shareAudioCapture2.message, getUserMedia.shareScreenAndAudioCapture2.message):
# %S is the website origin (e.g. www.mozilla.org)
getUserMedia.shareCamera.message = Would you like to share your camera with %S?
getUserMedia.shareMicrophone.message = Would you like to share your microphone with %S?
getUserMedia.shareScreen.message = Would you like to share your screen with %S?
getUserMedia.shareCameraAndMicrophone.message = Would you like to share your camera and microphone with %S?
getUserMedia.shareCameraAndAudioCapture.message = Would you like to share your camera and this tabs audio with %S?
getUserMedia.shareScreenAndMicrophone.message = Would you like to share your microphone and screen with %S?
getUserMedia.shareScreenAndAudioCapture.message = Would you like to share this tabs audio and your screen with %S?
getUserMedia.shareAudioCapture.message = Would you like to share this tabs audio with %S?
getUserMedia.shareCamera2.message = Will you allow %S to use your camera?
getUserMedia.shareMicrophone2.message = Will you allow %S to use your microphone?
getUserMedia.shareScreen2.message = Will you allow %S to see your screen or application window?
getUserMedia.shareCameraAndMicrophone2.message = Will you allow %S to use your camera and microphone?
getUserMedia.shareCameraAndAudioCapture2.message = Will you allow %S to use your camera and listen to this tabs audio?
getUserMedia.shareScreenAndMicrophone2.message = Will you allow %S to use your microphone and see your screen or application window?
getUserMedia.shareScreenAndAudioCapture2.message = Will you allow %S to listen to this tabs audio and see your screen or application window?
getUserMedia.shareAudioCapture2.message = Will you allow %S to listen to this tabs audio?
# LOCALIZATION NOTE (getUserMedia.shareScreenWarning.message): NB: inserted via innerHTML, so please don't use <, > or & in this string.
# %S will be the 'learn more' link
getUserMedia.shareScreenWarning.message = Only share screens with sites you trust. Sharing can allow deceptive sites to browse as you and steal your private data. %S
@ -515,22 +510,18 @@ getUserMedia.shareMonitor.label = Screen %S
# Replacement for #1 is the name of the application.
# Replacement for #2 is the number of windows currently displayed by the application.
getUserMedia.shareApplicationWindowCount.label=#1 (#2 window);#1 (#2 windows)
# LOCALIZATION NOTE (getUserMedia.shareSelectedDevices.label):
# Semicolon-separated list of plural forms. See:
# http://developer.mozilla.org/en/docs/Localization_and_Plurals
# The number of devices can be either one or two.
getUserMedia.shareSelectedDevices.label = Share Selected Device;Share Selected Devices
getUserMedia.shareSelectedDevices.accesskey = S
getUserMedia.shareScreen.label = Share Screen
getUserMedia.shareApplication.label = Share Selected Application
getUserMedia.shareWindow.label = Share Selected Window
getUserMedia.shareSelectedItems.label = Share Selected Items
getUserMedia.always.label = Always Share
getUserMedia.always.accesskey = A
getUserMedia.denyRequest.label = Dont Share
getUserMedia.denyRequest.accesskey = D
getUserMedia.never.label = Never Share
getUserMedia.never.accesskey = N
getUserMedia.allow.label = Allow
getUserMedia.allow.accesskey = A
getUserMedia.dontAllow.label = Dont Allow
getUserMedia.dontAllow.accesskey = D
getUserMedia.remember=Remember this decision
# LOCALIZATION NOTE (ggetUserMedia.reasonForNoPermanentAllow.screen,
# getUserMedia.reasonForNoPermanentAllow.audio,
# getUserMedia.reasonForNoPermanentAllow.insecure):
# %S is brandShortName
getUserMedia.reasonForNoPermanentAllow.screen=%S can not allow permanent access to your screen or application without asking which one to share.
getUserMedia.reasonForNoPermanentAllow.audio=%S can not allow permanent access to your tabs audio without asking which tab to share.
getUserMedia.reasonForNoPermanentAllow.insecure=Your connection to this site is not secure. To protect you, %S will only allow access for this session.
getUserMedia.sharingMenu.label = Tabs sharing devices
getUserMedia.sharingMenu.accesskey = d

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

@ -226,7 +226,10 @@ this.PermissionPromptPrototype = {
*
* If action is not set, expireType will be ignored.
* callback (function, optional)
* A callback function that will fire if the user makes this choice.
* A callback function that will fire if the user makes this choice, with
* a single parameter, state. State is an Object that contains the property
* checkboxChecked, which identifies whether the checkbox to remember this
* decision was checked.
*/
get promptActions() {
return [];
@ -297,14 +300,14 @@ this.PermissionPromptPrototype = {
let action = {
label: promptAction.label,
accessKey: promptAction.accessKey,
callback: () => {
callback: state => {
if (promptAction.callback) {
promptAction.callback();
}
if (this.permissionKey) {
// Remember permissions.
if (promptAction.action) {
if (state && state.checkboxChecked && promptAction.action) {
Services.perms.addFromPrincipal(this.principal,
this.permissionKey,
promptAction.action,
@ -337,6 +340,9 @@ this.PermissionPromptPrototype = {
if (!options.hasOwnProperty('displayURI') || options.displayURI) {
options.displayURI = this.principal.URI;
}
// Permission prompts are always persistent and don't have a close button.
options.persistent = true;
options.hideClose = true;
this.onBeforeShow();
chromeWin.PopupNotifications.show(this.browser,
@ -413,9 +419,25 @@ GeolocationPermissionPrompt.prototype = {
get popupOptions() {
let pref = "browser.geolocation.warning.infoURL";
return {
let options = {
learnMoreURL: Services.urlFormatter.formatURLPref(pref),
displayURI: false
};
if (this.principal.URI.schemeIs("file")) {
options.checkbox = { show: false };
} else {
// Don't offer "always remember" action in PB mode
options.checkbox = {
show: !PrivateBrowsingUtils.isWindowPrivate(this.browser.ownerGlobal)
};
}
if (options.checkbox.show) {
options.checkbox.label = gBrowserBundle.GetStringFromName("geolocation.remember");
}
return options;
},
get notificationID() {
@ -429,9 +451,14 @@ GeolocationPermissionPrompt.prototype = {
get message() {
let message;
if (this.principal.URI.schemeIs("file")) {
message = gBrowserBundle.GetStringFromName("geolocation.shareWithFile2");
message = gBrowserBundle.GetStringFromName("geolocation.shareWithFile3");
} else {
message = gBrowserBundle.GetStringFromName("geolocation.shareWithSite2");
let hostPort = "<>";
try {
hostPort = this.principal.URI.hostPort;
} catch (ex) { }
message = gBrowserBundle.formatStringFromName("geolocation.shareWithSite3",
[hostPort], 1);
}
return message;
},
@ -448,44 +475,33 @@ GeolocationPermissionPrompt.prototype = {
let secHistogram = Services.telemetry.getHistogramById("SECURITY_UI");
let actions = [{
label: gBrowserBundle.GetStringFromName("geolocation.shareLocation"),
return [{
label: gBrowserBundle.GetStringFromName("geolocation.allowLocation"),
accessKey:
gBrowserBundle.GetStringFromName("geolocation.shareLocation.accesskey"),
gBrowserBundle.GetStringFromName("geolocation.allowLocation.accesskey"),
action: null,
expireType: null,
callback: function() {
secHistogram.add(SHARE_LOCATION);
callback: function(state) {
if (state && state.checkboxChecked) {
secHistogram.add(ALWAYS_SHARE);
} else {
secHistogram.add(SHARE_LOCATION);
}
},
}, {
label: gBrowserBundle.GetStringFromName("geolocation.dontAllowLocation"),
accessKey:
gBrowserBundle.GetStringFromName("geolocation.dontAllowLocation.accesskey"),
action: Ci.nsIPermissionManager.DENY_ACTION,
expireType: PrivateBrowsingUtils.isWindowPrivate(this.browser.ownerGlobal) ?
Ci.nsIPermissionManager.EXPIRE_SESSION :
null,
callback: function(state) {
if (state && state.checkboxChecked) {
secHistogram.add(NEVER_SHARE);
}
},
}];
if (!this.principal.URI.schemeIs("file")) {
// Always share location action.
actions.push({
label: gBrowserBundle.GetStringFromName("geolocation.alwaysShareLocation"),
accessKey:
gBrowserBundle.GetStringFromName("geolocation.alwaysShareLocation.accesskey"),
action: Ci.nsIPermissionManager.ALLOW_ACTION,
expireType: null,
callback: function() {
secHistogram.add(ALWAYS_SHARE);
},
});
// Never share location action.
actions.push({
label: gBrowserBundle.GetStringFromName("geolocation.neverShareLocation"),
accessKey:
gBrowserBundle.GetStringFromName("geolocation.neverShareLocation.accesskey"),
action: Ci.nsIPermissionManager.DENY_ACTION,
expireType: null,
callback: function() {
secHistogram.add(NEVER_SHARE);
},
});
}
return actions;
},
onBeforeShow() {
@ -520,25 +536,23 @@ DesktopNotificationPermissionPrompt.prototype = {
let learnMoreURL =
Services.urlFormatter.formatURLPref("app.support.baseURL") + "push";
// The eventCallback is bound to the Notification that's being
// shown. We'll stash a reference to this in the closure so that
// the request can be cancelled.
let prompt = this;
let eventCallback = function(type) {
if (type == "dismissed") {
// Bug 1259148: Hide the doorhanger icon. Unlike other permission
// doorhangers, the user can't restore the doorhanger using the icon
// in the location bar. Instead, the site will be notified that the
// doorhanger was dismissed.
this.remove();
prompt.request.cancel();
}
let checkbox = {
show: true,
checked: true,
label: gBrowserBundle.GetStringFromName("webNotifications.remember")
};
// In PB mode, the "always remember" checkbox should only remember for the
// session.
if (PrivateBrowsingUtils.isWindowPrivate(this.browser.ownerGlobal)) {
checkbox.label =
gBrowserBundle.GetStringFromName("webNotifications.rememberForSession");
}
return {
learnMoreURL,
eventCallback,
checkbox,
displayURI: false
};
},
@ -551,43 +565,35 @@ DesktopNotificationPermissionPrompt.prototype = {
},
get message() {
return gBrowserBundle.GetStringFromName("webNotifications.receiveFromSite");
let hostPort = "<>";
try {
hostPort = this.principal.URI.hostPort;
} catch (ex) { }
return gBrowserBundle.formatStringFromName("webNotifications.receiveFromSite2",
[hostPort], 1);
},
get promptActions() {
let promptActions;
// Only show "allow for session" in PB mode, we don't
// support "allow for session" in non-PB mode.
if (PrivateBrowsingUtils.isBrowserPrivate(this.browser)) {
promptActions = [
{
label: gBrowserBundle.GetStringFromName("webNotifications.receiveForSession"),
accessKey:
gBrowserBundle.GetStringFromName("webNotifications.receiveForSession.accesskey"),
action: Ci.nsIPermissionManager.ALLOW_ACTION,
expireType: Ci.nsIPermissionManager.EXPIRE_SESSION,
}
];
} else {
promptActions = [
{
label: gBrowserBundle.GetStringFromName("webNotifications.alwaysReceive"),
accessKey:
gBrowserBundle.GetStringFromName("webNotifications.alwaysReceive.accesskey"),
action: Ci.nsIPermissionManager.ALLOW_ACTION,
expireType: null,
},
{
label: gBrowserBundle.GetStringFromName("webNotifications.neverShow"),
accessKey:
gBrowserBundle.GetStringFromName("webNotifications.neverShow.accesskey"),
action: Ci.nsIPermissionManager.DENY_ACTION,
expireType: null,
},
];
}
return promptActions;
return [
{
label: gBrowserBundle.GetStringFromName("webNotifications.allow"),
accessKey:
gBrowserBundle.GetStringFromName("webNotifications.allow.accesskey"),
action: Ci.nsIPermissionManager.ALLOW_ACTION,
expireType: PrivateBrowsingUtils.isBrowserPrivate(this.browser) ?
Ci.nsIPermissionManager.EXPIRE_SESSION :
null,
},
{
label: gBrowserBundle.GetStringFromName("webNotifications.dontAllow"),
accessKey:
gBrowserBundle.GetStringFromName("webNotifications.dontAllow.accesskey"),
action: Ci.nsIPermissionManager.DENY_ACTION,
expireType: PrivateBrowsingUtils.isBrowserPrivate(this.browser) ?
Ci.nsIPermissionManager.EXPIRE_SESSION :
null,
},
];
},
};

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

@ -567,6 +567,7 @@ this.SocialService = {
let options = {
learnMoreURL: Services.urlFormatter.formatURLPref("app.support.baseURL") + "social-api",
persistent: true,
};
let anchor = "servicesInstall-notification-icon";
let notificationid = "servicesInstall";

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

@ -63,21 +63,18 @@ function clickMainAction() {
}
/**
* For an opened PopupNotification, clicks on a secondary action,
* For an opened PopupNotification, clicks on the secondary action,
* and waits for the panel to fully close.
*
* @param {int} index
* The 0-indexed index of the secondary menuitem to choose.
* @return {Promise}
* Resolves once the panel has fired the "popuphidden"
* event.
*/
function clickSecondaryAction(index) {
function clickSecondaryAction() {
let removePromise =
BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden");
let popupNotification = getPopupNotificationNode();
let menuitems = popupNotification.children;
menuitems[index].click();
popupNotification.secondaryButton.click();
return removePromise;
}
@ -255,6 +252,13 @@ add_task(function* test_with_permission_key() {
permissionKey: kTestPermissionKey,
message: kTestMessage,
promptActions: [mainAction, secondaryAction],
popupOptions: {
checkbox: {
label: "Remember this decision",
show: true,
checked: true
}
}
};
let shownPromise =
@ -274,7 +278,7 @@ add_task(function* test_with_permission_key() {
// First test denying the permission request.
Assert.equal(notification.secondaryActions.length, 1,
"There should only be 1 secondary action");
yield clickSecondaryAction(0);
yield clickSecondaryAction();
curPerm = Services.perms.testPermissionFromPrincipal(principal,
kTestPermissionKey);
Assert.equal(curPerm, Ci.nsIPermissionManager.DENY_ACTION,
@ -429,7 +433,7 @@ add_task(function* test_no_request() {
// First test denying the permission request.
Assert.equal(notification.secondaryActions.length, 1,
"There should only be 1 secondary action");
yield clickSecondaryAction(0);
yield clickSecondaryAction();
Assert.ok(denied, "The secondaryAction callback should have fired");
Assert.ok(!allowed, "The mainAction callback should not have fired");

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

@ -18,6 +18,10 @@ XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
"resource://gre/modules/PluralForm.jsm");
XPCOMUtils.defineLazyGetter(this, "gBrandBundle", function() {
return Services.strings.createBundle("chrome://branding/locale/brand.properties");
});
this.webrtcUI = {
init: function() {
Services.obs.addObserver(maybeAddMenuIndicator, "browser-delayed-startup-finished", false);
@ -155,20 +159,10 @@ this.webrtcUI = {
identityBox.click();
},
updateMainActionLabel: function(aMenuList) {
updateWarningLabel: function(aMenuList) {
let type = aMenuList.selectedItem.getAttribute("devicetype");
let document = aMenuList.ownerDocument;
document.getElementById("webRTC-all-windows-shared").hidden = type != "Screen";
// If we are also requesting audio in addition to screen sharing,
// always use a generic label.
if (!document.getElementById("webRTC-selectMicrophone").hidden)
type = "";
let bundle = document.defaultView.gNavigatorBundle;
let stringId = "getUserMedia.share" + (type || "SelectedItems") + ".label";
let popupnotification = aMenuList.parentNode.parentNode;
popupnotification.setAttribute("buttonlabel", bundle.getString(stringId));
},
receiveMessage: function(aMessage) {
@ -294,21 +288,13 @@ function prompt(aBrowser, aRequest) {
let host = getHost(uri);
let chromeDoc = aBrowser.ownerDocument;
let stringBundle = chromeDoc.defaultView.gNavigatorBundle;
let stringId = "getUserMedia.share" + requestTypes.join("And") + ".message";
let stringId = "getUserMedia.share" + requestTypes.join("And") + "2.message";
let message = stringBundle.getFormattedString(stringId, [host]);
let mainLabel;
if (sharingScreen || sharingAudio) {
mainLabel = stringBundle.getString("getUserMedia.shareSelectedItems.label");
} else {
let string = stringBundle.getString("getUserMedia.shareSelectedDevices.label");
mainLabel = PluralForm.get(requestTypes.length, string);
}
let notification; // Used by action callbacks.
let mainAction = {
label: mainLabel,
accessKey: stringBundle.getString("getUserMedia.shareSelectedDevices.accesskey"),
label: stringBundle.getString("getUserMedia.allow.label"),
accessKey: stringBundle.getString("getUserMedia.allow.accesskey"),
// The real callback will be set during the "showing" event. The
// empty function here is so that PopupNotifications.show doesn't
// reject the action.
@ -317,45 +303,46 @@ function prompt(aBrowser, aRequest) {
let secondaryActions = [
{
label: stringBundle.getString("getUserMedia.denyRequest.label"),
accessKey: stringBundle.getString("getUserMedia.denyRequest.accesskey"),
callback: function() {
label: stringBundle.getString("getUserMedia.dontAllow.label"),
accessKey: stringBundle.getString("getUserMedia.dontAllow.accesskey"),
callback: function(aState) {
denyRequest(notification.browser, aRequest);
if (aState && aState.checkboxChecked) {
let perms = Services.perms;
if (audioDevices.length)
perms.add(uri, "microphone", perms.DENY_ACTION);
if (videoDevices.length)
perms.add(uri, "camera", perms.DENY_ACTION);
}
}
}
];
// Bug 1037438: implement 'never' for screen sharing.
if (!sharingScreen && !sharingAudio) {
secondaryActions.push({
label: stringBundle.getString("getUserMedia.never.label"),
accessKey: stringBundle.getString("getUserMedia.never.accesskey"),
callback: function() {
denyRequest(notification.browser, aRequest);
// Let someone save "Never" for http sites so that they can be stopped from
// bothering you with doorhangers.
let perms = Services.perms;
if (audioDevices.length)
perms.add(uri, "microphone", perms.DENY_ACTION);
if (videoDevices.length)
perms.add(uri, "camera", perms.DENY_ACTION);
}
});
}
if (aRequest.secure && !sharingScreen && !sharingAudio) {
// Don't show the 'Always' action if the connection isn't secure, or for
// screen/audio sharing (because we can't guess which window the user wants
// to share without prompting).
secondaryActions.unshift({
label: stringBundle.getString("getUserMedia.always.label"),
accessKey: stringBundle.getString("getUserMedia.always.accesskey"),
callback: function(aState) {
mainAction.callback(aState, true);
}
});
let productName = gBrandBundle.GetStringFromName("brandShortName");
// Disable the permanent 'Allow' action if the connection isn't secure, or for
// screen/audio sharing (because we can't guess which window the user wants to
// share without prompting).
let reasonForNoPermanentAllow = "";
if (sharingScreen) {
reasonForNoPermanentAllow = "getUserMedia.reasonForNoPermanentAllow.screen";
} else if (sharingAudio) {
reasonForNoPermanentAllow = "getUserMedia.reasonForNoPermanentAllow.audio";
} else if (!aRequest.secure) {
reasonForNoPermanentAllow = "getUserMedia.reasonForNoPermanentAllow.insecure";
}
let options = {
persistent: true,
hideClose: true,
checkbox: {
label: stringBundle.getString("getUserMedia.remember"),
checkedState: reasonForNoPermanentAllow ? {
disableMainAction: true,
warningLabel: stringBundle.getFormattedString(reasonForNoPermanentAllow,
[productName])
} : undefined,
},
eventCallback: function(aTopic, aNewBrowser) {
if (aTopic == "swapping")
return true;
@ -603,7 +590,8 @@ function prompt(aBrowser, aRequest) {
if (!sharingAudio)
listDevices(micMenupopup, audioDevices);
this.mainAction.callback = function(aState, aRemember) {
this.mainAction.callback = function(aState) {
let remember = aState && aState.checkboxChecked;
let allowedDevices = [];
let perms = Services.perms;
if (videoDevices.length) {
@ -617,7 +605,7 @@ function prompt(aBrowser, aRequest) {
perms.add(uri, "MediaManagerVideo", perms.ALLOW_ACTION,
perms.EXPIRE_SESSION);
}
if (aRemember) {
if (remember) {
perms.add(uri, "camera",
allowCamera ? perms.ALLOW_ACTION : perms.DENY_ACTION);
}
@ -628,7 +616,7 @@ function prompt(aBrowser, aRequest) {
let allowMic = audioDeviceIndex != "-1";
if (allowMic)
allowedDevices.push(audioDeviceIndex);
if (aRemember) {
if (remember) {
perms.add(uri, "microphone",
allowMic ? perms.ALLOW_ACTION : perms.DENY_ACTION);
}
@ -643,7 +631,7 @@ function prompt(aBrowser, aRequest) {
return;
}
if (aRemember) {
if (remember) {
// Remember on which URIs we set persistent permissions so that we
// can remove them if the user clicks 'Stop Sharing'.
aBrowser._devicePermissionURIs = aBrowser._devicePermissionURIs || [];

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

@ -344,6 +344,6 @@ menuitem[cmd="cmd_clearhistory"][disabled] {
.search-setting-button-compact > .button-box > .button-icon {
list-style-image: url("chrome://browser/skin/gear.svg");
filter: url(chrome://browser/skin/filters.svg#fill);
filter: url(chrome://global/skin/filters.svg#fill);
fill: currentColor;
}

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

@ -326,6 +326,6 @@
.search-setting-button-compact > .button-box > .button-icon {
list-style-image: url("chrome://browser/skin/gear.svg");
filter: url(chrome://browser/skin/filters.svg#fill);
filter: url(chrome://global/skin/filters.svg#fill);
fill: currentColor;
}

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

@ -12,7 +12,7 @@
width: 16px;
height: 16px;
margin: 7px;
filter: url(chrome://browser/skin/filters.svg#fill);
filter: url(chrome://global/skin/filters.svg#fill);
fill: currentColor;
}

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

@ -423,7 +423,7 @@ description#identity-popup-content-verifier,
width: 16px;
height: 16px;
list-style-image: url(chrome://browser/skin/panel-icons.svg#cancel);
filter: url(chrome://browser/skin/filters.svg#fill);
filter: url(chrome://global/skin/filters.svg#fill);
fill: graytext;
}

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

@ -296,7 +296,7 @@ window:not([chromehidden~="toolbar"]) #urlbar-wrapper {
.tab-icon-sound[soundplaying],
.tab-icon-sound[muted] {
filter: url(chrome://browser/skin/filters.svg#fill) !important; /* removes drop-shadow filter */
filter: url(chrome://global/skin/filters.svg#fill) !important; /* removes drop-shadow filter */
}
/* Don't need space for the tab curves (66px - 30px) */

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

@ -103,7 +103,7 @@
width: 16px;
height: 16px;
margin: 0;
filter: url("chrome://browser/skin/filters.svg#fill");
filter: url("chrome://global/skin/filters.svg#fill");
fill: currentColor;
}

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

@ -138,8 +138,8 @@ toolbarseparator.downloadsDropmarkerSplitter {
.downloadsDropmarker > .button-box > .button-menu-dropmarker > .dropmarker-icon {
width: 16px;
height: 16px;
list-style-image: url("chrome://browser/skin/downloads/menubutton-dropmarker.svg");
filter: url("chrome://browser/skin/filters.svg#fill");
list-style-image: url("chrome://global/skin/icons/menubutton-dropmarker.svg");
filter: url("chrome://global/skin/filters.svg#fill");
fill: currentColor;
}
@ -267,7 +267,7 @@ richlistitem[type="download"] > .downloadMainArea {
width: 16px;
height: 16px;
margin: 1px;
filter: url("chrome://browser/skin/filters.svg#fill");
filter: url("chrome://global/skin/filters.svg#fill");
fill: currentColor;
}

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

@ -1,9 +0,0 @@
<?xml version="1.0"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg">
<filter id="fill">
<feComposite in="FillPaint" in2="SourceGraphic" operator="in"/>
</filter>
</svg>

До

Ширина:  |  Высота:  |  Размер: 383 B

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

@ -52,10 +52,8 @@
skin/classic/browser/customizableui/whimsy@2x.png (../shared/customizableui/whimsy@2x.png)
skin/classic/browser/downloads/contentAreaDownloadsView.css (../shared/downloads/contentAreaDownloadsView.css)
skin/classic/browser/downloads/download-blocked.svg (../shared/downloads/download-blocked.svg)
skin/classic/browser/downloads/menubutton-dropmarker.svg (../shared/downloads/menubutton-dropmarker.svg)
skin/classic/browser/downloads/download-summary.svg (../shared/downloads/download-summary.svg)
skin/classic/browser/drm-icon.svg (../shared/drm-icon.svg)
skin/classic/browser/filters.svg (../shared/filters.svg)
skin/classic/browser/fullscreen/insecure.svg (../shared/fullscreen/insecure.svg)
skin/classic/browser/fullscreen/secure.svg (../shared/fullscreen/secure.svg)
skin/classic/browser/heartbeat-icon.svg (../shared/heartbeat-icon.svg)

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

@ -9,7 +9,7 @@ toolbarpaletteitem[place="palette"] > :-moz-any(@primaryToolbarButtons@) {
:-moz-any(@primaryToolbarButtons@)[cui-areatype="menu-panel"][panel-multiview-anchor=true] > .toolbarbutton-icon,
:-moz-any(@primaryToolbarButtons@)[cui-areatype="menu-panel"][panel-multiview-anchor=true] > .toolbarbutton-badge-stack > .toolbarbutton-icon,
:-moz-any(@primaryToolbarButtons@)[cui-areatype="menu-panel"][panel-multiview-anchor=true] > .toolbarbutton-menubutton-button > .toolbarbutton-icon {
filter: url(chrome://browser/skin/filters.svg#fill);
filter: url(chrome://global/skin/filters.svg#fill);
fill: currentColor;
}

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

@ -39,15 +39,21 @@
}
}
.popup-notification-icon {
width: 64px;
height: 64px;
margin-inline-end: 10px;
#notification-popup > .panel-arrowcontainer > .panel-arrowcontent {
/* In order to display the action buttons near the edge of the arrow panel we
* have to reset its default padding and specify the padding in the individual
* "popupnotification" elements instead. To keep the rounded borders of the
* panel, we also have to ensure the contents are clipped to the border box
* by hiding the overflow, and we have to override the "display" property so
* that the height of the contents is computed correctly in that case. */
padding: 0;
overflow: hidden;
display: block;
}
.notification-anchor-icon:not(.plugin-blocked):-moz-lwtheme,
#blocked-permissions-container > .blocked-permission-icon:-moz-lwtheme {
filter: url(chrome://browser/skin/filters.svg#fill);
filter: url(chrome://global/skin/filters.svg#fill);
fill: currentColor;
}

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

@ -207,7 +207,7 @@
.tab-icon-sound[muted],
.tab-icon-sound[blocked] {
list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio);
filter: url(chrome://browser/skin/filters.svg#fill);
filter: url(chrome://global/skin/filters.svg#fill);
fill: currentColor;
}
@ -222,13 +222,13 @@
.tab-icon-sound:-moz-lwtheme-darktext[soundplaying],
.tab-icon-sound:-moz-lwtheme-darktext[muted],
.tab-icon-sound:-moz-lwtheme-darktext[blocked] {
filter: url(chrome://browser/skin/filters.svg#fill) drop-shadow(1px 1px 1px white);
filter: url(chrome://global/skin/filters.svg#fill) drop-shadow(1px 1px 1px white);
}
.tab-icon-sound:-moz-lwtheme-brighttext[soundplaying],
.tab-icon-sound:-moz-lwtheme-brighttext[muted],
.tab-icon-sound:-moz-lwtheme-brighttext[blocked] {
filter: url(chrome://browser/skin/filters.svg#fill) drop-shadow(1px 1px 1px black);
filter: url(chrome://global/skin/filters.svg#fill) drop-shadow(1px 1px 1px black);
}
.tab-icon-sound[soundplaying]:not(:hover),
@ -553,7 +553,7 @@
.alltabs-endimage[muted],
.alltabs-endimage[blocked] {
list-style-image: url(chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio);
filter: url(chrome://browser/skin/filters.svg#fill);
filter: url(chrome://global/skin/filters.svg#fill);
fill: currentColor;
}

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

@ -2668,19 +2668,16 @@ notification.pluginVulnerable > .notification-inner > .messageCloseButton {
#ContentSelectDropdown > menupopup > menucaption,
#ContentSelectDropdown > menupopup > menuitem {
padding: 4px 6px;
padding: 0 6px;
border-width: 0;
}
#ContentSelectDropdown > menupopup > menucaption > .menu-iconic-text,
#ContentSelectDropdown > menupopup > menuitem > .menu-iconic-text {
font: message-box;
font-size: 11px;
/**
* Remove the extra vertical padding set by menu.css since
* the menuitem itself will include enough padding.
*/
padding-top: 0px;
padding-bottom: 0px;
/* Padding should follow the 4/12 ratio, where 12px is the default font-size
with 4px being the preferred padding size. */
padding-top: .3333em;
padding-bottom: .3333em;
}
#ContentSelectDropdown > menupopup > menucaption > .menu-iconic-text {
@ -2700,8 +2697,10 @@ notification.pluginVulnerable > .notification-inner > .messageCloseButton {
color: GrayText;
}
#ContentSelectDropdown > .isOpenedViaTouch > menucaption,
#ContentSelectDropdown > .isOpenedViaTouch > menuitem {
padding-top: 11px;
padding-bottom: 11px;
#ContentSelectDropdown > .isOpenedViaTouch > menucaption > .menu-iconic-text,
#ContentSelectDropdown > .isOpenedViaTouch > menuitem > .menu-iconic-text {
/* Touch padding should follow the 11/12 ratio, where 12px is the default
font-size with 11px being the preferred padding size. */
padding-top: .9167em;
padding-bottom: .9167em;
}

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

@ -336,6 +336,6 @@
.search-setting-button-compact > .button-box > .button-icon {
list-style-image: url("chrome://browser/skin/gear.svg");
filter: url(chrome://browser/skin/filters.svg#fill);
filter: url(chrome://global/skin/filters.svg#fill);
fill: currentColor;
}

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

@ -24,6 +24,7 @@ this.PermissionPrompts = {
Services.prefs.setCharPref("media.getusermedia.screensharing.allowed_domains",
"test1.example.com");
Services.prefs.setBoolPref("extensions.install.requireBuiltInCerts", false);
Services.prefs.setBoolPref("signon.rememberSignons", true);
},
configurations: {

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

@ -156,6 +156,8 @@ if test -n "$MOZ_SYSTEM_NSPR" -o -n "$NSPR_CFLAGS" -o -n "$NSPR_LIBS"; then
,
AC_MSG_ERROR([system NSPR does not support PR_UINT64 or including prtypes.h does not provide it]))
CFLAGS=$_SAVE_CFLAGS
NSPR_INCLUDE_DIR=`echo ${NSPR_CFLAGS} | sed -e 's/.*-I\([^ ]*\).*/\1/'`
NSPR_LIB_DIR=`echo ${NSPR_LIBS} | sed -e 's/.*-L\([^ ]*\).*/\1/'`
elif test -z "$JS_POSIX_NSPR"; then
NSPR_INCLUDE_DIR="${DIST}/include/nspr"
NSPR_CFLAGS="-I${NSPR_INCLUDE_DIR}"

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

@ -4,7 +4,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/.
gyp_vars = {
include('gyp_base.mozbuild')
gyp_vars.update({
'lsan': 0,
'asan': 0,
'build_with_mozilla': 1,
@ -69,16 +71,9 @@ gyp_vars = {
# linker to throw away uneeded bits.
'include_isac': 1,
'include_pcm16b': 1,
}
})
os = CONFIG['OS_TARGET']
if os == 'WINNT':
gyp_vars.update(
MSVS_VERSION=CONFIG['_MSVS_VERSION'],
MSVS_OS_BITS=64 if CONFIG['HAVE_64BIT_BUILD'] else 32,
)
elif os == 'Android':
if os == 'Android':
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
gyp_vars['build_with_gonk'] = 1
gyp_vars['moz_widget_toolkit_gonk'] = 1
@ -92,28 +87,6 @@ elif os == 'Android':
android_toolchain=CONFIG.get('ANDROID_TOOLCHAIN', ''),
)
flavors = {
'WINNT': 'win',
'Android': 'linux' if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' else 'android',
'Linux': 'linux',
'Darwin': 'mac' if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa' else 'ios',
'SunOS': 'solaris',
'GNU/kFreeBSD': 'freebsd',
'DragonFly': 'dragonfly',
'FreeBSD': 'freebsd',
'NetBSD': 'netbsd',
'OpenBSD': 'openbsd',
}
gyp_vars['OS'] = flavors.get(os)
arches = {
'x86_64': 'x64',
'x86': 'ia32',
'aarch64': 'arm64',
}
gyp_vars['target_arch'] = arches.get(CONFIG['CPU_ARCH'], CONFIG['CPU_ARCH'])
if CONFIG['ARM_ARCH']:
if int(CONFIG['ARM_ARCH']) < 7:
gyp_vars['armv7'] = 0

38
build/gyp_base.mozbuild Normal file
Просмотреть файл

@ -0,0 +1,38 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
gyp_vars = {}
os = CONFIG['OS_TARGET']
if os == 'WINNT':
gyp_vars.update(
MSVS_VERSION=CONFIG['_MSVS_VERSION'],
MSVS_OS_BITS=64 if CONFIG['HAVE_64BIT_BUILD'] else 32,
)
flavors = {
'WINNT': 'win',
'Android': 'linux' if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' else 'android',
'Linux': 'linux',
'Darwin': 'mac' if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa' else 'ios',
'SunOS': 'solaris',
'GNU/kFreeBSD': 'freebsd',
'DragonFly': 'dragonfly',
'FreeBSD': 'freebsd',
'NetBSD': 'netbsd',
'OpenBSD': 'openbsd',
}
gyp_vars['OS'] = flavors.get(os)
arches = {
'x86_64': 'x64',
'x86': 'ia32',
'aarch64': 'arm64',
}
gyp_vars['host_arch'] = arches.get(CONFIG['HOST_CPU_ARCH'], CONFIG['HOST_CPU_ARCH'])
gyp_vars['target_arch'] = arches.get(CONFIG['CPU_ARCH'], CONFIG['CPU_ARCH'])

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

@ -520,6 +520,7 @@ def host_variables(host):
HOST_OS_ARCH=os_arch,
)
set_config('HOST_CPU_ARCH', delayed_getattr(host, 'cpu'))
set_config('HOST_OS_ARCH', delayed_getattr(host_variables, 'HOST_OS_ARCH'))
add_old_configure_assignment('HOST_OS_ARCH',
delayed_getattr(host_variables, 'HOST_OS_ARCH'))

485
config/external/nss/Makefile.in поставляемый
Просмотреть файл

@ -1,485 +0,0 @@
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
ifndef MOZ_SYSTEM_NSS
CC_WRAPPER =
CXX_WRAPPER =
default::
include $(topsrcdir)/config/makefiles/functions.mk
NSS_LIBS = \
nss3 \
nssutil3 \
smime3 \
ssl3 \
$(NULL)
ifdef MOZ_FOLD_LIBS
NSS_DLLS = $(LIBRARY_NAME)
else
NSS_DLLS = $(NSS_LIBS)
endif
NSS_EXTRA_DLLS = \
nssckbi \
softokn3 \
$(NULL)
ifndef NSS_DISABLE_DBM
NSS_EXTRA_DLLS += nssdbm3
endif
SDK_LIBS = crmf
ifneq (,$(filter WINNT,$(OS_ARCH)))
SDK_LIBS += $(NSS_DLLS)
endif
# Default
HAVE_FREEBL_LIBS = 1
# 32-bit HP-UX PA-RISC
ifeq ($(OS_ARCH), HP-UX)
ifneq ($(OS_TEST), ia64)
ifndef HAVE_64BIT_BUILD
HAVE_FREEBL_LIBS =
HAVE_FREEBL_LIBS_32INT32 = 1
HAVE_FREEBL_LIBS_32FPU = 1
endif
endif
endif
# SunOS SPARC
ifeq ($(OS_ARCH), SunOS)
ifneq (86,$(findstring 86,$(OS_TEST)))
ifdef HAVE_64BIT_BUILD
HAVE_FREEBL_LIBS =
HAVE_FREEBL_LIBS_64 = 1
else
HAVE_FREEBL_LIBS =
HAVE_FREEBL_LIBS_32FPU = 1
HAVE_FREEBL_LIBS_32INT64 = 1
endif
endif
endif
ifeq ($(OS_TARGET),Linux)
HAVE_FREEBL_LIBS =
HAVE_FREEBL_LIBS_PRIV = 1
FREEBL_LOWHASH_FLAG = FREEBL_LOWHASH=1
endif
ifdef HAVE_FREEBL_LIBS
NSS_EXTRA_DLLS += freebl3
endif
ifdef HAVE_FREEBL_LIBS_PRIV
NSS_EXTRA_DLLS += freeblpriv3
endif
ifdef HAVE_FREEBL_LIBS_32INT32
NSS_EXTRA_DLLS += freebl_32int_3
endif
ifdef HAVE_FREEBL_LIBS_32FPU
NSS_EXTRA_DLLS += freebl_32fpu_3
endif
ifdef HAVE_FREEBL_LIBS_32INT64
NSS_EXTRA_DLLS += freebl_32int64_3
endif
ifdef HAVE_FREEBL_LIBS_64
NSS_EXTRA_DLLS += freebl_64int_3
NSS_EXTRA_DLLS += freebl_64fpu_3
endif
# For all variables such as DLLFLAGS, that may contain $(DIST)
DIST := $(ABS_DIST)
# TODO: move this all to configure, but in Python
ifndef MOZ_BUILD_NSPR
NSPR_INCLUDE_DIR = $(firstword $(filter -I%,$(NSPR_CFLAGS)))
ifneq (,$(strip $(NSPR_INCLUDE_DIR)))
NSPR_INCLUDE_DIR := $(subst -I,,$(subst -I$(DIST),-I$(ABS_DIST),$(NSPR_INCLUDE_DIR)))
else
$(error Your NSPR CFLAGS are broken!)
endif
NSPR_LIB_DIR = $(firstword $(filter -L%,$(NSPR_LIBS)))
ifneq (,$(strip $(NSPR_LIB_DIR)))
NSPR_LIB_DIR := $(subst -L,,$(subst -L$(DIST),-L$(ABS_DIST),$(NSPR_LIB_DIR)))
else
$(error Your NSPR LDFLAGS are broken!)
endif
endif
# To get debug symbols from NSS
export MOZ_DEBUG_SYMBOLS
DEFAULT_GMAKE_FLAGS =
DEFAULT_GMAKE_FLAGS += CC='$(CC)'
DEFAULT_GMAKE_FLAGS += MT='$(MT)'
DEFAULT_GMAKE_FLAGS += LD='$(LD)'
DEFAULT_GMAKE_FLAGS += SOURCE_MD_DIR=$(ABS_DIST)
DEFAULT_GMAKE_FLAGS += SOURCE_MDHEADERS_DIR=$(NSPR_INCLUDE_DIR)
DEFAULT_GMAKE_FLAGS += DIST=$(ABS_DIST)
DEFAULT_GMAKE_FLAGS += NSPR_INCLUDE_DIR=$(NSPR_INCLUDE_DIR)
DEFAULT_GMAKE_FLAGS += NSPR_LIB_DIR=$(NSPR_LIB_DIR)
DEFAULT_GMAKE_FLAGS += MOZILLA_CLIENT=1
DEFAULT_GMAKE_FLAGS += NO_MDUPDATE=1
DEFAULT_GMAKE_FLAGS += NSS_ENABLE_ECC=1
DEFAULT_GMAKE_FLAGS += NSS_ENABLE_TLS_1_3=1
ifeq ($(OS_ARCH)_$(GNU_CC),WINNT_1)
DEFAULT_GMAKE_FLAGS += OS_DLLFLAGS='-static-libgcc' NSPR31_LIB_PREFIX=lib
endif
ifndef MOZ_SYSTEM_SQLITE
ifdef MOZ_FOLD_LIBS
DEFAULT_GMAKE_FLAGS += SQLITE_LIB_NAME=nss3
else
DEFAULT_GMAKE_FLAGS += SQLITE_LIB_NAME=mozsqlite3
DEFAULT_GMAKE_FLAGS += SQLITE_LIB_DIR=$(ABS_DIST)/../config/external/sqlite
endif # MOZ_FOLD_LIBS
DEFAULT_GMAKE_FLAGS += SQLITE_INCLUDE_DIR=$(ABS_DIST)/include
endif
ifdef NSS_DISABLE_DBM
DEFAULT_GMAKE_FLAGS += NSS_DISABLE_DBM=1
endif
# Hack to force NSS build system to use "normal" object directories
DEFAULT_GMAKE_FLAGS += topsrcdir='$(topsrcdir)'
# topsrcdir can't be expanded here because msys path mangling likes to break
# paths in that case.
DEFAULT_GMAKE_FLAGS += BUILD='$(MOZ_BUILD_ROOT)/security/$$(subst $$(topsrcdir)/security/,,$$(CURDIR))'
DEFAULT_GMAKE_FLAGS += BUILD_TREE='$$(BUILD)' OBJDIR='$$(BUILD)' DEPENDENCIES='$$(BUILD)/.deps' SINGLE_SHLIB_DIR='$$(BUILD)'
DEFAULT_GMAKE_FLAGS += SOURCE_XP_DIR=$(ABS_DIST)
ifndef MOZ_DEBUG
DEFAULT_GMAKE_FLAGS += BUILD_OPT=1 OPT_CODE_SIZE=1
endif
ifdef GNU_CC
DEFAULT_GMAKE_FLAGS += NS_USE_GCC=1
else
DEFAULT_GMAKE_FLAGS += NS_USE_GCC=
endif
ifdef USE_N32
# It is not really necessary to specify USE_PTHREADS=1. USE_PTHREADS
# merely adds _PTH to coreconf's OBJDIR name.
DEFAULT_GMAKE_FLAGS += USE_N32=1 USE_PTHREADS=1
endif
ifdef HAVE_64BIT_BUILD
DEFAULT_GMAKE_FLAGS += USE_64=1
endif
ifeq ($(OS_ARCH),WINNT)
DEFAULT_GMAKE_FLAGS += OS_TARGET=WIN95
ifdef MOZ_DEBUG
ifndef MOZ_NO_DEBUG_RTL
DEFAULT_GMAKE_FLAGS += USE_DEBUG_RTL=1
endif
endif
endif # WINNT
ifeq ($(OS_ARCH),Darwin)
# Make nsinstall use absolute symlinks by default when building NSS
# for Mozilla on Mac OS X. (Bugzilla bug 193164)
ifndef NSDISTMODE
DEFAULT_GMAKE_FLAGS += NSDISTMODE=absolute_symlink
endif
ifdef MACOS_SDK_DIR
DEFAULT_GMAKE_FLAGS += MACOS_SDK_DIR=$(MACOS_SDK_DIR)
endif
endif
# Turn off TLS compression support because it requires system zlib.
# See bug 580679 comment 18.
DEFAULT_GMAKE_FLAGS += NSS_SSL_ENABLE_ZLIB=
# Disable building of the test programs in security/nss/lib/zlib
DEFAULT_GMAKE_FLAGS += PROGRAMS=
# Disable creating .chk files. They will be generated from packager.mk
# When bug 681624 lands, we can replace CHECKLOC= with SKIP_SHLIBSIGN=1
DEFAULT_GMAKE_FLAGS += CHECKLOC=
ifdef CROSS_COMPILE
DEFAULT_GMAKE_FLAGS += \
NATIVE_CC='$(HOST_CC)' \
CC='$(CC)' \
CCC='$(CXX)' \
AS='$(AS)' \
AR='$(AR) $(AR_FLAGS:$@=$$@)' \
RANLIB='$(RANLIB)' \
RC='$(RC) $(RCFLAGS)' \
OS_ARCH='$(OS_ARCH)' \
OS_TEST='$(OS_TEST)' \
CPU_ARCH='$(TARGET_CPU)' \
$(NULL)
# Android has pthreads integrated into -lc, so OS_PTHREAD is set to nothing
ifeq ($(OS_TARGET), Android)
DEFAULT_GMAKE_FLAGS += \
OS_RELEASE='2.6' \
OS_PTHREAD= \
$(NULL)
DEFAULT_GMAKE_FLAGS += ARCHFLAG='$(filter-out -W%,$(CFLAGS)) -DCHECK_FORK_GETPID $(addprefix -DANDROID_VERSION=,$(ANDROID_VERSION)) -include $(topsrcdir)/security/manager/android_stub.h'
endif
endif
ifdef WRAP_LDFLAGS
NSS_EXTRA_LDFLAGS += $(WRAP_LDFLAGS)
endif
# The SHARED_LIBS part is needed unconditionally on Android. It's not
# clear why this is the case, but see bug 1133073 (starting around
# comment #8) for context.
ifneq (,$(or $(MOZ_GLUE_WRAP_LDFLAGS), $(filter Android, $(OS_TARGET))))
NSS_EXTRA_LDFLAGS += $(SHARED_LIBS:$(DEPTH)%=$(MOZ_BUILD_ROOT)%) $(MOZ_GLUE_WRAP_LDFLAGS)
endif
ifneq (,$(NSS_EXTRA_LDFLAGS))
DEFAULT_GMAKE_FLAGS += \
LDFLAGS='$(LDFLAGS) $(NSS_EXTRA_LDFLAGS)' \
DSO_LDOPTS='$(DSO_LDOPTS) $(LDFLAGS) $(NSS_EXTRA_LDFLAGS)' \
$(NULL)
endif
DEFAULT_GMAKE_FLAGS += FREEBL_NO_DEPEND=0 $(FREEBL_LOWHASH_FLAG)
DEFAULT_GMAKE_FLAGS += NSS_ALLOW_SSLKEYLOGFILE=1
ifdef MOZ_NO_WLZDEFS
DEFAULT_GMAKE_FLAGS += ZDEFS_FLAG=
endif
ifdef MOZ_CFLAGS_NSS
NSS_XCFLAGS += $(filter-out -W%,$(CFLAGS))
DEFAULT_GMAKE_FLAGS += DARWIN_DYLIB_VERSIONS='-compatibility_version 1 -current_version 1 $(LDFLAGS)'
endif
ifeq (1_1,$(CLANG_CL)_$(MOZ_ASAN))
XLDFLAGS := $(OS_LDFLAGS)
DEFAULT_GMAKE_FLAGS += XLDFLAGS='$(XLDFLAGS)'
endif
DEFAULT_GMAKE_FLAGS += NSS_NO_PKCS11_BYPASS=1
# Put NSS headers directly under $(DIST)/include
DEFAULT_GMAKE_FLAGS += PUBLIC_EXPORT_DIR='$(ABS_DIST)/include/$$(MODULE)'
DEFAULT_GMAKE_FLAGS += SOURCE_XPHEADERS_DIR='$$(SOURCE_XP_DIR)/include/$$(MODULE)'
DEFAULT_GMAKE_FLAGS += MODULE_INCLUDES='$$(addprefix -I$$(SOURCE_XP_DIR)/include/,$$(REQUIRES))'
# Work around NSS's MAKE_OBJDIR being racy. See bug #836220
DEFAULT_GMAKE_FLAGS += MAKE_OBJDIR='$$(INSTALL) -D $$(OBJDIR)'
# Work around NSS adding IMPORT_LIBRARY to TARGETS with no rule for
# it, creating race conditions. See bug #836220
DEFAULT_GMAKE_FLAGS += TARGETS='$$(LIBRARY) $$(SHARED_LIBRARY) $$(PROGRAM)'
ifdef MOZ_FOLD_LIBS_FLAGS
NSS_XCFLAGS += $(MOZ_FOLD_LIBS_FLAGS)
endif
# Pass on the MSVC target arch from the main build system.
# Note this is case- and switch-character sensitive, while
# the MSVC option is not.
ifeq (WINNT,$(OS_TARGET))
NSS_XCFLAGS += $(filter -arch:%,$(CFLAGS))
endif
# Export accumulated XCFLAGS to modify nss defaults.
DEFAULT_GMAKE_FLAGS += XCFLAGS='$(NSS_XCFLAGS)'
NSS_SRCDIR = $(topsrcdir)
NSS_DIRS =
ifndef MOZ_FOLD_LIBS
NSS_DIRS += nss/lib
else
ifndef NSS_DISABLE_DBM
NSS_DIRS += nss/lib/dbm
endif
endif
NSS_DIRS += \
nss/cmd/lib \
nss/cmd/shlibsign \
$(NULL)
ifdef ENABLE_TESTS
NSS_DIRS += \
nss/cmd/certutil \
nss/cmd/pk12util \
nss/cmd/modutil \
$(NULL)
endif
ifneq (,$(filter %--build-id,$(LDFLAGS)))
DEFAULT_GMAKE_ENV = LDFLAGS=-Wl,--build-id
endif
ifdef MOZ_FOLD_LIBS
# TODO: The following can be replaced by something simpler when bug 844880
# is fixed.
# All static libraries required for nss, smime, ssl and nssutil.
# The strip is needed to remove potential linefeed characters, since they hang
# around in some cases on Windows.
NSS_STATIC_LIBS := $(strip $(shell $(MAKE) --no-print-directory -f $(srcdir)/nss.mk DEPTH='$(DEPTH)' topsrcdir='$(topsrcdir)' srcdir='$(srcdir)' echo-variable-libs))
# Corresponding build directories
NSS_STATIC_DIRS := $(foreach lib,$(NSS_STATIC_LIBS),$(patsubst %/,%,$(dir $(lib))))
NSS_DIRS += $(NSS_STATIC_DIRS)
# TODO: The following can be replaced by something simpler when bug 844884
# is fixed.
# Remaining nss/lib directories
NSS_DIRS += nss/lib/freebl nss/lib/softoken nss/lib/jar nss/lib/crmf nss/lib/ckfw
DEFAULT_GMAKE_FLAGS += NSS_DISABLE_LIBPKIX=1
ifeq (WINNT,$(OS_TARGET))
NSS_DIRS += nss/lib/zlib
endif
endif # MOZ_FOLD_LIBS
# Filter-out $(LIBRARY_NAME) because it's already handled in config/rules.mk.
NSS_DIST_DLL_FILES := $(addprefix $(DIST)/lib/$(DLL_PREFIX),$(addsuffix $(DLL_SUFFIX),$(filter-out $(LIBRARY_NAME),$(NSS_DLLS)) $(NSS_EXTRA_DLLS)))
NSS_DIST_DLL_DEST := $(DIST)/bin
NSS_DIST_DLL_TARGET := target
INSTALL_TARGETS += NSS_DIST_DLL
ifeq ($(OS_ARCH)_$(1), SunOS_softokn3)
# has to use copy mode on Solaris, see #665509
$(DIST)/bin/$(DLL_PREFIX)softokn3$(DLL_SUFFIX): INSTALL := $(INSTALL) -t
endif
NSS_SDK_LIB_FILES := \
$(addprefix $(DIST)/lib/$(LIB_PREFIX),$(addsuffix .$(LIB_SUFFIX),$(SDK_LIBS))) \
$(addprefix $(DIST)/bin/$(DLL_PREFIX),$(addsuffix $(DLL_SUFFIX),$(NSS_DLLS))) \
$(NULL)
NSS_SDK_LIB_DEST := $(DIST)/sdk/lib
NSS_SDK_LIB_TARGET := target
INSTALL_TARGETS += NSS_SDK_LIB
ifdef MOZ_FOLD_LIBS
# Add all static libraries for nss, smime, ssl and nssutil
STATIC_LIBS += $(addprefix $(DEPTH)/security/,$(NSS_STATIC_LIBS))
IMPORT_LIB_FILES = $(IMPORT_LIBRARY)
IMPORT_LIB_DEST ?= $(DIST)/lib
IMPORT_LIB_TARGET = target
INSTALL_TARGETS += IMPORT_LIB
endif # MOZ_FOLD_LIBS
include $(topsrcdir)/config/rules.mk
ifeq (1,$(ALLOW_COMPILER_WARNINGS))
DEFAULT_GMAKE_FLAGS += NSS_ENABLE_WERROR=0
endif
# Can't pass this in DEFAULT_GMAKE_FLAGS because that overrides
# definitions in NSS, so just export it into the sub-make's environment.
ifeq (WINNT_1,$(OS_TARGET)_$(MOZ_MEMORY))
DLLFLAGS := -LIBPATH:$(ABS_DIST)/../mozglue/build -DEFAULTLIB:mozglue
export DLLFLAGS
endif
ifdef MOZ_FOLD_LIBS
# Force the linker to include everything from the static libraries.
EXPAND_LIBS_EXEC += --extract
$(SHARED_LIBRARY): $(addprefix $(DEPTH)/security/,$(NSS_STATIC_LIBS))
ifdef IMPORT_LIB_SUFFIX
IMPORT_PREFIX = $(LIB_PREFIX)
IMPORT_SUFFIX = .$(IMPORT_LIB_SUFFIX)
else
IMPORT_PREFIX = $(DLL_PREFIX)
IMPORT_SUFFIX = $(DLL_SUFFIX)
endif
NSPR_IMPORT_LIBS = $(addprefix $(DIST)/lib/$(IMPORT_PREFIX),$(addsuffix $(IMPORT_SUFFIX),nspr4 plc4 plds4))
SQLITE_IMPORT_LIB = $(DIST)/lib/$(IMPORT_PREFIX)mozsqlite3$(IMPORT_SUFFIX)
# TODO: The following can be replaced by something simpler when bug 844884
# is fixed.
# Associate target files with the rules that build them.
$(DIST)/lib/$(LIB_PREFIX)crmf.$(LIB_SUFFIX): libs-nss/lib/crmf
$(DIST)/lib/$(DLL_PREFIX)freebl3$(DLL_SUFFIX): libs-nss/lib/freebl
$(DIST)/lib/$(DLL_PREFIX)nssckbi$(DLL_SUFFIX): libs-nss/lib/ckfw
$(DIST)/lib/$(DLL_PREFIX)softokn3$(DLL_SUFFIX): libs-nss/lib/softoken
$(DIST)/lib/$(DLL_PREFIX)nssdbm3$(DLL_SUFFIX): libs-nss/lib/softoken
$(foreach lib,$(NSS_STATIC_LIBS),$(eval $(DEPTH)/security/$(lib): libs-$(patsubst %/,%,$(dir $(lib)))))
# Create fake import libraries for the folded libraries, so that linking
# against them works both for the NSS build system (see dependencies below)
# and for the rest of the mozilla build system.
$(NSPR_IMPORT_LIBS) \
$(SQLITE_IMPORT_LIB) \
$(DIST)/lib/$(IMPORT_PREFIX)nssutil3$(IMPORT_SUFFIX) \
$(DIST)/lib/$(IMPORT_PREFIX)ssl3$(IMPORT_SUFFIX) \
$(DIST)/lib/$(IMPORT_PREFIX)smime3$(IMPORT_SUFFIX): $(DIST)/lib/$(IMPORT_PREFIX)nss3$(IMPORT_SUFFIX)
ifeq (WINNT,$(OS_TARGET))
cp $< $@
else
ln -sf $< $@
endif
# Interdependencies between nss sub-directories, and dependencies on NSPR/SQLite
libs-nss/lib/ckfw: libs-nss/lib/nss/../base $(NSPR_IMPORT_LIBS)
libs-nss/lib/softoken: $(NSPR_IMPORT_LIBS) $(SQLITE_IMPORT_LIB)
libs-nss/lib/softoken: libs-nss/lib/freebl
ifndef NSS_DISABLE_DBM
libs-nss/lib/softoken: libs-nss/lib/dbm
endif
libs-nss/lib/softoken: $(DIST)/lib/$(IMPORT_PREFIX)nssutil3$(IMPORT_SUFFIX)
libs-nss/lib/freebl: $(DIST)/lib/$(IMPORT_PREFIX)nssutil3$(IMPORT_SUFFIX) $(NSPR_IMPORT_LIBS)
# For each directory where we build static libraries, force the NSS build system
# to only build static libraries.
$(addprefix libs-,$(NSS_STATIC_DIRS)): DEFAULT_GMAKE_FLAGS += SHARED_LIBRARY= IMPORT_LIBRARY=
else
$(STATIC_LIBS) $(NSS_DIST_DLL_FILES) $(NSS_SDK_LIB_FILES): libs-nss/lib
endif # MOZ_FOLD_LIBS
ifeq ($(NSINSTALL_PY),$(NSINSTALL))
DEFAULT_GMAKE_FLAGS += PYTHON='$(PYTHON)'
DEFAULT_GMAKE_FLAGS += NSINSTALL_PY='$(abspath $(topsrcdir)/config/nsinstall.py)'
DEFAULT_GMAKE_FLAGS += NSINSTALL='$$(PYTHON) $$(NSINSTALL_PY)'
else
DEFAULT_GMAKE_FLAGS += NSINSTALL='$(abspath $(NSINSTALL))'
endif
ifeq ($(OS_ARCH),WINNT)
DEFAULT_GMAKE_FLAGS += INSTALL='$$(NSINSTALL) -t'
endif
DEFAULT_GMAKE_FLAGS += $(EXTRA_GMAKE_FLAGS)
$(addprefix libs-,$(NSS_DIRS)): libs-%:
# Work around NSS's export rule being racy when recursing for private_export
# See bug #836220.
$(addprefix export-,$(NSS_DIRS)): EXTRA_GMAKE_FLAGS = PRIVATE_EXPORTS=
$(addprefix export-,$(NSS_DIRS)): export-%: private_export-%
$(addprefix private_export-,$(NSS_DIRS)): EXTRA_GMAKE_FLAGS =
$(addprefix private_export-,$(NSS_DIRS)): private_export-%:
$(foreach p,libs export private_export,$(addprefix $(p)-,$(NSS_DIRS))):
$(DEFAULT_GMAKE_ENV) $(MAKE) -C $(NSS_SRCDIR)/security/$* $(@:-$*=) $(DEFAULT_GMAKE_FLAGS)
export:: $(addprefix export-,$(NSS_DIRS))
$(addprefix clean-,$(NSS_DIRS)): clean-%:
$(MAKE) -C $(NSS_SRCDIR)/security/$* $(DEFAULT_GMAKE_FLAGS) clean
clean clobber clobber_all realclean distclean depend:: $(addprefix clean-,$(NSS_DIRS))
NSS_CMD_TARGETS := $(addprefix libs-,$(filter-out nss/cmd/lib,$(filter nss/cmd/%,$(NSS_DIRS))))
target:: $(NSS_CMD_TARGETS)
ifdef MOZ_FOLD_LIBS
$(NSS_CMD_TARGETS): $(addprefix $(DIST)/lib/$(IMPORT_PREFIX),$(addsuffix $(IMPORT_SUFFIX),$(NSS_LIBS)))
libs-nss/cmd/modutil: libs-nss/lib/jar
ifeq (WINNT,$(OS_TARGET))
libs-nss/cmd/modutil: libs-nss/lib/zlib
endif
$(NSS_CMD_TARGETS): libs-nss/cmd/lib
else
$(NSS_CMD_TARGETS): libs-nss/lib libs-nss/cmd/lib
endif # MOZ_FOLD_LIBS
# Work around NSS build system race condition creating certdata.c in
# security/nss/lib/ckfw/builtins. See bug #836220.
libs-nss/lib$(if $(MOZ_FOLD_LIBS),/ckfw): $(call mkdir_deps,$(DEPTH)/security/nss/lib/ckfw/builtins)
endif

20
config/external/nss/crmf/moz.build поставляемый
Просмотреть файл

@ -1,20 +0,0 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
Library('crmf')
if CONFIG['MOZ_SYSTEM_NSS']:
OS_LIBS += [l for l in CONFIG['NSS_LIBS'] if l.startswith('-L')]
OS_LIBS += ['-lcrmf']
else:
USE_LIBS += [
# The dependency on nss is not real, but is required to force the
# parent directory being built before this one. This has no
# practical effect on linkage, since the only thing linking crmf
# will need nss anyways.
'nss',
'static:/security/nss/lib/crmf/crmf',
]

42
config/external/nss/moz.build поставляемый
Просмотреть файл

@ -1,42 +0,0 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DIRS += ['crmf']
if CONFIG['MOZ_SYSTEM_NSS']:
Library('nss')
OS_LIBS += CONFIG['NSS_LIBS']
elif CONFIG['MOZ_FOLD_LIBS']:
GeckoSharedLibrary('nss', linkage=None)
# TODO: The library name can be changed when bug 845217 is fixed.
SHARED_LIBRARY_NAME = 'nss3'
SDK_LIBRARY = True
USE_LIBS += [
'nspr4',
'plc4',
'plds4',
]
OS_LIBS += CONFIG['REALTIME_LIBS']
SYMBOLS_FILE = 'nss.symbols'
else:
Library('nss')
USE_LIBS += [
'/security/nss/lib/nss/nss3',
'/security/nss/lib/smime/smime3',
'/security/nss/lib/ssl/ssl3',
'/security/nss/lib/util/nssutil3',
'sqlite',
]
# XXX: We should fix these warnings.
ALLOW_COMPILER_WARNINGS = True
if CONFIG['NSS_EXTRA_SYMBOLS_FILE']:
DEFINES['NSS_EXTRA_SYMBOLS_FILE'] = CONFIG['NSS_EXTRA_SYMBOLS_FILE']

27
config/external/nss/nss.mk поставляемый
Просмотреть файл

@ -1,27 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/config.mk
dirs :=
define add_dirs
SHARED_LIBRARY_DIRS :=
include $(topsrcdir)/security/$(1)/config.mk
dirs += $$(addprefix $(1)/,$$(SHARED_LIBRARY_DIRS)) $(1)
endef
$(foreach dir,util nss ssl smime,$(eval $(call add_dirs,nss/lib/$(dir))))
libs :=
define add_lib
LIBRARY_NAME :=
include $(topsrcdir)/security/$(1)/manifest.mn
libs += $$(addprefix $(1)/,$(LIB_PREFIX)$$(LIBRARY_NAME).$(LIB_SUFFIX))
endef
$(foreach dir,$(dirs),$(eval $(call add_lib,$(dir))))
echo-variable-%:
@echo $($*)

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

@ -165,16 +165,13 @@ ifeq ($(MOZ_WIDGET_TOOLKIT),gtk3)
toolkit/library/target: widget/gtk/mozgtk/gtk3/target
endif
ifdef MOZ_LDAP_XPCOM
ldap/target: config/external/nss/target mozglue/build/target
ldap/target: security/target mozglue/build/target
toolkit/library/target: ldap/target
endif
ifeq ($(MOZ_REPLACE_MALLOC_LINKAGE),dummy library)
mozglue/build/target memory/replace/logalloc/replay/target: memory/replace/dummy/target
endif
endif
ifeq (,$(MOZ_SYSTEM_NSPR)$(MOZ_SYSTEM_NSS)$(MOZ_FOLD_LIBS))
config/external/nss/target: config/external/nspr/pr/target config/external/nspr/ds/target config/external/nspr/libc/target
endif
# Most things are built during compile (target/host), but some things happen during export
# Those need to depend on config/export for system wrappers.
$(addprefix build/unix/stdc++compat/,target host) build/clang-plugin/target: config/export

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

@ -32,8 +32,6 @@
<!ENTITY runtimeMenu_accesskey "R">
<!ENTITY runtimeMenu_disconnect_label "Disconnect">
<!ENTITY runtimeMenu_disconnect_accesskey "D">
<!ENTITY runtimeMenu_showPermissionTable_label "Permissions Table">
<!ENTITY runtimeMenu_showPermissionTable_accesskey "P">
<!ENTITY runtimeMenu_takeScreenshot_label "Screenshot">
<!ENTITY runtimeMenu_takeScreenshot_accesskey "S">
<!ENTITY runtimeMenu_showDetails_label "Runtime Info">
@ -141,10 +139,6 @@
<!ENTITY prefs_options_autosavefiles "Autosave files">
<!ENTITY prefs_options_autosavefiles_tooltip "Automatically save edited files before running project">
<!-- Permissions Table -->
<!ENTITY permissionstable_title "Permissions Table">
<!ENTITY permissionstable_name_header "Name">
<!-- Runtime Details -->
<!ENTITY runtimedetails_title "Runtime Info">
<!ENTITY runtimedetails_adbIsRoot "ADB is root: ">

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

@ -0,0 +1,29 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* globals NetMonitorView */
"use strict";
const { DOM } = require("devtools/client/shared/vendor/react");
const { L10N } = require("../l10n");
const { button } = DOM;
/*
* Clear button component
* A type of tool button is responsible for cleaning network requests.
*/
function ClearButton() {
return button({
id: "requests-menu-clear-button",
className: "devtools-button devtools-clear-icon",
title: L10N.getStr("netmonitor.toolbar.clear"),
onClick: () => {
NetMonitorView.RequestsMenu.clear();
},
});
}
module.exports = ClearButton;

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

@ -3,8 +3,10 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules(
'clear-button.js',
'filter-buttons.js',
'search-box.js',
'summary-button.js',
'toggle-button.js',
'toolbar.js',
)

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

@ -0,0 +1,37 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {
createFactory,
DOM,
} = require("devtools/client/shared/vendor/react");
const ClearButton = createFactory(require("./clear-button"));
const FilterButtons = createFactory(require("./filter-buttons"));
const SearchBox = createFactory(require("./search-box"));
const SummaryButton = createFactory(require("./summary-button"));
const ToggleButton = createFactory(require("./toggle-button"));
const { span } = DOM;
/*
* Network monitor toolbar component
* Toolbar contains a set of useful tools to control network requests
*/
function Toolbar() {
return span({ className: "devtools-toolbar devtools-toolbar-container" },
span({ className: "devtools-toolbar-group" },
ClearButton(),
FilterButtons()
),
span({ className: "devtools-toolbar-group" },
SummaryButton(),
SearchBox(),
ToggleButton()
)
);
}
module.exports = Toolbar;

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

@ -21,20 +21,8 @@
data-localization-bundle="devtools/client/locales/netmonitor.properties">
<vbox id="network-inspector-view" flex="1">
<hbox id="netmonitor-toolbar" class="devtools-toolbar">
<html:div xmlns="http://www.w3.org/1999/xhtml"
id="react-clear-button-hook"/>
<html:div xmlns="http://www.w3.org/1999/xhtml"
id="react-filter-buttons-hook"/>
<spacer id="requests-menu-spacer"
flex="1"/>
<html:div xmlns="http://www.w3.org/1999/xhtml"
id="react-summary-button-hook"/>
<html:div xmlns="http://www.w3.org/1999/xhtml"
id="react-search-box-hook"/>
<html:div xmlns="http://www.w3.org/1999/xhtml"
id="react-details-pane-toggle-hook"/>
</hbox>
<html:div xmlns="http://www.w3.org/1999/xhtml"
id="react-toolbar-hook"/>
<hbox id="network-table-and-sidebar"
class="devtools-responsive-container"
flex="1">

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

@ -10,9 +10,6 @@
add_task(function* () {
requestLongerTimeout(2);
let { getSummary } = require("devtools/client/netmonitor/selectors/index");
let { L10N } = require("devtools/client/netmonitor/l10n");
let { PluralForm } = require("devtools/shared/plural-form");
let { tab, monitor } = yield initNetMonitor(FILTERING_URL);
info("Starting test... ");
@ -20,6 +17,11 @@ add_task(function* () {
let { $, NetMonitorView, gStore } = monitor.panelWin;
let { RequestsMenu } = NetMonitorView;
let winRequire = monitor.panelWin.require;
let { getSummary } = winRequire("devtools/client/netmonitor/selectors/index");
let { L10N } = winRequire("devtools/client/netmonitor/l10n");
let { PluralForm } = winRequire("devtools/shared/plural-form");
RequestsMenu.lazyUpdate = false;
testStatus();

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

@ -2,21 +2,14 @@
* 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/. */
/* globals dumpn, $, NetMonitorView */
/* globals dumpn, $ */
"use strict";
const { createFactory, DOM } = require("devtools/client/shared/vendor/react");
const { createFactory } = require("devtools/client/shared/vendor/react");
const ReactDOM = require("devtools/client/shared/vendor/react-dom");
const Provider = createFactory(require("devtools/client/shared/vendor/react-redux").Provider);
const FilterButtons = createFactory(require("./components/filter-buttons"));
const ToggleButton = createFactory(require("./components/toggle-button"));
const SearchBox = createFactory(require("./components/search-box"));
const SummaryButton = createFactory(require("./components/summary-button"));
const { L10N } = require("./l10n");
// Shortcuts
const { button } = DOM;
const Toolbar = createFactory(require("./components/toolbar"));
/**
* Functions handling the toolbar view: expand/collapse button etc.
@ -27,63 +20,26 @@ function ToolbarView() {
ToolbarView.prototype = {
/**
* Initialization function, called when the debugger is started.
* Initialization function, called when the network monitor is started.
*/
initialize: function (store) {
dumpn("Initializing the ToolbarView");
this._clearContainerNode = $("#react-clear-button-hook");
this._filterContainerNode = $("#react-filter-buttons-hook");
this._summaryContainerNode = $("#react-summary-button-hook");
this._searchContainerNode = $("#react-search-box-hook");
this._toggleContainerNode = $("#react-details-pane-toggle-hook");
this._toolbarNode = $("#react-toolbar-hook");
// clear button
ReactDOM.render(button({
id: "requests-menu-clear-button",
className: "devtools-button devtools-clear-icon",
title: L10N.getStr("netmonitor.toolbar.clear"),
onClick: () => {
NetMonitorView.RequestsMenu.clear();
}
}), this._clearContainerNode);
// filter button
ReactDOM.render(Provider(
{ store },
FilterButtons()
), this._filterContainerNode);
// summary button
ReactDOM.render(Provider(
{ store },
SummaryButton()
), this._summaryContainerNode);
// search box
ReactDOM.render(Provider(
{ store },
SearchBox()
), this._searchContainerNode);
// details pane toggle button
ReactDOM.render(Provider(
{ store },
ToggleButton()
), this._toggleContainerNode);
Toolbar()
), this._toolbarNode);
},
/**
* Destruction function, called when the debugger is closed.
* Destruction function, called when the network monitor is closed.
*/
destroy: function () {
dumpn("Destroying the ToolbarView");
ReactDOM.unmountComponentAtNode(this._clearContainerNode);
ReactDOM.unmountComponentAtNode(this._filterContainerNode);
ReactDOM.unmountComponentAtNode(this._summaryContainerNode);
ReactDOM.unmountComponentAtNode(this._searchContainerNode);
ReactDOM.unmountComponentAtNode(this._toggleContainerNode);
ReactDOM.unmountComponentAtNode(this._toolbarNode);
}
};

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

@ -124,7 +124,7 @@ define(function (require, exports, module) {
items = [DOM.span({className: "length"}, isEmpty ? "" : object.length)];
brackets = needSpace(false);
} else {
let max = (mode == "short") ? 3 : 300;
let max = (mode == "short") ? 3 : 10;
items = this.arrayIterator(object, max);
brackets = needSpace(items.length > 0);
}

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

@ -123,7 +123,7 @@ define(function (require, exports, module) {
items = [span({className: "length"}, isEmpty ? "" : objectLength)];
brackets = needSpace(false);
} else {
let max = (mode == "short") ? 3 : 300;
let max = (mode == "short") ? 3 : 10;
items = this.arrayIterator(object, max);
brackets = needSpace(items.length > 0);
}

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

@ -146,7 +146,7 @@ define(function (require, exports, module) {
render: function () {
let object = this.props.object;
let props = this.safeEntriesIterator(object,
(this.props.mode == "long") ? 100 : 3);
(this.props.mode == "long") ? 10 : 3);
let objectLink = this.props.objectLink || span;
if (this.props.mode == "tiny") {

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

@ -197,7 +197,7 @@ define(function (require, exports, module) {
render: function () {
let object = this.props.object;
let props = this.safePropIterator(object,
(this.props.mode == "long") ? 100 : 3);
(this.props.mode == "long") ? 10 : 3);
let objectLink = this.props.objectLink || span;
if (this.props.mode == "tiny") {

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

@ -32,12 +32,13 @@ define(function (require, exports, module) {
},
getTitle: function (grip) {
const title = "#text";
if (this.props.objectLink) {
return this.props.objectLink({
object: grip
}, "#text ");
}, title);
}
return "";
return title;
},
render: function () {
@ -57,33 +58,17 @@ define(function (require, exports, module) {
});
}
if (mode == "short" || mode == "tiny") {
return (
DOM.span(baseConfig,
this.getTitle(grip),
DOM.span({className: "nodeValue"},
"\"" + this.getTextContent(grip) + "\""
)
)
);
if (mode == "tiny") {
return DOM.span(baseConfig, this.getTitle(grip));
}
let objectLink = this.props.objectLink || DOM.span;
return (
DOM.span(baseConfig,
this.getTitle(grip),
objectLink({
object: grip
}, "<"),
DOM.span({className: "nodeTag"}, "TextNode"),
" textContent=\"",
DOM.span({className: "nodeValue"},
this.getTextContent(grip)
),
"\"",
objectLink({
object: grip
}, ">;")
" ",
`"${this.getTextContent(grip)}"`
)
)
);
},

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

@ -26,7 +26,7 @@ window.onload = Task.async(function* () {
let componentUnderTest = ArrayRep;
const maxLength = {
short: 3,
long: 300
long: 10
};
try {
@ -222,14 +222,10 @@ window.onload = Task.async(function* () {
function testArray() {
let stub = [
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
"n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"
];
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];
const defaultOutput = `[ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j",` +
` "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",` +
` "u", "v", "w", "x", "y", "z" ]`;
const shortOutput = `[ "a", "b", "c", 23 more… ]`;
const defaultOutput = `[ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j" ]`;
const shortOutput = `[ "a", "b", "c", 7 more… ]`;
const modeTests = [
{
@ -238,7 +234,7 @@ window.onload = Task.async(function* () {
},
{
mode: "tiny",
expectedOutput: `[26]`,
expectedOutput: `[10]`,
},
{
mode: "short",

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

@ -23,7 +23,7 @@ window.onload = Task.async(function* () {
let componentUnderTest = GripArray;
const maxLength = {
short: 3,
long: 300
long: 10
};
try {

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

@ -174,8 +174,8 @@ window.onload = Task.async(function* () {
`Map { key-0: "value-0", key-1: "value-1", key-2: "value-2", 98 more… }`;
// Generate string with 101 entries, which is the max limit for 'long' mode.
let longString = Array.from({length: 100}).map((_, i) => `key-${i}: "value-${i}"`);
const longOutput = `Map { ${longString.join(", ")}, 1 more… }`;
let longString = Array.from({length: 10}).map((_, i) => `key-${i}: "value-${i}"`);
const longOutput = `Map { ${longString.join(", ")}, 91 more… }`;
const modeTests = [
{

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