Bug 1398354 part 2. Update document.all item() and legacycaller to new spec semantics. r=mccr8
☠☠ backed out by a42a9fc0c5f4 ☠ ☠
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 17 Oct 2018 23:00:49 -0400
changeset 490132 344b7e258ea5d73fdd919a6ed6459189874c3533
parent 490131 8e41c385edb99568fed370ef17d646dceefa00f9
child 490133 a42a9fc0c5f4bc801873a3803ffefbe0761c9b59
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersmccr8
bugs1398354
milestone64.0a1
Bug 1398354 part 2. Update document.all item() and legacycaller to new spec semantics. r=mccr8
dom/html/HTMLAllCollection.cpp
dom/html/HTMLAllCollection.h
dom/webidl/HTMLAllCollection.webidl
testing/web-platform/meta/html/dom/interfaces.https.html.ini
testing/web-platform/meta/html/infrastructure/common-dom-interfaces/collections/htmlallcollection.html.ini
--- a/dom/html/HTMLAllCollection.cpp
+++ b/dom/html/HTMLAllCollection.cpp
@@ -44,20 +44,47 @@ HTMLAllCollection::GetParentObject() con
 }
 
 uint32_t
 HTMLAllCollection::Length()
 {
   return Collection()->Length(true);
 }
 
-nsIContent*
+Element*
 HTMLAllCollection::Item(uint32_t aIndex)
 {
-  return Collection()->Item(aIndex);
+  nsIContent* item = Collection()->Item(aIndex);
+  return item ? item->AsElement() : nullptr;
+}
+
+void
+HTMLAllCollection::Item(const Optional<nsAString>& aNameOrIndex,
+                        Nullable<OwningHTMLCollectionOrElement>& aResult)
+{
+  if (!aNameOrIndex.WasPassed()) {
+    aResult.SetNull();
+    return;
+  }
+
+  const nsAString& nameOrIndex = aNameOrIndex.Value();
+  uint32_t indexVal;
+  if (js::StringIsArrayIndex(nameOrIndex.BeginReading(),
+                             nameOrIndex.Length(),
+                             &indexVal)) {
+    Element* element = Item(indexVal);
+    if (element) {
+      aResult.SetValue().SetAsElement() = element;
+    } else {
+      aResult.SetNull();
+    }
+    return;
+  }
+
+  NamedItem(nameOrIndex, aResult);
 }
 
 nsContentList*
 HTMLAllCollection::Collection()
 {
   if (!mCollection) {
     nsIDocument* document = mDocument;
     mCollection = document->GetElementsByTagName(NS_LITERAL_STRING("*"));
@@ -116,17 +143,17 @@ HTMLAllCollection::GetDocumentAllList(co
       return new nsContentList(mDocument, DocAllResultMatch, nullptr,
                                nullptr, true, id);
     });
 }
 
 void
 HTMLAllCollection::NamedGetter(const nsAString& aID,
                                bool& aFound,
-                               Nullable<OwningNodeOrHTMLCollection>& aResult)
+                               Nullable<OwningHTMLCollectionOrElement>& aResult)
 {
   if (aID.IsEmpty()) {
     aFound = false;
     aResult.SetNull();
     return;
   }
 
   nsContentList* docAllList = GetDocumentAllList(aID);
@@ -143,17 +170,17 @@ HTMLAllCollection::NamedGetter(const nsA
     aFound = true;
     aResult.SetValue().SetAsHTMLCollection() = docAllList;
     return;
   }
 
   // There's only 0 or 1 items. Return the first one or null.
   if (nsIContent* node = docAllList->Item(0, true)) {
     aFound = true;
-    aResult.SetValue().SetAsNode() = node;
+    aResult.SetValue().SetAsElement() = node->AsElement();
     return;
   }
 
   aFound = false;
   aResult.SetNull();
 }
 
 void
--- a/dom/html/HTMLAllCollection.h
+++ b/dom/html/HTMLAllCollection.h
@@ -11,76 +11,82 @@
 #include "nsISupportsImpl.h"
 #include "nsRefPtrHashtable.h"
 #include "nsWrapperCache.h"
 
 #include <stdint.h>
 
 class nsContentList;
 class nsHTMLDocument;
