Conversation
3d917e6 to
98c0155
Compare
| @@ -0,0 +1,24 @@ | |||
| // Copyright 2013 The Flutter Authors. All rights reserved. | |||
There was a problem hiding this comment.
FlutterTextEditingDelta here is nearly identical to its iOS counterpart (file), but here we use Cocoa instead of UIKit, and Mac seems to be using ARC. Is there any worthwhile way to share the code between the two despite that?
There was a problem hiding this comment.
Why the cocoa import then? Is it possible to replace that (and the UIKit import in the iOS implementation) with Foundation?
There was a problem hiding this comment.
Maybe we can implement something similar to TextInputModel in the shell/platform/common directory, that can be used across all platforms?
There was a problem hiding this comment.
The Cocoa import should have been AppKit. It looks like I can replace both with Foundation though 👍 . I'll attempt to create something reusable in shell/platform/common.
There was a problem hiding this comment.
The reusable class works, I've modified this PR to use it for both Mac and iOS. I'll use it in subsequent PRs on other platforms as well.
| @property(nonatomic, nonnull) NSString* inputAction; | ||
|
|
||
| /** | ||
| * Whether to enable that the engine sends text input updates to the framework |
There was a problem hiding this comment.
nit: this wording is a bit awkward.
Maybe something like: Whether to enable the engine sending text input updates to the framework as TextEditingDeltas rather than one TextEditingValue.
There was a problem hiding this comment.
Good call, I modified that slightly:
* Whether to enable the sending of text input updates from the engine to the
* framework as TextEditingDeltas rather than as one TextEditingValue.
| @@ -0,0 +1,24 @@ | |||
| // Copyright 2013 The Flutter Authors. All rights reserved. | |||
There was a problem hiding this comment.
Why the cocoa import then? Is it possible to replace that (and the UIKit import in the iOS implementation) with Foundation?
| @@ -0,0 +1,24 @@ | |||
| // Copyright 2013 The Flutter Authors. All rights reserved. | |||
There was a problem hiding this comment.
Maybe we can implement something similar to TextInputModel in the shell/platform/common directory, that can be used across all platforms?
| // engine since it sent this update, and needs to now be made to match the | ||
| // engine's version of the state. | ||
| [self updateEditState]; | ||
| if (!_enableDeltaModel) { |
There was a problem hiding this comment.
Is this not needed when the delta model is enabled?
There was a problem hiding this comment.
Hmm this is Mac's weird "Ack". In the race condition case that the comment mentions, you're probably right that it needs to update the framework. I'll update it to send an "empty" delta in that case. The client can compare the oldText with their current text to detect the race condition.
| if (_activeModel == nullptr) { | ||
| return; | ||
| } | ||
| NSString* textBeforeChange = [NSString stringWithUTF8String:_activeModel->GetText().c_str()]; |
There was a problem hiding this comment.
@cbracken is there a reason the UTF16 presentation of the string isn't exposed by TextInputModel?
There was a problem hiding this comment.
Internally it stores everything in UTF-16, so there's no technical reason we couldn't. If I remember correctly, TextInputModel tries to expose only a UTF-8 representation but will gladly convert from UTF-16.
I suspect that I did that just to minimize API surface (and minimise potential for confusion/bugs) and because we didn't need it for Linux which is the first platform I wrote it for.
|
This PR suddenly had an error show up in it that didn't exist before when running the example app. Maybe due to a change in the framework? I'll get it running again and then address the comments above. |
|
|
||
| #ifndef FLUTTER_SHELL_PLATFORM_COMMON_TEXT_EDITING_DELTA_H_ | ||
| #define FLUTTER_SHELL_PLATFORM_COMMON_TEXT_EDITING_DELTA_H_ | ||
| #define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING |
There was a problem hiding this comment.
The use of codecvt_utf8_utf16 caused a deprecation warning on Windows that wanted me to use wstring, but I've silenced it since this code needs to work on multiple platforms.
There was a problem hiding this comment.
Yep; we enable this in a few places. That said, instead of defining it here, please define this in shell/platform/common/BUILD.gn as we do here; that'll make it easier to rip this out later.
I've filed: flutter/flutter#93743
There was a problem hiding this comment.
Isn't that definition you linked exactly where I'd need to define this for this file? text_editing_delta.h and cc are included in that block in this PR. Or am I misunderstanding? I still seemed to get a failure in the Windows tests caused by this.
There was a problem hiding this comment.
Ah yeah -- looks like that is indeed the exact target. Will try patching this in to see if I can repro.
|
Ready for re-review. I've updated the TextEditingDelta struct to store the strings as utf-16 while providing setters and constructors for both utf 8 and 16. |
|
Gold has detected about 1 new digest(s) on patchset 28. |
cbracken
left a comment
There was a problem hiding this comment.
I've just reviewed the C++ bits -- haven't looked yet looked at the macOS specific Obj-C side.
|
|
||
| namespace flutter { | ||
|
|
||
| struct TextEditingDelta { |
There was a problem hiding this comment.
Add doc comments to this struct and the methods.
There was a problem hiding this comment.
Let me know if I've missed any that usually should have doc comments. I skipped some things that seemed obvious.
| std::string oldText() const { return utf16ToUtf8(oldText_); } | ||
| std::string deltaText() const { return utf16ToUtf8(deltaText_); } | ||
| int deltaStart() const { return deltaStart_; } | ||
| int deltaEnd() const { return deltaEnd_; } |
There was a problem hiding this comment.
Here and below, methods and functions should be named in UpperCamelCase().
Simple property getters/setters can be named foo_bar() and set_foo_bar().
Ref: https://google.github.io/styleguide/cppguide.html#Function_Names
| public: | ||
| TextEditingDelta(std::u16string textBeforeChange, | ||
| TextRange range, | ||
| std::u16string text); |
There was a problem hiding this comment.
It looks like TextEditingDeltas are copyable types. In this case, you should define:
- A copy constructor:
TextEditingDelta(const TextEditingDelta& other) - operator=:
TextEditingDelta& operator=(const TextEditingDelta& other)
In this case, you should be able to declare them as default.
Ref: https://google.github.io/styleguide/cppguide.html#Copyable_Movable_Types
| namespace flutter { | ||
|
|
||
| struct TextEditingDelta { | ||
| public: |
There was a problem hiding this comment.
This line is not needed since struct members are public by default.
|
|
||
| struct TextEditingDelta { | ||
| public: | ||
| TextEditingDelta(std::u16string textBeforeChange, |
There was a problem hiding this comment.
Here and below, parameters, fields, and variables should be formatted as text_before_change.
Ref: https://google.github.io/styleguide/cppguide.html#Variable_Names
| int deltaEnd_; | ||
|
|
||
| void setDeltas(std::u16string oldText, | ||
| std::u16string newTxt, |
There was a problem hiding this comment.
If we do keep this method around, s/txt/text/ on this, plus switch to words_separated_by_underscores form for all of these.
| deltaEnd_ = newEnd; | ||
| } | ||
|
|
||
| std::string utf16ToUtf8(std::u16string string) const { |
There was a problem hiding this comment.
Similarly here, use const std::u16string& text.
| std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> | ||
| utf16_converter; | ||
| return utf16_converter.from_bytes(string); | ||
| } |
There was a problem hiding this comment.
Since these two functions don't reference any instance variables they should just be static functions in the C++; that said they're basically just two-liners, and I bet deleting these functions and just using wstring_convert inline in the two places it's used would actually be less lines of code 😉.
e.g. of where else we do this:
engine/shell/platform/common/text_input_model.cc
Lines 36 to 42 in bba38c0
There was a problem hiding this comment.
I ended up keeping these methods around because I needed to use them in the initializers, where I think it would be harder to directly use wstring_convert. Let me know there is a slicker 1 liner way to use them that would be better.
There was a problem hiding this comment.
Nope -- no one-liner trick here unfortunately. SGTM!
| ASSERT_EQ(delta.oldText(), oldText); | ||
| ASSERT_EQ(delta.deltaText(), ""); | ||
| ASSERT_EQ(delta.deltaStart(), -1); | ||
| ASSERT_EQ(delta.deltaEnd(), -1); |
There was a problem hiding this comment.
Here and above: These could probably be EXPECT_EQ since these checks aren't interdependent on each other.
Ref: https://testing.googleblog.com/2008/07/tott-expect-vs-assert.html
| // Here we are simulating inserting an "o" at the end of "hell". | ||
| std::string oldText = "hell"; | ||
| std::string replacementText = "hello"; | ||
| flutter::TextRange range = flutter::TextRange(0, 4); |
There was a problem hiding this comment.
flutter:: prefix isn't necessary here since you're already in the flutter namespace.
Just:
TextRange range(0, 4);
|
@cbracken Ready for re-review. Thanks for all of the suggestions and references as I figure out C++ at Google. I think I took all of your suggestions except for two that I left questions on above. |
|
Gold has detected about 253 new digest(s) on patchset 29. |
| TEST(TextEditingDeltaTest, TestTextEditingDeltaConstructor) { | ||
| // Here we are simulating inserting an "o" at the end of "hell". | ||
| std::string old_text = "hell"; | ||
| std::string replacementText = "hello"; |
|
|
||
| TextEditingDelta::~TextEditingDelta() = default; | ||
|
|
||
| TextEditingDelta::TextEditingDelta(std::u16string text_before_change, |
There was a problem hiding this comment.
const std::u16string& text_before_change and a couple more places below.
|
|
||
| TextEditingDelta(const std::string& text); | ||
|
|
||
| virtual ~TextEditingDelta(); |
There was a problem hiding this comment.
You could mark this default and kill off the one in the cc file.
| // Copyright 2013 The Flutter Authors. All rights reserved. | ||
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
| // |
There was a problem hiding this comment.
Nit: this should be a blank line (kill the //)
aa7ab8d to
29ea28d
Compare
cbracken
left a comment
There was a problem hiding this comment.
LGTM on the C++ side modulo a couple minor nits. Will take a look at the macOS implementation after lunch!
|
Not sure why gold picked up 253 new gold images... I've merged in master and hopefully that fixes it. |
| : kTextAffinityDownstream; | ||
| } | ||
|
|
||
| - (NSRange)clampSelection:(NSRange*)range forText:(NSString*)text { |
There was a problem hiding this comment.
What about clampRange:(NSRange*)range forText:(NSString*)text in case we ever use this on e.g. mark text?
There was a problem hiding this comment.
Actually it looks like I've removed all usage of this 🤷. I'll remove it altogether then.
|
@cbracken I'm not authorized to merge this PR apparently, can you do it? |
|
Ah -- the issue is that you're trying to merge against |
|
Ah there we go, thanks! |
This PR will bring TextEditingDeltas, originally introduced by @Renzo-Olivares, to Mac. This is very similar to the iOS implementation (#28418).
Partial fix for flutter/flutter#87972