diff --git a/Source/Interface/Keyboard.js b/Source/Interface/Keyboard.js index c1f93483..0a9d4de1 100644 --- a/Source/Interface/Keyboard.js +++ b/Source/Interface/Keyboard.js @@ -10,15 +10,33 @@ Script: Keyboard.js Perrin Westrich Aaron Newton */ - (function(){ - var modifier_regex = /^(shift|ctrl|alt|meta)$/; - Events.Keyboard = new Class({ + this.Keyboard = new Class({ Extends: Events, + Implements: Options, + + options: { +/* onActivate: $empty, + onDeactivate: $empty, + preventDefault: false, + caseSensitive: false, */ + eventType: 'keydown', + active: true, + events: {} + }, + + initialize: function(){ + params = Array.link(arguments, {elem: Element.type, options: Object.type}); + this.setOptions(params.options); + this.active = this.options.active; + this.addEvents(this.options.events); + this.attach(); + }, + addEvent: function(type, fn, internal){ var modifiers = $H(); var parts = type.split('+'); @@ -35,71 +53,47 @@ Script: Keyboard.js return this.parent(modType, fn, internal); }, - Modifiers: ['shift', 'ctrl', 'alt', 'meta'] + Modifiers: ['shift', 'ctrl', 'alt', 'meta'], + + + attach: function(attach) { + this.boundHandle = this.handle.bind(this); + (params.elem || window)[$pick(attach, true) ? 'addEvent' : 'removeEvent'](this.options.eventType, this.boundHandle); + }, + + handle: function(e){ + if (!this.active) return; + if (this.options.preventDefault) e.preventDefault(); + if (this.options.caseSensitive) key = e.shift ? e.key.toUpperCase() : e.key; + else key = e.key; + if (Event.Keys.hasValue(e.key)) key = Event.Keys.keyOf(e.key); + key = ''+key; + var modKey = ''; + if (e.shift) modKey += 'shift+'; + if (e.ctrl) modKey += 'ctrl+'; + if (e.alt) modKey += 'alt+'; + if (e.meta) modKey += 'meta+'; + this.fireEvent(modKey + key, e); + }, + + /* Perhaps should move these to a subclass? */ + activate: function(){ + this.active = true; + this.fireEvent('activate'); + return this; + }, + + deactivate: function(){ + this.active = false; + this.fireEvent('deactivate'); + return this; + }, + + toggleActive: function(){ + return this[this.active ? 'deactivate' : 'activate'](); + } + }); -})(); - - -var Keyboard = new Class({ - - Implements: [Options, Events.Keyboard], - - options: { -/* onActivate: $empty, - onDeactivate: $empty, - preventDefault: false, - caseSensitive: false, */ - eventType: 'keydown', - active: true, - events: {} - }, - - initialize: function(){ - params = Array.link(arguments, {elem: Element.type, options: Object.type}); - this.setOptions(params.options); - this.active = this.options.active; - this.addEvents(this.options.events); - this.attach(); - }, - - attach: function(attach) { - this.boundHandle = this.handle.bind(this); - (params.elem || window)[$pick(attach, true) ? 'addEvents' : 'removeEvents'](this.options.eventType, this.boundHandle); - }, - - handle: function(e){ - if (!this.active) return; - if (this.options.preventDefault) e.preventDefault(); - if (this.options.caseSensitive) key = e.shift ? e.key.toUpperCase() : e.key; - else key = e.key; - if (Event.Keys.hasValue(e.key)) key = Event.Keys.keyOf(e.key); - key = ''+key; - var modKey = ''; - if (e.shift) modKey += 'shift+'; - if (e.ctrl) modKey += 'ctrl+'; - if (e.alt) modKey += 'alt+'; - if (e.meta) modKey += 'meta+'; - this.fireEvent(modKey + key, e); - }, - -/* Perhaps should move these to a subclass? */ - activate: function(){ - this.active = true; - this.fireEvent('activate'); - return this; - }, - - deactivate: function(){ - this.active = false; - this.fireEvent('deactivate'); - return this; - }, - - toggleActive: function(){ - return this[this.active ? 'deactivate' : 'activate'](); - } - - -}); +})(); \ No newline at end of file diff --git a/Source/scripts.json b/Source/scripts.json index 8f1a9cb3..5dcded40 100644 --- a/Source/scripts.json +++ b/Source/scripts.json @@ -258,6 +258,11 @@ "Interface": { + "Keyboard": { + "deps": ["Class.Extras", "Element.Event"], + "desc": "Provides enhanced group key event management." + }, + "Mask": { "deps": ["Class.Extras", "Element.Style", "Element.Event", "Element.Position", "IframeShim"], "desc": "Creates a mask over a specified element." diff --git a/Tests/UserTests/Interface/Keyboard.all.html b/Tests/UserTests/Interface/Keyboard.all.html new file mode 100644 index 00000000..5bcded32 --- /dev/null +++ b/Tests/UserTests/Interface/Keyboard.all.html @@ -0,0 +1,19 @@ + + +
shift + a
+
enter
+
up
+
ctrl+d
+
space
+
escape
diff --git a/Tests/UserTests/Interface/Keyboard.all.js b/Tests/UserTests/Interface/Keyboard.all.js new file mode 100644 index 00000000..d4392222 --- /dev/null +++ b/Tests/UserTests/Interface/Keyboard.all.js @@ -0,0 +1,44 @@ +{ + tests: [ + { + title: "Keyboard:activate", + description: "Captures keyboard evnets as you type them.", + verify: "Enter the keys defined in the box to make them toggle colors. Do they toggle?", + before: function(){ + var kb = new Keyboard({ + preventDefault: true, + events: { + 'shift+a': function(){ + $('sa').toggleClass('active'); + }, + 'enter': function(){ + $('enter').toggleClass('active'); + }, + 'up': function(){ + $('up').toggleClass('active'); + }, + 'control+d': function(){ + $('ctrld').toggleClass('active'); + }, + 'space': function(){ + $('space').toggleClass('active'); + }, + 'esc': function(){ + $('escape').toggleClass('active'); + } + } + }) + $(document.body).store('kb', kb); + } + }, + { + title: "Keyboard:deactivate", + description: "Disables the keyboard set up in the previous test.", + verify: "Hitting any of the keys will no longer toggle the colors. Are the keys no longer active?", + before: function(){ + $(document.body).retrieve('kb').deactivate(); + } + } + + ] +} \ No newline at end of file diff --git a/Tests/UserTests/tests.json b/Tests/UserTests/tests.json index b80f9c49..a6744184 100644 --- a/Tests/UserTests/tests.json +++ b/Tests/UserTests/tests.json @@ -30,6 +30,7 @@ "Fx.Sort":['all'] }, "Interface":{ + "Keyboard":['all'], "Mask":['all'], "Scroller":['all'], "Tips":['all'],