Bug 1461321 - input.list should work in shadow DOM, r=peterv
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Thu, 24 May 2018 22:46:11 +0300
changeset 476471 c116c385bb02387c9b2b8e2ff1780ee1754b6be7
parent 476470 4f26f870269622cdb4986380d653bf0d49e4f4b3
child 476472 64da061ca2eb674335c50fa59bc27610f9665c54
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)
reviewerspeterv
bugs1461321
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 1461321 - input.list should work in shadow DOM, r=peterv
dom/base/nsINode.cpp
dom/base/nsINode.h
dom/html/HTMLInputElement.cpp
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/shadow-dom/input-element-list.html
--- a/dom/base/nsINode.cpp
+++ b/dom/base/nsINode.cpp
@@ -445,17 +445,17 @@ nsINode::GetComposedDocInternal() const
              "Should only be caled on nodes in the shadow tree.");
 
   ShadowRoot* containingShadow = AsContent()->GetContainingShadow();
   return containingShadow && containingShadow->IsComposedDocParticipant() ?
     OwnerDoc() : nullptr;
 }
 
 DocumentOrShadowRoot*
-nsINode::GetUncomposedDocOrConnectedShadowRoot()
+nsINode::GetUncomposedDocOrConnectedShadowRoot() const
 {
   if (IsInUncomposedDoc()) {
     return OwnerDoc();
   }
 
   if (IsInComposedDoc() && HasFlag(NODE_IS_IN_SHADOW_TREE)) {
     return AsContent()->GetContainingShadow();
   }
--- a/dom/base/nsINode.h
+++ b/dom/base/nsINode.h
@@ -687,17 +687,17 @@ public:
   {
     return IsInUncomposedDoc() || (IsInShadowTree() && GetComposedDocInternal());
   }
 
   /**
    * Returns OwnerDoc() if the node is in uncomposed document and ShadowRoot if
    * the node is in Shadow DOM and is in composed document.
    */
-  mozilla::dom::DocumentOrShadowRoot* GetUncomposedDocOrConnectedShadowRoot();
+  mozilla::dom::DocumentOrShadowRoot* GetUncomposedDocOrConnectedShadowRoot() const;
 
   /**
    * The values returned by this function are the ones defined for
    * nsIDOMNode.nodeType
    */
   uint16_t NodeType() const
   {
     return mNodeInfo->NodeType();
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -6,16 +6,17 @@
 
 #include "mozilla/dom/HTMLInputElement.h"
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/AsyncEventDispatcher.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/dom/Date.h"
 #include "mozilla/dom/Directory.h"
+#include "mozilla/dom/DocumentOrShadowRoot.h"
 #include "mozilla/dom/DOMPrefs.h"
 #include "mozilla/dom/HTMLFormSubmission.h"
 #include "mozilla/dom/FileSystemUtils.h"
 #include "mozilla/dom/GetFilesHelper.h"
 #include "mozilla/dom/WheelEventBinding.h"
 #include "nsAttrValueInlines.h"
 #include "nsCRTGlue.h"
 #include "nsQueryObject.h"
@@ -1712,23 +1713,22 @@ nsGenericHTMLElement*
 HTMLInputElement::GetList() const
 {
   nsAutoString dataListId;
   GetAttr(kNameSpaceID_None, nsGkAtoms::list_, dataListId);
   if (dataListId.IsEmpty()) {
     return nullptr;
   }
 
-  //XXXsmaug How should this all work in case input element is in Shadow DOM.
-  nsIDocument* doc = GetUncomposedDoc();
-  if (!doc) {
+  DocumentOrShadowRoot* docOrShadow = GetUncomposedDocOrConnectedShadowRoot();
+  if (!docOrShadow) {
     return nullptr;
   }
 
-  Element* element = doc->GetElementById(dataListId);
+  Element* element = docOrShadow->GetElementById(dataListId);
   if (!element || !element->IsHTMLElement(nsGkAtoms::datalist)) {
     return nullptr;
   }
 
   return static_cast<nsGenericHTMLElement*>(element);
 }
 
 void
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -368883,16 +368883,22 @@
     ]
    ],
    "shadow-dom/historical.html": [
     [
      "/shadow-dom/historical.html",
      {}
     ]
    ],
+   "shadow-dom/input-element-list.html": [
+    [
+     "/shadow-dom/input-element-list.html",
+     {}
+    ]
+   ],
    "shadow-dom/leaktests/get-elements.html": [
     [
      "/shadow-dom/leaktests/get-elements.html",
      {}
     ]
    ],
    "shadow-dom/leaktests/html-collection.html": [
     [
@@ -606888,16 +606894,20 @@
   "shadow-dom/form-control-form-attribute.html": [
    "7726f8fe9056d3d5c9fb7b963c4bc6e777a8256a",
    "testharness"
   ],
   "shadow-dom/historical.html": [
    "1469992db34a25397dc3d5a5e1eb600e8afcf71b",
    "testharness"
   ],
+  "shadow-dom/input-element-list.html": [
+   "79b4a278f0e35646cfdffeebf8f0523e2772bc9b",
+   "testharness"
+  ],
   "shadow-dom/layout-slot-no-longer-assigned.html": [
    "224a688177941774e0bd3be74cb4aef20160d903",
    "reftest"
   ],
   "shadow-dom/layout-slot-no-longer-fallback.html": [
    "a9be2ec9174a8944a237462b51519a8f88b4987a",
    "reftest"
   ],
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/shadow-dom/input-element-list.html
@@ -0,0 +1,39 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Input.list</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id="testcontent">
+  <input id="input" list="datalist">
+</div>
+<script>
+
+test(() => {
+  assert_equals(document.getElementById('input').list, null);
+  var dl = document.createElement("datalist");
+  dl.id = "datalist";
+  document.getElementById("testcontent").appendChild(dl);
+  assert_equals(document.getElementById('input').list, dl);
+}, "Input element's list attribute should point to the datalist element.");
+
+
+test(() => {
+  var host = document.createElement("div");
+  document.getElementById("testcontent").appendChild(host);
+  var sr = host.attachShadow({mode: "open"});
+  var input = document.createElement("input");
+  input.setAttribute("list", "datalist");
+  sr.appendChild(input);
+  assert_equals(input.list, null);
+
+  var dl = document.createElement("datalist");
+  dl.id = "datalist";
+  sr.appendChild(dl);
+  assert_equals(input.list, dl);
+
+  dl.remove();
+  assert_equals(input.list, null);
+}, "Input element's list attribute should point to the datalist element in Shadow DOM.");
+
+
+</script>