
/*
 * Copyright (C) 2020-2025 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.
 */

#import "config.h"

#if PLATFORM(MAC) || PLATFORM(IOS_FAMILY)

#import "HTTPServer.h"
#import "PlatformUtilities.h"
#import "Test.h"
#import "TestNavigationDelegate.h"
#import "TestURLSchemeHandler.h"
#import "TestWKWebView.h"
#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
#import <WebKit/_WKArchiveConfiguration.h>
#import <WebKit/_WKArchiveExclusionRule.h>

#if PLATFORM(IOS_FAMILY)
#import <MobileCoreServices/MobileCoreServices.h>
#endif

namespace TestWebKitAPI {

static const char* mainBytes = R"TESTRESOURCE(
<head>
<script src="webarchivetest://host/script.js"></script>
</head>
)TESTRESOURCE";

static const char* scriptBytes = R"TESTRESOURCE(
window.webkit.messageHandlers.testHandler.postMessage("done");
)TESTRESOURCE";

TEST(WebArchive, CreateCustomScheme)
{
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webarchivetest"];

    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        const char* bytes = nullptr;
        if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/main.html"])
            bytes = mainBytes;
        else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/script.js"])
            bytes = scriptBytes;
        else
            FAIL();

        auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"text/html" expectedContentLength:0 textEncodingName:nil]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:[NSData dataWithBytes:bytes length:strlen(bytes)]];
        [task didFinish];
    }];

    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"]]];

    Util::run(&done);
    done = false;

    static RetainPtr<NSData> archiveData;
    [webView createWebArchiveDataWithCompletionHandler:^(NSData *result, NSError *error) {
        EXPECT_NULL(error);
        EXPECT_TRUE(!!result);
        archiveData = result;
        done = true;
    }];

    Util::run(&done);
    done = false;

    [webView performAfterReceivingMessage:@"done" action:[&] { done = true; }];
    [webView loadData:archiveData.get() MIMEType:UTTypeArchive.identifier characterEncodingName:@"utf-8" baseURL:[NSURL URLWithString:@"about:blank"]];

    Util::run(&done);
    done = false;
}

static RetainPtr<NSData> webArchiveAccessingCookies()
{
    HTTPServer server({ { "/"_s, { "<script>document.cookie</script>"_s } } }, HTTPServer::Protocol::HttpsProxy);
    auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectZero configuration:server.httpsProxyConfiguration()]);
    auto navigationDelegate = adoptNS([TestNavigationDelegate new]);
    [navigationDelegate allowAnyTLSCertificate];
    webView.get().navigationDelegate = navigationDelegate.get();
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://webkit.org/"]]];
    [navigationDelegate waitForDidFinishNavigation];

    __block RetainPtr<NSData> webArchive;
    [webView createWebArchiveDataWithCompletionHandler:^(NSData *result, NSError *error) {
        webArchive = result;
    }];
    while (!webArchive)
        Util::spinRunLoop();
    return webArchive;
}

TEST(WebArchive, CookieAccessAfterLoadRequest)
{
    auto webArchive = webArchiveAccessingCookies();

    NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:@"CookieAccessTest.webarchive"];
    [[NSFileManager defaultManager] removeItemAtPath:path error:nil];
    BOOL success = [webArchive writeToFile:path atomically:YES];
    EXPECT_TRUE(success);

    auto webView = adoptNS([WKWebView new]);
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:path isDirectory:NO]]];
    [webView _test_waitForDidFinishNavigation];
    [[NSFileManager defaultManager] removeItemAtPath:path error:nil];
}

TEST(WebArchive, CookieAccessAfterLoadData)
{
    auto webArchive = webArchiveAccessingCookies();
    auto webView = adoptNS([WKWebView new]);
    [webView loadData:webArchive.get() MIMEType:@"application/x-webarchive" characterEncodingName:@"utf-8" baseURL:[NSURL URLWithString:@"http://example.com/"]];
    [webView _test_waitForDidFinishNavigation];
}

TEST(WebArchive, ApplicationXWebarchiveMIMETypeDoesNotLoadHTML)
{
    HTTPServer server({ { "/"_s, { { { "Content-Type"_s, "application/x-webarchive"_s } }, "Not web archive content, should not load"_s } } });

    auto webView = adoptNS([WKWebView new]);
    [webView loadRequest:server.request()];
    [webView _test_waitForDidFailProvisionalNavigation];
}

TEST(WebArchive, SaveResourcesBasic)
{
    RetainPtr<NSURL> directoryURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"SaveResourcesTest"] isDirectory:YES];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:directoryURL.get() error:nil];

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webarchivetest"];
    NSData *htmlData = [@"<head><script src=\"script.js\"></script></head><img src=\"image.png\" onload=\"onImageLoad()\"><script>function onImageLoad() { notifyTestRunner(); }</script>" dataUsingEncoding:NSUTF8StringEncoding];
    NSData *scriptData = [@"function notifyTestRunner() { window.webkit.messageHandlers.testHandler.postMessage(\"done\"); }" dataUsingEncoding:NSUTF8StringEncoding];
    NSData *imageData = [NSData dataWithContentsOfURL:[NSBundle.test_resourcesBundle URLForResource:@"400x400-green" withExtension:@"png"]];
    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        RetainPtr<NSData> data;
        NSString *mimeType = nil;
        if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/main.html"]) {
            mimeType = @"text/html";
            data = htmlData;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/script.js"]) {
            mimeType = @"application/javascript";
            data = scriptData;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/image.png"]) {
            mimeType = @"image/png";
            data = imageData;
        } else
            FAIL();

        auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:mimeType expectedContentLength:data.get().length textEncodingName:nil]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:data.get()];
        [task didFinish];
    }];

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    static bool messageReceived = false;
    [webView performAfterReceivingMessage:@"done" action:[&] {
        messageReceived = true;
    }];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"webarchivetest://host/main.html"]]];
    Util::run(&messageReceived);

    static bool saved = false;
    [webView _saveResources:directoryURL.get() suggestedFileName:@"host" completionHandler:^(NSError *error) {
        EXPECT_NULL(error);
        auto htmlPath = [directoryURL URLByAppendingPathComponent:@"host.html"].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:htmlPath]);
        NSData *htmlDataWithReplacedURLs = [@"<html><head><meta charset=\"UTF-8\"><!-- Encoding specified by WebKit --><script src=\"host_files/script.js\"></script></head><body><img src=\"host_files/image.png\" onload=\"onImageLoad()\"><script>function onImageLoad() { notifyTestRunner(); }</script></body></html>" dataUsingEncoding:NSUTF8StringEncoding];
        EXPECT_TRUE([[NSData dataWithContentsOfFile:htmlPath] isEqualToData:htmlDataWithReplacedURLs]);

        auto scriptPath = [directoryURL URLByAppendingPathComponent:@"host_files/script.js"].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:scriptPath]);
        EXPECT_TRUE([[NSData dataWithContentsOfFile:scriptPath] isEqualToData:scriptData]);

        auto imagePath = [directoryURL URLByAppendingPathComponent:@"host_files/image.png"].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:imagePath]);
        EXPECT_TRUE([[NSData dataWithContentsOfFile:imagePath] isEqualToData:imageData]);
        saved = true;
    }];
    Util::run(&saved);
}

static const char* htmlDataBytesForIframe = R"TESTRESOURCE(
<script>
count = 0;
function onFrameLoaded() {
    if (++count == 3) {
        frame = document.getElementById("iframe1_id");
        if (frame && !frame.contentDocument.body.innerHTML)
            frame.contentDocument.body.innerHTML = "<p>iframe1</p><img src='image.png'>";
        window.webkit.messageHandlers.testHandler.postMessage("done");
    }
}
</script>
<iframe onload="onFrameLoaded();" id="iframe1_id"></iframe>
<iframe onload="onFrameLoaded();" src="iframe.html"></iframe>
<iframe onload="onFrameLoaded();" srcdoc="<p>iframe3</p><img src='image.png'>"></iframe>
)TESTRESOURCE";
static const char* iframeHTMLDataBytes = R"TESTRESOURCE(
<head>
<link rel="stylesheet" href="style.css">
</head>
<p>iframe2</p>
<img src='image.png'>
)TESTRESOURCE";
static const char* cssDataBytesForIframe = R"TESTRESOURCE(
div {
    height: 50%;
    width: 50%;
}
)TESTRESOURCE";

TEST(WebArchive, SaveResourcesIframe)
{
    RetainPtr<NSURL> directoryURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"SaveResourcesTest"] isDirectory:YES];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:directoryURL.get() error:nil];

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webarchivetest"];
    NSData *htmlData = [NSData dataWithBytes:htmlDataBytesForIframe length:strlen(htmlDataBytesForIframe)];
    NSData *iframeHTMLData = [NSData dataWithBytes:iframeHTMLDataBytes length:strlen(iframeHTMLDataBytes)];
    NSData *cssData = [NSData dataWithBytes:cssDataBytesForIframe length:strlen(cssDataBytesForIframe)];
    NSData *imageData = [NSData dataWithContentsOfURL:[NSBundle.test_resourcesBundle URLForResource:@"400x400-green" withExtension:@"png"]];
    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        RetainPtr<NSData> data;
        NSString *mimeType = nil;
        if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/main.html"]) {
            mimeType = @"text/html";
            data = htmlData;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/iframe.html"]) {
            mimeType = @"text/html";
            data = iframeHTMLData;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/image.png"]) {
            mimeType = @"image/png";
            data = imageData;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/style.css"]) {
            mimeType = @"text/css";
            data = cssData;
        } else
            FAIL();

        auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:mimeType expectedContentLength:data.get().length textEncodingName:nil]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:data.get()];
        [task didFinish];
    }];

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    static bool messageReceived = false;
    [webView performAfterReceivingMessage:@"done" action:[&] {
        messageReceived = true;
    }];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"webarchivetest://host/main.html"]]];
    Util::run(&messageReceived);

    static bool saved = false;
    [webView _saveResources:directoryURL.get() suggestedFileName:@"host" completionHandler:^(NSError *error) {
        EXPECT_NULL(error);
        NSString *mainResourcePath = [directoryURL URLByAppendingPathComponent:@"host.html"].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:mainResourcePath]);

        NSString *savedMainResourceString = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:mainResourcePath] encoding:NSUTF8StringEncoding];
        NSString *resourceDirectoryName = @"host_files";
        NSString *resourceDirectoryPath = [directoryURL URLByAppendingPathComponent:resourceDirectoryName].path;
        NSArray *savedResourceFileNames = [fileManager contentsOfDirectoryAtPath:resourceDirectoryPath error:0];
        EXPECT_EQ(5llu, savedResourceFileNames.count);

        unsigned frameFileCount = 0;
        unsigned imageFileCount = 0;
        unsigned cssFileCount = 0;
        NSMutableSet *frameResourceContentsToFind = [NSMutableSet set];
        [frameResourceContentsToFind addObjectsFromArray:[NSArray arrayWithObjects:@"iframe1", @"iframe2", @"iframe3", nil]];
        for (NSString *fileName in savedResourceFileNames) {
            if ([fileName containsString:@"frame_"]) {
                // Ensure urls are replaced with file path.
                NSString *replacementPath = [resourceDirectoryName stringByAppendingPathComponent:fileName];
                EXPECT_TRUE([savedMainResourceString containsString:replacementPath]);
                // Ensure all iframes are saved by looking at content.
                NSString *resourceFilePath = [resourceDirectoryPath stringByAppendingPathComponent:fileName];
                NSString* savedSubframeResourceString = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:resourceFilePath] encoding:NSUTF8StringEncoding];
                NSRange range = [savedSubframeResourceString rangeOfString:@"iframe"];
                EXPECT_NE(NSNotFound, (long)range.location);
                NSString *iframeContent = [savedSubframeResourceString substringWithRange:NSMakeRange(range.location, range.length + 1)];
                [frameResourceContentsToFind removeObject:iframeContent];
                ++frameFileCount;
            }

            if ([fileName isEqualToString:@"image.png"])
                ++imageFileCount;
            if ([fileName isEqualToString:@"style.css"])
                ++cssFileCount;
        }
        EXPECT_EQ(3u, frameFileCount);
        EXPECT_EQ(1u, imageFileCount);
        EXPECT_EQ(1u, cssFileCount);
        EXPECT_EQ(0u, frameResourceContentsToFind.count);
        saved = true;
    }];
    Util::run(&saved);
}

