Title: [208361] trunk
Revision
208361
Author
[email protected]
Date
2016-11-03 18:38:31 -0700 (Thu, 03 Nov 2016)

Log Message

[WK2][Cocoa] Implement user interface for HTML form validation
https://bugs.webkit.org/show_bug.cgi?id=164143
<rdar://problem/28944652>

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<>, 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("validationBubble")
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.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (208360 => 208361)


--- trunk/LayoutTests/ChangeLog	2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/LayoutTests/ChangeLog	2016-11-04 01:38:31 UTC (rev 208361)
@@ -1,3 +1,27 @@
+2016-11-03  Chris Dumez  <[email protected]>
+
+        [WK2][Cocoa] Implement user interface for HTML form validation
+        https://bugs.webkit.org/show_bug.cgi?id=164143
+        <rdar://problem/28944652>
+
+        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.
+
 2016-11-03  Ryosuke Niwa  <[email protected]>
 
         Update custom elements tests

Added: trunk/LayoutTests/fast/forms/validation-messages-expected.txt (0 => 208361)


--- 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)
@@ -0,0 +1,31 @@
+Tests the HTML form validation messages being shown on UI side.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS validationBubbleContents.message is "Please fill out this field."
+PASS validationBubbleContents.message is "Please check this box if you want to proceed."
+PASS validationBubbleContents.message is "Please select one of these options."
+PASS validationBubbleContents.message is "Please select a file."
+PASS validationBubbleContents.message is "Please enter an email address."
+PASS validationBubbleContents.message is "Please enter a URL."
+PASS validationBubbleContents.message is "Please match the requested format."
+PASS validationBubbleContents.message is "Please use at least 100 characters."
+PASS validationBubbleContents.message is "Value must be greater than or equal to 5."
+PASS validationBubbleContents.message is "Value must be less than or equal to 5."
+PASS validationBubbleContents.message is "Please enter a valid value."
+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: 

Added: trunk/LayoutTests/fast/forms/validation-messages.html (0 => 208361)


--- 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)
@@ -0,0 +1,103 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<form>
+  Required text input: <input type="text" required><input id="required_text_input_submit" type="submit">
+</form>
+<form>
+  Required checkbox input: <input type="checkbox" required><input id="required_checkbox_submit" type="submit">
+</form>
+<form>
+  Required radio input: <input type="radio" name="myradiogroup1" required><br>
+  Required radio input: <input type="radio" name="myradiogroup1">
+  <input id="required_radio_submit" type="submit">
+</form>
+<form>
+  Required file input: <input type="file" required><input id="required_file_submit" type="submit">
+</form>
+<form>
+  Required email input: <input type="email" value="invalid" required><input id="required_email_submit" type="submit">
+</form>
+<form>
+  Required url input: <input type="url" value="invalid" required><input id="required_url_submit" type="submit">
+</form>
+<form>
+  Required input with pattern: <input type="text" value="1" pattern="[a-z]" required><input id="input_with_pattern_submit" type="submit">
+</form>
+<form>
+  Required input with minlength=100: <input type="text" minlength=100 id="field_with_minlength" required><input id="input_with_minlength_submit" type="submit">
+</form>
+<form>
+  Required range with min=5: <input type="number" value="1" min=5 required><input id="range_with_min_submit" type="submit">
+</form>
+<form>
+  Required range with max=5: <input type="number" value="10" max=5 required><input id="range_with_max_submit" type="submit">
+</form>
+<form>
+  Required range with step=3 / min=0: <input type="number" value="10" min=0 step=3 required><input id="range_with_step_submit" type="submit">
+</form>
+<script>
+description("Tests the HTML form validation messages being shown on UI side.");
+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 >= 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("validationBubbleContents.message", "" + expectedMessage);
+        runNextTest();
+    });
+}
+
+function setup()
+{
+    var field = document.getElementById("field_with_minlength");
+    field.focus();
+    eventSender.keyDown("Z");
+}
+
+_onload_ = function() {
+    setup();
+    setTimeout(function() {
+        runNextTest();
+    }, 0);
+}
+</script>
+<script src=""
+</body>
+<html>

Modified: trunk/LayoutTests/platform/ios-simulator-wk2/TestExpectations (208360 => 208361)


--- 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)
@@ -1457,6 +1457,17 @@
 css2.1/20110323/replaced-intrinsic-002.htm [ Pass ]
 fast/replaced/pdf-as-object-and-embed.html [ Pass ]
 
+# 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 
+
 # Flaky as of 06/08/2015
 compositing/overflow/overflow-positioning.html [ Failure ImageOnlyFailure Pass ]
 editing/deleting/delete-3775172-fix.html [ Failure ImageOnlyFailure Pass ]

Added: trunk/LayoutTests/platform/ios-simulator-wk2/fast/forms/validation-messages-expected.txt (0 => 208361)


--- 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)
@@ -0,0 +1,31 @@
+Tests the HTML form validation messages being shown on UI side.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS validationBubbleContents.message is "Please fill out this field."
+PASS validationBubbleContents.message is "Please check this box if you want to proceed."
+PASS validationBubbleContents.message is "Please select one of these options."
+PASS validationBubbleContents.message is "Please select a file."
+PASS validationBubbleContents.message is "Please enter an email address."
+PASS validationBubbleContents.message is "Please enter a URL."
+PASS validationBubbleContents.message is "Please match the requested format."
+FAIL validationBubbleContents.message should be Please use at least 100 characters.. Was Please fill out this field..
+PASS validationBubbleContents.message is "Value must be greater than or equal to 5."
+PASS validationBubbleContents.message is "Value must be less than or equal to 5."
+PASS validationBubbleContents.message is "Please enter a valid value."
+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: 

Modified: trunk/LayoutTests/platform/mac-wk1/TestExpectations (208360 => 208361)


--- 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)
@@ -239,6 +239,9 @@
 # rdar://problem/26478296
 [ Sierra+ ] svg/hixie/text/003.html [ Failure ]
 
+# We do not support the new HTML validation UI on WebKit1 yet (rdar://problem/28944652).
+fast/forms/validation-messages.html [ Skip ]
+
 [ Yosemite ] http/tests/media/hls/video-controller-getStartDate.html [ Pass Timeout ]
 
 webkit.org/b/159893 [ Debug ] imported/w3c/web-platform-tests/XMLHttpRequest/event-readystatechange-loaded.htm [ Pass Failure ]

Modified: trunk/LayoutTests/platform/mac-wk2/TestExpectations (208360 => 208361)


--- 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)
@@ -193,6 +193,17 @@
 
 webkit.org/b/95043 http/tests/security/local-user-CSS-from-remote.html [ Failure ]
 
+# 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
+
 # All spatial navigation tests fail on Mac WK2
 webkit.org/b/96438 fast/spatial-navigation
 

Modified: trunk/Source/WebCore/ChangeLog (208360 => 208361)


