From a19b3bcc2849261043e0d354ac087d37473e5383 Mon Sep 17 00:00:00 2001 From: Ezequiel Surijon Date: Wed, 19 Oct 2016 16:02:52 -0300 Subject: [PATCH] Keyboard Shortcuts example (#1315) * Keyboard Shortcuts examle * rename example * add example description --- examples/keyboard-shortcuts/app.js | 61 ++++++++++ examples/keyboard-shortcuts/keyCodeMap.js | 107 ++++++++++++++++++ .../keyboard-shortcuts.html | 15 +++ .../keyboard-shortcuts/keyboard-shortcuts.js | 71 ++++++++++++ examples/keyboard-shortcuts/readme.md | 5 + 5 files changed, 259 insertions(+) create mode 100644 examples/keyboard-shortcuts/app.js create mode 100644 examples/keyboard-shortcuts/keyCodeMap.js create mode 100644 examples/keyboard-shortcuts/keyboard-shortcuts.html create mode 100644 examples/keyboard-shortcuts/keyboard-shortcuts.js create mode 100644 examples/keyboard-shortcuts/readme.md diff --git a/examples/keyboard-shortcuts/app.js b/examples/keyboard-shortcuts/app.js new file mode 100644 index 000000000..a458eb2d9 --- /dev/null +++ b/examples/keyboard-shortcuts/app.js @@ -0,0 +1,61 @@ +requirejs.config({ + paths: { + 'rx.all': '../../dist/rx.all', + 'jquery': 'https://code.jquery.com/jquery-3.1.0.min' + } +}); + +// Load the main app module to start the app +requirejs(['jquery', 'keyboard-shortcuts'], function($, kbShortcuts) { + + var shortuctSequences = Rx.Observable + .fromEvent(document.querySelector("button"), 'click') + .map( click => document.querySelector("input").value ) + .startWith('Ctrl+Alt+D', 'Ctrl+Shift+S', 'Trash') + .map( text => { + return { + id: text.replace(/\+/g,'_'), + text: text + } + }); + + var validShortcuts = shortuctSequences.filter( seq => kbShortcuts.validate(seq.text) ); + + var invalidShortcuts = shortuctSequences.filter( seq => !kbShortcuts.validate(seq.text) ); + + var shortCutPrompts = validShortcuts + .flatMap( obj => { + return kbShortcuts.create(obj.text) + .scan((acc, x, seed) => acc + 1, 0) + .map( count => { + return { + id: obj.id, + count: count + } + }) + } + ); + + + // Subscriptions for Side Effects + + validShortcuts.subscribe( + seq => { + var tmpl = '
  • ' + seq.text + ': 0
  • '; + var li = $(tmpl); + $('ul').append(li); + } + ); + + invalidShortcuts.subscribe( seq => { + var tmpl = '
  • Invalid sequence ' + seq.text + '
  • '; + var li = $(tmpl); + $('ul').append(li); + } + ); + + shortCutPrompts.subscribe( + obj => $('ul > li#' + obj.id + ' > span').eq(1).text(obj.count) + ); + +}); diff --git a/examples/keyboard-shortcuts/keyCodeMap.js b/examples/keyboard-shortcuts/keyCodeMap.js new file mode 100644 index 000000000..08ef5d8fa --- /dev/null +++ b/examples/keyboard-shortcuts/keyCodeMap.js @@ -0,0 +1,107 @@ +define([], function (Rx) { + + var map = { + 'backspace': 8, + 'tab': 9, + 'enter': 13, + 'shift': 16, + 'ctrl': 17, + 'alt': 18, + 'pause/break': 19, + 'caps lock': 20, + 'escape': 27, + 'page up': 33, + 'page down': 34, + 'end': 35, + 'home': 36, + 'left arrow': 37, + 'up arrow': 38, + 'right arrow': 39, + 'down arrow': 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, + 'left window key': 91, + 'right window key': 92, + 'select key': 93, + 'numpad 0': 96, + 'numpad 1': 97, + 'numpad 2': 98, + 'numpad 3': 99, + 'numpad 4': 100, + 'numpad 5': 101, + 'numpad 6': 102, + 'numpad 7': 103, + 'numpad 8': 104, + 'numpad 9': 105, + 'multiply': 106, + 'add': 107, + 'subtract': 109, + 'decimal point': 110, + '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, + 'num lock': 144, + 'scroll lock': 145, + 'semi-colon': 186, + 'equal sign': 187, + 'comma': 188, + 'dash': 189, + 'period': 190, + 'forward slash': 191, + 'grave accent': 192, + 'open bracket': 219, + 'back slash': 220, + 'close braket': 221, + 'single quote': 222, + }; + + return map; + +}); + diff --git a/examples/keyboard-shortcuts/keyboard-shortcuts.html b/examples/keyboard-shortcuts/keyboard-shortcuts.html new file mode 100644 index 000000000..f1e6da36c --- /dev/null +++ b/examples/keyboard-shortcuts/keyboard-shortcuts.html @@ -0,0 +1,15 @@ + + + + Keyboarb Shortcuts + + + + + + +

    Keyboard shortcuts:

    + + + diff --git a/examples/keyboard-shortcuts/keyboard-shortcuts.js b/examples/keyboard-shortcuts/keyboard-shortcuts.js new file mode 100644 index 000000000..21d74a967 --- /dev/null +++ b/examples/keyboard-shortcuts/keyboard-shortcuts.js @@ -0,0 +1,71 @@ +define(['rx.all', 'keyCodeMap'], function (Rx, keyCodeMap) { + + var keyDowns = Rx.Observable.fromEvent(document, 'keydown'); + + var keyUps = Rx.Observable.fromEvent(document, 'keyup'); + + var keyEvents = Rx.Observable + .merge(keyDowns, keyUps) + .distinctUntilChanged( + null, + (a,b) => { + return a.keyCode === b.keyCode && a.type === b.type; + } + ) + .share(); + + var createKeyPressStream = (charCode) => { + return { + char: charCode, + stream: keyEvents + .filter((event) => event.keyCode === charCode) + .map(function(e) { + return e.type; + }) + }; + } + + var createShortcutStream = (text) => { + + return Rx.Observable + .from(text.split('+')) + .map( c => { + var code = keyCodeMap[c.toLowerCase()]; + if(code === undefined) { + throw new Error('Invalid sequence ' + text); + } + return code; + }) + .map(createKeyPressStream) + .map( obj => obj.stream) + .toArray() + .flatMap( arr => { + return Rx.Observable.combineLatest(arr); + }) + .filter( arr => { + var isDown = true; + for (var i = 0; i < arr.length; i++) { + isDown = isDown && (arr[i] === 'keydown'); + } + return isDown; + }) + .map( x => text); + + } + + var validateSeq = text => { + var arr = text.split('+'); + for (var i = 0; i < arr.length; i++) { + if(keyCodeMap[arr[i].toLowerCase()] === undefined) { + return false; + } + } + return true; + } + + return { + create: createShortcutStream, + validate: validateSeq + }; + +}); diff --git a/examples/keyboard-shortcuts/readme.md b/examples/keyboard-shortcuts/readme.md new file mode 100644 index 000000000..781b0f744 --- /dev/null +++ b/examples/keyboard-shortcuts/readme.md @@ -0,0 +1,5 @@ +Keyboard shorcuts is an Observable that emit events when a specified sequence of characters are pressed at the same time. + +There is a function to create those Observables, which receives a text as parameter. + +Also it has a simple UI to create a and display keyboard shortcut occurrences, which shows usage of several Observables operators. \ No newline at end of file