static const char* htmlDataBytesForFrame = R"TESTRESOURCE(
<head>
<script>
count = 0;
function onFramesLoaded() {
    frame = document.getElementById("frame1_id");
    if (frame && !frame.contentDocument.body.innerHTML)
        frame.contentDocument.body.innerHTML = "<p>thisisframe1</p><img src='image.png'>";
    window.webkit.messageHandlers.testHandler.postMessage("done");
}
</script>
</head>
<frameset cols="50%, 50%" onload="onFramesLoaded()">
<frame id="frame1_id">
<frame src="frame.html">
</frameset>
)TESTRESOURCE";
static const char* frameHTMLDataBytes = R"TESTRESOURCE(<p>thisisframe2</p><img src='image.png'>)TESTRESOURCE";

TEST(WebArchive, SaveResourcesFrame)
{
    RetainPtr<NSURL> directoryURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"SaveResourcesTest"] isDirectory:YES];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:directoryURL.get() error:nil];

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webarchivetest"];
    NSData *htmlData = [NSData dataWithBytes:htmlDataBytesForFrame length:strlen(htmlDataBytesForFrame)];
    NSData *frameHTMLData = [NSData dataWithBytes:frameHTMLDataBytes length:strlen(frameHTMLDataBytes)];
    NSData *imageData = [NSData dataWithContentsOfURL:[NSBundle.test_resourcesBundle URLForResource:@"400x400-green" withExtension:@"png"]];
    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        RetainPtr<NSData> data;
        NSString *mimeType = nil;
        if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/main.html"]) {
            mimeType = @"text/html";
            data = htmlData;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/frame.html"]) {
            mimeType = @"text/html";
            data = frameHTMLData;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/image.png"]) {
            mimeType = @"image/png";
            data = imageData;
        } else
            FAIL();

        auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:mimeType expectedContentLength:data.get().length textEncodingName:nil]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:data.get()];
        [task didFinish];
    }];

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    static bool messageReceived = false;
    [webView performAfterReceivingMessage:@"done" action:[&] {
        messageReceived = true;
    }];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"webarchivetest://host/main.html"]]];
    Util::run(&messageReceived);

    static bool saved = false;
    [webView _saveResources:directoryURL.get() suggestedFileName:@"host" completionHandler:^(NSError *error) {
        EXPECT_NULL(error);
        NSString *mainResourcePath = [directoryURL URLByAppendingPathComponent:@"host.html"].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:mainResourcePath]);

        NSString *savedMainResource = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:mainResourcePath] encoding:NSUTF8StringEncoding];
        NSString *resourceDirectoryName = @"host_files";
        NSString *resourceDirectoryPath = [directoryURL URLByAppendingPathComponent:resourceDirectoryName].path;
        NSArray *resourceFileNames = [fileManager contentsOfDirectoryAtPath:resourceDirectoryPath error:0];
        EXPECT_EQ(3llu, resourceFileNames.count);

        unsigned frameFileCount = 0;
        unsigned imageFileCount = 0;
        NSMutableSet *frameResourceContentsToFind = [NSMutableSet set];
        [frameResourceContentsToFind addObjectsFromArray:[NSArray arrayWithObjects:@"thisisframe1", @"thisisframe2", nil]];
        for (NSString *fileName in resourceFileNames) {
            if ([fileName containsString:@"frame_"]) {
                NSString *replacementPath = [resourceDirectoryName stringByAppendingPathComponent:fileName];
                EXPECT_TRUE([savedMainResource containsString:replacementPath]);
                NSString *resourceFilePath = [resourceDirectoryPath stringByAppendingPathComponent:fileName];
                NSString* savedSubframeResource = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:resourceFilePath] encoding:NSUTF8StringEncoding];
                NSRange range = [savedSubframeResource rangeOfString:@"thisisframe"];
                EXPECT_NE(NSNotFound, (long)range.location);
                NSString *frameContent = [savedSubframeResource substringWithRange:NSMakeRange(range.location, range.length + 1)];
                [frameResourceContentsToFind removeObject:frameContent];
                ++frameFileCount;
            }

            if ([fileName isEqualToString:@"image.png"])
                ++imageFileCount;
        }
        EXPECT_EQ(2u, frameFileCount);
        EXPECT_EQ(1u, imageFileCount);
        EXPECT_EQ(0u, frameResourceContentsToFind.count);
        saved = true;
    }];
    Util::run(&saved);
}

TEST(WebArchive, SaveResourcesValidFileName)
{
    RetainPtr<NSURL> directoryURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"SaveResourcesTest"] isDirectory:YES];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:directoryURL.get() error:nil];

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webarchivetest"];

    NSMutableString *mutableFileName = [NSMutableString stringWithCapacity:256];
    for (unsigned i = 0; i < 256; ++i)
        [mutableFileName appendString:@"x"];
    NSArray *tests = [NSArray arrayWithObjects:[NSString stringWithString:mutableFileName], @"a/image.png", @"b/image.png", @"c/image.png", @"d/image.png", @"image.png(1)", @"webarchivetest://host/file:image.png", @"image1/", @"image2///", @"image3.png/./", @"image4/content/../", @"image5%20file.png", @"image 6.png", nil];
    NSMutableString *mutableHTMLString = [NSMutableString string];
    NSString *styleString = @"<link rel='stylesheet' href='imagestyle'><link rel='stylesheet' href='style.css'><link rel='stylesheet' href='style'>";
    NSString *scriptString = [NSString stringWithFormat:@"<script>count = 0; function onImageLoad() { if (++count == %d) window.webkit.messageHandlers.testHandler.postMessage('done'); }</script>", (int)tests.count];
    [mutableHTMLString appendString:styleString];
    [mutableHTMLString appendString:scriptString];
    for (NSString *item in tests)
        [mutableHTMLString appendString:[NSString stringWithFormat:@"<img src='%@' onload='onImageLoad()'>", item]];
    NSData *htmlData = [[NSString stringWithString:mutableHTMLString] dataUsingEncoding:NSUTF8StringEncoding];
    NSData *imageData = [NSData dataWithContentsOfURL:[NSBundle.test_resourcesBundle URLForResource:@"400x400-green" withExtension:@"png"]];
    NSString *cssString = @"img { width: 10px; }";
    NSData *cssData = [cssString dataUsingEncoding:NSUTF8StringEncoding];
    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        RetainPtr<NSData> data;
        NSString *mimeType = nil;
        if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/main.html"]) {
            mimeType = @"text/html";
            data = htmlData;
        } else if ([task.request.URL.absoluteString containsString:@"style"]) {
            mimeType = @"text/css";
            data = cssData;
        } else {
            mimeType = @"image/png";
            data = imageData;
        }
        auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:mimeType expectedContentLength:data.get().length textEncodingName:nil]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:data.get()];
        [task didFinish];
    }];

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    static bool messageReceived = false;
    [webView performAfterReceivingMessage:@"done" action:[&] {
        messageReceived = true;
    }];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"webarchivetest://host/main.html"]]];
    Util::run(&messageReceived);

    NSSet *expectedFileNames = [NSSet setWithArray:[NSArray arrayWithObjects:[mutableFileName substringFromIndex:1], @"image.png", @"image.png-1", @"image.png-2", @"image.png-3", @"image.png-1-", @"file-image.png", @"image1", @"file", @"image3.png", @"image4", @"image5-file.png", @"image-6.png", @"imagestyle.css", @"style.css", @"style-1.css", nil]];
    static bool saved = false;
    [webView _saveResources:directoryURL.get() suggestedFileName:@"host" completionHandler:^(NSError *error) {
        EXPECT_NULL(error);
        NSString *resourceDirectoryName = @"host_files";
        NSArray *resourceFileNames = [fileManager contentsOfDirectoryAtPath:[directoryURL URLByAppendingPathComponent:resourceDirectoryName].path error:nil];
        NSSet *savedFileNames = [NSSet setWithArray:resourceFileNames];
        EXPECT_TRUE([savedFileNames isEqualToSet:expectedFileNames]);

        saved = true;
    }];
    Util::run(&saved);
}

static const char* htmlDataBytesForBlobURL = R"TESTRESOURCE(
<body>
<script>
function onImageLoad() {
    window.webkit.messageHandlers.testHandler.postMessage("done");
}
async function fetchImage() {
    response = await fetch("image.png");
    blob = await response.blob();
    url = URL.createObjectURL(blob);

    frame = document.createElement("iframe");
    frame.src = url;
    document.body.appendChild(frame);

    img = document.createElement('img');
    img.onload = onImageLoad;
    img.src = url;
    document.body.appendChild(img);
}

function createIframe() {
    htmlString = "<p>thisisframe</p>";
    blob = new Blob([htmlString], { type: 'text/html' });
    url = URL.createObjectURL(blob);
    frame = document.createElement("iframe");
    frame.onload = fetchImage;
    frame.src = url;
    document.body.appendChild(frame);
}
createIframe();
</script>
</body>
)TESTRESOURCE";

