[WebKit2] Form controls handling.
authorenrica@apple.com <enrica@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 26 Feb 2014 03:05:19 +0000 (03:05 +0000)
committerenrica@apple.com <enrica@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 26 Feb 2014 03:05:19 +0000 (03:05 +0000)
https://bugs.webkit.org/show_bug.cgi?id=129344
<rdar://problem/16053643>

Reviewed by Simon Fraser and Joseph Pecoraro.

../WebCore:

Adding some exports.

* WebCore.exp.in:

../WebKit2:

This is the step toward adding support for
form controls iOS style. It adds the logic to
select the appropriate keyboard type based on the
element type and introduces the AssistedNodeInformation
structure used currently for the keyboard type selection
and that will be used to populate pickers and popovers.
It also provides information to enable/disable next/previous
buttons in the accessory view.

* Scripts/webkit2/messages.py:
(struct_or_class):
* Shared/AssistedNodeInformation.cpp: Added.
(WebKit::AssistedNodeInformation::encode):
(WebKit::AssistedNodeInformation::decode):
* Shared/AssistedNodeInformation.h: Added.
(WebKit::AssistedNodeInformation::AssistedNodeInformation):
* UIProcess/PageClient.h:
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* UIProcess/ios/PageClientImplIOS.h:
* UIProcess/ios/PageClientImplIOS.mm:
(WebKit::PageClientImpl::startAssistingNode):
* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView _requiresKeyboardWhenFirstResponder]):
(-[WKContentView _updateAccessory]):
(toUITextAutocapitalize):
(-[WKContentView textInputTraits]):
(-[WKContentView assistedNodeInformation]):
(-[WKContentView _startAssistingNode:]):
(-[WKContentView _stopAssistingNode]):
* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::startAssistingNode):
* WebKit2.xcodeproj/project.pbxproj:
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::isAssistableNode):
(WebKit::hasFocusableNode):
(WebKit::WebPage::getAssistedNodeInformation):
(WebKit::WebPage::elementDidFocus):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@164690 268f45cc-cd09-0410-ab3c-d52691b4dbfc

17 files changed:
Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebKit2/ChangeLog
Source/WebKit2/Scripts/webkit2/messages.py
Source/WebKit2/Shared/AssistedNodeInformation.cpp [new file with mode: 0644]
Source/WebKit2/Shared/AssistedNodeInformation.h [new file with mode: 0644]
Source/WebKit2/UIProcess/PageClient.h
Source/WebKit2/UIProcess/WebPageProxy.h
Source/WebKit2/UIProcess/WebPageProxy.messages.in
Source/WebKit2/UIProcess/ios/PageClientImplIOS.h
Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm
Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h
Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm
Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm
Source/WebKit2/WebKit2.xcodeproj/project.pbxproj
Source/WebKit2/WebProcess/WebPage/WebPage.h
Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm

index b44aac1..cc96136 100644 (file)
@@ -1,3 +1,15 @@
+2014-02-25  Enrica Casucci  <enrica@apple.com>
+
+        [WebKit2] Form controls handling.
+        https://bugs.webkit.org/show_bug.cgi?id=129344
+        <rdar://problem/16053643>
+
+        Reviewed by Simon Fraser and Joseph Pecoraro.
+
+        Adding some exports.
+        
+        * WebCore.exp.in:
+
 2014-02-25  Samuel White  <samuel_white@apple.com>
 
         Add accessibility search predicate support for AXOutlines
index 2103464..9c9ff19 100644 (file)
@@ -249,6 +249,32 @@ __ZN7WebCore12cacheStorageEv
 __ZN7WebCore12deleteCookieERKNS_21NetworkStorageSessionERKNS_3URLERKN3WTF6StringE
 __ZN7WebCore12gcControllerEv
 __ZN7WebCore12iconDatabaseEv
