Bug 203286 - Add a mechanism to find and manipulate text by paragraphs
Summary: Add a mechanism to find and manipulate text by paragraphs
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: HTML Editing (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Ryosuke Niwa
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2019-10-22 23:01 PDT by Ryosuke Niwa
Modified: 2019-10-24 17:08 PDT (History)
18 users (show)

See Also:


Attachments
WIP (62.60 KB, patch)
2019-10-23 00:48 PDT, Ryosuke Niwa
no flags Details | Formatted Diff | Diff
WIP2 (64.99 KB, patch)
2019-10-23 14:22 PDT, Ryosuke Niwa
no flags Details | Formatted Diff | Diff
Patch (70.95 KB, patch)
2019-10-23 15:22 PDT, Ryosuke Niwa
no flags Details | Formatted Diff | Diff
More build fixes (70.93 KB, patch)
2019-10-23 15:45 PDT, Ryosuke Niwa
no flags Details | Formatted Diff | Diff
Addressed review comments (72.75 KB, patch)
2019-10-23 20:58 PDT, Ryosuke Niwa
no flags Details | Formatted Diff | Diff
iOS build fix (74.33 KB, patch)
2019-10-23 21:24 PDT, Ryosuke Niwa
no flags Details | Formatted Diff | Diff
iOS build fix (72.34 KB, patch)
2019-10-23 21:26 PDT, Ryosuke Niwa
no flags Details | Formatted Diff | Diff
Patch for landing (72.50 KB, patch)
2019-10-24 16:07 PDT, Ryosuke Niwa
no flags Details | Formatted Diff | Diff
More iOS build fix (74.02 KB, patch)
2019-10-24 16:33 PDT, Ryosuke Niwa
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ryosuke Niwa 2019-10-22 23:01:57 PDT
Create a mechanism to find & replace paragraph of text in a WebPage.
Comment 1 Ryosuke Niwa 2019-10-23 00:48:46 PDT
Created attachment 381664 [details]
WIP
Comment 2 Ryosuke Niwa 2019-10-23 14:22:21 PDT
Created attachment 381728 [details]
WIP2
Comment 3 Ryosuke Niwa 2019-10-23 15:22:15 PDT
Created attachment 381739 [details]
Patch
Comment 4 Ryosuke Niwa 2019-10-23 15:45:57 PDT
Created attachment 381745 [details]
More build fixes
Comment 5 Tim Horton 2019-10-23 17:42:16 PDT
Comment on attachment 381745 [details]
More build fixes

View in context: https://bugs.webkit.org/attachment.cgi?id=381745&action=review

> Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm:7468
> +    WebCore::FrameIdentifier frameID;

Just a frame ID isn't enough to be globally unique. See ElementContext; I think you want a pageIdentifier as well. Or maybe a GlobalFrameIdentifier

> Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm:7505
> +        NSMutableArray *wkTokens = [NSMutableArray arrayWithCapacity: tokens.size()];

No space after :

> Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm:7508
> +            wkToken.get().identifier = String::number(token.identifier.toUInt64());

I (and some others) generally prefer [wkToken setIdentifier:] in the RetainPtr case (without a get()), but you can go either way.

> Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationDelegate.h:37
> +- (void)_webView:(WKWebView *)webView didFindItem:(_WKTextManipulationItem *)item forFrame:(_WKFrameHandle *)frame;

This sounds like find-in-page. Can it have a more specific name that's less likely to overlap?

> Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationItem.h:34
> +

You probably want to NS_UNAVAILABLE -init.

> Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationItem.mm:42
> +    _identifier = identifier;
> +    _tokens = tokens;

Should these copy the incoming objects?

> Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationToken.mm:29
> +#import <wtf/RetainPtr.h>

Why?

> Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationToken.mm:32
> +@implementation _WKTextManipulationToken {
> +}

No need for these braces

> Source/WebKit/WebKit.xcodeproj/project.pbxproj:11245
> +				9B02E0D1235EBCCA004044B2 /* _WKTextManipulationItem.mm in Sources */,
> +				9B02E0CF235EBB14004044B2 /* _WKTextManipulationToken.mm in Sources */,

These should not be here (uncheck them in the Xcode project), they should be in SourcesCocoa.txt or something instead

> Tools/TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm:62
> +    [_items.get() addObject:item];

No need for .get() here.

> Tools/TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm:67
> +    return _items.autorelease();

Really? This means _items will be nil after this. I think you just want .get()?
Comment 6 Wenson Hsieh 2019-10-23 19:22:27 PDT
Comment on attachment 381745 [details]
More build fixes

View in context: https://bugs.webkit.org/attachment.cgi?id=381745&action=review

> Source/WebCore/editing/TextManipulationController.cpp:67
> +                tokensInCurrentParagraph.append(ManipulationToken { m_tokenIdentifier.generate(), currentText.substring(endOfLastNewLine, offsetOfNextNewLine).toString() });

StringView::substring takes (unsigned start, unsigned length). Unless I’m missing something, it would appear that offsetOfNextNewLine isn’t a length.

> Source/WebCore/editing/TextManipulationController.cpp:77
> +                addItem(startOfCurrentParagraph, endOfCurrentParagraph, WTFMove(tokensInCurrentParagraph));

Is it guaranteed that tokensInCurrentParagraph is in a good state after the WTFMove here? I think in these cases where we will reuse the variable later on, we generally prefer to use std::exchange().

> Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm:7464
> +    StringBuilder result;
> +    result.appendNumber(frameID.toUInt64());
> +    result.append(':');
> +    result.appendNumber(itemID.toUInt64());
> +    return result.toString();

Nit - could also consider makeString here.

> Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm:7501
> +        auto delegate = retainedSelf.get()._textManipulationDelegate;

Nit - [retainedSelf _textManipulationDelegate]

>> Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm:7508
>> +            wkToken.get().identifier = String::number(token.identifier.toUInt64());
> 
> I (and some others) generally prefer [wkToken setIdentifier:] in the RetainPtr case (without a get()), but you can go either way.

(I also have a mild preference for using -[] in this case)

> Source/WebKit/WebProcess/WebPage/WebPage.cpp:6860
> +    auto completeManipulation = [&] () {

Nit - I don’t think you need the () here.

> Tools/TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm:72
> +namespace TestWebKitAPI {

It might be good to tweak one of these test cases to have two or more line breaks, as well.
Comment 7 Ryosuke Niwa 2019-10-23 20:27:15 PDT
(In reply to Tim Horton from comment #5)
> Comment on attachment 381745 [details]
> More build fixes
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=381745&action=review
> 
> > Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm:7468
> > +    WebCore::FrameIdentifier frameID;
> 
> Just a frame ID isn't enough to be globally unique. See ElementContext; I
> think you want a pageIdentifier as well. Or maybe a GlobalFrameIdentifier

I don't think this is true in the absence of process per frame but I'm going to get rid of the frame ID tracking for now since we don't support subframes at all for now.

> > Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm:7505
> > +        NSMutableArray *wkTokens = [NSMutableArray arrayWithCapacity: tokens.size()];
> 
> No space after :

Fixed.

> > Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm:7508
> > +            wkToken.get().identifier = String::number(token.identifier.toUInt64());
> 
> I (and some others) generally prefer [wkToken setIdentifier:] in the
> RetainPtr case (without a get()), but you can go either way.

Okay. Done.

> > Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationDelegate.h:37
> > +- (void)_webView:(WKWebView *)webView didFindItem:(_WKTextManipulationItem *)item forFrame:(_WKFrameHandle *)frame;
> 
> This sounds like find-in-page. Can it have a more specific name that's less
> likely to overlap?

Did rename to didFindTextManipulationItem.

> > Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationItem.h:34
> > +
> 
> You probably want to NS_UNAVAILABLE -init.

Done.

> > Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationItem.mm:42
> > +    _identifier = identifier;
> > +    _tokens = tokens;
> 
> Should these copy the incoming objects?

Maybe? I don't think it matters.

> > Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationToken.mm:29
> > +#import <wtf/RetainPtr.h>
> 
> Why?

Because I'm using RetainPtr??

> > Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationToken.mm:32
> > +@implementation _WKTextManipulationToken {
> > +}
> 
> No need for these braces

Okay.

> > Source/WebKit/WebKit.xcodeproj/project.pbxproj:11245
> > +				9B02E0D1235EBCCA004044B2 /* _WKTextManipulationItem.mm in Sources */,
> > +				9B02E0CF235EBB14004044B2 /* _WKTextManipulationToken.mm in Sources */,
> 
> These should not be here (uncheck them in the Xcode project), they should be
> in SourcesCocoa.txt or something instead

Fixed.

> > Tools/TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm:62
> > +    [_items.get() addObject:item];
> 
> No need for .get() here.

Removed.

> > Tools/TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm:67
> > +    return _items.autorelease();
> 
> Really? This means _items will be nil after this. I think you just want
> .get()?

Fixed. Honestly, I have no idea what this does. It complied and ran LOL. I really shouldn't be writing any Objective-C code.
Comment 8 Ryosuke Niwa 2019-10-23 20:31:00 PDT
(In reply to Wenson Hsieh from comment #6)
> Comment on attachment 381745 [details]
> More build fixes
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=381745&action=review
> 
> > Source/WebCore/editing/TextManipulationController.cpp:67
> > +                tokensInCurrentParagraph.append(ManipulationToken { m_tokenIdentifier.generate(), currentText.substring(endOfLastNewLine, offsetOfNextNewLine).toString() });
> 
> StringView::substring takes (unsigned start, unsigned length). Unless I’m
> missing something, it would appear that offsetOfNextNewLine isn’t a length.

Oops, this is clearly a bug. Will fix & add a test.

> > Source/WebCore/editing/TextManipulationController.cpp:77
> > +                addItem(startOfCurrentParagraph, endOfCurrentParagraph, WTFMove(tokensInCurrentParagraph));
> 
> Is it guaranteed that tokensInCurrentParagraph is in a good state after the
> WTFMove here? I think in these cases where we will reuse the variable later
> on, we generally prefer to use std::exchange().

Yes. WTF::Vector is guaranteed to be in a good state after WTFMove.

> > Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm:7464
> > +    StringBuilder result;
> > +    result.appendNumber(frameID.toUInt64());
> > +    result.append(':');
> > +    result.appendNumber(itemID.toUInt64());
> > +    return result.toString();
> 
> Nit - could also consider makeString here.

Removed this code entirely.

> > Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm:7501
> > +        auto delegate = retainedSelf.get()._textManipulationDelegate;
> 
> Nit - [retainedSelf _textManipulationDelegate]

Fixed.

> >> Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm:7508
> >> +            wkToken.get().identifier = String::number(token.identifier.toUInt64());
> > 
> > I (and some others) generally prefer [wkToken setIdentifier:] in the RetainPtr case (without a get()), but you can go either way.
> 
> (I also have a mild preference for using -[] in this case)

Okay, done that.

> > Source/WebKit/WebProcess/WebPage/WebPage.cpp:6860
> > +    auto completeManipulation = [&] () {
> 
> Nit - I don’t think you need the () here.

Sure. Removed.

> > Tools/TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm:72
> > +namespace TestWebKitAPI {
> 
> It might be good to tweak one of these test cases to have two or more line
> breaks, as well.

Some of them already have but I don't have any test case where a single text node has multiple line breaks (inside pre for example). Will add a test case for that.
Comment 9 Ryosuke Niwa 2019-10-23 20:58:28 PDT
Created attachment 381771 [details]
Addressed review comments
Comment 10 Radar WebKit Bug Importer 2019-10-23 21:01:31 PDT
<rdar://problem/56566991>
Comment 11 Ryosuke Niwa 2019-10-23 21:23:25 PDT
Ugh... unified builds strikes again.
Comment 12 Ryosuke Niwa 2019-10-23 21:24:17 PDT
Created attachment 381773 [details]
iOS build fix
Comment 13 Ryosuke Niwa 2019-10-23 21:26:53 PDT
Created attachment 381774 [details]
iOS build fix
Comment 14 Wenson Hsieh 2019-10-24 08:31:39 PDT
Comment on attachment 381774 [details]
iOS build fix

View in context: https://bugs.webkit.org/attachment.cgi?id=381774&action=review

> Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationDelegate.h:30
> +@class _WKFrameHandle;

Nit - do you need this forward declaration?

> Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationItem.mm:27
> +#include "config.h"
> +#include "_WKTextManipulationItem.h"

Nit - #include => #import

> Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationToken.mm:27
> +#include "config.h"
> +#include "_WKTextManipulationToken.h"

Nit - #include => #import

> Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationToken.mm:29
> +#import <wtf/RetainPtr.h>

Nit - Is this #import needed? I don’t see RetainPtr being used in this file.

> Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationToken.mm:38
> +- (instancetype)init
> +{
> +    if (!(self = [super init]))
> +        return nil;
> +    return self;
> +}

Nit - I’m not sure you need to override and implement -init here, since it’s not doing anything special.
Comment 15 Ryosuke Niwa 2019-10-24 13:58:35 PDT
(In reply to Wenson Hsieh from comment #14)
> Comment on attachment 381774 [details]
> iOS build fix
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=381774&action=review
> 
> > Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationDelegate.h:30
> > +@class _WKFrameHandle;
> 
> Nit - do you need this forward declaration?

Oops, that's a left over from when I had forFrame:. Removed.

> > Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationItem.mm:27
> > +#include "config.h"
> > +#include "_WKTextManipulationItem.h"
> 
> Nit - #include => #import

Fixed.

> > Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationToken.mm:27
> > +#include "config.h"
> > +#include "_WKTextManipulationToken.h"
> 
> Nit - #include => #import

Fixed.

> > Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationToken.mm:29
> > +#import <wtf/RetainPtr.h>
> 
> Nit - Is this #import needed? I don’t see RetainPtr being used in this file.

Good point. Removed.

> > Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationToken.mm:38
> > +- (instancetype)init
> > +{
> > +    if (!(self = [super init]))
> > +        return nil;
> > +    return self;
> > +}
> 
> Nit - I’m not sure you need to override and implement -init here, since it’s
> not doing anything special.

Removed.
Comment 16 Ryosuke Niwa 2019-10-24 14:01:24 PDT
Committed r251558: <https://trac.webkit.org/changeset/251558>
Comment 17 Matt Lewis 2019-10-24 15:25:53 PDT
This broke internal builds. See radar for details.
Comment 18 Matt Lewis 2019-10-24 15:51:17 PDT
Reverted r251558 for reason:

This broke internal builds

Committed r251569: <https://trac.webkit.org/changeset/251569>
Comment 19 Ryosuke Niwa 2019-10-24 16:01:04 PDT
(In reply to Matt Lewis from comment #18)
> Reverted r251558 for reason:
> 
> This broke internal builds
> 
> Committed r251569: <https://trac.webkit.org/changeset/251569>

I don't think that's accurate description. It seems that this patch broke all iOS builds even on build.webkit.org. What happened is that someone must have added another objective-C file between the time EWS processed my patch and I landed it this afternoon. And the offending file is nothing to do with this patch.

We really need a bot which builds everything with unified builds turned off.
Comment 20 Ryosuke Niwa 2019-10-24 16:07:09 PDT
Created attachment 381851 [details]
Patch for landing
Comment 21 Ryosuke Niwa 2019-10-24 16:07:24 PDT
Comment on attachment 381851 [details]
Patch for landing

Wait for EWS.
Comment 22 Ryosuke Niwa 2019-10-24 16:33:29 PDT
Created attachment 381857 [details]
More iOS build fix
Comment 23 Ryosuke Niwa 2019-10-24 17:08:15 PDT
Committed r251574: <https://trac.webkit.org/changeset/251574>