Changeset 208361 in webkit


Ignore:
Timestamp:
Nov 3, 2016 6:38:31 PM (7 years ago)
Author:
Chris Dumez
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.

Location:
trunk
Files:
5 added
33 edited
3 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r208360 r208361  
     12016-11-03  Chris Dumez  <cdumez@apple.com>
     2
     3        [WK2][Cocoa] Implement user interface for HTML form validation
     4        https://bugs.webkit.org/show_bug.cgi?id=164143
     5        <rdar://problem/28944652>
     6
     7        Reviewed by Simon Fraser.
     8
     9        * fast/forms/validation-messages-expected.txt: Added.
     10        * fast/forms/validation-messages.html: Added.
     11        Add layout test coverage for checking that the right validation messages
     12        are displayed when submitting forms with constraint violations. More
     13        testing will be landed in follow up to cover other things besides the
     14        messages (e.g. when does the bubble disappear).
     15
     16        * platform/mac-wk1/TestExpectations:
     17        Skip new test on WebKit1 because the feature is WebKit2 only at the
     18        moment.
     19
     20        * platform/ios-simulator-wk2/TestExpectations:
     21        * platform/mac-wk2/TestExpectations:
     22        Skip tests for the Shadow DOM based HTML form validation UI on
     23        Mac and iOS WK2 now that those ports use native popovers instead.
     24
    1252016-11-03  Ryosuke Niwa  <rniwa@webkit.org>
    226
  • trunk/LayoutTests/platform/ios-simulator-wk2/TestExpectations

    r207440 r208361  
    14581458fast/replaced/pdf-as-object-and-embed.html [ Pass ]
    14591459
     1460# These tests test the Shadow DOM based HTML form validation UI but iOS WK2 is using native dialogs instead.
     1461fast/forms/validation-message-on-listbox.html
     1462fast/forms/validation-message-on-menulist.html
     1463fast/forms/validation-message-on-radio.html
     1464fast/forms/validation-message-on-checkbox.html
     1465fast/forms/validation-message-on-range.html
     1466fast/forms/validation-message-clone.html
     1467fast/forms/validation-message-in-relative-body.html
     1468fast/forms/validation-message-appearance.html
     1469fast/forms/validation-message-on-textarea.html
     1470
    14601471# Flaky as of 06/08/2015
    14611472compositing/overflow/overflow-positioning.html [ Failure ImageOnlyFailure Pass ]
  • trunk/LayoutTests/platform/mac-wk1/TestExpectations

    r208249 r208361  
    240240[ Sierra+ ] svg/hixie/text/003.html [ Failure ]
    241241
     242# We do not support the new HTML validation UI on WebKit1 yet (rdar://problem/28944652).
     243fast/forms/validation-messages.html [ Skip ]
     244
    242245[ Yosemite ] http/tests/media/hls/video-controller-getStartDate.html [ Pass Timeout ]
    243246
  • trunk/LayoutTests/platform/mac-wk2/TestExpectations

    r208236 r208361  
    194194webkit.org/b/95043 http/tests/security/local-user-CSS-from-remote.html [ Failure ]
    195195
     196# These tests test the Shadow DOM based HTML form validation UI but Mac WK2 is using native dialogs instead.
     197fast/forms/validation-message-on-listbox.html
     198fast/forms/validation-message-on-menulist.html
     199fast/forms/validation-message-on-radio.html
     200fast/forms/validation-message-on-checkbox.html
     201fast/forms/validation-message-on-range.html
     202fast/forms/validation-message-clone.html
     203fast/forms/validation-message-in-relative-body.html
     204fast/forms/validation-message-appearance.html
     205fast/forms/validation-message-on-textarea.html
     206
    196207# All spatial navigation tests fail on Mac WK2
    197208webkit.org/b/96438 fast/spatial-navigation
  • trunk/Source/WebCore/ChangeLog

    r208359 r208361  
     12016-11-03  Chris Dumez  <cdumez@apple.com>
     2
     3        [WK2][Cocoa] Implement user interface for HTML form validation
     4        https://bugs.webkit.org/show_bug.cgi?id=164143
     5        <rdar://problem/28944652>
     6
     7        Reviewed by Simon Fraser.
     8
     9        Add ValidationBubble class to show HTML form validation messages
     10        using native dialogs. It currently has an implementation for both
     11        Mac and iOS. It is in WebCore under platform/ so that it can be
     12        used by both WebKit1 and WebKit2.
     13
     14        Update ownership of ValidationMessageClient so that is is owned
     15        by the Page using a unique_ptr<>, which seems to be the modern
     16        way of handling lifetime for page clients.
     17
     18        Test: fast/forms/validation-messages.html
     19
     20        * WebCore.xcodeproj/project.pbxproj:
     21        * html/HTMLFormControlElement.cpp:
     22        (WebCore::HTMLFormControlElement::focusAndShowValidationMessage):
     23        * html/ValidationMessage.cpp:
     24        (WebCore::ValidationMessage::updateValidationMessage):
     25        * page/Page.cpp:
     26        (WebCore::Page::Page):
     27        (WebCore::Page::~Page):
     28        * page/Page.h:
     29        (WebCore::Page::validationMessageClient):
     30        * page/PageConfiguration.cpp:
     31        * page/PageConfiguration.h:
     32        * platform/ValidationBubble.h: Copied from Tools/DumpRenderTree/mac/UIScriptControllerMac.mm.
     33        (WebCore::ValidationBubble::message):
     34        * platform/ios/ValidationBubbleIOS.mm: Added.
     35        (-[WebValidationBubbleDelegate adaptivePresentationStyleForPresentationController:traitCollection:]):
     36        (WebCore::ValidationBubble::ValidationBubble):
     37        (WebCore::ValidationBubble::~ValidationBubble):
     38        (WebCore::ValidationBubble::show):
     39        (WebCore::ValidationBubble::setAnchorRect):
     40        * platform/mac/ValidationBubbleMac.mm: Added.
     41        (WebCore::ValidationBubble::ValidationBubble):
     42        (WebCore::ValidationBubble::~ValidationBubble):
     43        (WebCore::ValidationBubble::showRelativeTo):
     44
    1452016-11-03  Brady Eidson  <beidson@apple.com>
    246
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r208344 r208361  
    29622962                8372DB311A6780A800C697C5 /* DiagnosticLoggingResultType.h in Headers */ = {isa = PBXBuildFile; fileRef = 8372DB301A6780A800C697C5 /* DiagnosticLoggingResultType.h */; settings = {ATTRIBUTES = (Private, ); }; };
    29632963                83765F951DAC522F00C06537 /* MouseEventInit.h in Headers */ = {isa = PBXBuildFile; fileRef = 83765F941DAC521800C06537 /* MouseEventInit.h */; settings = {ATTRIBUTES = (Private, ); }; };
     2964                837B7D201DC3F55000D051FC /* ValidationBubbleIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 837B7D1F1DC3F54C00D051FC /* ValidationBubbleIOS.mm */; };
    29642965                8386A96D19F61B2E00E1EC4A /* StyleBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 8386A96C19F61B2E00E1EC4A /* StyleBuilder.h */; };
    29652966                8386A97019F61E4F00E1EC4A /* StyleBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8386A96E19F61E4F00E1EC4A /* StyleBuilder.cpp */; };
     
    29952996                83C1D435178D5AB500141E68 /* SVGPathSegMovetoAbs.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C1D423178D5AB400141E68 /* SVGPathSegMovetoAbs.h */; };
    29962997                83C1D436178D5AB500141E68 /* SVGPathSegMovetoRel.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C1D424178D5AB400141E68 /* SVGPathSegMovetoRel.h */; };
     2998                83C45B8C1DC2B667008871BA /* ValidationBubbleMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83C45B8B1DC2B663008871BA /* ValidationBubbleMac.mm */; };
     2999                83C45B8E1DC2B68A008871BA /* ValidationBubble.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C45B8D1DC2B67C008871BA /* ValidationBubble.h */; settings = {ATTRIBUTES = (Private, ); }; };
    29973000                83C5795D1DA5C301006FACA8 /* ScrollToOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 8350C3E71DA59B6200356446 /* ScrollToOptions.h */; settings = {ATTRIBUTES = (Private, ); }; };
    29983001                83D35AEC1C7187FA00F70D5A /* XMLHttpRequestEventTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 83D35AEA1C7187ED00F70D5A /* XMLHttpRequestEventTarget.h */; };
     
    64206423                F50664F7157F52DC00AC226F /* FormController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F50664F5157F52DC00AC226F /* FormController.cpp */; };
    64216424                F50664F8157F52DC00AC226F /* FormController.h in Headers */ = {isa = PBXBuildFile; fileRef = F50664F6157F52DC00AC226F /* FormController.h */; };
    6422                 F513A3EA15FF4841001526DB /* ValidationMessageClient.h in Headers */ = {isa = PBXBuildFile; fileRef = F513A3E915FF4841001526DB /* ValidationMessageClient.h */; };
     6425                F513A3EA15FF4841001526DB /* ValidationMessageClient.h in Headers */ = {isa = PBXBuildFile; fileRef = F513A3E915FF4841001526DB /* ValidationMessageClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
    64236426                F52A8FD71D0A8D0E0073CF42 /* AccessibilityLabel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F52A8FD51D0A88010073CF42 /* AccessibilityLabel.cpp */; };
    64246427                F52AD5E41534245F0059FBE6 /* EmptyClients.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F52AD5E31534245F0059FBE6 /* EmptyClients.cpp */; };
     
    1033110334                83765F931DAC521800C06537 /* MouseEventInit.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MouseEventInit.idl; sourceTree = "<group>"; };
    1033210335                83765F941DAC521800C06537 /* MouseEventInit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MouseEventInit.h; sourceTree = "<group>"; };
     10336                837B7D1F1DC3F54C00D051FC /* ValidationBubbleIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ValidationBubbleIOS.mm; sourceTree = "<group>"; };
    1033310337                8386A96C19F61B2E00E1EC4A /* StyleBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleBuilder.h; sourceTree = "<group>"; };
    1033410338                8386A96E19F61E4F00E1EC4A /* StyleBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleBuilder.cpp; sourceTree = "<group>"; };
     
    1036410368                83C1D423178D5AB400141E68 /* SVGPathSegMovetoAbs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGPathSegMovetoAbs.h; sourceTree = "<group>"; };
    1036510369                83C1D424178D5AB400141E68 /* SVGPathSegMovetoRel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGPathSegMovetoRel.h; sourceTree = "<group>"; };
     10370                83C45B8B1DC2B663008871BA /* ValidationBubbleMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ValidationBubbleMac.mm; sourceTree = "<group>"; };
     10371                83C45B8D1DC2B67C008871BA /* ValidationBubble.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValidationBubble.h; sourceTree = "<group>"; };
    1036610372                83D26D3C1AFDCC50001B3873 /* ChildNode.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = ChildNode.idl; sourceTree = "<group>"; };
    1036710373                83D26D3D1AFDCC50001B3873 /* ParentNode.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = ParentNode.idl; sourceTree = "<group>"; };
     
    1755717563                                6593923909AE435C002C531F /* URLMac.mm */,
    1755817564                                868160D3187669E70021E79D /* UserActivityMac.mm */,
     17565                                83C45B8B1DC2B663008871BA /* ValidationBubbleMac.mm */,
    1755917566                                CDC69DD816371FD3007C38DF /* WebCoreFullScreenPlaceholderView.h */,
    1756017567                                CDC69DD916371FD3007C38DF /* WebCoreFullScreenPlaceholderView.mm */,
     
    1933519342                                1F72BF08187FD4270009BCB3 /* TileControllerMemoryHandlerIOS.cpp */,
    1933619343                                1F72BF09187FD4270009BCB3 /* TileControllerMemoryHandlerIOS.h */,
     19344                                837B7D1F1DC3F54C00D051FC /* ValidationBubbleIOS.mm */,
    1933719345                                CDA29A2C1CBF73FC00901CCF /* WebAVPlayerController.h */,
    1933819346                                CDA29A2D1CBF73FC00901CCF /* WebAVPlayerController.mm */,
     
    2235922367                                2E3BBF051162DA1100B9409A /* UUID.cpp */,
    2236022368                                2E3BBF061162DA1100B9409A /* UUID.h */,
     22369                                83C45B8D1DC2B67C008871BA /* ValidationBubble.h */,
    2236122370                                9A1142031832D134000BB8AD /* ValueToString.h */,
    2236222371                                46DB7D581B20FE58005651B2 /* VNodeTracker.cpp */,
     
    2642926438                                CDBEAEAD19D92B6C00BEBA88 /* MediaSelectionGroupAVFObjC.h in Headers */,
    2643026439                                C9027F421B1D0AD200BFBFEF /* MediaSession.h in Headers */,
     26440                                83C45B8E1DC2B68A008871BA /* ValidationBubble.h in Headers */,
    2643126441                                C9F87CFE1B28F40E00979B83 /* MediaSessionEvents.h in Headers */,
    2643226442                                C96F5EC81B5872260091EA9D /* MediaSessionInterruptionProvider.h in Headers */,
     
    2932929339                                FDA15EC912B03F50003A583A /* JSAnalyserNode.cpp in Sources */,
    2933029340                                31A795C61888BADC00382F90 /* JSANGLEInstancedArrays.cpp in Sources */,
     29341                                83C45B8C1DC2B667008871BA /* ValidationBubbleMac.mm in Sources */,
    2933129342                                12A253E21C8FFF6600C22295 /* JSAnimatable.cpp in Sources */,
    2933229343                                120DE3FE1C87E18800B6D4DD /* JSAnimationEffect.cpp in Sources */,
     
    2954729558                                A80E7B120A19D606007FB8C5 /* JSHTMLBaseElement.cpp in Sources */,
    2954829559                                1AE2AA220A1CDAB400B42B25 /* JSHTMLBodyElement.cpp in Sources */,
     29560                                837B7D201DC3F55000D051FC /* ValidationBubbleIOS.mm in Sources */,
    2954929561                                1AE2AA240A1CDAB400B42B25 /* JSHTMLBRElement.cpp in Sources */,
    2955029562                                A80E7EA00A1A83E3007FB8C5 /* JSHTMLButtonElement.cpp in Sources */,
  • trunk/Source/WebCore/html/HTMLFormControlElement.cpp

    r207458 r208361  
    518518void HTMLFormControlElement::focusAndShowValidationMessage()
    519519{
    520     scrollIntoViewIfNeeded(false);
     520    // Calling focus() will scroll the element into view.
    521521    focus();
    522522    updateVisibleValidationMessage();
  • trunk/Source/WebCore/html/ValidationMessage.cpp

    r208096 r208361  
    7777void ValidationMessage::updateValidationMessage(const String& message)
    7878{
     79    // We want to hide the validation message as soon as the user starts
     80    // typing, even if a constraint is still violated. Thefore, we hide the message instead
     81    // of updating it if it is already visible.
     82    if (isVisible()) {
     83        requestToHideMessage();
     84        return;
     85    }
     86
    7987    String updatedMessage = message;
    8088    if (!validationMessageClient()) {
  • trunk/Source/WebCore/page/Page.cpp

    r208329 r208361  
    9595#include "UserContentProvider.h"
    9696#include "UserInputBridge.h"
     97#include "ValidationMessageClient.h"
    9798#include "VisitedLinkState.h"
    9899#include "VisitedLinkStore.h"
     
    183184    , m_editorClient(WTFMove(pageConfiguration.editorClient))
    184185    , m_plugInClient(pageConfiguration.plugInClient)
    185     , m_validationMessageClient(pageConfiguration.validationMessageClient)
     186    , m_validationMessageClient(WTFMove(pageConfiguration.validationMessageClient))
    186187    , m_diagnosticLoggingClient(WTFMove(pageConfiguration.diagnosticLoggingClient))
    187188    , m_subframeCount(0)
     
    271272Page::~Page()
    272273{
     274    m_validationMessageClient = nullptr;
    273275    m_diagnosticLoggingClient = nullptr;
    274276    m_mainFrame->setView(nullptr);
  • trunk/Source/WebCore/page/Page.h

    r208329 r208361  
    206206    PointerLockController& pointerLockController() const { return *m_pointerLockController; }
    207207#endif
    208     ValidationMessageClient* validationMessageClient() const { return m_validationMessageClient; }
     208    ValidationMessageClient* validationMessageClient() const { return m_validationMessageClient.get(); }
    209209
    210210    WEBCORE_EXPORT ScrollingCoordinator* scrollingCoordinator();
     
    593593    UniqueRef<EditorClient> m_editorClient;
    594594    PlugInClient* m_plugInClient;
    595     ValidationMessageClient* m_validationMessageClient;
     595    std::unique_ptr<ValidationMessageClient> m_validationMessageClient;
    596596    std::unique_ptr<DiagnosticLoggingClient> m_diagnosticLoggingClient;
    597597
  • trunk/Source/WebCore/page/PageConfiguration.cpp

    r204268 r208361  
    3636#include "StorageNamespaceProvider.h"
    3737#include "UserContentController.h"
     38#include "ValidationMessageClient.h"
    3839#include "VisitedLinkStore.h"
    3940
  • trunk/Source/WebCore/page/PageConfiguration.h

    r204268 r208361  
    7878    ProgressTrackerClient* progressTrackerClient { nullptr };
    7979    RefPtr<BackForwardClient> backForwardClient;
    80     ValidationMessageClient* validationMessageClient { nullptr };
     80    std::unique_ptr<ValidationMessageClient> validationMessageClient;
    8181    FrameLoaderClient* loaderClientForMainFrame { nullptr };
    82     std::unique_ptr<DiagnosticLoggingClient> diagnosticLoggingClient { nullptr };
     82    std::unique_ptr<DiagnosticLoggingClient> diagnosticLoggingClient;
    8383
    8484    RefPtr<ApplicationCacheStorage> applicationCacheStorage;
  • trunk/Source/WebCore/platform/ValidationBubble.h

    r208360 r208361  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 #import "config.h"
    27 #import "UIScriptController.h"
     26#pragma once
    2827
    29 #import "DumpRenderTree.h"
    30 #import "UIScriptContext.h"
    31 #import <WebKit/WebKit.h>
    32 #import <WebKit/WebViewPrivate.h>
     28#include "IntRect.h"
     29#include <wtf/Forward.h>
     30#include <wtf/text/WTFString.h>
     31
     32#if PLATFORM(COCOA)
     33#include <wtf/RetainPtr.h>
     34#endif
    3335
    3436#if PLATFORM(MAC)
     37OBJC_CLASS NSPopover;
     38#elif PLATFORM(IOS)
     39OBJC_CLASS UIViewController;
     40OBJC_CLASS WebValidationBubbleDelegate;
     41#endif
    3542
    36 namespace WTR {
     43#if PLATFORM(MAC)
     44OBJC_CLASS NSView;
     45using PlatformView = NSView;
     46#elif PLATFORM(IOS)
     47OBJC_CLASS UIView;
     48using PlatformView = UIView;
     49#else
     50using PlatformView = void;
     51#endif
    3752
    38 void UIScriptController::doAsyncTask(JSValueRef callback)
    39 {
    40     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
     53namespace WebCore {
    4154
    42     dispatch_async(dispatch_get_main_queue(), ^{
    43         if (!m_context)
    44             return;
    45         m_context->asyncTaskComplete(callbackID);
    46     });
    47 }
     55class ValidationBubble {
     56public:
     57    WEBCORE_EXPORT ValidationBubble(PlatformView*, const String& message);
     58    WEBCORE_EXPORT ~ValidationBubble();
    4859
    49 void UIScriptController::insertText(JSStringRef, int, int)
    50 {
    51 }
     60    const String& message() const { return m_message; }
    5261
    53 void UIScriptController::zoomToScale(double scale, JSValueRef callback)
    54 {
    55     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
     62#if PLATFORM(IOS)
     63    WEBCORE_EXPORT void setAnchorRect(const IntRect& anchorRect, UIViewController* presentingViewController);
     64    WEBCORE_EXPORT void show();
     65#else
     66    WEBCORE_EXPORT void showRelativeTo(const IntRect& anchorRect);
     67#endif
    5668
    57     WebView *webView = [mainFrame webView];
    58     [webView _scaleWebView:scale atOrigin:NSZeroPoint];
    59 
    60     dispatch_async(dispatch_get_main_queue(), ^ {
    61         if (!m_context)
    62             return;
    63         m_context->asyncTaskComplete(callbackID);
    64     });
    65 }
     69private:
     70    PlatformView* m_view;
     71    String m_message;
     72#if PLATFORM(MAC)
     73    RetainPtr<NSPopover> m_popover;
     74#elif PLATFORM(IOS)
     75    RetainPtr<UIViewController> m_popoverController;
     76    RetainPtr<WebValidationBubbleDelegate> m_popoverDelegate;
     77    UIViewController *m_presentingViewController;
     78#endif
     79};
    6680
    6781}
    68 
    69 #endif // PLATFORM(MAC)
  • trunk/Source/WebKit2/ChangeLog

    r208347 r208361  
     12016-11-03  Chris Dumez  <cdumez@apple.com>
     2
     3        [WK2][Cocoa] Implement user interface for HTML form validation
     4        https://bugs.webkit.org/show_bug.cgi?id=164143
     5        <rdar://problem/28944652>
     6
     7        Reviewed by Simon Fraser.
     8
     9        Implement the ValidationMessageClient in WebKit2 and have it display
     10        a ValidationBubble on Cocoa. ValidationBubble is implemented using
     11        native popovers on both Mac and iOS. As a result, Mac and iOS WK2
     12        now use native popover for HTML form validation instead of the old
     13        Shadow DOM based UI in WebCore.
     14
     15        The native popover shows at the bottom (or top) of the input and it
     16        disapears as soon as the user starts typing or interacts with the
     17        view (e.g. tap / scroll / zoom).
     18
     19        The feature is still disabled at runtime.
     20
     21        * UIProcess/API/Cocoa/WKWebView.mm:
     22        (-[WKWebView _initializeWithConfiguration:]):
     23        (-[WKWebView _keyboardWillShow:]):
     24        (-[WKWebView _keyboardDidShow:]):
     25        (-[WKWebView _contentsOfUserInterfaceItem:]):
     26        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
     27        * UIProcess/Cocoa/WebPageProxyCocoa.mm:
     28        * UIProcess/PageClient.h:
     29        * UIProcess/WebPageProxy.cpp:
     30        (WebKit::WebPageProxy::handleWheelEvent):
     31        (WebKit::WebPageProxy::setPageZoomFactor):
     32        (WebKit::WebPageProxy::setPageAndTextZoomFactors):
     33        (WebKit::WebPageProxy::pageDidScroll):
     34        (WebKit::WebPageProxy::resetState):
     35        (WebKit::WebPageProxy::hideValidationMessage):
     36        * UIProcess/WebPageProxy.h:
     37        (WebKit::WebPageProxy::validationBubble):
     38        (WebKit::WebPageProxy::setIsKeyboardAnimatingIn):
     39        * UIProcess/WebPageProxy.messages.in:
     40        * UIProcess/ios/PageClientImplIOS.h:
     41        * UIProcess/ios/PageClientImplIOS.mm:
     42        (WebKit::PageClientImpl::createValidationBubble):
     43        * UIProcess/ios/WKContentViewInteraction.mm:
     44        (-[WKContentView _willStartScrollingOrZooming]):
     45        (-[WKContentView scrollViewWillStartPanOrPinchGesture]):
     46        (-[WKContentView _didEndScrollingOrZooming]):
     47        * UIProcess/ios/WebPageProxyIOS.mm:
     48        (WebKit::WebPageProxy::dynamicViewportSizeUpdate):
     49        (WebKit::WebPageProxy::potentialTapAtPosition):
     50        (WebKit::WebPageProxy::showValidationMessage):
     51        (WebKit::WebPageProxy::setIsScrollingOrZooming):
     52        * UIProcess/mac/PageClientImpl.h:
     53        * UIProcess/mac/PageClientImpl.mm:
     54        (WebKit::PageClientImpl::createValidationBubble):
     55        * UIProcess/mac/WebPageProxyMac.mm:
     56        (WebKit::WebPageProxy::showValidationMessage):
     57        * WebKit2.xcodeproj/project.pbxproj:
     58        * WebProcess/WebCoreSupport/WebValidationMessageClient.cpp: Copied from Tools/DumpRenderTree/mac/UIScriptControllerMac.mm.
     59        (WebKit::WebValidationMessageClient::WebValidationMessageClient):
     60        (WebKit::WebValidationMessageClient::~WebValidationMessageClient):
     61        (WebKit::WebValidationMessageClient::showValidationMessage):
     62        (WebKit::WebValidationMessageClient::hideValidationMessage):
     63        (WebKit::WebValidationMessageClient::isValidationMessageVisible):
     64        * WebProcess/WebCoreSupport/WebValidationMessageClient.h: Copied from Tools/DumpRenderTree/mac/UIScriptControllerMac.mm.
     65        * WebProcess/WebPage/WebPage.cpp:
     66        (WebKit::m_userInterfaceLayoutDirection):
     67
    1682016-11-03  Tim Horton  <timothy_horton@apple.com>
    269
  • trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm

    r208342 r208361  
    9494#import <WebCore/Settings.h>
    9595#import <WebCore/TextStream.h>
     96#import <WebCore/ValidationBubble.h>
    9697#import <WebCore/WritingMode.h>
    9798#import <wtf/HashMap.h>
     
    525526    [center addObserver:self selector:@selector(_keyboardDidChangeFrame:) name:UIKeyboardDidChangeFrameNotification object:nil];
    526527    [center addObserver:self selector:@selector(_keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
     528    [center addObserver:self selector:@selector(_keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
    527529    [center addObserver:self selector:@selector(_keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
    528530    [center addObserver:self selector:@selector(_windowDidRotate:) name:UIWindowDidRotateNotification object:nil];
     
    21782180    if ([self _shouldUpdateKeyboardWithInfo:notification.userInfo])
    21792181        [self _keyboardChangedWithInfo:notification.userInfo adjustScrollView:YES];
     2182
     2183    _page->setIsKeyboardAnimatingIn(true);
     2184}
     2185
     2186- (void)_keyboardDidShow:(NSNotification *)notification
     2187{
     2188    _page->setIsKeyboardAnimatingIn(false);
    21802189}
    21812190
     
    45284537@implementation WKWebView (WKTesting)
    45294538
     4539- (NSDictionary *)_contentsOfUserInterfaceItem:(NSString *)userInterfaceItem
     4540{
     4541    if ([userInterfaceItem isEqualToString:@"validationBubble"]) {
     4542        auto* validationBubble = _page->validationBubble();
     4543        String message = validationBubble ? validationBubble->message() : emptyString();
     4544        return @{ userInterfaceItem: @{ @"message": (NSString *)message } };
     4545    }
     4546
    45304547#if PLATFORM(IOS)
     4548    return [_contentView _contentsOfUserInterfaceItem:(NSString *)userInterfaceItem];
     4549#else
     4550    return nil;
     4551#endif
     4552}
     4553
     4554#if PLATFORM(IOS)
    45314555
    45324556- (CGRect)_contentVisibleRect
     
    45634587{
    45644588    [_contentView selectFormAccessoryPickerRow:rowIndex];
    4565 }
    4566 
    4567 - (NSDictionary *)_contentsOfUserInterfaceItem:(NSString *)userInterfaceItem
    4568 {
    4569     return [_contentView _contentsOfUserInterfaceItem:(NSString *)userInterfaceItem];
    45704589}
    45714590
  • trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h

    r208143 r208361  
    258258@interface WKWebView (WKTesting)
    259259
     260- (NSDictionary *)_contentsOfUserInterfaceItem:(NSString *)userInterfaceItem WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
     261
    260262#if TARGET_OS_IPHONE
    261263
     
    268270- (void)dismissFormAccessoryView WK_API_AVAILABLE(ios(WK_IOS_TBA));
    269271- (void)selectFormAccessoryPickerRow:(int)rowIndex WK_API_AVAILABLE(ios(WK_IOS_TBA));
    270 - (NSDictionary *)_contentsOfUserInterfaceItem:(NSString *)userInterfaceItem WK_API_AVAILABLE(ios(WK_IOS_TBA));
    271272
    272273- (void)didStartFormControlInteraction WK_API_AVAILABLE(ios(WK_IOS_TBA));
  • trunk/Source/WebKit2/UIProcess/Cocoa/WebPageProxyCocoa.mm

    r202889 r208361  
    3131#import "LoadParameters.h"
    3232#import "WebProcessProxy.h"
    33 
    3433#import <WebCore/SearchPopupMenuCocoa.h>
     34#import <WebCore/ValidationBubble.h>
    3535#import <wtf/cf/TypeCastsCF.h>
    3636
  • trunk/Source/WebKit2/UIProcess/PageClient.h

    r206771 r208361  
    5050class Cursor;
    5151class TextIndicator;
     52class ValidationBubble;
    5253class WebMediaSessionManager;
    5354enum class TextIndicatorWindowLifetime : uint8_t;
     
    225226#if ENABLE(INPUT_TYPE_COLOR)
    226227    virtual RefPtr<WebColorPicker> createColorPicker(WebPageProxy*, const WebCore::Color& initialColor, const WebCore::IntRect&) = 0;
     228#endif
     229
     230#if PLATFORM(COCOA)
     231    virtual std::unique_ptr<WebCore::ValidationBubble> createValidationBubble(const String& message) = 0;
    227232#endif
    228233
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp

    r208340 r208361  
    124124#include <WebCore/TextIndicator.h>
    125125#include <WebCore/URL.h>
     126#include <WebCore/ValidationBubble.h>
    126127#include <WebCore/WindowFeatures.h>
    127128#include <stdio.h>
     
    19291930        return;
    19301931
     1932    hideValidationMessage();
     1933
    19311934    if (!m_currentlyProcessedWheelEvents.isEmpty()) {
    19321935        m_wheelEventQueue.append(event);
     
    24662469        return;
    24672470
     2471    hideValidationMessage();
     2472
    24682473    m_pageZoomFactor = zoomFactor;
    24692474    m_process->send(Messages::WebPage::SetPageZoomFactor(m_pageZoomFactor), m_pageID);
     
    24772482    if (m_pageZoomFactor == pageZoomFactor && m_textZoomFactor == textZoomFactor)
    24782483        return;
     2484
     2485    hideValidationMessage();
    24792486
    24802487    m_pageZoomFactor = pageZoomFactor;
     
    41044111{
    41054112    m_uiClient->pageDidScroll(this);
     4113
     4114#if PLATFORM(IOS)
     4115    // Do not hide the validation message if the scrolling was caused by the keyboard showing up.
     4116    if (m_isKeyboardAnimatingIn)
     4117        return;
     4118#endif
     4119    hideValidationMessage();
    41064120}
    41074121
     
    53075321#endif
    53085322    m_drawingArea = nullptr;
     5323    hideValidationMessage();
    53095324
    53105325    if (m_inspector) {
     
    53795394    m_layerTreeTransactionIdAtLastTouchStart = 0;
    53805395    m_hasNetworkRequestsOnSuspended = false;
     5396    m_isKeyboardAnimatingIn = false;
     5397    m_isScrollingOrZooming = false;
    53815398#endif
    53825399
     
    66406657    m_process->send(Messages::WebPage::SetUserInterfaceLayoutDirection(static_cast<uint32_t>(userInterfaceLayoutDirection)), m_pageID);
    66416658}
     6659
     6660void WebPageProxy::hideValidationMessage()
     6661{
     6662#if PLATFORM(COCOA)
     6663    m_validationBubble = nullptr;
     6664#endif
     6665}
    66426666   
    66436667#if ENABLE(POINTER_LOCK)
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.h

    r208340 r208361  
    154154class SharedBuffer;
    155155class TextIndicator;
     156class ValidationBubble;
    156157enum class HasInsecureContent;
    157158struct DictionaryPopupInfo;
     
    528529    void handleTwoFingerTapAtPoint(const WebCore::IntPoint&, uint64_t requestID);
    529530    void setForceAlwaysUserScalable(bool);
     531    void setIsScrollingOrZooming(bool);
    530532#endif
    531533#if ENABLE(DATA_DETECTION)
     
    10931095    void logSampledDiagnosticMessageWithResult(const String& message, const String& description, uint32_t result);
    10941096    void logSampledDiagnosticMessageWithValue(const String& message, const String& description, const String& value);
     1097
     1098    // Form validation messages.
     1099    void showValidationMessage(const WebCore::IntRect& anchorClientRect, const String& message);
     1100    void hideValidationMessage();
     1101#if PLATFORM(COCOA)
     1102    WebCore::ValidationBubble* validationBubble() const { return m_validationBubble.get(); } // For testing.
     1103#endif
     1104
     1105#if PLATFORM(IOS)
     1106    void setIsKeyboardAnimatingIn(bool isKeyboardAnimatingIn) { m_isKeyboardAnimatingIn = isKeyboardAnimatingIn; }
     1107#endif
    10951108
    10961109#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
     
    16271640    uint64_t m_currentDynamicViewportSizeUpdateID { 0 };
    16281641    bool m_hasNetworkRequestsOnSuspended;
     1642    bool m_isKeyboardAnimatingIn { false };
     1643    bool m_isScrollingOrZooming { false };
    16291644#endif
    16301645
     
    17781793    RefPtr<WebColorPicker> m_colorPicker;
    17791794#endif
     1795#if PLATFORM(COCOA)
     1796    std::unique_ptr<WebCore::ValidationBubble> m_validationBubble;
     1797#endif
    17801798
    17811799    const uint64_t m_pageID;
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in

    r208225 r208361  
    6565    RootViewToScreen(WebCore::IntRect rect) -> (WebCore::IntRect screenFrame)
    6666
     67#if PLATFORM(COCOA)
     68    ShowValidationMessage(WebCore::IntRect anchorRect, String message)
     69    HideValidationMessage()
     70#endif
     71
    6772#if PLATFORM(IOS)
    6873    AccessibilityScreenToRootView(WebCore::IntPoint screenPoint) -> (WebCore::IntPoint windowPoint)
  • trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.h

    r204013 r208361  
    9797    std::unique_ptr<WebContextMenuProxy> createContextMenuProxy(WebPageProxy&, const ContextMenuContextData&, const UserData&) override;
    9898#endif
     99    std::unique_ptr<WebCore::ValidationBubble> createValidationBubble(const String& message) final;
     100
    99101    void setTextIndicator(Ref<WebCore::TextIndicator>, WebCore::TextIndicatorWindowLifetime) override;
    100102    void clearTextIndicator(WebCore::TextIndicatorWindowDismissalAnimation) override;
  • trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm

    r206413 r208361  
    5252#import <WebCore/SharedBuffer.h>
    5353#import <WebCore/TextIndicator.h>
     54#import <WebCore/ValidationBubble.h>
    5455
    5556#define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, m_webView->_page->process().connection())
     
    744745}
    745746
     747std::unique_ptr<ValidationBubble> PageClientImpl::createValidationBubble(const String& message)
     748{
     749    return std::make_unique<ValidationBubble>(m_contentView, message);
     750}
     751
    746752} // namespace WebKit
    747753
  • trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm

    r207478 r208361  
    15921592    [_webSelectionAssistant willStartScrollingOrZoomingPage];
    15931593    [_textSelectionAssistant willStartScrollingOverflow];
     1594    _page->setIsScrollingOrZooming(true);
    15941595}
    15951596
    15961597- (void)scrollViewWillStartPanOrPinchGesture
    15971598{
     1599    _page->hideValidationMessage();
     1600
    15981601    _canSendTouchEventsAsynchronously = YES;
    15991602}
     
    16031606    [_webSelectionAssistant didEndScrollingOrZoomingPage];
    16041607    [_textSelectionAssistant didEndScrollingOverflow];
     1608    _page->setIsScrollingOrZooming(false);
    16051609}
    16061610
  • trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm

    r208340 r208361  
    5151#import <WebCore/SharedBuffer.h>
    5252#import <WebCore/UserAgent.h>
     53#import <WebCore/ValidationBubble.h>
    5354
    5455#if USE(QUICK_LOOK)
     
    267268    if (!isValid())
    268269        return;
     270
     271    hideValidationMessage();
    269272
    270273    m_dynamicViewportSizeUpdateWaitingForTarget = true;
     
    753756void WebPageProxy::potentialTapAtPosition(const WebCore::FloatPoint& position, uint64_t& requestID)
    754757{
     758    hideValidationMessage();
    755759    process().send(Messages::WebPage::PotentialTapAtPosition(requestID, position), m_pageID);
    756760}
     
    10081012    // even during composition to support phrase boundary gesture.
    10091013    m_pageClient.selectionDidChange();
     1014}
     1015
     1016void WebPageProxy::showValidationMessage(const IntRect& anchorClientRect, const String& message)
     1017{
     1018    m_validationBubble = m_pageClient.createValidationBubble(message);
     1019    m_validationBubble->setAnchorRect(anchorClientRect, uiClient().presentingViewController());
     1020
     1021    // If we are currently doing a scrolling / zoom animation, then we'll delay showing the validation
     1022    // bubble until the animation is over.
     1023    if (!m_isScrollingOrZooming)
     1024        m_validationBubble->show();
     1025}
     1026
     1027void WebPageProxy::setIsScrollingOrZooming(bool isScrollingOrZooming)
     1028{
     1029    m_isScrollingOrZooming = isScrollingOrZooming;
     1030
     1031    // We finished doing the scrolling / zoom animation so we can now show the validation
     1032    // bubble if we're supposed to.
     1033    if (!m_isScrollingOrZooming && m_validationBubble)
     1034        m_validationBubble->show();
    10101035}
    10111036
  • trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h

    r206771 r208361  
    132132#endif
    133133
     134    std::unique_ptr<WebCore::ValidationBubble> createValidationBubble(const String& message) final;
     135
    134136    void setTextIndicator(Ref<WebCore::TextIndicator>, WebCore::TextIndicatorWindowLifetime) override;
    135137    void clearTextIndicator(WebCore::TextIndicatorWindowDismissalAnimation) override;
  • trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm

    r206771 r208361  
    6868#import <WebCore/TextIndicatorWindow.h>
    6969#import <WebCore/TextUndoInsertionMarkupMac.h>
     70#import <WebCore/ValidationBubble.h>
    7071#import <WebKitSystemInterface.h>
    7172#import <wtf/text/CString.h>
     
    440441#endif
    441442
     443std::unique_ptr<ValidationBubble> PageClientImpl::createValidationBubble(const String& message)
     444{
     445    return std::make_unique<ValidationBubble>(m_view, message);
     446}
     447
    442448void PageClientImpl::setTextIndicator(Ref<TextIndicator> textIndicator, WebCore::TextIndicatorWindowLifetime lifetime)
    443449{
  • trunk/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm

    r204466 r208361  
    5555#import <WebCore/TextAlternativeWithRange.h>
    5656#import <WebCore/UserAgent.h>
     57#import <WebCore/ValidationBubble.h>
    5758#import <mach-o/dyld.h>
    5859#import <wtf/text/StringConcatenate.h>
     
    595596}
    596597
     598void WebPageProxy::showValidationMessage(const IntRect& anchorClientRect, const String& message)
     599{
     600    m_validationBubble = m_pageClient.createValidationBubble(message);
     601    m_validationBubble->showRelativeTo(anchorClientRect);
     602}
     603
    597604#if WK_API_ENABLED
    598605NSView *WebPageProxy::inspectorAttachmentView()
  • trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj

    r208344 r208361  
    12171217                83BFAC431D96137C00433490 /* BlobDownloadClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83BFAC411D96136000433490 /* BlobDownloadClient.cpp */; };
    12181218                83D454D71BE9D3C4006C93BD /* NetworkLoadClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 83D454D61BE9D3C4006C93BD /* NetworkLoadClient.h */; };
     1219                83EE575B1DB7D61100C74C50 /* WebValidationMessageClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83EE57591DB7D60600C74C50 /* WebValidationMessageClient.cpp */; };
     1220                83EE575C1DB7D61100C74C50 /* WebValidationMessageClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 83EE575A1DB7D60600C74C50 /* WebValidationMessageClient.h */; };
    12191221                84477853176FCC0800CDC7BB /* InjectedBundleHitTestResultMediaType.h in Headers */ = {isa = PBXBuildFile; fileRef = 84477851176FCAC100CDC7BB /* InjectedBundleHitTestResultMediaType.h */; };
    12201222                868160D0187645570021E79D /* WindowServerConnection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 868160CF187645370021E79D /* WindowServerConnection.mm */; };
     
    33223324                83BFAC411D96136000433490 /* BlobDownloadClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BlobDownloadClient.cpp; path = NetworkProcess/Downloads/BlobDownloadClient.cpp; sourceTree = "<group>"; };
    33233325                83D454D61BE9D3C4006C93BD /* NetworkLoadClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NetworkLoadClient.h; path = NetworkProcess/NetworkLoadClient.h; sourceTree = "<group>"; };
     3326                83EE57591DB7D60600C74C50 /* WebValidationMessageClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebValidationMessageClient.cpp; sourceTree = "<group>"; };
     3327                83EE575A1DB7D60600C74C50 /* WebValidationMessageClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebValidationMessageClient.h; sourceTree = "<group>"; };
    33243328                84477851176FCAC100CDC7BB /* InjectedBundleHitTestResultMediaType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InjectedBundleHitTestResultMediaType.h; sourceTree = "<group>"; };
    33253329                868160CD18763D4B0021E79D /* WindowServerConnection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WindowServerConnection.h; sourceTree = "<group>"; };
     
    60366040                                4A410F4819AF7B80002EBAB5 /* WebUserMediaClient.cpp */,
    60376041                                4A410F4919AF7B80002EBAB5 /* WebUserMediaClient.h */,
     6042                                83EE57591DB7D60600C74C50 /* WebValidationMessageClient.cpp */,
     6043                                83EE575A1DB7D60600C74C50 /* WebValidationMessageClient.h */,
    60386044                        );
    60396045                        path = WebCoreSupport;
     
    78097815                                1A6FB7D311E651E200DB1371 /* Plugin.h in Headers */,
    78107816                                31A67E0D165B2A99006CBA66 /* PlugInAutoStartProvider.h in Headers */,
     7817                                83EE575C1DB7D61100C74C50 /* WebValidationMessageClient.h in Headers */,
    78117818                                1A9FBA8D13FF04E600DEED67 /* PluginComplexTextInputState.h in Headers */,
    78127819                                1AA56F2911E92BC80061B882 /* PluginController.h in Headers */,
     
    97319738                                0F174AA7142AAC610039250F /* WKGeometry.cpp in Sources */,
    97329739                                B62E7310143047A60069EC35 /* WKHitTestResult.cpp in Sources */,
     9740                                83EE575B1DB7D61100C74C50 /* WebValidationMessageClient.cpp in Sources */,
    97339741                                5110AE0C133C16CB0072717A /* WKIconDatabase.cpp in Sources */,
    97349742                                5123CF1B133D260A0056F800 /* WKIconDatabaseCG.cpp in Sources */,
  • trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebValidationMessageClient.cpp

    r208360 r208361  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 #import "config.h"
    27 #import "UIScriptController.h"
     26#include "config.h"
     27#include "WebValidationMessageClient.h"
    2828
    29 #import "DumpRenderTree.h"
    30 #import "UIScriptContext.h"
    31 #import <WebKit/WebKit.h>
    32 #import <WebKit/WebViewPrivate.h>
     29#include "WebPage.h"
     30#include "WebPageProxyMessages.h"
     31#include <WebCore/Element.h>
     32#include <WebCore/Frame.h>
    3333
    34 #if PLATFORM(MAC)
     34namespace WebKit {
    3535
    36 namespace WTR {
     36using namespace WebCore;
    3737
    38 void UIScriptController::doAsyncTask(JSValueRef callback)
    39 {
    40     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
    41 
    42     dispatch_async(dispatch_get_main_queue(), ^{
    43         if (!m_context)
    44             return;
    45         m_context->asyncTaskComplete(callbackID);
    46     });
    47 }
    48 
    49 void UIScriptController::insertText(JSStringRef, int, int)
     38WebValidationMessageClient::WebValidationMessageClient(WebPage& page)
     39    : m_page(page)
    5040{
    5141}
    5242
    53 void UIScriptController::zoomToScale(double scale, JSValueRef callback)
     43WebValidationMessageClient::~WebValidationMessageClient()
    5444{
    55     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
    56 
    57     WebView *webView = [mainFrame webView];
    58     [webView _scaleWebView:scale atOrigin:NSZeroPoint];
    59 
    60     dispatch_async(dispatch_get_main_queue(), ^ {
    61         if (!m_context)
    62             return;
    63         m_context->asyncTaskComplete(callbackID);
    64     });
     45    if (m_currentAnchor)
     46        hideValidationMessage(*m_currentAnchor);
    6547}
    6648
     49void WebValidationMessageClient::showValidationMessage(const Element& anchor, const String& message)
     50{
     51    if (m_currentAnchor)
     52        hideValidationMessage(*m_currentAnchor);
     53
     54    m_currentAnchor = &anchor;
     55    m_page.send(Messages::WebPageProxy::ShowValidationMessage(anchor.clientRect(), message));
    6756}
    6857
    69 #endif // PLATFORM(MAC)
     58void WebValidationMessageClient::hideValidationMessage(const Element& anchor)
     59{
     60    if (!isValidationMessageVisible(anchor))
     61        return;
     62
     63    m_currentAnchor = nullptr;
     64    m_page.send(Messages::WebPageProxy::HideValidationMessage());
     65}
     66
     67bool WebValidationMessageClient::isValidationMessageVisible(const Element& anchor)
     68{
     69    return m_currentAnchor == &anchor;
     70}
     71
     72} // namespace WebKit
  • trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebValidationMessageClient.h

    r208360 r208361  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 #import "config.h"
    27 #import "UIScriptController.h"
     26#pragma once
    2827
    29 #import "DumpRenderTree.h"
    30 #import "UIScriptContext.h"
    31 #import <WebKit/WebKit.h>
    32 #import <WebKit/WebViewPrivate.h>
     28#include <WebCore/IntRect.h>
     29#include <WebCore/ValidationMessageClient.h>
    3330
    34 #if PLATFORM(MAC)
     31namespace WebKit {
    3532
    36 namespace WTR {
     33class WebPage;
    3734
    38 void UIScriptController::doAsyncTask(JSValueRef callback)
    39 {
    40     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
     35class WebValidationMessageClient final : public WebCore::ValidationMessageClient {
     36public:
     37    explicit WebValidationMessageClient(WebPage&);
     38    ~WebValidationMessageClient();
    4139
    42     dispatch_async(dispatch_get_main_queue(), ^{
    43         if (!m_context)
    44             return;
    45         m_context->asyncTaskComplete(callbackID);
    46     });
    47 }
     40    // ValidationMessageClient API.
     41    void showValidationMessage(const WebCore::Element& anchor, const String& message) final;
     42    void hideValidationMessage(const WebCore::Element& anchor) final;
     43    bool isValidationMessageVisible(const WebCore::Element& anchor) final;
    4844
    49 void UIScriptController::insertText(JSStringRef, int, int)
    50 {
    51 }
    52 
    53 void UIScriptController::zoomToScale(double scale, JSValueRef callback)
    54 {
    55     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
    56 
    57     WebView *webView = [mainFrame webView];
    58     [webView _scaleWebView:scale atOrigin:NSZeroPoint];
    59 
    60     dispatch_async(dispatch_get_main_queue(), ^ {
    61         if (!m_context)
    62             return;
    63         m_context->asyncTaskComplete(callbackID);
    64     });
    65 }
     45private:
     46    WebPage& m_page;
     47    const WebCore::Element* m_currentAnchor { nullptr };
     48};
    6649
    6750}
    68 
    69 #endif // PLATFORM(MAC)
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp

    r208340 r208361  
    113113#include "WebUserContentController.h"
    114114#include "WebUserMediaClient.h"
     115#include "WebValidationMessageClient.h"
    115116#include <JavaScriptCore/APICast.h>
    116117#include <WebCore/ApplicationCacheStorage.h>
     
    410411    pageConfiguration.diagnosticLoggingClient = std::make_unique<WebDiagnosticLoggingClient>(*this);
    411412
     413#if PLATFORM(COCOA)
     414    pageConfiguration.validationMessageClient = std::make_unique<WebValidationMessageClient>(*this);
     415#endif
     416
    412417    pageConfiguration.applicationCacheStorage = &WebProcess::singleton().applicationCacheStorage();
    413418    pageConfiguration.databaseProvider = WebDatabaseProvider::getOrCreate(m_pageGroup->pageGroupID());
  • trunk/Tools/ChangeLog

    r208357 r208361  
     12016-11-03  Chris Dumez  <cdumez@apple.com>
     2
     3        [WK2][Cocoa] Implement user interface for HTML form validation
     4        https://bugs.webkit.org/show_bug.cgi?id=164143
     5        <rdar://problem/28944652>
     6
     7        Reviewed by Simon Fraser.
     8
     9        Add support for UIScriptController::contentsOfUserInterfaceItem("validationBubble")
     10        on both Mac and iOS to retrieve the currently displayed validation message.
     11
     12        * DumpRenderTree/mac/UIScriptControllerMac.mm:
     13        (WTR::UIScriptController::contentsOfUserInterfaceItem):
     14        * TestRunnerShared/UIScriptContext/UIScriptController.cpp:
     15        (WTR::UIScriptController::contentsOfUserInterfaceItem):
     16        (WTR::UIScriptController::selectFormAccessoryPickerRow):
     17        * WebKitTestRunner/mac/UIScriptControllerMac.mm:
     18        (WTR::UIScriptController::contentsOfUserInterfaceItem):
     19
    1202016-11-03  Konstantin Tokarev  <annulen@yandex.ru>
    221
  • trunk/Tools/DumpRenderTree/mac/UIScriptControllerMac.mm

    r208207 r208361  
    6565}
    6666
     67JSObjectRef UIScriptController::contentsOfUserInterfaceItem(JSStringRef interfaceItem) const
     68{
     69    return nullptr;
     70}
     71
    6772}
    6873
  • trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp

    r208207 r208361  
    162162{
    163163}
     164
     165JSObjectRef UIScriptController::contentsOfUserInterfaceItem(JSStringRef interfaceItem) const
     166{
     167    return nullptr;
     168}
    164169#endif
    165170
     
    236241{
    237242}
    238    
    239 JSObjectRef UIScriptController::contentsOfUserInterfaceItem(JSStringRef interfaceItem) const
    240 {
    241     return nullptr;
    242 }
    243243
    244244void UIScriptController::scrollToOffset(long x, long y)
  • trunk/Tools/WebKitTestRunner/mac/UIScriptControllerMac.mm

    r208207 r208361  
    2828
    2929#import "PlatformWebView.h"
     30#import "StringFunctions.h"
    3031#import "TestController.h"
    3132#import "TestRunnerWKWebView.h"
    3233#import "UIScriptContext.h"
     34#import <JavaScriptCore/JSContext.h>
    3335#import <JavaScriptCore/JSStringRefCF.h>
     36#import <JavaScriptCore/JSValue.h>
     37#import <JavaScriptCore/JavaScriptCore.h>
     38#import <JavaScriptCore/OpaqueJSString.h>
    3439#import <WebKit/WKWebViewPrivate.h>
    3540
     
    8691}
    8792
     93JSObjectRef UIScriptController::contentsOfUserInterfaceItem(JSStringRef interfaceItem) const
     94{
     95#if WK_API_ENABLED
     96    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
     97    NSDictionary *contentDictionary = [webView _contentsOfUserInterfaceItem:toWTFString(toWK(interfaceItem))];
     98    return JSValueToObject(m_context->jsContext(), [JSValue valueWithObject:contentDictionary inContext:[JSContext contextWithJSGlobalContextRef:m_context->jsContext()]].JSValueRef, nullptr);
     99#else
     100    UNUSED_PARAM(interfaceItem);
     101    return nullptr;
     102#endif
     103}
     104
    88105} // namespace WTR
Note: See TracChangeset for help on using the changeset viewer.