Skip to content

Commit

Permalink
Pasting a web archive drops <picture> when wrapped in a <span>
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=274062
rdar://127319160

Reviewed by Richard Robinson and Abrar Rahman Protyasha.

Pasting a web archive results in markup simplification being performed in
`SimplifyMarkupCommand`, via `ReplaceSelectionCommand`.

However, the logic for simplifying markup is incorrect. It currently
treats all inline elements that have the same style as equivalent. Then,
equivalent elements are removed bottom-up. This means that a `<picture>`
inside a `<span>` will be removed, as `<picture>` is an inline element,
with no custom style. Removing `<picture>` is incorrect, as it can affect the
rendered content due to source selection.

Fix by excluding `<picture>` from markup simplification. A better solution
would be to eliminate the `<span>` rather than the `<picture>`. However, that
approach requires a complete rewrite of the markup simplification algorithm.

* Source/WebCore/editing/SimplifyMarkupCommand.cpp:
(WebCore::SimplifyMarkupCommand::doApply):
* Tools/TestWebKitAPI/Tests/WebKitCocoa/PasteWebArchive.mm:
(TEST(PasteWebArchive, PreservesPictureInsideSpan)):

Canonical link: https://commits.webkit.org/278714@main
  • Loading branch information
pxlcoder committed May 13, 2024
1 parent 1cabcaf commit efc8e7c
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 0 deletions.
6 changes: 6 additions & 0 deletions Source/WebCore/editing/SimplifyMarkupCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ void SimplifyMarkupCommand::doApply()
RefPtr currentNode = startingNode;
RefPtr<Node> topNodeWithStartingStyle;
while (currentNode != rootNode) {
// FIXME: The simplification algorithm should be rewritten to eliminate redundant
// parents in cases where the children affect rendered content, as observed with
// <span><picture></picture></span>.
if (currentNode->hasTagName(HTMLNames::pictureTag))
break;

if (currentNode->parentNode() != rootNode && isRemovableBlock(currentNode.get()))
nodesToRemove.append(*currentNode);

Expand Down
27 changes: 27 additions & 0 deletions Tools/TestWebKitAPI/Tests/WebKitCocoa/PasteWebArchive.mm
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,33 @@ - (void)paste:(id)sender;
EXPECT_WK_STREQ("rgb(255, 0, 0)", [webView stringByEvaluatingJavaScript:@"document.queryCommandValue('foreColor')"]);
}

TEST(PasteWebArchive, PreservesPictureInsideSpan)
{
NSData *markupData = [@"<span class='s1'><picture><source srcset='1.png' type='image/png'><img src='2.gif'></picture></span>" dataUsingEncoding:NSUTF8StringEncoding];

auto mainResource = adoptNS([[WebResource alloc] initWithData:markupData URL:[NSURL URLWithString:@"foo.html"] MIMEType:@"text/html" textEncodingName:@"utf-8" frameName:nil]);

auto pngData = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"icon" withExtension:@"png" subdirectory:@"TestWebKitAPI.resources"]];
auto pngResource = adoptNS([[WebResource alloc] initWithData:pngData URL:[NSURL URLWithString:@"1.png"] MIMEType:@"image/png" textEncodingName:nil frameName:nil]);

auto gifData = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"apple" withExtension:@"gif" subdirectory:@"TestWebKitAPI.resources"]];
auto gifResource = adoptNS([[WebResource alloc] initWithData:gifData URL:[NSURL URLWithString:@"2.gif"] MIMEType:@"image/gif" textEncodingName:nil frameName:nil]);

auto archive = adoptNS([[WebArchive alloc] initWithMainResource:mainResource.get() subresources:@[ pngResource.get(), gifResource.get() ] subframeArchives:@[ ]]);

[[NSPasteboard generalPasteboard] declareTypes:@[WebArchivePboardType] owner:nil];
[[NSPasteboard generalPasteboard] setData:[archive data] forType:WebArchivePboardType];

auto webView = createWebViewWithCustomPasteboardDataEnabled();
[webView synchronouslyLoadTestPageNamed:@"paste-rtfd"];
[webView paste:nil];

EXPECT_WK_STREQ("SPAN", [webView stringByEvaluatingJavaScript:@"editor.children[0].tagName"]);
EXPECT_WK_STREQ("PICTURE", [webView stringByEvaluatingJavaScript:@"editor.children[0].children[0].tagName"]);
EXPECT_WK_STREQ("SOURCE", [webView stringByEvaluatingJavaScript:@"editor.children[0].children[0].children[0].tagName"]);
EXPECT_WK_STREQ("IMG", [webView stringByEvaluatingJavaScript:@"editor.children[0].children[0].children[1].tagName"]);
}

TEST(PasteWebArchive, WebArchiveTypeIdentifier)
{
NSURL *url = [NSURL URLWithString:@"file:///some-file.html"];
Expand Down

0 comments on commit efc8e7c

Please sign in to comment.