Changeset 256236 in webkit


Ignore:
Timestamp:
Feb 10, 2020 6:18:05 PM (4 years ago)
Author:
commit-queue@webkit.org
Message:

Add a variant of -[WKWebViewPrivate _getContentsAsStringWithCompletionHandler:] that includes contents from subframes
https://bugs.webkit.org/show_bug.cgi?id=207352
<rdar://problem/59115798>

Patch by Alan Sien Wei Hshieh <hshieh@apple.com> on 2020-02-10
Reviewed by Alex Christensen.

Source/WebKit:

A number of intelligence features like Spotlight rely on -_getContentsAsStringWithCompletionHandler:. However, this
method does not return content strings for subframes. This means that Spotlight and others are not able to get
text for things like AMP pages, that live in subframes. -_getContentsAsStringWithCompletionHandler: has clients outside
of just intelligence features, and we don't want to wholesale change their behavior. As a result, introduce a new
-_getContentsAsStringInAllFrames:withCompletionHandler: which clients can adopt as necessary. Providing NO for the first
parameter allows clients to get the same contents as -_getContentsAsStringWithCompletionHandler:. Otherwise, we enumerate
all subframes and extract text from there. Finally, append a test for getting stuff out of frames.

  • UIProcess/API/Cocoa/WKWebView.mm:

(-[WKWebView _getContentsAsStringWithCompletionHandler:]):
(-[WKWebView _getContentsOfAllFramesAsStringWithCompletionHandler:]): Call the new function to extract contents from all
frames.

  • UIProcess/API/Cocoa/WKWebViewPrivate.h: Expose a new SPI for clients.
  • UIProcess/WebPageProxy.cpp:

(WebKit::WebPageProxy::getContentsAsStringInAllFrames): Piping. This emulates what getContentsAsString() does.

  • UIProcess/WebPageProxy.h: Expose new method.
  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::getContentsAsString): Augment to take a flag saying whether or not we want to extract
from all frames. If we do, iterate over all the frames and get their content strings, appending two
new lines in the middle.

  • WebProcess/WebPage/WebPage.h:
  • WebProcess/WebPage/WebPage.messages.in: Piping.
  • Shared/ContentAsStringIncludesChildFrames.h: Add a new header to expose an enum.

Tools:

Add a test to exercise the new SPI.

  • TestWebKitAPI/Tests/WebKitCocoa/WKWebViewGetContents.mm: Add a test for getting text from all frames with

a webpage that contains text in subframes.

