This commit is contained in:
Ryan VanderMeulen 2016-08-31 22:33:17 -04:00
Родитель a6fa167a46 e7cae3eb49
Коммит 3611a7607d
154 изменённых файлов: 2071 добавлений и 1902 удалений

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

@ -7,11 +7,15 @@ module.metadata = {
"stability": "unstable"
};
const { Ci } = require("chrome");
const { Ci, Cc, Cu } = require("chrome");
const core = require("../l10n/core");
const { loadSheet, removeSheet } = require("../stylesheet/utils");
const { process, frames } = require("../remote/child");
const { Services } = require("resource://gre/modules/Services.jsm");
var observerService = Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
const { ShimWaiver } = Cu.import("resource://gre/modules/ShimWaiver.jsm");
const addObserver = ShimWaiver.getProperty(observerService, "addObserver");
const removeObserver = ShimWaiver.getProperty(observerService, "removeObserver");
const assetsURI = require('../self').data.url();
@ -115,7 +119,7 @@ let enabled = false;
function enable() {
if (enabled)
return;
Services.obs.addObserver(onContentWindow, ON_CONTENT, false);
addObserver(onContentWindow, ON_CONTENT, false);
enabled = true;
}
process.port.on("sdk/l10n/html/enable", enable);
@ -123,7 +127,7 @@ process.port.on("sdk/l10n/html/enable", enable);
function disable() {
if (!enabled)
return;
Services.obs.removeObserver(onContentWindow, ON_CONTENT);
removeObserver(onContentWindow, ON_CONTENT);
enabled = false;
}
process.port.on("sdk/l10n/html/disable", disable);

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

