import changes from tenfourfox-history:

- #469: expose adblock pref in UI (3c7ba565e) (partly)
- #483: speculative GC/CC retuning (851222ca4)
- enable intel atomic operations (8fba598e8)
- #482: better bidi M1358275 M1392181 M1428774 + backbugs (e88a717ab)
- #482: note to self (d70096a7c)
- #483: wrong way on purple buffer (otherwise OOMs result) (d1ee9ade1)
- #478 chemspill: M1446062 fixes M1446068 (d2a1328e6)
- #469: more hosts for adblock (d8ada86ef)
- M1252374 reduce mallocs in displayList generation (78a7470f6)
- #485: mostly working destructuring nested rest assignment (2edc0af3d)
- closes #486: amp up hashtables M1352889 M1352890 M1379282 (1a6015752)
- #469: more hosts and a miner for basic adblock (3b1a55df8)
- #405: fix idl (1dab98d2e)
- #469, #399: more adblock hosts, faster StringBegins/End, any-link, base/srcdoc M1247359 M843579 M1238804 (610226ea6)
- #334, closes #489: enable TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 for amtrak.com (595021326)
- #399: remove padding-box support M1166728 (845e1834f)
- #399: disable SPDY/3.1 M1287132 (540f47f9c)
- #488: basic support for DOM iterables, {NodeList,DOMTokenList}.forEach M1216751 M1290636 (8409d1511)
- closes #488: M1257849 M1244328 finish DOMTokenList transition, bustage fixes (6b1b6131e)
- #491: update certs and pins (d2003d9a6)
- closes #492: rc4 bad, increase throttle, update UAs, reduce font URL overhead, nerdwallet ATSUI font block (8f7a0cce0)
- #469: some more hosts for adblock (c1af11d1a)
This commit is contained in:
2018-05-31 20:53:21 +08:00
parent 46289f8b80
commit 1a65205c5b
74 changed files with 3131 additions and 1313 deletions
+55 -4
View File
@@ -707,6 +707,17 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
// https://github.com/AdguardTeam/AdguardFilters/issues/1278
// this may also be true for adziff.com
// don't block kxcdn
// https://github.com/EFForg/privacybadger/issues/1381
// miners
BLOK("coinhive.com") ||
BLOK("www.freecontent.stream") ||
BLOK("www.freecontent.stream.") ||
BLOK("allfontshere.press") || // caused crashes on VCF
BLOK("www.allfontshere.press") ||
// other obnoxious things
BLOK("c.amazon-adsystem.com") ||
BLOK("google-analytics.com") ||
@@ -746,6 +757,7 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
BLOK("ad.doubleclick.net") ||
BLOK("static.doubleclick.net") ||
BLOK("stats.g.doubleclick.net") ||
BLOK("pubads.g.doubleclick.net") ||
BLOK("googleads.g.doubleclick.net") ||
BLOK("securepubads.g.doubleclick.net") ||
@@ -802,6 +814,7 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
BLOK("cdn.revcontent.com") ||
BLOK("cas.criteo.com") ||
BLOK("rtax.criteo.com") ||
BLOK("static.criteo.net") ||
BLOK("jsc.idealmedia.com") ||
@@ -850,6 +863,7 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
BLOK("www.npttech.com") ||
BLOK("fw.adsafeprotected.com") ||
BLOK("cdn.adsafeprotected.com") ||
BLOK("pixel.adsafeprotected.com") ||
BLOK("static.adsafeprotected.com") ||
@@ -884,6 +898,7 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
BLOK("cdn.mediavoice.com") ||
BLOK("plugin.mediavoice.com") ||
BLOK("api-us-east.zqtk.net") ||
BLOK("segment-data.zqtk.net") ||
BLOK("d.turn.com") ||
@@ -904,6 +919,7 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
BLOK("se.monetate.net") ||
BLOK("ad.crwdcntrl.net") ||
BLOK("bcp.crwdcntrl.net") ||
BLOK("tags.crwdcntrl.net") ||
BLOK("cdn.nsstatic.net") ||
@@ -919,6 +935,7 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
BLOK("stats.cloudwp.io") ||
BLOK("ap.lijit.com") ||
BLOK("ce.lijit.com") ||
BLOK("tlx.3lift.com") ||
@@ -984,14 +1001,12 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
BLOK("cdata.carambo.la") ||
BLOK("route.carambo.la") ||
BLOK("us-u.openx.net") ||
BLOK("uk-ads.openx.net") ||
BLOK("us-ads.openx.net") ||
BLOK("s-static.innovid.com") ||
// This is controversial, but I'm pretty sure we
// don't want this.
BLOK("coinhive.com") ||
BLOK("ustatik.com") ||
BLOK("cdn.ustatik.com") ||
@@ -1007,6 +1022,42 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
BLOK("t.neodatagroup.com") ||
BLOK("ads.servebom.com") ||
BLOK("a.mailmunch.co") ||
BLOK("ads.adthrive.com") ||
BLOK("js.agkn.com") ||
BLOK("htl.bid") ||
BLOK("rtb.districtm.io") ||
BLOK("prebid.districtm.ca") ||
BLOK("speednetwork14.adk2.co") ||
BLOK("speednetwork14.adk2x.com") ||
BLOK("deloton.com") ||
BLOK("clickiocdn.com") ||
BLOK("clickioadve.com") ||
BLOK("cti.w55c.net") ||
BLOK("cdn.w55c.net") ||
BLOK("mobpushup.com") ||
BLOK("sc.iasds01.com") ||
BLOK("cdn.optimizely.com") ||
BLOK("cdn3.optimizely.com") ||
BLOK("p.d.emn0.com") ||
BLOK("p.w.emn0.com") ||
BLOK("api.b2c.com") ||
BLOK("bounceexchange.com") ||
0) {
#undef BLOK
// Yup.
+31
View File
@@ -0,0 +1,31 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* Definitions of supported tokens data types for nsDOMTokenList. This is in a
* separate header so Element.h can include it too.
*/
#ifndef mozilla_dom_DOMTokenListSupportedTokens_h
#define mozilla_dom_DOMTokenListSupportedTokens_h
namespace mozilla {
namespace dom {
// A single supported token.
typedef const char* const DOMTokenListSupportedToken;
// An array of supported tokens. This should end with a null
// DOMTokenListSupportedToken to indicate array termination. A null value for
// the DOMTokenListSupportedTokenArray means there is no definition of supported
// tokens for the given DOMTokenList. This should generally be a static table,
// or at least outlive the DOMTokenList whose constructor it's passed to.
typedef DOMTokenListSupportedToken* DOMTokenListSupportedTokenArray;
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_DOMTokenListSupportedTokens_h
+12 -12
View File
@@ -44,7 +44,6 @@
#include "nsNameSpaceManager.h"
#include "nsContentList.h"
#include "nsVariant.h"
#include "nsDOMSettableTokenList.h"
#include "nsDOMTokenList.h"
#include "nsXBLPrototypeBinding.h"
#include "nsError.h"
@@ -3086,11 +3085,11 @@ Element::GetLinkTarget(nsAString& aTarget)
}
static void
nsDOMSettableTokenListPropertyDestructor(void *aObject, nsIAtom *aProperty,
void *aPropertyValue, void *aData)
nsDOMTokenListPropertyDestructor(void *aObject, nsIAtom *aProperty,
void *aPropertyValue, void *aData)
{
nsDOMSettableTokenList* list =
static_cast<nsDOMSettableTokenList*>(aPropertyValue);
nsDOMTokenList* list =
static_cast<nsDOMTokenList*>(aPropertyValue);
NS_RELEASE(list);
}
@@ -3113,8 +3112,9 @@ Element::HTMLSVGPropertiesToTraverseAndUnlink()
return sPropertiesToTraverseAndUnlink;
}
nsDOMSettableTokenList*
Element::GetTokenList(nsIAtom* aAtom)
nsDOMTokenList*
Element::GetTokenList(nsIAtom* aAtom,
const DOMTokenListSupportedTokenArray aSupportedTokens)
{
#ifdef DEBUG
nsIAtom*** props =
@@ -3129,14 +3129,14 @@ Element::GetTokenList(nsIAtom* aAtom)
MOZ_ASSERT(found, "Trying to use an unknown tokenlist!");
#endif
nsDOMSettableTokenList* list = nullptr;
nsDOMTokenList* list = nullptr;
if (HasProperties()) {
list = static_cast<nsDOMSettableTokenList*>(GetProperty(aAtom));
list = static_cast<nsDOMTokenList*>(GetProperty(aAtom));
}
if (!list) {
list = new nsDOMSettableTokenList(this, aAtom);
list = new nsDOMTokenList(this, aAtom, aSupportedTokens);
NS_ADDREF(list);
SetProperty(aAtom, list, nsDOMSettableTokenListPropertyDestructor);
SetProperty(aAtom, list, nsDOMTokenListPropertyDestructor);
}
return list;
}
@@ -3153,7 +3153,7 @@ Element::GetTokenList(nsIAtom* aAtom, nsIVariant** aResult)
nsresult
Element::SetTokenList(nsIAtom* aAtom, nsIVariant* aValue)
{
nsDOMSettableTokenList* itemType = GetTokenList(aAtom);
nsDOMTokenList* itemType = GetTokenList(aAtom);
nsAutoString string;
aValue->GetAsAString(string);
ErrorResult rv;
+3 -2
View File
@@ -34,6 +34,7 @@
#include "nsAttrValue.h"
#include "mozilla/EventForwards.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/DOMTokenListSupportedTokens.h"
#include "mozilla/dom/WindowBinding.h"
#include "mozilla/dom/ElementBinding.h"
#include "Units.h"
@@ -44,7 +45,6 @@ class nsIURI;
class nsIScrollableFrame;
class nsAttrValueOrString;
class nsContentList;
class nsDOMSettableTokenList;
class nsDOMTokenList;
struct nsRect;
class nsFocusManager;
@@ -1342,7 +1342,8 @@ protected:
*/
virtual void GetLinkTarget(nsAString& aTarget);
nsDOMSettableTokenList* GetTokenList(nsIAtom* aAtom);
nsDOMTokenList* GetTokenList(nsIAtom* aAtom,
const DOMTokenListSupportedTokenArray aSupportedTokens = nullptr);
void GetTokenList(nsIAtom* aAtom, nsIVariant** aResult);
nsresult SetTokenList(nsIAtom* aAtom, nsIVariant* aValue);
+1 -1
View File
@@ -25,11 +25,11 @@
class ContentUnbinder;
class nsContentList;
class nsDOMAttributeMap;
class nsDOMTokenList;
class nsIControllers;
class nsICSSDeclaration;
class nsIDocument;
class nsDOMStringMap;
class nsDOMTokenList;
class nsIURI;
namespace mozilla {
+24
View File
@@ -0,0 +1,24 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
/* NOTE: no include guard; this file is meant to maybe be included multiple
times. It has a list of the sandbox keywords we support, with their
corresponding sandbox flags. */
#include "nsSandboxFlags.h"
// Each entry has the sandbox keyword as a string, the corresponding nsGkAtoms
// atom name, and the corresponding sandbox flags.
SANDBOX_KEYWORD("allow-same-origin", allowsameorigin, SANDBOXED_ORIGIN)
SANDBOX_KEYWORD("allow-forms", allowforms, SANDBOXED_FORMS)
SANDBOX_KEYWORD("allow-scripts", allowscripts,
SANDBOXED_SCRIPTS | SANDBOXED_AUTOMATIC_FEATURES)
SANDBOX_KEYWORD("allow-top-navigation", allowtopnavigation,
SANDBOXED_TOPLEVEL_NAVIGATION)
SANDBOX_KEYWORD("allow-pointer-lock", allowpointerlock, SANDBOXED_POINTER_LOCK)
SANDBOX_KEYWORD("allow-orientation-lock", alloworientationlock,
SANDBOXED_ORIENTATION_LOCK)
SANDBOX_KEYWORD("allow-popups", allowpopups, SANDBOXED_AUXILIARY_NAVIGATION)
+3 -1
View File
@@ -45,6 +45,7 @@ EXPORTS += [
'AutocompleteFieldList.h',
'Crypto.h',
'HTMLSplitOnSpacesTokenizer.h',
'IframeSandboxKeywordList.h',
'mozAutoDocUpdate.h',
'mozFlushType.h',
'nsAtomListUtils.h',
@@ -74,6 +75,7 @@ EXPORTS += [
'nsDOMJSUtils.h',
'nsDOMNavigationTiming.h',
'nsDOMString.h',
'nsDOMTokenList.h',
'nsFocusManager.h',
'nsFormData.h',
'nsFrameMessageManager.h',
@@ -174,6 +176,7 @@ EXPORTS.mozilla.dom += [
'DOMRect.h',
'DOMRequest.h',
'DOMStringList.h',
'DOMTokenListSupportedTokens.h',
'Element.h',
'ElementInlines.h',
'EventSource.h',
@@ -278,7 +281,6 @@ UNIFIED_SOURCES += [
'nsDOMNavigationTiming.cpp',
'nsDOMScriptObjectFactory.cpp',
'nsDOMSerializer.cpp',
'nsDOMSettableTokenList.cpp',
'nsDOMTokenList.cpp',
'nsDOMWindowList.cpp',
'nsFocusManager.cpp',
+3 -9
View File
@@ -1362,19 +1362,13 @@ nsContentUtils::ParseSandboxAttributeToFlags(const nsAttrValue* sandboxAttr)
| SANDBOXED_DOMAIN;
// Macro for updating the flag according to the keywords
#define IF_KEYWORD(atom, flags) \
#define SANDBOX_KEYWORD(string, atom, flags) \
if (sandboxAttr->Contains(nsGkAtoms::atom, eIgnoreCase)) { out &= ~(flags); }
IF_KEYWORD(allowsameorigin, SANDBOXED_ORIGIN)
IF_KEYWORD(allowforms, SANDBOXED_FORMS)
IF_KEYWORD(allowscripts, SANDBOXED_SCRIPTS | SANDBOXED_AUTOMATIC_FEATURES)
IF_KEYWORD(allowtopnavigation, SANDBOXED_TOPLEVEL_NAVIGATION)
IF_KEYWORD(allowpointerlock, SANDBOXED_POINTER_LOCK)
IF_KEYWORD(alloworientationlock, SANDBOXED_ORIENTATION_LOCK)
IF_KEYWORD(allowpopups, SANDBOXED_AUXILIARY_NAVIGATION)
#include "IframeSandboxKeywordList.h"
return out;
#undef IF_KEYWORD
#undef SANDBOX_KEYWORD
}
nsIBidiKeyboard*
+170 -61
View File
@@ -9,20 +9,25 @@
*/
#include "nsDOMTokenList.h"
#include "nsAttrValueInlines.h"
#include "nsDataHashtable.h"
#include "nsAttrValue.h"
#include "nsContentUtils.h"
#include "nsError.h"
#include "nsHashKeys.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/DOMTokenListBinding.h"
#include "mozilla/BloomFilter.h"
#include "mozilla/ErrorResult.h"
using namespace mozilla;
using namespace mozilla::dom;
nsDOMTokenList::nsDOMTokenList(Element* aElement, nsIAtom* aAttrAtom)
nsDOMTokenList::nsDOMTokenList(Element* aElement, nsIAtom* aAttrAtom,
const DOMTokenListSupportedTokenArray aSupportedTokens)
: mElement(aElement),
mAttrAtom(aAttrAtom)
mAttrAtom(aAttrAtom),
mSupportedTokens(aSupportedTokens)
{
// We don't add a reference to our element. If it goes away,
// we'll be told to drop our reference
@@ -50,6 +55,45 @@ nsDOMTokenList::GetParsedAttr()
return mElement->GetAttrInfo(kNameSpaceID_None, mAttrAtom).mValue;
}
void
nsDOMTokenList::RemoveDuplicates(const nsAttrValue* aAttr)
{
if (!aAttr || aAttr->Type() != nsAttrValue::eAtomArray) {
return;
}
BloomFilter<8, nsIAtom> filter;
nsAttrValue::AtomArray* array = aAttr->GetAtomArrayValue();
for (uint32_t i = 0; i < array->Length(); i++) {
nsIAtom* atom = array->ElementAt(i);
if (filter.mightContain(atom)) {
// Start again, with a hashtable
RemoveDuplicatesInternal(array, i);
return;
} else {
filter.add(atom);
}
}
}
void
nsDOMTokenList::RemoveDuplicatesInternal(nsAttrValue::AtomArray* aArray,
uint32_t aStart)
{
nsDataHashtable<nsPtrHashKey<nsIAtom>, bool> tokens;
for (uint32_t i = 0; i < aArray->Length(); i++) {
nsIAtom* atom = aArray->ElementAt(i);
// No need to check the hashtable below aStart
if (i >= aStart && tokens.Get(atom)) {
aArray->RemoveElementAt(i);
i--;
} else {
tokens.Put(atom, true);
}
}
}
uint32_t
nsDOMTokenList::Length()
{
@@ -58,6 +102,7 @@ nsDOMTokenList::Length()
return 0;
}
RemoveDuplicates(attr);
return attr->GetAtomCount();
}
@@ -66,6 +111,13 @@ nsDOMTokenList::IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aResult)
{
const nsAttrValue* attr = GetParsedAttr();
if (!attr || aIndex >= static_cast<uint32_t>(attr->GetAtomCount())) {
aFound = false;
return;
}
RemoveDuplicates(attr);
if (attr && aIndex < static_cast<uint32_t>(attr->GetAtomCount())) {
aFound = true;
attr->AtomAt(aIndex)->ToString(aResult);
@@ -74,6 +126,16 @@ nsDOMTokenList::IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aResult)
}
}
void
nsDOMTokenList::SetValue(const nsAString& aValue, ErrorResult& rv)
{
if (!mElement) {
return;
}
rv = mElement->SetAttr(kNameSpaceID_None, mAttrAtom, aValue, true);
}
nsresult
nsDOMTokenList::CheckToken(const nsAString& aStr)
{
@@ -130,10 +192,15 @@ nsDOMTokenList::AddInternal(const nsAttrValue* aAttr,
nsAutoString resultStr;
if (aAttr) {
aAttr->ToString(resultStr);
RemoveDuplicates(aAttr);
for (uint32_t i = 0; i < aAttr->GetAtomCount(); i++) {
if (i != 0) {
resultStr.AppendLiteral(" ");
}
resultStr.Append(nsDependentAtomString(aAttr->AtomAt(i)));
}
}
bool oneWasAdded = false;
nsAutoTArray<nsString, 10> addedClasses;
for (uint32_t i = 0, l = aTokens.Length(); i < l; ++i) {
@@ -144,16 +211,11 @@ nsDOMTokenList::AddInternal(const nsAttrValue* aAttr,
continue;
}
if (oneWasAdded ||
(!resultStr.IsEmpty() &&
!nsContentUtils::IsHTMLWhitespace(resultStr.Last()))) {
if (!resultStr.IsEmpty()) {
resultStr.Append(' ');
resultStr.Append(aToken);
} else {
resultStr.Append(aToken);
}
resultStr.Append(aToken);
oneWasAdded = true;
addedClasses.AppendElement(aToken);
}
@@ -186,60 +248,20 @@ nsDOMTokenList::RemoveInternal(const nsAttrValue* aAttr,
{
MOZ_ASSERT(aAttr, "Need an attribute");
nsAutoString input;
aAttr->ToString(input);
RemoveDuplicates(aAttr);
nsAString::const_iterator copyStart, tokenStart, iter, end;
input.BeginReading(iter);
input.EndReading(end);
copyStart = iter;
nsAutoString output;
bool lastTokenRemoved = false;
while (iter != end) {
// skip whitespace.
while (iter != end && nsContentUtils::IsHTMLWhitespace(*iter)) {
++iter;
nsAutoString resultStr;
for (uint32_t i = 0; i < aAttr->GetAtomCount(); i++) {
if (aTokens.Contains(nsDependentAtomString(aAttr->AtomAt(i)))) {
continue;
}
if (iter == end) {
// At this point we're sure the last seen token (if any) wasn't to be
// removed. So the trailing spaces will need to be kept.
MOZ_ASSERT(!lastTokenRemoved, "How did this happen?");
output.Append(Substring(copyStart, end));
break;
}
tokenStart = iter;
do {
++iter;
} while (iter != end && !nsContentUtils::IsHTMLWhitespace(*iter));
if (aTokens.Contains(Substring(tokenStart, iter))) {
// Skip whitespace after the token, it will be collapsed.
while (iter != end && nsContentUtils::IsHTMLWhitespace(*iter)) {
++iter;
}
copyStart = iter;
lastTokenRemoved = true;
} else {
if (lastTokenRemoved && !output.IsEmpty()) {
MOZ_ASSERT(!nsContentUtils::IsHTMLWhitespace(output.Last()),
"Invalid last output token");
output.Append(char16_t(' '));
}
lastTokenRemoved = false;
output.Append(Substring(copyStart, iter));
copyStart = iter;
if (!resultStr.IsEmpty()) {
resultStr.AppendLiteral(" ");
}
resultStr.Append(nsDependentAtomString(aAttr->AtomAt(i)));
}
mElement->SetAttr(kNameSpaceID_None, mAttrAtom, output, true);
mElement->SetAttr(kNameSpaceID_None, mAttrAtom, resultStr, true);
}
void
@@ -299,6 +321,93 @@ nsDOMTokenList::Toggle(const nsAString& aToken,
return isPresent;
}
void
nsDOMTokenList::Replace(const nsAString& aToken,
const nsAString& aNewToken,
ErrorResult& aError)
{
// Doing this here instead of using `CheckToken` because if aToken had invalid
// characters, and aNewToken is empty, the returned error should be a
// SyntaxError, not an InvalidCharacterError.
if (aNewToken.IsEmpty()) {
aError.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return;
}
aError = CheckToken(aToken);
if (aError.Failed()) {
return;
}
aError = CheckToken(aNewToken);
if (aError.Failed()) {
return;
}
const nsAttrValue* attr = GetParsedAttr();
if (!attr) {
return;
}
ReplaceInternal(attr, aToken, aNewToken);
}
void
nsDOMTokenList::ReplaceInternal(const nsAttrValue* aAttr,
const nsAString& aToken,
const nsAString& aNewToken)
{
RemoveDuplicates(aAttr);
bool sawIt = false;
nsAutoString resultStr;
for (uint32_t i = 0; i < aAttr->GetAtomCount(); i++) {
if (aAttr->AtomAt(i)->Equals(aToken) ||
aAttr->AtomAt(i)->Equals(aNewToken)) {
if (sawIt) {
// We keep only the first
continue;
}
sawIt = true;
if (!resultStr.IsEmpty()) {
resultStr.AppendLiteral(" ");
}
resultStr.Append(aNewToken);
continue;
}
if (!resultStr.IsEmpty()) {
resultStr.AppendLiteral(" ");
}
resultStr.Append(nsDependentAtomString(aAttr->AtomAt(i)));
}
if (sawIt) {
mElement->SetAttr(kNameSpaceID_None, mAttrAtom, resultStr, true);
}
}
bool
nsDOMTokenList::Supports(const nsAString& aToken,
ErrorResult& aError)
{
if (!mSupportedTokens) {
aError.ThrowTypeError<MSG_TOKENLIST_NO_SUPPORTED_TOKENS>(
mElement->LocalName(),
nsDependentAtomString(mAttrAtom));
return false;
}
for (DOMTokenListSupportedToken* supportedToken = mSupportedTokens;
*supportedToken;
++supportedToken) {
if (aToken.LowerCaseEqualsASCII(*supportedToken)) {
return true;
}
}
return false;
}
void
nsDOMTokenList::Stringify(nsAString& aResult)
{
+20 -2
View File
@@ -13,9 +13,11 @@
#include "nsCOMPtr.h"
#include "nsDOMString.h"
#include "nsDOMString.h"
#include "nsWrapperCache.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/DOMTokenListSupportedTokens.h"
namespace mozilla {
class ErrorResult;
@@ -26,7 +28,7 @@ class nsAttrValue;
class nsIAtom;
// nsISupports must be on the primary inheritance chain
// because nsDOMSettableTokenList is traversed by Element.
class nsDOMTokenList : public nsISupports,
public nsWrapperCache
{
@@ -37,7 +39,8 @@ public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMTokenList)
nsDOMTokenList(Element* aElement, nsIAtom* aAttrAtom);
nsDOMTokenList(Element* aElement, nsIAtom* aAttrAtom,
const mozilla::dom::DOMTokenListSupportedTokenArray = nullptr);
virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
@@ -46,6 +49,7 @@ public:
return mElement;
}
void RemoveDuplicates(const nsAttrValue* aAttr);
uint32_t Length();
void Item(uint32_t aIndex, nsAString& aResult)
{
@@ -63,9 +67,17 @@ public:
void Remove(const nsAString& aToken, mozilla::ErrorResult& aError);
void Remove(const nsTArray<nsString>& aTokens,
mozilla::ErrorResult& aError);
void Replace(const nsAString& aToken,
const nsAString& aNewToken,
mozilla::ErrorResult& aError);
bool Toggle(const nsAString& aToken,
const mozilla::dom::Optional<bool>& force,
mozilla::ErrorResult& aError);
bool Supports(const nsAString& aToken,
mozilla::ErrorResult& aError);
void GetValue(nsAString& aResult) { Stringify(aResult); }
void SetValue(const nsAString& aValue, mozilla::ErrorResult& rv);
void Stringify(nsAString& aResult);
protected:
@@ -73,14 +85,20 @@ protected:
nsresult CheckToken(const nsAString& aStr);
nsresult CheckTokens(const nsTArray<nsString>& aStr);
void RemoveDuplicatesInternal(nsTArray<nsCOMPtr<nsIAtom>>* aArray,
uint32_t aStart);
void AddInternal(const nsAttrValue* aAttr,
const nsTArray<nsString>& aTokens);
void RemoveInternal(const nsAttrValue* aAttr,
const nsTArray<nsString>& aTokens);
void ReplaceInternal(const nsAttrValue* aAttr,
const nsAString& aToken,
const nsAString& aNewToken);
inline const nsAttrValue* GetParsedAttr();
nsCOMPtr<Element> mElement;
nsCOMPtr<nsIAtom> mAttrAtom;
const mozilla::dom::DOMTokenListSupportedTokenArray mSupportedTokens;
};
#endif // nsDOMTokenList_h___
+21 -6
View File
@@ -347,17 +347,32 @@ public:
}
/**
* Return the base URI for relative URIs in the document (the document uri
* unless it's overridden by SetBaseURI, HTML <base> tags, etc.). The
* returned URI could be null if there is no document URI. If the document
* is a srcdoc document, return the parent document's base URL.
* Return the fallback base URL for this document, as defined in the HTML
* specification. Note that this can return null if there is no document URI.
*
* XXXbz: This doesn't implement the bits for about:blank yet.
*/
nsIURI* GetDocBaseURI() const
nsIURI* GetFallbackBaseURI() const
{
if (mIsSrcdocDocument && mParentDocument) {
return mParentDocument->GetDocBaseURI();
}
return mDocumentBaseURI ? mDocumentBaseURI : mDocumentURI;
return mDocumentURI;
}
/**
* Return the base URI for relative URIs in the document (the document uri
* unless it's overridden by SetBaseURI, HTML <base> tags, etc.). The
* returned URI could be null if there is no document URI. If the document is
* a srcdoc document and has no explicit base URL, return the parent
* document's base URL.
*/
nsIURI* GetDocBaseURI() const
{
if (mDocumentBaseURI) {
return mDocumentBaseURI;
}
return GetFallbackBaseURI();
}
virtual already_AddRefed<nsIURI> GetBaseURI(bool aTryUseXHRDocBaseURI = false) const override;
+7 -7
View File
@@ -93,16 +93,16 @@ const size_t gStackSize = 8192;
// The amount of time we wait from the first request to GC to actually
// doing the first GC.
#define NS_FIRST_GC_DELAY 10000 // ms
#define NS_FIRST_GC_DELAY 30000 // ms
#define NS_FULL_GC_DELAY 60000 // ms
#define NS_FULL_GC_DELAY 100000 // ms
// The default amount of time to wait from the user being idle to starting a
// shrinking GC.
#define NS_DEAULT_INACTIVE_GC_DELAY 300000 // ms
// Maximum amount of time that should elapse between incremental GC slices
#define NS_INTERSLICE_GC_DELAY 100 // ms
#define NS_INTERSLICE_GC_DELAY 1000 // ms
// If we haven't painted in 100ms, we allow for a longer GC budget
#define NS_INTERSLICE_GC_BUDGET 40 // ms
@@ -111,13 +111,13 @@ const size_t gStackSize = 8192;
// and doing the actual CC.
#define NS_CC_DELAY 6000 // ms
#define NS_CC_SKIPPABLE_DELAY 250 // ms
#define NS_CC_SKIPPABLE_DELAY 2500 // ms
// Maximum amount of time that should elapse between incremental CC slices
static const int64_t kICCIntersliceDelay = 32; // ms
static const int64_t kICCIntersliceDelay = 1000; // ms
// Time budget for an incremental CC slice
static const int64_t kICCSliceBudget = 5; // ms
static const int64_t kICCSliceBudget = 100; // ms
// Maximum total duration for an ICC
static const uint32_t kMaxICCDuration = 2000; // ms
@@ -125,7 +125,7 @@ static const uint32_t kMaxICCDuration = 2000; // ms
// Force a CC after this long if there's more than NS_CC_FORCED_PURPLE_LIMIT
// objects in the purple buffer.
#define NS_CC_FORCED (2 * 60 * PR_USEC_PER_SEC) // 2 min
#define NS_CC_FORCED_PURPLE_LIMIT 10
#define NS_CC_FORCED_PURPLE_LIMIT 9
// Don't allow an incremental GC to lock out the CC for too long.
#define NS_MAX_CC_LOCKEDOUT_TIME (30 * PR_USEC_PER_SEC) // 30 seconds
+3 -1
View File
@@ -149,7 +149,9 @@ nsStyleLinkElement::IsImportEnabled()
}
static uint32_t ToLinkMask(const nsAString& aLink, nsIPrincipal* aPrincipal)
{
{
// Keep this in sync with sRelValues in HTMLLinkElement.cpp
// XXX: "icon" and "search" are supported, but not listed here.
if (aLink.EqualsLiteral("prefetch"))
return nsStyleLinkElement::ePREFETCH;
else if (aLink.EqualsLiteral("dns-prefetch"))
+24 -34
View File
@@ -334,22 +334,22 @@ nsTextFragment::Append(const char16_t* aBuffer, uint32_t aLength, bool aUpdateBi
// Should we optimize for aData.Length() == 0?
CheckedUint32 length = mState.mLength;
length += aLength;
if (!length.isValid()) {
return false;
// FYI: Don't use CheckedInt in this method since here is very hot path
// in some performance tests.
if (MOZ_UNLIKELY(NS_MAX_TEXT_FRAGMENT_LENGTH - mState.mLength < aLength)) {
return false; // Would be overflown if we'd keep handling.
}
if (mState.mIs2b) {
length *= sizeof(char16_t);
if (!length.isValid()) {
return false;
size_t size = mState.mLength + aLength;
if (MOZ_UNLIKELY(SIZE_MAX / sizeof(char16_t) < size)) {
return false; // Would be overflown if we'd keep handling.
}
size *= sizeof(char16_t);
// Already a 2-byte string so the result will be too
char16_t* buff = static_cast<char16_t*>(realloc(m2b, length.value()));
if (!buff) {
char16_t* buff = static_cast<char16_t*>(realloc(m2b, size));
if (MOZ_UNLIKELY(!buff)) {
return false;
}
@@ -368,15 +368,16 @@ nsTextFragment::Append(const char16_t* aBuffer, uint32_t aLength, bool aUpdateBi
int32_t first16bit = FirstNon8Bit(aBuffer, aBuffer + aLength);
if (first16bit != -1) { // aBuffer contains no non-8bit character
length *= sizeof(char16_t);
if (!length.isValid()) {
return false;
size_t size = mState.mLength + aLength;
if (MOZ_UNLIKELY((SIZE_MAX / sizeof(char16_t)) < size)) {
return false; // Would be overflown if we'd keep handling.
}
size *= sizeof(char16_t);
// The old data was 1-byte, but the new is not so we have to expand it
// all to 2-byte
char16_t* buff = static_cast<char16_t*>(malloc(length.value()));
if (!buff) {
char16_t* buff = static_cast<char16_t*>(malloc(size));
if (MOZ_UNLIKELY(!buff)) {
return false;
}
@@ -403,16 +404,18 @@ nsTextFragment::Append(const char16_t* aBuffer, uint32_t aLength, bool aUpdateBi
}
// The new and the old data is all 1-byte
size_t size = mState.mLength + aLength;
MOZ_ASSERT(sizeof(char) == 1);
char* buff;
if (mState.mInHeap) {
buff = static_cast<char*>(realloc(const_cast<char*>(m1b), length.value()));
if (!buff) {
buff = static_cast<char*>(realloc(const_cast<char*>(m1b), size));
if (MOZ_UNLIKELY(!buff)) {
return false;
}
}
else {
buff = static_cast<char*>(malloc(length.value()));
if (!buff) {
buff = static_cast<char*>(malloc(size));
if (MOZ_UNLIKELY(!buff)) {
return false;
}
@@ -450,21 +453,8 @@ void
nsTextFragment::UpdateBidiFlag(const char16_t* aBuffer, uint32_t aLength)
{
if (mState.mIs2b && !mState.mIsBidi) {
const char16_t* cp = aBuffer;
const char16_t* end = cp + aLength;
while (cp < end) {
char16_t ch1 = *cp++;
uint32_t utf32Char = ch1;
if (NS_IS_HIGH_SURROGATE(ch1) &&
cp < end &&
NS_IS_LOW_SURROGATE(*cp)) {
char16_t ch2 = *cp++;
utf32Char = SURROGATE_TO_UCS4(ch1, ch2);
}
if (UTF32_CHAR_IS_BIDI(utf32Char) || IsBidiControl(utf32Char)) {
mState.mIsBidi = true;
break;
}
if (HasRTLChars(aBuffer, aLength)) {
mState.mIsBidi = true;
}
}
}
+4
View File
@@ -213,9 +213,13 @@ public:
uint32_t mInHeap : 1;
uint32_t mIs2b : 1;
uint32_t mIsBidi : 1;
// Note that when you change the bits of mLength, you also need to change
// NS_MAX_TEXT_FRAGMENT_LENGTH.
uint32_t mLength : 29;
};
#define NS_MAX_TEXT_FRAGMENT_LENGTH (static_cast<uint32_t>(0x1FFFFFFF))
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
private:
-4
View File
@@ -441,10 +441,6 @@ DOMInterfaces = {
'implicitJSContext': [ 'then' ],
},
'DOMSettableTokenList': {
'nativeType': 'nsDOMSettableTokenList',
},
'DOMStringMap': {
'nativeType': 'nsDOMStringMap'
},
+79 -35
View File
@@ -1136,11 +1136,13 @@ class CGHeaders(CGWrapper):
if desc.interface.maplikeOrSetlikeOrIterable:
# We need ToJSValue.h for maplike/setlike type conversions
bindingHeaders.add("mozilla/dom/ToJSValue.h")
# Add headers for the key and value types of the maplike, since
# they'll be needed for convenience functions
addHeadersForType((desc.interface.maplikeOrSetlikeOrIterable.keyType,
desc, None))
if desc.interface.maplikeOrSetlikeOrIterable.valueType:
# Add headers for the key and value types of the
# maplike/setlike/iterable, since they'll be needed for
# convenience functions
if desc.interface.maplikeOrSetlikeOrIterable.hasKeyType():
addHeadersForType((desc.interface.maplikeOrSetlikeOrIterable.keyType,
desc, None))
if desc.interface.maplikeOrSetlikeOrIterable.hasValueType():
addHeadersForType((desc.interface.maplikeOrSetlikeOrIterable.valueType,
desc, None))
@@ -2269,34 +2271,50 @@ class MethodDefiner(PropertyDefiner):
"condition": MemberCondition()
})
# Generate the maplike/setlike iterator, if one wasn't already
# generated by a method. If we already have an @@iterator symbol, fail.
if descriptor.interface.maplikeOrSetlikeOrIterable:
if hasIterator(methods, self.regular):
raise TypeError("Cannot have maplike/setlike/iterable interface with "
"other members that generate @@iterator "
"on interface %s, such as indexed getters "
"or aliased functions." %
self.descriptor.interface.identifier.name)
for m in methods:
if (m.isMaplikeOrSetlikeOrIterableMethod() and
(((m.maplikeOrSetlikeOrIterable.isMaplike() or
(m.maplikeOrSetlikeOrIterable.isIterable() and
m.maplikeOrSetlikeOrIterable.hasValueType())) and
m.identifier.name == "entries") or
(((m.maplikeOrSetlikeOrIterable.isSetlike() or
(m.maplikeOrSetlikeOrIterable.isIterable() and
not m.maplikeOrSetlikeOrIterable.hasValueType()))) and
m.identifier.name == "values"))):
self.regular.append({
"name": "@@iterator",
"methodName": m.identifier.name,
"length": methodLength(m),
"flags": "0",
"condition": PropertyDefiner.getControllingCondition(m,
descriptor),
})
break
# Generate the keys/values/entries aliases for value iterables.
maplikeOrSetlikeOrIterable = descriptor.interface.maplikeOrSetlikeOrIterable
if (not static and
not unforgeable and
maplikeOrSetlikeOrIterable and
maplikeOrSetlikeOrIterable.isIterable() and
maplikeOrSetlikeOrIterable.isValueIterator()):
# Add our keys/values/entries/forEach
self.regular.append({
"name": "keys",
"methodInfo": False,
"selfHostedName": "ArrayKeys",
"length": 0,
"flags": "JSPROP_ENUMERATE",
"condition": PropertyDefiner.getControllingCondition(m,
descriptor)
})
self.regular.append({
"name": "values",
"methodInfo": False,
"selfHostedName": "ArrayValues",
"length": 0,
"flags": "JSPROP_ENUMERATE",
"condition": PropertyDefiner.getControllingCondition(m,
descriptor)
})
self.regular.append({
"name": "entries",
"methodInfo": False,
"selfHostedName": "ArrayEntries",
"length": 0,
"flags": "JSPROP_ENUMERATE",
"condition": PropertyDefiner.getControllingCondition(m,
descriptor)
})
self.regular.append({
"name": "forEach",
"methodInfo": False,
"selfHostedName": "ArrayForEach",
"length": 1,
"flags": "JSPROP_ENUMERATE",
"condition": PropertyDefiner.getControllingCondition(m,
descriptor)
})
if not static:
stringifier = descriptor.operations['Stringifier']
@@ -13008,8 +13026,9 @@ class CGForwardDeclarations(CGWrapper):
# arguments to helper functions, and they'll need to be forward
# declared in the header.
if d.interface.maplikeOrSetlikeOrIterable:
builder.forwardDeclareForType(d.interface.maplikeOrSetlikeOrIterable.keyType,
config)
if d.interface.maplikeOrSetlikeOrIterable.hasKeyType():
builder.forwardDeclareForType(d.interface.maplikeOrSetlikeOrIterable.keyType,
config)
if d.interface.maplikeOrSetlikeOrIterable.hasValueType():
builder.forwardDeclareForType(d.interface.maplikeOrSetlikeOrIterable.valueType,
config)
@@ -15735,6 +15754,31 @@ class CGIterableMethodGenerator(CGGeneric):
using CGCallGenerator.
"""
def __init__(self, descriptor, iterable, methodName):
if methodName == "forEach":
CGGeneric.__init__(self, fill(
"""
if (!JS::IsCallable(arg0)) {
ThrowErrorMessage(cx, MSG_NOT_CALLABLE, "Argument 1 of ${ifaceName}.forEach");
return false;
}
JS::AutoValueArray<3> callArgs(cx);
callArgs[2].setObject(*obj);
JS::Rooted<JS::Value> ignoredReturnVal(cx);
for (size_t i = 0; i < self->GetIterableLength(); ++i) {
if (!ToJSValue(cx, self->GetValueAtIndex(i), callArgs[0])) {
return false;
}
if (!ToJSValue(cx, self->GetKeyAtIndex(i), callArgs[1])) {
return false;
}
if (!JS::Call(cx, arg1, arg0, JS::HandleValueArray(callArgs),
&ignoredReturnVal)) {
return false;
}
}
""",
ifaceName=descriptor.interface.identifier.name))
return
CGGeneric.__init__(self, fill(
"""
typedef ${iterClass} itrType;
+2 -5
View File
@@ -893,8 +893,5 @@ def getAllTypes(descriptors, dictionaries, callbacks):
def iteratorNativeType(descriptor):
assert descriptor.interface.isIterable()
iterableDecl = descriptor.interface.maplikeOrSetlikeOrIterable
if iterableDecl.valueType is None:
iterClass = "OneTypeIterableIterator"
else:
iterClass = "TwoTypeIterableIterator"
return "mozilla::dom::%s<%s>" % (iterClass, descriptor.nativeType)
assert iterableDecl.isPairIterator()
return "mozilla::dom::IterableIterator<%s>" % descriptor.nativeType
+1
View File
@@ -92,3 +92,4 @@ MSG_DEF(MSG_IS_NOT_PROMISE, 1, JSEXN_TYPEERR, "{0} is not a Promise")
MSG_DEF(MSG_SW_INSTALL_ERROR, 2, JSEXN_TYPEERR, "ServiceWorker script at {0} for scope {1} encountered an error during installation.")
MSG_DEF(MSG_SW_SCRIPT_THREW, 2, JSEXN_TYPEERR, "ServiceWorker script at {0} for scope {1} threw an exception during script evaluation.")
MSG_DEF(MSG_TYPEDARRAY_IS_SHARED, 1, JSEXN_TYPEERR, "{0} can't be a typed array on SharedArrayBuffer")
MSG_DEF(MSG_TOKENLIST_NO_SUPPORTED_TOKENS, 2, JSEXN_TYPEERR, "{0} attribute of <{1}> does not define any supported tokens")
+71 -164
View File
@@ -6,19 +6,17 @@
/**
* The IterableIterator class is used for WebIDL interfaces that have a
* iterable<> member defined. It handles the ES6 Iterator-like functions that
* are generated for the iterable interface.
* iterable<> member defined with two types (so a pair iterator). It handles
* the ES6 Iterator-like functions that are generated for the iterable
* interface.
*
* For iterable interfaces, the implementation class will need to
* implement these two functions:
* For iterable interfaces with a pair iterator, the implementation class will
* need to implement these two functions:
*
* - size_t GetIterableLength()
* - Returns the number of elements available to iterate over
* - [type] GetValueAtIndex(size_t index)
* - Returns the value at the requested index.
*
* If this is a two-type iterator, then the implementation class will also need to implement:
*
* - [type] GetKeyAtIndex(size_t index)
* - Returns the key at the requested index
*
@@ -60,13 +58,77 @@ protected:
};
template <typename T>
class IterableIterator : public IterableIteratorBase
class IterableIterator final : public IterableIteratorBase
{
public:
explicit IterableIterator(T* aIterableObj)
typedef bool (*WrapFunc)(JSContext* aCx,
IterableIterator<T>* aObject,
JS::Handle<JSObject*> aGivenProto,
JS::MutableHandle<JSObject*> aReflector);
explicit IterableIterator(T* aIterableObj,
IterableIteratorType aIteratorType,
WrapFunc aWrapFunc)
: mIterableObj(aIterableObj)
, mIteratorType(aIteratorType)
, mWrapFunc(aWrapFunc)
, mIndex(0)
{
MOZ_ASSERT(mIterableObj);
MOZ_ASSERT(mWrapFunc);
}
void
Next(JSContext* aCx, JS::MutableHandle<JSObject*> aResult, ErrorResult& aRv)
{
JS::Rooted<JS::Value> value(aCx, JS::UndefinedValue());
if (mIndex >= this->mIterableObj->GetIterableLength()) {
DictReturn(aCx, aResult, true, value, aRv);
return;
}
switch (mIteratorType) {
case IterableIteratorType::Keys:
{
if (!ToJSValue(aCx, this->mIterableObj->GetKeyAtIndex(mIndex), &value)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
DictReturn(aCx, aResult, false, value, aRv);
break;
}
case IterableIteratorType::Values:
{
if (!ToJSValue(aCx, this->mIterableObj->GetValueAtIndex(mIndex), &value)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
DictReturn(aCx, aResult, false, value, aRv);
break;
}
case IterableIteratorType::Entries:
{
JS::Rooted<JS::Value> key(aCx);
if (!ToJSValue(aCx, this->mIterableObj->GetKeyAtIndex(mIndex), &key)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
if (!ToJSValue(aCx, this->mIterableObj->GetValueAtIndex(mIndex), &value)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
KeyAndValueReturn(aCx, key, value, aResult, aRv);
break;
}
default:
MOZ_CRASH("Invalid iterator type!");
}
++mIndex;
}
bool
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aObj)
{
return (*mWrapFunc)(aCx, this, aGivenProto, aObj);
}
protected:
@@ -128,161 +190,6 @@ protected:
// Binding Implementation object that we're iterating over.
RefPtr<T> mIterableObj;
};
template<typename T>
class OneTypeIterableIterator final : public IterableIterator<T>
{
public:
typedef typename IterableIterator<T>::IterableIteratorType IterableIteratorType;
using IterableIterator<T>::DictReturn;
using IterableIterator<T>::KeyAndValueReturn;
typedef bool (*WrapFunc)(JSContext* aCx,
OneTypeIterableIterator<T>* aObject,
JS::Handle<JSObject*> aGivenProto,
JS::MutableHandle<JSObject*> aReflector);
OneTypeIterableIterator(T* aIterableObj,
IterableIteratorType aIteratorType,
WrapFunc aWrapFunc)
: IterableIterator<T>(aIterableObj)
, mIteratorType(aIteratorType)
, mWrapFunc(aWrapFunc)
, mIndex(0)
{
MOZ_ASSERT(mWrapFunc);
}
void
Next(JSContext* aCx, JS::MutableHandle<JSObject*> aResult, ErrorResult& aRv)
{
JS::Rooted<JS::Value> value(aCx, JS::UndefinedValue());
if (mIndex >= this->mIterableObj->GetIterableLength()) {
DictReturn(aCx, aResult, true, value, aRv);
return;
}
switch (mIteratorType) {
case IterableIteratorType::Keys:
case IterableIteratorType::Values:
{
if (!ToJSValue(aCx, this->mIterableObj->GetValueAtIndex(mIndex), &value)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
DictReturn(aCx, aResult, false, value, aRv);
break;
}
case IterableIteratorType::Entries:
{
if (!ToJSValue(aCx, this->mIterableObj->GetValueAtIndex(mIndex), &value)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
KeyAndValueReturn(aCx, value, value, aResult, aRv);
break;
}
default:
MOZ_CRASH("Invalid iterator type!");
}
++mIndex;
}
bool
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aObj)
{
return (*mWrapFunc)(aCx, this, aGivenProto, aObj);
}
protected:
virtual ~OneTypeIterableIterator() {}
// Tells whether this is a key, value, or entries iterator.
IterableIteratorType mIteratorType;
// Function pointer to binding-type-specific Wrap() call for this iterator.
WrapFunc mWrapFunc;
// Current index of iteration.
uint32_t mIndex;
};
template<typename T>
class TwoTypeIterableIterator final : public IterableIterator<T>
{
public:
typedef typename IterableIterator<T>::IterableIteratorType IterableIteratorType;
using IterableIterator<T>::DictReturn;
using IterableIterator<T>::KeyAndValueReturn;
typedef bool (*WrapFunc)(JSContext* aCx,
TwoTypeIterableIterator<T>* aObject,
JS::Handle<JSObject*> aGivenProto,
JS::MutableHandle<JSObject*> aReflector);
TwoTypeIterableIterator(T* aIterableObj, IterableIteratorType aIteratorType,
WrapFunc aWrapFunc)
: IterableIterator<T>(aIterableObj)
, mIteratorType(aIteratorType)
, mWrapFunc(aWrapFunc)
, mIndex(0)
{
MOZ_ASSERT(mWrapFunc);
}
void
Next(JSContext* aCx, JS::MutableHandle<JSObject*> aResult, ErrorResult& aRv)
{
JS::Rooted<JS::Value> value(aCx, JS::UndefinedValue());
if (mIndex >= this->mIterableObj->GetIterableLength()) {
DictReturn(aCx, aResult, true, value, aRv);
return;
}
switch (mIteratorType) {
case IterableIteratorType::Keys:
{
if (!ToJSValue(aCx, this->mIterableObj->GetKeyAtIndex(mIndex), &value)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
DictReturn(aCx, aResult, false, value, aRv);
break;
}
case IterableIteratorType::Values:
{
if (!ToJSValue(aCx, this->mIterableObj->GetValueAtIndex(mIndex), &value)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
DictReturn(aCx, aResult, false, value, aRv);
break;
}
case IterableIteratorType::Entries:
{
JS::Rooted<JS::Value> key(aCx);
if (!ToJSValue(aCx, this->mIterableObj->GetKeyAtIndex(mIndex), &key)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
if (!ToJSValue(aCx, this->mIterableObj->GetValueAtIndex(mIndex), &value)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
KeyAndValueReturn(aCx, key, value, aResult, aRv);
break;
}
default:
MOZ_CRASH("Invalid iterator type!");
}
++mIndex;
}
bool
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aObj)
{
return (*mWrapFunc)(aCx, this, aGivenProto, aObj);
}
protected:
virtual ~TwoTypeIterableIterator() {}
// Tells whether this is a key, value, or entries iterator.
IterableIteratorType mIteratorType;
// Function pointer to binding-type-specific Wrap() call for this iterator.
+100 -25
View File
@@ -1089,7 +1089,7 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
def validate(self):
# We don't support consequential unforgeable interfaces. Need to check
# this here, becaue in finish() an interface might not know yet that
# this here, because in finish() an interface might not know yet that
# it's consequential.
if self.getExtendedAttribute("Unforgeable") and self.isConsequential():
raise WebIDLError(
@@ -1108,6 +1108,8 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
self.identifier.name,
locations)
indexedGetter = None
hasLengthAttribute = False
for member in self.members:
member.validate()
@@ -1118,8 +1120,13 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
[self.location, member.location])
# Check that PutForwards refers to another attribute and that no
# cycles exist in forwarded assignments.
# cycles exist in forwarded assignments. Also check for a
# integer-typed "length" attribute.
if member.isAttr():
if (member.identifier.name == "length" and
member.type.isInteger()):
hasLengthAttribute = True
iface = self
attr = member
putForwards = attr.getExtendedAttribute("PutForwards")
@@ -1157,8 +1164,11 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
putForwards = attr.getExtendedAttribute("PutForwards")
# Check that the name of an [Alias] doesn't conflict with an
# interface member.
# interface member and whether we support indexed properties.
if member.isMethod():
if member.isGetter() and member.isIndexed():
indexedGetter = member
for alias in member.aliases:
if self.isOnGlobalProtoChain():
raise WebIDLError("[Alias] must not be used on a "
@@ -1219,6 +1229,35 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
"exposed conditionally",
[self.location])
# Value iterators are only allowed on interfaces with indexed getters,
# and pair iterators are only allowed on interfaces without indexed
# getters.
if self.isIterable():
iterableDecl = self.maplikeOrSetlikeOrIterable
if iterableDecl.isValueIterator():
if not indexedGetter:
raise WebIDLError("Interface with value iterator does not "
"support indexed properties",
[self.location])
if iterableDecl.valueType != indexedGetter.signatures()[0][0]:
raise WebIDLError("Iterable type does not match indexed "
"getter type",
[iterableDecl.location,
indexedGetter.location])
if not hasLengthAttribute:
raise WebIDLError('Interface with value iterator does not '
'have an integer-typed "length" attribute',
[self.location])
else:
assert iterableDecl.isPairIterator()
if indexedGetter:
raise WebIDLError("Interface with pair iterator supports "
"indexed properties",
[self.location, iterableDecl.location,
indexedGetter.location])
def isInterface(self):
return True
@@ -3408,7 +3447,10 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
def __init__(self, location, identifier, ifaceType, keyType, valueType, ifaceKind):
IDLInterfaceMember.__init__(self, location, identifier, ifaceKind)
assert isinstance(keyType, IDLType)
if keyType is not None:
assert isinstance(keyType, IDLType)
else:
assert valueType is not None
assert ifaceType in ['maplike', 'setlike', 'iterable']
if valueType is not None:
assert isinstance(valueType, IDLType)
@@ -3427,6 +3469,9 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
def isIterable(self):
return self.maplikeOrSetlikeOrIterableType == "iterable"
def hasKeyType(self):
return self.keyType is not None
def hasValueType(self):
return self.valueType is not None
@@ -3451,7 +3496,8 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
[self.location, member.location])
def addMethod(self, name, members, allowExistingOperations, returnType, args=[],
chromeOnly=False, isPure=False, affectsNothing=False, newObject=False):
chromeOnly=False, isPure=False, affectsNothing=False, newObject=False,
isIteratorAlias=False):
"""
Create an IDLMethod based on the parameters passed in.
@@ -3511,16 +3557,20 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
if newObject:
method.addExtendedAttributes(
[IDLExtendedAttribute(self.location, ("NewObject",))])
if isIteratorAlias:
method.addExtendedAttributes(
[IDLExtendedAttribute(self.location, ("Alias", "@@iterator"))])
members.append(method)
def resolve(self, parentScope):
self.keyType.resolveType(parentScope)
if self.keyType:
self.keyType.resolveType(parentScope)
if self.valueType:
self.valueType.resolveType(parentScope)
def finish(self, scope):
IDLInterfaceMember.finish(self, scope)
if not self.keyType.isComplete():
if self.keyType and not self.keyType.isComplete():
t = self.keyType.complete(scope)
assert not isinstance(t, IDLUnresolvedType)
@@ -3542,9 +3592,23 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
IDLInterfaceMember.handleExtendedAttribute(self, attr)
def _getDependentObjects(self):
deps = set()
if self.keyType:
deps.add(self.keyType)
if self.valueType:
return set([self.keyType, self.valueType])
return set([self.keyType])
deps.add(self.valueType)
return deps
def getForEachArguments(self):
return [IDLArgument(self.location,
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
"callback"),
BuiltinTypes[IDLBuiltinType.Types.object]),
IDLArgument(self.location,
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
"thisArg"),
BuiltinTypes[IDLBuiltinType.Types.any],
optional=True)]
# Iterable adds ES6 iterator style functions and traits
# (keys/values/entries/@@iterator) to an interface.
@@ -3565,9 +3629,15 @@ class IDLIterable(IDLMaplikeOrSetlikeOrIterableBase):
we generate our functions as if they were part of the interface
specification during parsing.
"""
# We only need to add entries/keys/values here if we're a pair iterator.
# Value iterators just copy these from %ArrayPrototype% instead.
if not self.isPairIterator():
return
# object entries()
self.addMethod("entries", members, False, self.iteratorType,
affectsNothing=True, newObject=True)
affectsNothing=True, newObject=True,
isIteratorAlias=True)
# object keys()
self.addMethod("keys", members, False, self.iteratorType,
affectsNothing=True, newObject=True)
@@ -3575,6 +3645,17 @@ class IDLIterable(IDLMaplikeOrSetlikeOrIterableBase):
self.addMethod("values", members, False, self.iteratorType,
affectsNothing=True, newObject=True)
# void forEach(callback(valueType, keyType), optional any thisArg)
self.addMethod("forEach", members, False,
BuiltinTypes[IDLBuiltinType.Types.void],
self.getForEachArguments())
def isValueIterator(self):
return not self.isPairIterator()
def isPairIterator(self):
return self.hasKeyType()
# MaplikeOrSetlike adds ES6 map-or-set-like traits to an interface.
class IDLMaplikeOrSetlike(IDLMaplikeOrSetlikeOrIterableBase):
@@ -3611,26 +3692,17 @@ class IDLMaplikeOrSetlike(IDLMaplikeOrSetlikeOrIterableBase):
# object entries()
self.addMethod("entries", members, False, BuiltinTypes[IDLBuiltinType.Types.object],
affectsNothing=True)
affectsNothing=True, isIteratorAlias=self.isMaplike())
# object keys()
self.addMethod("keys", members, False, BuiltinTypes[IDLBuiltinType.Types.object],
affectsNothing=True)
# object values()
self.addMethod("values", members, False, BuiltinTypes[IDLBuiltinType.Types.object],
affectsNothing=True)
affectsNothing=True, isIteratorAlias=self.isSetlike())
# void forEach(callback(valueType, keyType), thisVal)
foreachArguments = [IDLArgument(self.location,
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
"callback"),
BuiltinTypes[IDLBuiltinType.Types.object]),
IDLArgument(self.location,
IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
"thisArg"),
BuiltinTypes[IDLBuiltinType.Types.any],
optional=True)]
self.addMethod("forEach", members, False, BuiltinTypes[IDLBuiltinType.Types.void],
foreachArguments)
self.getForEachArguments())
def getKeyArg():
return IDLArgument(self.location,
@@ -5436,10 +5508,13 @@ class Parser(Tokenizer):
location = self.getLocation(p, 2)
identifier = IDLUnresolvedIdentifier(location, "__iterable",
allowDoubleUnderscore=True)
keyType = p[3]
valueType = None
if (len(p) > 6):
keyType = p[3]
valueType = p[5]
else:
keyType = None
valueType = p[3]
p[0] = IDLIterable(location, identifier, keyType, valueType, self.globalScope())
def p_Setlike(self, p):
@@ -6509,7 +6584,7 @@ class Parser(Tokenizer):
if isinstance(m, IDLIterable):
iterable = m
break
if iterable:
if iterable and iterable.isPairIterator():
def simpleExtendedAttr(str):
return IDLExtendedAttribute(iface.location, (str, ))
nextMethod = IDLMethod(
@@ -55,17 +55,22 @@ TestInterfaceIterableSingle::GetParentObject() const
return mParent;
}
size_t
TestInterfaceIterableSingle::GetIterableLength() const
uint32_t
TestInterfaceIterableSingle::Length() const
{
return mValues.Length();
}
uint32_t
TestInterfaceIterableSingle::GetValueAtIndex(uint32_t index) const
int32_t
TestInterfaceIterableSingle::IndexedGetter(uint32_t aIndex, bool& aFound) const
{
MOZ_ASSERT(index < mValues.Length());
return mValues.ElementAt(index);
if (aIndex >= mValues.Length()) {
aFound = false;
return 0;
}
aFound = true;
return mValues[aIndex];
}
} // namespace dom
@@ -36,12 +36,13 @@ public:
static already_AddRefed<TestInterfaceIterableSingle>
Constructor(const GlobalObject& aGlobal, ErrorResult& rv);
size_t GetIterableLength() const;
uint32_t GetValueAtIndex(uint32_t aIndex) const;
uint32_t Length() const;
int32_t IndexedGetter(uint32_t aIndex, bool& aFound) const;
private:
virtual ~TestInterfaceIterableSingle() {}
nsCOMPtr<nsPIDOMWindow> mParent;
nsTArray<uint32_t> mValues;
nsTArray<int32_t> mValues;
};
} // namespace dom
+7 -1
View File
@@ -39,6 +39,12 @@ ASSERT_NODE_FLAGS_SPACE(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET + 2);
#undef ANCHOR_ELEMENT_FLAG_BIT
// static
const DOMTokenListSupportedToken HTMLAnchorElement::sSupportedRelValues[] = {
"noreferrer",
nullptr
};
HTMLAnchorElement::~HTMLAnchorElement()
{
}
@@ -302,7 +308,7 @@ nsDOMTokenList*
HTMLAnchorElement::RelList()
{
if (!mRelList) {
mRelList = new nsDOMTokenList(this, nsGkAtoms::rel);
mRelList = new nsDOMTokenList(this, nsGkAtoms::rel, sSupportedRelValues);
}
return mRelList;
}
+2
View File
@@ -227,6 +227,8 @@ public:
GetHref(aResult);
}
static DOMTokenListSupportedToken sSupportedRelValues[];
protected:
virtual ~HTMLAnchorElement();
+3 -1
View File
@@ -7,6 +7,7 @@
#include "mozilla/dom/HTMLAreaElement.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/HTMLAnchorElement.h"
#include "mozilla/dom/HTMLAreaElementBinding.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/EventStates.h"
@@ -122,7 +123,8 @@ nsDOMTokenList*
HTMLAreaElement::RelList()
{
if (!mRelList) {
mRelList = new nsDOMTokenList(this, nsGkAtoms::rel);
mRelList = new nsDOMTokenList(this, nsGkAtoms::rel,
HTMLAnchorElement::sSupportedRelValues);
}
return mRelList;
}
+9
View File
@@ -18,6 +18,15 @@ NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(IFrame)
namespace mozilla {
namespace dom {
// static
const DOMTokenListSupportedToken HTMLIFrameElement::sSupportedSandboxTokens[] =
{
#define SANDBOX_KEYWORD(string, atom, flags) string,
#include "IframeSandboxKeywordList.h"
#undef SANDBOX_KEYWORD
nullptr
};
HTMLIFrameElement::HTMLIFrameElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
FromParser aFromParser)
: nsGenericHTMLFrameElement(aNodeInfo, aFromParser)
+5 -3
View File
@@ -10,7 +10,7 @@
#include "mozilla/Attributes.h"
#include "nsGenericHTMLFrameElement.h"
#include "nsIDOMHTMLIFrameElement.h"
#include "nsDOMSettableTokenList.h"
#include "nsDOMTokenList.h"
namespace mozilla {
namespace dom {
@@ -84,9 +84,9 @@ public:
{
SetHTMLAttr(nsGkAtoms::name, aName, aError);
}
nsDOMSettableTokenList* Sandbox()
nsDOMTokenList* Sandbox()
{
return GetTokenList(nsGkAtoms::sandbox);
return GetTokenList(nsGkAtoms::sandbox, sSupportedSandboxTokens);
}
bool AllowFullscreen() const
{
@@ -202,6 +202,8 @@ protected:
private:
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
nsRuleData* aData);
static const DOMTokenListSupportedToken sSupportedSandboxTokens[];
};
} // namespace dom
+21 -1
View File
@@ -26,6 +26,7 @@
#include "nsPIDOMWindow.h"
#include "nsReadableUtils.h"
#include "nsStyleConsts.h"
#include "nsStyleLinkElement.h"
#include "nsUnicharUtils.h"
#define LINK_ELEMENT_FLAG_BIT(n_) \
@@ -499,11 +500,30 @@ HTMLLinkElement::GetLinkTarget(nsAString& aTarget)
}
}
static const DOMTokenListSupportedToken sSupportedRelValues[] = {
// Keep this in sync with ToLinkMask in nsStyleLinkElement.cpp.
// "import" must come first because it's conditional.
"import"
"prefetch",
"dns-prefetch",
"stylesheet",
"next",
"alternate",
"preconnect",
"icon",
"search",
nullptr
};
nsDOMTokenList*
HTMLLinkElement::RelList()
{
if (!mRelList) {
mRelList = new nsDOMTokenList(this, nsGkAtoms::rel);
const DOMTokenListSupportedTokenArray relValues =
nsStyleLinkElement::IsImportEnabled() ?
sSupportedRelValues : &sSupportedRelValues[1];
mRelList = new nsDOMTokenList(this, nsGkAtoms::rel, relValues);
}
return mRelList;
}
+1 -1
View File
@@ -119,7 +119,7 @@ public:
{
SetHTMLAttr(nsGkAtoms::hreflang, aHreflang, aRv);
}
nsDOMSettableTokenList* Sizes()
nsDOMTokenList* Sizes()
{
return GetTokenList(nsGkAtoms::sizes);
}
+1
View File
@@ -11,6 +11,7 @@
#include "mozilla/dom/HTMLMenuItemElementBinding.h"
#include "nsAttrValueInlines.h"
#include "nsContentUtils.h"
#include "nsDOMTokenList.h"
NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(MenuItem)
+2 -3
View File
@@ -11,7 +11,6 @@
#include "mozilla/dom/HTMLFormElement.h"
#include "mozilla/dom/HTMLOutputElementBinding.h"
#include "nsContentUtils.h"
#include "nsDOMSettableTokenList.h"
#include "nsFormSubmission.h"
NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Output)
@@ -166,11 +165,11 @@ HTMLOutputElement::SetDefaultValue(const nsAString& aDefaultValue, ErrorResult&
}
}
nsDOMSettableTokenList*
nsDOMTokenList*
HTMLOutputElement::HtmlFor()
{
if (!mTokenList) {
mTokenList = new nsDOMSettableTokenList(this, nsGkAtoms::_for);
mTokenList = new nsDOMTokenList(this, nsGkAtoms::_for);
}
return mTokenList;
}
+2 -2
View File
@@ -64,7 +64,7 @@ public:
virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
// WebIDL
nsDOMSettableTokenList* HtmlFor();
nsDOMTokenList* HtmlFor();
// nsGenericHTMLFormElement::GetForm is fine.
void GetName(nsAString& aName)
{
@@ -108,7 +108,7 @@ protected:
ValueModeFlag mValueModeFlag;
bool mIsDoneAddingChildren;
nsString mDefaultValue;
RefPtr<nsDOMSettableTokenList> mTokenList;
RefPtr<nsDOMTokenList> mTokenList;
};
} // namespace dom
+1 -1
View File
@@ -9,7 +9,7 @@
#include "nsContentUtils.h"
#include "nsGenericHTMLElement.h"
#include "nsVariant.h"
#include "nsDOMSettableTokenList.h"
#include "nsDOMTokenList.h"
#include "nsAttrValue.h"
#include "nsWrapperCacheInlines.h"
#include "mozilla/dom/HTMLPropertiesCollectionBinding.h"
+3 -2
View File
@@ -164,14 +164,15 @@ SetBaseURIUsingFirstBaseWithHref(nsIDocument* aDocument, nsIContent* aMustMatch)
return;
}
// Resolve the <base> element's href relative to our document URI
// Resolve the <base> element's href relative to our document's
// fallback base URI.
nsAutoString href;
child->GetAttr(kNameSpaceID_None, nsGkAtoms::href, href);
nsCOMPtr<nsIURI> newBaseURI;
nsContentUtils::NewURIWithDocumentCharset(
getter_AddRefs(newBaseURI), href, aDocument,
aDocument->GetDocumentURI());
aDocument->GetFallbackBaseURI());
// Try to set our base URI. If that fails, try to set base URI to null
nsresult rv = aDocument->SetBaseURI(newBaseURI);
+1 -1
View File
@@ -47,7 +47,7 @@ public:
{
SetUnsignedIntAttr(nsGkAtoms::rowspan, aRowSpan, aError);
}
//already_AddRefed<nsDOMSettableTokenList> Headers() const;
//already_AddRefed<nsDOMTokenList> Headers() const;
void GetHeaders(DOMString& aHeaders)
{
GetHTMLAttr(nsGkAtoms::headers, aHeaders);
+1 -1
View File
@@ -96,7 +96,7 @@
#include "HTMLPropertiesCollection.h"
#include "nsVariant.h"
#include "nsDOMSettableTokenList.h"
#include "nsDOMTokenList.h"
#include "nsThreadUtils.h"
#include "nsTextFragment.h"
#include "mozilla/dom/BindingUtils.h"
+4 -4
View File
@@ -20,7 +20,7 @@
#include "mozilla/dom/ValidityState.h"
#include "mozilla/dom/ElementInlines.h"
class nsDOMSettableTokenList;
class nsDOMTokenList;
class nsIDOMHTMLMenuElement;
class nsIEditor;
class nsIFormControlFrame;
@@ -104,7 +104,7 @@ public:
{
SetHTMLBoolAttr(nsGkAtoms::itemscope, aItemScope, aError);
}
nsDOMSettableTokenList* ItemType()
nsDOMTokenList* ItemType()
{
return GetTokenList(nsGkAtoms::itemtype);
}
@@ -116,11 +116,11 @@ public:
{
SetHTMLAttr(nsGkAtoms::itemid, aItemID, aError);
}
nsDOMSettableTokenList* ItemRef()
nsDOMTokenList* ItemRef()
{
return GetTokenList(nsGkAtoms::itemref);
}
nsDOMSettableTokenList* ItemProp()
nsDOMTokenList* ItemProp()
{
return GetTokenList(nsGkAtoms::itemprop);
}
+1 -1
View File
@@ -32,7 +32,7 @@ interface nsIDOMHTMLElement : nsIDOMElement
attribute nsIVariant itemType;
attribute DOMString itemId;
readonly attribute nsISupports properties;
// The following attributes are really nsDOMSettableTokenList, which has
// The following attributes are really nsDOMTokenList, which has
// PutForwards, so we express them as nsIVariants to deal with this.
attribute nsIVariant itemValue;
attribute nsIVariant itemProp;
+7
View File
@@ -20,6 +20,13 @@ interface DOMTokenList {
[Throws]
void remove(DOMString... tokens);
[Throws]
void replace(DOMString token, DOMString newToken);
[Throws]
boolean toggle(DOMString token, optional boolean force);
[Throws]
boolean supports(DOMString token);
[SetterThrows]
attribute DOMString value;
stringifier DOMString ();
iterable<DOMString?>;
};
+1 -1
View File
@@ -30,7 +30,7 @@ interface Element : Node {
attribute DOMString id;
[Pure]
attribute DOMString className;
[Constant]
[Constant, PutForwards=value]
readonly attribute DOMTokenList classList;
[SameObject]
+1
View File
@@ -23,6 +23,7 @@ interface HTMLAnchorElement : HTMLElement {
attribute DOMString rel;
[SetterThrows, Pref="network.http.enablePerElementReferrer"]
attribute DOMString referrerPolicy;
[PutForwards=value]
readonly attribute DOMTokenList relList;
[SetterThrows]
attribute DOMString hreflang;
+1
View File
@@ -30,6 +30,7 @@ interface HTMLAreaElement : HTMLElement {
attribute DOMString rel;
[SetterThrows, Pref="network.http.enablePerElementReferrer"]
attribute DOMString referrerPolicy;
[PutForwards=value]
readonly attribute DOMTokenList relList;
};
+4 -4
View File
@@ -28,11 +28,11 @@ interface HTMLElement : Element {
// microdata
[SetterThrows, Pure]
attribute boolean itemScope;
[PutForwards=value,Constant] readonly attribute DOMSettableTokenList itemType;
[PutForwards=value,Constant] readonly attribute DOMTokenList itemType;
[SetterThrows, Pure]
attribute DOMString itemId;
[PutForwards=value,Constant] readonly attribute DOMSettableTokenList itemRef;
[PutForwards=value,Constant] readonly attribute DOMSettableTokenList itemProp;
[PutForwards=value,Constant] readonly attribute DOMTokenList itemRef;
[PutForwards=value,Constant] readonly attribute DOMTokenList itemProp;
[Constant]
readonly attribute HTMLPropertiesCollection properties;
[Throws]
@@ -54,7 +54,7 @@ interface HTMLElement : Element {
readonly attribute DOMString accessKeyLabel;
[SetterThrows, Pure]
attribute boolean draggable;
//[PutForwards=value] readonly attribute DOMSettableTokenList dropzone;
//[PutForwards=value] readonly attribute DOMTokenList dropzone;
[SetterThrows, Pure]
attribute DOMString contentEditable;
[Pure]
+1 -1
View File
@@ -18,7 +18,7 @@ interface HTMLIFrameElement : HTMLElement {
attribute DOMString srcdoc;
[SetterThrows, Pure]
attribute DOMString name;
[PutForwards=value] readonly attribute DOMSettableTokenList sandbox;
[PutForwards=value] readonly attribute DOMTokenList sandbox;
// attribute boolean seamless;
[SetterThrows, Pure]
attribute boolean allowFullscreen;
+2 -1
View File
@@ -21,6 +21,7 @@ interface HTMLLinkElement : HTMLElement {
attribute DOMString? crossOrigin;
[SetterThrows, Pure]
attribute DOMString rel;
[PutForwards=value]
readonly attribute DOMTokenList relList;
[SetterThrows, Pure]
attribute DOMString media;
@@ -28,7 +29,7 @@ interface HTMLLinkElement : HTMLElement {
attribute DOMString hreflang;
[SetterThrows, Pure]
attribute DOMString type;
[PutForwards=value] readonly attribute DOMSettableTokenList sizes;
[PutForwards=value] readonly attribute DOMTokenList sizes;
};
HTMLLinkElement implements LinkStyle;
+1 -1
View File
@@ -14,7 +14,7 @@
// http://www.whatwg.org/specs/web-apps/current-work/#the-output-element
interface HTMLOutputElement : HTMLElement {
[PutForwards=value, Constant]
readonly attribute DOMSettableTokenList htmlFor;
readonly attribute DOMTokenList htmlFor;
readonly attribute HTMLFormElement? form;
[SetterThrows, Pure]
attribute DOMString name;
+1 -1
View File
@@ -16,7 +16,7 @@ interface HTMLTableCellElement : HTMLElement {
attribute unsigned long colSpan;
[SetterThrows]
attribute unsigned long rowSpan;
//[PutForwards=value] readonly attribute DOMSettableTokenList headers;
//[PutForwards=value] readonly attribute DOMTokenList headers;
[SetterThrows]
attribute DOMString headers;
readonly attribute long cellIndex;
+1
View File
@@ -13,4 +13,5 @@
interface NodeList {
getter Node? item(unsigned long index);
readonly attribute unsigned long length;
iterable<Node?>;
};
@@ -50,6 +50,8 @@ interface TestInterfaceSetlikeNode {
Pref="dom.expose_test_interfaces"]
interface TestInterfaceIterableSingle {
iterable<long>;
getter long(unsigned long index);
readonly attribute unsigned long length;
};
[Constructor(),
-1
View File
@@ -132,7 +132,6 @@ WEBIDL_FILES = [
'DOMRect.webidl',
'DOMRectList.webidl',
'DOMRequest.webidl',
'DOMSettableTokenList.webidl',
'DOMStringList.webidl',
'DOMStringMap.webidl',
'DOMTokenList.webidl',
+7 -7
View File
@@ -183,21 +183,21 @@ gfxPlatformMac::MakePlatformFont(const nsAString& aFontName,
// Automates a whole buncha boilerplate.
// Since HTTPS is becoming more common, check that first.
#define HTTP_OR_HTTPS_SUBDIR(x) \
#define HTTP_OR_HTTPS_SUBDIR(x, y) \
{ \
NS_NAMED_LITERAL_CSTRING(https_, "https://" x); \
spec.Left(loc, https_.Length()); \
if (loc.Equals(https_)) { \
if (hostname.Equals(x)) { \
NS_NAMED_LITERAL_CSTRING(https_, "https://" x y); \
if (StringBeginsWith(spec, https_)) { \
failed = true; \
goto halt_font; \
} else { \
NS_NAMED_LITERAL_CSTRING(http_, "http://" x); \
spec.Left(loc, http_.Length()); \
if (loc.Equals(http_)) { \
NS_NAMED_LITERAL_CSTRING(http_, "http://" x y); \
if (StringBeginsWith(spec, http_)) { \
failed = true; \
goto halt_font; \
} \
} \
} \
}
// TenFourFox issue 477: deal with changing infix version URLs, such as latimes.com
+15 -9
View File
@@ -5,6 +5,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsBidiUtils.h"
namespace mozilla {
static const uint32_t kMinRTLChar = 0x0590;
} // namespace mozilla;
#define ARABIC_TO_HINDI_DIGIT_INCREMENT (START_HINDI_DIGITS - START_ARABIC_DIGITS)
#define PERSIAN_TO_HINDI_DIGIT_INCREMENT (START_HINDI_DIGITS - START_FARSI_DIGITS)
#define ARABIC_TO_PERSIAN_DIGIT_INCREMENT (START_FARSI_DIGITS - START_ARABIC_DIGITS)
@@ -82,16 +86,18 @@ nsresult HandleNumbers(char16_t* aBuffer, uint32_t aSize, uint32_t aNumFlag)
return NS_OK;
}
bool HasRTLChars(const nsAString& aString)
bool HasRTLChars(const char16_t* aText, uint32_t aLength)
{
// This is used to determine whether to enable bidi if a string has
// right-to-left characters. To simplify things, anything that could be a
// surrogate or RTL presentation form is covered just by testing >= 0xD800).
// It's fine to enable bidi in rare cases where it actually isn't needed.
int32_t length = aString.Length();
for (int32_t i = 0; i < length; i++) {
char16_t ch = aString.CharAt(i);
if (ch >= 0xD800 || IS_IN_BMP_RTL_BLOCK(ch)) {
// This is used to determine whether a string has right-to-left characters
// that mean it will require bidi processing.
const char16_t* cp = aText;
const char16_t* end = cp + aLength;
while (cp < end) {
char16_t ch = *cp++;
if (ch < mozilla::kMinRTLChar) {
continue;
}
if (UTF16_CODE_UNIT_IS_BIDI(ch) || IsBidiControlRTL(ch)) {
return true;
}
}
+44 -2
View File
@@ -110,10 +110,19 @@ typedef enum nsCharType nsCharType;
* Return false, otherwise
*/
#define LRM_CHAR 0x200e
#define RLM_CHAR 0x200f
#define LRE_CHAR 0x202a
#define RLE_CHAR 0x202b
#define PDF_CHAR 0x202c
#define LRO_CHAR 0x202d
#define RLO_CHAR 0x202e
#define LRI_CHAR 0x2066
#define RLI_CHAR 0x2067
#define FSI_CHAR 0x2068
#define PDI_CHAR 0x2069
#define ALM_CHAR 0x061C
inline bool IsBidiControl(uint32_t aChar) {
return ((LRE_CHAR <= aChar && aChar <= RLO_CHAR) ||
@@ -123,10 +132,32 @@ typedef enum nsCharType nsCharType;
}
/**
* Give an nsString.
* Give a UTF-16 codepoint (changed for TenFourFox; we don't use this for
* UTF-32 characters, so the conversion is unnecessary).
* Return true if the codepoint is a Bidi control character that may result
* in RTL directionality and therefore needs to trigger bidi resolution;
* return false otherwise.
*/
inline bool IsBidiControlRTL(char16_t aChar) {
return aChar == RLM_CHAR ||
aChar == RLE_CHAR ||
aChar == RLO_CHAR ||
aChar == RLI_CHAR ||
aChar == ALM_CHAR;
}
/**
* Give a 16-bit (UTF-16) text buffer and length
* @return true if the string contains right-to-left characters
*/
bool HasRTLChars(const nsAString& aString);
bool HasRTLChars(const char16_t* aText, uint32_t aLength);
/**
* Convenience function to call the above on an nsAString.
*/
inline bool HasRTLChars(const nsAString& aString) {
return HasRTLChars(aString.BeginReading(), aString.Length());
}
// These values are shared with Preferences dialog
// ------------------
@@ -248,6 +279,17 @@ typedef enum nsCharType nsCharType;
((0xfe70 <= (c)) && ((c) <= 0xfefc)))
#define IS_IN_SMP_RTL_BLOCK(c) (((0x10800 <= (c)) && ((c) <= 0x10fff)) || \
((0x1e800 <= (c)) && ((c) <= 0x1eFFF)))
// Due to the supplementary-plane RTL blocks being identifiable from the
// high surrogate without examining the low surrogate, it is correct to
// use this by-code-unit check on potentially astral text without doing
// the math to decode surrogate pairs into code points. However, unpaired
// high surrogates that are RTL high surrogates then count as RTL even
// though, if replaced by the REPLACEMENT CHARACTER, it would not be
// RTL.
#define UTF16_CODE_UNIT_IS_BIDI(c) ((IS_IN_BMP_RTL_BLOCK(c)) || \
(IS_RTL_PRESENTATION_FORM(c)) || \
(c) == 0xD802 || (c) == 0xD803 || \
(c) == 0xD83A || (c) == 0xD83B)
#define UCS2_CHAR_IS_BIDI(c) ((IS_IN_BMP_RTL_BLOCK(c)) || \
(IS_RTL_PRESENTATION_FORM(c)))
#define UTF32_CHAR_IS_BIDI(c) ((IS_IN_BMP_RTL_BLOCK(c)) || \
-1
View File
@@ -3761,7 +3761,6 @@ BytecodeEmitter::emitDestructuringDeclsWithEmitter(JSOp prologueOp, ParseNode* p
continue;
ParseNode* target = element;
if (element->isKind(PNK_SPREAD)) {
MOZ_ASSERT(element->pn_kid->isKind(PNK_NAME));
target = element->pn_kid;
}
if (target->isKind(PNK_ASSIGN))
-5
View File
@@ -4276,11 +4276,6 @@ Parser<FullParseHandler>::checkDestructuringArray(BindData<FullParseHandler>* da
return false;
}
target = element->pn_kid;
if (handler.isUnparenthesizedDestructuringPattern(target)) {
report(ParseError, false, target, JSMSG_BAD_DESTRUCT_TARGET);
return false;
}
} else if (handler.isUnparenthesizedAssignment(element)) {
target = element->pn_left;
} else {
@@ -49,6 +49,23 @@ assertIterable([5,5,4,4],
it => { var [,,...rest] = it; return rest; },
[3,4]);
// the iterator should be exhausted before any error is thrown
if(0) {
// XXX: this doesn't throw right now. just test syntax below.
// plan to reenable this for issue 485
assertIterable([5,5,4,4],
it => {
assertThrowsInstanceOf(function () {
"use strict";
[...{0: "".x}] = it;
}, TypeError);
return [];
},
[]);
} else {
assertIterable([5,5,4,4], it => { [...{0: "".x}] = it; return []; }, []);
}
var arraycalls = 0;
var ArrayIterator = Array.prototype[Symbol.iterator];
Array.prototype[Symbol.iterator] = function () {
@@ -58,7 +75,11 @@ Array.prototype[Symbol.iterator] = function () {
// [...rest] should not call Array#@@iterator for the LHS
var [...rest] = iterable;
assertEq(arraycalls, 0, 'calls to Array#@@iterator');
// [...[...rest]] should do so, since it creates an implicit array for the
// first rest pattern, then destructures that again using @@iterator() for the
// second rest pattern.
var [...[...rest]] = iterable;
assertEq(arraycalls, 1, 'calls to Array#@@iterator');
// loop `fn` a few times, to get it JIT-compiled
function loop(fn) {
@@ -67,7 +88,7 @@ function loop(fn) {
}
loop(() => { doneafter = 4; var [a] = iterable; return a; });
loop(() => { doneafter = 4; var [a,b,...rest] = iterable; return rest; });
loop(() => { doneafter = 4; var [a,b,...[...rest]] = iterable; return rest; });
// destructuring assignment should always use iterators and not optimize
@@ -4,8 +4,6 @@ load(libdir + 'eqArrayHelper.js');
assertThrowsInstanceOf(() => new Function('[...a, ,] = []'), SyntaxError, 'trailing elision');
assertThrowsInstanceOf(() => new Function('[a, ...b, c] = []'), SyntaxError, 'trailing param');
assertThrowsInstanceOf(() => new Function('[...[a]] = []'), SyntaxError, 'nested arraypattern');
assertThrowsInstanceOf(() => new Function('[...{a}] = []'), SyntaxError, 'nested objectpattern');
assertThrowsInstanceOf(() => new Function('[...a=b] = []'), SyntaxError, 'assignment expression');
assertThrowsInstanceOf(() => new Function('[...a()] = []'), SyntaxError, 'call expression');
assertThrowsInstanceOf(() => new Function('[...(a,b)] = []'), SyntaxError, 'comma expression');
@@ -22,6 +20,14 @@ assertThrowsInstanceOf(() =>
assertThrowsInstanceOf(() => new Function('[...b,] = []'), SyntaxError)
, Error);
assertThrowsInstanceOf(() => {
try {
eval('let [...[...x]] = (() => { throw "foo"; } )();');
} catch(e) {
assertEq(e, "foo");
}
x;
}, ReferenceError);
var inputArray = [1, 2, 3];
var inputDeep = [1, inputArray];
@@ -45,6 +51,11 @@ function testAll(fn) {
assertEqArray(fn('[, ...(o.prop)]', inputArray, 'o.prop'), expected);
o.prop = null;
assertEqArray(fn('[, ...(o.call().prop)]', inputArray, 'o.prop'), expected);
o.prop = null;
assertEqArray(fn('[, ...[...(o.prop)]]', inputArray, 'o.prop'), expected);
o.prop = null;
assertEqArray(fn('[, ...[...(o.call().prop)]]', inputArray, 'o.prop'), expected);
}
function testDeclaration(fn) {
testStr(fn);
@@ -53,10 +64,24 @@ function testDeclaration(fn) {
assertEqArray(fn('[, ...rest]', inputGenerator()), expected);
assertEqArray(fn('[, [, ...rest]]', inputDeep), expected);
assertEqArray(fn('{a: [, ...rest]}', inputObject), expected);
assertEqArray(fn('[, ...[...rest]]', inputArray), expected);
assertEqArray(fn('[, ...[...rest]]', inputGenerator()), expected);
assertEqArray(fn('[, [, ...[...rest]]]', inputDeep), expected);
assertEqArray(fn('{a: [, ...[...rest]]}', inputObject), expected);
assertEqArray(fn('[, ...{0: a, 1: b}]', inputArray, '[a, b]'), expected);
assertEqArray(fn('[, ...{0: a, 1: b}]', inputGenerator(), '[a, b]'), expected);
assertEqArray(fn('[, [, ...{0: a, 1: b}]]', inputDeep, '[a, b]'), expected);
assertEqArray(fn('{a: [, ...{0: a, 1: b}]}', inputObject, '[a, b]'), expected);
}
function testStr(fn) {
assertEqArray(fn('[, ...rest]', inputStr), expectedStr);
assertEqArray(fn('[, ...[...rest]]', inputStr), expectedStr);
assertEqArray(fn('[, ...{0: a, 1: b}]', inputStr, '[a, b]'), expectedStr);
}
function testForIn(pattern, input, binding) {
@@ -88,8 +113,9 @@ testAll(testGlobal);
function testClosure(pattern, input, binding) {
binding = binding || 'rest';
const decl = binding.replace('[', '').replace(']', '');
return new Function('input',
'var ' + binding + '; (function () {' +
'var ' + decl + '; (function () {' +
'(' + pattern + ' = input);' +
'})();' +
'return ' + binding
+4
View File
@@ -305,7 +305,11 @@ AtomicOperations::isLockfree(int32_t size)
|| defined(__ppc__) || defined(__PPC__)
# include "jit/none/AtomicOperations-ppc.h"
#elif defined(JS_CODEGEN_NONE)
#if defined(__i386__) || defined(__x86_64__)
# include "jit/x86-shared/AtomicOperations-x86-shared.h"
#else
# include "jit/none/AtomicOperations-none.h"
#endif
#elif defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
# include "jit/x86-shared/AtomicOperations-x86-shared.h"
#else
+109 -1
View File
@@ -110,6 +110,7 @@ struct BidiParagraphData {
nsTArray<nsLineBox*> mLinePerFrame;
nsDataHashtable<nsISupportsHashKey, int32_t> mContentToFrameIndex;
bool mIsVisual;
bool mRequiresBidi;
bool mReset;
nsBidiLevel mParaLevel;
nsIContent* mPrevContent;
@@ -121,10 +122,14 @@ struct BidiParagraphData {
void Init(nsBlockFrame *aBlockFrame)
{
mBidiEngine = new nsBidi();
mRequiresBidi = false;
mPrevContent = nullptr;
mParagraphDepth = 0;
mParaLevel = nsBidiPresUtils::BidiLevelFromStyle(aBlockFrame->StyleContext());
if (mParaLevel > 0) {
mRequiresBidi = true;
}
mIsVisual = aBlockFrame->PresContext()->IsVisualMode();
if (mIsVisual) {
@@ -664,14 +669,67 @@ nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame)
char16_t ch = GetBidiControl(aBlockFrame->StyleContext(), kOverride);
if (ch != 0) {
bpd.PushBidiControl(ch);
bpd.mRequiresBidi = true;
} else if (!bpd.mRequiresBidi) {
// If there are no unicode-bidi properties and no RTL characters in the
// block's content, then it is pure LTR and we can skip the rest of bidi
// resolution.
nsIContent* currContent = nullptr;
for (nsBlockFrame* block = aBlockFrame; block;
block = static_cast<nsBlockFrame*>(block->GetNextContinuation())) {
block->RemoveStateBits(NS_BLOCK_NEEDS_BIDI_RESOLUTION);
if (/* !bpd.mRequiresBidi && */
ChildListMayRequireBidi(block->PrincipalChildList().FirstChild(),
&currContent)) {
bpd.mRequiresBidi = true;
// Optimization for TenFourFox issue 482:
// It's safe to break here if mRequiresBidi is true because we'll
// pull the state bits off in the loop below (if we didn't, we would
// essentially cause bug 1362423). This also allows us to reduce
// checking mRequiresBidi all the time.
break;
}
#if(0)
// XXX: Unnecessary work given that the below isn't executed.
// If we need bidi support for overflow, we need to enable this too.
/* if (!bpd.mRequiresBidi) { */
nsBlockFrame::FrameLines* overflowLines = block->GetOverflowLines();
if (overflowLines) { // XXX: see below
if (ChildListMayRequireBidi(overflowLines->mFrames.FirstChild(),
&currContent)) {
bpd.mRequiresBidi = true;
break; // as above
}
}
/* } */
#endif
}
// Moving the below here so that we can keep partial work causes RTL
// to get munged. It seems we really do have to iterate through all the
// frames again from the beginning if any are RTL.
if (!bpd.mRequiresBidi) {
return NS_OK;
}
}
for (nsBlockFrame* block = aBlockFrame; block;
block = static_cast<nsBlockFrame*>(block->GetNextContinuation())) {
block->RemoveStateBits(NS_BLOCK_NEEDS_BIDI_RESOLUTION);
nsBlockInFlowLineIterator lineIter(block, block->begin_lines());
bpd.ResetForNewBlock();
TraverseFrames(aBlockFrame, &lineIter, block->GetFirstPrincipalChild(), &bpd);
// XXX what about overflow lines?
#if(0)
nsBlockFrame::FrameLines* overflowLines = block->GetOverflowLines();
// XXX: Not sure if this is going to break anything.
// It's safe to do above (from bug 1358275) because that doesn't actually
// bidi-process the overflow lines; it just checks if we need to.
if (overflowLines) {
nsBlockInFlowLineIterator it(block, overflowLines->mLines.begin(), true);
bpd.ResetForNewBlock();
TraverseFrames(aBlockFrame, &it, overflowLines->mFrames.FirstChild(), &bpd);
}
#endif
}
if (ch != 0) {
@@ -1241,6 +1299,56 @@ nsBidiPresUtils::TraverseFrames(nsBlockFrame* aBlockFrame,
MOZ_ASSERT(initialLineContainer == aLineIter->GetContainer());
}
bool
nsBidiPresUtils::ChildListMayRequireBidi(nsIFrame* aFirstChild,
nsIContent** aCurrContent)
{
MOZ_ASSERT(!aFirstChild || !aFirstChild->GetPrevSibling(),
"Expecting to traverse from the start of a child list");
for (nsIFrame* childFrame = aFirstChild; childFrame;
childFrame = childFrame->GetNextSibling()) {
nsIFrame* frame = childFrame;
// If the real frame for a placeholder is a first-letter frame, we need to
// consider its contents for potential Bidi resolution.
if (childFrame->GetType() == nsGkAtoms::placeholderFrame) {
nsIFrame* realFrame =
nsPlaceholderFrame::GetRealFrameForPlaceholder(childFrame);
if (realFrame->GetType() == nsGkAtoms::letterFrame) {
frame = realFrame;
}
}
// If unicode-bidi properties are present, we should do bidi resolution.
nsStyleContext* sc = frame->StyleContext();
if (GetBidiControl(sc, kOverrideOrEmbed)) {
return true;
}
if (IsBidiLeaf(frame)) {
if (frame->GetType() == nsGkAtoms::textFrame) {
// Check whether the text frame has any RTL characters; if so, bidi
// resolution will be needed.
nsIContent* content = frame->GetContent();
if (content != *aCurrContent) {
*aCurrContent = content;
const nsTextFragment* txt = content->GetText();
if (txt->Is2b() && HasRTLChars(txt->Get2b(), txt->GetLength())) {
return true;
}
}
}
} else if (ChildListMayRequireBidi(frame->PrincipalChildList().FirstChild(),
aCurrContent)) {
return true;
}
}
return false;
}
void
nsBidiPresUtils::ResolveParagraphWithinBlock(nsBlockFrame* aBlockFrame,
BidiParagraphData* aBpd)
+17
View File
@@ -399,6 +399,23 @@ private:
nsIFrame* aCurrentFrame,
BidiParagraphData* aBpd);
/**
* Perform a recursive "pre-traversal" of the child frames of a block or
* inline container frame, to determine whether full bidi resolution is
* actually needed.
* This explores the same frames as TraverseFrames (above), but is less
* expensive and may allow us to avoid performing the full TraverseFrames
* operation.
* @param aFirstChild frame to start traversal from
* @param[in/out] aCurrContent the content node that we've most recently
* scanned for RTL characters (so that when descendant frames refer
* to the same content, we can avoid repeatedly scanning it).
* @return true if it finds that bidi is (or may be) required,
* false if no potentially-bidi content is present.
*/
static bool ChildListMayRequireBidi(nsIFrame* aFirstChild,
nsIContent** aCurrContent);
/**
* Position ruby content frames (ruby base/text frame).
* Called from RepositionRubyFrame.
+1 -1
View File
@@ -647,7 +647,7 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
mAsyncPanZoomEnabled(nsLayoutUtils::AsyncPanZoomEnabled(aReferenceFrame))
{
MOZ_COUNT_CTOR(nsDisplayListBuilder);
PL_InitArenaPool(&mPool, "displayListArena", 1024,
PL_InitArenaPool(&mPool, "displayListArena", 4096,
std::max(NS_ALIGNMENT_OF(void*),NS_ALIGNMENT_OF(double))-1);
nsPresContext* pc = aReferenceFrame->PresContext();
+1 -1
View File
@@ -935,7 +935,7 @@ nsRefreshDriver::GetThrottledTimerInterval()
if (rate <= 0) {
rate = DEFAULT_THROTTLED_FRAME_RATE;
}
return 3000.0 / rate;
return 10000.0 / rate;
}
/* static */ mozilla::TimeDuration
+5 -2
View File
@@ -1176,10 +1176,13 @@ GetStatesForPseudoClass(const nsAString& aStatePseudo)
nsCOMPtr<nsIAtom> atom = do_GetAtom(aStatePseudo);
// Ignore :moz-any-link so we don't give the element simultaneous
// Ignore :any-link so we don't give the element simultaneous
// visited and unvisited style state
if (nsCSSPseudoClasses::GetPseudoType(atom) ==
nsCSSPseudoClasses::ePseudoClass_mozAnyLink) {
nsCSSPseudoClasses::ePseudoClass_mozAnyLink ||
// XXX: this could be cleaned up. do it once it's building
nsCSSPseudoClasses::GetPseudoType(atom) ==
nsCSSPseudoClasses::ePseudoClass_anyLink) {
return EventStates();
}
// Our array above is long enough that indexing into it with
-1
View File
@@ -991,7 +991,6 @@ const KTableEntry nsCSSProps::kBoxShadowTypeKTable[] = {
const KTableEntry nsCSSProps::kBoxSizingKTable[] = {
{ eCSSKeyword_content_box, uint8_t(StyleBoxSizing::Content) },
{ eCSSKeyword_border_box, uint8_t(StyleBoxSizing::Border) },
{ eCSSKeyword_padding_box, uint8_t(StyleBoxSizing::Padding) },
{ eCSSKeyword_UNKNOWN, -1 }
};
+2
View File
@@ -142,6 +142,8 @@ CSS_STATE_PSEUDO_CLASS(link, ":link", 0, "", NS_EVENT_STATE_UNVISITED)
// what matches :link or :visited
CSS_STATE_PSEUDO_CLASS(mozAnyLink, ":-moz-any-link", 0, "",
NS_EVENT_STATE_VISITED | NS_EVENT_STATE_UNVISITED)
CSS_STATE_PSEUDO_CLASS(anyLink, ":any-link", 0, "",
NS_EVENT_STATE_VISITED | NS_EVENT_STATE_UNVISITED)
CSS_STATE_PSEUDO_CLASS(visited, ":visited", 0, "", NS_EVENT_STATE_VISITED)
CSS_STATE_PSEUDO_CLASS(active, ":active", 0, "", NS_EVENT_STATE_ACTIVE)
+2 -2
View File
@@ -1420,7 +1420,7 @@ pref("network.http.bypass-cachelock-threshold", 250);
// Try and use SPDY when using SSL
pref("network.http.spdy.enabled", true);
pref("network.http.spdy.enabled.v3-1", true);
pref("network.http.spdy.enabled.v3-1", false);
pref("network.http.spdy.enabled.http2", true);
pref("network.http.spdy.enabled.deps", true);
pref("network.http.spdy.enforce-tls-profile", true);
@@ -5145,4 +5145,4 @@ pref("toolkit.pageThumbs.minWidth", 0);
pref("toolkit.pageThumbs.minHeight", 0);
pref("tenfourfox.adblock.enabled", false);
pref("tenfourfox.adblock.logging.enabled", true);
pref("tenfourfox.adblock.logging.enabled", false);
+5 -4
View File
@@ -20,18 +20,19 @@ pref("security.ssl.enable_alpn", true);
pref("security.ssl3.ecdhe_rsa_aes_128_gcm_sha256", true);
pref("security.ssl3.ecdhe_ecdsa_aes_128_gcm_sha256", true);
pref("security.ssl3.ecdhe_rsa_aes_128_sha", true);
pref("security.ssl3.ecdhe_rsa_aes_128_sha256", true);
pref("security.ssl3.ecdhe_ecdsa_aes_128_sha", true);
pref("security.ssl3.ecdhe_rsa_aes_256_sha", true);
pref("security.ssl3.ecdhe_ecdsa_aes_256_sha", true);
pref("security.ssl3.dhe_rsa_aes_128_sha", true);
pref("security.ssl3.dhe_rsa_aes_256_sha", true);
pref("security.ssl3.ecdhe_rsa_rc4_128_sha", true);
pref("security.ssl3.ecdhe_ecdsa_rc4_128_sha", true);
pref("security.ssl3.ecdhe_rsa_rc4_128_sha", false);
pref("security.ssl3.ecdhe_ecdsa_rc4_128_sha", false);
pref("security.ssl3.rsa_aes_128_sha", true);
pref("security.ssl3.rsa_aes_256_sha", true);
pref("security.ssl3.rsa_des_ede3_sha", true);
pref("security.ssl3.rsa_rc4_128_sha", true);
pref("security.ssl3.rsa_rc4_128_md5", true);
pref("security.ssl3.rsa_rc4_128_sha", false);
pref("security.ssl3.rsa_rc4_128_md5", false);
pref("security.default_personal_cert", "Ask Every Time");
pref("security.remember_cert_checkbox_default_setting", true);
+1 -1
View File
@@ -1184,4 +1184,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
static const int32_t kUnknownId = -1;
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1528837162062000);
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1530217066204000);
File diff suppressed because it is too large Load Diff
+7
View File
@@ -59,6 +59,13 @@ interface nsIDatePicker : nsISupports
*/
attribute AString maxDate;
/**
* The selected date.
*
* @return Returns the date currently selected.
*/
readonly attribute AString selectedDate;
/**
* Show date dialog. The dialog is displayed modally.
*
+30 -6
View File
@@ -12,6 +12,7 @@
#include "mozilla/HashFunctions.h"
#include "mozilla/MathAlgorithms.h"
#include "nsAlgorithm.h"
#include "mozilla/HashFunctions.h"
#include "mozilla/Likely.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/ChaosMode.h"
@@ -71,7 +72,7 @@ PLDHashTable::HashStringKey(PLDHashTable* aTable, const void* aKey)
/* static */ PLDHashNumber
PLDHashTable::HashVoidPtrKeyStub(PLDHashTable* aTable, const void* aKey)
{
return (PLDHashNumber)(ptrdiff_t)aKey >> 2;
return mozilla::HashGeneric(aKey);
}
/* static */ bool
@@ -256,15 +257,38 @@ PLDHashTable::Hash1(PLDHashNumber aHash0)
return aHash0 >> mHashShift;
}
// Double hashing needs the second hash code to be relatively prime to table
// size, so we simply make hash2 odd.
void
PLDHashTable::Hash2(PLDHashNumber aHash,
PLDHashTable::Hash2(PLDHashNumber aHash0,
uint32_t& aHash2Out, uint32_t& aSizeMaskOut)
{
uint32_t sizeLog2 = kHashBits - mHashShift;
aHash2Out = ((aHash << sizeLog2) >> mHashShift) | 1;
aSizeMaskOut = (PLDHashNumber(1) << sizeLog2) - 1;
uint32_t sizeMask = (PLDHashNumber(1) << sizeLog2) - 1;
aSizeMaskOut = sizeMask;
// The incoming aHash0 always has the low bit unset (since we leave it
// free for the collision flag), and should have reasonably random
// data in the other 31 bits. We used the high bits of aHash0 for
// Hash1, so we use the low bits here. If the table size is large,
// the bits we use may overlap, but that's still more random than
// filling with 0s.
//
// Since the result of Hash2 controls how far we jump around the table
// to build a chain after starting at a location determined by Hash1,
// we'd like to keep it small, to improve cache behavior.
// Keep the jumps from the second hash small, to improve cache behavior.
const uint32_t kHash2MaskMaxBits = 6;
uint32_t hash2Mask;
if (sizeLog2 >= kHash2MaskMaxBits) {
hash2Mask = (PLDHashNumber(1) << kHash2MaskMaxBits) - 1;
} else {
hash2Mask = sizeMask;
}
// Double hashing needs the second hash code to be relatively prime to table
// size, so we simply make hash2 odd.
//
// This also conveniently covers up the fact that we have the low bit
// unset since aHash0 has the low bit unset.
aHash2Out = (aHash0 & hash2Mask) | 1;
}
// Reserve mKeyHash 0 for free entries and 1 for removed-entry sentinels. Note
+44
View File
@@ -1026,6 +1026,17 @@ CountCharInReadable(const nsACString& aStr, char aChar)
return count;
}
bool
StringBeginsWith(const nsAString& aSource, const nsAString& aSubstring)
{
nsAString::size_type src_len = aSource.Length(),
sub_len = aSubstring.Length();
if (sub_len > src_len) {
return false;
}
return Substring(aSource, 0, sub_len).Equals(aSubstring);
}
bool
StringBeginsWith(const nsAString& aSource, const nsAString& aSubstring,
const nsStringComparator& aComparator)
@@ -1038,6 +1049,17 @@ StringBeginsWith(const nsAString& aSource, const nsAString& aSubstring,
return Substring(aSource, 0, sub_len).Equals(aSubstring, aComparator);
}
bool
StringBeginsWith(const nsACString& aSource, const nsACString& aSubstring)
{
nsACString::size_type src_len = aSource.Length(),
sub_len = aSubstring.Length();
if (sub_len > src_len) {
return false;
}
return Substring(aSource, 0, sub_len).Equals(aSubstring);
}
bool
StringBeginsWith(const nsACString& aSource, const nsACString& aSubstring,
const nsCStringComparator& aComparator)
@@ -1050,6 +1072,17 @@ StringBeginsWith(const nsACString& aSource, const nsACString& aSubstring,
return Substring(aSource, 0, sub_len).Equals(aSubstring, aComparator);
}
bool
StringEndsWith(const nsAString& aSource, const nsAString& aSubstring)
{
nsAString::size_type src_len = aSource.Length(),
sub_len = aSubstring.Length();
if (sub_len > src_len) {
return false;
}
return Substring(aSource, src_len - sub_len, sub_len).Equals(aSubstring);
}
bool
StringEndsWith(const nsAString& aSource, const nsAString& aSubstring,
const nsStringComparator& aComparator)
@@ -1063,6 +1096,17 @@ StringEndsWith(const nsAString& aSource, const nsAString& aSubstring,
aComparator);
}
bool
StringEndsWith(const nsACString& aSource, const nsACString& aSubstring)
{
nsACString::size_type src_len = aSource.Length(),
sub_len = aSubstring.Length();
if (sub_len > src_len) {
return false;
}
return Substring(aSource, src_len - sub_len, sub_len).Equals(aSubstring);
}
bool
StringEndsWith(const nsACString& aSource, const nsACString& aSubstring,
const nsCStringComparator& aComparator)
+8 -8
View File
@@ -386,18 +386,18 @@ uint32_t CountCharInReadable(const nsAString& aStr,
uint32_t CountCharInReadable(const nsACString& aStr,
char aChar);
bool StringBeginsWith(const nsAString& aSource, const nsAString& aSubstring);
bool StringBeginsWith(const nsAString& aSource, const nsAString& aSubstring,
const nsStringComparator& aComparator =
nsDefaultStringComparator());
const nsStringComparator& aComparator);
bool StringBeginsWith(const nsACString& aSource, const nsACString& aSubstring);
bool StringBeginsWith(const nsACString& aSource, const nsACString& aSubstring,
const nsCStringComparator& aComparator =
nsDefaultCStringComparator());
const nsCStringComparator& aComparator);
bool StringEndsWith(const nsAString& aSource, const nsAString& aSubstring);
bool StringEndsWith(const nsAString& aSource, const nsAString& aSubstring,
const nsStringComparator& aComparator =
nsDefaultStringComparator());
const nsStringComparator& aComparator);
bool StringEndsWith(const nsACString& aSource, const nsACString& aSubstring);
bool StringEndsWith(const nsACString& aSource, const nsACString& aSubstring,
const nsCStringComparator& aComparator =
nsDefaultCStringComparator());
const nsCStringComparator& aComparator);
const nsAFlatString& EmptyString();
const nsAFlatCString& EmptyCString();