Location:
trunk
Files:
1 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r256234 r256236  
     12020-02-10  Alan Sien Wei Hshieh  <hshieh@apple.com>
     2
     3        Add a variant of -[WKWebViewPrivate _getContentsAsStringWithCompletionHandler:] that includes contents from subframes
     4        https://bugs.webkit.org/show_bug.cgi?id=207352
     5        <rdar://problem/59115798>
     6
     7        Reviewed by Alex Christensen.
     8
     9        A number of intelligence features like Spotlight rely on -_getContentsAsStringWithCompletionHandler:. However, this
     10        method does not return content strings for subframes. This means that Spotlight and others are not able to get
     11        text for things like AMP pages, that live in subframes. -_getContentsAsStringWithCompletionHandler: has clients outside
     12        of just intelligence features, and we don't want to wholesale change their behavior. As a result, introduce a new
     13        -_getContentsAsStringInAllFrames:withCompletionHandler: which clients can adopt as necessary. Providing NO for the first
     14        parameter allows clients to get the same contents as -_getContentsAsStringWithCompletionHandler:. Otherwise, we enumerate
     15        all subframes and extract text from there. Finally, append a test for getting stuff out of frames.
     16
     17        * UIProcess/API/Cocoa/WKWebView.mm:
     18        (-[WKWebView _getContentsAsStringWithCompletionHandler:]):
     19        (-[WKWebView _getContentsOfAllFramesAsStringWithCompletionHandler:]): Call the new function to extract contents from all
     20        frames.
     21
     22        * UIProcess/API/Cocoa/WKWebViewPrivate.h: Expose a new SPI for clients.
     23
     24        * UIProcess/WebPageProxy.cpp:
     25        (WebKit::WebPageProxy::getContentsAsStringInAllFrames): Piping. This emulates what getContentsAsString() does.
     26
     27        * UIProcess/WebPageProxy.h: Expose new method.
     28
     29        * WebProcess/WebPage/WebPage.cpp:
     30        (WebKit::WebPage::getContentsAsString): Augment to take a flag saying whether or not we want to extract
     31        from all frames. If we do, iterate over all the frames and get their content strings, appending two
     32        new lines in the middle.
     33 
     34        * WebProcess/WebPage/WebPage.h:
     35        * WebProcess/WebPage/WebPage.messages.in: Piping.
     36
     37        * Shared/ContentAsStringIncludesChildFrames.h: Add a new header to expose an enum.
     38
    1392020-02-10  Per Arne Vollan  <pvollan@apple.com>
    240
  • trunk/Source/WebKit/UIProcess/API/C/WKPage.cpp

    r254384 r256236  
    5353#include "AuthenticationChallengeProxy.h"
    5454#include "AuthenticationDecisionListener.h"
     55#include "ContentAsStringIncludesChildFrames.h"
    5556#include "LegacySessionStateCoding.h"
    5657#include "Logging.h"
     
    25112512void WKPageGetContentsAsString(WKPageRef pageRef, void* context, WKPageGetContentsAsStringFunction callback)
    25122513{
    2513     toImpl(pageRef)->getContentsAsString(toGenericCallbackFunction(context, callback));
     2514    toImpl(pageRef)->getContentsAsString(ContentAsStringIncludesChildFrames::No, toGenericCallbackFunction(context, callback));
    25142515}
    25152516
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm

    r256191 r256236  
    3232#import "AttributedString.h"
    3333#import "CompletionHandlerCallChecker.h"
     34#import "ContentAsStringIncludesChildFrames.h"
    3435#import "DiagnosticLoggingClient.h"
    3536#import "FindClient.h"
     
    22872288    auto handler = makeBlockPtr(completionHandler);
    22882289
    2289     _page->getContentsAsString([handler](String string, WebKit::CallbackBase::Error error) {
     2290    _page->getContentsAsString(WebKit::ContentAsStringIncludesChildFrames::No, [handler](String string, WebKit::CallbackBase::Error error) {
    22902291        if (error != WebKit::CallbackBase::Error::None) {
    22912292            // FIXME: Pipe a proper error in from the WebPageProxy.
     
    22932294        } else
    22942295            handler(string, nil);
     2296    });
     2297}
     2298
     2299- (void)_getContentsOfAllFramesAsStringWithCompletionHandler:(void (^)(NSString *))completionHandler
     2300{
     2301    auto handler = makeBlockPtr(completionHandler);
     2302    _page->getContentsAsString(WebKit::ContentAsStringIncludesChildFrames::Yes, [handler](String string, WebKit::CallbackBase::Error error) {
     2303        if (error != WebKit::CallbackBase::Error::None)
     2304            handler(nil);
     2305        else
     2306            handler(string);
    22952307    });
    22962308}
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h

    r255998 r256236  
    267267- (void)_getWebArchiveDataWithCompletionHandler:(void (^)(NSData *, NSError *))completionHandler;
    268268- (void)_getContentsAsStringWithCompletionHandler:(void (^)(NSString *, NSError *))completionHandler WK_API_AVAILABLE(macos(10.13), ios(11.0));
     269- (void)_getContentsOfAllFramesAsStringWithCompletionHandler:(void (^)(NSString *))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
    269270- (void)_getContentsAsAttributedStringWithCompletionHandler:(void (^)(NSAttributedString *, NSDictionary<NSAttributedStringDocumentAttributeKey, id> *, NSError *))completionHandler WK_API_AVAILABLE(macos(10.15), ios(13.0));
    270271
  • trunk/Source/WebKit/UIProcess/WebPageProxy.cpp

    r256075 r256236  
    39633963}
    39643964
    3965 void WebPageProxy::getContentsAsString(WTF::Function<void (const String&, CallbackBase::Error)>&& callbackFunction)
     3965void WebPageProxy::getContentsAsString(ContentAsStringIncludesChildFrames includesChildFrames, WTF::Function<void(const String&, CallbackBase::Error)>&& callbackFunction)
    39663966{
    39673967    if (!hasRunningProcess()) {
     
    39693969        return;
    39703970    }
    3971    
     3971
    39723972    auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivity("WebPageProxy::getContentsAsString"_s));
    39733973    m_loadDependentStringCallbackIDs.add(callbackID);
    3974     send(Messages::WebPage::GetContentsAsString(callbackID));
     3974    send(Messages::WebPage::GetContentsAsString(includesChildFrames, callbackID));
    39753975}
    39763976
  • trunk/Source/WebKit/UIProcess/WebPageProxy.h

    r256075 r256236  
    2828#include "APIObject.h"
    2929#include "Connection.h"
     30#include "ContentAsStringIncludesChildFrames.h"
    3031#include "ContextMenuContextData.h"
    3132#include "DownloadID.h"
     
    10791080    void didFindStringMatches(const String&, const Vector<Vector<WebCore::IntRect>>& matchRects, int32_t firstIndexAfterSelection);
    10801081
    1081     void getContentsAsString(WTF::Function<void (const String&, CallbackBase::Error)>&&);
     1082    void getContentsAsString(ContentAsStringIncludesChildFrames, WTF::Function<void(const String&, CallbackBase::Error)>&&);
    10821083#if PLATFORM(COCOA)
    10831084    void getContentsAsAttributedString(CompletionHandler<void(const AttributedString&)>&&);
  • trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj

    r256185 r256236  
    16851685                C9CD43981B4B001D00239E33 /* WebMediaSessionMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = C9CD43941B4B000E00239E33 /* WebMediaSessionMetadata.h */; };
    16861686                C9CD439D1B4B024F00239E33 /* WKMediaSessionMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = C9CD439A1B4B024200239E33 /* WKMediaSessionMetadata.h */; settings = {ATTRIBUTES = (Private, ); }; };
     1687                CA05397723EE31E100A553DC /* ContentAsStringIncludesChildFrames.h in Headers */ = {isa = PBXBuildFile; fileRef = CA05397623EE31E100A553DC /* ContentAsStringIncludesChildFrames.h */; };
     1688                CA05397923EE324400A553DC /* ContentAsStringIncludesChildFrames.h in Headers */ = {isa = PBXBuildFile; fileRef = CA05397823EE324400A553DC /* ContentAsStringIncludesChildFrames.h */; };
    16871689                CD003A5319D49B5D005ABCE0 /* WebMediaKeyStorageManager.h in Headers */ = {isa = PBXBuildFile; fileRef = CD003A5119D49B5D005ABCE0 /* WebMediaKeyStorageManager.h */; };
    16881690                CD0C6831201FD10100A59409 /* WKFullScreenViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = CD0C682F201FD10100A59409 /* WKFullScreenViewController.h */; };
     
    49114913                C9CD43991B4B024200239E33 /* WKMediaSessionMetadata.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKMediaSessionMetadata.cpp; sourceTree = "<group>"; };
    49124914                C9CD439A1B4B024200239E33 /* WKMediaSessionMetadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKMediaSessionMetadata.h; sourceTree = "<group>"; };
     4915                CA05397623EE31E100A553DC /* ContentAsStringIncludesChildFrames.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ContentAsStringIncludesChildFrames.h; sourceTree = "<group>"; };
     4916                CA05397823EE324400A553DC /* ContentAsStringIncludesChildFrames.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ContentAsStringIncludesChildFrames.h; sourceTree = "<group>"; };
    49134917                CD003A5019D49B5D005ABCE0 /* WebMediaKeyStorageManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebMediaKeyStorageManager.cpp; path = MediaCache/WebMediaKeyStorageManager.cpp; sourceTree = "<group>"; };
    49144918                CD003A5119D49B5D005ABCE0 /* WebMediaKeyStorageManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebMediaKeyStorageManager.h; path = MediaCache/WebMediaKeyStorageManager.h; sourceTree = "<group>"; };
     
    56705674                                BC3065F91259344E00E71278 /* CacheModel.h */,
    56715675                                9BC59D6C1EFCCCB6001E8D09 /* CallbackID.h */,
     5676                                CA05397823EE324400A553DC /* ContentAsStringIncludesChildFrames.h */,
    56725677                                5129EB1123D0DE7800AF1CD7 /* ContentWorldShared.h */,
    56735678                                5106D7BF18BDBE73000AB166 /* ContextMenuContextData.cpp */,
     
    84518456                                46A2B6061E5675A200C3DEDA /* BackgroundProcessResponsivenessTimer.cpp */,
    84528457                                46A2B6071E5675A200C3DEDA /* BackgroundProcessResponsivenessTimer.h */,
     8458                                CA05397623EE31E100A553DC /* ContentAsStringIncludesChildFrames.h */,
    84538459                                07297F9C1C1711EA003F0735 /* DeviceIdHashSaltStorage.cpp */,
    84548460                                07297F9D1C17BBEA223F0735 /* DeviceIdHashSaltStorage.h */,
     
    1019310199                                37C4E9F6131C6E7E0029BD5A /* config.h in Headers */,
    1019410200                                BC032DAB10F437D10058C15A /* Connection.h in Headers */,
     10201                                CA05397923EE324400A553DC /* ContentAsStringIncludesChildFrames.h in Headers */,
     10202                                CA05397723EE31E100A553DC /* ContentAsStringIncludesChildFrames.h in Headers */,
    1019510203                                5129EB1223D0DE7B00AF1CD7 /* ContentWorldShared.h in Headers */,
    1019610204                                5106D7C418BDBE73000AB166 /* ContextMenuContextData.h in Headers */,
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp

    r256075 r256236  
    34473447}
    34483448
    3449 void WebPage::getContentsAsString(CallbackID callbackID)
    3450 {
    3451     String resultString = m_mainFrame->contentsAsString();
    3452     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
     3449void WebPage::getContentsAsString(ContentAsStringIncludesChildFrames includeChildFrames, CallbackID callbackID)
     3450{
     3451    switch (includeChildFrames) {
     3452    case ContentAsStringIncludesChildFrames::No: {
     3453        String resultString = m_mainFrame->contentsAsString();
     3454        send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
     3455        break;
     3456    }
     3457    case ContentAsStringIncludesChildFrames::Yes: {
     3458        StringBuilder builder;
     3459        for (RefPtr<Frame> frame = &corePage()->mainFrame(); frame; frame = frame->tree().traverseNextRendered()) {
     3460            if (auto* webFrame = WebFrame::fromCoreFrame(*frame)) {
     3461                if (!builder.isEmpty()) {
     3462                    builder.append('\n');
     3463                    builder.append('\n');
     3464                }
     3465
     3466                builder.append(webFrame->contentsAsString());
     3467            }
     3468        }
     3469
     3470        send(Messages::WebPageProxy::StringCallback(builder.toString(), callbackID));
     3471        break;
     3472    }
     3473    }
    34533474}
    34543475
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.h

    r256075 r256236  
    3434#include "APIObject.h"
    3535#include "CallbackID.h"
     36#include "ContentAsStringIncludesChildFrames.h"
    3637#include "DrawingAreaInfo.h"
    3738#include "EditingRange.h"
     
    14521453    void viewWillEndLiveResize();
    14531454
    1454     void getContentsAsString(CallbackID);
     1455    void getContentsAsString(ContentAsStringIncludesChildFrames, CallbackID);
    14551456#if PLATFORM(COCOA)
    14561457    void getContentsAsAttributedString(CompletionHandler<void(const AttributedString&)>&&);
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in

    r256075 r256236  
    193193
    194194    # Callbacks.
    195     GetContentsAsString(WebKit::CallbackID callbackID)
     195    GetContentsAsString(enum:bool WebKit::ContentAsStringIncludesChildFrames inChildFrames, WebKit::CallbackID callbackID)
    196196#if PLATFORM(COCOA)
    197197    GetContentsAsAttributedString() -> (struct WebKit::AttributedString result) Async
  • trunk/Tools/ChangeLog

    r256234 r256236  
     12020-02-10  Alan Sien Wei Hshieh  <hshieh@apple.com>
     2
     3        Add a variant of -[WKWebViewPrivate _getContentsAsStringWithCompletionHandler:] that includes contents from subframes
     4        https://bugs.webkit.org/show_bug.cgi?id=207352
     5        <rdar://problem/59115798>
     6
     7        Reviewed by Alex Christensen.
     8
     9        Add a test to exercise the new SPI.
     10
     11        * TestWebKitAPI/Tests/WebKitCocoa/WKWebViewGetContents.mm: Add a test for getting text from all frames with
     12        a webpage that contains text in subframes.
     13
     14
    1152020-02-10  Per Arne Vollan  <pvollan@apple.com>
    216
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewGetContents.mm

    r243116 r256236  
    4444        EXPECT_NULL(error);
    4545        EXPECT_WK_STREQ(@"Simple HTML file.", string);
     46        finished = true;
     47    }];
     48
     49    TestWebKitAPI::Util::run(&finished);
     50}
     51
     52TEST(WKWebView, GetContentsOfAllFramesShouldReturnString)
     53{
     54    RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
     55
     56    [webView synchronouslyLoadHTMLString:@"<body>beep<iframe srcdoc=\"meep\">herp</iframe><iframe srcdoc=\"moop\">derp</iframe></body>"];
     57
     58    __block bool finished = false;
     59
     60    [webView _getContentsOfAllFramesAsStringWithCompletionHandler:^(NSString *string) {
     61        EXPECT_WK_STREQ(@"beep\n\nmeep\n\nmoop", string);
    4662        finished = true;
    4763    }];
Note: See TracChangeset for help on using the changeset viewer.