diff options
author | Gaming4JC <g4jc@hyperbola.info> | 2020-01-02 21:24:22 -0500 |
---|---|---|
committer | Gaming4JC <g4jc@hyperbola.info> | 2020-01-26 15:50:08 -0500 |
commit | 2d31ebf6b6bba8c1b90982f687346e5c6a0ff6ef (patch) | |
tree | 6608bac749f8ec0d2a334f49ab79f99ec232ccd4 | |
parent | bc8543bf793b5c203600c57565214b5e20f54592 (diff) | |
download | uxp-2d31ebf6b6bba8c1b90982f687346e5c6a0ff6ef.tar.gz |
Bug 1274159 - Part 1: Support looking up definitions by using constructor as a key;
Tag UXP Issue #1344
5 files changed, 50 insertions, 36 deletions
diff --git a/dom/base/CustomElementRegistry.cpp b/dom/base/CustomElementRegistry.cpp index 3f202d33b3..43e4e7e2a6 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> 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 ff803a0542..9034dd7ea3 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<nsISupportsHashKey, nsTArray<nsWeakPtr>> CandidateMap; + typedef JS::GCHashMap<JS::Heap<JSObject*>, + nsCOMPtr<nsIAtom>, + js::MovableCellHasher<JS::Heap<JSObject*>>, + 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<nsISupportsHashKey, Promise> 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 82bb1c2c6d..0eebff1160 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"); </script> diff --git a/testing/web-platform/meta/custom-elements/CustomElementRegistry.html.ini b/testing/web-platform/meta/custom-elements/CustomElementRegistry.html.ini index 9e2bf73856..f62b64dfb5 100644 --- a/testing/web-platform/meta/custom-elements/CustomElementRegistry.html.ini +++ b/testing/web-platform/meta/custom-elements/CustomElementRegistry.html.ini @@ -1,8 +1,5 @@ [CustomElementRegistry.html] type: testharness - [customElements.define must throw a NotSupportedError when there is already a custom element with the same class] - expected: FAIL - [customElements.define must get callbacks of the constructor prototype] expected: FAIL diff --git a/testing/web-platform/meta/custom-elements/custom-element-registry/define.html.ini b/testing/web-platform/meta/custom-elements/custom-element-registry/define.html.ini deleted file mode 100644 index 122abccd31..0000000000 --- a/testing/web-platform/meta/custom-elements/custom-element-registry/define.html.ini +++ /dev/null @@ -1,26 +0,0 @@ -[define.html] - type: testharness - [If constructor is HTMLElement, should throw a TypeError] - expected: FAIL - - [If constructor is HTMLButtonElement, should throw a TypeError] - expected: FAIL - - [If constructor is HTMLImageElement, should throw a TypeError] - expected: FAIL - - [If constructor is HTMLMediaElement, should throw a TypeError] - expected: FAIL - - [If constructor is Image, should throw a TypeError] - expected: FAIL - - [If constructor is Audio, should throw a TypeError] - expected: FAIL - - [If constructor is Option, should throw a TypeError] - expected: FAIL - - [If the constructor is already defined, should throw a NotSupportedError] - expected: FAIL - |