HTMLOutputElement.htmlFor should be settable
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 22 Sep 2015 21:24:28 +0000 (21:24 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 22 Sep 2015 21:24:28 +0000 (21:24 +0000)
https://bugs.webkit.org/show_bug.cgi?id=149418

Reviewed by Darin Adler.

Source/WebCore:

HTMLOutputElement.htmlFor should be settable as per the latest HTML
specification:
- https://html.spec.whatwg.org/multipage/forms.html#the-output-element

It is supposed to call DOMSettableTokenList.setValue() with the input
String. This patch adds support for this by adding [PutForwards=value]
IDL extended attribute.

This aligns our behavior with the specification, Firefox and Chrome.

No new tests, already covered by existing test.

* accessibility/AccessibilityObject.cpp:
(WebCore::AccessibilityObject::classList):
* dom/Element.cpp:
(WebCore::Element::classList):
* dom/ElementRareData.h:
(WebCore::ElementRareData::setClassList):
* html/AttributeDOMTokenList.h:
* html/DOMSettableTokenList.h:
* html/HTMLAnchorElement.cpp:
(WebCore::HTMLAnchorElement::relList):
* html/HTMLAnchorElement.h:
* html/HTMLLinkElement.cpp:
(WebCore::HTMLLinkElement::relList):
* html/HTMLLinkElement.h:
* html/HTMLOutputElement.cpp:
(WebCore::HTMLOutputElement::HTMLOutputElement):
(WebCore::HTMLOutputElement::parseAttribute):
(WebCore::HTMLOutputElement::childrenChanged): Deleted.
* html/HTMLOutputElement.h:
* html/HTMLOutputElement.idl:

LayoutTests:

Update existing layout test now that HTMLOutputElement.htmlFor is
settable.

* fast/dom/HTMLOutputElement/dom-settable-token-list-expected.txt:
* fast/dom/HTMLOutputElement/script-tests/dom-settable-token-list.js:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@190134 268f45cc-cd09-0410-ab3c-d52691b4dbfc

19 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/dom/HTMLOutputElement/dom-settable-token-list-expected.txt
LayoutTests/fast/dom/HTMLOutputElement/script-tests/dom-settable-token-list.js
Source/WebCore/ChangeLog
Source/WebCore/dom/Element.cpp
Source/WebCore/dom/ElementRareData.h
Source/WebCore/html/AttributeDOMTokenList.cpp
Source/WebCore/html/AttributeDOMTokenList.h
Source/WebCore/html/DOMSettableTokenList.cpp
Source/WebCore/html/DOMSettableTokenList.h
Source/WebCore/html/DOMTokenList.cpp
Source/WebCore/html/DOMTokenList.h
Source/WebCore/html/HTMLAnchorElement.cpp
Source/WebCore/html/HTMLAnchorElement.h
Source/WebCore/html/HTMLLinkElement.cpp
Source/WebCore/html/HTMLLinkElement.h
Source/WebCore/html/HTMLOutputElement.cpp
Source/WebCore/html/HTMLOutputElement.h
Source/WebCore/html/HTMLOutputElement.idl

index ad72069..e0e6373 100644 (file)
@@ -1,3 +1,16 @@
+2015-09-22  Chris Dumez  <cdumez@apple.com>
+
+        HTMLOutputElement.htmlFor should be settable
+        https://bugs.webkit.org/show_bug.cgi?id=149418
+
+        Reviewed by Darin Adler.
+
+        Update existing layout test now that HTMLOutputElement.htmlFor is
+        settable.
+
+        * fast/dom/HTMLOutputElement/dom-settable-token-list-expected.txt:
+        * fast/dom/HTMLOutputElement/script-tests/dom-settable-token-list.js:
+
 2015-09-22  Tim Horton  <timothy_horton@apple.com>
 
         Demystify why a few text tests depend on threaded scrolling being disabled
index b3b29f7..9e7ea90 100644 (file)
@@ -4,7 +4,10 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 
 
 - Tests from http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/
-PASS String(element.htmlFor) is "x"
+PASS element.htmlFor.__proto__ is DOMSettableTokenList.prototype
+PASS String(element.htmlFor) is "y z"
+PASS element.getAttribute("for") is "y z"
+PASS String(element.htmlFor) is "r s t"
 PASS element.htmlFor.length is 0
 PASS element.htmlFor.length is 1
 PASS element.htmlFor.length is 1
index 44dc678..fd0f988 100644 (file)
@@ -14,10 +14,14 @@ function createElement(tokenList)
 
 debug('- Tests from http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/');
 
-// HTMLOutputElement::htmlFor is readonly attribute.
+// HTMLOutputElement::htmlFor should be settable.
 createElement('x');
-element.htmlFor = 'y';
-shouldBeEqualToString('String(element.htmlFor)', 'x');
+shouldBe('element.htmlFor.__proto__', 'DOMSettableTokenList.prototype');
+element.htmlFor = 'y  z';
+shouldBeEqualToString('String(element.htmlFor)', 'y z');
+shouldBeEqualToString('element.getAttribute("for")', 'y z');
+element.setAttribute('for', 'r s t');
+shouldBeEqualToString('String(element.htmlFor)', 'r s t');
 
 // http://simon.html5.org/test/html/dom/reflecting/DOMTokenList/getting/001.htm
 createElement('');
index 2594901..82f8f55 100644 (file)
@@ -1,3 +1,43 @@
+2015-09-22  Chris Dumez  <cdumez@apple.com>
+
+        HTMLOutputElement.htmlFor should be settable
+        https://bugs.webkit.org/show_bug.cgi?id=149418
+
+        Reviewed by Darin Adler.
+
+        HTMLOutputElement.htmlFor should be settable as per the latest HTML
+        specification:
+        - https://html.spec.whatwg.org/multipage/forms.html#the-output-element
+
+        It is supposed to call DOMSettableTokenList.setValue() with the input
+        String. This patch adds support for this by adding [PutForwards=value]
+        IDL extended attribute.
+
+        This aligns our behavior with the specification, Firefox and Chrome.
+
+        No new tests, already covered by existing test.
+
+        * accessibility/AccessibilityObject.cpp:
+        (WebCore::AccessibilityObject::classList):
+        * dom/Element.cpp:
+        (WebCore::Element::classList):
+        * dom/ElementRareData.h:
+        (WebCore::ElementRareData::setClassList):
+        * html/AttributeDOMTokenList.h:
+        * html/DOMSettableTokenList.h:
+        * html/HTMLAnchorElement.cpp:
+        (WebCore::HTMLAnchorElement::relList):
+        * html/HTMLAnchorElement.h:
+        * html/HTMLLinkElement.cpp:
+        (WebCore::HTMLLinkElement::relList):
+        * html/HTMLLinkElement.h:
+        * html/HTMLOutputElement.cpp:
+        (WebCore::HTMLOutputElement::HTMLOutputElement):
+        (WebCore::HTMLOutputElement::parseAttribute):
+        (WebCore::HTMLOutputElement::childrenChanged): Deleted.
+        * html/HTMLOutputElement.h:
+        * html/HTMLOutputElement.idl:
+
 2015-09-22  Filip Pizlo  <fpizlo@apple.com>
 
         Get rid of ENABLE(GGC)
index abaa14f..67deec9 100644 (file)
@@ -2715,7 +2715,7 @@ DOMTokenList& Element::classList()
 {
     ElementRareData& data = ensureElementRareData();
     if (!data.classList())
-        data.setClassList(std::make_unique<AttributeDOMTokenList>(*this, HTMLNames::classAttr));
+        data.setClassList(AttributeDOMTokenList::create(*this, HTMLNames::classAttr));
     return *data.classList();
 }
 
index 5981cf4..099e6a2 100644 (file)
@@ -93,7 +93,7 @@ public:
     void setComputedStyle(Ref<RenderStyle>&& computedStyle) { m_computedStyle = WTF::move(computedStyle); }
 
     AttributeDOMTokenList* classList() const { return m_classList.get(); }
-    void setClassList(std::unique_ptr<AttributeDOMTokenList> classList) { m_classList = WTF::move(classList); }
+    void setClassList(RefPtr<AttributeDOMTokenList>&& classList) { m_classList = WTF::move(classList); }
 
     DatasetDOMStringMap* dataset() const { return m_dataset.get(); }
     void setDataset(std::unique_ptr<DatasetDOMStringMap> dataset) { m_dataset = WTF::move(dataset); }
@@ -134,7 +134,7 @@ private:
     RefPtr<RenderStyle> m_computedStyle;
 
     std::unique_ptr<DatasetDOMStringMap> m_dataset;
-    std::unique_ptr<AttributeDOMTokenList> m_classList;
+    RefPtr<AttributeDOMTokenList> m_classList;
     RefPtr<ShadowRoot> m_shadowRoot;
     std::unique_ptr<NamedNodeMap> m_attributeMap;
 
index 88ec6f4..2164d8a 100644 (file)
@@ -34,7 +34,7 @@ AttributeDOMTokenList::AttributeDOMTokenList(Element& element, const QualifiedNa
     : m_element(element)
     , m_attributeName(attributeName)
 {
-    setValue(m_element.getAttribute(m_attributeName));
+    setValueInternal(m_element.getAttribute(m_attributeName));
 }
 
 void AttributeDOMTokenList::attributeValueChanged(const AtomicString& newValue)
@@ -43,7 +43,7 @@ void AttributeDOMTokenList::attributeValueChanged(const AtomicString& newValue)
     if (m_isUpdatingAttributeValue)
         return;
 
-    DOMTokenList::setValue(newValue);
+    setValueInternal(newValue);
 }
 
 void AttributeDOMTokenList::updateAfterTokenChange()
index 34130fd..e735ea9 100644 (file)
 #ifndef AttributeDOMTokenList_h
 #define AttributeDOMTokenList_h
 
-#include "DOMTokenList.h"
+#include "DOMSettableTokenList.h"
 #include "Element.h"
 
 namespace WebCore {
 
-class AttributeDOMTokenList final : public DOMTokenList {
+class AttributeDOMTokenList final : public DOMSettableTokenList {
 public:
-    AttributeDOMTokenList(Element&, const QualifiedName& attributeName);
+    static Ref<AttributeDOMTokenList> create(Element& element, const QualifiedName& attributeName)
+    {
+        return adoptRef(*new AttributeDOMTokenList(element, attributeName));
+    }
+
     void attributeValueChanged(const AtomicString&);
 
 private:
-    virtual void ref() override { m_element.ref(); }
-    virtual void deref() override { m_element.deref(); }
+    AttributeDOMTokenList(Element&, const QualifiedName& attributeName);
 
     virtual Element* element() const override { return &m_element; }
     virtual void updateAfterTokenChange() override;
index 45d3b39..8d32dc5 100644 (file)
@@ -38,4 +38,10 @@ void DOMSettableTokenList::deref()
     RefCounted<DOMSettableTokenList>::deref();
 }
 
+void DOMSettableTokenList::setValue(const String& value)
+{
+    setValueInternal(value);
+    updateAfterTokenChange();
+}
+
 } // namespace WebCore
index 159eb51..3f600f1 100644 (file)
@@ -35,7 +35,7 @@ namespace WebCore {
 
 typedef int ExceptionCode;
 
-class DOMSettableTokenList final : public DOMTokenList, public RefCounted<DOMSettableTokenList> {
+class DOMSettableTokenList : public DOMTokenList, public RefCounted<DOMSettableTokenList> {
     WTF_MAKE_FAST_ALLOCATED;
 public:
     static Ref<DOMSettableTokenList> create()
@@ -43,12 +43,13 @@ public:
         return adoptRef(*new DOMSettableTokenList);
     }
 
+    void setValue(const String&);
+
     // Make public.
     using DOMTokenList::value;
-    using DOMTokenList::setValue;
 
-    virtual void ref() override;
-    virtual void deref() override;
+    virtual void ref() override final;
+    virtual void deref() override final;
 };
 
 } // namespace WebCore
index c86e0e2..acb4567 100644 (file)
@@ -158,7 +158,7 @@ const AtomicString& DOMTokenList::value() const
     return m_cachedValue;
 }
 
-void DOMTokenList::setValue(const String& value)
+void DOMTokenList::setValueInternal(const WTF::String& value)
 {
     // Clear tokens but not capacity.
     m_tokens.shrink(0);
index dc6ddfe..a27d47b 100644 (file)
@@ -61,7 +61,7 @@ public:
 protected:
     DOMTokenList() = default;
     const AtomicString& value() const;
-    void setValue(const String&);
+    void setValueInternal(const String&);
 
     virtual void updateAfterTokenChange() { m_cachedValue = nullAtom; }
 
index 053ec45..ef439af 100644 (file)
@@ -316,7 +316,7 @@ bool HTMLAnchorElement::hasRel(uint32_t relation) const
 DOMTokenList& HTMLAnchorElement::relList()
 {
     if (!m_relList) 
-        m_relList = std::make_unique<AttributeDOMTokenList>(*this, HTMLNames::relAttr);
+        m_relList = AttributeDOMTokenList::create(*this, HTMLNames::relAttr);
     return *m_relList;
 }
 
index fd9d966..c1fcdf2 100644 (file)
@@ -145,7 +145,7 @@ private:
     uint32_t m_linkRelations : 30;
     mutable LinkHash m_cachedVisitedLinkHash;
 
-    std::unique_ptr<AttributeDOMTokenList> m_relList;
+    RefPtr<AttributeDOMTokenList> m_relList;
 };
 
 inline LinkHash HTMLAnchorElement::visitedLinkHash() const
index ac19fca..750346b 100644 (file)
@@ -403,7 +403,7 @@ void HTMLLinkElement::dispatchPendingEvent(LinkEventSender* eventSender)
 DOMTokenList& HTMLLinkElement::relList()
 {
     if (!m_relList) 
-        m_relList = std::make_unique<AttributeDOMTokenList>(*this, HTMLNames::relAttr);
+        m_relList = AttributeDOMTokenList::create(*this, HTMLNames::relAttr);
     return *m_relList;
 }
 
index 091125e..be34821 100644 (file)
@@ -139,7 +139,7 @@ private:
 
     PendingSheetType m_pendingSheetType;
 
-    std::unique_ptr<AttributeDOMTokenList> m_relList;
+    RefPtr<AttributeDOMTokenList> m_relList;
 };
 
 } //namespace
