2009-08-25 Kent Tamura <tkent@chromium.org>
authoreric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 26 Aug 2009 00:51:02 +0000 (00:51 +0000)
committereric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 26 Aug 2009 00:51:02 +0000 (00:51 +0000)
        Reviewed by Eric Seidel.

        Support for HTMLInputElement::list and HTMLInputElement::selectedOption.
        https://bugs.webkit.org/show_bug.cgi?id=27756

        Tests: fast/forms/input-list.html
               fast/forms/input-selectedoption.html

        * html/HTMLAttributeNames.in:
        * html/HTMLInputElement.cpp:
        (WebCore::HTMLInputElement::parseMappedAttribute):
        (WebCore::HTMLInputElement::list):
        (WebCore::HTMLInputElement::selectedOption):
        * html/HTMLInputElement.h:
        * html/HTMLInputElement.idl:
2009-08-25  Kent Tamura  <tkent@chromium.org>

        Reviewed by Eric Seidel.

        Support for HTMLInputElement::list and HTMLInputElement::selectedOption.
        https://bugs.webkit.org/show_bug.cgi?id=27756

        * fast/forms/input-list-expected.txt: Added.
        * fast/forms/input-list.html: Added.
        * fast/forms/input-selectedoption-expected.txt: Added.
        * fast/forms/input-selectedoption.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/fast/forms/input-list-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/input-list.html [new file with mode: 0644]
LayoutTests/fast/forms/input-selectedoption-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/input-selectedoption.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/html/HTMLAttributeNames.in
WebCore/html/HTMLInputElement.cpp
WebCore/html/HTMLInputElement.h
WebCore/html/HTMLInputElement.idl

index a330f51..b59cf35 100644 (file)
@@ -1,3 +1,15 @@
+2009-08-25  Kent Tamura  <tkent@chromium.org>
+
+        Reviewed by Eric Seidel.
+
+        Support for HTMLInputElement::list and HTMLInputElement::selectedOption.
+        https://bugs.webkit.org/show_bug.cgi?id=27756
+
+        * fast/forms/input-list-expected.txt: Added.
+        * fast/forms/input-list.html: Added.
+        * fast/forms/input-selectedoption-expected.txt: Added.
+        * fast/forms/input-selectedoption.html: Added.
+
 2009-08-25  Eric Carlson  <eric.carlson@apple.com>
 
         Reviewed by Oliver Hunt.
