LayoutTests/ChangeLog

 12010-11-09 Dai Mikurube <dmikurube@google.com>
 2
 3 Reviewed by NOBODY (OOPS!).
 4
 5 Implement formaction, formenctype, formmethod and formtarget attributes for input and button tags
 6 https://bugs.webkit.org/show_bug.cgi?id=49240
 7
 8 * fast/forms/formaction-attribute-expected.txt: Added.
 9 * fast/forms/formaction-attribute.html: Added.
 10 * fast/forms/formmethod-attribute-button-expected.txt: Added.
 11 * fast/forms/formmethod-attribute-button.html: Added.
 12 * fast/forms/formmethod-attribute-input-expected.txt: Added.
 13 * fast/forms/formmethod-attribute-input.html: Added.
 14 * fast/forms/formtarget-attribute-button-expected.txt: Added.
 15 * fast/forms/formtarget-attribute-button.html: Added.
 16 * fast/forms/formtarget-attribute-input-expected.txt: Added.
 17 * fast/forms/formtarget-attribute-input.html: Added.
 18 * fast/forms/mailto/formenctype-attribute-button-expected.txt: Added.
 19 * fast/forms/mailto/formenctype-attribute-button.html: Added.
 20 * fast/forms/mailto/formenctype-attribute-input-expected.txt: Added.
 21 * fast/forms/mailto/formenctype-attribute-input.html: Added.
 22
1232010-11-10 Fumitoshi Ukai <ukai@chromium.org>
224
325 Unreviewed, updating Chromium expectations.

LayoutTests/fast/forms/formaction-attribute-expected.txt

 1Test for the formaction attribute in input and button tags.
 2
 3On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 4
 5
 6PASS The formaction attribute in the input tag was used
 7PASS The formaction attribute in the button tag was used
 8PASS successfullyParsed is true
 9
 10TEST COMPLETE
 11

LayoutTests/fast/forms/formaction-attribute.html

 1<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
 2<html>
 3<head>
 4<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
 5<script src="../../fast/js/resources/js-test-pre.js"></script>
 6</head>
 7<body>
 8<p id="description"></p>
 9<div id="console"></div>
 10<form action="javascript: test1(this)" method="get">
 11<select><option>A</option><option>B</option><option>C</option></select><input type="submit" formaction="javascript: test2(this)" /><button formaction="javascript: test3(this)" />
 12</form>
 13<script>
 14description("Test for the formaction attribute in input and button tags.");
 15var doneAction = false;
 16
 17function test1(ul)
 18{
 19 doneAction = true;
 20 testFailed('The formaction attribute in the input or button tag was ignored');
 21}
 22function test2(ul)
 23{
 24 doneAction = true;
 25 testPassed('The formaction attribute in the input tag was used');
 26}
 27function test3(ul)
 28{
 29 doneAction = true;
 30 testPassed('The formaction attribute in the button tag was used');
 31}
 32
 33var select = document.getElementsByTagName('select')[0];
 34select.options[2].selected = true;
 35
 36doneAction = false;
 37var input = document.getElementsByTagName('input')[0];
 38input.click();
 39if (!doneAction)
 40 testFailed('Both action and formaction attributes were ignored');
 41
 42doneAction = false;
 43var button = document.getElementsByTagName('button')[0];
 44button.click();
 45if (!doneAction)
 46 testFailed('Both action and formaction attributes were ignored');
 47
 48var successfullyParsed = true;
 49</script>
 50<script src="../../fast/js/resources/js-test-post.js"></script>
 51</body>
 52</html>

LayoutTests/fast/forms/formmethod-attribute-button-expected.txt

 1Test for the formmethod attribute in button tags.
 2
 3On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 4
 5
 6PASS The formmethod attribute was successfully used
 7PASS successfullyParsed is true
 8
 9TEST COMPLETE
 10

LayoutTests/fast/forms/formmethod-attribute-button.html

 1<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
 2<html>
 3<head>
 4<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
 5<script src="../../fast/js/resources/js-test-pre.js"></script>
 6</head>
 7<body>
 8<p id="description"></p>
 9<div id="console"></div>
 10<form method="get" action="?" name=f>
 11 <input type="hidden" name="hidden" value="I am hidden">
 12 <button formmethod="post" type="submit" value="press me" name=g>
 13</form>
 14<script>
 15description("Test for the formmethod attribute in button tags.");
 16if (window.layoutTestController) {
 17 layoutTestController.waitUntilDone();
 18}
 19
 20if (document.URL.substring(0, 4) == "file") {
 21 if (document.URL.indexOf('?') == -1) {
 22 document.f.g.click();
 23 } else {
 24 if (document.URL.substring(document.URL.indexOf('?') + 1, document.URL.length) == "")
 25 testPassed('The formmethod attribute was successfully used');
 26 else
 27 testFailed('The formmethod attribute was not used');
 28
 29 if (window.layoutTestController)
 30 layoutTestController.notifyDone();
 31 }
 32}
 33var successfullyParsed = true;
 34</script>
 35<script src="../../fast/js/resources/js-test-post.js"></script>
 36</body>
 37</html>

