From 2e664f449e923561f205724f359cb411cca63205 Mon Sep 17 00:00:00 2001 From: ryan Date: Fri, 29 Aug 2008 21:43:34 +0000 Subject: [PATCH] Comment manipulation keyboard shorcuts from nbachiyski. see #7643 git-svn-id: http://svn.automattic.com/wordpress/trunk@8777 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-admin/css/colors-classic.css | 5 + wp-admin/css/colors-fresh.css | 5 + wp-admin/edit-comments.php | 1 + wp-admin/includes/template.php | 14 +- wp-admin/js/edit-comments.js | 1 + wp-includes/js/jquery/jquery.hotkeys.js | 126 ++++++++++++++++++ wp-includes/js/jquery/jquery.table-hotkeys.js | 76 +++++++++++ wp-includes/script-loader.php | 4 +- 8 files changed, 224 insertions(+), 8 deletions(-) create mode 100644 wp-includes/js/jquery/jquery.hotkeys.js create mode 100644 wp-includes/js/jquery/jquery.table-hotkeys.js 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'] = "" . __( 'Approve' ) . " | "; - $actions['unapprove'] = "" . __( 'Unapprove' ) . " | "; + $actions['approve'] = "" . __( 'Approve' ) . " | "; + $actions['unapprove'] = "" . __( 'Unapprove' ) . " | "; $actions['edit'] = "". __('Edit') . ' | '; if ( 'spam' != $the_comment_status ) - $actions['spam'] = "" . __( 'Spam' ) . ' | '; - $actions['delete'] = "" . __('Delete') . ''; + $actions['spam'] = "" . __( 'Spam' ) . ' | '; + $actions['delete'] = "" . __('Delete') . ''; if ( $comment_status ) { // not looking at all comments if ( 'approved' == $the_comment_status ) { - $actions['unapprove'] = "" . __( 'Unapprove' ) . ' | '; + $actions['unapprove'] = "" . __( 'Unapprove' ) . ' | '; unset($actions['approve']); } else { - $actions['approve'] = "" . __( 'Approve' ) . ' | '; + $actions['approve'] = "" . __( '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' );