@@ -4,29 +4,76 @@ 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+ isChanged = true;
50+ // We know that a change must only be one of the following cases
51+ if (parentID = down.id && !(NList.member(down.value)(this.value))) {
52+ this.value = NList.Cons(down.value, this.value);
53+ } else if (parentID = up.id) {
54+ var notEq = function(kc) { return kc !== up.value };
55+ this.value = NList.filter(notEq)(this.value);
56+ } else if (parentID = blur.id) {
57+ this.value = NList.Nil;
58+ }
59+ }
60+ if (count == n) {
61+ console.log(this.value);
62+ send(this, timestep, isChanged);
63+ isChanged = false;
64+ count = 0;
65+ }
66+ };
67+
68+ for (var i = n; i--; ) { args[i].kids.push(this); }
69+
70+ }
71+
72+ var keysDown = Signal.dropRepeats(new KeyMerge(downEvents,upEvents,blurEvents));
2773
2874 function keySignal(f) {
29− var signal = Signal.dropRepeats(A2(Signal.lift, f, keysDown));
75+ var signal = A2(Signal.lift, f, keysDown);
76+ // what's the significance of these two following lines? -jpm
3077 keysDown.defaultNumberOfKids += 1;
3178 signal.defaultNumberOfKids = 0;
3279 return signal;
@@ -51,11 +98,13 @@ Elm.Native.Keyboard = function(elm) {
5198
5299 function is(key) { return keySignal(NList.member(key)); }
53100
101+ var lastPressed = Signal.dropRepeats(downEvents);
102+
54103 return elm.Native.Keyboard = {
55− isDown:is,
56− directions:F4(dir),
57− keysDown:keysDown,
58− lastPressed:lastKey
104+ isDown:is,
105+ directions:F4(dir),
106+ keysDown:keysDown,
107+ lastPressed:lastPressed
59108 };
60109
61110};