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