diff --git a/LayoutTests/fast/forms/input-list-expected.txt b/LayoutTests/fast/forms/input-list-expected.txt
new file mode 100644 (file)
index 0000000..07a1af8
--- /dev/null
@@ -0,0 +1,15 @@
+Test for the list attribute.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS input.list is null
+PASS input.list is null
+PASS input.list is null
+PASS input.list is document.getElementById("dl1")
+PASS input.list is null
+PASS datalist.className is "former"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+         
diff --git a/LayoutTests/fast/forms/input-list.html b/LayoutTests/fast/forms/input-list.html
new file mode 100644 (file)
index 0000000..5bd4170
--- /dev/null
@@ -0,0 +1,60 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
+<script src="../../fast/js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+
+<!-- No list attribute -->
+<input type="text" id="i1">
+<!-- Empty list -->
+<input type="text" id="i2" list="">
+<!-- Non-existent ID -->
+<input type="text" id="i3" list="nonexist">
+<!-- Normal case -->
+<input type="text" id="i4" list="dl1">
+<!-- Unsupported type -->
+<input type="password" id="i5" list="dl1">
+<!-- ID confilict -->
+<Input type="text" id="i6" list="dl2">
+
+<datalist id="dl1">
+ <option>value1</option>
+</datalist>
+
+<datalist id="dl2" class="former">
+ <option>value1</option>
+</datalist>
+<datalist id="dl2" class="latter">
+ <option>value1</option>
+</datalist>
+
+<script>
+description('Test for the list attribute.');
+
+var input = document.getElementById('i1');
+shouldBeNull('input.list');
+
+input = document.getElementById('i2');
+shouldBeNull('input.list');
+
+input = document.getElementById('i3');
+shouldBeNull('input.list');
+
+input = document.getElementById('i4');
+shouldBe('input.list', 'document.getElementById("dl1")');
+
+input = document.getElementById('i5');
+shouldBeNull('input.list');
+
+var datalist = document.getElementById('i6').list;
+shouldBe('datalist.className', '"former"');
+
+var successfullyParsed = true;
+</script>
+<script src="../../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/forms/input-selectedoption-expected.txt b/LayoutTests/fast/forms/input-selectedoption-expected.txt
new file mode 100644 (file)
index 0000000..9af894b
--- /dev/null
@@ -0,0 +1,17 @@
+Test for the selectedOption attribute.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS input.selectedOption is null
+PASS input.selectedOption is null
+PASS input.selectedOption is null
+PASS input.selectedOption is null
+PASS input.selectedOption is document.getElementById("o1")
+PASS input.selectedOption is document.getElementById("o2")
+PASS input.selectedOption is null
+PASS input.selectedOption is null
+PASS successfullyParsed is true
+
+TEST COMPLETE
+           
diff --git a/LayoutTests/fast/forms/input-selectedoption.html b/LayoutTests/fast/forms/input-selectedoption.html
new file mode 100644 (file)
index 0000000..201b0db
--- /dev/null
@@ -0,0 +1,70 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
+<script src="../../fast/js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+
+<!-- Empty value and no list attribute -->
+<input type="text" id="i1" value="">
+<!-- Empty list -->
+<input type="text" id="i2" value="foo" list="">
+<!-- Empty datalist -->
+<input type="text" id="i3" value="foo" list="dl1">
+<!-- Empty value and empty option -->
+<input type="text" id="i4" value="" list="dl2">
+<!-- Match cases -->
+<Input type="text" id="i5" value="foo" list="dl3">
+<Input type="text" id="i6" value="bar" list="dl3">
+<!-- Unmatch case -->
+<Input type="text" id="i7" value="foo" list="dl4">
+
+<datalist id="dl1">
+</datalist>
+<datalist id="dl2">
+ <option></option>
+</datalist>
+<datalist id="dl3">
+ <option id="o1">foo</option>
+ <option id="o2">bar</option>
+</datalist>
+<datalist id="dl3">
+ <option>bar</option>
+</datalist>
+
+<script>
+description('Test for the selectedOption attribute.');
+
+var input = document.getElementById('i1');
+shouldBeNull('input.selectedOption');
+
+input = document.getElementById('i2');
+shouldBeNull('input.selectedOption');
+
+input = document.getElementById('i3');
+shouldBeNull('input.selectedOption');
+
+input = document.getElementById('i4');
+shouldBeNull('input.selectedOption');
+
+input = document.getElementById('i5');
+shouldBe('input.selectedOption', 'document.getElementById("o1")');
+input = document.getElementById('i6');
+shouldBe('input.selectedOption', 'document.getElementById("o2")');
+
+document.getElementById('o1').disabled = true;
+input = document.getElementById('i5');
+shouldBeNull('input.selectedOption');
+
+input = document.getElementById('i7');
+shouldBeNull('input.selectedOption');
+
+
+var successfullyParsed = true;
+</script>
+<script src="../../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
index 3420ce5..1628297 100644 (file)
@@ -1,3 +1,21 @@
+2009-08-25  Kent Tamura  <tkent@chromium.org>
+
+        Reviewed by Eric Seidel.
+
+        Support for HTMLInputElement::list and HTMLInputElement::selectedOption.
+        https://bugs.webkit.org/show_bug.cgi?id=27756
+
+        Tests: fast/forms/input-list.html
+               fast/forms/input-selectedoption.html
+
+        * html/HTMLAttributeNames.in:
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::parseMappedAttribute):
+        (WebCore::HTMLInputElement::list):
+        (WebCore::HTMLInputElement::selectedOption):
+        * html/HTMLInputElement.h:
+        * html/HTMLInputElement.idl:
+
 2009-08-25  Eric Carlson  <eric.carlson@apple.com>
 
         Reviewed by Oliver Hunt.
index 279316d..e45eed0 100644 (file)
@@ -98,6 +98,7 @@ lang
 language
 leftmargin
 link
+list
 longdesc
 loop
 playcount
index b348d3a..5ffe4bf 100644 (file)
 #include "FocusController.h"
 #include "FormDataList.h"
 #include "Frame.h"
+#include "HTMLDataListElement.h"
 #include "HTMLFormElement.h"
 #include "HTMLImageLoader.h"
 #include "HTMLNames.h"
+#include "HTMLOptionElement.h"
 #include "ScriptEventListener.h"
 #include "KeyboardEvent.h"
 #include "LocalizedStrings.h"
@@ -735,6 +737,11 @@ void HTMLInputElement::parseMappedAttribute(MappedAttribute *attr)
              attr->name() == multipleAttr ||
              attr->name() == precisionAttr)
         setNeedsStyleRecalc();
