[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
commit-queue at webkit.org
commit-queue at webkit.org
Wed Dec 22 15:51:05 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit 2cc417aa04c01a52def0e6894007e9c3c40fca69
Author: commit-queue at webkit.org <commit-queue at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Mon Nov 15 04:57:04 2010 +0000
2010-11-14 Kenichi Ishibashi <bashi at google.com>
Reviewed by Kent Tamura.
[HTML5] "form" attribute support for form control elements
https://bugs.webkit.org/show_bug.cgi?id=47813
Adds a test file for "form" attribute of form-associated elements.
The test might need to be revised because <label> and <object> don't
support "form" attribute for now, in spite of the HTML5 spec says that
they should support.
* fast/forms/form-attribute-elements-expected.txt: Added.
* fast/forms/form-attribute-elements-order-expected.txt: Added.
* fast/forms/form-attribute-elements-order.html: Added.
* fast/forms/form-attribute-elements-order2-expected.txt: Added.
* fast/forms/form-attribute-elements-order2.html: Added.
* fast/forms/form-attribute-elements.html: Added.
* fast/forms/form-attribute-expected.txt: Added.
* fast/forms/form-attribute.html: Added.
* fast/forms/script-tests/form-attribute-elements-order.js: Added.
* fast/forms/script-tests/form-attribute-elements-order2.js: Added.
* fast/forms/script-tests/form-attribute-elements.js: Added.
* fast/forms/script-tests/form-attribute.js: Added.
2010-11-14 Kenichi Ishibashi <bashi at google.com>
Reviewed by Kent Tamura.
[HTML5] "form" attribute support for form control elements
https://bugs.webkit.org/show_bug.cgi?id=47813
Adds a list of form-associated elements with form attribute into
the Document class to support form attribute.
Adds a function to determine the right place to locate
form-associated elements with form attribute into
m_associatedElements of HTMLFormElement class.
Tests: fast/forms/form-attribute-elements-order.html
fast/forms/form-attribute-elements-order2.html
fast/forms/form-attribute-elements.html
fast/forms/form-attribute.html
* dom/Document.cpp:
(WebCore::Document::registerFormElementWithFormAttribute): Added.
(WebCore::Document::unregisterFormElementWithFormAttribute): Added.
(WebCore::Document::resetFormElementsOwner): Added.
* dom/Document.h: Added the list for elements with form attribute.
* html/HTMLAttributeNames.in: Added form attribute.
* html/HTMLFormControlElement.cpp:
(WebCore::HTMLFormControlElement::insertedIntoTree): Modified to handle
form attribute.
(WebCore::HTMLFormControlElement::removedFromTree): Ditto.
(WebCore::HTMLFormControlElement::resetFormOwner): Added.
(WebCore::HTMLFormControlElement::attributeChanged): Added.
* html/HTMLFormControlElement.h:
* html/HTMLFormElement.cpp:
(WebCore::HTMLFormElement::HTMLFormElement): Modified to initialize
newly-added variables.
(WebCore::HTMLFormElement::insertedIntoDocument): Modified to reset
form owner of form-associated elements.
(WebCore::HTMLFormElement::removedFromDocument): Ditto.
(WebCore::HTMLFormElement::formElementIndexWithFormAttribute): Added.
(WebCore::HTMLFormElement::formElementIndex): Modified to treat
form-associated elements with form attribute separately.
(WebCore::HTMLFormElement::removeFormElement): Modified to handle
form-associated elements with form attribute.
* html/HTMLFormElement.h: Added three variables to handle form attribute.
* html/HTMLOutputElement.cpp: Removed "FIXME" comment.
(WebCore::HTMLOutputElement::parseMappedAttribute):
* html/HTMLOutputElement.h: Removed setForm().
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@71994 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index a907c43..adb7a63 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,28 @@
+2010-11-14 Kenichi Ishibashi <bashi at google.com>
+
+ Reviewed by Kent Tamura.
+
+ [HTML5] "form" attribute support for form control elements
+ https://bugs.webkit.org/show_bug.cgi?id=47813
+
+ Adds a test file for "form" attribute of form-associated elements.
+ The test might need to be revised because <label> and <object> don't
+ support "form" attribute for now, in spite of the HTML5 spec says that
+ they should support.
+
+ * fast/forms/form-attribute-elements-expected.txt: Added.
+ * fast/forms/form-attribute-elements-order-expected.txt: Added.
+ * fast/forms/form-attribute-elements-order.html: Added.
+ * fast/forms/form-attribute-elements-order2-expected.txt: Added.
+ * fast/forms/form-attribute-elements-order2.html: Added.
+ * fast/forms/form-attribute-elements.html: Added.
+ * fast/forms/form-attribute-expected.txt: Added.
+ * fast/forms/form-attribute.html: Added.
+ * fast/forms/script-tests/form-attribute-elements-order.js: Added.
+ * fast/forms/script-tests/form-attribute-elements-order2.js: Added.
+ * fast/forms/script-tests/form-attribute-elements.js: Added.
+ * fast/forms/script-tests/form-attribute.js: Added.
+
2010-11-14 Mihai Parparita <mihaip at chromium.org>
Unreviewed Chromium expectations update.
diff --git a/LayoutTests/fast/forms/form-attribute-elements-expected.txt b/LayoutTests/fast/forms/form-attribute-elements-expected.txt
new file mode 100644
index 0000000..dc61c4c
--- /dev/null
+++ b/LayoutTests/fast/forms/form-attribute-elements-expected.txt
@@ -0,0 +1,20 @@
+This test checks a form element can handle elements of which form attribute points the form element even if elements are outside of the form.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+- Ensures that elements attribute of the form contains elements which are outside of the form.
+PASS owner.elements.length is 3
+PASS owner.elements[0] is outerBefore
+PASS owner.elements[1] is inner
+PASS owner.elements[2] is outerAfter
+
+- Ensures that form submission contains name and value pairs for such elements.
+PASS pairs.length is 3
+PASS pairs[0] is "key1=value1"
+PASS pairs[1] is "key2=value2"
+PASS pairs[2] is "submitted=true"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/forms/form-attribute-elements-order-expected.txt b/LayoutTests/fast/forms/form-attribute-elements-order-expected.txt
new file mode 100644
index 0000000..0f6048c
--- /dev/null
+++ b/LayoutTests/fast/forms/form-attribute-elements-order-expected.txt
@@ -0,0 +1,95 @@
+This test examines the order of the elements attribute of a form element.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+- Test for the case where some elements are outside of the form.
+PASS owner.elements.length is 6
+PASS owner.elements[0] is before1
+PASS owner.elements[1] is before2
+PASS owner.elements[2] is inner1
+PASS owner.elements[3] is inner2
+PASS owner.elements[4] is after1
+PASS owner.elements[5] is after2
+
+- Test for changing the value of the form attribute of a element which is located before the form owner.
+PASS owner.elements.length is 5
+PASS owner.elements[0] is before1
+PASS owner.elements[1] is inner1
+PASS owner.elements[2] is inner2
+PASS owner.elements[3] is after1
+PASS owner.elements[4] is after2
+PASS owner.elements.length is 6
+PASS owner.elements[0] is before1
+PASS owner.elements[1] is before2
+PASS owner.elements[2] is inner1
+PASS owner.elements[3] is inner2
+PASS owner.elements[4] is after1
+PASS owner.elements[5] is after2
+
+- Test for changing the value of the form attribute of a element which is located inside of the form owner.
+PASS owner.elements.length is 5
+PASS owner.elements[0] is before1
+PASS owner.elements[1] is before2
+PASS owner.elements[2] is inner1
+PASS owner.elements[3] is after1
+PASS owner.elements[4] is after2
+PASS owner.elements.length is 6
+PASS owner.elements[0] is before1
+PASS owner.elements[1] is before2
+PASS owner.elements[2] is inner1
+PASS owner.elements[3] is inner2
+PASS owner.elements[4] is after1
+PASS owner.elements[5] is after2
+
+- Test for changing the value of the form attribute of a element which is located after the form owner.
+PASS owner.elements.length is 5
+PASS owner.elements[0] is before1
+PASS owner.elements[1] is before2
+PASS owner.elements[2] is inner1
+PASS owner.elements[3] is inner2
+PASS owner.elements[4] is after2
+PASS owner.elements.length is 6
+PASS owner.elements[0] is before1
+PASS owner.elements[1] is before2
+PASS owner.elements[2] is inner1
+PASS owner.elements[3] is inner2
+PASS owner.elements[4] is after1
+PASS owner.elements[5] is after2
+
+- Test for setting form attribute of elements in reverse order.
+PASS owner.elements.length is 6
+PASS owner.elements[0] is before1
+PASS owner.elements[1] is before2
+PASS owner.elements[2] is inner1
+PASS owner.elements[3] is inner2
+PASS owner.elements[4] is after1
+PASS owner.elements[5] is after2
+
+- Test for setting form attribute of elements in random order.
+PASS owner.elements.length is 6
+PASS owner.elements[0] is before1
+PASS owner.elements[1] is before2
+PASS owner.elements[2] is inner1
+PASS owner.elements[3] is inner2
+PASS owner.elements[4] is after1
+PASS owner.elements[5] is after2
+
+- Test for removing/adding elements
+PASS owner.elements.length is 3
+PASS owner.elements[0] is before1
+PASS owner.elements[1] is inner1
+PASS owner.elements[2] is after2
+PASS owner.elements.length is 6
+PASS owner.elements[0] is before1
+PASS owner.elements[1] is before2
+PASS owner.elements[2] is inner1
+PASS owner.elements[3] is inner2
+PASS owner.elements[4] is after1
+PASS owner.elements[5] is after2
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
+
+
diff --git a/LayoutTests/fast/forms/form-attribute-elements-order.html b/LayoutTests/fast/forms/form-attribute-elements-order.html
new file mode 100644
index 0000000..2e1721d
--- /dev/null
+++ b/LayoutTests/fast/forms/form-attribute-elements-order.html
@@ -0,0 +1,13 @@
+<!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>
+<script src="script-tests/form-attribute-elements-order.js"></script>
+<script src="../../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/forms/form-attribute-elements-order2-expected.txt b/LayoutTests/fast/forms/form-attribute-elements-order2-expected.txt
new file mode 100644
index 0000000..25460ed
--- /dev/null
+++ b/LayoutTests/fast/forms/form-attribute-elements-order2-expected.txt
@@ -0,0 +1,49 @@
+This test examines the order of the elements attribute of a form element with form-associated elements with form attribute or witout form attibute.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+- Test for the case where some elements have form attribute but some others not.
+PASS owner.elements.length is 3
+PASS owner.elements[0] is input1
+PASS owner.elements[1] is input2
+PASS owner.elements[2] is input3
+PASS owner.elements.length is 3
+PASS owner.elements[0] is input1
+PASS owner.elements[1] is input2
+PASS owner.elements[2] is input3
+
+- Test for inserting/removing a form-associated element without form attribute.
+PASS owner.elements.length is 4
+PASS owner.elements[0] is before
+PASS owner.elements[1] is inner
+PASS owner.elements[2] is inner2
+PASS owner.elements[3] is after
+PASS owner.elements.length is 4
+PASS owner.elements[0] is before
+PASS owner.elements[1] is inner
+PASS owner.elements[2] is inner2
+PASS owner.elements[3] is after
+
+- Test for inserting/removing a form-associated element with form attribute.
+PASS owner.elements.length is 6
+PASS owner.elements[0] is before
+PASS owner.elements[1] is before2
+PASS owner.elements[2] is inner
+PASS owner.elements[3] is inner2
+PASS owner.elements[4] is after
+PASS owner.elements[5] is after2
+PASS owner.elements.length is 6
+PASS owner.elements[0] is before
+PASS owner.elements[1] is before2
+PASS owner.elements[2] is inner
+PASS owner.elements[3] is inner2
+PASS owner.elements[4] is after
+PASS owner.elements[5] is after2
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
+
+
diff --git a/LayoutTests/fast/forms/form-attribute-elements-order2.html b/LayoutTests/fast/forms/form-attribute-elements-order2.html
new file mode 100644
index 0000000..493a7db
--- /dev/null
+++ b/LayoutTests/fast/forms/form-attribute-elements-order2.html
@@ -0,0 +1,13 @@
+<!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>
+<script src="script-tests/form-attribute-elements-order2.js"></script>
+<script src="../../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/forms/form-attribute-elements.html b/LayoutTests/fast/forms/form-attribute-elements.html
new file mode 100644
index 0000000..3389bce
--- /dev/null
+++ b/LayoutTests/fast/forms/form-attribute-elements.html
@@ -0,0 +1,13 @@
+<!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>
+<script src="script-tests/form-attribute-elements.js"></script>
+<script src="../../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/forms/form-attribute-expected.txt b/LayoutTests/fast/forms/form-attribute-expected.txt
new file mode 100644
index 0000000..7f20967
--- /dev/null
+++ b/LayoutTests/fast/forms/form-attribute-expected.txt
@@ -0,0 +1,53 @@
+This test checks the form attribute of the form-associated elements.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+- Checks the existence of the form attribute for each form-associated elements.
+FIXME: <label> and <object> don't support the form attribute for now.
+PASS document.getElementsByTagName("button")[0].form is owner
+PASS document.getElementsByTagName("fieldset")[0].form is owner
+PASS document.getElementsByTagName("input")[0].form is owner
+PASS document.getElementsByTagName("keygen")[0].form is owner
+FAIL document.getElementsByTagName("label")[0].form should be [object HTMLFormElement]. Was null.
+PASS document.getElementsByTagName("meter")[0].form is owner
+FAIL document.getElementsByTagName("object")[0].form should be [object HTMLFormElement]. Was null.
+PASS document.getElementsByTagName("output")[0].form is owner
+PASS document.getElementsByTagName("progress")[0].form is owner
+PASS document.getElementsByTagName("select")[0].form is owner
+PASS document.getElementsByTagName("textarea")[0].form is owner
+
+- Ensures that the form attribute points the form owner even if the element is within another form element.
+PASS inputElement.form is owner
+
+- Ensures that the form attribute of all form-associated element with or witout form attribute points the form owner.
+PASS inputElement1.form is owner
+PASS inputElement2.form is owner
+PASS inputElement3.form is owner
+
+- Ensures that the form attribute points the form owner even if the form element is nested another form element.
+NOTE: It seems that nesting form elements is not allowed so we ensure each form-associated elements associate with the outmost form element.
+PASS inputElement1.form is owner
+PASS inputElement2.form is owner
+PASS inputElement3.form is owner
+
+- Ensures whether the form owner is set correctly when the value of form attribute of a form-associated element changed.
+PASS inputElement.form is form1
+PASS inputElement.form is form2
+
+- Ensures whether the form owner is set correctly when the value of form attribute is added/removed.
+PASS inputElement.form is null
+PASS inputElement.form is owner
+PASS inputElement.form is null
+
+- Ensures whether the form owner is set correctly when the form owner is added/removed.
+PASS owner.name is "firstOwner"
+PASS owner.name is "secondOwner"
+PASS inputElement.form is owner
+PASS inputElement.form is null
+PASS inputElement.form is owner
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
+
diff --git a/LayoutTests/fast/forms/form-attribute.html b/LayoutTests/fast/forms/form-attribute.html
new file mode 100644
index 0000000..3069b0c
--- /dev/null
+++ b/LayoutTests/fast/forms/form-attribute.html
@@ -0,0 +1,13 @@
+<!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>
+<script src="script-tests/form-attribute.js"></script>
+<script src="../../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/forms/script-tests/form-attribute-elements-order.js b/LayoutTests/fast/forms/script-tests/form-attribute-elements-order.js
new file mode 100644
index 0000000..6dcdae3
--- /dev/null
+++ b/LayoutTests/fast/forms/script-tests/form-attribute-elements-order.js
@@ -0,0 +1,153 @@
+description("This test examines the order of the elements attribute of a form element.");
+
+var container = document.createElement('div');
+document.body.appendChild(container);
+container.innerHTML = '<input name=victim id=before1 form=owner />' +
+ '<input name=victim id=before2 form=owner />' +
+ '<form id=owner action= method=GET>' +
+ ' <input name=victim id=inner1 form=owner />' +
+ ' <input name=victim id=inner2 form=owner />' +
+ '</form>' +
+ '<input name=victim id=after1 form=owner />' +
+ '<input name=victim id=after2 form=owner />';
+
+var owner = document.getElementById('owner');
+var before1 = document.getElementById('before1');
+var before2 = document.getElementById('before2');
+var inner1 = document.getElementById('inner1');
+var inner2 = document.getElementById('inner2');
+var after1 = document.getElementById('after1');
+var after2 = document.getElementById('after2');
+
+debug('- Test for the case where some elements are outside of the form.');
+shouldBe('owner.elements.length', '6');
+shouldBe('owner.elements[0]', 'before1');
+shouldBe('owner.elements[1]', 'before2');
+shouldBe('owner.elements[2]', 'inner1');
+shouldBe('owner.elements[3]', 'inner2');
+shouldBe('owner.elements[4]', 'after1');
+shouldBe('owner.elements[5]', 'after2');
+
+debug('');
+debug('- Test for changing the value of the form attribute of a element which is located before the form owner.');
+before2.attributes['form'].value = '';
+shouldBe('owner.elements.length', '5');
+shouldBe('owner.elements[0]', 'before1');
+shouldBe('owner.elements[1]', 'inner1');
+shouldBe('owner.elements[2]', 'inner2');
+shouldBe('owner.elements[3]', 'after1');
+shouldBe('owner.elements[4]', 'after2');
+before2.attributes['form'].value = 'owner';
+shouldBe('owner.elements.length', '6');
+shouldBe('owner.elements[0]', 'before1');
+shouldBe('owner.elements[1]', 'before2');
+shouldBe('owner.elements[2]', 'inner1');
+shouldBe('owner.elements[3]', 'inner2');
+shouldBe('owner.elements[4]', 'after1');
+shouldBe('owner.elements[5]', 'after2');
+
+debug('');
+debug('- Test for changing the value of the form attribute of a element which is located inside of the form owner.');
+inner2.attributes['form'].value = '';
+shouldBe('owner.elements.length', '5');
+shouldBe('owner.elements[0]', 'before1');
+shouldBe('owner.elements[1]', 'before2');
+shouldBe('owner.elements[2]', 'inner1');
+shouldBe('owner.elements[3]', 'after1');
+shouldBe('owner.elements[4]', 'after2');
+inner2.attributes['form'].value = 'owner';
+shouldBe('owner.elements.length', '6');
+shouldBe('owner.elements[0]', 'before1');
+shouldBe('owner.elements[1]', 'before2');
+shouldBe('owner.elements[2]', 'inner1');
+shouldBe('owner.elements[3]', 'inner2');
+shouldBe('owner.elements[4]', 'after1');
+shouldBe('owner.elements[5]', 'after2');
+
+debug('');
+debug('- Test for changing the value of the form attribute of a element which is located after the form owner.');
+after1.attributes['form'].value = '';
+shouldBe('owner.elements.length', '5');
+shouldBe('owner.elements[0]', 'before1');
+shouldBe('owner.elements[1]', 'before2');
+shouldBe('owner.elements[2]', 'inner1');
+shouldBe('owner.elements[3]', 'inner2');
+shouldBe('owner.elements[4]', 'after2');
+after1.attributes['form'].value = 'owner';
+shouldBe('owner.elements.length', '6');
+shouldBe('owner.elements[0]', 'before1');
+shouldBe('owner.elements[1]', 'before2');
+shouldBe('owner.elements[2]', 'inner1');
+shouldBe('owner.elements[3]', 'inner2');
+shouldBe('owner.elements[4]', 'after1');
+shouldBe('owner.elements[5]', 'after2');
+
+debug('');
+debug('- Test for setting form attribute of elements in reverse order.');
+before1.attributes['form'].value = '';
+before2.attributes['form'].value = '';
+inner1.attributes['form'].value = '';
+inner2.attributes['form'].value = '';
+after1.attributes['form'].value = '';
+after2.attributes['form'].value = '';
+
+after2.attributes['form'].value = 'owner';
+after1.attributes['form'].value = 'owner';
+inner2.attributes['form'].value = 'owner';
+inner1.attributes['form'].value = 'owner';
+before2.attributes['form'].value = 'owner';
+before1.attributes['form'].value = 'owner';
+
+shouldBe('owner.elements.length', '6');
+shouldBe('owner.elements[0]', 'before1');
+shouldBe('owner.elements[1]', 'before2');
+shouldBe('owner.elements[2]', 'inner1');
+shouldBe('owner.elements[3]', 'inner2');
+shouldBe('owner.elements[4]', 'after1');
+shouldBe('owner.elements[5]', 'after2');
+
+debug('');
+debug('- Test for setting form attribute of elements in random order.');
+before1.attributes['form'].value = '';
+before2.attributes['form'].value = '';
+inner1.attributes['form'].value = '';
+inner2.attributes['form'].value = '';
+after1.attributes['form'].value = '';
+after2.attributes['form'].value = '';
+
+after1.attributes['form'].value = 'owner';
+before1.attributes['form'].value = 'owner';
+inner2.attributes['form'].value = 'owner';
+before2.attributes['form'].value = 'owner';
+after2.attributes['form'].value = 'owner';
+inner1.attributes['form'].value = 'owner';
+
+shouldBe('owner.elements.length', '6');
+shouldBe('owner.elements[0]', 'before1');
+shouldBe('owner.elements[1]', 'before2');
+shouldBe('owner.elements[2]', 'inner1');
+shouldBe('owner.elements[3]', 'inner2');
+shouldBe('owner.elements[4]', 'after1');
+shouldBe('owner.elements[5]', 'after2');
+
+debug('');
+debug('- Test for removing/adding elements');
+container.removeChild(before2);
+owner.removeChild(inner2);
+container.removeChild(after1);
+shouldBe('owner.elements.length', '3');
+shouldBe('owner.elements[0]', 'before1');
+shouldBe('owner.elements[1]', 'inner1');
+shouldBe('owner.elements[2]', 'after2');
+container.insertBefore(before2, owner);
+owner.appendChild(inner2);
+container.insertBefore(after1, after2);
+shouldBe('owner.elements.length', '6');
+shouldBe('owner.elements[0]', 'before1');
+shouldBe('owner.elements[1]', 'before2');
+shouldBe('owner.elements[2]', 'inner1');
+shouldBe('owner.elements[3]', 'inner2');
+shouldBe('owner.elements[4]', 'after1');
+shouldBe('owner.elements[5]', 'after2');
+
+var successfullyParsed = true;
diff --git a/LayoutTests/fast/forms/script-tests/form-attribute-elements-order2.js b/LayoutTests/fast/forms/script-tests/form-attribute-elements-order2.js
new file mode 100644
index 0000000..6d7f799
--- /dev/null
+++ b/LayoutTests/fast/forms/script-tests/form-attribute-elements-order2.js
@@ -0,0 +1,98 @@
+description("This test examines the order of the elements attribute of a form element with form-associated elements with form attribute or witout form attibute.");
+
+var container = document.createElement('div');
+document.body.appendChild(container);
+
+debug('');
+debug('- Test for the case where some elements have form attribute but some others not.');
+container.innerHTML = '<form id=owner>' +
+ ' <input id=input1 name=victim />' +
+ ' <input id=input2 name=victim form=owner />' +
+ ' <input id=input3 name=victim />' +
+ '</form>';
+var owner = document.getElementById('owner');
+var input1 = document.getElementById('input1');
+var input2 = document.getElementById('input2');
+var input3 = document.getElementById('input3');
+shouldBe('owner.elements.length', '3');
+shouldBe('owner.elements[0]', 'input1');
+shouldBe('owner.elements[1]', 'input2');
+shouldBe('owner.elements[2]', 'input3');
+
+container.innerHTML = '<form id=owner>' +
+ ' <input id=input1 name=victim form=owner />' +
+ ' <input id=input2 name=victim />' +
+ ' <input id=input3 name=victim form=owner />' +
+ '</form>';
+owner = document.getElementById('owner');
+input1 = document.getElementById('input1');
+input2 = document.getElementById('input2');
+input3 = document.getElementById('input3');
+shouldBe('owner.elements.length', '3');
+shouldBe('owner.elements[0]', 'input1');
+shouldBe('owner.elements[1]', 'input2');
+shouldBe('owner.elements[2]', 'input3');
+
+debug('');
+debug('- Test for inserting/removing a form-associated element without form attribute.');
+container.innerHTML = '<input name=victim id=before form=owner />' +
+ '<form id=owner action= method=GET>' +
+ ' <input name=victim id=inner />' +
+ '</form>' +
+ '<input name=victim id=after form=owner />';
+owner = document.getElementById('owner');
+var before = document.getElementById('before');
+var inner = document.getElementById('inner');
+var after = document.getElementById('after');
+
+var inner2 = document.createElement('input');
+inner2.name = 'victim';
+inner2.id = 'inner2';
+owner.appendChild(inner2);
+shouldBe('owner.elements.length', '4');
+shouldBe('owner.elements[0]', 'before');
+shouldBe('owner.elements[1]', 'inner');
+shouldBe('owner.elements[2]', 'inner2');
+shouldBe('owner.elements[3]', 'after');
+
+owner.removeChild(inner);
+owner.insertBefore(inner, inner2);
+shouldBe('owner.elements.length', '4');
+shouldBe('owner.elements[0]', 'before');
+shouldBe('owner.elements[1]', 'inner');
+shouldBe('owner.elements[2]', 'inner2');
+shouldBe('owner.elements[3]', 'after');
+
+debug('');
+debug('- Test for inserting/removing a form-associated element with form attribute.');
+var before2 = document.createElement('input');
+before2.name = 'victim';
+before2.id = 'before2';
+before2.setAttribute('form', 'owner');
+container.insertBefore(before2, owner);
+var after2 = document.createElement('input');
+after2.name = 'victim';
+after2.id = 'after2';
+after2.setAttribute('form', 'owner');
+container.appendChild(after2);
+shouldBe('owner.elements.length', '6');
+shouldBe('owner.elements[0]', 'before');
+shouldBe('owner.elements[1]', 'before2');
+shouldBe('owner.elements[2]', 'inner');
+shouldBe('owner.elements[3]', 'inner2');
+shouldBe('owner.elements[4]', 'after');
+shouldBe('owner.elements[5]', 'after2');
+
+container.removeChild(before);
+container.removeChild(after);
+container.insertBefore(before, before2);
+container.insertBefore(after, after2);
+shouldBe('owner.elements.length', '6');
+shouldBe('owner.elements[0]', 'before');
+shouldBe('owner.elements[1]', 'before2');
+shouldBe('owner.elements[2]', 'inner');
+shouldBe('owner.elements[3]', 'inner2');
+shouldBe('owner.elements[4]', 'after');
+shouldBe('owner.elements[5]', 'after2');
+
+var successfullyParsed = true;
diff --git a/LayoutTests/fast/forms/script-tests/form-attribute-elements.js b/LayoutTests/fast/forms/script-tests/form-attribute-elements.js
new file mode 100644
index 0000000..3826447
--- /dev/null
+++ b/LayoutTests/fast/forms/script-tests/form-attribute-elements.js
@@ -0,0 +1,42 @@
+description("This test checks a form element can handle elements of which form attribute points the form element even if elements are outside of the form.");
+
+if (window.layoutTestController)
+ layoutTestController.waitUntilDone();
+
+var container = document.createElement('div');
+document.body.appendChild(container);
+
+container.innerHTML = '<input type=hidden name=key1 value=value1 id=outer-before form=owner />' +
+ '<form id=owner action="" method="GET">' +
+ ' <input type=hidden name=key2 value=value2 id=inner form=owner />' +
+ '</form>' +
+ '<input type=hidden name=submitted value=true id=outer-after form=owner />';
+
+var owner = document.getElementById('owner');
+var outerBefore = document.getElementById('outer-before');
+var inner = document.getElementById('inner');
+var outerAfter = document.getElementById('outer-after');
+var query = window.location.search;
+
+if (query.indexOf('submitted=true') == -1) {
+ owner.submit();
+} else {
+ debug('- Ensures that elements attribute of the form contains elements which are outside of the form.');
+
+ shouldBe('owner.elements.length', '3');
+ shouldBe('owner.elements[0]', 'outerBefore');
+ shouldBe('owner.elements[1]', 'inner');
+ shouldBe('owner.elements[2]', 'outerAfter');
+
+ debug('');
+ debug('- Ensures that form submission contains name and value pairs for such elements.');
+ var pairs = query.substr(1).split('&');
+ shouldBe('pairs.length', '3');
+ shouldBeEqualToString('pairs[0]', 'key1=value1');
+ shouldBeEqualToString('pairs[1]', 'key2=value2');
+ shouldBeEqualToString('pairs[2]', 'submitted=true');
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+
+var successfullyParsed = true;
diff --git a/LayoutTests/fast/forms/script-tests/form-attribute.js b/LayoutTests/fast/forms/script-tests/form-attribute.js
new file mode 100644
index 0000000..082afe6
--- /dev/null
+++ b/LayoutTests/fast/forms/script-tests/form-attribute.js
@@ -0,0 +1,119 @@
+description("This test checks the form attribute of the form-associated elements.");
+
+var container = document.createElement('div');
+document.body.appendChild(container);
+
+debug('- Checks the existence of the form attribute for each form-associated elements.');
+debug('FIXME: <label> and <object> don\'t support the form attribute for now.');
+container.innerHTML = '<form id=owner></form>' +
+ '<button name=victim form=owner />' +
+ '<fieldset name=victim form=owner />' +
+ '<input name=victim form=owner />' +
+ '<keygen name=victim form=owner />' +
+ '<label name=victim form=owner />' +
+ '<meter name=victim form=owner />' +
+ '<object name=victim form=owner />' +
+ '<output name=victim form=owner />' +
+ '<progress name=victim form=owner />' +
+ '<select name=victim form=owner />' +
+ '<textarea name=victim form=owner />';
+
+var owner = document.getElementById('owner');
+shouldBe('document.getElementsByTagName("button")[0].form', 'owner');
+shouldBe('document.getElementsByTagName("fieldset")[0].form', 'owner');
+shouldBe('document.getElementsByTagName("input")[0].form', 'owner');
+shouldBe('document.getElementsByTagName("keygen")[0].form', 'owner');
+shouldBe('document.getElementsByTagName("label")[0].form', 'owner');
+shouldBe('document.getElementsByTagName("meter")[0].form', 'owner');
+shouldBe('document.getElementsByTagName("object")[0].form', 'owner');
+shouldBe('document.getElementsByTagName("output")[0].form', 'owner');
+shouldBe('document.getElementsByTagName("progress")[0].form', 'owner');
+shouldBe('document.getElementsByTagName("select")[0].form', 'owner');
+shouldBe('document.getElementsByTagName("textarea")[0].form', 'owner');
+
+debug('');
+debug('- Ensures that the form attribute points the form owner even if the element is within another form element.');
+container.innerHTML = '<form id=owner></form>' +
+ '<form id=shouldNotBeOwner>' +
+ ' <input id=inputElement name=victim form=owner />' +
+ '</form>';
+owner = document.getElementById('owner');
+var inputElement = document.getElementById('inputElement');
+shouldBe('inputElement.form', 'owner');
+
+debug('');
+debug('- Ensures that the form attribute of all form-associated element with or witout form attribute points the form owner.');
+container.innerHTML = '<form id=owner>' +
+ ' <input id=inputElement1 name=victim />' +
+ ' <input id=inputElement2 name=victim form=owner />' +
+ ' <input id=inputElement3 name=victim />' +
+ '</form>';
+owner = document.getElementById('owner');
+var inputElement1 = document.getElementById('inputElement1');
+var inputElement2 = document.getElementById('inputElement2');
+var inputElement3 = document.getElementById('inputElement3');
+shouldBe('inputElement1.form', 'owner');
+shouldBe('inputElement2.form', 'owner');
+shouldBe('inputElement3.form', 'owner');
+
+debug('');
+debug('- Ensures that the form attribute points the form owner even if the form element is nested another form element.');
+debug('NOTE: It seems that nesting form elements is not allowed so we ensure each form-associated elements associate with the outmost form element.');
+container.innerHTML = '<form id=owner>' +
+ ' <form>' +
+ ' <input id=inputElement1 name=victim form=owner/>' +
+ ' <input id=inputElement2 name=victim />' +
+ ' <input id=inputElement3 name=victim form=owner/>' +
+ ' </form>' +
+ '</form>';
+owner = document.getElementById('owner');
+inputElement1 = document.getElementById('inputElement1');
+inputElement2 = document.getElementById('inputElement2');
+inputElement3 = document.getElementById('inputElement3');
+shouldBe('inputElement1.form', 'owner');
+shouldBe('inputElement2.form', 'owner');
+shouldBe('inputElement3.form', 'owner');
+
+debug('');
+debug('- Ensures whether the form owner is set correctly when the value of form attribute of a form-associated element changed.');
+container.innerHTML = '<form id=form1></form>' +
+ '<form id=form2></form>' +
+ '<input id=inputElement name=victim form=form1 />';
+var form1 = document.getElementById('form1');
+var form2 = document.getElementById('form2');
+inputElement = document.getElementById('inputElement');
+shouldBe('inputElement.form', 'form1');
+inputElement.attributes['form'].value = 'form2';
+shouldBe('inputElement.form', 'form2');
+
+debug('');
+debug('- Ensures whether the form owner is set correctly when the value of form attribute is added/removed.');
+container.innerHTML = '<form id=owner name=firstOwner></form>' +
+ '<input id=inputElement name=victim />';
+owner = document.getElementById('owner');
+inputElement = document.getElementById('inputElement');
+shouldBe('inputElement.form', 'null');
+var formAttribute = document.createAttribute('form');
+inputElement.setAttribute('form', 'owner');
+shouldBe('inputElement.form', 'owner');
+inputElement.removeAttribute('form');
+shouldBe('inputElement.form', 'null');
+
+debug('');
+debug('- Ensures whether the form owner is set correctly when the form owner is added/removed.');
+container.innerHTML = '<form id=owner name=firstOwner></form>' +
+ '<form id=owner name=secondOwner></form>' +
+ '<input id=inputElement name=victim form=owner />';
+owner = document.getElementById('owner');
+shouldBeEqualToString('owner.name', 'firstOwner');
+inputElement = document.getElementById('inputElement');
+container.removeChild(owner);
+owner = document.getElementById('owner');
+shouldBeEqualToString('owner.name', 'secondOwner');
+shouldBe('inputElement.form', 'owner');
+container.removeChild(owner);
+shouldBe('inputElement.form', 'null');
+container.appendChild(owner);
+shouldBe('inputElement.form', 'owner');
+
+var successfullyParsed = true;
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 5bccc86..2ca2eda 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,50 @@
+2010-11-14 Kenichi Ishibashi <bashi at google.com>
+
+ Reviewed by Kent Tamura.
+
+ [HTML5] "form" attribute support for form control elements
+ https://bugs.webkit.org/show_bug.cgi?id=47813
+
+ Adds a list of form-associated elements with form attribute into
+ the Document class to support form attribute.
+ Adds a function to determine the right place to locate
+ form-associated elements with form attribute into
+ m_associatedElements of HTMLFormElement class.
+
+ Tests: fast/forms/form-attribute-elements-order.html
+ fast/forms/form-attribute-elements-order2.html
+ fast/forms/form-attribute-elements.html
+ fast/forms/form-attribute.html
+
+ * dom/Document.cpp:
+ (WebCore::Document::registerFormElementWithFormAttribute): Added.
+ (WebCore::Document::unregisterFormElementWithFormAttribute): Added.
+ (WebCore::Document::resetFormElementsOwner): Added.
+ * dom/Document.h: Added the list for elements with form attribute.
+ * html/HTMLAttributeNames.in: Added form attribute.
+ * html/HTMLFormControlElement.cpp:
+ (WebCore::HTMLFormControlElement::insertedIntoTree): Modified to handle
+ form attribute.
+ (WebCore::HTMLFormControlElement::removedFromTree): Ditto.
+ (WebCore::HTMLFormControlElement::resetFormOwner): Added.
+ (WebCore::HTMLFormControlElement::attributeChanged): Added.
+ * html/HTMLFormControlElement.h:
+ * html/HTMLFormElement.cpp:
+ (WebCore::HTMLFormElement::HTMLFormElement): Modified to initialize
+ newly-added variables.
+ (WebCore::HTMLFormElement::insertedIntoDocument): Modified to reset
+ form owner of form-associated elements.
+ (WebCore::HTMLFormElement::removedFromDocument): Ditto.
+ (WebCore::HTMLFormElement::formElementIndexWithFormAttribute): Added.
+ (WebCore::HTMLFormElement::formElementIndex): Modified to treat
+ form-associated elements with form attribute separately.
+ (WebCore::HTMLFormElement::removeFormElement): Modified to handle
+ form-associated elements with form attribute.
+ * html/HTMLFormElement.h: Added three variables to handle form attribute.
+ * html/HTMLOutputElement.cpp: Removed "FIXME" comment.
+ (WebCore::HTMLOutputElement::parseMappedAttribute):
+ * html/HTMLOutputElement.h: Removed setForm().
+
2010-11-14 David Hyatt <hyatt at apple.com>
Reviewed by Dan Bernstein.
diff --git a/WebCore/dom/Document.cpp b/WebCore/dom/Document.cpp
index 7f77b3e..4c3425a 100644
--- a/WebCore/dom/Document.cpp
+++ b/WebCore/dom/Document.cpp
@@ -4365,6 +4365,25 @@ void Document::setIconURL(const String& iconURL, const String& type)
f->loader()->setIconURL(m_iconURL);
}
+void Document::registerFormElementWithFormAttribute(Element* control)
+{
+ ASSERT(control->fastHasAttribute(formAttr));
+ m_formElementsWithFormAttribute.add(control);
+}
+
+void Document::unregisterFormElementWithFormAttribute(Element* control)
+{
+ m_formElementsWithFormAttribute.remove(control);
+}
+
+void Document::resetFormElementsOwner(HTMLFormElement* form)
+{
+ typedef FormElementListHashSet::iterator Iterator;
+ Iterator end = m_formElementsWithFormAttribute.end();
+ for (Iterator it = m_formElementsWithFormAttribute.begin(); it != end; ++it)
+ static_cast<HTMLFormControlElement*>(*it)->resetFormOwner(form);
+}
+
void Document::setUseSecureKeyboardEntryWhenActive(bool usesSecureKeyboard)
{
if (m_useSecureKeyboardEntryWhenActive == usesSecureKeyboard)
diff --git a/WebCore/dom/Document.h b/WebCore/dom/Document.h
index 8cc6272..ba48d6f 100644
--- a/WebCore/dom/Document.h
+++ b/WebCore/dom/Document.h
@@ -483,6 +483,10 @@ public:
bool hasStateForNewFormElements() const;
bool takeStateForFormElement(AtomicStringImpl* name, AtomicStringImpl* type, String& state);
+ void registerFormElementWithFormAttribute(Element*);
+ void unregisterFormElementWithFormAttribute(Element*);
+ void resetFormElementsOwner(HTMLFormElement*);
+
FrameView* view() const; // can be NULL
Frame* frame() const { return m_frame; } // can be NULL
Page* page() const; // can be NULL
@@ -1197,6 +1201,7 @@ private:
typedef ListHashSet<Element*, 64> FormElementListHashSet;
FormElementListHashSet m_formElementsWithState;
+ FormElementListHashSet m_formElementsWithFormAttribute;
typedef HashMap<FormElementKey, Vector<String>, FormElementKeyHash, FormElementKeyHashTraits> FormElementStateMap;
FormElementStateMap m_stateForNewFormElements;
diff --git a/WebCore/html/HTMLAttributeNames.in b/WebCore/html/HTMLAttributeNames.in
index d9759fc..1881b6f 100644
--- a/WebCore/html/HTMLAttributeNames.in
+++ b/WebCore/html/HTMLAttributeNames.in
@@ -94,6 +94,7 @@ expanded
face
focused
for
+form
formnovalidate
frame
frameborder
diff --git a/WebCore/html/HTMLFormControlElement.cpp b/WebCore/html/HTMLFormControlElement.cpp
index 8fa000f..2f5d414 100644
--- a/WebCore/html/HTMLFormControlElement.cpp
+++ b/WebCore/html/HTMLFormControlElement.cpp
@@ -154,6 +154,16 @@ void HTMLFormControlElement::attach()
void HTMLFormControlElement::insertedIntoTree(bool deep)
{
+ if (fastHasAttribute(formAttr)) {
+ document()->registerFormElementWithFormAttribute(this);
+ Element* element = document()->getElementById(fastGetAttribute(formAttr));
+ if (element && element->hasTagName(formTag)) {
+ if (m_form)
+ m_form->removeFormElement(this);
+ m_form = static_cast<HTMLFormElement*>(element);
+ m_form->registerFormElement(this);
+ }
+ }
if (!m_form) {
// This handles the case of a new form element being created by
// JavaScript and inserted inside a form. In the case of the parser
@@ -179,6 +189,9 @@ static inline Node* findRoot(Node* n)
void HTMLFormControlElement::removedFromTree(bool deep)
{
+ if (fastHasAttribute(formAttr))
+ document()->unregisterFormElementWithFormAttribute(this);
+
// If the form and element are both in the same tree, preserve the connection to the form.
// Otherwise, null out our form and remove ourselves from the form's list of elements.
if (m_form && findRoot(this) != findRoot(m_form)) {
@@ -431,6 +444,50 @@ void HTMLFormControlElement::removeFromForm()
m_form = 0;
}
+void HTMLFormControlElement::resetFormOwner(HTMLFormElement* form)
+{
+ if (m_form) {
+ if (!fastHasAttribute(formAttr))
+ return;
+ m_form->removeFormElement(this);
+ }
+ m_form = 0;
+ if (fastHasAttribute(formAttr)) {
+ // The HTML5 spec says that the element should be associated with
+ // the first element in the document to have an ID that equal to
+ // the value of form attribute, so we put the result of
+ // document()->getElementById() over the given element.
+ Element* firstElement = document()->getElementById(fastGetAttribute(formAttr));
+ if (firstElement && firstElement->hasTagName(formTag))
+ m_form = static_cast<HTMLFormElement*>(firstElement);
+ else
+ m_form = form;
+ } else
+ m_form = findFormAncestor();
+ if (m_form)
+ m_form->registerFormElement(this);
+ else
+ document()->checkedRadioButtons().addButton(this);
+}
+
+void HTMLFormControlElement::attributeChanged(Attribute* attr, bool preserveDecls)
+{
+ if (attr->name() == formAttr) {
+ if (!fastHasAttribute(formAttr)) {
+ // The form attribute removed. We need to reset form owner here.
+ if (m_form)
+ m_form->removeFormElement(this);
+ m_form = findFormAncestor();
+ if (m_form)
+ m_form->registerFormElement(this);
+ else
+ document()->checkedRadioButtons().addButton(this);
+ } else
+ resetFormOwner(0);
+ }
+ HTMLElement::attributeChanged(attr, preserveDecls);
+}
+
bool HTMLFormControlElement::isLabelable() const
{
// FIXME: Add meterTag and outputTag to the list once we support them.
diff --git a/WebCore/html/HTMLFormControlElement.h b/WebCore/html/HTMLFormControlElement.h
index 1960fc3..8c98d91 100644
--- a/WebCore/html/HTMLFormControlElement.h
+++ b/WebCore/html/HTMLFormControlElement.h
@@ -99,6 +99,9 @@ public:
bool readOnly() const { return m_readOnly; }
+ void resetFormOwner(HTMLFormElement*);
+ virtual void attributeChanged(Attribute*, bool preserveDecls = false);
+
protected:
HTMLFormControlElement(const QualifiedName& tagName, Document*, HTMLFormElement*);
diff --git a/WebCore/html/HTMLFormElement.cpp b/WebCore/html/HTMLFormElement.cpp
index da388d5..1aeb360 100644
--- a/WebCore/html/HTMLFormElement.cpp
+++ b/WebCore/html/HTMLFormElement.cpp
@@ -65,6 +65,8 @@ using namespace HTMLNames;
HTMLFormElement::HTMLFormElement(const QualifiedName& tagName, Document* document)
: HTMLElement(tagName, document)
+ , m_associatedElementsBeforeIndex(0)
+ , m_associatedElementsAfterIndex(0)
, m_wasUserSubmitted(false)
, m_autocomplete(true)
, m_insubmit(false)
@@ -133,6 +135,9 @@ void HTMLFormElement::insertedIntoDocument()
static_cast<HTMLDocument*>(document())->addNamedItem(m_name);
HTMLElement::insertedIntoDocument();
+
+ if (hasID())
+ document()->resetFormElementsOwner(this);
}
void HTMLFormElement::removedFromDocument()
@@ -141,6 +146,9 @@ void HTMLFormElement::removedFromDocument()
static_cast<HTMLDocument*>(document())->removeNamedItem(m_name);
HTMLElement::removedFromDocument();
+
+ if (hasID())
+ document()->resetFormElementsOwner(0);
}
void HTMLFormElement::handleLocalEvents(Event* event)
@@ -388,24 +396,64 @@ template<class T, size_t n> static void removeFromVector(Vector<T*, n> & vec, T*
}
}
+unsigned HTMLFormElement::formElementIndexWithFormAttribute(HTMLFormControlElement* element)
+{
+ // Compares the position of the form element and the inserted element.
+ // Updates the indeces in order to the relation of the position:
+ unsigned short position = compareDocumentPosition(element);
+ if (position & DOCUMENT_POSITION_CONTAINS)
+ ++m_associatedElementsAfterIndex;
+ else if (position & DOCUMENT_POSITION_PRECEDING) {
+ ++m_associatedElementsBeforeIndex;
+ ++m_associatedElementsAfterIndex;
+ }
+
+ if (m_associatedElements.isEmpty())
+ return 0;
+
+ // Does binary search on m_associatedElements in order to find the index
+ // to be inserted.
+ unsigned left = 0, right = m_associatedElements.size() - 1;
+ while (left != right) {
+ unsigned middle = left + ((right - left) / 2);
+ position = element->compareDocumentPosition(m_associatedElements[middle]);
+ if (position & DOCUMENT_POSITION_FOLLOWING)
+ right = middle;
+ else
+ left = middle + 1;
+ }
+
+ position = element->compareDocumentPosition(m_associatedElements[left]);
+ if (position & DOCUMENT_POSITION_FOLLOWING)
+ return left;
+ return left + 1;
+}
+
unsigned HTMLFormElement::formElementIndex(HTMLFormControlElement* e)
{
+ // Treats separately the case where this element has the form attribute
+ // for performance consideration.
+ if (e->fastHasAttribute(formAttr))
+ return formElementIndexWithFormAttribute(e);
+
// Check for the special case where this element is the very last thing in
// the form's tree of children; we don't want to walk the entire tree in that
// common case that occurs during parsing; instead we'll just return a value
// that says "add this form element to the end of the array".
if (e->traverseNextNode(this)) {
- unsigned i = 0;
+ unsigned i = m_associatedElementsBeforeIndex;
for (Node* node = this; node; node = node->traverseNextNode(this)) {
- if (node == e)
+ if (node == e) {
+ ++m_associatedElementsAfterIndex;
return i;
+ }
if (node->isHTMLElement()
&& static_cast<Element*>(node)->isFormControlElement()
&& static_cast<HTMLFormControlElement*>(node)->form() == this)
++i;
}
}
- return m_associatedElements.size();
+ return m_associatedElementsAfterIndex++;
}
void HTMLFormElement::registerFormElement(HTMLFormControlElement* e)
@@ -418,6 +466,18 @@ void HTMLFormElement::registerFormElement(HTMLFormControlElement* e)
void HTMLFormElement::removeFormElement(HTMLFormControlElement* e)
{
m_checkedRadioButtons.removeButton(e);
+ if (e->fastHasAttribute(formAttr)) {
+ unsigned index;
+ for (index = 0; index < m_associatedElements.size(); ++index)
+ if (m_associatedElements[index] == e)
+ break;
+ ASSERT(index < m_associatedElements.size());
+ if (index < m_associatedElementsBeforeIndex)
+ --m_associatedElementsBeforeIndex;
+ if (index < m_associatedElementsAfterIndex)
+ --m_associatedElementsAfterIndex;
+ } else
+ --m_associatedElementsAfterIndex;
removeFromVector(m_associatedElements, e);
}
diff --git a/WebCore/html/HTMLFormElement.h b/WebCore/html/HTMLFormElement.h
index b996d9d..4e06bec 100644
--- a/WebCore/html/HTMLFormElement.h
+++ b/WebCore/html/HTMLFormElement.h
@@ -131,6 +131,7 @@ private:
void submit(Event*, bool activateSubmitButton, bool processingUserGesture, FormSubmissionTrigger);
+ unsigned formElementIndexWithFormAttribute(HTMLFormControlElement*);
unsigned formElementIndex(HTMLFormControlElement*);
// Returns true if the submission should be proceeded.
bool validateInteractively(Event*);
@@ -148,6 +149,8 @@ private:
CheckedRadioButtons m_checkedRadioButtons;
+ unsigned m_associatedElementsBeforeIndex;
+ unsigned m_associatedElementsAfterIndex;
Vector<HTMLFormControlElement*> m_associatedElements;
Vector<HTMLImageElement*> m_imageElements;
diff --git a/WebCore/html/HTMLOutputElement.cpp b/WebCore/html/HTMLOutputElement.cpp
index dee21ae..b83263e 100644
--- a/WebCore/html/HTMLOutputElement.cpp
+++ b/WebCore/html/HTMLOutputElement.cpp
@@ -58,7 +58,6 @@ const AtomicString& HTMLOutputElement::formControlType() const
void HTMLOutputElement::parseMappedAttribute(Attribute* attr)
{
- // FIXME: Should handle the 'form' attribute here.
if (attr->name() == HTMLNames::forAttr)
setFor(attr->value());
else
@@ -75,11 +74,6 @@ void HTMLOutputElement::setFor(const String& value)
m_tokens->setValue(value);
}
-void HTMLOutputElement::setForm(const String& /*id*/)
-{
- // FIXME: Implement this function.
-}
-
void HTMLOutputElement::childrenChanged(bool createdByParser, Node*, Node*, int)
{
if (createdByParser || m_isSetTextContentInProgress) {
diff --git a/WebCore/html/HTMLOutputElement.h b/WebCore/html/HTMLOutputElement.h
index df807fb..83ecee2 100644
--- a/WebCore/html/HTMLOutputElement.h
+++ b/WebCore/html/HTMLOutputElement.h
@@ -43,7 +43,6 @@ public:
virtual bool willValidate() const { return false; }
- void setForm(const String&);
String value() const;
void setValue(const String&);
String defaultValue() const;
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list