Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 9ec7007ca6e9833edb89decb0b9293c69197c906
      
https://github.com/WebKit/WebKit/commit/9ec7007ca6e9833edb89decb0b9293c69197c906
  Author: Wenson Hsieh <[email protected]>
  Date:   2023-10-12 (Thu, 12 Oct 2023)

  Changed paths:
    M Source/WebCore/editing/cocoa/AttributedString.h
    M Source/WebCore/editing/cocoa/AttributedString.mm
    M Source/WebKit/Shared/Cocoa/WebCoreArgumentCodersCocoa.serialization.in
    M Source/WebKit/Shared/WTFArgumentCoders.serialization.in
    M Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewGetContents.mm

  Log Message:
  -----------
  REGRESSION (266700@main): Copying a table from Mail to Numbers results in 
visibly broken content
https://bugs.webkit.org/show_bug.cgi?id=263071
rdar://116785572

Reviewed by Aditya Keerthi.

After the changes in 266700@main, copying tables in webpages and pasting into 
Numbers (which reads
RTF data from the pasteboard and converts to `NSAttributedString`) causes cells 
to be erroneously
merged, in the case where a cell (represented by `NSTextTableBlock`) consists 
of 2 or more
attributed string subranges.

This happens because, in the process of converting from `NSAttributedString` ->
`WebCore::AttributedString` -> `NSAttributedString` under 
`Editor::writeSelectionToPasteboard`, we
lose the fact that multiple paragraph styles can end up referencing not only 
the same `NSTextTable`
object, but the same `NSTextTableBlock` object; Pages relies on this in order 
to properly map text
to the correct table cell. While the changes in 266700@main preserve 
`NSTextTable` and `NSTextList`
identity upon serialization/deserialization of the attributed string via lists 
of identifiers,
there's no attempt to preserve `NSTextTableBlock` identity. This means that two 
pieces of text that
reference the same block:

```
"foo" => {
   "NSParagraphStyle" => {
       textBlocks => [ NSTextTableBlock(0x14233c360, table=<NSTextTable 
0x1423319e0>, {0, 1}) ],
   }
}

"bar" => {
   "NSParagraphStyle" => {
       textBlocks => [ NSTextTableBlock(0x14233c360, table=<NSTextTable 
0x1423319e0>, {0, 1}) ],
   }
}
```

...will reference different blocks after serialization:

```
"foo" => {
   "NSParagraphStyle" => {
       textBlocks => [ NSTextTableBlock(0x127686a00, table=<NSTextTable 
0x12761a060>, {0, 1}) ],
   }
}

"bar" => {
   "NSParagraphStyle" => {
       textBlocks => [ NSTextTableBlock(0x127693ff0, table=<NSTextTable 
0x12761a060>, {0, 1}) ],
   }
}
```

To fix this, we augment the existing table ID lists to include table block IDs 
as well, and use this
information upon deserialization to preserve text table block identity in the 
deserialized
attributed string.

* Source/WebCore/editing/cocoa/AttributedString.h:
* Source/WebCore/editing/cocoa/AttributedString.mm:
(WebCore::reconstructStyle):

Add support for plumbing a list of table block IDs along with table IDs; use 
this information to
ensure that two paragraph styles that pointed to the same `NSTextTableBlock` 
before serialization
will continue to point to the same `NSTextTableBlock` after deserialization.

(WebCore::toNSObject):
(WebCore::toNSDictionary):
(WebCore::AttributedString::documentAttributesAsNSDictionary const):
(WebCore::AttributedString::nsAttributedString const):
(WebCore::extractTableBlockAndTableIDs):
(WebCore::extractValue):
(WebCore::extractDictionary):
(WebCore::AttributedString::fromNSAttributedStringAndDocumentAttributes):
(WebCore::extractTableIDs): Deleted.
* Source/WebKit/Shared/Cocoa/WebCoreArgumentCodersCocoa.serialization.in:
* Source/WebKit/Shared/WTFArgumentCoders.serialization.in:
* Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewGetContents.mm:

Add an API test to exercise the fix.

Canonical link: https://commits.webkit.org/269265@main


_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to