-class nsIContent;
 class nsINode;
 
 namespace mozilla {
 namespace dom {
 
-class OwningNodeOrHTMLCollection;
+class Element;
+class OwningHTMLCollectionOrElement;
 template<typename> struct Nullable;
+template<typename> class Optional;
 
 class HTMLAllCollection final : public nsISupports
                               , public nsWrapperCache
 {
   ~HTMLAllCollection();
 
 public:
   explicit HTMLAllCollection(nsHTMLDocument* aDocument);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(HTMLAllCollection)
 
   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
   nsINode* GetParentObject() const;
 
   uint32_t Length();
-  nsIContent* Item(uint32_t aIndex);
-  void Item(const nsAString& aName, Nullable<OwningNodeOrHTMLCollection>& aResult)
+  Element* IndexedGetter(uint32_t aIndex, bool& aFound)
   {
-    NamedItem(aName, aResult);
-  }
-  nsIContent* IndexedGetter(uint32_t aIndex, bool& aFound)
-  {
-    nsIContent* result = Item(aIndex);
+    Element* result = Item(aIndex);
     aFound = !!result;
     return result;
   }
 
   void NamedItem(const nsAString& aName,
-                 Nullable<OwningNodeOrHTMLCollection>& aResult)
+                 Nullable<OwningHTMLCollectionOrElement>& aResult)
   {
     bool found = false;
     NamedGetter(aName, found, aResult);
   }
   void NamedGetter(const nsAString& aName,
                    bool& aFound,
-                   Nullable<OwningNodeOrHTMLCollection>& aResult);
+                   Nullable<OwningHTMLCollectionOrElement>& aResult);
   void GetSupportedNames(nsTArray<nsString>& aNames);
-  void LegacyCall(JS::Handle<JS::Value>, const nsAString& aName,
-                  Nullable<OwningNodeOrHTMLCollection>& aResult)
+
+  void Item(const Optional<nsAString>& aNameOrIndex,
+            Nullable<OwningHTMLCollectionOrElement>& aResult);
+
+  void LegacyCall(JS::Handle<JS::Value>,
+                  const Optional<nsAString>& aNameOrIndex,
+                  Nullable<OwningHTMLCollectionOrElement>& aResult)
   {
-    NamedItem(aName, aResult);
+    Item(aNameOrIndex, aResult);
   }
 
 private:
   nsContentList* Collection();
 
   /**
    * Returns the HTMLCollection for document.all[aID], or null if there isn't one.
    */
   nsContentList* GetDocumentAllList(const nsAString& aID);
 
+  /**
+   * Helper for indexed getter and spec Item() method.
+   */
+  Element* Item(uint32_t aIndex);
+
   RefPtr<nsHTMLDocument> mDocument;
   RefPtr<nsContentList> mCollection;
   nsRefPtrHashtable<nsStringHashKey, nsContentList> mNamedMap;
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/webidl/HTMLAllCollection.webidl
+++ b/dom/webidl/HTMLAllCollection.webidl
@@ -1,14 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* Emulates undefined through Codegen.py. */
 [LegacyUnenumerableNamedProperties]
 interface HTMLAllCollection {
   readonly attribute unsigned long length;
-  getter Node? (unsigned long index);
-  Node? item(unsigned long index);
-  (Node or HTMLCollection)? item(DOMString name);
-  legacycaller (Node or HTMLCollection)? (DOMString name);
-  getter (Node or HTMLCollection)? namedItem(DOMString name);
+  getter Element (unsigned long index);
+  getter (HTMLCollection or Element)? namedItem(DOMString name);
+  (HTMLCollection or Element)? item(optional DOMString nameOrIndex);
+  legacycaller (HTMLCollection or Element)? (optional DOMString nameOrIndex);
 };
--- a/testing/web-platform/meta/html/dom/interfaces.https.html.ini
+++ b/testing/web-platform/meta/html/dom/interfaces.https.html.ini
@@ -353,19 +353,16 @@
   [Window interface: operation postMessage(any, [object Object\], WindowPostMessageOptions)]
     expected: FAIL
 
   [html interfaces]
     expected: FAIL
 
 
 [interfaces.https.html?include=HTML.*]
-  [HTMLAllCollection interface: operation item(DOMString)]
-    expected: FAIL
-
   [HTMLAllCollection must be primary interface of document.all]
     expected: FAIL
 
   [Stringification of document.all]
     expected: FAIL
 
   [HTMLAllCollection interface: document.all must inherit property "length" with the proper type]
     expected: FAIL
--- a/testing/web-platform/meta/html/infrastructure/common-dom-interfaces/collections/htmlallcollection.html.ini
+++ b/testing/web-platform/meta/html/infrastructure/common-dom-interfaces/collections/htmlallcollection.html.ini
@@ -1,31 +1,3 @@
 [htmlallcollection.html]
-  [legacy caller with "array index property name"]
-    expected: FAIL
-
-  [legacy caller with "array index property name" as number]
-    expected: FAIL
-
-  [legacy caller with invalid "array index property name"]
-    expected: FAIL
-
-  [legacy caller with no argument]
-    expected: FAIL
-
-  [item method with "array index property name"]
-    expected: FAIL
-
-  [item method with invalid "array index property name"]
-    expected: FAIL
-
-  [item method with no argument]
-    expected: FAIL
-
   [collections are new live HTMLCollection instances]
     expected: FAIL
-
-  [legacy caller with undefined]
-    expected: FAIL
-
-  [item method with undefined]
-    expected: FAIL
-