LayoutTests/fast/forms/formmethod-attribute-input-expected.txt

 1Test for the formmethod attribute in input tags.
 2
 3On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 4
 5
 6PASS The formmethod attribute was successfully used
 7PASS successfullyParsed is true
 8
 9TEST COMPLETE
 10

LayoutTests/fast/forms/formmethod-attribute-input.html

 1<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
 2<html>
 3<head>
 4<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
 5<script src="../../fast/js/resources/js-test-pre.js"></script>
 6</head>
 7<body>
 8<p id="description"></p>
 9<div id="console"></div>
 10<form method="get" action="?" name=f>
 11 <input type="hidden" name="hidden" value="I am hidden">
 12 <input formmethod="post" type="submit" value="press me" name=g>
 13</form>
 14<script>
 15description("Test for the formmethod attribute in input tags.");
 16if (window.layoutTestController) {
 17 layoutTestController.waitUntilDone();
 18}
 19
 20if (document.URL.substring(0, 4) == "file") {
 21 if (document.URL.indexOf('?') == -1) {
 22 document.f.g.click();
 23 } else {
 24 if (document.URL.substring(document.URL.indexOf('?') + 1, document.URL.length) == "")
 25 testPassed('The formmethod attribute was successfully used');
 26 else
 27 testFailed('The formmethod attribute was not used');
 28
 29 if (window.layoutTestController)
 30 layoutTestController.notifyDone();
 31 }
 32}
 33var successfullyParsed = true;
 34</script>
 35<script src="../../fast/js/resources/js-test-post.js"></script>
 36</body>
 37</html>

LayoutTests/fast/forms/formtarget-attribute-button-expected.txt

 1Test for the formtarget attribute in a button tag.
 2
 3On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 4
 5
 6PASS The formtarget attribute was successfully used.
 7PASS successfullyParsed is true
 8
 9TEST COMPLETE
 10

LayoutTests/fast/forms/formtarget-attribute-button.html

 1<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
 2<html>
 3<head>
 4<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
 5<script src="../../fast/js/resources/js-test-pre.js"></script>
 6<script src="../../fast/js/resources/js-test-post-function.js"></script>
 7</head>
 8<body onload="runTest()">
 9<p id="description"></p>
 10<div id="console"></div>
 11<script>
 12description("Test for the formtarget attribute in a button tag.");
 13function runTest()
 14{
 15 if (window.layoutTestController) {
 16 layoutTestController.setAllowUniversalAccessFromFileURLs(true);
 17 layoutTestController.waitUntilDone();
 18 }
 19
 20 // Not dumping as text since the DumpRenderTree does not dump the text content of child frames.
 21 var button = document.getElementById('loadButton');
 22 button.click();
 23}
 24
 25function passingFrameLoaded()
 26{
 27 if (document.getElementById('passing').contentDocument.URL == "about:blank")
 28 return;
 29 testPassed("The formtarget attribute was successfully used.");
 30 isSuccessfullyParsed();
 31 if (window.layoutTestController)
 32 layoutTestController.notifyDone();
 33}
 34
 35function failingFrameLoaded()
 36{
 37 if (document.getElementById('failing').contentDocument.URL == "about:blank")
 38 return;
 39 testFailed("The formtarget attribute was not used.");
 40 isSuccessfullyParsed();
 41 if (window.layoutTestController)
 42 layoutTestController.notifyDone();
 43}
 44var successfullyParsed = true;
 45</script>
 46<form action="resources/success.txt" method="GET" target="failingFrame">
 47<button type="submit" value="form" id="loadButton" formtarget="passingFrame">
 48</form>
 49<iframe src="about:blank" id="passing" name="passingFrame" onload="passingFrameLoaded()"></iframe>
 50<iframe src="about:blank" id="failing" name="failingFrame" onload="failingFrameLoaded()"></iframe>
 51</body>
 52</html>

