<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[208361] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/208361">208361</a></dd>
<dt>Author</dt> <dd>cdumez@apple.com</dd>
<dt>Date</dt> <dd>2016-11-03 18:38:31 -0700 (Thu, 03 Nov 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[WK2][Cocoa] Implement user interface for HTML form validation
https://bugs.webkit.org/show_bug.cgi?id=164143
&lt;rdar://problem/28944652&gt;

Reviewed by Simon Fraser.

Source/WebCore:

Add ValidationBubble class to show HTML form validation messages
using native dialogs. It currently has an implementation for both
Mac and iOS. It is in WebCore under platform/ so that it can be
used by both WebKit1 and WebKit2.

Update ownership of ValidationMessageClient so that is is owned
by the Page using a unique_ptr&lt;&gt;, which seems to be the modern
way of handling lifetime for page clients.

Test: fast/forms/validation-messages.html

* WebCore.xcodeproj/project.pbxproj:
* html/HTMLFormControlElement.cpp:
(WebCore::HTMLFormControlElement::focusAndShowValidationMessage):
* html/ValidationMessage.cpp:
(WebCore::ValidationMessage::updateValidationMessage):
* page/Page.cpp:
(WebCore::Page::Page):
(WebCore::Page::~Page):
* page/Page.h:
(WebCore::Page::validationMessageClient):
* page/PageConfiguration.cpp:
* page/PageConfiguration.h:
* platform/ValidationBubble.h: Copied from Tools/DumpRenderTree/mac/UIScriptControllerMac.mm.
(WebCore::ValidationBubble::message):
* platform/ios/ValidationBubbleIOS.mm: Added.
(-[WebValidationBubbleDelegate adaptivePresentationStyleForPresentationController:traitCollection:]):
(WebCore::ValidationBubble::ValidationBubble):
(WebCore::ValidationBubble::~ValidationBubble):
(WebCore::ValidationBubble::show):
(WebCore::ValidationBubble::setAnchorRect):
* platform/mac/ValidationBubbleMac.mm: Added.
(WebCore::ValidationBubble::ValidationBubble):
(WebCore::ValidationBubble::~ValidationBubble):
(WebCore::ValidationBubble::showRelativeTo):

Source/WebKit2:

Implement the ValidationMessageClient in WebKit2 and have it display
a ValidationBubble on Cocoa. ValidationBubble is implemented using
native popovers on both Mac and iOS. As a result, Mac and iOS WK2
now use native popover for HTML form validation instead of the old
Shadow DOM based UI in WebCore.

The native popover shows at the bottom (or top) of the input and it
disapears as soon as the user starts typing or interacts with the
view (e.g. tap / scroll / zoom).

The feature is still disabled at runtime.

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _initializeWithConfiguration:]):
(-[WKWebView _keyboardWillShow:]):
(-[WKWebView _keyboardDidShow:]):
(-[WKWebView _contentsOfUserInterfaceItem:]):
* UIProcess/API/Cocoa/WKWebViewPrivate.h:
* UIProcess/Cocoa/WebPageProxyCocoa.mm:
* UIProcess/PageClient.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::handleWheelEvent):
(WebKit::WebPageProxy::setPageZoomFactor):
(WebKit::WebPageProxy::setPageAndTextZoomFactors):
(WebKit::WebPageProxy::pageDidScroll):
(WebKit::WebPageProxy::resetState):
(WebKit::WebPageProxy::hideValidationMessage):
* UIProcess/WebPageProxy.h:
(WebKit::WebPageProxy::validationBubble):
(WebKit::WebPageProxy::setIsKeyboardAnimatingIn):
* UIProcess/WebPageProxy.messages.in:
* UIProcess/ios/PageClientImplIOS.h:
* UIProcess/ios/PageClientImplIOS.mm:
(WebKit::PageClientImpl::createValidationBubble):
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView _willStartScrollingOrZooming]):
(-[WKContentView scrollViewWillStartPanOrPinchGesture]):
(-[WKContentView _didEndScrollingOrZooming]):
* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::dynamicViewportSizeUpdate):
(WebKit::WebPageProxy::potentialTapAtPosition):
(WebKit::WebPageProxy::showValidationMessage):
(WebKit::WebPageProxy::setIsScrollingOrZooming):
* UIProcess/mac/PageClientImpl.h:
* UIProcess/mac/PageClientImpl.mm:
(WebKit::PageClientImpl::createValidationBubble):
* UIProcess/mac/WebPageProxyMac.mm:
(WebKit::WebPageProxy::showValidationMessage):
* WebKit2.xcodeproj/project.pbxproj:
* WebProcess/WebCoreSupport/WebValidationMessageClient.cpp: Copied from Tools/DumpRenderTree/mac/UIScriptControllerMac.mm.
(WebKit::WebValidationMessageClient::WebValidationMessageClient):
(WebKit::WebValidationMessageClient::~WebValidationMessageClient):
(WebKit::WebValidationMessageClient::showValidationMessage):
(WebKit::WebValidationMessageClient::hideValidationMessage):
(WebKit::WebValidationMessageClient::isValidationMessageVisible):
* WebProcess/WebCoreSupport/WebValidationMessageClient.h: Copied from Tools/DumpRenderTree/mac/UIScriptControllerMac.mm.
* WebProcess/WebPage/WebPage.cpp:
(WebKit::m_userInterfaceLayoutDirection):

Tools:

Add support for UIScriptController::contentsOfUserInterfaceItem(&quot;validationBubble&quot;)
on both Mac and iOS to retrieve the currently displayed validation message.

* DumpRenderTree/mac/UIScriptControllerMac.mm:
(WTR::UIScriptController::contentsOfUserInterfaceItem):
* TestRunnerShared/UIScriptContext/UIScriptController.cpp:
(WTR::UIScriptController::contentsOfUserInterfaceItem):
(WTR::UIScriptController::selectFormAccessoryPickerRow):
* WebKitTestRunner/mac/UIScriptControllerMac.mm:
(WTR::UIScriptController::contentsOfUserInterfaceItem):

LayoutTests:

* fast/forms/validation-messages-expected.txt: Added.
* fast/forms/validation-messages.html: Added.
Add layout test coverage for checking that the right validation messages
are displayed when submitting forms with constraint violations. More
testing will be landed in follow up to cover other things besides the
messages (e.g. when does the bubble disappear).

* platform/mac-wk1/TestExpectations:
Skip new test on WebKit1 because the feature is WebKit2 only at the
moment.

