1 /** |
1 /** |
|
2 * Handles updating and editing comments. |
|
3 * |
|
4 * @file This file contains functionality for the admin comments page. |
|
5 * @since 2.1.0 |
2 * @output wp-admin/js/edit-comments.js |
6 * @output wp-admin/js/edit-comments.js |
3 */ |
7 */ |
4 |
8 |
5 /* global adminCommentsL10n, thousandsSeparator, list_args, QTags, ajaxurl, wpAjax */ |
9 /* global adminCommentsSettings, thousandsSeparator, list_args, QTags, ajaxurl, wpAjax */ |
6 /* global commentReply, theExtraList, theList, setCommentsList */ |
10 /* global commentReply, theExtraList, theList, setCommentsList */ |
7 |
11 |
8 (function($) { |
12 (function($) { |
9 var getCount, updateCount, updateCountText, updatePending, updateApproved, |
13 var getCount, updateCount, updateCountText, updatePending, updateApproved, |
10 updateHtmlTitle, updateDashboardText, updateInModerationText, adminTitle = document.title, |
14 updateHtmlTitle, updateDashboardText, updateInModerationText, adminTitle = document.title, |
11 isDashboard = $('#dashboard_right_now').length, |
15 isDashboard = $('#dashboard_right_now').length, |
12 titleDiv, titleRegEx; |
16 titleDiv, titleRegEx, |
13 |
17 __ = wp.i18n.__; |
|
18 |
|
19 /** |
|
20 * Extracts a number from the content of a jQuery element. |
|
21 * |
|
22 * @since 2.9.0 |
|
23 * @access private |
|
24 * |
|
25 * @param {jQuery} el jQuery element. |
|
26 * |
|
27 * @return {number} The number found in the given element. |
|
28 */ |
14 getCount = function(el) { |
29 getCount = function(el) { |
15 var n = parseInt( el.html().replace(/[^0-9]+/g, ''), 10 ); |
30 var n = parseInt( el.html().replace(/[^0-9]+/g, ''), 10 ); |
16 if ( isNaN(n) ) { |
31 if ( isNaN(n) ) { |
17 return 0; |
32 return 0; |
18 } |
33 } |
19 return n; |
34 return n; |
20 }; |
35 }; |
21 |
36 |
|
37 /** |
|
38 * Updates an html element with a localized number string. |
|
39 * |
|
40 * @since 2.9.0 |
|
41 * @access private |
|
42 * |
|
43 * @param {jQuery} el The jQuery element to update. |
|
44 * @param {number} n Number to be put in the element. |
|
45 * |
|
46 * @return {void} |
|
47 */ |
22 updateCount = function(el, n) { |
48 updateCount = function(el, n) { |
23 var n1 = ''; |
49 var n1 = ''; |
24 if ( isNaN(n) ) { |
50 if ( isNaN(n) ) { |
25 return; |
51 return; |
26 } |
52 } |
33 n = n + n1; |
59 n = n + n1; |
34 } |
60 } |
35 el.html(n); |
61 el.html(n); |
36 }; |
62 }; |
37 |
63 |
|
64 /** |
|
65 * Updates the number of approved comments on a specific post and the filter bar. |
|
66 * |
|
67 * @since 4.4.0 |
|
68 * @access private |
|
69 * |
|
70 * @param {number} diff The amount to lower or raise the approved count with. |
|
71 * @param {number} commentPostId The ID of the post to be updated. |
|
72 * |
|
73 * @return {void} |
|
74 */ |
38 updateApproved = function( diff, commentPostId ) { |
75 updateApproved = function( diff, commentPostId ) { |
39 var postSelector = '.post-com-count-' + commentPostId, |
76 var postSelector = '.post-com-count-' + commentPostId, |
40 noClass = 'comment-count-no-comments', |
77 noClass = 'comment-count-no-comments', |
41 approvedClass = 'comment-count-approved', |
78 approvedClass = 'comment-count-approved', |
42 approved, |
79 approved, |
46 |
83 |
47 if ( ! commentPostId ) { |
84 if ( ! commentPostId ) { |
48 return; |
85 return; |
49 } |
86 } |
50 |
87 |
51 // cache selectors to not get dupes |
88 // Cache selectors to not get duplicates. |
52 approved = $( 'span.' + approvedClass, postSelector ); |
89 approved = $( 'span.' + approvedClass, postSelector ); |
53 noComments = $( 'span.' + noClass, postSelector ); |
90 noComments = $( 'span.' + noClass, postSelector ); |
54 |
91 |
55 approved.each(function() { |
92 approved.each(function() { |
56 var a = $(this), n = getCount(a) + diff; |
93 var a = $(this), n = getCount(a) + diff; |
74 } |
111 } |
75 updateCount( a, diff ); |
112 updateCount( a, diff ); |
76 }); |
113 }); |
77 }; |
114 }; |
78 |
115 |
|
116 /** |
|
117 * Updates a number count in all matched HTML elements |
|
118 * |
|
119 * @since 4.4.0 |
|
120 * @access private |
|
121 * |
|
122 * @param {string} selector The jQuery selector for elements to update a count |
|
123 * for. |
|
124 * @param {number} diff The amount to lower or raise the count with. |
|
125 * |
|
126 * @return {void} |
|
127 */ |
79 updateCountText = function( selector, diff ) { |
128 updateCountText = function( selector, diff ) { |
80 $( selector ).each(function() { |
129 $( selector ).each(function() { |
81 var a = $(this), n = getCount(a) + diff; |
130 var a = $(this), n = getCount(a) + diff; |
82 if ( n < 1 ) { |
131 if ( n < 1 ) { |
83 n = 0; |
132 n = 0; |
84 } |
133 } |
85 updateCount( a, n ); |
134 updateCount( a, n ); |
86 }); |
135 }); |
87 }; |
136 }; |
88 |
137 |
|
138 /** |
|
139 * Updates a text about comment count on the dashboard. |
|
140 * |
|
141 * @since 4.4.0 |
|
142 * @access private |
|
143 * |
|
144 * @param {Object} response Ajax response from the server that includes a |
|
145 * translated "comment count" message. |
|
146 * |
|
147 * @return {void} |
|
148 */ |
89 updateDashboardText = function( response ) { |
149 updateDashboardText = function( response ) { |
90 if ( ! isDashboard || ! response || ! response.i18n_comments_text ) { |
150 if ( ! isDashboard || ! response || ! response.i18n_comments_text ) { |
91 return; |
151 return; |
92 } |
152 } |
93 |
153 |
115 $( '.comment-mod-count', '#dashboard_right_now' ) |
176 $( '.comment-mod-count', '#dashboard_right_now' ) |
116 [ response.in_moderation > 0 ? 'removeClass' : 'addClass' ]( 'hidden' ); |
177 [ response.in_moderation > 0 ? 'removeClass' : 'addClass' ]( 'hidden' ); |
117 } |
178 } |
118 }; |
179 }; |
119 |
180 |
|
181 /** |
|
182 * Updates the title of the document with the number comments to be approved. |
|
183 * |
|
184 * @since 4.4.0 |
|
185 * @access private |
|
186 * |
|
187 * @param {number} diff The amount to lower or raise the number of to be |
|
188 * approved comments with. |
|
189 * |
|
190 * @return {void} |
|
191 */ |
120 updateHtmlTitle = function( diff ) { |
192 updateHtmlTitle = function( diff ) { |
121 var newTitle, regExMatch, titleCount, commentFrag; |
193 var newTitle, regExMatch, titleCount, commentFrag; |
122 |
194 |
123 titleRegEx = titleRegEx || new RegExp( adminCommentsL10n.docTitleCommentsCount.replace( '%s', '\\([0-9' + thousandsSeparator + ']+\\)' ) + '?' ); |
195 /* translators: %s: Comments count. */ |
124 // count funcs operate on a $'d element |
196 titleRegEx = titleRegEx || new RegExp( __( 'Comments (%s)' ).replace( '%s', '\\([0-9' + thousandsSeparator + ']+\\)' ) + '?' ); |
|
197 // Count funcs operate on a $'d element. |
125 titleDiv = titleDiv || $( '<div />' ); |
198 titleDiv = titleDiv || $( '<div />' ); |
126 newTitle = adminTitle; |
199 newTitle = adminTitle; |
127 |
200 |
128 commentFrag = titleRegEx.exec( document.title ); |
201 commentFrag = titleRegEx.exec( document.title ); |
129 if ( commentFrag ) { |
202 if ( commentFrag ) { |
137 |
210 |
138 if ( titleCount >= 1 ) { |
211 if ( titleCount >= 1 ) { |
139 updateCount( titleDiv, titleCount ); |
212 updateCount( titleDiv, titleCount ); |
140 regExMatch = titleRegEx.exec( document.title ); |
213 regExMatch = titleRegEx.exec( document.title ); |
141 if ( regExMatch ) { |
214 if ( regExMatch ) { |
142 newTitle = document.title.replace( regExMatch[0], adminCommentsL10n.docTitleCommentsCount.replace( '%s', titleDiv.text() ) + ' ' ); |
215 /* translators: %s: Comments count. */ |
|
216 newTitle = document.title.replace( regExMatch[0], __( 'Comments (%s)' ).replace( '%s', titleDiv.text() ) + ' ' ); |
143 } |
217 } |
144 } else { |
218 } else { |
145 regExMatch = titleRegEx.exec( newTitle ); |
219 regExMatch = titleRegEx.exec( newTitle ); |
146 if ( regExMatch ) { |
220 if ( regExMatch ) { |
147 newTitle = newTitle.replace( regExMatch[0], adminCommentsL10n.docTitleComments ); |
221 newTitle = newTitle.replace( regExMatch[0], __( 'Comments' ) ); |
148 } |
222 } |
149 } |
223 } |
150 document.title = newTitle; |
224 document.title = newTitle; |
151 }; |
225 }; |
152 |
226 |
|
227 /** |
|
228 * Updates the number of pending comments on a specific post and the filter bar. |
|
229 * |
|
230 * @since 3.2.0 |
|
231 * @access private |
|
232 * |
|
233 * @param {number} diff The amount to lower or raise the pending count with. |
|
234 * @param {number} commentPostId The ID of the post to be updated. |
|
235 * |
|
236 * @return {void} |
|
237 */ |
153 updatePending = function( diff, commentPostId ) { |
238 updatePending = function( diff, commentPostId ) { |
154 var postSelector = '.post-com-count-' + commentPostId, |
239 var postSelector = '.post-com-count-' + commentPostId, |
155 noClass = 'comment-count-no-pending', |
240 noClass = 'comment-count-no-pending', |
156 noParentClass = 'post-com-count-no-pending', |
241 noParentClass = 'post-com-count-no-pending', |
157 pendingClass = 'comment-count-pending', |
242 pendingClass = 'comment-count-pending', |
172 |
257 |
173 if ( ! commentPostId ) { |
258 if ( ! commentPostId ) { |
174 return; |
259 return; |
175 } |
260 } |
176 |
261 |
177 // cache selectors to not get dupes |
262 // Cache selectors to not get dupes. |
178 pending = $( 'span.' + pendingClass, postSelector ); |
263 pending = $( 'span.' + pendingClass, postSelector ); |
179 noPending = $( 'span.' + noClass, postSelector ); |
264 noPending = $( 'span.' + noClass, postSelector ); |
180 |
265 |
181 pending.each(function() { |
266 pending.each(function() { |
182 var a = $(this), n = getCount(a) + diff; |
267 var a = $(this), n = getCount(a) + diff; |
204 } |
289 } |
205 updateCount( a, diff ); |
290 updateCount( a, diff ); |
206 }); |
291 }); |
207 }; |
292 }; |
208 |
293 |
|
294 /** |
|
295 * Initializes the comments list. |
|
296 * |
|
297 * @since 4.4.0 |
|
298 * |
|
299 * @global |
|
300 * |
|
301 * @return {void} |
|
302 */ |
209 window.setCommentsList = function() { |
303 window.setCommentsList = function() { |
210 var totalInput, perPageInput, pageInput, dimAfter, delBefore, updateTotalCount, delAfter, refillTheExtraList, diff, |
304 var totalInput, perPageInput, pageInput, dimAfter, delBefore, updateTotalCount, delAfter, refillTheExtraList, diff, |
211 lastConfidentTime = 0; |
305 lastConfidentTime = 0; |
212 |
306 |
213 totalInput = $('input[name="_total"]', '#comments-form'); |
307 totalInput = $('input[name="_total"]', '#comments-form'); |
214 perPageInput = $('input[name="_per_page"]', '#comments-form'); |
308 perPageInput = $('input[name="_per_page"]', '#comments-form'); |
215 pageInput = $('input[name="_page"]', '#comments-form'); |
309 pageInput = $('input[name="_page"]', '#comments-form'); |
216 |
310 |
217 // Updates the current total (stored in the _total input) |
311 /** |
|
312 * Updates the total with the latest count. |
|
313 * |
|
314 * The time parameter makes sure that we only update the total if this value is |
|
315 * a newer value than we previously received. |
|
316 * |
|
317 * The time and setConfidentTime parameters make sure that we only update the |
|
318 * total when necessary. So a value that has been generated earlier will not |
|
319 * update the total. |
|
320 * |
|
321 * @since 2.8.0 |
|
322 * @access private |
|
323 * |
|
324 * @param {number} total Total number of comments. |
|
325 * @param {number} time Unix timestamp of response. |
|
326 * @param {boolean} setConfidentTime Whether to update the last confident time |
|
327 * with the given time. |
|
328 * |
|
329 * @return {void} |
|
330 */ |
218 updateTotalCount = function( total, time, setConfidentTime ) { |
331 updateTotalCount = function( total, time, setConfidentTime ) { |
219 if ( time < lastConfidentTime ) |
332 if ( time < lastConfidentTime ) |
220 return; |
333 return; |
221 |
334 |
222 if ( setConfidentTime ) |
335 if ( setConfidentTime ) |
223 lastConfidentTime = time; |
336 lastConfidentTime = time; |
224 |
337 |
225 totalInput.val( total.toString() ); |
338 totalInput.val( total.toString() ); |
226 }; |
339 }; |
227 |
340 |
228 // this fires when viewing "All" |
341 /** |
|
342 * Changes DOM that need to be changed after a list item has been dimmed. |
|
343 * |
|
344 * @since 2.5.0 |
|
345 * @access private |
|
346 * |
|
347 * @param {Object} r Ajax response object. |
|
348 * @param {Object} settings Settings for the wpList object. |
|
349 * |
|
350 * @return {void} |
|
351 */ |
229 dimAfter = function( r, settings ) { |
352 dimAfter = function( r, settings ) { |
230 var editRow, replyID, replyButton, response, |
353 var editRow, replyID, replyButton, response, |
231 c = $( '#' + settings.element ); |
354 c = $( '#' + settings.element ); |
232 |
355 |
233 if ( true !== settings.parsed ) { |
356 if ( true !== settings.parsed ) { |
238 replyID = $('#comment_ID', editRow).val(); |
361 replyID = $('#comment_ID', editRow).val(); |
239 replyButton = $('#replybtn', editRow); |
362 replyButton = $('#replybtn', editRow); |
240 |
363 |
241 if ( c.is('.unapproved') ) { |
364 if ( c.is('.unapproved') ) { |
242 if ( settings.data.id == replyID ) |
365 if ( settings.data.id == replyID ) |
243 replyButton.text(adminCommentsL10n.replyApprove); |
366 replyButton.text( __( 'Approve and Reply' ) ); |
244 |
367 |
245 c.find( '.row-actions span.view' ).addClass( 'hidden' ).end() |
368 c.find( '.row-actions span.view' ).addClass( 'hidden' ).end() |
246 .find( 'div.comment_status' ).html( '0' ); |
369 .find( 'div.comment_status' ).html( '0' ); |
247 |
370 |
248 } else { |
371 } else { |
249 if ( settings.data.id == replyID ) |
372 if ( settings.data.id == replyID ) |
250 replyButton.text(adminCommentsL10n.reply); |
373 replyButton.text( __( 'Reply' ) ); |
251 |
374 |
252 c.find( '.row-actions span.view' ).removeClass( 'hidden' ).end() |
375 c.find( '.row-actions span.view' ).removeClass( 'hidden' ).end() |
253 .find( 'div.comment_status' ).html( '1' ); |
376 .find( 'div.comment_status' ).html( '1' ); |
254 } |
377 } |
255 |
378 |
263 updatePending( diff ); |
386 updatePending( diff ); |
264 updateApproved( -1 * diff ); |
387 updateApproved( -1 * diff ); |
265 } |
388 } |
266 }; |
389 }; |
267 |
390 |
268 // Send current total, page, per_page and url |
391 /** |
|
392 * Handles marking a comment as spam or trashing the comment. |
|
393 * |
|
394 * Is executed in the list delBefore hook. |
|
395 * |
|
396 * @since 2.8.0 |
|
397 * @access private |
|
398 * |
|
399 * @param {Object} settings Settings for the wpList object. |
|
400 * @param {HTMLElement} list Comments table element. |
|
401 * |
|
402 * @return {Object} The settings object. |
|
403 */ |
269 delBefore = function( settings, list ) { |
404 delBefore = function( settings, list ) { |
270 var note, id, el, n, h, a, author, |
405 var note, id, el, n, h, a, author, |
271 action = false, |
406 action = false, |
272 wpListsData = $( settings.target ).attr( 'data-wp-lists' ); |
407 wpListsData = $( settings.target ).attr( 'data-wp-lists' ); |
273 |
408 |
310 a.attr('class', 'vim-z vim-destructive aria-button-if-js'); |
445 a.attr('class', 'vim-z vim-destructive aria-button-if-js'); |
311 $('.avatar', el).first().clone().prependTo('#undo-' + id + ' .' + action + '-undo-inside'); |
446 $('.avatar', el).first().clone().prependTo('#undo-' + id + ' .' + action + '-undo-inside'); |
312 |
447 |
313 a.click(function( e ){ |
448 a.click(function( e ){ |
314 e.preventDefault(); |
449 e.preventDefault(); |
315 e.stopPropagation(); // ticket #35904 |
450 e.stopPropagation(); // Ticket #35904. |
316 list.wpList.del(this); |
451 list.wpList.del(this); |
317 $('#undo-' + id).css( {backgroundColor:'#ceb'} ).fadeOut(350, function(){ |
452 $('#undo-' + id).css( {backgroundColor:'#ceb'} ).fadeOut(350, function(){ |
318 $(this).remove(); |
453 $(this).remove(); |
319 $('#comment-' + id).css('backgroundColor', '').fadeIn(300, function(){ $(this).show(); }); |
454 $('#comment-' + id).css('backgroundColor', '').fadeIn(300, function(){ $(this).show(); }); |
320 }); |
455 }); |
322 } |
457 } |
323 |
458 |
324 return settings; |
459 return settings; |
325 }; |
460 }; |
326 |
461 |
327 // In admin-ajax.php, we send back the unix time stamp instead of 1 on success |
462 /** |
|
463 * Handles actions that need to be done after marking as spam or thrashing a |
|
464 * comment. |
|
465 * |
|
466 * The ajax requests return the unix time stamp a comment was marked as spam or |
|
467 * trashed. We use this to have a correct total amount of comments. |
|
468 * |
|
469 * @since 2.5.0 |
|
470 * @access private |
|
471 * |
|
472 * @param {Object} r Ajax response object. |
|
473 * @param {Object} settings Settings for the wpList object. |
|
474 * |
|
475 * @return {void} |
|
476 */ |
328 delAfter = function( r, settings ) { |
477 delAfter = function( r, settings ) { |
329 var total_items_i18n, total, animated, animatedCallback, |
478 var total_items_i18n, total, animated, animatedCallback, |
330 response = true === settings.parsed ? {} : settings.parsed.responses[0], |
479 response = true === settings.parsed ? {} : settings.parsed.responses[0], |
331 commentStatus = true === settings.parsed ? '' : response.supplemental.status, |
480 commentStatus = true === settings.parsed ? '' : response.supplemental.status, |
332 commentPostId = true === settings.parsed ? '' : response.supplemental.postId, |
481 commentPostId = true === settings.parsed ? '' : response.supplemental.postId, |
343 */ |
492 */ |
344 approved = commentRow.hasClass( 'approved' ) && ! commentRow.hasClass( 'unapproved' ), |
493 approved = commentRow.hasClass( 'approved' ) && ! commentRow.hasClass( 'unapproved' ), |
345 unapproved = commentRow.hasClass( 'unapproved' ), |
494 unapproved = commentRow.hasClass( 'unapproved' ), |
346 spammed = commentRow.hasClass( 'spam' ), |
495 spammed = commentRow.hasClass( 'spam' ), |
347 trashed = commentRow.hasClass( 'trash' ), |
496 trashed = commentRow.hasClass( 'trash' ), |
348 undoing = false; // ticket #35904 |
497 undoing = false; // Ticket #35904. |
349 |
498 |
350 updateDashboardText( newTotal ); |
499 updateDashboardText( newTotal ); |
351 updateInModerationText( newTotal ); |
500 updateInModerationText( newTotal ); |
352 |
501 |
353 // the order of these checks is important |
502 /* |
354 // .unspam can also have .approve or .unapprove |
503 * The order of these checks is important. |
355 // .untrash can also have .approve or .unapprove |
504 * .unspam can also have .approve or .unapprove. |
|
505 * .untrash can also have .approve or .unapprove. |
|
506 */ |
356 |
507 |
357 if ( targetParent.is( 'span.undo' ) ) { |
508 if ( targetParent.is( 'span.undo' ) ) { |
358 // the comment was spammed |
509 // The comment was spammed. |
359 if ( targetParent.hasClass( 'unspam' ) ) { |
510 if ( targetParent.hasClass( 'unspam' ) ) { |
360 spamDiff = -1; |
511 spamDiff = -1; |
361 |
512 |
362 if ( 'trash' === commentStatus ) { |
513 if ( 'trash' === commentStatus ) { |
363 trashDiff = 1; |
514 trashDiff = 1; |
380 } |
531 } |
381 } |
532 } |
382 |
533 |
383 undoing = true; |
534 undoing = true; |
384 |
535 |
385 // user clicked "Spam" |
536 // User clicked "Spam". |
386 } else if ( targetParent.is( 'span.spam' ) ) { |
537 } else if ( targetParent.is( 'span.spam' ) ) { |
387 // the comment is currently approved |
538 // The comment is currently approved. |
388 if ( approved ) { |
539 if ( approved ) { |
389 approvedDiff = -1; |
540 approvedDiff = -1; |
390 // the comment is currently pending |
541 // The comment is currently pending. |
391 } else if ( unapproved ) { |
542 } else if ( unapproved ) { |
392 pendingDiff = -1; |
543 pendingDiff = -1; |
393 // the comment was in the trash |
544 // The comment was in the Trash. |
394 } else if ( trashed ) { |
545 } else if ( trashed ) { |
395 trashDiff = -1; |
546 trashDiff = -1; |
396 } |
547 } |
397 // you can't spam an item on the spam screen |
548 // You can't spam an item on the Spam screen. |
398 spamDiff = 1; |
549 spamDiff = 1; |
399 |
550 |
400 // user clicked "Unspam" |
551 // User clicked "Unspam". |
401 } else if ( targetParent.is( 'span.unspam' ) ) { |
552 } else if ( targetParent.is( 'span.unspam' ) ) { |
402 if ( approved ) { |
553 if ( approved ) { |
403 pendingDiff = 1; |
554 pendingDiff = 1; |
404 } else if ( unapproved ) { |
555 } else if ( unapproved ) { |
405 approvedDiff = 1; |
556 approvedDiff = 1; |
406 } else if ( trashed ) { |
557 } else if ( trashed ) { |
407 // the comment was previously approved |
558 // The comment was previously approved. |
408 if ( targetParent.hasClass( 'approve' ) ) { |
559 if ( targetParent.hasClass( 'approve' ) ) { |
409 approvedDiff = 1; |
560 approvedDiff = 1; |
410 // the comment was previously pending |
561 // The comment was previously pending. |
411 } else if ( targetParent.hasClass( 'unapprove' ) ) { |
562 } else if ( targetParent.hasClass( 'unapprove' ) ) { |
412 pendingDiff = 1; |
563 pendingDiff = 1; |
413 } |
564 } |
414 } else if ( spammed ) { |
565 } else if ( spammed ) { |
415 if ( targetParent.hasClass( 'approve' ) ) { |
566 if ( targetParent.hasClass( 'approve' ) ) { |
417 |
568 |
418 } else if ( targetParent.hasClass( 'unapprove' ) ) { |
569 } else if ( targetParent.hasClass( 'unapprove' ) ) { |
419 pendingDiff = 1; |
570 pendingDiff = 1; |
420 } |
571 } |
421 } |
572 } |
422 // you can Unspam an item on the spam screen |
573 // You can unspam an item on the Spam screen. |
423 spamDiff = -1; |
574 spamDiff = -1; |
424 |
575 |
425 // user clicked "Trash" |
576 // User clicked "Trash". |
426 } else if ( targetParent.is( 'span.trash' ) ) { |
577 } else if ( targetParent.is( 'span.trash' ) ) { |
427 if ( approved ) { |
578 if ( approved ) { |
428 approvedDiff = -1; |
579 approvedDiff = -1; |
429 } else if ( unapproved ) { |
580 } else if ( unapproved ) { |
430 pendingDiff = -1; |
581 pendingDiff = -1; |
431 // the comment was in the spam queue |
582 // The comment was in the spam queue. |
432 } else if ( spammed ) { |
583 } else if ( spammed ) { |
433 spamDiff = -1; |
584 spamDiff = -1; |
434 } |
585 } |
435 // you can't trash an item on the trash screen |
586 // You can't trash an item on the Trash screen. |
436 trashDiff = 1; |
587 trashDiff = 1; |
437 |
588 |
438 // user clicked "Restore" |
589 // User clicked "Restore". |
439 } else if ( targetParent.is( 'span.untrash' ) ) { |
590 } else if ( targetParent.is( 'span.untrash' ) ) { |
440 if ( approved ) { |
591 if ( approved ) { |
441 pendingDiff = 1; |
592 pendingDiff = 1; |
442 } else if ( unapproved ) { |
593 } else if ( unapproved ) { |
443 approvedDiff = 1; |
594 approvedDiff = 1; |
446 approvedDiff = 1; |
597 approvedDiff = 1; |
447 } else if ( targetParent.hasClass( 'unapprove' ) ) { |
598 } else if ( targetParent.hasClass( 'unapprove' ) ) { |
448 pendingDiff = 1; |
599 pendingDiff = 1; |
449 } |
600 } |
450 } |
601 } |
451 // you can't go from trash to spam |
602 // You can't go from Trash to Spam. |
452 // you can untrash on the trash screen |
603 // You can untrash on the Trash screen. |
453 trashDiff = -1; |
604 trashDiff = -1; |
454 |
605 |
455 // User clicked "Approve" |
606 // User clicked "Approve". |
456 } else if ( targetParent.is( 'span.approve:not(.unspam):not(.untrash)' ) ) { |
607 } else if ( targetParent.is( 'span.approve:not(.unspam):not(.untrash)' ) ) { |
457 approvedDiff = 1; |
608 approvedDiff = 1; |
458 pendingDiff = -1; |
609 pendingDiff = -1; |
459 |
610 |
460 // User clicked "Unapprove" |
611 // User clicked "Unapprove". |
461 } else if ( targetParent.is( 'span.unapprove:not(.unspam):not(.untrash)' ) ) { |
612 } else if ( targetParent.is( 'span.unapprove:not(.unspam):not(.untrash)' ) ) { |
462 approvedDiff = -1; |
613 approvedDiff = -1; |
463 pendingDiff = 1; |
614 pendingDiff = 1; |
464 |
615 |
465 // User clicked "Delete Permanently" |
616 // User clicked "Delete Permanently". |
466 } else if ( targetParent.is( 'span.delete' ) ) { |
617 } else if ( targetParent.is( 'span.delete' ) ) { |
467 if ( spammed ) { |
618 if ( spammed ) { |
468 spamDiff = -1; |
619 spamDiff = -1; |
469 } else if ( trashed ) { |
620 } else if ( trashed ) { |
470 trashDiff = -1; |
621 trashDiff = -1; |
508 |
659 |
509 if ( 'object' === typeof r ) { |
660 if ( 'object' === typeof r ) { |
510 if ( response.supplemental.total_items_i18n && lastConfidentTime < response.supplemental.time ) { |
661 if ( response.supplemental.total_items_i18n && lastConfidentTime < response.supplemental.time ) { |
511 total_items_i18n = response.supplemental.total_items_i18n || ''; |
662 total_items_i18n = response.supplemental.total_items_i18n || ''; |
512 if ( total_items_i18n ) { |
663 if ( total_items_i18n ) { |
513 $('.displaying-num').text( total_items_i18n ); |
664 $('.displaying-num').text( total_items_i18n.replace( ' ', String.fromCharCode( 160 ) ) ); |
514 $('.total-pages').text( response.supplemental.total_pages_i18n ); |
665 $('.total-pages').text( response.supplemental.total_pages_i18n.replace( ' ', String.fromCharCode( 160 ) ) ); |
515 $('.tablenav-pages').find('.next-page, .last-page').toggleClass('disabled', response.supplemental.total_pages == $('.current-page').val()); |
666 $('.tablenav-pages').find('.next-page, .last-page').toggleClass('disabled', response.supplemental.total_pages == $('.current-page').val()); |
516 } |
667 } |
517 updateTotalCount( total, response.supplemental.time, true ); |
668 updateTotalCount( total, response.supplemental.time, true ); |
518 } else if ( response.supplemental.time ) { |
669 } else if ( response.supplemental.time ) { |
519 updateTotalCount( total, response.supplemental.time, false ); |
670 updateTotalCount( total, response.supplemental.time, false ); |
555 return; |
716 return; |
556 } |
717 } |
557 |
718 |
558 if (ev) { |
719 if (ev) { |
559 theExtraList.empty(); |
720 theExtraList.empty(); |
560 args.number = Math.min(8, per_page); // see WP_Comments_List_Table::prepare_items() @ class-wp-comments-list-table.php |
721 args.number = Math.min(8, per_page); // See WP_Comments_List_Table::prepare_items() in class-wp-comments-list-table.php. |
561 } else { |
722 } else { |
562 args.number = 1; |
723 args.number = 1; |
563 args.offset = Math.min(8, per_page) - 1; // fetch only the next item on the extra list |
724 args.offset = Math.min(8, per_page) - 1; // Fetch only the next item on the extra list. |
564 } |
725 } |
565 |
726 |
566 args.no_placeholder = true; |
727 args.no_placeholder = true; |
567 |
728 |
568 args.paged ++; |
729 args.paged ++; |
569 |
730 |
570 // $.query.get() needs some correction to be sent into an ajax request |
731 // $.query.get() needs some correction to be sent into an Ajax request. |
571 if ( true === args.comment_type ) |
732 if ( true === args.comment_type ) |
572 args.comment_type = ''; |
733 args.comment_type = ''; |
573 |
734 |
574 args = $.extend(args, { |
735 args = $.extend(args, { |
575 'action': 'fetch-list', |
736 'action': 'fetch-list', |
586 theExtraList.get(0).wpList.add( response.rows ); |
747 theExtraList.get(0).wpList.add( response.rows ); |
587 } |
748 } |
588 }); |
749 }); |
589 }; |
750 }; |
590 |
751 |
|
752 /** |
|
753 * Globally available jQuery object referring to the extra comments list. |
|
754 * |
|
755 * @global |
|
756 */ |
591 window.theExtraList = $('#the-extra-comment-list').wpList( { alt: '', delColor: 'none', addColor: 'none' } ); |
757 window.theExtraList = $('#the-extra-comment-list').wpList( { alt: '', delColor: 'none', addColor: 'none' } ); |
|
758 |
|
759 /** |
|
760 * Globally available jQuery object referring to the comments list. |
|
761 * |
|
762 * @global |
|
763 */ |
592 window.theList = $('#the-comment-list').wpList( { alt: '', delBefore: delBefore, dimAfter: dimAfter, delAfter: delAfter, addColor: 'none' } ) |
764 window.theList = $('#the-comment-list').wpList( { alt: '', delBefore: delBefore, dimAfter: dimAfter, delAfter: delAfter, addColor: 'none' } ) |
593 .bind('wpListDelEnd', function(e, s){ |
765 .bind('wpListDelEnd', function(e, s){ |
594 var wpListsData = $(s.target).attr('data-wp-lists'), id = s.element.replace(/[^0-9]+/g, ''); |
766 var wpListsData = $(s.target).attr('data-wp-lists'), id = s.element.replace(/[^0-9]+/g, ''); |
595 |
767 |
596 if ( wpListsData.indexOf(':trash=1') != -1 || wpListsData.indexOf(':spam=1') != -1 ) |
768 if ( wpListsData.indexOf(':trash=1') != -1 || wpListsData.indexOf(':spam=1') != -1 ) |
597 $('#undo-' + id).fadeIn(300, function(){ $(this).show(); }); |
769 $('#undo-' + id).fadeIn(300, function(){ $(this).show(); }); |
598 }); |
770 }); |
599 }; |
771 }; |
600 |
772 |
|
773 /** |
|
774 * Object containing functionality regarding the comment quick editor and reply |
|
775 * editor. |
|
776 * |
|
777 * @since 2.7.0 |
|
778 * |
|
779 * @global |
|
780 */ |
601 window.commentReply = { |
781 window.commentReply = { |
602 cid : '', |
782 cid : '', |
603 act : '', |
783 act : '', |
604 originalContent : '', |
784 originalContent : '', |
605 |
785 |
|
786 /** |
|
787 * Initializes the comment reply functionality. |
|
788 * |
|
789 * @since 2.7.0 |
|
790 * |
|
791 * @memberof commentReply |
|
792 */ |
606 init : function() { |
793 init : function() { |
607 var row = $('#replyrow'); |
794 var row = $('#replyrow'); |
608 |
795 |
609 $( '.cancel', row ).click( function() { return commentReply.revert(); } ); |
796 $( '.cancel', row ).click( function() { return commentReply.revert(); } ); |
610 $( '.save', row ).click( function() { return commentReply.send(); } ); |
797 $( '.save', row ).click( function() { return commentReply.send(); } ); |
627 }); |
814 }); |
628 |
815 |
629 this.comments_listing = $('#comments-form > input[name="comment_status"]').val() || ''; |
816 this.comments_listing = $('#comments-form > input[name="comment_status"]').val() || ''; |
630 }, |
817 }, |
631 |
818 |
|
819 /** |
|
820 * Adds doubleclick event handler to the given comment list row. |
|
821 * |
|
822 * The double-click event will toggle the comment edit or reply form. |
|
823 * |
|
824 * @since 2.7.0 |
|
825 * |
|
826 * @memberof commentReply |
|
827 * |
|
828 * @param {Object} r The row to add double click handlers to. |
|
829 * |
|
830 * @return {void} |
|
831 */ |
632 addEvents : function(r) { |
832 addEvents : function(r) { |
633 r.each(function() { |
833 r.each(function() { |
634 $(this).find('.column-comment > p').dblclick(function(){ |
834 $(this).find('.column-comment > p').dblclick(function(){ |
635 commentReply.toggle($(this).parent()); |
835 commentReply.toggle($(this).parent()); |
636 }); |
836 }); |
637 }); |
837 }); |
638 }, |
838 }, |
639 |
839 |
|
840 /** |
|
841 * Opens the quick edit for the given element. |
|
842 * |
|
843 * @since 2.7.0 |
|
844 * |
|
845 * @memberof commentReply |
|
846 * |
|
847 * @param {HTMLElement} el The element you want to open the quick editor for. |
|
848 * |
|
849 * @return {void} |
|
850 */ |
640 toggle : function(el) { |
851 toggle : function(el) { |
641 if ( 'none' !== $( el ).css( 'display' ) && ( $( '#replyrow' ).parent().is('#com-reply') || window.confirm( adminCommentsL10n.warnQuickEdit ) ) ) { |
852 if ( 'none' !== $( el ).css( 'display' ) && ( $( '#replyrow' ).parent().is('#com-reply') || window.confirm( __( 'Are you sure you want to edit this comment?\nThe changes you made will be lost.' ) ) ) ) { |
642 $( el ).find( 'a.vim-q' ).click(); |
853 $( el ).find( 'button.vim-q' ).click(); |
643 } |
854 } |
644 }, |
855 }, |
645 |
856 |
|
857 /** |
|
858 * Closes the comment quick edit or reply form and undoes any changes. |
|
859 * |
|
860 * @since 2.7.0 |
|
861 * |
|
862 * @memberof commentReply |
|
863 * |
|
864 * @return {void} |
|
865 */ |
646 revert : function() { |
866 revert : function() { |
647 |
867 |
648 if ( $('#the-comment-list #replyrow').length < 1 ) |
868 if ( $('#the-comment-list #replyrow').length < 1 ) |
649 return false; |
869 return false; |
650 |
870 |
651 $('#replyrow').fadeOut('fast', function(){ |
871 $('#replyrow').fadeOut('fast', function(){ |
652 commentReply.close(); |
872 commentReply.close(); |
653 }); |
873 }); |
654 }, |
874 }, |
655 |
875 |
|
876 /** |
|
877 * Closes the comment quick edit or reply form and undoes any changes. |
|
878 * |
|
879 * @since 2.7.0 |
|
880 * |
|
881 * @memberof commentReply |
|
882 * |
|
883 * @return {void} |
|
884 */ |
656 close : function() { |
885 close : function() { |
657 var commentRow = $(), |
886 var commentRow = $(), |
658 replyRow = $( '#replyrow' ); |
887 replyRow = $( '#replyrow' ); |
659 |
888 |
660 // replyrow is not showing? |
889 // Return if the replyrow is not showing. |
661 if ( replyRow.parent().is( '#com-reply' ) ) { |
890 if ( replyRow.parent().is( '#com-reply' ) ) { |
662 return; |
891 return; |
663 } |
892 } |
664 |
893 |
665 if ( this.cid ) { |
894 if ( this.cid ) { |
685 commentRow.find( '.vim-r' ) |
914 commentRow.find( '.vim-r' ) |
686 .attr( 'aria-expanded', 'false' ) |
915 .attr( 'aria-expanded', 'false' ) |
687 .focus(); |
916 .focus(); |
688 } |
917 } |
689 |
918 |
690 // reset the Quicktags buttons |
919 // Reset the Quicktags buttons. |
691 if ( typeof QTags != 'undefined' ) |
920 if ( typeof QTags != 'undefined' ) |
692 QTags.closeAllTags('replycontent'); |
921 QTags.closeAllTags('replycontent'); |
693 |
922 |
694 $('#add-new-comment').css('display', ''); |
923 $('#add-new-comment').css('display', ''); |
695 |
924 |
696 replyRow.hide(); |
925 replyRow.hide(); |
704 |
933 |
705 this.cid = ''; |
934 this.cid = ''; |
706 this.originalContent = ''; |
935 this.originalContent = ''; |
707 }, |
936 }, |
708 |
937 |
|
938 /** |
|
939 * Opens the comment quick edit or reply form. |
|
940 * |
|
941 * @since 2.7.0 |
|
942 * |
|
943 * @memberof commentReply |
|
944 * |
|
945 * @param {number} comment_id The comment ID to open an editor for. |
|
946 * @param {number} post_id The post ID to open an editor for. |
|
947 * @param {string} action The action to perform. Either 'edit' or 'replyto'. |
|
948 * |
|
949 * @return {boolean} Always false. |
|
950 */ |
709 open : function(comment_id, post_id, action) { |
951 open : function(comment_id, post_id, action) { |
710 var editRow, rowData, act, replyButton, editHeight, |
952 var editRow, rowData, act, replyButton, editHeight, |
711 t = this, |
953 t = this, |
712 c = $('#comment-' + comment_id), |
954 c = $('#comment-' + comment_id), |
713 h = c.height(), |
955 h = c.height(), |
766 $( '#edithead, #editlegend, #savebtn, #addhead, #addbtn', editRow ).hide(); |
1008 $( '#edithead, #editlegend, #savebtn, #addhead, #addbtn', editRow ).hide(); |
767 $('#replyhead, #replybtn', editRow).show(); |
1009 $('#replyhead, #replybtn', editRow).show(); |
768 c.after(editRow); |
1010 c.after(editRow); |
769 |
1011 |
770 if ( c.hasClass('unapproved') ) { |
1012 if ( c.hasClass('unapproved') ) { |
771 replyButton.text(adminCommentsL10n.replyApprove); |
1013 replyButton.text( __( 'Approve and Reply' ) ); |
772 } else { |
1014 } else { |
773 replyButton.text(adminCommentsL10n.reply); |
1015 replyButton.text( __( 'Reply' ) ); |
774 } |
1016 } |
775 |
1017 |
776 $('#replyrow').fadeIn(300, function(){ $(this).show(); }); |
1018 $('#replyrow').fadeIn(300, function(){ $(this).show(); }); |
777 } |
1019 } |
778 |
1020 |
790 else if ( rtop - 20 < scrollTop ) |
1032 else if ( rtop - 20 < scrollTop ) |
791 window.scroll(0, rtop - 35); |
1033 window.scroll(0, rtop - 35); |
792 |
1034 |
793 $('#replycontent').focus().keyup(function(e){ |
1035 $('#replycontent').focus().keyup(function(e){ |
794 if ( e.which == 27 ) |
1036 if ( e.which == 27 ) |
795 commentReply.revert(); // close on Escape |
1037 commentReply.revert(); // Close on Escape. |
796 }); |
1038 }); |
797 }, 600); |
1039 }, 600); |
798 |
1040 |
799 return false; |
1041 return false; |
800 }, |
1042 }, |
801 |
1043 |
|
1044 /** |
|
1045 * Submits the comment quick edit or reply form. |
|
1046 * |
|
1047 * @since 2.7.0 |
|
1048 * |
|
1049 * @memberof commentReply |
|
1050 * |
|
1051 * @return {void} |
|
1052 */ |
802 send : function() { |
1053 send : function() { |
803 var post = {}, |
1054 var post = {}, |
804 $errorNotice = $( '#replysubmit .error-notice' ); |
1055 $errorNotice = $( '#replysubmit .error-notice' ); |
805 |
1056 |
806 $errorNotice.addClass( 'hidden' ); |
1057 $errorNotice.addClass( 'hidden' ); |
826 success : function(x) { commentReply.show(x); }, |
1077 success : function(x) { commentReply.show(x); }, |
827 error : function(r) { commentReply.error(r); } |
1078 error : function(r) { commentReply.error(r); } |
828 }); |
1079 }); |
829 }, |
1080 }, |
830 |
1081 |
|
1082 /** |
|
1083 * Shows the new or updated comment or reply. |
|
1084 * |
|
1085 * This function needs to be passed the ajax result as received from the server. |
|
1086 * It will handle the response and show the comment that has just been saved to |
|
1087 * the server. |
|
1088 * |
|
1089 * @since 2.7.0 |
|
1090 * |
|
1091 * @memberof commentReply |
|
1092 * |
|
1093 * @param {Object} xml Ajax response object. |
|
1094 * |
|
1095 * @return {void} |
|
1096 */ |
831 show : function(xml) { |
1097 show : function(xml) { |
832 var t = this, r, c, id, bg, pid; |
1098 var t = this, r, c, id, bg, pid; |
833 |
1099 |
834 if ( typeof(xml) == 'string' ) { |
1100 if ( typeof(xml) == 'string' ) { |
835 t.error({'responseText': xml}); |
1101 t.error({'responseText': xml}); |
914 $('#no-comments').remove(); |
1202 $('#no-comments').remove(); |
915 }); |
1203 }); |
916 }, |
1204 }, |
917 |
1205 |
918 /** |
1206 /** |
919 * Alert the user if they have unsaved changes on a comment that will be |
1207 * Alert the user if they have unsaved changes on a comment that will be lost if |
920 * lost if they proceed. |
1208 * they proceed with the intended action. |
921 * |
1209 * |
922 * @returns {boolean} |
1210 * @since 4.6.0 |
|
1211 * |
|
1212 * @memberof commentReply |
|
1213 * |
|
1214 * @return {boolean} Whether it is safe the continue with the intended action. |
923 */ |
1215 */ |
924 discardCommentChanges: function() { |
1216 discardCommentChanges: function() { |
925 var editRow = $( '#replyrow' ); |
1217 var editRow = $( '#replyrow' ); |
926 |
1218 |
927 if ( this.originalContent === $( '#replycontent', editRow ).val() ) { |
1219 if ( this.originalContent === $( '#replycontent', editRow ).val() ) { |
928 return true; |
1220 return true; |
929 } |
1221 } |
930 |
1222 |
931 return window.confirm( adminCommentsL10n.warnCommentChanges ); |
1223 return window.confirm( __( 'Are you sure you want to do this?\nThe comment changes you made will be lost.' ) ); |
932 } |
1224 } |
933 }; |
1225 }; |
934 |
1226 |
935 $(document).ready(function(){ |
1227 $(document).ready(function(){ |
936 var make_hotkeys_redirect, edit_comment, toggle_all, make_bulk; |
1228 var make_hotkeys_redirect, edit_comment, toggle_all, make_bulk; |
941 $(document).on( 'click', 'span.delete a.delete', function( e ) { |
1233 $(document).on( 'click', 'span.delete a.delete', function( e ) { |
942 e.preventDefault(); |
1234 e.preventDefault(); |
943 }); |
1235 }); |
944 |
1236 |
945 if ( typeof $.table_hotkeys != 'undefined' ) { |
1237 if ( typeof $.table_hotkeys != 'undefined' ) { |
|
1238 /** |
|
1239 * Creates a function that navigates to a previous or next page. |
|
1240 * |
|
1241 * @since 2.7.0 |
|
1242 * @access private |
|
1243 * |
|
1244 * @param {string} which What page to navigate to: either next or prev. |
|
1245 * |
|
1246 * @return {Function} The function that executes the navigation. |
|
1247 */ |
946 make_hotkeys_redirect = function(which) { |
1248 make_hotkeys_redirect = function(which) { |
947 return function() { |
1249 return function() { |
948 var first_last, l; |
1250 var first_last, l; |
949 |
1251 |
950 first_last = 'next' == which? 'first' : 'last'; |
1252 first_last = 'next' == which? 'first' : 'last'; |
952 if (l.length) |
1254 if (l.length) |
953 window.location = l[0].href.replace(/\&hotkeys_highlight_(first|last)=1/g, '')+'&hotkeys_highlight_'+first_last+'=1'; |
1255 window.location = l[0].href.replace(/\&hotkeys_highlight_(first|last)=1/g, '')+'&hotkeys_highlight_'+first_last+'=1'; |
954 }; |
1256 }; |
955 }; |
1257 }; |
956 |
1258 |
|
1259 /** |
|
1260 * Navigates to the edit page for the selected comment. |
|
1261 * |
|
1262 * @since 2.7.0 |
|
1263 * @access private |
|
1264 * |
|
1265 * @param {Object} event The event that triggered this action. |
|
1266 * @param {Object} current_row A jQuery object of the selected row. |
|
1267 * |
|
1268 * @return {void} |
|
1269 */ |
957 edit_comment = function(event, current_row) { |
1270 edit_comment = function(event, current_row) { |
958 window.location = $('span.edit a', current_row).attr('href'); |
1271 window.location = $('span.edit a', current_row).attr('href'); |
959 }; |
1272 }; |
960 |
1273 |
|
1274 /** |
|
1275 * Toggles all comments on the screen, for bulk actions. |
|
1276 * |
|
1277 * @since 2.7.0 |
|
1278 * @access private |
|
1279 * |
|
1280 * @return {void} |
|
1281 */ |
961 toggle_all = function() { |
1282 toggle_all = function() { |
962 $('#cb-select-all-1').data( 'wp-toggle', 1 ).trigger( 'click' ).removeData( 'wp-toggle' ); |
1283 $('#cb-select-all-1').data( 'wp-toggle', 1 ).trigger( 'click' ).removeData( 'wp-toggle' ); |
963 }; |
1284 }; |
964 |
1285 |
|
1286 /** |
|
1287 * Creates a bulk action function that is executed on all selected comments. |
|
1288 * |
|
1289 * @since 2.7.0 |
|
1290 * @access private |
|
1291 * |
|
1292 * @param {string} value The name of the action to execute. |
|
1293 * |
|
1294 * @return {Function} The function that executes the bulk action. |
|
1295 */ |
965 make_bulk = function(value) { |
1296 make_bulk = function(value) { |
966 return function() { |
1297 return function() { |
967 var scope = $('select[name="action"]'); |
1298 var scope = $('select[name="action"]'); |
968 $('option[value="' + value + '"]', scope).prop('selected', true); |
1299 $('option[value="' + value + '"]', scope).prop('selected', true); |
969 $('#doaction').click(); |
1300 $('#doaction').click(); |
982 ['shift+t', make_bulk('trash')], |
1313 ['shift+t', make_bulk('trash')], |
983 ['shift+z', make_bulk('untrash')], |
1314 ['shift+z', make_bulk('untrash')], |
984 ['shift+u', make_bulk('unapprove')] |
1315 ['shift+u', make_bulk('unapprove')] |
985 ], |
1316 ], |
986 { |
1317 { |
987 highlight_first: adminCommentsL10n.hotkeys_highlight_first, |
1318 highlight_first: adminCommentsSettings.hotkeys_highlight_first, |
988 highlight_last: adminCommentsL10n.hotkeys_highlight_last, |
1319 highlight_last: adminCommentsSettings.hotkeys_highlight_last, |
989 prev_page_link_cb: make_hotkeys_redirect('prev'), |
1320 prev_page_link_cb: make_hotkeys_redirect('prev'), |
990 next_page_link_cb: make_hotkeys_redirect('next'), |
1321 next_page_link_cb: make_hotkeys_redirect('next'), |
991 hotkeys_opts: { |
1322 hotkeys_opts: { |
992 disableInInput: true, |
1323 disableInInput: true, |
993 type: 'keypress', |
1324 type: 'keypress', |