diff --git a/app/assets/javascripts/application.js.erb.coffee b/app/assets/javascripts/application.js.erb.coffee index 3693840e..f37ea0b7 100644 --- a/app/assets/javascripts/application.js.erb.coffee +++ b/app/assets/javascripts/application.js.erb.coffee @@ -6,6 +6,7 @@ #= require nprogress #= require nprogress-turbolinks #= require growl +#= require cheet #= require_tree . NProgress.configure diff --git a/app/assets/javascripts/memes.coffee b/app/assets/javascripts/memes.coffee new file mode 100644 index 00000000..6f01e963 --- /dev/null +++ b/app/assets/javascripts/memes.coffee @@ -0,0 +1,5 @@ +memes = 'up up down down left right left right b a' +cheet memes, -> + cheet.disable memes + ($ "body").addClass 'fa-spin' + ($ "p.answerbox--question-text").each (i) -> ($ this).html ":^)" \ No newline at end of file diff --git a/lib/assets/javascripts/cheet.js b/lib/assets/javascripts/cheet.js new file mode 100644 index 00000000..dd0806f3 --- /dev/null +++ b/lib/assets/javascripts/cheet.js @@ -0,0 +1,279 @@ +/* +The MIT License (MIT) + +Copyright (c) 2013 Louis Acresti + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + + +(function (global) { + 'use strict'; + + var cheet, + sequences = {}, + keys = { + backspace: 8, + tab: 9, + enter: 13, + 'return': 13, + shift: 16, + '⇧': 16, + control: 17, + ctrl: 17, + '⌃': 17, + alt: 18, + option: 18, + '⌥': 18, + pause: 19, + capslock: 20, + esc: 27, + space: 32, + pageup: 33, + pagedown: 34, + end: 35, + home: 36, + left: 37, + L: 37, + '←': 37, + up: 38, + U: 38, + '↑': 38, + right: 39, + R: 39, + '→': 39, + down: 40, + D: 40, + '↓': 40, + insert: 45, + 'delete': 46, + '0': 48, + '1': 49, + '2': 50, + '3': 51, + '4': 52, + '5': 53, + '6': 54, + '7': 55, + '8': 56, + '9': 57, + a: 65, + b: 66, + c: 67, + d: 68, + e: 69, + f: 70, + g: 71, + h: 72, + i: 73, + j: 74, + k: 75, + l: 76, + m: 77, + n: 78, + o: 79, + p: 80, + q: 81, + r: 82, + s: 83, + t: 84, + u: 85, + v: 86, + w: 87, + x: 88, + y: 89, + z: 90, + '⌘': 91, + command: 91, + kp_0: 96, + kp_1: 97, + kp_2: 98, + kp_3: 99, + kp_4: 100, + kp_5: 101, + kp_6: 102, + kp_7: 103, + kp_8: 104, + kp_9: 105, + kp_multiply: 106, + kp_plus: 107, + kp_minus: 109, + kp_decimal: 110, + kp_divide: 111, + f1: 112, + f2: 113, + f3: 114, + f4: 115, + f5: 116, + f6: 117, + f7: 118, + f8: 119, + f9: 120, + f10: 121, + f11: 122, + f12: 123, + equal: 187, + '=': 187, + comma: 188, + ',': 188, + minus: 189, + '-': 189, + period: 190, + '.': 190 + }, + Sequence, + NOOP = function NOOP() {}, + held = {}; + + Sequence = function Sequence (str, next, fail, done) { + var i; + + this.str = str; + this.next = next ? next : NOOP; + this.fail = fail ? fail : NOOP; + this.done = done ? done : NOOP; + + this.seq = str.split(' '); + this.keys = []; + + for (i=0; i 0) { + this.reset(); + this.fail(this.str); + cheet.__fail(this.str); + } + return; + } + + this.next(this.str, this.seq[i], i, this.seq); + cheet.__next(this.str, this.seq[i], i, this.seq); + + if (++this.idx === this.keys.length) { + this.done(this.str); + cheet.__done(this.str); + this.reset(); + } + }; + + Sequence.prototype.reset = function () { + this.idx = 0; + }; + + cheet = function cheet (str, handlers) { + var next, fail, done; + + if (typeof handlers === 'function') { + done = handlers; + } else if (handlers !== null && handlers !== undefined) { + next = handlers.next; + fail = handlers.fail; + done = handlers.done; + } + + sequences[str] = new Sequence(str, next, fail, done); + }; + + cheet.disable = function disable (str) { + delete sequences[str]; + }; + + function keydown (e) { + var id, + k = e ? e.keyCode : event.keyCode; + + if (held[k]) return; + held[k] = true; + + for (id in sequences) { + sequences[id].keydown(k); + } + } + + function keyup (e) { + var k = e ? e.keyCode : event.keyCode; + held[k] = false; + } + + function resetHeldKeys (e) { + var k; + for (k in held) { + held[k] = false; + } + } + + function on (obj, type, fn) { + if (obj.addEventListener) { + obj.addEventListener(type, fn, false); + } else if (obj.attachEvent) { + obj['e' + type + fn] = fn; + obj[type + fn] = function () { + obj['e' + type + fn](window.event); + }; + obj.attachEvent('on' + type, obj[type + fn]); + } + } + + on(window, 'keydown', keydown); + on(window, 'keyup', keyup); + on(window, 'blur', resetHeldKeys); + on(window, 'focus', resetHeldKeys); + + cheet.__next = NOOP; + cheet.next = function next (fn) { + cheet.__next = fn === null ? NOOP : fn; + }; + + cheet.__fail = NOOP; + cheet.fail = function fail (fn) { + cheet.__fail = fn === null ? NOOP : fn; + }; + + cheet.__done = NOOP; + cheet.done = function done (fn) { + cheet.__done = fn === null ? NOOP : fn; + }; + + cheet.reset = function reset (id) { + var seq = sequences[id]; + if (!(seq instanceof Sequence)) { + console.warn('cheet: Unknown sequence: ' + id); + return; + } + + seq.reset(); + }; + + global.cheet = cheet; + + if (typeof define === 'function' && define.amd) { + define([], function () { return cheet; }); + } else if (typeof module !== 'undefined' && module !== null) { + module.exports = cheet; + } + +})(this);