⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 242696 in webkit


Ignore:
Timestamp:
Mar 10, 2019, 8:32:50 PM (7 years ago)
Author:
timothy_horton@apple.com
Message:

Add SPI to retrieve the set of text inputs in a given rect, and later focus one
https://bugs.webkit.org/show_bug.cgi?id=195499

Reviewed by Darin Adler.

Source/WebCore:

New API tests: WebKit.RequestTextInputContext and WebKit.FocusTextInputContext

  • WebCore.xcodeproj/project.pbxproj:
  • dom/Document.cpp:

(WebCore::Document::identifierForElement):
(WebCore::Document::elementWithIdentifier):
(WebCore::Document::identifiedElementWasRemovedFromDocument):

  • dom/Document.h:

Add a mechanism where Document will vend an ObjectIdentifier for a given
element, and can (if possible) retrieve that element later.

  • dom/Element.cpp:

(WebCore::Element::removedFromAncestor):
If an Element has an identifier created for it, inform Document to remove
it from the identifier map when the element is detached.

(WebCore::Element::createElementIdentifier):

  • dom/Element.h:
  • dom/ElementIdentifier.h: Added.
  • dom/ElementRareData.cpp:
  • dom/ElementRareData.h:

(WebCore::ElementRareData::hasElementIdentifier const):
(WebCore::ElementRareData::setHasElementIdentifier):
(WebCore::ElementRareData::ElementRareData):
Store a bit indicating if the Element has had a identifier created for it,
so that we can avoid a hash lookup on every Element removal.

  • dom/Node.h:
  • html/HTMLTextFormControlElement.h:

Source/WebKit:

  • Scripts/webkit/messages.py:
  • Shared/TextInputContext.cpp: Added.

(IPC::ArgumentCoder<WebKit::TextInputContext>::encode):
(IPC::ArgumentCoder<WebKit::TextInputContext>::decode):

  • Shared/TextInputContext.h: Added.

(WebKit::TextInputContext::operator== const):
Add TextInputContext, which represents a minimal set of information
about a text field.

  • Sources.txt:
  • SourcesCocoa.txt:
  • UIProcess/API/Cocoa/WKWebView.mm:

(-[WKWebView _requestTextInputContextsInRect:completionHandler:]):
(-[WKWebView _focusTextInputContext:completionHandler:]):

  • UIProcess/API/Cocoa/WKWebViewPrivate.h:

Add SPI that allows clients to asynchronously request text input
contexts for a given rect, and later focus a given context.

  • UIProcess/API/Cocoa/_WKTextInputContext.h: Added.
  • UIProcess/API/Cocoa/_WKTextInputContext.mm: Added.

(-[_WKTextInputContext _initWithTextInputContext:]):
(-[_WKTextInputContext boundingRect]):
(-[_WKTextInputContext _textInputContext]):
(-[_WKTextInputContext isEqual:]):
(-[_WKTextInputContext hash]):
(-[_WKTextInputContext copyWithZone:]):

  • UIProcess/API/Cocoa/_WKTextInputContextInternal.h: Added.

Add an SPI object that exposes a read-only window on a TextInputContext to clients.

  • UIProcess/WebPageProxy.cpp:

(WebKit::WebPageProxy::textInputContextsInRect):
(WebKit::WebPageProxy::focusTextInputContext):

  • UIProcess/WebPageProxy.h:

Plumbing from WKWebView<->WebPage.

  • WebKit.xcodeproj/project.pbxproj:
  • WebProcess/WebPage/WebPage.cpp:

(WebKit::elementRectInWindowCoordinates):
(WebKit::isEditableTextInputElement):
(WebKit::WebPage::textInputContextsInRect):
Search the DOM for text input contexts: <input type='text'> (or other
form fields that fall back on text field behavior), <textarea>, and
contenteditable roots. Store the WebPage, Document, and Element identifiers
so that we can find the element again later.

(WebKit::WebPage::focusTextInputContext):
Find the element for a given (web page, document, element) triple and focus it,
if it's still available.

  • WebProcess/WebPage/WebPage.h:
  • WebProcess/WebPage/WebPage.messages.in:

Tools:

  • TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
  • TestWebKitAPI/Tests/WebKitCocoa/RequestTextInputContext.mm: Added.

(-[WKWebView synchronouslyRequestTextInputContextsInRect:]):
(-[WKWebView synchronouslyFocusTextInputContext:]):
(applyStyle):
(applyIframe):
(TEST):
Add some tests for this SPI.

Location:
trunk
Files:
7 added
24 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r242689 r242696  
     12019-03-10  Tim Horton  <timothy_horton@apple.com>
     2
     3        Add SPI to retrieve the set of text inputs in a given rect, and later focus one
     4        https://bugs.webkit.org/show_bug.cgi?id=195499
     5
     6        Reviewed by Darin Adler.
     7
     8        New API tests: WebKit.RequestTextInputContext and WebKit.FocusTextInputContext
     9
     10        * WebCore.xcodeproj/project.pbxproj:
     11        * dom/Document.cpp:
     12        (WebCore::Document::identifierForElement):
     13        (WebCore::Document::elementWithIdentifier):
     14        (WebCore::Document::identifiedElementWasRemovedFromDocument):
     15        * dom/Document.h:
     16        Add a mechanism where Document will vend an ObjectIdentifier for a given
     17        element, and can (if possible) retrieve that element later.
     18
     19        * dom/Element.cpp:
     20        (WebCore::Element::removedFromAncestor):
     21        If an Element has an identifier created for it, inform Document to remove
     22        it from the identifier map when the element is detached.
     23
     24        (WebCore::Element::createElementIdentifier):
     25        * dom/Element.h:
     26        * dom/ElementIdentifier.h: Added.
     27        * dom/ElementRareData.cpp:
     28        * dom/ElementRareData.h:
     29        (WebCore::ElementRareData::hasElementIdentifier const):
     30        (WebCore::ElementRareData::setHasElementIdentifier):
     31        (WebCore::ElementRareData::ElementRareData):
     32        Store a bit indicating if the Element has had a identifier created for it,
     33        so that we can avoid a hash lookup on every Element removal.
     34
     35        * dom/Node.h:
     36        * html/HTMLTextFormControlElement.h:
     37
    1382019-03-10  Zalan Bujtas  <zalan@apple.com>
    239
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r242664 r242696  
    749749                2D29ECC8192ECC8300984B78 /* DisplayRefreshMonitorManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D29ECC4192ECC8300984B78 /* DisplayRefreshMonitorManager.h */; settings = {ATTRIBUTES = (Private, ); }; };
    750750                2D29ECCA192F1F1D00984B78 /* DisplayRefreshMonitorIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D29ECC9192F1F1D00984B78 /* DisplayRefreshMonitorIOS.h */; };
     751                2D2BEB312234A335005544CA /* ElementIdentifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D2BEB2F2234A334005544CA /* ElementIdentifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
    751752                2D2E34AC21A4E192004598B5 /* EditableImageReference.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D2E34A921A4E191004598B5 /* EditableImageReference.h */; };
    752753                2D3A0E3613A7D76100E85AF0 /* SVGParsingError.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D3A0E3513A7D76100E85AF0 /* SVGParsingError.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    66986699                2D29ECC4192ECC8300984B78 /* DisplayRefreshMonitorManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DisplayRefreshMonitorManager.h; sourceTree = "<group>"; };
    66996700                2D29ECC9192F1F1D00984B78 /* DisplayRefreshMonitorIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DisplayRefreshMonitorIOS.h; sourceTree = "<group>"; };
     6701                2D2BEB2F2234A334005544CA /* ElementIdentifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementIdentifier.h; sourceTree = "<group>"; };
    67006702                2D2E34A921A4E191004598B5 /* EditableImageReference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EditableImageReference.h; sourceTree = "<group>"; };
    67016703                2D2E34AB21A4E192004598B5 /* EditableImageReference.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EditableImageReference.cpp; sourceTree = "<group>"; };
     
    2759327595                                B5B7A16E17C1048000E4AA0A /* ElementData.h */,
    2759427596                                ADE11F4A18D8311B0078983B /* ElementDescendantIterator.h */,
     27597                                2D2BEB2F2234A334005544CA /* ElementIdentifier.h */,
    2759527598                                E4AE7C1517D1BB950009FB31 /* ElementIterator.h */,
    2759627599                                E401C27417CE53EC00C41A35 /* ElementIteratorAssertions.h */,
     
    2919729200                                B5B7A17117C10AC000E4AA0A /* ElementData.h in Headers */,
    2919829201                                93D437A11D57B3F400AB85EA /* ElementDescendantIterator.h in Headers */,
     29202                                2D2BEB312234A335005544CA /* ElementIdentifier.h in Headers */,
    2919929203                                E4AE7C1617D1BB950009FB31 /* ElementIterator.h in Headers */,
    2920029204                                E401C27517CE53EC00C41A35 /* ElementIteratorAssertions.h in Headers */,
  • trunk/Source/WebCore/dom/Document.cpp

    r242664 r242696  
    86138613}
    86148614
     8615ElementIdentifier Document::identifierForElement(Element& element)
     8616{
     8617    ASSERT(&element.document() == this);
     8618    auto result = m_identifiedElementsMap.ensure(&element, [&] {
     8619        return element.createElementIdentifier();
     8620    });
     8621    return result.iterator->value;
     8622}
     8623
     8624Element* Document::searchForElementByIdentifier(const ElementIdentifier& identifier)
     8625{
     8626    for (auto it = m_identifiedElementsMap.begin(); it != m_identifiedElementsMap.end(); ++it) {
     8627        if (it->value == identifier)
     8628            return it->key;
     8629    }
     8630
     8631    return nullptr;
     8632}
     8633
     8634void Document::identifiedElementWasRemovedFromDocument(Element& element)
     8635{
     8636    m_identifiedElementsMap.remove(&element);
     8637}
     8638
    86158639#if ENABLE(DEVICE_ORIENTATION)
    86168640
  • trunk/Source/WebCore/dom/Document.h

    r242664 r242696  
    3535#include "DocumentIdentifier.h"
    3636#include "DocumentTiming.h"
     37#include "ElementIdentifier.h"
    3738#include "FocusDirection.h"
    3839#include "FontSelectorClient.h"
     
    389390    WEBCORE_EXPORT static DocumentsMap& allDocumentsMap();
    390391
     392    WEBCORE_EXPORT ElementIdentifier identifierForElement(Element&);
     393    WEBCORE_EXPORT Element* searchForElementByIdentifier(const ElementIdentifier&);
     394    void identifiedElementWasRemovedFromDocument(Element&);
     395
    391396    MediaQueryMatcher& mediaQueryMatcher();
    392397
     
    20842089    std::unique_ptr<ContentChangeObserver> m_contentChangeObserver;
    20852090#endif
     2091
     2092    HashMap<Element*, ElementIdentifier> m_identifiedElementsMap;
    20862093};
    20872094
  • trunk/Source/WebCore/dom/Element.cpp

    r242137 r242696  
    20502050        frame->page()->removeLatchingStateForTarget(*this);
    20512051#endif
     2052
     2053    if (hasRareData() && elementRareData()->hasElementIdentifier()) {
     2054        document().identifiedElementWasRemovedFromDocument(*this);
     2055        elementRareData()->setHasElementIdentifier(false);
     2056    }
    20522057}
    20532058
     
    41584163}
    41594164
     4165ElementIdentifier Element::createElementIdentifier()
     4166{
     4167    auto& rareData = ensureElementRareData();
     4168    ASSERT(!rareData.hasElementIdentifier());
     4169
     4170    rareData.setHasElementIdentifier(true);
     4171    return ElementIdentifier::generate();
     4172}
     4173
    41604174#if ENABLE(CSS_TYPED_OM)
    41614175StylePropertyMap* Element::attributeStyleMap()
  • trunk/Source/WebCore/dom/Element.h

    r240906 r242696  
    593593    Vector<RefPtr<WebAnimation>> getAnimations();
    594594
     595    ElementIdentifier createElementIdentifier();
     596
    595597#if ENABLE(POINTER_EVENTS)
    596598    OptionSet<TouchAction> computedTouchActions() const;
  • trunk/Source/WebCore/dom/ElementRareData.cpp

    r239341 r242696  
    3838    unsigned short childIndex;
    3939#if ENABLE(FULLSCREEN_API)
     40    unsigned bitfields : 12;
     41#else
    4042    unsigned bitfields : 11;
    41 #else
    42     unsigned bitfields : 10;
    4343#endif
    4444    LayoutSize sizeForResizing;
  • trunk/Source/WebCore/dom/ElementRareData.h

    r239341 r242696  
    123123    bool hasCSSAnimation() const { return m_hasCSSAnimation; }
    124124    void setHasCSSAnimation(bool value) { m_hasCSSAnimation = value; }
     125
     126    bool hasElementIdentifier() const { return m_hasElementIdentifier; }
     127    void setHasElementIdentifier(bool value) { m_hasElementIdentifier = value; }
    125128
    126129#if ENABLE(INTERSECTION_OBSERVER)
     
    181184    unsigned m_hasPendingResources : 1;
    182185    unsigned m_hasCSSAnimation : 1;
     186    unsigned m_hasElementIdentifier : 1;
    183187    unsigned m_childrenAffectedByHover : 1;
    184188    unsigned m_childrenAffectedByDrag : 1;
     
    229233    , m_hasPendingResources(false)
    230234    , m_hasCSSAnimation(false)
     235    , m_hasElementIdentifier(false)
    231236    , m_childrenAffectedByHover(false)
    232237    , m_childrenAffectedByDrag(false)
  • trunk/Source/WebCore/dom/Node.h

    r241932 r242696  
    284284    virtual bool canContainRangeEndPoint() const { return false; }
    285285
    286     bool isRootEditableElement() const;
     286    WEBCORE_EXPORT bool isRootEditableElement() const;
    287287    WEBCORE_EXPORT Element* rootEditableElement() const;
    288288
  • trunk/Source/WebCore/html/HTMLTextFormControlElement.h

    r237647 r242696  
    9999#endif
    100100
     101    WEBCORE_EXPORT virtual bool isInnerTextElementEditable() const;
     102
    101103protected:
    102104    HTMLTextFormControlElement(const QualifiedName&, Document&, HTMLFormElement*);
     
    108110    void disabledStateChanged() override;
    109111    void readOnlyStateChanged() override;
    110     virtual bool isInnerTextElementEditable() const;
     112
    111113    void updateInnerTextElementEditability();
    112114
  • trunk/Source/WebKit/ChangeLog

    r242695 r242696  
     12019-03-10  Tim Horton  <timothy_horton@apple.com>
     2
     3        Add SPI to retrieve the set of text inputs in a given rect, and later focus one
     4        https://bugs.webkit.org/show_bug.cgi?id=195499
     5
     6        Reviewed by Darin Adler.
     7
     8        * Scripts/webkit/messages.py:
     9        * Shared/TextInputContext.cpp: Added.
     10        (IPC::ArgumentCoder<WebKit::TextInputContext>::encode):
     11        (IPC::ArgumentCoder<WebKit::TextInputContext>::decode):
     12        * Shared/TextInputContext.h: Added.
     13        (WebKit::TextInputContext::operator== const):
     14        Add TextInputContext, which represents a minimal set of information
     15        about a text field.
     16
     17        * Sources.txt:
     18        * SourcesCocoa.txt:
     19        * UIProcess/API/Cocoa/WKWebView.mm:
     20        (-[WKWebView _requestTextInputContextsInRect:completionHandler:]):
     21        (-[WKWebView _focusTextInputContext:completionHandler:]):
     22        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
     23        Add SPI that allows clients to asynchronously request text input
     24        contexts for a given rect, and later focus a given context.
     25
     26        * UIProcess/API/Cocoa/_WKTextInputContext.h: Added.
     27        * UIProcess/API/Cocoa/_WKTextInputContext.mm: Added.
     28        (-[_WKTextInputContext _initWithTextInputContext:]):
     29        (-[_WKTextInputContext boundingRect]):
     30        (-[_WKTextInputContext _textInputContext]):
     31        (-[_WKTextInputContext isEqual:]):
     32        (-[_WKTextInputContext hash]):
     33        (-[_WKTextInputContext copyWithZone:]):
     34        * UIProcess/API/Cocoa/_WKTextInputContextInternal.h: Added.
     35        Add an SPI object that exposes a read-only window on a TextInputContext to clients.
     36
     37        * UIProcess/WebPageProxy.cpp:
     38        (WebKit::WebPageProxy::textInputContextsInRect):
     39        (WebKit::WebPageProxy::focusTextInputContext):
     40        * UIProcess/WebPageProxy.h:
     41        Plumbing from WKWebView<->WebPage.
     42
     43        * WebKit.xcodeproj/project.pbxproj:
     44        * WebProcess/WebPage/WebPage.cpp:
     45        (WebKit::elementRectInWindowCoordinates):
     46        (WebKit::isEditableTextInputElement):
     47        (WebKit::WebPage::textInputContextsInRect):
     48        Search the DOM for text input contexts: <input type='text'> (or other
     49        form fields that fall back on text field behavior), <textarea>, and
     50        contenteditable roots. Store the WebPage, Document, and Element identifiers
     51        so that we can find the element again later.
     52
     53        (WebKit::WebPage::focusTextInputContext):
     54        Find the element for a given (web page, document, element) triple and focus it,
     55        if it's still available.
     56
     57        * WebProcess/WebPage/WebPage.h:
     58        * WebProcess/WebPage/WebPage.messages.in:
     59
    1602019-03-10  Tim Horton  <timothy_horton@apple.com>
    261
  • trunk/Source/WebKit/Scripts/webkit/messages.py

    r242317 r242696  
    454454        'WebKit::WebTouchEvent': ['"WebEvent.h"'],
    455455        'WebKit::WebWheelEvent': ['"WebEvent.h"'],
     456        'struct WebKit::TextInputContext': ['"TextInputContext.h"'],
    456457        'struct WebKit::WebUserScriptData': ['"WebUserContentControllerDataTypes.h"'],
    457458        'struct WebKit::WebUserStyleSheetData': ['"WebUserContentControllerDataTypes.h"'],
  • trunk/Source/WebKit/Sources.txt

    r242503 r242696  
    129129Shared/SharedStringHashTable.cpp
    130130Shared/StatisticsData.cpp
     131Shared/TextInputContext.cpp
    131132Shared/TouchBarMenuData.cpp
    132133Shared/TouchBarMenuItemData.cpp
  • trunk/Source/WebKit/SourcesCocoa.txt

    r242616 r242696  
    255255UIProcess/API/Cocoa/_WKRemoteWebInspectorViewController.mm
    256256UIProcess/API/Cocoa/_WKSessionState.mm
     257UIProcess/API/Cocoa/_WKTextInputContext.mm
    257258UIProcess/API/Cocoa/_WKThumbnailView.mm
    258259UIProcess/API/Cocoa/_WKUserContentExtensionStore.mm
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm

    r242400 r242696  
    5050#import "RemoteObjectRegistryMessages.h"
    5151#import "SafeBrowsingWarning.h"
     52#import "TextInputContext.h"
    5253#import "UIDelegate.h"
    5354#import "UserMediaProcessManager.h"
     
    9798#import "_WKRemoteObjectRegistryInternal.h"
    9899#import "_WKSessionStateInternal.h"
     100#import "_WKTextInputContextInternal.h"
    99101#import "_WKVisitedLinkStoreInternal.h"
    100102#import "_WKWebsitePoliciesInternal.h"
     
    48274829}
    48284830
     4831- (void)_requestTextInputContextsInRect:(CGRect)rect completionHandler:(void(^)(NSArray<_WKTextInputContext *> *))completionHandler
     4832{
     4833    _page->textInputContextsInRect(rect, [capturedCompletionHandler = makeBlockPtr(completionHandler)] (const Vector<WebKit::TextInputContext>& contexts) {
     4834        RetainPtr<NSMutableArray> elements = adoptNS([[NSMutableArray alloc] initWithCapacity:contexts.size()]);
     4835
     4836        for (const auto& context : contexts)
     4837            [elements addObject:adoptNS([[_WKTextInputContext alloc] _initWithTextInputContext:context]).get()];
     4838
     4839        capturedCompletionHandler(elements.get());
     4840    });
     4841}
     4842
     4843- (void)_focusTextInputContext:(_WKTextInputContext *)textInputContext completionHandler:(void(^)(BOOL))completionHandler
     4844{
     4845    auto webContext = [textInputContext _textInputContext];
     4846    if (webContext.webPageIdentifier != _page->pageID())
     4847        [NSException raise:NSInvalidArgumentException format:@"The provided _WKTextInputContext was not created by this WKWebView."];
     4848
     4849    [self becomeFirstResponder];
     4850
     4851    _page->focusTextInputContext(webContext, [capturedCompletionHandler = makeBlockPtr(completionHandler)](bool success) {
     4852        capturedCompletionHandler(success);
     4853    });
     4854}
     4855
    48294856#if PLATFORM(MAC)
    48304857- (void)_setShouldSuppressFirstResponderChanges:(BOOL)shouldSuppress
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h

    r242339 r242696  
    112112@class _WKSafeBrowsingWarning;
    113113@class _WKSessionState;
     114@class _WKTextInputContext;
    114115@class _WKThumbnailView;
    115116@class _WKWebsitePolicies;
     
    419420- (void)_suspendAllMediaPlayback;
    420421- (void)_resumeAllMediaPlayback;
     422
     423- (void)_requestTextInputContextsInRect:(CGRect)rect completionHandler:(void(^)(NSArray<_WKTextInputContext *> *))completionHandler WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
     424- (void)_focusTextInputContext:(_WKTextInputContext *)textInputElement completionHandler:(void(^)(BOOL))completionHandler WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
     425
    421426@end
    422427
  • trunk/Source/WebKit/UIProcess/WebPageProxy.cpp

    r242678 r242696  
    8484#include "TextChecker.h"
    8585#include "TextCheckerState.h"
     86#include "TextInputContext.h"
    8687#include "UIMessagePortChannelProvider.h"
    8788#include "URLSchemeTaskParameters.h"
     
    88188819}
    88198820
     8821void WebPageProxy::textInputContextsInRect(WebCore::FloatRect rect, CompletionHandler<void(const Vector<WebKit::TextInputContext>&)>&& completionHandler)
     8822{
     8823    if (!isValid()) {
     8824        completionHandler({ });
     8825        return;
     8826    }
     8827
     8828    m_process->connection()->sendWithAsyncReply(Messages::WebPage::TextInputContextsInRect(rect), WTFMove(completionHandler), m_pageID);
     8829}
     8830
     8831void WebPageProxy::focusTextInputContext(const TextInputContext& context, CompletionHandler<void(bool)>&& completionHandler)
     8832{
     8833    if (!isValid()) {
     8834        completionHandler(false);
     8835        return;
     8836    }
     8837
     8838    m_process->connection()->sendWithAsyncReply(Messages::WebPage::FocusTextInputContext(context), WTFMove(completionHandler), m_pageID);
     8839}
     8840
    88208841} // namespace WebKit
    88218842
  • trunk/Source/WebKit/UIProcess/WebPageProxy.h

    r242678 r242696  
    276276struct PlatformPopupMenuData;
    277277struct PrintInfo;
     278struct TextInputContext;
    278279struct WebPopupItem;
    279280struct URLSchemeTaskParameters;
     
    606607    void requestFontAttributesAtSelectionStart(Function<void(const WebCore::FontAttributes&, CallbackBase::Error)>&&);
    607608    void fontAttributesCallback(const WebCore::FontAttributes&, CallbackID);
     609
     610    void textInputContextsInRect(WebCore::FloatRect, CompletionHandler<void(const Vector<TextInputContext>&)>&&);
     611    void focusTextInputContext(const TextInputContext&, CompletionHandler<void(bool)>&&);
    608612
    609613#if PLATFORM(IOS_FAMILY)
  • trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj

    r242686 r242696  
    727727                2DE6943D18BD2A68005C15E5 /* SmartMagnificationControllerMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2DE6943B18BD2A68005C15E5 /* SmartMagnificationControllerMessageReceiver.cpp */; };
    728728                2DE6943E18BD2A68005C15E5 /* SmartMagnificationControllerMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DE6943C18BD2A68005C15E5 /* SmartMagnificationControllerMessages.h */; };
     729                2DE9B1352231B5B2005287B7 /* TextInputContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DE9B1332231B5B2005287B7 /* TextInputContext.h */; };
     730                2DE9B13A2231F61C005287B7 /* _WKTextInputContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DE9B1382231F61C005287B7 /* _WKTextInputContext.h */; settings = {ATTRIBUTES = (Private, ); }; };
     731                2DE9B13C2231F77C005287B7 /* _WKTextInputContextInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DE9B13B2231F77C005287B7 /* _WKTextInputContextInternal.h */; };
    729732                2DEAC5CF1AC368BB00A195D8 /* _WKFindOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DEAC5CE1AC368BB00A195D8 /* _WKFindOptions.h */; settings = {ATTRIBUTES = (Private, ); }; };
    730733                2DEB1D2E2127473600933906 /* ArgumentCodersCF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AAF0C4912B16334008E49E2 /* ArgumentCodersCF.cpp */; };
     
    27862789                2DE6943B18BD2A68005C15E5 /* SmartMagnificationControllerMessageReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SmartMagnificationControllerMessageReceiver.cpp; path = DerivedSources/WebKit2/SmartMagnificationControllerMessageReceiver.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
    27872790                2DE6943C18BD2A68005C15E5 /* SmartMagnificationControllerMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SmartMagnificationControllerMessages.h; path = DerivedSources/WebKit2/SmartMagnificationControllerMessages.h; sourceTree = BUILT_PRODUCTS_DIR; };
     2791                2DE9B1332231B5B2005287B7 /* TextInputContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextInputContext.h; sourceTree = "<group>"; };
     2792                2DE9B1342231B5B2005287B7 /* TextInputContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextInputContext.cpp; sourceTree = "<group>"; };
     2793                2DE9B1372231F61C005287B7 /* _WKTextInputContext.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _WKTextInputContext.mm; sourceTree = "<group>"; };
     2794                2DE9B1382231F61C005287B7 /* _WKTextInputContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKTextInputContext.h; sourceTree = "<group>"; };
     2795                2DE9B13B2231F77C005287B7 /* _WKTextInputContextInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKTextInputContextInternal.h; sourceTree = "<group>"; };
    27882796                2DEAC5CE1AC368BB00A195D8 /* _WKFindOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKFindOptions.h; sourceTree = "<group>"; };
    27892797                2DF3962A21C8DC50008835E3 /* WKInkPickerView.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = WKInkPickerView.mm; path = ios/WKInkPickerView.mm; sourceTree = "<group>"; };
     
    51055113                                5272B2891406985D0096A5D0 /* StatisticsData.h */,
    51065114                                1A5E4DA312D3BD3D0099A2BB /* TextCheckerState.h */,
     5115                                2DE9B1342231B5B2005287B7 /* TextInputContext.cpp */,
     5116                                2DE9B1332231B5B2005287B7 /* TextInputContext.h */,
    51075117                                2FD43B921FA006A30083F51C /* TouchBarMenuData.cpp */,
    51085118                                2FD43B911FA006A10083F51C /* TouchBarMenuData.h */,
     
    60786088                                1A002D3E196B329400B9AD44 /* _WKSessionState.mm */,
    60796089                                1A002D42196B337000B9AD44 /* _WKSessionStateInternal.h */,
     6090                                2DE9B1382231F61C005287B7 /* _WKTextInputContext.h */,
     6091                                2DE9B1372231F61C005287B7 /* _WKTextInputContext.mm */,
     6092                                2DE9B13B2231F77C005287B7 /* _WKTextInputContextInternal.h */,
    60806093                                2D6B371918A967AD0042AE80 /* _WKThumbnailView.h */,
    60816094                                2D6B371A18A967AD0042AE80 /* _WKThumbnailView.mm */,
     
    89358948                                1A002D44196B338900B9AD44 /* _WKSessionState.h in Headers */,
    89368949                                1A002D43196B337000B9AD44 /* _WKSessionStateInternal.h in Headers */,
     8950                                2DE9B13A2231F61C005287B7 /* _WKTextInputContext.h in Headers */,
     8951                                2DE9B13C2231F77C005287B7 /* _WKTextInputContextInternal.h in Headers */,
    89378952                                2D6B371B18A967AD0042AE80 /* _WKThumbnailView.h in Headers */,
    89388953                                2DACE64E18ADBFF000E4CA76 /* _WKThumbnailViewInternal.h in Headers */,
     
    94029417                                53CFBBC82224D1B500266546 /* TextCheckerCompletion.h in Headers */,
    94039418                                1A5E4DA412D3BD3D0099A2BB /* TextCheckerState.h in Headers */,
     9419                                2DE9B1352231B5B2005287B7 /* TextInputContext.h in Headers */,
    94049420                                CE1A0BD71A48E6C60054EF74 /* TextInputSPI.h in Headers */,
    94059421                                1AAF263914687C39004A1E8A /* TiledCoreAnimationDrawingArea.h in Headers */,
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp

    r242678 r242696  
    64696469#endif // !PLATFORM(IOS_FAMILY)
    64706470
     6471static IntRect elementRectInWindowCoordinates(const Element& element, const Frame& frame)
     6472{
     6473    auto* view = frame.view();
     6474    if (!view)
     6475        return { };
     6476
     6477    auto* renderer = element.renderer();
     6478    if (!renderer)
     6479        return { };
     6480
     6481    return view->contentsToWindow(renderer->absoluteBoundingBoxRect());
     6482}
     6483
     6484static bool isEditableTextInputElement(Element& element)
     6485{
     6486    if (is<HTMLTextFormControlElement>(element)) {
     6487        if (!element.isTextField() && !is<HTMLTextAreaElement>(element))
     6488            return false;
     6489        return downcast<HTMLTextFormControlElement>(element).isInnerTextElementEditable();
     6490    }
     6491
     6492    return element.isRootEditableElement();
     6493}
     6494
     6495void WebPage::textInputContextsInRect(WebCore::FloatRect searchRect, CompletionHandler<void(const Vector<TextInputContext>&)>&& completionHandler)
     6496{
     6497    Vector<WebKit::TextInputContext> textInputContexts;
     6498
     6499    for (Frame* frame = &m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
     6500        Document* document = frame->document();
     6501        if (!document)
     6502            continue;
     6503
     6504        Deque<Node*> nodesToSearch;
     6505        nodesToSearch.append(document);
     6506        while (!nodesToSearch.isEmpty()) {
     6507            auto node = nodesToSearch.takeFirst();
     6508
     6509            // It is possible to have nested text input contexts (e.g. <input type='text'> inside contenteditable) but
     6510            // in this case we just take the outermost context and skip the rest.
     6511            if (!is<Element>(*node) || !isEditableTextInputElement(downcast<Element>(*node))) {
     6512                for (auto* child = node->firstChild(); child; child = child->nextSibling())
     6513                    nodesToSearch.append(child);
     6514                continue;
     6515            }
     6516
     6517            auto& element = downcast<Element>(*node);
     6518
     6519            IntRect elementRect = elementRectInWindowCoordinates(element, *frame);
     6520            if (!searchRect.intersects(elementRect))
     6521                continue;
     6522
     6523            WebKit::TextInputContext context;
     6524            context.webPageIdentifier = m_pageID;
     6525            context.documentIdentifier = document->identifier();
     6526            context.elementIdentifier = document->identifierForElement(element);
     6527            context.boundingRect = elementRect;
     6528
     6529            textInputContexts.append(context);
     6530        }
     6531    }
     6532
     6533    completionHandler(textInputContexts);
     6534}
     6535
     6536void WebPage::focusTextInputContext(const TextInputContext& textInputContext, CompletionHandler<void(bool)>&& completionHandler)
     6537{
     6538    completionHandler([&] {
     6539        if (textInputContext.webPageIdentifier != m_pageID)
     6540            return false;
     6541
     6542        auto* document = Document::allDocumentsMap().get(textInputContext.documentIdentifier);
     6543        if (!document)
     6544            return false;
     6545
     6546        if (document->page() != m_page.get())
     6547            return false;
     6548
     6549        auto* element = document->searchForElementByIdentifier(textInputContext.elementIdentifier);
     6550        if (!element)
     6551            return false;
     6552
     6553        element->focus();
     6554
     6555        return true;
     6556    }());
     6557}
     6558
    64716559} // namespace WebKit
    64726560
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.h

    r242678 r242696  
    252252struct LoadParameters;
    253253struct PrintInfo;
     254struct TextInputContext;
    254255struct WebAutocorrectionContext;
    255256struct WebPageCreationParameters;
     
    592593    void viewportPropertiesDidChange(const WebCore::ViewportArguments&);
    593594    void executeEditCommandWithCallback(const String&, const String& argument, CallbackID);
     595
     596    void textInputContextsInRect(WebCore::FloatRect, CompletionHandler<void(const Vector<WebKit::TextInputContext>&)>&&);
     597    void focusTextInputContext(const TextInputContext&, CompletionHandler<void(bool)>&&);
    594598
    595599#if PLATFORM(IOS_FAMILY)
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in

    r242678 r242696  
    546546    UpdateCurrentModifierState(OptionSet<WebCore::PlatformEvent::Modifier> modifiers)
    547547    SimulateDeviceOrientationChange(double alpha, double beta, double gamma)
     548
     549    TextInputContextsInRect(WebCore::FloatRect rect) -> (Vector<struct WebKit::TextInputContext> contexts) Async
     550    FocusTextInputContext(struct WebKit::TextInputContext context) -> (bool success) Async
    548551}
  • trunk/Tools/ChangeLog

    r242694 r242696  
     12019-03-10  Tim Horton  <timothy_horton@apple.com>
     2
     3        Add SPI to retrieve the set of text inputs in a given rect, and later focus one
     4        https://bugs.webkit.org/show_bug.cgi?id=195499
     5
     6        Reviewed by Darin Adler.
     7
     8        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
     9        * TestWebKitAPI/Tests/WebKitCocoa/RequestTextInputContext.mm: Added.
     10        (-[WKWebView synchronouslyRequestTextInputContextsInRect:]):
     11        (-[WKWebView synchronouslyFocusTextInputContext:]):
     12        (applyStyle):
     13        (applyIframe):
     14        (TEST):
     15        Add some tests for this SPI.
     16
    1172019-03-10  Yusuke Suzuki <utatane.tea@gmail.com>
    218
  • trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj

    r242468 r242696  
    9393                2D1C04A71D76298B000A6816 /* TestNavigationDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D1C04A61D76298B000A6816 /* TestNavigationDelegate.mm */; };
    9494                2D21FE591F04642900B58E7D /* WKPDFViewStablePresentationUpdateCallback.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D21FE581F04642800B58E7D /* WKPDFViewStablePresentationUpdateCallback.mm */; };
     95                2D2BEB2D22324E5F005544CA /* RequestTextInputContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D2BEB2C22324E5F005544CA /* RequestTextInputContext.mm */; };
    9596                2D3CA3A8221DF4B40088E803 /* PageOverlayPlugin.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D3CA3A4221DF2390088E803 /* PageOverlayPlugin.mm */; };
    9697                2D4CF8BD1D8360CC0001CE8D /* WKThumbnailView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2D4CF8BC1D8360CC0001CE8D /* WKThumbnailView.mm */; };
     
    14271428                2D1FE0AF1AD465C1006CD9E6 /* FixedLayoutSize.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FixedLayoutSize.mm; sourceTree = "<group>"; };
    14281429                2D21FE581F04642800B58E7D /* WKPDFViewStablePresentationUpdateCallback.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKPDFViewStablePresentationUpdateCallback.mm; sourceTree = "<group>"; };
     1430                2D2BEB2C22324E5F005544CA /* RequestTextInputContext.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RequestTextInputContext.mm; sourceTree = "<group>"; };
    14291431                2D3CA3A4221DF2390088E803 /* PageOverlayPlugin.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PageOverlayPlugin.mm; sourceTree = "<group>"; };
    14301432                2D4CF8BC1D8360CC0001CE8D /* WKThumbnailView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKThumbnailView.mm; path = WebKit/WKThumbnailView.mm; sourceTree = "<group>"; };
     
    25872589                                52D5D6BE21B9F1B20046ABA6 /* RenderingProgressPlugIn.mm */,
    25882590                                52D5D6BF21B9F1B20046ABA6 /* RenderingProgressProtocol.h */,
     2591                                2D2BEB2C22324E5F005544CA /* RequestTextInputContext.mm */,
    25892592                                CD9E292B1C90A71F000BB800 /* RequiresUserActionForPlayback.mm */,
    25902593                                51C8E1A41F26AC5400BF731B /* ResourceLoadStatistics.mm */,
     
    42204223                                52D5D6C021B9F1B30046ABA6 /* RenderingProgress.mm in Sources */,
    42214224                                F464AF9220BB66EA007F9B18 /* RenderingProgressTests.mm in Sources */,
     4225                                2D2BEB2D22324E5F005544CA /* RequestTextInputContext.mm in Sources */,
    42224226                                7C83E0C41D0A654200FEBCF3 /* RequiresUserActionForPlayback.mm in Sources */,
    42234227                                7CCE7F0E1A411AE600447C4C /* ResizeReversePaginatedWebView.cpp in Sources */,
Note: See TracChangeset for help on using the changeset viewer.