Skip to content

Commit 084dcfd

Browse files
committed
closes #110
1 parent e5dfd14 commit 084dcfd

File tree

3 files changed

+42
-6
lines changed

3 files changed

+42
-6
lines changed

ruby/hyper-component/lib/hyperstack/component/element.rb

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff 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
}

ruby/hyper-component/spec/client_features/misc_fixes_spec.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff 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

ruby/hyper-state/lib/hyperstack/internal/state/mapper.rb

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff 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

0 commit comments

Comments
 (0)