on master help sign in
Fix #532, correct behavior of click handlers
87509d6Evan Czaplicki
runtime/Render/Element.js+57−29
@@ -34,35 +34,59 @@ function setProps(elem, e) {
34 e.appendChild(a);
34 e.appendChild(a);
35 }
35 }
36 if (props.hover.ctor !== '_Tuple0') {
36 if (props.hover.ctor !== '_Tuple0') {
37− e.style.pointerEvents = 'auto';
38− e.elm_hover_handler = props.hover;
37+ addHover(e, props.hover);
39− e.elm_hover_count = 0;
40− e.addEventListener('mouseover', function() {
41− if (e.elm_hover_count++ > 0) return;
42− var handler = e.elm_hover_handler;
43− if (handler !== null) {
44− handler(true);
45− }
46− });
47− e.addEventListener('mouseout', function(evt) {
48− if (e.contains(evt.toElement || evt.relatedTarget)) return;
49− e.elm_hover_count = 0;
50− var handler = e.elm_hover_handler;
51− if (handler !== null) {
52− handler(false);
53− }
54− });
55 }
38 }
56 if (props.click.ctor !== '_Tuple0') {
39 if (props.click.ctor !== '_Tuple0') {
57− e.style.pointerEvents = 'auto';
58− e.elm_click_handler = props.click;
40+ addClick(e, props.click);
59− e.addEventListener('click', function() {
60− e.elm_click_handler(Tuple0);
61− });
62 }
41 }
63 return e;
42 return e;
64}
43}
65
44
45+function addClick(e, handler) {
46+ e.style.pointerEvents = 'auto';
47+ e.elm_click_handler = handler;
48+ function trigger() {
49+ e.elm_click_handler(Utils.Tuple0);
50+ }
51+ e.elm_click_trigger = trigger;
52+ e.addEventListener('click', trigger);
53+}
54+
55+function removeClick(e, handler) {
56+ if (e.elm_click_trigger) {
57+ e.removeEventListener('click', e.elm_click_trigger);
58+ }
59+}
60+
61+function addHover(e, handler) {
62+ e.style.pointerEvents = 'auto';
63+ e.elm_hover_handler = handler;
64+ e.elm_hover_count = 0;
65+
66+ function over() {
67+ if (e.elm_hover_count++ > 0) return;
68+ e.elm_hover_handler(true);
69+ }
70+ function out(evt) {
71+ if (e.contains(evt.toElement || evt.relatedTarget)) return;
72+ e.elm_hover_count = 0;
73+ e.elm_hover_handler(false);
74+ }
75+ e.elm_hover_over = over;
76+ e.elm_hover_out = out;
77+ e.addEventListener('mouseover', over);
78+ e.addEventListener('mouseout', out);
79+}
80+
81+function removeHover(e) {
82+ if (e.elm_hover_over) {
83+ e.removeEventListener('mouseover', e.elm_hover_over);
84+ }
85+ if (e.elm_hover_out) {
86+ e.removeEventListener('mouseout', e.elm_hover_out);
87+ }
88+}
89+
66function image(props, img) {
90function image(props, img) {
67 switch (img._0.ctor) {
91 switch (img._0.ctor) {
68 case 'Plain': return plainImage(img._3);
92 case 'Plain': return plainImage(img._3);
@@ -358,17 +382,21 @@ function updateProps(node, curr, next) {
358 }
382 }
359
383
360 // update hover handlers
384 // update hover handlers
361− if (props.hover.ctor !== '_Tuple0') {
385+ if (props.hover.ctor === '_Tuple0') {
362− e.elm_hover_handler = props.hover;
386+ removeHover(e);
363 } else if (e.elm_hover_handler) {
387 } else if (e.elm_hover_handler) {
364− e.elm_hover_handler = null;
388+ e.elm_hover_handler = props.hover;
389+ } else {
390+ addHover(e, props.hover);
365 }
391 }
366
392
367 // update click handlers
393 // update click handlers
368− if (props.click.ctor !== '_Tuple0') {
394+ if (props.click.ctor === '_Tuple0') {
369− e.elm_click_handler = props.click;
395+ removeClick(e);
370 } else if (e.elm_click_handler) {
396 } else if (e.elm_click_handler) {
371− e.elm_click_handler = null;
397+ e.elm_click_handler = props.click;
398+ } else {
399+ addClick(e, props.click);
372 }
400 }
373}
401}
374
402