TEST(WebArchive, SaveResourcesBlobURL)
{
    RetainPtr<NSURL> directoryURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"SaveResourcesTest"] isDirectory:YES];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:directoryURL.get() error:nil];

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webarchivetest"];

    NSData *htmlData = [NSData dataWithBytes:htmlDataBytesForBlobURL length:strlen(htmlDataBytesForBlobURL)];
    NSData *imageData = [NSData dataWithContentsOfURL:[NSBundle.test_resourcesBundle URLForResource:@"400x400-green" withExtension:@"png"]];
    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        RetainPtr<NSData> data;
        NSString *mimeType = nil;
        if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/main.html"]) {
            mimeType = @"text/html";
            data = htmlData;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/image.png"]) {
            mimeType = @"image/png";
            data = imageData;
        } else
            FAIL();

        auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:mimeType expectedContentLength:data.get().length textEncodingName:nil]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:data.get()];
        [task didFinish];
    }];

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    static bool messageReceived = false;
    [webView performAfterReceivingMessage:@"done" action:[&] {
        messageReceived = true;
    }];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"webarchivetest://host/main.html"]]];
    Util::run(&messageReceived);

    static bool saved = false;
    [webView _saveResources:directoryURL.get() suggestedFileName:@"host" completionHandler:^(NSError *error) {
        EXPECT_NULL(error);
        NSString *mainResourcePath = [directoryURL URLByAppendingPathComponent:@"host.html"].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:mainResourcePath]);

        NSString *savedMainResource = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:mainResourcePath] encoding:NSUTF8StringEncoding];
        NSString *resourceDirectoryName = @"host_files";
        NSString *resourceDirectoryPath = [directoryURL URLByAppendingPathComponent:resourceDirectoryName].path;
        NSArray *resourceFileNames = [fileManager contentsOfDirectoryAtPath:resourceDirectoryPath error:0];
        EXPECT_EQ(2llu, resourceFileNames.count);

        for (NSString *fileName in resourceFileNames) {
            NSString *replacementPath = [resourceDirectoryName stringByAppendingPathComponent:fileName];
            if ([fileName containsString:@"frame_"]) {
                // HTML file from the first iframe element.
                EXPECT_TRUE([savedMainResource containsString:replacementPath]);
                NSString *resourceFilePath = [resourceDirectoryPath stringByAppendingPathComponent:fileName];
                NSString* savedSubframeResource = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:resourceFilePath] encoding:NSUTF8StringEncoding];
                EXPECT_TRUE([savedSubframeResource containsString:@"thisisframe"]);
            } else {
                // Image file from img and the second iframe element.
                unsigned replacementPathCount = 0;
                NSString *savedMainResourceCopy = [NSString stringWithString:savedMainResource];
                NSRange range = [savedMainResourceCopy rangeOfString:replacementPath];
                while (range.location != NSNotFound) {
                    ++replacementPathCount;
                    savedMainResourceCopy = [savedMainResourceCopy substringFromIndex:range.location + 1];
                    range = [savedMainResourceCopy rangeOfString:replacementPath];
                }
                EXPECT_EQ(2u, replacementPathCount);
            }
        }
        saved = true;
    }];
    Util::run(&saved);
}

static const char* htmlDataBytesForResponsiveImages = R"TESTRESOURCE(
<head>
<script>
const dpr = window.devicePixelRatio;
// Use image-set for div.
style = document.createElement('style');
style.innerHTML = "div { background-image:image-set('div1.png' " + dpr + "x, 'div2.png' " + (dpr + 1) + "x)}";
document.getElementsByTagName("head")[0].appendChild(style);
</script>
</head>
<body>
<div id="div">Hello</div>
<script>
count = 0;
function addSrcsetToImage() {
    image = document.getElementById("image");
    image.removeAttribute("src");
    image.srcset = "image2.png " + dpr + "x, image1.png " + (dpr + 1) + "x";
}
function onImageLoad() {
    ++count;
    if (count == 2) // image1.png and picture2.png are loaded.
        addSrcsetToImage();
    if (count == 3) // image2.png is loaded.
        window.webkit.messageHandlers.testHandler.postMessage("done");
}
</script>
<img id="image" src="image1.png" onload="onImageLoad()">
<picture id="picture">
    <source srcset="picture1.png" media="(min-width: 3000px)">
    <img src="picture2.png" onload="onImageLoad()">
</picture>
</body>
)TESTRESOURCE";

TEST(WebArchive, SaveResourcesResponsiveImages)
{
    RetainPtr<NSURL> directoryURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"SaveResourcesTest"] isDirectory:YES];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:directoryURL.get() error:nil];

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webarchivetest"];
    NSData *htmlData = [NSData dataWithBytes:htmlDataBytesForResponsiveImages length:strlen(htmlDataBytesForResponsiveImages)];
    NSData *imageData = [NSData dataWithContentsOfURL:[NSBundle.test_resourcesBundle URLForResource:@"400x400-green" withExtension:@"png"]];
    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        RetainPtr<NSData> data;
        NSString *mimeType = nil;
        if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/main.html"]) {
            mimeType = @"text/html";
            data = htmlData;
        } else if ([task.request.URL.absoluteString containsString:@"png"]) {
            mimeType = @"image/png";
            data = imageData;
        } else
            FAIL();

        auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:mimeType expectedContentLength:data.get().length textEncodingName:nil]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:data.get()];
        [task didFinish];
    }];

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    static bool messageReceived = false;
    [webView performAfterReceivingMessage:@"done" action:[&] {
        messageReceived = true;
    }];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"webarchivetest://host/main.html"]]];
    Util::run(&messageReceived);

    static bool saved = false;
    [webView _saveResources:directoryURL.get() suggestedFileName:@"host" completionHandler:^(NSError *error) {
        NSString *mainResourcePath = [directoryURL URLByAppendingPathComponent:@"host.html"].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:mainResourcePath]);
        NSString *savedMainResourceString = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:mainResourcePath] encoding:NSUTF8StringEncoding];
        NSString *resourceDirectoryName = @"host_files";
        NSString *resourceDirectoryPath = [directoryURL URLByAppendingPathComponent:resourceDirectoryName].path;
        NSArray *resourceFileNames = [fileManager contentsOfDirectoryAtPath:resourceDirectoryPath error:0];
        NSSet *expectedFileNames = [NSSet setWithArray:[NSArray arrayWithObjects:@"image1.png", @"image2.png", @"picture2.png", @"div1.png", nil]];
        NSSet *savedFileNames = [NSSet setWithArray:resourceFileNames];
        EXPECT_TRUE([savedFileNames isEqualToSet:expectedFileNames]);

        for (NSString *fileName in resourceFileNames) {
            NSString *replacementPath = [resourceDirectoryName stringByAppendingPathComponent:fileName];
            EXPECT_TRUE([savedMainResourceString containsString:replacementPath]);
        }

        saved = true;
    }];
    Util::run(&saved);
}

static const char* hTMLDataBytesForDataURL = R"TESTRESOURCE(
<script>
count = 0;
function onLoad() {
    if (++count == 3)
        window.webkit.messageHandlers.testHandler.postMessage("done");
}
</script>
<img onload="onLoad()" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAIAAAAP3aGbAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QcOEyQ6arfsmQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAD5ElEQVR42u3UMQ0AAAgEsQflSEcFA0kr4YarTABeaAkAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIMSwLAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC+DSAp/KA6AWm53xAAAAAElFTkSuQmCC">
<iframe onload="onLoad()" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAIAAAAP3aGbAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QcOEyQ6arfsmQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAD5ElEQVR42u3UMQ0AAAgEsQflSEcFA0kr4YarTABeaAkAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIMSwLAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC+DSAp/KA6AWm53xAAAAAElFTkSuQmCC"></iframe>
<iframe onload="onLoad()" src="data:text/html,<img src='webarchivetest://host/image.png'>"></iframe>
)TESTRESOURCE";

TEST(WebArchive, SaveResourcesDataURL)
{
    RetainPtr<NSURL> directoryURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"SaveResourcesTest"] isDirectory:YES];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:directoryURL.get() error:nil];

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webarchivetest"];

    NSData *htmlData = [NSData dataWithBytes:hTMLDataBytesForDataURL length:strlen(hTMLDataBytesForDataURL)];
    NSData *imageData = [NSData dataWithContentsOfURL:[NSBundle.test_resourcesBundle URLForResource:@"400x400-green" withExtension:@"png"]];
    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        RetainPtr<NSData> data;
        NSString *mimeType = nil;
        if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/main.html"]) {
            mimeType = @"text/html";
            data = htmlData;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/image.png"]) {
            mimeType = @"image/png";
            data = imageData;
        } else
            FAIL();

        auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:mimeType expectedContentLength:data.get().length textEncodingName:nil]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:data.get()];
        [task didFinish];
    }];

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    static bool messageReceived = false;
    [webView performAfterReceivingMessage:@"done" action:[&] {
        messageReceived = true;
    }];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"webarchivetest://host/main.html"]]];
    Util::run(&messageReceived);

    static bool saved = false;
    [webView _saveResources:directoryURL.get() suggestedFileName:@"host" completionHandler:^(NSError *error) {
        EXPECT_NULL(error);
        NSString *mainResourcePath = [directoryURL URLByAppendingPathComponent:@"host.html"].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:mainResourcePath]);

        NSString *savedMainResource = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:mainResourcePath] encoding:NSUTF8StringEncoding];
        NSString *resourceDirectoryName = @"host_files";
        NSString *resourceDirectoryPath = [directoryURL URLByAppendingPathComponent:resourceDirectoryName].path;
        NSArray *resourceFileNames = [fileManager contentsOfDirectoryAtPath:resourceDirectoryPath error:nil];
        EXPECT_EQ(3llu, resourceFileNames.count);

        unsigned frameFileCount = 0;
        unsigned imageFileCount = 0;
        unsigned frameWithDataURLCount = 0;
        for (NSString *fileName in resourceFileNames) {
            if ([fileName containsString:@"frame_"]) {
                NSString *replacementPath = [resourceDirectoryName stringByAppendingPathComponent:fileName];
                EXPECT_TRUE([savedMainResource containsString:replacementPath]);
                NSString *resourceFilePath = [resourceDirectoryPath stringByAppendingPathComponent:fileName];
                NSString* savedSubframeResource = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:resourceFilePath] encoding:NSUTF8StringEncoding];
                if ([savedSubframeResource containsString:@"data:image/png"])
                    ++frameWithDataURLCount;
                ++frameFileCount;
            }

            if ([fileName containsString:@".png"])
                ++imageFileCount;
        }
        EXPECT_EQ(2u, frameFileCount);
        EXPECT_EQ(1u, imageFileCount);
        EXPECT_EQ(1u, frameWithDataURLCount);

        saved = true;
    }];
    Util::run(&saved);
}

static const char* htmlDataBytesForIframeInIframe = R"TESTRESOURCE(
<script>
count = 0;
function frameLoaded() {
    if (++count == 2)
        window.webkit.messageHandlers.testHandler.postMessage("done");
}
window.addEventListener('message', function(event) {
    if (event.data == 'loaded')
        frameLoaded();
});
</script>
<iframe onload="frameLoaded();" src="iframe1.html"></iframe>
)TESTRESOURCE";
static const char* iframe1HTMLDataBytes = R"TESTRESOURCE(
<script>
function frameLoaded() {
    window.parent.postMessage("loaded", "*");
}
</script>
<p>thisisiframe1</p>
<iframe onload="frameLoaded();" src="iframe2.html"></iframe>
)TESTRESOURCE";
static const char* iframe2HTMLDataBytes = R"TESTRESOURCE(<p>thisisiframe2</p>)TESTRESOURCE";

