From 7ea8e5925d4d2e18975712870d48912761ea1503 Mon Sep 17 00:00:00 2001 From: Marek Sacha Date: Tue, 27 Apr 2010 00:40:25 +0200 Subject: Reimplementation of Accesskeys in JavaScript (FS#1809) --- lib/scripts/hotkeys.js | 265 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 265 insertions(+) create mode 100644 lib/scripts/hotkeys.js (limited to 'lib/scripts/hotkeys.js') diff --git a/lib/scripts/hotkeys.js b/lib/scripts/hotkeys.js new file mode 100644 index 000000000..d062118fb --- /dev/null +++ b/lib/scripts/hotkeys.js @@ -0,0 +1,265 @@ +/** + * Some of these scripts were taken from TinyMCE (http://tinymce.moxiecode.com/) and were modified for DokuWiki + * + * Class handles accesskeys using javascript and also provides ability + * to register and use other hotkeys as well. + * + * @author Marek Sacha + */ +function Hotkeys() { + + this.shortcuts = new Array(); + + /** + * Set modifier keys, for instance: + * this.modifier = 'ctrl'; + * this.modifier = 'ctrl+shift'; + * this.modifier = 'ctrl+alt+shift'; + * this.modifier = 'alt'; + * this.modifier = 'alt+shift'; + */ + this.modifier = 'ctrl'; + + /** + * Initialization + * + * This function looks up all the accesskeys used in the current page + * (at anchor elements and input elements [type="submit"]) and registers + * appropriate shortcuts. + * + * @author Marek Sacha + */ + this.initialize = function() { + var t = this; + /** + * Lookup all anchors with accesskey and register event - go to anchor + * target. + */ + var anchors = document.getElementsByTagName("a"); + t.each(anchors, function(a) { + if (a.accessKey != "") { + t.addShortcut(t.modifier + '+' + a.accessKey, function() { + window.location.href = a.href; + }); + } + }); + + /** + * Lookup all input [type="submit"] with accesskey and register event - + * perform "click" on a button. + */ + var inputs = document.getElementsByTagName("input"); + t.each(inputs, function(i) { + if (i.type == "submit") { + t.addShortcut(t.modifier + '+' + i.accessKey, function() { + i.click(); + }); + } + }); + }; + + /** + * Keyup processing function + * Function returns true if keyboard event has registered handler, and + * executes the handler function. + * + * @param e KeyboardEvent + * @author Marek Sacha + * @return b boolean + */ + this.onkeyup = function(e) { + var t = this; + var v = t.findShortcut(e); + if (v != null && v != false) { + v.func.call(t); + return false; + } + return true; + }; + + /** + * Keydown processing function + * Function returns true if keyboard event has registered handler + * + * @param e KeyboardEvent + * @author Marek Sacha + * @return b boolean + */ + this.onkeydown = function(e) { + var t = this; + var v = t.findShortcut(e); + if (v != null && v != false) { + return false; + } + return true; + }; + + /** + * Keypress processing function + * Function returns true if keyboard event has registered handler + * + * @param e KeyboardEvent + * @author Marek Sacha + * @return b + */ + this.onkeypress = function(e) { + var t = this; + var v = t.findShortcut(e); + if (v != null && v != false) { + return false; + } + return true; + }; + + /** + * Register new shortcut + * + * This function registers new shortcuts, each shortcut is defined by its + * modifier keys and a key (with + as delimiter). If shortcut is pressed + * cmd_function is performed. + * + * For example: + * pa = "ctrl+alt+p"; + * pa = "shift+alt+s"; + * + * Full example of method usage: + * hotkeys.addShortcut('ctrl+s',function() { + * document.getElementByID('form_1').submit(); + * }); + * + * @param pa String description of the shortcut (ctrl+a, ctrl+shift+p, .. ) + * @param cmd_func Function to be called if shortcut is pressed + * @author Marek Sacha + */ + this.addShortcut = function(pa, cmd_func) { + var t = this; + + var o = { + func : cmd_func, + alt : false, + ctrl : false, + shift : false + }; + + t.each(t.explode(pa, '+'), function(v) { + switch (v) { + case 'alt': + case 'ctrl': + case 'shift': + o[v] = true; + break; + + default: + o.charCode = v.charCodeAt(0); + o.keyCode = v.toUpperCase().charCodeAt(0); + } + }); + + t.shortcuts.push((o.ctrl ? 'ctrl' : '') + ',' + (o.alt ? 'alt' : '') + ',' + (o.shift ? 'shift' : '') + ',' + o.keyCode, o); + + return true; + }; + + /** + * @property isMac + */ + this.isMac = (navigator.userAgent.indexOf('Mac') != -1); + + /** + * Apply function cb on each element of o in the namespace of s + * @param o Array of objects + * @param cb Function to be called on each object + * @param s Namespace to be used during call of cb (default namespace is o) + * @author Marek Sacha + */ + this.each = function(o, cb, s) { + var n, l; + + if (!o) + return 0; + + s = s || o; + + if (o.length !== undefined) { + // Indexed arrays, needed for Safari + for (n=0, l = o.length; n < l; n++) { + if (cb.call(s, o[n], n, o) === false) + return 0; + } + } else { + // Hashtables + for (n in o) { + if (o.hasOwnProperty(n)) { + if (cb.call(s, o[n], n, o) === false) + return 0; + } + } + } + + return 1; + }; + + /** + * Explode string according to delimiter + * @param s String + * @param d Delimiter (default ',') + * @author Marek Sacha + * @return a Array of tokens + */ + this.explode = function(s, d) { + return s.split(d || ','); + }; + + /** + * Find if the shortcut was registered + * + * @param e KeyboardEvent + * @author Marek Sacha + * @return v Shortcut structure or null if not found + */ + this.findShortcut = function (e) { + var t = this; + var v = null; + + /* No modifier key used - shortcut does not exist */ + if (!e.altKey && !e.ctrlKey && !e.metaKey) { + return v; + } + + t.each(t.shortcuts, function(o) { + if (t.isMac && o.ctrl != e.metaKey) + return; + else if (!t.isMac && o.ctrl != e.ctrlKey) + return; + + if (o.alt != e.altKey) + return; + + if (o.shift != e.shiftKey) + return; + + if (e.keyCode == o.keyCode || (e.charCode && e.charCode == o.charCode)) { + v = o; + return; + } + }); + return v; + }; +} + +addInitEvent(function(){ + var hotkeys = new Hotkeys(); + hotkeys.initialize(); + + addEvent(document,'keyup',function (e) { + return hotkeys.onkeyup.call(hotkeys,e); + }); + + addEvent(document,'keypress',function (e) { + return hotkeys.onkeypress.call(hotkeys,e); + }); + + addEvent(document,'keydown',function (e) { + return hotkeys.onkeydown.call(hotkeys,e); + }); +}); \ No newline at end of file -- cgit v1.2.3 From 4062d3d5c0c566751a1f098495e9aa836e8db9de Mon Sep 17 00:00:00 2001 From: Marek Sacha Date: Fri, 30 Apr 2010 17:18:40 +0200 Subject: Reimplementation of Accesskeys in javascript (FS#1809), toolbar accesskyes fix. --- lib/scripts/hotkeys.js | 58 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 16 deletions(-) (limited to 'lib/scripts/hotkeys.js') diff --git a/lib/scripts/hotkeys.js b/lib/scripts/hotkeys.js index d062118fb..9e2b9cb83 100644 --- a/lib/scripts/hotkeys.js +++ b/lib/scripts/hotkeys.js @@ -27,6 +27,9 @@ function Hotkeys() { * (at anchor elements and input elements [type="submit"]) and registers * appropriate shortcuts. * + * Secondly, initialization registers listeners on document to catch all + * keyboard events. + * * @author Marek Sacha */ this.initialize = function() { @@ -39,7 +42,7 @@ function Hotkeys() { t.each(anchors, function(a) { if (a.accessKey != "") { t.addShortcut(t.modifier + '+' + a.accessKey, function() { - window.location.href = a.href; + a.click(); }); } }); @@ -50,12 +53,41 @@ function Hotkeys() { */ var inputs = document.getElementsByTagName("input"); t.each(inputs, function(i) { - if (i.type == "submit") { + if (i.type == "submit" && i.accessKey != "") { t.addShortcut(t.modifier + '+' + i.accessKey, function() { i.click(); }); } }); + + /** + * Lookup all buttons with accesskey and register event - + * perform "click" on a button. + */ + var buttons = document.getElementsByTagName("button"); + t.each(buttons, function(b) { + if (b.accessKey != "") { + t.addShortcut(t.modifier + '+' + b.accessKey, function() { + b.click(); + }); + } + }); + + /** + * Register listeners on document to catch keyboard events. + */ + + addEvent(document,'keyup',function (e) { + return t.onkeyup.call(t,e); + }); + + addEvent(document,'keypress',function (e) { + return t.onkeypress.call(t,e); + }); + + addEvent(document,'keydown',function (e) { + return t.onkeydown.call(t,e); + }); }; /** @@ -247,19 +279,13 @@ function Hotkeys() { }; } -addInitEvent(function(){ +/** + * Init function for hotkeys. Called from js.php, to ensure hotkyes are initialized after toolbar. + * Call of addInitEvent(initializeHotkeys) is unnecessary now. + * + * @author Marek Sacha + */ +function initializeHotkeys() { var hotkeys = new Hotkeys(); hotkeys.initialize(); - - addEvent(document,'keyup',function (e) { - return hotkeys.onkeyup.call(hotkeys,e); - }); - - addEvent(document,'keypress',function (e) { - return hotkeys.onkeypress.call(hotkeys,e); - }); - - addEvent(document,'keydown',function (e) { - return hotkeys.onkeydown.call(hotkeys,e); - }); -}); \ No newline at end of file +} \ No newline at end of file -- cgit v1.2.3 From dd512d246ef7a200ca1137bb267aee87380a2f6c Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sat, 8 May 2010 12:09:19 +0200 Subject: use ALT as hotkey modifier --- lib/scripts/hotkeys.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/scripts/hotkeys.js') diff --git a/lib/scripts/hotkeys.js b/lib/scripts/hotkeys.js index 9e2b9cb83..2b696e78d 100644 --- a/lib/scripts/hotkeys.js +++ b/lib/scripts/hotkeys.js @@ -18,7 +18,7 @@ function Hotkeys() { * this.modifier = 'alt'; * this.modifier = 'alt+shift'; */ - this.modifier = 'ctrl'; + this.modifier = 'alt'; /** * Initialization @@ -288,4 +288,4 @@ function Hotkeys() { function initializeHotkeys() { var hotkeys = new Hotkeys(); hotkeys.initialize(); -} \ No newline at end of file +} -- cgit v1.2.3 From 7e1f9fd36044e5c651c71348897a3a3dc103d15a Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sat, 26 Jun 2010 13:54:29 +0200 Subject: Hotkey trigger is now CTRL-ALT FS#1958 Tests and feedbacks please! --- lib/scripts/hotkeys.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/scripts/hotkeys.js') diff --git a/lib/scripts/hotkeys.js b/lib/scripts/hotkeys.js index 2b696e78d..2b6fb6d96 100644 --- a/lib/scripts/hotkeys.js +++ b/lib/scripts/hotkeys.js @@ -18,7 +18,7 @@ function Hotkeys() { * this.modifier = 'alt'; * this.modifier = 'alt+shift'; */ - this.modifier = 'alt'; + this.modifier = 'ctrl+alt'; /** * Initialization -- cgit v1.2.3 From ce19c3413a33bcdabb5d71ec713555b540b12c84 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Sun, 27 Jun 2010 20:52:45 +0200 Subject: Use OS based Hotkey-Modifier FS#1958 Because ALT-GR fires a CTRL-ALT event on Windows systems, but ALT-GR is needed to write square brackets on German Keyboards, CTRL-ALT can not be used as modifier. This patch introdues OS dependent modifiers. Mac systems continue to use CTRL-ALT, all other systems use only ALT. Let's hope this works out. --- lib/scripts/hotkeys.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'lib/scripts/hotkeys.js') diff --git a/lib/scripts/hotkeys.js b/lib/scripts/hotkeys.js index 2b6fb6d96..c340c7f02 100644 --- a/lib/scripts/hotkeys.js +++ b/lib/scripts/hotkeys.js @@ -1,6 +1,6 @@ /** * Some of these scripts were taken from TinyMCE (http://tinymce.moxiecode.com/) and were modified for DokuWiki - * + * * Class handles accesskeys using javascript and also provides ability * to register and use other hotkeys as well. * @@ -17,6 +17,8 @@ function Hotkeys() { * this.modifier = 'ctrl+alt+shift'; * this.modifier = 'alt'; * this.modifier = 'alt+shift'; + * + * overwritten in intitialize (see below) */ this.modifier = 'ctrl+alt'; @@ -34,6 +36,14 @@ function Hotkeys() { */ this.initialize = function() { var t = this; + + //switch modifier key based on OS FS#1958 + if(is_macos){ + t.modifier = 'ctrl+alt'; + }else{ + t.modifier = 'alt'; + } + /** * Lookup all anchors with accesskey and register event - go to anchor * target. @@ -97,7 +107,7 @@ function Hotkeys() { * * @param e KeyboardEvent * @author Marek Sacha - * @return b boolean + * @return b boolean */ this.onkeyup = function(e) { var t = this; -- cgit v1.2.3 From b6bf4d661c4578a596f249f1a21ee588be6e4262 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Mon, 9 Aug 2010 21:55:45 +0200 Subject: remove accesskey once a JS handler was registered FS#2007 --- lib/scripts/hotkeys.js | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/scripts/hotkeys.js') diff --git a/lib/scripts/hotkeys.js b/lib/scripts/hotkeys.js index c340c7f02..356b691ea 100644 --- a/lib/scripts/hotkeys.js +++ b/lib/scripts/hotkeys.js @@ -54,6 +54,7 @@ function Hotkeys() { t.addShortcut(t.modifier + '+' + a.accessKey, function() { a.click(); }); + a.accessKey = ''; } }); @@ -67,6 +68,7 @@ function Hotkeys() { t.addShortcut(t.modifier + '+' + i.accessKey, function() { i.click(); }); + i.accessKey = ''; } }); @@ -80,6 +82,7 @@ function Hotkeys() { t.addShortcut(t.modifier + '+' + b.accessKey, function() { b.click(); }); + b.accessKey = ''; } }); -- cgit v1.2.3