From 2d31ebf6b6bba8c1b90982f687346e5c6a0ff6ef Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Thu, 2 Jan 2020 21:24:22 -0500 Subject: Bug 1274159 - Part 1: Support looking up definitions by using constructor as a key; Tag UXP Issue #1344 --- dom/base/CustomElementRegistry.cpp | 37 +++++++++++++++++++++++++++++++---- dom/base/CustomElementRegistry.h | 15 +++++++++++++- dom/bindings/test/test_bug560072.html | 5 +++-- 3 files changed, 50 insertions(+), 7 deletions(-) (limited to 'dom') diff --git a/dom/base/CustomElementRegistry.cpp b/dom/base/CustomElementRegistry.cpp index 3f202d33b..43e4e7e2a 100644 --- a/dom/base/CustomElementRegistry.cpp +++ b/dom/base/CustomElementRegistry.cpp @@ -103,6 +103,7 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(CustomElementRegistry) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CustomElementRegistry) tmp->mCustomDefinitions.Clear(); + tmp->mConstructors.clear(); NS_IMPL_CYCLE_COLLECTION_UNLINK(mWhenDefinedPromiseMap) NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow) NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER @@ -149,6 +150,11 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(CustomElementRegistry) "mCustomDefinitions prototype", aClosure); } + for (ConstructorMap::Enum iter(tmp->mConstructors); !iter.empty(); iter.popFront()) { + aCallbacks.Trace(&iter.front().mutableKey(), + "mConstructors key", + aClosure); + } NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER NS_IMPL_CYCLE_COLLECTION_TRACE_END @@ -183,6 +189,11 @@ CustomElementRegistry::Create(nsPIDOMWindowInner* aWindow) RefPtr customElementRegistry = new CustomElementRegistry(aWindow); + + if (!customElementRegistry->Init()) { + return nullptr; + } + return customElementRegistry.forget(); } @@ -241,6 +252,12 @@ CustomElementRegistry::~CustomElementRegistry() mozilla::DropJSObjects(this); } +bool +CustomElementRegistry::Init() +{ + return mConstructors.init(); +} + CustomElementDefinition* CustomElementRegistry::LookupCustomElementDefinition(const nsAString& aLocalName, const nsAString* aIs) const @@ -609,9 +626,13 @@ CustomElementRegistry::Define(const nsAString& aName, * 4. If this CustomElementRegistry contains an entry with constructor constructor, * then throw a "NotSupportedError" DOMException and abort these steps. */ - // TODO: Step 3 of HTMLConstructor also needs a way to look up definition by - // using constructor. So I plans to figure out a solution to support both of - // them in bug 1274159. + const auto& ptr = mConstructors.lookup(constructorUnwrapped); + if (ptr) { + MOZ_ASSERT(mCustomDefinitions.Get(ptr->value()), + "Definition must be found in mCustomDefinitions"); + aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); + return; + } /** * 5. Let localName be name. @@ -767,8 +788,16 @@ CustomElementRegistry::Define(const nsAString& aName, /** * 12. Add definition to this CustomElementRegistry. */ + if (!mConstructors.put(constructorUnwrapped, nameAtom)) { + aRv.Throw(NS_ERROR_FAILURE); + return; + } + mCustomDefinitions.Put(nameAtom, definition); + MOZ_ASSERT(mCustomDefinitions.Count() == mConstructors.count(), + "Number of entries should be the same"); + /** * 13. 14. 15. Upgrade candidates */ @@ -853,4 +882,4 @@ CustomElementDefinition::CustomElementDefinition(nsIAtom* aType, } } // namespace dom -} // namespace mozilla \ No newline at end of file +} // namespace mozilla diff --git a/dom/base/CustomElementRegistry.h b/dom/base/CustomElementRegistry.h index ff803a054..9034dd7ea 100644 --- a/dom/base/CustomElementRegistry.h +++ b/dom/base/CustomElementRegistry.h @@ -7,13 +7,14 @@ #ifndef mozilla_dom_CustomElementRegistry_h #define mozilla_dom_CustomElementRegistry_h +#include "js/GCHashTable.h" #include "js/TypeDecls.h" #include "mozilla/Attributes.h" #include "mozilla/ErrorResult.h" #include "mozilla/dom/BindingDeclarations.h" +#include "mozilla/dom/FunctionBinding.h" #include "nsCycleCollectionParticipant.h" #include "nsWrapperCache.h" -#include "mozilla/dom/FunctionBinding.h" class nsDocument; @@ -173,6 +174,8 @@ private: explicit CustomElementRegistry(nsPIDOMWindowInner* aWindow); ~CustomElementRegistry(); + bool Init(); + /** * Registers an unresolved custom element that is a candidate for * upgrade when the definition is registered via registerElement. @@ -192,15 +195,25 @@ private: DefinitionMap; typedef nsClassHashtable> CandidateMap; + typedef JS::GCHashMap, + nsCOMPtr, + js::MovableCellHasher>, + js::SystemAllocPolicy> ConstructorMap; // Hashtable for custom element definitions in web components. // Custom prototypes are stored in the compartment where // registerElement was called. DefinitionMap mCustomDefinitions; + // Hashtable for looking up definitions by using constructor as key. + // Custom elements' name are stored here and we need to lookup + // mCustomDefinitions again to get definitions. + ConstructorMap mConstructors; + typedef nsRefPtrHashtable WhenDefinedPromiseMap; WhenDefinedPromiseMap mWhenDefinedPromiseMap; + // The "upgrade candidates map" from the web components spec. Maps from a // namespace id and local name to a list of elements to upgrade if that // element is registered as a custom element. diff --git a/dom/bindings/test/test_bug560072.html b/dom/bindings/test/test_bug560072.html index 82bb1c2c6..0eebff116 100644 --- a/dom/bindings/test/test_bug560072.html +++ b/dom/bindings/test/test_bug560072.html @@ -20,11 +20,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=560072 /** Test for Bug 560072 **/ is(document.body, - Object.getOwnPropertyDescriptor(HTMLDocument.prototype, "body").get.call(document), + Object.getOwnPropertyDescriptor(Document.prototype, "body").get.call(document), "Should get body out of property descriptor"); is(document.body, - Object.getOwnPropertyDescriptor(Object.getPrototypeOf(document), "body").get.call(document), + Object.getOwnPropertyDescriptor( + Object.getPrototypeOf(Object.getPrototypeOf(document)), "body").get.call(document), "Should get body out of property descriptor this way too"); -- cgit v1.2.3