mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Merge m-i to m-c, a=merge
MozReview-Commit-ID: FA9OZyjP59N
This commit is contained in:
commit
6c91017f20
@ -56,13 +56,10 @@ const kTopicAlertFinished = "alertfinished";
|
||||
const kMozChromeNotificationEvent = "mozChromeNotificationEvent";
|
||||
const kMozContentNotificationEvent = "mozContentNotificationEvent";
|
||||
|
||||
const kMessageAppNotificationSend = "app-notification-send";
|
||||
const kMessageAppNotificationReturn = "app-notification-return";
|
||||
const kMessageAlertNotificationSend = "alert-notification-send";
|
||||
const kMessageAlertNotificationClose = "alert-notification-close";
|
||||
|
||||
const kMessages = [
|
||||
kMessageAppNotificationSend,
|
||||
kMessageAlertNotificationSend,
|
||||
kMessageAlertNotificationClose
|
||||
];
|
||||
@ -132,35 +129,6 @@ var AlertsHelper = {
|
||||
listener.observer.observe(null, topic, listener.cookie);
|
||||
} catch (e) { }
|
||||
} else {
|
||||
try {
|
||||
listener.mm.sendAsyncMessage(kMessageAppNotificationReturn, {
|
||||
uid: uid,
|
||||
topic: topic,
|
||||
target: listener.target
|
||||
});
|
||||
} catch (e) {
|
||||
// we get an exception if the app is not launched yet
|
||||
if (detail.type !== kDesktopNotificationShow) {
|
||||
// excluding the 'show' event: there is no reason a unlaunched app
|
||||
// would want to be notified that a notification is shown. This
|
||||
// happens when a notification is still displayed at reboot time.
|
||||
gSystemMessenger.sendMessage(kNotificationSystemMessageName, {
|
||||
clicked: (detail.type === kDesktopNotificationClick),
|
||||
title: listener.title,
|
||||
body: listener.text,
|
||||
imageURL: listener.imageURL,
|
||||
lang: listener.lang,
|
||||
dir: listener.dir,
|
||||
id: listener.id,
|
||||
tag: listener.tag,
|
||||
timestamp: listener.timestamp,
|
||||
data: listener.dataObj
|
||||
},
|
||||
Services.io.newURI(listener.target, null, null),
|
||||
Services.io.newURI(listener.manifestURL, null, null)
|
||||
);
|
||||
}
|
||||
}
|
||||
if (detail.type === kDesktopNotificationClose && listener.dbId) {
|
||||
notificationStorage.delete(listener.manifestURL, listener.dbId);
|
||||
}
|
||||
@ -280,31 +248,6 @@ var AlertsHelper = {
|
||||
data.lang, dataObj, null, data.inPrivateBrowsing);
|
||||
},
|
||||
|
||||
showAppNotification: function(aMessage) {
|
||||
let data = aMessage.data;
|
||||
let details = data.details;
|
||||
let dataObject = this.deserializeStructuredClone(details.data);
|
||||
let listener = {
|
||||
mm: aMessage.target,
|
||||
title: data.title,
|
||||
text: data.text,
|
||||
manifestURL: details.manifestURL,
|
||||
imageURL: data.imageURL,
|
||||
lang: details.lang || undefined,
|
||||
id: details.id || undefined,
|
||||
dbId: details.dbId || undefined,
|
||||
dir: details.dir || undefined,
|
||||
tag: details.tag || undefined,
|
||||
timestamp: details.timestamp || undefined,
|
||||
dataObj: dataObject || undefined
|
||||
};
|
||||
this.registerAppListener(data.uid, listener);
|
||||
this.showNotification(data.imageURL, data.title, data.text,
|
||||
details.textClickable, null, data.uid, details.dir,
|
||||
details.lang, dataObject, details.manifestURL,
|
||||
details.timestamp, details.mozbehavior);
|
||||
},
|
||||
|
||||
closeAlert: function(name) {
|
||||
SystemAppProxy._sendCustomEvent(kMozChromeNotificationEvent, {
|
||||
type: kDesktopNotificationClose,
|
||||
@ -321,10 +264,6 @@ var AlertsHelper = {
|
||||
}
|
||||
|
||||
switch(aMessage.name) {
|
||||
case kMessageAppNotificationSend:
|
||||
this.showAppNotification(aMessage);
|
||||
break;
|
||||
|
||||
case kMessageAlertNotificationSend:
|
||||
this.showAlertNotification(aMessage);
|
||||
break;
|
||||
|
@ -36,8 +36,6 @@ function debug(str) {
|
||||
|
||||
const kNotificationSystemMessageName = "notification";
|
||||
|
||||
const kMessageAppNotificationSend = "app-notification-send";
|
||||
const kMessageAppNotificationReturn = "app-notification-return";
|
||||
const kMessageAlertNotificationSend = "alert-notification-send";
|
||||
const kMessageAlertNotificationClose = "alert-notification-close";
|
||||
|
||||
@ -47,20 +45,17 @@ const kTopicAlertClickCallback = "alertclickcallback";
|
||||
|
||||
function AlertsService() {
|
||||
Services.obs.addObserver(this, "xpcom-shutdown", false);
|
||||
cpmm.addMessageListener(kMessageAppNotificationReturn, this);
|
||||
}
|
||||
|
||||
AlertsService.prototype = {
|
||||
classID: Components.ID("{fe33c107-82a4-41d6-8c64-5353267e04c9}"),
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAlertsService,
|
||||
Ci.nsIAppNotificationService,
|
||||
Ci.nsIObserver]),
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
switch (aTopic) {
|
||||
case "xpcom-shutdown":
|
||||
Services.obs.removeObserver(this, "xpcom-shutdown");
|
||||
cpmm.removeMessageListener(kMessageAppNotificationReturn, this);
|
||||
break;
|
||||
}
|
||||
},
|
||||
@ -104,44 +99,13 @@ AlertsService.prototype = {
|
||||
});
|
||||
},
|
||||
|
||||
// nsIAppNotificationService
|
||||
showAppNotification: function(aImageURL, aTitle, aText, aAlertListener,
|
||||
aDetails) {
|
||||
let uid = (aDetails.id == "") ?
|
||||
"app-notif-" + uuidGenerator.generateUUID() : aDetails.id;
|
||||
|
||||
let dataObj = this.deserializeStructuredClone(aDetails.data);
|
||||
this._listeners[uid] = {
|
||||
observer: aAlertListener,
|
||||
title: aTitle,
|
||||
text: aText,
|
||||
manifestURL: aDetails.manifestURL,
|
||||
imageURL: aImageURL,
|
||||
lang: aDetails.lang || undefined,
|
||||
id: aDetails.id || undefined,
|
||||
dbId: aDetails.dbId || undefined,
|
||||
dir: aDetails.dir || undefined,
|
||||
tag: aDetails.tag || undefined,
|
||||
timestamp: aDetails.timestamp || undefined,
|
||||
dataObj: dataObj || undefined
|
||||
};
|
||||
|
||||
cpmm.sendAsyncMessage(kMessageAppNotificationSend, {
|
||||
imageURL: aImageURL,
|
||||
title: aTitle,
|
||||
text: aText,
|
||||
uid: uid,
|
||||
details: aDetails
|
||||
});
|
||||
},
|
||||
|
||||
// AlertsService.js custom implementation
|
||||
_listeners: [],
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
let data = aMessage.data;
|
||||
let listener = this._listeners[data.uid];
|
||||
if (aMessage.name !== kMessageAppNotificationReturn || !listener) {
|
||||
if (!listener) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -150,31 +114,6 @@ AlertsService.prototype = {
|
||||
try {
|
||||
listener.observer.observe(null, topic, null);
|
||||
} catch (e) {
|
||||
// It seems like there is no callbacks anymore, forward the click on
|
||||
// notification via a system message containing the title/text/icon of
|
||||
// the notification so the app get a change to react.
|
||||
if (data.target) {
|
||||
if (topic !== kTopicAlertShow) {
|
||||
// excluding the 'show' event: there is no reason a unlaunched app
|
||||
// would want to be notified that a notification is shown. This
|
||||
// happens when a notification is still displayed at reboot time.
|
||||
gSystemMessenger.sendMessage(kNotificationSystemMessageName, {
|
||||
clicked: (topic === kTopicAlertClickCallback),
|
||||
title: listener.title,
|
||||
body: listener.text,
|
||||
imageURL: listener.imageURL,
|
||||
lang: listener.lang,
|
||||
dir: listener.dir,
|
||||
id: listener.id,
|
||||
tag: listener.tag,
|
||||
timestamp: listener.timestamp,
|
||||
data: listener.dataObj || undefined,
|
||||
},
|
||||
Services.io.newURI(data.target, null, null),
|
||||
Services.io.newURI(listener.manifestURL, null, null)
|
||||
);
|
||||
}
|
||||
}
|
||||
if (topic === kTopicAlertFinished && listener.dbId) {
|
||||
notificationStorage.delete(listener.manifestURL, listener.dbId);
|
||||
}
|
||||
|
@ -340,8 +340,6 @@
|
||||
@RESPATH@/components/zipwriter.xpt
|
||||
|
||||
; JavaScript components
|
||||
@RESPATH@/components/ChromeNotifications.js
|
||||
@RESPATH@/components/ChromeNotifications.manifest
|
||||
@RESPATH@/components/ConsoleAPI.manifest
|
||||
@RESPATH@/components/ConsoleAPIStorage.js
|
||||
@RESPATH@/components/BrowserElementParent.manifest
|
||||
|
@ -65,7 +65,6 @@ skip-if = !crashreporter
|
||||
[browser_blocking.js]
|
||||
[browser_plugins_added_dynamically.js]
|
||||
[browser_pluginnotification.js]
|
||||
[browser_plugin_infolink.js]
|
||||
[browser_plugin_reloading.js]
|
||||
[browser_blocklist_content.js]
|
||||
skip-if = !e10s
|
||||
|
@ -19,8 +19,6 @@ add_task(function* () {
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gTestBrowser = gBrowser.selectedBrowser;
|
||||
|
||||
let bindingPromise = waitForEvent(gTestBrowser, "PluginBindingAttached", null, true, true);
|
||||
|
||||
let consoleService = Cc["@mozilla.org/consoleservice;1"]
|
||||
.getService(Ci.nsIConsoleService);
|
||||
let errorListener = {
|
||||
@ -33,8 +31,6 @@ add_task(function* () {
|
||||
|
||||
yield promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_bug797677.html");
|
||||
|
||||
yield bindingPromise;
|
||||
|
||||
let pluginInfo = yield promiseForPluginInfo("plugin");
|
||||
is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_UNSUPPORTED, "plugin should not have been found.");
|
||||
|
||||
|
@ -1,48 +0,0 @@
|
||||
var gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
|
||||
var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost);
|
||||
var oldBrowserOpenAddonsMgr = window.BrowserOpenAddonsMgr;
|
||||
|
||||
registerCleanupFunction(function* cleanup() {
|
||||
clearAllPluginPermissions();
|
||||
Services.prefs.clearUserPref("plugins.click_to_play");
|
||||
setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
|
||||
window.BrowserOpenAddonsMgr = oldBrowserOpenAddonsMgr;
|
||||
window.focus();
|
||||
});
|
||||
|
||||
add_task(function* test_clicking_manage_link_in_plugin_overlay_should_open_about_addons() {
|
||||
Services.prefs.setBoolPref("plugins.click_to_play", true);
|
||||
setTestPluginEnabledState(Ci.nsIPluginTag.STATE_DISABLED, "Test Plug-in");
|
||||
|
||||
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, gTestRoot + "plugin_test.html");
|
||||
let browser = tab.linkedBrowser;
|
||||
yield promiseUpdatePluginBindings(browser);
|
||||
|
||||
let pluginInfo = yield promiseForPluginInfo("test", browser);
|
||||
is(pluginInfo.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_DISABLED,
|
||||
"plugin fallback type should be PLUGIN_DISABLED");
|
||||
|
||||
let awaitBrowserOpenAddonsMgr = new Promise(resolve => {
|
||||
window.BrowserOpenAddonsMgr = function(view) {
|
||||
resolve(view);
|
||||
}
|
||||
});
|
||||
|
||||
yield ContentTask.spawn(browser, null, function* () {
|
||||
let pluginNode = content.document.getElementById("test");
|
||||
let manageLink = content.document.getAnonymousElementByAttribute(pluginNode, "anonid", "managePluginsLink");
|
||||
let bounds = manageLink.getBoundingClientRect();
|
||||
let left = (bounds.left + bounds.right) / 2;
|
||||
let top = (bounds.top + bounds.bottom) / 2;
|
||||
let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIDOMWindowUtils);
|
||||
utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
|
||||
utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
|
||||
Assert.ok(true, "click on manage link");
|
||||
});
|
||||
|
||||
let requestedView = yield awaitBrowserOpenAddonsMgr;
|
||||
is(requestedView, "addons://list/plugin", "The Add-ons Manager should open the plugin view");
|
||||
|
||||
yield BrowserTestUtils.removeTab(tab);
|
||||
});
|
@ -345,8 +345,6 @@
|
||||
@RESPATH@/components/telemetry.xpt
|
||||
|
||||
; JavaScript components
|
||||
@RESPATH@/components/ChromeNotifications.js
|
||||
@RESPATH@/components/ChromeNotifications.manifest
|
||||
@RESPATH@/components/ConsoleAPI.manifest
|
||||
@RESPATH@/components/ConsoleAPIStorage.js
|
||||
@RESPATH@/components/BrowserElementParent.manifest
|
||||
|
@ -199,6 +199,11 @@ private:
|
||||
virtual void run(const MatchFinder::MatchResult &Result);
|
||||
};
|
||||
|
||||
class NonParamInsideFunctionDeclChecker : public MatchFinder::MatchCallback {
|
||||
public:
|
||||
virtual void run(const MatchFinder::MatchResult &Result);
|
||||
};
|
||||
|
||||
ScopeChecker Scope;
|
||||
ArithmeticArgChecker ArithmeticArg;
|
||||
TrivialCtorDtorChecker TrivialCtorDtor;
|
||||
@ -219,6 +224,7 @@ private:
|
||||
SprintfLiteralChecker SprintfLiteral;
|
||||
OverrideBaseCallChecker OverrideBaseCall;
|
||||
OverrideBaseCallUsageChecker OverrideBaseCallUsage;
|
||||
NonParamInsideFunctionDeclChecker NonParamInsideFunctionDecl;
|
||||
MatchFinder AstMatcher;
|
||||
};
|
||||
|
||||
@ -496,6 +502,8 @@ static CustomTypeAnnotation NonTemporaryClass =
|
||||
CustomTypeAnnotation("moz_non_temporary_class", "non-temporary");
|
||||
static CustomTypeAnnotation MustUse =
|
||||
CustomTypeAnnotation("moz_must_use_type", "must-use");
|
||||
static CustomTypeAnnotation NonParam =
|
||||
CustomTypeAnnotation("moz_non_param", "non-param");
|
||||
|
||||
class MemMoveAnnotation final : public CustomTypeAnnotation {
|
||||
public:
|
||||
@ -1329,6 +1337,17 @@ DiagnosticsMatcher::DiagnosticsMatcher() {
|
||||
AstMatcher.addMatcher(
|
||||
cxxMethodDecl(isNonVirtual(), isRequiredBaseMethod()).bind("method"),
|
||||
&OverrideBaseCallUsage);
|
||||
|
||||
AstMatcher.addMatcher(
|
||||
functionDecl(anyOf(allOf(isDefinition(),
|
||||
hasAncestor(classTemplateSpecializationDecl()
|
||||
.bind("spec"))),
|
||||
isDefinition()))
|
||||
.bind("func"),
|
||||
&NonParamInsideFunctionDecl);
|
||||
AstMatcher.addMatcher(
|
||||
lambdaExpr().bind("lambda"),
|
||||
&NonParamInsideFunctionDecl);
|
||||
}
|
||||
|
||||
// These enum variants determine whether an allocation has occured in the code.
|
||||
@ -2133,6 +2152,57 @@ void DiagnosticsMatcher::OverrideBaseCallUsageChecker::run(
|
||||
Diag.Report(Method->getLocation(), ErrorID);
|
||||
}
|
||||
|
||||
void DiagnosticsMatcher::NonParamInsideFunctionDeclChecker::run(
|
||||
const MatchFinder::MatchResult &Result) {
|
||||
static DenseSet<const FunctionDecl*> CheckedFunctionDecls;
|
||||
|
||||
const FunctionDecl *func = Result.Nodes.getNodeAs<FunctionDecl>("func");
|
||||
if (!func) {
|
||||
const LambdaExpr *lambda = Result.Nodes.getNodeAs<LambdaExpr>("lambda");
|
||||
if (lambda) {
|
||||
func = lambda->getCallOperator();
|
||||
}
|
||||
}
|
||||
|
||||
if (!func) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (func->isDeleted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't report errors on the same declarations more than once.
|
||||
if (CheckedFunctionDecls.count(func)) {
|
||||
return;
|
||||
}
|
||||
CheckedFunctionDecls.insert(func);
|
||||
|
||||
const ClassTemplateSpecializationDecl *Spec =
|
||||
Result.Nodes.getNodeAs<ClassTemplateSpecializationDecl>("spec");
|
||||
|
||||
DiagnosticsEngine &Diag = Result.Context->getDiagnostics();
|
||||
unsigned ErrorID = Diag.getDiagnosticIDs()->getCustomDiagID(
|
||||
DiagnosticIDs::Error, "Type %0 must not be used as parameter");
|
||||
unsigned NoteID = Diag.getDiagnosticIDs()->getCustomDiagID(
|
||||
DiagnosticIDs::Note, "Please consider passing a const reference instead");
|
||||
unsigned SpecNoteID = Diag.getDiagnosticIDs()->getCustomDiagID(
|
||||
DiagnosticIDs::Note, "The bad argument was passed to %0 here");
|
||||
|
||||
for (ParmVarDecl *p : func->parameters()) {
|
||||
QualType T = p->getType().withoutLocalFastQualifiers();
|
||||
if (NonParam.hasEffectiveAnnotation(T)) {
|
||||
Diag.Report(p->getLocation(), ErrorID) << T;
|
||||
Diag.Report(p->getLocation(), NoteID);
|
||||
|
||||
if (Spec) {
|
||||
Diag.Report(Spec->getPointOfInstantiation(), SpecNoteID)
|
||||
<< Spec->getSpecializedTemplate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MozCheckAction : public PluginASTAction {
|
||||
public:
|
||||
ASTConsumerPtr CreateASTConsumer(CompilerInstance &CI,
|
||||
|
61
build/clang-plugin/tests/NonParameterTestCases.h
Normal file
61
build/clang-plugin/tests/NonParameterTestCases.h
Normal file
@ -0,0 +1,61 @@
|
||||
MAYBE_STATIC void raw(Param x) {}
|
||||
|
||||
MAYBE_STATIC void raw(NonParam x) {} //expected-error {{Type 'NonParam' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
MAYBE_STATIC void raw(NonParamUnion x) {} //expected-error {{Type 'NonParamUnion' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
MAYBE_STATIC void raw(NonParamClass x) {} //expected-error {{Type 'NonParamClass' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
MAYBE_STATIC void raw(NonParamEnum x) {} //expected-error {{Type 'NonParamEnum' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
MAYBE_STATIC void raw(NonParamEnumClass x) {} //expected-error {{Type 'NonParamEnumClass' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
MAYBE_STATIC void raw(HasNonParamStruct x) {} //expected-error {{Type 'HasNonParamStruct' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
MAYBE_STATIC void raw(HasNonParamUnion x) {} //expected-error {{Type 'HasNonParamUnion' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
MAYBE_STATIC void raw(HasNonParamStructUnion x) {} //expected-error {{Type 'HasNonParamStructUnion' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
|
||||
MAYBE_STATIC void const_(const NonParam x) {} //expected-error {{Type 'NonParam' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
MAYBE_STATIC void const_(const NonParamUnion x) {} //expected-error {{Type 'NonParamUnion' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
MAYBE_STATIC void const_(const NonParamClass x) {} //expected-error {{Type 'NonParamClass' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
MAYBE_STATIC void const_(const NonParamEnum x) {} //expected-error {{Type 'NonParamEnum' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
MAYBE_STATIC void const_(const NonParamEnumClass x) {} //expected-error {{Type 'NonParamEnumClass' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
MAYBE_STATIC void const_(const HasNonParamStruct x) {} //expected-error {{Type 'HasNonParamStruct' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
MAYBE_STATIC void const_(const HasNonParamUnion x) {} //expected-error {{Type 'HasNonParamUnion' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
MAYBE_STATIC void const_(const HasNonParamStructUnion x) {} //expected-error {{Type 'HasNonParamStructUnion' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
|
||||
MAYBE_STATIC void array(NonParam x[]) {}
|
||||
MAYBE_STATIC void array(NonParamUnion x[]) {}
|
||||
MAYBE_STATIC void array(NonParamClass x[]) {}
|
||||
MAYBE_STATIC void array(NonParamEnum x[]) {}
|
||||
MAYBE_STATIC void array(NonParamEnumClass x[]) {}
|
||||
MAYBE_STATIC void array(HasNonParamStruct x[]) {}
|
||||
MAYBE_STATIC void array(HasNonParamUnion x[]) {}
|
||||
MAYBE_STATIC void array(HasNonParamStructUnion x[]) {}
|
||||
|
||||
MAYBE_STATIC void ptr(NonParam* x) {}
|
||||
MAYBE_STATIC void ptr(NonParamUnion* x) {}
|
||||
MAYBE_STATIC void ptr(NonParamClass* x) {}
|
||||
MAYBE_STATIC void ptr(NonParamEnum* x) {}
|
||||
MAYBE_STATIC void ptr(NonParamEnumClass* x) {}
|
||||
MAYBE_STATIC void ptr(HasNonParamStruct* x) {}
|
||||
MAYBE_STATIC void ptr(HasNonParamUnion* x) {}
|
||||
MAYBE_STATIC void ptr(HasNonParamStructUnion* x) {}
|
||||
|
||||
MAYBE_STATIC void ref(NonParam& x) {}
|
||||
MAYBE_STATIC void ref(NonParamUnion& x) {}
|
||||
MAYBE_STATIC void ref(NonParamClass& x) {}
|
||||
MAYBE_STATIC void ref(NonParamEnum& x) {}
|
||||
MAYBE_STATIC void ref(NonParamEnumClass& x) {}
|
||||
MAYBE_STATIC void ref(HasNonParamStruct& x) {}
|
||||
MAYBE_STATIC void ref(HasNonParamUnion& x) {}
|
||||
MAYBE_STATIC void ref(HasNonParamStructUnion& x) {}
|
||||
|
||||
MAYBE_STATIC void constRef(const NonParam& x) {}
|
||||
MAYBE_STATIC void constRef(const NonParamUnion& x) {}
|
||||
MAYBE_STATIC void constRef(const NonParamClass& x) {}
|
||||
MAYBE_STATIC void constRef(const NonParamEnum& x) {}
|
||||
MAYBE_STATIC void constRef(const NonParamEnumClass& x) {}
|
||||
MAYBE_STATIC void constRef(const HasNonParamStruct& x) {}
|
||||
MAYBE_STATIC void constRef(const HasNonParamUnion& x) {}
|
||||
MAYBE_STATIC void constRef(const HasNonParamStructUnion& x) {}
|
||||
|
||||
MAYBE_STATIC inline void inlineRaw(NonParam x) {} //expected-error {{Type 'NonParam' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
MAYBE_STATIC inline void inlineRaw(NonParamUnion x) {} //expected-error {{Type 'NonParamUnion' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
MAYBE_STATIC inline void inlineRaw(NonParamClass x) {} //expected-error {{Type 'NonParamClass' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
MAYBE_STATIC inline void inlineRaw(NonParamEnum x) {} //expected-error {{Type 'NonParamEnum' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
MAYBE_STATIC inline void inlineRaw(NonParamEnumClass x) {} //expected-error {{Type 'NonParamEnumClass' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
179
build/clang-plugin/tests/TestNonParameterChecker.cpp
Normal file
179
build/clang-plugin/tests/TestNonParameterChecker.cpp
Normal file
@ -0,0 +1,179 @@
|
||||
#define MOZ_NON_PARAM __attribute__((annotate("moz_non_param")))
|
||||
|
||||
struct Param {};
|
||||
struct MOZ_NON_PARAM NonParam {};
|
||||
union MOZ_NON_PARAM NonParamUnion {};
|
||||
class MOZ_NON_PARAM NonParamClass {};
|
||||
enum MOZ_NON_PARAM NonParamEnum { X, Y, Z };
|
||||
enum class MOZ_NON_PARAM NonParamEnumClass { X, Y, Z };
|
||||
|
||||
struct HasNonParamStruct { NonParam x; int y; };
|
||||
union HasNonParamUnion { NonParam x; int y; };
|
||||
struct HasNonParamStructUnion { HasNonParamUnion z; };
|
||||
|
||||
#define MAYBE_STATIC
|
||||
#include "NonParameterTestCases.h"
|
||||
#undef MAYBE_STATIC
|
||||
|
||||
// Do not check typedef and using.
|
||||
typedef void (*funcTypeParam)(Param x);
|
||||
typedef void (*funcTypeNonParam)(NonParam x);
|
||||
|
||||
using usingFuncTypeParam = void (*)(Param x);
|
||||
using usingFuncTypeNonParam = void (*)(NonParam x);
|
||||
|
||||
class class_
|
||||
{
|
||||
explicit class_(Param x) {}
|
||||
explicit class_(NonParam x) {} //expected-error {{Type 'NonParam' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
explicit class_(HasNonParamStruct x) {} //expected-error {{Type 'HasNonParamStruct' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
explicit class_(HasNonParamUnion x) {} //expected-error {{Type 'HasNonParamUnion' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
explicit class_(HasNonParamStructUnion x) {} //expected-error {{Type 'HasNonParamStructUnion' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
|
||||
#define MAYBE_STATIC
|
||||
#include "NonParameterTestCases.h"
|
||||
#undef MAYBE_STATIC
|
||||
};
|
||||
|
||||
class classWithStatic
|
||||
{
|
||||
#define MAYBE_STATIC static
|
||||
#include "NonParameterTestCases.h"
|
||||
#undef MAYBE_STATIC
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class tmplClassForParam
|
||||
{
|
||||
public:
|
||||
void raw(T x) {}
|
||||
void rawDefault(T x = T()) {}
|
||||
void const_(const T x) {}
|
||||
void ptr(T* x) {}
|
||||
void ref(T& x) {}
|
||||
void constRef(const T& x) {}
|
||||
|
||||
void notCalled(T x) {}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class tmplClassForNonParam
|
||||
{
|
||||
public:
|
||||
void raw(T x) {} //expected-error {{Type 'NonParam' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
void rawDefault(T x = T()) {} //expected-error {{Type 'NonParam' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
void const_(const T x) {} //expected-error {{Type 'NonParam' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
void ptr(T* x) {}
|
||||
void ref(T& x) {}
|
||||
void constRef(const T& x) {}
|
||||
|
||||
void notCalled(T x) {}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class tmplClassForHasNonParamStruct
|
||||
{
|
||||
public:
|
||||
void raw(T x) {} //expected-error {{Type 'HasNonParamStruct' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
void rawDefault(T x = T()) {} //expected-error {{Type 'HasNonParamStruct' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
void const_(const T x) {} //expected-error {{Type 'HasNonParamStruct' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
void ptr(T* x) {}
|
||||
void ref(T& x) {}
|
||||
void constRef(const T& x) {}
|
||||
|
||||
void notCalled(T x) {}
|
||||
};
|
||||
|
||||
void testTemplateClass()
|
||||
{
|
||||
tmplClassForParam<Param> paramClass;
|
||||
Param param;
|
||||
paramClass.raw(param);
|
||||
paramClass.rawDefault();
|
||||
paramClass.const_(param);
|
||||
paramClass.ptr(¶m);
|
||||
paramClass.ref(param);
|
||||
paramClass.constRef(param);
|
||||
|
||||
tmplClassForNonParam<NonParam> nonParamClass; //expected-note 3 {{The bad argument was passed to 'tmplClassForNonParam' here}}
|
||||
NonParam nonParam;
|
||||
nonParamClass.raw(nonParam);
|
||||
nonParamClass.rawDefault();
|
||||
nonParamClass.const_(nonParam);
|
||||
nonParamClass.ptr(&nonParam);
|
||||
nonParamClass.ref(nonParam);
|
||||
nonParamClass.constRef(nonParam);
|
||||
|
||||
tmplClassForHasNonParamStruct<HasNonParamStruct> hasNonParamStructClass;//expected-note 3 {{The bad argument was passed to 'tmplClassForHasNonParamStruct' here}}
|
||||
HasNonParamStruct hasNonParamStruct;
|
||||
hasNonParamStructClass.raw(hasNonParamStruct);
|
||||
hasNonParamStructClass.rawDefault();
|
||||
hasNonParamStructClass.const_(hasNonParamStruct);
|
||||
hasNonParamStructClass.ptr(&hasNonParamStruct);
|
||||
hasNonParamStructClass.ref(hasNonParamStruct);
|
||||
hasNonParamStructClass.constRef(hasNonParamStruct);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class NestedTemplateInner
|
||||
{
|
||||
public:
|
||||
void raw(T x) {} //expected-error {{Type 'NonParam' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class nestedTemplateOuter
|
||||
{
|
||||
public:
|
||||
void constRef(const T& x) {
|
||||
NestedTemplateInner<T> inner; //expected-note {{The bad argument was passed to 'NestedTemplateInner' here}}
|
||||
inner.raw(x);
|
||||
}
|
||||
};
|
||||
|
||||
void testNestedTemplateClass()
|
||||
{
|
||||
nestedTemplateOuter<NonParam> outer;
|
||||
NonParam nonParam;
|
||||
outer.constRef(nonParam); // FIXME: this line needs note "The bad argument was passed to 'constRef' here"
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void tmplFuncForParam(T x) {}
|
||||
template <typename T>
|
||||
void tmplFuncForNonParam(T x) {} //expected-error {{Type 'NonParam' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
template <typename T>
|
||||
void tmplFuncForNonParamImplicit(T x) {} //expected-error {{Type 'NonParam' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
template <typename T>
|
||||
void tmplFuncForHasNonParamStruct(T x) {} //expected-error {{Type 'HasNonParamStruct' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
template <typename T>
|
||||
void tmplFuncForHasNonParamStructImplicit(T x) {} //expected-error {{Type 'HasNonParamStruct' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
|
||||
void testTemplateFunc()
|
||||
{
|
||||
Param param;
|
||||
tmplFuncForParam<Param>(param);
|
||||
|
||||
NonParam nonParam;
|
||||
tmplFuncForNonParam<NonParam>(nonParam); // FIXME: this line needs note "The bad argument was passed to 'tmplFuncForNonParam' here"
|
||||
tmplFuncForNonParamImplicit(nonParam); // FIXME: this line needs note "The bad argument was passed to 'tmplFuncForNonParamImplicit' here"
|
||||
|
||||
HasNonParamStruct hasNonParamStruct;
|
||||
tmplFuncForHasNonParamStruct<HasNonParamStruct>(hasNonParamStruct); // FIXME: this line needs note "The bad argument was passed to 'tmplFuncForHasNonParamStruct' here"
|
||||
tmplFuncForHasNonParamStructImplicit(hasNonParamStruct); // FIXME: this line needs note "The bad argument was passed to 'tmplFuncForHasNonParamStructImplicit' here"
|
||||
}
|
||||
|
||||
void testLambda()
|
||||
{
|
||||
auto paramLambda = [](Param x) -> void {};
|
||||
auto nonParamLambda = [](NonParam x) -> void {}; //expected-error {{Type 'NonParam' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
auto nonParamStructLambda = [](HasNonParamStruct x) -> void {}; //expected-error {{Type 'HasNonParamStruct' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
auto nonParamUnionLambda = [](HasNonParamUnion x) -> void {}; //expected-error {{Type 'HasNonParamUnion' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
auto nonParamStructUnionLambda = [](HasNonParamStructUnion x) -> void {}; //expected-error {{Type 'HasNonParamStructUnion' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
|
||||
(void)[](Param x) -> void {};
|
||||
(void)[](NonParam x) -> void {}; //expected-error {{Type 'NonParam' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
(void)[](HasNonParamStruct x) -> void {}; //expected-error {{Type 'HasNonParamStruct' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
(void)[](HasNonParamUnion x) -> void {}; //expected-error {{Type 'HasNonParamUnion' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
(void)[](HasNonParamStructUnion x) -> void {}; //expected-error {{Type 'HasNonParamStructUnion' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
|
||||
}
|
@ -30,6 +30,7 @@ SOURCES += [
|
||||
'TestNonHeapClass.cpp',
|
||||
'TestNonMemMovable.cpp',
|
||||
'TestNonMemMovableStd.cpp',
|
||||
'TestNonParameterChecker.cpp',
|
||||
'TestNonTemporaryClass.cpp',
|
||||
'TestNoRefcountedInsideLambdas.cpp',
|
||||
'TestOverrideBaseCall.cpp',
|
||||
|
3
config/external/moz.build
vendored
3
config/external/moz.build
vendored
@ -61,4 +61,7 @@ external_dirs += [
|
||||
'media/psshparser'
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_LINKER']:
|
||||
external_dirs += ['modules/xz-embedded']
|
||||
|
||||
DIRS += ['../../' + i for i in external_dirs]
|
||||
|
@ -30,9 +30,13 @@ add_task(function* () {
|
||||
yield onColorPickerReady;
|
||||
|
||||
button = cPicker.tooltip.doc.querySelector("#eyedropper-button");
|
||||
ok(!isVisible(button), "The button is hidden in the color picker");
|
||||
ok(isDisabled(button), "The button is disabled in the color picker");
|
||||
});
|
||||
|
||||
function isVisible(button) {
|
||||
return button.getBoxQuads().length !== 0;
|
||||
}
|
||||
|
||||
function isDisabled(button) {
|
||||
return button.disabled;
|
||||
}
|
||||
|
@ -41,6 +41,10 @@ markupView.whitespaceOnly=Whitespace-only text node: %S
|
||||
#LOCALIZATION NOTE: Used in the image preview tooltip when the image could not be loaded
|
||||
previewTooltip.image.brokenImage=Could not load the image
|
||||
|
||||
# LOCALIZATION NOTE: Used in color picker tooltip when the eyedropper is disabled for
|
||||
# non-HTML documents
|
||||
eyedropper.disabled.title=Unavailable in non-HTML documents
|
||||
|
||||
#LOCALIZATION NOTE: Used in the image preview tooltip when the image could not be loaded
|
||||
eventsTooltip.openInDebugger=Open in Debugger
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
define(function (require, exports, module) {
|
||||
// Dependencies
|
||||
const React = require("devtools/client/shared/vendor/react");
|
||||
const { cropMultipleLines } = require("./rep-utils");
|
||||
const { cropString } = require("./rep-utils");
|
||||
|
||||
// Shortcuts
|
||||
const { span } = React.DOM;
|
||||
@ -43,13 +43,14 @@ define(function (require, exports, module) {
|
||||
}
|
||||
|
||||
let croppedString = this.props.cropLimit ?
|
||||
cropMultipleLines(text, this.props.cropLimit) : cropMultipleLines(text);
|
||||
cropString(text, this.props.cropLimit) : cropString(text);
|
||||
|
||||
let formattedString = this.props.useQuotes ?
|
||||
"\"" + croppedString + "\"" : croppedString;
|
||||
|
||||
return (
|
||||
span({className: "objectBox objectBox-string"}, formattedString
|
||||
span({className: "objectBox objectBox-string"},
|
||||
formattedString
|
||||
)
|
||||
);
|
||||
},
|
||||
|
@ -36,12 +36,12 @@ window.onload = Task.async(function* () {
|
||||
|
||||
function testMultiline() {
|
||||
const renderedComponent = renderComponent(StringRep.rep, { object: getGripStub("testMultiline") });
|
||||
is(renderedComponent.textContent, "\"aaaaaaaaaaaaaaaaaaaaa\\nbbbbbbbbbbbbbbbbbbb\\ncccccccccccccccc\\n\"", "String rep has expected text content for multiline string");
|
||||
is(renderedComponent.textContent, "\"aaaaaaaaaaaaaaaaaaaaa\nbbbbbbbbbbbbbbbbbbb\ncccccccccccccccc\n\"", "String rep has expected text content for multiline string");
|
||||
}
|
||||
|
||||
function testMultilineLimit() {
|
||||
const renderedComponent = renderComponent(StringRep.rep, { object: getGripStub("testMultiline"), cropLimit: 20 });
|
||||
is(renderedComponent.textContent, "\"aaaaaaaaaa…cccccccc\\n\"", "String rep has expected text content for multiline string with specified number of characters");
|
||||
is(renderedComponent.textContent, "\"aaaaaaaaaa…cccccccc\n\"", "String rep has expected text content for multiline string with specified number of characters");
|
||||
}
|
||||
|
||||
function testMultilineOpen() {
|
||||
|
@ -574,6 +574,7 @@ HTMLTooltip.prototype = {
|
||||
panel.setAttribute("noautofocus", true);
|
||||
panel.setAttribute("noautohide", true);
|
||||
panel.setAttribute("ignorekeys", true);
|
||||
panel.setAttribute("tooltip", "aHTMLTooltip");
|
||||
|
||||
// Use type="arrow" to prevent side effects (see Bug 1285206)
|
||||
panel.setAttribute("type", "arrow");
|
||||
|
@ -8,6 +8,8 @@ const {Task} = require("devtools/shared/task");
|
||||
const {colorUtils} = require("devtools/shared/css/color");
|
||||
const {Spectrum} = require("devtools/client/shared/widgets/Spectrum");
|
||||
const SwatchBasedEditorTooltip = require("devtools/client/shared/widgets/tooltip/SwatchBasedEditorTooltip");
|
||||
const {LocalizationHelper} = require("devtools/shared/l10n");
|
||||
const L10N = new LocalizationHelper("devtools/locale/inspector.properties");
|
||||
|
||||
const Heritage = require("sdk/core/heritage");
|
||||
|
||||
@ -56,6 +58,10 @@ SwatchColorPickerTooltip.prototype = Heritage.extend(SwatchBasedEditorTooltip.pr
|
||||
let eyedropper = doc.createElementNS(XHTML_NS, "button");
|
||||
eyedropper.id = "eyedropper-button";
|
||||
eyedropper.className = "devtools-button";
|
||||
/* pointerEvents for eyedropper has to be set auto to display tooltip when
|
||||
* eyedropper is disabled in non-HTML documents.
|
||||
*/
|
||||
eyedropper.style.pointerEvents = "auto";
|
||||
container.appendChild(eyedropper);
|
||||
|
||||
this.tooltip.setContent(container, { width: 218, height: 224 });
|
||||
@ -96,7 +102,8 @@ SwatchColorPickerTooltip.prototype = Heritage.extend(SwatchBasedEditorTooltip.pr
|
||||
if (value && this.inspector.selection.nodeFront.isInHTMLDocument) {
|
||||
eyeButton.addEventListener("click", this._openEyeDropper);
|
||||
} else {
|
||||
eyeButton.style.display = "none";
|
||||
eyeButton.disabled = true;
|
||||
eyeButton.title = L10N.getStr("eyedropper.disabled.title");
|
||||
}
|
||||
this.emit("ready");
|
||||
}, e => console.error(e));
|
||||
|
@ -14,6 +14,8 @@ const PropTypes = React.PropTypes;
|
||||
* It's essentially a list of name + value pairs.
|
||||
*/
|
||||
var NetInfoParams = React.createClass({
|
||||
displayName: "NetInfoParams",
|
||||
|
||||
propTypes: {
|
||||
params: PropTypes.arrayOf(PropTypes.shape({
|
||||
name: PropTypes.string.isRequired,
|
||||
@ -21,8 +23,6 @@ var NetInfoParams = React.createClass({
|
||||
})).isRequired,
|
||||
},
|
||||
|
||||
displayName: "NetInfoParams",
|
||||
|
||||
render() {
|
||||
let params = this.props.params || [];
|
||||
|
||||
@ -31,9 +31,9 @@ var NetInfoParams = React.createClass({
|
||||
});
|
||||
|
||||
let rows = [];
|
||||
params.forEach(param => {
|
||||
params.forEach((param, index) => {
|
||||
rows.push(
|
||||
DOM.tr({key: param.name},
|
||||
DOM.tr({key: index},
|
||||
DOM.td({className: "netInfoParamName"},
|
||||
DOM.span({title: param.name}, param.name)
|
||||
),
|
||||
|
@ -40,3 +40,30 @@ add_task(function* () {
|
||||
is(paramValue.textContent, "bar",
|
||||
"The param value must have proper value");
|
||||
});
|
||||
|
||||
/**
|
||||
* Test URL parameters with the same name.
|
||||
*/
|
||||
add_task(function* () {
|
||||
info("Test XHR Spy params started");
|
||||
|
||||
let {hud} = yield addTestTab(TEST_PAGE_URL);
|
||||
|
||||
let netInfoBody = yield executeAndInspectXhr(hud, {
|
||||
method: "GET",
|
||||
url: JSON_XHR_URL,
|
||||
queryString: "?box[]=123&box[]=456"
|
||||
});
|
||||
|
||||
// Check headers
|
||||
let tabBody = yield selectNetInfoTab(hud, netInfoBody, "params");
|
||||
|
||||
let params = tabBody.querySelectorAll(
|
||||
".netInfoParamName > span[title='box[]']");
|
||||
is(params.length, 2, "Two URI parameters must exist");
|
||||
|
||||
let values = tabBody.querySelectorAll(
|
||||
".netInfoParamValue > code");
|
||||
is(values[0].textContent, 123, "First value must match");
|
||||
is(values[1].textContent, 456, "Second value must match");
|
||||
});
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include "mozilla/EffectCompositor.h"
|
||||
#include "mozilla/KeyframeEffectParams.h"
|
||||
#include "mozilla/LayerAnimationInfo.h" // LayerAnimations::kRecords
|
||||
#include "mozilla/ServoBindingHelpers.h" // ServoDeclarationBlock and
|
||||
#include "mozilla/ServoBindingHelpers.h" // RawServoDeclarationBlock and
|
||||
// associated RefPtrTraits
|
||||
#include "mozilla/StyleAnimationValue.h"
|
||||
#include "mozilla/dom/AnimationEffectReadOnly.h"
|
||||
@ -67,7 +67,7 @@ struct PropertyValuePair
|
||||
// The specified value when using the Servo backend. However, even when
|
||||
// using the Servo backend, we still fill in |mValue| in the case where we
|
||||
// fail to parse the value since we use it to store the original string.
|
||||
RefPtr<ServoDeclarationBlock> mServoDeclarationBlock;
|
||||
RefPtr<RawServoDeclarationBlock> mServoDeclarationBlock;
|
||||
|
||||
bool operator==(const PropertyValuePair& aOther) const {
|
||||
return mProperty == aOther.mProperty &&
|
||||
|
@ -1006,7 +1006,7 @@ MakePropertyValuePair(nsCSSPropertyID aProperty, const nsAString& aStringValue,
|
||||
nsCString baseString;
|
||||
aDocument->GetDocumentURI()->GetSpec(baseString);
|
||||
|
||||
RefPtr<ServoDeclarationBlock> servoDeclarationBlock =
|
||||
RefPtr<RawServoDeclarationBlock> servoDeclarationBlock =
|
||||
Servo_ParseProperty(
|
||||
reinterpret_cast<const uint8_t*>(name.get()), name.Length(),
|
||||
reinterpret_cast<const uint8_t*>(value.get()), value.Length(),
|
||||
|
@ -37,22 +37,6 @@ AppsService.prototype = {
|
||||
localId == Ci.nsIScriptSecurityManager.UNKNOWN_APP_ID);
|
||||
},
|
||||
|
||||
getManifestCSPByLocalId: function getCSPByLocalId(localId) {
|
||||
debug("GetManifestCSPByLocalId( " + localId + " )");
|
||||
if (this.isInvalidId(localId)) {
|
||||
return null;
|
||||
}
|
||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
},
|
||||
|
||||
getDefaultCSPByLocalId: function getCSPByLocalId(localId) {
|
||||
debug("GetDefaultCSPByLocalId( " + localId + " )");
|
||||
if (this.isInvalidId(localId)) {
|
||||
return null;
|
||||
}
|
||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
},
|
||||
|
||||
getAppByManifestURL: function getAppByManifestURL(aManifestURL) {
|
||||
debug("GetAppByManifestURL( " + aManifestURL + " )");
|
||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
@ -371,16 +371,6 @@ this.DOMApplicationRegistry = {
|
||||
return AppsUtils.getAppLocalIdByManifestURL(this.webapps, aManifestURL);
|
||||
},
|
||||
|
||||
getManifestCSPByLocalId: function(aLocalId) {
|
||||
debug("getManifestCSPByLocalId:" + aLocalId);
|
||||
return AppsUtils.getManifestCSPByLocalId(this.webapps, aLocalId);
|
||||
},
|
||||
|
||||
getDefaultCSPByLocalId: function(aLocalId) {
|
||||
debug("getDefaultCSPByLocalId:" + aLocalId);
|
||||
return AppsUtils.getDefaultCSPByLocalId(this.webapps, aLocalId);
|
||||
},
|
||||
|
||||
getAppLocalIdByStoreId: function(aStoreId) {
|
||||
debug("getAppLocalIdByStoreId:" + aStoreId);
|
||||
return AppsUtils.getAppLocalIdByStoreId(this.webapps, aStoreId);
|
||||
|
@ -262,43 +262,6 @@ this.AppsUtils = {
|
||||
return Ci.nsIScriptSecurityManager.NO_APP_ID;
|
||||
},
|
||||
|
||||
getManifestCSPByLocalId: function getManifestCSPByLocalId(aApps, aLocalId) {
|
||||
debug("getManifestCSPByLocalId " + aLocalId);
|
||||
for (let id in aApps) {
|
||||
let app = aApps[id];
|
||||
if (app.localId == aLocalId) {
|
||||
return ( app.csp || "" );
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
},
|
||||
|
||||
getDefaultCSPByLocalId: function(aApps, aLocalId) {
|
||||
debug("getDefaultCSPByLocalId " + aLocalId);
|
||||
for (let id in aApps) {
|
||||
let app = aApps[id];
|
||||
if (app.localId == aLocalId) {
|
||||
// Use the app status to choose the right default CSP.
|
||||
try {
|
||||
switch (app.appStatus) {
|
||||
case Ci.nsIPrincipal.APP_STATUS_CERTIFIED:
|
||||
return Services.prefs.getCharPref("security.apps.certified.CSP.default");
|
||||
break;
|
||||
case Ci.nsIPrincipal.APP_STATUS_PRIVILEGED:
|
||||
return Services.prefs.getCharPref("security.apps.privileged.CSP.default");
|
||||
break;
|
||||
case Ci.nsIPrincipal.APP_STATUS_INSTALLED:
|
||||
return "";
|
||||
break;
|
||||
}
|
||||
} catch(e) {}
|
||||
}
|
||||
}
|
||||
|
||||
return "default-src 'self'; object-src 'none'";
|
||||
},
|
||||
|
||||
getAppByLocalId: function getAppByLocalId(aApps, aLocalId) {
|
||||
debug("getAppByLocalId " + aLocalId);
|
||||
for (let id in aApps) {
|
||||
|
@ -562,7 +562,7 @@ IsNativeAnonymousImplementationOfPseudoElement(nsIContent* aContent)
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
StyleChildrenIterator::IsNeeded(Element* aElement)
|
||||
StyleChildrenIterator::IsNeeded(const Element* aElement)
|
||||
{
|
||||
// If the node is in an anonymous subtree, we conservatively return true to
|
||||
// handle insertion points.
|
||||
|
@ -35,7 +35,8 @@ namespace dom {
|
||||
class ExplicitChildIterator
|
||||
{
|
||||
public:
|
||||
explicit ExplicitChildIterator(nsIContent* aParent, bool aStartAtBeginning = true)
|
||||
explicit ExplicitChildIterator(const nsIContent* aParent,
|
||||
bool aStartAtBeginning = true)
|
||||
: mParent(aParent),
|
||||
mChild(nullptr),
|
||||
mDefaultChild(nullptr),
|
||||
@ -99,7 +100,7 @@ protected:
|
||||
// The parent of the children being iterated. For the FlattenedChildIterator,
|
||||
// if there is a binding attached to the original parent, mParent points to
|
||||
// the <xbl:content> element for the binding.
|
||||
nsIContent* mParent;
|
||||
const nsIContent* mParent;
|
||||
|
||||
// The current child. When we encounter an insertion point,
|
||||
// mChild remains as the insertion point whose content we're iterating (and
|
||||
@ -136,7 +137,8 @@ protected:
|
||||
class FlattenedChildIterator : public ExplicitChildIterator
|
||||
{
|
||||
public:
|
||||
explicit FlattenedChildIterator(nsIContent* aParent, bool aStartAtBeginning = true)
|
||||
explicit FlattenedChildIterator(const nsIContent* aParent,
|
||||
bool aStartAtBeginning = true)
|
||||
: ExplicitChildIterator(aParent, aStartAtBeginning), mXBLInvolved(false)
|
||||
{
|
||||
Init(false);
|
||||
@ -155,7 +157,8 @@ protected:
|
||||
* This constructor is a hack to help AllChildrenIterator which sometimes
|
||||
* doesn't want to consider XBL.
|
||||
*/
|
||||
FlattenedChildIterator(nsIContent* aParent, uint32_t aFlags, bool aStartAtBeginning = true)
|
||||
FlattenedChildIterator(const nsIContent* aParent, uint32_t aFlags,
|
||||
bool aStartAtBeginning = true)
|
||||
: ExplicitChildIterator(aParent, aStartAtBeginning), mXBLInvolved(false)
|
||||
{
|
||||
bool ignoreXBL = aFlags & nsIContent::eAllButXBL;
|
||||
@ -181,7 +184,8 @@ protected:
|
||||
class AllChildrenIterator : private FlattenedChildIterator
|
||||
{
|
||||
public:
|
||||
AllChildrenIterator(nsIContent* aNode, uint32_t aFlags, bool aStartAtBeginning = true) :
|
||||
AllChildrenIterator(const nsIContent* aNode, uint32_t aFlags,
|
||||
bool aStartAtBeginning = true) :
|
||||
FlattenedChildIterator(aNode, aFlags, aStartAtBeginning),
|
||||
mOriginalContent(aNode), mAnonKidsIdx(aStartAtBeginning ? UINT32_MAX : 0),
|
||||
mFlags(aFlags), mPhase(aStartAtBeginning ? eAtBegin : eAtEnd) { }
|
||||
@ -211,7 +215,7 @@ public:
|
||||
|
||||
nsIContent* GetNextChild();
|
||||
nsIContent* GetPreviousChild();
|
||||
nsIContent* Parent() const { return mOriginalContent; }
|
||||
const nsIContent* Parent() const { return mOriginalContent; }
|
||||
|
||||
enum IteratorPhase
|
||||
{
|
||||
@ -229,7 +233,7 @@ private:
|
||||
void AppendNativeAnonymousChildren();
|
||||
void AppendNativeAnonymousChildrenFromFrame(nsIFrame* aFrame);
|
||||
|
||||
nsIContent* mOriginalContent;
|
||||
const nsIContent* mOriginalContent;
|
||||
|
||||
// mAnonKids is an array of native anonymous children, mAnonKidsIdx is index
|
||||
// in the array. If mAnonKidsIdx < mAnonKids.Length() and mPhase is
|
||||
@ -262,7 +266,7 @@ private:
|
||||
*/
|
||||
class StyleChildrenIterator : private AllChildrenIterator {
|
||||
public:
|
||||
explicit StyleChildrenIterator(nsIContent* aContent)
|
||||
explicit StyleChildrenIterator(const nsIContent* aContent)
|
||||
: AllChildrenIterator(aContent, nsIContent::eAllChildren)
|
||||
{
|
||||
MOZ_COUNT_CTOR(StyleChildrenIterator);
|
||||
@ -273,7 +277,7 @@ public:
|
||||
|
||||
// Returns true if we cannot find all the children we need to style by
|
||||
// traversing the siblings of the first child.
|
||||
static bool IsNeeded(Element* aParent);
|
||||
static bool IsNeeded(const Element* aParent);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -2014,14 +2014,14 @@ Element::IsInteractiveHTMLContent(bool aIgnoreTabindex) const
|
||||
return false;
|
||||
}
|
||||
|
||||
css::Declaration*
|
||||
DeclarationBlock*
|
||||
Element::GetInlineStyleDeclaration()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Element::SetInlineStyleDeclaration(css::Declaration* aDeclaration,
|
||||
Element::SetInlineStyleDeclaration(DeclarationBlock* aDeclaration,
|
||||
const nsAString* aSerialized,
|
||||
bool aNotify)
|
||||
{
|
||||
|
@ -56,6 +56,7 @@ class nsDocument;
|
||||
class nsDOMStringMap;
|
||||
|
||||
namespace mozilla {
|
||||
class DeclarationBlock;
|
||||
namespace dom {
|
||||
struct AnimationFilter;
|
||||
struct ScrollIntoViewOptions;
|
||||
@ -254,13 +255,13 @@ public:
|
||||
/**
|
||||
* Get the inline style declaration, if any, for this element.
|
||||
*/
|
||||
virtual css::Declaration* GetInlineStyleDeclaration();
|
||||
virtual DeclarationBlock* GetInlineStyleDeclaration();
|
||||
|
||||
/**
|
||||
* Set the inline style declaration for this element. This will send
|
||||
* an appropriate AttributeChanged notification if aNotify is true.
|
||||
*/
|
||||
virtual nsresult SetInlineStyleDeclaration(css::Declaration* aDeclaration,
|
||||
virtual nsresult SetInlineStyleDeclaration(DeclarationBlock* aDeclaration,
|
||||
const nsAString* aSerialized,
|
||||
bool aNotify);
|
||||
|
||||
|
@ -33,6 +33,9 @@ class nsDOMStringMap;
|
||||
class nsIURI;
|
||||
|
||||
namespace mozilla {
|
||||
namespace css {
|
||||
class Declaration;
|
||||
} // namespace css
|
||||
namespace dom {
|
||||
class Element;
|
||||
} // namespace dom
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/ServoBindingHelpers.h"
|
||||
#include "mozilla/css/Declaration.h"
|
||||
#include "mozilla/DeclarationBlockInlines.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "prprf.h"
|
||||
@ -73,26 +73,16 @@ void
|
||||
MiscContainer::Cache()
|
||||
{
|
||||
// Not implemented for anything else yet.
|
||||
MOZ_ASSERT(mType == nsAttrValue::eGeckoCSSDeclaration ||
|
||||
mType == nsAttrValue::eServoCSSDeclaration);
|
||||
if (mType != nsAttrValue::eCSSDeclaration) {
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected cached nsAttrValue type");
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(IsRefCounted());
|
||||
MOZ_ASSERT(mValue.mRefCount > 0);
|
||||
MOZ_ASSERT(!mValue.mCached);
|
||||
|
||||
nsHTMLCSSStyleSheet* sheet;
|
||||
switch (mType) {
|
||||
case nsAttrValue::eGeckoCSSDeclaration:
|
||||
sheet = mValue.mGeckoCSSDeclaration->GetHTMLCSSStyleSheet();
|
||||
break;
|
||||
case nsAttrValue::eServoCSSDeclaration:
|
||||
sheet = Servo_DeclarationBlock_GetCache(mValue.mServoCSSDeclaration);
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected cached nsAttrValue type");
|
||||
sheet = nullptr;
|
||||
break;
|
||||
}
|
||||
|
||||
nsHTMLCSSStyleSheet* sheet = mValue.mCSSDeclaration->GetHTMLCSSStyleSheet();
|
||||
if (!sheet) {
|
||||
return;
|
||||
}
|
||||
@ -107,25 +97,17 @@ MiscContainer::Cache()
|
||||
mValue.mCached = 1;
|
||||
|
||||
// This has to be immutable once it goes into the cache.
|
||||
switch (mType) {
|
||||
case nsAttrValue::eGeckoCSSDeclaration:
|
||||
mValue.mGeckoCSSDeclaration->SetImmutable();
|
||||
break;
|
||||
case nsAttrValue::eServoCSSDeclaration:
|
||||
Servo_DeclarationBlock_SetImmutable(mValue.mServoCSSDeclaration);
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected cached nsAttrValue type");
|
||||
break;
|
||||
}
|
||||
mValue.mCSSDeclaration->SetImmutable();
|
||||
}
|
||||
|
||||
void
|
||||
MiscContainer::Evict()
|
||||
{
|
||||
// Not implemented for anything else yet.
|
||||
MOZ_ASSERT(mType == nsAttrValue::eGeckoCSSDeclaration ||
|
||||
mType == nsAttrValue::eServoCSSDeclaration);
|
||||
if (mType != nsAttrValue::eCSSDeclaration) {
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected cached nsAttrValue type");
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(IsRefCounted());
|
||||
MOZ_ASSERT(mValue.mRefCount == 0);
|
||||
|
||||
@ -133,19 +115,7 @@ MiscContainer::Evict()
|
||||
return;
|
||||
}
|
||||
|
||||
nsHTMLCSSStyleSheet* sheet;
|
||||
switch (mType) {
|
||||
case nsAttrValue::eGeckoCSSDeclaration:
|
||||
sheet = mValue.mGeckoCSSDeclaration->GetHTMLCSSStyleSheet();
|
||||
break;
|
||||
case nsAttrValue::eServoCSSDeclaration:
|
||||
sheet = Servo_DeclarationBlock_GetCache(mValue.mServoCSSDeclaration);
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected cached nsAttrValue type");
|
||||
sheet = nullptr;
|
||||
break;
|
||||
}
|
||||
nsHTMLCSSStyleSheet* sheet = mValue.mCSSDeclaration->GetHTMLCSSStyleSheet();
|
||||
MOZ_ASSERT(sheet);
|
||||
|
||||
nsString str;
|
||||
@ -181,10 +151,11 @@ nsAttrValue::nsAttrValue(nsIAtom* aValue)
|
||||
SetTo(aValue);
|
||||
}
|
||||
|
||||
nsAttrValue::nsAttrValue(css::Declaration* aValue, const nsAString* aSerialized)
|
||||
nsAttrValue::nsAttrValue(already_AddRefed<DeclarationBlock> aValue,
|
||||
const nsAString* aSerialized)
|
||||
: mBits(0)
|
||||
{
|
||||
SetTo(aValue, aSerialized);
|
||||
SetTo(Move(aValue), aSerialized);
|
||||
}
|
||||
|
||||
nsAttrValue::nsAttrValue(const nsIntMargin& aValue)
|
||||
@ -343,8 +314,7 @@ nsAttrValue::SetTo(const nsAttrValue& aOther)
|
||||
cont->mValue.mColor = otherCont->mValue.mColor;
|
||||
break;
|
||||
}
|
||||
case eGeckoCSSDeclaration:
|
||||
case eServoCSSDeclaration:
|
||||
case eCSSDeclaration:
|
||||
{
|
||||
MOZ_CRASH("These should be refcounted!");
|
||||
}
|
||||
@ -451,25 +421,13 @@ nsAttrValue::SetTo(double aValue, const nsAString* aSerialized)
|
||||
}
|
||||
|
||||
void
|
||||
nsAttrValue::SetTo(css::Declaration* aValue, const nsAString* aSerialized)
|
||||
{
|
||||
MiscContainer* cont = EnsureEmptyMiscContainer();
|
||||
MOZ_ASSERT(cont->mValue.mRefCount == 0);
|
||||
NS_ADDREF(cont->mValue.mGeckoCSSDeclaration = aValue);
|
||||
cont->mType = eGeckoCSSDeclaration;
|
||||
NS_ADDREF(cont);
|
||||
SetMiscAtomOrString(aSerialized);
|
||||
MOZ_ASSERT(cont->mValue.mRefCount == 1);
|
||||
}
|
||||
|
||||
void
|
||||
nsAttrValue::SetTo(already_AddRefed<ServoDeclarationBlock> aValue,
|
||||
nsAttrValue::SetTo(already_AddRefed<DeclarationBlock> aValue,
|
||||
const nsAString* aSerialized)
|
||||
{
|
||||
MiscContainer* cont = EnsureEmptyMiscContainer();
|
||||
MOZ_ASSERT(cont->mValue.mRefCount == 0);
|
||||
cont->mValue.mServoCSSDeclaration = aValue.take();
|
||||
cont->mType = eServoCSSDeclaration;
|
||||
cont->mValue.mCSSDeclaration = aValue.take();
|
||||
cont->mType = eCSSDeclaration;
|
||||
NS_ADDREF(cont);
|
||||
SetMiscAtomOrString(aSerialized);
|
||||
MOZ_ASSERT(cont->mValue.mRefCount == 1);
|
||||
@ -682,17 +640,15 @@ nsAttrValue::ToString(nsAString& aResult) const
|
||||
|
||||
break;
|
||||
}
|
||||
case eGeckoCSSDeclaration:
|
||||
case eCSSDeclaration:
|
||||
{
|
||||
// XXXheycam Once we support CSSOM access to them, we should
|
||||
// probably serialize eServoCSSDeclarations like this too.
|
||||
// For now, we will return the string from the MiscContainer
|
||||
// at the top of this function.
|
||||
aResult.Truncate();
|
||||
MiscContainer *container = GetMiscContainer();
|
||||
css::Declaration *decl = container->mValue.mGeckoCSSDeclaration;
|
||||
if (decl) {
|
||||
decl->ToString(aResult);
|
||||
DeclarationBlock* decl = container->mValue.mCSSDeclaration;
|
||||
// XXXheycam Once we support CSSOM access to them, we should
|
||||
// probably serialize ServoDeclarationBlock like this too.
|
||||
if (decl && decl->IsGecko()) {
|
||||
decl->AsGecko()->ToString(aResult);
|
||||
}
|
||||
const_cast<nsAttrValue*>(this)->SetMiscAtomOrString(&aResult);
|
||||
|
||||
@ -935,13 +891,9 @@ nsAttrValue::HashValue() const
|
||||
{
|
||||
return cont->mValue.mColor;
|
||||
}
|
||||
case eGeckoCSSDeclaration:
|
||||
case eCSSDeclaration:
|
||||
{
|
||||
return NS_PTR_TO_INT32(cont->mValue.mGeckoCSSDeclaration);
|
||||
}
|
||||
case eServoCSSDeclaration:
|
||||
{
|
||||
return NS_PTR_TO_INT32(cont->mValue.mServoCSSDeclaration);
|
||||
return NS_PTR_TO_INT32(cont->mValue.mCSSDeclaration);
|
||||
}
|
||||
// Intentionally identical, so that loading the image does not change the
|
||||
// hash code.
|
||||
@ -1048,10 +1000,10 @@ nsAttrValue::Equals(const nsAttrValue& aOther) const
|
||||
}
|
||||
break;
|
||||
}
|
||||
case eGeckoCSSDeclaration:
|
||||
case eCSSDeclaration:
|
||||
{
|
||||
return thisCont->mValue.mGeckoCSSDeclaration ==
|
||||
otherCont->mValue.mGeckoCSSDeclaration;
|
||||
return thisCont->mValue.mCSSDeclaration ==
|
||||
otherCont->mValue.mCSSDeclaration;
|
||||
}
|
||||
case eURL:
|
||||
{
|
||||
@ -1081,11 +1033,6 @@ nsAttrValue::Equals(const nsAttrValue& aOther) const
|
||||
{
|
||||
return thisCont->mValue.mIntMargin == otherCont->mValue.mIntMargin;
|
||||
}
|
||||
case eServoCSSDeclaration:
|
||||
{
|
||||
return thisCont->mValue.mServoCSSDeclaration ==
|
||||
otherCont->mValue.mServoCSSDeclaration;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (IsSVGType(thisCont->mType)) {
|
||||
@ -1771,26 +1718,20 @@ nsAttrValue::ParseStyleAttribute(const nsAString& aString,
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<DeclarationBlock> decl;
|
||||
if (ownerDoc->GetStyleBackendType() == StyleBackendType::Servo) {
|
||||
NS_ConvertUTF16toUTF8 value(aString);
|
||||
RefPtr<ServoDeclarationBlock> decl = Servo_ParseStyleAttribute(
|
||||
reinterpret_cast<const uint8_t*>(value.get()),
|
||||
value.Length(), sheet).Consume();
|
||||
MOZ_ASSERT(decl);
|
||||
SetTo(decl.forget(), &aString);
|
||||
decl = ServoDeclarationBlock::FromStyleAttribute(aString);
|
||||
} else {
|
||||
css::Loader* cssLoader = ownerDoc->CSSLoader();
|
||||
nsCSSParser cssParser(cssLoader);
|
||||
|
||||
RefPtr<css::Declaration> declaration =
|
||||
cssParser.ParseStyleAttribute(aString, docURI, baseURI,
|
||||
aElement->NodePrincipal());
|
||||
if (!declaration) {
|
||||
return false;
|
||||
}
|
||||
declaration->SetHTMLCSSStyleSheet(sheet);
|
||||
SetTo(declaration, &aString);
|
||||
decl = cssParser.ParseStyleAttribute(aString, docURI, baseURI,
|
||||
aElement->NodePrincipal());
|
||||
}
|
||||
if (!decl) {
|
||||
return false;
|
||||
}
|
||||
decl->SetHTMLCSSStyleSheet(sheet);
|
||||
SetTo(decl.forget(), &aString);
|
||||
|
||||
if (cachingAllowed) {
|
||||
MiscContainer* cont = GetMiscContainer();
|
||||
@ -1808,15 +1749,14 @@ nsAttrValue::SetMiscAtomOrString(const nsAString* aValue)
|
||||
"Trying to re-set atom or string!");
|
||||
if (aValue) {
|
||||
uint32_t len = aValue->Length();
|
||||
// * We're allowing eGeckoCSSDeclaration and eServoCSSDeclaration
|
||||
// attributes to store empty strings as it can be beneficial to store
|
||||
// an empty style attribute as a parsed rule.
|
||||
// * We're allowing eCSSDeclaration attributes to store empty
|
||||
// strings as it can be beneficial to store an empty style
|
||||
// attribute as a parsed rule.
|
||||
// * We're allowing enumerated values because sometimes the empty
|
||||
// string corresponds to a particular enumerated value, especially
|
||||
// for enumerated values that are not limited enumerated.
|
||||
// Add other types as needed.
|
||||
NS_ASSERTION(len || Type() == eGeckoCSSDeclaration ||
|
||||
Type() == eServoCSSDeclaration || Type() == eEnum,
|
||||
NS_ASSERTION(len || Type() == eCSSDeclaration || Type() == eEnum,
|
||||
"Empty string?");
|
||||
MiscContainer* cont = GetMiscContainer();
|
||||
if (len <= NS_ATTRVALUE_MAX_STRINGLENGTH_ATOM) {
|
||||
@ -1880,17 +1820,12 @@ nsAttrValue::ClearMiscContainer()
|
||||
}
|
||||
else {
|
||||
switch (cont->mType) {
|
||||
case eGeckoCSSDeclaration:
|
||||
case eServoCSSDeclaration:
|
||||
case eCSSDeclaration:
|
||||
{
|
||||
MOZ_ASSERT(cont->mValue.mRefCount == 1);
|
||||
cont->Release();
|
||||
cont->Evict();
|
||||
if (cont->mType == eGeckoCSSDeclaration) {
|
||||
NS_RELEASE(cont->mValue.mGeckoCSSDeclaration);
|
||||
} else {
|
||||
Servo_DeclarationBlock_Release(cont->mValue.mServoCSSDeclaration);
|
||||
}
|
||||
NS_RELEASE(cont->mValue.mCSSDeclaration);
|
||||
break;
|
||||
}
|
||||
case eURL:
|
||||
@ -2020,16 +1955,12 @@ nsAttrValue::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
|
||||
n += str ? str->SizeOfIncludingThisIfUnshared(aMallocSizeOf) : 0;
|
||||
}
|
||||
|
||||
if (Type() == eGeckoCSSDeclaration &&
|
||||
container->mValue.mGeckoCSSDeclaration) {
|
||||
// TODO: mGeckoCSSDeclaration might be owned by another object which
|
||||
if (Type() == eCSSDeclaration && container->mValue.mCSSDeclaration) {
|
||||
// TODO: mCSSDeclaration might be owned by another object which
|
||||
// would make us count them twice, bug 677493.
|
||||
//n += container->mGeckoCSSDeclaration->SizeOfIncludingThis(aMallocSizeOf);
|
||||
} else if (Type() == eServoCSSDeclaration &&
|
||||
container->mValue.mServoCSSDeclaration) {
|
||||
// Bug 1281964: As with eGeckoCSSDeclaration, but if we do measure we'll
|
||||
// need a way to call the Servo heap_size_of function for the
|
||||
// declaration block.
|
||||
// Bug 1281964: For ServoDeclarationBlock if we do measure we'll
|
||||
// need a way to call the Servo heap_size_of function.
|
||||
//n += container->mCSSDeclaration->SizeOfIncludingThis(aMallocSizeOf);
|
||||
} else if (Type() == eAtomArray && container->mValue.mAtomArray) {
|
||||
// Don't measure each nsIAtom, they are measured separatly.
|
||||
n += container->mValue.mAtomArray->ShallowSizeOfIncludingThis(aMallocSizeOf);
|
||||
|
@ -35,11 +35,10 @@ class nsAString;
|
||||
class nsIDocument;
|
||||
class nsStyledElement;
|
||||
struct MiscContainer;
|
||||
struct ServoDeclarationBlock;
|
||||
|
||||
namespace mozilla {
|
||||
class DeclarationBlock;
|
||||
namespace css {
|
||||
class Declaration;
|
||||
struct URLValue;
|
||||
struct ImageValue;
|
||||
} // namespace css
|
||||
@ -98,8 +97,7 @@ public:
|
||||
ePercent = 0x0F, // 1111
|
||||
// Values below here won't matter, they'll be always stored in the 'misc'
|
||||
// struct.
|
||||
eGeckoCSSDeclaration = 0x10,
|
||||
eServoCSSDeclaration,
|
||||
eCSSDeclaration = 0x10,
|
||||
eURL,
|
||||
eImage,
|
||||
eAtomArray,
|
||||
@ -125,7 +123,8 @@ public:
|
||||
nsAttrValue(const nsAttrValue& aOther);
|
||||
explicit nsAttrValue(const nsAString& aValue);
|
||||
explicit nsAttrValue(nsIAtom* aValue);
|
||||
nsAttrValue(mozilla::css::Declaration* aValue, const nsAString* aSerialized);
|
||||
nsAttrValue(already_AddRefed<mozilla::DeclarationBlock> aValue,
|
||||
const nsAString* aSerialized);
|
||||
explicit nsAttrValue(const nsIntMargin& aValue);
|
||||
~nsAttrValue();
|
||||
|
||||
@ -150,8 +149,7 @@ public:
|
||||
void SetTo(int16_t aInt);
|
||||
void SetTo(int32_t aInt, const nsAString* aSerialized);
|
||||
void SetTo(double aValue, const nsAString* aSerialized);
|
||||
void SetTo(mozilla::css::Declaration* aValue, const nsAString* aSerialized);
|
||||
void SetTo(already_AddRefed<ServoDeclarationBlock> aDeclarationBlock,
|
||||
void SetTo(already_AddRefed<mozilla::DeclarationBlock> aValue,
|
||||
const nsAString* aSerialized);
|
||||
void SetTo(mozilla::css::URLValue* aValue, const nsAString* aSerialized);
|
||||
void SetTo(const nsIntMargin& aValue);
|
||||
@ -203,8 +201,7 @@ public:
|
||||
inline int16_t GetEnumValue() const;
|
||||
inline float GetPercentValue() const;
|
||||
inline AtomArray* GetAtomArrayValue() const;
|
||||
inline mozilla::css::Declaration* GetGeckoCSSDeclarationValue() const;
|
||||
inline ServoDeclarationBlock* GetServoCSSDeclarationValue() const;
|
||||
inline mozilla::DeclarationBlock* GetCSSDeclarationValue() const;
|
||||
inline mozilla::css::URLValue* GetURLValue() const;
|
||||
inline mozilla::css::ImageValue* GetImageValue() const;
|
||||
inline double GetDoubleValue() const;
|
||||
|
@ -20,7 +20,7 @@ struct MiscContainer final
|
||||
|
||||
ValueType mType;
|
||||
// mStringBits points to either nsIAtom* or nsStringBuffer* and is used when
|
||||
// mType isn't eGeckoCSSDeclaration.
|
||||
// mType isn't eCSSDeclaration.
|
||||
// Note eStringBase and eAtomBase is used also to handle the type of
|
||||
// mStringBits.
|
||||
uintptr_t mStringBits;
|
||||
@ -31,8 +31,7 @@ struct MiscContainer final
|
||||
nscolor mColor;
|
||||
uint32_t mEnumValue;
|
||||
int32_t mPercent;
|
||||
mozilla::css::Declaration* mGeckoCSSDeclaration;
|
||||
ServoDeclarationBlock* mServoCSSDeclaration;
|
||||
mozilla::DeclarationBlock* mCSSDeclaration;
|
||||
mozilla::css::URLValue* mURL;
|
||||
mozilla::css::ImageValue* mImage;
|
||||
nsAttrValue::AtomArray* mAtomArray;
|
||||
@ -87,8 +86,7 @@ public:
|
||||
// Nothing stops us from refcounting (and sharing) other types of
|
||||
// MiscContainer (except eDoubleValue types) but there's no compelling
|
||||
// reason to.
|
||||
return mType == nsAttrValue::eGeckoCSSDeclaration ||
|
||||
mType == nsAttrValue::eServoCSSDeclaration;
|
||||
return mType == nsAttrValue::eCSSDeclaration;
|
||||
}
|
||||
|
||||
inline int32_t AddRef() {
|
||||
@ -148,18 +146,11 @@ nsAttrValue::GetAtomArrayValue() const
|
||||
return GetMiscContainer()->mValue.mAtomArray;
|
||||
}
|
||||
|
||||
inline mozilla::css::Declaration*
|
||||
nsAttrValue::GetGeckoCSSDeclarationValue() const
|
||||
inline mozilla::DeclarationBlock*
|
||||
nsAttrValue::GetCSSDeclarationValue() const
|
||||
{
|
||||
NS_PRECONDITION(Type() == eGeckoCSSDeclaration, "wrong type");
|
||||
return GetMiscContainer()->mValue.mGeckoCSSDeclaration;
|
||||
}
|
||||
|
||||
inline ServoDeclarationBlock*
|
||||
nsAttrValue::GetServoCSSDeclarationValue() const
|
||||
{
|
||||
NS_PRECONDITION(Type() == eServoCSSDeclaration, "wrong type");
|
||||
return GetMiscContainer()->mValue.mServoCSSDeclaration;
|
||||
NS_PRECONDITION(Type() == eCSSDeclaration, "wrong type");
|
||||
return GetMiscContainer()->mValue.mCSSDeclaration;
|
||||
}
|
||||
|
||||
inline mozilla::css::URLValue*
|
||||
@ -207,9 +198,7 @@ nsAttrValue::StoresOwnData() const
|
||||
return true;
|
||||
}
|
||||
ValueType t = Type();
|
||||
return t != eGeckoCSSDeclaration &&
|
||||
t != eServoCSSDeclaration &&
|
||||
!IsSVGType(t);
|
||||
return t != eCSSDeclaration && !IsSVGType(t);
|
||||
}
|
||||
|
||||
inline void
|
||||
|
@ -203,7 +203,6 @@
|
||||
#include "nsWrapperCacheInlines.h"
|
||||
#include "nsSandboxFlags.h"
|
||||
#include "nsIAddonPolicyService.h"
|
||||
#include "nsIAppsService.h"
|
||||
#include "mozilla/dom/AnimatableBinding.h"
|
||||
#include "mozilla/dom/AnonymousContent.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
@ -2544,32 +2543,9 @@ nsDocument::InitCSP(nsIChannel* aChannel)
|
||||
NS_ConvertASCIItoUTF16 cspHeaderValue(tCspHeaderValue);
|
||||
NS_ConvertASCIItoUTF16 cspROHeaderValue(tCspROHeaderValue);
|
||||
|
||||
// Figure out if we need to apply an app default CSP or a CSP from an app manifest
|
||||
nsCOMPtr<nsIPrincipal> principal = NodePrincipal();
|
||||
|
||||
uint16_t appStatus = principal->GetAppStatus();
|
||||
bool applyAppDefaultCSP = false;
|
||||
bool applyAppManifestCSP = false;
|
||||
|
||||
nsAutoString appManifestCSP;
|
||||
nsAutoString appDefaultCSP;
|
||||
if (appStatus != nsIPrincipal::APP_STATUS_NOT_INSTALLED) {
|
||||
nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
|
||||
if (appsService) {
|
||||
uint32_t appId = principal->GetAppId();
|
||||
appsService->GetManifestCSPByLocalId(appId, appManifestCSP);
|
||||
if (!appManifestCSP.IsEmpty()) {
|
||||
applyAppManifestCSP = true;
|
||||
}
|
||||
appsService->GetDefaultCSPByLocalId(appId, appDefaultCSP);
|
||||
if (!appDefaultCSP.IsEmpty()) {
|
||||
applyAppDefaultCSP = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if this is a document from a WebExtension.
|
||||
nsString addonId;
|
||||
nsCOMPtr<nsIPrincipal> principal = NodePrincipal();
|
||||
principal->GetAddonId(addonId);
|
||||
bool applyAddonCSP = !addonId.IsEmpty();
|
||||
|
||||
@ -2581,9 +2557,7 @@ nsDocument::InitCSP(nsIChannel* aChannel)
|
||||
}
|
||||
|
||||
// If there's no CSP to apply, go ahead and return early
|
||||
if (!applyAppDefaultCSP &&
|
||||
!applyAppManifestCSP &&
|
||||
!applyAddonCSP &&
|
||||
if (!applyAddonCSP &&
|
||||
!applySignedContentCSP &&
|
||||
cspHeaderValue.IsEmpty() &&
|
||||
cspROHeaderValue.IsEmpty()) {
|
||||
@ -2593,53 +2567,19 @@ nsDocument::InitCSP(nsIChannel* aChannel)
|
||||
nsAutoCString aspec;
|
||||
chanURI->GetAsciiSpec(aspec);
|
||||
MOZ_LOG(gCspPRLog, LogLevel::Debug,
|
||||
("no CSP for document, %s, %s",
|
||||
aspec.get(),
|
||||
applyAppDefaultCSP ? "is app" : "not an app"));
|
||||
("no CSP for document, %s",
|
||||
aspec.get()));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_LOG(gCspPRLog, LogLevel::Debug, ("Document is an app or CSP header specified %p", this));
|
||||
|
||||
// If Document is an app check to see if we already set CSP and return early
|
||||
// if that is indeed the case.
|
||||
//
|
||||
// In general (see bug 947831), we should not be setting CSP on a principal
|
||||
// that aliases another document. For non-app code this is not a problem
|
||||
// since we only share the underlying principal with nested browsing
|
||||
// contexts for which a header cannot be set (e.g., about:blank and
|
||||
// about:srcodoc iframes) and thus won't try to set the CSP again. This
|
||||
// check ensures that we do not try to set CSP for an app.
|
||||
if (applyAppDefaultCSP || applyAppManifestCSP) {
|
||||
nsCOMPtr<nsIContentSecurityPolicy> csp;
|
||||
rv = principal->GetCsp(getter_AddRefs(csp));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (csp) {
|
||||
MOZ_LOG(gCspPRLog, LogLevel::Debug, ("%s %s %s",
|
||||
"This document is sharing principal with another document.",
|
||||
"Since the document is an app, CSP was already set.",
|
||||
"Skipping attempt to set CSP."));
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
MOZ_LOG(gCspPRLog, LogLevel::Debug, ("Document is an add-on or CSP header specified %p", this));
|
||||
|
||||
nsCOMPtr<nsIContentSecurityPolicy> csp;
|
||||
rv = principal->EnsureCSP(this, getter_AddRefs(csp));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// ----- if the doc is an app and we want a default CSP, apply it.
|
||||
if (applyAppDefaultCSP) {
|
||||
csp->AppendPolicy(appDefaultCSP, false, false);
|
||||
}
|
||||
|
||||
// ----- if the doc is an app and specifies a CSP in its manifest, apply it.
|
||||
if (applyAppManifestCSP) {
|
||||
csp->AppendPolicy(appManifestCSP, false, false);
|
||||
}
|
||||
|
||||
// ----- if the doc is an addon, apply its CSP.
|
||||
if (applyAddonCSP) {
|
||||
nsCOMPtr<nsIAddonPolicyService> aps = do_GetService("@mozilla.org/addons/policy-service;1");
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "mozIApplication.h"
|
||||
#include "nsDocShell.h"
|
||||
#include "nsIAppsService.h"
|
||||
#include "nsIDOMHTMLIFrameElement.h"
|
||||
#include "nsIDOMHTMLFrameElement.h"
|
||||
#include "nsIDOMMozBrowserFrame.h"
|
||||
|
@ -247,7 +247,7 @@ public:
|
||||
/**
|
||||
* Returns true if in a chrome document
|
||||
*/
|
||||
virtual bool IsInChromeDocument();
|
||||
virtual bool IsInChromeDocument() const;
|
||||
|
||||
/**
|
||||
* Get the namespace that this element's tag is defined in
|
||||
|
@ -19,7 +19,7 @@ nsIContent::IsInHTMLDocument() const
|
||||
}
|
||||
|
||||
inline bool
|
||||
nsIContent::IsInChromeDocument()
|
||||
nsIContent::IsInChromeDocument() const
|
||||
{
|
||||
return nsContentUtils::IsChromeDoc(OwnerDoc());
|
||||
}
|
||||
|
@ -1453,15 +1453,7 @@ nsObjectLoadingContent::ObjectState() const
|
||||
return NS_EVENT_STATE_BROKEN | NS_EVENT_STATE_HANDLER_BLOCKED;
|
||||
case eFallbackCrashed:
|
||||
return NS_EVENT_STATE_BROKEN | NS_EVENT_STATE_HANDLER_CRASHED;
|
||||
case eFallbackUnsupported: {
|
||||
// Check to see if plugins are blocked on this platform.
|
||||
char* pluginsBlocked = PR_GetEnv("MOZ_PLUGINS_BLOCKED");
|
||||
if (pluginsBlocked && pluginsBlocked[0] == '1') {
|
||||
return NS_EVENT_STATE_BROKEN | NS_EVENT_STATE_TYPE_UNSUPPORTED_PLATFORM;
|
||||
} else {
|
||||
return NS_EVENT_STATE_BROKEN | NS_EVENT_STATE_TYPE_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
case eFallbackUnsupported:
|
||||
case eFallbackOutdated:
|
||||
case eFallbackAlternate:
|
||||
return NS_EVENT_STATE_BROKEN;
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "nsDOMCSSAttrDeclaration.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "mozilla/css/Declaration.h"
|
||||
#include "mozilla/DeclarationBlockInlines.h"
|
||||
#include "nsCSSParser.h"
|
||||
#include "mozilla/css/Loader.h"
|
||||
#include "nsIDOMMutationEvent.h"
|
||||
@ -49,7 +49,7 @@ nsStyledElement::ParseAttribute(int32_t aNamespaceID,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsStyledElement::SetInlineStyleDeclaration(css::Declaration* aDeclaration,
|
||||
nsStyledElement::SetInlineStyleDeclaration(DeclarationBlock* aDeclaration,
|
||||
const nsAString* aSerialized,
|
||||
bool aNotify)
|
||||
{
|
||||
@ -81,7 +81,7 @@ nsStyledElement::SetInlineStyleDeclaration(css::Declaration* aDeclaration,
|
||||
modification = !!mAttrsAndChildren.GetAttr(nsGkAtoms::style);
|
||||
}
|
||||
|
||||
nsAttrValue attrValue(aDeclaration, aSerialized);
|
||||
nsAttrValue attrValue(do_AddRef(aDeclaration), aSerialized);
|
||||
|
||||
// XXXbz do we ever end up with ADDITION here? I doubt it.
|
||||
uint8_t modType = modification ?
|
||||
@ -93,7 +93,7 @@ nsStyledElement::SetInlineStyleDeclaration(css::Declaration* aDeclaration,
|
||||
aNotify, kDontCallAfterSetAttr);
|
||||
}
|
||||
|
||||
css::Declaration*
|
||||
DeclarationBlock*
|
||||
nsStyledElement::GetInlineStyleDeclaration()
|
||||
{
|
||||
if (!MayHaveStyle()) {
|
||||
@ -101,8 +101,8 @@ nsStyledElement::GetInlineStyleDeclaration()
|
||||
}
|
||||
const nsAttrValue* attrVal = mAttrsAndChildren.GetAttr(nsGkAtoms::style);
|
||||
|
||||
if (attrVal && attrVal->Type() == nsAttrValue::eGeckoCSSDeclaration) {
|
||||
return attrVal->GetGeckoCSSDeclarationValue();
|
||||
if (attrVal && attrVal->Type() == nsAttrValue::eCSSDeclaration) {
|
||||
return attrVal->GetCSSDeclarationValue();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
@ -134,13 +134,7 @@ nsStyledElement::ReparseStyleAttribute(bool aForceInDataDoc)
|
||||
return NS_OK;
|
||||
}
|
||||
const nsAttrValue* oldVal = mAttrsAndChildren.GetAttr(nsGkAtoms::style);
|
||||
|
||||
nsAttrValue::ValueType desiredType =
|
||||
OwnerDoc()->GetStyleBackendType() == StyleBackendType::Gecko ?
|
||||
nsAttrValue::eGeckoCSSDeclaration :
|
||||
nsAttrValue::eServoCSSDeclaration;
|
||||
|
||||
if (oldVal && oldVal->Type() != desiredType) {
|
||||
if (oldVal && oldVal->Type() != nsAttrValue::eCSSDeclaration) {
|
||||
nsAttrValue attrValue;
|
||||
nsAutoString stringValue;
|
||||
oldVal->ToString(stringValue);
|
||||
|
@ -18,9 +18,7 @@
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace css {
|
||||
class Declaration;
|
||||
} // namespace css
|
||||
class DeclarationBlock;
|
||||
} // namespace mozilla
|
||||
|
||||
// IID for nsStyledElement interface
|
||||
@ -46,8 +44,8 @@ public:
|
||||
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
|
||||
|
||||
// Element interface methods
|
||||
virtual mozilla::css::Declaration* GetInlineStyleDeclaration() override;
|
||||
virtual nsresult SetInlineStyleDeclaration(mozilla::css::Declaration* aDeclaration,
|
||||
virtual mozilla::DeclarationBlock* GetInlineStyleDeclaration() override;
|
||||
virtual nsresult SetInlineStyleDeclaration(mozilla::DeclarationBlock* aDeclaration,
|
||||
const nsAString* aSerialized,
|
||||
bool aNotify) override;
|
||||
|
||||
|
@ -6,8 +6,6 @@ support-files =
|
||||
bug418986-1.js
|
||||
cpows_child.js
|
||||
cpows_parent.xul
|
||||
file_bug391728.html
|
||||
file_bug391728_2.html
|
||||
file_bug549682.xul
|
||||
file_bug616841.xul
|
||||
file_bug816340.xul
|
||||
@ -36,7 +34,6 @@ support-files = ../file_bug357450.js
|
||||
[test_bug380418.html]
|
||||
[test_bug380418.html^headers^]
|
||||
[test_bug383430.html]
|
||||
[test_bug391728.html]
|
||||
[test_bug418986-1.xul]
|
||||
[test_bug421622.xul]
|
||||
[test_bug429785.xul]
|
||||
|
@ -1,85 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
embed,object {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
embed:-moz-handler-disabled,
|
||||
object:-moz-handler-disabled {
|
||||
border-style: dotted !important;
|
||||
}
|
||||
|
||||
embed:-moz-handler-blocked,
|
||||
object:-moz-handler-blocked {
|
||||
border-style: dashed !important;
|
||||
}
|
||||
|
||||
embed:-moz-type-unsupported,
|
||||
object:-moz-type-unsupported {
|
||||
border-style: none !important;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
function plugin_binding_attached(event) {
|
||||
window.parent.plugin_binding_attached(event);
|
||||
}
|
||||
document.addEventListener("PluginBindingAttached", plugin_binding_attached, true, true);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Embeds always fire events and have the pseudo class attached -->
|
||||
<div><embed id="plugin1" style="width: 100px; height: 100px" type="application/x-test"></div>
|
||||
<div><embed id="plugin2" style="width: 100px; height: 100px" src="data:application/x-test,test"></div>
|
||||
|
||||
<!-- So do objects with a type/uri and no content -->
|
||||
<div><object id="plugin3" style="width: 100px; height: 100px" type="application/x-test"></object></div>
|
||||
<div><object id="plugin4" style="width: 100px; height: 100px" data="data:application/x-test,test"></object></div>
|
||||
|
||||
<!-- Params are not considered content -->
|
||||
<div><object id="plugin5" style="width: 100px; height: 100px" type="application/x-test">
|
||||
<param name="foo" value="bar">
|
||||
</object></div>
|
||||
<div><object id="plugin6" style="width: 100px; height: 100px" data="data:application/x-test,test">
|
||||
<param name="foo" value="bar">
|
||||
</object></div>
|
||||
|
||||
<!-- Nor is whitespace -->
|
||||
<div><object id="plugin7" style="width: 100px; height: 100px" type="application/x-test">
|
||||
|
||||
|
||||
</object></div>
|
||||
<div><object id="plugin8" style="width: 100px; height: 100px" data="data:application/x-test,test">
|
||||
|
||||
|
||||
</object></div>
|
||||
|
||||
<!-- No errors or psuedo classes for objects with fallback content -->
|
||||
<div><object id="fallback1" style="width: 100px; height: 100px" type="application/x-test">
|
||||
<p>Fallback content</p>
|
||||
</object></div>
|
||||
<div><object id="fallback2" style="width: 100px; height: 100px" data="data:application/x-test,test">
|
||||
<p>Fallback content</p>
|
||||
</object></div>
|
||||
|
||||
<!-- Even other plugins are considered content so no errors dispatched from these
|
||||
objects, but the inner embeds do get processed -->
|
||||
<div><object id="fallback3" style="width: 100px; height: 100px" type="application/x-test">
|
||||
<embed id="plugin9" style="width: 100px; height: 100px" type="application/x-test">
|
||||
</object></div>
|
||||
<div><object id="fallback4" style="width: 100px; height: 100px" data="data:application/x-test,test">
|
||||
<embed id="plugin10" style="width: 100px; height: 100px" type="application/x-test">
|
||||
</object></div>
|
||||
|
||||
<!-- pluginurl was removed in bug 548133, and should not affect fallback -->
|
||||
<div><object id="plugin11" style="width: 100px; height: 100px" data="data:application/x-test,test">
|
||||
<param name="pluginurl">
|
||||
</object></div>
|
||||
|
||||
<div><object id="fallback5" style="width: 100px; height: 100px" data="data:application/x-test,test">
|
||||
<param name="pluginurl">
|
||||
Fallback content
|
||||
</object></div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,85 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
embed,object {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
embed:-moz-handler-disabled,
|
||||
object:-moz-handler-disabled {
|
||||
border-style: dotted !important;
|
||||
}
|
||||
|
||||
embed:-moz-handler-blocked,
|
||||
object:-moz-handler-blocked {
|
||||
border-style: dashed !important;
|
||||
}
|
||||
|
||||
embed:-moz-type-unsupported,
|
||||
object:-moz-type-unsupported {
|
||||
border-style: none !important;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
function plugin_binding_attached(event) {
|
||||
window.parent.plugin_binding_attached(event);
|
||||
}
|
||||
document.addEventListener("PluginBindingAttached", plugin_binding_attached, true, true);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Embeds always fire events and have the pseudo class attached -->
|
||||
<div><embed id="plugin1" style="width: 100px; height: 100px" type="application/x-unknown"></div>
|
||||
<div><embed id="plugin2" style="width: 100px; height: 100px" src="data:application/x-unknown,test"></div>
|
||||
|
||||
<!-- So do objects with a type/uri and no content -->
|
||||
<div><object id="plugin3" style="width: 100px; height: 100px" type="application/x-unknown"></object></div>
|
||||
<div><object id="plugin4" style="width: 100px; height: 100px" data="data:application/x-unknown,test"></object></div>
|
||||
|
||||
<!-- Params are not considered content -->
|
||||
<div><object id="plugin5" style="width: 100px; height: 100px" type="application/x-unknown">
|
||||
<param name="foo" value="bar">
|
||||
</object></div>
|
||||
<div><object id="plugin6" style="width: 100px; height: 100px" data="data:application/x-unknown,test">
|
||||
<param name="foo" value="bar">
|
||||
</object></div>
|
||||
|
||||
<!-- Nor is whitespace -->
|
||||
<div><object id="plugin7" style="width: 100px; height: 100px" type="application/x-unknown">
|
||||
|
||||
|
||||
</object></div>
|
||||
<div><object id="plugin8" style="width: 100px; height: 100px" data="data:application/x-unknown,test">
|
||||
|
||||
|
||||
</object></div>
|
||||
|
||||
<!-- No errors or psuedo classes for objects with fallback content -->
|
||||
<div><object id="fallback1" style="width: 100px; height: 100px" type="application/x-unknown">
|
||||
<p>Fallback content</p>
|
||||
</object></div>
|
||||
<div><object id="fallback2" style="width: 100px; height: 100px" data="data:application/x-unknown,test">
|
||||
<p>Fallback content</p>
|
||||
</object></div>
|
||||
|
||||
<!-- Even other plugins are considered content so no errors dispatched from these
|
||||
objects, but the inner embeds do get processed -->
|
||||
<div><object id="fallback3" style="width: 100px; height: 100px" type="application/x-unknown">
|
||||
<embed id="plugin9" style="width: 100px; height: 100px" type="application/x-unknown">
|
||||
</object></div>
|
||||
<div><object id="fallback4" style="width: 100px; height: 100px" data="data:application/x-unknown,test">
|
||||
<embed id="plugin10" style="width: 100px; height: 100px" type="application/x-unknown">
|
||||
</object></div>
|
||||
|
||||
<!-- pluginurl was removed in bug 548133, and should not affect fallback -->
|
||||
<div><object id="plugin11" style="width: 100px; height: 100px" type="application/x-unknown">
|
||||
<param name="pluginurl">
|
||||
</object></div>
|
||||
|
||||
<div><object id="fallback5" style="width: 100px; height: 100px" type="applicatin/x-unknown">
|
||||
<param name="pluginurl">
|
||||
Fallback content
|
||||
</object></div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,201 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=391728
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 391728</title>
|
||||
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=391728">Mozilla Bug 391728</a>
|
||||
<p id="display"></p>
|
||||
<div id="content">
|
||||
<iframe id="testframe" width="150" height="250" src="about:blank"></iframe>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
const gHttpTestRoot = location.toString().replace("chrome://mochitests/content/", "http://127.0.0.1:8888/").split(/\//).slice(0, -1).join('/') + '/';
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
/** Test for Bug 391728 **/
|
||||
// Plugins that should dispatch error events and have the pseudo classes set
|
||||
const PLUGIN_COUNT = 11;
|
||||
// Plugins that should neither dispatch error events or have the pseudo classes set
|
||||
const FALLBACK_COUNT = 5;
|
||||
const OBJLC = Components.interfaces.nsIObjectLoadingContent;
|
||||
|
||||
var gNextTest = null;
|
||||
var gUnknown = [];
|
||||
var gBlocked = [];
|
||||
var gDisabled = [];
|
||||
|
||||
function plugin_binding_attached(event) {
|
||||
var plugin = event.target;
|
||||
plugin instanceof OBJLC;
|
||||
switch (SpecialPowers.wrap(plugin).pluginFallbackType) {
|
||||
case OBJLC.PLUGIN_DISABLED:
|
||||
gDisabled.push(plugin.id);
|
||||
break;
|
||||
case OBJLC.PLUGIN_BLOCKLISTED:
|
||||
gBlocked.push(plugin.id);
|
||||
break;
|
||||
case OBJLC.PLUGIN_UNSUPPORTED:
|
||||
gUnknown.push(plugin.id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function init_test() {
|
||||
if (!PluginUtils.withTestPlugin(start_test))
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function updateBlocklist(aCallback) {
|
||||
var blocklistNotifier = Components.classes["@mozilla.org/extensions/blocklist;1"]
|
||||
.getService(Components.interfaces.nsITimerCallback);
|
||||
var observer = function() {
|
||||
Services.obs.removeObserver(observer, "blocklist-updated");
|
||||
SimpleTest.executeSoon(aCallback);
|
||||
};
|
||||
Services.obs.addObserver(observer, "blocklist-updated", false);
|
||||
blocklistNotifier.notify(null);
|
||||
}
|
||||
|
||||
var _originalBlocklistURL = null;
|
||||
function setAndUpdateBlocklist(aURL, aCallback) {
|
||||
info("Setting blocklist to " + aURL);
|
||||
if (!_originalBlocklistURL) {
|
||||
_originalBlocklistURL = Services.prefs.getCharPref("extensions.blocklist.url");
|
||||
}
|
||||
Services.prefs.setCharPref("extensions.blocklist.url", aURL);
|
||||
updateBlocklist(aCallback);
|
||||
}
|
||||
|
||||
function resetBlocklist() {
|
||||
info("resetting blocklist URL to " + _originalBlocklistURL);
|
||||
Services.prefs.setCharPref("extensions.blocklist.url", _originalBlocklistURL);
|
||||
}
|
||||
|
||||
function start_test(plugin) {
|
||||
Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
|
||||
|
||||
is(plugin.description, "Plug-in for testing purposes.\u2122 " +
|
||||
"(\u0939\u093f\u0928\u094d\u0926\u0940 " +
|
||||
"\u4e2d\u6587 " +
|
||||
"\u0627\u0644\u0639\u0631\u0628\u064a\u0629)",
|
||||
"Test plugin had an incorrect description");
|
||||
is(plugin.version, "1.0.0.0", "Test plugin had an incorrect version");
|
||||
ok(!plugin.disabled, "Test plugin should not be disabled");
|
||||
ok(!plugin.blocklisted, "Test plugin should not be blocklisted");
|
||||
|
||||
var frame = document.getElementById("testframe");
|
||||
frame.addEventListener("load", frame_loaded, true);
|
||||
load_frame(test_normal, "file_bug391728");
|
||||
}
|
||||
|
||||
function finish_test(plugin) {
|
||||
Services.prefs.clearUserPref("extensions.blocklist.suppressUI");
|
||||
resetBlocklist();
|
||||
plugin.enabledState = Components.interfaces.nsIPluginTag.STATE_ENABLED;
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function load_frame(nextTest, file) {
|
||||
gNextTest = nextTest;
|
||||
gDisabled = [];
|
||||
gUnknown = [];
|
||||
gBlocked = [];
|
||||
var frame = document.getElementById("testframe");
|
||||
frame.src = file + ".html?" + Math.random();
|
||||
}
|
||||
|
||||
function next_text() {
|
||||
PluginUtils.withTestPlugin(gNextTest);
|
||||
}
|
||||
|
||||
function frame_loaded() {
|
||||
SimpleTest.requestFlakyTimeout("We must delay to wait for the plugin sources to be loaded :(");
|
||||
setTimeout(next_text, 500);
|
||||
}
|
||||
|
||||
function test_style(expected) {
|
||||
var frame = document.getElementById("testframe");
|
||||
for (var i = 1; i <= PLUGIN_COUNT; i++) {
|
||||
var tag = frame.contentDocument.getElementById("plugin" + i);
|
||||
ok(tag, "Plugin " + i + " did not exist");
|
||||
var style = frame.contentWindow.getComputedStyle(tag, null);
|
||||
is(style.borderTopStyle, expected, "Plugin " + i + " had an incorrect border style");
|
||||
}
|
||||
for (i = 1; i <= FALLBACK_COUNT; i++) {
|
||||
var tag = frame.contentDocument.getElementById("fallback" + i);
|
||||
ok(tag, "Fallback plugin " + i + " did not exist");
|
||||
var style = frame.contentWindow.getComputedStyle(tag, null);
|
||||
is(style.borderTopStyle, "solid", "Fallback plugin " + i + " had an incorrect border style");
|
||||
}
|
||||
}
|
||||
|
||||
function test_list(list) {
|
||||
for (var i = 1; i <= PLUGIN_COUNT; i++) {
|
||||
ok(list.indexOf("plugin" + i) >= 0, "Plugin " + i + " did not send the event");
|
||||
}
|
||||
for (i = 1; i <= FALLBACK_COUNT; i++) {
|
||||
ok(list.indexOf("fallback" + i) < 0, "Fallback plugin " + i + " should not have sent the event");
|
||||
}
|
||||
}
|
||||
|
||||
function test_normal(plugin) {
|
||||
is(gUnknown.length, 0, "Should not have been any unknown plugins");
|
||||
is(gDisabled.length, 0, "Should not have been any disabled plugins");
|
||||
is(gBlocked.length, 0, "Should not have been any blocked plugins");
|
||||
test_style("solid");
|
||||
plugin.enabledState = Components.interfaces.nsIPluginTag.STATE_DISABLED;
|
||||
load_frame(test_disabled, "file_bug391728");
|
||||
}
|
||||
|
||||
function test_disabled(plugin) {
|
||||
is(gUnknown.length, 0, "Should not have been any unknown plugins");
|
||||
is(gDisabled.length, PLUGIN_COUNT, "Should have been disabled plugins");
|
||||
test_list(gDisabled);
|
||||
is(gBlocked.length, 0, "Should not have been any blocked plugins");
|
||||
test_style("dotted");
|
||||
ok(plugin.disabled, "Plugin lost its disabled status");
|
||||
plugin.enabledState = Components.interfaces.nsIPluginTag.STATE_ENABLED;
|
||||
|
||||
setAndUpdateBlocklist(gHttpTestRoot + "blockPluginHard.xml",
|
||||
function() {
|
||||
load_frame(test_blocked, "file_bug391728");
|
||||
});
|
||||
}
|
||||
|
||||
function test_blocked(plugin) {
|
||||
is(gUnknown.length, 0, "Should not have been any unknown plugins");
|
||||
is(gDisabled.length, 0, "Should not have been any disabled plugins");
|
||||
is(gBlocked.length, PLUGIN_COUNT, "Should have been blocked plugins");
|
||||
test_list(gBlocked);
|
||||
test_style("dashed");
|
||||
ok(plugin.blocklisted, "Plugin lost its blocklist status");
|
||||
load_frame(test_unknown, "file_bug391728_2");
|
||||
}
|
||||
|
||||
function test_unknown(plugin) {
|
||||
is(gUnknown.length, PLUGIN_COUNT, "Should have been unknown plugins");
|
||||
test_list(gUnknown);
|
||||
is(gDisabled.length, 0, "Should not have been any disabled plugins");
|
||||
is(gBlocked.length, 0, "Should not have been any blocked plugins");
|
||||
test_style("none");
|
||||
setAndUpdateBlocklist(gHttpTestRoot + "blockNoPlugins.xml", function() {
|
||||
ok(!plugin.blocklisted, "Plugin shouldn't remain blocklisted");
|
||||
finish_test(plugin);
|
||||
});
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
window.addEventListener("load", init_test, false);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -391,7 +391,6 @@ skip-if = buildapp == 'b2g'
|
||||
skip-if = buildapp == 'b2g'
|
||||
[test_bug424359-2.html]
|
||||
skip-if = buildapp == 'b2g'
|
||||
[test_bug425013.html]
|
||||
[test_bug426308.html]
|
||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk')
|
||||
[test_bug426646.html]
|
||||
|
@ -80,31 +80,37 @@ Object height=100 (stylesheet width:400px height:400px)
|
||||
function check_size(id, width, height) {
|
||||
var element = document.getElementById(id);
|
||||
ok(element, "Plugin element " + id + " did not exist");
|
||||
if (width != "auto") {
|
||||
width = width + "px";
|
||||
}
|
||||
if (height != "auto") {
|
||||
height = height + "px";
|
||||
}
|
||||
var style = window.getComputedStyle(element, null);
|
||||
is(style.width, width + "px", "Plugin element " + id + " had an incorrect width");
|
||||
is(style.height, height + "px", "Plugin element " + id + " had an incorrect height");
|
||||
is(style.width, width, "Plugin element " + id + " had an incorrect width");
|
||||
is(style.height, height, "Plugin element " + id + " had an incorrect height");
|
||||
}
|
||||
|
||||
check_size("embed1", 240, 200);
|
||||
check_size("embed1", "auto", "auto");
|
||||
check_size("embed2", 0, 0);
|
||||
check_size("embed3", 100, 100);
|
||||
check_size("embed4", 240, 100);
|
||||
check_size("embed5", 100, 200);
|
||||
check_size("embed4", "auto", 100);
|
||||
check_size("embed5", 100, "auto");
|
||||
check_size("embed6", 100, 100);
|
||||
check_size("embed7", 100, 100);
|
||||
check_size("embed8", 240, 100);
|
||||
check_size("embed8", "auto", 100);
|
||||
check_size("embed9", 400, 100);
|
||||
check_size("embed10", 400, 100);
|
||||
check_size("embed11", 400, 400);
|
||||
|
||||
check_size("object1", 240, 200);
|
||||
check_size("object1", "auto", "auto");
|
||||
check_size("object2", 0, 0);
|
||||
check_size("object3", 100, 100);
|
||||
check_size("object4", 240, 100);
|
||||
check_size("object5", 100, 200);
|
||||
check_size("object4", "auto", 100);
|
||||
check_size("object5", 100, "auto");
|
||||
check_size("object6", 100, 100);
|
||||
check_size("object7", 100, 100);
|
||||
check_size("object8", 240, 100);
|
||||
check_size("object8", "auto", 100);
|
||||
check_size("object9", 400, 100);
|
||||
check_size("object10", 400, 100);
|
||||
check_size("object11", 400, 400);
|
||||
|
@ -1,85 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=425013
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 425013</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body onload="runtests();">
|
||||
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=425013">Mozilla Bug 425013</a>
|
||||
<br>
|
||||
|
||||
<script type="text/javascript;version=1.7">
|
||||
var missingPlugins = new Array();
|
||||
var OBJLC = SpecialPowers.Ci.nsIObjectLoadingContent;
|
||||
|
||||
function pluginBinding(event)
|
||||
{
|
||||
var plugin = event.target;
|
||||
plugin instanceof OBJLC;
|
||||
if (SpecialPowers.wrap(plugin).pluginFallbackType == OBJLC.PLUGIN_UNSUPPORTED)
|
||||
missingPlugins.push(plugin);
|
||||
}
|
||||
|
||||
document.addEventListener("PluginBindingAttached", pluginBinding, true);
|
||||
</script>
|
||||
|
||||
<object type="foo/bar" id="obj1"></object>
|
||||
|
||||
<object type="foo/bar" id="obj2">
|
||||
<embed type="a/b" id="embed1"></embed>
|
||||
</object>
|
||||
|
||||
<object type="foo/bar"
|
||||
data="data:foo/bar,bah" id="obj3">
|
||||
<param name="movie" value="data:foo/bar,bah">
|
||||
</object>
|
||||
|
||||
<object type="foo/bar"
|
||||
data="data:foo/bar,bah" id="obj4">
|
||||
<param name="movie" value="data:foo/bar,bah">
|
||||
<p>Alternate content</p>
|
||||
</object>
|
||||
|
||||
<object type="text/html"
|
||||
data="data:text/html,an html document in an object tag" id="obj5">
|
||||
</object>
|
||||
|
||||
<object type="text/html"
|
||||
data="data:text/html,an html document in an object tag" id="obj6">
|
||||
<p>Alternate content</p>
|
||||
</object>
|
||||
|
||||
<embed type="a/b" id="embed2"></embed>
|
||||
|
||||
<script class="testbody" type="text/javascript">
|
||||
function runtests()
|
||||
{
|
||||
// Force layout flush so the binding is attached and the event is fired
|
||||
document.getElementById("obj1").clientTop;
|
||||
document.getElementById("obj3").clientTop;
|
||||
document.getElementById("embed1").clientTop;
|
||||
document.getElementById("embed2").clientTop;
|
||||
|
||||
// Let pending events flush
|
||||
SimpleTest.executeSoon(function () {
|
||||
ok(missingPlugins.indexOf(document.getElementById("obj1")) >= 0, "Missing plugin element obj1");
|
||||
ok(missingPlugins.indexOf(document.getElementById("embed1")) >= 0, "Missing plugin element embed1");
|
||||
ok(missingPlugins.indexOf(document.getElementById("embed2")) >= 0, "Missing plugin element embed2");
|
||||
ok(missingPlugins.indexOf(document.getElementById("obj3")) >= 0, "Missing plugin element obj3");
|
||||
|
||||
is(missingPlugins.length, 4, "Wrong number of missing plugins");
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
1
dom/cache/CacheStorage.cpp
vendored
1
dom/cache/CacheStorage.cpp
vendored
@ -119,7 +119,6 @@ IsTrusted(const PrincipalInfo& aPrincipalInfo, bool aTestingPrefEnabled)
|
||||
|
||||
nsAutoCString scheme(Substring(flatURL, schemePos, schemeLen));
|
||||
if (scheme.LowerCaseEqualsLiteral("https") ||
|
||||
scheme.LowerCaseEqualsLiteral("app") ||
|
||||
scheme.LowerCaseEqualsLiteral("file")) {
|
||||
return true;
|
||||
}
|
||||
|
3
dom/cache/TypeUtils.cpp
vendored
3
dom/cache/TypeUtils.cpp
vendored
@ -400,8 +400,7 @@ TypeUtils::ProcessURL(nsACString& aUrl, bool* aSchemeValidOut,
|
||||
if (aSchemeValidOut) {
|
||||
nsAutoCString scheme(Substring(flatURL, schemePos, schemeLen));
|
||||
*aSchemeValidOut = scheme.LowerCaseEqualsLiteral("http") ||
|
||||
scheme.LowerCaseEqualsLiteral("https") ||
|
||||
scheme.LowerCaseEqualsLiteral("app");
|
||||
scheme.LowerCaseEqualsLiteral("https");
|
||||
}
|
||||
|
||||
uint32_t queryPos;
|
||||
|
@ -643,16 +643,10 @@ createTestFile('.txt');
|
||||
var gTestRunner = runTest();
|
||||
SpecialPowers.addPermission("browser", true, gTestUri);
|
||||
|
||||
// We are more permissive with CSP in our testing environment....
|
||||
const DEFAULT_CSP_PRIV = "default-src *; script-src 'self'; style-src 'self' 'unsafe-inline'; object-src 'none'";
|
||||
const DEFAULT_CSP_CERT = "default-src *; script-src 'self'; style-src 'self'; object-src 'none'";
|
||||
|
||||
SpecialPowers.pushPrefEnv({'set': [["dom.mozBrowserFramesEnabled", true],
|
||||
["device.storage.enabled", true],
|
||||
["device.storage.testing", true],
|
||||
["device.storage.prompt.testing", false],
|
||||
["security.apps.privileged.CSP.default", DEFAULT_CSP_PRIV],
|
||||
["security.apps.certified.CSP.default", DEFAULT_CSP_CERT]]},
|
||||
["device.storage.prompt.testing", false]]},
|
||||
function() { gTestRunner.next(); });
|
||||
|
||||
</script>
|
||||
|
@ -818,16 +818,10 @@ function createTestFile(extension) {
|
||||
let gTestRunner = runTest();
|
||||
SpecialPowers.addPermission("browser", true, gTestUri);
|
||||
|
||||
// We are more permissive with CSP in our testing environment....
|
||||
const DEFAULT_CSP_PRIV = "default-src *; script-src 'self'; style-src 'self' 'unsafe-inline'; object-src 'none'";
|
||||
const DEFAULT_CSP_CERT = "default-src *; script-src 'self'; style-src 'self'; object-src 'none'";
|
||||
|
||||
SpecialPowers.pushPrefEnv({'set': [["dom.mozBrowserFramesEnabled", true],
|
||||
["device.storage.enabled", true],
|
||||
["device.storage.testing", true],
|
||||
["device.storage.prompt.testing", false],
|
||||
["security.apps.privileged.CSP.default", DEFAULT_CSP_PRIV],
|
||||
["security.apps.certified.CSP.default", DEFAULT_CSP_CERT]]},
|
||||
["device.storage.prompt.testing", false]]},
|
||||
function() { gTestRunner.next(); });
|
||||
|
||||
</script>
|
||||
|
@ -254,8 +254,6 @@ private:
|
||||
// Content is still loading such that there is nothing to show the
|
||||
// user (eg an image which hasn't started coming in yet).
|
||||
#define NS_EVENT_STATE_LOADING NS_DEFINE_EVENT_STATE_MACRO(23)
|
||||
// Content is of a type that gecko can't handle.
|
||||
#define NS_EVENT_STATE_TYPE_UNSUPPORTED NS_DEFINE_EVENT_STATE_MACRO(24)
|
||||
#define NS_EVENT_STATE_INCREMENT_SCRIPT_LEVEL NS_DEFINE_EVENT_STATE_MACRO(25)
|
||||
// Handler for the content has been blocked.
|
||||
#define NS_EVENT_STATE_HANDLER_BLOCKED NS_DEFINE_EVENT_STATE_MACRO(26)
|
||||
@ -288,8 +286,6 @@ private:
|
||||
#define NS_EVENT_STATE_VULNERABLE_UPDATABLE NS_DEFINE_EVENT_STATE_MACRO(39)
|
||||
// Handler for click to play plugin (vulnerable w/no update)
|
||||
#define NS_EVENT_STATE_VULNERABLE_NO_UPDATE NS_DEFINE_EVENT_STATE_MACRO(40)
|
||||
// Platform does not support plugin content (some mobile platforms)
|
||||
#define NS_EVENT_STATE_TYPE_UNSUPPORTED_PLATFORM NS_DEFINE_EVENT_STATE_MACRO(41)
|
||||
// Element is ltr (for :dir pseudo-class)
|
||||
#define NS_EVENT_STATE_LTR NS_DEFINE_EVENT_STATE_MACRO(42)
|
||||
// Element is rtl (for :dir pseudo-class)
|
||||
|
@ -1247,14 +1247,8 @@ Geolocation::GetCurrentPosition(GeoPositionCallback callback,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return GetCurrentPositionReady(request);
|
||||
}
|
||||
|
||||
nsresult
|
||||
Geolocation::GetCurrentPositionReady(nsGeolocationRequest* aRequest)
|
||||
{
|
||||
if (mOwner) {
|
||||
if (!RegisterRequestWithPrompt(aRequest)) {
|
||||
if (!RegisterRequestWithPrompt(request)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
@ -1265,7 +1259,7 @@ Geolocation::GetCurrentPositionReady(nsGeolocationRequest* aRequest)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> ev = new RequestAllowEvent(true, aRequest);
|
||||
nsCOMPtr<nsIRunnable> ev = new RequestAllowEvent(true, request);
|
||||
NS_DispatchToMainThread(ev);
|
||||
|
||||
return NS_OK;
|
||||
@ -1334,14 +1328,8 @@ Geolocation::WatchPosition(GeoPositionCallback aCallback,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return WatchPositionReady(request);
|
||||
}
|
||||
|
||||
nsresult
|
||||
Geolocation::WatchPositionReady(nsGeolocationRequest* aRequest)
|
||||
{
|
||||
if (mOwner) {
|
||||
if (!RegisterRequestWithPrompt(aRequest))
|
||||
if (!RegisterRequestWithPrompt(request))
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
return NS_OK;
|
||||
@ -1351,7 +1339,7 @@ Geolocation::WatchPositionReady(nsGeolocationRequest* aRequest)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
aRequest->Allow(JS::UndefinedHandleValue);
|
||||
request->Allow(JS::UndefinedHandleValue);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1390,20 +1378,6 @@ Geolocation::ClearWatch(int32_t aWatchId)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
Geolocation::ServiceReady()
|
||||
{
|
||||
for (uint32_t length = mPendingRequests.Length(); length > 0; --length) {
|
||||
if (mPendingRequests[0]->IsWatch()) {
|
||||
WatchPositionReady(mPendingRequests[0]);
|
||||
} else {
|
||||
GetCurrentPositionReady(mPendingRequests[0]);
|
||||
}
|
||||
|
||||
mPendingRequests.RemoveElementAt(0);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Geolocation::WindowOwnerStillExists()
|
||||
{
|
||||
|
@ -171,9 +171,6 @@ public:
|
||||
// Check to see if any active request requires high accuracy
|
||||
bool HighAccuracyRequested();
|
||||
|
||||
// Notification from the service:
|
||||
void ServiceReady();
|
||||
|
||||
private:
|
||||
|
||||
~Geolocation();
|
||||
@ -187,10 +184,6 @@ private:
|
||||
|
||||
bool RegisterRequestWithPrompt(nsGeolocationRequest* request);
|
||||
|
||||
// Methods for the service when it's ready to process requests:
|
||||
nsresult GetCurrentPositionReady(nsGeolocationRequest* aRequest);
|
||||
nsresult WatchPositionReady(nsGeolocationRequest* aRequest);
|
||||
|
||||
// Check if clearWatch is already called
|
||||
bool IsAlreadyCleared(nsGeolocationRequest* aRequest);
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/DeclarationBlockInlines.h"
|
||||
#include "mozilla/EventDispatcher.h"
|
||||
#include "mozilla/EventListenerManager.h"
|
||||
#include "mozilla/EventStateManager.h"
|
||||
@ -187,12 +188,18 @@ nsGenericHTMLElement::CopyInnerTo(Element* aDst)
|
||||
value->ToString(valStr);
|
||||
|
||||
if (name->Equals(nsGkAtoms::style, kNameSpaceID_None) &&
|
||||
value->Type() == nsAttrValue::eGeckoCSSDeclaration) {
|
||||
value->Type() == nsAttrValue::eCSSDeclaration) {
|
||||
DeclarationBlock* decl = value->GetCSSDeclarationValue();
|
||||
if (decl->IsServo()) {
|
||||
MOZ_CRASH("stylo: clone not implemented");
|
||||
continue;
|
||||
}
|
||||
|
||||
// We can't just set this as a string, because that will fail
|
||||
// to reparse the string into style data until the node is
|
||||
// inserted into the document. Clone the Rule instead.
|
||||
RefPtr<css::Declaration> declClone =
|
||||
new css::Declaration(*value->GetGeckoCSSDeclarationValue());
|
||||
RefPtr<css::Declaration>
|
||||
declClone = new css::Declaration(*decl->AsGecko());
|
||||
|
||||
rv = aDst->SetInlineStyleDeclaration(declClone, &valStr, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -46,16 +46,6 @@ interface nsIAppsService : nsISupports
|
||||
*/
|
||||
DOMString getManifestURLByLocalId(in unsigned long localId);
|
||||
|
||||
/**
|
||||
* Returns the manifest CSP associated to this localId.
|
||||
*/
|
||||
DOMString getManifestCSPByLocalId(in unsigned long localId);
|
||||
|
||||
/**
|
||||
* Returns the default CSP associated to this localId.
|
||||
*/
|
||||
DOMString getDefaultCSPByLocalId(in unsigned long localId);
|
||||
|
||||
/**
|
||||
* Returns the basepath for core apps
|
||||
*/
|
||||
|
@ -5,7 +5,6 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
'nsIDOMDesktopNotification.idl',
|
||||
'nsINotificationStorage.idl',
|
||||
]
|
||||
|
||||
|
@ -1,20 +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 "domstubs.idl"
|
||||
|
||||
interface nsIObserver;
|
||||
|
||||
// Notification service that also provides the manifest URL
|
||||
[scriptable, uuid(50cb17d2-dc8a-4aa6-bcd3-94d76af14e20)]
|
||||
interface nsIAppNotificationService : nsISupports
|
||||
{
|
||||
void showAppNotification(in AString imageUrl,
|
||||
in AString title,
|
||||
in AString text,
|
||||
in nsIObserver alertListener,
|
||||
// details should be a WebIDL
|
||||
// AppNotificationServiceOptions Dictionary object
|
||||
in jsval details);
|
||||
};
|
@ -46,6 +46,8 @@ support-files =
|
||||
|
||||
[test_AudioChange_mp4.html]
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
|
||||
[test_AutoRevocation.html]
|
||||
tags = firstpartyisolation
|
||||
[test_BufferedSeek.html]
|
||||
[test_BufferedSeek_mp4.html]
|
||||
skip-if = ((os == "win" && os_version == "5.1") || (toolkit == 'android')) # Not supported on xp and android 2.3
|
||||
|
40
dom/media/mediasource/test/test_AutoRevocation.html
Normal file
40
dom/media/mediasource/test/test_AutoRevocation.html
Normal file
@ -0,0 +1,40 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>MSE: auto-revocation</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="mediasource.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
runWithMSE(function () {
|
||||
var ms = new MediaSource();
|
||||
var o = URL.createObjectURL(ms);
|
||||
var v = document.createElement("video");
|
||||
|
||||
v.addEventListener("error", function (e) {
|
||||
ok(true, "ObjectURL should be auto-revoked");
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
v.addEventListener("stalled", function (e) {
|
||||
ok(false, "If auto-revocation is gone, please turn on TODOs in browser_mediaSourceURL.js");
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
v.src = o;
|
||||
v.preload = "auto";
|
||||
document.body.appendChild(v);
|
||||
}, 0);
|
||||
});
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -1,126 +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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const DEBUG = false;
|
||||
|
||||
function debug(s) {
|
||||
dump("-*- ChromeNotifications.js: " + s + "\n");
|
||||
}
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
||||
"@mozilla.org/childprocessmessagemanager;1",
|
||||
"nsIMessageSender");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "appNotifier",
|
||||
"@mozilla.org/system-alerts-service;1",
|
||||
"nsIAppNotificationService");
|
||||
|
||||
const CHROMENOTIFICATIONS_CID = "{74f94093-8b37-497e-824f-c3b250a911da}";
|
||||
const CHROMENOTIFICATIONS_CONTRACTID = "@mozilla.org/mozChromeNotifications;1";
|
||||
|
||||
function ChromeNotifications() {
|
||||
this.innerWindowID = null;
|
||||
this.resendCallback = null;
|
||||
}
|
||||
|
||||
ChromeNotifications.prototype = {
|
||||
|
||||
init: function(aWindow) {
|
||||
let util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
this.innerWindowID = util.currentInnerWindowID;
|
||||
Services.obs.addObserver(this, "inner-window-destroyed", false);
|
||||
cpmm.addMessageListener("Notification:GetAllCrossOrigin:Return:OK", this);
|
||||
},
|
||||
|
||||
performResend: function(notifications) {
|
||||
let resentNotifications = 0;
|
||||
|
||||
notifications.forEach(function(notification) {
|
||||
let behavior;
|
||||
try {
|
||||
behavior = JSON.parse(notification.mozbehavior);
|
||||
} catch(e) {
|
||||
behavior = undefined;
|
||||
}
|
||||
|
||||
if (behavior && behavior.showOnlyOnce === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
appNotifier.showAppNotification(
|
||||
notification.icon,
|
||||
notification.title,
|
||||
notification.body,
|
||||
null,
|
||||
{
|
||||
manifestURL: notification.origin,
|
||||
id: notification.alertName,
|
||||
dir: notification.dir,
|
||||
lang: notification.lang,
|
||||
tag: notification.tag,
|
||||
dbId: notification.id,
|
||||
timestamp: notification.timestamp,
|
||||
data: notification.data,
|
||||
mozbehavior: behavior
|
||||
}
|
||||
);
|
||||
resentNotifications++;
|
||||
});
|
||||
|
||||
try {
|
||||
this.resendCallback && this.resendCallback(resentNotifications);
|
||||
} catch (ex) {
|
||||
if (DEBUG) debug("Content sent exception: " + ex);
|
||||
}
|
||||
},
|
||||
|
||||
mozResendAllNotifications: function(resendCallback) {
|
||||
this.resendCallback = resendCallback;
|
||||
cpmm.sendAsyncMessage("Notification:GetAllCrossOrigin", {});
|
||||
},
|
||||
|
||||
receiveMessage: function(message) {
|
||||
switch (message.name) {
|
||||
case "Notification:GetAllCrossOrigin:Return:OK":
|
||||
this.performResend(message.data.notifications);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (DEBUG) { debug("Unrecognized message: " + message.name); }
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
if (DEBUG) debug("Topic: " + aTopic);
|
||||
if (aTopic == "inner-window-destroyed") {
|
||||
let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
|
||||
if (wId != this.innerWindowID) {
|
||||
return;
|
||||
}
|
||||
Services.obs.removeObserver(this, "inner-window-destroyed");
|
||||
cpmm.removeMessageListener("Notification:GetAllCrossOrigin:Return:OK", this);
|
||||
}
|
||||
},
|
||||
|
||||
classID : Components.ID(CHROMENOTIFICATIONS_CID),
|
||||
contractID : CHROMENOTIFICATIONS_CONTRACTID,
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIChromeNotifications,
|
||||
Ci.nsIDOMGlobalPropertyInitializer,
|
||||
Ci.nsIObserver,
|
||||
Ci.nsIMessageListener]),
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ChromeNotifications]);
|
@ -1,3 +0,0 @@
|
||||
# ChromeNotifications.js
|
||||
component {74f94093-8b37-497e-824f-c3b250a911da} ChromeNotifications.js
|
||||
contract @mozilla.org/mozChromeNotifications;1 {74f94093-8b37-497e-824f-c3b250a911da}
|
@ -11,10 +11,8 @@
|
||||
#include "nsContentPermissionHelper.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "mozilla/dom/PBrowserChild.h"
|
||||
#include "nsIDOMDesktopNotification.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "nsIAppsService.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "PermissionMessageUtils.h"
|
||||
@ -73,34 +71,6 @@ DesktopNotification::PostDesktopNotification()
|
||||
mObserver = new AlertServiceObserver(this);
|
||||
}
|
||||
|
||||
#ifdef MOZ_B2G
|
||||
nsCOMPtr<nsIAppNotificationService> appNotifier =
|
||||
do_GetService("@mozilla.org/system-alerts-service;1");
|
||||
if (appNotifier) {
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
|
||||
uint32_t appId = window ? window->GetDoc()->NodePrincipal()->GetAppId()
|
||||
: nsIScriptSecurityManager::UNKNOWN_APP_ID;
|
||||
|
||||
if (appId != nsIScriptSecurityManager::UNKNOWN_APP_ID) {
|
||||
nsCOMPtr<nsIAppsService> appsService = do_GetService("@mozilla.org/AppsService;1");
|
||||
nsString manifestUrl = EmptyString();
|
||||
appsService->GetManifestURLByLocalId(appId, manifestUrl);
|
||||
mozilla::AutoSafeJSContext cx;
|
||||
JS::Rooted<JS::Value> val(cx);
|
||||
AppNotificationServiceOptions ops;
|
||||
ops.mTextClickable = true;
|
||||
ops.mManifestURL = manifestUrl;
|
||||
|
||||
if (!ToJSValue(cx, ops, &val)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return appNotifier->ShowAppNotification(mIconURL, mTitle, mDescription,
|
||||
mObserver, val);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIAlertsService> alerts = do_GetService("@mozilla.org/alerts-service;1");
|
||||
if (!alerts) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include "nsDOMJSUtils.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "nsIAlertsService.h"
|
||||
#include "nsIAppsService.h"
|
||||
#include "nsIContentPermissionPrompt.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsILoadContext.h"
|
||||
@ -56,10 +55,6 @@
|
||||
#include "WorkerRunnable.h"
|
||||
#include "WorkerScope.h"
|
||||
|
||||
#ifdef MOZ_B2G
|
||||
#include "nsIDOMDesktopNotification.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
@ -1506,15 +1501,6 @@ MainThreadNotificationObserver::Observe(nsISupports* aSubject, const char* aTopi
|
||||
}
|
||||
}
|
||||
} else if (!strcmp("alertfinished", aTopic)) {
|
||||
// In b2g-desktop, if the app is closed, closing a notification still
|
||||
// triggers the observer which might be alive even though the owner window
|
||||
// was closed. Keeping this until we remove the close event (Bug 1139363)
|
||||
// from implementation.
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = notification->GetOwner();
|
||||
if (NS_WARN_IF(!window || !window->IsCurrentInnerWindow())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
notification->UnpersistNotification();
|
||||
notification->mIsClosed = true;
|
||||
notification->DispatchTrustedEvent(NS_LITERAL_STRING("close"));
|
||||
@ -1784,52 +1770,6 @@ Notification::ShowInternal()
|
||||
IsInPrivateBrowsing());
|
||||
|
||||
|
||||
#ifdef MOZ_B2G
|
||||
nsCOMPtr<nsIAppNotificationService> appNotifier =
|
||||
do_GetService("@mozilla.org/system-alerts-service;1");
|
||||
if (appNotifier) {
|
||||
uint32_t appId = nsIScriptSecurityManager::UNKNOWN_APP_ID;
|
||||
if (mWorkerPrivate) {
|
||||
appId = mWorkerPrivate->GetPrincipal()->GetAppId();
|
||||
} else {
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
|
||||
if (window) {
|
||||
appId = window->GetDoc()->NodePrincipal()->GetAppId();
|
||||
}
|
||||
}
|
||||
|
||||
if (appId != nsIScriptSecurityManager::UNKNOWN_APP_ID) {
|
||||
nsCOMPtr<nsIAppsService> appsService = do_GetService("@mozilla.org/AppsService;1");
|
||||
nsString manifestUrl = EmptyString();
|
||||
nsresult rv = appsService->GetManifestURLByLocalId(appId, manifestUrl);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mozilla::AutoSafeJSContext cx;
|
||||
JS::Rooted<JS::Value> val(cx);
|
||||
AppNotificationServiceOptions ops;
|
||||
ops.mTextClickable = true;
|
||||
ops.mManifestURL = manifestUrl;
|
||||
GetAlertName(ops.mId);
|
||||
ops.mDbId = mID;
|
||||
ops.mDir = DirectionToString(mDir);
|
||||
ops.mLang = mLang;
|
||||
ops.mTag = mTag;
|
||||
ops.mData = mDataAsBase64;
|
||||
ops.mMozbehavior = mBehavior;
|
||||
ops.mMozbehavior.mSoundFile = soundUrl;
|
||||
|
||||
if (!ToJSValue(cx, ops, &val)) {
|
||||
NS_WARNING("Converting dict to object failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
appNotifier->ShowAppNotification(iconUrl, mTitle, mBody,
|
||||
alertObserver, val);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// In the case of IPC, the parent process uses the cookie to map to
|
||||
// nsIObserver. Thus the cookie must be unique to differentiate observers.
|
||||
nsString uniqueCookie = NS_LITERAL_STRING("notification:");
|
||||
@ -2364,23 +2304,8 @@ Notification::GetOrigin(nsIPrincipal* aPrincipal, nsString& aOrigin)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
uint16_t appStatus = aPrincipal->GetAppStatus();
|
||||
uint32_t appId = aPrincipal->GetAppId();
|
||||
|
||||
nsresult rv;
|
||||
if (appStatus == nsIPrincipal::APP_STATUS_NOT_INSTALLED ||
|
||||
appId == nsIScriptSecurityManager::NO_APP_ID ||
|
||||
appId == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
|
||||
rv = nsContentUtils::GetUTFOrigin(aPrincipal, aOrigin);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
// If we are in "app code", use manifest URL as unique origin since
|
||||
// multiple apps can share the same origin but not same notifications.
|
||||
nsCOMPtr<nsIAppsService> appsService =
|
||||
do_GetService("@mozilla.org/AppsService;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
appsService->GetManifestURLByLocalId(appId, aOrigin);
|
||||
}
|
||||
nsresult rv = nsContentUtils::GetUTFOrigin(aPrincipal, aOrigin);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -2827,22 +2752,7 @@ Notification::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
obs->RemoveObserver(this, DOM_WINDOW_FROZEN_TOPIC);
|
||||
}
|
||||
|
||||
uint16_t appStatus = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
|
||||
uint32_t appId = nsIScriptSecurityManager::UNKNOWN_APP_ID;
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = window ? window->GetExtantDoc() : nullptr;
|
||||
nsCOMPtr<nsIPrincipal> nodePrincipal = doc ? doc->NodePrincipal() :
|
||||
nullptr;
|
||||
if (nodePrincipal) {
|
||||
appStatus = nodePrincipal->GetAppStatus();
|
||||
appId = nodePrincipal->GetAppId();
|
||||
}
|
||||
|
||||
if (appStatus == nsIPrincipal::APP_STATUS_NOT_INSTALLED ||
|
||||
appId == nsIScriptSecurityManager::NO_APP_ID ||
|
||||
appId == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
|
||||
CloseInternal();
|
||||
}
|
||||
CloseInternal();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,8 +35,7 @@ const NOTIFICATION_STORE_PATH =
|
||||
const kMessages = [
|
||||
"Notification:Save",
|
||||
"Notification:Delete",
|
||||
"Notification:GetAll",
|
||||
"Notification:GetAllCrossOrigin"
|
||||
"Notification:GetAll"
|
||||
];
|
||||
|
||||
var NotificationDB = {
|
||||
@ -197,19 +196,6 @@ var NotificationDB = {
|
||||
});
|
||||
break;
|
||||
|
||||
case "Notification:GetAllCrossOrigin":
|
||||
this.queueTask("getallaccrossorigin", message.data).then(
|
||||
function(notifications) {
|
||||
returnMessage("Notification:GetAllCrossOrigin:Return:OK", {
|
||||
notifications: notifications
|
||||
});
|
||||
}).catch(function(error) {
|
||||
returnMessage("Notification:GetAllCrossOrigin:Return:KO", {
|
||||
errorMsg: error
|
||||
});
|
||||
});
|
||||
break;
|
||||
|
||||
case "Notification:Save":
|
||||
this.queueTask("save", message.data).then(function() {
|
||||
returnMessage("Notification:Save:Return:OK", {
|
||||
@ -286,10 +272,6 @@ var NotificationDB = {
|
||||
return this.taskGetAll(task.data);
|
||||
break;
|
||||
|
||||
case "getallaccrossorigin":
|
||||
return this.taskGetAllCrossOrigin();
|
||||
break;
|
||||
|
||||
case "save":
|
||||
return this.taskSave(task.data);
|
||||
break;
|
||||
@ -330,31 +312,6 @@ var NotificationDB = {
|
||||
return Promise.resolve(notifications);
|
||||
},
|
||||
|
||||
taskGetAllCrossOrigin: function() {
|
||||
if (DEBUG) { debug("Task, getting all whatever origin"); }
|
||||
var notifications = [];
|
||||
for (var origin in this.notifications) {
|
||||
if (!this.notifications[origin]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (var i in this.notifications[origin]) {
|
||||
var notification = this.notifications[origin][i];
|
||||
|
||||
// Notifications without the alertName field cannot be resent by
|
||||
// mozResendAllNotifications, so we just skip them. They will
|
||||
// still be available to applications via Notification.get()
|
||||
if (!('alertName' in notification)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
notification.origin = origin;
|
||||
notifications.push(notification);
|
||||
}
|
||||
}
|
||||
return Promise.resolve(notifications);
|
||||
},
|
||||
|
||||
taskSave: function(data) {
|
||||
if (DEBUG) { debug("Task, saving"); }
|
||||
var origin = data.origin;
|
||||
|
@ -23,10 +23,6 @@ XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
||||
"@mozilla.org/childprocessmessagemanager;1",
|
||||
"nsIMessageSender");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "appsService",
|
||||
"@mozilla.org/AppsService;1",
|
||||
"nsIAppsService");
|
||||
|
||||
const kMessageNotificationGetAllOk = "Notification:GetAll:Return:OK";
|
||||
const kMessageNotificationGetAllKo = "Notification:GetAll:Return:KO";
|
||||
const kMessageNotificationSaveKo = "Notification:Save:Return:KO";
|
||||
|
@ -5,8 +5,6 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
EXTRA_COMPONENTS += [
|
||||
'ChromeNotifications.js',
|
||||
'ChromeNotifications.manifest',
|
||||
'NotificationStorage.js',
|
||||
'NotificationStorage.manifest',
|
||||
]
|
||||
|
@ -11,7 +11,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
||||
|
||||
function getNotificationObject(app, id, tag) {
|
||||
return {
|
||||
origin: "app://" + app + ".gaiamobile.org/manifest.webapp",
|
||||
origin: "https://" + app + ".gaiamobile.org/",
|
||||
id: id,
|
||||
title: app + "Notification:" + Date.now(),
|
||||
dir: "auto",
|
||||
|
@ -308,101 +308,3 @@ add_test(function test_delete_previous() {
|
||||
requestID: requestID
|
||||
});
|
||||
});
|
||||
|
||||
// Store two notifications, one without alertName and one with
|
||||
add_test(function test_send_two_alertName() {
|
||||
let requestID = 30;
|
||||
let notifications = [
|
||||
{
|
||||
origin: "app://system.gaiamobile.org/manifest.webapp",
|
||||
id: "{27ead857-4f43-457f-a770-93b82fbfc223}",
|
||||
title: "Notification title",
|
||||
dir: "auto",
|
||||
lang: "",
|
||||
body: "Notification body",
|
||||
tag: "",
|
||||
icon: "icon.png",
|
||||
timestamp: new Date().getTime()
|
||||
}, {
|
||||
origin: "app://system.gaiamobile.org/manifest.webapp",
|
||||
id: "{40275e04-58d0-47be-8cc7-540578f793a4}",
|
||||
title: "Notification title",
|
||||
dir: "auto",
|
||||
lang: "",
|
||||
body: "Notification body",
|
||||
tag: "",
|
||||
icon: "icon.png",
|
||||
alertName: "alertName",
|
||||
timestamp: new Date().getTime()
|
||||
}
|
||||
];
|
||||
let origin = notifications[0].origin;
|
||||
|
||||
let msgGetCrossOriginReply = "Notification:GetAllCrossOrigin:Return:OK";
|
||||
let msgGetCrossOriginHandler = {
|
||||
receiveMessage: function(message) {
|
||||
if (message.name === msgGetCrossOriginReply) {
|
||||
cpmm.removeMessageListener(
|
||||
msgGetCrossOriginReply, msgGetCrossOriginHandler);
|
||||
|
||||
let gotNotifications = message.data.notifications;
|
||||
|
||||
// we expect to have one notification
|
||||
do_check_eq(1, gotNotifications.length);
|
||||
|
||||
// compare the only notification we should have got back
|
||||
compareNotification(gotNotifications[0], notifications[1]);
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
}
|
||||
};
|
||||
cpmm.addMessageListener(msgGetCrossOriginReply, msgGetCrossOriginHandler);
|
||||
|
||||
let msgGetReply = "Notification:GetAll:Return:OK";
|
||||
let msgGetHandler = {
|
||||
receiveMessage: function(message) {
|
||||
if (message.name === msgGetReply) {
|
||||
cpmm.removeMessageListener(msgGetReply, msgGetHandler);
|
||||
|
||||
let gotNotifications = message.data.notifications;
|
||||
|
||||
// we expect to have two notifications
|
||||
do_check_eq(2, gotNotifications.length);
|
||||
|
||||
// compare each notification
|
||||
for (let i = 0; i < gotNotifications.length; i++) {
|
||||
compareNotification(gotNotifications[i], notifications[i]);
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
}
|
||||
};
|
||||
cpmm.addMessageListener(msgGetReply, msgGetHandler);
|
||||
|
||||
let msgSaveReply = "Notification:Save:Return:OK";
|
||||
let msgSaveCalls = 0;
|
||||
let msgSaveHandler = {
|
||||
receiveMessage: function(message) {
|
||||
if (message.name === msgSaveReply) {
|
||||
msgSaveCalls++;
|
||||
if (msgSaveCalls === 2) {
|
||||
cpmm.removeMessageListener(msgSaveReply, msgSaveHandler);
|
||||
// Trigger getall
|
||||
cpmm.sendAsyncMessage("Notification:GetAll", {
|
||||
origin: origin
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
cpmm.addMessageListener(msgSaveReply, msgSaveHandler);
|
||||
|
||||
notifications.forEach(function(n) {
|
||||
cpmm.sendAsyncMessage("Notification:Save", {
|
||||
origin: origin,
|
||||
notification: n
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1022,14 +1022,14 @@ class GetUsageOp final
|
||||
public:
|
||||
explicit GetUsageOp(const UsageRequestParams& aParams);
|
||||
|
||||
bool
|
||||
MOZ_IS_CLASS_INIT bool
|
||||
Init(Quota* aQuota);
|
||||
|
||||
private:
|
||||
~GetUsageOp()
|
||||
{ }
|
||||
|
||||
virtual nsresult
|
||||
MOZ_IS_CLASS_INIT virtual nsresult
|
||||
DoInitOnMainThread() override;
|
||||
|
||||
nsresult
|
||||
|
@ -1,29 +0,0 @@
|
||||
function handleRequest(request, response) {
|
||||
|
||||
var query = {};
|
||||
|
||||
request.queryString.split('&').forEach(function(val) {
|
||||
var [name, value] = val.split('=');
|
||||
query[name] = unescape(value);
|
||||
});
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
|
||||
if ("type" in query) {
|
||||
switch (query.type) {
|
||||
case "script":
|
||||
response.setHeader("Content-Type", "application/javascript");
|
||||
response.write("\n\ndocument.write('<pre>script loaded\\n</pre>');\n\n");
|
||||
return;
|
||||
case "style":
|
||||
response.setHeader("Content-Type", "text/css");
|
||||
response.write("\n\n.cspfoo { color:red; }\n\n");
|
||||
return;
|
||||
case "img":
|
||||
response.setHeader("Content-Type", "image/png");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
response.setHeader("Content-Type", "text/plain");
|
||||
response.write("ohnoes!");
|
||||
}
|
@ -258,7 +258,7 @@ nsSVGElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
}
|
||||
const nsAttrValue* oldVal = mAttrsAndChildren.GetAttr(nsGkAtoms::style);
|
||||
|
||||
if (oldVal && oldVal->Type() == nsAttrValue::eGeckoCSSDeclaration) {
|
||||
if (oldVal && oldVal->Type() == nsAttrValue::eCSSDeclaration) {
|
||||
// we need to force a reparse because the baseURI of the document
|
||||
// may have changed, and in particular because we may be clones of
|
||||
// XBL anonymous content now being bound to the document we should
|
||||
|
@ -61,25 +61,6 @@ var MockServices = (function () {
|
||||
}, alertListener);
|
||||
},
|
||||
|
||||
showAppNotification: function(aImageUrl, aTitle, aText, aAlertListener, aDetails) {
|
||||
var listener = aAlertListener || (activeAlertNotifications[aDetails.id] ? activeAlertNotifications[aDetails.id].listener : undefined);
|
||||
activeAppNotifications[aDetails.id] = {
|
||||
observer: listener,
|
||||
title: aTitle,
|
||||
text: aText,
|
||||
manifestURL: aDetails.manifestURL,
|
||||
imageURL: aImageUrl,
|
||||
lang: aDetails.lang || undefined,
|
||||
id: aDetails.id || undefined,
|
||||
dbId: aDetails.dbId || undefined,
|
||||
dir: aDetails.dir || undefined,
|
||||
tag: aDetails.tag || undefined,
|
||||
timestamp: aDetails.timestamp || undefined,
|
||||
data: aDetails.data || undefined
|
||||
};
|
||||
this.showAlertNotification(aImageUrl, aTitle, aText, true, "", listener, aDetails.id);
|
||||
},
|
||||
|
||||
closeAlert: function(name) {
|
||||
var alertNotification = activeAlertNotifications[name];
|
||||
if (alertNotification) {
|
||||
@ -97,8 +78,7 @@ var MockServices = (function () {
|
||||
|
||||
QueryInterface: function(aIID) {
|
||||
if (SpecialPowers.wrap(aIID).equals(SpecialPowers.Ci.nsISupports) ||
|
||||
SpecialPowers.wrap(aIID).equals(SpecialPowers.Ci.nsIAlertsService) ||
|
||||
SpecialPowers.wrap(aIID).equals(SpecialPowers.Ci.nsIAppNotificationService)) {
|
||||
SpecialPowers.wrap(aIID).equals(SpecialPowers.Ci.nsIAlertsService)) {
|
||||
return this;
|
||||
}
|
||||
throw SpecialPowers.Components.results.NS_ERROR_NO_INTERFACE;
|
||||
|
@ -1,8 +0,0 @@
|
||||
[DEFAULT]
|
||||
skip-if = toolkit == 'android' # Bug 1287455: takes too long to complete on Android
|
||||
support-files =
|
||||
MockServices.js
|
||||
NotificationTest.js
|
||||
|
||||
[test_notification_noresend.html]
|
||||
skip-if = (toolkit == 'gonk') # Mochitest on Gonk registers an app manifest that messes with the logic
|
@ -27,16 +27,9 @@ var mockAlertsService = {
|
||||
}, alertListener);
|
||||
},
|
||||
|
||||
showAppNotification: function(imageUrl, title, text, alertListener, details) {
|
||||
this.showAlertNotification(imageUrl, title, text, details.textClickable, "",
|
||||
alertListener, details.name, details.dir,
|
||||
details.lang, details.data);
|
||||
},
|
||||
|
||||
QueryInterface: function(aIID) {
|
||||
if (SpecialPowers.wrap(aIID).equals(SpecialPowers.Ci.nsISupports) ||
|
||||
SpecialPowers.wrap(aIID).equals(SpecialPowers.Ci.nsIAlertsService) ||
|
||||
SpecialPowers.wrap(aIID).equals(SpecialPowers.Ci.nsIAppNotificationService)) {
|
||||
SpecialPowers.wrap(aIID).equals(SpecialPowers.Ci.nsIAlertsService)) {
|
||||
return this;
|
||||
}
|
||||
throw SpecialPowers.Components.results.NS_ERROR_NO_INTERFACE;
|
||||
|
@ -1,88 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Testing mozResendAllNotifications() resend behavior for Pages</title>
|
||||
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="MockServices.js"></script>
|
||||
<script type="text/javascript" src="NotificationTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1159128">Bug 1159128</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<script type="text/javascript">
|
||||
var info = NotificationTest.info;
|
||||
var notifications = [];
|
||||
|
||||
SimpleTest.requestFlakyTimeout("untriaged");
|
||||
|
||||
var steps = [
|
||||
function (done) {
|
||||
if (window.Notification) {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["dom.ignore_webidl_scope_checks", true],
|
||||
]}, done);
|
||||
} else {
|
||||
ok(true, "Notifications are not enabled on the platform.");
|
||||
done();
|
||||
}
|
||||
},
|
||||
|
||||
function (done) {
|
||||
info("Test that we have mozChromeNotifications API");
|
||||
ok(('mozChromeNotifications' in navigator), "should have mozChromeNotifications API");
|
||||
ok(('mozResendAllNotifications' in navigator.mozChromeNotifications), "should have mozResendAllNotifications()");
|
||||
done();
|
||||
},
|
||||
|
||||
function (done) {
|
||||
info("Making sure we have no previous notification pending");
|
||||
var promise = Notification.get();
|
||||
promise.then(function (notifications) {
|
||||
is(notifications.length, 0, "notifications are all cleaned");
|
||||
done();
|
||||
});
|
||||
},
|
||||
|
||||
// The notification is expected to be created and living properly
|
||||
// so it will be accessible via Notification.get(), but NotificationStorage
|
||||
// should not have sent it to NotificationDB.
|
||||
function (done) {
|
||||
info("Sending one notification");
|
||||
var notif = new Notification("title");
|
||||
ok(notif, "Notification object is valid");
|
||||
notifications.push(notif);
|
||||
|
||||
var promise = Notification.get();
|
||||
promise.then(function (notifications) {
|
||||
is(notifications.length, 1, "one notification has been sent");
|
||||
done();
|
||||
});
|
||||
},
|
||||
|
||||
// mozResendAllNotifications will poke directly NotificationDB, so we
|
||||
// expect our notification to NOT have been put there and thus not being
|
||||
// resent.
|
||||
function (done) {
|
||||
info("Trying to resend the notification");
|
||||
var notif = notifications.pop();
|
||||
notif.onclose = function() {
|
||||
done();
|
||||
};
|
||||
|
||||
navigator.mozChromeNotifications.mozResendAllNotifications(function(number) {
|
||||
is(number, 0, "No notification resent");
|
||||
notif.close();
|
||||
});
|
||||
}
|
||||
];
|
||||
|
||||
MockServices.register();
|
||||
NotificationTest.run(steps, function () {
|
||||
MockServices.unregister();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -36,7 +36,6 @@ MOCHITEST_CHROME_MANIFESTS += [
|
||||
'mochitest/general/chrome.ini',
|
||||
'mochitest/geolocation/chrome.ini',
|
||||
'mochitest/localstorage/chrome.ini',
|
||||
'mochitest/notification/chrome.ini',
|
||||
'mochitest/sessionstorage/chrome.ini',
|
||||
'mochitest/whatwg/chrome.ini',
|
||||
]
|
||||
|
@ -191,7 +191,7 @@ private:
|
||||
uint16_t mCount;
|
||||
bool mIsStopped;
|
||||
nsString mResponse;
|
||||
ErrorCode mErrorCode;
|
||||
MOZ_INIT_OUTSIDE_CTOR ErrorCode mErrorCode;
|
||||
ReentrantMonitor mReentrantMonitor;
|
||||
};
|
||||
|
||||
|
@ -1,14 +0,0 @@
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/.
|
||||
*/
|
||||
|
||||
[JSImplementation="@mozilla.org/mozChromeNotifications;1",
|
||||
NavigatorProperty="mozChromeNotifications",
|
||||
ChromeOnly]
|
||||
interface ChromeNotifications {
|
||||
void mozResendAllNotifications(ResendCallback resendCallback);
|
||||
};
|
||||
|
||||
callback ResendCallback = void (long count);
|
@ -74,7 +74,6 @@ WEBIDL_FILES = [
|
||||
'CheckerboardReportService.webidl',
|
||||
'ChildNode.webidl',
|
||||
'ChromeNodeList.webidl',
|
||||
'ChromeNotifications.webidl',
|
||||
'ChromeUtils.webidl',
|
||||
'Client.webidl',
|
||||
'Clients.webidl',
|
||||
|
@ -125,7 +125,7 @@ nsBindingManager::~nsBindingManager(void)
|
||||
}
|
||||
|
||||
nsXBLBinding*
|
||||
nsBindingManager::GetBindingWithContent(nsIContent* aContent)
|
||||
nsBindingManager::GetBindingWithContent(const nsIContent* aContent)
|
||||
{
|
||||
nsXBLBinding* binding = aContent ? aContent->GetXBLBinding() : nullptr;
|
||||
return binding ? binding->GetBindingWithContent() : nullptr;
|
||||
|
@ -46,7 +46,7 @@ public:
|
||||
|
||||
explicit nsBindingManager(nsIDocument* aDocument);
|
||||
|
||||
nsXBLBinding* GetBindingWithContent(nsIContent* aContent);
|
||||
nsXBLBinding* GetBindingWithContent(const nsIContent* aContent);
|
||||
|
||||
void AddBoundContent(nsIContent* aContent);
|
||||
void RemoveBoundContent(nsIContent* aContent);
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "mozilla/EventListenerManager.h"
|
||||
#include "mozilla/EventStateManager.h"
|
||||
#include "mozilla/EventStates.h"
|
||||
#include "mozilla/DeclarationBlockInlines.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "nsHTMLStyleSheet.h"
|
||||
#include "nsNameSpaceManager.h"
|
||||
@ -374,14 +375,15 @@ nsXULElement::Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const
|
||||
nsAttrValue attrValue;
|
||||
|
||||
// Style rules need to be cloned.
|
||||
if (originalValue->Type() == nsAttrValue::eGeckoCSSDeclaration) {
|
||||
RefPtr<css::Declaration> declClone = new css::Declaration(
|
||||
*originalValue->GetGeckoCSSDeclarationValue());
|
||||
if (originalValue->Type() == nsAttrValue::eCSSDeclaration) {
|
||||
DeclarationBlock* decl = originalValue->GetCSSDeclarationValue();
|
||||
RefPtr<css::Declaration>
|
||||
declClone = new css::Declaration(*decl->AsGecko());
|
||||
|
||||
nsString stringValue;
|
||||
originalValue->ToString(stringValue);
|
||||
|
||||
attrValue.SetTo(declClone, &stringValue);
|
||||
attrValue.SetTo(declClone.forget(), &stringValue);
|
||||
} else {
|
||||
attrValue.SetTo(*originalValue);
|
||||
}
|
||||
@ -1860,14 +1862,15 @@ nsXULElement::MakeHeavyweight(nsXULPrototypeElement* aPrototype)
|
||||
nsAttrValue attrValue;
|
||||
|
||||
// Style rules need to be cloned.
|
||||
if (protoattr->mValue.Type() == nsAttrValue::eGeckoCSSDeclaration) {
|
||||
RefPtr<css::Declaration> declClone = new css::Declaration(
|
||||
*protoattr->mValue.GetGeckoCSSDeclarationValue());
|
||||
if (protoattr->mValue.Type() == nsAttrValue::eCSSDeclaration) {
|
||||
DeclarationBlock* decl = protoattr->mValue.GetCSSDeclarationValue();
|
||||
RefPtr<css::Declaration>
|
||||
declClone = new css::Declaration(*decl->AsGecko());
|
||||
|
||||
nsString stringValue;
|
||||
protoattr->mValue.ToString(stringValue);
|
||||
|
||||
attrValue.SetTo(declClone, &stringValue);
|
||||
attrValue.SetTo(declClone.forget(), &stringValue);
|
||||
} else {
|
||||
attrValue.SetTo(protoattr->mValue);
|
||||
}
|
||||
@ -2450,7 +2453,7 @@ nsXULPrototypeElement::SetAttrAt(uint32_t aPos, const nsAString& aValue,
|
||||
mNodeInfo->NodeInfoManager()->
|
||||
DocumentPrincipal());
|
||||
if (declaration) {
|
||||
mAttributes[aPos].mValue.SetTo(declaration, &aValue);
|
||||
mAttributes[aPos].mValue.SetTo(declaration.forget(), &aValue);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include "mozilla/ChangeStyleTransaction.h"
|
||||
#include "mozilla/HTMLEditor.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/css/Declaration.h"
|
||||
#include "mozilla/DeclarationBlockInlines.h"
|
||||
#include "mozilla/css/StyleRule.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/mozalloc.h"
|
||||
@ -544,15 +544,19 @@ CSSEditUtils::GetCSSInlinePropertyBase(nsINode* aNode,
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aStyleType == eSpecified);
|
||||
RefPtr<css::Declaration> decl = element->GetInlineStyleDeclaration();
|
||||
RefPtr<DeclarationBlock> decl = element->GetInlineStyleDeclaration();
|
||||
if (!decl) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (decl->IsServo()) {
|
||||
MOZ_CRASH("stylo: not implemented");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
nsCSSPropertyID prop =
|
||||
nsCSSProps::LookupProperty(nsDependentAtomString(aProperty),
|
||||
CSSEnabledState::eForAllContent);
|
||||
MOZ_ASSERT(prop != eCSSProperty_UNKNOWN);
|
||||
decl->GetValue(prop, aValue);
|
||||
decl->AsGecko()->GetValue(prop, aValue);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -2271,6 +2271,15 @@ EditorBase::ScrollSelectionIntoView(bool aScrollToAnchor)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
EditorBase::FindBetterInsertionPoint(nsCOMPtr<nsIDOMNode>& aNode,
|
||||
int32_t& aOffset)
|
||||
{
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
|
||||
FindBetterInsertionPoint(node, aOffset);
|
||||
aNode = do_QueryInterface(node);
|
||||
}
|
||||
|
||||
void
|
||||
EditorBase::FindBetterInsertionPoint(nsCOMPtr<nsINode>& aNode,
|
||||
int32_t& aOffset)
|
||||
|
@ -922,6 +922,8 @@ public:
|
||||
* FindBetterInsertionPoint() tries to look for better insertion point which
|
||||
* is typically the nearest text node and offset in it.
|
||||
*/
|
||||
void FindBetterInsertionPoint(nsCOMPtr<nsIDOMNode>& aNode,
|
||||
int32_t& aOffset);
|
||||
void FindBetterInsertionPoint(nsCOMPtr<nsINode>& aNode,
|
||||
int32_t& aOffset);
|
||||
|
||||
|
@ -616,6 +616,9 @@ TextEditor::ExtendSelectionForDelete(Selection* aSelection,
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
|
||||
|
||||
// node might be anonymous DIV, so we find better text node
|
||||
FindBetterInsertionPoint(node, offset);
|
||||
|
||||
if (IsTextNode(node)) {
|
||||
nsCOMPtr<nsIDOMCharacterData> charData = do_QueryInterface(node);
|
||||
if (charData) {
|
||||
|
@ -147,6 +147,7 @@ subsuite = clipboard
|
||||
[test_bug795785.html]
|
||||
[test_bug796839.html]
|
||||
[test_bug832025.html]
|
||||
[test_bug850043.html]
|
||||
[test_bug857487.html]
|
||||
[test_bug858918.html]
|
||||
[test_bug915962.html]
|
||||
|
64
editor/libeditor/tests/test_bug850043.html
Normal file
64
editor/libeditor/tests/test_bug850043.html
Normal file
@ -0,0 +1,64 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=850043
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 850043</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=850043">Mozilla Bug 850043</a>
|
||||
<div id="display">
|
||||
<textarea id="textarea">b邀󠄏辺󠄁</textarea>
|
||||
<div contenteditable id="edit">b邀󠄏辺󠄁</div>
|
||||
</div>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<script>
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.waitForFocus(() => {
|
||||
let fm = SpecialPowers.Cc["@mozilla.org/focus-manager;1"].
|
||||
getService(SpecialPowers.Ci.nsIFocusManager);
|
||||
|
||||
let element = document.getElementById("textarea");
|
||||
element.focus();
|
||||
is(SpecialPowers.unwrap(fm.focusedElement), element, "failed to move focus");
|
||||
|
||||
synthesizeKey("VK_END", { });
|
||||
synthesizeKey("a", { });
|
||||
is(element.value, "b\u{9080}\u{e010f}\u{8fba}\u{e0101}a", "a isn't last character");
|
||||
|
||||
synthesizeKey("VK_BACK_SPACE", { });
|
||||
synthesizeKey("VK_BACK_SPACE", { });
|
||||
synthesizeKey("VK_BACK_SPACE", { });
|
||||
is(element.value, 'b', "cannot remove all IVS characters");
|
||||
|
||||
element = document.getElementById("edit");
|
||||
element.focus();
|
||||
is(SpecialPowers.unwrap(fm.focusedElement), element, "failed to move focus");
|
||||
|
||||
let sel = window.getSelection();
|
||||
sel.collapse(element.childNodes[0], element.textContent.length);
|
||||
|
||||
synthesizeKey("a", { });
|
||||
is(element.textContent, "b\u{9080}\u{e010f}\u{8fba}\u{e0101}a", "a isn't last character");
|
||||
|
||||
synthesizeKey("VK_BACK_SPACE", { });
|
||||
synthesizeKey("VK_BACK_SPACE", { });
|
||||
synthesizeKey("VK_BACK_SPACE", { });
|
||||
is(element.textContent, 'b', "cannot remove all IVS characters");
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -153,7 +153,7 @@ public:
|
||||
|
||||
// OnSVGDocumentParsed will release our owner's reference to us, so ensure
|
||||
// we stick around long enough to complete our work.
|
||||
RefPtr<SVGParseCompleteListener> kungFuDeathGroup(this);
|
||||
RefPtr<SVGParseCompleteListener> kungFuDeathGrip(this);
|
||||
|
||||
mImage->OnSVGDocumentParsed();
|
||||
}
|
||||
@ -212,7 +212,7 @@ public:
|
||||
|
||||
// OnSVGDocumentLoaded/OnSVGDocumentError will release our owner's reference
|
||||
// to us, so ensure we stick around long enough to complete our work.
|
||||
RefPtr<SVGLoadEventListener> kungFuDeathGroup(this);
|
||||
RefPtr<SVGLoadEventListener> kungFuDeathGrip(this);
|
||||
|
||||
nsAutoString eventType;
|
||||
aEvent->GetType(eventType);
|
||||
@ -536,8 +536,8 @@ VectorImage::RequestRefresh(const TimeStamp& aTime)
|
||||
mSVGDocumentWrapper->TickRefreshDriver();
|
||||
|
||||
if (mHasPendingInvalidation) {
|
||||
SendInvalidationNotifications();
|
||||
mHasPendingInvalidation = false;
|
||||
SendInvalidationNotifications();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1140,6 +1140,10 @@ VectorImage::OnStartRequest(nsIRequest* aRequest, nsISupports* aCtxt)
|
||||
return rv;
|
||||
}
|
||||
|
||||
// ProgressTracker::SyncNotifyProgress may release us, so ensure we
|
||||
// stick around long enough to complete our work.
|
||||
RefPtr<VectorImage> kungFuDeathGrip(this);
|
||||
|
||||
// Block page load until the document's ready. (We unblock it in
|
||||
// OnSVGDocumentLoaded or OnSVGDocumentError.)
|
||||
if (mProgressTracker) {
|
||||
@ -1220,6 +1224,10 @@ VectorImage::OnSVGDocumentLoaded()
|
||||
// Start listening to our image for rendering updates.
|
||||
mRenderingObserver = new SVGRootRenderingObserver(mSVGDocumentWrapper, this);
|
||||
|
||||
// ProgressTracker::SyncNotifyProgress may release us, so ensure we
|
||||
// stick around long enough to complete our work.
|
||||
RefPtr<VectorImage> kungFuDeathGrip(this);
|
||||
|
||||
// Tell *our* observers that we're done loading.
|
||||
if (mProgressTracker) {
|
||||
Progress progress = FLAG_SIZE_AVAILABLE |
|
||||
|
@ -30,7 +30,7 @@ ToBooleanSlow(JS::HandleValue v);
|
||||
|
||||
/* DO NOT CALL THIS. Use JS::ToNumber. */
|
||||
extern JS_PUBLIC_API(bool)
|
||||
ToNumberSlow(JSContext* cx, const JS::Value& v, double* dp);
|
||||
ToNumberSlow(JSContext* cx, JS::HandleValue v, double* dp);
|
||||
|
||||
/* DO NOT CALL THIS. Use JS::ToInt8. */
|
||||
extern JS_PUBLIC_API(bool)
|
||||
|
1214
js/public/Value.h
1214
js/public/Value.h
File diff suppressed because it is too large
Load Diff
@ -25,13 +25,10 @@
|
||||
* Unimplemented functionality:
|
||||
*
|
||||
* - Tiered compilation (bug 1277562)
|
||||
* - int64 operations on 32-bit systems
|
||||
* - SIMD
|
||||
* - Atomics (very simple now, we have range checking)
|
||||
* - current_memory, grow_memory
|
||||
* - non-signaling interrupts
|
||||
* - profiler support (devtools)
|
||||
* - ARM-32 support (bug 1277011)
|
||||
* - SIMD
|
||||
* - Atomics
|
||||
* - profiler support (devtools)
|
||||
*
|
||||
* There are lots of machine dependencies here but they are pretty
|
||||
* well isolated to a segment of the compiler. Many dependencies
|
||||
@ -166,6 +163,9 @@ static const Register StackPointer = RealStackPointer;
|
||||
// EBX not being one of the WasmTableCall registers; and needing a
|
||||
// temp register for load/store that has a single-byte persona.
|
||||
static const Register ScratchRegX86 = ebx;
|
||||
|
||||
# define QUOT_REM_I64_CALLOUT
|
||||
|
||||
#endif
|
||||
|
||||
class BaseCompiler
|
||||
@ -1729,6 +1729,20 @@ class BaseCompiler
|
||||
}
|
||||
}
|
||||
|
||||
void maybeReserveJoinRegI(ExprType type) {
|
||||
if (type == ExprType::I32)
|
||||
needI32(joinRegI32);
|
||||
else if (type == ExprType::I64)
|
||||
needI64(joinRegI64);
|
||||
}
|
||||
|
||||
void maybeUnreserveJoinRegI(ExprType type) {
|
||||
if (type == ExprType::I32)
|
||||
freeI32(joinRegI32);
|
||||
else if (type == ExprType::I64)
|
||||
freeI64(joinRegI64);
|
||||
}
|
||||
|
||||
// Return the amount of execution stack consumed by the top numval
|
||||
// values on the value stack.
|
||||
|
||||
@ -2469,8 +2483,8 @@ class BaseCompiler
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef QUOT_REM_I64_CALLOUT
|
||||
void quotientI64(RegI64 rhs, RegI64 srcDest, IsUnsigned isUnsigned) {
|
||||
// This follows quotientI32, above.
|
||||
Label done;
|
||||
|
||||
checkDivideByZeroI64(rhs, srcDest, &done);
|
||||
@ -2478,7 +2492,7 @@ class BaseCompiler
|
||||
if (!isUnsigned)
|
||||
checkDivideSignedOverflowI64(rhs, srcDest, &done, ZeroOnOverflow(false));
|
||||
|
||||
#if defined(JS_CODEGEN_X64)
|
||||
# if defined(JS_CODEGEN_X64)
|
||||
// The caller must set up the following situation.
|
||||
MOZ_ASSERT(srcDest.reg.reg == rax);
|
||||
MOZ_ASSERT(isAvailable(rdx));
|
||||
@ -2489,12 +2503,14 @@ class BaseCompiler
|
||||
masm.cqo();
|
||||
masm.idivq(rhs.reg.reg);
|
||||
}
|
||||
#else
|
||||
# else
|
||||
MOZ_CRASH("BaseCompiler platform hook: quotientI64");
|
||||
#endif
|
||||
# endif
|
||||
masm.bind(&done);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef QUOT_REM_I64_CALLOUT
|
||||
void remainderI64(RegI64 rhs, RegI64 srcDest, IsUnsigned isUnsigned) {
|
||||
Label done;
|
||||
|
||||
@ -2503,7 +2519,7 @@ class BaseCompiler
|
||||
if (!isUnsigned)
|
||||
checkDivideSignedOverflowI64(rhs, srcDest, &done, ZeroOnOverflow(true));
|
||||
|
||||
#if defined(JS_CODEGEN_X64)
|
||||
# if defined(JS_CODEGEN_X64)
|
||||
// The caller must set up the following situation.
|
||||
MOZ_ASSERT(srcDest.reg.reg == rax);
|
||||
MOZ_ASSERT(isAvailable(rdx));
|
||||
@ -2516,11 +2532,12 @@ class BaseCompiler
|
||||
masm.idivq(rhs.reg.reg);
|
||||
}
|
||||
masm.movq(rdx, rax);
|
||||
#else
|
||||
# else
|
||||
MOZ_CRASH("BaseCompiler platform hook: remainderI64");
|
||||
#endif
|
||||
# endif
|
||||
masm.bind(&done);
|
||||
}
|
||||
#endif
|
||||
|
||||
void orI64(RegI64 rhs, RegI64 srcDest) {
|
||||
masm.or64(rhs.reg, srcDest.reg);
|
||||
@ -3302,9 +3319,9 @@ class BaseCompiler
|
||||
bool emitUnaryMathBuiltinCall(SymbolicAddress callee, ValType operandType);
|
||||
MOZ_MUST_USE
|
||||
bool emitBinaryMathBuiltinCall(SymbolicAddress callee, ValType operandType);
|
||||
#ifdef JS_NUNBOX32
|
||||
void emitDivOrModI64BuiltinCall(SymbolicAddress callee, RegI64 rhs, RegI64 srcDest,
|
||||
RegI32 temp);
|
||||
#ifdef QUOT_REM_I64_CALLOUT
|
||||
MOZ_MUST_USE
|
||||
bool emitDivOrModI64BuiltinCall(SymbolicAddress callee, ValType operandType);
|
||||
#endif
|
||||
MOZ_MUST_USE
|
||||
bool emitGetLocal();
|
||||
@ -3356,12 +3373,14 @@ class BaseCompiler
|
||||
void emitMultiplyF64();
|
||||
void emitQuotientI32();
|
||||
void emitQuotientU32();
|
||||
void emitQuotientI64();
|
||||
void emitQuotientU64();
|
||||
void emitRemainderI32();
|
||||
void emitRemainderU32();
|
||||
#ifndef QUOT_REM_I64_CALLOUT
|
||||
void emitQuotientI64();
|
||||
void emitQuotientU64();
|
||||
void emitRemainderI64();
|
||||
void emitRemainderU64();
|
||||
#endif
|
||||
void emitDivideF32();
|
||||
void emitDivideF64();
|
||||
void emitMinI32();
|
||||
@ -3636,75 +3655,51 @@ BaseCompiler::emitQuotientU32()
|
||||
pushI32(r0);
|
||||
}
|
||||
|
||||
#ifndef QUOT_REM_I64_CALLOUT
|
||||
void
|
||||
BaseCompiler::emitQuotientI64()
|
||||
{
|
||||
#ifdef JS_PUNBOX64
|
||||
# ifdef JS_PUNBOX64
|
||||
RegI64 r0, r1;
|
||||
# ifdef JS_CODEGEN_X64
|
||||
# ifdef JS_CODEGEN_X64
|
||||
// srcDest must be rax, and rdx will be clobbered.
|
||||
need2xI64(specific_rax, specific_rdx);
|
||||
r1 = popI64();
|
||||
r0 = popI64ToSpecific(specific_rax);
|
||||
freeI64(specific_rdx);
|
||||
# else
|
||||
# else
|
||||
pop2xI64(&r0, &r1);
|
||||
# endif
|
||||
# endif
|
||||
quotientI64(r1, r0, IsUnsigned(false));
|
||||
freeI64(r1);
|
||||
pushI64(r0);
|
||||
#else
|
||||
# if defined(JS_CODEGEN_X86)
|
||||
RegI64 r0, r1;
|
||||
RegI32 temp;
|
||||
needI64(abiReturnRegI64);
|
||||
temp = needI32();
|
||||
r1 = popI64();
|
||||
r0 = popI64ToSpecific(abiReturnRegI64);
|
||||
emitDivOrModI64BuiltinCall(SymbolicAddress::DivI64, r1, r0, temp);
|
||||
freeI32(temp);
|
||||
freeI64(r1);
|
||||
pushI64(r0);
|
||||
# else
|
||||
MOZ_CRASH("BaseCompiler platform hook: emitQuotientI64");
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
BaseCompiler::emitQuotientU64()
|
||||
{
|
||||
#ifdef JS_PUNBOX64
|
||||
# ifdef JS_PUNBOX64
|
||||
RegI64 r0, r1;
|
||||
# ifdef JS_CODEGEN_X64
|
||||
# ifdef JS_CODEGEN_X64
|
||||
// srcDest must be rax, and rdx will be clobbered.
|
||||
need2xI64(specific_rax, specific_rdx);
|
||||
r1 = popI64();
|
||||
r0 = popI64ToSpecific(specific_rax);
|
||||
freeI64(specific_rdx);
|
||||
# else
|
||||
# else
|
||||
pop2xI64(&r0, &r1);
|
||||
# endif
|
||||
# endif
|
||||
quotientI64(r1, r0, IsUnsigned(true));
|
||||
freeI64(r1);
|
||||
pushI64(r0);
|
||||
#else
|
||||
# if defined(JS_CODEGEN_X86)
|
||||
RegI64 r0, r1;
|
||||
RegI32 temp;
|
||||
needI64(abiReturnRegI64);
|
||||
temp = needI32();
|
||||
r1 = popI64();
|
||||
r0 = popI64ToSpecific(abiReturnRegI64);
|
||||
emitDivOrModI64BuiltinCall(SymbolicAddress::UDivI64, r1, r0, temp);
|
||||
freeI32(temp);
|
||||
freeI64(r1);
|
||||
pushI64(r0);
|
||||
# else
|
||||
MOZ_CRASH("BaseCompiler platform hook: emitQuotientU64");
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
BaseCompiler::emitRemainderI32()
|
||||
@ -3755,73 +3750,49 @@ BaseCompiler::emitRemainderU32()
|
||||
pushI32(r0);
|
||||
}
|
||||
|
||||
#ifndef QUOT_REM_I64_CALLOUT
|
||||
void
|
||||
BaseCompiler::emitRemainderI64()
|
||||
{
|
||||
#ifdef JS_PUNBOX64
|
||||
# ifdef JS_PUNBOX64
|
||||
RegI64 r0, r1;
|
||||
# ifdef JS_CODEGEN_X64
|
||||
# ifdef JS_CODEGEN_X64
|
||||
need2xI64(specific_rax, specific_rdx);
|
||||
r1 = popI64();
|
||||
r0 = popI64ToSpecific(specific_rax);
|
||||
freeI64(specific_rdx);
|
||||
# else
|
||||
# else
|
||||
pop2xI64(&r0, &r1);
|
||||
# endif
|
||||
# endif
|
||||
remainderI64(r1, r0, IsUnsigned(false));
|
||||
freeI64(r1);
|
||||
pushI64(r0);
|
||||
#else
|
||||
# if defined(JS_CODEGEN_X86)
|
||||
RegI64 r0, r1;
|
||||
RegI32 temp;
|
||||
needI64(abiReturnRegI64);
|
||||
temp = needI32();
|
||||
r1 = popI64();
|
||||
r0 = popI64ToSpecific(abiReturnRegI64);
|
||||
emitDivOrModI64BuiltinCall(SymbolicAddress::ModI64, r1, r0, temp);
|
||||
freeI32(temp);
|
||||
freeI64(r1);
|
||||
pushI64(r0);
|
||||
# else
|
||||
MOZ_CRASH("BaseCompiler platform hook: emitRemainderI64");
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
BaseCompiler::emitRemainderU64()
|
||||
{
|
||||
#ifdef JS_PUNBOX64
|
||||
# ifdef JS_PUNBOX64
|
||||
RegI64 r0, r1;
|
||||
# ifdef JS_CODEGEN_X64
|
||||
# ifdef JS_CODEGEN_X64
|
||||
need2xI64(specific_rax, specific_rdx);
|
||||
r1 = popI64();
|
||||
r0 = popI64ToSpecific(specific_rax);
|
||||
freeI64(specific_rdx);
|
||||
# else
|
||||
# else
|
||||
pop2xI64(&r0, &r1);
|
||||
# endif
|
||||
# endif
|
||||
remainderI64(r1, r0, IsUnsigned(true));
|
||||
freeI64(r1);
|
||||
pushI64(r0);
|
||||
#else
|
||||
# if defined(JS_CODEGEN_X86)
|
||||
RegI64 r0, r1;
|
||||
RegI32 temp;
|
||||
needI64(abiReturnRegI64);
|
||||
temp = needI32();
|
||||
r1 = popI64();
|
||||
r0 = popI64ToSpecific(abiReturnRegI64);
|
||||
emitDivOrModI64BuiltinCall(SymbolicAddress::UModI64, r1, r0, temp);
|
||||
freeI32(temp);
|
||||
freeI64(r1);
|
||||
pushI64(r0);
|
||||
# else
|
||||
MOZ_CRASH("BaseCompiler platform hook: emitRemainderU64");
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
BaseCompiler::emitDivideF32()
|
||||
@ -4964,16 +4935,13 @@ BaseCompiler::emitBrIf()
|
||||
// allowing a conditional expression to be left on the stack and
|
||||
// reified here as part of the branch instruction.
|
||||
|
||||
// We'll need the joinreg later, so don't use it for rc.
|
||||
// We assume joinRegI32 and joinRegI64 overlap.
|
||||
if (type == ExprType::I32 || type == ExprType::I64)
|
||||
needI32(joinRegI32);
|
||||
// Don't use joinReg for rc
|
||||
maybeReserveJoinRegI(type);
|
||||
|
||||
// Condition value is on top, always I32.
|
||||
RegI32 rc = popI32();
|
||||
|
||||
if (type == ExprType::I32 || type == ExprType::I64)
|
||||
freeI32(joinRegI32);
|
||||
maybeUnreserveJoinRegI(type);
|
||||
|
||||
// Save any value in the designated join register, where the
|
||||
// normal block exit code will also leave it.
|
||||
@ -5024,16 +4992,13 @@ BaseCompiler::emitBrTable()
|
||||
if (deadCode_)
|
||||
return true;
|
||||
|
||||
// We'll need the joinreg later, so don't use it for rc.
|
||||
// We assume joinRegI32 and joinRegI64 overlap.
|
||||
if (type == ExprType::I32 || type == ExprType::I64)
|
||||
needI32(joinRegI32);
|
||||
// Don't use joinReg for rc
|
||||
maybeReserveJoinRegI(type);
|
||||
|
||||
// Table switch value always on top.
|
||||
RegI32 rc = popI32();
|
||||
|
||||
if (type == ExprType::I32 || type == ExprType::I64)
|
||||
freeI32(joinRegI32);
|
||||
maybeUnreserveJoinRegI(type);
|
||||
|
||||
AnyReg r;
|
||||
if (!IsVoid(type))
|
||||
@ -5493,15 +5458,25 @@ BaseCompiler::emitBinaryMathBuiltinCall(SymbolicAddress callee, ValType operandT
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef JS_NUNBOX32
|
||||
void
|
||||
BaseCompiler::emitDivOrModI64BuiltinCall(SymbolicAddress callee, RegI64 rhs, RegI64 srcDest,
|
||||
RegI32 temp)
|
||||
#ifdef QUOT_REM_I64_CALLOUT
|
||||
bool
|
||||
BaseCompiler::emitDivOrModI64BuiltinCall(SymbolicAddress callee, ValType operandType)
|
||||
{
|
||||
Label done;
|
||||
MOZ_ASSERT(operandType == ValType::I64);
|
||||
|
||||
if (deadCode_)
|
||||
return true;
|
||||
|
||||
sync();
|
||||
|
||||
needI64(abiReturnRegI64);
|
||||
|
||||
RegI32 temp = needI32();
|
||||
RegI64 rhs = popI64();
|
||||
RegI64 srcDest = popI64ToSpecific(abiReturnRegI64);
|
||||
|
||||
Label done;
|
||||
|
||||
checkDivideByZeroI64(rhs, srcDest, &done);
|
||||
|
||||
if (callee == SymbolicAddress::DivI64)
|
||||
@ -5516,9 +5491,13 @@ BaseCompiler::emitDivOrModI64BuiltinCall(SymbolicAddress callee, RegI64 rhs, Reg
|
||||
masm.passABIArg(rhs.reg.low);
|
||||
masm.callWithABI(callee);
|
||||
|
||||
MOZ_ASSERT(abiReturnRegI64.reg == srcDest.reg);
|
||||
|
||||
masm.bind(&done);
|
||||
|
||||
freeI32(temp);
|
||||
freeI64(rhs);
|
||||
pushI64(srcDest);
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -6544,13 +6523,29 @@ BaseCompiler::emitBody()
|
||||
case Expr::I64Mul:
|
||||
CHECK_NEXT(emitBinary(emitMultiplyI64, ValType::I64));
|
||||
case Expr::I64DivS:
|
||||
#ifdef QUOT_REM_I64_CALLOUT
|
||||
CHECK_NEXT(emitDivOrModI64BuiltinCall(SymbolicAddress::DivI64, ValType::I64));
|
||||
#else
|
||||
CHECK_NEXT(emitBinary(emitQuotientI64, ValType::I64));
|
||||
#endif
|
||||
case Expr::I64DivU:
|
||||
#ifdef QUOT_REM_I64_CALLOUT
|
||||
CHECK_NEXT(emitDivOrModI64BuiltinCall(SymbolicAddress::UDivI64, ValType::I64));
|
||||
#else
|
||||
CHECK_NEXT(emitBinary(emitQuotientU64, ValType::I64));
|
||||
#endif
|
||||
case Expr::I64RemS:
|
||||
#ifdef QUOT_REM_I64_CALLOUT
|
||||
CHECK_NEXT(emitDivOrModI64BuiltinCall(SymbolicAddress::ModI64, ValType::I64));
|
||||
#else
|
||||
CHECK_NEXT(emitBinary(emitRemainderI64, ValType::I64));
|
||||
#endif
|
||||
case Expr::I64RemU:
|
||||
#ifdef QUOT_REM_I64_CALLOUT
|
||||
CHECK_NEXT(emitDivOrModI64BuiltinCall(SymbolicAddress::UModI64, ValType::I64));
|
||||
#else
|
||||
CHECK_NEXT(emitBinary(emitRemainderU64, ValType::I64));
|
||||
#endif
|
||||
case Expr::I64TruncSF32:
|
||||
CHECK_NEXT(emitConversionOOM(emitTruncateF32ToI64<false>, ValType::F32, ValType::I64));
|
||||
case Expr::I64TruncUF32:
|
||||
@ -7198,3 +7193,5 @@ js::wasm::BaselineCompileFunction(IonCompileTask* task)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#undef QUOT_REM_I64_CALLOUT
|
||||
|
@ -85,40 +85,39 @@ function FunctionBind(thisArg, ...boundArgs) {
|
||||
*/
|
||||
function bind_bindFunction0(fun, thisArg, boundArgs) {
|
||||
return function bound() {
|
||||
var a = arguments;
|
||||
var newTarget;
|
||||
if (_IsConstructing()) {
|
||||
newTarget = new.target;
|
||||
if (newTarget === bound)
|
||||
newTarget = fun;
|
||||
switch (a.length) {
|
||||
switch (arguments.length) {
|
||||
case 0:
|
||||
return constructContentFunction(fun, newTarget);
|
||||
case 1:
|
||||
return constructContentFunction(fun, newTarget, a[0]);
|
||||
return constructContentFunction(fun, newTarget, SPREAD(arguments, 1));
|
||||
case 2:
|
||||
return constructContentFunction(fun, newTarget, a[0], a[1]);
|
||||
return constructContentFunction(fun, newTarget, SPREAD(arguments, 2));
|
||||
case 3:
|
||||
return constructContentFunction(fun, newTarget, a[0], a[1], a[2]);
|
||||
return constructContentFunction(fun, newTarget, SPREAD(arguments, 3));
|
||||
case 4:
|
||||
return constructContentFunction(fun, newTarget, a[0], a[1], a[2], a[3]);
|
||||
return constructContentFunction(fun, newTarget, SPREAD(arguments, 4));
|
||||
case 5:
|
||||
return constructContentFunction(fun, newTarget, a[0], a[1], a[2], a[3], a[4]);
|
||||
return constructContentFunction(fun, newTarget, SPREAD(arguments, 5));
|
||||
}
|
||||
} else {
|
||||
switch (a.length) {
|
||||
switch (arguments.length) {
|
||||
case 0:
|
||||
return callContentFunction(fun, thisArg);
|
||||
case 1:
|
||||
return callContentFunction(fun, thisArg, a[0]);
|
||||
return callContentFunction(fun, thisArg, SPREAD(arguments, 1));
|
||||
case 2:
|
||||
return callContentFunction(fun, thisArg, a[0], a[1]);
|
||||
return callContentFunction(fun, thisArg, SPREAD(arguments, 2));
|
||||
case 3:
|
||||
return callContentFunction(fun, thisArg, a[0], a[1], a[2]);
|
||||
return callContentFunction(fun, thisArg, SPREAD(arguments, 3));
|
||||
case 4:
|
||||
return callContentFunction(fun, thisArg, a[0], a[1], a[2], a[3]);
|
||||
return callContentFunction(fun, thisArg, SPREAD(arguments, 4));
|
||||
case 5:
|
||||
return callContentFunction(fun, thisArg, a[0], a[1], a[2], a[3], a[4]);
|
||||
return callContentFunction(fun, thisArg, SPREAD(arguments, 5));
|
||||
}
|
||||
}
|
||||
var callArgs = FUN_APPLY(bind_mapArguments, null, arguments);
|
||||
@ -129,40 +128,39 @@ function bind_bindFunction0(fun, thisArg, boundArgs) {
|
||||
function bind_bindFunction1(fun, thisArg, boundArgs) {
|
||||
var bound1 = boundArgs[0];
|
||||
return function bound() {
|
||||
var a = arguments;
|
||||
var newTarget;
|
||||
if (_IsConstructing()) {
|
||||
newTarget = new.target;
|
||||
if (newTarget === bound)
|
||||
newTarget = fun;
|
||||
switch (a.length) {
|
||||
switch (arguments.length) {
|
||||
case 0:
|
||||
return constructContentFunction(fun, newTarget, bound1);
|
||||
case 1:
|
||||
return constructContentFunction(fun, newTarget, bound1, a[0]);
|
||||
return constructContentFunction(fun, newTarget, bound1, SPREAD(arguments, 1));
|
||||
case 2:
|
||||
return constructContentFunction(fun, newTarget, bound1, a[0], a[1]);
|
||||
return constructContentFunction(fun, newTarget, bound1, SPREAD(arguments, 2));
|
||||
case 3:
|
||||
return constructContentFunction(fun, newTarget, bound1, a[0], a[1], a[2]);
|
||||
return constructContentFunction(fun, newTarget, bound1, SPREAD(arguments, 3));
|
||||
case 4:
|
||||
return constructContentFunction(fun, newTarget, bound1, a[0], a[1], a[2], a[3]);
|
||||
return constructContentFunction(fun, newTarget, bound1, SPREAD(arguments, 4));
|
||||
case 5:
|
||||
return constructContentFunction(fun, newTarget, bound1, a[0], a[1], a[2], a[3], a[4]);
|
||||
return constructContentFunction(fun, newTarget, bound1, SPREAD(arguments, 5));
|
||||
}
|
||||
} else {
|
||||
switch (a.length) {
|
||||
switch (arguments.length) {
|
||||
case 0:
|
||||
return callContentFunction(fun, thisArg, bound1);
|
||||
case 1:
|
||||
return callContentFunction(fun, thisArg, bound1, a[0]);
|
||||
return callContentFunction(fun, thisArg, bound1, SPREAD(arguments, 1));
|
||||
case 2:
|
||||
return callContentFunction(fun, thisArg, bound1, a[0], a[1]);
|
||||
return callContentFunction(fun, thisArg, bound1, SPREAD(arguments, 2));
|
||||
case 3:
|
||||
return callContentFunction(fun, thisArg, bound1, a[0], a[1], a[2]);
|
||||
return callContentFunction(fun, thisArg, bound1, SPREAD(arguments, 3));
|
||||
case 4:
|
||||
return callContentFunction(fun, thisArg, bound1, a[0], a[1], a[2], a[3]);
|
||||
return callContentFunction(fun, thisArg, bound1, SPREAD(arguments, 4));
|
||||
case 5:
|
||||
return callContentFunction(fun, thisArg, bound1, a[0], a[1], a[2], a[3], a[4]);
|
||||
return callContentFunction(fun, thisArg, bound1, SPREAD(arguments, 5));
|
||||
}
|
||||
}
|
||||
var callArgs = FUN_APPLY(bind_mapArguments, null, arguments);
|
||||
@ -174,40 +172,39 @@ function bind_bindFunction2(fun, thisArg, boundArgs) {
|
||||
var bound1 = boundArgs[0];
|
||||
var bound2 = boundArgs[1];
|
||||
return function bound() {
|
||||
var a = arguments;
|
||||
var newTarget;
|
||||
if (_IsConstructing()) {
|
||||
newTarget = new.target;
|
||||
if (newTarget === bound)
|
||||
newTarget = fun;
|
||||
switch (a.length) {
|
||||
switch (arguments.length) {
|
||||
case 0:
|
||||
return constructContentFunction(fun, newTarget, bound1, bound2);
|
||||
case 1:
|
||||
return constructContentFunction(fun, newTarget, bound1, bound2, a[0]);
|
||||
return constructContentFunction(fun, newTarget, bound1, bound2, SPREAD(arguments, 1));
|
||||
case 2:
|
||||
return constructContentFunction(fun, newTarget, bound1, bound2, a[0], a[1]);
|
||||
return constructContentFunction(fun, newTarget, bound1, bound2, SPREAD(arguments, 2));
|
||||
case 3:
|
||||
return constructContentFunction(fun, newTarget, bound1, bound2, a[0], a[1], a[2]);
|
||||
return constructContentFunction(fun, newTarget, bound1, bound2, SPREAD(arguments, 3));
|
||||
case 4:
|
||||
return constructContentFunction(fun, newTarget, bound1, bound2, a[0], a[1], a[2], a[3]);
|
||||
return constructContentFunction(fun, newTarget, bound1, bound2, SPREAD(arguments, 4));
|
||||
case 5:
|
||||
return constructContentFunction(fun, newTarget, bound1, bound2, a[0], a[1], a[2], a[3], a[4]);
|
||||
return constructContentFunction(fun, newTarget, bound1, bound2, SPREAD(arguments, 5));
|
||||
}
|
||||
} else {
|
||||
switch (a.length) {
|
||||
switch (arguments.length) {
|
||||
case 0:
|
||||
return callContentFunction(fun, thisArg, bound1, bound2);
|
||||
case 1:
|
||||
return callContentFunction(fun, thisArg, bound1, bound2, a[0]);
|
||||
return callContentFunction(fun, thisArg, bound1, bound2, SPREAD(arguments, 1));
|
||||
case 2:
|
||||
return callContentFunction(fun, thisArg, bound1, bound2, a[0], a[1]);
|
||||
return callContentFunction(fun, thisArg, bound1, bound2, SPREAD(arguments, 2));
|
||||
case 3:
|
||||
return callContentFunction(fun, thisArg, bound1, bound2, a[0], a[1], a[2]);
|
||||
return callContentFunction(fun, thisArg, bound1, bound2, SPREAD(arguments, 3));
|
||||
case 4:
|
||||
return callContentFunction(fun, thisArg, bound1, bound2, a[0], a[1], a[2], a[3]);
|
||||
return callContentFunction(fun, thisArg, bound1, bound2, SPREAD(arguments, 4));
|
||||
case 5:
|
||||
return callContentFunction(fun, thisArg, bound1, bound2, a[0], a[1], a[2], a[3], a[4]);
|
||||
return callContentFunction(fun, thisArg, bound1, bound2, SPREAD(arguments, 5));
|
||||
}
|
||||
}
|
||||
var callArgs = FUN_APPLY(bind_mapArguments, null, arguments);
|
||||
@ -256,62 +253,62 @@ function bind_invokeFunctionN(fun, thisArg, newTarget, boundArgs, callArgs) {
|
||||
return bind_applyFunctionN(fun, thisArg, args);
|
||||
}
|
||||
|
||||
function bind_applyFunctionN(fun, thisArg, a) {
|
||||
switch (a.length) {
|
||||
function bind_applyFunctionN(fun, thisArg, args) {
|
||||
switch (args.length) {
|
||||
case 0:
|
||||
return callContentFunction(fun, thisArg);
|
||||
case 1:
|
||||
return callContentFunction(fun, thisArg, a[0]);
|
||||
return callContentFunction(fun, thisArg, SPREAD(args, 1));
|
||||
case 2:
|
||||
return callContentFunction(fun, thisArg, a[0], a[1]);
|
||||
return callContentFunction(fun, thisArg, SPREAD(args, 2));
|
||||
case 3:
|
||||
return callContentFunction(fun, thisArg, a[0], a[1], a[2]);
|
||||
return callContentFunction(fun, thisArg, SPREAD(args, 3));
|
||||
case 4:
|
||||
return callContentFunction(fun, thisArg, a[0], a[1], a[2], a[3]);
|
||||
return callContentFunction(fun, thisArg, SPREAD(args, 4));
|
||||
case 5:
|
||||
return callContentFunction(fun, thisArg, a[0], a[1], a[2], a[3], a[4]);
|
||||
return callContentFunction(fun, thisArg, SPREAD(args, 5));
|
||||
case 6:
|
||||
return callContentFunction(fun, thisArg, a[0], a[1], a[2], a[3], a[4], a[5]);
|
||||
return callContentFunction(fun, thisArg, SPREAD(args, 6));
|
||||
case 7:
|
||||
return callContentFunction(fun, thisArg, a[0], a[1], a[2], a[3], a[4], a[5], a[6]);
|
||||
return callContentFunction(fun, thisArg, SPREAD(args, 7));
|
||||
case 8:
|
||||
return callContentFunction(fun, thisArg, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
|
||||
return callContentFunction(fun, thisArg, SPREAD(args, 8));
|
||||
case 9:
|
||||
return callContentFunction(fun, thisArg, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]);
|
||||
return callContentFunction(fun, thisArg, SPREAD(args, 9));
|
||||
default:
|
||||
return FUN_APPLY(fun, thisArg, a);
|
||||
return FUN_APPLY(fun, thisArg, args);
|
||||
}
|
||||
}
|
||||
|
||||
function bind_constructFunctionN(fun, newTarget, a) {
|
||||
switch (a.length) {
|
||||
function bind_constructFunctionN(fun, newTarget, args) {
|
||||
switch (args.length) {
|
||||
case 1:
|
||||
return constructContentFunction(fun, newTarget, a[0]);
|
||||
return constructContentFunction(fun, newTarget, SPREAD(args, 1));
|
||||
case 2:
|
||||
return constructContentFunction(fun, newTarget, a[0], a[1]);
|
||||
return constructContentFunction(fun, newTarget, SPREAD(args, 2));
|
||||
case 3:
|
||||
return constructContentFunction(fun, newTarget, a[0], a[1], a[2]);
|
||||
return constructContentFunction(fun, newTarget, SPREAD(args, 3));
|
||||
case 4:
|
||||
return constructContentFunction(fun, newTarget, a[0], a[1], a[2], a[3]);
|
||||
return constructContentFunction(fun, newTarget, SPREAD(args, 4));
|
||||
case 5:
|
||||
return constructContentFunction(fun, newTarget, a[0], a[1], a[2], a[3], a[4]);
|
||||
return constructContentFunction(fun, newTarget, SPREAD(args, 5));
|
||||
case 6:
|
||||
return constructContentFunction(fun, newTarget, a[0], a[1], a[2], a[3], a[4], a[5]);
|
||||
return constructContentFunction(fun, newTarget, SPREAD(args, 6));
|
||||
case 7:
|
||||
return constructContentFunction(fun, newTarget, a[0], a[1], a[2], a[3], a[4], a[5], a[6]);
|
||||
return constructContentFunction(fun, newTarget, SPREAD(args, 7));
|
||||
case 8:
|
||||
return constructContentFunction(fun, newTarget, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
|
||||
return constructContentFunction(fun, newTarget, SPREAD(args, 8));
|
||||
case 9:
|
||||
return constructContentFunction(fun, newTarget, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]);
|
||||
return constructContentFunction(fun, newTarget, SPREAD(args, 9));
|
||||
case 10:
|
||||
return constructContentFunction(fun, newTarget, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]);
|
||||
return constructContentFunction(fun, newTarget, SPREAD(args, 10));
|
||||
case 11:
|
||||
return constructContentFunction(fun, newTarget, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10]);
|
||||
return constructContentFunction(fun, newTarget, SPREAD(args, 11));
|
||||
case 12:
|
||||
return constructContentFunction(fun, newTarget, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11]);
|
||||
return constructContentFunction(fun, newTarget, SPREAD(args, 12));
|
||||
default:
|
||||
assert(a.length !== 0,
|
||||
assert(args.length !== 0,
|
||||
"bound function construction without args should be handled by caller");
|
||||
return _ConstructFunction(fun, newTarget, a);
|
||||
return _ConstructFunction(fun, newTarget, args);
|
||||
}
|
||||
}
|
||||
|
@ -394,15 +394,18 @@ function CanonicalizeLanguageTag(locale) {
|
||||
if (subtag.length === 1 && (i > 0 || subtag === "x"))
|
||||
break;
|
||||
|
||||
if (subtag.length === 4) {
|
||||
// 4-character subtags are script codes; their first character
|
||||
// needs to be capitalized. "hans" -> "Hans"
|
||||
subtag = callFunction(std_String_toUpperCase, subtag[0]) +
|
||||
callFunction(String_substring, subtag, 1);
|
||||
} else if (i !== 0 && subtag.length === 2) {
|
||||
// 2-character subtags that are not in initial position are region
|
||||
// codes; they need to be upper case. "bu" -> "BU"
|
||||
subtag = callFunction(std_String_toUpperCase, subtag);
|
||||
if (i !== 0) {
|
||||
if (subtag.length === 4) {
|
||||
// 4-character subtags that are not in initial position are
|
||||
// script codes; their first character needs to be capitalized.
|
||||
// "hans" -> "Hans"
|
||||
subtag = callFunction(std_String_toUpperCase, subtag[0]) +
|
||||
callFunction(String_substring, subtag, 1);
|
||||
} else if (subtag.length === 2) {
|
||||
// 2-character subtags that are not in initial position are
|
||||
// region codes; they need to be upper case. "bu" -> "BU"
|
||||
subtag = callFunction(std_String_toUpperCase, subtag);
|
||||
}
|
||||
}
|
||||
if (callFunction(std_Object_hasOwnProperty, langSubtagMappings, subtag)) {
|
||||
// Replace deprecated subtags with their preferred values.
|
||||
|
@ -19,100 +19,6 @@ using namespace js;
|
||||
|
||||
/*** Reflect methods *****************************************************************************/
|
||||
|
||||
/*
|
||||
* ES draft rev 32 (2015 Feb 2) 7.3.17 CreateListFromArrayLike.
|
||||
* The elementTypes argument is not supported. The result list is
|
||||
* pushed to *args.
|
||||
*/
|
||||
template <class InvokeArgs>
|
||||
static bool
|
||||
InitArgsFromArrayLike(JSContext* cx, HandleValue v, InvokeArgs* args)
|
||||
{
|
||||
// Step 3.
|
||||
RootedObject obj(cx, NonNullObject(cx, v));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
// Steps 4-5.
|
||||
uint32_t len;
|
||||
if (!GetLengthProperty(cx, obj, &len))
|
||||
return false;
|
||||
|
||||
// Allocate space for the arguments.
|
||||
if (!args->init(cx, len))
|
||||
return false;
|
||||
|
||||
// Steps 6-8.
|
||||
for (uint32_t index = 0; index < len; index++) {
|
||||
if (!GetElement(cx, obj, obj, index, (*args)[index]))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Step 9.
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ES6 26.1.1 Reflect.apply(target, thisArgument, argumentsList) */
|
||||
static bool
|
||||
Reflect_apply(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
// Step 1.
|
||||
if (!IsCallable(args.get(0))) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_FUNCTION,
|
||||
"Reflect.apply argument");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Steps 2-3.
|
||||
FastCallGuard fig(cx, args.get(0));
|
||||
InvokeArgs& invokeArgs = fig.args();
|
||||
if (!InitArgsFromArrayLike(cx, args.get(2), &invokeArgs))
|
||||
return false;
|
||||
|
||||
// Steps 4-5. This is specified to be a tail call, but isn't.
|
||||
return fig.call(cx, args.get(0), args.get(1), args.rval());
|
||||
}
|
||||
|
||||
/* ES6 26.1.2 Reflect.construct(target, argumentsList [, newTarget]) */
|
||||
static bool
|
||||
Reflect_construct(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
// Step 1.
|
||||
if (!IsConstructor(args.get(0))) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_CONSTRUCTOR,
|
||||
"Reflect.construct argument");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Steps 2-3.
|
||||
RootedValue newTarget(cx, args.get(0));
|
||||
if (argc > 2) {
|
||||
newTarget = args[2];
|
||||
if (!IsConstructor(newTarget)) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_CONSTRUCTOR,
|
||||
"Reflect.construct argument 3");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Step 4-5.
|
||||
ConstructArgs constructArgs(cx);
|
||||
if (!InitArgsFromArrayLike(cx, args.get(1), &constructArgs))
|
||||
return false;
|
||||
|
||||
// Step 6.
|
||||
RootedObject obj(cx);
|
||||
if (!Construct(cx, args.get(0), constructArgs, newTarget, &obj))
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ES6 26.1.3 Reflect.defineProperty(target, propertyKey, attributes) */
|
||||
static bool
|
||||
Reflect_defineProperty(JSContext* cx, unsigned argc, Value* vp)
|
||||
@ -340,8 +246,8 @@ Reflect_setPrototypeOf(JSContext* cx, unsigned argc, Value* vp)
|
||||
}
|
||||
|
||||
static const JSFunctionSpec methods[] = {
|
||||
JS_FN("apply", Reflect_apply, 3, 0),
|
||||
JS_FN("construct", Reflect_construct, 2, 0),
|
||||
JS_SELF_HOSTED_FN("apply", "Reflect_apply", 3, 0),
|
||||
JS_SELF_HOSTED_FN("construct", "Reflect_construct", 2, 0),
|
||||
JS_FN("defineProperty", Reflect_defineProperty, 3, 0),
|
||||
JS_FN("deleteProperty", Reflect_deleteProperty, 2, 0),
|
||||
JS_FN("get", Reflect_get, 2, 0),
|
||||
|
@ -2,12 +2,111 @@
|
||||
* 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/. */
|
||||
|
||||
// ES6 draft rev 32 (2015 Feb 2) 26.1.9
|
||||
// ES2017 draft rev a785b0832b071f505a694e1946182adeab84c972
|
||||
// 7.3.17 CreateListFromArrayLike (obj [ , elementTypes ] )
|
||||
function CreateListFromArrayLikeForArgs(obj) {
|
||||
// Step 1 (not applicable).
|
||||
|
||||
// Step 2.
|
||||
assert(IsObject(obj), "object must be passed to CreateListFromArrayLikeForArgs");
|
||||
|
||||
// Step 3.
|
||||
var len = ToLength(obj.length);
|
||||
|
||||
// This version of CreateListFromArrayLike is only used for argument lists.
|
||||
if (len > MAX_ARGS_LENGTH)
|
||||
ThrowRangeError(JSMSG_TOO_MANY_ARGUMENTS);
|
||||
|
||||
// Steps 4-6.
|
||||
var list = std_Array(len);
|
||||
for (var i = 0; i < len; i++)
|
||||
_DefineDataProperty(list, i, obj[i]);
|
||||
|
||||
// Step 7.
|
||||
return list;
|
||||
}
|
||||
|
||||
// ES2017 draft rev a785b0832b071f505a694e1946182adeab84c972
|
||||
// 26.1.1 Reflect.apply ( target, thisArgument, argumentsList )
|
||||
function Reflect_apply(target, thisArgument, argumentsList) {
|
||||
// Step 1.
|
||||
if (!IsCallable(target))
|
||||
ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, target));
|
||||
|
||||
// Step 2.
|
||||
if (!IsObject(argumentsList))
|
||||
ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, DecompileArg(2, argumentsList));
|
||||
|
||||
// Steps 2-4.
|
||||
return callFunction(std_Function_apply, target, thisArgument, argumentsList);
|
||||
}
|
||||
|
||||
// ES2017 draft rev a785b0832b071f505a694e1946182adeab84c972
|
||||
// 26.1.2 Reflect.construct ( target, argumentsList [ , newTarget ] )
|
||||
function Reflect_construct(target, argumentsList/*, newTarget*/) {
|
||||
// Step 1.
|
||||
if (!IsConstructor(target))
|
||||
ThrowTypeError(JSMSG_NOT_CONSTRUCTOR, DecompileArg(0, target));
|
||||
|
||||
// Steps 2-3.
|
||||
var newTarget;
|
||||
if (arguments.length > 2) {
|
||||
newTarget = arguments[2];
|
||||
if (!IsConstructor(newTarget))
|
||||
ThrowTypeError(JSMSG_NOT_CONSTRUCTOR, DecompileArg(2, newTarget));
|
||||
} else {
|
||||
newTarget = target;
|
||||
}
|
||||
|
||||
// Step 4.
|
||||
if (!IsObject(argumentsList))
|
||||
ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, DecompileArg(1, argumentsList));
|
||||
|
||||
// Fast path when we can avoid calling CreateListFromArrayLikeForArgs().
|
||||
var args = (IsPackedArray(argumentsList) && argumentsList.length <= MAX_ARGS_LENGTH)
|
||||
? argumentsList
|
||||
: CreateListFromArrayLikeForArgs(argumentsList);
|
||||
|
||||
// Step 5.
|
||||
switch (args.length) {
|
||||
case 0:
|
||||
return constructContentFunction(target, newTarget);
|
||||
case 1:
|
||||
return constructContentFunction(target, newTarget, SPREAD(args, 1));
|
||||
case 2:
|
||||
return constructContentFunction(target, newTarget, SPREAD(args, 2));
|
||||
case 3:
|
||||
return constructContentFunction(target, newTarget, SPREAD(args, 3));
|
||||
case 4:
|
||||
return constructContentFunction(target, newTarget, SPREAD(args, 4));
|
||||
case 5:
|
||||
return constructContentFunction(target, newTarget, SPREAD(args, 5));
|
||||
case 6:
|
||||
return constructContentFunction(target, newTarget, SPREAD(args, 6));
|
||||
case 7:
|
||||
return constructContentFunction(target, newTarget, SPREAD(args, 7));
|
||||
case 8:
|
||||
return constructContentFunction(target, newTarget, SPREAD(args, 8));
|
||||
case 9:
|
||||
return constructContentFunction(target, newTarget, SPREAD(args, 9));
|
||||
case 10:
|
||||
return constructContentFunction(target, newTarget, SPREAD(args, 10));
|
||||
case 11:
|
||||
return constructContentFunction(target, newTarget, SPREAD(args, 11));
|
||||
case 12:
|
||||
return constructContentFunction(target, newTarget, SPREAD(args, 12));
|
||||
default:
|
||||
return _ConstructFunction(target, newTarget, args);
|
||||
}
|
||||
}
|
||||
|
||||
// ES2017 draft rev a785b0832b071f505a694e1946182adeab84c972
|
||||
// 26.1.8 Reflect.has ( target, propertyKey )
|
||||
function Reflect_has(target, propertyKey) {
|
||||
// Step 1.
|
||||
if (!IsObject(target))
|
||||
ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, DecompileArg(0, target));
|
||||
|
||||
// Steps 2-4 are identical to the runtime semantics of the "in" operator.
|
||||
// Steps 2-3 are identical to the runtime semantics of the "in" operator.
|
||||
return propertyKey in target;
|
||||
}
|
||||
|
@ -3496,7 +3496,6 @@ ASTSerializer::functionArgs(ParseNode* pn, ParseNode* pnargs,
|
||||
if (!pattern(pat, &node))
|
||||
return false;
|
||||
if (rest.isUndefined() && arg->pn_next == pnargs->last()) {
|
||||
MOZ_ASSERT(arg->isKind(PNK_NAME));
|
||||
rest.setObject(node.toObject());
|
||||
} else {
|
||||
if (!args.append(node))
|
||||
|
@ -380,16 +380,13 @@ function RegExpGetComplexReplacement(result, matched, S, position,
|
||||
case 0:
|
||||
return ToString(replaceValue(matched, position, S));
|
||||
case 1:
|
||||
return ToString(replaceValue(matched, captures[0], position, S));
|
||||
return ToString(replaceValue(matched, SPREAD(captures, 1), position, S));
|
||||
case 2:
|
||||
return ToString(replaceValue(matched, captures[0], captures[1],
|
||||
position, S));
|
||||
return ToString(replaceValue(matched, SPREAD(captures, 2), position, S));
|
||||
case 3:
|
||||
return ToString(replaceValue(matched, captures[0], captures[1],
|
||||
captures[2], position, S));
|
||||
return ToString(replaceValue(matched, SPREAD(captures, 3), position, S));
|
||||
case 4:
|
||||
return ToString(replaceValue(matched, captures[0], captures[1],
|
||||
captures[2], captures[3], position, S));
|
||||
return ToString(replaceValue(matched, SPREAD(captures, 4), position, S));
|
||||
default:
|
||||
// Steps 14.j.ii-v.
|
||||
_DefineDataProperty(captures, capturesLength++, position);
|
||||
|
@ -19,6 +19,27 @@
|
||||
#define FUN_APPLY(FUN, RECEIVER, ARGS) \
|
||||
callFunction(std_Function_apply, FUN, RECEIVER, ARGS)
|
||||
|
||||
// NB: keep this in sync with the copy in vm/ArgumentsObject.h.
|
||||
#define MAX_ARGS_LENGTH (500 * 1000)
|
||||
|
||||
// Spread non-empty argument list of up to 15 elements.
|
||||
#define SPREAD(v, n) SPREAD_##n(v)
|
||||
#define SPREAD_1(v) v[0]
|
||||
#define SPREAD_2(v) SPREAD_1(v), v[1]
|
||||
#define SPREAD_3(v) SPREAD_2(v), v[2]
|
||||
#define SPREAD_4(v) SPREAD_3(v), v[3]
|
||||
#define SPREAD_5(v) SPREAD_4(v), v[4]
|
||||
#define SPREAD_6(v) SPREAD_5(v), v[5]
|
||||
#define SPREAD_7(v) SPREAD_6(v), v[6]
|
||||
#define SPREAD_8(v) SPREAD_7(v), v[7]
|
||||
#define SPREAD_9(v) SPREAD_8(v), v[8]
|
||||
#define SPREAD_10(v) SPREAD_9(v), v[9]
|
||||
#define SPREAD_11(v) SPREAD_10(v), v[10]
|
||||
#define SPREAD_12(v) SPREAD_11(v), v[11]
|
||||
#define SPREAD_13(v) SPREAD_12(v), v[12]
|
||||
#define SPREAD_14(v) SPREAD_13(v), v[13]
|
||||
#define SPREAD_15(v) SPREAD_14(v), v[14]
|
||||
|
||||
// Property descriptor attributes.
|
||||
#define ATTR_ENUMERABLE 0x01
|
||||
#define ATTR_CONFIGURABLE 0x02
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user