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

Internal PR #1

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,5 +104,6 @@
},
"resolutions": {
"react-is": "19.0.0-rc-fb9a90fa48-20240614"
}
},
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
}
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,9 @@ export interface TextInputKeyPressEventData {
export interface TextInputChangeEventData extends TargetedEvent {
eventCount: number;
text: string;
before: number;
start: number;
count: number;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1160,7 +1160,7 @@ function InternalTextInput(props: Props): React.Node {
selection?.start ?? -1,
selection?.end ?? -1,
);
}
console.log('JS -> Native setText:', text); }
}, [
mostRecentEventCount,
inputRef,
Expand Down Expand Up @@ -1266,6 +1266,7 @@ function InternalTextInput(props: Props): React.Node {
return;
}

console.log('native -> JS onChange:', currentText, { eventCount: event.nativeEvent.eventCount });
setLastNativeText(currentText);
// This must happen last, after we call setLastNativeText.
// Different ordering can cause bugs when editing AndroidTextInputs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ @implementation RCTTextInputComponentView {
*/
BOOL _comingFromJS;
BOOL _didMoveToWindow;

NSInteger changeStart;
NSInteger changeBefore;
NSInteger changeCount;
}

#pragma mark - UIView overrides
Expand Down Expand Up @@ -327,6 +331,10 @@ - (void)textInputDidReturn
- (NSString *)textInputShouldChangeText:(NSString *)text inRange:(NSRange)range
{
const auto &props = static_cast<const TextInputProps &>(*_props);

changeStart = range.location;
changeBefore = range.length;
changeCount = text.length;

if (!_backedTextInputView.textWasPasted) {
if (_eventEmitter) {
Expand Down Expand Up @@ -575,6 +583,9 @@ - (void)handleInputAccessoryDoneButton
return {
.text = RCTStringFromNSString(_backedTextInputView.attributedText.string),
.selectionRange = [self _selectionRange],
.count = static_cast<int>(changeCount),
.before = static_cast<int>(changeBefore),
.start = static_cast<int>(changeStart),
.eventCount = static_cast<int>(_mostRecentEventCount),
.contentOffset = RCTPointFromCGPoint(_backedTextInputView.contentOffset),
.contentInset = RCTEdgeInsetsFromUIEdgeInsets(_backedTextInputView.contentInset),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
public class NativeViewHierarchyManager {

private static final String TAG = NativeViewHierarchyManager.class.getSimpleName();
private final boolean DEBUG_MODE = ReactBuildConfig.DEBUG && false;
private final boolean DEBUG_MODE = ReactBuildConfig.DEBUG && true;

private final SparseArray<View> mTagsToViews;
private final SparseArray<ViewManager> mTagsToViewManagers;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import android.text.TextWatcher;
import android.text.method.KeyListener;
import android.text.method.QwertyKeyListener;
import android.util.Log;
import android.util.TypedValue;
import android.view.ActionMode;
import android.view.Gravity;
Expand Down Expand Up @@ -87,7 +88,7 @@ public class ReactEditText extends AppCompatEditText {

private final InputMethodManager mInputMethodManager;
private final String TAG = ReactEditText.class.getSimpleName();
public static final boolean DEBUG_MODE = ReactBuildConfig.DEBUG && false;
public static final boolean DEBUG_MODE = ReactBuildConfig.DEBUG && true;

// This flag is set to true when we set the text of the EditText explicitly. In that case, no
// *TextChanged events should be triggered. This is less expensive than removing the text
Expand Down Expand Up @@ -624,12 +625,14 @@ public int incrementAndGetEventCounter() {
}

public void maybeSetTextFromJS(ReactTextUpdate reactTextUpdate) {
FLog.e(TAG, "maybeSetTextFromJS text: '" + reactTextUpdate.getText() + "'");
mIsSettingTextFromJS = true;
maybeSetText(reactTextUpdate);
mIsSettingTextFromJS = false;
}

public void maybeSetTextFromState(ReactTextUpdate reactTextUpdate) {
FLog.e(TAG, "maybeSetTextFromState text: '" + reactTextUpdate.getText() + "'");
mIsSettingTextFromState = true;
maybeSetText(reactTextUpdate);
mIsSettingTextFromState = false;
Expand All @@ -646,7 +649,9 @@ public void maybeSetText(ReactTextUpdate reactTextUpdate) {
}

// Only set the text if it is up to date.
if (!canUpdateWithEventCount(reactTextUpdate.getJsEventCounter())) {
int jsEventCounter = reactTextUpdate.getJsEventCounter();
if (!canUpdateWithEventCount(jsEventCounter)) {
Log.e(TAG, String.format("Skip update, js event counter is lagging behind. JS: %d native: %d", jsEventCounter, mNativeEventCount));
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,23 @@ public class ReactTextChangedEvent extends Event<ReactTextChangedEvent> {

private String mText;
private int mEventCount;
// See https://developer.android.com/reference/android/text/TextWatcher#onTextChanged(java.lang.CharSequence,%20int,%20int,%20int)
private int mStart;
private int mCount;
private int mBefore;

@Deprecated
public ReactTextChangedEvent(int viewId, String text, int eventCount) {
this(ViewUtil.NO_SURFACE_ID, viewId, text, eventCount);
public ReactTextChangedEvent(int viewId, String text, int eventCount, int start, int count, int before) {
this(ViewUtil.NO_SURFACE_ID, viewId, text, eventCount, start, count, before);
}

public ReactTextChangedEvent(int surfaceId, int viewId, String text, int eventCount) {
public ReactTextChangedEvent(int surfaceId, int viewId, String text, int eventCount, int start, int count, int before) {
super(surfaceId, viewId);
mText = text;
mEventCount = eventCount;
mStart = start;
mCount = count;
mBefore = before;
}

@Override
Expand All @@ -47,6 +54,9 @@ protected WritableMap getEventData() {
eventData.putString("text", mText);
eventData.putInt("eventCount", mEventCount);
eventData.putInt("target", getViewTag());
eventData.putInt("start", mStart);
eventData.putInt("count", mCount);
eventData.putInt("before", mBefore);
return eventData;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ public void receiveCommand(

if (!args.isNull(1)) {
String text = args.getString(1);
FLog.e("ReactEditText", "receive command text: '"+text+"'");
reactEditText.maybeSetTextFromJS(getReactTextUpdate(text, mostRecentEventCount));
}
reactEditText.maybeSetSelection(mostRecentEventCount, start, end);
Expand All @@ -326,6 +327,7 @@ private ReactTextUpdate getReactTextUpdate(String text, int mostRecentEventCount
SpannableStringBuilder sb = new SpannableStringBuilder();
sb.append(TextTransform.apply(text, TextTransform.UNSET));

FLog.e("ReactEditText", "getReactTextUpdate: '"+sb.toString()+"'");
return new ReactTextUpdate(
sb, mostRecentEventCount, false, 0, 0, 0, 0, Gravity.NO_GRAVITY, 0, 0);
}
Expand Down Expand Up @@ -1118,7 +1120,13 @@ public void onTextChanged(CharSequence s, int start, int before, int count) {
mSurfaceId,
mEditText.getId(),
s.toString(),
mEditText.incrementAndGetEventCounter()));
mEditText.incrementAndGetEventCounter(),
start,
count,
before
)
);
FLog.e("ReactTextInputManager", String.format("Dispatched event to JS with text '%s'", s));
}

@Override
Expand Down Expand Up @@ -1356,6 +1364,8 @@ public Object updateState(
view.setPadding(0, 0, 0, 0);
}

// TODO: why do we do that here? The wrapper is already a ref taken from the view ...
// Ah, we do that here, because we receive the state wrapper as parameter
view.setStateWrapper(stateWrapper);

MapBuffer stateMapBuffer = stateWrapper.getStateDataMapBuffer();
Expand Down Expand Up @@ -1387,6 +1397,7 @@ public Object updateState(
int currentJustificationMode =
Build.VERSION.SDK_INT < Build.VERSION_CODES.O ? 0 : view.getJustificationMode();

FLog.e("ReactTextInputManager", String.format("getReactTextUpdate text: '%s'", spanned.toString()));
return ReactTextUpdate.buildReactTextUpdateFromState(
spanned,
state.getInt(TX_STATE_KEY_MOST_RECENT_EVENT_COUNT),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ static jsi::Value textInputMetricsPayload(
jsi::String::createFromUtf8(runtime, textInputMetrics.text));

payload.setProperty(runtime, "eventCount", textInputMetrics.eventCount);
payload.setProperty(runtime, "start", textInputMetrics.start);
payload.setProperty(runtime, "count", textInputMetrics.count);
payload.setProperty(runtime, "before", textInputMetrics.before);

{
auto selection = jsi::Object(runtime);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ class TextInputEventEmitter : public ViewEventEmitter {
struct Metrics {
std::string text;
AttributedString::Range selectionRange;
int count;
int start;
int before;
// ScrollView-like metrics
Size contentSize;
Point contentOffset;
Expand Down
Loading
Loading