Revert "[web] Don't overwrite editing state with semantic updates (#38271)"

This reverts commit 45713ea105104ac45ad10d2db7090add5246622a.
diff --git a/lib/web_ui/lib/src/engine/semantics/text_field.dart b/lib/web_ui/lib/src/engine/semantics/text_field.dart
index 289248e..3e36ffb 100644
--- a/lib/web_ui/lib/src/engine/semantics/text_field.dart
+++ b/lib/web_ui/lib/src/engine/semantics/text_field.dart
@@ -364,7 +364,11 @@
     // element, so that both the framework and the browser agree on what's
     // currently focused.
     bool needsDomFocusRequest = false;
-
+    final EditingState editingState = EditingState(
+      text: semanticsObject.value,
+      baseOffset: semanticsObject.textSelectionBase,
+      extentOffset: semanticsObject.textSelectionExtent,
+    );
     if (semanticsObject.hasFocus) {
       if (!_hasFocused) {
         _hasFocused = true;
@@ -374,9 +378,14 @@
       if (domDocument.activeElement != editableElement) {
         needsDomFocusRequest = true;
       }
+      // Focused elements should have full text editing state applied.
+      SemanticsTextEditingStrategy.instance.setEditingState(editingState);
     } else if (_hasFocused) {
       SemanticsTextEditingStrategy.instance.deactivate(this);
 
+      // Only apply text, because this node is not focused.
+      editingState.applyTextToDomElement(editableElement);
+
       if (_hasFocused && domDocument.activeElement == editableElement) {
         // Unlike `editableElement.focus()` we don't need to schedule `blur`
         // post-update because `document.activeElement` implies that the
diff --git a/lib/web_ui/test/engine/semantics/text_field_test.dart b/lib/web_ui/test/engine/semantics/text_field_test.dart
index fb87725..91129dc 100644
--- a/lib/web_ui/test/engine/semantics/text_field_test.dart
+++ b/lib/web_ui/test/engine/semantics/text_field_test.dart
@@ -4,8 +4,6 @@
 
 @TestOn('chrome || safari || firefox')
 
-import 'dart:typed_data';
-
 import 'package:test/bootstrap/browser.dart';
 import 'package:test/test.dart';
 
@@ -50,11 +48,6 @@
       testTextEditing.configuration = singlelineConfig;
     });
 
-    /// Emulates sending of a message by the framework to the engine.
-    void sendFrameworkMessage(ByteData? message) {
-      testTextEditing.channel.handleTextInput(message, (ByteData? data) {});
-    }
-
   test('renders a text field', () async {
     semantics()
       ..debugOverrideTimestampFunction(() => _testTime)
@@ -134,7 +127,7 @@
       // TODO(yjbanov): https://github.com/flutter/flutter/issues/50754
       skip: browserEngine != BrowserEngine.blink);
 
-    test('Syncs semantic state from framework', () async {
+    test('Syncs editing state from framework', () async {
       semantics()
         ..debugOverrideTimestampFunction(() => _testTime)
         ..semanticsEnabled = true;
@@ -166,6 +159,7 @@
       expect(domDocument.activeElement, flutterViewEmbedder.glassPaneElement);
       expect(appHostNode.activeElement, strategy.domElement);
       expect(textField.editableElement, strategy.domElement);
+      expect((textField.editableElement as dynamic).value, 'hello');
       expect(textField.editableElement.getAttribute('aria-label'), 'greeting');
       expect(textField.editableElement.style.width, '10px');
       expect(textField.editableElement.style.height, '15px');
@@ -180,6 +174,7 @@
       expect(domDocument.activeElement, domDocument.body);
       expect(appHostNode.activeElement, null);
       expect(strategy.domElement, null);
+      expect((textField.editableElement as dynamic).value, 'bye');
       expect(textField.editableElement.getAttribute('aria-label'), 'farewell');
       expect(textField.editableElement.style.width, '12px');
       expect(textField.editableElement.style.height, '17px');
@@ -193,92 +188,6 @@
       expect(actionCount, 0);
     });
 
-    test(
-        'Does not overwrite text value and selection editing state on semantic updates',
-        () async {
-      semantics()
-        ..debugOverrideTimestampFunction(() => _testTime)
-        ..semanticsEnabled = true;
-
-      strategy.enable(
-        singlelineConfig,
-        onChange: (_, __) {},
-        onAction: (_) {},
-      );
-
-      final SemanticsObject textFieldSemantics = createTextFieldSemantics(
-          value: 'hello',
-          textSelectionBase: 1,
-          textSelectionExtent: 3,
-          isFocused: true,
-          rect: const ui.Rect.fromLTWH(0, 0, 10, 15));
-
-      final TextField textField =
-          textFieldSemantics.debugRoleManagerFor(Role.textField)! as TextField;
-      final DomHTMLInputElement editableElement =
-          textField.editableElement as DomHTMLInputElement;
-
-      expect(editableElement, strategy.domElement);
-      expect(editableElement.value, '');
-      expect(editableElement.selectionStart, 0);
-      expect(editableElement.selectionEnd, 0);
-
-      strategy.disable();
-      semantics().semanticsEnabled = false;
-    });
-
-    test(
-        'Updates editing state when receiving framework messages from the text input channel',
-        () async {
-      semantics()
-        ..debugOverrideTimestampFunction(() => _testTime)
-        ..semanticsEnabled = true;
-
-      expect(domDocument.activeElement, domDocument.body);
-      expect(appHostNode.activeElement, null);
-
-      strategy.enable(
-        singlelineConfig,
-        onChange: (_, __) {},
-        onAction: (_) {},
-      );
-
-      final SemanticsObject textFieldSemantics = createTextFieldSemantics(
-          value: 'hello',
-          textSelectionBase: 1,
-          textSelectionExtent: 3,
-          isFocused: true,
-          rect: const ui.Rect.fromLTWH(0, 0, 10, 15));
-
-      final TextField textField =
-          textFieldSemantics.debugRoleManagerFor(Role.textField)! as TextField;
-      final DomHTMLInputElement editableElement =
-          textField.editableElement as DomHTMLInputElement;
-
-      // No updates expected on semantic updates
-      expect(editableElement, strategy.domElement);
-      expect(editableElement.value, '');
-      expect(editableElement.selectionStart, 0);
-      expect(editableElement.selectionEnd, 0);
-
-      // Update from framework
-      const MethodCall setEditingState =
-          MethodCall('TextInput.setEditingState', <String, dynamic>{
-        'text': 'updated',
-        'selectionBase': 2,
-        'selectionExtent': 3,
-      });
-      sendFrameworkMessage(codec.encodeMethodCall(setEditingState));
-
-      // Editing state should now be updated
-      expect(editableElement.value, 'updated');
-      expect(editableElement.selectionStart, 2);
-      expect(editableElement.selectionEnd, 3);
-
-      strategy.disable();
-      semantics().semanticsEnabled = false;
-    });
-
     test('Gives up focus after DOM blur', () async {
       semantics()
         ..debugOverrideTimestampFunction(() => _testTime)
@@ -537,8 +446,6 @@
   bool isFocused = false,
   bool isMultiline = false,
   ui.Rect rect = const ui.Rect.fromLTRB(0, 0, 100, 50),
-  int textSelectionBase = 0,
-  int textSelectionExtent = 0,
 }) {
   final SemanticsTester tester = SemanticsTester(semantics());
   tester.updateNode(
@@ -551,8 +458,6 @@
     hasTap: true,
     rect: rect,
     textDirection: ui.TextDirection.ltr,
-    textSelectionBase: textSelectionBase,
-    textSelectionExtent: textSelectionExtent
   );
   tester.apply();
   return tester.getSemanticsObject(0);