Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Conversation

@chunhtai
Copy link
Contributor

@chunhtai chunhtai commented Mar 5, 2021

The UITextInputStringTokenizer does not parse the line correctly, This pr fixes it.

fixes flutter/flutter#77274

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the Flutter Style Guide and the C++, Objective-C, Java style guides.
  • I listed at least one issue that this PR fixes in the description above.
  • I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test-exempt. See testing the engine for instructions on
    writing and running engine tests.
  • I updated/added relevant documentation (doc comments with ///).
  • I signed the CLA.
  • All existing and new tests are passing.
  • The reviewer has submitted any presubmit flakes in this PR using the engine presubmit flakes form before re-triggering the failure.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

Copy link
Member

@gaaclarke gaaclarke left a comment

Choose a reason for hiding this comment

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

Mostly looks good, just 2 comments.

#pragma mark - FlutterTokenizer

@implementation FlutterTokenizer {
FlutterTextInputView* _textInputView;
Copy link
Member

Choose a reason for hiding this comment

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

Please use a property so we can know if you intend this to be a strong or a weak reference. Right now this is being treated as a weak reference. I suspect you want a strong reference.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This should be a weak reference, FlutterTextInputView owns the FlutterTokenizer. I will update


@interface FlutterTokenizer ()

@property(nonatomic, assign) FlutterTextInputView* textInputView;
Copy link
Member

Choose a reason for hiding this comment

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

s/assign/weak for more modern objc and forward compatibility with ARC

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried to use weak, but it complains this file is MRC and can't use weak

return self;
}

- (UITextRange*)rangeEnclosingPosition:(UITextPosition*)position
Copy link
Member

Choose a reason for hiding this comment

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

If you just pass in the FlutterTextInputView as an argument to this method you wouldn't have to keep an instance variable around. The instance variable is a bit problematic because if the class is used differently it can cause a crash.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor Author

@chunhtai chunhtai Mar 9, 2021

Choose a reason for hiding this comment

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

I figured it is quite hard to know whether this is an override or private method for a reviewer. is there a best practice way to annotate an override method?

Copy link
Member

@gaaclarke gaaclarke Mar 9, 2021

Choose a reason for hiding this comment

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

You almost never use inheritance in objc. I didn't see this was inheriting UITextInputStringTokenizer. Is there a reason it has to inherit from UITextInputStringTokenizer?

The documentation says this for subclassing UITextInputString:

When you subclass UITextInputStringTokenizer, override all UITextInputTokenizer methods, calling the superclass implementation (super) when method parameters are not affected by layout. For example, the subclass needs a custom implementation of all methods for line granularity. For the left direction, it needs to decide whether left corresponds at a given position to forward or backward, and then call super passing in the storage direction (UITextStorageDirection).

Sounds like it might be a problem if you aren't calling super.

edit: You should probably be implementing UITextInputTokenizer then delegating to an instance of UITextInputStringTokenizer when you need to.

Copy link
Contributor Author

@chunhtai chunhtai Mar 9, 2021

Choose a reason for hiding this comment

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

calling the superclass implementation (super) when method parameters are not affected by layout.

it does not seems to be a hard requirement? a little background on this change.

If you have text = "how are you"
and you call

[UITextInputStringTokenizer  rangeEnclosingPosition:<at the end> withGranularity:line inDirection:forward]

it returns NSRange(location =8, length =3) which corresponds to "you". It is same result of Granularity word

The result is completely unusable. That is why i have to complete rewrite the line logic.

Copy link
Member

Choose a reason for hiding this comment

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

Yea, maybe you are right. I have a hard time understanding if that warning in the documentation is actually applicable. We do have tests I guess.

@"The FlutterTokenizer can only be used in a FlutterTextInputView");
self = [super initWithTextInput:textInput];
if (self) {
_textInputView = (FlutterTextInputView*)textInput;
Copy link
Member

Choose a reason for hiding this comment

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

Why cast here? Why not just pass in a FlutterTextInputView? If you want to keep the cast you should have an assert that it a valid cast (isKindOf:).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

I thought i saw it somewhere, thanks.


- (FlutterTextRange*)getLineRangeFromTokenizer:(id<UITextInputTokenizer>)tokenizer
atIndex:(NSInteger)index {
return (FlutterTextRange*)[tokenizer
Copy link
Member

Choose a reason for hiding this comment

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

Probably should add an assert here too if you are going to cast.

@chunhtai chunhtai added the waiting for tree to go green This PR is approved and tested, but waiting for the tree to be green to land. label Mar 10, 2021
@fluttergithubbot fluttergithubbot merged commit a560c26 into flutter:master Mar 10, 2021
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Mar 10, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

cla: yes platform-ios waiting for tree to go green This PR is approved and tested, but waiting for the tree to be green to land.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

iOS Voice control cannot delete line

4 participants