--- 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)
@@ -1,3 +1,47 @@
+2016-11-03  Chris Dumez  <[email protected]>
+
+        [WK2][Cocoa] Implement user interface for HTML form validation
+        https://bugs.webkit.org/show_bug.cgi?id=164143
+        <rdar://problem/28944652>
+
+        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<>, 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):
+
 2016-11-03  Brady Eidson  <[email protected]>
 
         IndexedDB 2.0: Rename IDBKeyRange.contains to IDBKeyRange.includes.

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (208360 => 208361)


--- 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)
@@ -2961,6 +2961,7 @@
 		836FBCEC178C117F00B21A15 /* SVGAnimatedProperty.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 836FBCEB178C117F00B21A15 /* SVGAnimatedProperty.cpp */; };
 		8372DB311A6780A800C697C5 /* DiagnosticLoggingResultType.h in Headers */ = {isa = PBXBuildFile; fileRef = 8372DB301A6780A800C697C5 /* DiagnosticLoggingResultType.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		83765F951DAC522F00C06537 /* MouseEventInit.h in Headers */ = {isa = PBXBuildFile; fileRef = 83765F941DAC521800C06537 /* MouseEventInit.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		837B7D201DC3F55000D051FC /* ValidationBubbleIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 837B7D1F1DC3F54C00D051FC /* ValidationBubbleIOS.mm */; };
 		8386A96D19F61B2E00E1EC4A /* StyleBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 8386A96C19F61B2E00E1EC4A /* StyleBuilder.h */; };
 		8386A97019F61E4F00E1EC4A /* StyleBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8386A96E19F61E4F00E1EC4A /* StyleBuilder.cpp */; };
 		838867351D13BA5F003697D0 /* RenderObjectEnums.h in Headers */ = {isa = PBXBuildFile; fileRef = 838867341D13BA59003697D0 /* RenderObjectEnums.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -2994,6 +2995,8 @@
 		83C1D434178D5AB500141E68 /* SVGPathSegLinetoVerticalRel.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C1D422178D5AB400141E68 /* SVGPathSegLinetoVerticalRel.h */; };
 		83C1D435178D5AB500141E68 /* SVGPathSegMovetoAbs.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C1D423178D5AB400141E68 /* SVGPathSegMovetoAbs.h */; };
 		83C1D436178D5AB500141E68 /* SVGPathSegMovetoRel.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C1D424178D5AB400141E68 /* SVGPathSegMovetoRel.h */; };
+		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, ); }; };
 		83C5795D1DA5C301006FACA8 /* ScrollToOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 8350C3E71DA59B6200356446 /* ScrollToOptions.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		83D35AEC1C7187FA00F70D5A /* XMLHttpRequestEventTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 83D35AEA1C7187ED00F70D5A /* XMLHttpRequestEventTarget.h */; };
 		83D35AF11C718D9000F70D5A /* JSXMLHttpRequestEventTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83D35AEF1C718D8400F70D5A /* JSXMLHttpRequestEventTarget.cpp */; };
@@ -6419,7 +6422,7 @@
 		F47A5E3F195B8E4800483100 /* StyleScrollSnapPoints.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F47A5E3A195B8C8A00483100 /* StyleScrollSnapPoints.cpp */; };
 		F50664F7157F52DC00AC226F /* FormController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F50664F5157F52DC00AC226F /* FormController.cpp */; };
 		F50664F8157F52DC00AC226F /* FormController.h in Headers */ = {isa = PBXBuildFile; fileRef = F50664F6157F52DC00AC226F /* FormController.h */; };
-		F513A3EA15FF4841001526DB /* ValidationMessageClient.h in Headers */ = {isa = PBXBuildFile; fileRef = F513A3E915FF4841001526DB /* ValidationMessageClient.h */; };
+		F513A3EA15FF4841001526DB /* ValidationMessageClient.h in Headers */ = {isa = PBXBuildFile; fileRef = F513A3E915FF4841001526DB /* ValidationMessageClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		F52A8FD71D0A8D0E0073CF42 /* AccessibilityLabel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F52A8FD51D0A88010073CF42 /* AccessibilityLabel.cpp */; };
 		F52AD5E41534245F0059FBE6 /* EmptyClients.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F52AD5E31534245F0059FBE6 /* EmptyClients.cpp */; };
 		F544F78815CFB2A800AF33A8 /* PlatformLocale.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F544F78615CFB2A800AF33A8 /* PlatformLocale.cpp */; };
@@ -10330,6 +10333,7 @@
 		8372DB301A6780A800C697C5 /* DiagnosticLoggingResultType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiagnosticLoggingResultType.h; sourceTree = "<group>"; };
 		83765F931DAC521800C06537 /* MouseEventInit.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MouseEventInit.idl; sourceTree = "<group>"; };
 		83765F941DAC521800C06537 /* MouseEventInit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MouseEventInit.h; sourceTree = "<group>"; };
+		837B7D1F1DC3F54C00D051FC /* ValidationBubbleIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ValidationBubbleIOS.mm; sourceTree = "<group>"; };
 		8386A96C19F61B2E00E1EC4A /* StyleBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleBuilder.h; sourceTree = "<group>"; };
 		8386A96E19F61E4F00E1EC4A /* StyleBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleBuilder.cpp; sourceTree = "<group>"; };
 		838867341D13BA59003697D0 /* RenderObjectEnums.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderObjectEnums.h; sourceTree = "<group>"; };
@@ -10363,6 +10367,8 @@
 		83C1D422178D5AB400141E68 /* SVGPathSegLinetoVerticalRel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGPathSegLinetoVerticalRel.h; sourceTree = "<group>"; };
 		83C1D423178D5AB400141E68 /* SVGPathSegMovetoAbs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGPathSegMovetoAbs.h; sourceTree = "<group>"; };
 		83C1D424178D5AB400141E68 /* SVGPathSegMovetoRel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGPathSegMovetoRel.h; sourceTree = "<group>"; };
+		83C45B8B1DC2B663008871BA /* ValidationBubbleMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ValidationBubbleMac.mm; sourceTree = "<group>"; };
+		83C45B8D1DC2B67C008871BA /* ValidationBubble.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValidationBubble.h; sourceTree = "<group>"; };
 		83D26D3C1AFDCC50001B3873 /* ChildNode.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = ChildNode.idl; sourceTree = "<group>"; };
 		83D26D3D1AFDCC50001B3873 /* ParentNode.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = ParentNode.idl; sourceTree = "<group>"; };
 		83D35AEA1C7187ED00F70D5A /* XMLHttpRequestEventTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLHttpRequestEventTarget.h; sourceTree = "<group>"; };
@@ -17556,6 +17562,7 @@
 				51DF6D7F0B92A18E00C2DC85 /* ThreadCheck.mm */,
 				6593923909AE435C002C531F /* URLMac.mm */,
 				868160D3187669E70021E79D /* UserActivityMac.mm */,
+				83C45B8B1DC2B663008871BA /* ValidationBubbleMac.mm */,
 				CDC69DD816371FD3007C38DF /* WebCoreFullScreenPlaceholderView.h */,
 				CDC69DD916371FD3007C38DF /* WebCoreFullScreenPlaceholderView.mm */,
 				CDC69DD41632026C007C38DF /* WebCoreFullScreenWarningView.h */,
