Compare commits

...
Author SHA1 Message Date
Jan de Mooij e28170c980 [js] Handle functions with rest parameters in isObservableArgumentSlot. 2020-04-08 08:53:39 +02:00
wolfbeast 0507f298e9 [Docshell] Ensure nsDocShell::mContentViewer is released properly. 2020-04-08 08:53:25 +02:00
wolfbeast d9c31941e7 Issue #1505 - Rebuild application version string
To respond dynamically to the pref change, the mAppVersion string needs
to be rebuilt.
Includes some minor improvements for corner cases and removes leftover
b2g junk.
2020-04-05 12:15:10 +02:00
wolfbeast 2c2d82d310 Issue #1507 - Remove nsRefreshDriver's use of high res system timers.
Since we are using vsync for timing anyway in the layout refresh driver,
there is no need to bump the system timer resolution down to 1 ms.

This resolves #1507.
2020-04-05 12:14:36 +02:00
wolfbeast 781bcc3a2e Issue #1508 - Redirect moz://a to http://thereisonlyxul.org/ 2020-04-05 12:14:14 +02:00
JustOff 2b6598bbb1 Issue #65 - Fix unprocessed directives in WebRequest.jsm 2020-04-05 12:13:13 +02:00
Matt A. Tobin 094bc0a678 Issue #1499 - Re-import ExtensionStorage.jsm 2020-03-27 14:16:28 +01:00
wolfbeast a731633d7b Revert "Issue #1473 - Add %OS_SLICE% macro to SSUAO to refine OS info"
This reverts commit 3c8bc3da7c.
2020-03-24 21:12:24 +01:00
wolfbeast cd2ffb4b8f Revert "Issue #1482 - Give dynamic SSUAO rules priority over static ones"
This reverts commit a20f208834.
2020-03-24 21:11:53 +01:00
Brian Smith df9ab936f2 Issue #1491 - Part 2: Disable a workaround on macOS 10.14+ for an Apple bug described in Mozilla bug 378645 involving popup windows that was fixed by Apple. 2020-03-22 14:44:22 +01:00
Brian Smith 8c7ca10cfe Issue #1491 - Part 1: Update nsCocoaFeatures for newer versions of MacOS X. 2020-03-22 14:44:09 +01:00
wolfbeast 0a5ad190c3 [devtools] Properly escape method arguments for curl. 2020-03-19 07:55:33 +01:00
wolfbeast 97b0520d7b Revert "Issue #1445 - Clarify the status of extensions in the Add-On manager"
This reverts commit f107de8a90.
2020-03-19 06:36:18 +01:00
wolfbeast b33a151836 Revert "Issue #1446 - Only allow extension add-on types for Firefox compat mode."
This reverts commit e8417acbff.
2020-03-19 06:36:03 +01:00
wolfbeast 32ca14f34b Revert "Issue #1446 - Only match extension add-on types for target applications."
This reverts commit 4889e6dbbd.
2020-03-19 06:35:47 +01:00
wolfbeast 0da8e0b496 Revert "Issue #1445 - Use the detailed string also in the list entries."
This reverts commit ac68f8cf6c.
2020-03-19 06:35:22 +01:00
wolfbeast 473e75d5aa Revert "Issue #1445 - remove redundant nativeIndicator"
This reverts commit 2073a7f1c9.
2020-03-19 06:34:46 +01:00
wolfbeast 28613ba836 Revert "Issue #1445 - Add a link to details on using Firefox extensions in Pale Moon"
This reverts commit c220c30bbb.
2020-03-19 06:34:28 +01:00
wolfbeast 8a5b121489 Revert "Issue #1445 - strings cleanup"
This reverts commit 461a9e86b2.
2020-03-19 06:34:02 +01:00
32 changed files with 413 additions and 268 deletions

No files matched your search