index 67b25e8..ebf766b 100644 (file)
 
 namespace WebCore {
 
+using namespace HTMLNames;
+
 inline HTMLOutputElement::HTMLOutputElement(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
     : HTMLFormControlElement(tagName, document, form)
     , m_isDefaultValueMode(true)
     , m_isSetTextContentInProgress(false)
     , m_defaultValue("")
-    , m_tokens(DOMSettableTokenList::create())
+    , m_tokens(AttributeDOMTokenList::create(*this, forAttr))
 {
 }
 
@@ -64,17 +66,12 @@ bool HTMLOutputElement::supportsFocus() const
 
 void HTMLOutputElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
-    if (name == HTMLNames::forAttr)
-        setFor(value);
+    if (name == forAttr)
+        m_tokens->attributeValueChanged(value);
     else
         HTMLFormControlElement::parseAttribute(name, value);
 }
 
-void HTMLOutputElement::setFor(const String& value)
-{
-    m_tokens->setValue(value);
-}
-
 void HTMLOutputElement::childrenChanged(const ChildChange& change)
 {
     HTMLFormControlElement::childrenChanged(change);
index 0c0f15e..576e3f7 100644 (file)
@@ -31,7 +31,7 @@
 #ifndef HTMLOutputElement_h
 #define HTMLOutputElement_h
 
-#include "DOMSettableTokenList.h"
+#include "AttributeDOMTokenList.h"
 #include "HTMLFormControlElement.h"
 
 namespace WebCore {
@@ -44,7 +44,6 @@ public:
     void setValue(const String&);
     String defaultValue() const;
     void setDefaultValue(const String&);
-    void setFor(const String&);
     DOMSettableTokenList& htmlFor() { return m_tokens.get(); }
     
     virtual bool canContainRangeEndPoint() const override { return false; }
@@ -66,7 +65,7 @@ private:
     bool m_isDefaultValueMode;
     bool m_isSetTextContentInProgress;
     String m_defaultValue;
-    Ref<DOMSettableTokenList> m_tokens;
+    Ref<AttributeDOMTokenList> m_tokens;
 };
 
 } // namespace
index 4f1c6c3..bdcb0bd 100644 (file)
@@ -23,9 +23,7 @@
  */
 
 interface HTMLOutputElement : HTMLElement {
-    // FIXME: This is supposed to be:
-    // [PutForwards=value] readonly attribute DOMSettableTokenList htmlFor;
-    readonly attribute DOMSettableTokenList htmlFor;
+    [PutForwards=value] readonly attribute DOMSettableTokenList htmlFor;
 
     readonly attribute HTMLFormElement form;
     [Reflect] attribute DOMString name;