@@ -19334,6 +19341,7 @@
 				44C9919E0F3D210E00586670 /* ThemeIOS.mm */,
 				1F72BF08187FD4270009BCB3 /* TileControllerMemoryHandlerIOS.cpp */,
 				1F72BF09187FD4270009BCB3 /* TileControllerMemoryHandlerIOS.h */,
+				837B7D1F1DC3F54C00D051FC /* ValidationBubbleIOS.mm */,
 				CDA29A2C1CBF73FC00901CCF /* WebAVPlayerController.h */,
 				CDA29A2D1CBF73FC00901CCF /* WebAVPlayerController.mm */,
 				31403797124BEA7F00AF40E4 /* WebCoreMotionManager.h */,
@@ -22358,6 +22366,7 @@
 				71C916071D1483A300ACA47D /* UserInterfaceLayoutDirection.h */,
 				2E3BBF051162DA1100B9409A /* UUID.cpp */,
 				2E3BBF061162DA1100B9409A /* UUID.h */,
+				83C45B8D1DC2B67C008871BA /* ValidationBubble.h */,
 				9A1142031832D134000BB8AD /* ValueToString.h */,
 				46DB7D581B20FE58005651B2 /* VNodeTracker.cpp */,
 				46DB7D591B20FE58005651B2 /* VNodeTracker.h */,
@@ -26428,6 +26437,7 @@
 				1B124D8D1D380B7000ECDFB0 /* MediaSampleAVFObjC.h in Headers */,
 				CDBEAEAD19D92B6C00BEBA88 /* MediaSelectionGroupAVFObjC.h in Headers */,
 				C9027F421B1D0AD200BFBFEF /* MediaSession.h in Headers */,
+				83C45B8E1DC2B68A008871BA /* ValidationBubble.h in Headers */,
 				C9F87CFE1B28F40E00979B83 /* MediaSessionEvents.h in Headers */,
 				C96F5EC81B5872260091EA9D /* MediaSessionInterruptionProvider.h in Headers */,
 				C96F5EC51B5872260091EA9D /* MediaSessionInterruptionProviderMac.h in Headers */,
@@ -29328,6 +29338,7 @@
 				577483161DAEC32300716EF9 /* JSAesKeyGenParams.cpp in Sources */,
 				FDA15EC912B03F50003A583A /* JSAnalyserNode.cpp in Sources */,
 				31A795C61888BADC00382F90 /* JSANGLEInstancedArrays.cpp in Sources */,
+				83C45B8C1DC2B667008871BA /* ValidationBubbleMac.mm in Sources */,
 				12A253E21C8FFF6600C22295 /* JSAnimatable.cpp in Sources */,
 				120DE3FE1C87E18800B6D4DD /* JSAnimationEffect.cpp in Sources */,
 				3198480B1A1E6CE400A13318 /* JSAnimationEvent.cpp in Sources */,
@@ -29546,6 +29557,7 @@
 				E44614370CD689C400FADA75 /* JSHTMLAudioElement.cpp in Sources */,
 				A80E7B120A19D606007FB8C5 /* JSHTMLBaseElement.cpp in Sources */,
 				1AE2AA220A1CDAB400B42B25 /* JSHTMLBodyElement.cpp in Sources */,
+				837B7D201DC3F55000D051FC /* ValidationBubbleIOS.mm in Sources */,
 				1AE2AA240A1CDAB400B42B25 /* JSHTMLBRElement.cpp in Sources */,
 				A80E7EA00A1A83E3007FB8C5 /* JSHTMLButtonElement.cpp in Sources */,
 				938E666009F09B81008A48EC /* JSHTMLCanvasElement.cpp in Sources */,

Modified: trunk/Source/WebCore/html/HTMLFormControlElement.cpp (208360 => 208361)


--- 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)
@@ -517,7 +517,7 @@
 
 void HTMLFormControlElement::focusAndShowValidationMessage()
 {
-    scrollIntoViewIfNeeded(false);
+    // Calling focus() will scroll the element into view.
     focus();
     updateVisibleValidationMessage();
 }

Modified: trunk/Source/WebCore/html/ValidationMessage.cpp (208360 => 208361)


--- 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)
@@ -76,6 +76,14 @@
 
 void ValidationMessage::updateValidationMessage(const String& message)
 {
+    // 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;
+    }
+
     String updatedMessage = message;
     if (!validationMessageClient()) {
         // HTML5 specification doesn't ask UA to show the title attribute value

Modified: trunk/Source/WebCore/page/Page.cpp (208360 => 208361)


--- 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)
@@ -94,6 +94,7 @@
 #include "TextResourceDecoder.h"
 #include "UserContentProvider.h"
 #include "UserInputBridge.h"
+#include "ValidationMessageClient.h"
 #include "VisitedLinkState.h"
 #include "VisitedLinkStore.h"
 #include "VoidCallback.h"
@@ -182,7 +183,7 @@
     , m_theme(RenderTheme::themeForPage(this))
     , m_editorClient(WTFMove(pageConfiguration.editorClient))
     , m_plugInClient(pageConfiguration.plugInClient)
-    , m_validationMessageClient(pageConfiguration.validationMessageClient)
+    , m_validationMessageClient(WTFMove(pageConfiguration.validationMessageClient))
     , m_diagnosticLoggingClient(WTFMove(pageConfiguration.diagnosticLoggingClient))
     , m_subframeCount(0)
     , m_openedByDOM(false)
@@ -270,6 +271,7 @@
 
 Page::~Page()
 {
+    m_validationMessageClient = nullptr;
     m_diagnosticLoggingClient = nullptr;
     m_mainFrame->setView(nullptr);
     setGroupName(String());

Modified: trunk/Source/WebCore/page/Page.h (208360 => 208361)


--- 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)
@@ -205,7 +205,7 @@
 #if ENABLE(POINTER_LOCK)
     PointerLockController& pointerLockController() const { return *m_pointerLockController; }
 #endif
-    ValidationMessageClient* validationMessageClient() const { return m_validationMessageClient; }
+    ValidationMessageClient* validationMessageClient() const { return m_validationMessageClient.get(); }
 
     WEBCORE_EXPORT ScrollingCoordinator* scrollingCoordinator();
 
@@ -592,7 +592,7 @@
 
     UniqueRef<EditorClient> m_editorClient;
     PlugInClient* m_plugInClient;
-    ValidationMessageClient* m_validationMessageClient;
+    std::unique_ptr<ValidationMessageClient> m_validationMessageClient;
     std::unique_ptr<DiagnosticLoggingClient> m_diagnosticLoggingClient;
 
     int m_subframeCount;

Modified: trunk/Source/WebCore/page/PageConfiguration.cpp (208360 => 208361)


--- 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)
@@ -35,6 +35,7 @@
 #include "SocketProvider.h"
 #include "StorageNamespaceProvider.h"
 #include "UserContentController.h"
