Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Unified Text Replacement] willBeginTextReplacementSession sometimes does not return a context if the text lengths differ #28722

Merged
merged 1 commit into from
May 20, 2024

Conversation

rr-codes
Copy link
Contributor

@rr-codes rr-codes commented May 17, 2024

90bbdbb

[Unified Text Replacement] `willBeginTextReplacementSession` sometimes does not return a context if the text lengths differ
https://bugs.webkit.org/show_bug.cgi?id=274325
rdar://128285414

Reviewed by Aditya Keerthi.

The length of the string produced by `editingAttributedString` and the character count produced by
`TextIterator` can sometimes differ. This can happen when there are images in the HTML, as `editingAttributedString`
handles them in a special case.

Fix by adding a new `TextIteratorBehavior` option that acts the same as `EmitsObjectReplacementCharacters`,
but only for images, and then use this behavior anywhere in UnifiedTextReplacementController that
needs character ranges or counts.

Also fix a few issues with attachments in attributed strings:

* When converting an `AttributedString` to an `NSAttributedString` with an attachment, if the attachment
does not have a "preferred" filename, an empty file wrapper will be created. Fix by always creating a file
wrapper.

* When converting HTML with an image to an attributed string, the position of the resulting attachment in
the produced attributed string is sometimes incorrect. This is because the length of the attachment itself
is never taken into account, and so consequent parts of the string will be inserted in too early of a position.
Fix by accounting for the length of the attachment.

* Source/WebCore/editing/TextIterator.cpp:
(WebCore::TextIterator::TextIterator):
(WebCore::TextIterator::handleReplacedElement):
* Source/WebCore/editing/TextIteratorBehavior.h:
* Source/WebCore/editing/cocoa/AttributedString.mm:
(WebCore::toNSObject):
* Source/WebCore/editing/cocoa/HTMLConverter.mm:
(WebCore::editingAttributedString):
* Source/WebKit/WebProcess/WebPage/Cocoa/UnifiedTextReplacementController.mm:
(WebKit::UnifiedTextReplacementController::characterRange):
(WebKit::UnifiedTextReplacementController::characterCount):
(WebKit::UnifiedTextReplacementController::resolveCharacterRange):
(WebKit::UnifiedTextReplacementController::plainText):
(WebKit::UnifiedTextReplacementController::willBeginTextReplacementSession):
(WebKit::UnifiedTextReplacementController::textReplacementSessionDidReceiveReplacements):
(WebKit::UnifiedTextReplacementController::textReplacementSessionDidReceiveTextWithReplacementRange):
(WebKit::UnifiedTextReplacementController::textReplacementSessionPerformEditActionForPlainText):
(WebKit::UnifiedTextReplacementController::contextRangeForSessionOrRangeWithUUID const):
(WebKit::UnifiedTextReplacementController::replaceContentsOfRangeInSessionInternal):
* Source/WebKit/WebProcess/WebPage/UnifiedTextReplacementController.h:

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

5c4632a

Misc iOS, tvOS & watchOS macOS Linux Windows
βœ… πŸ§ͺ style βœ… πŸ›  ios βœ… πŸ›  mac βœ… πŸ›  wpe βœ… πŸ›  wincairo
βœ… πŸ§ͺ bindings βœ… πŸ›  ios-sim βœ… πŸ›  mac-AS-debug βœ… πŸ§ͺ wpe-wk2 βœ… πŸ§ͺ wincairo-tests
βœ… πŸ§ͺ webkitperl βœ… πŸ§ͺ ios-wk2 βœ… πŸ§ͺ api-mac βœ… πŸ§ͺ api-wpe
βœ… πŸ§ͺ ios-wk2-wpt βœ… πŸ§ͺ mac-wk1 βœ… πŸ›  wpe-cairo
βœ… πŸ§ͺ api-ios βœ… πŸ§ͺ mac-wk2 βœ… πŸ›  gtk
βœ… πŸ›  tv βœ… πŸ§ͺ mac-AS-debug-wk2 βœ… πŸ§ͺ gtk-wk2
βœ… πŸ›  tv-sim βœ… πŸ§ͺ mac-wk2-stress βœ… πŸ§ͺ api-gtk
βœ… πŸ›  watch
βœ… πŸ›  πŸ§ͺ unsafe-merge βœ… πŸ›  watch-sim

@rr-codes rr-codes self-assigned this May 17, 2024
@rr-codes rr-codes added the HTML Editing For bugs in HTML editing support (including designMode and contentEditable). label May 17, 2024
[fileWrapper setPreferredFilename:filenameByFixingIllegalCharacters((NSString *)value.preferredFilename)];
}