TEST(WebArchive, SaveResourcesIframeInIframe)
{
    RetainPtr<NSURL> directoryURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"SaveResourcesTest"] isDirectory:YES];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:directoryURL.get() error:nil];

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webarchivetest"];
    NSData *htmlData = [NSData dataWithBytes:htmlDataBytesForIframeInIframe length:strlen(htmlDataBytesForIframeInIframe)];
    NSData *iframe1HTMLData = [NSData dataWithBytes:iframe1HTMLDataBytes length:strlen(iframe1HTMLDataBytes)];
    NSData *iframe2HTMLData = [NSData dataWithBytes:iframe2HTMLDataBytes length:strlen(iframe2HTMLDataBytes)];
    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        RetainPtr<NSData> data;
        NSString *mimeType = nil;
        if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/main.html"]) {
            mimeType = @"text/html";
            data = htmlData;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/iframe1.html"]) {
            mimeType = @"text/html";
            data = iframe1HTMLData;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/iframe2.html"]) {
            mimeType = @"text/html";
            data = iframe2HTMLData;
        } else
            FAIL();

        auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:mimeType expectedContentLength:data.get().length textEncodingName:nil]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:data.get()];
        [task didFinish];
    }];

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    static bool messageReceived = false;
    [webView performAfterReceivingMessage:@"done" action:[&] {
        messageReceived = true;
    }];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"webarchivetest://host/main.html"]]];
    Util::run(&messageReceived);

    static bool saved = false;
    [webView _saveResources:directoryURL.get() suggestedFileName:@"host" completionHandler:^(NSError *error) {
        EXPECT_NULL(error);
        NSString *mainResourcePath = [directoryURL URLByAppendingPathComponent:@"host.html"].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:mainResourcePath]);

        NSString *resourceDirectoryName = @"host_files";
        NSString *resourceDirectoryPath = [directoryURL URLByAppendingPathComponent:resourceDirectoryName].path;
        NSArray *resourceFileNames = [fileManager contentsOfDirectoryAtPath:resourceDirectoryPath error:0];
        EXPECT_EQ(2llu, resourceFileNames.count);

        NSMutableSet *frameResourceContentsToFind = [NSMutableSet set];
        [frameResourceContentsToFind addObjectsFromArray:[NSArray arrayWithObjects:@"thisisiframe1", @"thisisiframe2", nil]];
        for (NSString *fileName in resourceFileNames) {
            EXPECT_TRUE([fileName containsString:@"frame_"]);
            NSString *resourceFilePath = [resourceDirectoryPath stringByAppendingPathComponent:fileName];
            NSString* savedSubframeResource = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:resourceFilePath] encoding:NSUTF8StringEncoding];
            NSRange range = [savedSubframeResource rangeOfString:@"thisisiframe"];
            EXPECT_NE(NSNotFound, (long)range.location);
            NSString *iframeContent = [savedSubframeResource substringWithRange:NSMakeRange(range.location, range.length + 1)];
            if ([iframeContent isEqualToString:@"thisisiframe1"]) {
                // Main resources of iframes are stored in the same directory, so replaced url should not contain the directory name.
                EXPECT_FALSE([savedSubframeResource containsString:resourceDirectoryName]);
            }
            [frameResourceContentsToFind removeObject:iframeContent];
        }
        EXPECT_EQ(0u, frameResourceContentsToFind.count);
        saved = true;
    }];
    Util::run(&saved);
}

static const char* htmlDataBytesForIframesWithSameURL = R"TESTRESOURCE(
<script>
count = 0;
messageCount = 0;
function frameLoaded() {
    if (++count == 3) {
        const iframes = document.getElementsByTagName("iframe");
        for (let i = 0; i < iframes.length; ++i)
            iframes[i].contentWindow.postMessage("thisisiframe" + (i + 1), "*");
    }
}
window.addEventListener("message", function(event) {
    if (++messageCount == 3)
        window.webkit.messageHandlers.testHandler.postMessage("done");
});
</script>
<iframe onload="frameLoaded();" src="iframe.html"></iframe>
<iframe onload="frameLoaded();" src="iframe.html"></iframe>
<iframe onload="frameLoaded();" src="iframe.html"></iframe>
)TESTRESOURCE";
static const char* iframeHTMLDataBytesForIframesWithSameURL = R"TESTRESOURCE(
<head>
<script>
window.addEventListener("message", function(event) {
    if (!document.body.innerHTML)
        document.body.innerHTML = "<p>" + event.data + "</p>";
    window.parent.postMessage("done", "*");
});
</script>
</head>
)TESTRESOURCE";

TEST(WebArchive, SaveResourcesIframesWithSameURL)
{
    RetainPtr<NSURL> directoryURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"SaveResourcesTest"] isDirectory:YES];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:directoryURL.get() error:nil];

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webarchivetest"];
    NSData *htmlData = [NSData dataWithBytes:htmlDataBytesForIframesWithSameURL length:strlen(htmlDataBytesForIframesWithSameURL)];
    NSData *iframeHTMLData = [NSData dataWithBytes:iframeHTMLDataBytesForIframesWithSameURL length:strlen(iframeHTMLDataBytesForIframesWithSameURL)];
    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        RetainPtr<NSData> data;
        NSString *mimeType = nil;
        if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/main.html"]) {
            mimeType = @"text/html";
            data = htmlData;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/iframe.html"]) {
            mimeType = @"text/html";
            data = iframeHTMLData;
        } else
            FAIL();

        auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:mimeType expectedContentLength:data.get().length textEncodingName:nil]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:data.get()];
        [task didFinish];
    }];

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    static bool messageReceived = false;
    [webView performAfterReceivingMessage:@"done" action:[&] {
        messageReceived = true;
    }];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"webarchivetest://host/main.html"]]];
    Util::run(&messageReceived);

    static bool saved = false;
    [webView _saveResources:directoryURL.get() suggestedFileName:@"host" completionHandler:^(NSError *error) {
        EXPECT_NULL(error);
        NSString *mainResourcePath = [directoryURL URLByAppendingPathComponent:@"host.html"].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:mainResourcePath]);

        NSString *resourceDirectoryName = @"host_files";
        NSString *resourceDirectoryPath = [directoryURL URLByAppendingPathComponent:resourceDirectoryName].path;
        NSArray *resourceFileNames = [fileManager contentsOfDirectoryAtPath:resourceDirectoryPath error:0];
        EXPECT_EQ(3llu, resourceFileNames.count);

        NSMutableSet *frameResourceContentsToFind = [NSMutableSet set];
        [frameResourceContentsToFind addObjectsFromArray:[NSArray arrayWithObjects:@"thisisiframe1", @"thisisiframe2", @"thisisiframe3", nil]];
        for (NSString *fileName in resourceFileNames) {
            EXPECT_TRUE([fileName containsString:@"frame_"]);
            NSString *resourceFilePath = [resourceDirectoryPath stringByAppendingPathComponent:fileName];
            NSString* savedSubframeResource = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:resourceFilePath] encoding:NSUTF8StringEncoding];
            NSRange range = [savedSubframeResource rangeOfString:@"thisisiframe"];
            EXPECT_NE(NSNotFound, (long)range.location);
            NSString *iframeContent = [savedSubframeResource substringWithRange:NSMakeRange(range.location, range.length + 1)];
            [frameResourceContentsToFind removeObject:iframeContent];
        }
        EXPECT_EQ(0u, frameResourceContentsToFind.count);
        saved = true;
    }];
    Util::run(&saved);
}

static const char* htmlDataBytesForShadowDOM = R"TESTRESOURCE(
<button id="button" onclick="buttonClicked()"></button>
<script>
function buttonClicked() {
    div1 = document.createElement("div");
    div1.id = "div1";
    root1 = div1.attachShadow({ mode: "open" });
    root1.innerHTML = "ShadowRoot1";
    div2 = document.createElement("div");
    div2.id = "div2";
    root2 = div2.attachShadow({ mode: "closed" });
    root2.innerHTML = "ShadowRoot2<slot name='text'></slot>";
    span = document.createElement("span");
    span.slot= "text";
    span.innerHTML = "Text";
    root2.appendChild(span);
    root1.appendChild(div2);
    var button = document.getElementById("button");
    button.parentNode.removeChild(button);
    document.body.appendChild(div1);
    window.webkit.messageHandlers.testHandler.postMessage("done");
}
window.webkit.messageHandlers.testHandler.postMessage("start");
</script>
)TESTRESOURCE";

TEST(WebArchive, SaveResourcesShadowDOM)
{
    RetainPtr<NSURL> directoryURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"SaveResourcesTest"] isDirectory:YES];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:directoryURL.get() error:nil];

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webarchivetest"];
    NSData *htmlData = [NSData dataWithBytes:htmlDataBytesForShadowDOM length:strlen(htmlDataBytesForShadowDOM)];
    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        RetainPtr<NSData> data;
        NSString *mimeType = nil;
        if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/main.html"]) {
            mimeType = @"text/html";
            data = htmlData;
        } else
            FAIL();

        auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:mimeType expectedContentLength:data.get().length textEncodingName:nil]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:data.get()];
        [task didFinish];
    }];

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    static bool messageReceived = false;
    [webView performAfterReceivingMessage:@"start" action:[&] {
        messageReceived = true;
    }];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"webarchivetest://host/main.html"]]];
    Util::run(&messageReceived);

    messageReceived = false;
    [webView performAfterReceivingMessage:@"done" action:[&] {
        messageReceived = true;
    }];
    [webView evaluateJavaScript:@"document.getElementById('button').click();" completionHandler:nil];
    Util::run(&messageReceived);

    static bool saved = false;
    [webView _saveResources:directoryURL.get() suggestedFileName:@"host" completionHandler:^(NSError *error) {
        EXPECT_NULL(error);
        NSString *mainResourcePath = [directoryURL URLByAppendingPathComponent:@"host.html"].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:mainResourcePath]);
        NSString *savedMainResource = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:mainResourcePath] encoding:NSUTF8StringEncoding];
        EXPECT_TRUE([savedMainResource containsString:@"<div id=\"div1\"><template shadowrootmode=\"open\">ShadowRoot1<div id=\"div2\"><template shadowrootmode=\"closed\">ShadowRoot2<slot name=\"text\"></slot><span slot=\"text\">Text</span></template></div></template></div>"]);
        saved = true;
    }];
    Util::run(&saved);
}

static const char* htmlDataBytesForDeclarativeShadowDOM = R"TESTRESOURCE(
<script>
function loaded() {
    window.webkit.messageHandlers.testHandler.postMessage("done");
}
</script>
<body onload="loaded()">
<div>
<template shadowroot="open"><slot></slot></template><p>ShadowDOM</p><button>Button</button>
</div>
</body>
)TESTRESOURCE";