+__ZN7WebCore13KeyboardEventC1Ev
+__ZN7WebCore15FocusController20nextFocusableElementENS_20FocusNavigationScopeEPNS_4NodeEPNS_13KeyboardEventE
+__ZN7WebCore15FocusController24previousFocusableElementENS_20FocusNavigationScopeEPNS_4NodeEPNS_13KeyboardEventE
+__ZNK7WebCore11HTMLElement5titleEv
+__ZNK7WebCore17HTMLOptionElement4textEv
+__ZNK7WebCore17HTMLSelectElement13selectedIndexEv
+__ZNK7WebCore22HTMLFormControlElement18autocapitalizeTypeEv
+__ZNK7WebCore16HTMLInputElement13isSearchFieldEv
+__ZNK7WebCore16HTMLInputElement20isDateTimeLocalFieldEv
+__ZNK7WebCore16HTMLInputElement13valueAsNumberEv
+__ZNK7WebCore19HTMLTextAreaElement5valueEv
+__ZNK7WebCore22HTMLFormControlElement11autocorrectEv
+__ZNK7WebCore16HTMLInputElement12isEmailFieldEv
+__ZN7WebCore20FocusNavigationScope22focusNavigationScopeOfEPNS_4NodeE
+__ZNK7WebCore16HTMLInputElement12isMonthFieldEv
+__ZNK7WebCore16HTMLInputElement11isDateFieldEv
+__ZNK7WebCore17HTMLSelectElement9listItemsEv
+__ZNK7WebCore16HTMLInputElement15isDateTimeFieldEv
+__ZNK7WebCore16HTMLInputElement11isTimeFieldEv
+__ZNK7WebCore16HTMLInputElement13isNumberFieldEv
+__ZNK7WebCore16HTMLInputElement11isWeekFieldEv
+__ZNK7WebCore16HTMLInputElement10isURLFieldEv
+__ZNK7WebCore16HTMLInputElement16isTelephoneFieldEv
+__ZN7WebCore9HTMLNames10actionAttrE
+__ZNK7WebCore7Element15getURLAttributeERKNS_13QualifiedNameE
+__ZN7WebCore16HTMLInputElement16setValueAsNumberEdRiNS_22TextFieldEventBehaviorE
 __ZN7WebCore13AXObjectCache10rootObjectEv
 __ZN7WebCore13AXObjectCache18rootObjectForFrameEPNS_5FrameE
 __ZN7WebCore13AXObjectCache19enableAccessibilityEv
index a0489b1..0e4e7b0 100644 (file)
@@ -1,3 +1,52 @@
+2014-02-25  Enrica Casucci  <enrica@apple.com>
+
+        [WebKit2] Form controls handling.
+        https://bugs.webkit.org/show_bug.cgi?id=129344
+        <rdar://problem/16053643>
+
+        Reviewed by Simon Fraser and Joseph Pecoraro.
+
+        This is the step toward adding support for
+        form controls iOS style. It adds the logic to
+        select the appropriate keyboard type based on the
+        element type and introduces the AssistedNodeInformation
+        structure used currently for the keyboard type selection
+        and that will be used to populate pickers and popovers.
+        It also provides information to enable/disable next/previous
+        buttons in the accessory view.
+
+        * Scripts/webkit2/messages.py:
+        (struct_or_class):
+        * Shared/AssistedNodeInformation.cpp: Added.
+        (WebKit::AssistedNodeInformation::encode):
+        (WebKit::AssistedNodeInformation::decode):
+        * Shared/AssistedNodeInformation.h: Added.
+        (WebKit::AssistedNodeInformation::AssistedNodeInformation):
+        * UIProcess/PageClient.h:
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        * UIProcess/ios/PageClientImplIOS.h:
+        * UIProcess/ios/PageClientImplIOS.mm:
+        (WebKit::PageClientImpl::startAssistingNode):
+        * UIProcess/ios/WKContentViewInteraction.h:
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView _requiresKeyboardWhenFirstResponder]):
+        (-[WKContentView _updateAccessory]):
+        (toUITextAutocapitalize):
+        (-[WKContentView textInputTraits]):
+        (-[WKContentView assistedNodeInformation]):
+        (-[WKContentView _startAssistingNode:]):
+        (-[WKContentView _stopAssistingNode]):
+        * UIProcess/ios/WebPageProxyIOS.mm:
+        (WebKit::WebPageProxy::startAssistingNode):
+        * WebKit2.xcodeproj/project.pbxproj:
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::isAssistableNode):
+        (WebKit::hasFocusableNode):
+        (WebKit::WebPage::getAssistedNodeInformation):
+        (WebKit::WebPage::elementDidFocus):
+
 2014-02-25  Anders Carlsson  <andersca@apple.com>
 
         VisitedLinkProvider should be refcounted
index 3640e9a..81af7bd 100644 (file)
@@ -204,6 +204,7 @@ def struct_or_class(namespace, type):
         'WebCore::ViewportArguments',
         'WebCore::ViewportAttributes',
         'WebCore::WindowFeatures',
+        'WebKit::AssistedNodeInformation',
         'WebKit::AttributedString',
         'WebKit::ColorSpaceData',
         'WebKit::ContextMenuState',