auto textAttachment = adoptNS([[PlatformNSTextAttachment alloc] initWithFileWrapper:fileWrapper.get()]);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

intentionally added newlines for readability

if (RefPtr imageElement = dynamicDowncast<HTMLImageElement>(node); imageElement && includeImages == IncludeImages::Yes) {
RetainPtr attachmentAttributedString = attributedStringWithAttachmentForElement(*imageElement);
[string appendAttributedString:attachmentAttributedString.get()];
stringLength += [attachmentAttributedString length];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this compatible with:

auto currentTextLength = it.text().length();

and

[string setAttributes:attrs.get() range:NSMakeRange(stringLength, currentTextLength)]; below,

given that TextIterator it(range) does not have any additional behaviors specified?

Wouldn't it result in length mismatches?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it wasn't compatible before, but is now. This change doesn't actually affect the string lengths, just changes the position of where the text that comes after the attachment goes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(My tests also exercise this thoroughly)

@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label May 18, 2024
@rr-codes rr-codes removed the merging-blocked Applied to prevent a change from being merged label May 18, 2024
@rr-codes rr-codes added the unsafe-merge-queue Applied to send a pull request to merge-queue, but skip building and testing label May 20, 2024
…s does not return a context if the text lengths differ

https://bugs.webkit.org/show_bug.cgi?id=274325
rdar://128285414

Reviewed by Aditya Keerthi.

The length of the string produced by `editingAttributedString` and the character count produced by
`TextIterator` can sometimes differ. This can happen when there are images in the HTML, as `editingAttributedString`
handles them in a special case.

Fix by adding a new `TextIteratorBehavior` option that acts the same as `EmitsObjectReplacementCharacters`,
but only for images, and then use this behavior anywhere in UnifiedTextReplacementController that
needs character ranges or counts.

Also fix a few issues with attachments in attributed strings:

* When converting an `AttributedString` to an `NSAttributedString` with an attachment, if the attachment
does not have a "preferred" filename, an empty file wrapper will be created. Fix by always creating a file
wrapper.

* When converting HTML with an image to an attributed string, the position of the resulting attachment in
the produced attributed string is sometimes incorrect. This is because the length of the attachment itself
is never taken into account, and so consequent parts of the string will be inserted in too early of a position.
Fix by accounting for the length of the attachment.

* Source/WebCore/editing/TextIterator.cpp:
(WebCore::TextIterator::TextIterator):
(WebCore::TextIterator::handleReplacedElement):
* Source/WebCore/editing/TextIteratorBehavior.h:
* Source/WebCore/editing/cocoa/AttributedString.mm:
(WebCore::toNSObject):
* Source/WebCore/editing/cocoa/HTMLConverter.mm:
(WebCore::editingAttributedString):
* Source/WebKit/WebProcess/WebPage/Cocoa/UnifiedTextReplacementController.mm:
(WebKit::UnifiedTextReplacementController::characterRange):
(WebKit::UnifiedTextReplacementController::characterCount):
(WebKit::UnifiedTextReplacementController::resolveCharacterRange):
(WebKit::UnifiedTextReplacementController::plainText):
(WebKit::UnifiedTextReplacementController::willBeginTextReplacementSession):
(WebKit::UnifiedTextReplacementController::textReplacementSessionDidReceiveReplacements):
(WebKit::UnifiedTextReplacementController::textReplacementSessionDidReceiveTextWithReplacementRange):
(WebKit::UnifiedTextReplacementController::textReplacementSessionPerformEditActionForPlainText):
(WebKit::UnifiedTextReplacementController::contextRangeForSessionOrRangeWithUUID const):
(WebKit::UnifiedTextReplacementController::replaceContentsOfRangeInSessionInternal):
* Source/WebKit/WebProcess/WebPage/UnifiedTextReplacementController.h:

Canonical link: https://commits.webkit.org/279002@main
@webkit-commit-queue
Copy link
Collaborator

Committed 279002@main (90bbdbb): https://commits.webkit.org/279002@main

Reviewed commits have been landed. Closing PR #28722 and removing active labels.

@webkit-commit-queue webkit-commit-queue merged commit 90bbdbb into WebKit:main May 20, 2024
@webkit-commit-queue webkit-commit-queue removed the unsafe-merge-queue Applied to send a pull request to merge-queue, but skip building and testing label May 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
HTML Editing For bugs in HTML editing support (including designMode and contentEditable).
Projects
None yet
5 participants