[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-10851-g50815da

commit-queue at webkit.org commit-queue at webkit.org
Wed Dec 22 18:16:51 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit a259a13f74fd8e66f1f243b22aed5c3b5ae96e5d
Author: commit-queue at webkit.org <commit-queue at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Dec 9 13:07:15 2010 +0000

    2010-12-09  Dai Mikurube  <dmikurube at google.com>
    
            Reviewed by Kent Tamura.
    
            Implement "required" attribute for select tags
            https://bugs.webkit.org/show_bug.cgi?id=50380
    
            Added tests for require attributes, valueMissing and vadility check for select elements.
    
            * fast/forms/ValidityState-valueMissing-001-expected.txt:
            * fast/forms/ValidityState-valueMissing-001.html:
            * fast/forms/ValidityState-valueMissing-002-expected.txt:
            * fast/forms/ValidityState-valueMissing-002.html:
            * fast/forms/ValidityState-valueMissing-003-expected.txt:
            * fast/forms/ValidityState-valueMissing-003.html:
            * fast/forms/checkValidity-002-expected.txt:
            * fast/forms/checkValidity-002.html:
            * fast/forms/required-attribute-001-expected.txt:
            * fast/forms/required-attribute-001.html:
            * fast/forms/required-attribute-002-expected.txt:
            * fast/forms/required-attribute-002.html:
            * fast/forms/resources/select-live-pseudo-selectors.js: Added.
            (makeInvalid):
            (appendOption):
            (backgroundOf):
            * fast/forms/script-tests/validationMessage.js:
            * fast/forms/select-live-pseudo-selectors-expected.txt: Added.
            * fast/forms/select-live-pseudo-selectors.html: Added.
            * fast/forms/validationMessage-expected.txt:
            * platform/mac/fast/objc/dom-html-select-live-pseudo-selectors.html: Added.
            * platform/mac/fast/objc/dom-html-select-live-pseudo-selectors-expected.txt: Added.
    2010-12-09  Dai Mikurube  <dmikurube at google.com>
    
            Reviewed by Kent Tamura.
    
            Implement "required" attribute for select tags
            https://bugs.webkit.org/show_bug.cgi?id=50380
    
            Test: fast/forms/select-live-pseudo-selectors.html
                  platform/mac/fast/objc/dom-html-select-live-pseudo-selectors.html
    
            * dom/SelectElement.cpp:
            (WebCore::SelectElement::updateValidity): Added. It's a pure virtual function which is prepared so that HTMLSelectElement::updateValidity() calls HTMLSelectElement::setNeedsValidityCheck().
            (WebCore::SelectElement::parseMultipleAttribute): Added calling updateValidity().
            * html/HTMLSelectElement.cpp:
            (WebCore::HTMLSelectElement::deselectItems): Added calling setNeedsValidityCheck() to enable validity check after changing. No tests for this change since this function is not exposed to JavaScript or any web interface.
            (WebCore::HTMLSelectElement::setSelectedIndex): Added calling setNeedsValidityCheck().
            (WebCore::HTMLSelectElement::setSelectedIndexByUser): Added calling setNeedsValidityCheck().
            (WebCore::HTMLSelectElement::valueMissing): Added valueMissing() to check if selecting an invalid or placeholder label option when a valid required attribute is specified.
            (WebCore::HTMLSelectElement::listBoxSelectItem): Added calling setNeedsValidityCheck(). No tests for this change since it is not called yet. Look at the bug 36177 and the changeset 56180.
            (WebCore::HTMLSelectElement::add): Added calling setNeedsValidityCheck().
            (WebCore::HTMLSelectElement::remove): Added calling setNeedsValidityCheck().
            (WebCore::HTMLSelectElement::restoreFormControlState): Added calling setNeedsValidityCheck().
            (WebCore::HTMLSelectElement::parseMappedAttribute): Added calling setNeedsValidityCheck().
            (WebCore::HTMLSelectElement::selectAll): Added calling setNeedsValidityCheck().
            (WebCore::HTMLSelectElement::reset): Added calling setNeedsValidityCheck().
            (WebCore::HTMLSelectElement::updateListBoxSelection): Added calling setNeedsValidityCheck(). Skipped adding tests for this change as too complicated..
            (WebCore::HTMLSelectElement::setLength): Added calling setNeedsValidityCheck().
            (WebCore::HTMLSelectElement::isRequiredFormControl): Check if required or not.
            (WebCore::HTMLSelectElement::hasPlaceholderLabelOption): Added.
            (WebCore::HTMLSelectElement::updateValidity): Added. It calls setNeedsValidityCheck().
            * html/HTMLSelectElement.h:
            (WebCore::HTMLSelectElement::isOptionalFormControl): Check if not required.
            * html/HTMLSelectElement.idl: Added a required attribute to select elements..
            * html/ValidityState.cpp:
            (WebCore::ValidityState::valueMissing): Added valueMissing check for select elements into the global checker, ValidityState::valueMissing().
            * wml/WMLSelectElement.h:
            (WebCore::WMLSelectElement::updateValidity): Added. It does nothing.
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@73606 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 6bb06da..18287ef 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,35 @@
+2010-12-09  Dai Mikurube  <dmikurube at google.com>
+
+        Reviewed by Kent Tamura.
+
+        Implement "required" attribute for select tags
+        https://bugs.webkit.org/show_bug.cgi?id=50380
+
+        Added tests for require attributes, valueMissing and vadility check for select elements.
+
+        * fast/forms/ValidityState-valueMissing-001-expected.txt:
+        * fast/forms/ValidityState-valueMissing-001.html:
+        * fast/forms/ValidityState-valueMissing-002-expected.txt:
+        * fast/forms/ValidityState-valueMissing-002.html:
+        * fast/forms/ValidityState-valueMissing-003-expected.txt:
+        * fast/forms/ValidityState-valueMissing-003.html:
+        * fast/forms/checkValidity-002-expected.txt:
+        * fast/forms/checkValidity-002.html:
+        * fast/forms/required-attribute-001-expected.txt:
+        * fast/forms/required-attribute-001.html:
+        * fast/forms/required-attribute-002-expected.txt:
+        * fast/forms/required-attribute-002.html:
+        * fast/forms/resources/select-live-pseudo-selectors.js: Added.
+        (makeInvalid):
+        (appendOption):
+        (backgroundOf):
+        * fast/forms/script-tests/validationMessage.js:
+        * fast/forms/select-live-pseudo-selectors-expected.txt: Added.
+        * fast/forms/select-live-pseudo-selectors.html: Added.
+        * fast/forms/validationMessage-expected.txt:
+        * platform/mac/fast/objc/dom-html-select-live-pseudo-selectors.html: Added.
+        * platform/mac/fast/objc/dom-html-select-live-pseudo-selectors-expected.txt: Added.
+
 2010-12-07  Jeremy Orlow  <jorlow at chromium.org>
 
         Reviewed by Steve Block.
diff --git a/LayoutTests/fast/forms/ValidityState-valueMissing-001-expected.txt b/LayoutTests/fast/forms/ValidityState-valueMissing-001-expected.txt
index b069a74..11f45af 100644
--- a/LayoutTests/fast/forms/ValidityState-valueMissing-001-expected.txt
+++ b/LayoutTests/fast/forms/ValidityState-valueMissing-001-expected.txt
@@ -1,4 +1,24 @@
-There are two form control elements below, both required and blank: validity.valueMissing should be true in both cases.
+This test checks validity.valueMissing with blank values, blank options selected, or nothing selected.
 
- 
-SUCCESS
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS valueMissingFor("input") is true
+PASS valueMissingFor("textarea") is true
+PASS valueMissingFor("select-no-option") is true
+PASS valueMissingFor("select-placeholder-selected") is true
+PASS valueMissingFor("select-without-placeholder") is false
+PASS valueMissingFor("select-placeholder-selected-size2") is false
+PASS valueMissingFor("select-without-placeholder-size2") is false
+PASS valueMissingFor("select-none-selected-multiple") is true
+PASS valueMissingFor("select-fake-placeholder-selected-multiple") is false
+PASS valueMissingFor("select-without-fake-placeholder-multiple") is false
+PASS valueMissingFor("select-none-selected-size2-multiple") is true
+PASS valueMissingFor("select-fake-placeholder-selected-size2-multiple") is false
+PASS valueMissingFor("select-without-fake-placeholder-size2-multiple") is false
+PASS valueMissingFor("select-optgroup") is false
+PASS valueMissingFor("select-disabled-option") is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+              
diff --git a/LayoutTests/fast/forms/ValidityState-valueMissing-001.html b/LayoutTests/fast/forms/ValidityState-valueMissing-001.html
index dc88879..608c89e 100644
--- a/LayoutTests/fast/forms/ValidityState-valueMissing-001.html
+++ b/LayoutTests/fast/forms/ValidityState-valueMissing-001.html
@@ -1,27 +1,94 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
 <html>
 <head>
 <title>required and basic valueMissing</title>
+<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>
+<input id="input" name="victim" required/>
+<textarea id="textarea" name="victim" required></textarea>
+<select id="select-no-option" name="victim" required>
+</select>
+<select id="select-placeholder-selected" name="victim" required>
+  <option value="" selected />
+  <option value="X">X</option>
+</select>
+<select id="select-without-placeholder" name="victim" required>
+  <option value="X">X</option>
+  <option value="" selected />
+</select>
+<select id="select-placeholder-selected-size2" name="victim" size="2" required>
+  <option value="" selected />
+  <option value="X">X</option>
+</select>
+<select id="select-without-placeholder-size2" name="victim" size="2" required>
+  <option value="X">X</option>
+  <option value="" selected />
+</select>
+<select id="select-none-selected-multiple" name="victim" multiple required>
+  <option value="" />
+  <option value="X">X</option>
+</select>
+<select id="select-fake-placeholder-selected-multiple" name="victim" multiple required>
+  <option value="" selected />
+  <option value="X">X</option>
+</select>
+<select id="select-without-fake-placeholder-multiple" name="victim" multiple required>
+  <option value="X">X</option>
+  <option value="" selected />
+</select>
+<select id="select-none-selected-size2-multiple" name="victim" multiple size="2" required>
+  <option value="" />
+  <option value="X">X</option>
+</select>
+<select id="select-fake-placeholder-selected-size2-multiple" name="victim" multiple size="2" required>
+  <option value="" selected />
+  <option value="X">X</option>
+</select>
+<select id="select-without-fake-placeholder-size2-multiple" name="victim" multiple size="2" required>
+  <option value="X">X</option>
+  <option value="" selected />
+</select>
+<select id="select-optgroup" name="victim" required>
+  <optgroup label="1">
+    <option value="" selected />
+  </optgroup>
+  <option value="X">X</option>
+</select>
+<select id="select-disabled-option" name="victim" required>
+  <option value="" disabled selected />
+  <option value="X">X</option>
+</select>
 <script language="JavaScript" type="text/javascript">
-    function log(message) {
-        document.getElementById("console").innerHTML += "<li>"+message+"</li>";
+    function valueMissingFor(id) {
+        return document.getElementById(id).validity.valueMissing;
     }
 
-    function test() {
-        if (window.layoutTestController)
-            layoutTestController.dumpAsText();
+    description("This test checks validity.valueMissing with blank values, blank options selected, or nothing selected.");
 
-        v = document.getElementsByName("victim");
+    v = document.getElementsByName("victim");
 
-        log((v[0].validity.valueMissing && v[1].validity.valueMissing) ? "SUCCESS" : "FAILURE");
-    }
+    shouldBeTrue('valueMissingFor("input")');
+    shouldBeTrue('valueMissingFor("textarea")');
+    shouldBeTrue('valueMissingFor("select-no-option")');
+    shouldBeTrue('valueMissingFor("select-placeholder-selected")');
+    shouldBeFalse('valueMissingFor("select-without-placeholder")');
+    shouldBeFalse('valueMissingFor("select-placeholder-selected-size2")');
+    shouldBeFalse('valueMissingFor("select-without-placeholder-size2")');
+    shouldBeTrue('valueMissingFor("select-none-selected-multiple")');
+    shouldBeFalse('valueMissingFor("select-fake-placeholder-selected-multiple")');
+    shouldBeFalse('valueMissingFor("select-without-fake-placeholder-multiple")');
+    shouldBeTrue('valueMissingFor("select-none-selected-size2-multiple")');
+    shouldBeFalse('valueMissingFor("select-fake-placeholder-selected-size2-multiple")');
+    shouldBeFalse('valueMissingFor("select-without-fake-placeholder-size2-multiple")');
+    shouldBeFalse('valueMissingFor("select-optgroup")');
+    shouldBeFalse('valueMissingFor("select-disabled-option")');
+
+    var successfullyParsed = true;
 </script>
-</head>
-<body onload="test()">
-<p>There are two form control elements below, both required and blank:
-validity.valueMissing should be true in both cases.</p>
-<input name="victim" required/>
-<textarea name="victim" required></textarea>
-<hr>
-<ol id="console"></ol>
+<script src="../../fast/js/resources/js-test-post.js"></script>
 </body>
 </html>
diff --git a/LayoutTests/fast/forms/ValidityState-valueMissing-002-expected.txt b/LayoutTests/fast/forms/ValidityState-valueMissing-002-expected.txt
index 36069b8..bcb2a84 100644
--- a/LayoutTests/fast/forms/ValidityState-valueMissing-002-expected.txt
+++ b/LayoutTests/fast/forms/ValidityState-valueMissing-002-expected.txt
@@ -1,4 +1,19 @@
-There are two form control elements below, both required and with some value: validity.valueMissing should be false in both cases.
+This test checks validity.valueMissing with some values or options with some values selected.
 
- 
-SUCCESS
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS valueMissingFor("input") is false
+PASS valueMissingFor("textarea") is false
+PASS valueMissingFor("select-with-placeholder") is false
+PASS valueMissingFor("select-without-placeholder") is false
+PASS valueMissingFor("select-with-fake-placeholder-size2") is false
+PASS valueMissingFor("select-without-fake-placeholder-size2") is false
+PASS valueMissingFor("select-with-fake-placeholder-multiple") is false
+PASS valueMissingFor("select-without-fake-placeholder-multiple") is false
+PASS valueMissingFor("select-with-fake-placeholder-size2-multiple") is false
+PASS valueMissingFor("select-without-fake-placeholder-size2-multiple") is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+         
diff --git a/LayoutTests/fast/forms/ValidityState-valueMissing-002.html b/LayoutTests/fast/forms/ValidityState-valueMissing-002.html
index 6f06f9f..705f022 100644
--- a/LayoutTests/fast/forms/ValidityState-valueMissing-002.html
+++ b/LayoutTests/fast/forms/ValidityState-valueMissing-002.html
@@ -1,27 +1,69 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
 <html>
 <head>
 <title>required and basic valueMissing 2</title>
+<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>
+<input id="input" name="victim" value="something" required/>
+<textarea id="textarea" name="victim" required>something</textarea>
+<select id="select-with-placeholder" name="victim" required>
+  <option value="" />
+  <option value="X" selected>X</option>
+</select>
+<select id="select-without-placeholder" name="victim" required>
+  <option value="X" selected>X</option>
+  <option value="" />
+</select>
+<select id="select-with-fake-placeholder-size2" name="victim" size="2" required>
+  <option value="" />
+  <option value="X" selected>X</option>
+</select>
+<select id="select-without-fake-placeholder-size2" name="victim" size="2" required>
+  <option value="X" selected>X</option>
+  <option value="" />
+</select>
+<select id="select-with-fake-placeholder-multiple" name="victim" multiple required>
+  <option value="" />
+  <option value="X" selected>X</option>
+</select>
+<select id="select-without-fake-placeholder-multiple" name="victim" multiple required>
+  <option value="X" selected>X</option>
+  <option value="" />
+</select>
+<select id="select-with-fake-placeholder-size2-multiple" name="victim" multiple size="2" required>
+  <option value="" />
+  <option value="X" selected>X</option>
+</select>
+<select id="select-without-fake-placeholder-size2-multiple" name="victim" multiple size="2" required>
+  <option value="X" selected>X</option>
+  <option value="" />
+</select>
 <script language="JavaScript" type="text/javascript">
-    function log(message) {
-        document.getElementById("console").innerHTML += "<li>"+message+"</li>";
+    function valueMissingFor(id) {
+        return document.getElementById(id).validity.valueMissing;
     }
 
-    function test() {
-        if (window.layoutTestController)
-            layoutTestController.dumpAsText();
+    description("This test checks validity.valueMissing with some values or options with some values selected.");
 
-        v = document.getElementsByName("victim");
+    v = document.getElementsByName("victim");
 
-        log((!v[0].validity.valueMissing && !v[1].validity.valueMissing) ? "SUCCESS" : "FAILURE");
-    }
+    shouldBeFalse('valueMissingFor("input")');
+    shouldBeFalse('valueMissingFor("textarea")');
+    shouldBeFalse('valueMissingFor("select-with-placeholder")');
+    shouldBeFalse('valueMissingFor("select-without-placeholder")');
+    shouldBeFalse('valueMissingFor("select-with-fake-placeholder-size2")');
+    shouldBeFalse('valueMissingFor("select-without-fake-placeholder-size2")');
+    shouldBeFalse('valueMissingFor("select-with-fake-placeholder-multiple")');
+    shouldBeFalse('valueMissingFor("select-without-fake-placeholder-multiple")');
+    shouldBeFalse('valueMissingFor("select-with-fake-placeholder-size2-multiple")');
+    shouldBeFalse('valueMissingFor("select-without-fake-placeholder-size2-multiple")');
+
+    var successfullyParsed = true;
 </script>
-</head>
-<body onload="test()">
-<p>There are two form control elements below, both required and with some value:
-validity.valueMissing should be false in both cases.</p>
-<input name="victim" value="something" required/>
-<textarea name="victim" required>something</textarea>
-<hr>
-<ol id="console"></ol>
+<script src="../../fast/js/resources/js-test-post.js"></script>
 </body>
 </html>
diff --git a/LayoutTests/fast/forms/ValidityState-valueMissing-003-expected.txt b/LayoutTests/fast/forms/ValidityState-valueMissing-003-expected.txt
index dfe3398..63bdcc1 100644
--- a/LayoutTests/fast/forms/ValidityState-valueMissing-003-expected.txt
+++ b/LayoutTests/fast/forms/ValidityState-valueMissing-003-expected.txt
@@ -1,4 +1,22 @@
-There are two disabled form control elements below, both required and with some value: validity.valueMissing should be false in both cases.
+This test checks validity.valueMissing of disabled form controls with blank values, blank options selected, or nothing selected.
 
- 
-SUCCESS
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS valueMissingFor("input") is false
+PASS valueMissingFor("textarea") is false
+PASS valueMissingFor("select-no-option") is false
+PASS valueMissingFor("select-placeholder-selected") is false
+PASS valueMissingFor("select-without-placeholder") is false
+PASS valueMissingFor("select-placeholder-selected-size2") is false
+PASS valueMissingFor("select-without-placeholder-size2") is false
+PASS valueMissingFor("select-none-selected-multiple") is false
+PASS valueMissingFor("select-fake-placeholder-selected-multiple") is false
+PASS valueMissingFor("select-without-fake-placeholder-multiple") is false
+PASS valueMissingFor("select-none-selected-size2-multiple") is false
+PASS valueMissingFor("select-fake-placeholder-selected-size2-multiple") is false
+PASS valueMissingFor("select-without-fake-placeholder-size2-multiple") is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+            
diff --git a/LayoutTests/fast/forms/ValidityState-valueMissing-003.html b/LayoutTests/fast/forms/ValidityState-valueMissing-003.html
index 9d92ffb..9eb0f63 100644
--- a/LayoutTests/fast/forms/ValidityState-valueMissing-003.html
+++ b/LayoutTests/fast/forms/ValidityState-valueMissing-003.html
@@ -1,27 +1,82 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
 <html>
 <head>
 <title>required and valueMissing on disabled elements</title>
+<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>
+<input id="input" name="victim" disabled required />
+<textarea id="textarea" name="victim" disabled required></textarea>
+<select id="select-no-option" name="victim" disabled required>
+</select>
+<select id="select-placeholder-selected" name="victim" disabled required>
+  <option value="" selected />
+  <option value="X">X</option>
+</select>
+<select id="select-without-placeholder" name="victim" disabled required>
+  <option value="X">X</option>
+  <option value="" selected />
+</select>
+<select id="select-placeholder-selected-size2" name="victim" size="2" disabled required>
+  <option value="" selected />
+  <option value="X">X</option>
+</select>
+<select id="select-without-placeholder-size2" name="victim" size="2" disabled required>
+  <option value="X">X</option>
+  <option value="" selected />
+</select>
+<select id="select-none-selected-multiple" name="victim" multiple disabled required>
+  <option value="" />
+  <option value="X">X</option>
+</select>
+<select id="select-fake-placeholder-selected-multiple" name="victim" multiple disabled required>
+  <option value="" selected />
+  <option value="X">X</option>
+</select>
+<select id="select-without-fake-placeholder-multiple" name="victim" multiple disabled required>
+  <option value="X">X</option>
+  <option value="" selected />
+</select>
+<select id="select-none-selected-size2-multiple" name="victim" multiple size="2" disabled required>
+  <option value="" />
+  <option value="X">X</option>
+</select>
+<select id="select-fake-placeholder-selected-size2-multiple" name="victim" multiple size="2" disabled required>
+  <option value="" selected />
+  <option value="X">X</option>
+</select>
+<select id="select-without-fake-placeholder-size2-multiple" name="victim" multiple size="2" disabled required>
+  <option value="X">X</option>
+  <option value="" selected />
+</select>
 <script language="JavaScript" type="text/javascript">
-    function log(message) {
-        document.getElementById("console").innerHTML += "<li>"+message+"</li>";
+    function valueMissingFor(id) {
+        return document.getElementById(id).validity.valueMissing;
     }
 
-    function test() {
-        if (window.layoutTestController)
-            layoutTestController.dumpAsText();
+    description("This test checks validity.valueMissing of disabled form controls with blank values, blank options selected, or nothing selected.");
 
-        v = document.getElementsByName("victim");
+    v = document.getElementsByName("victim");
 
-        log((!v[0].validity.valueMissing && !v[1].validity.valueMissing) ? "SUCCESS" : "FAILURE");
-    }
+    shouldBeFalse('valueMissingFor("input")');
+    shouldBeFalse('valueMissingFor("textarea")');
+    shouldBeFalse('valueMissingFor("select-no-option")');
+    shouldBeFalse('valueMissingFor("select-placeholder-selected")');
+    shouldBeFalse('valueMissingFor("select-without-placeholder")');
+    shouldBeFalse('valueMissingFor("select-placeholder-selected-size2")');
+    shouldBeFalse('valueMissingFor("select-without-placeholder-size2")');
+    shouldBeFalse('valueMissingFor("select-none-selected-multiple")');
+    shouldBeFalse('valueMissingFor("select-fake-placeholder-selected-multiple")');
+    shouldBeFalse('valueMissingFor("select-without-fake-placeholder-multiple")');
+    shouldBeFalse('valueMissingFor("select-none-selected-size2-multiple")');
+    shouldBeFalse('valueMissingFor("select-fake-placeholder-selected-size2-multiple")');
+    shouldBeFalse('valueMissingFor("select-without-fake-placeholder-size2-multiple")');
+
+    var successfullyParsed = true;
 </script>
-</head>
-<body onload="test()">
-<p>There are two disabled form control elements below, both required and with some value:
-validity.valueMissing should be false in both cases.</p>
-<input name="victim" disabled required />
-<textarea name="victim" disabled required></textarea>
-<hr>
-<ol id="console"></ol>
+<script src="../../fast/js/resources/js-test-post.js"></script>
 </body>
 </html>
diff --git a/LayoutTests/fast/forms/checkValidity-002-expected.txt b/LayoutTests/fast/forms/checkValidity-002-expected.txt
index 1857944..8388828 100644
--- a/LayoutTests/fast/forms/checkValidity-002-expected.txt
+++ b/LayoutTests/fast/forms/checkValidity-002-expected.txt
@@ -1,12 +1,14 @@
-This test checks if checkValidity() returns correctly a false (meaning error) result on invalid elements.
+This test checks if checkValidity() returns correctly a false (meaning error) result on invalid elements, and returns a true result on a blank but valid elements. Blank but non-placeholder label options are valid.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-  
-PASS v[i].checkValidity() is false
-PASS v[i].checkValidity() is false
-PASS v[i].checkValidity() is false
+    
+PASS checkValidityFor("input-empty") is false
+PASS checkValidityFor("input-pattern-mismatch") is false
+PASS checkValidityFor("textarea") is false
+PASS checkValidityFor("select-placeholder") is false
+PASS checkValidityFor("select-non-placeholder") is true
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/LayoutTests/fast/forms/checkValidity-002.html b/LayoutTests/fast/forms/checkValidity-002.html
index 2872fad..662f6eb 100644
--- a/LayoutTests/fast/forms/checkValidity-002.html
+++ b/LayoutTests/fast/forms/checkValidity-002.html
@@ -7,19 +7,33 @@
 <body>
 <p id="description"></p>
 <form method="get">
-<input name="victim" type="text" required/>
-<input name="victim" type="text" pattern="Lorem ipsum" value="Loremipsum"/>
-<textarea name="victim" required></textarea>
+<input id="input-empty" name="victim" type="text" required/>
+<input id="input-pattern-mismatch" name="victim" type="text" pattern="Lorem ipsum" value="Loremipsum"/>
+<textarea id="textarea" name="victim" required></textarea>
+<select id="select-placeholder" name="victim" required>
+  <option value="" selected />
+  <option value="X">X</option>
+</select>
+<select id="select-non-placeholder" name="victim" required>
+  <option value="X">X</option>
+  <option value="" selected />
+</select>
 </form>
 <div id="console"></div>
 <script>
-description("This test checks if checkValidity() returns correctly a false (meaning error) result on invalid elements.");
+    function checkValidityFor(id) {
+        return document.getElementById(id).checkValidity();
+    }
 
-v = document.getElementsByName("victim");
-for (i = 0; i < v.length; i++)
-    shouldBe("v[i].checkValidity()", "false");
+    description("This test checks if checkValidity() returns correctly a false (meaning error) result on invalid elements, and returns a true result on a blank but valid elements. Blank but non-placeholder label options are valid.");
 
-var successfullyParsed = true;
+    shouldBeFalse('checkValidityFor("input-empty")');
+    shouldBeFalse('checkValidityFor("input-pattern-mismatch")');
+    shouldBeFalse('checkValidityFor("textarea")');
+    shouldBeFalse('checkValidityFor("select-placeholder")');
+    shouldBeTrue('checkValidityFor("select-non-placeholder")');
+
+    var successfullyParsed = true;
 </script>
 <script src="../js/resources/js-test-post.js"></script>
 </body>
diff --git a/LayoutTests/fast/forms/required-attribute-001-expected.txt b/LayoutTests/fast/forms/required-attribute-001-expected.txt
index 9b20143..b9b54b8 100644
--- a/LayoutTests/fast/forms/required-attribute-001-expected.txt
+++ b/LayoutTests/fast/forms/required-attribute-001-expected.txt
@@ -1,4 +1,12 @@
-There are two form control elements below, both required.
+There are three form control elements below, all required.
 
- 
-SUCCESS
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS requiredFor("input") is true
+PASS requiredFor("textarea") is true
+PASS requiredFor("select") is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+  
diff --git a/LayoutTests/fast/forms/required-attribute-001.html b/LayoutTests/fast/forms/required-attribute-001.html
index 2f34c16..8aea57c 100644
--- a/LayoutTests/fast/forms/required-attribute-001.html
+++ b/LayoutTests/fast/forms/required-attribute-001.html
@@ -1,26 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
 <html>
 <head>
 <title>required attribute presence test</title>
+<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>
+<input id="input" name="victim" required />
+<textarea id="textarea" name="victim" required></textarea>
+<select id="select" name="victim" required>
+  <option value="" selected />
+  <option value="X">X</option>
+</select>
 <script language="JavaScript" type="text/javascript">
-    function log(message) {
-        document.getElementById("console").innerHTML += "<li>"+message+"</li>";
+    function requiredFor(id) {
+        return document.getElementById(id).required;
     }
 
-    function test() {
-        if (window.layoutTestController)
-            layoutTestController.dumpAsText();
+    description("There are three form control elements below, all required.");
 
-        v = document.getElementsByName("victim");
+    v = document.getElementsByName("victim");
 
-        log((v[0].required && v[1].required) ? "SUCCESS" : "FAILURE");
-    }
+    shouldBeTrue('requiredFor("input")');
+    shouldBeTrue('requiredFor("textarea")');
+    shouldBeTrue('requiredFor("select")');
+
+    var successfullyParsed = true;
 </script>
-</head>
-<body onload="test()">
-<p>There are two form control elements below, both required.</p>
-<input name="victim" required />
-<textarea name="victim" required></textarea>
-<hr>
-<ol id="console"></ol>
+<script src="../../fast/js/resources/js-test-post.js"></script>
 </body>
 </html>
diff --git a/LayoutTests/fast/forms/required-attribute-002-expected.txt b/LayoutTests/fast/forms/required-attribute-002-expected.txt
index ac5c0ff..c25561d 100644
--- a/LayoutTests/fast/forms/required-attribute-002-expected.txt
+++ b/LayoutTests/fast/forms/required-attribute-002-expected.txt
@@ -1,4 +1,19 @@
-There are two form control elements below, both optional. They're set as required via required DOM attribute.
+There are three form control elements below, all optional. They're set as required via required DOM attribute.
 
- 
-SUCCESS
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Before set:
+PASS requiredFor("input") is false
+PASS requiredFor("textarea") is false
+PASS requiredFor("select") is false
+
+After set:
+PASS requiredFor("input") is true
+PASS requiredFor("textarea") is true
+PASS requiredFor("select") is true
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+  
diff --git a/LayoutTests/fast/forms/required-attribute-002.html b/LayoutTests/fast/forms/required-attribute-002.html
index aa85e89..928e33f 100644
--- a/LayoutTests/fast/forms/required-attribute-002.html
+++ b/LayoutTests/fast/forms/required-attribute-002.html
@@ -1,32 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
 <html>
 <head>
 <title>required attribute JS set</title>
+<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>
+<input id="input" name="victim" />
+<textarea id="textarea" name="victim"></textarea>
+<select id="select" name="victim">
+  <option value="" selected />
+  <option value="X">X</option>
+</select>
 <script language="JavaScript" type="text/javascript">
-    function log(message) {
-        document.getElementById("console").innerHTML += "<li>"+message+"</li>";
+    function requiredFor(id) {
+        return document.getElementById(id).required;
     }
 
-    function test() {
-        if (window.layoutTestController)
-            layoutTestController.dumpAsText();
+    description("There are three form control elements below, all optional. They're set as required via required DOM attribute.");
 
-        v = document.getElementsByName("victim");
+    v = document.getElementsByName("victim");
 
-        if (v[0].required == false && v[1].required == false) {
-            v[0].required = true;
-            v[1].required = true;
-            log ((v[0].required && v[1].required) ? "SUCCESS" : "FAILURE");
-        }
-        else
-            log("FAILURE");
-    }
+    debug("Before set:");
+    shouldBeFalse('requiredFor("input")');
+    shouldBeFalse('requiredFor("textarea")');
+    shouldBeFalse('requiredFor("select")');
+    debug("");
+
+    v[0].required = true;
+    v[1].required = true;
+    v[2].required = true;
+
+    debug("After set:");
+    shouldBeTrue('requiredFor("input")');
+    shouldBeTrue('requiredFor("textarea")');
+    shouldBeTrue('requiredFor("select")');
+    debug("");
+
+    var successfullyParsed = true;
 </script>
-</head>
-<body onload="test()">
-<p>There are two form control elements below, both optional. They're set as required via required DOM attribute.</p>
-<input name="victim" />
-<textarea name="victim"></textarea>
-<hr>
-<ol id="console"></ol>
+<script src="../../fast/js/resources/js-test-post.js"></script>
 </body>
 </html>
diff --git a/LayoutTests/fast/forms/resources/select-live-pseudo-selectors.js b/LayoutTests/fast/forms/resources/select-live-pseudo-selectors.js
new file mode 100644
index 0000000..c22133c
--- /dev/null
+++ b/LayoutTests/fast/forms/resources/select-live-pseudo-selectors.js
@@ -0,0 +1,183 @@
+description("This test performs a check that :valid/:invalid CSS psudo selectors are lively applied.");
+
+// Setup for static elements.
+var form = document.createElement('form');
+document.body.appendChild(form);
+var nonForm = document.createElement('div');
+document.body.appendChild(nonForm);
+
+function makeInvalid() {
+    var select = document.createElement('select');
+    select.name = 'foo';
+    select.required = true;
+    select.value = '';
+    form.appendChild(select);
+    return select;
+}
+
+function appendOption(value, select) {
+    var option = document.createElement('option');
+    option.value = value;
+    option.innerText = value;
+    select.add(option);
+    return option;
+}
+
+function insertOptionBefore(value, select, before) {
+    var option = document.createElement('option');
+    option.value = value;
+    option.innerText = value;
+    select.add(option, before);
+    return option;
+}
+
+function removeOption(option, select) {
+    select.remove(option);
+    return option;
+}
+
+function backgroundOf(el) {
+    return document.defaultView.getComputedStyle(el, null).getPropertyValue('background-color');
+}
+
+var elBackground = 'backgroundOf(el)';
+var invalidColor = 'rgb(255, 0, 0)';
+var normalColor = 'rgb(255, 255, 255)';
+var disabledColor = 'rgb(0, 0, 0)';
+var readOnlyColor = 'rgb(0, 255, 0)'
+var validColor = 'rgb(0, 0, 255)';
+
+// --------------------------------
+//     willValidate change
+// --------------------------------
+var el = makeInvalid();
+var o1 = appendOption('', el);
+var o2 = appendOption('X', el);
+o1.selected = true;
+// Confirm this element is invalid.
+debug('Check the initial state:');
+shouldBe(elBackground, 'invalidColor');
+
+debug('Change name:');
+el.name = '';
+shouldBe(elBackground, 'invalidColor');
+el.name = 'bar';
+shouldBe(elBackground, 'invalidColor');
+
+debug('Change disabled:');
+el = makeInvalid();
+o1 = appendOption('', el);
+o2 = appendOption('X', el);
+o1.selected = true;
+el.disabled = true;
+shouldBe(elBackground, 'disabledColor');
+el.disabled = false;
+shouldBe(elBackground, 'invalidColor');
+
+debug('Inside/outside of a form:');
+el = makeInvalid();
+o1 = appendOption('', el);
+o2 = appendOption('X', el);
+o1.selected = true;
+nonForm.appendChild(el);
+shouldBe(elBackground, 'invalidColor');
+form.appendChild(el);
+shouldBe(elBackground, 'invalidColor');
+
+// --------------------------------
+//     value change
+// --------------------------------
+debug('Change the value with a placeholder label option:');
+el = makeInvalid();
+o1 = appendOption('', el);
+o2 = appendOption('X', el);
+o2.selected = true;
+shouldBe(elBackground, 'validColor');
+o1.selected = true;
+shouldBe(elBackground, 'invalidColor');
+
+debug('Change the value without a placeholder label option:');
+el = makeInvalid();
+o1 = appendOption('X', el);
+o2 = appendOption('', el);
+o2.selected = true;
+shouldBe(elBackground, 'validColor');
+o1.selected = true;
+shouldBe(elBackground, 'validColor');
+
+debug('Insert/remove options:');
+el = makeInvalid();
+o1 = appendOption('', el);
+o2 = appendOption('X', el);
+o1.selected = true;
+shouldBe(elBackground, 'invalidColor');
+o3 = insertOptionBefore('Y', el, el.firstChild);
+shouldBe(elBackground, 'validColor');
+removeOption(o3, el);
+shouldBe(elBackground, 'invalidColor');
+o3 = appendOption('Z', el);
+o3.selected = true;
+shouldBe(elBackground, 'validColor');
+el.length = 2;
+shouldBe(elBackground, 'invalidColor');
+
+debug('Set an attribute: multiple:');
+el = makeInvalid();
+o1 = appendOption('', el);
+o2 = appendOption('X', el);
+o1.selected = true;
+shouldBe(elBackground, 'invalidColor');
+el.multiple = true;
+shouldBe(elBackground, 'validColor');
+el.removeAttribute('multiple');
+shouldBe(elBackground, 'invalidColor');
+
+debug('Set an attribute: size:');
+el = makeInvalid();
+o1 = appendOption('', el);
+o2 = appendOption('X', el);
+o1.selected = true;
+shouldBe(elBackground, 'invalidColor');
+el.size = 2;
+shouldBe(elBackground, 'validColor');
+el.removeAttribute('size');
+shouldBe(elBackground, 'invalidColor');
+
+debug('SelectAll:');
+el = makeInvalid();
+o1 = appendOption('', el);
+o2 = appendOption('X', el);
+el.multiple = true;
+o1.selected = false;
+o2.selected = false;
+shouldBe(elBackground, 'invalidColor');
+el.focus();
+document.execCommand("SelectAll");
+shouldBe(elBackground, 'validColor');
+el.multiple = false;
+o1.selected = false;
+o2.selected = true;
+
+debug('Reset:');
+el = makeInvalid();
+o1 = appendOption('', el);
+o2 = appendOption('X', el);
+o2.selected = true;
+shouldBe(elBackground, 'validColor');
+form.reset();
+shouldBe(elBackground, 'invalidColor');
+
+// --------------------------------
+//     Constraints change
+// --------------------------------
+debug('Change required:');
+el = makeInvalid();
+o1 = appendOption('', el);
+o2 = appendOption('X', el);
+o1.selected = true;
+el.required = false;
+shouldBe(elBackground, 'validColor');
+el.required = true;
+shouldBe(elBackground, 'invalidColor');
+
+var successfullyParsed = true;
diff --git a/LayoutTests/fast/forms/script-tests/validationMessage.js b/LayoutTests/fast/forms/script-tests/validationMessage.js
index d6826de..5c56542 100644
--- a/LayoutTests/fast/forms/script-tests/validationMessage.js
+++ b/LayoutTests/fast/forms/script-tests/validationMessage.js
@@ -24,6 +24,13 @@ requiredTextArea.required = true;
 form.appendChild(requiredTextArea);
 shouldBe("requiredTextArea.validationMessage", "'value missing'");
 
+// A required select with an empty value
+var requiredSelect = document.createElement("select");
+requiredSelect.name = "requiredSelect";
+requiredSelect.required = true;
+form.appendChild(requiredSelect);
+shouldBe("requiredSelect.validationMessage", "'value missing'");
+
 // A type=email input for the "type mismatch" flag
 var emailInput = document.createElement("input");
 emailInput.name = "emailInput";
diff --git a/LayoutTests/fast/forms/select-live-pseudo-selectors-expected.txt b/LayoutTests/fast/forms/select-live-pseudo-selectors-expected.txt
new file mode 100644
index 0000000..4d7cb73
--- /dev/null
+++ b/LayoutTests/fast/forms/select-live-pseudo-selectors-expected.txt
@@ -0,0 +1,50 @@
+This test performs a check that :valid/:invalid CSS psudo selectors are lively applied.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Check the initial state:
+PASS backgroundOf(el) is invalidColor
+Change name:
+PASS backgroundOf(el) is invalidColor
+PASS backgroundOf(el) is invalidColor
+Change disabled:
+PASS backgroundOf(el) is disabledColor
+PASS backgroundOf(el) is invalidColor
+Inside/outside of a form:
+PASS backgroundOf(el) is invalidColor
+PASS backgroundOf(el) is invalidColor
+Change the value with a placeholder label option:
+PASS backgroundOf(el) is validColor
+PASS backgroundOf(el) is invalidColor
+Change the value without a placeholder label option:
+PASS backgroundOf(el) is validColor
+PASS backgroundOf(el) is validColor
+Insert/remove options:
+PASS backgroundOf(el) is invalidColor
+PASS backgroundOf(el) is validColor
+PASS backgroundOf(el) is invalidColor
+PASS backgroundOf(el) is validColor
+PASS backgroundOf(el) is invalidColor
+Set an attribute: multiple:
+PASS backgroundOf(el) is invalidColor
+PASS backgroundOf(el) is validColor
+PASS backgroundOf(el) is invalidColor
+Set an attribute: size:
+PASS backgroundOf(el) is invalidColor
+PASS backgroundOf(el) is validColor
+PASS backgroundOf(el) is invalidColor
+SelectAll:
+PASS backgroundOf(el) is invalidColor
+PASS backgroundOf(el) is validColor
+Reset:
+PASS backgroundOf(el) is validColor
+PASS backgroundOf(el) is invalidColor
+Change required:
+PASS backgroundOf(el) is validColor
+PASS backgroundOf(el) is invalidColor
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
+
diff --git a/LayoutTests/fast/forms/select-live-pseudo-selectors.html b/LayoutTests/fast/forms/select-live-pseudo-selectors.html
new file mode 100644
index 0000000..02e9f87
--- /dev/null
+++ b/LayoutTests/fast/forms/select-live-pseudo-selectors.html
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html
+<head>
+<link rel="stylesheet" href="../js/resources/js-test-style.css">
+<link rel="stylesheet" href="resources/live-pseudo-selectors.css">
+<script src="../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="resources/select-live-pseudo-selectors.js"></script>
+<script src="../js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/forms/validationMessage-expected.txt b/LayoutTests/fast/forms/validationMessage-expected.txt
index 0e12d8a..e91961d 100644
--- a/LayoutTests/fast/forms/validationMessage-expected.txt
+++ b/LayoutTests/fast/forms/validationMessage-expected.txt
@@ -6,6 +6,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 PASS patternInput.validationMessage is 'pattern mismatch'
 PASS requiredInput.validationMessage is 'value missing'
 PASS requiredTextArea.validationMessage is 'value missing'
+PASS requiredSelect.validationMessage is 'value missing'
 PASS emailInput.validationMessage is 'type mismatch'
 PASS but.validationMessage is ''
 PASS anoninput.validationMessage is ''
diff --git a/LayoutTests/platform/mac/fast/objc/dom-html-select-live-pseudo-selectors-expected.txt b/LayoutTests/platform/mac/fast/objc/dom-html-select-live-pseudo-selectors-expected.txt
new file mode 100644
index 0000000..fa89fa5
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/objc/dom-html-select-live-pseudo-selectors-expected.txt
@@ -0,0 +1,15 @@
+This test performs a check that :valid/:invalid CSS psudo selectors are lively applied by HTMLSelectElement::setSelectedIndexByUser.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Change the value of a menulist select by setSelectedIndexByUser:
+PASS backgroundOf(el) is validColor
+PASS backgroundOf(el) is invalidColor
+Change the value of a listbox select by setSelectedIndexByUser:
+PASS backgroundOf(el) is invalidColor
+PASS backgroundOf(el) is validColor
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/platform/mac/fast/objc/dom-html-select-live-pseudo-selectors.html b/LayoutTests/platform/mac/fast/objc/dom-html-select-live-pseudo-selectors.html
new file mode 100644
index 0000000..e194166
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/objc/dom-html-select-live-pseudo-selectors.html
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title></title>
+<link rel="stylesheet" href="../../../../fast/js/resources/js-test-style.css">
+<link rel="stylesheet" href="../../../../fast/forms/resources/live-pseudo-selectors.css">
+<script src="../../../../fast/js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+description("This test performs a check that :valid/:invalid CSS psudo selectors are lively applied by HTMLSelectElement::setSelectedIndexByUser.");
+
+// Setup for static elements.
+var form = document.createElement('form');
+document.body.appendChild(form);
+
+function makeInvalid(id) {
+    var select = document.createElement('select');
+    select.name = 'foo';
+    select.required = true;
+    if (id != undefined)
+        select.id = id;
+    select.value = '';
+    form.appendChild(select);
+    return select;
+}
+
+function appendOption(value, select) {
+    var option = document.createElement('option');
+    option.value = value;
+    option.innerText = value;
+    select.add(option);
+    return option;
+}
+
+function backgroundOf(el) {
+    return document.defaultView.getComputedStyle(el, null).getPropertyValue('background-color');
+}
+
+var elBackground = 'backgroundOf(el)';
+var invalidColor = 'rgb(255, 0, 0)';
+var normalColor = 'rgb(255, 255, 255)';
+var disabledColor = 'rgb(0, 0, 0)';
+var readOnlyColor = 'rgb(0, 255, 0)'
+var validColor = 'rgb(0, 0, 255)';
+
+debug('Change the value of a menulist select by setSelectedIndexByUser:');
+el = makeInvalid('menulist');
+o1 = appendOption('', el);
+o2 = appendOption('X', el);
+objCController.setSelectElementSelectedIndexAllowingMultiple(el, 1, false);
+shouldBe(elBackground, 'validColor');
+objCController.setSelectElementSelectedIndexAllowingMultiple(el, 0, false);
+shouldBe(elBackground, 'invalidColor');
+
+debug('Change the value of a listbox select by setSelectedIndexByUser:');
+el = makeInvalid('listbox');
+el.multiple = true;
+o1 = appendOption('', el);
+o2 = appendOption('X', el);
+o1.selected = false;
+o2.selected = false;
+shouldBe(elBackground, 'invalidColor');
+objCController.setSelectElementSelectedIndexAllowingMultiple(el, 0, false);
+shouldBe(elBackground, 'validColor');
+
+var successfullyParsed = true;
+</script>
+<script src="../../../../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 43e5bbc..6ded679 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,41 @@
+2010-12-09  Dai Mikurube  <dmikurube at google.com>
+
+        Reviewed by Kent Tamura.
+
+        Implement "required" attribute for select tags
+        https://bugs.webkit.org/show_bug.cgi?id=50380
+
+        Test: fast/forms/select-live-pseudo-selectors.html
+              platform/mac/fast/objc/dom-html-select-live-pseudo-selectors.html
+
+        * dom/SelectElement.cpp:
+        (WebCore::SelectElement::updateValidity): Added. It's a pure virtual function which is prepared so that HTMLSelectElement::updateValidity() calls HTMLSelectElement::setNeedsValidityCheck().
+        (WebCore::SelectElement::parseMultipleAttribute): Added calling updateValidity().
+        * html/HTMLSelectElement.cpp:
+        (WebCore::HTMLSelectElement::deselectItems): Added calling setNeedsValidityCheck() to enable validity check after changing. No tests for this change since this function is not exposed to JavaScript or any web interface.
+        (WebCore::HTMLSelectElement::setSelectedIndex): Added calling setNeedsValidityCheck().
+        (WebCore::HTMLSelectElement::setSelectedIndexByUser): Added calling setNeedsValidityCheck().
+        (WebCore::HTMLSelectElement::valueMissing): Added valueMissing() to check if selecting an invalid or placeholder label option when a valid required attribute is specified.
+        (WebCore::HTMLSelectElement::listBoxSelectItem): Added calling setNeedsValidityCheck(). No tests for this change since it is not called yet. Look at the bug 36177 and the changeset 56180.
+        (WebCore::HTMLSelectElement::add): Added calling setNeedsValidityCheck().
+        (WebCore::HTMLSelectElement::remove): Added calling setNeedsValidityCheck().
+        (WebCore::HTMLSelectElement::restoreFormControlState): Added calling setNeedsValidityCheck().
+        (WebCore::HTMLSelectElement::parseMappedAttribute): Added calling setNeedsValidityCheck().
+        (WebCore::HTMLSelectElement::selectAll): Added calling setNeedsValidityCheck().
+        (WebCore::HTMLSelectElement::reset): Added calling setNeedsValidityCheck().
+        (WebCore::HTMLSelectElement::updateListBoxSelection): Added calling setNeedsValidityCheck(). Skipped adding tests for this change as too complicated..
+        (WebCore::HTMLSelectElement::setLength): Added calling setNeedsValidityCheck().
+        (WebCore::HTMLSelectElement::isRequiredFormControl): Check if required or not.
+        (WebCore::HTMLSelectElement::hasPlaceholderLabelOption): Added.
+        (WebCore::HTMLSelectElement::updateValidity): Added. It calls setNeedsValidityCheck().
+        * html/HTMLSelectElement.h:
+        (WebCore::HTMLSelectElement::isOptionalFormControl): Check if not required.
+        * html/HTMLSelectElement.idl: Added a required attribute to select elements..
+        * html/ValidityState.cpp:
+        (WebCore::ValidityState::valueMissing): Added valueMissing check for select elements into the global checker, ValidityState::valueMissing().
+        * wml/WMLSelectElement.h:
+        (WebCore::WMLSelectElement::updateValidity): Added. It does nothing.
+
 2010-12-07  Jeremy Orlow  <jorlow at chromium.org>
 
         Reviewed by Steve Block.
diff --git a/WebCore/dom/SelectElement.cpp b/WebCore/dom/SelectElement.cpp
index 99e0c29..bfa1b93 100644
--- a/WebCore/dom/SelectElement.cpp
+++ b/WebCore/dom/SelectElement.cpp
@@ -453,6 +453,7 @@ void SelectElement::parseMultipleAttribute(SelectElementData& data, Element* ele
 {
     bool oldUsesMenuList = data.usesMenuList();
     data.setMultiple(!attribute->isNull());
+    toSelectElement(element)->updateValidity();
     if (oldUsesMenuList != data.usesMenuList() && element->attached()) {
         element->detach();
         element->attach();
diff --git a/WebCore/dom/SelectElement.h b/WebCore/dom/SelectElement.h
index 53815f2..222a1bb 100644
--- a/WebCore/dom/SelectElement.h
+++ b/WebCore/dom/SelectElement.h
@@ -63,6 +63,8 @@ public:
 
     virtual void listBoxSelectItem(int listIndex, bool allowMultiplySelections, bool shift, bool fireOnChangeNow = true) = 0;
 
+    virtual void updateValidity() = 0;
+
 protected:
     virtual ~SelectElement() { }
 
diff --git a/WebCore/html/HTMLSelectElement.cpp b/WebCore/html/HTMLSelectElement.cpp
index c680e92..968f629 100644
--- a/WebCore/html/HTMLSelectElement.cpp
+++ b/WebCore/html/HTMLSelectElement.cpp
@@ -78,11 +78,13 @@ int HTMLSelectElement::selectedIndex() const
 void HTMLSelectElement::deselectItems(HTMLOptionElement* excludeElement)
 {
     SelectElement::deselectItems(m_data, this, excludeElement);
+    setNeedsValidityCheck();
 }
 
 void HTMLSelectElement::setSelectedIndex(int optionIndex, bool deselect)
 {
     SelectElement::setSelectedIndex(m_data, this, optionIndex, deselect, false, false);
+    setNeedsValidityCheck();
 }
 
 void HTMLSelectElement::setSelectedIndexByUser(int optionIndex, bool deselect, bool fireOnChangeNow, bool allowMultipleSelection)
@@ -91,6 +93,7 @@ void HTMLSelectElement::setSelectedIndexByUser(int optionIndex, bool deselect, b
     // mousedown events. This allows that same behavior programmatically.
     if (!m_data.usesMenuList()) {
         updateSelectedState(m_data, this, optionIndex, allowMultipleSelection, false);
+        setNeedsValidityCheck();
         if (fireOnChangeNow)
             listBoxOnChange();
         return;
@@ -104,6 +107,42 @@ void HTMLSelectElement::setSelectedIndexByUser(int optionIndex, bool deselect, b
         return;
     
     SelectElement::setSelectedIndex(m_data, this, optionIndex, deselect, fireOnChangeNow, true);
+    setNeedsValidityCheck();
+}
+
+bool HTMLSelectElement::hasPlaceholderLabelOption() const
+{
+    // The select element has no placeholder label option if it has an attribute "multiple" specified or a display size of non-1.
+    // 
+    // The condition "size() > 1" is actually not compliant with the HTML5 spec as of Dec 3, 2010. "size() != 1" is correct.
+    // Using "size() > 1" here because size() may be 0 in WebKit.
+    // See the discussion at https://bugs.webkit.org/show_bug.cgi?id=43887
+    //
+    // "0 size()" happens when an attribute "size" is absent or an invalid size attribute is specified.
+    // In this case, the display size should be assumed as the default.
+    // The default display size is 1 for non-multiple select elements, and 4 for multiple select elements.
+    //
+    // Finally, if size() == 0 and non-multiple, the display size can be assumed as 1.
+    if (multiple() || size() > 1)
+        return false;
+
+    int listIndex = optionToListIndex(0);
+    ASSERT(listIndex >= 0);
+    if (listIndex < 0)
+        return false;
+    HTMLOptionElement* option = static_cast<HTMLOptionElement*>(listItems()[listIndex]);
+    return !option->disabled() && !listIndex && option->value().isEmpty();
+}
+
+bool HTMLSelectElement::valueMissing() const
+{
+    if (!isRequiredFormControl())
+        return false;
+
+    int firstSelectionIndex = selectedIndex();
+
+    // If a non-placeholer label option is selected (firstSelectionIndex > 0), it's not value-missing.
+    return firstSelectionIndex < 0 || (!firstSelectionIndex && hasPlaceholderLabelOption());
 }
 
 void HTMLSelectElement::listBoxSelectItem(int listIndex, bool allowMultiplySelections, bool shift, bool fireOnChangeNow)
@@ -112,6 +151,7 @@ void HTMLSelectElement::listBoxSelectItem(int listIndex, bool allowMultiplySelec
         setSelectedIndexByUser(listToOptionIndex(listIndex), true, fireOnChangeNow);
     else {
         updateSelectedState(m_data, this, listIndex, allowMultiplySelections, shift);
+        setNeedsValidityCheck();
         if (fireOnChangeNow)
             listBoxOnChange();
     }
@@ -144,6 +184,7 @@ void HTMLSelectElement::add(HTMLElement *element, HTMLElement *before, Exception
         return;
 
     insertBefore(element, before, ec);
+    setNeedsValidityCheck();
 }
 
 void HTMLSelectElement::remove(int index)
@@ -156,6 +197,7 @@ void HTMLSelectElement::remove(int index)
     ASSERT(item->parentNode());
     ExceptionCode ec;
     item->parentNode()->removeChild(item, ec);
+    setNeedsValidityCheck();
 }
 
 String HTMLSelectElement::value()
@@ -195,6 +237,7 @@ bool HTMLSelectElement::saveFormControlState(String& value) const
 void HTMLSelectElement::restoreFormControlState(const String& state)
 {
     SelectElement::restoreFormControlState(m_data, this, state);
+    setNeedsValidityCheck();
 }
 
 void HTMLSelectElement::parseMappedAttribute(Attribute* attr) 
@@ -215,6 +258,7 @@ void HTMLSelectElement::parseMappedAttribute(Attribute* attr)
             recalcListItemsIfNeeded();
 
         m_data.setSize(size);
+        setNeedsValidityCheck();
         if ((oldUsesMenuList != m_data.usesMenuList() || (!oldUsesMenuList && m_data.size() != oldSize)) && attached()) {
             detach();
             attach();
@@ -255,6 +299,7 @@ bool HTMLSelectElement::canSelectAll() const
 void HTMLSelectElement::selectAll()
 {
     SelectElement::selectAll(m_data, this);
+    setNeedsValidityCheck();
 }
 
 RenderObject* HTMLSelectElement::createRenderer(RenderArena* arena, RenderStyle*)
@@ -315,6 +360,7 @@ void HTMLSelectElement::setRecalcListItems()
 void HTMLSelectElement::reset()
 {
     SelectElement::reset(m_data, this);
+    setNeedsValidityCheck();
 }
 
 void HTMLSelectElement::dispatchFocusEvent()
@@ -350,6 +396,7 @@ void HTMLSelectElement::setActiveSelectionEndIndex(int index)
 void HTMLSelectElement::updateListBoxSelection(bool deselectOtherOptions)
 {
     SelectElement::updateListBoxSelection(m_data, this, deselectOtherOptions);
+    setNeedsValidityCheck();
 }
 
 void HTMLSelectElement::menuListOnChange()
@@ -458,6 +505,7 @@ void HTMLSelectElement::setLength(unsigned newLen, ExceptionCode& ec)
             }
         }
     }
+    setNeedsValidityCheck();
 }
 
 void HTMLSelectElement::scrollToSelection()
@@ -471,4 +519,9 @@ void HTMLSelectElement::insertedIntoTree(bool deep)
     HTMLFormControlElementWithState::insertedIntoTree(deep);
 }
 
+bool HTMLSelectElement::isRequiredFormControl() const
+{
+    return required();
+}
+
 } // namespace
diff --git a/WebCore/html/HTMLSelectElement.h b/WebCore/html/HTMLSelectElement.h
index a3b4460..0bfb6a0 100644
--- a/WebCore/html/HTMLSelectElement.h
+++ b/WebCore/html/HTMLSelectElement.h
@@ -43,6 +43,9 @@ public:
     virtual void setSelectedIndex(int index, bool deselect = true);
     virtual void setSelectedIndexByUser(int index, bool deselect = true, bool fireOnChangeNow = false, bool allowMultipleSelection = false);
 
+    // For ValidityState
+    bool valueMissing() const;
+
     unsigned length() const;
 
     virtual int size() const { return m_data.size(); }
@@ -82,6 +85,8 @@ public:
 
     void listBoxSelectItem(int listIndex, bool allowMultiplySelections, bool shift, bool fireOnChangeNow = true);
 
+    virtual void updateValidity() { setNeedsValidityCheck(); }
+
 protected:
     HTMLSelectElement(const QualifiedName&, Document*, HTMLFormElement*);
 
@@ -134,7 +139,10 @@ private:
 
     virtual void insertedIntoTree(bool);
 
-    virtual bool isOptionalFormControl() const { return true; }
+    virtual bool isOptionalFormControl() const { return !isRequiredFormControl(); }
+    virtual bool isRequiredFormControl() const;
+
+    bool hasPlaceholderLabelOption() const;
 
     SelectElementData m_data;
     CollectionCache m_collectionInfo;
diff --git a/WebCore/html/HTMLSelectElement.idl b/WebCore/html/HTMLSelectElement.idl
index 2e53bca..f5ac69b 100644
--- a/WebCore/html/HTMLSelectElement.idl
+++ b/WebCore/html/HTMLSelectElement.idl
@@ -49,6 +49,7 @@ module html {
         attribute [Reflect] boolean autofocus;
         attribute boolean multiple;
         attribute [ConvertNullToNullString] DOMString name;
+        attribute [Reflect] boolean required;
         attribute long size;
         
         [OldStyleObjC] void add(in HTMLElement element, in HTMLElement before) raises(DOMException);
diff --git a/WebCore/html/ValidityState.cpp b/WebCore/html/ValidityState.cpp
index 2fb1e2c..0565035 100644
--- a/WebCore/html/ValidityState.cpp
+++ b/WebCore/html/ValidityState.cpp
@@ -26,6 +26,7 @@
 
 #include "HTMLInputElement.h"
 #include "HTMLNames.h"
+#include "HTMLSelectElement.h"
 #include "HTMLTextAreaElement.h"
 #include "HTMLTreeBuilder.h"
 #include "LocalizedStrings.h"
@@ -105,6 +106,9 @@ void ValidityState::setCustomErrorMessage(const String& message)
 bool ValidityState::valueMissing() const
 {
     HTMLElement* element = toHTMLElement(m_control);
+    if (!element->willValidate())
+        return false;
+
     if (element->hasTagName(inputTag)) {
         HTMLInputElement* input = static_cast<HTMLInputElement*>(element);
         return input->valueMissing(input->value());
@@ -113,6 +117,10 @@ bool ValidityState::valueMissing() const
         HTMLTextAreaElement* textArea = static_cast<HTMLTextAreaElement*>(element);
         return textArea->valueMissing(textArea->value());
     }
+    if (element->hasTagName(selectTag)) {
+        HTMLSelectElement* select = static_cast<HTMLSelectElement*>(element);
+        return select->valueMissing();
+    }
     return false;
 }
 
diff --git a/WebCore/wml/WMLSelectElement.h b/WebCore/wml/WMLSelectElement.h
index 16bb382..3d8c726 100644
--- a/WebCore/wml/WMLSelectElement.h
+++ b/WebCore/wml/WMLSelectElement.h
@@ -103,6 +103,8 @@ private:
     String optionIndicesToValueString() const;
     String optionIndicesToString() const;
 
+    virtual void updateValidity() {}
+
     String name() const;
     String value() const;
     String iname() const;

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list