TEST(WebArchive, SaveResourcesDeclarativeShadowDOM)
{
    RetainPtr<NSURL> directoryURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"SaveResourcesTest"] isDirectory:YES];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:directoryURL.get() error:nil];

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webarchivetest"];
    NSData *htmlData = [NSData dataWithBytes:htmlDataBytesForDeclarativeShadowDOM length:strlen(htmlDataBytesForDeclarativeShadowDOM)];
    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        RetainPtr<NSData> data;
        NSString *mimeType = nil;
        if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/main.html"]) {
            mimeType = @"text/html";
            data = htmlData;
        } else
            FAIL();

        auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:mimeType expectedContentLength:data.get().length textEncodingName:nil]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:data.get()];
        [task didFinish];
    }];

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    static bool messageReceived = false;
    [webView performAfterReceivingMessage:@"done" action:[&] {
        messageReceived = true;
    }];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"webarchivetest://host/main.html"]]];
    Util::run(&messageReceived);

    static bool saved = false;
    [webView _saveResources:directoryURL.get() suggestedFileName:@"host" completionHandler:^(NSError *error) {
        EXPECT_NULL(error);
        NSString *mainResourcePath = [directoryURL URLByAppendingPathComponent:@"host.html"].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:mainResourcePath]);

        NSString *savedMainResource = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:mainResourcePath] encoding:NSUTF8StringEncoding];
        EXPECT_TRUE([savedMainResource containsString:@"<template shadowroot=\"open\"><slot></slot></template><p>ShadowDOM</p><button>Button</button>"]);
        saved = true;
    }];
    Util::run(&saved);
}

static const char* htmlDataBytesForStyle = R"TESTRESOURCE(
<style>
@font-face {
    font-family: "WebFont";
    src: url("Ahem-10000A.ttf");
}
div {
    height: 50%;
    width: 50%;
    font-family: "WebFont";
    background-image: url("image.png");
}
</style>
<div id="div">Hello</div>
<script>
    div = document.getElementById("div");
    imageURL = getComputedStyle(div).backgroundImage;
    document.fonts.ready.then(() => { window.webkit.messageHandlers.testHandler.postMessage("done"); });
</script>
)TESTRESOURCE";

TEST(WebArchive, SaveResourcesStyle)
{
    RetainPtr<NSURL> directoryURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"SaveResourcesTest"] isDirectory:YES];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:directoryURL.get() error:nil];

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webarchivetest"];
    NSData *htmlData = [NSData dataWithBytes:htmlDataBytesForStyle length:strlen(htmlDataBytesForStyle)];
    NSData *imageData = [NSData dataWithContentsOfURL:[NSBundle.test_resourcesBundle URLForResource:@"400x400-green" withExtension:@"png"]];
    NSData *fontData = [NSData dataWithContentsOfURL:[NSBundle.test_resourcesBundle URLForResource:@"Ahem-10000A" withExtension:@"ttf"]];
    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        RetainPtr<NSData> data;
        NSString *mimeType = nil;
        if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/main.html"]) {
            mimeType = @"text/html";
            data = htmlData;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/image.png"]) {
            mimeType = @"image/png";
            data = imageData;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/Ahem-10000A.ttf"]) {
            mimeType = @"font/ttf";
            data = fontData;
        } else
            FAIL();

        auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:mimeType expectedContentLength:data.get().length textEncodingName:nil]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:data.get()];
        [task didFinish];
    }];

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    static bool messageReceived = false;
    [webView performAfterReceivingMessage:@"done" action:[&] {
        messageReceived = true;
    }];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"webarchivetest://host/main.html"]]];
    Util::run(&messageReceived);

    static bool saved = false;
    [webView _saveResources:directoryURL.get() suggestedFileName:@"host" completionHandler:^(NSError *error) {
        EXPECT_NULL(error);
        NSString *mainResourcePath = [directoryURL URLByAppendingPathComponent:@"host.html"].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:mainResourcePath]);

        NSString *savedMainResource = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:mainResourcePath] encoding:NSUTF8StringEncoding];
        NSString *resourceDirectoryName = @"host_files";
        NSString *resourceDirectoryPath = [directoryURL URLByAppendingPathComponent:resourceDirectoryName].path;
        NSArray *resourceFileNames = [fileManager contentsOfDirectoryAtPath:resourceDirectoryPath error:0];
        EXPECT_EQ(2llu, resourceFileNames.count);

        for (NSString *fileName in resourceFileNames) {
            NSString *replacementPath = [resourceDirectoryName stringByAppendingPathComponent:fileName];
            EXPECT_TRUE([savedMainResource containsString:replacementPath]);
        }

        saved = true;
    }];
    Util::run(&saved);
}

static const char* htmlDataBytesForInlineStyle = R"TESTRESOURCE(
<div id="div" style="background-image:url('image.png');width:50%;height:50%;color:red">Hello</div>
<script>
    div = document.getElementById("div");
    div.style.color = "fuchsia";
    imageURL = getComputedStyle(div).backgroundImage;
    window.webkit.messageHandlers.testHandler.postMessage("done");
</script>
)TESTRESOURCE";

TEST(WebArchive, SaveResourcesInlineStyle)
{
    RetainPtr<NSURL> directoryURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"SaveResourcesTest"] isDirectory:YES];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:directoryURL.get() error:nil];

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webarchivetest"];
    NSData *htmlData = [NSData dataWithBytes:htmlDataBytesForInlineStyle length:strlen(htmlDataBytesForInlineStyle)];
    NSData *imageData = [NSData dataWithContentsOfURL:[NSBundle.test_resourcesBundle URLForResource:@"400x400-green" withExtension:@"png"]];
    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        RetainPtr<NSData> data;
        NSString *mimeType = nil;
        if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/main.html"]) {
            mimeType = @"text/html";
            data = htmlData;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/image.png"]) {
            mimeType = @"image/png";
            data = imageData;
        } else
            FAIL();

        auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:mimeType expectedContentLength:data.get().length textEncodingName:nil]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:data.get()];
        [task didFinish];
    }];

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    static bool messageReceived = false;
    [webView performAfterReceivingMessage:@"done" action:[&] {
        messageReceived = true;
    }];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"webarchivetest://host/main.html"]]];
    Util::run(&messageReceived);

    static bool saved = false;
    [webView _saveResources:directoryURL.get() suggestedFileName:@"host" completionHandler:^(NSError *error) {
        EXPECT_NULL(error);
        NSString *mainResourcePath = [directoryURL URLByAppendingPathComponent:@"host.html"].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:mainResourcePath]);

        NSString *savedMainResource = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:mainResourcePath] encoding:NSUTF8StringEncoding];
        EXPECT_TRUE([savedMainResource containsString:@"color: fuchsia"]);

        NSString *resourceDirectoryName = @"host_files";
        NSString *resourceDirectoryPath = [directoryURL URLByAppendingPathComponent:resourceDirectoryName].path;
        NSArray *resourceFileNames = [fileManager contentsOfDirectoryAtPath:resourceDirectoryPath error:0];
        EXPECT_EQ(1llu, resourceFileNames.count);

        for (NSString *fileName in resourceFileNames) {
            NSString *replacementPath = [resourceDirectoryName stringByAppendingPathComponent:fileName];
            EXPECT_TRUE([savedMainResource containsString:replacementPath]);
        }

        saved = true;
    }];
    Util::run(&saved);
}

static const char* htmlDataBytesForLink = R"TESTRESOURCE(
<head>
<link rel="manifest" href="manifest.json">
<link rel="preload" href="Ahem-10000A.ttf" as="font" type="font/ttf">
<link rel="stylesheet" href="style.css">
</head>
<div><p id="console">Hello</p></div>
<script>
img = null;
function onImageLoad() {
    img = null;
    window.webkit.messageHandlers.testHandler.postMessage("done");
}
document.styleSheets[0].insertRule("p { color: fuchsia; }");
console = document.getElementById("console");
computedStyle = getComputedStyle(console);
var img = document.createElement("img");
img.src = "files/image.png";
img.onload = onImageLoad;
</script>
)TESTRESOURCE";
static const char* cssDataBytesForLink = R"TESTRESOURCE(
div {
    height: 50%;
    width: 50%;
    background-image: url("files/image.png");
}
)TESTRESOURCE";
static const char* manifestDataBytesForLink = R"TESTRESOURCE(
{
    "name": "webarchivetest",
    "short_name": "wat",
    "description": "This is a test app."
}
)TESTRESOURCE";

TEST(WebArchive, SaveResourcesLink)
{
    RetainPtr<NSURL> directoryURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"SaveResourcesTest"] isDirectory:YES];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:directoryURL.get() error:nil];

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webarchivetest"];
    NSData *htmlData = [NSData dataWithBytes:htmlDataBytesForLink length:strlen(htmlDataBytesForLink)];
    NSData *cssData = [NSData dataWithBytes:cssDataBytesForLink length:strlen(cssDataBytesForLink)];
    NSData *imageData = [NSData dataWithContentsOfURL:[NSBundle.test_resourcesBundle URLForResource:@"400x400-green" withExtension:@"png"]];
    NSData *manifestData = [NSData dataWithBytes:manifestDataBytesForLink length:strlen(manifestDataBytesForLink)];
    NSData *fontData = [NSData dataWithContentsOfURL:[NSBundle.test_resourcesBundle URLForResource:@"Ahem-10000A" withExtension:@"ttf"]];
    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        RetainPtr<NSData> data;
        NSString *mimeType = nil;
        if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/main.html"]) {
            mimeType = @"text/html";
            data = htmlData;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/files/image.png"]) {
            mimeType = @"image/png";
            data = imageData;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/style.css"]) {
            mimeType = @"text/css";
            data = cssData;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/manifest.json"]) {
            mimeType = @"application/json";
            data = manifestData;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/Ahem-10000A.ttf"]) {
            mimeType = @"font/ttf";
            data = fontData;
        }

        auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:mimeType expectedContentLength:data.get().length textEncodingName:nil]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:data.get()];
        [task didFinish];
    }];

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    static bool messageReceived = false;
    [webView performAfterReceivingMessage:@"done" action:[&] {
        messageReceived = true;
    }];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"webarchivetest://host/main.html"]]];
    Util::run(&messageReceived);

    static bool saved = false;
    [webView _saveResources:directoryURL.get() suggestedFileName:@"host" completionHandler:^(NSError *error) {
        EXPECT_NULL(error);
        NSString *mainResourcePath = [directoryURL URLByAppendingPathComponent:@"host.html"].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:mainResourcePath]);
        NSString *savedMainResource = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:mainResourcePath] encoding:NSUTF8StringEncoding];

        NSString *resourceDirectoryName = @"host_files";
        NSString *resourceDirectoryPath =[directoryURL URLByAppendingPathComponent:resourceDirectoryName].path;
        NSArray *resourceFileNames = [fileManager contentsOfDirectoryAtPath:resourceDirectoryPath error:nil];
        NSSet *savedFileNames = [NSSet setWithArray:resourceFileNames];
        NSSet *expectedFileNames = [NSSet setWithArray:[NSArray arrayWithObjects:@"image.png", @"style.css", @"manifest.json", @"Ahem-10000A.ttf", nil]];
        EXPECT_TRUE([savedFileNames isEqualToSet:expectedFileNames]);
        for (NSString *savedFileName in resourceFileNames) {
            // image.png is not subresource in main resource file.
            if ([savedFileName isEqualToString:@"image.png"])
                continue;

            NSString *savedFileRelativePath = [resourceDirectoryName stringByAppendingPathComponent:savedFileName];
            EXPECT_TRUE([savedMainResource containsString:savedFileRelativePath]);
        }

        NSString *styleResourceFilePath = [resourceDirectoryPath stringByAppendingPathComponent:@"style.css"];
        NSString *savedStyleResource = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:styleResourceFilePath] encoding:NSUTF8StringEncoding];
        EXPECT_TRUE([savedStyleResource containsString:@"url(\"image.png\")"]);
        EXPECT_TRUE([savedStyleResource containsString:@"color: fuchsia"]);

        saved = true;
    }];
    Util::run(&saved);
}