+#if ENABLE(DATALIST)
+    else if (attr->name() == listAttr)
+        m_hasNonEmptyList = !attr->isEmpty();
+        // FIXME: we need to tell this change to a renderer if the attribute affects the appearance.
+#endif
     else
         HTMLFormControlElementWithState::parseMappedAttribute(attr);
 }
@@ -1765,4 +1772,59 @@ bool HTMLInputElement::placeholderShouldBeVisible() const
     return InputElement::placeholderShouldBeVisible(this, this);
 }
 
+#if ENABLE(DATALIST)
+HTMLDataListElement* HTMLInputElement::list()
+{
+    if (!m_hasNonEmptyList)
+        return 0;
+
+    switch (inputType()) {
+    case TEXT:
+    case SEARCH:
+    case URL:
+    case TELEPHONE:
+    case EMAIL:
+    case NUMBER:
+    case RANGE: {
+        Element* element = document()->getElementById(getAttribute(listAttr));
+        if (element && element->hasTagName(datalistTag))
+            return static_cast<HTMLDataListElement*>(element);
+        break;
+    }
+    case HIDDEN:
+    case PASSWORD:
+    case CHECKBOX:
+    case RADIO:
+    case FILE:
+    case SUBMIT:
+    case IMAGE:
+    case RESET:
+    case BUTTON:
+    case ISINDEX:
+        break;
+    }
+    return 0;
+}
+
+HTMLOptionElement* HTMLInputElement::selectedOption()
+{
+    String currentValue = value();
+    // The empty value never matches to a datalist option because it
+    // doesn't represent a suggestion according to the standard.
+    if (currentValue.isEmpty())
+        return 0;
+
+    HTMLDataListElement* sourceElement = list();
+    if (!sourceElement)
+        return 0;
+    RefPtr<HTMLCollection> options = sourceElement->options();
+    for (unsigned i = 0; options && i < options->length(); ++i) {
+        HTMLOptionElement* option = static_cast<HTMLOptionElement*>(options->item(i));
+        if (!option->disabled() && currentValue == option->value())
+            return option;
+    }
+    return 0;
+}
+#endif  // ENABLE(DATALIST)
+
 } // namespace
index ccb37e0..6154cfc 100644 (file)
@@ -31,7 +31,9 @@
 namespace WebCore {
 
 class FileList;
+class HTMLDataListElement;
 class HTMLImageLoader;
+class HTMLOptionElement;
 class KURL;
 class VisibleSelection;
 
@@ -194,6 +196,11 @@ public:
     KURL src() const;
     void setSrc(const String&);
 
+#if ENABLE(DATALIST)
+    HTMLDataListElement* list();
+    HTMLOptionElement* selectedOption();
+#endif
+
     int maxLength() const;
     void setMaxLength(int);
 
@@ -259,6 +266,9 @@ private:
     unsigned m_autocomplete : 2; // AutoCompleteSetting
     bool m_autofilled : 1;
     bool m_inited : 1;
+#if ENABLE(DATALIST)
+    bool m_hasNonEmptyList : 1;
+#endif
 };
 
 } //namespace
index ee9196a..7f5c001 100644 (file)
@@ -39,6 +39,12 @@ module html {
                  attribute boolean         checked;
                  attribute boolean         disabled;
                  attribute boolean         autofocus;
+#if defined(ENABLE_DATALIST) && ENABLE_DATALIST
+                 // The type of the list is HTMLElement according to the standard.
+                 // We intentionally use HTMLDataListElement for it because our implementation
+                 // always returns an HTMLDataListElement instance.
+        readonly attribute HTMLDataListElement list;
+#endif
                  attribute long            maxLength;
                  attribute boolean         multiple;
                  attribute [ConvertNullToNullString] DOMString name;
@@ -56,6 +62,9 @@ module html {
                  attribute [ConvertNullToNullString, JSCCustomGetter] DOMString type; // readonly dropped as part of DOM level 2
                  attribute [ConvertNullToNullString] DOMString useMap;
                  attribute [ConvertNullToNullString] DOMString value;
+#if defined(ENABLE_DATALIST) && ENABLE_DATALIST
+        readonly attribute HTMLOptionElement selectedOption;
+#endif
         readonly attribute boolean         willValidate;
         boolean            checkValidity();
         void               setCustomValidity(in [ConvertUndefinedOrNullToNullString] DOMString error);