@ -62,7 +62,6 @@ function WindowTracker(delegate) {
}
this._delegate = delegate;
this._loadingWindows = [];
for (let window of getWindows())
this._regWindow(window);
@ -81,17 +80,12 @@ WindowTracker.prototype = {
if (ignoreWindow(window))
return;
this._loadingWindows.push(window);
window.addEventListener('load', this, true);
},
_unregLoadingWindow: function _unregLoadingWindow(window) {
var index = this._loadingWindows.indexOf(window);
if (index != -1) {
this._loadingWindows.splice(index, 1);
window.removeEventListener('load', this, true);
}
// This may have no effect if we ignored the window in _regLoadingWindow().
window.removeEventListener('load', this, true);
},
_regWindow: function _regWindow(window) {

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

@ -221,7 +221,7 @@ var gDropTargetShim = {
*/
_dispatchEvent: function (aEvent, aType, aTarget) {
let node = aTarget.node;
let event = document.createEvent("DragEvents");
let event = document.createEvent("DragEvent");
// The event should not bubble to prevent recursion.
event.initDragEvent(aType, false, true, window, 0, 0, 0, 0, 0, false, false,

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

@ -19,7 +19,7 @@ add_task(function* () {
function sendDragEvent(aEventType, aTarget) {
let dataTransfer = new content.DataTransfer(aEventType, false);
let event = content.document.createEvent("DragEvents");
let event = content.document.createEvent("DragEvent");
event.initDragEvent(aEventType, true, true, content, 0, 0, 0, 0, 0,
false, false, false, false, 0, null, dataTransfer);
aTarget.dispatchEvent(event);

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

@ -12,7 +12,7 @@ add_task(function* () {
return ContentTask.spawn(gBrowser.selectedBrowser, { data: data }, function*(args) {
let dataTransfer = new content.DataTransfer("dragstart", false);
dataTransfer.mozSetDataAt("text/x-moz-url", args.data, 0);
let event = content.document.createEvent("DragEvents");
let event = content.document.createEvent("DragEvent");
event.initDragEvent("drop", true, true, content, 0, 0, 0, 0, 0,
false, false, false, false, 0, null, dataTransfer);

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

@ -15,7 +15,7 @@ add_task(function* () {
function sendDropEvent(aCellIndex, aDragData) {
let dataTransfer = new content.DataTransfer("dragstart", false);
dataTransfer.mozSetDataAt("text/x-moz-url", aDragData, 0);
let event = content.document.createEvent("DragEvents");
let event = content.document.createEvent("DragEvent");
event.initDragEvent("drop", true, true, content, 0, 0, 0, 0, 0,
false, false, false, false, 0, null, dataTransfer);

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

@ -78,14 +78,14 @@ function doDragEvent(sourceIndex, dropIndex) {
return ContentTask.spawn(gBrowser.selectedBrowser,
{ sourceIndex: sourceIndex, dropIndex: dropIndex }, function*(args) {
let dataTransfer = new content.DataTransfer("dragstart", false);
let event = content.document.createEvent("DragEvents");
let event = content.document.createEvent("DragEvent");
event.initDragEvent("dragstart", true, true, content, 0, 0, 0, 0, 0,
false, false, false, false, 0, null, dataTransfer);
let target = content.gGrid.cells[args.sourceIndex].site.node;
target.dispatchEvent(event);
event = content.document.createEvent("DragEvents");
event = content.document.createEvent("DragEvent");
event.initDragEvent("drop", true, true, content, 0, 0, 0, 0, 0,
false, false, false, false, 0, null, dataTransfer);

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

@ -419,7 +419,7 @@ function* simulateExternalDrop(aDestIndex) {
let dataTransfer = new iframe.contentWindow.DataTransfer("dragstart", false);
dataTransfer.mozSetDataAt("text/x-moz-url", "http://example99.com/", 0);
let event = content.document.createEvent("DragEvents");
let event = content.document.createEvent("DragEvent");
event.initDragEvent("drop", true, true, content, 0, 0, 0, 0, 0,
false, false, false, false, 0, null, dataTransfer);

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

@ -834,7 +834,7 @@
"name": "result",
"optional": true,
"type": "array",
"items": {"type": "any", "minimum": 0},
"items": {"type": "any"},
"description": "The result of the script in every injected frame."
}
]

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

@ -2614,6 +2614,45 @@ ContentPermissionPrompt.prototype = {
"geo-notification-icon", options);
},
_promptFlyWebPublishServer : function(aRequest) {
var message = "Would you like to let this site start a server accessible to nearby devices and people?";
var actions = [
{
stringId: "flyWebPublishServer.allowPublishServer",
action: Ci.nsIPermissionManager.ALLOW_ACTION,
expireType: Ci.nsIPermissionManager.EXPIRE_SESSION
},
{
stringId: "flyWebPublishServer.denyPublishServer",
action: Ci.nsIPermissionManager.DENY_ACTION,
expireType: Ci.nsIPermissionManager.EXPIRE_SESSION
}
];
let options = {
learnMoreURL: "https://flyweb.github.io",
popupIconURL: "chrome://flyweb/skin/icon-64.png"
};
let browser = this._getBrowserForRequest(aRequest);
let chromeDoc = browser.ownerDocument;
let iconElem = chromeDoc.getElementById("flyweb-publish-server-notification-icon");
if (!iconElem) {
let notificationPopupBox = chromeDoc.getElementById("notification-popup-box");
let notificationIcon = chromeDoc.createElement("image");
notificationIcon.setAttribute("id", "flyweb-publish-server-notification-icon");
notificationIcon.setAttribute("src", "chrome://flyweb/skin/icon-64.png");
notificationIcon.setAttribute("class", "notification-anchor-icon flyweb-publish-server-icon");
notificationIcon.setAttribute("style", "filter: url(chrome://browser/skin/filters.svg#fill); fill: currentColor; opacity: .4;");
notificationIcon.setAttribute("role", "button");
notificationIcon.setAttribute("aria-label", "View the publish-server request");
notificationPopupBox.appendChild(notificationIcon);
}
this._showPrompt(aRequest, message, "flyweb-publish-server", actions, "flyweb-publish-server",
"flyweb-publish-server-notification-icon", options);
},
_promptWebNotifications : function(aRequest) {
var message = gBrowserBundle.GetStringFromName("webNotifications.receiveFromSite");
@ -2678,7 +2717,8 @@ ContentPermissionPrompt.prototype = {
let perm = types.queryElementAt(0, Ci.nsIContentPermissionType);
const kFeatureKeys = { "geolocation" : "geo",
"desktop-notification" : "desktop-notification"
"desktop-notification" : "desktop-notification",
"flyweb-publish-server": "flyweb-publish-server"
};
// Make sure that we support the request.
@ -2721,6 +2761,11 @@ ContentPermissionPrompt.prototype = {
case "desktop-notification":
this._promptWebNotifications(request);
break;
case "flyweb-publish-server":
if (AppConstants.NIGHTLY_BUILD) {
this._promptFlyWebPublishServer(request);
}
break;
}
},

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

@ -13,6 +13,7 @@ Cu.import("resource://gre/modules/UpdateUtils.jsm");
// The amount of people to be part of e10s
const TEST_THRESHOLD = {
"beta" : 0.5, // 50%
"release" : 1.0, // 100%
};
const ADDON_ROLLOUT_POLICY = {

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

@ -10,7 +10,7 @@
<Description about="urn:mozilla:install-manifest">
<em:id>e10srollout@mozilla.org</em:id>
<em:version>1.0</em:version>
<em:version>1.2</em:version>
<em:type>2</em:type>
<em:bootstrap>true</em:bootstrap>
<em:multiprocessCompatible>true</em:multiprocessCompatible>

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

@ -378,6 +378,16 @@ geolocation.neverShareLocation.accesskey=N
geolocation.shareWithSite2=Would you like to share your location with this site?
geolocation.shareWithFile2=Would you like to share your location with this file?
# FlyWeb UI
# LOCALIZATION NOTE (flyWebPublishServer.allowPublishServer): This is an experimental feature only shipping in Nightly, and doesn't need translation.
flyWebPublishServer.allowPublishServer=Allow Server
# LOCALIZATION NOTE (flyWebPublishServer.allowPublishServer.accessKey): This is an experimental feature only shipping in Nightly, and doesn't need translation.
flyWebPublishServer.allowPublishServer.accesskey=A
# LOCALIZATION NOTE (flyWebPublishServer.denyPublishServer): This is an experimental feature only shipping in Nightly, and doesn't need translation.
flyWebPublishServer.denyPublishServer=Block Server
# LOCALIZATION NOTE (flyWebPublishServer.denyPublishServer.accessKey): This is an experimental feature only shipping in Nightly, and doesn't need translation.
flyWebPublishServer.denyPublishServer.accesskey=B
webNotifications.receiveForSession=Receive for this session
webNotifications.receiveForSession.accesskey=s
webNotifications.alwaysReceive=Always Receive Notifications

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

@ -58,10 +58,6 @@
--urlbar-dropmarker-active-2x-region: rect(0px, 33px, 14px, 22px);
}
:root[devtoolstheme="dark"] #identity-box {
--identity-box-chrome-color: #46afe3;
}
:root[devtoolstheme="light"] {
--url-and-searchbar-background-color: #fff;

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

@ -5,17 +5,6 @@
%endif
#identity-box {
--identity-box-verified-color: hsl(92,100%,30%);
%ifdef MOZ_OFFICIAL_BRANDING
--identity-box-chrome-color: rgb(229,115,0);
%else
%if MOZ_UPDATE_CHANNEL == aurora
--identity-box-chrome-color: rgb(51,30,84);
%else
--identity-box-chrome-color: rgb(0,33,71);
%endif
%endif
font-size: .9em;
padding: 3px 5px;
overflow: hidden;
@ -24,14 +13,16 @@
transition: padding-left, padding-right;
}
#urlbar[pageproxystate="valid"] > #identity-box.verifiedIdentity > #connection-icon,
#urlbar[pageproxystate="valid"] > #identity-box.verifiedIdentity > #identity-icon-labels {
color: var(--identity-box-verified-color);
color: hsl(92,100%,30%);
}
#urlbar[pageproxystate="valid"] > #identity-box.chromeUI > #connection-icon,
#urlbar[pageproxystate="valid"] > #identity-box.chromeUI > #identity-icon-labels {
color: var(--identity-box-chrome-color);
%ifdef MOZ_OFFICIAL_BRANDING
color: rgb(229,115,0);
%else
color: inherit;
%endif
}
#identity-icon-labels:-moz-locale-dir(ltr) {

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

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

@ -120,10 +120,6 @@
#include "mozilla/DetailedPromise.h"
#endif
#ifdef MOZ_WIDGET_GONK
#include <cutils/properties.h>
#endif
namespace mozilla {
namespace dom {
@ -1639,157 +1635,6 @@ Navigator::PublishServer(const nsAString& aName,
return domPromise.forget();
}
already_AddRefed<Promise>
Navigator::GetFeature(const nsAString& aName, ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
RefPtr<Promise> p = Promise::Create(go, aRv);
if (aRv.Failed()) {
return nullptr;
}
#if defined(XP_LINUX)
if (aName.EqualsLiteral("hardware.memory")) {
// with seccomp enabled, fopen() should be in a non-sandboxed process
if (XRE_IsParentProcess()) {
uint32_t memLevel = mozilla::hal::GetTotalSystemMemoryLevel();
if (memLevel == 0) {
p->MaybeReject(NS_ERROR_NOT_AVAILABLE);
return p.forget();
}
p->MaybeResolve((int)memLevel);
} else {
mozilla::dom::ContentChild* cc =
mozilla::dom::ContentChild::GetSingleton();
RefPtr<Promise> ipcRef(p);
cc->SendGetSystemMemory(reinterpret_cast<uint64_t>(ipcRef.forget().take()));
}
return p.forget();
} // hardware.memory
#endif
#ifdef MOZ_WIDGET_GONK
if (StringBeginsWith(aName, NS_LITERAL_STRING("acl.")) &&
(aName.EqualsLiteral("acl.version") || CheckPermission("external-app"))) {
char value[PROPERTY_VALUE_MAX];
nsCString propertyKey("persist.");
propertyKey.Append(NS_ConvertUTF16toUTF8(aName));
uint32_t len = property_get(propertyKey.get(), value, nullptr);
if (len > 0) {
p->MaybeResolve(NS_ConvertUTF8toUTF16(value));
return p.forget();
}
}
#endif
// Mirror the dom.apps.developer_mode pref to let apps get it read-only.
if (aName.EqualsLiteral("dom.apps.developer_mode")) {
p->MaybeResolve(Preferences::GetBool("dom.apps.developer_mode", false));
return p.forget();
}
p->MaybeResolveWithUndefined();
return p.forget();
}
already_AddRefed<Promise>
Navigator::HasFeature(const nsAString& aName, ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
RefPtr<Promise> p = Promise::Create(go, aRv);
if (aRv.Failed()) {
return nullptr;
}
// Hardcoded extensions features which are b2g specific.
#ifdef MOZ_B2G
if (aName.EqualsLiteral("web-extensions") ||
aName.EqualsLiteral("late-customization")) {
p->MaybeResolve(true);
return p.forget();
}
#endif
// Hardcoded manifest features. Some are still b2g specific.
const char manifestFeatures[][64] = {
"manifest.origin"
, "manifest.redirects"
#ifdef MOZ_B2G
, "manifest.chrome.navigation"
, "manifest.precompile"
, "manifest.role.homescreen"
#endif
};
nsAutoCString feature = NS_ConvertUTF16toUTF8(aName);
for (uint32_t i = 0; i < MOZ_ARRAY_LENGTH(manifestFeatures); i++) {
if (feature.Equals(manifestFeatures[i])) {
p->MaybeResolve(true);
return p.forget();
}
}
NS_NAMED_LITERAL_STRING(apiWindowPrefix, "api.window.");
if (StringBeginsWith(aName, apiWindowPrefix)) {
const nsAString& featureName = Substring(aName, apiWindowPrefix.Length());
// Temporary hardcoded entry points due to technical constraints
if (featureName.EqualsLiteral("Navigator.mozTCPSocket")) {
p->MaybeResolve(Preferences::GetBool("dom.mozTCPSocket.enabled"));
return p.forget();
}
if (featureName.EqualsLiteral("Navigator.mozMobileConnections") ||
featureName.EqualsLiteral("MozMobileNetworkInfo")) {
p->MaybeResolve(Preferences::GetBool("dom.mobileconnection.enabled"));
return p.forget();
}
if (featureName.EqualsLiteral("Navigator.mozInputMethod")) {
p->MaybeResolve(Preferences::GetBool("dom.mozInputMethod.enabled"));
return p.forget();
}
if (featureName.EqualsLiteral("Navigator.getDeviceStorage")) {
p->MaybeResolve(Preferences::GetBool("device.storage.enabled"));
return p.forget();
}
if (featureName.EqualsLiteral("Navigator.mozNetworkStats")) {
p->MaybeResolve(Preferences::GetBool("dom.mozNetworkStats.enabled"));
return p.forget();
}
if (featureName.EqualsLiteral("Navigator.push")) {
p->MaybeResolve(Preferences::GetBool("services.push.enabled"));
return p.forget();
}
if (featureName.EqualsLiteral("Navigator.mozAlarms")) {
p->MaybeResolve(Preferences::GetBool("dom.mozAlarms.enabled"));
return p.forget();
}
if (featureName.EqualsLiteral("Navigator.mozCameras")) {
p->MaybeResolve(true);
return p.forget();
}
if (featureName.EqualsLiteral("XMLHttpRequest.mozSystem")) {
p->MaybeResolve(true);
return p.forget();
}
p->MaybeResolveWithUndefined();
return p.forget();
}
// resolve with <undefined> because the feature name is not supported
p->MaybeResolveWithUndefined();
return p.forget();
}
PowerManager*
Navigator::GetMozPower(ErrorResult& aRv)
{

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

@ -185,13 +185,6 @@ public:
// NavigatorBinding::ClearCachedUserAgentValue(this);
void ClearUserAgentCache();
// Feature Detection API
already_AddRefed<Promise> GetFeature(const nsAString& aName,
ErrorResult& aRv);
already_AddRefed<Promise> HasFeature(const nsAString &aName,
ErrorResult& aRv);
bool Vibrate(uint32_t aDuration);
bool Vibrate(const nsTArray<uint32_t>& aDuration);
void SetVibrationPermission(bool aPermitted, bool aPersistent);

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

@ -26,6 +26,4 @@ skip-if = buildapp == 'mulet'
[test_bug1008126.html]
[test_sandboxed_blob_uri.html]
[test_websocket_frame.html]
[test_getFeature_with_perm.html]
[test_hasFeature.html]
[test_mozbrowser_apis_allowed.html]

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

@ -1,135 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=979109
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 979109</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.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=983502">Mozilla Bug 983502</a>
<script type="application/javascript">
function testSupported() {
var mem;
navigator.getFeature("hardware.memory").then(function(mem) {
var isLinux = (navigator.platform.indexOf('Linux') != -1);
var isAndroid = !!navigator.userAgent.includes("Android");
var isB2G = !isAndroid && /Mobile|Tablet/.test(navigator.userAgent);
if (isLinux) {
info("It is Linux version:");
}
if (isAndroid) {
info("It is Android version");
}
if (isB2G) {
info("It is B2G version");
}
if (isLinux || isAndroid || isB2G) {
ok(typeof mem === 'number' && (mem) % 1 === 0, "We should receive an integer on this platform");
ok(mem > 0, "hardware.memory is supported on this platform. mem=" + mem + "MiB");
} else {
ok(typeof mem === 'undefined', "hardware.memory is not support on this platform");
}
runNextTest();
},function(mem) {
ok(false, "The Promise should not be rejected");
});
}
function testNotSupported() {
var tv;
navigator.getFeature("hardware.tv").then(function(tv) {
ok(typeof tv === 'undefined', "Resolve the Promise with undefined value (hardware.tv)");
runNextTest();
},function(tv) {
ok(false, "The Promise should not be rejected");
});
}
function testNotSupportedManifest() {
navigator.getFeature("manifest.origin").then(function(feature) {
ok(typeof feature == 'undefined', "manifest.* resolves with undefined on getFeature");
runNextTest();
}, function() {
ok(false, "The Promise should not be rejected");
});
}
function createManifestTest(aFeature) {
return function() {
var res;
navigator.hasFeature(aFeature).then(function(res) {
ok(res === true, "Resolve the Promise with 'true' for " + aFeature);
runNextTest();
}, function(tv) {
ok(false, "The Promise should not be rejected");
});
}
}
function testDevMode(aExpected) {
return function() {
navigator.getFeature("dom.apps.developer_mode").then(res => {
is(res, aExpected, "dom.apps.developer_mode is " + aExpected);
runNextTest();
}, function() {
ok(false, "The Promise should not be rejected");
});
}
}
function enableDevMode() {
SpecialPowers.pushPrefEnv({"set": [["dom.apps.developer_mode", true]]}, runNextTest);
}
var currentTest = -1;
var tests = [
testNotSupported,
testNotSupportedManifest,
testSupported,
createManifestTest("manifest.origin"),
createManifestTest("manifest.redirects"),
testDevMode(false),
enableDevMode,
testDevMode(true)
];
function runNextTest() {
currentTest++;
if (currentTest < tests.length) {
tests[currentTest]();
} else {
SimpleTest.finish();
}
}
info("About to run " + tests.length + " tests");
ok('getFeature' in navigator, "navigator.getFeature should exist");
ok('hasFeature' in navigator, "navigator.hasFeature should exist");
// B2G specific manifest features.
// Touching navigator before pushPermissions makes it fail.
if (!navigator.userAgent.includes("Android") &&
/Mobile|Tablet/.test(navigator.userAgent)) {
info("Adding B2G specific tests");
tests.push(createManifestTest("manifest.chrome.navigation"));
tests.push(createManifestTest("manifest.precompile"));
tests.push(createManifestTest("manifest.role.homescreen"));
}
runNextTest();
ok(true, "Test DONE");
SimpleTest.waitForExplicitFinish();
</script>
</body>
</html>

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

@ -1,101 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1009645
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1009645</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.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=1009645">Mozilla Bug 1009645</a>
<script type="application/javascript">
var b2gOnly;
function pref(name) {
try {
return SpecialPowers.getBoolPref(name);
} catch (e) {
return false;
}
}
function testAPIs() {
var APIEndPoints = [
{ name: "MozMobileNetworkInfo", enabled: pref("dom.mobileconnection.enabled") },
// { name: "Navigator.mozBluetooth", enabled: b2gOnly }, // conditional on MOZ_B2G_BT, tricky to test
// Bug 1266035 { name: "Navigator.mozContacts", enabled: pref("dom.mozContacts.enabled") },
{ name: "Navigator.getDeviceStorage", enabled: pref("device.storage.enabled") },
// Bug 1266035 { name: "Navigator.addIdleObserver", enabled: true },
{ name: "Navigator.mozNetworkStats", enabled: pref("dom.mozNetworkStats.enabled") },
{ name: "Navigator.push", enabled: pref("services.push.enabled") },
// { name: "Navigator.mozTime", enabled: b2gOnly }, // conditional on MOZ_TIME_MANAGER, tricky to test
// { name: "Navigator.mozFMRadio", enabled: b2gOnly }, // conditional on MOZ_B2G_FM, tricky to test
{ name: "Navigator.mozCameras", enabled: true },
{ name: "Navigator.mozAlarms", enabled: pref("dom.mozAlarms.enabled") },
{ name: "Navigator.mozTCPSocket", enabled: pref("dom.mozTCPSocket.enabled") },
{ name: "Navigator.mozInputMethod", enabled: pref("dom.mozInputMethod.enabled") },
{ name: "Navigator.mozMobileConnections", enabled: pref("dom.mobileconnection.enabled") },
{ name: "XMLHttpRequest.mozSystem", enabled: true }
];
var promises = [];
APIEndPoints.forEach(function(v) {
promises.push(navigator.hasFeature("api.window." + v.name));
});
return Promise.all(promises).then(function(values) {
for (var i = 0; i < values.length; ++i) {
is(values[i], APIEndPoints[i].enabled,
"Endpoint " + APIEndPoints[i].name + " resolved with the correct value. " +
"If this is failing because you're changing how an API is exposed, you " +
"must contact the Marketplace team to let them know about the change.");
}
}, function() {
ok(false, "The Promise should not be rejected");
});
}
function testExtensions() {
if (!b2gOnly) {
return Promise.resolve();
}
var builtInFeatures = [
{feature: "web-extensions", value: true},
{feature: "late-customization", value: true}
];
builtInFeatures.forEach(function(x) {
navigator.hasFeature(x.feature).then(function(value) {
is(value, x.value, "Resolve the Promise with " + value + " for feature: " + x.feature);
}).catch(function(ex) {
ok(false, "The Promise should not be rejected");
});
});
return Promise.resolve();
}
SpecialPowers.pushPermissions([
{type: "feature-detection", allow: true, context: document}
], function() {
b2gOnly = (function() {
var isAndroid = !!navigator.userAgent.includes("Android");
var isMulet = pref("b2g.is_mulet");
var isB2g = isMulet || (!isAndroid && /Mobile|Tablet/.test(navigator.userAgent));
return isB2g ? true : undefined;
})();
ok('hasFeature' in navigator, "navigator.hasFeature should exist");
testAPIs().then(testExtensions).catch(function(e) {
ok(false, "The Promise should not be rejected: " + e);
}).then(SimpleTest.finish);
});
SimpleTest.waitForExplicitFinish();
</script>
</body>
</html>

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

@ -789,39 +789,25 @@ BrowserElementParent.prototype = {
radiisX, radiisY, rotationAngles, forces,
count, modifiers) {
let tabParent = this._frameLoader.tabParent;
if (tabParent && tabParent.useAsyncPanZoom) {
tabParent.injectTouchEvent(type,
identifiers,
touchesX,
touchesY,
radiisX,
radiisY,
rotationAngles,
forces,
count,
modifiers);
} else {
let offset = this.getChildProcessOffset();
for (var i = 0; i < touchesX.length; i++) {
touchesX[i] += offset.x;
}
for (var i = 0; i < touchesY.length; i++) {
touchesY[i] += offset.y;
}
this._sendAsyncMsg("send-touch-event", {
"type": type,
"identifiers": identifiers,
"touchesX": touchesX,
"touchesY": touchesY,
"radiisX": radiisX,
"radiisY": radiisY,
"rotationAngles": rotationAngles,
"forces": forces,
"count": count,
"modifiers": modifiers
});
let offset = this.getChildProcessOffset();
for (var i = 0; i < touchesX.length; i++) {
touchesX[i] += offset.x;
}
for (var i = 0; i < touchesY.length; i++) {
touchesY[i] += offset.y;
}
this._sendAsyncMsg("send-touch-event", {
"type": type,
"identifiers": identifiers,
"touchesX": touchesX,
"touchesY": touchesY,
"radiisX": radiisX,
"radiisY": radiisY,
"rotationAngles": rotationAngles,
"forces": forces,
"count": count,
"modifiers": modifiers
});
}),
getCanGoBack: defineDOMRequestMethod('get-can-go-back'),

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

@ -77,17 +77,6 @@ void main() {
color = (a == 2.0) ? vec4(0, 1.0, 0, 1.0) : vec4(1.0, 0, 0, 1.0);
}
</script>
<script id="fshader-sequence-operator" type="x-shader/x-fragment">#version 300 es
precision mediump float;
out vec4 color;
void main() {
float a[2] = float[2](1.0, 0.0);
float b[2] = float[2](2.0, 3.0);
float c = (a, b)[0];
color = (c == 2.0) ? vec4(0, 1.0, 0, 1.0) : vec4(1.0, 0, 0, 1.0);
}
</script>
<script type="application/javascript">
"use strict";
description("Indexing complex array expressions");
@ -112,12 +101,6 @@ GLSLConformanceTester.runRenderTests([
linkSuccess: true,
passMsg: 'Test indexing an array initialization: (float[3](2.0, 1.0, 0.0))[0]'
},
{
fShaderId: 'fshader-sequence-operator',
fShaderSuccess: true,
linkSuccess: true,
passMsg: 'Test indexing a sequence operator: (a, b)[0]'
},
], 2);
</script>

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

@ -23,7 +23,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=456273
/** Test for Bug 456273 **/
function doTest() {
var ev = document.createEvent('KeyEvents');
var ev = document.createEvent('KeyboardEvent');
ev.initKeyEvent("keypress", true, true, null, true, false,
false, false, 0, "z".charCodeAt(0));
SpecialPowers.dispatchEvent(window, document.getElementById('edit456273'), ev);

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

@ -39,7 +39,7 @@ function fireDrop(element, shouldAllowDrop, shouldAllowOnlyChromeDrop) {
ds.startDragSession();
var event = document.createEvent("DragEvents");
var event = document.createEvent("DragEvent");
event.initDragEvent("dragover", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null, dataTransfer);
fireEvent(element, event);
@ -47,7 +47,7 @@ function fireDrop(element, shouldAllowDrop, shouldAllowOnlyChromeDrop) {
is(ds.getCurrentSession().onlyChromeDrop, shouldAllowOnlyChromeDrop,
"Unexpected .onlyChromeDrop");
event = document.createEvent("DragEvents");
event = document.createEvent("DragEvent");
event.initDragEvent("drop", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null, dataTransfer);
fireEvent(element, event);

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

@ -60,7 +60,7 @@ function RunTest() {
window.removeEventListener("dragstart", trapDrag, true);
synthesizeMouse(image, 20, 20, { type: "mouseup" });
var event = document.createEvent("DragEvents");
var event = document.createEvent("DragEvent");
event.initDragEvent("dragover", true, true, iBox.ownerDocument.defaultView, 0, 0, 0, 0, 0, false, false, false, false, 0, iBox, dataTransfer);
fireEvent(iBox, event);
synthesizeMouse(image, 3, 3, { type: "mousedown" });

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

@ -42,22 +42,22 @@ function testInitializingUntrustedEvent()
ctrlKey: false, altKey: false, shiftKey: true, metaKey: false,
keyCode: 0x30, charCode: 0x40 },
{ createEventArg: "KeyEvents",
{ createEventArg: "KeyBoardEvent",
type: "foo", bubbles: true, cancelable: true, view: null,
ctrlKey: false, altKey: false, shiftKey: false, metaKey: true,
keyCode: 0x00, charCode: 0x50 },
{ createEventArg: "keyevents",
{ createEventArg: "keyboardevEnt",
type: "bar", bubbles: false, cancelable: true, view: window,
ctrlKey: true, altKey: true, shiftKey: false, metaKey: false,
keyCode: 0x00, charCode: 0x60 },
{ createEventArg: "Keyevents",
{ createEventArg: "KeyboaRdevent",
type: "keydown", bubbles: true, cancelable: false, view: null,
ctrlKey: false, altKey: true, shiftKey: false, metaKey: true,
keyCode: 0x30, charCode: 0x00 },
{ createEventArg: "keyEvents",
{ createEventArg: "KEYBOARDEVENT",
type: "keyup", bubbles: false, cancelable: false, view: window,
ctrlKey: true, altKey: false, shiftKey: true, metaKey: false,
keyCode: 0x10, charCode: 0x80 },

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

@ -57,8 +57,8 @@ function afterDragTests()
false, true, false, false, 0, null, null);
$("synthetic").dispatchEvent(evt);
var evt = document.createEvent("dragevents");
ok(evt instanceof DragEvent, "synthetic dragevents class")
var evt = document.createEvent("dragevent");
ok(evt instanceof DragEvent, "synthetic dragevent class")
evt.initDragEvent("dragover", true, true, window, 0, 40, 35, 20, 15,
true, false, true, true, 2, document.documentElement, null);
$("synthetic2").dispatchEvent(evt);

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

@ -171,6 +171,16 @@ FlyWebPublishedServerImpl::FlyWebPublishedServerImpl(nsPIDOMWindowInner* aOwner,
, mHttpServer(new HttpServer())
{
LOG_I("FlyWebPublishedServerImpl::FlyWebPublishedServerImpl(%p)", this);
}
void
FlyWebPublishedServerImpl::PermissionGranted(bool aGranted)
{
LOG_I("FlyWebPublishedServerImpl::PermissionGranted(%b)", aGranted);
if (!aGranted) {
PublishedServerStarted(NS_ERROR_FAILURE);
return;
}
mHttpServer->Init(-1, Preferences::GetBool("flyweb.use-tls", false), this);
}
@ -252,25 +262,37 @@ FlyWebPublishedServerChild::FlyWebPublishedServerChild(nsPIDOMWindowInner* aOwne
const nsAString& aName,
const FlyWebPublishOptions& aOptions)
: FlyWebPublishedServer(aOwner, aName, aOptions)
, mActorDestroyed(false)
, mActorExists(false)
{
LOG_I("FlyWebPublishedServerChild::FlyWebPublishedServerChild(%p)", this);
ContentChild::GetSingleton()->
SendPFlyWebPublishedServerConstructor(this,
PromiseFlatString(aName),
aOptions);
// The matching release happens when the actor is destroyed, in
// ContentChild::DeallocPFlyWebPublishedServerChild
NS_ADDREF_THIS();
}
void
FlyWebPublishedServerChild::PermissionGranted(bool aGranted)
{
if (!aGranted) {
PublishedServerStarted(NS_ERROR_FAILURE);
return;
}
mActorExists = true;
FlyWebPublishOptions options;
options.mUiUrl = mUiUrl;
// Proceed with initialization.
ContentChild::GetSingleton()->
SendPFlyWebPublishedServerConstructor(this, mName, options);
}
bool
FlyWebPublishedServerChild::RecvServerReady(const nsresult& aStatus)
{
LOG_I("FlyWebPublishedServerChild::RecvServerReady(%p)", this);
MOZ_ASSERT(!mActorDestroyed);
MOZ_ASSERT(mActorExists);
PublishedServerStarted(aStatus);
return true;
@ -280,7 +302,7 @@ bool
FlyWebPublishedServerChild::RecvServerClose()
{
LOG_I("FlyWebPublishedServerChild::RecvServerClose(%p)", this);
MOZ_ASSERT(!mActorDestroyed);
MOZ_ASSERT(mActorExists);
Close();
@ -292,7 +314,7 @@ FlyWebPublishedServerChild::RecvFetchRequest(const IPCInternalRequest& aRequest,
const uint64_t& aRequestId)
{
LOG_I("FlyWebPublishedServerChild::RecvFetchRequest(%p)", this);
MOZ_ASSERT(!mActorDestroyed);
MOZ_ASSERT(mActorExists);
RefPtr<InternalRequest> request = new InternalRequest(aRequest);
mPendingRequests.Put(request, aRequestId);
@ -307,7 +329,7 @@ FlyWebPublishedServerChild::RecvWebSocketRequest(const IPCInternalRequest& aRequ
PTransportProviderChild* aProvider)
{
LOG_I("FlyWebPublishedServerChild::RecvWebSocketRequest(%p)", this);
MOZ_ASSERT(!mActorDestroyed);
MOZ_ASSERT(mActorExists);
RefPtr<InternalRequest> request = new InternalRequest(aRequest);
mPendingRequests.Put(request, aRequestId);
@ -327,7 +349,7 @@ FlyWebPublishedServerChild::ActorDestroy(ActorDestroyReason aWhy)
{
LOG_I("FlyWebPublishedServerChild::ActorDestroy(%p)", this);
mActorDestroyed = true;
mActorExists = false;
}
void
@ -336,7 +358,7 @@ FlyWebPublishedServerChild::OnFetchResponse(InternalRequest* aRequest,
{
LOG_I("FlyWebPublishedServerChild::OnFetchResponse(%p)", this);
if (mActorDestroyed) {
if (!mActorExists) {
LOG_I("FlyWebPublishedServerChild::OnFetchResponse(%p) - No actor!", this);
return;
}
@ -361,7 +383,7 @@ FlyWebPublishedServerChild::OnWebSocketAcceptInternal(InternalRequest* aRequest,
{
LOG_I("FlyWebPublishedServerChild::OnWebSocketAcceptInternal(%p)", this);
if (mActorDestroyed) {
if (!mActorExists) {
LOG_I("FlyWebPublishedServerChild::OnWebSocketAcceptInternal(%p) - No actor!", this);
return nullptr;
}
@ -400,7 +422,7 @@ FlyWebPublishedServerChild::OnWebSocketResponse(InternalRequest* aRequest,
{
LOG_I("FlyWebPublishedServerChild::OnFetchResponse(%p)", this);
if (mActorDestroyed) {
if (!mActorExists) {
LOG_I("FlyWebPublishedServerChild::OnFetchResponse(%p) - No actor!", this);
return;
}
@ -428,7 +450,7 @@ FlyWebPublishedServerChild::Close()
FlyWebPublishedServer::Close();
if (!mActorDestroyed) {
if (mActorExists) {
LOG_I("FlyWebPublishedServerChild::Close - sending __delete__ (%p)", this);
Send__delete__(this);

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

@ -57,6 +57,8 @@ public:
aUiUrl = mUiUrl;
}
virtual void PermissionGranted(bool aGranted) = 0;
virtual void OnFetchResponse(InternalRequest* aRequest,
InternalResponse* aResponse) = 0;
already_AddRefed<WebSocket>

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

@ -50,6 +50,7 @@ public:
}
}
virtual void PermissionGranted(bool aGranted) override;
virtual void OnFetchResponse(InternalRequest* aRequest,
InternalResponse* aResponse) override;
virtual void OnWebSocketResponse(InternalRequest* aConnectRequest,
@ -98,6 +99,7 @@ public:
const nsAString& aName,
const FlyWebPublishOptions& aOptions);
virtual void PermissionGranted(bool aGranted) override;
virtual bool RecvServerReady(const nsresult& aStatus) override;
virtual bool RecvServerClose() override;
virtual bool RecvFetchRequest(const IPCInternalRequest& aRequest,
@ -125,7 +127,7 @@ private:
nsDataHashtable<nsRefPtrHashKey<InternalRequest>, uint64_t> mPendingRequests;
nsRefPtrHashtable<nsUint64HashKey, TransportProviderChild>
mPendingTransportProviders;
bool mActorDestroyed;
bool mActorExists;
};
class FlyWebPublishedServerParent final : public PFlyWebPublishedServerParent

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

@ -9,6 +9,7 @@
#include "mozilla/ScopeExit.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/FlyWebPublishedServerIPC.h"
#include "mozilla/AddonPathService.h"
#include "nsISocketTransportService.h"
#include "mdns/libmdns/nsDNSServiceInfo.h"
#include "nsIUUIDGenerator.h"
@ -18,6 +19,7 @@
#include "mozilla/dom/FlyWebDiscoveryManagerBinding.h"
#include "prnetdb.h"
#include "DNS.h"
#include "nsContentPermissionHelper.h"
#include "nsSocketTransportService2.h"
#include "nsSocketTransport2.h"
#include "nsHashPropertyBag.h"
@ -34,11 +36,123 @@ struct FlyWebPublishOptions;
static LazyLogModule gFlyWebServiceLog("FlyWebService");
#undef LOG_I
#define LOG_I(...) MOZ_LOG(mozilla::dom::gFlyWebServiceLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
#undef LOG_E
#define LOG_E(...) MOZ_LOG(mozilla::dom::gFlyWebServiceLog, mozilla::LogLevel::Error, (__VA_ARGS__))
#undef LOG_TEST_I
#define LOG_TEST_I(...) MOZ_LOG_TEST(mozilla::dom::gFlyWebServiceLog, mozilla::LogLevel::Debug)
class FlyWebPublishServerPermissionCheck final
: public nsIContentPermissionRequest
, public nsIRunnable
{
public:
NS_DECL_ISUPPORTS
FlyWebPublishServerPermissionCheck(const nsCString& aServiceName, uint64_t aWindowID,
FlyWebPublishedServer* aServer)
: mServiceName(aServiceName)
, mWindowID(aWindowID)
, mServer(aServer)
{}
uint64_t WindowID() const
{
return mWindowID;
}
NS_IMETHOD Run() override
{
MOZ_ASSERT(NS_IsMainThread());
nsGlobalWindow* globalWindow = nsGlobalWindow::GetInnerWindowWithId(mWindowID);
if (!globalWindow) {
return Cancel();
}
mWindow = globalWindow->AsInner();
if (NS_WARN_IF(!mWindow)) {
return Cancel();
}
nsCOMPtr<nsIDocument> doc = mWindow->GetDoc();
if (NS_WARN_IF(!doc)) {
return Cancel();
}
mPrincipal = doc->NodePrincipal();
MOZ_ASSERT(mPrincipal);
mRequester = new nsContentPermissionRequester(mWindow);
return nsContentPermissionUtils::AskPermission(this, mWindow);
}
NS_IMETHOD Cancel() override
{
Resolve(false);
return NS_OK;
}
NS_IMETHOD Allow(JS::HandleValue aChoices) override
{
MOZ_ASSERT(aChoices.isUndefined());
Resolve(true);
return NS_OK;
}
NS_IMETHOD GetTypes(nsIArray** aTypes) override
{
nsTArray<nsString> emptyOptions;
return nsContentPermissionUtils::CreatePermissionArray(NS_LITERAL_CSTRING("flyweb-publish-server"),
NS_LITERAL_CSTRING("unused"), emptyOptions, aTypes);
}
NS_IMETHOD GetRequester(nsIContentPermissionRequester** aRequester) override
{
NS_ENSURE_ARG_POINTER(aRequester);
nsCOMPtr<nsIContentPermissionRequester> requester = mRequester;
requester.forget(aRequester);
return NS_OK;
}
NS_IMETHOD GetPrincipal(nsIPrincipal** aRequestingPrincipal) override
{
NS_IF_ADDREF(*aRequestingPrincipal = mPrincipal);
return NS_OK;
}
NS_IMETHOD GetWindow(mozIDOMWindow** aRequestingWindow) override
{
NS_IF_ADDREF(*aRequestingWindow = mWindow);
return NS_OK;
}
NS_IMETHOD GetElement(nsIDOMElement** aRequestingElement) override
{
*aRequestingElement = nullptr;
return NS_OK;
}
private:
void Resolve(bool aResolve)
{
mServer->PermissionGranted(aResolve);
}
virtual ~FlyWebPublishServerPermissionCheck() = default;
nsCString mServiceName;
uint64_t mWindowID;
RefPtr<FlyWebPublishedServer> mServer;
nsCOMPtr<nsPIDOMWindowInner> mWindow;
nsCOMPtr<nsIPrincipal> mPrincipal;
nsCOMPtr<nsIContentPermissionRequester> mRequester;
};
NS_IMPL_ISUPPORTS(FlyWebPublishServerPermissionCheck,
nsIContentPermissionRequest,
nsIRunnable)
class FlyWebMDNSService final
: public nsIDNSServiceDiscoveryListener
, public nsIDNSServiceResolveListener
@ -841,6 +955,15 @@ FlyWebService::Init()
return ErrorResult(NS_OK);
}
static already_AddRefed<FlyWebPublishPromise>
MakeRejectionPromise(const char* name)
{
MozPromiseHolder<FlyWebPublishPromise> holder;
RefPtr<FlyWebPublishPromise> promise = holder.Ensure(name);
holder.Reject(NS_ERROR_FAILURE, name);
return promise.forget();
}
already_AddRefed<FlyWebPublishPromise>
FlyWebService::PublishServer(const nsAString& aName,
const FlyWebPublishOptions& aOptions,
@ -853,10 +976,7 @@ FlyWebService::PublishServer(const nsAString& aName,
if (existingServer) {
LOG_I("PublishServer: Trying to publish server with already-existing name %s.",
NS_ConvertUTF16toUTF8(aName).get());
MozPromiseHolder<FlyWebPublishPromise> holder;
RefPtr<FlyWebPublishPromise> promise = holder.Ensure(__func__);
holder.Reject(NS_ERROR_FAILURE, __func__);
return promise.forget();
return MakeRejectionPromise(__func__);
}
RefPtr<FlyWebPublishedServer> server;
@ -864,6 +984,49 @@ FlyWebService::PublishServer(const nsAString& aName,
server = new FlyWebPublishedServerChild(aWindow, aName, aOptions);
} else {
server = new FlyWebPublishedServerImpl(aWindow, aName, aOptions);
// Before proceeding, ensure that the FlyWeb system addon exists.
nsresult rv;
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("chrome://flyweb/skin/icon-64.png"));
if (NS_FAILED(rv)) {
return MakeRejectionPromise(__func__);
}
JSAddonId *addonId = MapURIToAddonID(uri);
if (!addonId) {
LOG_E("PublishServer: Failed to find FlyWeb system addon.");
return MakeRejectionPromise(__func__);
}
JSFlatString* flat = JS_ASSERT_STRING_IS_FLAT(JS::StringOfAddonId(addonId));
nsAutoString addonIdString;
AssignJSFlatString(addonIdString, flat);
if (!addonIdString.EqualsLiteral("flyweb@mozilla.org")) {
nsCString addonIdCString = NS_ConvertUTF16toUTF8(addonIdString);
LOG_E("PublishServer: FlyWeb resource found on wrong system addon: %s.", addonIdCString.get());
return MakeRejectionPromise(__func__);
}
}
if (aWindow) {
nsresult rv;
MOZ_ASSERT(NS_IsMainThread());
rv = NS_DispatchToCurrentThread(
MakeAndAddRef<FlyWebPublishServerPermissionCheck>(
NS_ConvertUTF16toUTF8(aName), aWindow->WindowID(), server));
if (NS_WARN_IF(NS_FAILED(rv))) {
LOG_E("PublishServer: Failed to dispatch permission check runnable for %s",
NS_ConvertUTF16toUTF8(aName).get());
return MakeRejectionPromise(__func__);
}
} else {
// If aWindow is null, we're definitely in the e10s parent process.
// In this case, we know that permission has already been granted
// by the user because of content-process prompt.
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
server->PermissionGranted(true);
}
mServers.AppendElement(server);

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

@ -1537,7 +1537,7 @@ HTMLFormElement::NamedGetter(const nsAString& aName, bool &aFound)
void
HTMLFormElement::GetSupportedNames(nsTArray<nsString >& aRetval)
{
// TODO https://www.w3.org/Bugs/Public/show_bug.cgi?id=22320
// TODO https://github.com/whatwg/html/issues/1731
}
already_AddRefed<nsISupports>

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

@ -3289,7 +3289,7 @@ HTMLInputElement::GetRadioGroupContainer() const
}
already_AddRefed<nsIDOMHTMLInputElement>
HTMLInputElement::GetSelectedRadioButton()
HTMLInputElement::GetSelectedRadioButton() const
{
nsIRadioGroupContainer* container = GetRadioGroupContainer();
if (!container) {
@ -3360,6 +3360,13 @@ HTMLInputElement::SetCheckedInternal(bool aChecked, bool aNotify)
// Notify the document that the CSS :checked pseudoclass for this element
// has changed state.
UpdateState(aNotify);
// Notify all radios in the group that value has changed, this is to let
// radios to have the chance to update its states, e.g., :indeterminate.
if (mType == NS_FORM_INPUT_RADIO) {
nsCOMPtr<nsIRadioVisitor> visitor = new nsRadioUpdateStateVisitor(this);
VisitGroup(visitor, aNotify);
}
}
void
@ -6420,6 +6427,15 @@ HTMLInputElement::IntrinsicState() const
state |= NS_EVENT_STATE_INDETERMINATE;
}
if (mType == NS_FORM_INPUT_RADIO) {
nsCOMPtr<nsIDOMHTMLInputElement> selected = GetSelectedRadioButton();
bool indeterminate = !selected && !mChecked;
if (indeterminate) {
state |= NS_EVENT_STATE_INDETERMINATE;
}
}
// Check whether we are the default checked element (:default)
if (DefaultChecked()) {
state |= NS_EVENT_STATE_DEFAULT;
@ -6643,6 +6659,9 @@ HTMLInputElement::WillRemoveFromRadioGroup()
// longer a selected radio button
if (mChecked) {
container->SetCurrentRadioButton(name, nullptr);
nsCOMPtr<nsIRadioVisitor> visitor = new nsRadioUpdateStateVisitor(this);
VisitGroup(visitor, true);
}
// Remove this radio from its group in the container.

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

@ -264,7 +264,7 @@ public:
*
* @return the selected button (or null).
*/
already_AddRefed<nsIDOMHTMLInputElement> GetSelectedRadioButton();
already_AddRefed<nsIDOMHTMLInputElement> GetSelectedRadioButton() const;
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override;

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

@ -55,3 +55,15 @@ nsRadioSetValueMissingState::Visit(nsIFormControl* aRadio)
return true;
}
bool
nsRadioUpdateStateVisitor::Visit(nsIFormControl* aRadio)
{
if (aRadio == mExcludeElement) {
return true;
}
HTMLInputElement* input = static_cast<HTMLInputElement*>(aRadio);
input->UpdateState(true);
return true;
}

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

@ -94,5 +94,18 @@ protected:
bool mNotify;
};
class nsRadioUpdateStateVisitor : public nsRadioVisitor
{
public:
explicit nsRadioUpdateStateVisitor(nsIFormControl* aExcludeElement)
: mExcludeElement(aExcludeElement)
{ }
virtual bool Visit(nsIFormControl* aRadio) override;
protected:
nsIFormControl* mExcludeElement;
};
#endif // _nsRadioVisitor_h__

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

@ -6,7 +6,7 @@ skip-if(B2G||Mulet) fuzzy-if(skiaContent,1,3) needs-focus == button-load.html bu
skip-if(B2G||Mulet) fuzzy-if(skiaContent,1,3) needs-focus == button-create.html button-ref.html # B2G timed out waiting for reftest-wait to be removed # Initial mulet triage: parity with B2G/B2G Desktop
skip-if(B2G||Mulet) fuzzy-if(skiaContent,1,3) needs-focus == textarea-load.html textarea-ref.html # B2G timed out waiting for reftest-wait to be removed # Initial mulet triage: parity with B2G/B2G Desktop
skip-if(B2G||Mulet) fuzzy-if(skiaContent,1,3) needs-focus == textarea-create.html textarea-ref.html # B2G timed out waiting for reftest-wait to be removed # Initial mulet triage: parity with B2G/B2G Desktop
skip-if(B2G||Mulet) fuzzy-if(skiaContent,2,4) needs-focus == select-load.html select-ref.html # B2G timed out waiting for reftest-wait to be removed # Initial mulet triage: parity with B2G/B2G Desktop
skip-if(B2G||Mulet) fuzzy-if(skiaContent,9,6) needs-focus == select-load.html select-ref.html # B2G timed out waiting for reftest-wait to be removed # Initial mulet triage: parity with B2G/B2G Desktop
skip-if(B2G||Mulet) fuzzy-if(skiaContent,2,4) needs-focus == select-create.html select-ref.html # B2G timed out waiting for reftest-wait to be removed # Initial mulet triage: parity with B2G/B2G Desktop
needs-focus == autofocus-after-load.html autofocus-after-load-ref.html
fails-if(B2G||Mulet) fuzzy-if(skiaContent,2,5) needs-focus == autofocus-leaves-iframe.html autofocus-leaves-iframe-ref.html # B2G focus difference between test and reference # Initial mulet triage: parity with B2G/B2G Desktop

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

@ -9,19 +9,19 @@ window.addEventListener("Test:DispatchKeyEvents", aEvent => {
var keyCode = KeyEvent["DOM_" + aEvent.detail.code];
document.body.focus();
var evt = document.createEvent("KeyEvents");
var evt = document.createEvent("KeyboardEvent");
evt.initKeyEvent("keydown", true, true, window,
false, false, false, false,
keyCode, 0);
document.body.dispatchEvent(evt);
evt = document.createEvent("KeyEvents");
evt = document.createEvent("KeyboardEvent");
evt.initKeyEvent("keypress", true, true, window,
false, false, false, false,
keyCode, 0);
document.body.dispatchEvent(evt);
evt = document.createEvent("KeyEvents");
evt = document.createEvent("KeyboardEvent");
evt.initKeyEvent("keyup", true, true, window,
false, false, false, false,
keyCode, 0);

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

@ -9,6 +9,7 @@ support-files =
[test_bug1286509.html]
skip-if = os == "android" || appname == "b2g" # up/down arrow keys not supported on android/b2g
[test_button_attributes_reflection.html]
[test_input_radio_indeterminate.html]
[test_input_radio_radiogroup.html]
[test_input_radio_required.html]
[test_change_event.html]

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

@ -0,0 +1,109 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=885359
-->
<head>
<title>Test for Bug 885359</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.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=885359">Mozilla Bug 343444</a>
<p id="display"></p>
<form>
<input type="radio" id='radio1'/><br/>
<input type="radio" id="g1radio1" name="group1"/>
<input type="radio" id="g1radio2" name="group1"/></br>
<input type="radio" id="g1radio3" name="group1"/></br>
<input type="radio" id="g2radio1" name="group2"/>
<input type="radio" id="g2radio2" name="group2" checked/></br>
</form>
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
var radio1 = document.getElementById("radio1");
var g1radio1 = document.getElementById("g1radio1");
var g1radio2 = document.getElementById("g1radio2");
var g1radio3 = document.getElementById("g1radio3");
var g2radio1 = document.getElementById("g2radio1");
var g2radio2 = document.getElementById("g2radio2");
SimpleTest.waitForFocus(function() {
test();
SimpleTest.finish();
});
function verifyIndeterminateState(aElement, aIsIndeterminate, aMessage) {
is(aElement.mozMatchesSelector(':indeterminate'), aIsIndeterminate, aMessage);
}
function test() {
// Initial State.
verifyIndeterminateState(radio1, true,
"Unchecked radio in its own group (no name attribute)");
verifyIndeterminateState(g1radio1, true, "No selected radio in its group");
verifyIndeterminateState(g1radio2, true, "No selected radio in its group");
verifyIndeterminateState(g1radio3, true, "No selected radio in its group");
verifyIndeterminateState(g2radio1, false, "Selected radio in its group");
verifyIndeterminateState(g2radio2, false, "Selected radio in its group");
// Selecting radio buttion.
g1radio1.checked = true;
verifyIndeterminateState(g1radio1, false,
"Selecting a radio should affect all radios in the group");
verifyIndeterminateState(g1radio2, false,
"Selecting a radio should affect all radios in the group");
verifyIndeterminateState(g1radio3, false,
"Selecting a radio should affect all radios in the group");
// Changing the selected radio button.
g1radio3.checked = true;
verifyIndeterminateState(g1radio1, false,
"Selecting a radio should affect all radios in the group");
verifyIndeterminateState(g1radio2, false,
"Selecting a radio should affect all radios in the group");
verifyIndeterminateState(g1radio3, false,
"Selecting a radio should affect all radios in the group");
// Deselecting radio button.
g2radio2.checked = false;
verifyIndeterminateState(g2radio1, true,
"Deselecting a radio should affect all radios in the group");
verifyIndeterminateState(g2radio2, true,
"Deselecting a radio should affect all radios in the group");
// Move a selected radio button to another group.
g1radio3.name = "group2";
// The radios' state in the original group becomes indeterminated.
verifyIndeterminateState(g1radio1, true,
"Removing a radio from a group should affect all radios in the group");
verifyIndeterminateState(g1radio2, true,
"Removing a radio from a group should affect all radios in the group");
// The radios' state in the new group becomes determinated.
verifyIndeterminateState(g1radio3, false,
"Adding a radio from a group should affect all radios in the group");
verifyIndeterminateState(g2radio1, false,
"Adding a radio from a group should affect all radios in the group");
verifyIndeterminateState(g2radio2, false,
"Adding a radio from a group should affect all radios in the group");
// Change input type to 'text'.
g1radio3.type = "text";
verifyIndeterminateState(g1radio3, false,
"Input type text does not have an indeterminate state");
verifyIndeterminateState(g2radio1, true,
"Changing input type should affect all radios in the group");
verifyIndeterminateState(g2radio2, true,
"Changing input type should affect all radios in the group");
}
</script>
</pre>
</body>
</html>

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

@ -8,17 +8,6 @@
[builtinclass, scriptable, uuid(8e49f7b0-1f98-4939-bf91-e9c39cd56434)]
interface nsITabParent : nsISupports
{
void injectTouchEvent(in AString aType,
[array, size_is(count)] in uint32_t aIdentifiers,
[array, size_is(count)] in int32_t aXs,
[array, size_is(count)] in int32_t aYs,
[array, size_is(count)] in uint32_t aRxs,
[array, size_is(count)] in uint32_t aRys,
[array, size_is(count)] in float aRotationAngles,
[array, size_is(count)] in float aForces,
in uint32_t count,
in long aModifiers);
void getChildProcessOffset(out int32_t aCssX, out int32_t aCssY);
readonly attribute boolean useAsyncPanZoom;

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

@ -32,7 +32,6 @@
#include "mozilla/dom/GetFilesHelper.h"
#include "mozilla/dom/PCrashReporterChild.h"
#include "mozilla/dom/ProcessGlobal.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/workers/ServiceWorkerManager.h"
#include "mozilla/dom/nsIContentChild.h"
#include "mozilla/gfx/gfxVars.h"
@ -2263,22 +2262,6 @@ ContentChild::AddRemoteAlertObserver(const nsString& aData,
return NS_OK;
}
bool
ContentChild::RecvSystemMemoryAvailable(const uint64_t& aGetterId,
const uint32_t& aMemoryAvailable)
{
RefPtr<Promise> p = dont_AddRef(reinterpret_cast<Promise*>(aGetterId));
if (!aMemoryAvailable) {
p->MaybeReject(NS_ERROR_NOT_AVAILABLE);
return true;
}
p->MaybeResolve((int)aMemoryAvailable);
return true;
}
bool
ContentChild::RecvPreferenceUpdate(const PrefSetting& aPref)
{

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

@ -404,9 +404,6 @@ public:
// auto remove when alertfinished is received.
nsresult AddRemoteAlertObserver(const nsString& aData, nsIObserver* aObserver);
virtual bool RecvSystemMemoryAvailable(const uint64_t& aGetterId,
const uint32_t& aMemoryAvailable) override;
virtual bool RecvPreferenceUpdate(const PrefSetting& aPref) override;
virtual bool RecvVarUpdate(const GfxVarUpdate& pref) override;

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

@ -3909,20 +3909,6 @@ ContentParent::RecvNSSU2FTokenSign(nsTArray<uint8_t>&& aApplication,
return NS_SUCCEEDED(rv);
}
bool
ContentParent::RecvGetSystemMemory(const uint64_t& aGetterId)
{
uint32_t memoryTotal = 0;
#if defined(XP_LINUX)
memoryTotal = mozilla::hal::GetTotalSystemMemoryLevel();
#endif
Unused << SendSystemMemoryAvailable(aGetterId, memoryTotal);
return true;
}
bool
ContentParent::RecvGetLookAndFeelCache(nsTArray<LookAndFeelInt>* aLookAndFeelIntCache)
{

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

@ -1013,8 +1013,6 @@ private:
const bool& aContentOrNormalChannel,
const bool& aAnyChannel) override;
virtual bool RecvGetSystemMemory(const uint64_t& getterId) override;
virtual bool RecvGetLookAndFeelCache(nsTArray<LookAndFeelInt>* aLookAndFeelIntCache) override;
virtual bool RecvSpeakerManagerGetSpeakerStatus(bool* aValue) override;

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

@ -518,8 +518,6 @@ child:
async NotifyVisited(URIParams uri);
async SystemMemoryAvailable(uint64_t getterId, uint32_t memoryAvailable);
async PreferenceUpdate(PrefSetting pref);
async VarUpdate(GfxVarUpdate var);
@ -829,8 +827,6 @@ parent:
uint8_t[] keyHandle)
returns (uint8_t[] signature);
async GetSystemMemory(uint64_t getterId);
sync IsSecureURI(uint32_t type, URIParams uri, uint32_t flags)
returns (bool isSecureURI);

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

@ -2809,71 +2809,6 @@ TabParent::GetLoadContext()
return loadContext.forget();
}
NS_IMETHODIMP
TabParent::InjectTouchEvent(const nsAString& aType,
uint32_t* aIdentifiers,
int32_t* aXs,
int32_t* aYs,
uint32_t* aRxs,
uint32_t* aRys,
float* aRotationAngles,
float* aForces,
uint32_t aCount,
int32_t aModifiers)
{
EventMessage msg;
nsContentUtils::GetEventMessageAndAtom(aType, eTouchEventClass, &msg);
if (msg != eTouchStart && msg != eTouchMove &&
msg != eTouchEnd && msg != eTouchCancel) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
return NS_ERROR_FAILURE;
}
WidgetTouchEvent event(true, msg, widget);
event.mModifiers = aModifiers;
event.mTime = PR_IntervalNow();
nsCOMPtr<nsIContent> content = do_QueryInterface(mFrameElement);
if (!content || !content->OwnerDoc()) {
return NS_ERROR_FAILURE;
}
nsIDocument* doc = content->OwnerDoc();
if (!doc || !doc->GetShell()) {
return NS_ERROR_FAILURE;
}
nsPresContext* presContext = doc->GetShell()->GetPresContext();
event.mTouches.SetCapacity(aCount);
for (uint32_t i = 0; i < aCount; ++i) {
LayoutDeviceIntPoint pt =
LayoutDeviceIntPoint::FromAppUnitsRounded(
CSSPoint::ToAppUnits(CSSPoint(aXs[i], aYs[i])),
presContext->AppUnitsPerDevPixel());
LayoutDeviceIntPoint radius =
LayoutDeviceIntPoint::FromAppUnitsRounded(
CSSPoint::ToAppUnits(CSSPoint(aRxs[i], aRys[i])),
presContext->AppUnitsPerDevPixel());
RefPtr<Touch> t =
new Touch(aIdentifiers[i], pt, radius, aRotationAngles[i], aForces[i]);
// Consider all injected touch events as changedTouches. For more details
// about the meaning of changedTouches for each event, see
// https://developer.mozilla.org/docs/Web/API/TouchEvent.changedTouches
t->mChanged = true;
event.mTouches.AppendElement(t);
}
SendRealTouchEvent(event);
return NS_OK;
}
NS_IMETHODIMP
TabParent::GetUseAsyncPanZoom(bool* useAsyncPanZoom)
{

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

@ -1,8 +1,8 @@
# basic sanity checking
random-if(!haveTestPlugin) != plugin-sanity.html about:blank
fails-if(!haveTestPlugin) == plugin-sanity.html div-sanity.html
fails-if(!haveTestPlugin) fuzzy-if(skiaContent,1,160000) == plugin-alpha-zindex.html div-alpha-zindex.html
fails-if(!haveTestPlugin) fuzzy-if(skiaContent,1,164000) == plugin-alpha-opacity.html div-alpha-opacity.html
fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,160000) == plugin-alpha-zindex.html div-alpha-zindex.html
fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,164000) == plugin-alpha-opacity.html div-alpha-opacity.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == windowless-clipping-1.html windowless-clipping-1-ref.html # bug 631832
# fuzzy because of anti-aliasing in dashed border
fuzzy(16,256) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == border-padding-1.html border-padding-1-ref.html # bug 629430
@ -11,14 +11,14 @@ fuzzy(16,256) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) skip-if(!have
# The following two "pluginproblemui-direction" tests are unreliable on all platforms. They should be re-written or replaced.
#random-if(cocoaWidget||d2d||/^Windows\x20NT\x205\.1/.test(http.oscpu)) fails-if(!haveTestPlugin&&!Android) == pluginproblemui-direction-1.html pluginproblemui-direction-1-ref.html # bug 567367
#random-if(cocoaWidget) fails-if(!haveTestPlugin&&!Android) == pluginproblemui-direction-2.html pluginproblemui-direction-2-ref.html
fails-if(!haveTestPlugin) fuzzy-if(skiaContent,1,160000) == plugin-canvas-alpha-zindex.html div-alpha-zindex.html
fails-if(!haveTestPlugin) fuzzy-if(skiaContent,1,160000) == plugin-transform-alpha-zindex.html div-alpha-zindex.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) fuzzy-if(skiaContent,1,160000) == plugin-busy-alpha-zindex.html div-alpha-zindex.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) fuzzy-if(skiaContent,1,32400) == plugin-background.html plugin-background-ref.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) fuzzy-if(skiaContent,1,32400) == plugin-background-1-step.html plugin-background-ref.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) fuzzy-if(skiaContent,1,32400) == plugin-background-2-step.html plugin-background-ref.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) fuzzy-if(skiaContent,1,32400) == plugin-background-5-step.html plugin-background-ref.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) fuzzy-if(skiaContent,1,32400) == plugin-background-10-step.html plugin-background-ref.html
fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,160000) == plugin-canvas-alpha-zindex.html div-alpha-zindex.html
fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,160000) == plugin-transform-alpha-zindex.html div-alpha-zindex.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,160000) == plugin-busy-alpha-zindex.html div-alpha-zindex.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,32400) == plugin-background.html plugin-background-ref.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,32400) == plugin-background-1-step.html plugin-background-ref.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,32400) == plugin-background-2-step.html plugin-background-ref.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,32400) == plugin-background-5-step.html plugin-background-ref.html
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) fuzzy-if(skiaContent&&haveTestPlugin,1,32400) == plugin-background-10-step.html plugin-background-ref.html
random-if(!haveTestPlugin) == plugin-transform-1.html plugin-transform-1-ref.html
fails-if(!haveTestPlugin) == plugin-transform-2.html plugin-transform-2-ref.html
skip-if(!haveTestPlugin) == shrink-1.html shrink-1-ref.html

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

@ -63,7 +63,7 @@ Event.simulateKey = function(element, eventName) {
charCode: 0
}, arguments[2] || {});
var oEvent = document.createEvent("KeyEvents");
var oEvent = document.createEvent("KeyboardEvent");
oEvent.initKeyEvent(eventName, true, true, window,
options.ctrlKey, options.altKey, options.shiftKey, options.metaKey,
options.keyCode, options.charCode );

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

@ -54,7 +54,7 @@ Event.simulateKey = function(element, eventName) {
charCode: 0
}, arguments[2] || {});
var oEvent = document.createEvent("KeyEvents");
var oEvent = document.createEvent("KeyboardEvent");
oEvent.initKeyEvent(eventName, true, true, window,
options.ctrlKey, options.altKey, options.shiftKey, options.metaKey,
options.keyCode, options.charCode );

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

@ -30,7 +30,7 @@ function start()
function dispatch(eventName)
{
var event = document.createEvent("DragEvents");
var event = document.createEvent("DragEvent");
event.initDragEvent(eventName, true, true, window, 0, 5, 5, 5, 5,
false, false, false, false, 0, null, null);
element.dispatchEvent(event);

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

@ -11,9 +11,7 @@
* and create derivative works of this document.
*/
// Should be LegacyUnenumerableNamedProperties. See
// https://bugzilla.mozilla.org/show_bug.cgi?id=1270369
[OverrideBuiltins]
[OverrideBuiltins, LegacyUnenumerableNamedProperties]
interface HTMLFormElement : HTMLElement {
[Pure, SetterThrows]
attribute DOMString acceptCharset;

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

@ -4,9 +4,7 @@
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// [LegacyUnenumerableNamedProperties]
// Named properties enumerable for now; see
// https://bugzilla.mozilla.org/show_bug.cgi?id=1270364
[LegacyUnenumerableNamedProperties]
interface MimeTypeArray {
readonly attribute unsigned long length;

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

@ -29,7 +29,6 @@ Navigator implements NavigatorLanguage;
Navigator implements NavigatorOnLine;
Navigator implements NavigatorContentUtils;
Navigator implements NavigatorStorageUtils;
Navigator implements NavigatorFeatures;
Navigator implements NavigatorConcurrentHardware;
[NoInterfaceObject, Exposed=(Window,Worker)]
@ -92,15 +91,6 @@ interface NavigatorStorageUtils {
//void yieldForStorageUpdates();
};
[NoInterfaceObject]
interface NavigatorFeatures {
[ChromeOnly, Throws]
Promise<any> getFeature(DOMString name);
[ChromeOnly, Throws]
Promise<any> hasFeature(DOMString name);
};
partial interface Navigator {
[Throws]
readonly attribute Permissions permissions;

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

@ -4,9 +4,7 @@
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// [LegacyUnenumerableNamedProperties]
// Named properties enumerable for now; see
// https://bugzilla.mozilla.org/show_bug.cgi?id=1270366
[LegacyUnenumerableNamedProperties]
interface Plugin {
readonly attribute DOMString description;
readonly attribute DOMString filename;

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

@ -4,9 +4,7 @@
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// [LegacyUnenumerableNamedProperties]
// Named properties enumerable for now; see
// https://bugzilla.mozilla.org/show_bug.cgi?id=1270366
[LegacyUnenumerableNamedProperties]
interface PluginArray {
readonly attribute unsigned long length;

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

@ -165,7 +165,7 @@ function runTests()
var targetDescription = " (dispatched to " + aTarget._description + ")";
function dispatchKeyEvent(aKeyCode, aChar, aTarget)
{
var keyEvent = document.createEvent("KeyEvents");
var keyEvent = document.createEvent("KeyboardEvent");
keyEvent.initKeyEvent("keypress", true, true, null, false, false,
false, false, aKeyCode,
aChar ? aChar.charCodeAt(0) : 0);

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

@ -290,15 +290,11 @@ APZEventState::ProcessTouchEvent(const WidgetTouchEvent& aEvent,
sentContentResponse = SendPendingTouchPreventedResponse(false);
// sentContentResponse can be true here if we get two TOUCH_STARTs in a row
// and just responded to the first one.
if (!aEvent.mFlags.mHandledByAPZ) {
// This condition being true means this touchstart is synthetic and is
// coming from TabParent.injectTouchEvent.
// Since APZ doesn't know about it we don't want to send a response for
// this block; we want to just skip over it from the point of view of
// prevent-default notifications.
APZES_LOG("Got a synthetic touch-start!\n");
break;
}
// We're about to send a response back to APZ, but we should only do it
// for events that went through APZ (which should be all of them).
MOZ_ASSERT(aEvent.mFlags.mHandledByAPZ);
if (isTouchPrevented) {
mContentReceivedInputBlockCallback(aGuid, aInputBlockId, isTouchPrevented);
sentContentResponse = true;

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

@ -1071,6 +1071,7 @@ CompositorBridgeParent::ResumeComposition()
mPaused = false;
Invalidate();
mCompositorScheduler->ResumeComposition();
// if anyone's waiting to make sure that composition really got resumed, tell them

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

@ -499,10 +499,11 @@ gfxPlatform::gfxPlatform()
mSkiaGlue = nullptr;
uint32_t canvasMask = BackendTypeBit(BackendType::CAIRO);
uint32_t contentMask = BackendTypeBit(BackendType::CAIRO);
#ifdef USE_SKIA
canvasMask |= BackendTypeBit(BackendType::SKIA);
contentMask |= BackendTypeBit(BackendType::SKIA);
#endif
uint32_t contentMask = BackendTypeBit(BackendType::CAIRO);
InitBackendPrefs(canvasMask, BackendType::CAIRO,
contentMask, BackendType::CAIRO);
mTotalSystemMemory = mozilla::hal::GetTotalSystemMemory();

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

@ -1212,12 +1212,6 @@ GetTotalSystemMemory()
return hal_impl::GetTotalSystemMemory();
}
uint32_t
GetTotalSystemMemoryLevel()
{
return hal_impl::GetTotalSystemMemoryLevel();
}
bool IsHeadphoneEventFromInputDev()
{
AssertMainThread();

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

@ -627,14 +627,6 @@ void StopDiskSpaceWatcher();
*/
uint32_t GetTotalSystemMemory();
/**
* Get the level of total system memory on device in MiB.
* (round the value up to the next power of two)
*
* Returns 0 if we are unable to determine this information from /proc/meminfo.
*/
uint32_t GetTotalSystemMemoryLevel();
/**
* Determine whether the headphone switch event is from input device
*/

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

@ -16,11 +16,5 @@ GetTotalSystemMemory()
return 0;
}
uint32_t
GetTotalSystemMemoryLevel()
{
return 0;
}
} // namespace hal_impl
} // namespace mozilla

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

@ -35,37 +35,5 @@ GetTotalSystemMemory()
return sTotalMemory * 1024;
}
uint32_t
GetTotalSystemMemoryLevel()
{
static uint32_t sTotalMemoryLevel = 1;
uint32_t sTotalMemory;
static bool sTotalMemoryObtained = false;
if (!sTotalMemoryObtained) {
sTotalMemoryObtained = true;
FILE* fd = fopen("/proc/meminfo", "r");
if (!fd) {
return 0;
}
int rv = fscanf(fd, "MemTotal: %i kB", &sTotalMemory);
if (fclose(fd) || rv != 1) {
return 0;
}
// From KB to MiB
sTotalMemory /= 1024;
while (sTotalMemoryLevel <= sTotalMemory) {
sTotalMemoryLevel *= 2;
}
}
return sTotalMemoryLevel;
}
} // namespace hal_impl
} // namespace mozilla

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

@ -87,7 +87,7 @@ fuzzy(20,999) != downscale-2c.html?205,53,bottom about:blank
fuzzy(20,999) != downscale-2d.html?205,53,bottom about:blank
fuzzy(20,999) fails-if(OSX>=1008&&!skiaContent) != downscale-2e.html?205,53,bottom about:blank
fuzzy(63,3386) == downscale-moz-icon-1.html downscale-moz-icon-1-ref.html
fuzzy(63,3391) == downscale-moz-icon-1.html downscale-moz-icon-1-ref.html
== downscale-png.html?16,16,interlaced downscale-png.html?16,16,normal
== downscale-png.html?24,24,interlaced downscale-png.html?24,24,normal

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

@ -787,7 +787,7 @@ struct JSClass {
// application.
#define JSCLASS_GLOBAL_APPLICATION_SLOTS 5
#define JSCLASS_GLOBAL_SLOT_COUNT \
(JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 3 + 37)
(JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 2 + 37)
#define JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(n) \
(JSCLASS_IS_GLOBAL | JSCLASS_HAS_RESERVED_SLOTS(JSCLASS_GLOBAL_SLOT_COUNT + (n)))
#define JSCLASS_GLOBAL_FLAGS \

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

@ -144,10 +144,13 @@ struct GCPolicy<mozilla::UniquePtr<T, D>>
{
static mozilla::UniquePtr<T,D> initial() { return mozilla::UniquePtr<T,D>(); }
static void trace(JSTracer* trc, mozilla::UniquePtr<T,D>* tp, const char* name) {
GCPolicy<T>::trace(trc, tp->get(), name);
if (tp->get())
GCPolicy<T>::trace(trc, tp->get(), name);
}
static bool needsSweep(mozilla::UniquePtr<T,D>* tp) {
return GCPolicy<T>::needsSweep(tp->get());
if (tp->get())
return GCPolicy<T>::needsSweep(tp->get());
return false;
}
};

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

@ -301,6 +301,7 @@ static bool
ScopeKindIsInBody(ScopeKind kind)
{
return kind == ScopeKind::Lexical ||
kind == ScopeKind::SimpleCatch ||
kind == ScopeKind::Catch ||
kind == ScopeKind::With ||
kind == ScopeKind::FunctionBodyVar ||
@ -681,6 +682,7 @@ BytecodeEmitter::EmitterScope::searchInEnclosingScope(JSAtom* name, Scope* scope
case ScopeKind::Lexical:
case ScopeKind::NamedLambda:
case ScopeKind::StrictNamedLambda:
case ScopeKind::SimpleCatch:
case ScopeKind::Catch:
if (hasEnv) {
for (BindingIter bi(si.scope()); bi; bi++) {
@ -1412,6 +1414,7 @@ BytecodeEmitter::EmitterScope::leave(BytecodeEmitter* bce, bool nonLocal)
ScopeKind kind = scope(bce)->kind();
switch (kind) {
case ScopeKind::Lexical:
case ScopeKind::SimpleCatch:
case ScopeKind::Catch:
if (!bce->emit1(hasEnvironment() ? JSOP_POPLEXICALENV : JSOP_DEBUGLEAVELEXICALENV))
return false;
@ -5664,7 +5667,7 @@ BytecodeEmitter::emitLexicalScope(ParseNode* pn)
// For example, consider the following code.
//
// L1: {
// L2: let x = 42;
// L2: let x = 42;
// L3: }
//
// If line number notes were not updated before the TDZ poison, the TDZ
@ -5679,7 +5682,12 @@ BytecodeEmitter::emitLexicalScope(ParseNode* pn)
}
EmitterScope emitterScope(this);
ScopeKind kind = body->isKind(PNK_CATCH) ? ScopeKind::Catch : ScopeKind::Lexical;
ScopeKind kind;
if (body->isKind(PNK_CATCH))
kind = body->pn_kid1->isKind(PNK_NAME) ? ScopeKind::SimpleCatch : ScopeKind::Catch;
else
kind = ScopeKind::Lexical;
if (!emitterScope.enterLexical(this, kind, pn->scopeBindings()))
return false;

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

@ -170,15 +170,47 @@ ParseContext::Scope::removeVarForAnnexBLexicalFunction(ParseContext* pc, JSAtom*
pc->removeInnerFunctionBoxesForAnnexB(name);
}
static bool
DeclarationKindIsCatchParameter(DeclarationKind kind)
{
return kind == DeclarationKind::SimpleCatchParameter ||
kind == DeclarationKind::CatchParameter;
}
bool
ParseContext::Scope::addCatchParameters(ParseContext* pc, Scope& catchParamScope)
{
if (pc->useAsmOrInsideUseAsm())
return true;
for (DeclaredNameMap::Range r = catchParamScope.declared_->all(); !r.empty(); r.popFront()) {
DeclarationKind kind = r.front().value()->kind();
MOZ_ASSERT(DeclarationKindIsCatchParameter(kind));
JSAtom* name = r.front().key();
AddDeclaredNamePtr p = lookupDeclaredNameForAdd(name);
MOZ_ASSERT(!p);
if (!addDeclaredName(pc, p, name, kind))
return false;
}
return true;
}
void
ParseContext::Scope::removeSimpleCatchParameter(ParseContext* pc, JSAtom* name)
ParseContext::Scope::removeCatchParameters(ParseContext* pc, Scope& catchParamScope)
{
if (pc->useAsmOrInsideUseAsm())
return;
DeclaredNamePtr p = declared_->lookup(name);
MOZ_ASSERT(p && p->value()->kind() == DeclarationKind::SimpleCatchParameter);
declared_->remove(p);
for (DeclaredNameMap::Range r = catchParamScope.declared_->all(); !r.empty(); r.popFront()) {
DeclaredNamePtr p = declared_->lookup(r.front().key());
MOZ_ASSERT(p);
// This check is needed because the catch body could have declared
// vars, which would have been added to catchParamScope.
if (DeclarationKindIsCatchParameter(r.front().value()->kind()))
declared_->remove(p);
}
}
void
@ -921,6 +953,60 @@ DeclarationKindIsVar(DeclarationKind kind)
kind == DeclarationKind::ForOfVar;
}
template <typename ParseHandler>
Maybe<DeclarationKind>
Parser<ParseHandler>::isVarRedeclaredInEval(HandlePropertyName name, DeclarationKind kind)
{
MOZ_ASSERT(DeclarationKindIsVar(kind));
MOZ_ASSERT(pc->sc()->isEvalContext());
// In the case of eval, we also need to check enclosing VM scopes to see
// if the var declaration is allowed in the context.
//
// This check is necessary in addition to
// js::CheckEvalDeclarationConflicts because we only know during parsing
// if a var is bound by for-of.
Scope* enclosingScope = pc->sc()->compilationEnclosingScope();
Scope* varScope = EvalScope::nearestVarScopeForDirectEval(enclosingScope);
MOZ_ASSERT(varScope);
for (ScopeIter si(enclosingScope); si; si++) {
for (js::BindingIter bi(si.scope()); bi; bi++) {
if (bi.name() != name)
continue;
switch (bi.kind()) {
case BindingKind::Let: {
// Annex B.3.5 allows redeclaring simple (non-destructured)
// catch parameters with var declarations, except when it
// appears in a for-of.
bool annexB35Allowance = si.kind() == ScopeKind::SimpleCatch &&
kind != DeclarationKind::ForOfVar;
if (!annexB35Allowance) {
return Some(ScopeKindIsCatch(si.kind())
? DeclarationKind::CatchParameter
: DeclarationKind::Let);
}
break;
}
case BindingKind::Const:
return Some(DeclarationKind::Const);
case BindingKind::Import:
case BindingKind::FormalParameter:
case BindingKind::Var:
case BindingKind::NamedLambdaCallee:
break;
}
}
if (si.scope() == varScope)
break;
}
return Nothing();
}
static bool
DeclarationKindIsParameter(DeclarationKind kind)
{
@ -976,6 +1062,9 @@ Parser<ParseHandler>::tryDeclareVar(HandlePropertyName name, DeclarationKind kin
}
}
if (!pc->sc()->strict() && pc->sc()->isEvalContext())
*redeclaredKind = isVarRedeclaredInEval(name, kind);
return true;
}
@ -988,46 +1077,6 @@ Parser<ParseHandler>::tryDeclareVarForAnnexBLexicalFunction(HandlePropertyName n
if (!tryDeclareVar(name, DeclarationKind::VarForAnnexBLexicalFunction, &redeclaredKind))
return false;
// In the case of eval, we also need to check enclosing VM scopes to see
// if an Annex B var should be synthesized.
if (!redeclaredKind && pc->sc()->isEvalContext()) {
Scope* enclosingScope = pc->sc()->compilationEnclosingScope();
Scope* varScope = EvalScope::nearestVarScopeForDirectEval(enclosingScope);
MOZ_ASSERT(varScope);
for (ScopeIter si(enclosingScope); si; si++) {
for (js::BindingIter bi(si.scope()); bi; bi++) {
if (bi.name() != name)
continue;
switch (bi.kind()) {
case BindingKind::Let: {
// Annex B.3.5 allows redeclaring simple (non-destructured)
// catch parameters with var declarations, except when it
// appears in a for-of, which a function declaration is
// definitely not.
bool annexB35Allowance = si.kind() == ScopeKind::Catch;
if (!annexB35Allowance)
redeclaredKind = Some(DeclarationKind::Let);
break;
}
case BindingKind::Const:
redeclaredKind = Some(DeclarationKind::Const);
break;
case BindingKind::Import:
case BindingKind::FormalParameter:
case BindingKind::Var:
case BindingKind::NamedLambdaCallee:
break;
}
}
if (si.scope() == varScope)
break;
}
}
if (redeclaredKind) {
// If an early error would have occurred, undo all the
// VarForAnnexBLexicalFunction declarations.
@ -2704,7 +2753,7 @@ Parser<ParseHandler>::functionArguments(YieldHandling yieldHandling, FunctionSyn
template <typename ParseHandler>
bool
Parser<ParseHandler>::checkFunctionDefinition(HandleAtom funAtom, Node pn, FunctionSyntaxKind kind,
bool *tryAnnexB)
GeneratorKind generatorKind, bool* tryAnnexB)
{
if (kind == Statement) {
TokenPos pos = handler.getPosition(pn);
@ -2733,7 +2782,7 @@ Parser<ParseHandler>::checkFunctionDefinition(HandleAtom funAtom, Node pn, Funct
MOZ_ASSERT(declaredInStmt->kind() != StatementKind::Label);
MOZ_ASSERT(StatementKindIsBraced(declaredInStmt->kind()));
if (!pc->sc()->strict()) {
if (!pc->sc()->strict() && generatorKind == NotGenerator) {
// Under sloppy mode, try Annex B.3.3 semantics. If making an
// additional 'var' binding of the same name does not throw an
// early error, do so. This 'var' binding would be assigned
@ -2893,7 +2942,7 @@ Parser<ParseHandler>::functionDefinition(InHandling inHandling, YieldHandling yi
// Note the declared name and check for early errors.
bool tryAnnexB = false;
if (!checkFunctionDefinition(funName, pn, kind, &tryAnnexB))
if (!checkFunctionDefinition(funName, pn, kind, generatorKind, &tryAnnexB))
return null();
// When fully parsing a LazyScript, we do not fully reparse its inner
@ -5974,8 +6023,6 @@ Parser<ParseHandler>::tryStatement(YieldHandling yieldHandling)
*/
MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_CATCH);
RootedPropertyName simpleCatchParam(context);
if (!tokenStream.getToken(&tt))
return null();
Node catchName;
@ -5998,17 +6045,15 @@ Parser<ParseHandler>::tryStatement(YieldHandling yieldHandling)
if (!checkYieldNameValidity())
return null();
MOZ_FALLTHROUGH;
case TOK_NAME:
simpleCatchParam = tokenStream.currentName();
catchName = newName(simpleCatchParam);
case TOK_NAME: {
RootedPropertyName param(context, tokenStream.currentName());
catchName = newName(param);
if (!catchName)
return null();
if (!noteDeclaredName(simpleCatchParam, DeclarationKind::SimpleCatchParameter,
pos()))
{
if (!noteDeclaredName(param, DeclarationKind::SimpleCatchParameter, pos()))
return null();
}
break;
}
default:
report(ParseError, false, null(), JSMSG_CATCH_IDENTIFIER);
@ -6035,7 +6080,7 @@ Parser<ParseHandler>::tryStatement(YieldHandling yieldHandling)
MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_CATCH);
Node catchBody = catchBlockStatement(yieldHandling, simpleCatchParam);
Node catchBody = catchBlockStatement(yieldHandling, scope);
if (!catchBody)
return null();
@ -6089,43 +6134,33 @@ Parser<ParseHandler>::tryStatement(YieldHandling yieldHandling)
template <typename ParseHandler>
typename ParseHandler::Node
Parser<ParseHandler>::catchBlockStatement(YieldHandling yieldHandling,
HandlePropertyName simpleCatchParam)
ParseContext::Scope& catchParamScope)
{
ParseContext::Statement stmt(pc, StatementKind::Block);
// Annex B.3.5 requires that vars be allowed to redeclare a simple
// (non-destructured) catch parameter (including via a direct eval), so
// the catch parameter needs to live in its own scope. So if we have a
// simple catch parameter, make a new scope.
Node body;
if (simpleCatchParam) {
ParseContext::Scope scope(this);
if (!scope.init(pc))
return null();
// ES 13.15.7 CatchClauseEvaluation
//
// Step 8 means that the body of a catch block always has an additional
// lexical scope.
ParseContext::Scope scope(this);
if (!scope.init(pc))
return null();
// The catch parameter name cannot be redeclared inside the catch
// block, so declare the name in the inner scope.
if (!noteDeclaredName(simpleCatchParam, DeclarationKind::SimpleCatchParameter, pos()))
return null();
// The catch parameter names cannot be redeclared inside the catch
// block, so declare the name in the inner scope.
if (!scope.addCatchParameters(pc, catchParamScope))
return null();
Node list = statementList(yieldHandling);
if (!list)
return null();
// The catch parameter name is not bound in this scope, so remove it
// before generating bindings.
scope.removeSimpleCatchParameter(pc, simpleCatchParam);
body = finishLexicalScope(scope, list);
} else {
body = statementList(yieldHandling);
}
if (!body)
Node list = statementList(yieldHandling);
if (!list)
return null();
MUST_MATCH_TOKEN_MOD(TOK_RC, TokenStream::Operand, JSMSG_CURLY_AFTER_CATCH);
return body;
// The catch parameter names are not bound in the body scope, so remove
// them before generating bindings.
scope.removeCatchParameters(pc, catchParamScope);
return finishLexicalScope(scope, list);
}
template <typename ParseHandler>

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

@ -154,9 +154,10 @@ class ParseContext : public Nestable<ParseContext>
// name from all scopes in pc's scope stack.
static void removeVarForAnnexBLexicalFunction(ParseContext* pc, JSAtom* name);
// Remove a simple catch parameter name. Used to implement the odd
// semantics of Annex B.3.5.
void removeSimpleCatchParameter(ParseContext* pc, JSAtom* name);
// Add and remove catch parameter names. Used to implement the odd
// semantics of catch bodies.
bool addCatchParameters(ParseContext* pc, Scope& catchParamScope);
void removeCatchParameters(ParseContext* pc, Scope& catchParamScope);
void useAsVarScope(ParseContext* pc) {
MOZ_ASSERT(!pc->varScope_);
@ -1042,7 +1043,7 @@ class Parser final : private JS::AutoGCRooter, public StrictModeGetter
Node withStatement(YieldHandling yieldHandling);
Node throwStatement(YieldHandling yieldHandling);
Node tryStatement(YieldHandling yieldHandling);
Node catchBlockStatement(YieldHandling yieldHandling, HandlePropertyName simpleCatchParam);
Node catchBlockStatement(YieldHandling yieldHandling, ParseContext::Scope& catchParamScope);
Node debuggerStatement();
Node variableStatement(YieldHandling yieldHandling);
@ -1239,7 +1240,7 @@ class Parser final : private JS::AutoGCRooter, public StrictModeGetter
bool declareDotGeneratorName();
bool checkFunctionDefinition(HandleAtom funAtom, Node pn, FunctionSyntaxKind kind,
bool *tryAnnexB);
GeneratorKind generatorKind, bool* tryAnnexB);
bool skipLazyInnerFunction(Node pn, bool tryAnnexB);
bool innerFunction(Node pn, ParseContext* outerpc, HandleFunction fun,
InHandling inHandling, FunctionSyntaxKind kind,
@ -1275,6 +1276,8 @@ class Parser final : private JS::AutoGCRooter, public StrictModeGetter
bool disallowDuplicateParams = false,
bool* duplicatedParam = nullptr);
bool noteDestructuredPositionalFormalParameter(Node fn, Node destruct);
mozilla::Maybe<DeclarationKind> isVarRedeclaredInEval(HandlePropertyName name,
DeclarationKind kind);
bool tryDeclareVar(HandlePropertyName name, DeclarationKind kind,
mozilla::Maybe<DeclarationKind>* redeclaredKind);
bool tryDeclareVarForAnnexBLexicalFunction(HandlePropertyName name, bool* tryAnnexB);

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

@ -1277,6 +1277,7 @@ Scope::traceChildren(JSTracer* trc)
reinterpret_cast<VarScope::Data*>(data_)->trace(trc);
break;
case ScopeKind::Lexical:
case ScopeKind::SimpleCatch:
case ScopeKind::Catch:
case ScopeKind::NamedLambda:
case ScopeKind::StrictNamedLambda:
@ -1324,6 +1325,7 @@ js::GCMarker::eagerlyMarkChildren(Scope* scope)
}
case ScopeKind::Lexical:
case ScopeKind::SimpleCatch:
case ScopeKind::Catch:
case ScopeKind::NamedLambda:
case ScopeKind::StrictNamedLambda: {

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

@ -1,8 +0,0 @@
// |jit-test| error: TypeError
eval("\
function NaN() {}\
for(w in s) {}\
")
// Don't assert.

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

@ -652,7 +652,7 @@ class InlineFrameIterator
private:
void findNextFrame();
JSObject* computeEnvironmentChain(Value envChainValue, MaybeReadFallback& fallback,
bool* hasCallObj = nullptr) const;
bool* hasInitialEnv = nullptr) const;
public:
InlineFrameIterator(JSContext* cx, const JitFrameIterator* iter);
@ -694,7 +694,7 @@ class InlineFrameIterator
template <class ArgOp, class LocalOp>
void readFrameArgsAndLocals(JSContext* cx, ArgOp& argOp, LocalOp& localOp,
JSObject** envChain, bool* hasCallObj,
JSObject** envChain, bool* hasInitialEnv,
Value* rval, ArgumentsObject** argsObj, Value* thisv,
ReadFrameArgsBehavior behavior,
MaybeReadFallback& fallback) const
@ -704,7 +704,7 @@ class InlineFrameIterator
// Read the env chain.
if (envChain) {
Value envChainValue = s.maybeRead(fallback);
*envChain = computeEnvironmentChain(envChainValue, fallback, hasCallObj);
*envChain = computeEnvironmentChain(envChainValue, fallback, hasInitialEnv);
} else {
s.skip();
}

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

@ -2397,17 +2397,19 @@ InlineFrameIterator::callee(MaybeReadFallback& fallback) const
JSObject*
InlineFrameIterator::computeEnvironmentChain(Value envChainValue, MaybeReadFallback& fallback,
bool* hasCallObj) const
bool* hasInitialEnv) const
{
if (envChainValue.isObject()) {
if (hasCallObj) {
if (hasInitialEnv) {
if (fallback.canRecoverResults()) {
RootedObject obj(fallback.maybeCx, &envChainValue.toObject());
*hasCallObj = isFunctionFrame() && callee(fallback)->needsCallObject();
*hasInitialEnv = isFunctionFrame() &&
callee(fallback)->needsFunctionEnvironmentObjects();
return obj;
} else {
JS::AutoSuppressGCAnalysis nogc; // If we cannot recover then we cannot GC.
*hasCallObj = isFunctionFrame() && callee(fallback)->needsCallObject();
*hasInitialEnv = isFunctionFrame() &&
callee(fallback)->needsFunctionEnvironmentObjects();
}
}

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

@ -1669,27 +1669,6 @@ DefineStandardSlot(JSContext* cx, HandleObject obj, JSProtoKey key, JSAtom* atom
HandleValue v, uint32_t attrs, bool& named)
{
RootedId id(cx, AtomToId(atom));
if (key != JSProto_Null) {
/*
* Initializing an actual standard class on a global object. If the
* property is not yet present, force it into a new one bound to a
* reserved slot. Otherwise, go through the normal property path.
*/
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
if (!global->lookup(cx, id)) {
global->setConstructorPropertySlot(key, v);
uint32_t slot = GlobalObject::constructorPropertySlot(key);
if (!NativeObject::addProperty(cx, global, id, nullptr, nullptr, slot, attrs, 0))
return false;
named = true;
return true;
}
}
named = DefineProperty(cx, obj, id, v, nullptr, nullptr, attrs);
return named;
}

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

@ -711,6 +711,7 @@ js::XDRScript(XDRState<mode>* xdr, HandleScope scriptEnclosingScope, HandleScrip
return false;
break;
case ScopeKind::Lexical:
case ScopeKind::SimpleCatch:
case ScopeKind::Catch:
case ScopeKind::NamedLambda:
case ScopeKind::StrictNamedLambda:

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

@ -0,0 +1,26 @@
// Tests by André Bargull <andrebargull@googlemail.com>
// Annex B.3.3.1
function f1() {
{ function* g() {} }
assertEq(typeof g, "undefined");
}
f1();
// Annex B.3.3.2
{ function* g() {} }
assertEq(typeof g, "undefined");
// Annex B.3.3.3
function f2() {
eval("{ function* g() {} }");
assertEq(typeof g, "undefined");
}
f2();
// Annex B.3.3.3
eval("{ function* g() {} }");
assertEq(typeof g, "undefined");
if (typeof reportCompare === "function")
reportCompare(true, true);

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

@ -0,0 +1,19 @@
function f() {
var probeParam, probeBlock;
let x = 'outside';
try {
throw [];
} catch ([_ = probeParam = function() { return x; }]) {
probeBlock = function() { return x; };
let x = 'inside';
}
assertEq(probeBlock(), 'inside');
assertEq(probeParam(), 'outside');
}
f();
if (typeof reportCompare === 'function')
reportCompare(true, true);

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

@ -0,0 +1,10 @@
// |reftest| skip-if(!xulRuntime.shell)
assertThrowsInstanceOf(() => evaluate(`try { throw {} } catch ({e}) { var e; }`), SyntaxError);
assertThrowsInstanceOf(() => evaluate(`try { throw {} } catch ({e}) { eval('var e'); }`), SyntaxError);
assertThrowsInstanceOf(() => new Function(`try { throw {} } catch ({e}) { var e; }`), SyntaxError);
assertThrowsInstanceOf(new Function(`try { throw {} } catch ({e}) { eval('var e'); }`), SyntaxError);
if (typeof reportCompare === "function")
reportCompare(true, true);

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

@ -0,0 +1,12 @@
// |reftest| skip-if(!xulRuntime.shell)
assertThrowsInstanceOf(() => evaluate(`
try { throw null; } catch (e) { eval("for (var e of []) {}") }
`), SyntaxError);
assertThrowsInstanceOf(new Function(`
try { throw null; } catch (e) { eval("for (var e of []) {}") }
`), SyntaxError);
if (typeof reportCompare === "function")
reportCompare(true, true);

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

@ -551,14 +551,14 @@ class js::WasmArrayRawBuffer
# ifdef XP_WIN
if (!VirtualAlloc(dataPointer(), newMapped, MEM_RESERVE, PAGE_NOACCESS))
return;
# elif defined(XP_DARWIN)
// No mechanism for remapping on MaxOS. Luckily shouldn't need it here
// as most MacOS configs are 64 bit
return;
#else // Unix
# elif defined(XP_LINUX)
// Note this will not move memory (no MREMAP_MAYMOVE specified)
if (MAP_FAILED == mremap(dataPointer(), mappedSize_, newMapped, 0))
return;
# else
// No mechanism for remapping on MaxOS. Luckily shouldn't need it here
// as most MacOS configs are 64 bit
return;
# endif // !XP_WIN
mappedSize_ = newMapped;

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

@ -101,4 +101,18 @@ js::DebuggerObject::owner() const
return Debugger::fromJSObject(dbgobj);
}
inline js::PromiseObject*
js::DebuggerObject::promise() const
{
MOZ_ASSERT(isPromise());
JSObject* referent = this->referent();
if (IsCrossCompartmentWrapper(referent)) {
referent = CheckedUnwrap(referent);
MOZ_ASSERT(referent);
}
return &referent->as<PromiseObject>();
}
#endif /* vm_Debugger_inl_h */

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

@ -20,7 +20,6 @@
#include "jswrapper.h"
#include "asmjs/WasmInstance.h"
#include "builtin/Promise.h"
#include "frontend/BytecodeCompiler.h"
#include "frontend/Parser.h"
#include "gc/Marking.h"
@ -750,7 +749,7 @@ Debugger::getScriptFrameWithIter(JSContext* cx, AbstractFramePtr referent,
RootedNativeObject debugger(cx, object);
RootedDebuggerFrame frame(cx, DebuggerFrame::create(cx, proto, referent, maybeIter,
debugger));
debugger));
if (!frame)
return false;
@ -6189,11 +6188,13 @@ Debugger::replaceFrameGuts(JSContext* cx, AbstractFramePtr from, AbstractFramePt
{
auto removeFromDebuggerFramesOnExit = MakeScopeExit([&] {
// Remove any remaining old entries on exit, as the 'from' frame will
// be gone. On success, the range will be empty.
Debugger::forEachDebuggerFrame(from, [&](NativeObject* frameobj) {
frameobj->setPrivate(nullptr);
Debugger::fromChildJSObject(frameobj)->frames.remove(from);
});
// be gone. This is only done in the failure case. On failure, the
// removeToDebuggerFramesOnExit lambda below will rollback any frames
// that were replaced, resulting in !frameMaps(to). On success, the
// range will be empty, as all from Frame.Debugger instances will have
// been removed.
MOZ_ASSERT_IF(inFrameMaps(to), !inFrameMaps(from));
removeFromFrameMapsAndClearBreakpointsIn(cx, from);
// Rekey missingScopes to maintain Debugger.Environment identity and
// forward liveScopes to point to the new frame.
@ -6202,8 +6203,13 @@ Debugger::replaceFrameGuts(JSContext* cx, AbstractFramePtr from, AbstractFramePt
// Forward live Debugger.Frame objects.
Rooted<DebuggerFrameVector> frames(cx, DebuggerFrameVector(cx));
if (!getDebuggerFrames(from, &frames))
if (!getDebuggerFrames(from, &frames)) {
// An OOM here means that all Debuggers' frame maps still contain
// entries for 'from' and no entries for 'to'. Since the 'from' frame
// will be gone, they are removed by removeFromDebuggerFramesOnExit
// above.
return false;
}
// If during the loop below we hit an OOM, we must also rollback any of
// the frames that were successfully replaced. For OSR frames, OOM here
@ -6220,8 +6226,18 @@ Debugger::replaceFrameGuts(JSContext* cx, AbstractFramePtr from, AbstractFramePt
// Update frame object's ScriptFrameIter::data pointer.
DebuggerFrame_freeScriptFrameIterData(cx->runtime()->defaultFreeOp(), frameobj);
ScriptFrameIter::Data* data = iter.copyData();
if (!data)
if (!data) {
// An OOM here means that some Debuggers' frame maps may still
// contain entries for 'from' and some Debuggers' frame maps may
// also contain entries for 'to'. Thus both
// removeFromDebuggerFramesOnExit and
// removeToDebuggerFramesOnExit must both run.
//
// The current frameobj in question is still in its Debugger's
// frame map keyed by 'from', so it will be covered by
// removeFromDebuggerFramesOnExit.
return false;
}
frameobj->setPrivate(data);
// Remove old frame.
@ -6229,6 +6245,17 @@ Debugger::replaceFrameGuts(JSContext* cx, AbstractFramePtr from, AbstractFramePt
// Add the frame object with |to| as key.
if (!dbg->frames.putNew(to, frameobj)) {
// This OOM is subtle. At this point, both
// removeFromDebuggerFramesOnExit and removeToDebuggerFramesOnExit
// must both run for the same reason given above.
//
// The difference is that the current frameobj is no longer in its
// Debugger's frame map, so it will not be cleaned up by neither
// lambda. Manually clean it up here.
FreeOp* fop = cx->runtime()->defaultFreeOp();
DebuggerFrame_freeScriptFrameIterData(fop, frameobj);
DebuggerFrame_maybeDecrementFrameScriptStepModeCount(fop, to, frameobj);
ReportOutOfMemory(cx);
return false;
}
@ -8602,21 +8629,20 @@ DebuggerObject::isPromiseGetter(JSContext* cx, unsigned argc, Value* vp)
{
THIS_DEBUGOBJECT(cx, argc, vp, "get isPromise", args, object)
bool result;
if (!DebuggerObject::getIsPromise(cx, object, result))
return false;
args.rval().setBoolean(result);
args.rval().setBoolean(object->isPromise());
return true;
}
/* static */ bool
DebuggerObject::promiseStateGetter(JSContext* cx, unsigned argc, Value* vp)
{
THIS_DEBUGOBJECT_PROMISE(cx, argc, vp, "get promiseState", args, refobj);
THIS_DEBUGOBJECT(cx, argc, vp, "get promiseState", args, object);
if (!DebuggerObject::requirePromise(cx, object))
return false;
RootedValue result(cx);
switch (promise->state()) {
switch (object->promiseState()) {
case JS::PromiseState::Pending:
result.setString(cx->names().pending);
break;
@ -8635,37 +8661,33 @@ DebuggerObject::promiseStateGetter(JSContext* cx, unsigned argc, Value* vp)
/* static */ bool
DebuggerObject::promiseValueGetter(JSContext* cx, unsigned argc, Value* vp)
{
THIS_DEBUGOBJECT_OWNER_PROMISE(cx, argc, vp, "get promiseValue", args, dbg, refobj);
THIS_DEBUGOBJECT(cx, argc, vp, "get promiseValue", args, object);
if (promise->state() != JS::PromiseState::Fulfilled) {
if (!DebuggerObject::requirePromise(cx, object))
return false;
if (object->promiseState() != JS::PromiseState::Fulfilled) {
args.rval().setUndefined();
return true;
}
RootedValue result(cx, promise->value());
if (!dbg->wrapDebuggeeValue(cx, &result))
return false;
args.rval().set(result);
return true;
return DebuggerObject::getPromiseValue(cx, object, args.rval());;
}
/* static */ bool
DebuggerObject::promiseReasonGetter(JSContext* cx, unsigned argc, Value* vp)
{
THIS_DEBUGOBJECT_OWNER_PROMISE(cx, argc, vp, "get promiseReason", args, dbg, refobj);
THIS_DEBUGOBJECT(cx, argc, vp, "get promiseReason", args, object);
if (promise->state() != JS::PromiseState::Rejected) {
if (!DebuggerObject::requirePromise(cx, object))
return false;
if (object->promiseState() != JS::PromiseState::Rejected) {
args.rval().setUndefined();
return true;
}
RootedValue result(cx, promise->reason());
if (!dbg->wrapDebuggeeValue(cx, &result))
return false;
args.rval().set(result);
return true;
return DebuggerObject::getPromiseReason(cx, object, args.rval());;
}
/* static */ bool
@ -9325,22 +9347,18 @@ DebuggerObject::isScriptedProxy() const
}
#ifdef SPIDERMONKEY_PROMISE
/* static */ bool
DebuggerObject::getIsPromise(JSContext* cx, HandleDebuggerObject object,
bool& result)
bool
DebuggerObject::isPromise() const
{
JSObject* referent = object->referent();
JSObject* referent = this->referent();
if (IsCrossCompartmentWrapper(referent)) {
referent = CheckedUnwrap(referent);
if (!referent) {
JS_ReportError(cx, "Permission denied to access object");
if (!referent)
return false;
}
}
}
result = referent->is<PromiseObject>();
return true;
return referent->is<PromiseObject>();
}
#endif // SPIDERMONKEY_PROMISE
@ -9391,6 +9409,12 @@ DebuggerObject::displayName() const
return referent()->as<JSFunction>().displayAtom();
}
JS::PromiseState
DebuggerObject::promiseState() const
{
return promise()->state();
}
/* static */ bool
DebuggerObject::getParameterNames(JSContext* cx, HandleDebuggerObject object,
MutableHandle<StringVector> result)
@ -9530,6 +9554,28 @@ DebuggerObject::getErrorMessageName(JSContext* cx, HandleDebuggerObject object,
return true;
}
#ifdef SPIDERMONKEY_PROMISE
/* static */ bool
DebuggerObject::getPromiseValue(JSContext* cx, HandleDebuggerObject object,
MutableHandleValue result)
{
MOZ_ASSERT(object->promiseState() == JS::PromiseState::Fulfilled);
result.set(object->promise()->value());
return object->owner()->wrapDebuggeeValue(cx, result);
}
/* static */ bool
DebuggerObject::getPromiseReason(JSContext* cx, HandleDebuggerObject object,
MutableHandleValue result)
{
MOZ_ASSERT(object->promiseState() == JS::PromiseState::Rejected);
result.set(object->promise()->reason());
return object->owner()->wrapDebuggeeValue(cx, result);
}
#endif // SPIDERMONKEY_PROMISE
/* static */ bool
DebuggerObject::isExtensible(JSContext* cx, HandleDebuggerObject object, bool& result)
{
@ -9999,6 +10045,30 @@ DebuggerObject::requireGlobal(JSContext* cx, HandleDebuggerObject object)
return true;
}
#ifdef SPIDERMONKEY_PROMISE
/* static */ bool
DebuggerObject::requirePromise(JSContext* cx, HandleDebuggerObject object)
{
RootedObject referent(cx, object->referent());
if (IsCrossCompartmentWrapper(referent)) {
referent = CheckedUnwrap(referent);
if (!referent) {
JS_ReportError(cx, "Permission denied to access object");
return false;
}
}
if (!referent->is<PromiseObject>()) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
"Debugger", "Promise", object->getClass()->name);
return false;
}
return true;
}
#endif // SPIDERMONKEY_PROMISE
/* static */ bool
DebuggerObject::getScriptedProxyTarget(JSContext* cx, HandleDebuggerObject object,
MutableHandleDebuggerObject result)

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

@ -19,6 +19,7 @@
#include "jswrapper.h"
#include "asmjs/WasmJS.h"
#include "builtin/Promise.h"
#include "ds/TraceableFifo.h"
#include "gc/Barrier.h"
#include "js/Debug.h"
@ -1257,8 +1258,10 @@ class DebuggerObject : public NativeObject
static MOZ_MUST_USE bool getScriptedProxyHandler(JSContext* cx, HandleDebuggerObject object,
MutableHandleDebuggerObject result);
#ifdef SPIDERMONKEY_PROMISE
static MOZ_MUST_USE bool getIsPromise(JSContext* cx, HandleDebuggerObject object,
bool& result);
static MOZ_MUST_USE bool getPromiseValue(JSContext* cx, HandleDebuggerObject object,
MutableHandleValue result);
static MOZ_MUST_USE bool getPromiseReason(JSContext* cx, HandleDebuggerObject object,
MutableHandleValue result);
#endif // SPIDERMONKEY_PROMISE
// Methods
@ -1309,8 +1312,14 @@ class DebuggerObject : public NativeObject
bool isArrowFunction() const;
bool isGlobal() const;
bool isScriptedProxy() const;
#ifdef SPIDERMONKEY_PROMISE
bool isPromise() const;
#endif // SPIDERMONKEY_PROMISE
JSAtom* name() const;
JSAtom* displayName() const;
#ifdef SPIDERMONKEY_PROMISE
JS::PromiseState promiseState() const;
#endif // SPIDERMONKEY_PROMISE
private:
enum {
@ -1335,8 +1344,15 @@ class DebuggerObject : public NativeObject
Debugger* owner() const;
#ifdef SPIDERMONKEY_PROMISE
PromiseObject* promise() const;
#endif // SPIDERMONKEY_PROMISE
static DebuggerObject* checkThis(JSContext* cx, const CallArgs& args, const char* fnname);
static MOZ_MUST_USE bool requireGlobal(JSContext* cx, HandleDebuggerObject object);
#ifdef SPIDERMONKEY_PROMISE
static MOZ_MUST_USE bool requirePromise(JSContext* cx, HandleDebuggerObject object);
#endif // SPIDERMONKEY_PROMISE
static MOZ_MUST_USE bool construct(JSContext* cx, unsigned argc, Value* vp);

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

@ -3229,9 +3229,11 @@ CheckVarNameConflictsInEnv(JSContext* cx, HandleScript script, HandleObject obj)
return true;
}
if (env->isSyntactic() && !env->isGlobal() && env->scope().kind() == ScopeKind::Catch) {
// Annex B.3.5 says 'var' declarations with the same name as catch
// parameters are allowed.
if (env->isSyntactic() && !env->isGlobal() && env->scope().kind() == ScopeKind::SimpleCatch) {
// Annex B.3.5 allows redeclaring simple (non-destructured) catch
// parameters with var declarations, except when it appears in a
// for-of. The for-of allowance is computed in
// Parser::isVarRedeclaredInEval.
return true;
}
@ -3249,8 +3251,6 @@ bool
js::CheckEvalDeclarationConflicts(JSContext* cx, HandleScript script,
HandleObject scopeChain, HandleObject varObj)
{
// We don't need to check body-level lexical bindings for conflict. Eval
// scripts always execute under their own lexical scope.
if (!script->bodyScope()->as<EvalScope>().hasBindings())
return true;

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

@ -220,12 +220,12 @@ GlobalObject::resolveConstructor(JSContext* cx, Handle<GlobalObject*> global, JS
RootedId id(cx, NameToId(ClassName(key, cx)));
if (isObjectOrFunction) {
if (clasp->specShouldDefineConstructor()) {
if (!global->addDataProperty(cx, id, constructorPropertySlot(key), 0))
RootedValue ctorValue(cx, ObjectValue(*ctor));
if (!DefineProperty(cx, global, id, ctorValue, nullptr, nullptr, JSPROP_RESOLVING))
return false;
}
global->setConstructor(key, ObjectValue(*ctor));
global->setConstructorPropertySlot(key, ObjectValue(*ctor));
}
// Define any specified functions and properties, unless we're a dependent
@ -267,23 +267,17 @@ GlobalObject::resolveConstructor(JSContext* cx, Handle<GlobalObject*> global, JS
// Fallible operation that modifies the global object.
if (clasp->specShouldDefineConstructor()) {
if (!global->addDataProperty(cx, id, constructorPropertySlot(key), 0))
RootedValue ctorValue(cx, ObjectValue(*ctor));
if (!DefineProperty(cx, global, id, ctorValue, nullptr, nullptr, JSPROP_RESOLVING))
return false;
}
// Infallible operations that modify the global object.
global->setConstructor(key, ObjectValue(*ctor));
global->setConstructorPropertySlot(key, ObjectValue(*ctor));
if (proto)
global->setPrototype(key, ObjectValue(*proto));
}
if (clasp->specShouldDefineConstructor()) {
// Stash type information, so that what we do here is equivalent to
// initBuiltinConstructor.
AddTypePropertyId(cx, global, id, ObjectValue(*ctor));
}
return true;
}
@ -299,14 +293,12 @@ GlobalObject::initBuiltinConstructor(JSContext* cx, Handle<GlobalObject*> global
RootedId id(cx, NameToId(ClassName(key, cx)));
MOZ_ASSERT(!global->lookup(cx, id));
if (!global->addDataProperty(cx, id, constructorPropertySlot(key), 0))
RootedValue ctorValue(cx, ObjectValue(*ctor));
if (!DefineProperty(cx, global, id, ctorValue, nullptr, nullptr, JSPROP_RESOLVING))
return false;
global->setConstructor(key, ObjectValue(*ctor));
global->setPrototype(key, ObjectValue(*proto));
global->setConstructorPropertySlot(key, ObjectValue(*ctor));
AddTypePropertyId(cx, global, id, ObjectValue(*ctor));
return true;
}

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

@ -46,22 +46,18 @@ enum class SimdType;
* [APPLICATION_SLOTS + JSProto_LIMIT, APPLICATION_SLOTS + 2 * JSProto_LIMIT)
* Stores the prototype, if any, for the constructor for the corresponding
* JSProtoKey offset from JSProto_LIMIT.
* [APPLICATION_SLOTS + 2 * JSProto_LIMIT, APPLICATION_SLOTS + 3 * JSProto_LIMIT)
* Stores the current value of the global property named for the JSProtoKey
* for the corresponding JSProtoKey offset from 2 * JSProto_LIMIT.
* [APPLICATION_SLOTS + 3 * JSProto_LIMIT, RESERVED_SLOTS)
* [APPLICATION_SLOTS + 2 * JSProto_LIMIT, RESERVED_SLOTS)
* Various one-off values: ES5 13.2.3's [[ThrowTypeError]], RegExp statics,
* the original eval for this global object (implementing |var eval =
* otherWindow.eval; eval(...)| as an indirect eval), a bit indicating
* whether this object has been cleared (see JS_ClearScope), and a cache for
* whether eval is allowed (per the global's Content Security Policy).
*
* The first two JSProto_LIMIT-sized ranges are necessary to implement
* The two JSProto_LIMIT-sized ranges are necessary to implement
* js::FindClassObject, and spec language speaking in terms of "the original
* Array prototype object", or "as if by the expression new Array()" referring
* to the original Array constructor. The third range stores the (writable and
* even deletable) Object, Array, &c. properties (although a slot won't be used
* again if its property is deleted and readded).
* to the original Array constructor. The actual (writable and even deletable)
* Object, Array, &c. properties are not stored in reserved slots.
*/
class GlobalObject : public NativeObject
{
@ -69,10 +65,10 @@ class GlobalObject : public NativeObject
static const unsigned APPLICATION_SLOTS = JSCLASS_GLOBAL_APPLICATION_SLOTS;
/*
* Count of slots to store built-in constructors, prototypes, and initial
* visible properties for the constructors.
* Count of slots to store built-in prototypes and initial visible
* properties for the constructors.
*/
static const unsigned STANDARD_CLASS_SLOTS = JSProto_LIMIT * 3;
static const unsigned STANDARD_CLASS_SLOTS = JSProto_LIMIT * 2;
enum : unsigned {
/* Various function values needed by the engine. */
@ -184,19 +180,6 @@ class GlobalObject : public NativeObject
setSlot(APPLICATION_SLOTS + JSProto_LIMIT + key, value);
}
static uint32_t constructorPropertySlot(JSProtoKey key) {
MOZ_ASSERT(key <= JSProto_LIMIT);
return APPLICATION_SLOTS + JSProto_LIMIT * 2 + key;
}
Value getConstructorPropertySlot(JSProtoKey key) {
return getSlot(constructorPropertySlot(key));
}
void setConstructorPropertySlot(JSProtoKey key, const Value& ctor) {
setSlot(constructorPropertySlot(key), ctor);
}
bool classIsInitialized(JSProtoKey key) const {
bool inited = !getConstructor(key).isUndefined();
MOZ_ASSERT(inited == !getPrototype(key).isUndefined());

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

@ -984,7 +984,10 @@ PopEnvironment(JSContext* cx, EnvironmentIter& ei)
{
switch (ei.scope().kind()) {
case ScopeKind::Lexical:
case ScopeKind::SimpleCatch:
case ScopeKind::Catch:
case ScopeKind::NamedLambda:
case ScopeKind::StrictNamedLambda:
if (MOZ_UNLIKELY(cx->compartment()->isDebuggee()))
DebugEnvironments::onPopLexical(cx, ei);
if (ei.scope().hasEnvironment())
@ -1010,8 +1013,6 @@ PopEnvironment(JSContext* cx, EnvironmentIter& ei)
ei.initialFrame().popOffEnvironmentChain<VarEnvironmentObject>();
break;
case ScopeKind::Eval:
case ScopeKind::NamedLambda:
case ScopeKind::StrictNamedLambda:
case ScopeKind::Global:
case ScopeKind::NonSyntactic:
case ScopeKind::Module:

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

@ -56,6 +56,7 @@ js::ScopeKindString(ScopeKind kind)
return "parameter expression var";
case ScopeKind::Lexical:
return "lexical";
case ScopeKind::SimpleCatch:
case ScopeKind::Catch:
return "catch";
case ScopeKind::NamedLambda:
@ -274,6 +275,23 @@ Scope::create(ExclusiveContext* cx, ScopeKind kind, HandleScope enclosing, Handl
return scope;
}
template <typename T, typename D>
/* static */ Scope*
Scope::create(ExclusiveContext* cx, ScopeKind kind, HandleScope enclosing,
HandleShape envShape, mozilla::UniquePtr<T, D> data)
{
Scope* scope = create(cx, kind, enclosing, envShape);
if (!scope)
return nullptr;
// It is an invariant that all Scopes that have data (currently, all
// ScopeKinds except With) must have non-null data.
MOZ_ASSERT(data);
scope->initData(Move(data));
return scope;
}
uint32_t
Scope::chainLength() const
{
@ -318,10 +336,6 @@ Scope::clone(JSContext* cx, HandleScope scope, HandleScope enclosing)
return nullptr;
}
Scope* scopeClone = create(cx, scope->kind_, enclosing, envShape);
if (!scopeClone)
return nullptr;
switch (scope->kind_) {
case ScopeKind::Function:
MOZ_CRASH("Use FunctionScope::clone.");
@ -333,11 +347,11 @@ Scope::clone(JSContext* cx, HandleScope scope, HandleScope enclosing)
UniquePtr<VarScope::Data> dataClone = CopyScopeData<VarScope>(cx, original);
if (!dataClone)
return nullptr;
scopeClone->initData(Move(dataClone));
break;
return create(cx, scope->kind_, enclosing, envShape, Move(dataClone));
}
case ScopeKind::Lexical:
case ScopeKind::SimpleCatch:
case ScopeKind::Catch:
case ScopeKind::NamedLambda:
case ScopeKind::StrictNamedLambda: {
@ -345,12 +359,11 @@ Scope::clone(JSContext* cx, HandleScope scope, HandleScope enclosing)
UniquePtr<LexicalScope::Data> dataClone = CopyScopeData<LexicalScope>(cx, original);
if (!dataClone)
return nullptr;
scopeClone->initData(Move(dataClone));
break;
return create(cx, scope->kind_, enclosing, envShape, Move(dataClone));
}
case ScopeKind::With:
break;
return create(cx, scope->kind_, enclosing, envShape);
case ScopeKind::Eval:
case ScopeKind::StrictEval: {
@ -358,8 +371,7 @@ Scope::clone(JSContext* cx, HandleScope scope, HandleScope enclosing)
UniquePtr<EvalScope::Data> dataClone = CopyScopeData<EvalScope>(cx, original);
if (!dataClone)
return nullptr;
scopeClone->initData(Move(dataClone));
break;
return create(cx, scope->kind_, enclosing, envShape, Move(dataClone));
}
case ScopeKind::Global:
@ -372,7 +384,7 @@ Scope::clone(JSContext* cx, HandleScope scope, HandleScope enclosing)
break;
}
return scopeClone;
return nullptr;
}
void
@ -408,6 +420,7 @@ LexicalScope::firstFrameSlot() const
{
switch (kind()) {
case ScopeKind::Lexical:
case ScopeKind::SimpleCatch:
case ScopeKind::Catch:
// For intra-frame scopes, find the enclosing scope's next frame slot.
return nextFrameSlot(enclosing());
@ -433,6 +446,7 @@ LexicalScope::nextFrameSlot(Scope* scope)
case ScopeKind::ParameterExpressionVar:
return si.scope()->as<VarScope>().nextFrameSlot();
case ScopeKind::Lexical:
case ScopeKind::SimpleCatch:
case ScopeKind::Catch:
return si.scope()->as<LexicalScope>().nextFrameSlot();
case ScopeKind::NamedLambda:
@ -477,15 +491,11 @@ LexicalScope::create(ExclusiveContext* cx, ScopeKind kind, Handle<Data*> data,
if (!copy)
return nullptr;
Scope* scope = Scope::create(cx, kind, enclosing, envShape);
Scope* scope = Scope::create(cx, kind, enclosing, envShape, Move(copy.get()));
if (!scope)
return nullptr;
MOZ_ASSERT(scope->as<LexicalScope>().firstFrameSlot() == firstFrameSlot);
LexicalScope* lexicalScope = &scope->as<LexicalScope>();
lexicalScope->initData(Move(copy.get()));
return lexicalScope;
return &scope->as<LexicalScope>();
}
/* static */ Shape*
@ -774,13 +784,10 @@ VarScope::create(ExclusiveContext* cx, ScopeKind kind, Handle<Data*> data,
return nullptr;
}
Scope* scope = Scope::create(cx, kind, enclosing, envShape);
Scope* scope = Scope::create(cx, kind, enclosing, envShape, Move(copy.get()));
if (!scope)
return nullptr;
VarScope* varScope = &scope->as<VarScope>();
varScope->initData(Move(copy.get()));
return varScope;
return &scope->as<VarScope>();
}
/* static */ Shape*
@ -880,13 +887,10 @@ GlobalScope::create(ExclusiveContext* cx, ScopeKind kind, Handle<Data*> data)
if (!copy)
return nullptr;
Scope* scope = Scope::create(cx, kind, nullptr, nullptr);
Scope* scope = Scope::create(cx, kind, nullptr, nullptr, Move(copy.get()));
if (!scope)
return nullptr;
GlobalScope* globalScope = &scope->as<GlobalScope>();
globalScope->initData(Move(copy.get()));
return globalScope;
return &scope->as<GlobalScope>();
}
/* static */ GlobalScope*
@ -897,13 +901,10 @@ GlobalScope::clone(JSContext* cx, Handle<GlobalScope*> scope, ScopeKind kind)
if (!dataClone)
return nullptr;
Scope* scopeClone = Scope::create(cx, kind, nullptr, nullptr);
Scope* scopeClone = Scope::create(cx, kind, nullptr, nullptr, Move(dataClone.get()));
if (!scopeClone)
return nullptr;
GlobalScope* globalScopeClone = &scopeClone->as<GlobalScope>();
globalScopeClone->initData(Move(dataClone.get()));
return globalScopeClone;
return &scopeClone->as<GlobalScope>();
}
template <XDRMode mode>
@ -998,13 +999,10 @@ EvalScope::create(ExclusiveContext* cx, ScopeKind scopeKind, Handle<Data*> data,
return nullptr;
}
Scope* scope = Scope::create(cx, scopeKind, enclosing, envShape);
Scope* scope = Scope::create(cx, scopeKind, enclosing, envShape, Move(copy.get()));
if (!scope)
return nullptr;
EvalScope* evalScope = &scope->as<EvalScope>();
evalScope->initData(Move(copy.get()));
return evalScope;
return &scope->as<EvalScope>();
}
/* static */ Scope*
@ -1155,6 +1153,7 @@ BindingIter::BindingIter(Scope* scope)
{
switch (scope->kind()) {
case ScopeKind::Lexical:
case ScopeKind::SimpleCatch:
case ScopeKind::Catch:
init(scope->as<LexicalScope>().data(),
scope->as<LexicalScope>().firstFrameSlot(), 0);

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

@ -53,6 +53,7 @@ enum class ScopeKind : uint8_t
// LexicalScope
Lexical,
SimpleCatch,
Catch,
NamedLambda,
StrictNamedLambda,
@ -72,6 +73,12 @@ enum class ScopeKind : uint8_t
Module
};
static inline bool
ScopeKindIsCatch(ScopeKind kind)
{
return kind == ScopeKind::SimpleCatch || kind == ScopeKind::Catch;
}
const char* BindingKindString(BindingKind kind);
const char* ScopeKindString(ScopeKind kind);
@ -205,6 +212,10 @@ class Scope : public js::gc::TenuredCell
static Scope* create(ExclusiveContext* cx, ScopeKind kind, HandleScope enclosing,
HandleShape envShape);
template <typename T, typename D>
static Scope* create(ExclusiveContext* cx, ScopeKind kind, HandleScope enclosing,
HandleShape envShape, mozilla::UniquePtr<T, D> data);
template <typename ConcreteScope, XDRMode mode>
static bool XDRSizedBindingNames(XDRState<mode>* xdr, Handle<ConcreteScope*> scope,
MutableHandle<typename ConcreteScope::Data*> data);
@ -298,6 +309,9 @@ class Scope : public js::gc::TenuredCell
// Lexical
// A plain lexical scope.
//
// SimpleCatch
// Holds the single catch parameter of a catch block.
//
// Catch
// Holds the catch parameters (and only the catch parameters) of a catch
// block.
@ -376,6 +390,7 @@ inline bool
Scope::is<LexicalScope>() const
{
return kind_ == ScopeKind::Lexical ||
kind_ == ScopeKind::SimpleCatch ||
kind_ == ScopeKind::Catch ||
kind_ == ScopeKind::NamedLambda ||
kind_ == ScopeKind::StrictNamedLambda;

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

@ -125,6 +125,7 @@ AssertScopeMatchesEnvironment(Scope* scope, JSObject* originalEnv)
break;
case ScopeKind::Lexical:
case ScopeKind::SimpleCatch:
case ScopeKind::Catch:
case ScopeKind::NamedLambda:
case ScopeKind::StrictNamedLambda:

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

@ -280,17 +280,21 @@ ServoRestyleManager::ProcessPendingRestyles()
{
MOZ_ASSERT(PresContext()->Document(), "No document? Pshaw!");
MOZ_ASSERT(!nsContentUtils::IsSafeToRunScript(), "Missing a script blocker!");
if (MOZ_UNLIKELY(!PresContext()->PresShell()->DidInitialize())) {
// PresShell::FlushPendingNotifications doesn't early-return in the case
// where the PreShell hasn't yet been initialized (and therefore we haven't
// yet done the initial style traversal of the DOM tree). We should arguably
// fix up the callers and assert against this case, but we just detect and
// handle it for now.
return;
}
if (!HasPendingRestyles()) {
return;
}
ServoStyleSet* styleSet = StyleSet();
if (!styleSet->StylingStarted()) {
// If something caused us to restyle, and we haven't started styling yet,
// do nothing. Everything is dirty, and we'll style it all later.
return;
}
nsIDocument* doc = PresContext()->Document();
Element* root = doc->GetRootElement();
if (root) {
@ -331,7 +335,7 @@ ServoRestyleManager::ProcessPendingRestyles()
}
MOZ_ASSERT(!doc->IsDirtyForServo());
MOZ_ASSERT(!doc->HasDirtyDescendantsForServo());
doc->UnsetHasDirtyDescendantsForServo();
mModifiedElements.Clear();
@ -354,6 +358,20 @@ ServoRestyleManager::RestyleForInsertOrChange(nsINode* aContainer,
void
ServoRestyleManager::ContentInserted(nsINode* aContainer, nsIContent* aChild)
{
if (aContainer == aContainer->OwnerDoc()) {
// If we're getting this notification for the insertion of a root element,
// that means either:
// (a) We initialized the PresShell before the root element existed, or
// (b) The root element was removed and it or another root is being
// inserted.
//
// Either way the whole tree is dirty, so we should style the document.
MOZ_ASSERT(aChild == aChild->OwnerDoc()->GetRootElement());
MOZ_ASSERT(aChild->IsDirtyForServo());
StyleSet()->StyleDocument(/* aLeaveDirtyBits = */ false);
return;
}
if (!aContainer->ServoData().get()) {
// This can happen with display:none. Bug 1297249 tracks more investigation
// and assertions here.

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

@ -233,7 +233,7 @@ TouchManager::PreHandleEvent(WidgetEvent* aEvent,
}
nsCOMPtr<EventTarget> targetPtr = info.mTouch->mTarget;
nsCOMPtr<nsINode> targetNode(do_QueryInterface(targetPtr));
if (!targetNode->IsInComposedDoc()) {
if (targetNode && !targetNode->IsInComposedDoc()) {
targetPtr = do_QueryInterface(info.mNonAnonymousTarget);
}

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

@ -2502,8 +2502,9 @@ nsPresContext::HasCachedStyleData()
nsStyleSet* styleSet = mShell->StyleSet()->GetAsGecko();
if (!styleSet) {
// XXXheycam ServoStyleSets do not use the rule tree, so just assume for now
// that we need to restyle when e.g. dppx changes.
return true;
// that we need to restyle when e.g. dppx changes assuming we're sufficiently
// bootstrapped.
return mShell->DidInitialize();
}
return styleSet->HasCachedStyleData();

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

@ -1682,8 +1682,15 @@ PresShell::Initialize(nscoord aWidth, nscoord aHeight)
mPresContext->SetVisibleArea(nsRect(0, 0, aWidth, aHeight));
if (mStyleSet->IsServo()) {
mStyleSet->AsServo()->StartStyling(GetPresContext());
if (mStyleSet->IsServo() && mDocument->GetRootElement()) {
// If we have the root element already, go ahead style it along with any
// descendants.
//
// Some things, like nsDocumentViewer::GetPageMode, recreate the PresShell
// while keeping the content tree alive (see bug 1292280) - so we
// unconditionally mark the root as dirty.
mDocument->GetRootElement()->SetIsDirtyForServo();
mStyleSet->AsServo()->StyleDocument(/* aLeaveDirtyBits = */ false);
}
// Get the root frame from the frame manager

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

@ -58,11 +58,11 @@ function fireDrop(element) {
ds.startDragSession();
var event = document.createEvent("DragEvents");
var event = document.createEvent("DragEvent");
event.initDragEvent("dragover", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null, null);
fireEvent(element, event);
event = document.createEvent("DragEvents");
event = document.createEvent("DragEvent");
event.initDragEvent("drop", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null, null);
fireEvent(element, event);

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

@ -43,8 +43,8 @@ is(document.defaultView.getComputedStyle($("s"), null).getPropertyValue("margin-
$("s").setAttribute("type", "radio");
is(document.defaultView.getComputedStyle($("s"), null).getPropertyValue("margin-left"),
"10px",
"Only checkboxes should have indeterminate styles applied to them");
"30px",
"Setting an indeterminate element to type radio should give it indeterminate styles");
$("s").setAttribute("type", "checkbox");

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

@ -34,7 +34,7 @@ skip-if(!asyncPan) == position-fixed-inside-sticky-1.html position-fixed-inside-
fuzzy(1,60000) skip-if(!asyncPan) == group-opacity-surface-size-1.html group-opacity-surface-size-1-ref.html
skip-if(!asyncPan) == position-sticky-transformed.html position-sticky-transformed-ref.html
skip-if(!asyncPan) == offscreen-prerendered-active-opacity.html offscreen-prerendered-active-opacity-ref.html
fuzzy-if(Android,6,4) fuzzy-if(skiaContent,1,34) skip-if(!asyncPan) == offscreen-clipped-blendmode-1.html offscreen-clipped-blendmode-ref.html
fuzzy-if(Android,6,4) fuzzy-if(skiaContent&&!Android,1,34) skip-if(!asyncPan) == offscreen-clipped-blendmode-1.html offscreen-clipped-blendmode-ref.html
fuzzy-if(Android,6,4) skip-if(!asyncPan) == offscreen-clipped-blendmode-2.html offscreen-clipped-blendmode-ref.html
fuzzy-if(Android,6,4) skip == offscreen-clipped-blendmode-3.html offscreen-clipped-blendmode-ref.html # bug 1251588 - wrong AGR on mix-blend-mode item
fuzzy-if(Android,6,4) skip-if(!asyncPan) == offscreen-clipped-blendmode-4.html offscreen-clipped-blendmode-ref.html

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

@ -46,7 +46,7 @@ fuzzy-if(asyncPan&&!layersGPUAccelerated,121,514) == border-image-outset-move-1.
fuzzy(1,98) fuzzy-if(skiaContent,1,350) == border-image-linear-gradient-slice-1.html border-image-linear-gradient-slice-1-ref.html
fuzzy(1,149) fuzzy-if(OSX,1,10595) == border-image-linear-gradient-slice-2.html border-image-linear-gradient-slice-2-ref.html
fuzzy(1,433) fuzzy-if(skiaContent,1,2500) == border-image-linear-gradient-slice-fill-1.html border-image-linear-gradient-slice-fill-1-ref.html
fuzzy(1,177) fuzzy-if(OSX,1,25771) fuzzy-if(skiaContent,1,300) == border-image-linear-gradient-slice-fill-2.html border-image-linear-gradient-slice-fill-2-ref.html
fuzzy(1,177) fuzzy-if(OSX,1,25771) fuzzy-if(skiaContent,1,400) == border-image-linear-gradient-slice-fill-2.html border-image-linear-gradient-slice-fill-2-ref.html
fuzzy(1,48) fuzzy-if(OSX,5,1676) == border-image-linear-gradient-width.html border-image-linear-gradient-width-ref.html
fuzzy(1,5000) fuzzy-if(OSX,1,15000) == border-image-linear-gradient-slice-width.html border-image-linear-gradient-slice-width-ref.html
fuzzy(1,3000) fuzzy-if(OSX,1,6000) == border-image-linear-gradient-outset.html border-image-linear-gradient-outset-ref.html

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