diff --git a/Source/WebKit2/Shared/AssistedNodeInformation.cpp b/Source/WebKit2/Shared/AssistedNodeInformation.cpp
new file mode 100644 (file)
index 0000000..da5971a
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2014 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 "AssistedNodeInformation.h"
+
+#include "Arguments.h"
+#include "WebCoreArgumentCoders.h"
+
+namespace WebKit {
+
+#if PLATFORM(IOS)
+void AssistedNodeInformation::encode(IPC::ArgumentEncoder& encoder) const
+{
+    encoder << elementRect;
+    encoder << hasNextNode;
+    encoder << hasPreviousNode;
+    encoder << isAutocorrect;
+    encoder << (uint32_t)autocapitalizeType;
+    encoder << (uint32_t)elementType;
+    encoder << formAction;
+    encoder << selectionOptions;
+    encoder << selectedIndex;
+    encoder << isMultiSelect;
+    encoder << isReadOnly;
+    encoder << value;
+    encoder << valueAsNumber;
+    encoder << title;
+}
+
+bool AssistedNodeInformation::decode(IPC::ArgumentDecoder& decoder, AssistedNodeInformation& result)
+{
+    if (!decoder.decode(result.elementRect))
+        return false;
+
+    if (!decoder.decode(result.hasNextNode))
+        return false;
+
+    if (!decoder.decode(result.hasPreviousNode))
+        return false;
+
+    if (!decoder.decode(result.isAutocorrect))
+        return false;
+
+    if (!decoder.decode((uint32_t&)result.autocapitalizeType))
+        return false;
+
+    if (!decoder.decode((uint32_t&)result.elementType))
+        return false;
+
+    if (!decoder.decode(result.formAction))
+        return false;
+
+    if (!decoder.decode(result.selectionOptions))
+        return false;
+
+    if (!decoder.decode(result.selectedIndex))
+        return false;
+
+    if (!decoder.decode(result.isMultiSelect))
+        return false;
+
+    if (!decoder.decode(result.isReadOnly))
+        return false;
+
+    if (!decoder.decode(result.value))
+        return false;
+
+    if (!decoder.decode(result.valueAsNumber))
+        return false;
+
+    if (!decoder.decode(result.title))
+        return false;
+
+    return true;
+}
+#endif
+
+}
diff --git a/Source/WebKit2/Shared/AssistedNodeInformation.h b/Source/WebKit2/Shared/AssistedNodeInformation.h
new file mode 100644 (file)
index 0000000..92efacc
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef AssistedNodeInformation_h
+#define AssistedNodeInformation_h
+
+#include "ArgumentCoders.h"
+#include <WebCore/IntRect.h>
+#include <WebCore/WebAutocapitalize.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebKit {
+
+enum WKInputType {
+    WKTypeNone,
+    WKTypeContentEditable,
+    WKTypeText,
+    WKTypePassword,
+    WKTypeTextArea,
+    WKTypeSearch,
+    WKTypeEmail,
+    WKTypeURL,
+    WKTypePhone,
+    WKTypeNumber,
+    WKTypeNumberPad,
+    WKTypeDate,
+    WKTypeDateTime,
+    WKTypeDateTimeLocal,
+    WKTypeMonth,
+    WKTypeWeek,
+    WKTypeTime,
+    WKTypeSelect
+};
+
+#if PLATFORM(IOS)
+struct AssistedNodeInformation {
+    AssistedNodeInformation()
+        : hasNextNode(false)
+        , hasPreviousNode(false)
+        , isAutocorrect(false)
+        , isMultiSelect(false)
+        , isReadOnly(false)
+        , autocapitalizeType(WebAutocapitalizeTypeDefault)
+        , elementType(WKTypeNone)
+        , selectedIndex(-1)
+        , valueAsNumber(0)
+    {
+    }
+
+    WebCore::IntRect elementRect;
+    bool hasNextNode;
+    bool hasPreviousNode;
+    bool isAutocorrect;
+    bool isMultiSelect;
+    bool isReadOnly;
+    WebAutocapitalizeType autocapitalizeType;
+    WKInputType elementType;
+    String formAction;
+    Vector<String> selectionOptions;
+    int selectedIndex;
+    String value;
+    double valueAsNumber;
+    String title;
+
+    void encode(IPC::ArgumentEncoder&) const;
+    static bool decode(IPC::ArgumentDecoder&, AssistedNodeInformation&);
+};
+#endif
+
+}
+
+#endif // InteractionInformationAtPosition_h
index e31bb76..0ac16e9 100644 (file)
@@ -243,7 +243,7 @@ public:
 
     virtual void didCommitLayerTree(const RemoteLayerTreeTransaction&) = 0;
 
-    virtual void startAssistingNode(const WebCore::IntRect&, bool hasNextFocusable, bool hasPreviousFocusable) = 0;
+    virtual void startAssistingNode(const AssistedNodeInformation&) = 0;
     virtual void stopAssistingNode() = 0;
     virtual void selectionDidChange() = 0;
     virtual bool interpretKeyEvent(const NativeWebKeyboardEvent&, bool isCharEvent) = 0;
index c924c97..ebee2a7 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "APIObject.h"
 #include "APISession.h"
+#include "AssistedNodeInformation.h"
 #include "AutoCorrectionCallback.h"
 #include "Connection.h"
 #include "DragControllerAction.h"
@@ -1163,7 +1164,7 @@ private:
 #if PLATFORM(IOS)
     void didGetTapHighlightGeometries(uint64_t requestID, const WebCore::Color& color, const Vector<WebCore::FloatQuad>& geometries, const WebCore::IntSize& topLeftRadius, const WebCore::IntSize& topRightRadius, const WebCore::IntSize& bottomLeftRadius, const WebCore::IntSize& bottomRightRadius);
 