+#include "ValidationMessageClient.h"
 #include "VisitedLinkStore.h"
 
 namespace WebCore {

Modified: trunk/Source/WebCore/page/PageConfiguration.h (208360 => 208361)


--- 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)
@@ -77,9 +77,9 @@
     PlugInClient* plugInClient { nullptr };
     ProgressTrackerClient* progressTrackerClient { nullptr };
     RefPtr<BackForwardClient> backForwardClient;
-    ValidationMessageClient* validationMessageClient { nullptr };
+    std::unique_ptr<ValidationMessageClient> validationMessageClient;
     FrameLoaderClient* loaderClientForMainFrame { nullptr };
-    std::unique_ptr<DiagnosticLoggingClient> diagnosticLoggingClient { nullptr };
+    std::unique_ptr<DiagnosticLoggingClient> diagnosticLoggingClient;
 
     RefPtr<ApplicationCacheStorage> applicationCacheStorage;
     RefPtr<DatabaseProvider> databaseProvider;

Copied: trunk/Source/WebCore/platform/ValidationBubble.h (from rev 208360, trunk/Tools/DumpRenderTree/mac/UIScriptControllerMac.mm) (0 => 208361)


--- trunk/Source/WebCore/platform/ValidationBubble.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/ValidationBubble.h	2016-11-04 01:38:31 UTC (rev 208361)
@@ -0,0 +1,81 @@
+/*
+ * 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 "IntRect.h"
+#include <wtf/Forward.h>
+#include <wtf/text/WTFString.h>
+
+#if PLATFORM(COCOA)
+#include <wtf/RetainPtr.h>
+#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& message);
+    WEBCORE_EXPORT ~ValidationBubble();
+
+    const String& message() const { return m_message; }
+
+#if PLATFORM(IOS)
+    WEBCORE_EXPORT void setAnchorRect(const IntRect& anchorRect, UIViewController* presentingViewController);
+    WEBCORE_EXPORT void show();
+#else
+    WEBCORE_EXPORT void showRelativeTo(const IntRect& anchorRect);
+#endif
+
+private:
+    PlatformView* m_view;
+    String m_message;
+#if PLATFORM(MAC)
+    RetainPtr<NSPopover> m_popover;
+#elif PLATFORM(IOS)
+    RetainPtr<UIViewController> m_popoverController;
+    RetainPtr<WebValidationBubbleDelegate> m_popoverDelegate;
+    UIViewController *m_presentingViewController;
+#endif
+};
+
+}

Added: trunk/Source/WebCore/platform/ios/ValidationBubbleIOS.mm (0 => 208361)


--- 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)
@@ -0,0 +1,110 @@
+/*
+ * 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 "config.h"
+
+#if PLATFORM(IOS)
+#import "ValidationBubble.h"
+
+#import "SoftLinking.h"
+#import "UIKitSPI.h"
+#import <wtf/text/WTFString.h>
+
+SOFT_LINK_FRAMEWORK(UIKit);
+SOFT_LINK_CLASS(UIKit, UILabel);
+SOFT_LINK_CLASS(UIKit, UIView);
+SOFT_LINK_CLASS(UIKit, UIViewController);
+
+@interface WebValidationBubbleDelegate : NSObject <UIPopoverPresentationControllerDelegate> {
+}
+@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& message)
+    : m_view(view)
+    , m_message(message)
+{
+    m_popoverController = adoptNS([[getUIViewControllerClass() alloc] init]);
+    [m_popoverController setModalPresentationStyle:UIModalPresentationPopover];
+
+    RetainPtr<UIView> popoverView = adoptNS([[getUIViewClass() alloc] initWithFrame:CGRectZero]);
+    [m_popoverController setView:popoverView.get()];
+
+    RetainPtr<UILabel> 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& 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)

Added: trunk/Source/WebCore/platform/mac/ValidationBubbleMac.mm (0 => 208361)


--- 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)
@@ -0,0 +1,78 @@
+/*
+ * 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 "config.h"
+
+#if PLATFORM(MAC)
+#import "ValidationBubble.h"
+
+#import <AppKit/AppKit.h>
+#import <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+static const CGFloat horizontalPadding = 5;
+static const CGFloat verticalPadding = 5;
+static const CGFloat maxLabelWidth = 300;
+
+ValidationBubble::ValidationBubble(NSView* view, const String& message)
+    : m_view(view)
+    , m_message(message)
+{
+    RetainPtr<NSViewController> controller = adoptNS([[NSViewController alloc] init]);
+
+    RetainPtr<NSView> popoverView = adoptNS([[NSView alloc] initWithFrame:NSZeroRect]);
+    [controller setView:popoverView.get()];
+
+    RetainPtr<NSTextField> 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& 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)

Modified: trunk/Source/WebKit2/ChangeLog (208360 => 208361)


--- 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)
@@ -1,3 +1,70 @@
+2016-11-03  Chris Dumez  <[email protected]>
+
+        [WK2][Cocoa] Implement user interface for HTML form validation
+        https://bugs.webkit.org/show_bug.cgi?id=164143
+        <rdar://problem/28944652>
+
+        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):
+
 2016-11-03  Tim Horton  <[email protected]>
 
         Printing to PDF should produce internal links when HTML has internal links

Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm (208360 => 208361)


--- 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)
@@ -93,6 +93,7 @@
 #import <WebCore/RuntimeApplicationChecks.h>
 #import <WebCore/Settings.h>
 #import <WebCore/TextStream.h>
+#import <WebCore/ValidationBubble.h>
 #import <WebCore/WritingMode.h>
 #import <wtf/HashMap.h>
 #import <wtf/MathExtras.h>
@@ -524,6 +525,7 @@
     [center addObserver:self selector:@selector(_keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
     [center addObserver:self selector:@selector(_keyboardDidChangeFrame:) name:UIKeyboardDidChangeFrameNotification object:nil];
     [center addObserver:self selector:@selector(_keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
+    [center addObserver:self selector:@selector(_keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
     [center addObserver:self selector:@selector(_keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
     [center addObserver:self selector:@selector(_windowDidRotate:) name:UIWindowDidRotateNotification object:nil];
     [center addObserver:self selector:@selector(_contentSizeCategoryDidChange:) name:UIContentSizeCategoryDidChangeNotification object:nil];
@@ -2177,8 +2179,15 @@
 {
     if ([self _shouldUpdateKeyboardWithInfo:notification.userInfo])
         [self _keyboardChangedWithInfo:notification.userInfo adjustScrollView:YES];
+
+    _page->setIsKeyboardAnimatingIn(true);
 }
 
+- (void)_keyboardDidShow:(NSNotification *)notification
+{
+    _page->setIsKeyboardAnimatingIn(false);
+}
+
 - (void)_keyboardWillHide:(NSNotification *)notification
 {
     // Ignore keyboard will hide notifications sent during rotation. They're just there for
@@ -4527,8 +4536,23 @@
 
 @implementation WKWebView (WKTesting)
 
+- (NSDictionary *)_contentsOfUserInterfaceItem:(NSString *)userInterfaceItem
+{
+    if ([userInterfaceItem isEqualToString:@"validationBubble"]) {
+        auto* validationBubble = _page->validationBubble();
+        String message = validationBubble ? validationBubble->message() : emptyString();
+        return @{ userInterfaceItem: @{ @"message": (NSString *)message } };
+    }
+
 #if PLATFORM(IOS)
+    return [_contentView _contentsOfUserInterfaceItem:(NSString *)userInterfaceItem];
+#else
+    return nil;
+#endif
+}
 
+#if PLATFORM(IOS)
+
 - (CGRect)_contentVisibleRect
 {
     return [self convertRect:[self bounds] toView:self._currentContentView];
@@ -4564,11 +4588,6 @@
     [_contentView selectFormAccessoryPickerRow:rowIndex];
 }
 
-- (NSDictionary *)_contentsOfUserInterfaceItem:(NSString *)userInterfaceItem
-{
-    return [_contentView _contentsOfUserInterfaceItem:(NSString *)userInterfaceItem];
-}
-
 - (void)didStartFormControlInteraction
 {
     // For subclasses to override.

Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h (208360 => 208361)


--- 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)
@@ -257,6 +257,8 @@
 
 @interface WKWebView (WKTesting)
 
+- (NSDictionary *)_contentsOfUserInterfaceItem:(NSString *)userInterfaceItem WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
+
 #if TARGET_OS_IPHONE
 
 @property (nonatomic, readonly) CGRect _contentVisibleRect WK_API_AVAILABLE(ios(10.0));
@@ -267,7 +269,6 @@
 - (void)keyboardAccessoryBarPrevious WK_API_AVAILABLE(ios(10.0));
 - (void)dismissFormAccessoryView WK_API_AVAILABLE(ios(WK_IOS_TBA));
 - (void)selectFormAccessoryPickerRow:(int)rowIndex WK_API_AVAILABLE(ios(WK_IOS_TBA));
-- (NSDictionary *)_contentsOfUserInterfaceItem:(NSString *)userInterfaceItem WK_API_AVAILABLE(ios(WK_IOS_TBA));
 
 - (void)didStartFormControlInteraction WK_API_AVAILABLE(ios(WK_IOS_TBA));
 - (void)didEndFormControlInteraction WK_API_AVAILABLE(ios(WK_IOS_TBA));

Modified: trunk/Source/WebKit2/UIProcess/Cocoa/WebPageProxyCocoa.mm (208360 => 208361)


--- 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)
@@ -30,8 +30,8 @@
 #import "DataDetectionResult.h"
 #import "LoadParameters.h"
 #import "WebProcessProxy.h"
-
 #import <WebCore/SearchPopupMenuCocoa.h>
+#import <WebCore/ValidationBubble.h>
 #import <wtf/cf/TypeCastsCF.h>
 
 namespace WebKit {

Modified: trunk/Source/WebKit2/UIProcess/PageClient.h (208360 => 208361)


--- 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)
@@ -49,6 +49,7 @@
 namespace WebCore {
 class Cursor;
 class TextIndicator;
+class ValidationBubble;
 class WebMediaSessionManager;
 enum class TextIndicatorWindowLifetime : uint8_t;
 enum class TextIndicatorWindowDismissalAnimation : uint8_t;
@@ -227,6 +228,10 @@
 #endif
 
 #if PLATFORM(COCOA)
+    virtual std::unique_ptr<WebCore::ValidationBubble> createValidationBubble(const String& message) = 0;
+#endif
+
+#if PLATFORM(COCOA)
     virtual void setTextIndicator(Ref<WebCore::TextIndicator>, WebCore::TextIndicatorWindowLifetime) = 0;
     virtual void clearTextIndicator(WebCore::TextIndicatorWindowDismissalAnimation) = 0;
     virtual void setTextIndicatorAnimationProgress(float) = 0;

Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (208360 => 208361)


--- 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)
@@ -123,6 +123,7 @@
 #include <WebCore/TextCheckerClient.h>
 #include <WebCore/TextIndicator.h>
 #include <WebCore/URL.h>
+#include <WebCore/ValidationBubble.h>
 #include <WebCore/WindowFeatures.h>
 #include <stdio.h>
 #include <wtf/NeverDestroyed.h>
@@ -1928,6 +1929,8 @@
     if (!isValid())
         return;
 
+    hideValidationMessage();
+
     if (!m_currentlyProcessedWheelEvents.isEmpty()) {
         m_wheelEventQueue.append(event);
         if (m_wheelEventQueue.size() < wheelEventQueueSizeThreshold)
@@ -2465,6 +2468,8 @@
     if (m_pageZoomFactor == zoomFactor)
         return;
 
+    hideValidationMessage();
+
     m_pageZoomFactor = zoomFactor;
     m_process->send(Messages::WebPage::SetPageZoomFactor(m_pageZoomFactor), m_pageID); 
 }
@@ -2477,6 +2482,8 @@
     if (m_pageZoomFactor == pageZoomFactor && m_textZoomFactor == textZoomFactor)
         return;
 
+    hideValidationMessage();
+
     m_pageZoomFactor = pageZoomFactor;
     m_textZoomFactor = textZoomFactor;
     m_process->send(Messages::WebPage::SetPageAndTextZoomFactors(m_pageZoomFactor, m_textZoomFactor), m_pageID); 
@@ -4103,6 +4110,13 @@
 void WebPageProxy::pageDidScroll()
 {
     m_uiClient->pageDidScroll(this);
+
+#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();
 }
 
 void WebPageProxy::runOpenPanel(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, const FileChooserSettings& settings)
@@ -5306,6 +5320,7 @@
     m_scrollingPerformanceData = nullptr;
 #endif
     m_drawingArea = nullptr;
+    hideValidationMessage();
 
     if (m_inspector) {
         m_inspector->invalidate();
@@ -5378,6 +5393,8 @@
     m_dynamicViewportSizeUpdateLayerTreeTransactionID = 0;
     m_layerTreeTransactionIdAtLastTouchStart = 0;
     m_hasNetworkRequestsOnSuspended = false;
+    m_isKeyboardAnimatingIn = false;
+    m_isScrollingOrZooming = false;
 #endif
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
@@ -6639,6 +6656,13 @@
 
     m_process->send(Messages::WebPage::SetUserInterfaceLayoutDirection(static_cast<uint32_t>(userInterfaceLayoutDirection)), m_pageID);
 }
+
+void WebPageProxy::hideValidationMessage()
+{
+#if PLATFORM(COCOA)
+    m_validationBubble = nullptr;
+#endif
+}
     
 #if ENABLE(POINTER_LOCK)
 void WebPageProxy::requestPointerLock()

Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (208360 => 208361)


--- 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)
@@ -153,6 +153,7 @@
 class RunLoopObserver;
 class SharedBuffer;
 class TextIndicator;
+class ValidationBubble;
 enum class HasInsecureContent;
 struct DictionaryPopupInfo;
 struct ExceptionDetails;
@@ -527,6 +528,7 @@
     void getSelectionContext(std::function<void(const String&, const String&, const String&, CallbackBase::Error)>);
     void handleTwoFingerTapAtPoint(const WebCore::IntPoint&, uint64_t requestID);
     void setForceAlwaysUserScalable(bool);
+    void setIsScrollingOrZooming(bool);
 #endif
 #if ENABLE(DATA_DETECTION)
     void setDataDetectionResult(const DataDetectionResult&);
@@ -1093,6 +1095,17 @@
     void logSampledDiagnosticMessageWithResult(const String& message, const String& description, uint32_t result);
     void logSampledDiagnosticMessageWithValue(const String& message, const String& description, const String& value);
 
+    // Form validation messages.
+    void showValidationMessage(const WebCore::IntRect& anchorClientRect, const String& 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
+
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
     void addPlaybackTargetPickerClient(uint64_t);
     void removePlaybackTargetPickerClient(uint64_t);
@@ -1626,6 +1639,8 @@
     uint64_t m_layerTreeTransactionIdAtLastTouchStart;
     uint64_t m_currentDynamicViewportSizeUpdateID { 0 };
     bool m_hasNetworkRequestsOnSuspended;
+    bool m_isKeyboardAnimatingIn { false };
+    bool m_isScrollingOrZooming { false };
 #endif
 
 #if ENABLE(VIBRATION)
@@ -1777,6 +1792,9 @@
 #if ENABLE(INPUT_TYPE_COLOR)
     RefPtr<WebColorPicker> m_colorPicker;
 #endif
+#if PLATFORM(COCOA)
+    std::unique_ptr<WebCore::ValidationBubble> m_validationBubble;
+#endif
 
     const uint64_t m_pageID;
     const WebCore::SessionID m_sessionID;

Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in (208360 => 208361)


--- 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)
@@ -64,6 +64,11 @@
     ScreenToRootView(WebCore::IntPoint screenPoint) -> (WebCore::IntPoint windowPoint)
     RootViewToScreen(WebCore::IntRect rect) -> (WebCore::IntRect screenFrame)
 
+#if PLATFORM(COCOA)
+    ShowValidationMessage(WebCore::IntRect anchorRect, String message)
+    HideValidationMessage()
+#endif
+
 #if PLATFORM(IOS)
     AccessibilityScreenToRootView(WebCore::IntPoint screenPoint) -> (WebCore::IntPoint windowPoint)
     RootViewToAccessibilityScreen(WebCore::IntRect rect) -> (WebCore::IntRect screenFrame)

Modified: trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.h (208360 => 208361)


--- 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)
@@ -96,6 +96,8 @@
 #if ENABLE(CONTEXT_MENUS)
     std::unique_ptr<WebContextMenuProxy> createContextMenuProxy(WebPageProxy&, const ContextMenuContextData&, const UserData&) override;
 #endif
+    std::unique_ptr<WebCore::ValidationBubble> createValidationBubble(const String& message) final;
+
     void setTextIndicator(Ref<WebCore::TextIndicator>, WebCore::TextIndicatorWindowLifetime) override;
     void clearTextIndicator(WebCore::TextIndicatorWindowDismissalAnimation) override;
     void setTextIndicatorAnimationProgress(float) override;

Modified: trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm (208360 => 208361)


--- 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)
@@ -51,6 +51,7 @@
 #import <WebCore/PlatformScreen.h>
 #import <WebCore/SharedBuffer.h>
 #import <WebCore/TextIndicator.h>
+#import <WebCore/ValidationBubble.h>
 
 #define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, m_webView->_page->process().connection())
 
@@ -743,6 +744,11 @@
     return ([UIView userInterfaceLayoutDirectionForSemanticContentAttribute:[m_webView semanticContentAttribute]] == UIUserInterfaceLayoutDirectionLeftToRight) ? WebCore::UserInterfaceLayoutDirection::LTR : WebCore::UserInterfaceLayoutDirection::RTL;
 }
 
+std::unique_ptr<ValidationBubble> PageClientImpl::createValidationBubble(const String& message)
+{
+    return std::make_unique<ValidationBubble>(m_contentView, message);
+}
+
 } // namespace WebKit
 
 #endif // PLATFORM(IOS)

Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm (208360 => 208361)


--- 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)
@@ -1591,10 +1591,13 @@
 {
     [_webSelectionAssistant willStartScrollingOrZoomingPage];
     [_textSelectionAssistant willStartScrollingOverflow];
+    _page->setIsScrollingOrZooming(true);
 }
 
 - (void)scrollViewWillStartPanOrPinchGesture
 {
+    _page->hideValidationMessage();
+
     _canSendTouchEventsAsynchronously = YES;
 }
 
@@ -1602,6 +1605,7 @@
 {
     [_webSelectionAssistant didEndScrollingOrZoomingPage];
     [_textSelectionAssistant didEndScrollingOverflow];
+    _page->setIsScrollingOrZooming(false);
 }
 
 - (BOOL)requiresAccessoryView

Modified: trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm (208360 => 208361)


--- 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)
@@ -50,6 +50,7 @@
 #import <WebCore/PlatformScreen.h>
 #import <WebCore/SharedBuffer.h>
 #import <WebCore/UserAgent.h>
+#import <WebCore/ValidationBubble.h>
 
 #if USE(QUICK_LOOK)
 #import "APILoaderClient.h"
@@ -267,6 +268,8 @@
     if (!isValid())
         return;
 
+    hideValidationMessage();
+
     m_dynamicViewportSizeUpdateWaitingForTarget = true;
     m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit = true;
     m_process->send(Messages::WebPage::DynamicViewportSizeUpdate(minimumLayoutSize, maximumUnobscuredSize, targetExposedContentRect, targetUnobscuredRect, targetUnobscuredRectInScrollViewCoordinates, targetScale, deviceOrientation, ++m_currentDynamicViewportSizeUpdateID), m_pageID);
@@ -752,6 +755,7 @@
 
 void WebPageProxy::potentialTapAtPosition(const WebCore::FloatPoint& position, uint64_t& requestID)
 {
+    hideValidationMessage();
     process().send(Messages::WebPage::PotentialTapAtPosition(requestID, position), m_pageID);
 }
 
@@ -1009,6 +1013,27 @@
     m_pageClient.selectionDidChange();
 }
 
+void WebPageProxy::showValidationMessage(const IntRect& anchorClientRect, const String& message)
+{
+    m_validationBubble = m_pageClient.createValidationBubble(message);
+    m_validationBubble->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->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 && m_validationBubble)
+        m_validationBubble->show();
+}
+
 #if USE(QUICK_LOOK)
     
 void WebPageProxy::didStartLoadForQuickLookDocumentInMainFrame(const String& fileName, const String& uti)

Modified: trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h (208360 => 208361)


--- 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)
@@ -131,6 +131,8 @@
     RefPtr<WebColorPicker> createColorPicker(WebPageProxy*, const WebCore::Color& initialColor, const WebCore::IntRect&) override;
 #endif
 
+    std::unique_ptr<WebCore::ValidationBubble> createValidationBubble(const String& message) final;
+
     void setTextIndicator(Ref<WebCore::TextIndicator>, WebCore::TextIndicatorWindowLifetime) override;
     void clearTextIndicator(WebCore::TextIndicatorWindowDismissalAnimation) override;
     void setTextIndicatorAnimationProgress(float) override;

Modified: trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm (208360 => 208361)


--- 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)
@@ -67,6 +67,7 @@
 #import <WebCore/TextIndicator.h>
 #import <WebCore/TextIndicatorWindow.h>
 #import <WebCore/TextUndoInsertionMarkupMac.h>
+#import <WebCore/ValidationBubble.h>
 #import <WebKitSystemInterface.h>
 #import <wtf/text/CString.h>
 #import <wtf/text/WTFString.h>
@@ -439,6 +440,11 @@
 }
 #endif
 
+std::unique_ptr<ValidationBubble> PageClientImpl::createValidationBubble(const String& message)
+{
+    return std::make_unique<ValidationBubble>(m_view, message);
+}
+
 void PageClientImpl::setTextIndicator(Ref<TextIndicator> textIndicator, WebCore::TextIndicatorWindowLifetime lifetime)
 {
     m_impl->setTextIndicator(textIndicator.get(), lifetime);

Modified: trunk/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm (208360 => 208361)


--- 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)
@@ -54,6 +54,7 @@
 #import <WebCore/SharedBuffer.h>
 #import <WebCore/TextAlternativeWithRange.h>
 #import <WebCore/UserAgent.h>
+#import <WebCore/ValidationBubble.h>
 #import <mach-o/dyld.h>
 #import <wtf/text/StringConcatenate.h>
 
@@ -594,6 +595,12 @@
     windowRect = m_pageClient.rootViewToWindow(viewRect);
 }
 
+void WebPageProxy::showValidationMessage(const IntRect& anchorClientRect, const String& message)
+{
+    m_validationBubble = m_pageClient.createValidationBubble(message);
+    m_validationBubble->showRelativeTo(anchorClientRect);
+}
+
 #if WK_API_ENABLED
 NSView *WebPageProxy::inspectorAttachmentView()
 {

Modified: trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj (208360 => 208361)


--- 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)
@@ -1216,6 +1216,8 @@
 		83BFAC421D96137C00433490 /* BlobDownloadClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 83BFAC401D96136000433490 /* BlobDownloadClient.h */; };
 		83BFAC431D96137C00433490 /* BlobDownloadClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83BFAC411D96136000433490 /* BlobDownloadClient.cpp */; };
 		83D454D71BE9D3C4006C93BD /* NetworkLoadClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 83D454D61BE9D3C4006C93BD /* NetworkLoadClient.h */; };
