зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to m-c. a=merge
This commit is contained in:
Коммит
3611a7607d
|
@ -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;
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче