Changeset 252254 in webkit


Ignore:
Timestamp:
Nov 8, 2019 12:50:02 PM (4 years ago)
Author:
dbates@webkit.org
Message:

Add WebKit Legacy SPI to retrieve editable elements in rect
https://bugs.webkit.org/show_bug.cgi?id=204006
<rdar://problem/57024093>

Reviewed by Wenson Hsieh.

Source/WebCore:

Extract code to retrieve the editable elements inside a specified rect from WebKit
to WebCore so that it can be shared by both Modern WebKit and Legacy WebKit.

  • page/Page.cpp:

(WebCore::isEditableTextInputElement):
(WebCore::Page::editableElementsInRect const):

  • page/Page.h:

Source/WebKit:

Write WebPage::textInputContextsInRect() in terms of Page::editableElementsInRect().
Also make use of Element::clientRect() instead of elementRectInRootViewCoordinates(),
which duplicates what the former does.

  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::textInputContextsInRect): Write in terms of Page::editableElementsInRect().
(WebKit::WebPage::contextForElement const): Use Element::clientRect() which does what
elementRectInRootViewCoordinates() does.
(WebKit::elementRectInRootViewCoordinates): Deleted.
(WebKit::isEditableTextInputElement): Deleted.

Source/WebKitLegacy/mac:

Add SPI to retrieve all the editable elements in a rect.

  • WebView/WebView.mm:

(-[WebView _editableElementsInRect:]): Added.

  • WebView/WebViewPrivate.h:
Location:
trunk/Source
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r252253 r252254  
     12019-11-08  Daniel Bates  <dabates@apple.com>
     2
     3        Add WebKit Legacy SPI to retrieve editable elements in rect
     4        https://bugs.webkit.org/show_bug.cgi?id=204006
     5        <rdar://problem/57024093>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        Extract code to retrieve the editable elements inside a specified rect from WebKit
     10        to WebCore so that it can be shared by both Modern WebKit and Legacy WebKit.
     11
     12        * page/Page.cpp:
     13        (WebCore::isEditableTextInputElement):
     14        (WebCore::Page::editableElementsInRect const):
     15        * page/Page.h:
     16
    1172019-11-08  Antoine Quint  <graouts@apple.com>
    218
  • trunk/Source/WebCore/page/Page.cpp

    r252208 r252254  
    6363#include "HTMLElement.h"
    6464#include "HTMLMediaElement.h"
     65#include "HTMLTextAreaElement.h"
     66#include "HTMLTextFormControlElement.h"
    6567#include "HistoryController.h"
    6668#include "HistoryItem.h"
     
    125127#include "WheelEventDeltaFilter.h"
    126128#include "Widget.h"
     129#include <wtf/Deque.h>
    127130#include <wtf/FileSystem.h>
    128131#include <wtf/RefCountedLeakCounter.h>
     
    911914        frame = incrementFrame(frame, true, CanWrap::No);
    912915    } while (frame);
     916}
     917
     918static bool isEditableTextInputElement(const Element& element)
     919{
     920    if (is<HTMLTextFormControlElement>(element)) {
     921        if (!element.isTextField() && !is<HTMLTextAreaElement>(element))
     922            return false;
     923        return downcast<HTMLTextFormControlElement>(element).isInnerTextElementEditable();
     924    }
     925    return element.isRootEditableElement();
     926}
     927
     928Vector<Ref<Element>> Page::editableElementsInRect(const FloatRect& searchRectInRootViewCoordinates) const
     929{
     930    Vector<Ref<Element>> result;
     931    for (auto* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
     932        auto* document = frame->document();
     933        if (!document)
     934            continue;
     935
     936        Deque<Node*> nodesToSearch;
     937        nodesToSearch.append(document);
     938        while (!nodesToSearch.isEmpty()) {
     939            auto* node = nodesToSearch.takeFirst();
     940
     941            // It is possible to have nested text input contexts (e.g. <input type='text'> inside contenteditable) but
     942            // in this case we just take the outermost context and skip the rest.
     943            if (!is<Element>(node) || !isEditableTextInputElement(downcast<Element>(*node))) {
     944                for (auto* child = node->firstChild(); child; child = child->nextSibling())
     945                    nodesToSearch.append(child);
     946                continue;
     947            }
     948
     949            auto& element = downcast<Element>(*node);
     950            if (searchRectInRootViewCoordinates.intersects(element.clientRect()))
     951                result.append(element);
     952        }
     953    }
     954    return result;
    913955}
    914956
  • trunk/Source/WebCore/page/Page.h

    r251737 r252254  
    718718    void configureLoggingChannel(const String&, WTFLogChannelState, WTFLogLevel);
    719719
     720    WEBCORE_EXPORT Vector<Ref<Element>> editableElementsInRect(const FloatRect&) const;
     721
    720722private:
    721723    struct Navigation {
  • trunk/Source/WebKit/ChangeLog

    r252248 r252254  
     12019-11-08  Daniel Bates  <dabates@apple.com>
     2
     3        Add WebKit Legacy SPI to retrieve editable elements in rect
     4        https://bugs.webkit.org/show_bug.cgi?id=204006
     5        <rdar://problem/57024093>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        Write WebPage::textInputContextsInRect() in terms of Page::editableElementsInRect().
     10        Also make use of Element::clientRect() instead of elementRectInRootViewCoordinates(),
     11        which duplicates what the former does.
     12
     13        * WebProcess/WebPage/WebPage.cpp:
     14        (WebKit::WebPage::textInputContextsInRect): Write in terms of Page::editableElementsInRect().
     15        (WebKit::WebPage::contextForElement const): Use Element::clientRect() which does what
     16        elementRectInRootViewCoordinates() does.
     17        (WebKit::elementRectInRootViewCoordinates): Deleted.
     18        (WebKit::isEditableTextInputElement): Deleted.
     19
    1202019-11-06  Jiewen Tan  <jiewen_tan@apple.com>
    221
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp

    r251650 r252254  
    179179#include <WebCore/HTMLPlugInImageElement.h>
    180180#include <WebCore/HTMLSelectElement.h>
    181 #include <WebCore/HTMLTextAreaElement.h>
    182181#include <WebCore/HTMLTextFormControlElement.h>
    183182#include <WebCore/HTMLUListElement.h>
     
    66926691#endif // !PLATFORM(IOS_FAMILY)
    66936692
    6694 static IntRect elementRectInRootViewCoordinates(const Element& element, const Frame& frame)
    6695 {
    6696     auto* view = frame.view();
    6697     if (!view)
    6698         return { };
    6699 
    6700     auto* renderer = element.renderer();
    6701     if (!renderer)
    6702         return { };
    6703 
    6704     return view->contentsToRootView(renderer->absoluteBoundingBoxRect());
    6705 }
    6706 
    6707 static bool isEditableTextInputElement(Element& element)
    6708 {
    6709     if (is<HTMLTextFormControlElement>(element)) {
    6710         if (!element.isTextField() && !is<HTMLTextAreaElement>(element))
    6711             return false;
    6712         return downcast<HTMLTextFormControlElement>(element).isInnerTextElementEditable();
    6713     }
    6714 
    6715     return element.isRootEditableElement();
    6716 }
    6717 
    67186693void WebPage::textInputContextsInRect(WebCore::FloatRect searchRect, CompletionHandler<void(const Vector<WebCore::ElementContext>&)>&& completionHandler)
    67196694{
    6720     Vector<WebCore::ElementContext> textInputContexts;
    6721 
    6722     for (Frame* frame = &m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
    6723         Document* document = frame->document();
    6724         if (!document)
    6725             continue;
    6726 
    6727         Deque<Node*> nodesToSearch;
    6728         nodesToSearch.append(document);
    6729         while (!nodesToSearch.isEmpty()) {
    6730             auto node = nodesToSearch.takeFirst();
    6731 
    6732             // It is possible to have nested text input contexts (e.g. <input type='text'> inside contenteditable) but
    6733             // in this case we just take the outermost context and skip the rest.
    6734             if (!is<Element>(*node) || !isEditableTextInputElement(downcast<Element>(*node))) {
    6735                 for (auto* child = node->firstChild(); child; child = child->nextSibling())
    6736                     nodesToSearch.append(child);
    6737                 continue;
    6738             }
    6739 
    6740             auto& element = downcast<Element>(*node);
    6741 
    6742             IntRect elementRect = elementRectInRootViewCoordinates(element, *frame);
    6743             if (!searchRect.intersects(elementRect))
    6744                 continue;
    6745 
    6746             WebCore::ElementContext context;
    6747             context.webPageIdentifier = m_identifier;
    6748             context.documentIdentifier = document->identifier();
    6749             context.elementIdentifier = document->identifierForElement(element);
    6750             context.boundingRect = elementRect;
    6751 
    6752             textInputContexts.append(context);
    6753         }
    6754     }
    6755 
    6756     completionHandler(textInputContexts);
     6695    auto contexts = m_page->editableElementsInRect(searchRect).map([&] (const auto& element) {
     6696        auto& document = element->document();
     6697
     6698        WebCore::ElementContext context;
     6699        context.webPageIdentifier = m_identifier;
     6700        context.documentIdentifier = document.identifier();
     6701        context.elementIdentifier = document.identifierForElement(element);
     6702        context.boundingRect = element->clientRect();
     6703        return context;
     6704    });
     6705    completionHandler(contexts);
    67576706}
    67586707
     
    67926741        return WTF::nullopt;
    67936742
    6794     return WebCore::ElementContext { elementRectInRootViewCoordinates(element, *frame), m_identifier, document.identifier(), document.identifierForElement(element) };
     6743    return WebCore::ElementContext { element.clientRect(), m_identifier, document.identifier(), document.identifierForElement(element) };
    67956744}
    67966745
  • trunk/Source/WebKitLegacy/mac/ChangeLog

    r252000 r252254  
     12019-11-08  Daniel Bates  <dabates@apple.com>
     2
     3        Add WebKit Legacy SPI to retrieve editable elements in rect
     4        https://bugs.webkit.org/show_bug.cgi?id=204006
     5        <rdar://problem/57024093>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        Add SPI to retrieve all the editable elements in a rect.
     10
     11        * WebView/WebView.mm:
     12        (-[WebView _editableElementsInRect:]): Added.
     13        * WebView/WebViewPrivate.h:
     14
    1152019-11-04  Alex Christensen  <achristensen@webkit.org>
    216
  • trunk/Source/WebKitLegacy/mac/WebView/WebView.mm

    r251950 r252254  
    1013210132
    1013310133#if PLATFORM(IOS_FAMILY)
     10134
    1013410135@implementation WebView (WebViewIOSPDF)
    1013510136
     
    1015910160
    1016010161@end
     10162
     10163@implementation WebView (WebViewIOSAdditions)
     10164
     10165- (NSArray<DOMElement *> *)_editableElementsInRect:(CGRect)rect
     10166{
     10167    auto* page = core(self);
     10168    if (!page)
     10169        return @[];
     10170    auto coreElements = page->editableElementsInRect(rect);
     10171    if (coreElements.isEmpty())
     10172        return @[];
     10173    auto result = adoptNS([[NSMutableArray alloc] initWithCapacity:coreElements.size()]);
     10174    for (auto& coreElement : coreElements)
     10175        [result addObject:kit(coreElement.ptr())];
     10176    return result.autorelease();
     10177}
     10178
     10179@end
     10180
    1016110181#endif
    1016210182
  • trunk/Source/WebKitLegacy/mac/WebView/WebViewPrivate.h

    r250066 r252254  
    10761076
    10771077#if TARGET_OS_IPHONE
     1078
    10781079@interface WebView (WebViewIOSPDF)
    10791080+ (Class)_getPDFRepresentationClass;
     
    10831084+ (void)_setPDFViewClass:(Class)pdfViewClass;
    10841085@end
     1086
     1087@interface WebView (WebViewIOSAdditions)
     1088- (NSArray<DOMElement *> *)_editableElementsInRect:(CGRect)rect;
     1089@end
     1090
    10851091#endif
    10861092
Note: See TracChangeset for help on using the changeset viewer.