Bug 1443722 - Implement customElements.upgrade() , r=mrbkap
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Wed, 20 Jun 2018 02:06:33 +0300
changeset 479779 693b36bb1292c4b999c4ef8b9ed6b06256be0bca
parent 479778 c159c8750ee1aa29a568a5d4609af98d8a9ea1b0
child 479780 c14e3d00d74076f7908f4c1259ccd7e869e60a31
push id1757
push userffxbld-merge
push dateFri, 24 Aug 2018 17:02:43 +0000
treeherdermozilla-release@736023aebdb1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap
bugs1443722
milestone62.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1443722 - Implement customElements.upgrade() , r=mrbkap
dom/base/CustomElementRegistry.cpp
dom/base/CustomElementRegistry.h
dom/webidl/CustomElementRegistry.webidl
testing/web-platform/meta/custom-elements/custom-element-registry/upgrade.html.ini
testing/web-platform/meta/html/dom/interfaces.https.html.ini
--- a/dom/base/CustomElementRegistry.cpp
+++ b/dom/base/CustomElementRegistry.cpp
@@ -977,16 +977,55 @@ CustomElementRegistry::SetElementCreatio
   }
 
   RefPtr<CustomElementCreationCallback> callback = &aCallback;
   mElementCreationCallbacks.Put(nameAtom, callback.forget());
   return;
 }
 
 void
+TryUpgrade(nsINode& aNode)
+{
+  Element* element = aNode.IsElement() ? aNode.AsElement() : nullptr;
+  if (element) {
+    CustomElementData* ceData = element->GetCustomElementData();
+    if (ceData) {
+      NodeInfo* nodeInfo = element->NodeInfo();
+      nsAtom* typeAtom = ceData->GetCustomElementType();
+      CustomElementDefinition* definition =
+        nsContentUtils::LookupCustomElementDefinition(nodeInfo->GetDocument(),
+                                                      nodeInfo->NameAtom(),
+                                                      nodeInfo->NamespaceID(),
+                                                      typeAtom);
+      if (definition) {
+        nsContentUtils::EnqueueUpgradeReaction(element, definition);
+      }
+    }
+
+    if (ShadowRoot* root = element->GetShadowRoot()) {
+      for (Element* child = root->GetFirstElementChild(); child;
+           child = child->GetNextElementSibling()) {
+        TryUpgrade(*child);
+      }
+    }
+  }
+
+  for (Element* child = aNode.GetFirstElementChild(); child;
+       child = child->GetNextElementSibling()) {
+    TryUpgrade(*child);
+  }
+}
+
+void
+CustomElementRegistry::Upgrade(nsINode& aRoot)
+{
+  TryUpgrade(aRoot);
+}
+
+void
 CustomElementRegistry::Get(JSContext* aCx, const nsAString& aName,
                            JS::MutableHandle<JS::Value> aRetVal)
 {
   RefPtr<nsAtom> nameAtom(NS_Atomize(aName));
   CustomElementDefinition* data = mCustomDefinitions.GetWeak(nameAtom);
 
   if (!data) {
     aRetVal.setUndefined();
--- a/dom/base/CustomElementRegistry.h
+++ b/dom/base/CustomElementRegistry.h
@@ -549,16 +549,18 @@ public:
   void Get(JSContext* cx, const nsAString& name,
            JS::MutableHandle<JS::Value> aRetVal);
 
   already_AddRefed<Promise> WhenDefined(const nsAString& aName, ErrorResult& aRv);
 
   // Chrome-only method that give JS an opportunity to only load the custom
   // element definition script when needed.
   void SetElementCreationCallback(const nsAString& aName, CustomElementCreationCallback& aCallback, ErrorResult& aRv);
+
+  void Upgrade(nsINode& aRoot);
 };
 
 class MOZ_RAII AutoCEReaction final {
   public:
     // JSContext is allowed to be a nullptr if we are guaranteeing that we're
     // not doing something that might throw but not finish reporting a JS
     // exception during the lifetime of the AutoCEReaction.
     AutoCEReaction(CustomElementReactionsStack* aReactionsStack, JSContext* aCx)
--- a/dom/webidl/CustomElementRegistry.webidl
+++ b/dom/webidl/CustomElementRegistry.webidl
@@ -8,15 +8,16 @@ interface CustomElementRegistry {
   [CEReactions, Throws]
   void define(DOMString name, Function functionConstructor,
               optional ElementDefinitionOptions options);
   [ChromeOnly, Throws]
   void setElementCreationCallback(DOMString name, CustomElementCreationCallback callback);
   any get(DOMString name);
   [Throws]
   Promise<void> whenDefined(DOMString name);
+  [CEReactions] void upgrade(Node root);
 };
 
 dictionary ElementDefinitionOptions {
   DOMString extends;
 };
 
 callback CustomElementCreationCallback = void (DOMString name);
--- a/testing/web-platform/meta/custom-elements/custom-element-registry/upgrade.html.ini
+++ b/testing/web-platform/meta/custom-elements/custom-element-registry/upgrade.html.ini
@@ -1,16 +1,2 @@
 [upgrade.html]
-  [Upgrading an element directly (example from the spec)]
-    expected: FAIL
-
-  [Two elements as children of the upgraded node]
-    expected: FAIL
-
-  [Two elements as descendants of the upgraded node]
-    expected: FAIL
-
-  [Two elements as shadow-including descendants (and not descendants) of the upgraded node]
-    expected: FAIL
-
-  [Elements inside a template contents DocumentFragment node]
-    expected: FAIL
-
+  prefs: [dom.webcomponents.shadowdom.enabled:true]
--- a/testing/web-platform/meta/html/dom/interfaces.https.html.ini
+++ b/testing/web-platform/meta/html/dom/interfaces.https.html.ini
@@ -1398,11 +1398,8 @@
     expected: FAIL
 
   [HTMLFrameSetElement interface: document.createElement("frameset") must inherit property "onrejectionhandled" with the proper type]
     expected: FAIL
 
   [HTMLFrameSetElement interface: document.createElement("frameset") must inherit property "onunhandledrejection" with the proper type]
     expected: FAIL
 
-  [CustomElementRegistry interface: operation upgrade(Node)]
-    expected: FAIL
-