+2012-03-16 Yoshifumi Inoue <yosin@chromium.org>
+
+ [Forms] label.form attribute doesn't work
+ https://bugs.webkit.org/show_bug.cgi?id=80499
+
+ Reviewed by Kent Tamura.
+
+ This patch updates test cases and expectation for functional
+ "form" attribute of the "label" element.
+
+ * fast/forms/form-attribute-expected.txt:
+ * fast/forms/form-attribute-nonexistence-form-id-expected.txt:
+ * fast/forms/form-attribute-nonexistence-form-id.html:
+ * fast/forms/form-attribute.html:
+
2012-03-16 Kihong Kwon <kihong.kwon@samsung.com>
Support for Battery Status API.
- Checks the existence of the form attribute for each form-associated elements.
-FIXME: <label> doesn'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("label")[0].form is owner
PASS document.getElementsByTagName("object")[0].form is owner
PASS document.getElementsByTagName("output")[0].form is owner
PASS document.getElementsByTagName("progress")[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
+PASS labelElement.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
+PASS labelElement1.form is owner
+PASS labelElement2.form is owner
+PASS labelElement3.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
+PASS labelElement1.form is owner
+PASS labelElement2.form is owner
+PASS labelElement3.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
+PASS labelElement.form is form1
+PASS labelElement.form is form2
PASS objectElement.form is form1
PASS objectElement.form is form2
PASS inputElement.form is null
PASS inputElement.form is owner
PASS inputElement.form is null
+PASS labelElement.form is null
+PASS labelElement.form is owner
+PASS labelElement.form is null
PASS objectElement.form is null
PASS objectElement.form is owner
PASS objectElement.form is null
PASS owner.name is "firstOwner"
PASS owner.name is "secondOwner"
PASS inputElement.form is owner
+PASS labelElement.form is owner
PASS inputElement.form is null
+PASS labelElement.form is null
PASS inputElement.form is owner
+PASS labelElement.form is owner
PASS successfullyParsed is true
TEST COMPLETE
-This page ensures that <input from="X"> don't associate with any form elements when there is no <form id="X">.
+This page ensures that <input from="X"> and <label from="X"> don't associate with any form elements when there is no <form id="X">.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-PASS elementShouldHaveForm.form is form
-PASS elementShouldNotHaveForm.form is null
+label1 label2
+PASS inputShouldHaveForm.form is form
+PASS inputShouldNotHaveForm.form is null
+PASS labelShouldHaveForm.form is form
+PASS labelShouldNotHaveForm.form is null
PASS successfullyParsed is true
TEST COMPLETE
<form id="form">
<input type="hidden" id="input1" value="value1">
<input type="hidden" id="input2" value="value2" form="X">
+ <label id="label1">label1</label>
+ <label id="label2" form="X">label2</label>
</form>
<div id="console"></div>
<script>
-description('This page ensures that <input from="X"> don\'t associate with any form elements when there is no <form id="X">.');
+description('This page ensures that <input from="X"> and <label from="X"> don\'t associate with any form elements when there is no <form id="X">.');
var form = document.getElementById('form');
-var elementShouldHaveForm = document.getElementById('input1');
-var elementShouldNotHaveForm = document.getElementById('input2');
-shouldBe('elementShouldHaveForm.form', 'form');
-shouldBeNull('elementShouldNotHaveForm.form');
+var inputShouldHaveForm = document.getElementById('input1');
+var inputShouldNotHaveForm = document.getElementById('input2');
+var labelShouldHaveForm = document.getElementById('label1');
+var labelShouldNotHaveForm = document.getElementById('label2');
+shouldBe('inputShouldHaveForm.form', 'form');
+shouldBeNull('inputShouldNotHaveForm.form');
+shouldBe('labelShouldHaveForm.form', 'form');
+shouldBeNull('labelShouldNotHaveForm.form');
</script>
<script src="../../fast/js/resources/js-test-post.js"></script>
</body>
document.body.appendChild(container);
debug('- Checks the existence of the form attribute for each form-associated elements.');
-debug('FIXME: <label> doesn\'t support the form attribute for now.');
container.innerHTML = '<form id=owner></form>' +
'<button name=victim form=owner />' +
'<fieldset name=victim form=owner />' +
container.innerHTML = '<form id=owner></form>' +
'<form id=shouldNotBeOwner>' +
' <input id=inputElement name=victim form=owner />' +
+ ' <label id=labelElement name=victim form=owner />' +
'</form>';
owner = document.getElementById('owner');
var inputElement = document.getElementById('inputElement');
+var labelElement = document.getElementById('labelElement');
shouldBe('inputElement.form', 'owner');
+shouldBe('labelElement.form', 'owner');
+
debug('');
debug('- Ensures that the form attribute of all form-associated element with or witout form attribute points the form owner.');
' <input id=inputElement1 name=victim />' +
' <input id=inputElement2 name=victim form=owner />' +
' <input id=inputElement3 name=victim />' +
+ ' <label id=labelElement1 name=victim />' +
+ ' <label id=labelElement2 name=victim form=owner />' +
+ ' <label id=labelElement3 name=victim />' +
'</form>';
owner = document.getElementById('owner');
var inputElement1 = document.getElementById('inputElement1');
var inputElement2 = document.getElementById('inputElement2');
var inputElement3 = document.getElementById('inputElement3');
+var labelElement1 = document.getElementById('labelElement1');
+var labelElement2 = document.getElementById('labelElement2');
+var labelElement3 = document.getElementById('labelElement3');
shouldBe('inputElement1.form', 'owner');
shouldBe('inputElement2.form', 'owner');
shouldBe('inputElement3.form', 'owner');
+shouldBe('labelElement1.form', 'owner');
+shouldBe('labelElement2.form', 'owner');
+shouldBe('labelElement3.form', 'owner');
debug('');
debug('- Ensures that the form attribute points the form owner even if the form element is nested another form element.');
' <input id=inputElement1 name=victim form=owner />' +
' <input id=inputElement2 name=victim />' +
' <input id=inputElement3 name=victim form=owner />' +
+ ' <label id=labelElement1 name=victim form=owner />' +
+ ' <label id=labelElement2 name=victim />' +
+ ' <label id=labelElement3 name=victim form=owner />' +
' </form>' +
'</form>';
owner = document.getElementById('owner');
inputElement1 = document.getElementById('inputElement1');
inputElement2 = document.getElementById('inputElement2');
inputElement3 = document.getElementById('inputElement3');
+labelElement1 = document.getElementById('labelElement1');
+labelElement2 = document.getElementById('labelElement2');
+labelElement3 = document.getElementById('labelElement3');
shouldBe('inputElement1.form', 'owner');
shouldBe('inputElement2.form', 'owner');
shouldBe('inputElement3.form', 'owner');
+shouldBe('labelElement1.form', 'owner');
+shouldBe('labelElement2.form', 'owner');
+shouldBe('labelElement3.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 />' +
+ '<label id=labelElement name=victim form=form1 />' +
'<object id=objectElement name=victim form=form1></object>';
var form1 = document.getElementById('form1');
var form2 = document.getElementById('form2');
inputElement.attributes['form'].value = 'form2';
shouldBe('inputElement.form', 'form2');
+// HTMLabelElement has its own implementation of formAttr processing and so needs its own test.
+labelElement = document.getElementById('labelElement');
+shouldBe('labelElement.form', 'form1');
+labelElement.attributes['form'].value = 'form2';
+shouldBe('labelElement.form', 'form2');
+
// HTMLObjectElement has its own implementation of formAttr processing and so needs its own test.
objectElement = document.getElementById('objectElement');
shouldBe('objectElement.form', 'form1');
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 />' +
+ '<label id=labelElement name=victim />' +
'<object id=objectElement name=victim></object>';
owner = document.getElementById('owner');
inputElement = document.getElementById('inputElement');
inputElement.removeAttribute('form');
shouldBe('inputElement.form', 'null');
+// HTMLLabelElement has its own implementation of formAttr processing and so needs its own test.
+labelElement = document.getElementById('labelElement');
+shouldBe('labelElement.form', 'null');
+labelElement.setAttribute('form', 'owner');
+shouldBe('labelElement.form', 'owner');
+labelElement.removeAttribute('form');
+shouldBe('labelElement.form', 'null');
+
// HTMLObjectElement has its own implementation of formAttr processing and so needs its own test.
objectElement = document.getElementById('objectElement');
shouldBe('objectElement.form', 'null');
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 />';
+ '<input id=inputElement name=victim form=owner />' +
+ '<label id=labelElement name=victim form=owner />';
owner = document.getElementById('owner');
shouldBeEqualToString('owner.name', 'firstOwner');
inputElement = document.getElementById('inputElement');
+labelElement = document.getElementById('labelElement');
container.removeChild(owner);
owner = document.getElementById('owner');
shouldBeEqualToString('owner.name', 'secondOwner');
shouldBe('inputElement.form', 'owner');
+shouldBe('labelElement.form', 'owner');
container.removeChild(owner);
shouldBe('inputElement.form', 'null');
+shouldBe('labelElement.form', 'null');
container.appendChild(owner);
shouldBe('inputElement.form', 'owner');
+shouldBe('labelElement.form', 'owner');
</script>
<script src="../../fast/js/resources/js-test-post.js"></script>
</body>
+2012-03-16 Yoshifumi Inoue <yosin@chromium.org>
+
+ [Forms] label.form attribute doesn't work
+ https://bugs.webkit.org/show_bug.cgi?id=80499
+
+ Reviewed by Kent Tamura.
+
+ This patch changes implementation of label.form of IDL attribute to
+ compute it to the form element specified by the "form" HTML attribute
+ or form ancestor when the "form" HTML attribute isn't in HTML.
+
+ This patch introduces new function FormAssociatedElement::findAssociatedForm
+ for sharing code among FormAssociateElement::insertedIntoTree, resetFormOwner
+ and HTMLLabelElement::form.
+
+ No new tests. Update existing tests.
+
+ * html/FormAssociatedElement.cpp:
+ (WebCore::FormAssociatedElement::findAssociatedForm): Added.
+ (WebCore):
+ (WebCore::FormAssociatedElement::insertedIntoTree):
+ (WebCore::FormAssociatedElement::resetFormOwner):
+ * html/FormAssociatedElement.h:
+ (FormAssociatedElement):
+ * html/HTMLLabelElement.cpp: Remove unused include files
+ (WebCore::HTMLLabelElement::form): Added.
+
2012-03-16 Kenneth Rohde Christiansen <kenneth@webkit.org>
Use the normalize method of FloatPoint instead of normalizing manually
element->document()->unregisterFormElementWithFormAttribute(this);
}
+HTMLFormElement* FormAssociatedElement::findAssociatedForm(const HTMLElement* element, HTMLFormElement* currentAssociatedForm)
+{
+ const AtomicString& formId(element->fastGetAttribute(formAttr));
+ if (!formId.isNull() && element->inDocument()) {
+ // 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
+ // treeScope()->getElementById() over the given element.
+ HTMLFormElement* newForm = 0;
+ Element* newFormCandidate = element->treeScope()->getElementById(formId);
+ if (newFormCandidate && newFormCandidate->hasTagName(formTag))
+ newForm = static_cast<HTMLFormElement*>(newFormCandidate);
+ return newForm;
+ }
+
+ if (!currentAssociatedForm)
+ return element->findFormAncestor();
+
+ return currentAssociatedForm;
+}
+
void FormAssociatedElement::insertedIntoTree()
{
resetFormOwner();
void FormAssociatedElement::resetFormOwner()
{
- HTMLElement* element = toHTMLElement(this);
- const AtomicString& formId(element->fastGetAttribute(formAttr));
- if (m_form) {
- if (formId.isNull())
- return;
- }
- HTMLFormElement* newForm = 0;
- if (!formId.isNull() && element->inDocument()) {
- // 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
- // treeScope()->getElementById() over the given element.
- Element* firstElement = element->treeScope()->getElementById(formId);
- if (firstElement && firstElement->hasTagName(formTag))
- newForm = static_cast<HTMLFormElement*>(firstElement);
- } else
- newForm = element->findFormAncestor();
- setForm(newForm);
+ setForm(findAssociatedForm(toHTMLElement(this), m_form));
}
void FormAssociatedElement::formAttributeChanged()
void ref() { refFormAssociatedElement(); }
void deref() { derefFormAssociatedElement(); }
+ static HTMLFormElement* findAssociatedForm(const HTMLElement*, HTMLFormElement*);
HTMLFormElement* form() const { return m_form; }
ValidityState* validity();
#include "Document.h"
#include "Event.h"
#include "EventNames.h"
-#include "LabelableElement.h"
+#include "FormAssociatedElement.h"
#include "HTMLNames.h"
namespace WebCore {
return nodeAsLabelableElement(treeScope()->getElementById(controlId));
}
+HTMLFormElement* HTMLLabelElement::form() const
+{
+ return FormAssociatedElement::findAssociatedForm(this, 0);
+}
+
void HTMLLabelElement::setActive(bool down, bool pause)
{
if (down == active())
static PassRefPtr<HTMLLabelElement> create(const QualifiedName&, Document*);
LabelableElement* control();
+ HTMLFormElement* form() const;
private:
HTMLLabelElement(const QualifiedName&, Document*);