diff --git a/patches/components/script/dom/html/form_controls/htmlinputelement.rs.patch b/patches/components/script/dom/html/form_controls/htmlinputelement.rs.patch
index d2067c2..cb37f24 100644
--- a/patches/components/script/dom/html/form_controls/htmlinputelement.rs.patch
+++ b/patches/components/script/dom/html/form_controls/htmlinputelement.rs.patch
@@ -11,7 +11,56 @@
use encoding_rs::Encoding;
use html5ever::{LocalName, Prefix, local_name};
use js::context::JSContext;
-@@ -1019,6 +1021,9 @@
+@@ -987,26 +989,31 @@
+ }
+
+ fn maybe_update_shared_selection(&self) {
+- let mut text_input = self.textinput.borrow_mut();
+- let selection_range = text_input.selection_start()..text_input.selection_end();
+- let enabled = self.is_textual_or_password() && self.upcast::().focus_state();
++ // The borrow ends before the widget update below: that path is free to read the
++ // element's value back out, and `Value()` borrows `textinput` again.
++ let selection = {
++ let mut text_input = self.textinput.borrow_mut();
++ let selection_range = text_input.selection_start()..text_input.selection_end();
++ let enabled = self.is_textual_or_password() && self.upcast::().focus_state();
+
+- let range_remained_equal = selection_range == text_input.previous_selection_range;
+- if range_remained_equal && enabled == text_input.selection_for_layout.is_some() {
+- return;
+- }
++ let range_remained_equal = selection_range == text_input.previous_selection_range;
++ if range_remained_equal && enabled == text_input.selection_for_layout.is_some() {
++ return;
++ }
+
+- if !range_remained_equal {
+- // https://w3c.github.io/selection-api/#selectionchange-event
+- // > When an input or textarea element provide a text selection and its selection changes
+- // > (in either extent or direction),
+- // > the user agent must schedule a selectionchange event on the element.
+- self.schedule_a_selection_change_event();
+- }
++ if !range_remained_equal {
++ // https://w3c.github.io/selection-api/#selectionchange-event
++ // > When an input or textarea element provide a text selection and its selection changes
++ // > (in either extent or direction),
++ // > the user agent must schedule a selectionchange event on the element.
++ self.schedule_a_selection_change_event();
++ }
+
+- let selection = enabled.then(|| text_input.sorted_selection_character_offsets_range());
+- text_input.previous_selection_range = selection_range;
+- text_input.selection_for_layout = selection;
++ let selection = enabled.then(|| text_input.sorted_selection_character_offsets_range());
++ text_input.previous_selection_range = selection_range;
++ text_input.selection_for_layout = selection;
++ selection
++ };
+
+ if let Some(text_input_widget) = self.input_type.borrow().as_specific().text_input_widget()
+ {
+@@ -1019,6 +1026,9 @@
} else {
// Non-text input type. Would this be even called?
}
@@ -21,7 +70,7 @@
}
fn is_password_field(&self) -> bool {
-@@ -1966,10 +1971,25 @@
+@@ -1966,10 +1976,25 @@
.hide_embedder_control(self.upcast());
} else if *event_type == *"focus" {
let input_type = &*self.input_type();
diff --git a/patches/components/script/dom/html/form_controls/htmltextareaelement.rs.patch b/patches/components/script/dom/html/form_controls/htmltextareaelement.rs.patch
index d777ebc..e70ddd2 100644
--- a/patches/components/script/dom/html/form_controls/htmltextareaelement.rs.patch
+++ b/patches/components/script/dom/html/form_controls/htmltextareaelement.rs.patch
@@ -1,6 +1,55 @@
--- original
+++ modified
-@@ -303,6 +303,9 @@
+@@ -272,26 +272,31 @@
+ }
+
+ fn maybe_update_shared_selection(&self) {
+- let mut text_input = self.textinput.borrow_mut();
+- let selection_range = text_input.selection_start()..text_input.selection_end();
+- let enabled = self.upcast::().focus_state();
++ // The borrow ends before the widget update below: that path is free to read the
++ // element's value back out, and `Value()` borrows `textinput` again.
++ let selection = {
++ let mut text_input = self.textinput.borrow_mut();
++ let selection_range = text_input.selection_start()..text_input.selection_end();
++ let enabled = self.upcast::().focus_state();
+
+- let range_remained_equal = selection_range == text_input.previous_selection_range;
+- if range_remained_equal && enabled == text_input.selection_for_layout.is_some() {
+- return;
+- }
++ let range_remained_equal = selection_range == text_input.previous_selection_range;
++ if range_remained_equal && enabled == text_input.selection_for_layout.is_some() {
++ return;
++ }
+
+- if !range_remained_equal {
+- // https://w3c.github.io/selection-api/#selectionchange-event
+- // > When an input or textarea element provide a text selection and its selection changes
+- // > (in either extent or direction),
+- // > the user agent must schedule a selectionchange event on the element.
+- self.schedule_a_selection_change_event();
+- }
++ if !range_remained_equal {
++ // https://w3c.github.io/selection-api/#selectionchange-event
++ // > When an input or textarea element provide a text selection and its selection changes
++ // > (in either extent or direction),
++ // > the user agent must schedule a selectionchange event on the element.
++ self.schedule_a_selection_change_event();
++ }
+
+- let selection = enabled.then(|| text_input.sorted_selection_character_offsets_range());
+- text_input.previous_selection_range = selection_range;
+- text_input.selection_for_layout = selection;
++ let selection = enabled.then(|| text_input.sorted_selection_character_offsets_range());
++ text_input.previous_selection_range = selection_range;
++ text_input.selection_for_layout = selection;
++ selection
++ };
+
+ if self
+ .text_input_widget
+@@ -303,6 +308,9 @@
} else {
// If there isn’t a text run, layout is pending to create it anyway
}