Skip to content

Commit

Permalink
Serialize CSSMediaRule with URL replacement
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=271285
rdar://121207334

Reviewed by Ryosuke Niwa.

This patch fixes the issue that subresources URLs in CSSMediaRule are not rewritten when saving web page resources by
adding implementation for CSSMediaRule::cssTextWithReplacementURLs().

API test: WebArchive.SaveResourcesCSSMediaRule

* Source/WebCore/css/CSSMediaRule.cpp:
(WebCore::CSSMediaRule::cssTextWithReplacementURLs const):
* Source/WebCore/css/CSSMediaRule.h:
* Tools/TestWebKitAPI/Tests/WebKitCocoa/CreateWebArchive.mm:

Canonical link: https://commits.webkit.org/276387@main
  • Loading branch information
szewai committed Mar 20, 2024
1 parent 4ff86d0 commit 0881857
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 0 deletions.
8 changes: 8 additions & 0 deletions Source/WebCore/css/CSSMediaRule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ String CSSMediaRule::cssText() const
return builder.toString();
}

String CSSMediaRule::cssTextWithReplacementURLs(const HashMap<String, String>& replacementURLStrings, const HashMap<RefPtr<CSSStyleSheet>, String>& replacementURLStringsForCSSStyleSheet) const
{
StringBuilder builder;
builder.append("@media ", conditionText());
appendCSSTextWithReplacementURLsForItems(builder, replacementURLStrings, replacementURLStringsForCSSStyleSheet);
return builder.toString();
}

String CSSMediaRule::conditionText() const
{
StringBuilder builder;
Expand Down
1 change: 1 addition & 0 deletions Source/WebCore/css/CSSMediaRule.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class CSSMediaRule final : public CSSConditionRule {

StyleRuleType styleRuleType() const final { return StyleRuleType::Media; }
String cssText() const final;
String cssTextWithReplacementURLs(const HashMap<String, String>&, const HashMap<RefPtr<CSSStyleSheet>, String>&) const final;
String conditionText() const final;

const MQ::MediaQueryList& mediaQueries() const;
Expand Down
79 changes: 79 additions & 0 deletions Tools/TestWebKitAPI/Tests/WebKitCocoa/CreateWebArchive.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1706,6 +1706,85 @@ function onImageLoad() {
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 mainBundle] URLForResource:@"400x400-green" withExtension:@"png" subdirectory:@"TestWebKitAPI.resources"]];
[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">
Expand Down

0 comments on commit 0881857

Please sign in to comment.