From 9a87f6a0e586e2dce82a26cd6c6f57d7c0b6abe3 Mon Sep 17 00:00:00 2001
From: Tim Taubert
Date: Tue, 28 Apr 2015 09:13:16 +0200
Subject: [PATCH 001/151] Bug 1050175 - Add raw import/export for EC public
keys to the WebCrypto API r=rbarnes,smaug
---
dom/crypto/CryptoKey.cpp | 113 +++++++++++++++++-----
dom/crypto/CryptoKey.h | 7 ++
dom/crypto/WebCryptoTask.cpp | 47 ++++++++-
dom/crypto/test/test-vectors.js | 38 +++++++-
dom/crypto/test/test_WebCrypto_ECDH.html | 108 +++++++++++++++++++++
dom/crypto/test/test_WebCrypto_ECDSA.html | 34 +++++++
dom/webidl/SubtleCrypto.webidl | 4 +
7 files changed, 321 insertions(+), 30 deletions(-)
diff --git a/dom/crypto/CryptoKey.cpp b/dom/crypto/CryptoKey.cpp
index 0ac5bf56380c8..be87903d07660 100644
--- a/dom/crypto/CryptoKey.cpp
+++ b/dom/crypto/CryptoKey.cpp
@@ -951,6 +951,41 @@ CryptoKey::PrivateKeyToJwk(SECKEYPrivateKey* aPrivKey,
}
}
+SECKEYPublicKey*
+CreateECPublicKey(const SECItem* aKeyData, const nsString& aNamedCurve)
+{
+ ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
+ if (!arena) {
+ return nullptr;
+ }
+
+ SECKEYPublicKey* key = PORT_ArenaZNew(arena, SECKEYPublicKey);
+ if (!key) {
+ return nullptr;
+ }
+
+ key->keyType = ecKey;
+ key->pkcs11Slot = nullptr;
+ key->pkcs11ID = CK_INVALID_HANDLE;
+
+ // Create curve parameters.
+ SECItem* params = CreateECParamsForCurve(aNamedCurve, arena);
+ if (!params) {
+ return nullptr;
+ }
+ key->u.ec.DEREncodedParams = *params;
+
+ // Set public point.
+ key->u.ec.publicValue = *aKeyData;
+
+ // Ensure the given point is on the curve.
+ if (!CryptoKey::PublicKeyValid(key)) {
+ return nullptr;
+ }
+
+ return SECKEY_CopyPublicKey(key);
+}
+
SECKEYPublicKey*
CryptoKey::PublicKeyFromJwk(const JsonWebKey& aJwk,
const nsNSSShutDownPreventionLock& /*proofOfLock*/)
@@ -1002,39 +1037,18 @@ CryptoKey::PublicKeyFromJwk(const JsonWebKey& aJwk,
return nullptr;
}
- SECKEYPublicKey* key = PORT_ArenaZNew(arena, SECKEYPublicKey);
- if (!key) {
- return nullptr;
- }
-
- key->keyType = ecKey;
- key->pkcs11Slot = nullptr;
- key->pkcs11ID = CK_INVALID_HANDLE;
-
- nsString namedCurve;
- if (!NormalizeToken(aJwk.mCrv.Value(), namedCurve)) {
- return nullptr;
- }
-
- // Create parameters.
- SECItem* params = CreateECParamsForCurve(namedCurve, arena.get());
- if (!params) {
- return nullptr;
- }
- key->u.ec.DEREncodedParams = *params;
-
// Create point.
SECItem* point = CreateECPointForCoordinates(x, y, arena.get());
if (!point) {
return nullptr;
}
- key->u.ec.publicValue = *point;
- if (!PublicKeyValid(key)) {
+ nsString namedCurve;
+ if (!NormalizeToken(aJwk.mCrv.Value(), namedCurve)) {
return nullptr;
}
- return SECKEY_CopyPublicKey(key);
+ return CreateECPublicKey(point, namedCurve);
}
return nullptr;
@@ -1115,6 +1129,57 @@ CryptoKey::PublicDhKeyToRaw(SECKEYPublicKey* aPubKey,
return NS_OK;
}
+SECKEYPublicKey*
+CryptoKey::PublicECKeyFromRaw(CryptoBuffer& aKeyData,
+ const nsString& aNamedCurve,
+ const nsNSSShutDownPreventionLock& /*proofOfLock*/)
+{
+ ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
+ if (!arena) {
+ return nullptr;
+ }
+
+ SECItem rawItem = { siBuffer, nullptr, 0 };
+ if (!aKeyData.ToSECItem(arena, &rawItem)) {
+ return nullptr;
+ }
+
+ uint32_t flen;
+ if (aNamedCurve.EqualsLiteral(WEBCRYPTO_NAMED_CURVE_P256)) {
+ flen = 32; // bytes
+ } else if (aNamedCurve.EqualsLiteral(WEBCRYPTO_NAMED_CURVE_P384)) {
+ flen = 48; // bytes
+ } else if (aNamedCurve.EqualsLiteral(WEBCRYPTO_NAMED_CURVE_P521)) {
+ flen = 66; // bytes
+ } else {
+ return nullptr;
+ }
+
+ // Check length of uncompressed point coordinates. There are 2 field elements
+ // and a leading point form octet (which must EC_POINT_FORM_UNCOMPRESSED).
+ if (rawItem.len != (2 * flen + 1)) {
+ return nullptr;
+ }
+
+ // No support for compressed points.
+ if (rawItem.data[0] != EC_POINT_FORM_UNCOMPRESSED) {
+ return nullptr;
+ }
+
+ return CreateECPublicKey(&rawItem, aNamedCurve);
+}
+
+nsresult
+CryptoKey::PublicECKeyToRaw(SECKEYPublicKey* aPubKey,
+ CryptoBuffer& aRetVal,
+ const nsNSSShutDownPreventionLock& /*proofOfLock*/)
+{
+ if (!aRetVal.Assign(&aPubKey->u.ec.publicValue)) {
+ return NS_ERROR_DOM_OPERATION_ERR;
+ }
+ return NS_OK;
+}
+
bool
CryptoKey::PublicKeyValid(SECKEYPublicKey* aPubKey)
{
diff --git a/dom/crypto/CryptoKey.h b/dom/crypto/CryptoKey.h
index e0401edf1b240..e34edcdd4bd22 100644
--- a/dom/crypto/CryptoKey.h
+++ b/dom/crypto/CryptoKey.h
@@ -180,6 +180,13 @@ class CryptoKey final : public nsISupports,
CryptoBuffer& aRetVal,
const nsNSSShutDownPreventionLock& /*proofOfLock*/);
+ static SECKEYPublicKey* PublicECKeyFromRaw(CryptoBuffer& aKeyData,
+ const nsString& aNamedCurve,
+ const nsNSSShutDownPreventionLock& /*proofOfLock*/);
+ static nsresult PublicECKeyToRaw(SECKEYPublicKey* aPubKey,
+ CryptoBuffer& aRetVal,
+ const nsNSSShutDownPreventionLock& /*proofOfLock*/);
+
static bool PublicKeyValid(SECKEYPublicKey* aPubKey);
// Structured clone methods use these to clone keys
diff --git a/dom/crypto/WebCryptoTask.cpp b/dom/crypto/WebCryptoTask.cpp
index fd81d244af3fb..ac260f3b1836e 100644
--- a/dom/crypto/WebCryptoTask.cpp
+++ b/dom/crypto/WebCryptoTask.cpp
@@ -1644,7 +1644,7 @@ class ImportEcKeyTask : public ImportKeyTask
const ObjectOrString& aAlgorithm, bool aExtractable,
const Sequence& aKeyUsages)
{
- ImportKeyTask::Init(aCx, aFormat, aAlgorithm, aExtractable, aKeyUsages);
+ Init(aCx, aFormat, aAlgorithm, aExtractable, aKeyUsages);
}
ImportEcKeyTask(JSContext* aCx, const nsAString& aFormat,
@@ -1652,7 +1652,7 @@ class ImportEcKeyTask : public ImportKeyTask
const ObjectOrString& aAlgorithm, bool aExtractable,
const Sequence& aKeyUsages)
{
- ImportKeyTask::Init(aCx, aFormat, aAlgorithm, aExtractable, aKeyUsages);
+ Init(aCx, aFormat, aAlgorithm, aExtractable, aKeyUsages);
if (NS_FAILED(mEarlyRv)) {
return;
}
@@ -1661,6 +1661,30 @@ class ImportEcKeyTask : public ImportKeyTask
NS_ENSURE_SUCCESS_VOID(mEarlyRv);
}
+ void Init(JSContext* aCx, const nsAString& aFormat,
+ const ObjectOrString& aAlgorithm, bool aExtractable,
+ const Sequence& aKeyUsages)
+ {
+ ImportKeyTask::Init(aCx, aFormat, aAlgorithm, aExtractable, aKeyUsages);
+ if (NS_FAILED(mEarlyRv)) {
+ return;
+ }
+
+ if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_RAW)) {
+ RootedDictionary params(aCx);
+ mEarlyRv = Coerce(aCx, params, aAlgorithm);
+ if (NS_FAILED(mEarlyRv) || !params.mNamedCurve.WasPassed()) {
+ mEarlyRv = NS_ERROR_DOM_SYNTAX_ERR;
+ return;
+ }
+
+ if (!NormalizeToken(params.mNamedCurve.Value(), mNamedCurve)) {
+ mEarlyRv = NS_ERROR_DOM_NOT_SUPPORTED_ERR;
+ return;
+ }
+ }
+ }
+
private:
nsString mNamedCurve;
@@ -1680,14 +1704,19 @@ class ImportEcKeyTask : public ImportKeyTask
mKey->SetPrivateKey(privKey.get());
mKey->SetType(CryptoKey::PRIVATE);
- } else if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_SPKI) ||
+ } else if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_RAW) ||
+ mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_SPKI) ||
(mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_JWK) &&
!mJwk.mD.WasPassed())) {
// Public key import
- if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_SPKI)) {
+ if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_RAW)) {
+ pubKey = CryptoKey::PublicECKeyFromRaw(mKeyData, mNamedCurve, locker);
+ } else if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_SPKI)) {
pubKey = CryptoKey::PublicKeyFromSpki(mKeyData, locker);
- } else {
+ } else if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_JWK)) {
pubKey = CryptoKey::PublicKeyFromJwk(mJwk, locker);
+ } else {
+ MOZ_ASSERT(false);
}
if (!pubKey) {
@@ -1901,6 +1930,14 @@ class ExportKeyTask : public WebCryptoTask
return NS_OK;
}
+ if (mPublicKey && mPublicKey->keyType == ecKey) {
+ nsresult rv = CryptoKey::PublicECKeyToRaw(mPublicKey, mResult, locker);
+ if (NS_FAILED(rv)) {
+ return NS_ERROR_DOM_OPERATION_ERR;
+ }
+ return NS_OK;
+ }
+
mResult = mSymKey;
if (mResult.Length() == 0) {
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
diff --git a/dom/crypto/test/test-vectors.js b/dom/crypto/test/test-vectors.js
index ef192c946c13a..d6f822b7373cc 100644
--- a/dom/crypto/test/test-vectors.js
+++ b/dom/crypto/test/test-vectors.js
@@ -518,6 +518,11 @@ tv = {
"405dd1f1adeb090107edcfb2b4963739d87679e3056cb0557d0adf"
),
+ raw: util.hex2abv(
+ "045ce7b86e3b32660403e63712ef0998deae1027faec3c1be9f76f934dfeb58e" +
+ "98f4cf075b39405dd1f1adeb090107edcfb2b4963739d87679e3056cb0557d0adf"
+ ),
+
secret: util.hex2abv(
"35669cd5c244ba6c1ea89b8802c3d1db815cd769979072e6556eb98548c65f7d"
)
@@ -606,7 +611,31 @@ tv = {
kty: "EC",
crv: "P-256",
x: "XOe4bjsyZgQD5jcS7wmY3q4QJ_rsPBvp92-TTf61jpg",
- }
+ },
+
+ // Public point with Y not on the curve.
+ raw_bad: util.hex2abv(
+ "045ce7b86e3b32660403e63712ef0998deae1027faec3c1be9f76f934dfeb58e" +
+ "98f4cf075b39405dd1f1adeb090106edcfb2b4963739d87679e3056cb0557d0adf"
+ ),
+
+ // Public point with Y a little too short.
+ raw_short: util.hex2abv(
+ "045ce7b86e3b32660403e63712ef0998deae1027faec3c1be9f76f934dfeb58e" +
+ "98f4cf075b39405dd1f1adeb090107edcfb2b4963739d87679e3056cb0557d0a"
+ ),
+
+ // Public point with Y a little too long.
+ raw_long: util.hex2abv(
+ "045ce7b86e3b32660403e63712ef0998deae1027faec3c1be9f76f934dfeb58e" +
+ "98f4cf075b39405dd1f1adeb090107edcfb2b4963739d87679e3056cb0557d0adfff"
+ ),
+
+ // Public point with EC_POINT_FORM_COMPRESSED_Y0.
+ raw_compressed: util.hex2abv(
+ "025ce7b86e3b32660403e63712ef0998deae1027faec3c1be9f76f934dfeb58e" +
+ "98f4cf075b39405dd1f1adeb090107edcfb2b4963739d87679e3056cb0557d0adf"
+ )
},
// NIST ECDSA test vectors
@@ -626,6 +655,13 @@ tv = {
"9Y33NGQ1_wQ0GZWDyXxmWpfxL3BvI1faS0Aoje-Ijlnm",
},
+ raw: util.hex2abv(
+ "040061387fd6b95914e885f912edfbb5fb274655027f216c4091ca83e19336740fd" +
+ "81aedfe047f51b42bdf68161121013e0d55b117a14e4303f926c8debb77a7fdaad1" +
+ "00e7d0c75c38626e895ca21526b9f9fdf84dcecb93f2b233390550d2b1463b7ee3f" +
+ "58df7346435ff0434199583c97c665a97f12f706f2357da4b40288def888e59e6"
+ ),
+
"data": util.hex2abv(
"9ecd500c60e701404922e58ab20cc002651fdee7cbc9336adda33e4c1088fab1" +
"964ecb7904dc6856865d6c8e15041ccf2d5ac302e99d346ff2f686531d255216" +
diff --git a/dom/crypto/test/test_WebCrypto_ECDH.html b/dom/crypto/test/test_WebCrypto_ECDH.html
index 4aa2a00e9579b..856e60ba38c67 100644
--- a/dom/crypto/test/test_WebCrypto_ECDH.html
+++ b/dom/crypto/test/test_WebCrypto_ECDH.html
@@ -438,6 +438,114 @@
.then(memcmp_complete(that, tv.ecdh_p256.secret), error(that));
}
);
+
+// -----------------------------------------------------------------------------
+TestArray.addTest(
+ "Raw import/export of a public ECDH key (P-256)",
+ function () {
+ var that = this;
+ var alg = { name: "ECDH", namedCurve: "P-256" };
+
+ function doExport(x) {
+ return crypto.subtle.exportKey("raw", x);
+ }
+
+ crypto.subtle.importKey("raw", tv.ecdh_p256.raw, alg, true, ["deriveBits"])
+ .then(doExport)
+ .then(memcmp_complete(that, tv.ecdh_p256.raw), error(that));
+ }
+);
+
+// -----------------------------------------------------------------------------
+TestArray.addTest(
+ "Test that importing bad raw ECDH keys fails",
+ function () {
+ var that = this;
+ var alg = { name: "ECDH", namedCurve: "P-256" };
+ var tvs = tv.ecdh_p256_negative.raw_bad;
+
+ crypto.subtle.importKey("raw", tv, alg, false, ["deriveBits"])
+ .then(error(that), complete(that));
+ }
+);
+
+// -----------------------------------------------------------------------------
+TestArray.addTest(
+ "Test that importing ECDH keys with an unknown format fails",
+ function () {
+ var that = this;
+ var alg = { name: "ECDH", namedCurve: "P-256" };
+ var tvs = tv.ecdh_p256.raw;
+
+ crypto.subtle.importKey("unknown", tv, alg, false, ["deriveBits"])
+ .then(error(that), complete(that));
+ }
+);
+
+// -----------------------------------------------------------------------------
+TestArray.addTest(
+ "Test that importing too short raw ECDH keys fails",
+ function () {
+ var that = this;
+ var alg = { name: "ECDH", namedCurve: "P-256" };
+ var tvs = tv.ecdh_p256_negative.raw_short;
+
+ crypto.subtle.importKey("raw", tv, alg, false, ["deriveBits"])
+ .then(error(that), complete(that));
+ }
+);
+
+// -----------------------------------------------------------------------------
+TestArray.addTest(
+ "Test that importing too long raw ECDH keys fails",
+ function () {
+ var that = this;
+ var alg = { name: "ECDH", namedCurve: "P-256" };
+ var tvs = tv.ecdh_p256_negative.raw_long;
+
+ crypto.subtle.importKey("raw", tv, alg, false, ["deriveBits"])
+ .then(error(that), complete(that));
+ }
+);
+
+// -----------------------------------------------------------------------------
+TestArray.addTest(
+ "Test that importing compressed raw ECDH keys fails",
+ function () {
+ var that = this;
+ var alg = { name: "ECDH", namedCurve: "P-256" };
+ var tvs = tv.ecdh_p256_negative.raw_compressed;
+
+ crypto.subtle.importKey("raw", tv, alg, false, ["deriveBits"])
+ .then(error(that), complete(that));
+ }
+);
+
+// -----------------------------------------------------------------------------
+TestArray.addTest(
+ "RAW/JWK import ECDH keys (P-256) and derive a known secret",
+ function () {
+ var that = this;
+ var alg = { name: "ECDH", namedCurve: "P-256" };
+
+ var pubKey, privKey;
+ function setPub(x) { pubKey = x; }
+ function setPriv(x) { privKey = x; }
+
+ function doDerive() {
+ var alg = { name: "ECDH", public: pubKey };
+ return crypto.subtle.deriveBits(alg, privKey, tv.ecdh_p256.secret.byteLength * 8);
+ }
+
+ Promise.all([
+ crypto.subtle.importKey("raw", tv.ecdh_p256.raw, alg, false, ["deriveBits"])
+ .then(setPub),
+ crypto.subtle.importKey("jwk", tv.ecdh_p256.jwk_priv, alg, false, ["deriveBits"])
+ .then(setPriv)
+ ]).then(doDerive)
+ .then(memcmp_complete(that, tv.ecdh_p256.secret), error(that));
+ }
+);
/*]]>*/
diff --git a/dom/crypto/test/test_WebCrypto_ECDSA.html b/dom/crypto/test/test_WebCrypto_ECDSA.html
index 409928fcc7ed8..3ada61b2d5c05 100644
--- a/dom/crypto/test/test_WebCrypto_ECDSA.html
+++ b/dom/crypto/test/test_WebCrypto_ECDSA.html
@@ -144,6 +144,40 @@
}
);
+// -----------------------------------------------------------------------------
+TestArray.addTest(
+ "Raw import/export of a public ECDSA key (P-521)",
+ function () {
+ var that = this;
+ var alg = { name: "ECDSA", namedCurve: "P-521", hash: "SHA-512" };
+
+ function doExport(x) {
+ return crypto.subtle.exportKey("raw", x);
+ }
+
+ crypto.subtle.importKey("raw", tv.ecdsa_verify.raw, alg, true, ["verify"])
+ .then(doExport)
+ .then(memcmp_complete(that, tv.ecdsa_verify.raw), error(that));
+ }
+);
+
+// -----------------------------------------------------------------------------
+TestArray.addTest(
+ "ECDSA raw import and verify a known-good signature",
+ function() {
+ var that = this;
+ var alg = { name: "ECDSA", namedCurve: "P-521", hash: "SHA-512" };
+
+ function doVerify(x) {
+ return crypto.subtle.verify(alg, x, tv.ecdsa_verify.sig, tv.ecdsa_verify.data);
+ }
+
+ crypto.subtle.importKey("raw", tv.ecdsa_verify.raw, alg, true, ["verify"])
+ .then(doVerify)
+ .then(complete(that), error(that))
+ }
+);
+
/*]]>*/
diff --git a/dom/webidl/SubtleCrypto.webidl b/dom/webidl/SubtleCrypto.webidl
index 25f5a4d93d872..9bb530e08c8bc 100644
--- a/dom/webidl/SubtleCrypto.webidl
+++ b/dom/webidl/SubtleCrypto.webidl
@@ -100,6 +100,10 @@ dictionary EcdsaParams : Algorithm {
required AlgorithmIdentifier hash;
};
+dictionary EcKeyImportParams : Algorithm {
+ NamedCurve namedCurve;
+};
+
/***** JWK *****/
dictionary RsaOtherPrimesInfo {
From 58f7625db18b47675527ac0b5e3123de49d64370 Mon Sep 17 00:00:00 2001
From: Michael Layzell
Date: Mon, 25 May 2015 13:43:00 +0200
Subject: [PATCH 002/151] Bug 1012662 - Part 1 - Allow
document.execCommand('copy'/'cut') in user-generated event handlers. r=ehsan
--HG--
extra : rebase_source : fc3525f8a9494cc1f9b01abb00f4d042e8062160
---
dom/html/nsHTMLDocument.cpp | 30 ++++++++++++++++++++++++++----
1 file changed, 26 insertions(+), 4 deletions(-)
diff --git a/dom/html/nsHTMLDocument.cpp b/dom/html/nsHTMLDocument.cpp
index 3cc31eb2992ee..0986f6f37c916 100644
--- a/dom/html/nsHTMLDocument.cpp
+++ b/dom/html/nsHTMLDocument.cpp
@@ -3251,8 +3251,11 @@ nsHTMLDocument::ExecCommand(const nsAString& commandID,
return false;
}
+ bool isCutCopy = (commandID.LowerCaseEqualsLiteral("cut") ||
+ commandID.LowerCaseEqualsLiteral("copy"));
+
// if editing is not on, bail
- if (!IsEditingOnAfterFlush()) {
+ if (!isCutCopy && !IsEditingOnAfterFlush()) {
rv.Throw(NS_ERROR_FAILURE);
return false;
}
@@ -3262,14 +3265,33 @@ nsHTMLDocument::ExecCommand(const nsAString& commandID,
return false;
}
+ // special case for cut & copy
+ // cut & copy are allowed in non editable documents
+ if (isCutCopy) {
+ if (!nsContentUtils::IsCutCopyAllowed()) {
+ return false;
+ }
+
+ // For cut & copy commands, we need the behaviour from nsWindowRoot::GetControllers
+ // which is to look at the focused element, and defer to a focused textbox's controller
+ // The code past taken by other commands in ExecCommand always uses the window directly,
+ // rather than deferring to the textbox, which is desireable for most editor commands,
+ // but not 'cut' and 'copy' (as those should allow copying out of embedded editors).
+ // This behaviour is invoked if we call DoCommand directly on the docShell.
+ nsCOMPtr docShell(mDocumentContainer);
+ if (docShell) {
+ nsresult res = docShell->DoCommand(cmdToDispatch.get());
+ return NS_SUCCEEDED(res);
+ }
+ return false;
+ }
+
if (commandID.LowerCaseEqualsLiteral("gethtml")) {
rv.Throw(NS_ERROR_FAILURE);
return false;
}
- bool restricted = commandID.LowerCaseEqualsLiteral("cut") ||
- commandID.LowerCaseEqualsLiteral("copy")||
- commandID.LowerCaseEqualsLiteral("paste");
+ bool restricted = commandID.LowerCaseEqualsLiteral("paste");
if (restricted && !nsContentUtils::IsCallerChrome()) {
rv = NS_ERROR_DOM_SECURITY_ERR;
return false;
From eb959a2cdfb5fb3b3a69f9410821b0ec9f4524b4 Mon Sep 17 00:00:00 2001
From: Michael Layzell
Date: Wed, 13 May 2015 08:51:00 +0200
Subject: [PATCH 003/151] Bug 1012662 - Part 2 - Updates to clipboard command
controllers to match cut/copy action spec. r=ehsan
--HG--
extra : rebase_source : 1e7a8ff1ae6e243d8ac7a6a5a8efe2ef86a83dc3
---
dom/base/nsCopySupport.cpp | 72 +++++++++++++------
dom/base/nsCopySupport.h | 6 +-
dom/base/nsGlobalWindowCommands.cpp | 16 ++++-
.../general/test_clipboard_events.html | 2 +-
editor/libeditor/nsPlaintextEditor.cpp | 18 +++--
editor/libeditor/nsPlaintextEditor.h | 2 +-
6 files changed, 80 insertions(+), 36 deletions(-)
diff --git a/dom/base/nsCopySupport.cpp b/dom/base/nsCopySupport.cpp
index 892287077cda1..bde0e70b9172f 100644
--- a/dom/base/nsCopySupport.cpp
+++ b/dom/base/nsCopySupport.cpp
@@ -620,8 +620,13 @@ IsSelectionInsideRuby(nsISelection* aSelection)
}
bool
-nsCopySupport::FireClipboardEvent(int32_t aType, int32_t aClipboardType, nsIPresShell* aPresShell, nsISelection* aSelection)
+nsCopySupport::FireClipboardEvent(int32_t aType, int32_t aClipboardType, nsIPresShell* aPresShell,
+ nsISelection* aSelection, bool* aActionTaken)
{
+ if (aActionTaken) {
+ *aActionTaken = false;
+ }
+
NS_ASSERTION(aType == NS_CUT || aType == NS_COPY || aType == NS_PASTE,
"Invalid clipboard event type");
@@ -646,14 +651,6 @@ nsCopySupport::FireClipboardEvent(int32_t aType, int32_t aClipboardType, nsIPres
// retrieve the event target node from the start of the selection
nsresult rv;
if (sel) {
- // Only cut or copy when there is an uncollapsed selection
- if (aType == NS_CUT || aType == NS_COPY) {
- bool isCollapsed;
- sel->GetIsCollapsed(&isCollapsed);
- if (isCollapsed)
- return false;
- }
-
nsCOMPtr range;
rv = sel->GetRangeAt(0, getter_AddRefs(range));
if (NS_SUCCEEDED(rv) && range) {
@@ -696,7 +693,7 @@ nsCopySupport::FireClipboardEvent(int32_t aType, int32_t aClipboardType, nsIPres
// If the event was cancelled, don't do the clipboard operation
doDefault = (status != nsEventStatus_eConsumeNoDefault);
}
-
+
// No need to do anything special during a paste. Either an event listener
// took care of it and cancelled the event, or the caller will handle it.
// Return true to indicate that the event wasn't cancelled.
@@ -708,6 +705,9 @@ nsCopySupport::FireClipboardEvent(int32_t aType, int32_t aClipboardType, nsIPres
clipboardData->SetReadOnly();
}
+ if (aActionTaken) {
+ *aActionTaken = true;
+ }
return doDefault;
}
@@ -721,20 +721,43 @@ nsCopySupport::FireClipboardEvent(int32_t aType, int32_t aClipboardType, nsIPres
// use the data added to the data transfer and copy that instead.
uint32_t count = 0;
if (doDefault) {
- // get the data from the selection if any
- bool isCollapsed;
- sel->GetIsCollapsed(&isCollapsed);
- if (isCollapsed) {
- return false;
+ // find the focused node
+ nsCOMPtr srcNode = content;
+ if (content->IsInNativeAnonymousSubtree()) {
+ srcNode = content->FindFirstNonChromeOnlyAccessContent();
}
- // XXX Code which decides whether we should copy text with ruby
- // annotation is currenct depending on whether each range of the
- // selection is inside a same ruby container. But we really should
- // expose the full functionality in browser. See bug 1130891.
- bool withRubyAnnotation = IsSelectionInsideRuby(sel);
- // call the copy code
- rv = HTMLCopy(sel, doc, aClipboardType, withRubyAnnotation);
- if (NS_FAILED(rv)) {
+
+ // check if we are looking at a password input
+ nsCOMPtr formControl = do_QueryInterface(srcNode);
+ if (formControl) {
+ if (formControl->GetType() == NS_FORM_INPUT_PASSWORD) {
+ return false;
+ }
+ }
+
+ // when cutting non-editable content, do nothing
+ // XXX this is probably the wrong editable flag to check
+ if (aType != NS_CUT || content->IsEditable()) {
+ // get the data from the selection if any
+ bool isCollapsed;
+ sel->GetIsCollapsed(&isCollapsed);
+ if (isCollapsed) {
+ if (aActionTaken) {
+ *aActionTaken = true;
+ }
+ return false;
+ }
+ // XXX Code which decides whether we should copy text with ruby
+ // annotation is currenct depending on whether each range of the
+ // selection is inside a same ruby container. But we really should
+ // expose the full functionality in browser. See bug 1130891.
+ bool withRubyAnnotation = IsSelectionInsideRuby(sel);
+ // call the copy code
+ rv = HTMLCopy(sel, doc, aClipboardType, withRubyAnnotation);
+ if (NS_FAILED(rv)) {
+ return false;
+ }
+ } else {
return false;
}
} else if (clipboardData) {
@@ -763,5 +786,8 @@ nsCopySupport::FireClipboardEvent(int32_t aType, int32_t aClipboardType, nsIPres
piWindow->UpdateCommands(NS_LITERAL_STRING("clipboard"), nullptr, 0);
}
+ if (aActionTaken) {
+ *aActionTaken = true;
+ }
return doDefault;
}
diff --git a/dom/base/nsCopySupport.h b/dom/base/nsCopySupport.h
index 15670a52198d8..222134c259347 100644
--- a/dom/base/nsCopySupport.h
+++ b/dom/base/nsCopySupport.h
@@ -83,12 +83,16 @@ class nsCopySupport
*
* aClipboardType specifies which clipboard to use, from nsIClipboard.
*
+ * If aActionTaken is non-NULL, it will be set to true if an action was
+ * taken, whether it be the default action or the default being prevented.
+ *
* If the event is cancelled or an error occurs, false will be returned.
*/
static bool FireClipboardEvent(int32_t aType,
int32_t aClipboardType,
nsIPresShell* aPresShell,
- nsISelection* aSelection);
+ nsISelection* aSelection,
+ bool* aActionTaken = nullptr);
};
#endif
diff --git a/dom/base/nsGlobalWindowCommands.cpp b/dom/base/nsGlobalWindowCommands.cpp
index a1f2fac33960a..738d228f6c911 100644
--- a/dom/base/nsGlobalWindowCommands.cpp
+++ b/dom/base/nsGlobalWindowCommands.cpp
@@ -500,7 +500,8 @@ nsClipboardCommand::IsCommandEnabled(const char* aCommandName, nsISupports *aCon
nsresult
nsClipboardCommand::DoCommand(const char *aCommandName, nsISupports *aContext)
{
- if (strcmp(aCommandName, "cmd_copy") &&
+ if (strcmp(aCommandName, "cmd_cut") &&
+ strcmp(aCommandName, "cmd_copy") &&
strcmp(aCommandName, "cmd_copyAndCollapseToEnd"))
return NS_OK;
@@ -513,7 +514,13 @@ nsClipboardCommand::DoCommand(const char *aCommandName, nsISupports *aContext)
nsCOMPtr presShell = docShell->GetPresShell();
NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
- nsCopySupport::FireClipboardEvent(NS_COPY, nsIClipboard::kGlobalClipboard, presShell, nullptr);
+ int32_t eventType = NS_COPY;
+ if (strcmp(aCommandName, "cmd_cut") == 0) {
+ eventType = NS_CUT;
+ }
+
+ bool actionTaken = false;
+ nsCopySupport::FireClipboardEvent(eventType, nsIClipboard::kGlobalClipboard, presShell, nullptr, &actionTaken);
if (!strcmp(aCommandName, "cmd_copyAndCollapseToEnd")) {
dom::Selection *sel =
@@ -522,7 +529,10 @@ nsClipboardCommand::DoCommand(const char *aCommandName, nsISupports *aContext)
sel->CollapseToEnd();
}
- return NS_OK;
+ if (actionTaken) {
+ return NS_OK;
+ }
+ return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
diff --git a/dom/tests/mochitest/general/test_clipboard_events.html b/dom/tests/mochitest/general/test_clipboard_events.html
index 5daa0d4f2a3ea..eeae382cd5475 100644
--- a/dom/tests/mochitest/general/test_clipboard_events.html
+++ b/dom/tests/mochitest/general/test_clipboard_events.html
@@ -150,7 +150,7 @@
content.oncut = function() { oncut_fired = true; };
try {
synthesizeKey("x", {accelKey: 1});
- ok(!oncut_fired, "cut event firing on DOM element")
+ ok(oncut_fired, "cut event firing on DOM element")
is(getClipboardText(), clipboardInitialValue,
"cut on DOM element did not modify clipboard");
} finally {
diff --git a/editor/libeditor/nsPlaintextEditor.cpp b/editor/libeditor/nsPlaintextEditor.cpp
index 7533eb3cca644..7a05f13215f6f 100644
--- a/editor/libeditor/nsPlaintextEditor.cpp
+++ b/editor/libeditor/nsPlaintextEditor.cpp
@@ -1168,7 +1168,7 @@ nsPlaintextEditor::CanCutOrCopy(PasswordFieldAllowed aPasswordFieldAllowed)
}
bool
-nsPlaintextEditor::FireClipboardEvent(int32_t aType, int32_t aSelectionType)
+nsPlaintextEditor::FireClipboardEvent(int32_t aType, int32_t aSelectionType, bool* aActionTaken)
{
if (aType == NS_PASTE)
ForceCompositionEnd();
@@ -1181,7 +1181,7 @@ nsPlaintextEditor::FireClipboardEvent(int32_t aType, int32_t aSelectionType)
return false;
}
- if (!nsCopySupport::FireClipboardEvent(aType, aSelectionType, presShell, selection))
+ if (!nsCopySupport::FireClipboardEvent(aType, aSelectionType, presShell, selection, aActionTaken))
return false;
// If the event handler caused the editor to be destroyed, return false.
@@ -1191,9 +1191,11 @@ nsPlaintextEditor::FireClipboardEvent(int32_t aType, int32_t aSelectionType)
NS_IMETHODIMP nsPlaintextEditor::Cut()
{
- if (FireClipboardEvent(NS_CUT, nsIClipboard::kGlobalClipboard))
- return DeleteSelection(eNone, eStrip);
- return NS_OK;
+ bool actionTaken = false;
+ if (FireClipboardEvent(NS_CUT, nsIClipboard::kGlobalClipboard, &actionTaken)) {
+ DeleteSelection(eNone, eStrip);
+ }
+ return actionTaken ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP nsPlaintextEditor::CanCut(bool *aCanCut)
@@ -1205,8 +1207,10 @@ NS_IMETHODIMP nsPlaintextEditor::CanCut(bool *aCanCut)
NS_IMETHODIMP nsPlaintextEditor::Copy()
{
- FireClipboardEvent(NS_COPY, nsIClipboard::kGlobalClipboard);
- return NS_OK;
+ bool actionTaken = false;
+ FireClipboardEvent(NS_COPY, nsIClipboard::kGlobalClipboard, &actionTaken);
+
+ return actionTaken ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP nsPlaintextEditor::CanCopy(bool *aCanCopy)
diff --git a/editor/libeditor/nsPlaintextEditor.h b/editor/libeditor/nsPlaintextEditor.h
index cf32364be9962..79b5bd7b41e47 100644
--- a/editor/libeditor/nsPlaintextEditor.h
+++ b/editor/libeditor/nsPlaintextEditor.h
@@ -207,7 +207,7 @@ class nsPlaintextEditor : public nsEditor,
ePasswordFieldNotAllowed
};
bool CanCutOrCopy(PasswordFieldAllowed aPasswordFieldAllowed);
- bool FireClipboardEvent(int32_t aType, int32_t aSelectionType);
+ bool FireClipboardEvent(int32_t aType, int32_t aSelectionType, bool* aActionTaken = nullptr);
bool UpdateMetaCharset(nsIDOMDocument* aDocument,
const nsACString& aCharacterSet);
From 827fee71cd16880c964d263ad9e1bf6d2abd48bc Mon Sep 17 00:00:00 2001
From: Michael Layzell
Date: Wed, 27 May 2015 06:54:00 +0200
Subject: [PATCH 004/151] Bug 1012662 - Part 3 - Tests for new Cut/Copy
behaviour. r=ehsan
--HG--
extra : rebase_source : e087d44fad03beb9754fc07d9776048f8ad6b8f7
---
dom/tests/mochitest/general/mochitest.ini | 3 +
.../general/test_bug1012662_common.js | 341 ++++++++++++++++++
.../general/test_bug1012662_editor.html | 29 ++
.../general/test_bug1012662_noeditor.html | 28 ++
.../mochitest/tests/SimpleTest/SimpleTest.js | 45 ++-
5 files changed, 436 insertions(+), 10 deletions(-)
create mode 100644 dom/tests/mochitest/general/test_bug1012662_common.js
create mode 100644 dom/tests/mochitest/general/test_bug1012662_editor.html
create mode 100644 dom/tests/mochitest/general/test_bug1012662_noeditor.html
diff --git a/dom/tests/mochitest/general/mochitest.ini b/dom/tests/mochitest/general/mochitest.ini
index d1368823c9641..021d1978f1ce5 100644
--- a/dom/tests/mochitest/general/mochitest.ini
+++ b/dom/tests/mochitest/general/mochitest.ini
@@ -36,6 +36,7 @@ support-files =
res8.resource^headers^
resource_timing.js
navigation_timing.html
+ test_bug1012662_common.js
[test_497898.html]
skip-if = ((buildapp == 'mulet' || buildapp == 'b2g') && toolkit != 'gonk') || toolkit == 'android' #Bug 931116, b2g desktop specific, initial triage
@@ -100,4 +101,6 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop spec
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_navigation_timing.html]
skip-if = buildapp == 'b2g' || buildapp == 'mulet'
+[test_bug1012662_editor.html]
+[test_bug1012662_noeditor.html]
[test_bug1161721.html]
diff --git a/dom/tests/mochitest/general/test_bug1012662_common.js b/dom/tests/mochitest/general/test_bug1012662_common.js
new file mode 100644
index 0000000000000..0d1ba29631a57
--- /dev/null
+++ b/dom/tests/mochitest/general/test_bug1012662_common.js
@@ -0,0 +1,341 @@
+/** Test for Bug 1012662 **/
+// This test is called from both test_bug1012662_editor.html and test_bug1012662_noeditor.html
+// This is to test that the code works both in the presence of a contentEditable node, and in the absense of one
+var WATCH_TIMEOUT = 300;
+
+// Some global variables to make the debug messages easier to track down
+var gTestN0 = 0, gTestN1 = 0, gTestN2 = 0;
+function testLoc() { return " " + gTestN0 + " - " + gTestN1 + " - " + gTestN2; }
+
+// Listen for cut & copy events
+var gCopyCount = 0, gCutCount = 0;
+document.addEventListener('copy', function() {
+ gCopyCount++;
+});
+document.addEventListener('cut', function() {
+ gCutCount++;
+});
+
+
+// Helper methods
+function selectNode(aSelector, aCb) {
+ var dn = document.querySelector(aSelector);
+ var range = document.createRange();
+ range.selectNodeContents(dn);
+ window.getSelection().removeAllRanges();
+ window.getSelection().addRange(range);
+ if (aCb) {
+ aCb();
+ }
+}
+
+function selectInputNode(aSelector, aCb) {
+ var dn = document.querySelector(aSelector);
+ synthesizeMouse(dn, 10, 10, {});
+ SimpleTest.executeSoon(function() {
+ synthesizeKey("A", {accelKey: true});
+ SimpleTest.executeSoon(aCb);
+ });
+}
+
+// Callback functions for attaching to the button
+function execCut(aShouldSucceed) {
+ var cb = function(e) {
+ e.preventDefault();
+ document.removeEventListener('keydown', cb);
+
+ is(aShouldSucceed, document.execCommand('cut'), "Keydown caused cut invocation" + testLoc());
+ };
+ return cb;
+}
+function execCopy(aShouldSucceed) {
+ var cb = function(e) {
+ e.preventDefault();
+ document.removeEventListener('keydown', cb);
+
+ is(aShouldSucceed, document.execCommand('copy'), "Keydown caused copy invocation" + testLoc());
+ };
+ return cb;
+}
+
+// The basic test set. Tries to cut/copy everything
+function cutCopyAll(aDoCut, aDoCopy, aDone, aNegate, aClipOverride, aJustClipboardNegate) {
+ var execCommandAlwaysSucceed = !!(aClipOverride || aJustClipboardNegate);
+
+ function waitForClipboard(aCond, aSetup, aNext, aNegateOne) {
+ if (aClipOverride) {
+ aCond = aClipOverride;
+ aNegateOne = false;
+ }
+ if (aNegate || aNegateOne || aJustClipboardNegate) {
+ SimpleTest.waitForClipboard(null, aSetup, aNext, aNext, "text/unicode", WATCH_TIMEOUT, true);
+ } else {
+ SimpleTest.waitForClipboard(aCond, aSetup, aNext, aNext);
+ }
+ }
+
+ function validateCutCopy(aExpectedCut, aExpectedCopy) {
+ if (aNegate) {
+ aExpectedCut = aExpectedCopy = 0;
+ } // When we are negating - we always expect callbacks not to be run
+
+ is(aExpectedCut, gCutCount,
+ (aExpectedCut > 0 ? "Expect cut callback to run" : "Expect cut callback not to run") + testLoc());
+ is(aExpectedCopy, gCopyCount,
+ (aExpectedCopy > 0 ? "Expect copy callback to run" : "Expect copy callback not to run") + testLoc());
+ gCutCount = gCopyCount = 0;
+ }
+
+ function step(n) {
+ function nextStep() { step(n + 1); }
+
+ document.querySelector('span').textContent = 'span text';
+ document.querySelector('input[type=text]').value = 'text text';
+ document.querySelector('input[type=password]').value = 'password text';
+ document.querySelector('textarea').value = 'textarea text';
+
+ var contentEditableNode = document.querySelector('div[contentEditable=true]');
+ if (contentEditableNode) {
+ contentEditableNode.textContent = 'contenteditable text';
+ }
+
+ gTestN2 = n;
+ switch (n) {
+ case 0:
+ // copy on readonly selection
+ selectNode('span');
+ waitForClipboard("span text", function() {
+ aDoCopy(true);
+ }, nextStep);
+ return;
+
+ case 1:
+ validateCutCopy(0, 1);
+
+ // cut on readonly selection
+ selectNode('span');
+
+ waitForClipboard("span text", function() {
+ aDoCut(execCommandAlwaysSucceed);
+ }, nextStep, true);
+ return;
+
+ case 2:
+ validateCutCopy(1, 0);
+
+ // copy on textbox selection
+ selectInputNode('input[type=text]', nextStep);
+ return;
+
+ case 3:
+ waitForClipboard("text text", function() {
+ selectInputNode('input[type=text]', function() { aDoCopy(true); });
+ }, nextStep);
+ return;
+
+ case 4:
+ validateCutCopy(0, 1);
+
+ // cut on textbox selection
+ selectInputNode('input[type=text]', nextStep);
+ return;
+
+ case 5:
+ waitForClipboard("text text", function() {
+ aDoCut(true);
+ }, nextStep);
+ return;
+
+ case 6:
+ validateCutCopy(1, 0);
+
+ // copy on password selection
+ selectInputNode('input[type=password]', nextStep);
+ return;
+
+ case 7:
+ waitForClipboard(null, function() {
+ aDoCopy(execCommandAlwaysSucceed);
+ }, nextStep, true);
+ return;
+
+ case 8:
+ validateCutCopy(0, 1);
+
+ // cut on password selection
+ selectInputNode('input[type=password]', nextStep);
+ return;
+
+ case 9:
+ waitForClipboard(null, function() {
+ aDoCut(execCommandAlwaysSucceed);
+ }, nextStep, true);
+ return;
+
+ case 10:
+ validateCutCopy(1, 0);
+
+ // copy on textarea selection
+ selectInputNode('textarea', nextStep);
+ return;
+
+ case 11:
+ waitForClipboard("textarea text", function() {
+ aDoCopy(true);
+ }, nextStep);
+ return;
+
+ case 12:
+ validateCutCopy(0, 1);
+
+ // cut on password selection
+ selectInputNode('textarea', nextStep);
+ return;
+
+ case 13:
+ waitForClipboard("textarea text", function() {
+ aDoCut(true);
+ }, nextStep);
+ return;
+
+ case 14:
+ validateCutCopy(1, 0);
+
+ // copy on no selection
+ document.querySelector('textarea').blur();
+
+ waitForClipboard(null, function() {
+ aDoCopy(true);
+ }, nextStep, true);
+ return;
+
+ case 15:
+ validateCutCopy(0, 1);
+
+ // cut on no selection
+ waitForClipboard(null, function() {
+ aDoCut(execCommandAlwaysSucceed);
+ }, nextStep, true);
+ return;
+
+ case 16:
+ validateCutCopy(1, 0);
+
+ if (!document.querySelector('div[contentEditable=true]')) {
+ // We're done! (no contentEditable node!)
+ step(-1);
+ return;
+ }
+ break;
+
+ case 17:
+ // copy on contenteditable selection
+ waitForClipboard("contenteditable text", function() {
+ selectNode('div[contentEditable=true]', function() {
+ aDoCopy(true);
+ });
+ }, nextStep);
+ return;
+
+ case 18:
+ validateCutCopy(0, 1);
+ break;
+
+ case 19:
+ // cut on contenteditable selection
+ waitForClipboard("contenteditable text", function() {
+ selectNode('div[contentEditable=true]', function() {
+ aDoCut(true);
+ });
+ }, nextStep);
+ return;
+
+ case 20:
+ validateCutCopy(1, 0);
+ break;
+
+ default:
+ aDone();
+ return;
+ }
+
+ SimpleTest.executeSoon(function() { step(n + 1); });
+ }
+
+ step(0);
+}
+
+function allMechanisms(aCb, aClipOverride, aNegateAll) {
+ function testStep(n) {
+ gTestN1 = n;
+ switch (n) {
+ case 0:
+ // Keyboard issued
+ cutCopyAll(function docut(aSucc) {
+ synthesizeKey("X", {accelKey: true});
+ }, function docopy(aSucc) {
+ synthesizeKey("C", {accelKey: true});
+ }, function done() { testStep(n + 1); }, false, aClipOverride, aNegateAll);
+ return;
+
+ case 1:
+ // Button issued
+ cutCopyAll(function docut(aSucc) {
+ document.addEventListener('keydown', execCut(aSucc));
+ synthesizeKey("Q", {});
+ }, function docopy(aSucc) {
+ document.addEventListener('keydown', execCopy(aSucc));
+ synthesizeKey("Q", {});
+ }, function done() { testStep(n + 1); }, false, aClipOverride, aNegateAll);
+ return;
+
+ case 2:
+ // Button issued
+ cutCopyAll(function doCut(aSucc) {
+ is(false, document.execCommand('cut'), "Can't directly execCommand not in a user callback");
+ }, function doCopy(aSucc) {
+ is(false, document.execCommand('copy'), "Can't directly execCommand not in a user callback");
+ }, function done() { testStep(n + 1); }, true, aClipOverride, aNegateAll);
+ return;
+
+ default:
+ aCb();
+ return;
+ }
+
+ SimpleTest.executeSoon(function() { testStep(n + 1); });
+ }
+ testStep(0);
+}
+
+// Run the tests
+SimpleTest.waitForExplicitFinish();
+SimpleTest.requestLongerTimeout(5); // On the emulator - this times out occasionally
+SimpleTest.waitForFocus(function() {
+ function justCancel(aEvent) {
+ aEvent.preventDefault();
+ }
+
+ function override(aEvent) {
+ aEvent.clipboardData.setData('text/plain', 'overridden');
+ aEvent.preventDefault();
+ }
+
+ allMechanisms(function() {
+ gTestN0 = 1;
+ document.addEventListener('cut', override);
+ document.addEventListener('copy', override);
+
+ allMechanisms(function() {
+ gTestN0 = 2;
+ document.removeEventListener('cut', override);
+ document.removeEventListener('copy', override);
+ document.addEventListener('cut', justCancel);
+ document.addEventListener('copy', justCancel);
+
+ allMechanisms(function() {
+ SimpleTest.finish();
+ }, null, true);
+ }, 'overridden');
+ });
+});
diff --git a/dom/tests/mochitest/general/test_bug1012662_editor.html b/dom/tests/mochitest/general/test_bug1012662_editor.html
new file mode 100644
index 0000000000000..c77adcfc749c2
--- /dev/null
+++ b/dom/tests/mochitest/general/test_bug1012662_editor.html
@@ -0,0 +1,29 @@
+
+
+
+
+ Test for Bug 1012662
+
+
+
+
+
+
+Mozilla Bug 1012662
+
+
+
+
span text
+
+
+
+
contenteditable text
+
+
+
+
+
+
+
diff --git a/dom/tests/mochitest/general/test_bug1012662_noeditor.html b/dom/tests/mochitest/general/test_bug1012662_noeditor.html
new file mode 100644
index 0000000000000..a3c2be71e18e4
--- /dev/null
+++ b/dom/tests/mochitest/general/test_bug1012662_noeditor.html
@@ -0,0 +1,28 @@
+
+
+
+
+ Test for Bug 1012662
+
+
+
+
+
+
+Mozilla Bug 1012662
+
+
+
+ span text
+
+
+
+
+
+
+
+
+
+
diff --git a/testing/mochitest/tests/SimpleTest/SimpleTest.js b/testing/mochitest/tests/SimpleTest/SimpleTest.js
index 1a752c222d2bc..20df877fbdb05 100644
--- a/testing/mochitest/tests/SimpleTest/SimpleTest.js
+++ b/testing/mochitest/tests/SimpleTest/SimpleTest.js
@@ -896,19 +896,45 @@ SimpleTest.waitForClipboard_polls = 0;
* A function called if the expected value isn't found on the clipboard
* within 5s. It can also be called if the known value can't be found.
* @param aFlavor [optional] The flavor to look for. Defaults to "text/unicode".
+ * @param aTimeout [optional]
+ * The timeout (in milliseconds) to wait for a clipboard change.
+ * Defaults to 5000.
+ * @param aExpectFailure [optional]
+ * If true, fail if the clipboard contents are modified within the timeout
+ * interval defined by aTimeout. When aExpectFailure is true, the argument
+ * aExpectedStringOrValidatorFn must be null, as it won't be used.
+ * Defaults to false.
*/
SimpleTest.__waitForClipboardMonotonicCounter = 0;
SimpleTest.__defineGetter__("_waitForClipboardMonotonicCounter", function () {
return SimpleTest.__waitForClipboardMonotonicCounter++;
});
SimpleTest.waitForClipboard = function(aExpectedStringOrValidatorFn, aSetupFn,
- aSuccessFn, aFailureFn, aFlavor) {
+ aSuccessFn, aFailureFn, aFlavor, aTimeout, aExpectFailure) {
var requestedFlavor = aFlavor || "text/unicode";
- // Build a default validator function for common string input.
- var inputValidatorFn = typeof(aExpectedStringOrValidatorFn) == "string"
- ? function(aData) { return aData == aExpectedStringOrValidatorFn; }
- : aExpectedStringOrValidatorFn;
+ // The known value we put on the clipboard before running aSetupFn
+ var initialVal = SimpleTest._waitForClipboardMonotonicCounter +
+ "-waitForClipboard-known-value";
+
+ var inputValidatorFn;
+ if (aExpectFailure) {
+ // If we expect failure, the aExpectedStringOrValidatorFn should be null
+ if (aExpectedStringOrValidatorFn !== null) {
+ SimpleTest.ok(false, "When expecting failure, aExpectedStringOrValidatorFn must be null");
+ }
+
+ inputValidatorFn = function(aData) {
+ return aData != initialVal;
+ };
+ } else {
+ // Build a default validator function for common string input.
+ inputValidatorFn = typeof(aExpectedStringOrValidatorFn) == "string"
+ ? function(aData) { return aData == aExpectedStringOrValidatorFn; }
+ : aExpectedStringOrValidatorFn;
+ }
+
+ var maxPolls = aTimeout ? aTimeout / 100 : 50;
// reset for the next use
function reset() {
@@ -916,9 +942,9 @@ SimpleTest.waitForClipboard = function(aExpectedStringOrValidatorFn, aSetupFn,
}
function wait(validatorFn, successFn, failureFn, flavor) {
- if (++SimpleTest.waitForClipboard_polls > 50) {
+ if (++SimpleTest.waitForClipboard_polls > maxPolls) {
// Log the failure.
- SimpleTest.ok(false, "Timed out while polling clipboard for pasted data.");
+ SimpleTest.ok(aExpectFailure, "Timed out while polling clipboard for pasted data");
reset();
failureFn();
return;
@@ -931,7 +957,7 @@ SimpleTest.waitForClipboard = function(aExpectedStringOrValidatorFn, aSetupFn,
if (preExpectedVal)
preExpectedVal = null;
else
- SimpleTest.ok(true, "Clipboard has the correct value");
+ SimpleTest.ok(!aExpectFailure, "Clipboard has the given value");
reset();
successFn();
} else {
@@ -940,8 +966,7 @@ SimpleTest.waitForClipboard = function(aExpectedStringOrValidatorFn, aSetupFn,
}
// First we wait for a known value different from the expected one.
- var preExpectedVal = SimpleTest._waitForClipboardMonotonicCounter +
- "-waitForClipboard-known-value";
+ var preExpectedVal = initialVal;
SpecialPowers.clipboardCopyString(preExpectedVal);
wait(function(aData) { return aData == preExpectedVal; },
function() {
From adddf68b3c854975e751437fcd9818f8acdaeedb Mon Sep 17 00:00:00 2001
From: Honza Bambas
Date: Mon, 13 Apr 2015 16:58:00 +0200
Subject: [PATCH 005/151] Bug 1122420 - Improve after-shutdown dispatch
assertion on CacheIOThread. r=michal
--HG--
extra : rebase_source : f4e438e004b4e18e81ce35db5659a6c9cef18ce1
---
netwerk/cache2/CacheIOThread.cpp | 6 +++++-
netwerk/cache2/CacheIOThread.h | 2 ++
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/netwerk/cache2/CacheIOThread.cpp b/netwerk/cache2/CacheIOThread.cpp
index 8a2737c023c53..9eee735cb9abe 100644
--- a/netwerk/cache2/CacheIOThread.cpp
+++ b/netwerk/cache2/CacheIOThread.cpp
@@ -27,6 +27,7 @@ CacheIOThread::CacheIOThread()
, mHasXPCOMEvents(false)
, mRerunCurrentEvent(false)
, mShutdown(false)
+, mInsideLoop(true)
{
sSelf = this;
}
@@ -237,6 +238,9 @@ void CacheIOThread::ThreadFunc()
} while (true);
MOZ_ASSERT(!EventsPending());
+
+ // This is for correct assertion on XPCOM events dispatch.
+ mInsideLoop = false;
} // lock
if (threadInternal)
@@ -313,7 +317,7 @@ NS_IMETHODIMP CacheIOThread::OnDispatchedEvent(nsIThreadInternal *thread)
{
MonitorAutoLock lock(mMonitor);
mHasXPCOMEvents = true;
- MOZ_ASSERT(!mShutdown || (PR_GetCurrentThread() == mThread));
+ MOZ_ASSERT(mInsideLoop);
lock.Notify();
return NS_OK;
}
diff --git a/netwerk/cache2/CacheIOThread.h b/netwerk/cache2/CacheIOThread.h
index b84b27ae7230b..c276546f69c2c 100644
--- a/netwerk/cache2/CacheIOThread.h
+++ b/netwerk/cache2/CacheIOThread.h
@@ -11,6 +11,7 @@
#include "nsTArray.h"
#include "nsAutoPtr.h"
#include "mozilla/Monitor.h"
+#include "mozilla/DebugOnly.h"
class nsIRunnable;
@@ -94,6 +95,7 @@ class CacheIOThread : public nsIThreadObserver
bool mHasXPCOMEvents;
bool mRerunCurrentEvent;
bool mShutdown;
+ DebugOnly mInsideLoop;
};
} // net
From aa913043f6128f0306828bdaaf0c47cd9bf3699a Mon Sep 17 00:00:00 2001
From: Andrew McCreight
Date: Wed, 27 May 2015 07:53:00 +0200
Subject: [PATCH 006/151] Bug 1157308 - part 1 - Reduce the leak threshold for
content processes more. r=erahm
---
layout/tools/reftest/runreftest.py | 2 +-
testing/mochitest/mochitest_options.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/layout/tools/reftest/runreftest.py b/layout/tools/reftest/runreftest.py
index fda6b857b2577..5a1cd3fd89d9b 100644
--- a/layout/tools/reftest/runreftest.py
+++ b/layout/tools/reftest/runreftest.py
@@ -820,7 +820,7 @@ def verifyCommonOptions(self, options, reftest):
options.leakThresholds = {
"default": options.defaultLeakThreshold,
- "tab": 25000, # See dependencies of bug 1051230.
+ "tab": 5000, # See dependencies of bug 1051230.
}
return options
diff --git a/testing/mochitest/mochitest_options.py b/testing/mochitest/mochitest_options.py
index 2453f69336600..51fec77fa9bed 100644
--- a/testing/mochitest/mochitest_options.py
+++ b/testing/mochitest/mochitest_options.py
@@ -718,7 +718,7 @@ def validate(self, parser, options, context):
options.leakThresholds = {
"default": options.defaultLeakThreshold,
- "tab": 25000, # See dependencies of bug 1051230.
+ "tab": 10000, # See dependencies of bug 1051230.
# GMP rarely gets a log, but when it does, it leaks a little.
"geckomediaplugin": 20000,
}
From 95802bd4a7383d3f9e72d3ad4e592aee67da5e66 Mon Sep 17 00:00:00 2001
From: Andrew McCreight
Date: Wed, 27 May 2015 09:33:00 +0200
Subject: [PATCH 007/151] Bug 1157308 - part 2 - Reduce the content process
leak limit on OS X. r=erahm
The intermittent media leak seems to have been fixed.
---
testing/mochitest/mochitest_options.py | 4 ----
1 file changed, 4 deletions(-)
diff --git a/testing/mochitest/mochitest_options.py b/testing/mochitest/mochitest_options.py
index 51fec77fa9bed..0e9487a23d1a4 100644
--- a/testing/mochitest/mochitest_options.py
+++ b/testing/mochitest/mochitest_options.py
@@ -728,10 +728,6 @@ def validate(self, parser, options, context):
if mozinfo.isWin:
options.ignoreMissingLeaks.append("tab")
- # Bug 1121539 - OSX-only intermittent tab process leak in test_ipc.html
- if mozinfo.isMac:
- options.leakThresholds["tab"] = 100000
-
return options
From 1ea1d4d58773b7171bd85b2a8e80e4a154c7409a Mon Sep 17 00:00:00 2001
From: Nicholas Hurley
Date: Wed, 27 May 2015 09:49:00 +0200
Subject: [PATCH 008/151] Bug 1159747 - delete h2 static compression table in
such a way to avoid crashes after network changes. r=mcmanus
---
netwerk/build/nsNetModule.cpp | 5 +++++
netwerk/protocol/http/Http2Compression.cpp | 4 ++++
netwerk/protocol/http/nsHttpConnectionMgr.cpp | 2 --
3 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/netwerk/build/nsNetModule.cpp b/netwerk/build/nsNetModule.cpp
index 63ee99de43da3..568d5152288d2 100644
--- a/netwerk/build/nsNetModule.cpp
+++ b/netwerk/build/nsNetModule.cpp
@@ -225,6 +225,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsFtpProtocolHandler, Init)
#ifdef NECKO_PROTOCOL_http
// http/https
#include "nsHttpHandler.h"
+#include "Http2Compression.h"
#undef LOG
#undef LOG_ENABLED
#include "nsHttpAuthManager.h"
@@ -655,6 +656,10 @@ static void nsNetShutdown()
mozilla::net::WebSocketChannel::Shutdown();
#endif // NECKO_PROTOCOL_websocket
+#ifdef NECKO_PROTOCOL_http
+ mozilla::net::Http2CompressionCleanup();
+#endif // NECKO_PROTOCOL_http
+
delete gNetSniffers;
gNetSniffers = nullptr;
delete gDataSniffers;
diff --git a/netwerk/protocol/http/Http2Compression.cpp b/netwerk/protocol/http/Http2Compression.cpp
index 854a02889bcc3..cf649612eae27 100644
--- a/netwerk/protocol/http/Http2Compression.cpp
+++ b/netwerk/protocol/http/Http2Compression.cpp
@@ -228,6 +228,10 @@ Http2BaseCompressor::MakeRoom(uint32_t amount, const char *direction)
void
Http2BaseCompressor::DumpState()
{
+ if (!LOG_ENABLED()) {
+ return;
+ }
+
LOG(("Header Table"));
uint32_t i;
uint32_t length = mHeaderTable.Length();
diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
index 9e711d5b130a1..5b80813fbd02e 100644
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -30,7 +30,6 @@
#include "nsITransport.h"
#include "nsISocketTransportService.h"
#include
-#include "Http2Compression.h"
#include "mozilla/ChaosMode.h"
#include "mozilla/unused.h"
@@ -177,7 +176,6 @@ nsHttpConnectionMgr::Shutdown()
// wait for shutdown event to complete
while (!shutdown)
NS_ProcessNextEvent(NS_GetCurrentThread());
- Http2CompressionCleanup();
return NS_OK;
}
From 682368e16791e3dd4a0dce3fa491ec57d9eb536b Mon Sep 17 00:00:00 2001
From: Boris Chiou
Date: Wed, 27 May 2015 03:18:00 +0200
Subject: [PATCH 009/151] Bug 1161372 - Add EventRegions on LayerScope.
r=dglastonbury
---
gfx/layers/Layers.cpp | 19 ++
gfx/layers/protobuf/LayerScopePacket.pb.cc | 202 +++++++++++++++++-
gfx/layers/protobuf/LayerScopePacket.pb.h | 232 +++++++++++++++++++--
gfx/layers/protobuf/LayerScopePacket.proto | 5 +
4 files changed, 436 insertions(+), 22 deletions(-)
diff --git a/gfx/layers/Layers.cpp b/gfx/layers/Layers.cpp
index 1552bb906c850..a658640559078 100644
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -1716,6 +1716,25 @@ Layer::DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent)
if (!mVisibleRegion.IsEmpty()) {
DumpRegion(layer->mutable_vregion(), mVisibleRegion);
}
+ // EventRegions
+ if (!mEventRegions.IsEmpty()) {
+ const EventRegions &e = mEventRegions;
+ if (!e.mHitRegion.IsEmpty()) {
+ DumpRegion(layer->mutable_hitregion(), e.mHitRegion);
+ }
+ if (!e.mDispatchToContentHitRegion.IsEmpty()) {
+ DumpRegion(layer->mutable_dispatchregion(), e.mDispatchToContentHitRegion);
+ }
+ if (!e.mNoActionRegion.IsEmpty()) {
+ DumpRegion(layer->mutable_noactionregion(), e.mNoActionRegion);
+ }
+ if (!e.mHorizontalPanRegion.IsEmpty()) {
+ DumpRegion(layer->mutable_hpanregion(), e.mHorizontalPanRegion);
+ }
+ if (!e.mVerticalPanRegion.IsEmpty()) {
+ DumpRegion(layer->mutable_vpanregion(), e.mVerticalPanRegion);
+ }
+ }
// Opacity
layer->set_opacity(mOpacity);
// Content opaque
diff --git a/gfx/layers/protobuf/LayerScopePacket.pb.cc b/gfx/layers/protobuf/LayerScopePacket.pb.cc
index ed9445d529a91..6fd63805763df 100644
--- a/gfx/layers/protobuf/LayerScopePacket.pb.cc
+++ b/gfx/layers/protobuf/LayerScopePacket.pb.cc
@@ -2115,6 +2115,11 @@ const int LayersPacket_Layer::kCAlphaFieldNumber;
const int LayersPacket_Layer::kDirectFieldNumber;
const int LayersPacket_Layer::kBarIDFieldNumber;
const int LayersPacket_Layer::kMaskFieldNumber;
+const int LayersPacket_Layer::kHitRegionFieldNumber;
+const int LayersPacket_Layer::kDispatchRegionFieldNumber;
+const int LayersPacket_Layer::kNoActionRegionFieldNumber;
+const int LayersPacket_Layer::kHPanRegionFieldNumber;
+const int LayersPacket_Layer::kVPanRegionFieldNumber;
const int LayersPacket_Layer::kValidFieldNumber;
const int LayersPacket_Layer::kColorFieldNumber;
const int LayersPacket_Layer::kFilterFieldNumber;
@@ -2132,6 +2137,11 @@ void LayersPacket_Layer::InitAsDefaultInstance() {
transform_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Matrix::default_instance());
vregion_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Region::default_instance());
shadow_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Shadow*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Shadow::default_instance());
+ hitregion_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Region::default_instance());
+ dispatchregion_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Region::default_instance());
+ noactionregion_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Region::default_instance());
+ hpanregion_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Region::default_instance());
+ vpanregion_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Region::default_instance());
valid_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Region::default_instance());
size_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Size*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Size::default_instance());
}
@@ -2157,6 +2167,11 @@ void LayersPacket_Layer::SharedCtor() {
direct_ = 1;
barid_ = GOOGLE_ULONGLONG(0);
mask_ = GOOGLE_ULONGLONG(0);
+ hitregion_ = NULL;
+ dispatchregion_ = NULL;
+ noactionregion_ = NULL;
+ hpanregion_ = NULL;
+ vpanregion_ = NULL;
valid_ = NULL;
color_ = 0u;
filter_ = 0;
@@ -2175,6 +2190,11 @@ void LayersPacket_Layer::SharedDtor() {
delete transform_;
delete vregion_;
delete shadow_;
+ delete hitregion_;
+ delete dispatchregion_;
+ delete noactionregion_;
+ delete hpanregion_;
+ delete vpanregion_;
delete valid_;
delete size_;
}
@@ -2220,13 +2240,28 @@ void LayersPacket_Layer::Clear() {
direct_ = 1;
barid_ = GOOGLE_ULONGLONG(0);
mask_ = GOOGLE_ULONGLONG(0);
+ if (has_hitregion()) {
+ if (hitregion_ != NULL) hitregion_->::mozilla::layers::layerscope::LayersPacket_Layer_Region::Clear();
+ }
+ if (has_dispatchregion()) {
+ if (dispatchregion_ != NULL) dispatchregion_->::mozilla::layers::layerscope::LayersPacket_Layer_Region::Clear();
+ }
+ if (has_noactionregion()) {
+ if (noactionregion_ != NULL) noactionregion_->::mozilla::layers::layerscope::LayersPacket_Layer_Region::Clear();
+ }
+ }
+ if (_has_bits_[16 / 32] & (0xffu << (16 % 32))) {
+ if (has_hpanregion()) {
+ if (hpanregion_ != NULL) hpanregion_->::mozilla::layers::layerscope::LayersPacket_Layer_Region::Clear();
+ }
+ if (has_vpanregion()) {
+ if (vpanregion_ != NULL) vpanregion_->::mozilla::layers::layerscope::LayersPacket_Layer_Region::Clear();
+ }
if (has_valid()) {
if (valid_ != NULL) valid_->::mozilla::layers::layerscope::LayersPacket_Layer_Region::Clear();
}
color_ = 0u;
filter_ = 0;
- }
- if (_has_bits_[16 / 32] & (0xffu << (16 % 32))) {
refid_ = GOOGLE_ULONGLONG(0);
if (has_size()) {
if (size_ != NULL) size_->::mozilla::layers::layerscope::LayersPacket_Layer_Size::Clear();
@@ -2442,6 +2477,76 @@ bool LayersPacket_Layer::MergePartialFromCodedStream(
} else {
goto handle_uninterpreted;
}
+ if (input->ExpectTag(162)) goto parse_hitRegion;
+ break;
+ }
+
+ // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region hitRegion = 20;
+ case 20: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_hitRegion:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, mutable_hitregion()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(170)) goto parse_dispatchRegion;
+ break;
+ }
+
+ // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region dispatchRegion = 21;
+ case 21: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_dispatchRegion:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, mutable_dispatchregion()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(178)) goto parse_noActionRegion;
+ break;
+ }
+
+ // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region noActionRegion = 22;
+ case 22: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_noActionRegion:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, mutable_noactionregion()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(186)) goto parse_hPanRegion;
+ break;
+ }
+
+ // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region hPanRegion = 23;
+ case 23: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_hPanRegion:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, mutable_hpanregion()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(194)) goto parse_vPanRegion;
+ break;
+ }
+
+ // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vPanRegion = 24;
+ case 24: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_vPanRegion:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, mutable_vpanregion()));
+ } else {
+ goto handle_uninterpreted;
+ }
if (input->ExpectTag(802)) goto parse_valid;
break;
}
@@ -2613,6 +2718,36 @@ void LayersPacket_Layer::SerializeWithCachedSizes(
::google::protobuf::internal::WireFormatLite::WriteUInt64(19, this->mask(), output);
}
+ // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region hitRegion = 20;
+ if (has_hitregion()) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessage(
+ 20, this->hitregion(), output);
+ }
+
+ // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region dispatchRegion = 21;
+ if (has_dispatchregion()) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessage(
+ 21, this->dispatchregion(), output);
+ }
+
+ // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region noActionRegion = 22;
+ if (has_noactionregion()) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessage(
+ 22, this->noactionregion(), output);
+ }
+
+ // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region hPanRegion = 23;
+ if (has_hpanregion()) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessage(
+ 23, this->hpanregion(), output);
+ }
+
+ // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vPanRegion = 24;
+ if (has_vpanregion()) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessage(
+ 24, this->vpanregion(), output);
+ }
+
// optional .mozilla.layers.layerscope.LayersPacket.Layer.Region valid = 100;
if (has_valid()) {
::google::protobuf::internal::WireFormatLite::WriteMessage(
@@ -2732,6 +2867,43 @@ int LayersPacket_Layer::ByteSize() const {
this->mask());
}
+ // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region hitRegion = 20;
+ if (has_hitregion()) {
+ total_size += 2 +
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->hitregion());
+ }
+
+ // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region dispatchRegion = 21;
+ if (has_dispatchregion()) {
+ total_size += 2 +
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->dispatchregion());
+ }
+
+ // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region noActionRegion = 22;
+ if (has_noactionregion()) {
+ total_size += 2 +
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->noactionregion());
+ }
+
+ }
+ if (_has_bits_[16 / 32] & (0xffu << (16 % 32))) {
+ // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region hPanRegion = 23;
+ if (has_hpanregion()) {
+ total_size += 2 +
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->hpanregion());
+ }
+
+ // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vPanRegion = 24;
+ if (has_vpanregion()) {
+ total_size += 2 +
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->vpanregion());
+ }
+
// optional .mozilla.layers.layerscope.LayersPacket.Layer.Region valid = 100;
if (has_valid()) {
total_size += 2 +
@@ -2752,8 +2924,6 @@ int LayersPacket_Layer::ByteSize() const {
::google::protobuf::internal::WireFormatLite::EnumSize(this->filter());
}
- }
- if (_has_bits_[16 / 32] & (0xffu << (16 % 32))) {
// optional uint64 refID = 103;
if (has_refid()) {
total_size += 2 +
@@ -2824,6 +2994,23 @@ void LayersPacket_Layer::MergeFrom(const LayersPacket_Layer& from) {
if (from.has_mask()) {
set_mask(from.mask());
}
+ if (from.has_hitregion()) {
+ mutable_hitregion()->::mozilla::layers::layerscope::LayersPacket_Layer_Region::MergeFrom(from.hitregion());
+ }
+ if (from.has_dispatchregion()) {
+ mutable_dispatchregion()->::mozilla::layers::layerscope::LayersPacket_Layer_Region::MergeFrom(from.dispatchregion());
+ }
+ if (from.has_noactionregion()) {
+ mutable_noactionregion()->::mozilla::layers::layerscope::LayersPacket_Layer_Region::MergeFrom(from.noactionregion());
+ }
+ }
+ if (from._has_bits_[16 / 32] & (0xffu << (16 % 32))) {
+ if (from.has_hpanregion()) {
+ mutable_hpanregion()->::mozilla::layers::layerscope::LayersPacket_Layer_Region::MergeFrom(from.hpanregion());
+ }
+ if (from.has_vpanregion()) {
+ mutable_vpanregion()->::mozilla::layers::layerscope::LayersPacket_Layer_Region::MergeFrom(from.vpanregion());
+ }
if (from.has_valid()) {
mutable_valid()->::mozilla::layers::layerscope::LayersPacket_Layer_Region::MergeFrom(from.valid());
}
@@ -2833,8 +3020,6 @@ void LayersPacket_Layer::MergeFrom(const LayersPacket_Layer& from) {
if (from.has_filter()) {
set_filter(from.filter());
}
- }
- if (from._has_bits_[16 / 32] & (0xffu << (16 % 32))) {
if (from.has_refid()) {
set_refid(from.refid());
}
@@ -2871,6 +3056,11 @@ void LayersPacket_Layer::Swap(LayersPacket_Layer* other) {
std::swap(direct_, other->direct_);
std::swap(barid_, other->barid_);
std::swap(mask_, other->mask_);
+ std::swap(hitregion_, other->hitregion_);
+ std::swap(dispatchregion_, other->dispatchregion_);
+ std::swap(noactionregion_, other->noactionregion_);
+ std::swap(hpanregion_, other->hpanregion_);
+ std::swap(vpanregion_, other->vpanregion_);
std::swap(valid_, other->valid_);
std::swap(color_, other->color_);
std::swap(filter_, other->filter_);
diff --git a/gfx/layers/protobuf/LayerScopePacket.pb.h b/gfx/layers/protobuf/LayerScopePacket.pb.h
index ac84d4a375ec2..8c1d4dc9d3272 100644
--- a/gfx/layers/protobuf/LayerScopePacket.pb.h
+++ b/gfx/layers/protobuf/LayerScopePacket.pb.h
@@ -1064,6 +1064,46 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite {
inline ::google::protobuf::uint64 mask() const;
inline void set_mask(::google::protobuf::uint64 value);
+ // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region hitRegion = 20;
+ inline bool has_hitregion() const;
+ inline void clear_hitregion();
+ static const int kHitRegionFieldNumber = 20;
+ inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& hitregion() const;
+ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* mutable_hitregion();
+ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* release_hitregion();
+
+ // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region dispatchRegion = 21;
+ inline bool has_dispatchregion() const;
+ inline void clear_dispatchregion();
+ static const int kDispatchRegionFieldNumber = 21;
+ inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& dispatchregion() const;
+ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* mutable_dispatchregion();
+ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* release_dispatchregion();
+
+ // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region noActionRegion = 22;
+ inline bool has_noactionregion() const;
+ inline void clear_noactionregion();
+ static const int kNoActionRegionFieldNumber = 22;
+ inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& noactionregion() const;
+ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* mutable_noactionregion();
+ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* release_noactionregion();
+
+ // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region hPanRegion = 23;
+ inline bool has_hpanregion() const;
+ inline void clear_hpanregion();
+ static const int kHPanRegionFieldNumber = 23;
+ inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& hpanregion() const;
+ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* mutable_hpanregion();
+ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* release_hpanregion();
+
+ // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vPanRegion = 24;
+ inline bool has_vpanregion() const;
+ inline void clear_vpanregion();
+ static const int kVPanRegionFieldNumber = 24;
+ inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& vpanregion() const;
+ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* mutable_vpanregion();
+ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* release_vpanregion();
+
// optional .mozilla.layers.layerscope.LayersPacket.Layer.Region valid = 100;
inline bool has_valid() const;
inline void clear_valid();
@@ -1129,6 +1169,16 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite {
inline void clear_has_barid();
inline void set_has_mask();
inline void clear_has_mask();
+ inline void set_has_hitregion();
+ inline void clear_has_hitregion();
+ inline void set_has_dispatchregion();
+ inline void clear_has_dispatchregion();
+ inline void set_has_noactionregion();
+ inline void clear_has_noactionregion();
+ inline void set_has_hpanregion();
+ inline void clear_has_hpanregion();
+ inline void set_has_vpanregion();
+ inline void clear_has_vpanregion();
inline void set_has_valid();
inline void clear_has_valid();
inline void set_has_color();
@@ -1153,6 +1203,11 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite {
int direct_;
::google::protobuf::uint64 barid_;
::google::protobuf::uint64 mask_;
+ ::mozilla::layers::layerscope::LayersPacket_Layer_Region* hitregion_;
+ ::mozilla::layers::layerscope::LayersPacket_Layer_Region* dispatchregion_;
+ ::mozilla::layers::layerscope::LayersPacket_Layer_Region* noactionregion_;
+ ::mozilla::layers::layerscope::LayersPacket_Layer_Region* hpanregion_;
+ ::mozilla::layers::layerscope::LayersPacket_Layer_Region* vpanregion_;
::mozilla::layers::layerscope::LayersPacket_Layer_Region* valid_;
::google::protobuf::uint32 color_;
int filter_;
@@ -1160,7 +1215,7 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite {
::mozilla::layers::layerscope::LayersPacket_Layer_Size* size_;
mutable int _cached_size_;
- ::google::protobuf::uint32 _has_bits_[(18 + 31) / 32];
+ ::google::protobuf::uint32 _has_bits_[(23 + 31) / 32];
friend void protobuf_AddDesc_LayerScopePacket_2eproto();
friend void protobuf_AssignDesc_LayerScopePacket_2eproto();
@@ -2796,15 +2851,160 @@ inline void LayersPacket_Layer::set_mask(::google::protobuf::uint64 value) {
mask_ = value;
}
+// optional .mozilla.layers.layerscope.LayersPacket.Layer.Region hitRegion = 20;
+inline bool LayersPacket_Layer::has_hitregion() const {
+ return (_has_bits_[0] & 0x00002000u) != 0;
+}
+inline void LayersPacket_Layer::set_has_hitregion() {
+ _has_bits_[0] |= 0x00002000u;
+}
+inline void LayersPacket_Layer::clear_has_hitregion() {
+ _has_bits_[0] &= ~0x00002000u;
+}
+inline void LayersPacket_Layer::clear_hitregion() {
+ if (hitregion_ != NULL) hitregion_->::mozilla::layers::layerscope::LayersPacket_Layer_Region::Clear();
+ clear_has_hitregion();
+}
+inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& LayersPacket_Layer::hitregion() const {
+ return hitregion_ != NULL ? *hitregion_ : *default_instance_->hitregion_;
+}
+inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::mutable_hitregion() {
+ set_has_hitregion();
+ if (hitregion_ == NULL) hitregion_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Region;
+ return hitregion_;
+}
+inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::release_hitregion() {
+ clear_has_hitregion();
+ ::mozilla::layers::layerscope::LayersPacket_Layer_Region* temp = hitregion_;
+ hitregion_ = NULL;
+ return temp;
+}
+
+// optional .mozilla.layers.layerscope.LayersPacket.Layer.Region dispatchRegion = 21;
+inline bool LayersPacket_Layer::has_dispatchregion() const {
+ return (_has_bits_[0] & 0x00004000u) != 0;
+}
+inline void LayersPacket_Layer::set_has_dispatchregion() {
+ _has_bits_[0] |= 0x00004000u;
+}
+inline void LayersPacket_Layer::clear_has_dispatchregion() {
+ _has_bits_[0] &= ~0x00004000u;
+}
+inline void LayersPacket_Layer::clear_dispatchregion() {
+ if (dispatchregion_ != NULL) dispatchregion_->::mozilla::layers::layerscope::LayersPacket_Layer_Region::Clear();
+ clear_has_dispatchregion();
+}
+inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& LayersPacket_Layer::dispatchregion() const {
+ return dispatchregion_ != NULL ? *dispatchregion_ : *default_instance_->dispatchregion_;
+}
+inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::mutable_dispatchregion() {
+ set_has_dispatchregion();
+ if (dispatchregion_ == NULL) dispatchregion_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Region;
+ return dispatchregion_;
+}
+inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::release_dispatchregion() {
+ clear_has_dispatchregion();
+ ::mozilla::layers::layerscope::LayersPacket_Layer_Region* temp = dispatchregion_;
+ dispatchregion_ = NULL;
+ return temp;
+}
+
+// optional .mozilla.layers.layerscope.LayersPacket.Layer.Region noActionRegion = 22;
+inline bool LayersPacket_Layer::has_noactionregion() const {
+ return (_has_bits_[0] & 0x00008000u) != 0;
+}
+inline void LayersPacket_Layer::set_has_noactionregion() {
+ _has_bits_[0] |= 0x00008000u;
+}
+inline void LayersPacket_Layer::clear_has_noactionregion() {
+ _has_bits_[0] &= ~0x00008000u;
+}
+inline void LayersPacket_Layer::clear_noactionregion() {
+ if (noactionregion_ != NULL) noactionregion_->::mozilla::layers::layerscope::LayersPacket_Layer_Region::Clear();
+ clear_has_noactionregion();
+}
+inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& LayersPacket_Layer::noactionregion() const {
+ return noactionregion_ != NULL ? *noactionregion_ : *default_instance_->noactionregion_;
+}
+inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::mutable_noactionregion() {
+ set_has_noactionregion();
+ if (noactionregion_ == NULL) noactionregion_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Region;
+ return noactionregion_;
+}
+inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::release_noactionregion() {
+ clear_has_noactionregion();
+ ::mozilla::layers::layerscope::LayersPacket_Layer_Region* temp = noactionregion_;
+ noactionregion_ = NULL;
+ return temp;
+}
+
+// optional .mozilla.layers.layerscope.LayersPacket.Layer.Region hPanRegion = 23;
+inline bool LayersPacket_Layer::has_hpanregion() const {
+ return (_has_bits_[0] & 0x00010000u) != 0;
+}
+inline void LayersPacket_Layer::set_has_hpanregion() {
+ _has_bits_[0] |= 0x00010000u;
+}
+inline void LayersPacket_Layer::clear_has_hpanregion() {
+ _has_bits_[0] &= ~0x00010000u;
+}
+inline void LayersPacket_Layer::clear_hpanregion() {
+ if (hpanregion_ != NULL) hpanregion_->::mozilla::layers::layerscope::LayersPacket_Layer_Region::Clear();
+ clear_has_hpanregion();
+}
+inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& LayersPacket_Layer::hpanregion() const {
+ return hpanregion_ != NULL ? *hpanregion_ : *default_instance_->hpanregion_;
+}
+inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::mutable_hpanregion() {
+ set_has_hpanregion();
+ if (hpanregion_ == NULL) hpanregion_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Region;
+ return hpanregion_;
+}
+inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::release_hpanregion() {
+ clear_has_hpanregion();
+ ::mozilla::layers::layerscope::LayersPacket_Layer_Region* temp = hpanregion_;
+ hpanregion_ = NULL;
+ return temp;
+}
+
+// optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vPanRegion = 24;
+inline bool LayersPacket_Layer::has_vpanregion() const {
+ return (_has_bits_[0] & 0x00020000u) != 0;
+}
+inline void LayersPacket_Layer::set_has_vpanregion() {
+ _has_bits_[0] |= 0x00020000u;
+}
+inline void LayersPacket_Layer::clear_has_vpanregion() {
+ _has_bits_[0] &= ~0x00020000u;
+}
+inline void LayersPacket_Layer::clear_vpanregion() {
+ if (vpanregion_ != NULL) vpanregion_->::mozilla::layers::layerscope::LayersPacket_Layer_Region::Clear();
+ clear_has_vpanregion();
+}
+inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& LayersPacket_Layer::vpanregion() const {
+ return vpanregion_ != NULL ? *vpanregion_ : *default_instance_->vpanregion_;
+}
+inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::mutable_vpanregion() {
+ set_has_vpanregion();
+ if (vpanregion_ == NULL) vpanregion_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Region;
+ return vpanregion_;
+}
+inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::release_vpanregion() {
+ clear_has_vpanregion();
+ ::mozilla::layers::layerscope::LayersPacket_Layer_Region* temp = vpanregion_;
+ vpanregion_ = NULL;
+ return temp;
+}
+
// optional .mozilla.layers.layerscope.LayersPacket.Layer.Region valid = 100;
inline bool LayersPacket_Layer::has_valid() const {
- return (_has_bits_[0] & 0x00002000u) != 0;
+ return (_has_bits_[0] & 0x00040000u) != 0;
}
inline void LayersPacket_Layer::set_has_valid() {
- _has_bits_[0] |= 0x00002000u;
+ _has_bits_[0] |= 0x00040000u;
}
inline void LayersPacket_Layer::clear_has_valid() {
- _has_bits_[0] &= ~0x00002000u;
+ _has_bits_[0] &= ~0x00040000u;
}
inline void LayersPacket_Layer::clear_valid() {
if (valid_ != NULL) valid_->::mozilla::layers::layerscope::LayersPacket_Layer_Region::Clear();
@@ -2827,13 +3027,13 @@ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_La
// optional uint32 color = 101;
inline bool LayersPacket_Layer::has_color() const {
- return (_has_bits_[0] & 0x00004000u) != 0;
+ return (_has_bits_[0] & 0x00080000u) != 0;
}
inline void LayersPacket_Layer::set_has_color() {
- _has_bits_[0] |= 0x00004000u;
+ _has_bits_[0] |= 0x00080000u;
}
inline void LayersPacket_Layer::clear_has_color() {
- _has_bits_[0] &= ~0x00004000u;
+ _has_bits_[0] &= ~0x00080000u;
}
inline void LayersPacket_Layer::clear_color() {
color_ = 0u;
@@ -2849,13 +3049,13 @@ inline void LayersPacket_Layer::set_color(::google::protobuf::uint32 value) {
// optional .mozilla.layers.layerscope.LayersPacket.Layer.Filter filter = 102;
inline bool LayersPacket_Layer::has_filter() const {
- return (_has_bits_[0] & 0x00008000u) != 0;
+ return (_has_bits_[0] & 0x00100000u) != 0;
}
inline void LayersPacket_Layer::set_has_filter() {
- _has_bits_[0] |= 0x00008000u;
+ _has_bits_[0] |= 0x00100000u;
}
inline void LayersPacket_Layer::clear_has_filter() {
- _has_bits_[0] &= ~0x00008000u;
+ _has_bits_[0] &= ~0x00100000u;
}
inline void LayersPacket_Layer::clear_filter() {
filter_ = 0;
@@ -2872,13 +3072,13 @@ inline void LayersPacket_Layer::set_filter(::mozilla::layers::layerscope::Layers
// optional uint64 refID = 103;
inline bool LayersPacket_Layer::has_refid() const {
- return (_has_bits_[0] & 0x00010000u) != 0;
+ return (_has_bits_[0] & 0x00200000u) != 0;
}
inline void LayersPacket_Layer::set_has_refid() {
- _has_bits_[0] |= 0x00010000u;
+ _has_bits_[0] |= 0x00200000u;
}
inline void LayersPacket_Layer::clear_has_refid() {
- _has_bits_[0] &= ~0x00010000u;
+ _has_bits_[0] &= ~0x00200000u;
}
inline void LayersPacket_Layer::clear_refid() {
refid_ = GOOGLE_ULONGLONG(0);
@@ -2894,13 +3094,13 @@ inline void LayersPacket_Layer::set_refid(::google::protobuf::uint64 value) {
// optional .mozilla.layers.layerscope.LayersPacket.Layer.Size size = 104;
inline bool LayersPacket_Layer::has_size() const {
- return (_has_bits_[0] & 0x00020000u) != 0;
+ return (_has_bits_[0] & 0x00400000u) != 0;
}
inline void LayersPacket_Layer::set_has_size() {
- _has_bits_[0] |= 0x00020000u;
+ _has_bits_[0] |= 0x00400000u;
}
inline void LayersPacket_Layer::clear_has_size() {
- _has_bits_[0] &= ~0x00020000u;
+ _has_bits_[0] &= ~0x00400000u;
}
inline void LayersPacket_Layer::clear_size() {
if (size_ != NULL) size_->::mozilla::layers::layerscope::LayersPacket_Layer_Size::Clear();
diff --git a/gfx/layers/protobuf/LayerScopePacket.proto b/gfx/layers/protobuf/LayerScopePacket.proto
index 724f7801ab24c..9beaafc81bff6 100644
--- a/gfx/layers/protobuf/LayerScopePacket.proto
+++ b/gfx/layers/protobuf/LayerScopePacket.proto
@@ -97,6 +97,11 @@ message LayersPacket {
optional ScrollingDirect direct = 17;
optional uint64 barID = 18;
optional uint64 mask = 19; // mask layer
+ optional Region hitRegion = 20;
+ optional Region dispatchRegion = 21;
+ optional Region noActionRegion = 22;
+ optional Region hPanRegion = 23;
+ optional Region vPanRegion = 24;
// Specific info (100 to max)
// Painted Layer
From 93dcf227cd10b645dd6221270562a375c6c7aef7 Mon Sep 17 00:00:00 2001
From: Tim Nguyen
Date: Thu, 21 May 2015 12:16:00 +0200
Subject: [PATCH 010/151] Bug 1166867 - Support -moz-os-version: windows-win10.
r=jimm
---
layout/style/nsMediaFeatures.cpp | 1 +
widget/LookAndFeel.h | 9 +++++----
widget/windows/nsLookAndFeel.cpp | 8 +++++---
3 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/layout/style/nsMediaFeatures.cpp b/layout/style/nsMediaFeatures.cpp
index 30cbbb28b8844..d3a15e7480025 100644
--- a/layout/style/nsMediaFeatures.cpp
+++ b/layout/style/nsMediaFeatures.cpp
@@ -61,6 +61,7 @@ const OperatingSystemVersionInfo osVersionStrings[] = {
{ LookAndFeel::eOperatingSystemVersion_WindowsVista, L"windows-vista" },
{ LookAndFeel::eOperatingSystemVersion_Windows7, L"windows-win7" },
{ LookAndFeel::eOperatingSystemVersion_Windows8, L"windows-win8" },
+ { LookAndFeel::eOperatingSystemVersion_Windows10, L"windows-win10" }
};
#endif
diff --git a/widget/LookAndFeel.h b/widget/LookAndFeel.h
index df3fa4a52f1f0..98816b2d3ea2d 100644
--- a/widget/LookAndFeel.h
+++ b/widget/LookAndFeel.h
@@ -165,7 +165,7 @@ class LookAndFeel
// Hyperlink color extracted from the system, not affected by the
// browser.anchor_color user pref.
- // There is no OS-specified safe background color for this text,
+ // There is no OS-specified safe background color for this text,
// but it is used regularly within Windows and the Gnome DE on Dialog and
// Window colors.
eColorID__moz_nativehyperlinktext,
@@ -393,13 +393,13 @@ class LookAndFeel
* is shown.
*/
eIntID_PhysicalHomeButton,
-
+
/*
* Controls whether overlay scrollbars display when the user moves
* the mouse in a scrollable frame.
*/
eIntID_ScrollbarDisplayOnMouseMove,
-
+
/*
* Overlay scrollbar animation constants.
*/
@@ -430,6 +430,7 @@ class LookAndFeel
eOperatingSystemVersion_WindowsVista,
eOperatingSystemVersion_Windows7,
eOperatingSystemVersion_Windows8,
+ eOperatingSystemVersion_Windows10,
eOperatingSystemVersion_Unknown
};
@@ -444,7 +445,7 @@ class LookAndFeel
enum {
// single arrow at each end
eScrollArrowStyle_Single =
- eScrollArrow_StartBackward | eScrollArrow_EndForward,
+ eScrollArrow_StartBackward | eScrollArrow_EndForward,
// both arrows at bottom/right, none at top/left
eScrollArrowStyle_BothAtBottom =
eScrollArrow_EndBackward | eScrollArrow_EndForward,
diff --git a/widget/windows/nsLookAndFeel.cpp b/widget/windows/nsLookAndFeel.cpp
index 7058ef31f03fa..e4177d57bfd58 100644
--- a/widget/windows/nsLookAndFeel.cpp
+++ b/widget/windows/nsLookAndFeel.cpp
@@ -28,7 +28,9 @@ nsLookAndFeel::GetOperatingSystemVersion()
return version;
}
- if (IsWin8OrLater()) {
+ if (IsWin10OrLater()) {
+ version = eOperatingSystemVersion_Windows10;
+ } else if (IsWin8OrLater()) {
version = eOperatingSystemVersion_Windows8;
} else if (IsWin7OrLater()) {
version = eOperatingSystemVersion_Windows7;
@@ -59,7 +61,7 @@ static nsresult GetColorFromTheme(nsUXThemeClass cls,
static int32_t GetSystemParam(long flag, int32_t def)
{
- DWORD value;
+ DWORD value;
return ::SystemParametersInfo(flag, 0, &value, 0) ? value : def;
}
@@ -354,7 +356,7 @@ nsLookAndFeel::GetIntImpl(IntID aID, int32_t &aResult)
aResult = ::GetSystemMetrics(SM_CYDRAG) - 1;
break;
case eIntID_UseAccessibilityTheme:
- // High contrast is a misnomer under Win32 -- any theme can be used with it,
+ // High contrast is a misnomer under Win32 -- any theme can be used with it,
// e.g. normal contrast with large fonts, low contrast, etc.
// The high contrast flag really means -- use this theme and don't override it.
aResult = nsUXThemeData::IsHighContrastOn();
From f222d23c4eba5ee066150073bead83aec14810a1 Mon Sep 17 00:00:00 2001
From: Matt Brubeck
Date: Wed, 27 May 2015 19:06:33 -0700
Subject: [PATCH 011/151] Bug 1169088 - Remove unused nsBidiPresUtils methods.
r=dbaron
These were used only in nsSVGGlyphFrame which was removed in bug 889736.
---
layout/base/nsBidiPresUtils.cpp | 119 --------------------------------
layout/base/nsBidiPresUtils.h | 28 --------
2 files changed, 147 deletions(-)
diff --git a/layout/base/nsBidiPresUtils.cpp b/layout/base/nsBidiPresUtils.cpp
index 3a82eeb60c688..489d390ad1699 100644
--- a/layout/base/nsBidiPresUtils.cpp
+++ b/layout/base/nsBidiPresUtils.cpp
@@ -2250,125 +2250,6 @@ nsresult nsBidiPresUtils::ProcessTextForRenderingContext(const char16_t* a
aMode, aPosResolve, aPosResolveCount, aWidth, &bidiEngine);
}
-/* static */
-void nsBidiPresUtils::WriteReverse(const char16_t* aSrc,
- uint32_t aSrcLength,
- char16_t* aDest)
-{
- char16_t* dest = aDest + aSrcLength;
- mozilla::unicode::ClusterIterator iter(aSrc, aSrcLength);
-
- while (!iter.AtEnd()) {
- iter.Next();
- for (const char16_t *cp = iter; cp > aSrc; ) {
- // Here we rely on the fact that there are no non-BMP mirrored pairs
- // currently in Unicode, so we don't need to look for surrogates
- *--dest = mozilla::unicode::GetMirroredChar(*--cp);
- }
- aSrc = iter;
- }
-
- NS_ASSERTION(dest == aDest, "Whole string not copied");
-}
-
-/* static */
-bool nsBidiPresUtils::WriteLogicalToVisual(const char16_t* aSrc,
- uint32_t aSrcLength,
- char16_t* aDest,
- nsBidiLevel aBaseDirection,
- nsBidi* aBidiEngine)
-{
- const char16_t* src = aSrc;
- nsresult rv = aBidiEngine->SetPara(src, aSrcLength, aBaseDirection, nullptr);
- if (NS_FAILED(rv)) {
- return false;
- }
-
- nsBidiDirection dir;
- rv = aBidiEngine->GetDirection(&dir);
- // NSBIDI_LTR returned from GetDirection means the whole text is LTR
- if (NS_FAILED(rv) || dir == NSBIDI_LTR) {
- return false;
- }
-
- int32_t runCount;
- rv = aBidiEngine->CountRuns(&runCount);
- if (NS_FAILED(rv)) {
- return false;
- }
-
- int32_t runIndex, start, length;
- char16_t* dest = aDest;
-
- for (runIndex = 0; runIndex < runCount; ++runIndex) {
- rv = aBidiEngine->GetVisualRun(runIndex, &start, &length, &dir);
- if (NS_FAILED(rv)) {
- return false;
- }
-
- src = aSrc + start;
-
- if (dir == NSBIDI_RTL) {
- WriteReverse(src, length, dest);
- dest += length;
- } else {
- do {
- NS_ASSERTION(src >= aSrc && src < aSrc + aSrcLength,
- "logical index out of range");
- NS_ASSERTION(dest < aDest + aSrcLength, "visual index out of range");
- *(dest++) = *(src++);
- } while (--length);
- }
- }
-
- NS_ASSERTION(static_cast(dest - aDest) == aSrcLength,
- "whole string not copied");
- return true;
-}
-
-void nsBidiPresUtils::CopyLogicalToVisual(const nsAString& aSource,
- nsAString& aDest,
- nsBidiLevel aBaseDirection,
- bool aOverride)
-{
- aDest.SetLength(0);
- uint32_t srcLength = aSource.Length();
- if (srcLength == 0)
- return;
- if (!aDest.SetLength(srcLength, fallible)) {
- return;
- }
- nsAString::const_iterator fromBegin, fromEnd;
- nsAString::iterator toBegin;
- aSource.BeginReading(fromBegin);
- aSource.EndReading(fromEnd);
- aDest.BeginWriting(toBegin);
-
- if (aOverride) {
- if (aBaseDirection == NSBIDI_RTL) {
- // no need to use the converter -- just copy the string in reverse order
- WriteReverse(fromBegin.get(), srcLength, toBegin.get());
- } else {
- // if aOverride && aBaseDirection == NSBIDI_LTR, fall through to the
- // simple copy
- aDest.SetLength(0);
- }
- } else {
- nsBidi bidiEngine;
- if (!WriteLogicalToVisual(fromBegin.get(), srcLength, toBegin.get(),
- aBaseDirection, &bidiEngine)) {
- aDest.SetLength(0);
- }
- }
-
- if (aDest.IsEmpty()) {
- // Either there was an error or the source is unidirectional
- // left-to-right. In either case, just copy source to dest.
- CopyUnicodeTo(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd),
- aDest);
- }
-}
-
/* static */
nsBidiLevel
nsBidiPresUtils::BidiLevelFromStyle(nsStyleContext* aStyleContext)
diff --git a/layout/base/nsBidiPresUtils.h b/layout/base/nsBidiPresUtils.h
index b6db05ea7d197..c7a60f8a5b0b5 100644
--- a/layout/base/nsBidiPresUtils.h
+++ b/layout/base/nsBidiPresUtils.h
@@ -354,24 +354,6 @@ class nsBidiPresUtils {
nscoord* aWidth,
nsBidi* aBidiEngine);
- /**
- * Make a copy of a string, converting from logical to visual order
- *
- * @param aSource the source string
- * @param aDest the destination string
- * @param aBaseDirection the base direction of the string
- * (NSBIDI_LTR or NSBIDI_RTL to force the base direction;
- * NSBIDI_DEFAULT_LTR or NSBIDI_DEFAULT_RTL to let the bidi engine
- * determine the direction from rules P2 and P3 of the bidi algorithm.
- * @see nsBidi::GetPara
- * @param aOverride if TRUE, the text has a bidi override, according to
- * the direction in aDir
- */
- static void CopyLogicalToVisual(const nsAString& aSource,
- nsAString& aDest,
- nsBidiLevel aBaseDirection,
- bool aOverride);
-
/**
* Use style attributes to determine the base paragraph level to pass to the
* bidi algorithm.
@@ -557,16 +539,6 @@ class nsBidiPresUtils {
static void StripBidiControlCharacters(char16_t* aText,
int32_t& aTextLength);
-
- static bool WriteLogicalToVisual(const char16_t* aSrc,
- uint32_t aSrcLength,
- char16_t* aDest,
- nsBidiLevel aBaseDirection,
- nsBidi* aBidiEngine);
-
- static void WriteReverse(const char16_t* aSrc,
- uint32_t aSrcLength,
- char16_t* aDest);
};
#endif /* nsBidiPresUtils_h___ */
From b215dd5f0e999d4755a2191ed1872cd7efda72c8 Mon Sep 17 00:00:00 2001
From: Jon Coppeard
Date: Thu, 28 May 2015 09:57:57 +0100
Subject: [PATCH 012/151] Bug 1154391 - Update import declarations to current
ES6 spec r=shu
---
js/src/frontend/ParseNode.h | 2 +
js/src/frontend/Parser.cpp | 178 ++++++++++++------
js/src/frontend/Parser.h | 2 +
.../tests/modules/import-declaration.js | 152 +++++++++++++++
js/src/js.msg | 5 +-
js/src/jsreflect.cpp | 1 +
js/src/vm/CommonPropertyNames.h | 1 +
js/src/vm/Xdr.h | 4 +-
8 files changed, 282 insertions(+), 63 deletions(-)
diff --git a/js/src/frontend/ParseNode.h b/js/src/frontend/ParseNode.h
index 498be8ac456b2..f611588352ebb 100644
--- a/js/src/frontend/ParseNode.h
+++ b/js/src/frontend/ParseNode.h
@@ -332,6 +332,8 @@ enum ParseNodeKind
* in original source, not introduced via
* constant folding or other tree rewriting
* PNK_LABEL name pn_atom: label, pn_expr: labeled statement
+ * PNK_IMPORT binary pn_left: PNK_IMPORT_SPEC_LIST import specifiers
+ * pn_right: PNK_STRING module specifier
*
*
* All left-associated binary trees of the same type are optimized into lists
diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp
index 1b342a6d7a872..acc44768b5aaf 100644
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -4177,6 +4177,105 @@ Parser::letDeclarationOrBlock(YieldHandling yieldHandling)
return SyntaxParseHandler::NodeFailure;
}
+template<>
+bool
+Parser::namedImportsOrNamespaceImport(TokenKind tt, Node importSpecSet)
+{
+ if (tt == TOK_LC) {
+ while (true) {
+ // Handle the forms |import {} from 'a'| and
+ // |import { ..., } from 'a'| (where ... is non empty), by
+ // escaping the loop early if the next token is }.
+ if (!tokenStream.peekToken(&tt, TokenStream::KeywordIsName))
+ return false;
+
+ if (tt == TOK_RC)
+ break;
+
+ // If the next token is a keyword, the previous call to
+ // peekToken matched it as a TOK_NAME, and put it in the
+ // lookahead buffer, so this call will match keywords as well.
+ MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NO_IMPORT_NAME);
+ Node importName = newName(tokenStream.currentName());
+ if (!importName)
+ return false;
+
+ if (!tokenStream.getToken(&tt))
+ return false;
+
+ if (tt == TOK_NAME && tokenStream.currentName() == context->names().as) {
+ MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NO_BINDING_NAME);
+ } else {
+ // Keywords cannot be bound to themselves, so an import name
+ // that is a keyword is a syntax error if it is not followed
+ // by the keyword 'as'.
+ // See the ImportSpecifier production in ES6 section 15.2.2.
+ if (IsKeyword(importName->name())) {
+ JSAutoByteString bytes;
+ if (!AtomToPrintableString(context, importName->name(), &bytes))
+ return false;
+ report(ParseError, false, null(), JSMSG_AS_AFTER_RESERVED_WORD, bytes.ptr());
+ return false;
+ }
+ tokenStream.ungetToken();
+ }
+ Node bindingName = newName(tokenStream.currentName());
+ if (!bindingName)
+ return false;
+
+ Node importSpec = handler.newBinary(PNK_IMPORT_SPEC, importName, bindingName);
+ if (!importSpec)
+ return false;
+
+ handler.addList(importSpecSet, importSpec);
+
+ bool matched;
+ if (!tokenStream.matchToken(&matched, TOK_COMMA))
+ return false;
+
+ if (!matched)
+ break;
+ }
+
+ MUST_MATCH_TOKEN(TOK_RC, JSMSG_RC_AFTER_IMPORT_SPEC_LIST);
+ } else {
+ MOZ_ASSERT(tt == TOK_MUL);
+ if (!tokenStream.getToken(&tt))
+ return false;
+
+ if (tt != TOK_NAME || tokenStream.currentName() != context->names().as) {
+ report(ParseError, false, null(), JSMSG_AS_AFTER_IMPORT_STAR);
+ return false;
+ }
+
+ MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NO_BINDING_NAME);
+
+ Node importName = newName(context->names().star);
+ if (!importName)
+ return null();
+
+ Node bindingName = newName(tokenStream.currentName());
+ if (!bindingName)
+ return false;
+
+ Node importSpec = handler.newBinary(PNK_IMPORT_SPEC, importName, bindingName);
+ if (!importSpec)
+ return false;
+
+ handler.addList(importSpecSet, importSpec);
+ }
+
+ return true;
+}
+
+template<>
+bool
+Parser::namedImportsOrNamespaceImport(TokenKind tt, Node importSpecSet)
+{
+ MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
+ return false;
+}
+
template
typename ParseHandler::Node
Parser::importDeclaration()
@@ -4197,7 +4296,7 @@ Parser::importDeclaration()
if (!importSpecSet)
return null();
- if (tt == TOK_NAME || tt == TOK_LC) {
+ if (tt == TOK_NAME || tt == TOK_LC || tt == TOK_MUL) {
if (tt == TOK_NAME) {
// Handle the form |import a from 'b'|, by adding a single import
// specifier to the list, with 'default' as the import name and
@@ -4216,83 +4315,43 @@ Parser::importDeclaration()
return null();
handler.addList(importSpecSet, importSpec);
- } else {
- while (true) {
- // Handle the forms |import {} from 'a'| and
- // |import { ..., } from 'a'| (where ... is non empty), by
- // escaping the loop early if the next token is }.
- if (!tokenStream.peekToken(&tt, TokenStream::KeywordIsName))
- return null();
- if (tt == TOK_RC)
- break;
- // If the next token is a keyword, the previous call to
- // peekToken matched it as a TOK_NAME, and put it in the
- // lookahead buffer, so this call will match keywords as well.
- MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NO_IMPORT_NAME);
- Node importName = newName(tokenStream.currentName());
- if (!importName)
- return null();
+ if (!tokenStream.peekToken(&tt))
+ return null();
- if (!tokenStream.getToken(&tt))
- return null();
- if (tt == TOK_NAME && tokenStream.currentName() == context->names().as) {
- if (!tokenStream.getToken(&tt))
- return null();
- if (tt != TOK_NAME) {
- report(ParseError, false, null(), JSMSG_NO_BINDING_NAME);
- return null();
- }
- } else {
- // Keywords cannot be bound to themselves, so an import name
- // that is a keyword is a syntax error if it is not followed
- // by the keyword 'as'.
- if (IsKeyword(importName->name())) {
- JSAutoByteString bytes;
- if (!AtomToPrintableString(context, importName->name(), &bytes))
- return null();
- report(ParseError, false, null(), JSMSG_AS_AFTER_RESERVED_WORD, bytes.ptr());
- return null();
- }
- tokenStream.ungetToken();
- }
- Node bindingName = newName(tokenStream.currentName());
- if (!bindingName)
+ if (tt == TOK_COMMA) {
+ if (!tokenStream.getToken(&tt) || !tokenStream.getToken(&tt))
return null();
- Node importSpec = handler.newBinary(PNK_IMPORT_SPEC, importName, bindingName);
- if (!importSpec)
+ if (tt != TOK_LC && tt != TOK_MUL) {
+ report(ParseError, false, null(), JSMSG_NAMED_IMPORTS_OR_NAMESPACE_IMPORT);
return null();
+ }
- handler.addList(importSpecSet, importSpec);
-
- bool matched;
- if (!tokenStream.matchToken(&matched, TOK_COMMA))
+ if (!namedImportsOrNamespaceImport(tt, importSpecSet))
return null();
- if (!matched)
- break;
}
-
- MUST_MATCH_TOKEN(TOK_RC, JSMSG_RC_AFTER_IMPORT_SPEC_LIST);
+ } else {
+ if (!namedImportsOrNamespaceImport(tt, importSpecSet))
+ return null();
}
if (!tokenStream.getToken(&tt))
return null();
+
if (tt != TOK_NAME || tokenStream.currentName() != context->names().from) {
- report(ParseError, false, null(), JSMSG_FROM_AFTER_IMPORT_SPEC_SET);
+ report(ParseError, false, null(), JSMSG_FROM_AFTER_IMPORT_CLAUSE);
return null();
}
MUST_MATCH_TOKEN(TOK_STRING, JSMSG_MODULE_SPEC_AFTER_FROM);
- } else {
- if (tt != TOK_STRING) {
- report(ParseError, false, null(), JSMSG_DECLARATION_AFTER_IMPORT);
- return null();
- }
-
+ } else if (tt == TOK_STRING) {
// Handle the form |import 'a'| by leaving the list empty. This is
// equivalent to |import {} from 'a'|.
importSpecSet->pn_pos.end = importSpecSet->pn_pos.begin;
+ } else {
+ report(ParseError, false, null(), JSMSG_DECLARATION_AFTER_IMPORT);
+ return null();
}
Node moduleSpec = stringLiteral();
@@ -4302,8 +4361,7 @@ Parser::importDeclaration()
if (!MatchOrInsertSemicolon(tokenStream))
return null();
- return handler.newImportDeclaration(importSpecSet, moduleSpec,
- TokenPos(begin, pos().end));
+ return handler.newImportDeclaration(importSpecSet, moduleSpec, TokenPos(begin, pos().end));
}
template<>
diff --git a/js/src/frontend/Parser.h b/js/src/frontend/Parser.h
index 2b247f2066dd2..e443655e47fd8 100644
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -635,6 +635,8 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
Node destructuringExprWithoutYield(YieldHandling yieldHandling, BindData* data,
TokenKind tt, unsigned msg);
+ bool namedImportsOrNamespaceImport(TokenKind tt, Node importSpecSet);
+
enum ClassContext { ClassStatement, ClassExpression };
Node classDefinition(YieldHandling yieldHandling, ClassContext classContext);
diff --git a/js/src/jit-test/tests/modules/import-declaration.js b/js/src/jit-test/tests/modules/import-declaration.js
index 54596359a92af..cf5468c3f08e7 100644
--- a/js/src/jit-test/tests/modules/import-declaration.js
+++ b/js/src/jit-test/tests/modules/import-declaration.js
@@ -38,6 +38,18 @@ program([
)
]).assert(Reflect.parse("import a from 'b'"));
+program([
+ importDeclaration(
+ [
+ importSpecifier(
+ ident("*"),
+ ident("a")
+ )
+ ],
+ lit("b")
+ )
+]).assert(Reflect.parse("import * as a from 'b'"));
+
program([
importDeclaration(
[],
@@ -93,6 +105,106 @@ program([
)
]).assert(Reflect.parse("import { as as as } from 'a'"));
+program([
+ importDeclaration(
+ [
+ importSpecifier(
+ ident("default"),
+ ident("a")
+ ),
+ importSpecifier(
+ ident("*"),
+ ident("b")
+ )
+ ],
+ lit("c")
+ )
+]).assert(Reflect.parse("import a, * as b from 'c'"));
+
+program([
+ importDeclaration(
+ [
+ importSpecifier(
+ ident("default"),
+ ident("d")
+ )
+ ],
+ lit("a")
+ )
+]).assert(Reflect.parse("import d, {} from 'a'"));
+
+program([
+ importDeclaration(
+ [
+ importSpecifier(
+ ident("default"),
+ ident("d")
+ ),
+ importSpecifier(
+ ident("a"),
+ ident("a")
+ )
+ ],
+ lit("b")
+ )
+]).assert(Reflect.parse("import d, { a } from 'b'"));
+
+program([
+ importDeclaration(
+ [
+ importSpecifier(
+ ident("default"),
+ ident("d")
+ ),
+ importSpecifier(
+ ident("a"),
+ ident("b")
+ )
+ ],
+ lit("c")
+ )
+]).assert(Reflect.parse("import d, { a as b } from 'c'"));
+
+program([
+ importDeclaration(
+ [
+ importSpecifier(
+ ident("default"),
+ ident("d")
+ ),
+ importSpecifier(
+ ident("a"),
+ ident("a")
+ ),
+ importSpecifier(
+ ident("b"),
+ ident("b")
+ ),
+ ],
+ lit("c")
+ )
+]).assert(Reflect.parse("import d, { a, b } from 'c'"));
+
+program([
+ importDeclaration(
+ [
+ importSpecifier(
+ ident("default"),
+ ident("d")
+ ),
+ importSpecifier(
+ ident("a"),
+ ident("b")
+ ),
+ importSpecifier(
+ ident("c"),
+ ident("d")
+ ),
+ ],
+ lit("e")
+ )
+]).assert(Reflect.parse("import d, { a as b, c as d } from 'e'"));
+
program([
importDeclaration(
[
@@ -184,3 +296,43 @@ assertThrowsInstanceOf(function() {
assertThrowsInstanceOf(function() {
Reflect.parse("import { true } from 'a'");
}, SyntaxError);
+
+assertThrowsInstanceOf(function() {
+ Reflect.parse("import a,");
+}, SyntaxError);
+
+assertThrowsInstanceOf(function() {
+ Reflect.parse("import a, b from 'a'");
+}, SyntaxError);
+
+assertThrowsInstanceOf(function() {
+ Reflect.parse("import * as a,");
+}, SyntaxError);
+
+assertThrowsInstanceOf(function() {
+ Reflect.parse("import * as a, {} from 'a'");
+}, SyntaxError);
+
+assertThrowsInstanceOf(function() {
+ Reflect.parse("import as a from 'a'");
+}, SyntaxError);
+
+assertThrowsInstanceOf(function() {
+ Reflect.parse("import * a from 'a'");
+}, SyntaxError);
+
+assertThrowsInstanceOf(function() {
+ Reflect.parse("import * as from 'a'");
+}, SyntaxError);
+
+assertThrowsInstanceOf(function() {
+ Reflect.parse("import , {} from 'a'");
+}, SyntaxError);
+
+assertThrowsInstanceOf(function() {
+ Reflect.parse("import d, from 'a'");
+}, SyntaxError);
+
+assertThrowsInstanceOf(function() {
+ Reflect.parse("import * as true from 'b'");
+}, SyntaxError);
diff --git a/js/src/js.msg b/js/src/js.msg
index 3c5ab3cf3ea80..dc48d53274a02 100644
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -182,6 +182,7 @@ MSG_DEF(JSMSG_ACCESSOR_WRONG_ARGS, 3, JSEXN_SYNTAXERR, "{0} functions must h
MSG_DEF(JSMSG_ARGUMENTS_AND_REST, 0, JSEXN_SYNTAXERR, "'arguments' object may not be used in conjunction with a rest parameter")
MSG_DEF(JSMSG_ARRAY_COMP_LEFTSIDE, 0, JSEXN_SYNTAXERR, "invalid array comprehension left-hand side")
MSG_DEF(JSMSG_ARRAY_INIT_TOO_BIG, 0, JSEXN_INTERNALERR, "array initialiser too large")
+MSG_DEF(JSMSG_AS_AFTER_IMPORT_STAR, 0, JSEXN_SYNTAXERR, "missing keyword 'as' after import *")
MSG_DEF(JSMSG_AS_AFTER_RESERVED_WORD, 1, JSEXN_SYNTAXERR, "missing keyword 'as' after reserved word '{0}'")
MSG_DEF(JSMSG_BAD_ANON_GENERATOR_RETURN, 0, JSEXN_TYPEERR, "anonymous generator function returns a value")
MSG_DEF(JSMSG_BAD_ARROW_ARGS, 0, JSEXN_SYNTAXERR, "invalid arrow-function arguments (parentheses around the arrow-function may help)")
@@ -249,7 +250,7 @@ MSG_DEF(JSMSG_EMPTY_CONSEQUENT, 0, JSEXN_SYNTAXERR, "mistyped ; after con
MSG_DEF(JSMSG_EQUAL_AS_ASSIGN, 0, JSEXN_SYNTAXERR, "test for equality (==) mistyped as assignment (=)?")
MSG_DEF(JSMSG_EXPORT_DECL_AT_TOP_LEVEL,0, JSEXN_SYNTAXERR, "export declarations may only appear at top level")
MSG_DEF(JSMSG_FINALLY_WITHOUT_TRY, 0, JSEXN_SYNTAXERR, "finally without try")
-MSG_DEF(JSMSG_FROM_AFTER_IMPORT_SPEC_SET, 0, JSEXN_SYNTAXERR, "missing keyword 'from' after import specifier set")
+MSG_DEF(JSMSG_FROM_AFTER_IMPORT_CLAUSE, 0, JSEXN_SYNTAXERR, "missing keyword 'from' after import clause")
MSG_DEF(JSMSG_GARBAGE_AFTER_INPUT, 2, JSEXN_SYNTAXERR, "unexpected garbage after {0}, starting with {1}")
MSG_DEF(JSMSG_IDSTART_AFTER_NUMBER, 0, JSEXN_SYNTAXERR, "identifier starts immediately after numeric literal")
MSG_DEF(JSMSG_ILLEGAL_CHARACTER, 0, JSEXN_SYNTAXERR, "illegal character")
@@ -271,6 +272,8 @@ MSG_DEF(JSMSG_MISSING_OCTAL_DIGITS, 0, JSEXN_SYNTAXERR, "missing octal digits
MSG_DEF(JSMSG_MODULES_NOT_IMPLEMENTED, 0, JSEXN_SYNTAXERR, "modules are not implemented yet")
MSG_DEF(JSMSG_MODULE_SPEC_AFTER_FROM, 0, JSEXN_SYNTAXERR, "missing module specifier after 'from' keyword")
MSG_DEF(JSMSG_NAME_AFTER_DOT, 0, JSEXN_SYNTAXERR, "missing name after . operator")
+MSG_DEF(JSMSG_NAME_AFTER_IMPORT_STAR_AS, 0, JSEXN_SYNTAXERR, "missing name after import * as")
+MSG_DEF(JSMSG_NAMED_IMPORTS_OR_NAMESPACE_IMPORT, 0, JSEXN_SYNTAXERR, "expected named imports or namespace import after comma")
MSG_DEF(JSMSG_NONDEFAULT_FORMAL_AFTER_DEFAULT, 0, JSEXN_SYNTAXERR, "parameter(s) with default followed by parameter without default")
MSG_DEF(JSMSG_NO_BINDING_NAME, 0, JSEXN_SYNTAXERR, "missing binding name")
MSG_DEF(JSMSG_NO_CLASS_CONSTRUCTOR, 0, JSEXN_TYPEERR, "class default constructors not yet implemented")
diff --git a/js/src/jsreflect.cpp b/js/src/jsreflect.cpp
index 9807333bcf66f..25adf62b1ad31 100644
--- a/js/src/jsreflect.cpp
+++ b/js/src/jsreflect.cpp
@@ -2156,6 +2156,7 @@ bool
ASTSerializer::importDeclaration(ParseNode* pn, MutableHandleValue dst)
{
MOZ_ASSERT(pn->isKind(PNK_IMPORT));
+ MOZ_ASSERT(pn->isArity(PN_BINARY));
MOZ_ASSERT(pn->pn_left->isKind(PNK_IMPORT_SPEC_LIST));
MOZ_ASSERT(pn->pn_right->isKind(PNK_STRING));
diff --git a/js/src/vm/CommonPropertyNames.h b/js/src/vm/CommonPropertyNames.h
index a2bf63fed0505..9d4d1b8cee286 100644
--- a/js/src/vm/CommonPropertyNames.h
+++ b/js/src/vm/CommonPropertyNames.h
@@ -187,6 +187,7 @@
macro(signMask, signMask, "signMask") \
macro(source, source, "source") \
macro(stack, stack, "stack") \
+ macro(star, star, "*") \
macro(startTimestamp, startTimestamp, "startTimestamp") \
macro(static, static_, "static") \
macro(sticky, sticky, "sticky") \
diff --git a/js/src/vm/Xdr.h b/js/src/vm/Xdr.h
index 2bfe458f540ff..28f39537e198d 100644
--- a/js/src/vm/Xdr.h
+++ b/js/src/vm/Xdr.h
@@ -29,11 +29,11 @@ namespace js {
*
* https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode
*/
-static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 285;
+static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 286;
static const uint32_t XDR_BYTECODE_VERSION =
uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND);
-static_assert(JSErr_Limit == 394,
+static_assert(JSErr_Limit == 397,
"GREETINGS, POTENTIAL SUBTRAHEND INCREMENTER! If you added or "
"removed MSG_DEFs from js.msg, you should increment "
"XDR_BYTECODE_VERSION_SUBTRAHEND and update this assertion's "
From c9b6da8d6f972e52d4e45364d1ca9ceb384b1a9b Mon Sep 17 00:00:00 2001
From: Jon Coppeard
Date: Thu, 28 May 2015 09:57:57 +0100
Subject: [PATCH 013/151] Bug 1154391 - Update parsing of export declarations
to match current ES6 spec r=shu
---
js/src/frontend/FoldConstants.cpp | 1 +
js/src/frontend/FullParseHandler.h | 4 +
js/src/frontend/NameFunctions.cpp | 1 +
js/src/frontend/ParseNode.cpp | 1 +
js/src/frontend/ParseNode.h | 5 +
js/src/frontend/Parser.cpp | 80 ++++++++--
js/src/frontend/Parser.h | 5 +-
.../tests/modules/export-declaration.js | 140 +++++++++++++++---
js/src/js.msg | 1 +
js/src/jsreflect.cpp | 30 +++-
js/src/vm/CommonPropertyNames.h | 1 +
js/src/vm/Xdr.h | 4 +-
12 files changed, 227 insertions(+), 46 deletions(-)
diff --git a/js/src/frontend/FoldConstants.cpp b/js/src/frontend/FoldConstants.cpp
index 9d167d04dcd6f..3f450dd96eeef 100644
--- a/js/src/frontend/FoldConstants.cpp
+++ b/js/src/frontend/FoldConstants.cpp
@@ -128,6 +128,7 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result)
case PNK_IMPORT_SPEC_LIST:
case PNK_IMPORT_SPEC:
case PNK_EXPORT_FROM:
+ case PNK_EXPORT_DEFAULT:
case PNK_EXPORT_SPEC_LIST:
case PNK_EXPORT_SPEC:
case PNK_EXPORT:
diff --git a/js/src/frontend/FullParseHandler.h b/js/src/frontend/FullParseHandler.h
index 51ff365e5f62a..6d96779ef93b3 100644
--- a/js/src/frontend/FullParseHandler.h
+++ b/js/src/frontend/FullParseHandler.h
@@ -464,6 +464,10 @@ class FullParseHandler
return pn;
}
+ ParseNode* newExportDefaultDeclaration(ParseNode* kid, const TokenPos& pos) {
+ return new_(PNK_EXPORT_DEFAULT, JSOP_NOP, pos, kid);
+ }
+
ParseNode* newExprStatement(ParseNode* expr, uint32_t end) {
MOZ_ASSERT(expr->pn_pos.end <= end);
return new_(PNK_SEMI, JSOP_NOP, TokenPos(expr->pn_pos.begin, end), expr);
diff --git a/js/src/frontend/NameFunctions.cpp b/js/src/frontend/NameFunctions.cpp
index cb764d9d9555f..8e4d85d6ca6d6 100644
--- a/js/src/frontend/NameFunctions.cpp
+++ b/js/src/frontend/NameFunctions.cpp
@@ -396,6 +396,7 @@ class NameResolver
case PNK_MUTATEPROTO:
case PNK_SUPERELEM:
case PNK_EXPORT:
+ case PNK_EXPORT_DEFAULT:
MOZ_ASSERT(cur->isArity(PN_UNARY));
if (!resolve(cur->pn_kid, prefix))
return false;
diff --git a/js/src/frontend/ParseNode.cpp b/js/src/frontend/ParseNode.cpp
index 8e994c8b96784..13fe7947fa87a 100644
--- a/js/src/frontend/ParseNode.cpp
+++ b/js/src/frontend/ParseNode.cpp
@@ -238,6 +238,7 @@ PushNodeChildren(ParseNode* pn, NodeStack* stack)
case PNK_SPREAD:
case PNK_MUTATEPROTO:
case PNK_EXPORT:
+ case PNK_EXPORT_DEFAULT:
case PNK_SUPERELEM:
return PushUnaryNodeChild(pn, stack);
diff --git a/js/src/frontend/ParseNode.h b/js/src/frontend/ParseNode.h
index f611588352ebb..add179638a7d8 100644
--- a/js/src/frontend/ParseNode.h
+++ b/js/src/frontend/ParseNode.h
@@ -138,6 +138,7 @@ class UpvarCookie
F(IMPORT_SPEC) \
F(EXPORT) \
F(EXPORT_FROM) \
+ F(EXPORT_DEFAULT) \
F(EXPORT_SPEC_LIST) \
F(EXPORT_SPEC) \
F(EXPORT_BATCH_SPEC) \
@@ -334,6 +335,10 @@ enum ParseNodeKind
* PNK_LABEL name pn_atom: label, pn_expr: labeled statement
* PNK_IMPORT binary pn_left: PNK_IMPORT_SPEC_LIST import specifiers
* pn_right: PNK_STRING module specifier
+ * PNK_EXPORT unary pn_kid: declaration expression
+ * PNK_EXPORT_FROM binary pn_left: PNK_EXPORT_SPEC_LIST export specifiers
+ * pn_right: PNK_STRING module specifier
+ * PNK_EXPORT_DEFAULT unary pn_kid: export default declaration or expression
*
*
* All left-associated binary trees of the same type are optimized into lists
diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp
index acc44768b5aaf..7b3f7769c1f3f 100644
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -2598,7 +2598,7 @@ Parser::checkYieldNameValidity()
template
typename ParseHandler::Node
-Parser::functionStmt(YieldHandling yieldHandling)
+Parser::functionStmt(YieldHandling yieldHandling, DefaultHandling defaultHandling)
{
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_FUNCTION));
@@ -2620,6 +2620,9 @@ Parser::functionStmt(YieldHandling yieldHandling)
if (!checkYieldNameValidity())
return null();
name = tokenStream.currentName();
+ } else if (defaultHandling == AllowDefaultName) {
+ name = context->names().starDefaultStar;
+ tokenStream.ungetToken();
} else {
/* Unnamed function expressions are forbidden in statement context. */
report(ParseError, false, null(), JSMSG_UNNAMED_FUNCTION_STMT);
@@ -4372,9 +4375,15 @@ Parser::importDeclaration()
return SyntaxParseHandler::NodeFailure;
}
-template
-typename ParseHandler::Node
-Parser::exportDeclaration()
+template <>
+ParseNode*
+Parser::classDefinition(YieldHandling yieldHandling,
+ ClassContext classContext,
+ DefaultHandling defaultHandling);
+
+template<>
+ParseNode*
+Parser::exportDeclaration()
{
MOZ_ASSERT(tokenStream.currentToken().type == TOK_EXPORT);
@@ -4389,6 +4398,7 @@ Parser::exportDeclaration()
TokenKind tt;
if (!tokenStream.getToken(&tt))
return null();
+ bool isExportStar = tt == TOK_MUL;
switch (tt) {
case TOK_LC:
case TOK_MUL:
@@ -4445,7 +4455,7 @@ Parser::exportDeclaration()
// Handle the form |export *| by adding a special export batch
// specifier to the list.
Node exportSpec = handler.newNullary(PNK_EXPORT_BATCH_SPEC, JSOP_NOP, pos());
- if (!kid)
+ if (!exportSpec)
return null();
handler.addList(kid, exportSpec);
@@ -4463,17 +4473,25 @@ Parser::exportDeclaration()
return null();
return handler.newExportFromDeclaration(begin, kid, moduleSpec);
+ } else if (isExportStar) {
+ report(ParseError, false, null(), JSMSG_FROM_AFTER_EXPORT_STAR);
+ return null();
} else {
tokenStream.ungetToken();
}
- kid = MatchOrInsertSemicolon(tokenStream) ? kid : nullptr;
- if (!kid)
+ if (!MatchOrInsertSemicolon(tokenStream))
return null();
break;
case TOK_FUNCTION:
- kid = functionStmt(YieldIsKeyword);
+ kid = functionStmt(YieldIsKeyword, NameRequired);
+ if (!kid)
+ return null();
+ break;
+
+ case TOK_CLASS:
+ kid = classDefinition(YieldIsKeyword, ClassStatement, NameRequired);
if (!kid)
return null();
break;
@@ -4488,6 +4506,28 @@ Parser::exportDeclaration()
return null();
break;
+ case TOK_DEFAULT: {
+ if (!tokenStream.getToken(&tt))
+ return null();
+
+ switch (tt) {
+ case TOK_FUNCTION:
+ kid = functionStmt(YieldIsKeyword, AllowDefaultName);
+ break;
+ case TOK_CLASS:
+ kid = classDefinition(YieldIsKeyword, ClassStatement, AllowDefaultName);
+ break;
+ default:
+ tokenStream.ungetToken();
+ kid = assignExpr(InAllowed, YieldIsKeyword);
+ break;
+ }
+ if (!kid)
+ return null();
+
+ return handler.newExportDefaultDeclaration(kid, TokenPos(begin, pos().end));
+ }
+
case TOK_NAME:
// Handle the form |export a| in the same way as |export let a|, by
// acting as if we've just seen the let keyword. Simply unget the token
@@ -5900,7 +5940,8 @@ Parser::debuggerStatement()
template <>
ParseNode*
Parser::classDefinition(YieldHandling yieldHandling,
- ClassContext classContext)
+ ClassContext classContext,
+ DefaultHandling defaultHandling)
{
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_CLASS));
@@ -5919,9 +5960,14 @@ Parser::classDefinition(YieldHandling yieldHandling,
MOZ_ASSERT(yieldHandling != YieldIsKeyword);
name = tokenStream.currentName();
} else if (classContext == ClassStatement) {
- // Class statements must have a bound name
- report(ParseError, false, null(), JSMSG_UNNAMED_CLASS_STMT);
- return null();
+ if (defaultHandling == AllowDefaultName) {
+ name = context->names().starDefaultStar;
+ tokenStream.ungetToken();
+ } else {
+ // Class statements must have a bound name
+ report(ParseError, false, null(), JSMSG_UNNAMED_CLASS_STMT);
+ return null();
+ }
} else {
// Make sure to put it back, whatever it was
tokenStream.ungetToken();
@@ -5995,7 +6041,9 @@ Parser::classDefinition(YieldHandling yieldHandling,
template <>
SyntaxParseHandler::Node
-Parser::classDefinition(YieldHandling yieldHandling, ClassContext classContext)
+Parser::classDefinition(YieldHandling yieldHandling,
+ ClassContext classContext,
+ DefaultHandling defaultHandling)
{
MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
return SyntaxParseHandler::NodeFailure;
@@ -6140,13 +6188,13 @@ Parser::statement(YieldHandling yieldHandling, bool canHaveDirecti
// HoistableDeclaration[?Yield]
case TOK_FUNCTION:
- return functionStmt(yieldHandling);
+ return functionStmt(yieldHandling, NameRequired);
// ClassDeclaration[?Yield]
case TOK_CLASS:
if (!abortIfSyntaxParser())
return null();
- return classDefinition(yieldHandling, ClassStatement);
+ return classDefinition(yieldHandling, ClassStatement, NameRequired);
// LexicalDeclaration[In, ?Yield]
case TOK_LET:
@@ -8575,7 +8623,7 @@ Parser::primaryExpr(YieldHandling yieldHandling, TokenKind tt,
return functionExpr(invoked);
case TOK_CLASS:
- return classDefinition(yieldHandling, ClassExpression);
+ return classDefinition(yieldHandling, ClassExpression, NameRequired);
case TOK_LB:
return arrayInitializer(yieldHandling);
diff --git a/js/src/frontend/Parser.h b/js/src/frontend/Parser.h
index e443655e47fd8..918db51bd72da 100644
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -335,6 +335,7 @@ enum PropListType { ObjectLiteral, ClassBody };
// parameter everywhere.
enum YieldHandling { YieldIsName, YieldIsKeyword };
enum InHandling { InAllowed, InProhibited };
+enum DefaultHandling { NameRequired, AllowDefaultName };
template
class Parser : private JS::AutoGCRooter, public StrictModeGetter
@@ -543,7 +544,7 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
* Some parsers have two versions: an always-inlined version (with an 'i'
* suffix) and a never-inlined version (with an 'n' suffix).
*/
- Node functionStmt(YieldHandling yieldHandling);
+ Node functionStmt(YieldHandling yieldHandling, DefaultHandling defaultHandling);
Node functionExpr(InvokedPrediction invoked = PredictUninvoked);
Node statements(YieldHandling yieldHandling);
@@ -638,7 +639,7 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
bool namedImportsOrNamespaceImport(TokenKind tt, Node importSpecSet);
enum ClassContext { ClassStatement, ClassExpression };
- Node classDefinition(YieldHandling yieldHandling, ClassContext classContext);
+ Node classDefinition(YieldHandling yieldHandling, ClassContext classContext, DefaultHandling defaultHandling);
Node identifierName(YieldHandling yieldHandling);
diff --git a/js/src/jit-test/tests/modules/export-declaration.js b/js/src/jit-test/tests/modules/export-declaration.js
index b03d227e2fd87..9d3245aa58bf0 100644
--- a/js/src/jit-test/tests/modules/export-declaration.js
+++ b/js/src/jit-test/tests/modules/export-declaration.js
@@ -7,11 +7,12 @@ program = (elts) => Pattern({
type: "Program",
body: elts
})
-exportDeclaration = (declaration, specifiers, source) => Pattern({
+exportDeclaration = (declaration, specifiers, source, isDefault) => Pattern({
type: "ExportDeclaration",
declaration: declaration,
specifiers: specifiers,
- source: source
+ source: source,
+ isDefault: isDefault
});
exportSpecifier = (id, name) => Pattern({
type: "ExportSpecifier",
@@ -34,6 +35,10 @@ functionDeclaration = (id, params, body) => Pattern({
rest: null,
generator: false
});
+classDeclaration = (name) => Pattern({
+ type: "ClassStatement",
+ name: name
+});
variableDeclaration = (decls) => Pattern({
type: "VariableDeclaration",
kind: "var",
@@ -62,7 +67,8 @@ program([
exportDeclaration(
null,
[],
- null
+ null,
+ false
)
]).assert(Reflect.parse("export {}"));
@@ -75,7 +81,8 @@ program([
ident("a")
)
],
- null
+ null,
+ false
)
]).assert(Reflect.parse("export { a }"));
@@ -88,7 +95,8 @@ program([
ident("b")
)
],
- null
+ null,
+ false
)
]).assert(Reflect.parse("export { a as b }"));
@@ -101,7 +109,8 @@ program([
ident("as")
)
],
- null
+ null,
+ false
)
]).assert(Reflect.parse("export { as as as }"));
@@ -114,7 +123,8 @@ program([
ident("true")
)
],
- null
+ null,
+ false
)
]).assert(Reflect.parse("export { a as true }"));
@@ -131,7 +141,8 @@ program([
ident("b")
),
],
- null
+ null,
+ false
)
]).assert(Reflect.parse("export { a, b }"));
@@ -148,7 +159,8 @@ program([
ident("d")
),
],
- null
+ null,
+ false
)
]).assert(Reflect.parse("export { a as b, c as d }"));
@@ -156,11 +168,15 @@ program([
exportDeclaration(
null,
[
- exportBatchSpecifier()
+ exportSpecifier(
+ ident("a"),
+ ident("a")
+ )
],
- null
+ lit("b"),
+ false
)
-]).assert(Reflect.parse("export *"));
+]).assert(Reflect.parse("export { a } from 'b'"));
program([
exportDeclaration(
@@ -168,7 +184,8 @@ program([
[
exportBatchSpecifier()
],
- lit("a")
+ lit("a"),
+ false
)
]).assert(Reflect.parse("export * from 'a'"));
@@ -180,10 +197,22 @@ program([
blockStatement([])
),
null,
- null
+ null,
+ false
)
]).assert(Reflect.parse("export function f() {}"));
+program([
+ exportDeclaration(
+ classDeclaration(
+ ident("Foo")
+ ),
+ null,
+ null,
+ false
+ )
+]).assert(Reflect.parse("export class Foo { constructor() {} }"));
+
program([
exportDeclaration(
variableDeclaration([
@@ -196,7 +225,8 @@ program([
}
]),
null,
- null
+ null,
+ false
)
]).assert(Reflect.parse("export var a = 1, b = 2;"));
@@ -212,12 +242,13 @@ program([
}
]),
null,
- null
+ null,
+ false
)
]).assert(Reflect.parse("export const a = 1, b = 2;"));
// FIXME: In scripts, top level lets are converted back to vars. Fix this when
-// we implement compiling scripts as modules.
+// we implement compiling scripts as modules (bug 589199).
program([
exportDeclaration(
variableDeclaration([
@@ -230,7 +261,8 @@ program([
}
]),
null,
- null
+ null,
+ false
)
]).assert(Reflect.parse("export let a = 1, b = 2;"));
@@ -248,10 +280,68 @@ program([
}
]),
null,
- null
+ null,
+ false
)
]).assert(Reflect.parse("export a = 1, b = 2;"));
+program([
+ exportDeclaration(
+ functionDeclaration(
+ ident("*default*"),
+ [],
+ blockStatement([])
+ ),
+ null,
+ null,
+ true
+ )
+]).assert(Reflect.parse("export default function() {}"));
+
+program([
+ exportDeclaration(
+ functionDeclaration(
+ ident("foo"),
+ [],
+ blockStatement([])
+ ),
+ null,
+ null,
+ true
+ )
+]).assert(Reflect.parse("export default function foo() {}"));
+
+program([
+ exportDeclaration(
+ classDeclaration(
+ ident("*default*")
+ ),
+ null,
+ null,
+ true
+ )
+]).assert(Reflect.parse("export default class { constructor() {} }"));
+
+program([
+ exportDeclaration(
+ classDeclaration(
+ ident("Foo")
+ ),
+ null,
+ null,
+ true
+ )
+]).assert(Reflect.parse("export default class Foo { constructor() {} }"));
+
+program([
+ exportDeclaration(
+ lit(1234),
+ null,
+ null,
+ true
+ )
+]).assert(Reflect.parse("export default 1234"));
+
var loc = Reflect.parse("export { a as b } from 'c'", {
loc: true
}).body[0].loc;
@@ -289,6 +379,10 @@ assertThrowsInstanceOf(function () {
Reflect.parse("export { a } from 'b' f();");
}, SyntaxError);
+assertThrowsInstanceOf(function () {
+ Reflect.parse("export *");
+}, SyntaxError);
+
assertThrowsInstanceOf(function () {
Reflect.parse("export * from 'b' f();");
}, SyntaxError);
@@ -296,3 +390,11 @@ assertThrowsInstanceOf(function () {
assertThrowsInstanceOf(function() {
Reflect.parse("export {}\nfrom ()");
}, SyntaxError);
+
+assertThrowsInstanceOf(function() {
+ Reflect.parse("function() {}");
+}, SyntaxError);
+
+assertThrowsInstanceOf(function() {
+ Reflect.parse("class() { constructor() {} }");
+}, SyntaxError);
diff --git a/js/src/js.msg b/js/src/js.msg
index dc48d53274a02..4d84c8f4738c6 100644
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -251,6 +251,7 @@ MSG_DEF(JSMSG_EQUAL_AS_ASSIGN, 0, JSEXN_SYNTAXERR, "test for equality (=
MSG_DEF(JSMSG_EXPORT_DECL_AT_TOP_LEVEL,0, JSEXN_SYNTAXERR, "export declarations may only appear at top level")
MSG_DEF(JSMSG_FINALLY_WITHOUT_TRY, 0, JSEXN_SYNTAXERR, "finally without try")
MSG_DEF(JSMSG_FROM_AFTER_IMPORT_CLAUSE, 0, JSEXN_SYNTAXERR, "missing keyword 'from' after import clause")
+MSG_DEF(JSMSG_FROM_AFTER_EXPORT_STAR, 0, JSEXN_SYNTAXERR, "missing keyword 'from' after export *")
MSG_DEF(JSMSG_GARBAGE_AFTER_INPUT, 2, JSEXN_SYNTAXERR, "unexpected garbage after {0}, starting with {1}")
MSG_DEF(JSMSG_IDSTART_AFTER_NUMBER, 0, JSEXN_SYNTAXERR, "identifier starts immediately after numeric literal")
MSG_DEF(JSMSG_ILLEGAL_CHARACTER, 0, JSEXN_SYNTAXERR, "illegal character")
diff --git a/js/src/jsreflect.cpp b/js/src/jsreflect.cpp
index 25adf62b1ad31..5752e8d750070 100644
--- a/js/src/jsreflect.cpp
+++ b/js/src/jsreflect.cpp
@@ -610,7 +610,8 @@ class NodeBuilder
bool importSpecifier(HandleValue importName, HandleValue bindingName, TokenPos* pos, MutableHandleValue dst);
- bool exportDeclaration(HandleValue decl, NodeVector& elts, HandleValue moduleSpec, TokenPos* pos, MutableHandleValue dst);
+ bool exportDeclaration(HandleValue decl, NodeVector& elts, HandleValue moduleSpec,
+ HandleValue isDefault, TokenPos* pos, MutableHandleValue dst);
bool exportSpecifier(HandleValue bindingName, HandleValue exportName, TokenPos* pos, MutableHandleValue dst);
@@ -1524,13 +1525,13 @@ NodeBuilder::importSpecifier(HandleValue importName, HandleValue bindingName, To
bool
NodeBuilder::exportDeclaration(HandleValue decl, NodeVector& elts, HandleValue moduleSpec,
- TokenPos* pos, MutableHandleValue dst)
+ HandleValue isDefault, TokenPos* pos, MutableHandleValue dst)
{
RootedValue array(cx, NullValue());
if (decl.isNull() && !newArray(elts, &array))
return false;
- RootedValue cb(cx, callbacks[AST_IMPORT_DECL]);
+ RootedValue cb(cx, callbacks[AST_EXPORT_DECL]);
if (!cb.isNull())
return callback(cb, decl, array, moduleSpec, pos, dst);
@@ -1539,6 +1540,7 @@ NodeBuilder::exportDeclaration(HandleValue decl, NodeVector& elts, HandleValue m
"declaration", decl,
"specifiers", array,
"source", moduleSpec,
+ "isDefault", isDefault,
dst);
}
@@ -2191,13 +2193,15 @@ ASTSerializer::importSpecifier(ParseNode* pn, MutableHandleValue dst)
bool
ASTSerializer::exportDeclaration(ParseNode* pn, MutableHandleValue dst)
{
- MOZ_ASSERT(pn->isKind(PNK_EXPORT) || pn->isKind(PNK_EXPORT_FROM));
+ MOZ_ASSERT(pn->isKind(PNK_EXPORT) ||
+ pn->isKind(PNK_EXPORT_FROM) ||
+ pn->isKind(PNK_EXPORT_DEFAULT));
MOZ_ASSERT_IF(pn->isKind(PNK_EXPORT_FROM), pn->pn_right->isKind(PNK_STRING));
RootedValue decl(cx, NullValue());
NodeVector elts(cx);
- ParseNode* kid = pn->isKind(PNK_EXPORT) ? pn->pn_kid : pn->pn_left;
+ ParseNode* kid = pn->isKind(PNK_EXPORT_FROM) ? pn->pn_left: pn->pn_kid;
switch (ParseNodeKind kind = kid->getKind()) {
case PNK_EXPORT_SPEC_LIST:
if (!elts.reserve(pn->pn_left->pn_count))
@@ -2221,6 +2225,11 @@ ASTSerializer::exportDeclaration(ParseNode* pn, MutableHandleValue dst)
return false;
break;
+ case PNK_CLASS:
+ if (!classDefinition(kid, false, &decl))
+ return false;
+ break;
+
case PNK_VAR:
case PNK_CONST:
case PNK_GLOBALCONST:
@@ -2230,14 +2239,20 @@ ASTSerializer::exportDeclaration(ParseNode* pn, MutableHandleValue dst)
break;
default:
- LOCAL_NOT_REACHED("unexpected statement type");
+ if (!expression(kid, &decl))
+ return false;
+ break;
}
RootedValue moduleSpec(cx, NullValue());
if (pn->isKind(PNK_EXPORT_FROM) && !literal(pn->pn_right, &moduleSpec))
return false;
- return builder.exportDeclaration(decl, elts, moduleSpec, &pn->pn_pos, dst);
+ RootedValue isDefault(cx, BooleanValue(false));
+ if (pn->isKind(PNK_EXPORT_DEFAULT))
+ isDefault.setBoolean(true);
+
+ return builder.exportDeclaration(decl, elts, moduleSpec, isDefault, &pn->pn_pos, dst);
}
bool
@@ -2430,6 +2445,7 @@ ASTSerializer::statement(ParseNode* pn, MutableHandleValue dst)
return importDeclaration(pn, dst);
case PNK_EXPORT:
+ case PNK_EXPORT_DEFAULT:
case PNK_EXPORT_FROM:
return exportDeclaration(pn, dst);
diff --git a/js/src/vm/CommonPropertyNames.h b/js/src/vm/CommonPropertyNames.h
index 9d4d1b8cee286..ebbbd43c3566f 100644
--- a/js/src/vm/CommonPropertyNames.h
+++ b/js/src/vm/CommonPropertyNames.h
@@ -188,6 +188,7 @@
macro(source, source, "source") \
macro(stack, stack, "stack") \
macro(star, star, "*") \
+ macro(starDefaultStar, starDefaultStar, "*default*") \
macro(startTimestamp, startTimestamp, "startTimestamp") \
macro(static, static_, "static") \
macro(sticky, sticky, "sticky") \
diff --git a/js/src/vm/Xdr.h b/js/src/vm/Xdr.h
index 28f39537e198d..1121294af792b 100644
--- a/js/src/vm/Xdr.h
+++ b/js/src/vm/Xdr.h
@@ -29,11 +29,11 @@ namespace js {
*
* https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode
*/
-static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 286;
+static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 287;
static const uint32_t XDR_BYTECODE_VERSION =
uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND);
-static_assert(JSErr_Limit == 397,
+static_assert(JSErr_Limit == 398,
"GREETINGS, POTENTIAL SUBTRAHEND INCREMENTER! If you added or "
"removed MSG_DEFs from js.msg, you should increment "
"XDR_BYTECODE_VERSION_SUBTRAHEND and update this assertion's "
From 8e863f2bce6b0ecca2df8e47f5ac6b8b1512d52a Mon Sep 17 00:00:00 2001
From: Jon Coppeard
Date: Thu, 28 May 2015 09:57:57 +0100
Subject: [PATCH 014/151] Bug 1154391 - Remove export syntax that's not present
in ES6 r=shu
---
js/src/frontend/Parser.cpp | 7 --
.../basic/syntax-error-illegal-character.js | 76 +++++++++++++++++--
.../tests/modules/export-declaration.js | 27 ++-----
3 files changed, 79 insertions(+), 31 deletions(-)
diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp
index 7b3f7769c1f3f..5b965abc45207 100644
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -4528,13 +4528,6 @@ Parser::exportDeclaration()
return handler.newExportDefaultDeclaration(kid, TokenPos(begin, pos().end));
}
- case TOK_NAME:
- // Handle the form |export a| in the same way as |export let a|, by
- // acting as if we've just seen the let keyword. Simply unget the token
- // and fall through.
- //
- // XXX This |export foo = 5| syntax is *not* in ES6! Remove it!
- tokenStream.ungetToken();
case TOK_LET:
case TOK_CONST:
kid = lexicalDeclaration(YieldIsName, tt == TOK_CONST);
diff --git a/js/src/jit-test/tests/basic/syntax-error-illegal-character.js b/js/src/jit-test/tests/basic/syntax-error-illegal-character.js
index 18fede5850a25..1a8551bafa703 100644
--- a/js/src/jit-test/tests/basic/syntax-error-illegal-character.js
+++ b/js/src/jit-test/tests/basic/syntax-error-illegal-character.js
@@ -414,11 +414,6 @@ test("debugger; @");
// export
test_no_fun_no_eval("export @");
-test_no_fun_no_eval("export x @");
-test_no_fun_no_eval("export x, @");
-test_no_fun_no_eval("export x, y @");
-test_no_fun_no_eval("export x, y; @");
-
test_no_fun_no_eval("export { @");
test_no_fun_no_eval("export { x @");
test_no_fun_no_eval("export { x, @");
@@ -473,6 +468,54 @@ test_no_fun_no_eval("export const a = 1, b = @");
test_no_fun_no_eval("export const a = 1, b = 2 @");
test_no_fun_no_eval("export const a = 1, b = 2; @");
+test_no_fun_no_eval("export class @");
+test_no_fun_no_eval("export class Foo @");
+test_no_fun_no_eval("export class Foo { @");
+test_no_fun_no_eval("export class Foo { constructor @");
+test_no_fun_no_eval("export class Foo { constructor( @");
+test_no_fun_no_eval("export class Foo { constructor() @");
+test_no_fun_no_eval("export class Foo { constructor() { @");
+test_no_fun_no_eval("export class Foo { constructor() {} @");
+test_no_fun_no_eval("export class Foo { constructor() {} } @");
+test_no_fun_no_eval("export class Foo { constructor() {} }; @");
+
+test_no_fun_no_eval("export default @");
+test_no_fun_no_eval("export default 1 @");
+test_no_fun_no_eval("export default 1; @");
+
+test_no_fun_no_eval("export default function @");
+test_no_fun_no_eval("export default function() @");
+test_no_fun_no_eval("export default function() { @");
+test_no_fun_no_eval("export default function() {} @");
+test_no_fun_no_eval("export default function() {}; @");
+
+test_no_fun_no_eval("export default function foo @");
+test_no_fun_no_eval("export default function foo( @");
+test_no_fun_no_eval("export default function foo() @");
+test_no_fun_no_eval("export default function foo() { @");
+test_no_fun_no_eval("export default function foo() {} @");
+test_no_fun_no_eval("export default function foo() {}; @");
+
+test_no_fun_no_eval("export default class @");
+test_no_fun_no_eval("export default class { @");
+test_no_fun_no_eval("export default class { constructor @");
+test_no_fun_no_eval("export default class { constructor( @");
+test_no_fun_no_eval("export default class { constructor() @");
+test_no_fun_no_eval("export default class { constructor() { @");
+test_no_fun_no_eval("export default class { constructor() {} @");
+test_no_fun_no_eval("export default class { constructor() {} } @");
+test_no_fun_no_eval("export default class { constructor() {} }; @");
+
+test_no_fun_no_eval("export default class Foo @");
+test_no_fun_no_eval("export default class Foo { @");
+test_no_fun_no_eval("export default class Foo { constructor @");
+test_no_fun_no_eval("export default class Foo { constructor( @");
+test_no_fun_no_eval("export default class Foo { constructor() @");
+test_no_fun_no_eval("export default class Foo { constructor() { @");
+test_no_fun_no_eval("export default class Foo { constructor() {} @");
+test_no_fun_no_eval("export default class Foo { constructor() {} } @");
+test_no_fun_no_eval("export default class Foo { constructor() {} }; @");
+
// import
test_no_fun_no_eval("import @");
@@ -500,6 +543,29 @@ test_no_fun_no_eval("import { x as y } from 'a'; @");
test_no_fun_no_eval("import 'a' @");
test_no_fun_no_eval("import 'a'; @");
+test_no_fun_no_eval("import * @");
+test_no_fun_no_eval("import * as @");
+test_no_fun_no_eval("import * as a @");
+test_no_fun_no_eval("import * as a from @");
+test_no_fun_no_eval("import * as a from 'a' @");
+test_no_fun_no_eval("import * as a from 'a'; @");
+
+test_no_fun_no_eval("import a @");
+test_no_fun_no_eval("import a, @");
+test_no_fun_no_eval("import a, * @");
+test_no_fun_no_eval("import a, * as @");
+test_no_fun_no_eval("import a, * as b @");
+test_no_fun_no_eval("import a, * as b from @");
+test_no_fun_no_eval("import a, * as b from 'c' @");
+test_no_fun_no_eval("import a, * as b from 'c'; @");
+
+test_no_fun_no_eval("import a, { @");
+test_no_fun_no_eval("import a, { b @");
+test_no_fun_no_eval("import a, { b } @");
+test_no_fun_no_eval("import a, { b } from @");
+test_no_fun_no_eval("import a, { b } from 'c' @");
+test_no_fun_no_eval("import a, { b } from 'c'; @");
+
// label
test("a @");
diff --git a/js/src/jit-test/tests/modules/export-declaration.js b/js/src/jit-test/tests/modules/export-declaration.js
index 9d3245aa58bf0..e65ae49f710ed 100644
--- a/js/src/jit-test/tests/modules/export-declaration.js
+++ b/js/src/jit-test/tests/modules/export-declaration.js
@@ -266,25 +266,6 @@ program([
)
]).assert(Reflect.parse("export let a = 1, b = 2;"));
-// NOTE: binding lists are treated as if they were let declarations by esprima,
-// so we follow that convention.
-program([
- exportDeclaration(
- variableDeclaration([
- {
- id: ident("a"),
- init: lit(1)
- }, {
- id: ident("b"),
- init: lit(2)
- }
- ]),
- null,
- null,
- false
- )
-]).assert(Reflect.parse("export a = 1, b = 2;"));
-
program([
exportDeclaration(
functionDeclaration(
@@ -398,3 +379,11 @@ assertThrowsInstanceOf(function() {
assertThrowsInstanceOf(function() {
Reflect.parse("class() { constructor() {} }");
}, SyntaxError);
+
+assertThrowsInstanceOf(function() {
+ Reflect.parse("export x");
+}, SyntaxError);
+
+assertThrowsInstanceOf(function() {
+ Reflect.parse("export foo = 5");
+}, SyntaxError);
From 657c062d2a8d3d771075df9973a441d31fb99357 Mon Sep 17 00:00:00 2001
From: Franziskus Kiefer
Date: Wed, 27 May 2015 13:29:00 -0700
Subject: [PATCH 015/151] Bug 1165501 - using most recent referrer policy found
in the document. r=sstamm
--HG--
extra : rebase_source : 1513da5ff6a896ab4987323354458004b5ddb787
---
dom/base/nsDocument.cpp | 29 +++++----------
dom/base/test/bug704320.sjs | 35 ++++++++++++++----
dom/base/test/mochitest.ini | 2 ++
dom/base/test/test_bug1165501.html | 51 +++++++++++++++++++++++++++
parser/html/nsHtml5TreeOpExecutor.cpp | 19 +++-------
parser/html/nsHtml5TreeOpExecutor.h | 3 +-
6 files changed, 94 insertions(+), 45 deletions(-)
create mode 100644 dom/base/test/test_bug1165501.html
diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
index 66e1c05686517..d2f23772cb547 100644
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -2976,19 +2976,10 @@ nsDocument::InitCSP(nsIChannel* aChannel)
rv = csp->GetReferrerPolicy(&referrerPolicy, &hasReferrerPolicy);
NS_ENSURE_SUCCESS(rv, rv);
if (hasReferrerPolicy) {
- // Referrer policy spec (section 6.1) says that once the referrer policy
- // is set, any future attempts to change it result in No-Referrer.
- if (!mReferrerPolicySet) {
- mReferrerPolicy = static_cast(referrerPolicy);
- mReferrerPolicySet = true;
- } else if (mReferrerPolicy != referrerPolicy) {
- mReferrerPolicy = mozilla::net::RP_No_Referrer;
- {
- MOZ_LOG(gCspPRLog, PR_LOG_DEBUG, ("%s %s",
- "CSP wants to set referrer, but nsDocument"
- "already has it set. No referrers will be sent"));
- }
- }
+ // Referrer policy spec (section 6.1) says that we always use the newest
+ // referrer policy we find
+ mReferrerPolicy = static_cast(referrerPolicy);
+ mReferrerPolicySet = true;
// Referrer Policy is set separately for the speculative parser in
// nsHTMLDocument::StartDocumentLoad() so there's nothing to do here for
@@ -3776,14 +3767,10 @@ nsDocument::SetHeaderData(nsIAtom* aHeaderField, const nsAString& aData)
if (aHeaderField == nsGkAtoms::referrer && !aData.IsEmpty()) {
ReferrerPolicy policy = mozilla::net::ReferrerPolicyFromString(aData);
- // Referrer policy spec (section 6.1) says that once the referrer policy
- // is set, any future attempts to change it result in No-Referrer.
- if (!mReferrerPolicySet) {
- mReferrerPolicy = policy;
- mReferrerPolicySet = true;
- } else if (mReferrerPolicy != policy) {
- mReferrerPolicy = mozilla::net::RP_No_Referrer;
- }
+ // Referrer policy spec (section 6.1) says that we always use the newest
+ // referrer policy we find
+ mReferrerPolicy = policy;
+ mReferrerPolicySet = true;
}
}
diff --git a/dom/base/test/bug704320.sjs b/dom/base/test/bug704320.sjs
index b154475d05b21..bdcbbb4bd1834 100644
--- a/dom/base/test/bug704320.sjs
+++ b/dom/base/test/bug704320.sjs
@@ -44,17 +44,23 @@ function create2ndLevelIframeUrl(schemeFrom, schemeTo, policy, type) {
// loaded. The click triggers a redirection to file_bug704320_redirect.html,
// which in turn notifies the main window that it's time to check the test
// results.
-function createTest(schemeFrom, schemeTo, policy) {
+function createTest(schemeFrom, schemeTo, policy, optionalEarlierPolicy) {
var _createTestUrl = createTestUrl.bind(
null, schemeFrom, schemeTo, policy, 'test');
var _create2ndLevelIframeUrl = create2ndLevelIframeUrl.bind(
null, schemeFrom, schemeTo, policy);
+ var metaReferrerPolicyString = '';
+ if (optionalEarlierPolicy && optionalEarlierPolicy != '') {
+ metaReferrerPolicyString += '\n';
+ }
+ metaReferrerPolicyString += '';
+
return '\n\
\n\
\n\
- \n\
+ '+metaReferrerPolicyString+'\n\
\n\
@@ -44,10 +39,5 @@
content-box 20px
-padding-box 20px
-padding-box 50px
-padding-box 20px
-
-
diff --git a/layout/reftests/box-sizing/computed-size-reporting-ref.html b/layout/reftests/box-sizing/computed-size-reporting-ref.html
index 0784b309e0fe9..f910417e596c9 100644
--- a/layout/reftests/box-sizing/computed-size-reporting-ref.html
+++ b/layout/reftests/box-sizing/computed-size-reporting-ref.html
@@ -9,26 +9,14 @@
box-sizing:border-box;
}
- #paddingBox {
- background:gold;
- height:100px;
- box-sizing:padding-box;
- }
-
-
-
diff --git a/layout/reftests/box-sizing/computed-size-reporting.html b/layout/reftests/box-sizing/computed-size-reporting.html
index fbcd62577a1f2..227ea2cfbd26c 100644
--- a/layout/reftests/box-sizing/computed-size-reporting.html
+++ b/layout/reftests/box-sizing/computed-size-reporting.html
@@ -10,27 +10,14 @@
border: 20px solid gold;
}
- #paddingBox {
- background:gold;
- height:100px;
- box-sizing:padding-box;
- padding: 20px;
- }
-
-
-
diff --git a/layout/reftests/box-sizing/intrinsic-1a.html b/layout/reftests/box-sizing/intrinsic-1a.html
index b2e7ebf46c6a9..2a678176dd1e3 100644
--- a/layout/reftests/box-sizing/intrinsic-1a.html
+++ b/layout/reftests/box-sizing/intrinsic-1a.html
@@ -4,6 +4,6 @@
+ box-sizing: border-box;">
- The two divs should be side-by-side, not one on top of another. No red should be visible.
-
-
-
LEFT HALF
-
RIGHT HALF
-
-
diff --git a/layout/reftests/box-sizing/intrinsic-1b.html b/layout/reftests/box-sizing/intrinsic-1b.html
index 398b2e37a8db6..0bb5af75f3103 100644
--- a/layout/reftests/box-sizing/intrinsic-1b.html
+++ b/layout/reftests/box-sizing/intrinsic-1b.html
@@ -4,6 +4,6 @@
+ box-sizing: border-box;">
diff --git a/layout/reftests/box-sizing/intrinsic-1d.html b/layout/reftests/box-sizing/intrinsic-1d.html
index 6865d0b499c3a..08a982ff0ca16 100644
--- a/layout/reftests/box-sizing/intrinsic-1d.html
+++ b/layout/reftests/box-sizing/intrinsic-1d.html
@@ -4,6 +4,6 @@
+ box-sizing: border-box;">
diff --git a/layout/reftests/box-sizing/intrinsic-1e.html b/layout/reftests/box-sizing/intrinsic-1e.html
index 3b35b67544d59..c27cab66a1d32 100644
--- a/layout/reftests/box-sizing/intrinsic-1e.html
+++ b/layout/reftests/box-sizing/intrinsic-1e.html
@@ -4,6 +4,6 @@
+ box-sizing: border-box;">
diff --git a/layout/reftests/box-sizing/intrinsic-1f.html b/layout/reftests/box-sizing/intrinsic-1f.html
index 6301127267ae5..a273761ab5dea 100644
--- a/layout/reftests/box-sizing/intrinsic-1f.html
+++ b/layout/reftests/box-sizing/intrinsic-1f.html
@@ -4,6 +4,6 @@
+ box-sizing: border-box;">
diff --git a/layout/reftests/w3c-css/submitted/ui3/box-sizing-padding-box-001-ref.xht b/layout/reftests/w3c-css/submitted/ui3/box-sizing-padding-box-001-ref.xht
deleted file mode 100644
index d9a1f41e4cc4e..0000000000000
--- a/layout/reftests/w3c-css/submitted/ui3/box-sizing-padding-box-001-ref.xht
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-