LayoutTests/fast/forms/formtarget-attribute-input-expected.txt

 1Test for the formtarget attribute in an input tag.
 2
 3On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 4
 5
 6PASS The formtarget attribute was successfully used.
 7PASS successfullyParsed is true
 8
 9TEST COMPLETE
 10
 11

LayoutTests/fast/forms/formtarget-attribute-input.html

 1<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
 2<html>
 3<head>
 4<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
 5<script src="../../fast/js/resources/js-test-pre.js"></script>
 6<script src="../../fast/js/resources/js-test-post-function.js"></script>
 7</head>
 8<body onload="runTest()">
 9<p id="description"></p>
 10<div id="console"></div>
 11<script>
 12description("Test for the formtarget attribute in an input tag.");
 13function runTest()
 14{
 15 if (window.layoutTestController) {
 16 layoutTestController.setAllowUniversalAccessFromFileURLs(true);
 17 layoutTestController.waitUntilDone();
 18 }
 19
 20 // Not dumping as text since the DumpRenderTree does not dump the text content of child frames.
 21 var button = document.getElementById('loadButton');
 22 button.click();
 23}
 24
 25function passingFrameLoaded()
 26{
 27 if (document.getElementById('passing').contentDocument.URL == "about:blank")
 28 return;
 29 testPassed("The formtarget attribute was successfully used.");
 30 isSuccessfullyParsed();
 31 if (window.layoutTestController)
 32 layoutTestController.notifyDone();
 33}
 34
 35function failingFrameLoaded()
 36{
 37 if (document.getElementById('failing').contentDocument.URL == "about:blank")
 38 return;
 39 testFailed("The formtarget attribute was not used.");
 40 isSuccessfullyParsed();
 41 if (window.layoutTestController)
 42 layoutTestController.notifyDone();
 43}
 44var successfullyParsed = true;
 45</script>
 46<form action="resources/success.txt" method="GET" target="failingFrame">
 47<input type="submit" value="form" id="loadButton" formtarget="passingFrame">
 48</form>
 49<iframe src="about:blank" id="passing" name="passingFrame" onload="passingFrameLoaded()"></iframe>
 50<iframe src="about:blank" id="failing" name="failingFrame" onload="failingFrameLoaded()"></iframe>
 51</body>
 52</html>

LayoutTests/fast/forms/mailto/formenctype-attribute-button-expected.txt

 1Policy delegate: attempt to load mailto:?body=to%3Done%40example.org%0D%0Abody%3DLine%201%0D%0ALine%202%0D%0A%40%26%3D%2C%3B%3F%22%2B%0D%0A with navigation type 'form submitted' originating from HTML > #document
 2Field 1: Field 2:

LayoutTests/fast/forms/mailto/formenctype-attribute-button.html

 1<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
 2<html>
 3<head>
 4</head>
 5<body onload="test()">
 6<p id="description"></p>
 7<div id="console"></div>
 8<form method="post" action="mailto:">
 9Field 1: <input type="text" size="10" maxlength="40" name="to" value="one@example.org">
 10Field 2: <textarea name="body">Line 1
 11Line 2
 12@&amp;=,;?"+</textarea>
 13<button type="submit" value="Send" id="submit" formenctype="text/plain">
 14</form>
 15<script>
 16function test()
 17{
 18 if (window.layoutTestController) {
 19 layoutTestController.dumpAsText();
 20 layoutTestController.waitForPolicyDelegate();
 21 }
 22 document.getElementById("submit").click();
 23}
 24</script>
 25</body>
 26</html>

LayoutTests/fast/forms/mailto/formenctype-attribute-input-expected.txt

 1Policy delegate: attempt to load mailto:?body=to%3Done%40example.org%0D%0Abody%3DLine%201%0D%0ALine%202%0D%0A%40%26%3D%2C%3B%3F%22%2B%0D%0A with navigation type 'form submitted' originating from HTML > #document
 2Field 1: Field 2:

LayoutTests/fast/forms/mailto/formenctype-attribute-input.html

 1<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
 2<html>
 3<head>
 4</head>
 5<body onload="test()">
 6<p id="description"></p>
 7<div id="console"></div>
 8<form method="post" action="mailto:">
 9Field 1: <input type="text" size="10" maxlength="40" name="to" value="one@example.org">
 10Field 2: <textarea name="body">Line 1
 11Line 2
 12@&amp;=,;?"+</textarea>
 13<input type="submit" value="Send" id="submit" formenctype="text/plain">
 14</form>
 15<script>
 16function test()
 17{
 18 if (window.layoutTestController) {
 19 layoutTestController.dumpAsText();
 20 layoutTestController.waitForPolicyDelegate();
 21 }
 22 document.getElementById("submit").click();
 23}
 24</script>
 25</body>
 26</html>