static const char* htmlDataBytesForEmptyStyleSheet = R"TESTRESOURCE(
<head>
<link rel="stylesheet" href="empty.css">
</head>
<script>
window.webkit.messageHandlers.testHandler.postMessage("done");
</script>
)TESTRESOURCE";

TEST(WebArchive, SaveResourcesEmptyStyleSheet)
{
    RetainPtr directoryURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"SaveResourcesTest"] isDirectory:YES];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:directoryURL.get() error:nil];

    RetainPtr configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    RetainPtr schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webarchivetest"];
    RetainPtr htmlData = [NSData dataWithBytes:htmlDataBytesForEmptyStyleSheet length:strlen(htmlDataBytesForEmptyStyleSheet)];
    RetainPtr cssData = adoptNS([[NSData alloc] init]);
    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        NSData *data = nil;
        NSString *mimeType = nil;
        if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/main.html"]) {
            mimeType = @"text/html";
            data = htmlData.get();
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/empty.css"]) {
            mimeType = @"text/css";
            data = cssData.get();
        }

        RetainPtr response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:mimeType expectedContentLength:data.length textEncodingName:nil]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:data];
        [task didFinish];
    }];

    RetainPtr webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    static bool messageReceived = false;
    [webView performAfterReceivingMessage:@"done" action:[&] {
        messageReceived = true;
    }];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"webarchivetest://host/main.html"]]];
    Util::run(&messageReceived);

    static bool saved = false;
    [webView _saveResources:directoryURL.get() suggestedFileName:@"host" completionHandler:^(NSError *error) {
        EXPECT_NULL(error);
        NSString *mainResourcePath = [directoryURL URLByAppendingPathComponent:@"host.html"].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:mainResourcePath]);
        RetainPtr savedMainResource = adoptNS([[NSString alloc] initWithData:[NSData dataWithContentsOfFile:mainResourcePath] encoding:NSUTF8StringEncoding]);

        NSString *resourceDirectoryName = @"host_files";
        NSString *styleReourceName = @"empty.css";
        NSString *resourceDirectoryPath = [directoryURL URLByAppendingPathComponent:resourceDirectoryName].path;
        NSString *styleResourceFilePath = [resourceDirectoryPath stringByAppendingPathComponent:styleReourceName];
        EXPECT_TRUE([fileManager fileExistsAtPath:styleResourceFilePath]);
        RetainPtr savedStyleResource = adoptNS([[NSString alloc] initWithData:[NSData dataWithContentsOfFile:styleResourceFilePath] encoding:NSUTF8StringEncoding]);
        EXPECT_EQ([savedStyleResource length], 0u);

        NSString *styleResourceRelativePath = [resourceDirectoryName stringByAppendingPathComponent:styleReourceName];
        EXPECT_TRUE([savedMainResource.get() containsString:styleResourceRelativePath]);
        saved = true;
    }];
    Util::run(&saved);
}

static const char* htmlDataBytesForLinksWithSameURL = R"TESTRESOURCE(
<head>
<link href="style.css" rel="stylesheet">
<link href="style.css" rel="stylesheet">
</head>
<div>Hello</div>
<p id="console">World</p>
<script>
document.styleSheets[0].deleteRule(0);
document.styleSheets[0].insertRule("p { color: gray; }");
console = document.getElementById("console");
computedStyle = getComputedStyle(console);
window.webkit.messageHandlers.testHandler.postMessage("done");
</script>
)TESTRESOURCE";
static const char* cssDataBytesForLinksWithSameURL = R"TESTRESOURCE(
div {
    color: blue;
}
)TESTRESOURCE";

TEST(WebArchive, SaveResourcesLinksWithSameURL)
{
    RetainPtr<NSURL> directoryURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"SaveResourcesTest"] isDirectory:YES];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:directoryURL.get() error:nil];

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webarchivetest"];
    NSData *htmlData = [NSData dataWithBytes:htmlDataBytesForLinksWithSameURL length:strlen(htmlDataBytesForLinksWithSameURL)];
    NSData *cssData = [NSData dataWithBytes:cssDataBytesForLinksWithSameURL length:strlen(cssDataBytesForLinksWithSameURL)];
    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        RetainPtr<NSData> data;
        NSString *mimeType = nil;
        if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/main.html"]) {
            mimeType = @"text/html";
            data = htmlData;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/style.css"]) {
            mimeType = @"text/css";
            data = cssData;
        }

        auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:mimeType expectedContentLength:data.get().length textEncodingName:nil]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:data.get()];
        [task didFinish];
    }];

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    static bool messageReceived = false;
    [webView performAfterReceivingMessage:@"done" action:[&] {
        messageReceived = true;
    }];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"webarchivetest://host/main.html"]]];
    Util::run(&messageReceived);

    static bool saved = false;
    [webView _saveResources:directoryURL.get() suggestedFileName:@"host" completionHandler:^(NSError *error) {
        EXPECT_NULL(error);
        NSString *mainResourcePath = [directoryURL URLByAppendingPathComponent:@"host.html"].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:mainResourcePath]);
        NSString *savedMainResource = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:mainResourcePath] encoding:NSUTF8StringEncoding];

        NSString *resourceDirectoryName = @"host_files";
        NSString *resourceDirectoryPath =[directoryURL URLByAppendingPathComponent:resourceDirectoryName].path;
        NSArray *resourceFileNames = [fileManager contentsOfDirectoryAtPath:resourceDirectoryPath error:nil];
        EXPECT_EQ(2llu, resourceFileNames.count);

        NSMutableSet *styleResourceContentsToFind = [NSMutableSet set];
        [styleResourceContentsToFind addObjectsFromArray:[NSArray arrayWithObjects:@"color: blue", @"color: fuchsia", nil]];
        for (NSString *fileName in resourceFileNames) {
            NSString *replacementPath = [resourceDirectoryName stringByAppendingPathComponent:fileName];
            EXPECT_TRUE([savedMainResource containsString:replacementPath]);
            NSString *resourceFilePath = [resourceDirectoryPath stringByAppendingPathComponent:fileName];
            NSString* savedStyleResource = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:resourceFilePath] encoding:NSUTF8StringEncoding];
            NSRange range = [savedStyleResource rangeOfString:@"color: "];
            EXPECT_NE(NSNotFound, (long)range.location);
            NSString *styleResourceContent = [savedStyleResource substringWithRange:NSMakeRange(range.location, range.length + 4)];
            [styleResourceContentsToFind removeObject:styleResourceContent];
        }

        saved = true;
    }];
    Util::run(&saved);
}

static const char* htmlDataBytesForCSSImportRule = R"TESTRESOURCE(
<head>
<style>
@import url("style.css");
</style>
</head>
<div><p id="console">Hello</p></div>
<script>
img = null;
function onImageLoad() {
    img = null;
    window.webkit.messageHandlers.testHandler.postMessage("done");
}
document.styleSheets[0].cssRules[0].styleSheet.insertRule("p { color: fuchsia; }");
console = document.getElementById("console");
computedStyle = getComputedStyle(console);
var img = document.createElement("img");
img.src = "files/image.png";
img.onload = onImageLoad;
</script>
)TESTRESOURCE";

TEST(WebArchive, SaveResourcesCSSImportRule)
{
    RetainPtr<NSURL> directoryURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"SaveResourcesTest"] isDirectory:YES];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:directoryURL.get() error:nil];

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webarchivetest"];
    NSData *htmlData = [NSData dataWithBytes:htmlDataBytesForCSSImportRule length:strlen(htmlDataBytesForCSSImportRule)];
    NSData *cssData = [NSData dataWithBytes:cssDataBytesForLink length:strlen(cssDataBytesForLink)];
    NSData *imageData = [NSData dataWithContentsOfURL:[NSBundle.test_resourcesBundle URLForResource:@"400x400-green" withExtension:@"png"]];
    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        RetainPtr<NSData> data;
        NSString *mimeType = nil;
        if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/main.html"]) {
            mimeType = @"text/html";
            data = htmlData;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/files/image.png"]) {
            mimeType = @"image/png";
            data = imageData;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/style.css"]) {
            mimeType = @"text/css";
            data = cssData;
        }

        auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:mimeType expectedContentLength:data.get().length textEncodingName:nil]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:data.get()];
        [task didFinish];
    }];

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    static bool messageReceived = false;
    [webView performAfterReceivingMessage:@"done" action:[&] {
        messageReceived = true;
    }];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"webarchivetest://host/main.html"]]];
    Util::run(&messageReceived);

    static bool saved = false;
    [webView _saveResources:directoryURL.get() suggestedFileName:@"host" completionHandler:^(NSError *error) {
        EXPECT_NULL(error);
        NSString *mainResourcePath = [directoryURL URLByAppendingPathComponent:@"host.html"].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:mainResourcePath]);
        NSString *savedMainResource = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:mainResourcePath] encoding:NSUTF8StringEncoding];

        NSString *resourceDirectoryName = @"host_files";
        NSString *resourceDirectoryPath =[directoryURL URLByAppendingPathComponent:resourceDirectoryName].path;
        NSArray *resourceFileNames = [fileManager contentsOfDirectoryAtPath:resourceDirectoryPath error:nil];
        NSSet *savedFileNames = [NSSet setWithArray:resourceFileNames];
        NSSet *expectedFileNames = [NSSet setWithArray:[NSArray arrayWithObjects:@"image.png", @"style.css", nil]];
        EXPECT_TRUE([savedFileNames isEqualToSet:expectedFileNames]);

        NSString *styleResourceFileName = [resourceDirectoryName stringByAppendingPathComponent:@"style.css"];
        EXPECT_TRUE([savedMainResource containsString:styleResourceFileName]);
        NSString *styleResourceFilePath = [resourceDirectoryPath stringByAppendingPathComponent:@"style.css"];
        NSString *savedStyleResource = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:styleResourceFilePath] encoding:NSUTF8StringEncoding];
        EXPECT_TRUE([savedStyleResource containsString:@"url(\"image.png\")"]);
        EXPECT_TRUE([savedStyleResource containsString:@"color: fuchsia"]);

        saved = true;
    }];
    Util::run(&saved);
}

static const char* htmlDataBytesForCSSSupportsRule = R"TESTRESOURCE(
<head>
<style>
@supports (background-image: url()) {
    div {
        background-image: url("image.png");
    }
}
</style>
</head>
<div>Hello</div>
<script>
img = null;
function onImageLoad() {
    img = null;
    window.webkit.messageHandlers.testHandler.postMessage("done");
}
var img = document.createElement("img");
img.src = "image.png";
img.onload = onImageLoad;
</script>
)TESTRESOURCE";

