Bug 1443722 - Implement customElements.upgrade() , r=mrbkap
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Wed, 20 Jun 2018 02:06:33 +0300
changeset 423074 693b36bb1292c4b999c4ef8b9ed6b06256be0bca
parent 423073 c159c8750ee1aa29a568a5d4609af98d8a9ea1b0
child 423075 c14e3d00d74076f7908f4c1259ccd7e869e60a31
push id65342
push userapavel@mozilla.com
push dateWed, 20 Jun 2018 11:30:38 +0000
treeherderautoland@dadc58a65c2e [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
-