WebCore/ChangeLog

 12010-11-09 Dai Mikurube <dmikurube@google.com>
 2
 3 Reviewed by NOBODY (OOPS!).
 4
 5 Implement formaction, formenctype, formmethod and formtarget attributes for input and button tags
 6 https://bugs.webkit.org/show_bug.cgi?id=49240
 7
 8 Tests: fast/forms/formaction-attribute.html
 9 fast/forms/formmethod-attribute-button.html
 10 fast/forms/formmethod-attribute-input.html
 11 fast/forms/formtarget-attribute-button.html
 12 fast/forms/formtarget-attribute-input.html
 13 fast/forms/mailto/formenctype-attribute-button.html
 14 fast/forms/mailto/formenctype-attribute-input.html
 15
 16 * html/HTMLAttributeNames.in: Added formaction, formmethod, formtarget and formenctype attributes
 17 * html/HTMLFormControlElement.cpp:
 18 (WebCore::HTMLFormControlElement::formEnctype):
 19 (WebCore::HTMLFormControlElement::setFormEnctype):
 20 * html/HTMLFormControlElement.h:
 21 * html/HTMLFormElement.cpp: Modified to check the pressed button and its attributes
 22 (WebCore::HTMLFormElement::submit):
 23 * html/HTMLInputElement.idl:
 24 * loader/FormSubmission.cpp:
 25 (WebCore::FormSubmission::Attributes::copyFrom):
 26 * loader/FormSubmission.h:
 27
1282010-11-10 Dan Bernstein <mitz@apple.com>
229
330 Style fix I said I’d make then forgot to make.

WebCore/html/HTMLAttributeNames.in

@@expanded
9494face
9595focused
9696for
 97formaction
 98formenctype
 99formmethod
97100formnovalidate
 101formtarget
98102frame
99103frameborder
100104headers

WebCore/html/HTMLFormControlElement.cpp

@@void HTMLFormControlElement::detach()
8484 HTMLElement::detach();
8585}
8686
 87String HTMLFormControlElement::formEnctype() const
 88{
 89 return getAttribute(formenctypeAttr);
 90}
 91
 92void HTMLFormControlElement::setFormEnctype(const String &value)
 93{
 94 setAttribute(formenctypeAttr, value);
 95}
 96