TEST(WebArchive, SaveResourcesCSSSupportsRule)
{
    RetainPtr<NSURL> directoryURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"SaveResourcesTest"] isDirectory:YES];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:directoryURL.get() error:nil];

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webarchivetest"];
    NSData *htmlData = [NSData dataWithBytes:htmlDataBytesForCSSSupportsRule length:strlen(htmlDataBytesForCSSSupportsRule)];
    NSData *imageData = [NSData dataWithContentsOfURL:[NSBundle.test_resourcesBundle URLForResource:@"400x400-green" withExtension:@"png"]];
    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        RetainPtr<NSData> data;
        NSString *mimeType = nil;
        if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/main.html"]) {
            mimeType = @"text/html";
            data = htmlData;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/image.png"]) {
            mimeType = @"image/png";
            data = imageData;
        }

        auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:mimeType expectedContentLength:data.get().length textEncodingName:nil]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:data.get()];
        [task didFinish];
    }];

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    static bool messageReceived = false;
    [webView performAfterReceivingMessage:@"done" action:[&] {
        messageReceived = true;
    }];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"webarchivetest://host/main.html"]]];
    Util::run(&messageReceived);

    static bool saved = false;
    [webView _saveResources:directoryURL.get() suggestedFileName:@"host" completionHandler:^(NSError *error) {
        EXPECT_NULL(error);
        NSString *mainResourcePath = [directoryURL URLByAppendingPathComponent:@"host.html"].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:mainResourcePath]);

        NSString *savedMainResource = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:mainResourcePath] encoding:NSUTF8StringEncoding];
        NSString *imageFile = @"image.png";
        NSString *resourceDirectoryName = @"host_files";
        NSString *imageResouceRelativePath = [resourceDirectoryName stringByAppendingPathComponent:imageFile];
        EXPECT_TRUE([savedMainResource containsString:imageResouceRelativePath]);

        NSString *imageResourcePath = [directoryURL URLByAppendingPathComponent:imageResouceRelativePath].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:imageResourcePath]);

        saved = true;
    }];
    Util::run(&saved);
}

static const char* htmlDataBytesForCSSMediaRule = R"TESTRESOURCE(
<head>
<style>
@media (min-width: 1px) {
    div {
        background-image: url("image.png");
    }
}
</style>
</head>
<div>Hello</div>
<script>
img = null;
function onImageLoad() {
    img = null;
    window.webkit.messageHandlers.testHandler.postMessage("done");
}
var img = document.createElement("img");
img.src = "image.png";
img.onload = onImageLoad;
</script>
)TESTRESOURCE";

TEST(WebArchive, SaveResourcesCSSMediaRule)
{
    RetainPtr<NSURL> directoryURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"SaveResourcesTest"] isDirectory:YES];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:directoryURL.get() error:nil];

    RetainPtr configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    RetainPtr schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webarchivetest"];
    RetainPtr htmlData = [NSData dataWithBytes:htmlDataBytesForCSSMediaRule length:strlen(htmlDataBytesForCSSMediaRule)];
    RetainPtr imageData = [NSData dataWithContentsOfURL:[NSBundle.test_resourcesBundle URLForResource:@"400x400-green" withExtension:@"png"]];
    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        NSData *data = nil;
        NSString *mimeType = nil;
        if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/main.html"]) {
            mimeType = @"text/html";
            data = htmlData.get();
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/image.png"]) {
            mimeType = @"image/png";
            data = imageData.get();
        }

        auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:mimeType expectedContentLength:data.length textEncodingName:nil]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:data];
        [task didFinish];
    }];

    RetainPtr webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    static bool messageReceived = false;
    [webView performAfterReceivingMessage:@"done" action:[&] {
        messageReceived = true;
    }];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"webarchivetest://host/main.html"]]];
    Util::run(&messageReceived);

    static bool saved = false;
    [webView _saveResources:directoryURL.get() suggestedFileName:@"host" completionHandler:^(NSError *error) {
        EXPECT_NULL(error);
        NSString *mainResourcePath = [directoryURL URLByAppendingPathComponent:@"host.html"].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:mainResourcePath]);

        NSString *savedMainResource = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:mainResourcePath] encoding:NSUTF8StringEncoding];
        NSString *imageFile = @"image.png";
        NSString *resourceDirectoryName = @"host_files";
        NSString *imageResouceRelativePath = [resourceDirectoryName stringByAppendingPathComponent:imageFile];
        EXPECT_TRUE([savedMainResource containsString:imageResouceRelativePath]);

        NSString *imageResourcePath = [directoryURL URLByAppendingPathComponent:imageResouceRelativePath].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:imageResourcePath]);

        saved = true;
    }];
    Util::run(&saved);
}

static const char* htmlDataBytesForCrossOriginLink = R"TESTRESOURCE(
<head>
<link href="webarchivetest://resource.com/style.css" rel="stylesheet">
</head>
<div id="console">Hello</div>
<script>
console = document.getElementById("console");
computedStyle = getComputedStyle(console);
window.webkit.messageHandlers.testHandler.postMessage("done");
</script>
)TESTRESOURCE";
static const char* cssDataBytesForCrossOriginLink = R"TESTRESOURCE(
div {
    height: 50%;
    width: 50%;
}
)TESTRESOURCE";

TEST(WebArchive, SaveResourcesCrossOriginLink)
{
    RetainPtr<NSURL> directoryURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"SaveResourcesTest"] isDirectory:YES];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:directoryURL.get() error:nil];

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webarchivetest"];
    NSData *htmlData = [NSData dataWithBytes:htmlDataBytesForCrossOriginLink length:strlen(htmlDataBytesForCrossOriginLink)];
    NSData *cssData = [NSData dataWithBytes:cssDataBytesForCrossOriginLink length:strlen(cssDataBytesForCrossOriginLink)];
    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        RetainPtr<NSData> data;
        NSString *mimeType = nil;
        if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host.com/main.html"]) {
            mimeType = @"text/html";
            data = htmlData;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://resource.com/style.css"]) {
            mimeType = @"text/css";
            data = cssData;
        }

        auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:mimeType expectedContentLength:data.get().length textEncodingName:nil]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:data.get()];
        [task didFinish];
    }];

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    static bool messageReceived = false;
    [webView performAfterReceivingMessage:@"done" action:[&] {
        messageReceived = true;
    }];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"webarchivetest://host.com/main.html"]]];
    Util::run(&messageReceived);

    static bool saved = false;
    [webView _saveResources:directoryURL.get() suggestedFileName:@"host" completionHandler:^(NSError *error) {
        EXPECT_NULL(error);
        NSString *mainResourcePath = [directoryURL URLByAppendingPathComponent:@"host.html"].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:mainResourcePath]);

        NSString *savedMainResource = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:mainResourcePath] encoding:NSUTF8StringEncoding];
        NSString *cssFile = @"style.css";
        NSString *resourceDirectoryName = @"host_files";
        NSString *cssResourceRelativePath = [resourceDirectoryName stringByAppendingPathComponent:cssFile];
        EXPECT_TRUE([savedMainResource containsString:cssResourceRelativePath]);

        NSString *cssResourcePath = [directoryURL URLByAppendingPathComponent:cssResourceRelativePath].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:cssResourcePath]);

        saved = true;
    }];
    Util::run(&saved);
}

static const char* htmlDataBytesForExcludeBaseElement = R"TESTRESOURCE(
<head>
<base href="webarchivetest://resource.com" target="_blank">
</head>
<img src="image.png" onload="onImageLoad()">
<a href="/link">Open Link</a>
<script>
function onImageLoad() {
    window.webkit.messageHandlers.testHandler.postMessage("done");
}
</script>
)TESTRESOURCE";

TEST(WebArchive, SaveResourcesExcludeBaseElement)
{
    RetainPtr<NSURL> directoryURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"SaveResourcesTest"] isDirectory:YES];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:directoryURL.get() error:nil];

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webarchivetest"];
    NSData *htmlData = [NSData dataWithBytes:htmlDataBytesForExcludeBaseElement length:strlen(htmlDataBytesForExcludeBaseElement)];
    NSData *imageData = [NSData dataWithContentsOfURL:[NSBundle.test_resourcesBundle URLForResource:@"400x400-green" withExtension:@"png"]];
    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        RetainPtr<NSData> data;
        NSString *mimeType = nil;
        if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host.com/main.html"]) {
            mimeType = @"text/html";
            data = htmlData;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://resource.com/image.png"]) {
            mimeType = @"image/png";
            data = imageData;
        }

        auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:mimeType expectedContentLength:data.get().length textEncodingName:nil]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:data.get()];
        [task didFinish];
    }];

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    static bool messageReceived = false;
    [webView performAfterReceivingMessage:@"done" action:[&] {
        messageReceived = true;
    }];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"webarchivetest://host.com/main.html"]]];
    Util::run(&messageReceived);

    static bool saved = false;
    [webView _saveResources:directoryURL.get() suggestedFileName:@"host" completionHandler:^(NSError *error) {
        EXPECT_NULL(error);
        NSString *mainResourcePath = [directoryURL URLByAppendingPathComponent:@"host.html"].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:mainResourcePath]);

        NSString *savedMainResource = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:mainResourcePath] encoding:NSUTF8StringEncoding];
        NSString *imageFile = @"image.png";
        NSString *resourceDirectoryName = @"host_files";
        NSString *imageResourceRelativePath = [resourceDirectoryName stringByAppendingPathComponent:imageFile];
        EXPECT_TRUE([savedMainResource containsString:imageResourceRelativePath]);
        EXPECT_FALSE([savedMainResource containsString:@"base"]);
        // The anchor element's url should be resolved.
        EXPECT_TRUE([savedMainResource containsString:@"webarchivetest://resource.com/link"]);

        NSString *imageResourcePath = [directoryURL URLByAppendingPathComponent:imageResourceRelativePath].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:imageResourcePath]);

        saved = true;
    }];
    Util::run(&saved);
}

static const char* htmlDataBytesForExclusionRules = R"TESTRESOURCE(
<a href="foo.html" target="_blank">Blank</a>
<a href="#bar" target="_self">Self</a>
<textarea disabled hidden>Text</textarea>
<button disabled>Button</button>
<script>
window.webkit.messageHandlers.testHandler.postMessage("done");
</script>
)TESTRESOURCE";

