Form-associated custom elements: Fix missing validation bubble

- Override validationMessage() and ValidationSubMessage() to return
  correct strings

- ValidationMessaeClientImpl doesn't reject display:inline anchor
  elements.

Bug: 905922
Bug: https://github.com/w3c/webcomponents/issues/187
Change-Id: Ie743d6018bb38f30db0b8624a6313519dd5737f4
Reviewed-on: https://chromium-review.googlesource.com/c/1365108
Commit-Queue: Kent Tamura <tkent@chromium.org>
Reviewed-by: Keishi Hattori <keishi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#614334}
diff --git a/third_party/blink/renderer/core/html/custom/element_internals.cc b/third_party/blink/renderer/core/html/custom/element_internals.cc
index ff75c8f..f20c50b7 100644
--- a/third_party/blink/renderer/core/html/custom/element_internals.cc
+++ b/third_party/blink/renderer/core/html/custom/element_internals.cc
@@ -16,6 +16,19 @@
 
 namespace blink {
 
+namespace {
+bool IsValidityStateFlagsValid(const ValidityStateFlags* flags) {
+  if (!flags)
+    return true;
+  if (flags->badInput() || flags->customError() || flags->patternMismatch() ||
+      flags->rangeOverflow() || flags->rangeUnderflow() ||
+      flags->stepMismatch() || flags->tooLong() || flags->tooShort() ||
+      flags->typeMismatch() || flags->valueMissing())
+    return false;
+  return true;
+}
+}  // anonymous namespace
+
 ElementInternals::ElementInternals(HTMLElement& target) : target_(target) {
   value_.SetUSVString(String());
 }
@@ -78,11 +91,7 @@
   }
   // Custom element authors should provide a message. They can omit the message
   // argument only if nothing if | flags| is true.
-  if ((flags->badInput() || flags->customError() || flags->patternMismatch() ||
-       flags->rangeOverflow() || flags->rangeUnderflow() ||
-       flags->stepMismatch() || flags->tooLong() || flags->tooShort() ||
-       flags->typeMismatch() || flags->valueMissing()) &&
-      message.IsEmpty()) {
+  if (!IsValidityStateFlagsValid(flags) && message.IsEmpty()) {
     exception_state.ThrowDOMException(
         DOMExceptionCode::kTypeMismatchError,
         "The second argument should not be empty if one or more flags in the "
@@ -122,11 +131,21 @@
         "The target element is not a form-associated custom element.");
     return String();
   }
-  if (ListedElement::validity()->valid())
+  return validationMessage();
+}
+
+String ElementInternals::validationMessage() const {
+  if (IsValidityStateFlagsValid(validity_flags_))
     return String();
   return CustomValidationMessage();
 }
 