* platform/ios-simulator-wk2/TestExpectations:
* platform/mac-wk2/TestExpectations:
Skip tests for the Shadow DOM based HTML form validation UI on
Mac and iOS WK2 now that those ports use native popovers instead.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsplatformiossimulatorwk2TestExpectations">trunk/LayoutTests/platform/ios-simulator-wk2/TestExpectations</a></li>
<li><a href="#trunkLayoutTestsplatformmacwk1TestExpectations">trunk/LayoutTests/platform/mac-wk1/TestExpectations</a></li>
<li><a href="#trunkLayoutTestsplatformmacwk2TestExpectations">trunk/LayoutTests/platform/mac-wk2/TestExpectations</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLFormControlElementcpp">trunk/Source/WebCore/html/HTMLFormControlElement.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlValidationMessagecpp">trunk/Source/WebCore/html/ValidationMessage.cpp</a></li>
<li><a href="#trunkSourceWebCorepagePagecpp">trunk/Source/WebCore/page/Page.cpp</a></li>
<li><a href="#trunkSourceWebCorepagePageh">trunk/Source/WebCore/page/Page.h</a></li>
<li><a href="#trunkSourceWebCorepagePageConfigurationcpp">trunk/Source/WebCore/page/PageConfiguration.cpp</a></li>
<li><a href="#trunkSourceWebCorepagePageConfigurationh">trunk/Source/WebCore/page/PageConfiguration.h</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICocoaWKWebViewmm">trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICocoaWKWebViewPrivateh">trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessCocoaWebPageProxyCocoamm">trunk/Source/WebKit2/UIProcess/Cocoa/WebPageProxyCocoa.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessPageClienth">trunk/Source/WebKit2/UIProcess/PageClient.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxycpp">trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxyh">trunk/Source/WebKit2/UIProcess/WebPageProxy.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxymessagesin">trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosPageClientImplIOSh">trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosPageClientImplIOSmm">trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosWKContentViewInteractionmm">trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosWebPageProxyIOSmm">trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessmacPageClientImplh">trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessmacPageClientImplmm">trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessmacWebPageProxyMacmm">trunk/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm</a></li>
<li><a href="#trunkSourceWebKit2WebKit2xcodeprojprojectpbxproj">trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebPagecpp">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsDumpRenderTreemacUIScriptControllerMacmm">trunk/Tools/DumpRenderTree/mac/UIScriptControllerMac.mm</a></li>
<li><a href="#trunkToolsTestRunnerSharedUIScriptContextUIScriptControllercpp">trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp</a></li>
<li><a href="#trunkToolsWebKitTestRunnermacUIScriptControllerMacmm">trunk/Tools/WebKitTestRunner/mac/UIScriptControllerMac.mm</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastformsvalidationmessagesexpectedtxt">trunk/LayoutTests/fast/forms/validation-messages-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastformsvalidationmessageshtml">trunk/LayoutTests/fast/forms/validation-messages.html</a></li>
<li><a href="#trunkLayoutTestsplatformiossimulatorwk2fastformsvalidationmessagesexpectedtxt">trunk/LayoutTests/platform/ios-simulator-wk2/fast/forms/validation-messages-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreplatformValidationBubbleh">trunk/Source/WebCore/platform/ValidationBubble.h</a></li>
<li><a href="#trunkSourceWebCoreplatformiosValidationBubbleIOSmm">trunk/Source/WebCore/platform/ios/ValidationBubbleIOS.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformmacValidationBubbleMacmm">trunk/Source/WebCore/platform/mac/ValidationBubbleMac.mm</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebCoreSupportWebValidationMessageClientcpp">trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebValidationMessageClient.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebCoreSupportWebValidationMessageClienth">trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebValidationMessageClient.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/LayoutTests/ChangeLog        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2016-11-03  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        [WK2][Cocoa] Implement user interface for HTML form validation
+        https://bugs.webkit.org/show_bug.cgi?id=164143
+        &lt;rdar://problem/28944652&gt;
+
+        Reviewed by Simon Fraser.
+
+        * fast/forms/validation-messages-expected.txt: Added.
+        * fast/forms/validation-messages.html: Added.
+        Add layout test coverage for checking that the right validation messages
+        are displayed when submitting forms with constraint violations. More
+        testing will be landed in follow up to cover other things besides the
+        messages (e.g. when does the bubble disappear).
+
+        * platform/mac-wk1/TestExpectations:
+        Skip new test on WebKit1 because the feature is WebKit2 only at the
+        moment.
+
+        * platform/ios-simulator-wk2/TestExpectations:
+        * platform/mac-wk2/TestExpectations:
+        Skip tests for the Shadow DOM based HTML form validation UI on
+        Mac and iOS WK2 now that those ports use native popovers instead.
+
</ins><span class="cx"> 2016-11-03  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Update custom elements tests
</span></span></pre></div>
<a id="trunkLayoutTestsfastformsvalidationmessagesexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/forms/validation-messages-expected.txt (0 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/forms/validation-messages-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/forms/validation-messages-expected.txt        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -0,0 +1,31 @@
</span><ins>+Tests the HTML form validation messages being shown on UI side.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS validationBubbleContents.message is &quot;Please fill out this field.&quot;
+PASS validationBubbleContents.message is &quot;Please check this box if you want to proceed.&quot;
+PASS validationBubbleContents.message is &quot;Please select one of these options.&quot;
+PASS validationBubbleContents.message is &quot;Please select a file.&quot;
+PASS validationBubbleContents.message is &quot;Please enter an email address.&quot;
+PASS validationBubbleContents.message is &quot;Please enter a URL.&quot;
+PASS validationBubbleContents.message is &quot;Please match the requested format.&quot;
+PASS validationBubbleContents.message is &quot;Please use at least 100 characters.&quot;
+PASS validationBubbleContents.message is &quot;Value must be greater than or equal to 5.&quot;
+PASS validationBubbleContents.message is &quot;Value must be less than or equal to 5.&quot;
+PASS validationBubbleContents.message is &quot;Please enter a valid value.&quot;
+PASS successfullyParsed is true
+
+TEST COMPLETE
+Required text input: 
+Required checkbox input: 
+Required radio input: 
+Required radio input:   
+Required file input: 
+Required email input: 
+Required url input: 
+Required input with pattern: 
+Required input with minlength=100: 
+Required range with min=5: 
+Required range with max=5: 
+Required range with step=3 / min=0: 
</ins></span></pre></div>
<a id="trunkLayoutTestsfastformsvalidationmessageshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/forms/validation-messages.html (0 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/forms/validation-messages.html                                (rev 0)
+++ trunk/LayoutTests/fast/forms/validation-messages.html        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -0,0 +1,103 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;body&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;form&gt;
+  Required text input: &lt;input type=&quot;text&quot; required&gt;&lt;input id=&quot;required_text_input_submit&quot; type=&quot;submit&quot;&gt;
+&lt;/form&gt;
+&lt;form&gt;
+  Required checkbox input: &lt;input type=&quot;checkbox&quot; required&gt;&lt;input id=&quot;required_checkbox_submit&quot; type=&quot;submit&quot;&gt;
+&lt;/form&gt;
+&lt;form&gt;
+  Required radio input: &lt;input type=&quot;radio&quot; name=&quot;myradiogroup1&quot; required&gt;&lt;br&gt;
+  Required radio input: &lt;input type=&quot;radio&quot; name=&quot;myradiogroup1&quot;&gt;
+  &lt;input id=&quot;required_radio_submit&quot; type=&quot;submit&quot;&gt;
+&lt;/form&gt;
+&lt;form&gt;
+  Required file input: &lt;input type=&quot;file&quot; required&gt;&lt;input id=&quot;required_file_submit&quot; type=&quot;submit&quot;&gt;
+&lt;/form&gt;
+&lt;form&gt;
+  Required email input: &lt;input type=&quot;email&quot; value=&quot;invalid&quot; required&gt;&lt;input id=&quot;required_email_submit&quot; type=&quot;submit&quot;&gt;
+&lt;/form&gt;
+&lt;form&gt;
+  Required url input: &lt;input type=&quot;url&quot; value=&quot;invalid&quot; required&gt;&lt;input id=&quot;required_url_submit&quot; type=&quot;submit&quot;&gt;
+&lt;/form&gt;
+&lt;form&gt;
+  Required input with pattern: &lt;input type=&quot;text&quot; value=&quot;1&quot; pattern=&quot;[a-z]&quot; required&gt;&lt;input id=&quot;input_with_pattern_submit&quot; type=&quot;submit&quot;&gt;
+&lt;/form&gt;
+&lt;form&gt;
+  Required input with minlength=100: &lt;input type=&quot;text&quot; minlength=100 id=&quot;field_with_minlength&quot; required&gt;&lt;input id=&quot;input_with_minlength_submit&quot; type=&quot;submit&quot;&gt;
+&lt;/form&gt;
+&lt;form&gt;
+  Required range with min=5: &lt;input type=&quot;number&quot; value=&quot;1&quot; min=5 required&gt;&lt;input id=&quot;range_with_min_submit&quot; type=&quot;submit&quot;&gt;
+&lt;/form&gt;
+&lt;form&gt;
+  Required range with max=5: &lt;input type=&quot;number&quot; value=&quot;10&quot; max=5 required&gt;&lt;input id=&quot;range_with_max_submit&quot; type=&quot;submit&quot;&gt;
+&lt;/form&gt;
+&lt;form&gt;
+  Required range with step=3 / min=0: &lt;input type=&quot;number&quot; value=&quot;10&quot; min=0 step=3 required&gt;&lt;input id=&quot;range_with_step_submit&quot; type=&quot;submit&quot;&gt;
+&lt;/form&gt;
+&lt;script&gt;
+description(&quot;Tests the HTML form validation messages being shown on UI side.&quot;);
+jsTestIsAsync = true;
+
+function getValidationBubbleContents()
+{
+    return `
+    (function() {
+        uiController.uiScriptComplete(JSON.stringify(uiController.contentsOfUserInterfaceItem('validationBubble')));
+    })();`
+}
+
+var tests = [
+    ['required_text_input_submit', 'Please fill out this field.'],
+    ['required_checkbox_submit', 'Please check this box if you want to proceed.'],
+    ['required_radio_submit', 'Please select one of these options.'],
+    ['required_file_submit', 'Please select a file.'],
+    ['required_email_submit', 'Please enter an email address.'],
+    ['required_url_submit', 'Please enter a URL.'],
+    ['input_with_pattern_submit', 'Please match the requested format.'],
+    ['input_with_minlength_submit', 'Please use at least 100 characters.'],
+    ['range_with_min_submit', 'Value must be greater than or equal to 5.'],
+    ['range_with_max_submit', 'Value must be less than or equal to 5.'],
+    ['range_with_step_submit', 'Please enter a valid value.'],
+];
+var currentTestIndex = -1;
+
+function runNextTest()
+{
+    ++currentTestIndex;
+    if (currentTestIndex &gt;= tests.length) {
+        finishJSTest();
+        return;
+    }
+
+    var currentTest = tests[currentTestIndex];
+    var submitButton = document.getElementById(currentTest[0]);
+    expectedMessage = currentTest[1];
+
+    submitButton.click();
+    testRunner.runUIScript(getValidationBubbleContents(), function(result) {
+        validationBubbleContents = JSON.parse(result).validationBubble;
+        shouldBeEqualToString(&quot;validationBubbleContents.message&quot;, &quot;&quot; + expectedMessage);
+        runNextTest();
+    });
+}
+
+function setup()
+{
+    var field = document.getElementById(&quot;field_with_minlength&quot;);
+    field.focus();
+    eventSender.keyDown(&quot;Z&quot;);
+}
+
+onload = function() {
+    setup();
+    setTimeout(function() {
+        runNextTest();
+    }, 0);
+}
+&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsplatformiossimulatorwk2TestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/ios-simulator-wk2/TestExpectations (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/ios-simulator-wk2/TestExpectations        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/LayoutTests/platform/ios-simulator-wk2/TestExpectations        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -1457,6 +1457,17 @@
</span><span class="cx"> css2.1/20110323/replaced-intrinsic-002.htm [ Pass ]
</span><span class="cx"> fast/replaced/pdf-as-object-and-embed.html [ Pass ]
</span><span class="cx"> 
</span><ins>+# These tests test the Shadow DOM based HTML form validation UI but iOS WK2 is using native dialogs instead.
+fast/forms/validation-message-on-listbox.html
+fast/forms/validation-message-on-menulist.html
+fast/forms/validation-message-on-radio.html
+fast/forms/validation-message-on-checkbox.html
+fast/forms/validation-message-on-range.html
+fast/forms/validation-message-clone.html
+fast/forms/validation-message-in-relative-body.html
+fast/forms/validation-message-appearance.html
+fast/forms/validation-message-on-textarea.html 
+
</ins><span class="cx"> # Flaky as of 06/08/2015
</span><span class="cx"> compositing/overflow/overflow-positioning.html [ Failure ImageOnlyFailure Pass ]
</span><span class="cx"> editing/deleting/delete-3775172-fix.html [ Failure ImageOnlyFailure Pass ]
</span></span></pre></div>
<a id="trunkLayoutTestsplatformiossimulatorwk2fastformsvalidationmessagesexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/platform/ios-simulator-wk2/fast/forms/validation-messages-expected.txt (0 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/ios-simulator-wk2/fast/forms/validation-messages-expected.txt                                (rev 0)
+++ trunk/LayoutTests/platform/ios-simulator-wk2/fast/forms/validation-messages-expected.txt        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -0,0 +1,31 @@
</span><ins>+Tests the HTML form validation messages being shown on UI side.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS validationBubbleContents.message is &quot;Please fill out this field.&quot;
+PASS validationBubbleContents.message is &quot;Please check this box if you want to proceed.&quot;
+PASS validationBubbleContents.message is &quot;Please select one of these options.&quot;
+PASS validationBubbleContents.message is &quot;Please select a file.&quot;
+PASS validationBubbleContents.message is &quot;Please enter an email address.&quot;
+PASS validationBubbleContents.message is &quot;Please enter a URL.&quot;
+PASS validationBubbleContents.message is &quot;Please match the requested format.&quot;
+FAIL validationBubbleContents.message should be Please use at least 100 characters.. Was Please fill out this field..
+PASS validationBubbleContents.message is &quot;Value must be greater than or equal to 5.&quot;
+PASS validationBubbleContents.message is &quot;Value must be less than or equal to 5.&quot;
+PASS validationBubbleContents.message is &quot;Please enter a valid value.&quot;
+PASS successfullyParsed is true
+
+TEST COMPLETE
+Required text input: 
+Required checkbox input: 
+Required radio input: 
+Required radio input:   
+Required file input: 
+Required email input: 
+Required url input: 
+Required input with pattern: 
+Required input with minlength=100: 
+Required range with min=5: 
+Required range with max=5: 
+Required range with step=3 / min=0: 
</ins></span></pre></div>
<a id="trunkLayoutTestsplatformmacwk1TestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac-wk1/TestExpectations (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-wk1/TestExpectations        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/LayoutTests/platform/mac-wk1/TestExpectations        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -239,6 +239,9 @@
</span><span class="cx"> # rdar://problem/26478296
</span><span class="cx"> [ Sierra+ ] svg/hixie/text/003.html [ Failure ]
</span><span class="cx"> 
</span><ins>+# We do not support the new HTML validation UI on WebKit1 yet (rdar://problem/28944652).
+fast/forms/validation-messages.html [ Skip ]
+
</ins><span class="cx"> [ Yosemite ] http/tests/media/hls/video-controller-getStartDate.html [ Pass Timeout ]
</span><span class="cx"> 
</span><span class="cx"> webkit.org/b/159893 [ Debug ] imported/w3c/web-platform-tests/XMLHttpRequest/event-readystatechange-loaded.htm [ Pass Failure ]
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacwk2TestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac-wk2/TestExpectations (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-wk2/TestExpectations        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/LayoutTests/platform/mac-wk2/TestExpectations        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -193,6 +193,17 @@
</span><span class="cx"> 
</span><span class="cx"> webkit.org/b/95043 http/tests/security/local-user-CSS-from-remote.html [ Failure ]
</span><span class="cx"> 
</span><ins>+# These tests test the Shadow DOM based HTML form validation UI but Mac WK2 is using native dialogs instead.
+fast/forms/validation-message-on-listbox.html
+fast/forms/validation-message-on-menulist.html
+fast/forms/validation-message-on-radio.html
+fast/forms/validation-message-on-checkbox.html
+fast/forms/validation-message-on-range.html
+fast/forms/validation-message-clone.html
+fast/forms/validation-message-in-relative-body.html
+fast/forms/validation-message-appearance.html
+fast/forms/validation-message-on-textarea.html
+
</ins><span class="cx"> # All spatial navigation tests fail on Mac WK2
</span><span class="cx"> webkit.org/b/96438 fast/spatial-navigation
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Source/WebCore/ChangeLog        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -1,3 +1,47 @@
</span><ins>+2016-11-03  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        [WK2][Cocoa] Implement user interface for HTML form validation
+        https://bugs.webkit.org/show_bug.cgi?id=164143
+        &lt;rdar://problem/28944652&gt;
+
+        Reviewed by Simon Fraser.
+
+        Add ValidationBubble class to show HTML form validation messages
+        using native dialogs. It currently has an implementation for both
+        Mac and iOS. It is in WebCore under platform/ so that it can be
+        used by both WebKit1 and WebKit2.
+
+        Update ownership of ValidationMessageClient so that is is owned
+        by the Page using a unique_ptr&lt;&gt;, which seems to be the modern
+        way of handling lifetime for page clients.
+
+        Test: fast/forms/validation-messages.html
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * html/HTMLFormControlElement.cpp:
+        (WebCore::HTMLFormControlElement::focusAndShowValidationMessage):
+        * html/ValidationMessage.cpp:
+        (WebCore::ValidationMessage::updateValidationMessage):
+        * page/Page.cpp:
+        (WebCore::Page::Page):
+        (WebCore::Page::~Page):
+        * page/Page.h:
+        (WebCore::Page::validationMessageClient):
+        * page/PageConfiguration.cpp:
+        * page/PageConfiguration.h:
+        * platform/ValidationBubble.h: Copied from Tools/DumpRenderTree/mac/UIScriptControllerMac.mm.
+        (WebCore::ValidationBubble::message):
+        * platform/ios/ValidationBubbleIOS.mm: Added.
+        (-[WebValidationBubbleDelegate adaptivePresentationStyleForPresentationController:traitCollection:]):
+        (WebCore::ValidationBubble::ValidationBubble):
+        (WebCore::ValidationBubble::~ValidationBubble):
+        (WebCore::ValidationBubble::show):
+        (WebCore::ValidationBubble::setAnchorRect):
+        * platform/mac/ValidationBubbleMac.mm: Added.
+        (WebCore::ValidationBubble::ValidationBubble):
+        (WebCore::ValidationBubble::~ValidationBubble):
+        (WebCore::ValidationBubble::showRelativeTo):
+
</ins><span class="cx"> 2016-11-03  Brady Eidson  &lt;beidson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         IndexedDB 2.0: Rename IDBKeyRange.contains to IDBKeyRange.includes.
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -2961,6 +2961,7 @@
</span><span class="cx">                 836FBCEC178C117F00B21A15 /* SVGAnimatedProperty.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 836FBCEB178C117F00B21A15 /* SVGAnimatedProperty.cpp */; };
</span><span class="cx">                 8372DB311A6780A800C697C5 /* DiagnosticLoggingResultType.h in Headers */ = {isa = PBXBuildFile; fileRef = 8372DB301A6780A800C697C5 /* DiagnosticLoggingResultType.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 83765F951DAC522F00C06537 /* MouseEventInit.h in Headers */ = {isa = PBXBuildFile; fileRef = 83765F941DAC521800C06537 /* MouseEventInit.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                837B7D201DC3F55000D051FC /* ValidationBubbleIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 837B7D1F1DC3F54C00D051FC /* ValidationBubbleIOS.mm */; };
</ins><span class="cx">                 8386A96D19F61B2E00E1EC4A /* StyleBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 8386A96C19F61B2E00E1EC4A /* StyleBuilder.h */; };
</span><span class="cx">                 8386A97019F61E4F00E1EC4A /* StyleBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8386A96E19F61E4F00E1EC4A /* StyleBuilder.cpp */; };
</span><span class="cx">                 838867351D13BA5F003697D0 /* RenderObjectEnums.h in Headers */ = {isa = PBXBuildFile; fileRef = 838867341D13BA59003697D0 /* RenderObjectEnums.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -2994,6 +2995,8 @@
</span><span class="cx">                 83C1D434178D5AB500141E68 /* SVGPathSegLinetoVerticalRel.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C1D422178D5AB400141E68 /* SVGPathSegLinetoVerticalRel.h */; };
</span><span class="cx">                 83C1D435178D5AB500141E68 /* SVGPathSegMovetoAbs.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C1D423178D5AB400141E68 /* SVGPathSegMovetoAbs.h */; };
</span><span class="cx">                 83C1D436178D5AB500141E68 /* SVGPathSegMovetoRel.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C1D424178D5AB400141E68 /* SVGPathSegMovetoRel.h */; };
</span><ins>+                83C45B8C1DC2B667008871BA /* ValidationBubbleMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83C45B8B1DC2B663008871BA /* ValidationBubbleMac.mm */; };
+                83C45B8E1DC2B68A008871BA /* ValidationBubble.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C45B8D1DC2B67C008871BA /* ValidationBubble.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 83C5795D1DA5C301006FACA8 /* ScrollToOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 8350C3E71DA59B6200356446 /* ScrollToOptions.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 83D35AEC1C7187FA00F70D5A /* XMLHttpRequestEventTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 83D35AEA1C7187ED00F70D5A /* XMLHttpRequestEventTarget.h */; };
</span><span class="cx">                 83D35AF11C718D9000F70D5A /* JSXMLHttpRequestEventTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83D35AEF1C718D8400F70D5A /* JSXMLHttpRequestEventTarget.cpp */; };
</span><span class="lines">@@ -6419,7 +6422,7 @@
</span><span class="cx">                 F47A5E3F195B8E4800483100 /* StyleScrollSnapPoints.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F47A5E3A195B8C8A00483100 /* StyleScrollSnapPoints.cpp */; };
</span><span class="cx">                 F50664F7157F52DC00AC226F /* FormController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F50664F5157F52DC00AC226F /* FormController.cpp */; };
</span><span class="cx">                 F50664F8157F52DC00AC226F /* FormController.h in Headers */ = {isa = PBXBuildFile; fileRef = F50664F6157F52DC00AC226F /* FormController.h */; };
</span><del>-                F513A3EA15FF4841001526DB /* ValidationMessageClient.h in Headers */ = {isa = PBXBuildFile; fileRef = F513A3E915FF4841001526DB /* ValidationMessageClient.h */; };
</del><ins>+                F513A3EA15FF4841001526DB /* ValidationMessageClient.h in Headers */ = {isa = PBXBuildFile; fileRef = F513A3E915FF4841001526DB /* ValidationMessageClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 F52A8FD71D0A8D0E0073CF42 /* AccessibilityLabel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F52A8FD51D0A88010073CF42 /* AccessibilityLabel.cpp */; };
</span><span class="cx">                 F52AD5E41534245F0059FBE6 /* EmptyClients.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F52AD5E31534245F0059FBE6 /* EmptyClients.cpp */; };
</span><span class="cx">                 F544F78815CFB2A800AF33A8 /* PlatformLocale.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F544F78615CFB2A800AF33A8 /* PlatformLocale.cpp */; };
</span><span class="lines">@@ -10330,6 +10333,7 @@
</span><span class="cx">                 8372DB301A6780A800C697C5 /* DiagnosticLoggingResultType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiagnosticLoggingResultType.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 83765F931DAC521800C06537 /* MouseEventInit.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MouseEventInit.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 83765F941DAC521800C06537 /* MouseEventInit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MouseEventInit.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                837B7D1F1DC3F54C00D051FC /* ValidationBubbleIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ValidationBubbleIOS.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 8386A96C19F61B2E00E1EC4A /* StyleBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleBuilder.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 8386A96E19F61E4F00E1EC4A /* StyleBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleBuilder.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 838867341D13BA59003697D0 /* RenderObjectEnums.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderObjectEnums.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -10363,6 +10367,8 @@
</span><span class="cx">                 83C1D422178D5AB400141E68 /* SVGPathSegLinetoVerticalRel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGPathSegLinetoVerticalRel.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 83C1D423178D5AB400141E68 /* SVGPathSegMovetoAbs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGPathSegMovetoAbs.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 83C1D424178D5AB400141E68 /* SVGPathSegMovetoRel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGPathSegMovetoRel.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                83C45B8B1DC2B663008871BA /* ValidationBubbleMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ValidationBubbleMac.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
+                83C45B8D1DC2B67C008871BA /* ValidationBubble.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValidationBubble.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 83D26D3C1AFDCC50001B3873 /* ChildNode.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = ChildNode.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 83D26D3D1AFDCC50001B3873 /* ParentNode.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = ParentNode.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 83D35AEA1C7187ED00F70D5A /* XMLHttpRequestEventTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLHttpRequestEventTarget.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -17556,6 +17562,7 @@
</span><span class="cx">                                 51DF6D7F0B92A18E00C2DC85 /* ThreadCheck.mm */,
</span><span class="cx">                                 6593923909AE435C002C531F /* URLMac.mm */,
</span><span class="cx">                                 868160D3187669E70021E79D /* UserActivityMac.mm */,
</span><ins>+                                83C45B8B1DC2B663008871BA /* ValidationBubbleMac.mm */,
</ins><span class="cx">                                 CDC69DD816371FD3007C38DF /* WebCoreFullScreenPlaceholderView.h */,
</span><span class="cx">                                 CDC69DD916371FD3007C38DF /* WebCoreFullScreenPlaceholderView.mm */,
</span><span class="cx">                                 CDC69DD41632026C007C38DF /* WebCoreFullScreenWarningView.h */,
</span><span class="lines">@@ -19334,6 +19341,7 @@
</span><span class="cx">                                 44C9919E0F3D210E00586670 /* ThemeIOS.mm */,
</span><span class="cx">                                 1F72BF08187FD4270009BCB3 /* TileControllerMemoryHandlerIOS.cpp */,
</span><span class="cx">                                 1F72BF09187FD4270009BCB3 /* TileControllerMemoryHandlerIOS.h */,
</span><ins>+                                837B7D1F1DC3F54C00D051FC /* ValidationBubbleIOS.mm */,
</ins><span class="cx">                                 CDA29A2C1CBF73FC00901CCF /* WebAVPlayerController.h */,
</span><span class="cx">                                 CDA29A2D1CBF73FC00901CCF /* WebAVPlayerController.mm */,
</span><span class="cx">                                 31403797124BEA7F00AF40E4 /* WebCoreMotionManager.h */,
</span><span class="lines">@@ -22358,6 +22366,7 @@
</span><span class="cx">                                 71C916071D1483A300ACA47D /* UserInterfaceLayoutDirection.h */,
</span><span class="cx">                                 2E3BBF051162DA1100B9409A /* UUID.cpp */,
</span><span class="cx">                                 2E3BBF061162DA1100B9409A /* UUID.h */,
</span><ins>+                                83C45B8D1DC2B67C008871BA /* ValidationBubble.h */,
</ins><span class="cx">                                 9A1142031832D134000BB8AD /* ValueToString.h */,
</span><span class="cx">                                 46DB7D581B20FE58005651B2 /* VNodeTracker.cpp */,
</span><span class="cx">                                 46DB7D591B20FE58005651B2 /* VNodeTracker.h */,
</span><span class="lines">@@ -26428,6 +26437,7 @@
</span><span class="cx">                                 1B124D8D1D380B7000ECDFB0 /* MediaSampleAVFObjC.h in Headers */,
</span><span class="cx">                                 CDBEAEAD19D92B6C00BEBA88 /* MediaSelectionGroupAVFObjC.h in Headers */,
</span><span class="cx">                                 C9027F421B1D0AD200BFBFEF /* MediaSession.h in Headers */,
</span><ins>+                                83C45B8E1DC2B68A008871BA /* ValidationBubble.h in Headers */,
</ins><span class="cx">                                 C9F87CFE1B28F40E00979B83 /* MediaSessionEvents.h in Headers */,
</span><span class="cx">                                 C96F5EC81B5872260091EA9D /* MediaSessionInterruptionProvider.h in Headers */,
</span><span class="cx">                                 C96F5EC51B5872260091EA9D /* MediaSessionInterruptionProviderMac.h in Headers */,
</span><span class="lines">@@ -29328,6 +29338,7 @@
</span><span class="cx">                                 577483161DAEC32300716EF9 /* JSAesKeyGenParams.cpp in Sources */,
</span><span class="cx">                                 FDA15EC912B03F50003A583A /* JSAnalyserNode.cpp in Sources */,
</span><span class="cx">                                 31A795C61888BADC00382F90 /* JSANGLEInstancedArrays.cpp in Sources */,
</span><ins>+                                83C45B8C1DC2B667008871BA /* ValidationBubbleMac.mm in Sources */,
</ins><span class="cx">                                 12A253E21C8FFF6600C22295 /* JSAnimatable.cpp in Sources */,
</span><span class="cx">                                 120DE3FE1C87E18800B6D4DD /* JSAnimationEffect.cpp in Sources */,
</span><span class="cx">                                 3198480B1A1E6CE400A13318 /* JSAnimationEvent.cpp in Sources */,
</span><span class="lines">@@ -29546,6 +29557,7 @@
</span><span class="cx">                                 E44614370CD689C400FADA75 /* JSHTMLAudioElement.cpp in Sources */,
</span><span class="cx">                                 A80E7B120A19D606007FB8C5 /* JSHTMLBaseElement.cpp in Sources */,
</span><span class="cx">                                 1AE2AA220A1CDAB400B42B25 /* JSHTMLBodyElement.cpp in Sources */,
</span><ins>+                                837B7D201DC3F55000D051FC /* ValidationBubbleIOS.mm in Sources */,
</ins><span class="cx">                                 1AE2AA240A1CDAB400B42B25 /* JSHTMLBRElement.cpp in Sources */,
</span><span class="cx">                                 A80E7EA00A1A83E3007FB8C5 /* JSHTMLButtonElement.cpp in Sources */,
</span><span class="cx">                                 938E666009F09B81008A48EC /* JSHTMLCanvasElement.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLFormControlElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLFormControlElement.cpp (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLFormControlElement.cpp        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Source/WebCore/html/HTMLFormControlElement.cpp        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -517,7 +517,7 @@
</span><span class="cx"> 
</span><span class="cx"> void HTMLFormControlElement::focusAndShowValidationMessage()
</span><span class="cx"> {
</span><del>-    scrollIntoViewIfNeeded(false);
</del><ins>+    // Calling focus() will scroll the element into view.
</ins><span class="cx">     focus();
</span><span class="cx">     updateVisibleValidationMessage();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlValidationMessagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/ValidationMessage.cpp (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/ValidationMessage.cpp        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Source/WebCore/html/ValidationMessage.cpp        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -76,6 +76,14 @@
</span><span class="cx"> 
</span><span class="cx"> void ValidationMessage::updateValidationMessage(const String&amp; message)
</span><span class="cx"> {
</span><ins>+    // We want to hide the validation message as soon as the user starts
+    // typing, even if a constraint is still violated. Thefore, we hide the message instead
+    // of updating it if it is already visible.
+    if (isVisible()) {
+        requestToHideMessage();
+        return;
+    }
+
</ins><span class="cx">     String updatedMessage = message;
</span><span class="cx">     if (!validationMessageClient()) {
</span><span class="cx">         // HTML5 specification doesn't ask UA to show the title attribute value
</span></span></pre></div>
<a id="trunkSourceWebCorepagePagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/Page.cpp (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/Page.cpp        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Source/WebCore/page/Page.cpp        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -94,6 +94,7 @@
</span><span class="cx"> #include &quot;TextResourceDecoder.h&quot;
</span><span class="cx"> #include &quot;UserContentProvider.h&quot;
</span><span class="cx"> #include &quot;UserInputBridge.h&quot;
</span><ins>+#include &quot;ValidationMessageClient.h&quot;
</ins><span class="cx"> #include &quot;VisitedLinkState.h&quot;
</span><span class="cx"> #include &quot;VisitedLinkStore.h&quot;
</span><span class="cx"> #include &quot;VoidCallback.h&quot;
</span><span class="lines">@@ -182,7 +183,7 @@
</span><span class="cx">     , m_theme(RenderTheme::themeForPage(this))
</span><span class="cx">     , m_editorClient(WTFMove(pageConfiguration.editorClient))
</span><span class="cx">     , m_plugInClient(pageConfiguration.plugInClient)
</span><del>-    , m_validationMessageClient(pageConfiguration.validationMessageClient)
</del><ins>+    , m_validationMessageClient(WTFMove(pageConfiguration.validationMessageClient))
</ins><span class="cx">     , m_diagnosticLoggingClient(WTFMove(pageConfiguration.diagnosticLoggingClient))
</span><span class="cx">     , m_subframeCount(0)
</span><span class="cx">     , m_openedByDOM(false)
</span><span class="lines">@@ -270,6 +271,7 @@
</span><span class="cx"> 
</span><span class="cx"> Page::~Page()
</span><span class="cx"> {
</span><ins>+    m_validationMessageClient = nullptr;
</ins><span class="cx">     m_diagnosticLoggingClient = nullptr;
</span><span class="cx">     m_mainFrame-&gt;setView(nullptr);
</span><span class="cx">     setGroupName(String());
</span></span></pre></div>
<a id="trunkSourceWebCorepagePageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/Page.h (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/Page.h        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Source/WebCore/page/Page.h        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -205,7 +205,7 @@
</span><span class="cx"> #if ENABLE(POINTER_LOCK)
</span><span class="cx">     PointerLockController&amp; pointerLockController() const { return *m_pointerLockController; }
</span><span class="cx"> #endif
</span><del>-    ValidationMessageClient* validationMessageClient() const { return m_validationMessageClient; }
</del><ins>+    ValidationMessageClient* validationMessageClient() const { return m_validationMessageClient.get(); }
</ins><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT ScrollingCoordinator* scrollingCoordinator();
</span><span class="cx"> 
</span><span class="lines">@@ -592,7 +592,7 @@
</span><span class="cx"> 
</span><span class="cx">     UniqueRef&lt;EditorClient&gt; m_editorClient;
</span><span class="cx">     PlugInClient* m_plugInClient;
</span><del>-    ValidationMessageClient* m_validationMessageClient;
</del><ins>+    std::unique_ptr&lt;ValidationMessageClient&gt; m_validationMessageClient;
</ins><span class="cx">     std::unique_ptr&lt;DiagnosticLoggingClient&gt; m_diagnosticLoggingClient;
</span><span class="cx"> 
</span><span class="cx">     int m_subframeCount;
</span></span></pre></div>
<a id="trunkSourceWebCorepagePageConfigurationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/PageConfiguration.cpp (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/PageConfiguration.cpp        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Source/WebCore/page/PageConfiguration.cpp        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -35,6 +35,7 @@
</span><span class="cx"> #include &quot;SocketProvider.h&quot;
</span><span class="cx"> #include &quot;StorageNamespaceProvider.h&quot;
</span><span class="cx"> #include &quot;UserContentController.h&quot;
</span><ins>+#include &quot;ValidationMessageClient.h&quot;
</ins><span class="cx"> #include &quot;VisitedLinkStore.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span></span></pre></div>
<a id="trunkSourceWebCorepagePageConfigurationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/PageConfiguration.h (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/PageConfiguration.h        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Source/WebCore/page/PageConfiguration.h        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -77,9 +77,9 @@
</span><span class="cx">     PlugInClient* plugInClient { nullptr };
</span><span class="cx">     ProgressTrackerClient* progressTrackerClient { nullptr };
</span><span class="cx">     RefPtr&lt;BackForwardClient&gt; backForwardClient;
</span><del>-    ValidationMessageClient* validationMessageClient { nullptr };
</del><ins>+    std::unique_ptr&lt;ValidationMessageClient&gt; validationMessageClient;
</ins><span class="cx">     FrameLoaderClient* loaderClientForMainFrame { nullptr };
</span><del>-    std::unique_ptr&lt;DiagnosticLoggingClient&gt; diagnosticLoggingClient { nullptr };
</del><ins>+    std::unique_ptr&lt;DiagnosticLoggingClient&gt; diagnosticLoggingClient;
</ins><span class="cx"> 
</span><span class="cx">     RefPtr&lt;ApplicationCacheStorage&gt; applicationCacheStorage;
</span><span class="cx">     RefPtr&lt;DatabaseProvider&gt; databaseProvider;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformValidationBubblehfromrev208360trunkToolsDumpRenderTreemacUIScriptControllerMacmm"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/ValidationBubble.h (from rev 208360, trunk/Tools/DumpRenderTree/mac/UIScriptControllerMac.mm) (0 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ValidationBubble.h                                (rev 0)
+++ trunk/Source/WebCore/platform/ValidationBubble.h        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -0,0 +1,81 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include &quot;IntRect.h&quot;
+#include &lt;wtf/Forward.h&gt;
+#include &lt;wtf/text/WTFString.h&gt;
+
+#if PLATFORM(COCOA)
+#include &lt;wtf/RetainPtr.h&gt;
+#endif
+
+#if PLATFORM(MAC)
+OBJC_CLASS NSPopover;
+#elif PLATFORM(IOS)
+OBJC_CLASS UIViewController;
+OBJC_CLASS WebValidationBubbleDelegate;
+#endif
+
+#if PLATFORM(MAC)
+OBJC_CLASS NSView;
+using PlatformView = NSView;
+#elif PLATFORM(IOS)
+OBJC_CLASS UIView;
+using PlatformView = UIView;
+#else
+using PlatformView = void;
+#endif
+
+namespace WebCore {
+
+class ValidationBubble {
+public:
+    WEBCORE_EXPORT ValidationBubble(PlatformView*, const String&amp; message);
+    WEBCORE_EXPORT ~ValidationBubble();
+
+    const String&amp; message() const { return m_message; }
+
+#if PLATFORM(IOS)
+    WEBCORE_EXPORT void setAnchorRect(const IntRect&amp; anchorRect, UIViewController* presentingViewController);
+    WEBCORE_EXPORT void show();
+#else
+    WEBCORE_EXPORT void showRelativeTo(const IntRect&amp; anchorRect);
+#endif
+
+private:
+    PlatformView* m_view;
+    String m_message;
+#if PLATFORM(MAC)
+    RetainPtr&lt;NSPopover&gt; m_popover;
+#elif PLATFORM(IOS)
+    RetainPtr&lt;UIViewController&gt; m_popoverController;
+    RetainPtr&lt;WebValidationBubbleDelegate&gt; m_popoverDelegate;
+    UIViewController *m_presentingViewController;
+#endif
+};
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformiosValidationBubbleIOSmm"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/ios/ValidationBubbleIOS.mm (0 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ios/ValidationBubbleIOS.mm                                (rev 0)
+++ trunk/Source/WebCore/platform/ios/ValidationBubbleIOS.mm        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -0,0 +1,110 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import &quot;config.h&quot;
+
+#if PLATFORM(IOS)
+#import &quot;ValidationBubble.h&quot;
+
+#import &quot;SoftLinking.h&quot;
+#import &quot;UIKitSPI.h&quot;
+#import &lt;wtf/text/WTFString.h&gt;
+
+SOFT_LINK_FRAMEWORK(UIKit);
+SOFT_LINK_CLASS(UIKit, UILabel);
+SOFT_LINK_CLASS(UIKit, UIView);
+SOFT_LINK_CLASS(UIKit, UIViewController);
+
+@interface WebValidationBubbleDelegate : NSObject &lt;UIPopoverPresentationControllerDelegate&gt; {
+}
+@end
+
+@implementation WebValidationBubbleDelegate
+
+- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(UITraitCollection *)traitCollection
+{
+    UNUSED_PARAM(controller);
+    UNUSED_PARAM(traitCollection);
+    // This is needed to force UIKit to use a popover on iPhone as well.
+    return UIModalPresentationNone;
+}
+
+@end
+
+namespace WebCore {
+
+static const CGFloat horizontalPadding = 8;
+static const CGFloat verticalPadding = 8;
+static const CGFloat maxLabelWidth = 300;
+
+ValidationBubble::ValidationBubble(UIView* view, const String&amp; message)
+    : m_view(view)
+    , m_message(message)
+{
+    m_popoverController = adoptNS([[getUIViewControllerClass() alloc] init]);
+    [m_popoverController setModalPresentationStyle:UIModalPresentationPopover];
+
+    RetainPtr&lt;UIView&gt; popoverView = adoptNS([[getUIViewClass() alloc] initWithFrame:CGRectZero]);
+    [m_popoverController setView:popoverView.get()];
+
+    RetainPtr&lt;UILabel&gt; label = adoptNS([[getUILabelClass() alloc] initWithFrame:CGRectZero]);
+    [label setText:message];
+    [label setLineBreakMode:NSLineBreakByWordWrapping];
+    [label setNumberOfLines:0]; // No limit.
+    [popoverView addSubview:label.get()];
+
+    CGSize labelSize = [label sizeThatFits:CGSizeMake(maxLabelWidth, CGFLOAT_MAX)];
+    [label setFrame:CGRectMake(horizontalPadding, verticalPadding, labelSize.width, labelSize.height)];
+    [popoverView setFrame:CGRectMake(horizontalPadding, verticalPadding, labelSize.width + horizontalPadding * 2, labelSize.height + verticalPadding * 2)];
+
+    [m_popoverController setPreferredContentSize:popoverView.get().frame.size];
+}
+
+ValidationBubble::~ValidationBubble()
+{
+    [m_popoverController dismissViewControllerAnimated:NO completion:nil];
+}
+
+void ValidationBubble::show()
+{
+    [m_presentingViewController presentViewController:m_popoverController.get() animated:NO completion:nil];
+}
+
+void ValidationBubble::setAnchorRect(const IntRect&amp; anchorRect, UIViewController* presentingViewController)
+{
+    UIPopoverPresentationController *presentationController = [m_popoverController popoverPresentationController];
+    m_popoverDelegate = adoptNS([[WebValidationBubbleDelegate alloc] init]);
+    presentationController.delegate = m_popoverDelegate.get();
+    presentationController.passthroughViews = [NSArray arrayWithObjects:presentingViewController.view, m_view, nil];
+
+    presentationController.permittedArrowDirections = UIPopoverArrowDirectionUp;
+    presentationController.sourceView = m_view;
+    presentationController.sourceRect = CGRectMake(anchorRect.x(), anchorRect.y(), anchorRect.width(), anchorRect.height());
+    m_presentingViewController = presentingViewController;
+}
+
+} // namespace WebCore
+
+#endif // PLATFORM(IOS)
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformmacValidationBubbleMacmm"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/mac/ValidationBubbleMac.mm (0 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mac/ValidationBubbleMac.mm                                (rev 0)
+++ trunk/Source/WebCore/platform/mac/ValidationBubbleMac.mm        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -0,0 +1,78 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import &quot;config.h&quot;
+
+#if PLATFORM(MAC)
+#import &quot;ValidationBubble.h&quot;
+
+#import &lt;AppKit/AppKit.h&gt;
+#import &lt;wtf/text/WTFString.h&gt;
+
+namespace WebCore {
+
+static const CGFloat horizontalPadding = 5;
+static const CGFloat verticalPadding = 5;
+static const CGFloat maxLabelWidth = 300;
+
+ValidationBubble::ValidationBubble(NSView* view, const String&amp; message)
+    : m_view(view)
+    , m_message(message)
+{
+    RetainPtr&lt;NSViewController&gt; controller = adoptNS([[NSViewController alloc] init]);
+
+    RetainPtr&lt;NSView&gt; popoverView = adoptNS([[NSView alloc] initWithFrame:NSZeroRect]);
+    [controller setView:popoverView.get()];
+
+    RetainPtr&lt;NSTextField&gt; label = adoptNS([[NSTextField alloc] init]);
+    [label setEditable:NO];
+    [label setDrawsBackground:NO];
+    [label setBordered:NO];
+    [label setStringValue:message];
+    [popoverView addSubview:label.get()];
+    NSSize labelSize = [label sizeThatFits:NSMakeSize(maxLabelWidth, CGFLOAT_MAX)];
+    [label setFrame:NSMakeRect(horizontalPadding, verticalPadding, labelSize.width, labelSize.height)];
+    [popoverView setFrame:NSMakeRect(0, 0, labelSize.width + horizontalPadding * 2, labelSize.height + verticalPadding * 2)];
+
+    m_popover = adoptNS([[NSPopover alloc] init]);
+    [m_popover setContentViewController:controller.get()];
+    [m_popover setBehavior:NSPopoverBehaviorTransient];
+    [m_popover setAnimates:NO];
+}
+
+ValidationBubble::~ValidationBubble()
+{
+    [m_popover close];
+}
+
+void ValidationBubble::showRelativeTo(const IntRect&amp; anchorRect)
+{
+    NSRect rect = NSMakeRect(anchorRect.x(), anchorRect.y(), anchorRect.width(), anchorRect.height());
+    [m_popover showRelativeToRect:rect ofView:m_view preferredEdge:NSMinYEdge];
+}
+
+} // namespace WebCore
+
+#endif // PLATFORM(MAC)
</ins></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Source/WebKit2/ChangeLog        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -1,3 +1,70 @@
</span><ins>+2016-11-03  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        [WK2][Cocoa] Implement user interface for HTML form validation
+        https://bugs.webkit.org/show_bug.cgi?id=164143
+        &lt;rdar://problem/28944652&gt;
+
+        Reviewed by Simon Fraser.
+
+        Implement the ValidationMessageClient in WebKit2 and have it display
+        a ValidationBubble on Cocoa. ValidationBubble is implemented using
+        native popovers on both Mac and iOS. As a result, Mac and iOS WK2
+        now use native popover for HTML form validation instead of the old
+        Shadow DOM based UI in WebCore.
+
+        The native popover shows at the bottom (or top) of the input and it
+        disapears as soon as the user starts typing or interacts with the
+        view (e.g. tap / scroll / zoom).
+
+        The feature is still disabled at runtime.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _initializeWithConfiguration:]):
+        (-[WKWebView _keyboardWillShow:]):
+        (-[WKWebView _keyboardDidShow:]):
+        (-[WKWebView _contentsOfUserInterfaceItem:]):
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+        * UIProcess/Cocoa/WebPageProxyCocoa.mm:
+        * UIProcess/PageClient.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::handleWheelEvent):
+        (WebKit::WebPageProxy::setPageZoomFactor):
+        (WebKit::WebPageProxy::setPageAndTextZoomFactors):
+        (WebKit::WebPageProxy::pageDidScroll):
+        (WebKit::WebPageProxy::resetState):
+        (WebKit::WebPageProxy::hideValidationMessage):
+        * UIProcess/WebPageProxy.h:
+        (WebKit::WebPageProxy::validationBubble):
+        (WebKit::WebPageProxy::setIsKeyboardAnimatingIn):
+        * UIProcess/WebPageProxy.messages.in:
+        * UIProcess/ios/PageClientImplIOS.h:
+        * UIProcess/ios/PageClientImplIOS.mm:
+        (WebKit::PageClientImpl::createValidationBubble):
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView _willStartScrollingOrZooming]):
+        (-[WKContentView scrollViewWillStartPanOrPinchGesture]):
+        (-[WKContentView _didEndScrollingOrZooming]):
+        * UIProcess/ios/WebPageProxyIOS.mm:
+        (WebKit::WebPageProxy::dynamicViewportSizeUpdate):
+        (WebKit::WebPageProxy::potentialTapAtPosition):
+        (WebKit::WebPageProxy::showValidationMessage):
+        (WebKit::WebPageProxy::setIsScrollingOrZooming):
+        * UIProcess/mac/PageClientImpl.h:
+        * UIProcess/mac/PageClientImpl.mm:
+        (WebKit::PageClientImpl::createValidationBubble):
+        * UIProcess/mac/WebPageProxyMac.mm:
+        (WebKit::WebPageProxy::showValidationMessage):
+        * WebKit2.xcodeproj/project.pbxproj:
+        * WebProcess/WebCoreSupport/WebValidationMessageClient.cpp: Copied from Tools/DumpRenderTree/mac/UIScriptControllerMac.mm.
+        (WebKit::WebValidationMessageClient::WebValidationMessageClient):
+        (WebKit::WebValidationMessageClient::~WebValidationMessageClient):
+        (WebKit::WebValidationMessageClient::showValidationMessage):
+        (WebKit::WebValidationMessageClient::hideValidationMessage):
+        (WebKit::WebValidationMessageClient::isValidationMessageVisible):
+        * WebProcess/WebCoreSupport/WebValidationMessageClient.h: Copied from Tools/DumpRenderTree/mac/UIScriptControllerMac.mm.
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::m_userInterfaceLayoutDirection):
+
</ins><span class="cx"> 2016-11-03  Tim Horton  &lt;timothy_horton@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Printing to PDF should produce internal links when HTML has internal links
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICocoaWKWebViewmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -93,6 +93,7 @@
</span><span class="cx"> #import &lt;WebCore/RuntimeApplicationChecks.h&gt;
</span><span class="cx"> #import &lt;WebCore/Settings.h&gt;
</span><span class="cx"> #import &lt;WebCore/TextStream.h&gt;
</span><ins>+#import &lt;WebCore/ValidationBubble.h&gt;
</ins><span class="cx"> #import &lt;WebCore/WritingMode.h&gt;
</span><span class="cx"> #import &lt;wtf/HashMap.h&gt;
</span><span class="cx"> #import &lt;wtf/MathExtras.h&gt;
</span><span class="lines">@@ -524,6 +525,7 @@
</span><span class="cx">     [center addObserver:self selector:@selector(_keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
</span><span class="cx">     [center addObserver:self selector:@selector(_keyboardDidChangeFrame:) name:UIKeyboardDidChangeFrameNotification object:nil];
</span><span class="cx">     [center addObserver:self selector:@selector(_keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
</span><ins>+    [center addObserver:self selector:@selector(_keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
</ins><span class="cx">     [center addObserver:self selector:@selector(_keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
</span><span class="cx">     [center addObserver:self selector:@selector(_windowDidRotate:) name:UIWindowDidRotateNotification object:nil];
</span><span class="cx">     [center addObserver:self selector:@selector(_contentSizeCategoryDidChange:) name:UIContentSizeCategoryDidChangeNotification object:nil];
</span><span class="lines">@@ -2177,8 +2179,15 @@
</span><span class="cx"> {
</span><span class="cx">     if ([self _shouldUpdateKeyboardWithInfo:notification.userInfo])
</span><span class="cx">         [self _keyboardChangedWithInfo:notification.userInfo adjustScrollView:YES];
</span><ins>+
+    _page-&gt;setIsKeyboardAnimatingIn(true);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)_keyboardDidShow:(NSNotification *)notification
+{
+    _page-&gt;setIsKeyboardAnimatingIn(false);
+}
+
</ins><span class="cx"> - (void)_keyboardWillHide:(NSNotification *)notification
</span><span class="cx"> {
</span><span class="cx">     // Ignore keyboard will hide notifications sent during rotation. They're just there for
</span><span class="lines">@@ -4527,8 +4536,23 @@
</span><span class="cx"> 
</span><span class="cx"> @implementation WKWebView (WKTesting)
</span><span class="cx"> 
</span><ins>+- (NSDictionary *)_contentsOfUserInterfaceItem:(NSString *)userInterfaceItem
+{
+    if ([userInterfaceItem isEqualToString:@&quot;validationBubble&quot;]) {
+        auto* validationBubble = _page-&gt;validationBubble();
+        String message = validationBubble ? validationBubble-&gt;message() : emptyString();
+        return @{ userInterfaceItem: @{ @&quot;message&quot;: (NSString *)message } };
+    }
+
</ins><span class="cx"> #if PLATFORM(IOS)
</span><ins>+    return [_contentView _contentsOfUserInterfaceItem:(NSString *)userInterfaceItem];
+#else
+    return nil;
+#endif
+}
</ins><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
+
</ins><span class="cx"> - (CGRect)_contentVisibleRect
</span><span class="cx"> {
</span><span class="cx">     return [self convertRect:[self bounds] toView:self._currentContentView];
</span><span class="lines">@@ -4564,11 +4588,6 @@
</span><span class="cx">     [_contentView selectFormAccessoryPickerRow:rowIndex];
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-- (NSDictionary *)_contentsOfUserInterfaceItem:(NSString *)userInterfaceItem
-{
-    return [_contentView _contentsOfUserInterfaceItem:(NSString *)userInterfaceItem];
-}
-
</del><span class="cx"> - (void)didStartFormControlInteraction
</span><span class="cx"> {
</span><span class="cx">     // For subclasses to override.
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICocoaWKWebViewPrivateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -257,6 +257,8 @@
</span><span class="cx"> 
</span><span class="cx"> @interface WKWebView (WKTesting)
</span><span class="cx"> 
</span><ins>+- (NSDictionary *)_contentsOfUserInterfaceItem:(NSString *)userInterfaceItem WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
+
</ins><span class="cx"> #if TARGET_OS_IPHONE
</span><span class="cx"> 
</span><span class="cx"> @property (nonatomic, readonly) CGRect _contentVisibleRect WK_API_AVAILABLE(ios(10.0));
</span><span class="lines">@@ -267,7 +269,6 @@
</span><span class="cx"> - (void)keyboardAccessoryBarPrevious WK_API_AVAILABLE(ios(10.0));
</span><span class="cx"> - (void)dismissFormAccessoryView WK_API_AVAILABLE(ios(WK_IOS_TBA));
</span><span class="cx"> - (void)selectFormAccessoryPickerRow:(int)rowIndex WK_API_AVAILABLE(ios(WK_IOS_TBA));
</span><del>-- (NSDictionary *)_contentsOfUserInterfaceItem:(NSString *)userInterfaceItem WK_API_AVAILABLE(ios(WK_IOS_TBA));
</del><span class="cx"> 
</span><span class="cx"> - (void)didStartFormControlInteraction WK_API_AVAILABLE(ios(WK_IOS_TBA));
</span><span class="cx"> - (void)didEndFormControlInteraction WK_API_AVAILABLE(ios(WK_IOS_TBA));
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessCocoaWebPageProxyCocoamm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/Cocoa/WebPageProxyCocoa.mm (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/Cocoa/WebPageProxyCocoa.mm        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/WebPageProxyCocoa.mm        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -30,8 +30,8 @@
</span><span class="cx"> #import &quot;DataDetectionResult.h&quot;
</span><span class="cx"> #import &quot;LoadParameters.h&quot;
</span><span class="cx"> #import &quot;WebProcessProxy.h&quot;
</span><del>-
</del><span class="cx"> #import &lt;WebCore/SearchPopupMenuCocoa.h&gt;
</span><ins>+#import &lt;WebCore/ValidationBubble.h&gt;
</ins><span class="cx"> #import &lt;wtf/cf/TypeCastsCF.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebKit {
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessPageClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/PageClient.h (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/PageClient.h        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Source/WebKit2/UIProcess/PageClient.h        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -49,6 +49,7 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> class Cursor;
</span><span class="cx"> class TextIndicator;
</span><ins>+class ValidationBubble;
</ins><span class="cx"> class WebMediaSessionManager;
</span><span class="cx"> enum class TextIndicatorWindowLifetime : uint8_t;
</span><span class="cx"> enum class TextIndicatorWindowDismissalAnimation : uint8_t;
</span><span class="lines">@@ -227,6 +228,10 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(COCOA)
</span><ins>+    virtual std::unique_ptr&lt;WebCore::ValidationBubble&gt; createValidationBubble(const String&amp; message) = 0;
+#endif
+
+#if PLATFORM(COCOA)
</ins><span class="cx">     virtual void setTextIndicator(Ref&lt;WebCore::TextIndicator&gt;, WebCore::TextIndicatorWindowLifetime) = 0;
</span><span class="cx">     virtual void clearTextIndicator(WebCore::TextIndicatorWindowDismissalAnimation) = 0;
</span><span class="cx">     virtual void setTextIndicatorAnimationProgress(float) = 0;
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -123,6 +123,7 @@
</span><span class="cx"> #include &lt;WebCore/TextCheckerClient.h&gt;
</span><span class="cx"> #include &lt;WebCore/TextIndicator.h&gt;
</span><span class="cx"> #include &lt;WebCore/URL.h&gt;
</span><ins>+#include &lt;WebCore/ValidationBubble.h&gt;
</ins><span class="cx"> #include &lt;WebCore/WindowFeatures.h&gt;
</span><span class="cx"> #include &lt;stdio.h&gt;
</span><span class="cx"> #include &lt;wtf/NeverDestroyed.h&gt;
</span><span class="lines">@@ -1928,6 +1929,8 @@
</span><span class="cx">     if (!isValid())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    hideValidationMessage();
+
</ins><span class="cx">     if (!m_currentlyProcessedWheelEvents.isEmpty()) {
</span><span class="cx">         m_wheelEventQueue.append(event);
</span><span class="cx">         if (m_wheelEventQueue.size() &lt; wheelEventQueueSizeThreshold)
</span><span class="lines">@@ -2465,6 +2468,8 @@
</span><span class="cx">     if (m_pageZoomFactor == zoomFactor)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    hideValidationMessage();
+
</ins><span class="cx">     m_pageZoomFactor = zoomFactor;
</span><span class="cx">     m_process-&gt;send(Messages::WebPage::SetPageZoomFactor(m_pageZoomFactor), m_pageID); 
</span><span class="cx"> }
</span><span class="lines">@@ -2477,6 +2482,8 @@
</span><span class="cx">     if (m_pageZoomFactor == pageZoomFactor &amp;&amp; m_textZoomFactor == textZoomFactor)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    hideValidationMessage();
+
</ins><span class="cx">     m_pageZoomFactor = pageZoomFactor;
</span><span class="cx">     m_textZoomFactor = textZoomFactor;
</span><span class="cx">     m_process-&gt;send(Messages::WebPage::SetPageAndTextZoomFactors(m_pageZoomFactor, m_textZoomFactor), m_pageID); 
</span><span class="lines">@@ -4103,6 +4110,13 @@
</span><span class="cx"> void WebPageProxy::pageDidScroll()
</span><span class="cx"> {
</span><span class="cx">     m_uiClient-&gt;pageDidScroll(this);
</span><ins>+
+#if PLATFORM(IOS)
+    // Do not hide the validation message if the scrolling was caused by the keyboard showing up.
+    if (m_isKeyboardAnimatingIn)
+        return;
+#endif
+    hideValidationMessage();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebPageProxy::runOpenPanel(uint64_t frameID, const SecurityOriginData&amp; frameSecurityOrigin, const FileChooserSettings&amp; settings)
</span><span class="lines">@@ -5306,6 +5320,7 @@
</span><span class="cx">     m_scrollingPerformanceData = nullptr;
</span><span class="cx"> #endif
</span><span class="cx">     m_drawingArea = nullptr;
</span><ins>+    hideValidationMessage();
</ins><span class="cx"> 
</span><span class="cx">     if (m_inspector) {
</span><span class="cx">         m_inspector-&gt;invalidate();
</span><span class="lines">@@ -5378,6 +5393,8 @@
</span><span class="cx">     m_dynamicViewportSizeUpdateLayerTreeTransactionID = 0;
</span><span class="cx">     m_layerTreeTransactionIdAtLastTouchStart = 0;
</span><span class="cx">     m_hasNetworkRequestsOnSuspended = false;
</span><ins>+    m_isKeyboardAnimatingIn = false;
+    m_isScrollingOrZooming = false;
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(WIRELESS_PLAYBACK_TARGET) &amp;&amp; !PLATFORM(IOS)
</span><span class="lines">@@ -6639,6 +6656,13 @@
</span><span class="cx"> 
</span><span class="cx">     m_process-&gt;send(Messages::WebPage::SetUserInterfaceLayoutDirection(static_cast&lt;uint32_t&gt;(userInterfaceLayoutDirection)), m_pageID);
</span><span class="cx"> }
</span><ins>+
+void WebPageProxy::hideValidationMessage()
+{
+#if PLATFORM(COCOA)
+    m_validationBubble = nullptr;
+#endif
+}
</ins><span class="cx">     
</span><span class="cx"> #if ENABLE(POINTER_LOCK)
</span><span class="cx"> void WebPageProxy::requestPointerLock()
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -153,6 +153,7 @@
</span><span class="cx"> class RunLoopObserver;
</span><span class="cx"> class SharedBuffer;
</span><span class="cx"> class TextIndicator;
</span><ins>+class ValidationBubble;
</ins><span class="cx"> enum class HasInsecureContent;
</span><span class="cx"> struct DictionaryPopupInfo;
</span><span class="cx"> struct ExceptionDetails;
</span><span class="lines">@@ -527,6 +528,7 @@
</span><span class="cx">     void getSelectionContext(std::function&lt;void(const String&amp;, const String&amp;, const String&amp;, CallbackBase::Error)&gt;);
</span><span class="cx">     void handleTwoFingerTapAtPoint(const WebCore::IntPoint&amp;, uint64_t requestID);
</span><span class="cx">     void setForceAlwaysUserScalable(bool);
</span><ins>+    void setIsScrollingOrZooming(bool);
</ins><span class="cx"> #endif
</span><span class="cx"> #if ENABLE(DATA_DETECTION)
</span><span class="cx">     void setDataDetectionResult(const DataDetectionResult&amp;);
</span><span class="lines">@@ -1093,6 +1095,17 @@
</span><span class="cx">     void logSampledDiagnosticMessageWithResult(const String&amp; message, const String&amp; description, uint32_t result);
</span><span class="cx">     void logSampledDiagnosticMessageWithValue(const String&amp; message, const String&amp; description, const String&amp; value);
</span><span class="cx"> 
</span><ins>+    // Form validation messages.
+    void showValidationMessage(const WebCore::IntRect&amp; anchorClientRect, const String&amp; message);
+    void hideValidationMessage();
+#if PLATFORM(COCOA)
+    WebCore::ValidationBubble* validationBubble() const { return m_validationBubble.get(); } // For testing.
+#endif
+
+#if PLATFORM(IOS)
+    void setIsKeyboardAnimatingIn(bool isKeyboardAnimatingIn) { m_isKeyboardAnimatingIn = isKeyboardAnimatingIn; }
+#endif
+
</ins><span class="cx"> #if ENABLE(WIRELESS_PLAYBACK_TARGET) &amp;&amp; !PLATFORM(IOS)
</span><span class="cx">     void addPlaybackTargetPickerClient(uint64_t);
</span><span class="cx">     void removePlaybackTargetPickerClient(uint64_t);
</span><span class="lines">@@ -1626,6 +1639,8 @@
</span><span class="cx">     uint64_t m_layerTreeTransactionIdAtLastTouchStart;
</span><span class="cx">     uint64_t m_currentDynamicViewportSizeUpdateID { 0 };
</span><span class="cx">     bool m_hasNetworkRequestsOnSuspended;
</span><ins>+    bool m_isKeyboardAnimatingIn { false };
+    bool m_isScrollingOrZooming { false };
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(VIBRATION)
</span><span class="lines">@@ -1777,6 +1792,9 @@
</span><span class="cx"> #if ENABLE(INPUT_TYPE_COLOR)
</span><span class="cx">     RefPtr&lt;WebColorPicker&gt; m_colorPicker;
</span><span class="cx"> #endif
</span><ins>+#if PLATFORM(COCOA)
+    std::unique_ptr&lt;WebCore::ValidationBubble&gt; m_validationBubble;
+#endif
</ins><span class="cx"> 
</span><span class="cx">     const uint64_t m_pageID;
</span><span class="cx">     const WebCore::SessionID m_sessionID;
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxymessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -64,6 +64,11 @@
</span><span class="cx">     ScreenToRootView(WebCore::IntPoint screenPoint) -&gt; (WebCore::IntPoint windowPoint)
</span><span class="cx">     RootViewToScreen(WebCore::IntRect rect) -&gt; (WebCore::IntRect screenFrame)
</span><span class="cx"> 
</span><ins>+#if PLATFORM(COCOA)
+    ShowValidationMessage(WebCore::IntRect anchorRect, String message)
+    HideValidationMessage()
+#endif
+
</ins><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     AccessibilityScreenToRootView(WebCore::IntPoint screenPoint) -&gt; (WebCore::IntPoint windowPoint)
</span><span class="cx">     RootViewToAccessibilityScreen(WebCore::IntRect rect) -&gt; (WebCore::IntRect screenFrame)
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosPageClientImplIOSh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.h (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.h        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.h        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -96,6 +96,8 @@
</span><span class="cx"> #if ENABLE(CONTEXT_MENUS)
</span><span class="cx">     std::unique_ptr&lt;WebContextMenuProxy&gt; createContextMenuProxy(WebPageProxy&amp;, const ContextMenuContextData&amp;, const UserData&amp;) override;
</span><span class="cx"> #endif
</span><ins>+    std::unique_ptr&lt;WebCore::ValidationBubble&gt; createValidationBubble(const String&amp; message) final;
+
</ins><span class="cx">     void setTextIndicator(Ref&lt;WebCore::TextIndicator&gt;, WebCore::TextIndicatorWindowLifetime) override;
</span><span class="cx">     void clearTextIndicator(WebCore::TextIndicatorWindowDismissalAnimation) override;
</span><span class="cx">     void setTextIndicatorAnimationProgress(float) override;
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosPageClientImplIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -51,6 +51,7 @@
</span><span class="cx"> #import &lt;WebCore/PlatformScreen.h&gt;
</span><span class="cx"> #import &lt;WebCore/SharedBuffer.h&gt;
</span><span class="cx"> #import &lt;WebCore/TextIndicator.h&gt;
</span><ins>+#import &lt;WebCore/ValidationBubble.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> #define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, m_webView-&gt;_page-&gt;process().connection())
</span><span class="cx"> 
</span><span class="lines">@@ -743,6 +744,11 @@
</span><span class="cx">     return ([UIView userInterfaceLayoutDirectionForSemanticContentAttribute:[m_webView semanticContentAttribute]] == UIUserInterfaceLayoutDirectionLeftToRight) ? WebCore::UserInterfaceLayoutDirection::LTR : WebCore::UserInterfaceLayoutDirection::RTL;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+std::unique_ptr&lt;ValidationBubble&gt; PageClientImpl::createValidationBubble(const String&amp; message)
+{
+    return std::make_unique&lt;ValidationBubble&gt;(m_contentView, message);
+}
+
</ins><span class="cx"> } // namespace WebKit
</span><span class="cx"> 
</span><span class="cx"> #endif // PLATFORM(IOS)
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosWKContentViewInteractionmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -1591,10 +1591,13 @@
</span><span class="cx"> {
</span><span class="cx">     [_webSelectionAssistant willStartScrollingOrZoomingPage];
</span><span class="cx">     [_textSelectionAssistant willStartScrollingOverflow];
</span><ins>+    _page-&gt;setIsScrollingOrZooming(true);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)scrollViewWillStartPanOrPinchGesture
</span><span class="cx"> {
</span><ins>+    _page-&gt;hideValidationMessage();
+
</ins><span class="cx">     _canSendTouchEventsAsynchronously = YES;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1602,6 +1605,7 @@
</span><span class="cx"> {
</span><span class="cx">     [_webSelectionAssistant didEndScrollingOrZoomingPage];
</span><span class="cx">     [_textSelectionAssistant didEndScrollingOverflow];
</span><ins>+    _page-&gt;setIsScrollingOrZooming(false);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (BOOL)requiresAccessoryView
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosWebPageProxyIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -50,6 +50,7 @@
</span><span class="cx"> #import &lt;WebCore/PlatformScreen.h&gt;
</span><span class="cx"> #import &lt;WebCore/SharedBuffer.h&gt;
</span><span class="cx"> #import &lt;WebCore/UserAgent.h&gt;
</span><ins>+#import &lt;WebCore/ValidationBubble.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> #if USE(QUICK_LOOK)
</span><span class="cx"> #import &quot;APILoaderClient.h&quot;
</span><span class="lines">@@ -267,6 +268,8 @@
</span><span class="cx">     if (!isValid())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    hideValidationMessage();
+
</ins><span class="cx">     m_dynamicViewportSizeUpdateWaitingForTarget = true;
</span><span class="cx">     m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit = true;
</span><span class="cx">     m_process-&gt;send(Messages::WebPage::DynamicViewportSizeUpdate(minimumLayoutSize, maximumUnobscuredSize, targetExposedContentRect, targetUnobscuredRect, targetUnobscuredRectInScrollViewCoordinates, targetScale, deviceOrientation, ++m_currentDynamicViewportSizeUpdateID), m_pageID);
</span><span class="lines">@@ -752,6 +755,7 @@
</span><span class="cx"> 
</span><span class="cx"> void WebPageProxy::potentialTapAtPosition(const WebCore::FloatPoint&amp; position, uint64_t&amp; requestID)
</span><span class="cx"> {
</span><ins>+    hideValidationMessage();
</ins><span class="cx">     process().send(Messages::WebPage::PotentialTapAtPosition(requestID, position), m_pageID);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1009,6 +1013,27 @@
</span><span class="cx">     m_pageClient.selectionDidChange();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebPageProxy::showValidationMessage(const IntRect&amp; anchorClientRect, const String&amp; message)
+{
+    m_validationBubble = m_pageClient.createValidationBubble(message);
+    m_validationBubble-&gt;setAnchorRect(anchorClientRect, uiClient().presentingViewController());
+
+    // If we are currently doing a scrolling / zoom animation, then we'll delay showing the validation
+    // bubble until the animation is over.
+    if (!m_isScrollingOrZooming)
+        m_validationBubble-&gt;show();
+}
+
+void WebPageProxy::setIsScrollingOrZooming(bool isScrollingOrZooming)
+{
+    m_isScrollingOrZooming = isScrollingOrZooming;
+
+    // We finished doing the scrolling / zoom animation so we can now show the validation
+    // bubble if we're supposed to.
+    if (!m_isScrollingOrZooming &amp;&amp; m_validationBubble)
+        m_validationBubble-&gt;show();
+}
+
</ins><span class="cx"> #if USE(QUICK_LOOK)
</span><span class="cx">     
</span><span class="cx"> void WebPageProxy::didStartLoadForQuickLookDocumentInMainFrame(const String&amp; fileName, const String&amp; uti)
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessmacPageClientImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -131,6 +131,8 @@
</span><span class="cx">     RefPtr&lt;WebColorPicker&gt; createColorPicker(WebPageProxy*, const WebCore::Color&amp; initialColor, const WebCore::IntRect&amp;) override;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    std::unique_ptr&lt;WebCore::ValidationBubble&gt; createValidationBubble(const String&amp; message) final;
+
</ins><span class="cx">     void setTextIndicator(Ref&lt;WebCore::TextIndicator&gt;, WebCore::TextIndicatorWindowLifetime) override;
</span><span class="cx">     void clearTextIndicator(WebCore::TextIndicatorWindowDismissalAnimation) override;
</span><span class="cx">     void setTextIndicatorAnimationProgress(float) override;
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessmacPageClientImplmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -67,6 +67,7 @@
</span><span class="cx"> #import &lt;WebCore/TextIndicator.h&gt;
</span><span class="cx"> #import &lt;WebCore/TextIndicatorWindow.h&gt;
</span><span class="cx"> #import &lt;WebCore/TextUndoInsertionMarkupMac.h&gt;
</span><ins>+#import &lt;WebCore/ValidationBubble.h&gt;
</ins><span class="cx"> #import &lt;WebKitSystemInterface.h&gt;
</span><span class="cx"> #import &lt;wtf/text/CString.h&gt;
</span><span class="cx"> #import &lt;wtf/text/WTFString.h&gt;
</span><span class="lines">@@ -439,6 +440,11 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+std::unique_ptr&lt;ValidationBubble&gt; PageClientImpl::createValidationBubble(const String&amp; message)
+{
+    return std::make_unique&lt;ValidationBubble&gt;(m_view, message);
+}
+
</ins><span class="cx"> void PageClientImpl::setTextIndicator(Ref&lt;TextIndicator&gt; textIndicator, WebCore::TextIndicatorWindowLifetime lifetime)
</span><span class="cx"> {
</span><span class="cx">     m_impl-&gt;setTextIndicator(textIndicator.get(), lifetime);
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessmacWebPageProxyMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -54,6 +54,7 @@
</span><span class="cx"> #import &lt;WebCore/SharedBuffer.h&gt;
</span><span class="cx"> #import &lt;WebCore/TextAlternativeWithRange.h&gt;
</span><span class="cx"> #import &lt;WebCore/UserAgent.h&gt;
</span><ins>+#import &lt;WebCore/ValidationBubble.h&gt;
</ins><span class="cx"> #import &lt;mach-o/dyld.h&gt;
</span><span class="cx"> #import &lt;wtf/text/StringConcatenate.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -594,6 +595,12 @@
</span><span class="cx">     windowRect = m_pageClient.rootViewToWindow(viewRect);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebPageProxy::showValidationMessage(const IntRect&amp; anchorClientRect, const String&amp; message)
+{
+    m_validationBubble = m_pageClient.createValidationBubble(message);
+    m_validationBubble-&gt;showRelativeTo(anchorClientRect);
+}
+
</ins><span class="cx"> #if WK_API_ENABLED
</span><span class="cx"> NSView *WebPageProxy::inspectorAttachmentView()
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceWebKit2WebKit2xcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -1216,6 +1216,8 @@
</span><span class="cx">                 83BFAC421D96137C00433490 /* BlobDownloadClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 83BFAC401D96136000433490 /* BlobDownloadClient.h */; };
</span><span class="cx">                 83BFAC431D96137C00433490 /* BlobDownloadClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83BFAC411D96136000433490 /* BlobDownloadClient.cpp */; };
</span><span class="cx">                 83D454D71BE9D3C4006C93BD /* NetworkLoadClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 83D454D61BE9D3C4006C93BD /* NetworkLoadClient.h */; };
</span><ins>+                83EE575B1DB7D61100C74C50 /* WebValidationMessageClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83EE57591DB7D60600C74C50 /* WebValidationMessageClient.cpp */; };
+                83EE575C1DB7D61100C74C50 /* WebValidationMessageClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 83EE575A1DB7D60600C74C50 /* WebValidationMessageClient.h */; };
</ins><span class="cx">                 84477853176FCC0800CDC7BB /* InjectedBundleHitTestResultMediaType.h in Headers */ = {isa = PBXBuildFile; fileRef = 84477851176FCAC100CDC7BB /* InjectedBundleHitTestResultMediaType.h */; };
</span><span class="cx">                 868160D0187645570021E79D /* WindowServerConnection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 868160CF187645370021E79D /* WindowServerConnection.mm */; };
</span><span class="cx">                 86E67A251910B9D100004AB7 /* ProcessThrottler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E67A21190F411800004AB7 /* ProcessThrottler.h */; };
</span><span class="lines">@@ -3321,6 +3323,8 @@
</span><span class="cx">                 83BFAC401D96136000433490 /* BlobDownloadClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BlobDownloadClient.h; path = NetworkProcess/Downloads/BlobDownloadClient.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 83BFAC411D96136000433490 /* BlobDownloadClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BlobDownloadClient.cpp; path = NetworkProcess/Downloads/BlobDownloadClient.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 83D454D61BE9D3C4006C93BD /* NetworkLoadClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NetworkLoadClient.h; path = NetworkProcess/NetworkLoadClient.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                83EE57591DB7D60600C74C50 /* WebValidationMessageClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebValidationMessageClient.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                83EE575A1DB7D60600C74C50 /* WebValidationMessageClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebValidationMessageClient.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 84477851176FCAC100CDC7BB /* InjectedBundleHitTestResultMediaType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InjectedBundleHitTestResultMediaType.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 868160CD18763D4B0021E79D /* WindowServerConnection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WindowServerConnection.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 868160CF187645370021E79D /* WindowServerConnection.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = WindowServerConnection.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -6035,6 +6039,8 @@
</span><span class="cx">                                 D3B9484511FF4B6500032B39 /* WebSearchPopupMenu.h */,
</span><span class="cx">                                 4A410F4819AF7B80002EBAB5 /* WebUserMediaClient.cpp */,
</span><span class="cx">                                 4A410F4919AF7B80002EBAB5 /* WebUserMediaClient.h */,
</span><ins>+                                83EE57591DB7D60600C74C50 /* WebValidationMessageClient.cpp */,
+                                83EE575A1DB7D60600C74C50 /* WebValidationMessageClient.h */,
</ins><span class="cx">                         );
</span><span class="cx">                         path = WebCoreSupport;
</span><span class="cx">                         sourceTree = &quot;&lt;group&gt;&quot;;
</span><span class="lines">@@ -7808,6 +7814,7 @@
</span><span class="cx">                                 BCC43ABB127B95DC00317F16 /* PlatformPopupMenuData.h in Headers */,
</span><span class="cx">                                 1A6FB7D311E651E200DB1371 /* Plugin.h in Headers */,
</span><span class="cx">                                 31A67E0D165B2A99006CBA66 /* PlugInAutoStartProvider.h in Headers */,
</span><ins>+                                83EE575C1DB7D61100C74C50 /* WebValidationMessageClient.h in Headers */,
</ins><span class="cx">                                 1A9FBA8D13FF04E600DEED67 /* PluginComplexTextInputState.h in Headers */,
</span><span class="cx">                                 1AA56F2911E92BC80061B882 /* PluginController.h in Headers */,
</span><span class="cx">                                 1A8EF4CB1252403700F7067F /* PluginControllerProxy.h in Headers */,
</span><span class="lines">@@ -9730,6 +9737,7 @@
</span><span class="cx">                                 0FCB4E5118BBE044000FCFC9 /* WKGeolocationProviderIOSObjCSecurityOrigin.mm in Sources */,
</span><span class="cx">                                 0F174AA7142AAC610039250F /* WKGeometry.cpp in Sources */,
</span><span class="cx">                                 B62E7310143047A60069EC35 /* WKHitTestResult.cpp in Sources */,
</span><ins>+                                83EE575B1DB7D61100C74C50 /* WebValidationMessageClient.cpp in Sources */,
</ins><span class="cx">                                 5110AE0C133C16CB0072717A /* WKIconDatabase.cpp in Sources */,
</span><span class="cx">                                 5123CF1B133D260A0056F800 /* WKIconDatabaseCG.cpp in Sources */,
</span><span class="cx">                                 BCCF6AC212C91F34008F9C35 /* WKImage.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebCoreSupportWebValidationMessageClientcppfromrev208360trunkToolsDumpRenderTreemacUIScriptControllerMacmm"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebValidationMessageClient.cpp (from rev 208360, trunk/Tools/DumpRenderTree/mac/UIScriptControllerMac.mm) (0 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebValidationMessageClient.cpp                                (rev 0)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebValidationMessageClient.cpp        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -0,0 +1,72 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;WebValidationMessageClient.h&quot;
+
+#include &quot;WebPage.h&quot;
+#include &quot;WebPageProxyMessages.h&quot;
+#include &lt;WebCore/Element.h&gt;
+#include &lt;WebCore/Frame.h&gt;
+
+namespace WebKit {
+
+using namespace WebCore;
+
+WebValidationMessageClient::WebValidationMessageClient(WebPage&amp; page)
+    : m_page(page)
+{
+}
+
+WebValidationMessageClient::~WebValidationMessageClient()
+{
+    if (m_currentAnchor)
+        hideValidationMessage(*m_currentAnchor);
+}
+
+void WebValidationMessageClient::showValidationMessage(const Element&amp; anchor, const String&amp; message)
+{
+    if (m_currentAnchor)
+        hideValidationMessage(*m_currentAnchor);
+
+    m_currentAnchor = &amp;anchor;
+    m_page.send(Messages::WebPageProxy::ShowValidationMessage(anchor.clientRect(), message));
+}
+
+void WebValidationMessageClient::hideValidationMessage(const Element&amp; anchor)
+{
+    if (!isValidationMessageVisible(anchor))
+        return;
+
+    m_currentAnchor = nullptr;
+    m_page.send(Messages::WebPageProxy::HideValidationMessage());
+}
+
+bool WebValidationMessageClient::isValidationMessageVisible(const Element&amp; anchor)
+{
+    return m_currentAnchor == &amp;anchor;
+}
+
+} // namespace WebKit
</ins></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebCoreSupportWebValidationMessageClienthfromrev208360trunkToolsDumpRenderTreemacUIScriptControllerMacmm"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebValidationMessageClient.h (from rev 208360, trunk/Tools/DumpRenderTree/mac/UIScriptControllerMac.mm) (0 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebValidationMessageClient.h                                (rev 0)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebValidationMessageClient.h        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -0,0 +1,50 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include &lt;WebCore/IntRect.h&gt;
+#include &lt;WebCore/ValidationMessageClient.h&gt;
+
+namespace WebKit {
+
+class WebPage;
+
+class WebValidationMessageClient final : public WebCore::ValidationMessageClient {
+public:
+    explicit WebValidationMessageClient(WebPage&amp;);
+    ~WebValidationMessageClient();
+
+    // ValidationMessageClient API.
+    void showValidationMessage(const WebCore::Element&amp; anchor, const String&amp; message) final;
+    void hideValidationMessage(const WebCore::Element&amp; anchor) final;
+    bool isValidationMessageVisible(const WebCore::Element&amp; anchor) final;
+
+private:
+    WebPage&amp; m_page;
+    const WebCore::Element* m_currentAnchor { nullptr };
+};
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -112,6 +112,7 @@
</span><span class="cx"> #include &quot;WebUndoStep.h&quot;
</span><span class="cx"> #include &quot;WebUserContentController.h&quot;
</span><span class="cx"> #include &quot;WebUserMediaClient.h&quot;
</span><ins>+#include &quot;WebValidationMessageClient.h&quot;
</ins><span class="cx"> #include &lt;JavaScriptCore/APICast.h&gt;
</span><span class="cx"> #include &lt;WebCore/ApplicationCacheStorage.h&gt;
</span><span class="cx"> #include &lt;WebCore/ArchiveResource.h&gt;
</span><span class="lines">@@ -409,6 +410,10 @@
</span><span class="cx">     pageConfiguration.progressTrackerClient = new WebProgressTrackerClient(*this);
</span><span class="cx">     pageConfiguration.diagnosticLoggingClient = std::make_unique&lt;WebDiagnosticLoggingClient&gt;(*this);
</span><span class="cx"> 
</span><ins>+#if PLATFORM(COCOA)
+    pageConfiguration.validationMessageClient = std::make_unique&lt;WebValidationMessageClient&gt;(*this);
+#endif
+
</ins><span class="cx">     pageConfiguration.applicationCacheStorage = &amp;WebProcess::singleton().applicationCacheStorage();
</span><span class="cx">     pageConfiguration.databaseProvider = WebDatabaseProvider::getOrCreate(m_pageGroup-&gt;pageGroupID());
</span><span class="cx">     pageConfiguration.pluginInfoProvider = &amp;WebPluginInfoProvider::singleton();
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Tools/ChangeLog        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -1,3 +1,22 @@
</span><ins>+2016-11-03  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        [WK2][Cocoa] Implement user interface for HTML form validation
+        https://bugs.webkit.org/show_bug.cgi?id=164143
+        &lt;rdar://problem/28944652&gt;
+
+        Reviewed by Simon Fraser.
+
+        Add support for UIScriptController::contentsOfUserInterfaceItem(&quot;validationBubble&quot;)
+        on both Mac and iOS to retrieve the currently displayed validation message.
+
+        * DumpRenderTree/mac/UIScriptControllerMac.mm:
+        (WTR::UIScriptController::contentsOfUserInterfaceItem):
+        * TestRunnerShared/UIScriptContext/UIScriptController.cpp:
+        (WTR::UIScriptController::contentsOfUserInterfaceItem):
+        (WTR::UIScriptController::selectFormAccessoryPickerRow):
+        * WebKitTestRunner/mac/UIScriptControllerMac.mm:
+        (WTR::UIScriptController::contentsOfUserInterfaceItem):
+
</ins><span class="cx"> 2016-11-03  Konstantin Tokarev  &lt;annulen@yandex.ru&gt;
</span><span class="cx"> 
</span><span class="cx">         Fixes to build JSCOnly on macOS
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreemacUIScriptControllerMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/mac/UIScriptControllerMac.mm (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/mac/UIScriptControllerMac.mm        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Tools/DumpRenderTree/mac/UIScriptControllerMac.mm        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -64,6 +64,11 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+JSObjectRef UIScriptController::contentsOfUserInterfaceItem(JSStringRef interfaceItem) const
+{
+    return nullptr;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+}
+
</ins><span class="cx"> #endif // PLATFORM(MAC)
</span></span></pre></div>
<a id="trunkToolsTestRunnerSharedUIScriptContextUIScriptControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -161,6 +161,11 @@
</span><span class="cx"> void UIScriptController::zoomToScale(double, JSValueRef)
</span><span class="cx"> {
</span><span class="cx"> }
</span><ins>+
+JSObjectRef UIScriptController::contentsOfUserInterfaceItem(JSStringRef interfaceItem) const
+{
+    return nullptr;
+}
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if !PLATFORM(IOS)
</span><span class="lines">@@ -235,11 +240,6 @@
</span><span class="cx"> void UIScriptController::selectFormAccessoryPickerRow(long)
</span><span class="cx"> {
</span><span class="cx"> }
</span><del>-    
-JSObjectRef UIScriptController::contentsOfUserInterfaceItem(JSStringRef interfaceItem) const
-{
-    return nullptr;
-}
</del><span class="cx"> 
</span><span class="cx"> void UIScriptController::scrollToOffset(long x, long y)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnermacUIScriptControllerMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/mac/UIScriptControllerMac.mm (208360 => 208361)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/mac/UIScriptControllerMac.mm        2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Tools/WebKitTestRunner/mac/UIScriptControllerMac.mm        2016-11-04 01:38:31 UTC (rev 208361)
</span><span class="lines">@@ -27,10 +27,15 @@
</span><span class="cx"> #import &quot;UIScriptController.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #import &quot;PlatformWebView.h&quot;
</span><ins>+#import &quot;StringFunctions.h&quot;
</ins><span class="cx"> #import &quot;TestController.h&quot;
</span><span class="cx"> #import &quot;TestRunnerWKWebView.h&quot;
</span><span class="cx"> #import &quot;UIScriptContext.h&quot;
</span><ins>+#import &lt;JavaScriptCore/JSContext.h&gt;
</ins><span class="cx"> #import &lt;JavaScriptCore/JSStringRefCF.h&gt;
</span><ins>+#import &lt;JavaScriptCore/JSValue.h&gt;
+#import &lt;JavaScriptCore/JavaScriptCore.h&gt;
+#import &lt;JavaScriptCore/OpaqueJSString.h&gt;
</ins><span class="cx"> #import &lt;WebKit/WKWebViewPrivate.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WTR {
</span><span class="lines">@@ -85,4 +90,16 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+JSObjectRef UIScriptController::contentsOfUserInterfaceItem(JSStringRef interfaceItem) const
+{
+#if WK_API_ENABLED
+    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()-&gt;platformView();
+    NSDictionary *contentDictionary = [webView _contentsOfUserInterfaceItem:toWTFString(toWK(interfaceItem))];
+    return JSValueToObject(m_context-&gt;jsContext(), [JSValue valueWithObject:contentDictionary inContext:[JSContext contextWithJSGlobalContextRef:m_context-&gt;jsContext()]].JSValueRef, nullptr);
+#else
+    UNUSED_PARAM(interfaceItem);
+    return nullptr;
+#endif
+}
+
</ins><span class="cx"> } // namespace WTR
</span></span></pre>
</div>
</div>

</body>
</html>