on master help sign in
Merge pull request #218 from johnpmayer/topic/kbd_caper

fixed wierd keyboard stuff by factoring out keypress events

commit6bffee3525965a64716d2ba172fe8de5cd837153 authorEvan Czaplicki <info@elm-lang.org> dateSun 18 Aug 2013, 13:27 (13 years ago) parentc608e759a56f13
2 files changed+75−23
libraries/Native/Char.js+1−1 libraries/Native/Signal/Keyboard.js+74−22
libraries/Native/Char.js+1−1
@@ -16,7 +16,7 @@ Elm.Native.Char = function(elm) {
1616
1717 return elm.Native.Char = {
1818 fromCode : function(c) { return String.fromCharCode(c); },
19− toCode : function(c) { return c.charCodeAt(0); },
19+ toCode : function(c) { return c.toUpperCase().charCodeAt(0); },
2020 toUpper : function(c) { return c.toUpperCase(); },
2121 toLower : function(c) { return c.toLowerCase(); },
2222 toLocaleUpper : function(c) { return c.toLocaleUpperCase(); },
libraries/Native/Signal/Keyboard.js+74−22
@@ -4,29 +4,79 @@ Elm.Native.Keyboard = function(elm) {
44 elm.Native = elm.Native || {};
55 if (elm.Native.Keyboard) return elm.Native.Keyboard;
66
7+ // Duplicated from Native.Signal
8+ function send(node, timestep, changed) {
9+ var kids = node.kids;
10+ for (var i = kids.length; i--; ) {
11+ kids[i].recv(timestep, changed, node.id);
12+ }
13+ }
14+
715 var Signal = Elm.Signal(elm);
816 var NList = Elm.Native.List(elm);
17+ var Utils = Elm.Native.Utils(elm);
18+
19+ var downEvents = Signal.constant(0);
20+ var upEvents = Signal.constant(0);
21+ var blurEvents = Signal.constant(0);
22+
23+ elm.addListener([downEvents.id], document, 'keydown', function down(e) {
24+ elm.notify(downEvents.id, e.keyCode);
25+ });
26+
27+ elm.addListener([upEvents.id], document, 'keyup', function up(e) {
28+ elm.notify(upEvents.id, e.keyCode);
29+ });
30+
31+ elm.addListener([blurEvents.id], document, 'blur', function blur(e) {
32+ elm.notify(blurEvents.id, NList.Nil);
33+ });
34+
35+ function KeyMerge(down, up, blur) {
36+ var args = [down,up,blur];
37+ this.id = Utils.guid();
38+ // Ignore starting values here
39+ this.value = NList.Nil
40+ this.kids = [];
41+
42+ var n = args.length;
43+ var count = 0;
44+ var isChanged = false;
945
10− var keysDown = Signal.constant(NList.Nil);
11− var lastKey = Signal.constant('\0');
12−
13− elm.addListener([keysDown.id], document, 'keydown', function down(e) {
14− if (NList.member(e.keyCode)(keysDown.value)) return;
15− elm.notify(keysDown.id, NList.Cons(e.keyCode, keysDown.value));
16− });
17− elm.addListener([keysDown.id], document, 'keyup', function up(e) {
18− function notEq(kc) { return kc !== e.keyCode; }
19− elm.notify(keysDown.id, NList.filter(notEq)(keysDown.value));
20− });
21− elm.addListener([keysDown.id], document, 'blur', function blur(e) {
22− elm.notify(keysDown.id, NList.Nil);
23− });
24− elm.addListener([lastKey.id], document, 'keypress', function press(e) {
25− elm.notify(lastKey.id, e.charCode || e.keyCode);
26− });
46+ this.recv = function(timestep, changed, parentID) {
47+ ++count;
48+ if (changed) {
49+ // We know this a change must only be one of the following cases
50+ if (parentID === down.id && !(NList.member(down.value)(this.value))) {
51+ isChanged = true;
52+ this.value = NList.Cons(down.value, this.value);
53+ }
54+ if (parentID === up.id) {
55+ isChanged = true;
56+ var notEq = function(kc) { return kc !== up.value };
57+ this.value = NList.filter(notEq)(this.value);
58+ }
59+ if (parentID === blur.id) {
60+ isChanged = true;
61+ this.value = NList.Nil;
62+ }
63+ }
64+ if (count == n) {
65+ send(this, timestep, isChanged);
66+ isChanged = false;
67+ count = 0;
68+ }
69+ };
70+
71+ for (var i = n; i--; ) { args[i].kids.push(this); }
72+
73+ }
74+
75+ var keysDown = Signal.dropRepeats(new KeyMerge(downEvents,upEvents,blurEvents));
2776
2877 function keySignal(f) {
29− var signal = Signal.dropRepeats(A2(Signal.lift, f, keysDown));
78+ var signal = A2(Signal.lift, f, keysDown);
79+ // what's the significance of these two following lines? -jpm
3080 keysDown.defaultNumberOfKids += 1;
3181 signal.defaultNumberOfKids = 0;
3282 return signal;
@@ -51,11 +101,13 @@ Elm.Native.Keyboard = function(elm) {
51101
52102 function is(key) { return keySignal(NList.member(key)); }
53103
104+ var lastPressed = Signal.dropRepeats(downEvents);
105+
54106 return elm.Native.Keyboard = {
55− isDown:is,
56− directions:F4(dir),
57− keysDown:keysDown,
58− lastPressed:lastKey
107+ isDown:is,
108+ directions:F4(dir),
109+ keysDown:keysDown,
110+ lastPressed:lastPressed
59111 };
60112
61113};