+25 -13
View File
@@ -58,9 +58,21 @@ const Curl = {
* A cURL command.
*/
generateCommand: function (data) {
let utils = CurlUtils;
const utils = CurlUtils;
let command = ["curl"];
// Make sure to use the following helpers to sanitize arguments before execution.
const addParam = value => {
const safe = /^[a-zA-Z-]+$/.test(value) ? value : escapeString(value);
command.push(safe);
};
const addPostData = value => {
const safe = /^[a-zA-Z-]+$/.test(value) ? value : escapeString(value);
postData.push(safe);
};
let ignoredHeaders = new Set();
// The cURL command is expected to run on the same platform that Firefox runs
@@ -69,7 +81,7 @@ const Curl = {
utils.escapeStringWin : utils.escapeStringPosix;
// Add URL.
command.push(escapeString(data.url));
addParam(data.url);
let postDataText = null;
let multipartRequest = utils.isMultipartRequest(data);
@@ -79,15 +91,15 @@ const Curl = {
if (utils.isUrlEncodedRequest(data) ||
["PUT", "POST", "PATCH"].includes(data.method)) {
postDataText = data.postDataText;
postData.push("--data");
postData.push(escapeString(utils.writePostDataTextParams(postDataText)));
addPostData("--data");
addPostData(utils.writePostDataTextParams(postDataText));
ignoredHeaders.add("content-length");
} else if (multipartRequest) {
postDataText = data.postDataText;
postData.push("--data-binary");
addPostData("--data-binary");
let boundary = utils.getMultipartBoundary(data);
let text = utils.removeBinaryDataFromMultipartText(postDataText, boundary);
postData.push(escapeString(text));
addPostData(text);
ignoredHeaders.add("content-length");
}
@@ -95,15 +107,15 @@ const Curl = {
// For GET and POST requests this is not necessary as GET is the
// default. If --data or --binary is added POST is the default.
if (!(data.method == "GET" || data.method == "POST")) {
command.push("-X");
command.push(data.method);
addParam("-X");
addParam(data.method);
}
// Add -I (HEAD)
// For servers that supports HEAD.
// This will fetch the header of a document only.
if (data.method == "HEAD") {
command.push("-I");
addParam("-I");
}
// Add http version.
@@ -114,7 +126,7 @@ const Curl = {
// data.httpVersion are HTTP/1.0, HTTP/1.1 and HTTP/2.0
// So in case of HTTP/2.0 (which should ideally be HTTP/2) we are using
// only major version, and full version in other cases
command.push("--http" + (version == "2.0" ? version.split(".")[0] : version));
addParam("--http" + (version == "2.0" ? version.split(".")[0] : version));
}
// Add request headers.
@@ -126,14 +138,14 @@ const Curl = {
for (let i = 0; i < headers.length; i++) {
let header = headers[i];
if (header.name.toLowerCase() === "accept-encoding") {
command.push("--compressed");
addParam("--compressed");
continue;
}
if (ignoredHeaders.has(header.name.toLowerCase())) {
continue;
}
command.push("-H");
command.push(escapeString(header.name + ": " + header.value));
addParam("-H");
addParam(header.name + ": " + header.value);
}
// Add post data.
+6
View File
@@ -860,6 +860,12 @@ nsDocShell::~nsDocShell()
shPrivate->SetRootDocShell(nullptr);
}
if (mContentViewer) {
mContentViewer->Close(nullptr);
mContentViewer->Destroy();
mContentViewer = nullptr;
}
if (--gDocShellCount == 0) {
NS_IF_RELEASE(sURIFixup);
}
+1 -1
View File
@@ -487,7 +487,7 @@ class CompileInfo
// Function.arguments can be used to access all arguments in non-strict
// scripts, so we can't optimize out any arguments.
if ((hasArguments() || !script()->strict()) &&
if ((mayReadFrameArgsDirectly_ || !script()->strict()) &&
firstArgSlot() <= slot && slot - firstArgSlot() < nargs())
{
return true;
-98
View File
@@ -851,12 +851,6 @@ NS_IMPL_ISUPPORTS(VsyncChildCreateCallback, nsIIPCBackgroundChildCreateCallback)
static StaticRefPtr<RefreshDriverTimer> sRegularRateTimer;
static StaticRefPtr<InactiveRefreshDriverTimer> sThrottledRateTimer;
#ifdef XP_WIN
static int32_t sHighPrecisionTimerRequests = 0;
// a bare pointer to avoid introducing a static constructor
static nsITimer *sDisableHighPrecisionTimersTimer = nullptr;
#endif
static void
CreateContentVsyncRefreshTimer(void*)
{
@@ -934,16 +928,6 @@ nsRefreshDriver::Shutdown()
sRegularRateTimer = nullptr;
sThrottledRateTimer = nullptr;
#ifdef XP_WIN
if (sDisableHighPrecisionTimersTimer) {
sDisableHighPrecisionTimersTimer->Cancel();
NS_RELEASE(sDisableHighPrecisionTimersTimer);
timeEndPeriod(1);
} else if (sHighPrecisionTimerRequests) {
timeEndPeriod(1);
}
#endif
}
/* static */ int32_t
@@ -1062,7 +1046,6 @@ nsRefreshDriver::nsRefreshDriver(nsPresContext* aPresContext)
mNeedToRecomputeVisibility(false),
mTestControllingRefreshes(false),
mViewManagerFlushIsPending(false),
mRequestedHighPrecision(false),
mInRefresh(false),
mWaitingForTransaction(false),
mSkippedPaints(false),
@@ -1300,83 +1283,6 @@ nsRefreshDriver::StopTimer()
mActiveTimer->RemoveRefreshDriver(this);
mActiveTimer = nullptr;
if (mRequestedHighPrecision) {
SetHighPrecisionTimersEnabled(false);
}
}
#ifdef XP_WIN
static void
DisableHighPrecisionTimersCallback(nsITimer *aTimer, void *aClosure)
{
timeEndPeriod(1);
NS_RELEASE(sDisableHighPrecisionTimersTimer);
}
#endif
void
nsRefreshDriver::ConfigureHighPrecision()
{
bool haveUnthrottledFrameRequestCallbacks =
mFrameRequestCallbackDocs.Length() > 0;
// if the only change that's needed is that we need high precision,
// then just set that
if (!mThrottled && !mRequestedHighPrecision &&
haveUnthrottledFrameRequestCallbacks) {
SetHighPrecisionTimersEnabled(true);
} else if (mRequestedHighPrecision && !haveUnthrottledFrameRequestCallbacks) {
SetHighPrecisionTimersEnabled(false);
}
}
void
nsRefreshDriver::SetHighPrecisionTimersEnabled(bool aEnable)
{
LOG("[%p] SetHighPrecisionTimersEnabled (%s)", this, aEnable ? "true" : "false");
if (aEnable) {
NS_ASSERTION(!mRequestedHighPrecision, "SetHighPrecisionTimersEnabled(true) called when already requested!");
#ifdef XP_WIN
if (++sHighPrecisionTimerRequests == 1) {
// If we had a timer scheduled to disable it, that means that it's already
// enabled; just cancel the timer. Otherwise, really enable it.
if (sDisableHighPrecisionTimersTimer) {
sDisableHighPrecisionTimersTimer->Cancel();
NS_RELEASE(sDisableHighPrecisionTimersTimer);
} else {
timeBeginPeriod(1);
}
}
#endif
mRequestedHighPrecision = true;
} else {
NS_ASSERTION(mRequestedHighPrecision, "SetHighPrecisionTimersEnabled(false) called when not requested!");
#ifdef XP_WIN
if (--sHighPrecisionTimerRequests == 0) {
// Don't jerk us around between high precision and low precision
// timers; instead, only allow leaving high precision timers
// after 90 seconds. This is arbitrary, but hopefully good
// enough.
NS_ASSERTION(!sDisableHighPrecisionTimersTimer, "We shouldn't have an outstanding disable-high-precision timer !");
nsCOMPtr<nsITimer> timer = do_CreateInstance(NS_TIMER_CONTRACTID);
if (timer) {
timer.forget(&sDisableHighPrecisionTimersTimer);
sDisableHighPrecisionTimersTimer->InitWithFuncCallback(DisableHighPrecisionTimersCallback,
nullptr,
90 * 1000,
nsITimer::TYPE_ONE_SHOT);
} else {
// might happen if we're shutting down XPCOM; just drop the time period down
// immediately
timeEndPeriod(1);
}
}
#endif
mRequestedHighPrecision = false;
}
}
uint32_t
@@ -1993,8 +1899,6 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime)
observer->DidRefresh();
}
ConfigureHighPrecision();
NS_ASSERTION(mInRefresh, "Still in refresh");
if (mPresContext->IsRoot() && XRE_IsContentProcess() && gfxPrefs::AlwaysPaint()) {
@@ -2247,7 +2151,6 @@ nsRefreshDriver::ScheduleFrameRequestCallbacks(nsIDocument* aDocument)
}
// make sure that the timer is running
ConfigureHighPrecision();
EnsureTimerStarted();
}
@@ -2256,7 +2159,6 @@ nsRefreshDriver::RevokeFrameRequestCallbacks(nsIDocument* aDocument)
{
mFrameRequestCallbackDocs.RemoveElement(aDocument);
mThrottledFrameRequestCallbackDocs.RemoveElement(aDocument);
ConfigureHighPrecision();
// No need to worry about restarting our timer in slack mode if it's already
// running; that will happen automatically when it fires.
}
-5
View File
@@ -450,7 +450,6 @@ private:
bool mNeedToRecomputeVisibility;
bool mTestControllingRefreshes;
bool mViewManagerFlushIsPending;
bool mRequestedHighPrecision;
bool mInRefresh;
// True if the refresh driver is suspended waiting for transaction
@@ -502,10 +501,6 @@ private:
friend class mozilla::RefreshDriverTimer;
// turn on or turn off high precision based on various factors
void ConfigureHighPrecision();
void SetHighPrecisionTimersEnabled(bool aEnable);
static void Shutdown();
// `true` if we are currently in jank-critical mode.
+7 -22
View File
@@ -18,9 +18,6 @@ const PREF_OVERRIDES_ENABLED = "general.useragent.site_specific_overrides";
const DEFAULT_UA = Cc["@mozilla.org/network/protocol;1?name=http"]
.getService(Ci.nsIHttpProtocolHandler)
.userAgent;
const OS_SLICE = Cc["@mozilla.org/network/protocol;1?name=http"]
.getService(Ci.nsIHttpProtocolHandler)
.oscpu + ";";
const MAX_OVERRIDE_FOR_HOST_CACHE_SIZE = 250;
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
@@ -30,7 +27,6 @@ XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
var gPrefBranch;
var gOverrides = new Map;
var gUpdatedOverrides;
var gOldDynOverrides;
var gOverrideForHostCache = new Map;
var gInitialized = false;
var gOverrideFunctions = [
@@ -56,10 +52,7 @@ this.UserAgentOverrides = {
}
UserAgentUpdates.init(function(overrides) {
if (overrides == gOldDynOverrides) {
return;
}
gOldDynOverrides = overrides;
gOverrideForHostCache.clear();
if (overrides) {
for (let domain in overrides) {
overrides[domain] = getUserAgentFromOverride(overrides[domain]);
@@ -67,7 +60,6 @@ this.UserAgentOverrides = {
overrides.get = function(key) { return this[key]; };
}
gUpdatedOverrides = overrides;
buildOverrides();
});
buildOverrides();
@@ -151,7 +143,7 @@ function getUserAgentFromOverride(override)
if (search && replace) {
userAgent = DEFAULT_UA.replace(new RegExp(search, "g"), replace);
} else {
userAgent = override.replace(/%OS_SLICE%/g, OS_SLICE);
userAgent = override;
}
gBuiltUAs.set(override, userAgent);
return userAgent;
@@ -164,22 +156,15 @@ function buildOverrides() {
if (!Services.prefs.getBoolPref(PREF_OVERRIDES_ENABLED))
return;
let builtUAs = new Map;
let domains = gPrefBranch.getChildList("");
// Since the static override map has the highest priority, we build it so
// that it includes only domains with user-set overrides and domains with
// default pre-set overrides that are not overridden by dynamic updates.
for (let domain of domains) {
if (!(gUpdatedOverrides && gUpdatedOverrides.get(domain)) ||
gPrefBranch.prefHasUserValue(domain)) {
// Here we selected domains that are not dynamically overridden
// or have a user-set override.
let override = gPrefBranch.getCharPref(domain);
let userAgent = getUserAgentFromOverride(override);
let override = gPrefBranch.getCharPref(domain);
let userAgent = getUserAgentFromOverride(override);
if (userAgent != DEFAULT_UA) {
gOverrides.set(domain, userAgent);
}
if (userAgent != DEFAULT_UA) {
gOverrides.set(domain, userAgent);
}
}
}
+45 -37
View File
@@ -310,28 +310,9 @@ nsHttpHandler::Init()
}
mAppName.StripChars(R"( ()<>@,;:\"/[]?={})");
}
nsCString dynamicBuildID;
if (appInfo) {
appInfo->GetPlatformBuildID(dynamicBuildID);
if (dynamicBuildID.Length() > 8 )
dynamicBuildID.Left(dynamicBuildID, 8);
}
if (mAppVersionIsBuildID) {
// Override BuildID
mAppVersion.AssignLiteral(MOZ_UA_BUILDID);
} else if (appInfo) {
appInfo->GetVersion(mAppVersion);
} else {
// Fall back to platform if appInfo is unavailable
mAppVersion.AssignLiteral(MOZILLA_UAVERSION);
}
BuildAppVersion();
// If there's no override set, set it to the dynamic BuildID
if (mAppVersion.IsEmpty())
mAppVersion.Assign(dynamicBuildID);
mSessionStartTime = NowInSeconds();
mHandlerActive = true;
@@ -350,8 +331,15 @@ nsHttpHandler::Init()
// Goanna slice version
mProductSub.AssignLiteral(MOZILLA_UAVERSION);
if (mProductSub.IsEmpty())
mProductSub.Assign(dynamicBuildID);
if (mProductSub.IsEmpty()) {
nsCString dynamicBuildID;
if (appInfo) {
appInfo->GetPlatformBuildID(dynamicBuildID);
if (dynamicBuildID.Length() > 8 )
dynamicBuildID.Left(dynamicBuildID, 8);
}
mProductSub.Assign(dynamicBuildID);
}
#if DEBUG
// dump user agent prefs
@@ -657,6 +645,37 @@ nsHttpHandler::GenerateHostPort(const nsCString& host, int32_t port,
// nsHttpHandler <private>
//-----------------------------------------------------------------------------
void
nsHttpHandler::BuildAppVersion()
{
nsCOMPtr<nsIXULAppInfo> appInfo = do_GetService("@mozilla.org/xre/app-info;1");
nsCString dynamicBuildID;
if (appInfo) {
appInfo->GetPlatformBuildID(dynamicBuildID);
if (dynamicBuildID.Length() > 8 )
dynamicBuildID.Left(dynamicBuildID, 8);
}
if (mAppVersionIsBuildID) {
// Override BuildID
mAppVersion.Assign(dynamicBuildID);
} else if (appInfo) {
appInfo->GetVersion(mAppVersion);
} else {
// Fall back to platform if appInfo is unavailable
mAppVersion.AssignLiteral(MOZILLA_UAVERSION);
}
// If there's still no version set, set it to a fixed BuildID
if (mAppVersion.IsEmpty()) {
mAppVersion.AssignLiteral(MOZ_UA_BUILDID);
}
if (mAppVersion.IsEmpty()) {
mAppVersion.AssignLiteral("20200101");
}
}
const nsAFlatCString &
nsHttpHandler::UserAgent()
{
@@ -782,21 +801,6 @@ nsHttpHandler::InitUserAgentComponents()
);
#endif
#ifdef MOZ_MULET
{
// Add the `Mobile` or `Tablet` or `TV` token when running in the b2g
// desktop simulator via preference.
nsCString deviceType;
nsresult rv = Preferences::GetCString("devtools.useragent.device_type", &deviceType);
if (NS_SUCCEEDED(rv)) {
mCompatDevice.Assign(deviceType);
} else {
mCompatDevice.AssignLiteral("Mobile");
}
}
#endif // MOZ_MULET
#ifndef MOZ_UA_OS_AGNOSTIC
// Gather OS/CPU.
#if defined(XP_WIN)
@@ -924,6 +928,10 @@ nsHttpHandler::PrefsChanged(nsIPrefBranch *prefs, const char *pref)
if (PREF_CHANGED(UA_PREF("appVersionIsBuildID"))) {
rv = prefs->GetBoolPref(UA_PREF("appVersionIsBuildID"), &cVar);
mAppVersionIsBuildID = (NS_SUCCEEDED(rv) && cVar);
// Rebuild application version string.
BuildAppVersion();
mUserAgentIsDirty = true;
}
+1
View File
@@ -391,6 +391,7 @@ private:
//
// Useragent/prefs helper methods
//
void BuildAppVersion();
void BuildUserAgent();
void InitUserAgentComponents();
void PrefsChanged(nsIPrefBranch *prefs, const char *pref);
@@ -11,7 +11,7 @@ Cu.import("resource://gre/modules/NetUtil.jsm");
function mozProtocolHandler() {
XPCOMUtils.defineLazyPreferenceGetter(this, "urlToLoad", "toolkit.mozprotocol.url",
"https://www.mozilla.org/protocol");
"http://thereisonlyxul.org/");
}
mozProtocolHandler.prototype = {
@@ -211,6 +211,9 @@
<!ENTITY addon.loadingReleaseNotes.label "Loading…">
<!ENTITY addon.errorLoadingReleaseNotes.label "Sorry, but there was an error loading the release notes.">
<!ENTITY addon.nativeAddon "This add-on directly targets &brandFullName;">
<!ENTITY addon.compatAddon "This add-on targets Mozilla Firefox and runs in compatibility mode">
<!ENTITY addon.createdBy.label "By ">
<!ENTITY eula.title "End-User License Agreement">
@@ -30,9 +30,6 @@ notification.blocked.link=More Information
#LOCALIZATION NOTE (notification.softblocked) %1$S is the add-on name
notification.softblocked=%1$S is known to cause issues.
notification.softblocked.link=More Information
#LOCALIZATION NOTE (notification.compatibility) %1$S is the add-on name, %2$S is brand name
notification.compatibility=%1$S was not designed for %2$S. It may not function properly or cease to function.
notification.compatibility.link=More Information
#LOCALIZATION NOTE (notification.outdated) %1$S is the add-on name
notification.outdated=An important update is available for %1$S.
notification.outdated.link=Update Now
@@ -81,9 +78,6 @@ details.notification.incompatible=%1$S is incompatible with %2$S %3$S.
#LOCALIZATION NOTE (details.notification.blocked) %1$S is the add-on name
details.notification.blocked=%1$S has been disabled due to security or stability issues.
details.notification.blocked.link=More Information
#LOCALIZATION NOTE (details.notification.compatibility) %1$S is the add-on name, %2$S is brand name
details.notification.compatibility=%1$S was not designed for %2$S. It may not function properly or cease to function.
details.notification.compatibility.link=More Information
#LOCALIZATION NOTE (details.notification.softblocked) %1$S is the add-on name
details.notification.softblocked=%1$S is known to cause issues.
details.notification.softblocked.link=More Information
+241
View File
@@ -0,0 +1,241 @@
/* 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";
this.EXPORTED_SYMBOLS = ["ExtensionStorage"];
const Ci = Components.interfaces;
const Cc = Components.classes;
const Cu = Components.utils;
const Cr = Components.results;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "OS",
"resource://gre/modules/osfile.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AsyncShutdown",
"resource://gre/modules/AsyncShutdown.jsm");
function jsonReplacer(key, value) {
switch (typeof(value)) {
// Serialize primitive types as-is.
case "string":
case "number":
case "boolean":
return value;
case "object":
if (value === null) {
return value;
}
switch (Cu.getClassName(value, true)) {
// Serialize arrays and ordinary objects as-is.
case "Array":
case "Object":
return value;
// Serialize Date objects and regular expressions as their
// string representations.
case "Date":
case "RegExp":
return String(value);
}
break;
}
if (!key) {
// If this is the root object, and we can't serialize it, serialize
// the value to an empty object.
return {};
}
// Everything else, omit entirely.
return undefined;
}
this.ExtensionStorage = {
cache: new Map(),
listeners: new Map(),
/**
* Sanitizes the given value, and returns a JSON-compatible
* representation of it, based on the privileges of the given global.
*
* @param {value} value
* The value to sanitize.
* @param {Context} context
* The extension context in which to sanitize the value
* @returns {value}
* The sanitized value.
*/
sanitize(value, context) {
let json = context.jsonStringify(value, jsonReplacer);
return JSON.parse(json);
},
getExtensionDir(extensionId) {
return OS.Path.join(this.extensionDir, extensionId);
},
getStorageFile(extensionId) {
return OS.Path.join(this.extensionDir, extensionId, "storage.js");
},
read(extensionId) {
if (this.cache.has(extensionId)) {
return this.cache.get(extensionId);
}
let path = this.getStorageFile(extensionId);
let decoder = new TextDecoder();
let promise = OS.File.read(path);
promise = promise.then(array => {
return JSON.parse(decoder.decode(array));
}).catch((error) => {
if (!error.becauseNoSuchFile) {
Cu.reportError("Unable to parse JSON data for extension storage.");
}
return {};
});
this.cache.set(extensionId, promise);
return promise;
},
write(extensionId) {
let promise = this.read(extensionId).then(extData => {
let encoder = new TextEncoder();
let array = encoder.encode(JSON.stringify(extData));
let path = this.getStorageFile(extensionId);
OS.File.makeDir(this.getExtensionDir(extensionId), {
ignoreExisting: true,
from: OS.Constants.Path.profileDir,
});
let promise = OS.File.writeAtomic(path, array);
return promise;
}).catch(() => {
// Make sure this promise is never rejected.
Cu.reportError("Unable to write JSON data for extension storage.");
});
AsyncShutdown.profileBeforeChange.addBlocker(
"ExtensionStorage: Finish writing extension data",
promise);
return promise.then(() => {
AsyncShutdown.profileBeforeChange.removeBlocker(promise);
});
},
set(extensionId, items, context) {
return this.read(extensionId).then(extData => {
let changes = {};
for (let prop in items) {
let item = this.sanitize(items[prop], context);
changes[prop] = {oldValue: extData[prop], newValue: item};
extData[prop] = item;
}
this.notifyListeners(extensionId, changes);
return this.write(extensionId);
});
},
remove(extensionId, items) {
return this.read(extensionId).then(extData => {
let changes = {};
for (let prop of [].concat(items)) {
changes[prop] = {oldValue: extData[prop]};
delete extData[prop];
}
this.notifyListeners(extensionId, changes);
return this.write(extensionId);
});
},
clear(extensionId) {
return this.read(extensionId).then(extData => {
let changes = {};
for (let prop of Object.keys(extData)) {
changes[prop] = {oldValue: extData[prop]};
delete extData[prop];
}
this.notifyListeners(extensionId, changes);
return this.write(extensionId);
});
},
get(extensionId, keys) {
return this.read(extensionId).then(extData => {
let result = {};
if (keys === null) {
Object.assign(result, extData);
} else if (typeof(keys) == "object" && !Array.isArray(keys)) {
for (let prop in keys) {
if (prop in extData) {
result[prop] = extData[prop];
} else {
result[prop] = keys[prop];
}
}
} else {
for (let prop of [].concat(keys)) {
if (prop in extData) {
result[prop] = extData[prop];
}
}
}
return result;
});
},
addOnChangedListener(extensionId, listener) {
let listeners = this.listeners.get(extensionId) || new Set();
listeners.add(listener);
this.listeners.set(extensionId, listeners);
},
removeOnChangedListener(extensionId, listener) {
let listeners = this.listeners.get(extensionId);
listeners.delete(listener);
},
notifyListeners(extensionId, changes) {
let listeners = this.listeners.get(extensionId);
if (listeners) {
for (let listener of listeners) {
listener(changes);
}
}
},
init() {
if (Services.appinfo.processType != Services.appinfo.PROCESS_TYPE_DEFAULT) {
return;
}
Services.obs.addObserver(this, "extension-invalidate-storage-cache", false);
Services.obs.addObserver(this, "xpcom-shutdown", false);
},
observe(subject, topic, data) {
if (topic == "xpcom-shutdown") {
Services.obs.removeObserver(this, "extension-invalidate-storage-cache");
Services.obs.removeObserver(this, "xpcom-shutdown");
} else if (topic == "extension-invalidate-storage-cache") {
this.cache.clear();
}
},
};
XPCOMUtils.defineLazyGetter(ExtensionStorage, "extensionDir",
() => OS.Path.join(OS.Constants.Path.profileDir, "browser-extension-data"));
ExtensionStorage.init();
+2 -1
View File
@@ -11,7 +11,6 @@ EXTRA_JS_MODULES += [
'addons/WebNavigation.jsm',
'addons/WebNavigationContent.js',
'addons/WebNavigationFrames.jsm',
'addons/WebRequest.jsm',
'addons/WebRequestCommon.jsm',
'addons/WebRequestContent.js',
'addons/WebRequestUpload.jsm',
@@ -29,6 +28,7 @@ EXTRA_JS_MODULES += [
'debug.js',
'DeferredTask.jsm',
'Deprecated.jsm',
'ExtensionStorage.jsm',
'FileUtils.jsm',
'Finder.jsm',
'FinderHighlighter.jsm',
@@ -84,6 +84,7 @@ EXTRA_JS_MODULES.third_party.jsesc += ['third_party/jsesc/jsesc.js']
EXTRA_JS_MODULES.sessionstore += ['sessionstore/Utils.jsm']
EXTRA_PP_JS_MODULES += [
'addons/WebRequest.jsm',
'NewTabUtils.jsm',
'ResetProfile.jsm',
'Troubleshoot.jsm',
@@ -152,6 +152,8 @@ setting[type="menulist"] {
.addon:not([notification="info"]) .info,
.addon:not([pending]) .pending,
.addon:not([upgrade="true"]) .update-postfix,
.addon:not([native="true"]) .nativeAddon,
.addon:not([native="false"]) .compatAddon,
.addon[active="true"] .disabled-postfix,
.addon[pending="install"] .update-postfix,
.addon[pending="install"] .disabled-postfix,
@@ -264,6 +266,21 @@ richlistitem:not([selected]) * {
display: none;
}
/* Indicator style for extension target application */
.addon[native] .nativeIndicator {
margin-left: 5pt;
padding-bottom: 1pt;
}
.addon[native][active="false"] .nativeIndicator {
opacity: 0.4;
}
.addon[native] .nativeAddon {
color: #3366FF;
}
.addon[native] .compatAddon {
color: #FF6600;
}
/* Translators for Language Pack details */
.translators > label {
-moz-margin-start: 0px;
@@ -3059,19 +3059,6 @@ var gDetailView = {
warning.textContent =
gStrings.ext.formatStringFromName("details.notification.gmpPending",
[this._addon.name], 1);
#ifdef MOZ_PHOENIX_EXTENSIONS
} else if (this._addon.native == false) {
this.node.setAttribute("notification", "warning");
this.node.setAttribute("native", "false");
document.getElementById("detail-warning").textContent = gStrings.ext.formatStringFromName(
"details.notification.compatibility",
[this._addon.name, gStrings.brandShortName], 2
);
var warningLink = document.getElementById("detail-warning-link");
warningLink.value = gStrings.ext.GetStringFromName("details.notification.compatibility.link");
warningLink.href = Services.urlFormatter.formatURLPref("extensions.compatibility.url");
warningLink.hidden = false;
#endif
} else {
this.node.removeAttribute("notification");
}
@@ -857,6 +857,10 @@
<xul:label anonid="name" class="name" crop="end" flex="1"
xbl:inherits="value=name,tooltiptext=name"/>
<xul:label anonid="version" class="version"/>
#ifdef MOZ_PHOENIX_EXTENSIONS
<xul:label class="nativeIndicator nativeAddon" value="●" tooltiptext="&addon.nativeAddon;"/>
<xul:label class="nativeIndicator compatAddon" value="●" tooltiptext="&addon.compatAddon;"/>
#endif
<xul:label class="disabled-postfix" value="&addon.disabled.postfix;"/>
<xul:label class="update-postfix" value="&addon.update.postfix;"/>
<xul:spacer flex="5000"/> <!-- Necessary to make the name crop -->
@@ -1355,20 +1359,8 @@
} else {
this.removeAttribute("notification");
#ifdef MOZ_PHOENIX_EXTENSIONS
if (this.mAddon.type == "extension") {
if (this.mAddon.type == "extension")
this.setAttribute("native", this.mAddon.native);
if (this.mAddon.native == false) {
this.setAttribute("notification", "warning");
this._warning.textContent = gStrings.ext.formatStringFromName(
"notification.compatibility",
[this.mAddon.name, gStrings.brandShortName], 2
);
this._warningLink.value = gStrings.ext.GetStringFromName("notification.compatibility.link");
this._warningLink.href = Services.urlFormatter.formatURLPref("extensions.compatibility.url");
this._warningLink.hidden = false;
this._warningBtn.hidden = true;
}
}
#endif
}
}
@@ -6472,8 +6472,8 @@ AddonInternal.prototype = {
}
else if (app.id == FIREFOX_ID) {
version = FIREFOX_APPCOMPATVERSION;
if (this.type != "extension")
//Only allow extensions in Firefox compatibility mode
if (this.type == "locale")
//Never allow language packs in Firefox compatibility mode
return false;
#endif
}
@@ -6528,15 +6528,12 @@ AddonInternal.prototype = {
app = targetApp;
}
#ifdef MOZ_PHOENIX_EXTENSIONS
// Special case: check for Firefox TargetApps. this has to be done AFTER
// the initial check to make sure appinfo.ID is preferred, even if
// Firefox is listed before it in the install manifest.
// Only do this for extensions. Other types should not be allowed.
if (this.type == "extension") {
for (let targetApp of this.targetApplications) {
if (targetApp.id == FIREFOX_ID) //Firefox GUID
return targetApp;
}
//Special case: check for Firefox TargetApps. this has to be done AFTER
//the initial check to make sure appinfo.ID is preferred, even if
//Firefox is listed before it in the install manifest.
for (let targetApp of this.targetApplications) {
if (targetApp.id == FIREFOX_ID) //Firefox GUID
return targetApp;
}
#endif
// Return toolkit ID if toolkit.
@@ -517,13 +517,6 @@
background-repeat: repeat-x;
}
.addon-view[notification="warning"][native="false"] {
background-image: url("chrome://mozapps/skin/extensions/stripes-compatibility.png"),
linear-gradient(rgba(255, 128, 0, 0.04),
rgba(255, 128, 0, 0));
background-repeat: repeat-x;
}
.addon-view[notification="error"] {
background-image: url("chrome://mozapps/skin/extensions/stripes-error.png"),
linear-gradient(rgba(255, 0, 0, 0.04),
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

-5
View File
@@ -26,11 +26,6 @@ toolkit.jar:
skin/classic/mozapps/extensions/themeGeneric.png (extensions/themeGeneric.png)
skin/classic/mozapps/extensions/themeGeneric-16.png (extensions/themeGeneric-16.png)
skin/classic/mozapps/extensions/localeGeneric.png (extensions/localeGeneric.png)
skin/classic/mozapps/extensions/stripes-warning.png (extensions/stripes-warning.png)
skin/classic/mozapps/extensions/stripes-compatibility.png (extensions/stripes-compatibility.png)
skin/classic/mozapps/extensions/stripes-error.png (extensions/stripes-error.png)
skin/classic/mozapps/extensions/stripes-info-positive.png (extensions/stripes-info-positive.png)
skin/classic/mozapps/extensions/stripes-info-negative.png (extensions/stripes-info-negative.png)
skin/classic/mozapps/extensions/newaddon.css (extensions/newaddon.css)
skin/classic/mozapps/extensions/selectAddons.css (extensions/selectAddons.css)
skin/classic/mozapps/xpinstall/xpinstallItemGeneric.png (extensions/extensionGeneric.png)
@@ -659,13 +659,6 @@
background-repeat: repeat-x;
}
.addon-view[notification="warning"][native="false"] {
background-image: url("chrome://mozapps/skin/extensions/stripes-compatibility.png"),
linear-gradient(rgba(255, 128, 0, 0.04),
rgba(255, 128, 0, 0));
background-repeat: repeat-x;
}
.addon-view[notification="error"] {
background-image: url("chrome://mozapps/skin/extensions/stripes-error.png"),
linear-gradient(rgba(255, 0, 0, 0.04),
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

@@ -648,13 +648,6 @@
background-repeat: repeat-x;
}
.addon-view[notification="warning"][native="false"] {
background-image: url("chrome://mozapps/skin/extensions/stripes-compatibility.png"),
linear-gradient(rgba(255, 128, 0, 0.04),
rgba(255, 128, 0, 0));
background-repeat: repeat-x;
}
.addon-view[notification="error"] {
background-image: url("chrome://mozapps/skin/extensions/stripes-error.png"),
linear-gradient(rgba(255, 0, 0, 0.04),
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

-1
View File
@@ -39,7 +39,6 @@ toolkit.jar:
skin/classic/mozapps/extensions/heart.png (extensions/heart.png)
skin/classic/mozapps/extensions/navigation.png (extensions/navigation.png)
skin/classic/mozapps/extensions/stripes-warning.png (extensions/stripes-warning.png)
skin/classic/mozapps/extensions/stripes-compatibility.png (extensions/stripes-compatibility.png)
skin/classic/mozapps/extensions/stripes-error.png (extensions/stripes-error.png)
skin/classic/mozapps/extensions/stripes-info-positive.png (extensions/stripes-info-positive.png)
skin/classic/mozapps/extensions/stripes-info-negative.png (extensions/stripes-info-negative.png)
+3
View File
@@ -21,6 +21,9 @@ public:
static bool OnYosemiteOrLater();
static bool OnElCapitanOrLater();
static bool OnSierraOrLater();
static bool OnHighSierraOrLater();
static bool OnMojaveOrLater();
static bool OnCatalinaOrLater();
static bool IsAtLeastVersion(int32_t aMajor, int32_t aMinor, int32_t aBugFix=0);
+21
View File
@@ -19,6 +19,9 @@
#define MAC_OS_X_VERSION_10_10_HEX 0x000010A0
#define MAC_OS_X_VERSION_10_11_HEX 0x000010B0
#define MAC_OS_X_VERSION_10_12_HEX 0x000010C0
#define MAC_OS_X_VERSION_10_13_HEX 0x000010D0
#define MAC_OS_X_VERSION_10_14_HEX 0x000010E0
#define MAC_OS_X_VERSION_10_15_HEX 0x000010F0
#include "nsCocoaFeatures.h"
#include "nsCocoaUtils.h"
@@ -167,6 +170,24 @@ nsCocoaFeatures::OnSierraOrLater()
return (OSXVersion() >= MAC_OS_X_VERSION_10_12_HEX);
}
/* static */ bool
nsCocoaFeatures::OnHighSierraOrLater()
{
return (OSXVersion() >= MAC_OS_X_VERSION_10_13_HEX);
}
/* static */ bool
nsCocoaFeatures::OnMojaveOrLater()
{
return (OSXVersion() >= MAC_OS_X_VERSION_10_14_HEX);
}
/* static */ bool
nsCocoaFeatures::OnCatalinaOrLater()
{
return (OSXVersion() >= MAC_OS_X_VERSION_10_15_HEX);
}
/* static */ bool
nsCocoaFeatures::IsAtLeastVersion(int32_t aMajor, int32_t aMinor, int32_t aBugFix)
{
+27 -20
View File
@@ -810,15 +810,17 @@ NS_IMETHODIMP nsCocoaWindow::Show(bool bState)
}
}
else if (mWindowType == eWindowType_popup) {
// If a popup window is shown after being hidden, it needs to be "reset"
// for it to receive any mouse events aside from mouse-moved events
// (because it was removed from the "window cache" when it was hidden
// -- see below). Setting the window number to -1 and then back to its
// original value seems to accomplish this. The idea was "borrowed"
// from the Java Embedding Plugin.
NSInteger windowNumber = [mWindow windowNumber];
[mWindow _setWindowNumber:-1];
[mWindow _setWindowNumber:windowNumber];
if (!nsCocoaFeatures::OnMojaveOrLater()) {
// If a popup window is shown after being hidden, it needs to be "reset"
// for it to receive any mouse events aside from mouse-moved events
// (because it was removed from the "window cache" when it was hidden
// -- see below). Setting the window number to -1 and then back to its
// original value seems to accomplish this. The idea was "borrowed"
// from the Java Embedding Plugin. This is fixed on macOS 10.14+.
NSInteger windowNumber = [mWindow windowNumber];
[mWindow _setWindowNumber:-1];
[mWindow _setWindowNumber:windowNumber];
}
// For reasons that aren't yet clear, calls to [NSWindow orderFront:] or
// [NSWindow makeKeyAndOrderFront:] can sometimes trigger "Error (1000)
// creating CGSWindow", which in turn triggers an internal inconsistency
@@ -951,17 +953,22 @@ NS_IMETHODIMP nsCocoaWindow::Show(bool bState)
[nativeParentWindow removeChildWindow:mWindow];
[mWindow orderOut:nil];
// Unless it's explicitly removed from NSApp's "window cache", a popup
// window will keep receiving mouse-moved events even after it's been
// "ordered out" (instead of the browser window that was underneath it,
// until you click on that window). This is bmo bug 378645, but it's
// surely an Apple bug. The "window cache" is an undocumented subsystem,
// all of whose methods are included in the NSWindowCache category of
// the NSApplication class (in header files generated using class-dump).
// This workaround was "borrowed" from the Java Embedding Plugin (which
// uses it for a different purpose).
if (mWindowType == eWindowType_popup)
[NSApp _removeWindowFromCache:mWindow];
if (!nsCocoaFeatures::OnMojaveOrLater()) {
// Unless it's explicitly removed from NSApp's "window cache", a popup
// window will keep receiving mouse-moved events even after it's been
// "ordered out" (instead of the browser window that was underneath it,
// until you click on that window). This is bmo bug 378645, but it's
// surely an Apple bug. The "window cache" is an undocumented
// subsystem, all of whose methods are included in the NSWindowCache
// category of the NSApplication class (in header files generated using
// class-dump). This workaround was "borrowed" from the Java Embedding
// Plugin (which uses it for a different purpose). This is fixed on
// macOS 10.14+.
if (mWindowType == eWindowType_popup) {
[NSApp _removeWindowFromCache:mWindow];
}
}
// If our popup window is a non-native context menu, tell the OS (and
// other programs) that a menu has closed.