+		83EE575B1DB7D61100C74C50 /* WebValidationMessageClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83EE57591DB7D60600C74C50 /* WebValidationMessageClient.cpp */; };
+		83EE575C1DB7D61100C74C50 /* WebValidationMessageClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 83EE575A1DB7D60600C74C50 /* WebValidationMessageClient.h */; };
 		84477853176FCC0800CDC7BB /* InjectedBundleHitTestResultMediaType.h in Headers */ = {isa = PBXBuildFile; fileRef = 84477851176FCAC100CDC7BB /* InjectedBundleHitTestResultMediaType.h */; };
 		868160D0187645570021E79D /* WindowServerConnection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 868160CF187645370021E79D /* WindowServerConnection.mm */; };
 		86E67A251910B9D100004AB7 /* ProcessThrottler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E67A21190F411800004AB7 /* ProcessThrottler.h */; };
@@ -3321,6 +3323,8 @@
 		83BFAC401D96136000433490 /* BlobDownloadClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BlobDownloadClient.h; path = NetworkProcess/Downloads/BlobDownloadClient.h; sourceTree = "<group>"; };
 		83BFAC411D96136000433490 /* BlobDownloadClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BlobDownloadClient.cpp; path = NetworkProcess/Downloads/BlobDownloadClient.cpp; sourceTree = "<group>"; };
 		83D454D61BE9D3C4006C93BD /* NetworkLoadClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NetworkLoadClient.h; path = NetworkProcess/NetworkLoadClient.h; sourceTree = "<group>"; };
+		83EE57591DB7D60600C74C50 /* WebValidationMessageClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebValidationMessageClient.cpp; sourceTree = "<group>"; };
+		83EE575A1DB7D60600C74C50 /* WebValidationMessageClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebValidationMessageClient.h; sourceTree = "<group>"; };
 		84477851176FCAC100CDC7BB /* InjectedBundleHitTestResultMediaType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InjectedBundleHitTestResultMediaType.h; sourceTree = "<group>"; };
 		868160CD18763D4B0021E79D /* WindowServerConnection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WindowServerConnection.h; sourceTree = "<group>"; };
 		868160CF187645370021E79D /* WindowServerConnection.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = WindowServerConnection.mm; sourceTree = "<group>"; };
@@ -6035,6 +6039,8 @@
 				D3B9484511FF4B6500032B39 /* WebSearchPopupMenu.h */,
 				4A410F4819AF7B80002EBAB5 /* WebUserMediaClient.cpp */,
 				4A410F4919AF7B80002EBAB5 /* WebUserMediaClient.h */,