+String ElementInternals::ValidationSubMessage() const {
+  if (PatternMismatch())
+    return Target().FastGetAttribute(html_names::kTitleAttr).GetString();
+  return String();
+}
+
 bool ElementInternals::checkValidity(ExceptionState& exception_state) {
   if (!IsTargetFormAssociated()) {
     exception_state.ThrowDOMException(
diff --git a/third_party/blink/renderer/core/html/custom/element_internals.h b/third_party/blink/renderer/core/html/custom/element_internals.h
index 7eb3572..77d233b 100644
--- a/third_party/blink/renderer/core/html/custom/element_internals.h
+++ b/third_party/blink/renderer/core/html/custom/element_internals.h
@@ -64,6 +64,8 @@
   bool TypeMismatch() const override;
   bool ValueMissing() const override;
   bool CustomError() const override;
+  String validationMessage() const override;
+  String ValidationSubMessage() const override;
   void DisabledStateMightBeChanged() override;
 
   Member<HTMLElement> target_;
diff --git a/third_party/blink/renderer/core/page/validation_message_client_impl.cc b/third_party/blink/renderer/core/page/validation_message_client_impl.cc
index 0bc6df7..f01feb3c 100644
--- a/third_party/blink/renderer/core/page/validation_message_client_impl.cc
+++ b/third_party/blink/renderer/core/page/validation_message_client_impl.cc
@@ -63,7 +63,7 @@
     HideValidationMessage(anchor);
     return;
   }
-  if (!anchor.GetLayoutBox())
+  if (!anchor.GetLayoutObject())
     return;
   if (current_anchor_)
     HideValidationMessageImmediately(*current_anchor_);
diff --git a/third_party/blink/web_tests/custom-elements/form-validation-bubble-appearance-expected.txt b/third_party/blink/web_tests/custom-elements/form-validation-bubble-appearance-expected.txt
new file mode 100644
index 0000000..d79b8697
--- /dev/null
+++ b/third_party/blink/web_tests/custom-elements/form-validation-bubble-appearance-expected.txt
@@ -0,0 +1,3 @@
+Check if a validation bubble is shown
+
+🆖
diff --git a/third_party/blink/web_tests/custom-elements/form-validation-bubble-appearance.html b/third_party/blink/web_tests/custom-elements/form-validation-bubble-appearance.html
new file mode 100644
index 0000000..0a30a1e
--- /dev/null
+++ b/third_party/blink/web_tests/custom-elements/form-validation-bubble-appearance.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<body>
+<p>Check if a validation bubble is shown</p>
+<script>
+class MyControl extends HTMLElement {
+  static get formAssociated() { return true; }
+
+  constructor() {
+    super();
+    this.internals_ = this.attachInternals();
+  }
+  get i() { return this.internals_; }
+
+  // Must provide ‘value’ setter.
+  set value(v) {}
+}
+
+customElements.define('my-control', MyControl);
+</script>
+<my-control title="Please specify four digits." tabindex=0>&#x1f196;</my-control>
+<script>
+if (window.testRunner) {
+  // Layout tree dump doesn't matter.
+  testRunner.dumpAsTextWithPixelResults();
+}
+const myControl = document.querySelector('my-control');
+myControl.i.setValidity({patternMismatch:true}, 'The value does not match to the requested format');
+myControl.i.reportValidity();
+</script>
+<body>
diff --git a/third_party/blink/web_tests/platform/linux/custom-elements/form-validation-bubble-appearance-expected.png b/third_party/blink/web_tests/platform/linux/custom-elements/form-validation-bubble-appearance-expected.png
new file mode 100644
index 0000000..6d6b8882
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/custom-elements/form-validation-bubble-appearance-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/custom-elements/form-validation-bubble-appearance-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/custom-elements/form-validation-bubble-appearance-expected.png
new file mode 100644
index 0000000..d86617d
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.10/custom-elements/form-validation-bubble-appearance-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/custom-elements/form-validation-bubble-appearance-expected.png b/third_party/blink/web_tests/platform/mac-mac10.11/custom-elements/form-validation-bubble-appearance-expected.png
new file mode 100644
index 0000000..94cc585
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.11/custom-elements/form-validation-bubble-appearance-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/custom-elements/form-validation-bubble-appearance-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/custom-elements/form-validation-bubble-appearance-expected.png
new file mode 100644
index 0000000..75eb01d
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.12/custom-elements/form-validation-bubble-appearance-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/custom-elements/form-validation-bubble-appearance-expected.png b/third_party/blink/web_tests/platform/mac/custom-elements/form-validation-bubble-appearance-expected.png
new file mode 100644
index 0000000..d3abce0
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/custom-elements/form-validation-bubble-appearance-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/custom-elements/form-validation-bubble-appearance-expected.png b/third_party/blink/web_tests/platform/win/custom-elements/form-validation-bubble-appearance-expected.png
new file mode 100644
index 0000000..a97540f
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/custom-elements/form-validation-bubble-appearance-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/custom-elements/form-validation-bubble-appearance-expected.png b/third_party/blink/web_tests/platform/win7/custom-elements/form-validation-bubble-appearance-expected.png
new file mode 100644
index 0000000..1f00461
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win7/custom-elements/form-validation-bubble-appearance-expected.png
Binary files differ