8797bool HTMLFormControlElement::formNoValidate() const
8898{
8999 return !getAttribute(formnovalidateAttr).isNull();

WebCore/html/HTMLFormControlElement.h

@@public:
4444 HTMLFormElement* form() const { return m_form; }
4545 ValidityState* validity();
4646
 47 String formEnctype() const;
 48 void setFormEnctype(const String&);
4749 bool formNoValidate() const;
4850
4951 virtual void reset() { }

WebCore/html/HTMLInputElement.idl

@@module html {
2424 attribute [ConvertNullToNullString] DOMString defaultValue;
2525 attribute [Reflect=checked] boolean defaultChecked;
2626 readonly attribute HTMLFormElement form;
 27 attribute [Reflect, URL] DOMString formAction;
 28 attribute [ConvertNullToNullString] DOMString formEnctype;
 29 attribute [Reflect] DOMString formMethod;
2730 attribute [Reflect] boolean formNoValidate;
 31 attribute [Reflect] DOMString formTarget;
2832 readonly attribute ValidityState validity;
2933 attribute [Reflect] DOMString accept;
3034 attribute [Reflect] DOMString accessKey;

WebCore/loader/FormSubmission.cpp

@@void FormSubmission::Attributes::parseMethodType(const String& type)
110110 m_method = FormSubmission::GetMethod;
111111}
112112
 113void FormSubmission::Attributes::copyFrom(const Attributes& other)
 114{
 115 m_method = other.m_method;
 116 m_action = other.m_action;
 117 m_target = other.m_target;
 118 m_encodingType = other.m_encodingType;
 119 m_acceptCharset = other.m_acceptCharset;
 120}
 121
113122inline FormSubmission::FormSubmission(Method method, const KURL& action, const String& target, const String& contentType, PassRefPtr<FormState> state, PassRefPtr<FormData> data, const String& boundary, bool lockHistory, PassRefPtr<Event> event)
114123 : m_method(method)
115124 , m_action(action)

@@inline FormSubmission::FormSubmission(Method method, const KURL& action, const S
126135PassRefPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const Attributes& attributes, PassRefPtr<Event> event, bool lockHistory, FormSubmissionTrigger trigger)
127136{
128137 ASSERT(form);
 138
 139 HTMLFormControlElement* submitButton = 0;
 140 if (event && event->target() && event->target()->toNode())
 141 submitButton = static_cast<HTMLFormControlElement*>(event->target()->toNode());
 142
 143 FormSubmission::Attributes copiedAttributes;
 144 copiedAttributes.copyFrom(attributes);
 145 if (submitButton) {
 146 String attributeValue;
 147 if (!(attributeValue = submitButton->getAttribute(formactionAttr)).isNull())
 148 copiedAttributes.parseAction(attributeValue);
 149 if (!(attributeValue = submitButton->getAttribute(formenctypeAttr)).isNull())
 150 copiedAttributes.parseEncodingType(attributeValue);
 151 if (!(attributeValue = submitButton->getAttribute(formmethodAttr)).isNull())
 152 copiedAttributes.parseMethodType(attributeValue);
 153 if (!(attributeValue = submitButton->getAttribute(formtargetAttr)).isNull())
 154 copiedAttributes.setTarget(attributeValue);
 155 }
 156
129157 Document* document = form->document();
130  KURL actionURL = document->completeURL(attributes.action().isEmpty() ? document->url().string() : attributes.action());
 158 KURL actionURL = document->completeURL(copiedAttributes.action().isEmpty() ? document->url().string() : copiedAttributes.action());
131159 bool isMailtoForm = actionURL.protocolIs("mailto");
132160 bool isMultiPartForm = false;
133  String encodingType = attributes.encodingType();
 161 String encodingType = copiedAttributes.encodingType();
134162
135  if (attributes.method() == PostMethod) {
136  isMultiPartForm = attributes.isMultiPartForm();
 163 if (copiedAttributes.method() == PostMethod) {
 164 isMultiPartForm = copiedAttributes.isMultiPartForm();
137165 if (isMultiPartForm && isMailtoForm) {
138166 encodingType = "application/x-www-form-urlencoded";
139167 isMultiPartForm = false;
140168 }
141169 }
142170
143  TextEncoding dataEncoding = isMailtoForm ? UTF8Encoding() : FormDataBuilder::encodingFromAcceptCharset(attributes.acceptCharset(), document);
 171 TextEncoding dataEncoding = isMailtoForm ? UTF8Encoding() : FormDataBuilder::encodingFromAcceptCharset(copiedAttributes.acceptCharset(), document);
144172 RefPtr<DOMFormData> domFormData = DOMFormData::create(dataEncoding.encodingForFormSubmission());
145173 Vector<pair<String, String> > formValues;
146174

@@PassRefPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const A
166194 boundary = formData->boundary().data();
167195 } else {
168196 formData = FormData::create(*(static_cast<FormDataList*>(domFormData.get())), domFormData->encoding());
169  if (attributes.method() == PostMethod && isMailtoForm) {
 197 if (copiedAttributes.method() == PostMethod && isMailtoForm) {
170198 // Convert the form data into a string that we put into the URL.
171199 appendMailtoPostFormDataToURL(actionURL, *formData, encodingType);
172200 formData = FormData::create();

@@PassRefPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const A
174202 }
175203
176204 formData->setIdentifier(generateFormDataIdentifier());
177  String targetOrBaseTarget = attributes.target().isEmpty() ? document->baseTarget() : attributes.target();
 205 String targetOrBaseTarget = copiedAttributes.target().isEmpty() ? document->baseTarget() : copiedAttributes.target();
178206 RefPtr<FormState> formState = FormState::create(form, formValues, document->frame(), trigger);
179  return adoptRef(new FormSubmission(attributes.method(), actionURL, targetOrBaseTarget, encodingType, formState.release(), formData.release(), boundary, lockHistory, event));
 207 return adoptRef(new FormSubmission(copiedAttributes.method(), actionURL, targetOrBaseTarget, encodingType, formState.release(), formData.release(), boundary, lockHistory, event));
180208}
181209
182210KURL FormSubmission::requestURL() const

WebCore/loader/FormSubmission.h

@@public:
7272 const String& acceptCharset() const { return m_acceptCharset; }
7373 void setAcceptCharset(const String& value) { m_acceptCharset = value; }
7474
 75 void copyFrom(const Attributes&);
 76
7577 private:
7678 Method m_method;
7779 bool m_isMultiPartForm;