+				83EE57591DB7D60600C74C50 /* WebValidationMessageClient.cpp */,
+				83EE575A1DB7D60600C74C50 /* WebValidationMessageClient.h */,
 			);
 			path = WebCoreSupport;
 			sourceTree = "<group>";
@@ -7808,6 +7814,7 @@
 				BCC43ABB127B95DC00317F16 /* PlatformPopupMenuData.h in Headers */,
 				1A6FB7D311E651E200DB1371 /* Plugin.h in Headers */,
 				31A67E0D165B2A99006CBA66 /* PlugInAutoStartProvider.h in Headers */,
+				83EE575C1DB7D61100C74C50 /* WebValidationMessageClient.h in Headers */,
 				1A9FBA8D13FF04E600DEED67 /* PluginComplexTextInputState.h in Headers */,
 				1AA56F2911E92BC80061B882 /* PluginController.h in Headers */,
 				1A8EF4CB1252403700F7067F /* PluginControllerProxy.h in Headers */,
@@ -9730,6 +9737,7 @@
 				0FCB4E5118BBE044000FCFC9 /* WKGeolocationProviderIOSObjCSecurityOrigin.mm in Sources */,
 				0F174AA7142AAC610039250F /* WKGeometry.cpp in Sources */,
 				B62E7310143047A60069EC35 /* WKHitTestResult.cpp in Sources */,
