Comment manipulation keyboard shorcuts from nbachiyski. see #7643

git-svn-id: http://svn.automattic.com/wordpress/trunk@8777 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
ryan 2008-08-29 21:43:34 +00:00
parent ac010ffb8d
commit 2e664f449e
8 changed files with 224 additions and 8 deletions

View File

@ -799,3 +799,8 @@ table.diff .diff-addedline ins {
border-color: #ddd;
background-color: #f8f8f8;
}
/* table vim shorcuts */
.vim-current {
background-color: #CFEBF7 !important;
}

View File

@ -782,3 +782,8 @@ table.diff .diff-addedline ins {
border-color: #ddd;
background-color: #f8f8f8;
}
/* table vim shorcuts */
.vim-current {
background-color: #E4F2FD !important;
}

View File

@ -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');

View File

@ -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'] = "<a href='$approve_url' class='dim:the-comment-list:comment-$comment->comment_ID:unapproved:e7e7d3:e7e7d3:new=approved' title='" . __( 'Approve this comment' ) . "'>" . __( 'Approve' ) . "</a> | ";
$actions['unapprove'] = "<a href='$unapprove_url' class='dim:the-comment-list:comment-$comment->comment_ID:unapproved:e7e7d3:e7e7d3:new=unapproved' title='" . __( 'Unapprove this comment' ) . "'>" . __( 'Unapprove' ) . "</a> | ";
$actions['approve'] = "<a href='$approve_url' class='dim:the-comment-list:comment-$comment->comment_ID:unapproved:e7e7d3:e7e7d3:new=approved vim-a' title='" . __( 'Approve this comment' ) . "'>" . __( 'Approve' ) . "</a> | ";
$actions['unapprove'] = "<a href='$unapprove_url' class='dim:the-comment-list:comment-$comment->comment_ID:unapproved:e7e7d3:e7e7d3:new=unapproved vim-u' title='" . __( 'Unapprove this comment' ) . "'>" . __( 'Unapprove' ) . "</a> | ";
$actions['edit'] = "<a href='comment.php?action=editcomment&amp;c={$comment->comment_ID}' title='" . __('Edit comment') . "'>". __('Edit') . '</a> | ';
if ( 'spam' != $the_comment_status )
$actions['spam'] = "<a href='$spam_url' class='delete:the-comment-list:comment-$comment->comment_ID::spam=1' title='" . __( 'Mark this comment as spam' ) . "'>" . __( 'Spam' ) . '</a> | ';
$actions['delete'] = "<a href='$delete_url' class='delete:the-comment-list:comment-$comment->comment_ID delete'>" . __('Delete') . '</a>';
$actions['spam'] = "<a href='$spam_url' class='delete:the-comment-list:comment-$comment->comment_ID::spam=1 vim-s vim-destructive' title='" . __( 'Mark this comment as spam' ) . "'>" . __( 'Spam' ) . '</a> | ';
$actions['delete'] = "<a href='$delete_url' class='delete:the-comment-list:comment-$comment->comment_ID delete vim-d vim-destructive'>" . __('Delete') . '</a>';
if ( $comment_status ) { // not looking at all comments
if ( 'approved' == $the_comment_status ) {
$actions['unapprove'] = "<a href='$unapprove_url' class='delete:the-comment-list:comment-$comment->comment_ID:e7e7d3:action=dim-comment' title='" . __( 'Unapprove this comment' ) . "'>" . __( 'Unapprove' ) . '</a> | ';
$actions['unapprove'] = "<a href='$unapprove_url' class='delete:the-comment-list:comment-$comment->comment_ID:e7e7d3:action=dim-comment vim-u vim-destructive' title='" . __( 'Unapprove this comment' ) . "'>" . __( 'Unapprove' ) . '</a> | ';
unset($actions['approve']);
} else {
$actions['approve'] = "<a href='$approve_url' class='delete:the-comment-list:comment-$comment->comment_ID:e7e7d3:action=dim-comment' title='" . __( 'Approve this comment' ) . "'>" . __( 'Approve' ) . '</a> | ';
$actions['approve'] = "<a href='$approve_url' class='delete:the-comment-list:comment-$comment->comment_ID:e7e7d3:action=dim-comment vim-a vim-destructive' title='" . __( 'Approve this comment' ) . "'>" . __( 'Approve' ) . '</a> | ';
unset($actions['unapprove']);
}
}
if ( 'spam' != $the_comment_status )
$actions['reply'] = '<span class="hide-if-no-js"> | <a onclick="commentReply.open(\''.$comment->comment_ID.'\',\''.$post->ID.'\',this);return false;" title="'.__('Reply to this comment').'" href="#">' . __('Reply') . '</a></span>';
$actions['reply'] = '<span class="hide-if-no-js"> | <a onclick="commentReply.open(\''.$comment->comment_ID.'\',\''.$post->ID.'\',this);return false;" class="vim-r" title="'.__('Reply to this comment').'" href="#">' . __('Reply') . '</a></span>';
$actions = apply_filters( 'comment_row_actions', $actions, $comment );

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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' );