Fixed the behaviour of form submit to match the standard: no submit is taken place when the form is detached from the document (e.g., form is removed).

One additional layout test (form-removed-from-document.html) is added to verify the change made above.

Two layout tests has been modified to match the behaviour of submitting form (when from is detached from/attached to the document) in Firefox.

BUG=586749

Review-Url: https://codereview.chromium.org/2416033002
Cr-Commit-Position: refs/heads/master@{#425734}
diff --git a/third_party/WebKit/LayoutTests/fast/forms/form-submission-crash-successful-submit-button.html b/third_party/WebKit/LayoutTests/fast/forms/form-submission-crash-successful-submit-button.html
index d44e8cb..97d665d 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/form-submission-crash-successful-submit-button.html
+++ b/third_party/WebKit/LayoutTests/fast/forms/form-submission-crash-successful-submit-button.html
@@ -16,6 +16,7 @@
     form1.action = 'javascript:removeImage()';
     form1.appendChild(submit1);
     form1.appendChild(submit2);
+    document.body.appendChild(form1);
     submit1.click();
     testPassed('if not crashed.');
     finishJSTest();
diff --git a/third_party/WebKit/LayoutTests/fast/forms/form-submission-crash.html b/third_party/WebKit/LayoutTests/fast/forms/form-submission-crash.html
index b8b42b3..b361f67 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/form-submission-crash.html
+++ b/third_party/WebKit/LayoutTests/fast/forms/form-submission-crash.html
@@ -13,6 +13,7 @@
     form1.addEventListener('submit', handleSubmit, false);
     form1.action = 'javascript:gc()';
     form1.appendChild(submit1);
+    document.body.appendChild(form1);
     submit1.click();
     testPassed('if not crashed.');
     finishJSTest();
diff --git a/third_party/WebKit/LayoutTests/fast/forms/submit-form-not-attached-to-document.html b/third_party/WebKit/LayoutTests/fast/forms/submit-form-not-attached-to-document.html
new file mode 100644
index 0000000..08353c8e8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/forms/submit-form-not-attached-to-document.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<body>
+  <form action="javascript: redirect()"></form>
+<script>
+var f1 = document.forms[0];
+test(function() {
+  f1.parentNode.removeChild(f1);
+  f1.submit();
+}, 'Submitting a form that has been removed.');
+
+var f2 = document.createElement('form');
+f2.action = "javascript: redirect()";
+test(function() {
+  f2.submit();
+}, 'Submitting a form that has never been attached to the document.');
+
+document.body.appendChild(f2);
+var f3 = f2.cloneNode(true);
+f2.action = "javascript: submit_success()";
+f3.action = "javascript: redirect()";
+test(function() {
+  f2.submit();
+}, 'Submitting a form that is attached to the document.');
+
+test(function() {
+  f3.submit();
+}, 'Submitting a form cloned from a form that is attached to the document.');
+
+function redirect() {
+  assert_unreached('A form should never be submitted if it is not attached to the document.');
+}
+
+function submit_success() {
+  assert_true(true, 'A form that is attached to the document should be submitted.');
+}
+
+</script>
+</body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cookies/same-site/popup-cross-site-post.html b/third_party/WebKit/LayoutTests/http/tests/cookies/same-site/popup-cross-site-post.html
index ec32a89..44be2fbe 100644
--- a/third_party/WebKit/LayoutTests/http/tests/cookies/same-site/popup-cross-site-post.html
+++ b/third_party/WebKit/LayoutTests/http/tests/cookies/same-site/popup-cross-site-post.html
@@ -2,6 +2,7 @@
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/cookies/resources/testharness-helpers.js"></script>
+<body>
 <script>
 // Set cookies on ORIGINAL_HOST, then move ourselves to TEST_ROOT so
 // we can verify cross-origin behavior.
@@ -29,6 +30,8 @@
         f.method = "POST";
         f.target = "_blank"
         window.onload = t.step_func(f.submit.bind(f));
+        document.body.appendChild(f);
     }, "'" + ORIGINAL_HOST + "' is not same-site with '" + TEST_HOST + "', so samesite cookies are not sent via POST.");
 }
 </script>
+</body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cookies/same-site/popup-same-site-post.html b/third_party/WebKit/LayoutTests/http/tests/cookies/same-site/popup-same-site-post.html
index eee74be..dc68018 100644
--- a/third_party/WebKit/LayoutTests/http/tests/cookies/same-site/popup-same-site-post.html
+++ b/third_party/WebKit/LayoutTests/http/tests/cookies/same-site/popup-same-site-post.html
@@ -2,6 +2,7 @@
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/cookies/resources/testharness-helpers.js"></script>
+<body>
 <script>
 if (window.location.hostname == "127.0.0.1") {
     window.location.hostname = ORIGINAL_HOST;
@@ -25,6 +26,8 @@
         f.method = "POST";
         f.target = "_blank";
         window.onload = t.step_func(f.submit.bind(f));
+        document.body.appendChild(f);
     }, "'" + ORIGINAL_HOST + "' is same-site with itself, so samesite cookies are sent.");
 }
 </script>
+</body>
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h
index 8ce4de0..351a1b3 100644
--- a/third_party/WebKit/Source/core/frame/UseCounter.h
+++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -1119,7 +1119,6 @@
     V8RegExpPrototypeSourceGetter = 1396,
     V8RegExpPrototypeOldFlagGetter = 1397,
     V8DecimalWithLeadingZeroInStrictMode = 1398,
-    FormSubmissionNotInDocumentTree = 1399,
     GetUserMediaPrefixed = 1400,
     GetUserMediaLegacy = 1401,
     GetUserMediaPromise = 1402,
diff --git a/third_party/WebKit/Source/core/html/HTMLFormElement.cpp b/third_party/WebKit/Source/core/html/HTMLFormElement.cpp
index dd75c5d..aaf9d65 100644
--- a/third_party/WebKit/Source/core/html/HTMLFormElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLFormElement.cpp
@@ -347,9 +347,16 @@
   if (!view || !frame || !frame->page())
     return;
 
-  // See crbug.com/586749.
-  if (!isConnected())
-    UseCounter::count(document(), UseCounter::FormSubmissionNotInDocumentTree);
+  // https://html.spec.whatwg.org/multipage/forms.html#form-submission-algorithm
+  // 2. If form document is not connected, has no associated browsing context,
+  // or its active sandboxing flag set has its sandboxed forms browsing
+  // context flag set, then abort these steps without doing anything.
+  if (!isConnected()) {
+    document().addConsoleMessage(ConsoleMessage::create(
+        JSMessageSource, WarningMessageLevel,
+        "Form submission canceled because the form is not connected"));
+    return;
+  }
 
   if (m_isSubmitting)
     return;
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 24ce1c18..9abd4ea 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -83804,7 +83804,7 @@
   <int value="1396" label="V8RegExpPrototypeSourceGetter"/>
   <int value="1397" label="V8RegExpPrototypeOldFlagGetter"/>
   <int value="1398" label="V8DecimalWithLeadingZeroInStrictMode"/>
-  <int value="1399" label="FormSubmissionNotInDocumentTree"/>
+  <int value="1399" label="OBSOLETE_FormSubmissionNotInDocumentTree"/>
   <int value="1400" label="GetUserMediaPrefixed"/>
   <int value="1401" label="GetUserMediaLegacy"/>
   <int value="1402" label="GetUserMediaPromise"/>