+				83EE575B1DB7D61100C74C50 /* WebValidationMessageClient.cpp in Sources */,
 				5110AE0C133C16CB0072717A /* WKIconDatabase.cpp in Sources */,
 				5123CF1B133D260A0056F800 /* WKIconDatabaseCG.cpp in Sources */,
 				BCCF6AC212C91F34008F9C35 /* WKImage.cpp in Sources */,

Copied: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebValidationMessageClient.cpp (from rev 208360, trunk/Tools/DumpRenderTree/mac/UIScriptControllerMac.mm) (0 => 208361)


--- 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)
@@ -0,0 +1,72 @@
+/*
+ * 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 "config.h"
+#include "WebValidationMessageClient.h"
+
+#include "WebPage.h"
+#include "WebPageProxyMessages.h"
+#include <WebCore/Element.h>
+#include <WebCore/Frame.h>
+
+namespace WebKit {
+
+using namespace WebCore;
+
+WebValidationMessageClient::WebValidationMessageClient(WebPage& page)
+    : m_page(page)
+{
+}
+
+WebValidationMessageClient::~WebValidationMessageClient()
+{
+    if (m_currentAnchor)
+        hideValidationMessage(*m_currentAnchor);
+}
+
+void WebValidationMessageClient::showValidationMessage(const Element& anchor, const String& message)
+{
+    if (m_currentAnchor)
+        hideValidationMessage(*m_currentAnchor);
+
+    m_currentAnchor = &anchor;
+    m_page.send(Messages::WebPageProxy::ShowValidationMessage(anchor.clientRect(), message));
+}
+
+void WebValidationMessageClient::hideValidationMessage(const Element& anchor)
+{
+    if (!isValidationMessageVisible(anchor))
+        return;
+
+    m_currentAnchor = nullptr;
+    m_page.send(Messages::WebPageProxy::HideValidationMessage());
+}
+
+bool WebValidationMessageClient::isValidationMessageVisible(const Element& anchor)
+{
+    return m_currentAnchor == &anchor;
+}
+
+} // namespace WebKit

Copied: trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebValidationMessageClient.h (from rev 208360, trunk/Tools/DumpRenderTree/mac/UIScriptControllerMac.mm) (0 => 208361)


--- 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)
@@ -0,0 +1,50 @@
+/*
+ * 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 <WebCore/IntRect.h>
+#include <WebCore/ValidationMessageClient.h>
+
+namespace WebKit {
+
+class WebPage;
+
+class WebValidationMessageClient final : public WebCore::ValidationMessageClient {
+public:
+    explicit WebValidationMessageClient(WebPage&);
+    ~WebValidationMessageClient();
+
+    // ValidationMessageClient API.
+    void showValidationMessage(const WebCore::Element& anchor, const String& message) final;
+    void hideValidationMessage(const WebCore::Element& anchor) final;
+    bool isValidationMessageVisible(const WebCore::Element& anchor) final;
+
+private:
+    WebPage& m_page;
+    const WebCore::Element* m_currentAnchor { nullptr };
+};
+
+}

Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp (208360 => 208361)


--- 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)
@@ -112,6 +112,7 @@
 #include "WebUndoStep.h"
 #include "WebUserContentController.h"
 #include "WebUserMediaClient.h"
+#include "WebValidationMessageClient.h"
 #include <_javascript_Core/APICast.h>
 #include <WebCore/ApplicationCacheStorage.h>
 #include <WebCore/ArchiveResource.h>
@@ -409,6 +410,10 @@
     pageConfiguration.progressTrackerClient = new WebProgressTrackerClient(*this);
     pageConfiguration.diagnosticLoggingClient = std::make_unique<WebDiagnosticLoggingClient>(*this);
 
+#if PLATFORM(COCOA)
+    pageConfiguration.validationMessageClient = std::make_unique<WebValidationMessageClient>(*this);
+#endif
+
     pageConfiguration.applicationCacheStorage = &WebProcess::singleton().applicationCacheStorage();
     pageConfiguration.databaseProvider = WebDatabaseProvider::getOrCreate(m_pageGroup->pageGroupID());
     pageConfiguration.pluginInfoProvider = &WebPluginInfoProvider::singleton();

Modified: trunk/Tools/ChangeLog (208360 => 208361)


--- trunk/Tools/ChangeLog	2016-11-04 01:37:01 UTC (rev 208360)
+++ trunk/Tools/ChangeLog	2016-11-04 01:38:31 UTC (rev 208361)
@@ -1,3 +1,22 @@
+2016-11-03  Chris Dumez  <[email protected]>
+
+        [WK2][Cocoa] Implement user interface for HTML form validation
+        https://bugs.webkit.org/show_bug.cgi?id=164143
+        <rdar://problem/28944652>
+
+        Reviewed by Simon Fraser.
+
+        Add support for UIScriptController::contentsOfUserInterfaceItem("validationBubble")
+        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):
+
 2016-11-03  Konstantin Tokarev  <[email protected]>
 
         Fixes to build JSCOnly on macOS

Modified: trunk/Tools/DumpRenderTree/mac/UIScriptControllerMac.mm (208360 => 208361)


--- 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)
@@ -64,6 +64,11 @@
     });
 }
 
+JSObjectRef UIScriptController::contentsOfUserInterfaceItem(JSStringRef interfaceItem) const
+{
+    return nullptr;
 }
 
+}
+
 #endif // PLATFORM(MAC)

Modified: trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp (208360 => 208361)


--- 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)
@@ -161,6 +161,11 @@
 void UIScriptController::zoomToScale(double, JSValueRef)
 {
 }
+
+JSObjectRef UIScriptController::contentsOfUserInterfaceItem(JSStringRef interfaceItem) const
+{
+    return nullptr;
+}
 #endif
 
 #if !PLATFORM(IOS)
@@ -235,11 +240,6 @@
 void UIScriptController::selectFormAccessoryPickerRow(long)
 {
 }
-    
-JSObjectRef UIScriptController::contentsOfUserInterfaceItem(JSStringRef interfaceItem) const
-{
-    return nullptr;
-}
 
 void UIScriptController::scrollToOffset(long x, long y)
 {

Modified: trunk/Tools/WebKitTestRunner/mac/UIScriptControllerMac.mm (208360 => 208361)


--- 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)
@@ -27,10 +27,15 @@
 #import "UIScriptController.h"
 
 #import "PlatformWebView.h"
+#import "StringFunctions.h"
 #import "TestController.h"
 #import "TestRunnerWKWebView.h"
 #import "UIScriptContext.h"
+#import <_javascript_Core/JSContext.h>
 #import <_javascript_Core/JSStringRefCF.h>
+#import <_javascript_Core/JSValue.h>
+#import <_javascript_Core/_javascript_Core.h>
+#import <_javascript_Core/OpaqueJSString.h>
 #import <WebKit/WKWebViewPrivate.h>
 
 namespace WTR {
@@ -85,4 +90,16 @@
 #endif
 }
 
+JSObjectRef UIScriptController::contentsOfUserInterfaceItem(JSStringRef interfaceItem) const
+{
+#if WK_API_ENABLED
+    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
+    NSDictionary *contentDictionary = [webView _contentsOfUserInterfaceItem:toWTFString(toWK(interfaceItem))];
+    return JSValueToObject(m_context->jsContext(), [JSValue valueWithObject:contentDictionary inContext:[JSContext contextWithJSGlobalContextRef:m_context->jsContext()]].JSValueRef, nullptr);
+#else
+    UNUSED_PARAM(interfaceItem);
+    return nullptr;
+#endif
+}
+
 } // namespace WTR
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to