[webkit-changes] [WebKit/WebKit] 9ec700: REGRESSION (266700 at main): Copying a table from Mai...

Wenson Hsieh noreply at github.com
Thu Oct 12 12:01:57 PDT 2023


  Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 9ec7007ca6e9833edb89decb0b9293c69197c906
      https://github.com/WebKit/WebKit/commit/9ec7007ca6e9833edb89decb0b9293c69197c906
  Author: Wenson Hsieh <wenson_hsieh at apple.com>
  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 at 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 at 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 at 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




More information about the webkit-changes mailing list