TEST(WebArchive, SaveResourcesExclusionRules)
{
    RetainPtr<NSURL> directoryURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"SaveResourcesTest"] isDirectory:YES];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:directoryURL.get() error:nil];

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webarchivetest"];
    NSData *htmlData = [NSData dataWithBytes:htmlDataBytesForExclusionRules length:strlen(htmlDataBytesForExclusionRules)];
    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        RetainPtr<NSData> data;
        NSString *mimeType = nil;
        if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/main.html"]) {
            mimeType = @"text/html";
            data = htmlData;
        }

        EXPECT_TRUE(data.get());
        auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:mimeType expectedContentLength:data.get().length textEncodingName:nil]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:data.get()];
        [task didFinish];
    }];

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    static bool messageReceived = false;
    [webView performAfterReceivingMessage:@"done" action:[&] {
        messageReceived = true;
    }];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"webarchivetest://host/main.html"]]];
    Util::run(&messageReceived);

    static bool saved = false;
    RetainPtr<_WKArchiveConfiguration> archiveConfiguration = adoptNS([[_WKArchiveConfiguration alloc] init]);
    archiveConfiguration.get().directory = directoryURL.get();
    archiveConfiguration.get().suggestedFileName = @"host";
    archiveConfiguration.get().exclusionRules = @[
        adoptNS([[_WKArchiveExclusionRule alloc] initWithElementLocalName:@"script" attributeLocalNames:nil attributeValues:nil]).get(),
        adoptNS([[_WKArchiveExclusionRule alloc] initWithElementLocalName:nil attributeLocalNames:@[@"disabled", @"hidden"] attributeValues:@[@"", @""]]).get(),
        adoptNS([[_WKArchiveExclusionRule alloc] initWithElementLocalName:@"a" attributeLocalNames:@[@"target"] attributeValues:@[@"_blank"]]).get(),
    ];
    [webView _archiveWithConfiguration:archiveConfiguration.get() completionHandler:^(NSError *error) {
        EXPECT_NULL(error);
        NSString *mainResourcePath = [directoryURL URLByAppendingPathComponent:@"host.html"].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:mainResourcePath]);

        NSString *savedMainResource = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:mainResourcePath] encoding:NSUTF8StringEncoding];
        EXPECT_FALSE([savedMainResource containsString:@"script"]);
        EXPECT_FALSE([savedMainResource containsString:@"hidden"]);
        EXPECT_FALSE([savedMainResource containsString:@"target=\"_blank\""]);
        saved = true;
    }];
    Util::run(&saved);
}

static const char* htmlDataBytesForExcludeCrossOriginAttribute = R"TESTRESOURCE(
<head>
<link href="webarchivetest://resource.com/style.css" rel="stylesheet" crossorigin="anonymous">
</head>
<div id="console"></div>
<script src="webarchivetest://resource.com/script.js" integrity="sha256-whXcIuErT+KLyiIBuDxrli97oBljDS1fLlyogfljnnM=" crossorigin="anonymous"></script>
<script>
div = document.getElementById("console");
div.innerHTML += getComputedStyle(div).width;
window.webkit.messageHandlers.testHandler.postMessage("done");
</script>
)TESTRESOURCE";

static const char* scriptDataBytesForExcludeCrossOriginAttribute = R"TESTRESOURCE(document.getElementById("console").innerHTML = "ScriptRuns";)TESTRESOURCE";
static const char* cssDataBytesForExcludeCrossOriginAttribute = R"TESTRESOURCE(div { width: 10px; })TESTRESOURCE";

TEST(WebArchive, SaveResourcesExcludeCrossOriginAttribute)
{
    RetainPtr<NSURL> directoryURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"SaveResourcesTest"] isDirectory:YES];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:directoryURL.get() error:nil];

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webarchivetest"];
    NSData *htmlData = [NSData dataWithBytes:htmlDataBytesForExcludeCrossOriginAttribute length:strlen(htmlDataBytesForExcludeCrossOriginAttribute)];
    NSData *scriptData = [NSData dataWithBytes:scriptDataBytesForExcludeCrossOriginAttribute length:strlen(scriptDataBytesForExcludeCrossOriginAttribute)];
    NSData *cssData = [NSData dataWithBytes:cssDataBytesForExcludeCrossOriginAttribute length:strlen(cssDataBytesForExcludeCrossOriginAttribute)];
    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        RetainPtr<NSData> data;
        NSString *mimeType = nil;
        bool shouldAddAccessControlHeader = false;
        if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/main.html"]) {
            mimeType = @"text/html";
            data = htmlData;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://resource.com/script.js"]) {
            mimeType = @"application/javascript";
            data = scriptData;
            shouldAddAccessControlHeader = true;
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://resource.com/style.css"]) {
            mimeType = @"text/css";
            data = cssData;
            shouldAddAccessControlHeader = true;
        }
        EXPECT_TRUE(data.get());

        RetainPtr<NSMutableDictionary> headerFields = adoptNS(@{
            @"Content-Length": [NSString stringWithFormat:@"%zu", (size_t)data.get().length],
            @"Content-Type": mimeType,
        }.mutableCopy);
        if (shouldAddAccessControlHeader)
            [headerFields setObject:@"*" forKey:@"Access-Control-Allow-Origin"];

        auto response = adoptNS([[NSHTTPURLResponse alloc] initWithURL:task.request.URL statusCode:200 HTTPVersion:nil headerFields:headerFields.get()]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:data.get()];
        [task didFinish];
    }];

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    static bool messageReceived = false;
    [webView performAfterReceivingMessage:@"done" action:[&] {
        messageReceived = true;
    }];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"webarchivetest://host/main.html"]]];
    Util::run(&messageReceived);

    static bool saved = false;
    [webView _saveResources:directoryURL.get() suggestedFileName:@"host" completionHandler:^(NSError *error) {
        EXPECT_NULL(error);
        NSString *mainResourcePath = [directoryURL URLByAppendingPathComponent:@"host.html"].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:mainResourcePath]);

        NSString *savedMainResource = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:mainResourcePath] encoding:NSUTF8StringEncoding];
        EXPECT_TRUE([savedMainResource containsString:@"ScriptRuns"]);
        EXPECT_TRUE([savedMainResource containsString:@"10px"]);
        EXPECT_FALSE([savedMainResource containsString:@"integrity"]);
        EXPECT_FALSE([savedMainResource containsString:@"crossorigin"]);

        NSString *resourceDirectoryName = @"host_files";
        NSString *scriptFile = @"script.js";
        NSString *scriptResourceRelativePath = [resourceDirectoryName stringByAppendingPathComponent:scriptFile];
        EXPECT_TRUE([savedMainResource containsString:scriptResourceRelativePath]);
        NSString *scriptResourcePath = [directoryURL URLByAppendingPathComponent:scriptResourceRelativePath].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:scriptResourcePath]);

        NSString *cssFile = @"style.css";
        NSString *cssResourceRelativePath = [resourceDirectoryName stringByAppendingPathComponent:cssFile];
        EXPECT_TRUE([savedMainResource containsString:cssResourceRelativePath]);
        NSString *cssResourcePath = [directoryURL URLByAppendingPathComponent:scriptResourceRelativePath].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:cssResourcePath]);

        saved = true;
    }];
    Util::run(&saved);
}

static const char* htmlDataBytesForUnsavedSubresources = R"TESTRESOURCE(
<style>
@font-face {
    font-family: "WebFont";
    src: url("Ahem-10000A.ttf") format("truetype"), url("Ahem-10000A-backup.ttf") format("truetype")
}
div {
    width: 100%;
    font-family: "WebFont";
}
</style>
<div id="div">Hello</div>
<script>
    div = document.getElementById("div");
    computedFontFamily = getComputedStyle(div).getPropertyValue("font-family");
    document.fonts.ready.then(() => { window.webkit.messageHandlers.testHandler.postMessage("done"); });
</script>
)TESTRESOURCE";

TEST(WebArchive, SaveResourcesStyleWithUnloadedResources)
{
    RetainPtr directoryURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"SaveResourcesTest"] isDirectory:YES];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:directoryURL.get() error:nil];

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webarchivetest"];
    RetainPtr htmlData = [NSData dataWithBytes:htmlDataBytesForUnsavedSubresources length:strlen(htmlDataBytesForUnsavedSubresources)];
    RetainPtr fontData = [NSData dataWithContentsOfURL:[NSBundle.test_resourcesBundle URLForResource:@"Ahem-10000A" withExtension:@"ttf"]];
    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        NSData *data = nil;
        NSString *mimeType = nil;
        if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/main.html"]) {
            mimeType = @"text/html";
            data = htmlData.get();
        } else if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/Ahem-10000A.ttf"]) {
            mimeType = @"font/ttf";
            data = fontData.get();
        }
        RetainPtr response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:mimeType expectedContentLength:data.length textEncodingName:nil]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:data];
        [task didFinish];
    }];

    RetainPtr webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    static bool messageReceived = false;
    [webView performAfterReceivingMessage:@"done" action:[&] {
        messageReceived = true;
    }];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"webarchivetest://host/main.html"]]];
    Util::run(&messageReceived);

    static bool saved = false;
    [webView _saveResources:directoryURL.get() suggestedFileName:@"host" completionHandler:^(NSError *error) {
        EXPECT_NULL(error);
        NSString *mainResourcePath = [directoryURL URLByAppendingPathComponent:@"host.html"].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:mainResourcePath]);

        NSString *savedMainResource = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:mainResourcePath] encoding:NSUTF8StringEncoding];
        EXPECT_TRUE([savedMainResource containsString:@"host_files/Ahem-10000A.ttf"]);
        EXPECT_FALSE([savedMainResource containsString:@"host_files/Ahem-10000A-backup.ttf"]);
        EXPECT_TRUE([savedMainResource containsString:@"webarchivetest://host/Ahem-10000A-backup.ttf"]);

        saved = true;
    }];
    Util::run(&saved);
}

static const char* htmlDataBytesForUTF8Encoding = R"TESTRESOURCE(
<head>
<meta http-equiv="content-type" content="text/html; charset=Windows-1252">
<script>
function loaded() {
    window.webkit.messageHandlers.testHandler.postMessage("done");
}
</script>
</head>
<body onload="loaded()">
Hello World!
</body>
)TESTRESOURCE";

TEST(WebArchive, SaveResourcesWithUTF8Encoding)
{
    RetainPtr<NSURL> directoryURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"SaveResourcesTest"] isDirectory:YES];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:directoryURL.get() error:nil];

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webarchivetest"];
    NSData *htmlData = [NSData dataWithBytes:htmlDataBytesForUTF8Encoding length:strlen(htmlDataBytesForUTF8Encoding)];
    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        RetainPtr<NSData> data;
        NSString *mimeType = nil;
        if ([task.request.URL.absoluteString isEqualToString:@"webarchivetest://host/main.html"]) {
            mimeType = @"text/html";
            data = htmlData;
        }
        EXPECT_TRUE(data.get());

        RetainPtr response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:mimeType expectedContentLength:data.get().length textEncodingName:nil]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:data.get()];
        [task didFinish];
    }];

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    static bool messageReceived = false;
    [webView performAfterReceivingMessage:@"done" action:[&] {
        messageReceived = true;
    }];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"webarchivetest://host/main.html"]]];
    Util::run(&messageReceived);

    static bool saved = false;
    [webView _saveResources:directoryURL.get() suggestedFileName:@"host" completionHandler:^(NSError *error) {
        EXPECT_NULL(error);
        NSString *mainResourcePath = [directoryURL URLByAppendingPathComponent:@"host.html"].path;
        EXPECT_TRUE([fileManager fileExistsAtPath:mainResourcePath]);

        NSString *savedMainResource = [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:mainResourcePath] encoding:NSUTF8StringEncoding];
        EXPECT_TRUE([savedMainResource containsString:@"<meta charset=\"UTF-8\">"]);
        saved = true;
    }];
    Util::run(&saved);
}

} // namespace TestWebKitAPI

#endif // PLATFORM(MAC) || PLATFORM(IOS_FAMILY)
