Skip to content

Commit

Permalink
WKWebView.createWebArchiveDataWithCompletionHandler should actually r…
Browse files Browse the repository at this point in the history
…espond with an error if there is no data

https://bugs.webkit.org/show_bug.cgi?id=273667
rdar://127469660

Reviewed by Brady Eidson.

This makes the API a little more ergonomic. I also add a call to launchInitialProcessIfNecessary
and use the main frame if no frame is specified to prevent errors when the main frame hasn't been
created yet or if the process hasn't been launched yet.

* Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView createWebArchiveDataWithCompletionHandler:]):
* Source/WebKit/UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::getWebArchiveOfFrame):
* Source/WebKit/WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::getWebArchiveOfFrame):
* Source/WebKit/WebProcess/WebPage/WebPage.h:
* Source/WebKit/WebProcess/WebPage/WebPage.messages.in:
* Tools/TestWebKitAPI/Tests/WebKitCocoa/CreateWebArchive.mm:
(TestWebKitAPI::(WebArchive, CreateCustomScheme)):

Canonical link: https://commits.webkit.org/278542@main
  • Loading branch information
achristensen07 committed May 9, 2024
1 parent 806925c commit 44201c4
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 16 deletions.
7 changes: 5 additions & 2 deletions Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1845,8 +1845,11 @@ - (void)createPDFWithConfiguration:(WKPDFConfiguration *)pdfConfiguration comple
- (void)createWebArchiveDataWithCompletionHandler:(void (^)(NSData *, NSError *))completionHandler
{
THROW_IF_SUSPENDED;
_page->getWebArchiveOfFrame(_page->mainFrame(), [completionHandler = makeBlockPtr(completionHandler)](API::Data* data) {
completionHandler(wrapper(data), nil);
_page->getWebArchiveOfFrame(nullptr, [completionHandler = makeBlockPtr(completionHandler)](API::Data* data) {
if (data)
completionHandler(wrapper(data), nil);
else
completionHandler(nil, [NSError errorWithDomain:WKErrorDomain code:WKErrorUnknown userInfo:nil]);
});
}

Expand Down
5 changes: 2 additions & 3 deletions Source/WebKit/UIProcess/WebPageProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5776,9 +5776,8 @@ void WebPageProxy::getResourceDataFromFrame(WebFrameProxy& frame, API::URL* reso

void WebPageProxy::getWebArchiveOfFrame(WebFrameProxy* frame, CompletionHandler<void(API::Data*)>&& callback)
{
if (!frame)
return callback(nullptr);
sendWithAsyncReply(Messages::WebPage::GetWebArchiveOfFrame(frame->frameID()), toAPIDataCallback(WTFMove(callback)));
launchInitialProcessIfNecessary();
sendWithAsyncReply(Messages::WebPage::GetWebArchiveOfFrame(frame ? std::optional(frame->frameID()) : std::nullopt), toAPIDataCallback(WTFMove(callback)));
}

void WebPageProxy::getAccessibilityTreeData(CompletionHandler<void(API::Data*)>&& callback)
Expand Down
18 changes: 9 additions & 9 deletions Source/WebKit/WebProcess/WebPage/WebPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4536,22 +4536,22 @@ void WebPage::getWebArchiveOfFrameWithFileName(WebCore::FrameIdentifier frameID,
completionHandler(result);
}

void WebPage::getWebArchiveOfFrame(FrameIdentifier frameID, CompletionHandler<void(const std::optional<IPC::SharedBufferReference>&)>&& callback)
void WebPage::getWebArchiveOfFrame(std::optional<FrameIdentifier> frameID, CompletionHandler<void(const std::optional<IPC::SharedBufferReference>&)>&& callback)
{
#if PLATFORM(COCOA)
RetainPtr<CFDataRef> data;
if (RefPtr frame = WebProcess::singleton().webFrame(frameID))
RefPtr<WebFrame> frame;
if (frameID)
frame = WebProcess::singleton().webFrame(*frameID);
else
frame = m_mainFrame.ptr();
if (frame)
data = frame->webArchiveData(nullptr, nullptr);
callback(IPC::SharedBufferReference(SharedBuffer::create(data.get())));
#else
UNUSED_PARAM(frameID);
callback({ });
#endif

IPC::SharedBufferReference dataBuffer;
#if PLATFORM(COCOA)
if (data)
dataBuffer = IPC::SharedBufferReference(SharedBuffer::create(data.get()));
#endif
callback(dataBuffer);
}

void WebPage::getAccessibilityTreeData(CompletionHandler<void(const std::optional<IPC::SharedBufferReference>&)>&& callback)
Expand Down
2 changes: 1 addition & 1 deletion Source/WebKit/WebProcess/WebPage/WebPage.h
Original file line number Diff line number Diff line change
Expand Up @@ -1959,7 +1959,7 @@ class WebPage : public API::ObjectImpl<API::Object::Type::BundlePage>, public IP
void getSelectionOrContentsAsString(CompletionHandler<void(const String&)>&&);
void getSelectionAsWebArchiveData(CompletionHandler<void(const std::optional<IPC::SharedBufferReference>&)>&&);
void getSourceForFrame(WebCore::FrameIdentifier, CompletionHandler<void(const String&)>&&);
void getWebArchiveOfFrame(WebCore::FrameIdentifier, CompletionHandler<void(const std::optional<IPC::SharedBufferReference>&)>&&);
void getWebArchiveOfFrame(std::optional<WebCore::FrameIdentifier>, CompletionHandler<void(const std::optional<IPC::SharedBufferReference>&)>&&);
void getWebArchiveOfFrameWithFileName(WebCore::FrameIdentifier, const Vector<WebCore::MarkupExclusionRule>&, const String& fileName, CompletionHandler<void(const std::optional<IPC::SharedBufferReference>&)>&&);
void runJavaScript(WebFrame*, WebCore::RunJavaScriptParameters&&, ContentWorldIdentifier, CompletionHandler<void(std::span<const uint8_t>, const std::optional<WebCore::ExceptionDetails>&)>&&);
void runJavaScriptInFrameInScriptWorld(WebCore::RunJavaScriptParameters&&, std::optional<WebCore::FrameIdentifier>, const std::pair<ContentWorldIdentifier, String>& worldData, CompletionHandler<void(std::span<const uint8_t>, const std::optional<WebCore::ExceptionDetails>&)>&&);
Expand Down
2 changes: 1 addition & 1 deletion Source/WebKit/WebProcess/WebPage/WebPage.messages.in
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType
GetSelectionOrContentsAsString() -> (String string)
GetSelectionAsWebArchiveData() -> (std::optional<IPC::SharedBufferReference> data)
GetSourceForFrame(WebCore::FrameIdentifier frameID) -> (String string)
GetWebArchiveOfFrame(WebCore::FrameIdentifier frameID) -> (std::optional<IPC::SharedBufferReference> dataReference)
GetWebArchiveOfFrame(std::optional<WebCore::FrameIdentifier> frameID) -> (std::optional<IPC::SharedBufferReference> dataReference)
GetWebArchiveOfFrameWithFileName(WebCore::FrameIdentifier frameID, Vector<WebCore::MarkupExclusionRule> markupExclusionRules, String fileName) -> (std::optional<IPC::SharedBufferReference> dataReference)

RunJavaScriptInFrameInScriptWorld(struct WebCore::RunJavaScriptParameters parameters, std::optional<WebCore::FrameIdentifier> frameID, std::pair<WebKit::ContentWorldIdentifier, String> world) -> (std::span<const uint8_t> resultData, std::optional<WebCore::ExceptionDetails> details)
Expand Down
18 changes: 18 additions & 0 deletions Tools/TestWebKitAPI/Tests/WebKitCocoa/CreateWebArchive.mm
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,24 @@
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);

static bool done = false;
[webView createWebArchiveDataWithCompletionHandler:^(NSData *result, NSError *error) {
EXPECT_NULL(error);
NSDictionary *expectedDictionary = @{
@"WebMainResource" : @{
@"WebResourceData" : [@"<html><head></head><body></body></html>" dataUsingEncoding:NSUTF8StringEncoding],
@"WebResourceFrameName" : @"",
@"WebResourceMIMEType" : @"text/html",
@"WebResourceTextEncodingName" : @"UTF-8",
@"WebResourceURL" : @""
}
};
NSDictionary* actualDictionary = [NSPropertyListSerialization propertyListWithData:result options:0 format:nullptr error:nullptr];
EXPECT_TRUE([expectedDictionary isEqualToDictionary:actualDictionary]);
done = true;
}];
Util::run(&done);
done = false;

[webView performAfterReceivingMessage:@"done" action:[&] { done = true; }];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"webarchivetest://host/main.html"]]];

Expand Down

0 comments on commit 44201c4

Please sign in to comment.