-    void startAssistingNode(const WebCore::IntRect&, bool hasNextFocusable, bool hasPreviousFocusable);
+    void startAssistingNode(const AssistedNodeInformation&);
     void stopAssistingNode();
     void notifyRevealedSelection();
 #endif // PLATFORM(IOS)
index 238d2df..47f236c 100644 (file)
@@ -307,7 +307,7 @@ messages -> WebPageProxy {
 #if PLATFORM(IOS)
     DidGetTapHighlightGeometries(uint64_t requestID, WebCore::Color color, Vector<WebCore::FloatQuad> geometries, WebCore::IntSize topLeftRadius, WebCore::IntSize topRightRadius, WebCore::IntSize bottomLeftRadius, WebCore::IntSize bottomRightRadius)
 
-    StartAssistingNode(WebCore::IntRect scrollRect, bool hasNextFocusable, bool hasPreviousFocusable)
+    StartAssistingNode(WebKit::AssistedNodeInformation information)
     StopAssistingNode()
     NotifyRevealedSelection()
 #endif
index 944e0b3..a2de6b7 100644 (file)
@@ -104,7 +104,7 @@ private:
 
     virtual void didCommitLayerTree(const RemoteLayerTreeTransaction&) override;
 
-    virtual void startAssistingNode(const WebCore::IntRect&, bool hasNextFocusable, bool hasPreviousFocusable) override;
+    virtual void startAssistingNode(const AssistedNodeInformation&) override;
     virtual void stopAssistingNode() override;
     virtual void selectionDidChange() override;
     virtual bool interpretKeyEvent(const NativeWebKeyboardEvent&, bool isCharEvent) override;
index 41228fe..53b4bee 100644 (file)
@@ -347,9 +347,9 @@ void PageClientImpl::didCommitLayerTree(const RemoteLayerTreeTransaction& layerT
     [m_contentView _didCommitLayerTree:layerTreeTransaction];
 }
 
-void PageClientImpl::startAssistingNode(const WebCore::IntRect&, bool, bool)
+void PageClientImpl::startAssistingNode(const AssistedNodeInformation& nodeInformation)
 {
-    [m_contentView _startAssistingNode];
+    [m_contentView _startAssistingNode:nodeInformation];
 }
 
 void PageClientImpl::stopAssistingNode()
index 173724e..4c46544 100644 (file)
@@ -25,6 +25,7 @@
 
 #import "WKContentView.h"
 
+#import "AssistedNodeInformation.h"
 #import "InteractionInformationAtPosition.h"
 #import "WKGestureTypes.h"
 #import <UIKit/UITextInput_Private.h>
@@ -46,6 +47,7 @@ class IntSize;
 namespace WebKit {
 class NativeWebTouchEvent;
 class WebPageProxy;
+struct AssistedNodeInformation;
 struct InteractionInformationAtPosition;
 }
 
@@ -97,6 +99,7 @@ struct WKAutoCorrectionData {
 
     WebKit::WKAutoCorrectionData _autocorrectionData;
     WebKit::InteractionInformationAtPosition _positionInformation;
+    WebKit::AssistedNodeInformation _assistedNodeInformation;
 
     BOOL _isEditable;
     BOOL _showingTextStyleOptions;
@@ -111,6 +114,7 @@ struct WKAutoCorrectionData {
 @property (nonatomic, readonly) BOOL isEditable;
 @property (nonatomic, readonly) const WebKit::InteractionInformationAtPosition& positionInformation;
 @property (nonatomic, readonly) const WebKit::WKAutoCorrectionData& autocorrectionData;
+@property (nonatomic, readonly) const WebKit::AssistedNodeInformation& assistedNodeInformation;
 
 - (void)setupInteraction;
 - (void)cleanupInteraction;
@@ -118,7 +122,7 @@ struct WKAutoCorrectionData {
 - (void)_webTouchEvent:(const WebKit::NativeWebTouchEvent&)touchEvent preventsNativeGestures:(BOOL)preventsDefault;
 - (void)_didGetTapHighlightForRequest:(uint64_t)requestID color:(const WebCore::Color&)color quads:(const Vector<WebCore::FloatQuad>&)highlightedQuads topLeftRadius:(const WebCore::IntSize&)topLeftRadius topRightRadius:(const WebCore::IntSize&)topRightRadius bottomLeftRadius:(const WebCore::IntSize&)bottomLeftRadius bottomRightRadius:(const WebCore::IntSize&)bottomRightRadius;
 
-- (void)_startAssistingNode;
+- (void)_startAssistingNode:(const WebKit::AssistedNodeInformation&)information;
 - (void)_stopAssistingNode;
 - (void)_selectionChanged;
 - (BOOL)_interpretKeyEvent:(WebIOSEvent *)theEvent isCharEvent:(BOOL)isCharEvent;
index 1289f2a..af5c29d 100644 (file)
@@ -357,6 +357,23 @@ static FloatQuad inflateQuad(const FloatQuad& quad, float inflateSize)
     [self _cancelInteraction];
 }
 
+- (BOOL)_requiresKeyboardWhenFirstResponder
+{
+    // FIXME: We should add the logic to handle keyboard visibility during focus redirects.
+    switch (_assistedNodeInformation.elementType) {
+    case WebKit::WKTypeSelect:
+        return !UICurrentUserInterfaceIdiomIsPad();
+    case WebKit::WKTypeDate:
+    case WebKit::WKTypeMonth:
+    case WebKit::WKTypeDateTimeLocal:
+    case WebKit::WKTypeTime:
+        return !UICurrentUserInterfaceIdiomIsPad();
+    default:
+        return !_assistedNodeInformation.isReadOnly;
+    }
+    return NO;
+}
+
 - (BOOL)_requiresKeyboardResetOnReload
 {
     return YES;
@@ -1223,9 +1240,8 @@ static void selectionChangedWithTouch(bool error, WKContentView *view, const Web
 
 - (void)_updateAccessory
 {
-    // FIXME: We need to initialize with values from the WebProcess.
-    [_formAccessoryView setNextEnabled:YES];
-    [_formAccessoryView setPreviousEnabled:YES];
+    [_formAccessoryView setNextEnabled:_assistedNodeInformation.hasNextNode];
+    [_formAccessoryView setPreviousEnabled:_assistedNodeInformation.hasPreviousNode];
     
     [_formAccessoryView setClearVisible:NO];
 
@@ -1403,6 +1419,24 @@ static void selectionChangedWithTouch(bool error, WKContentView *view, const Web
 
 // end of UITextInput protocol implementation
 
+static UITextAutocapitalizationType toUITextAutocapitalize(WebAutocapitalizeType webkitType)
+{
+    switch (webkitType) {
+    case WebAutocapitalizeTypeDefault:
+        return UITextAutocapitalizationTypeSentences;
+    case WebAutocapitalizeTypeNone:
+        return UITextAutocapitalizationTypeNone;
+    case WebAutocapitalizeTypeWords:
+        return UITextAutocapitalizationTypeWords;
+    case WebAutocapitalizeTypeSentences:
+        return UITextAutocapitalizationTypeSentences;
+    case WebAutocapitalizeTypeAllCharacters:
+        return UITextAutocapitalizationTypeAllCharacters;
+    }
+
+    return UITextAutocapitalizationTypeSentences;
+}
+
 // UITextInputPrivate protocol
 // Direct access to the (private) UITextInputTraits object.
 - (UITextInputTraits *)textInputTraits
@@ -1410,6 +1444,40 @@ static void selectionChangedWithTouch(bool error, WKContentView *view, const Web
     if (!_traits)
         _traits = adoptNS([[UITextInputTraits alloc] init]);
 
+    [_traits setSecureTextEntry:_assistedNodeInformation.elementType == WKTypePassword];
+    [_traits setShortcutConversionType:_assistedNodeInformation.elementType == WKTypePassword ? UITextShortcutConversionTypeNo : UITextShortcutConversionTypeDefault];
+
+    if (!_assistedNodeInformation.formAction.isEmpty())
+        [_traits setReturnKeyType:(_assistedNodeInformation.elementType == WebKit::WKTypeSearch) ? UIReturnKeySearch : UIReturnKeyGo];
+
+    if (_assistedNodeInformation.elementType == WKTypePassword || _assistedNodeInformation.elementType == WKTypeEmail || _assistedNodeInformation.elementType == WKTypeURL || _assistedNodeInformation.formAction.contains("login")) {
+        [_traits setAutocapitalizationType:UITextAutocapitalizationTypeNone];
+        [_traits setAutocorrectionType:UITextAutocorrectionTypeNo];
+    } else {
+        [_traits setAutocapitalizationType:toUITextAutocapitalize(_assistedNodeInformation.autocapitalizeType)];
+        [_traits setAutocorrectionType:_assistedNodeInformation.isAutocorrect ? UITextAutocorrectionTypeYes : UITextAutocorrectionTypeNo];
+    }
+
+    switch (_assistedNodeInformation.elementType) {
+    case WebKit::WKTypePhone:
+         [_traits setKeyboardType:UIKeyboardTypePhonePad];
+         break;
+    case WebKit::WKTypeURL:
+         [_traits setKeyboardType:UIKeyboardTypeURL];
+         break;
+    case WebKit::WKTypeEmail:
+         [_traits setKeyboardType:UIKeyboardTypeEmailAddress];
+          break;
+    case WebKit::WKTypeNumber:
+         [_traits setKeyboardType:UIKeyboardTypeNumbersAndPunctuation];
+         break;
+    case WebKit::WKTypeNumberPad:
+         [_traits setKeyboardType:UIKeyboardTypeNumberPad];
+         break;
+    default:
+         [_traits setKeyboardType:UIKeyboardTypeDefault];
+    }
+
     return _traits.get();
 }
 
@@ -1700,9 +1768,16 @@ static void selectionChangedWithTouch(bool error, WKContentView *view, const Web
     [self useSelectionAssistantWithMode:UIWebSelectionModeWeb];
 }
 
-- (void)_startAssistingNode
+- (const AssistedNodeInformation&)assistedNodeInformation
+{
+    return _assistedNodeInformation;
+}
+
+- (void)_startAssistingNode:(const AssistedNodeInformation&)information
 {
     _isEditable = YES;
+    _assistedNodeInformation = information;
+    _traits = nil;
     if (![self isFirstResponder])
         [self becomeFirstResponder];
 
@@ -1714,6 +1789,7 @@ static void selectionChangedWithTouch(bool error, WKContentView *view, const Web
 - (void)_stopAssistingNode
 {
     _isEditable = NO;
+    _assistedNodeInformation.elementType = WKTypeNone;
 
     [self _stopAssistingKeyboard];
     [self reloadInputViews];
index 9bacc8c..026a96a 100644 (file)
@@ -479,9 +479,9 @@ void WebPageProxy::didGetTapHighlightGeometries(uint64_t requestID, const WebCor
     m_pageClient.didGetTapHighlightGeometries(requestID, color, highlightedQuads, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius);
 }
 
-void WebPageProxy::startAssistingNode(const WebCore::IntRect& scrollRect, bool hasNextFocusable, bool hasPreviousFocusable)
+void WebPageProxy::startAssistingNode(const AssistedNodeInformation& information)
 {
-    m_pageClient.startAssistingNode(scrollRect, hasNextFocusable, hasPreviousFocusable);
+    m_pageClient.startAssistingNode(information);
 }
 
 void WebPageProxy::stopAssistingNode()
index 6602478..0eeedea 100644 (file)
                C58CDF2A1887548B00871536 /* InteractionInformationAtPosition.h in Headers */ = {isa = PBXBuildFile; fileRef = C58CDF281887548B00871536 /* InteractionInformationAtPosition.h */; };
                C58CDF2D1887609F00871536 /* InteractionInformationAtPosition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C58CDF2B1887609F00871536 /* InteractionInformationAtPosition.cpp */; };
                C58CDF2E1887609F00871536 /* InteractionInformationAtPosition.h in Headers */ = {isa = PBXBuildFile; fileRef = C58CDF2C1887609F00871536 /* InteractionInformationAtPosition.h */; };
+               C59C4A5818B81174007BDCB6 /* AssistedNodeInformation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C59C4A5618B81174007BDCB6 /* AssistedNodeInformation.cpp */; };
+               C59C4A5918B81174007BDCB6 /* AssistedNodeInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = C59C4A5718B81174007BDCB6 /* AssistedNodeInformation.h */; };
                C5E1AFE816B20B67006CC1F2 /* WKWebArchive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC329DA516ACE5A900316DE2 /* WKWebArchive.cpp */; };
                C5E1AFE916B20B75006CC1F2 /* WKWebArchive.h in Headers */ = {isa = PBXBuildFile; fileRef = BC329DA616ACE5A900316DE2 /* WKWebArchive.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C5E1AFEA16B20B7B006CC1F2 /* WKWebArchiveResource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC329DA916ACE5BF00316DE2 /* WKWebArchiveResource.cpp */; };
                C58CDF281887548B00871536 /* InteractionInformationAtPosition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InteractionInformationAtPosition.h; sourceTree = "<group>"; };
                C58CDF2B1887609F00871536 /* InteractionInformationAtPosition.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InteractionInformationAtPosition.cpp; sourceTree = "<group>"; };
                C58CDF2C1887609F00871536 /* InteractionInformationAtPosition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InteractionInformationAtPosition.h; sourceTree = "<group>"; };
+               C59C4A5618B81174007BDCB6 /* AssistedNodeInformation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AssistedNodeInformation.cpp; sourceTree = "<group>"; };
+               C59C4A5718B81174007BDCB6 /* AssistedNodeInformation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AssistedNodeInformation.h; sourceTree = "<group>"; };
                CD5C669E134B9D36004FE2A8 /* InjectedBundlePageFullScreenClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InjectedBundlePageFullScreenClient.cpp; sourceTree = "<group>"; };
                CD5C669F134B9D37004FE2A8 /* InjectedBundlePageFullScreenClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InjectedBundlePageFullScreenClient.h; sourceTree = "<group>"; };
                CD67D30815C07BE000843ADF /* InjectedBundlePageDiagnosticLoggingClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InjectedBundlePageDiagnosticLoggingClient.cpp; sourceTree = "<group>"; };
                                BC90A1D0122DD55E00CC8C50 /* APIURLResponse.h */,
                                A7D792D51767CB6E00881CBE /* ActivityAssertion.cpp */,
                                A7D792D41767CB0900881CBE /* ActivityAssertion.h */,
+                               C59C4A5618B81174007BDCB6 /* AssistedNodeInformation.cpp */,
+                               C59C4A5718B81174007BDCB6 /* AssistedNodeInformation.h */,
                                515E7725183DD6F60007203F /* AsyncRequest.cpp */,
                                515E7726183DD6F60007203F /* AsyncRequest.h */,
                                51BA24431858EE3000EA2811 /* AsyncTask.h */,
                                1AE4987811FF7FAA0048B464 /* JSNPObject.h in Headers */,
                                BCE0937814FB128C001138D9 /* LayerHostingContext.h in Headers */,
                                1A92DC1112F8BA460017AF65 /* LayerTreeContext.h in Headers */,
+                               C59C4A5918B81174007BDCB6 /* AssistedNodeInformation.h in Headers */,
                                1A186EEA12EF7618008E5F37 /* LayerTreeHost.h in Headers */,
                                1A1D8BA21731A36300141DA4 /* LocalStorageDatabase.h in Headers */,
                                1A8C728D1738477C000A6554 /* LocalStorageDatabaseTracker.h in Headers */,
                                0FCB4E4918BBE044000FCFC9 /* WKActionSheet.mm in Sources */,
                                5153569C1291B1D2000749DC /* WebPageContextMenuClient.cpp in Sources */,
                                C06C6095124C144B0001682F /* WebPageCreationParameters.cpp in Sources */,
+                               C59C4A5818B81174007BDCB6 /* AssistedNodeInformation.cpp in Sources */,
                                BC7B6207129A0A6700D174A4 /* WebPageGroup.cpp in Sources */,
                                BC7B625312A43C9600D174A4 /* WebPageGroupData.cpp in Sources */,
                                BC7B621612A4219A00D174A4 /* WebPageGroupProxy.cpp in Sources */,
index 124e8a0..1576b0e 100644 (file)
@@ -160,6 +160,7 @@ class WebPageGroupProxy;
 class WebPopupMenu;
 class WebVideoFullscreenManager;
 class WebWheelEvent;
+struct AssistedNodeInformation;
 struct AttributedString;
 struct EditorState;
 struct InteractionInformationAtPosition;
@@ -749,6 +750,7 @@ private:
     PassRefPtr<WebCore::Range> changeBlockSelection(const WebCore::IntPoint&, WKHandlePosition, float& growThreshold, float& shrinkThreshold, WKSelectionFlags&);
     PassRefPtr<WebCore::Range> expandedRangeFromHandle(WebCore::Range*, WKHandlePosition);
     PassRefPtr<WebCore::Range> contractedRangeFromHandle(WebCore::Range* currentRange, WKHandlePosition, WKSelectionFlags&);
+    void getAssistedNodeInformation(AssistedNodeInformation&);
 
     RefPtr<WebCore::Range> m_currentBlockSelection;
 #endif
index 2fbf8de..7159596 100644 (file)
@@ -26,6 +26,7 @@
 #import "config.h"
 #import "WebPage.h"
 
+#import "AssistedNodeInformation.h"
 #import "EditorState.h"
 #import "InteractionInformationAtPosition.h"
 #import "WebChromeClient.h"
 #import <WebCore/FrameView.h>
 #import <WebCore/HitTestResult.h>
 #import <WebCore/HTMLElementTypeHelpers.h>
+#import <WebCore/HTMLFormElement.h>
+#import <WebCore/HTMLInputElement.h>
+#import <WebCore/HTMLOptionElement.h>
 #import <WebCore/HTMLParserIdioms.h>
+#import <WebCore/HTMLSelectElement.h>
+#import <WebCore/HTMLTextAreaElement.h>
 #import <WebCore/MainFrame.h>
 #import <WebCore/Node.h>
 #import <WebCore/NotImplemented.h>
@@ -1475,11 +1481,111 @@ void WebPage::performActionOnElement(uint32_t action)
     }
 }
 
+static inline bool isAssistableNode(Node* node)
+{
+    if (isHTMLSelectElement(node))
+        return true;
+    if (isHTMLTextAreaElement(node))
+        return !toHTMLTextAreaElement(node)->isReadOnlyNode();
+    if (isHTMLInputElement(node)) {
+        HTMLInputElement* element = toHTMLInputElement(node);
+        return !element->isReadOnlyNode() && (element->isTextField() || element->isDateField() || element->isDateTimeLocalField() || element->isMonthField() || element->isTimeField());
+    }
+
+    return node->isContentEditable();
+}
+
+static inline bool hasFocusableNode(Node* startNode, Page* page, bool isForward)
+{
+    RefPtr<KeyboardEvent> key = KeyboardEvent::create();
+
+    Node* nextNode = startNode;
+    do {
+        nextNode = isForward ? page->focusController().nextFocusableElement(FocusNavigationScope::focusNavigationScopeOf(&nextNode->document()), nextNode, key.get())
+            : page->focusController().previousFocusableElement(FocusNavigationScope::focusNavigationScopeOf(&nextNode->document()), nextNode, key.get());
+    } while (nextNode && !isAssistableNode(startNode));
+
+    return nextNode;
+}
+
+void WebPage::getAssistedNodeInformation(AssistedNodeInformation& information)
+{
+    information.elementRect = m_page->focusController().focusedOrMainFrame().view()->contentsToRootView(m_assistedNode->renderer()->absoluteBoundingBoxRect());
+    information.hasNextNode = hasFocusableNode(m_assistedNode.get(), m_page.get(), true);
+    information.hasPreviousNode = hasFocusableNode(m_assistedNode.get(), m_page.get(), false);
+
+    if (isHTMLSelectElement(m_assistedNode.get())) {
+        HTMLSelectElement* element = toHTMLSelectElement(m_assistedNode.get());
+        information.elementType = WKTypeSelect;
+        size_t count = element->listItems().size();
+        // FIXME: We need to handle group elements as well
+        for (size_t i = 0; i < count; ++i) {
+            HTMLOptionElement* item = toHTMLOptionElement(element->listItems()[i]);
+            information.selectionOptions.append(item->text());
+        }
+        information.selectedIndex = element->selectedIndex();
+        information.isMultiSelect = element->multiple();
+    } else if (isHTMLTextAreaElement(m_assistedNode.get())) {
+        HTMLTextAreaElement* element = toHTMLTextAreaElement(m_assistedNode.get());
+        information.autocapitalizeType = static_cast<WebAutocapitalizeType>(element->autocapitalizeType());
+        information.isAutocorrect = element->autocorrect();
+        information.elementType = WKTypeTextArea;
+        information.isReadOnly = element->isReadOnly();
+        information.value = element->value();
+    } else if (isHTMLInputElement(m_assistedNode.get())) {
+        HTMLInputElement* element = toHTMLInputElement(m_assistedNode.get());
+        HTMLFormElement* form = element->form();
+        if (form)
+            information.formAction = form->getURLAttribute(WebCore::HTMLNames::actionAttr);
+        information.autocapitalizeType = static_cast<WebAutocapitalizeType>(element->autocapitalizeType());
+        information.isAutocorrect = element->autocorrect();
+        if (element->isPasswordField())
+            information.elementType = WKTypePassword;
+        else if (element->isSearchField())
+            information.elementType = WKTypeSearch;
+        else if (element->isEmailField())
+            information.elementType = WKTypeEmail;
+        else if (element->isTelephoneField())
+            information.elementType = WKTypePhone;
+        else if (element->isNumberField())
+            information.elementType = element->getAttribute("pattern") == "\\d*" || element->getAttribute("pattern") == "[0-9]*" ? WKTypeNumberPad : WKTypeNumber;
+        else if (element->isDateTimeLocalField())
+            information.elementType = WKTypeDateTimeLocal;
+        else if (element->isDateField())
+            information.elementType = WKTypeDate;
+        else if (element->isDateTimeField())
+            information.elementType = WKTypeDateTime;
+        else if (element->isTimeField())
+            information.elementType = WKTypeTime;
+        else if (element->isWeekField())
+            information.elementType = WKTypeWeek;
+        else if (element->isMonthField())
+            information.elementType = WKTypeMonth;
+        else if (element->isURLField())
+            information.elementType = WKTypeURL;
+        else if (element->isText())
+            information.elementType = element->getAttribute("pattern") == "\\d*" || element->getAttribute("pattern") == "[0-9]*" ? WKTypeNumberPad : WKTypeText;
+
+        information.isReadOnly = element->isReadOnly();
+        information.value = element->value();
+        information.valueAsNumber = element->valueAsNumber();
+        information.title = element->title();
+    } else if (m_assistedNode->hasEditableStyle()) {
+        information.elementType = WKTypeContentEditable;
+        information.isAutocorrect = true;   // FIXME: Should we look at the attribute?
+        information.autocapitalizeType = WebAutocapitalizeTypeSentences; // FIXME: Should we look at the attribute?
+        information.isReadOnly = false;
+    }
+}
+
 void WebPage::elementDidFocus(WebCore::Node* node)
 {
     m_assistedNode = node;
-    if (node->hasTagName(WebCore::HTMLNames::inputTag) || node->hasTagName(WebCore::HTMLNames::textareaTag) || node->hasEditableStyle())
-        send(Messages::WebPageProxy::StartAssistingNode(WebCore::IntRect(), true, true));    
+    if (node->hasTagName(WebCore::HTMLNames::inputTag) || node->hasTagName(WebCore::HTMLNames::textareaTag) || node->hasEditableStyle()) {
+        AssistedNodeInformation information;
+        getAssistedNodeInformation(information);
+        send(Messages::WebPageProxy::StartAssistingNode(information));
+    }
 }
 
 void WebPage::elementDidBlur(WebCore::Node* node)