File tree Expand file tree Collapse file tree 3 files changed +42
-6
lines changed
hyper-state/lib/hyperstack/internal/state Expand file tree Collapse file tree 3 files changed +42
-6
lines changed Original file line number Diff line number Diff line change @@ -96,7 +96,7 @@ def merge_event_prop!(event_name, &block)
9696 end
9797 end
9898
99- def merge_built_in_event_prop! ( prop_name )
99+ def merge_built_in_event_prop! ( prop_name , & block )
100100 @properties . merge! (
101101 prop_name => %x{
102102 function(){
@@ -106,9 +106,17 @@ def merge_built_in_event_prop!(prop_name)
106106 if (arguments.length > 1) {
107107 all_args = Array.prototype.slice.call(arguments);
108108 other_args = all_args.slice(1, arguments.length);
109- return #{ yield ( Event . new ( `react_event` ) , *( `other_args` ) ) } ;
109+ return #{
110+ Internal ::State ::Mapper . ignore_bulk_updates (
111+ Event . new ( `react_event` ) , *( `other_args` ) , &block
112+ )
113+ } ;
110114 } else {
111- return #{ yield ( Event . new ( `react_event` ) ) } ;
115+ return #{
116+ Internal ::State ::Mapper . ignore_bulk_updates (
117+ Event . new ( `react_event` ) , &block
118+ )
119+ } ;
112120 }
113121 }
114122 }
Original file line number Diff line number Diff line change @@ -32,6 +32,21 @@ class TestComp < Hyperloop::Component
3232 end
3333 expect ( page ) . to have_content ( 'hello' )
3434 end
35+ it "does not shift cursor position during controlled input updates" do
36+ mount "TestComp" do
37+ class TestComp < HyperComponent
38+ render ( DIV ) do
39+ INPUT ( id : :input , value : @input_value )
40+ . on ( :change ) { |e | mutate @input_value = e . target . value }
41+ end
42+ end
43+ end
44+ input = find ( '#input' )
45+ input . send_keys '1234567890'
46+ evaluate_script "$('#input').focus()[0].setSelectionRange(3, 3)"
47+ input . send_keys 'hello'
48+ expect ( input . value ) . to eq ( '123hello4567890' )
49+ end
3550 # it "and it can still use the deprecated mutate syntax" do
3651 # mount "TestComp" do
3752 # class TestComp < Hyperloop::Component
Original file line number Diff line number Diff line change @@ -102,6 +102,18 @@ def bulk_update
102102 @bulk_update_flag = saved_bulk_update_flag
103103 end
104104
105+ # React already will batch together updates inside of event handlers
106+ # so we don't have to, and having Hyperstack batch them outside of the
107+ # event handler causes INPUT/TEXT/SELECT s not to work properly.
108+ # This method is called by the Component event wrapper.
109+ def ignore_bulk_updates ( *args )
110+ saved_ignore_bulk_update_flag = @ignore_bulk_update_flag
111+ @ignore_bulk_update_flag = true
112+ yield ( *args )
113+ ensure
114+ @ignore_bulk_update_flag = saved_ignore_bulk_update_flag
115+ end
116+
105117 def ignore_mutations
106118 saved_ignore_mutations_flag = @ignore_mutations
107119 @ignore_mutations = true
@@ -207,9 +219,10 @@ def remove_current_observers_and_objects(observer)
207219 # case that the object being updated is themselves.
208220
209221 def delay_updates? ( object )
210- @bulk_update_flag ||
211- ( Hyperstack . on_client? &&
212- ( @immediate_update != @current_observer || @current_observer != object ) )
222+ return false if @ignore_bulk_update_flag
223+ return true if @bulk_update_flag
224+ return false unless Hyperstack . on_client?
225+ ( @immediate_update != @current_observer || @current_observer != object )
213226 end
214227
215228 # schedule_delayed_updater adds a new set to the
You can’t perform that action at this time.
0 commit comments