Ticket #21170: 21170-1.patch
File 21170-1.patch, 20.5 KB (added by , 11 years ago) |
---|
-
src/wp-admin/js/word-count.js
1 /* global wordCountL10n */1 /* global wordCountL10n, wp */ 2 2 var wpWordCount; 3 3 (function($,undefined) { 4 4 wpWordCount = { … … 38 38 } 39 39 }; 40 40 41 $(document).bind( 'wpcountwords', function(e,txt) {41 wp.hooks.addAction( 'wpcountwords', function(txt) { 42 42 wpWordCount.wc(txt); 43 43 }); 44 44 }(jQuery)); -
src/wp-includes/js/wp-hooks.js
1 window.wp = window.wp || {}; 2 3 (function(namespace) { 4 "use strict"; 5 6 /** 7 * Handles managing all events for whatever you plug it into. Priorities for 8 * hooks are based on lowest to highest in that, lowest priority hooks are 9 * fired first. 10 */ 11 var EventManager = function() { 12 /** 13 * Maintain a reference to the object scope so our public methods never 14 * get confusing. 15 */ 16 var MethodsAvailable = { 17 removeFilter : removeFilter, 18 applyFilters : applyFilters, 19 addFilter : addFilter, 20 removeAction : removeAction, 21 doAction : doAction, 22 addAction : addAction 23 }; 24 25 /** 26 * Contains the hooks that get registered with this EventManager. The 27 * array for storage utilizes a "flat" object literal such that looking 28 * up the hook utilizes the native object literal hash. 29 */ 30 var STORAGE = { 31 actions : {}, 32 filters : {} 33 }; 34 35 /** 36 * Adds an action to the event manager. 37 * 38 * @param action 39 * Must contain namespace.identifier 40 * @param callback 41 * Must be a valid callback function before this action is 42 * added 43 * @param [priority=10] 44 * Used to control when the function is executed in relation 45 * to other callbacks bound to the same hook 46 * @param [context] 47 * Supply a value to be used for this 48 */ 49 function addAction(action, callback, priority, context) { 50 if (typeof action === 'string' && typeof callback === 'function') { 51 priority = parseInt((priority || 10), 10); 52 _addHook('actions', action, callback, priority, context); 53 } 54 55 return MethodsAvailable; 56 } 57 58 /** 59 * Performs an action if it exists. You can pass as many arguments as 60 * you want to this function; the only rule is that the first argument 61 * must always be the action. 62 */ 63 function doAction( /* action, arg1, arg2, ... */) { 64 var args = Array.prototype.slice.call(arguments); 65 var action = args.shift(); 66 67 if (typeof action === 'string') { 68 _runHook('actions', action, args); 69 } 70 71 return MethodsAvailable; 72 } 73 74 /** 75 * Removes the specified action if it contains a namespace.identifier & 76 * exists. 77 * 78 * @param action 79 * The action to remove 80 * @param [callback] 81 * Callback function to remove 82 */ 83 function removeAction(action, callback) { 84 if (typeof action === 'string') { 85 _removeHook('actions', action, callback); 86 } 87 88 return MethodsAvailable; 89 } 90 91 /** 92 * Adds a filter to the event manager. 93 * 94 * @param filter 95 * Must contain namespace.identifier 96 * @param callback 97 * Must be a valid callback function before this action is 98 * added 99 * @param [priority=10] 100 * Used to control when the function is executed in relation 101 * to other callbacks bound to the same hook 102 * @param [context] 103 * Supply a value to be used for this 104 */ 105 function addFilter(filter, callback, priority, context) { 106 if (typeof filter === 'string' && typeof callback === 'function') { 107 priority = parseInt((priority || 10), 10); 108 _addHook('filters', filter, callback, priority); 109 } 110 111 return MethodsAvailable; 112 } 113 114 /** 115 * Performs a filter if it exists. You should only ever pass 1 argument 116 * to be filtered. The only rule is that the first argument must always 117 * be the filter. 118 */ 119 function applyFilters( /* filter, filtered arg, arg2, ... */) { 120 var args = Array.prototype.slice.call(arguments); 121 var filter = args.shift(); 122 123 if (typeof filter === 'string') { 124 return _runHook('filters', filter, args); 125 } 126 127 return MethodsAvailable; 128 } 129 130 /** 131 * Removes the specified filter if it contains a namespace.identifier & 132 * exists. 133 * 134 * @param filter 135 * The action to remove 136 * @param [callback] 137 * Callback function to remove 138 */ 139 function removeFilter(filter, callback) { 140 if (typeof filter === 'string') { 141 _removeHook('filters', filter, callback); 142 } 143 144 return MethodsAvailable; 145 } 146 147 /** 148 * Removes the specified hook by resetting the value of it. 149 * 150 * @param type 151 * Type of hook, either 'actions' or 'filters' 152 * @param hook 153 * The hook (namespace.identifier) to remove 154 * @private 155 */ 156 function _removeHook(type, hook, callback) { 157 var actions, action, index; 158 if (STORAGE[type][hook]) { 159 if (typeof callback === 'undefined') { 160 STORAGE[type][hook] = []; 161 } else { 162 actions = STORAGE[type][hook]; 163 for (index = 0; index < actions.length; index++) { 164 action = actions[index]; 165 if (action.callback === callback) { 166 STORAGE[type][hook].splice(index, 1); 167 } 168 } 169 } 170 } 171 } 172 173 /** 174 * Adds the hook to the appropriate storage container 175 * 176 * @param type 177 * 'actions' or 'filters' 178 * @param hook 179 * The hook (namespace.identifier) to add to our event 180 * manager 181 * @param callback 182 * The function that will be called when the hook is 183 * executed. 184 * @param priority 185 * The priority of this hook. Must be an integer. 186 * @param [context] 187 * A value to be used for this 188 * @private 189 */ 190 function _addHook(type, hook, callback, priority, context) { 191 var hookObject = { 192 callback : callback, 193 priority : priority, 194 context : context 195 }; 196 197 // Utilize 'prop itself' : 198 // http://jsperf.com/hasownproperty-vs-in-vs-undefined/19 199 var hooks = STORAGE[type][hook]; 200 if (hooks) { 201 hooks.push(hookObject); 202 hooks = _hookInsertSort(hooks); 203 } else { 204 hooks = [ hookObject ]; 205 } 206 207 STORAGE[type][hook] = hooks; 208 } 209 210 /** 211 * Use an insert sort for keeping our hooks organized based on priority. 212 * This function is ridiculously faster than bubble sort, etc: 213 * http://jsperf.com/javascript-sort 214 * 215 * @param hooks 216 * The custom array containing all of the appropriate hooks 217 * to perform an insert sort on. 218 * @private 219 */ 220 function _hookInsertSort(hooks) { 221 var tmpHook, j, prevHook; 222 for ( var i = 1, len = hooks.length; i < len; i++) { 223 tmpHook = hooks[i]; 224 j = i; 225 while ((prevHook = hooks[j - 1]) 226 && prevHook.priority > tmpHook.priority) { 227 hooks[j] = hooks[j - 1]; 228 --j; 229 } 230 hooks[j] = tmpHook; 231 } 232 233 return hooks; 234 } 235 236 /** 237 * Runs the specified hook. If it is an action, the value is not 238 * modified but if it is a filter, it is. 239 * 240 * @param type 241 * 'actions' or 'filters' 242 * @param hook 243 * The hook ( namespace.identifier ) to be ran. 244 * @param args 245 * Arguments to pass to the action/filter. If it's a filter, 246 * args is actually a single parameter. 247 * @private 248 */ 249 function _runHook(type, hook, args) { 250 var hooks = STORAGE[type][hook]; 251 if (typeof hooks === 'undefined') { 252 if (type === 'filters') { 253 return args[0]; 254 } 255 return false; 256 } 257 258 for ( var i = 0, len = hooks.length; i < len; i++) { 259 if (type === 'actions') { 260 hooks[i].callback.apply(hooks[i].context, args); 261 } else { 262 args[0] = hooks[i].callback.apply(hooks[i].context, args); 263 } 264 } 265 266 if (type === 'actions') { 267 return true; 268 } 269 270 return args[0]; 271 } 272 273 // return all of the publicly available methods 274 return MethodsAvailable; 275 276 }; 277 namespace = namespace || {}; 278 namespace.hooks = new EventManager(); 279 280 })(window.wp); 281 No newline at end of file -
src/wp-admin/js/post.js
258 258 ); 259 259 }; 260 260 261 $(document).on( 'heartbeat-send.refresh-lock', function( e,data ) {261 wp.hooks.addAction( 'heartbeat-send', function( data ) { 262 262 var lock = $('#active_post_lock').val(), 263 263 post_id = $('#post_ID').val(), 264 264 send = {}; … … 273 273 274 274 data['wp-refresh-post-lock'] = send; 275 275 276 }). on( 'heartbeat-tick.refresh-lock', function( e,data ) {276 }).addAction( 'heartbeat-tick', function( data ) { 277 277 // Post locks: update the lock string or show the dialog if somebody has taken over editing 278 278 var received, wrap, avatar; 279 279 … … 287 287 if ( wrap.length && ! wrap.is(':visible') ) { 288 288 if ( wp.autosave ) { 289 289 // Save the latest changes and disable 290 $(document).one( 'heartbeat-tick', function() {290 wp.hooks.addAction ( 'heartbeat-tick', function() { 291 291 wp.autosave.server.suspend(); 292 292 wrap.removeClass('saving').addClass('saved'); 293 293 $(window).off( 'beforeunload.edit-post' ); 294 } );294 }, 1); 295 295 296 296 wrap.addClass('saving'); 297 297 wp.autosave.server.triggerSave(); … … 309 309 $('#active_post_lock').val( received.new_lock ); 310 310 } 311 311 } 312 }).on( 'after-autosave.update-post-slug', function() { 312 }); 313 wp.hooks.addAction ( 'after-autosave', function() { 313 314 // create slug area only if not already there 314 315 if ( ! $('#edit-slug-box > *').length ) { 315 316 $.post( ajaxurl, { … … 338 339 timeout = window.setTimeout( function(){ check = true; }, 300000 ); 339 340 } 340 341 341 $(document).on( 'heartbeat-send.wp-refresh-nonces', function( e, data ) {342 wp.hooks.doAction( 'heartbeat-send', function( e, data ) { 342 343 var nonce, post_id; 343 344 344 345 if ( check ) { … … 349 350 }; 350 351 } 351 352 } 352 }). on( 'heartbeat-tick.wp-refresh-nonces', function( e,data ) {353 }).addAction( 'heartbeat-tick', function( data ) { 353 354 var nonces = data['wp-refresh-post-nonces']; 354 355 355 356 if ( nonces ) { … … 364 365 if ( nonces.heartbeatNonce ) 365 366 window.heartbeatSettings.nonce = nonces.heartbeatNonce; 366 367 } 367 }).ready( function() { 368 }) 369 $(document).ready( function() { 368 370 schedule(); 369 371 }); 370 372 }(jQuery)); … … 511 513 }); 512 514 } 513 515 514 $document.on( 'autosave-disable-buttons.edit-post', function() {516 wp.hooks.addAction ( 'autosave-disable-buttons', function() { 515 517 $submitButtons.addClass( 'disabled' ); 516 }). on( 'autosave-enable-buttons.edit-post', function() {518 }).addAction ( 'autosave-enable-buttons', function() { 517 519 if ( ! wp.heartbeat || ! wp.heartbeat.hasConnectionError() ) { 518 520 $submitButtons.removeClass( 'disabled' ); 519 521 } 520 }). on( 'before-autosave.edit-post', function() {522 }).addAction ( 'before-autosave', function() { 521 523 $( '.autosave-message' ).text( postL10n.savingText ); 522 }). on( 'after-autosave.edit-post', function( event,data ) {524 }).addAction( 'after-autosave', function( data ) { 523 525 $( '.autosave-message' ).text( data.message ); 524 526 }); 525 527 … … 942 944 943 945 // word count 944 946 if ( typeof(wpWordCount) != 'undefined' ) { 945 $document.triggerHandler('wpcountwords', [ co.val() ]);947 wp.hooks.doAction('wpcountwords', co.val() ); 946 948 947 949 co.keyup( function(e) { 948 950 var k = e.keyCode || e.charCode; … … 951 953 return true; 952 954 953 955 if ( 13 == k || 8 == last || 46 == last ) 954 $document.triggerHandler('wpcountwords', [ co.val() ]);956 wp.hooks.doAction ('wpcountwords', co.val() ); 955 957 956 958 last = k; 957 959 return true; -
src/wp-includes/js/tinymce/plugins/wordpress/plugin.js
394 394 } 395 395 396 396 if ( 13 === key || 8 === last || 46 === last ) { 397 window. jQuery( document ).triggerHandler( 'wpcountwords', [ editor.getContent({ format : 'raw' }) ]);397 window.wp.hooks.doAction( 'wpcountwords', editor.getContent({ format : 'raw' }) ); 398 398 } 399 399 400 400 last = key; -
src/wp-includes/js/wp-auth-check.js
1 /* global adminpage */1 /* global adminpage, wp */ 2 2 // Interim login dialog 3 3 (function($){ 4 4 var wrap, next; … … 88 88 next = ( new Date() ).getTime() + ( interval * 1000 ); 89 89 } 90 90 91 $( document ).on( 'heartbeat-tick.wp-auth-check', function( e,data ) {91 wp.hooks.addAction( 'heartbeat-tick', function( data ) { 92 92 if ( 'wp-auth-check' in data ) { 93 93 schedule(); 94 94 if ( ! data['wp-auth-check'] && wrap.hasClass('hidden') ) { … … 97 97 hide(); 98 98 } 99 99 } 100 }). on( 'heartbeat-send.wp-auth-check', function( e,data ) {100 }).addAction( 'heartbeat-send', function( data ) { 101 101 if ( ( new Date() ).getTime() > next ) { 102 102 data['wp-auth-check'] = true; 103 103 } 104 }).ready( function() { 104 }); 105 $(document).ready( function() { 105 106 schedule(); 106 107 wrap = $('#wp-auth-check-wrap'); 107 108 wrap.find('.wp-auth-check-close').on( 'click', function() { -
src/wp-includes/js/heartbeat.js
19 19 * - heartbeat_nopriv_tick 20 20 * @see wp_ajax_nopriv_heartbeat(), wp_ajax_heartbeat() 21 21 * 22 * Custom jQuery events:22 * WP-hooks actions: 23 23 * - heartbeat-send 24 24 * - heartbeat-tick 25 25 * - heartbeat-error … … 251 251 252 252 if ( trigger && ! hasConnectionError() ) { 253 253 settings.connectionError = true; 254 $document.trigger( 'heartbeat-connection-lost', [error, status]);254 wp.hooks.doAction('heartbeat-connection-lost', error, status); 255 255 } 256 256 } 257 257 } … … 270 270 if ( hasConnectionError() ) { 271 271 settings.errorcount = 0; 272 272 settings.connectionError = false; 273 $document.trigger( 'heartbeat-connection-restored' );273 wp.hooks.doAction( 'heartbeat-connection-restored' ); 274 274 } 275 275 } 276 276 … … 296 296 // Clear the data queue, anything added after this point will be send on the next tick 297 297 settings.queue = {}; 298 298 299 $document.trigger( 'heartbeat-send', [ heartbeatData ]);299 wp.hooks.doAction( 'heartbeat-send', heartbeatData ); 300 300 301 301 ajaxData = { 302 302 data: heartbeatData, … … 328 328 clearErrorState(); 329 329 330 330 if ( response.nonces_expired ) { 331 $document.trigger( 'heartbeat-nonces-expired' );331 wp.hooks.doAction( 'heartbeat-nonces-expired' ); 332 332 return; 333 333 } 334 334 … … 338 338 delete response.heartbeat_interval; 339 339 } 340 340 341 $document.trigger( 'heartbeat-tick', [response, textStatus, jqXHR]);341 wp.hooks.doAction ( 'heartbeat-tick', response, textStatus, jqXHR ); 342 342 343 343 // Do this last, can trigger the next XHR if connection time > 5 sec. and newInterval == 'fast' 344 344 if ( newInterval ) { … … 346 346 } 347 347 }).fail( function( jqXHR, textStatus, error ) { 348 348 setErrorState( textStatus || 'unknown', jqXHR.status ); 349 $document.trigger( 'heartbeat-error', [jqXHR, textStatus, error]);349 wp.hooks.doAction ( 'heartbeat-error', jqXHR, textStatus, error ); 350 350 }); 351 351 } 352 352 … … 660 660 * 661 661 * As the data is send asynchronously, this function doesn't return the XHR response. 662 662 * To see the response, use the custom jQuery event 'heartbeat-tick' on the document, example: 663 * $(document).on( 'heartbeat-tick.myname', function( event,data, textStatus, jqXHR ) {663 * wp.hooks.addAction( 'heartbeat-tick', function( data, textStatus, jqXHR ) { 664 664 * // code 665 665 * }); 666 666 * If the same 'handle' is used more than once, the data is not overwritten when the third argument is 'true'. -
src/wp-includes/js/autosave.js
1 /* global tinymce, wpCookies, autosaveL10n, switchEditors */1 /* global tinymce, wpCookies, autosaveL10n, switchEditors, wp */ 2 2 // Back-compat: prevent fatal errors 3 4 /** 5 * WP-hook actions 6 * - autosave-disable-buttons 7 * - autosave-enable-buttons 8 * - before-autosave 9 * - after-autosave 10 * - wpcountwords 11 * 12 */ 13 3 14 window.autosave = function(){}; 4 15 5 16 ( function( $, window ) { … … 77 88 } 78 89 79 90 function disableButtons() { 80 $document.trigger('autosave-disable-buttons');91 wp.hooks.doAction('autosave-disable-buttons'); 81 92 // Re-enable 5 sec later. Just gives autosave a head start to avoid collisions. 82 93 setTimeout( enableButtons, 5000 ); 83 94 } 84 95 85 96 function enableButtons() { 86 $document.trigger( 'autosave-enable-buttons' );97 wp.hooks.doAction( 'autosave-enable-buttons' ); 87 98 } 88 99 89 100 // Autosave in localStorage … … 452 463 lastCompareString = previousCompareString; 453 464 previousCompareString = ''; 454 465 455 $document.trigger( 'after-autosave', [data]);466 wp.hooks.doAction( 'after-autosave', data ); 456 467 enableButtons(); 457 468 458 469 if ( data.success ) { … … 514 525 tempBlockSave(); 515 526 disableButtons(); 516 527 517 $document.trigger( 'wpcountwords', [ postData.content ])518 . trigger( 'before-autosave', [ postData ]);528 wp.hooks.doAction ( 'wpcountwords', postData.content ) 529 .doAction( 'before-autosave', postData ); 519 530 520 531 postData._wpnonce = $( '#_wpnonce' ).val() || ''; 521 532 … … 526 537 nextRun = ( new Date() ).getTime() + ( autosaveL10n.autosaveInterval * 1000 ) || 60000; 527 538 } 528 539 529 $document.on( 'heartbeat-send.autosave', function( event,data ) {540 wp.hooks.addAction( 'heartbeat-send', function( data ) { 530 541 var autosaveData = save(); 531 542 532 543 if ( autosaveData ) { 533 544 data.wp_autosave = autosaveData; 534 545 } 535 }). on( 'heartbeat-tick.autosave', function( event,data ) {546 }).addAction( 'heartbeat-tick', function( data ) { 536 547 if ( data.wp_autosave ) { 537 548 response( data.wp_autosave ); 538 549 } 539 }). on( 'heartbeat-connection-lost.autosave', function( event,error, status ) {550 }).addAction( 'heartbeat-connection-lost', function( error, status ) { 540 551 // When connection is lost, keep user from submitting changes. 541 552 if ( 'timeout' === error || 603 === status ) { 542 553 var $notice = $('#lost-connection-notice'); … … 548 559 $notice.show(); 549 560 disableButtons(); 550 561 } 551 }). on( 'heartbeat-connection-restored.autosave', function() {562 }).addAction( 'heartbeat-connection-restored', function() { 552 563 $('#lost-connection-notice').hide(); 553 564 enableButtons(); 554 }).ready( function() { 565 }); 566 $document.ready( function() { 555 567 _schedule(); 556 568 }); 557 569 -
src/wp-admin/js/inline-edit-post.js
1 /* global inlineEditL10n, ajaxurl, typenow */1 /* global inlineEditL10n, ajaxurl, typenow, wp */ 2 2 3 3 var inlineEditPost; 4 4 (function($) { … … 314 314 $( document ).ready( function(){ inlineEditPost.init(); } ); 315 315 316 316 // Show/hide locks on posts 317 $( document ).on( 'heartbeat-tick.wp-check-locked-posts', function( e,data ) {317 wp.hooks.addAction( 'heartbeat-tick', function( data ) { 318 318 var locked = data['wp-check-locked-posts'] || {}; 319 319 320 320 $('#the-list tr').each( function(i, el) { … … 337 337 row.removeClass('wp-locked').delay(1000).find('.locked-info span').empty(); 338 338 } 339 339 }); 340 }). on( 'heartbeat-send.wp-check-locked-posts', function( e,data ) {340 }).addAction( 'heartbeat-send', function( data ) { 341 341 var check = []; 342 342 343 343 $('#the-list tr').each( function(i, el) { … … 349 349 if ( check.length ) { 350 350 data['wp-check-locked-posts'] = check; 351 351 } 352 }).ready( function() { 352 }); 353 $(document).ready( function() { 353 354 // Set the heartbeat interval to 15 sec. 354 355 if ( typeof wp !== 'undefined' && wp.heartbeat ) { 355 356 wp.heartbeat.interval( 15 );