diff --git a/wp-admin/css/colors-classic.css b/wp-admin/css/colors-classic.css
index d04ebb7fdf..7e1748dfed 100644
--- a/wp-admin/css/colors-classic.css
+++ b/wp-admin/css/colors-classic.css
@@ -799,3 +799,8 @@ table.diff .diff-addedline ins {
border-color: #ddd;
background-color: #f8f8f8;
}
+
+/* table vim shorcuts */
+.vim-current {
+ background-color: #CFEBF7 !important;
+}
\ No newline at end of file
diff --git a/wp-admin/css/colors-fresh.css b/wp-admin/css/colors-fresh.css
index 304db3b1fd..4a4e5a79db 100644
--- a/wp-admin/css/colors-fresh.css
+++ b/wp-admin/css/colors-fresh.css
@@ -782,3 +782,8 @@ table.diff .diff-addedline ins {
border-color: #ddd;
background-color: #f8f8f8;
}
+
+/* table vim shorcuts */
+.vim-current {
+ background-color: #E4F2FD !important;
+}
\ No newline at end of file
diff --git a/wp-admin/edit-comments.php b/wp-admin/edit-comments.php
index 2a7a30711e..5d2737f3ab 100644
--- a/wp-admin/edit-comments.php
+++ b/wp-admin/edit-comments.php
@@ -12,6 +12,7 @@ require_once('admin.php');
$title = __('Edit Comments');
wp_enqueue_script( 'admin-comments' );
wp_enqueue_script( 'admin-forms' );
+wp_enqueue_script( 'jquery-table-hotkeys' );
if ( !empty( $_REQUEST['delete_comments'] ) && isset($_REQUEST['action']) ) {
check_admin_referer('bulk-comments');
diff --git a/wp-admin/includes/template.php b/wp-admin/includes/template.php
index e77fd7a5a7..c617723b10 100644
--- a/wp-admin/includes/template.php
+++ b/wp-admin/includes/template.php
@@ -1016,25 +1016,25 @@ function _wp_comment_row( $comment_id, $mode, $comment_status, $checkbox = true
$actions = array();
if ( current_user_can('edit_post', $comment->comment_post_ID) ) {
- $actions['approve'] = " | ";
- $actions['unapprove'] = " | ";
+ $actions['approve'] = " | ";
+ $actions['unapprove'] = " | ";
$actions['edit'] = "". __('Edit') . ' | ';
if ( 'spam' != $the_comment_status )
- $actions['spam'] = " | ';
- $actions['delete'] = "';
+ $actions['spam'] = " | ';
+ $actions['delete'] = "';
if ( $comment_status ) { // not looking at all comments
if ( 'approved' == $the_comment_status ) {
- $actions['unapprove'] = " | ';
+ $actions['unapprove'] = " | ';
unset($actions['approve']);
} else {
- $actions['approve'] = " | ';
+ $actions['approve'] = " | ';
unset($actions['unapprove']);
}
}
if ( 'spam' != $the_comment_status )
- $actions['reply'] = ' | ' . __('Reply') . '';
+ $actions['reply'] = ' | ' . __('Reply') . '';
$actions = apply_filters( 'comment_row_actions', $actions, $comment );
diff --git a/wp-admin/js/edit-comments.js b/wp-admin/js/edit-comments.js
index 673c6ada39..1144b83ef5 100644
--- a/wp-admin/js/edit-comments.js
+++ b/wp-admin/js/edit-comments.js
@@ -235,6 +235,7 @@ commentReply = {
$(document).ready(function(){
if ( typeof QTags != 'undefined' )
ed_reply = new QTags('ed_reply', 'replycontent', 'replycontainer', 'more');
+ jQuery.table_hotkeys(jQuery('table.widefat'), ['a', 'u', 's', 'd', 'r']);
});
})(jQuery);
diff --git a/wp-includes/js/jquery/jquery.hotkeys.js b/wp-includes/js/jquery/jquery.hotkeys.js
new file mode 100644
index 0000000000..b545cd8211
--- /dev/null
+++ b/wp-includes/js/jquery/jquery.hotkeys.js
@@ -0,0 +1,126 @@
+/******************************************************************************************************************************
+
+ * @ Original idea by by Binny V A, Original version: 2.00.A
+ * @ http://www.openjs.com/scripts/events/keyboard_shortcuts/
+ * @ Original License : BSD
+
+ * @ jQuery Plugin by Tzury Bar Yochay
+ mail: tzury.by@gmail.com
+ blog: evalinux.wordpress.com
+ face: facebook.com/profile.php?id=513676303
+
+ (c) Copyrights 2007
+
+ * @ jQuery Plugin version Beta (0.0.2)
+ * @ License: jQuery-License.
+
+TODO:
+ add queue support (as in gmail) e.g. 'x' then 'y', etc.
+ add mouse + mouse wheel events.
+
+USAGE:
+ $.hotkeys.add('Ctrl+c', function(){ alert('copy anyone?');});
+ $.hotkeys.add('Ctrl+c', {target:'div#editor', type:'keyup', propagate: true},function(){ alert('copy anyone?');});>
+ $.hotkeys.remove('Ctrl+c');
+ $.hotkeys.remove('Ctrl+c', {target:'div#editor', type:'keypress'});
+
+******************************************************************************************************************************/
+(function (jQuery){
+ this.version = '(beta)(0.0.3)';
+ this.all = {};
+ this.special_keys = {
+ 27: 'esc', 9: 'tab', 32:'space', 13: 'return', 8:'backspace', 145: 'scroll', 20: 'capslock',
+ 144: 'numlock', 19:'pause', 45:'insert', 36:'home', 46:'del',35:'end', 33: 'pageup',
+ 34:'pagedown', 37:'left', 38:'up', 39:'right',40:'down', 112:'f1',113:'f2', 114:'f3',
+ 115:'f4', 116:'f5', 117:'f6', 118:'f7', 119:'f8', 120:'f9', 121:'f10', 122:'f11', 123:'f12'};
+
+ this.shift_nums = { "`":"~", "1":"!", "2":"@", "3":"#", "4":"$", "5":"%", "6":"^", "7":"&",
+ "8":"*", "9":"(", "0":")", "-":"_", "=":"+", ";":":", "'":"\"", ",":"<",
+ ".":">", "/":"?", "\\":"|" };
+
+ this.add = function(combi, options, callback) {
+ if (jQuery.isFunction(options)){
+ callback = options;
+ options = {};
+ }
+ var opt = {},
+ defaults = {type: 'keydown', propagate: false, disableInInput: false, target: jQuery('html')[0]},
+ that = this;
+ opt = jQuery.extend( opt , defaults, options || {} );
+ combi = combi.toLowerCase();
+
+ // inspect if keystroke matches
+ var inspector = function(event) {
+ event = jQuery.event.fix(event); // jQuery event normalization.
+ var element = event.target;
+ // @ TextNode -> nodeType == 3
+ element = (element.nodeType==3) ? element.parentNode : element;
+
+ if(opt['disableInInput']) { // Disable shortcut keys in Input, Textarea fields
+ var target = jQuery(element);
+ if( target.is("input") || target.is("textarea")){
+ return;
+ }
+ }
+ var code = event.which,
+ type = event.type,
+ character = String.fromCharCode(code).toLowerCase(),
+ special = that.special_keys[code],
+ shift = event.shiftKey,
+ ctrl = event.ctrlKey,
+ alt= event.altKey,
+ propagate = true, // default behaivour
+ mapPoint = null;
+
+ // in opera + safari, the event.target is unpredictable.
+ // for example: 'keydown' might be associated with HtmlBodyElement
+ // or the element where you last clicked with your mouse.
+ if (jQuery.browser.opera || jQuery.browser.safari){
+ while (!that.all[element] && element.parentNode){
+ element = element.parentNode;
+ }
+ }
+ var cbMap = that.all[element].events[type].callbackMap;
+ if(!shift && !ctrl && !alt) { // No Modifiers
+ mapPoint = cbMap[special] || cbMap[character]
+ }
+ // deals with combinaitons (alt|ctrl|shift+anything)
+ else{
+ var modif = '';
+ if(alt) modif +='alt+';
+ if(ctrl) modif+= 'ctrl+';
+ if(shift) modif += 'shift+';
+ // modifiers + special keys or modifiers + characters or modifiers + shift characters
+ mapPoint = cbMap[modif+special] || cbMap[modif+character] || cbMap[modif+that.shift_nums[character]]
+ }
+ if (mapPoint){
+ mapPoint.cb(event);
+ if(!mapPoint.propagate) {
+ event.stopPropagation();
+ event.preventDefault();
+ return false;
+ }
+ }
+ };
+ // first hook for this element
+ if (!this.all[opt.target]){
+ this.all[opt.target] = {events:{}};
+ }
+ if (!this.all[opt.target].events[opt.type]){
+ this.all[opt.target].events[opt.type] = {callbackMap: {}}
+ jQuery.event.add(opt.target, opt.type, inspector);
+ }
+ this.all[opt.target].events[opt.type].callbackMap[combi] = {cb: callback, propagate:opt.propagate};
+ return jQuery;
+ };
+ this.remove = function(exp, opt) {
+ opt = opt || {};
+ target = opt.target || jQuery('html')[0];
+ type = opt.type || 'keydown';
+ exp = exp.toLowerCase();
+ delete this.all[target].events[type].callbackMap[exp]
+ return jQuery;
+ };
+ jQuery.hotkeys = this;
+ return jQuery;
+})(jQuery);
\ No newline at end of file
diff --git a/wp-includes/js/jquery/jquery.table-hotkeys.js b/wp-includes/js/jquery/jquery.table-hotkeys.js
new file mode 100644
index 0000000000..b4792fa460
--- /dev/null
+++ b/wp-includes/js/jquery/jquery.table-hotkeys.js
@@ -0,0 +1,76 @@
+(function($){
+ $.table_hotkeys = function(table, keys, opts) {
+ opts = $.extend($.table_hotkeys.defaults, opts);
+ var selected_class = opts.class_prefix + opts.selected_suffix;
+ var destructive_class = opts.class_prefix + opts.destructive_suffix;
+ var set_current_row = function (tr) {
+ if ($.table_hotkeys.current_row) $.table_hotkeys.current_row.removeClass(selected_class);
+ tr.addClass(selected_class);
+ tr[0].scrollIntoView(false);
+ $.table_hotkeys.current_row = tr;
+ };
+ var next_row = function() {
+ var next = get_adjacent_row('next');
+ if (!next) return false;
+ set_current_row($(next));
+ return true;
+ };
+ var prev_row = function() {
+ var prev = get_adjacent_row('prev');
+ if (!prev) return false;
+ set_current_row($(prev));
+ return true;
+ };
+ var check = function() {
+ $(opts.checkbox_expr, $.table_hotkeys.current_row).each(function() {
+ this.checked = !this.checked;
+ });
+ };
+ var get_adjacent_row = function(which) {
+ if (!$.table_hotkeys.current_row) {
+ var start_row_dom = $(opts.cycle_expr, table)[opts.start_row_index];
+ $.table_hotkeys.current_row = $(start_row_dom);
+ return start_row_dom;
+ }
+ var method = 'prev' == which? $.fn.prevAll : $.fn.nextAll;
+ return method.call($.table_hotkeys.current_row, opts.cycle_expr).filter(':visible')[0];
+ }
+ var make_key_callback = function(expr) {
+ return function() {
+ var clickable = $(expr, $.table_hotkeys.current_row).filter(':visible');
+ if (!$($(clickable[0]).parent()[0]).is(':visible')) return false;
+ if (clickable.is('.'+destructive_class)) next_row() || prev_row();
+ clickable.click();
+ }
+ };
+ var make_key_expr = function(elem) {
+ if (typeof elem.key == 'string') {
+ key = elem.key;
+ if (typeof elem.expr == 'string')
+ expr = elem.expr;
+ else if (typeof elem.suffix == 'string')
+ expr = '.'+opts.class_prefix+elem.suffix;
+ else
+ expr = '.'+opts.class_prefix+elem.key;
+ } else {
+ key = elem;
+ expr = '.'+opts.class_prefix+elem;
+ }
+ return {key: key, expr: expr};
+ };
+ if (!$(opts.cycle_expr, table).length) return;
+ jQuery.hotkeys.add(opts.next_key, opts.hotkeys_opts, next_row);
+ jQuery.hotkeys.add(opts.prev_key, opts.hotkeys_opts, prev_row);
+ jQuery.hotkeys.add(opts.mark_key, opts.hotkeys_opts, check);
+ jQuery.each(keys, function() {
+ var key_expr = make_key_expr(this);
+ jQuery.hotkeys.add(key_expr.key, opts.hotkeys_opts, make_key_callback(key_expr.expr));
+ });
+
+ };
+ $.table_hotkeys.current_row = null;
+ $.table_hotkeys.defaults = {cycle_expr: 'tr', class_prefix: 'vim-', selected_suffix: 'current',
+ destructive_suffix: 'destructive', hotkeys_opts: {disableInInput: true, type: 'keypress'},
+ checkbox_expr: ':checkbox', next_key: 'j', prev_key: 'k', mark_key: 'x',
+ start_row_index: 1};
+})(jQuery);
\ No newline at end of file
diff --git a/wp-includes/script-loader.php b/wp-includes/script-loader.php
index 76f620f1ed..e9c9be2d71 100644
--- a/wp-includes/script-loader.php
+++ b/wp-includes/script-loader.php
@@ -72,6 +72,8 @@ function wp_default_scripts( &$scripts ) {
$scripts->add( 'interface', '/wp-includes/js/jquery/interface.js', array('jquery'), '1.2' );
$scripts->add( 'suggest', '/wp-includes/js/jquery/suggest.js', array('jquery'), '1.1b');
$scripts->add( 'schedule', '/wp-includes/js/jquery/jquery.schedule.js', array('jquery'), '20');
+ $scripts->add( 'jquery-hotkeys', '/wp-includes/js/jquery/jquery.hotkeys.js', array('jquery'), '0.0.2' );
+ $scripts->add( 'jquery-table-hotkeys', '/wp-includes/js/jquery/jquery.table-hotkeys.js', array('jquery', 'jquery-hotkeys'), '20080829' );
$scripts->add( 'thickbox', '/wp-includes/js/thickbox/thickbox.js', array('jquery'), '3.1-20080430');
$scripts->add( 'swfupload', '/wp-includes/js/swfupload/swfupload.js', false, '2.0.2-20080430');
$scripts->add( 'swfupload-degrade', '/wp-includes/js/swfupload/plugins/swfupload.graceful_degradation.js', array('swfupload'), '2.0.2');
@@ -224,7 +226,7 @@ function wp_default_styles( &$styles ) {
$rtl_styles = array( 'global', 'colors', 'dashboard', 'ie', 'install', 'login', 'media', 'theme-editor', 'upload', 'widgets', 'press-this', 'press-this-ie' );
- $styles->add( 'wp-admin', '/wp-admin/wp-admin.css' );
+ $styles->add( 'wp-admin', '/wp-admin/wp-admin.css', array(), '20080829' );
$styles->add_data( 'wp-admin', 'rtl', '/wp-admin/rtl.css' );
$styles->add( 'ie', '/wp-admin/css/ie.css' );