summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGaming4JC <g4jc@hyperbola.info>2020-01-02 21:24:22 -0500
committerGaming4JC <g4jc@hyperbola.info>2020-01-26 15:50:08 -0500
commit2d31ebf6b6bba8c1b90982f687346e5c6a0ff6ef (patch)
tree6608bac749f8ec0d2a334f49ab79f99ec232ccd4
parentbc8543bf793b5c203600c57565214b5e20f54592 (diff)
downloadUXP-2d31ebf6b6bba8c1b90982f687346e5c6a0ff6ef.tar
UXP-2d31ebf6b6bba8c1b90982f687346e5c6a0ff6ef.tar.gz
UXP-2d31ebf6b6bba8c1b90982f687346e5c6a0ff6ef.tar.lz
UXP-2d31ebf6b6bba8c1b90982f687346e5c6a0ff6ef.tar.xz
UXP-2d31ebf6b6bba8c1b90982f687346e5c6a0ff6ef.zip
Bug 1274159 - Part 1: Support looking up definitions by using constructor as a key;
Tag UXP Issue #1344
-rw-r--r--dom/base/CustomElementRegistry.cpp37
-rw-r--r--dom/base/CustomElementRegistry.h15
-rw-r--r--dom/bindings/test/test_bug560072.html5
-rw-r--r--testing/web-platform/meta/custom-elements/CustomElementRegistry.html.ini3
-rw-r--r--testing/web-platform/meta/custom-elements/custom-element-registry/define.html.ini26
5 files changed, 50 insertions, 36 deletions
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> 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<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 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");
</script>
diff --git a/testing/web-platform/meta/custom-elements/CustomElementRegistry.html.ini b/testing/web-platform/meta/custom-elements/CustomElementRegistry.html.ini
index 9e2bf7385..f62b64dfb 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 122abccd3..000000000
--- 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
-