Ticket #36264: 36264.diff
File 36264.diff, 34.8 KB (added by , 9 years ago) |
---|
-
src/wp-includes/js/wp-lists.js
1 1 /* global ajaxurl, wpAjax */ 2 (function($) { 3 var fs = {add:'ajaxAdd',del:'ajaxDel',dim:'ajaxDim',process:'process',recolor:'recolor'}, wpList; 4 2 ( function( $ ) { 3 var functions = { 4 add: 'ajaxAdd', 5 del: 'ajaxDel', 6 dim: 'ajaxDim', 7 process: 'process', 8 recolor: 'recolor' 9 }, wpList; 10 11 /** 12 * @namespace 13 */ 5 14 wpList = { 15 16 /** 17 * @member {object} 18 */ 6 19 settings: { 7 url: ajaxurl, type: 'POST', 20 21 /** 22 * URL for Ajax requests. 23 * 24 * @member {string} 25 */ 26 url: ajaxurl, 27 28 /** 29 * The HTTP method to use for Ajax requests. 30 * 31 * @member {string} 32 */ 33 type: 'POST', 34 35 /** 36 * ID of the element the parsed Ajax response will be stored in. 37 * 38 * @member {string} 39 */ 8 40 response: 'ajax-response', 9 41 42 /** 43 * The type of list. 44 * 45 * @member {string} 46 */ 10 47 what: '', 11 alt: 'alternate', altOffset: 0,12 addColor: null, delColor: null, dimAddColor: null, dimDelColor: null,13 48 49 /** 50 * CSS class name for alternate styling. 51 * 52 * @member {string} 53 */ 54 alt: 'alternate', 55 56 /** 57 * Offset to start alternate styling from. 58 * 59 * @member {number} 60 */ 61 altOffset: 0, 62 63 /** 64 * Color used in animation when adding an element. 65 * 66 * Can be 'none' to disable the animation. 67 * 68 * @member {string} 69 */ 70 addColor: '#ffff33', 71 72 /** 73 * Color used in animation when deleting an element. 74 * 75 * Can be 'none' to disable the animation. 76 * 77 * @member {string} 78 */ 79 delColor: '#faafaa', 80 81 /** 82 * Color used in dim add animation. 83 * 84 * Can be 'none' to disable the animation. 85 * 86 * @member {string} 87 */ 88 dimAddColor: '#ffff33', 89 90 /** 91 * Color used in dim delete animation. 92 * 93 * Can be 'none' to disable the animation. 94 * 95 * @member {string} 96 */ 97 dimDelColor: '#ff3333', 98 99 /** 100 * Callback that's run before a request is made. 101 * 102 * @callback wpList~confirm 103 * @param {object} this 104 * @param {HTMLElement} list The list DOM element. 105 * @param {object} settings Settings for the current list. 106 * @param {string} action The type of action to perform: 'add', 'delete', or 'dim'. 107 * @param {string} backgroundColor Background color of the list's DOM element. 108 * @returns {boolean} Whether to proceed with the action or not. 109 */ 14 110 confirm: null, 15 addBefore: null, addAfter: null, 16 delBefore: null, delAfter: null, 17 dimBefore: null, dimAfter: null 111 112 /** 113 * Callback that's run before an item gets added to the list. 114 * 115 * Allows to cancel the request. 116 * 117 * @callback wpList~addBefore 118 * @param {object} settings Settings for the Ajax request. 119 * @returns {object|boolean} Settings for the Ajax request or false to abort. 120 */ 121 addBefore: null, 122 123 /** 124 * Callback that's run after an item got added to the list. 125 * 126 * @callback wpList~addAfter 127 * @param {XML} returnedResponse Raw response returned from the server. 128 * @param {object} settings Settings for the Ajax request. 129 * @param {jqXHR} settings.xml jQuery XMLHttpRequest object. 130 * @param {string} settings.status Status of the request: 'success', 'notmodified', 'nocontent', 'error', 131 * 'timeout', 'abort', or 'parsererror'. 132 * @param {object} settings.parsed Parsed response object. 133 */ 134 addAfter: null, 135 136 /** 137 * Callback that's run before an item gets deleted from the list. 138 * 139 * Allows to cancel the request. 140 * 141 * @callback wpList~delBefore 142 * @param {object} settings Settings for the Ajax request. 143 * @param {HTMLElement} list The list DOM element. 144 * @returns {object|boolean} Settings for the Ajax request or false to abort. 145 */ 146 delBefore: null, 147 148 /** 149 * Callback that's run after an item got deleted from the list. 150 * 151 * @callback wpList~delAfter 152 * @param {XML} returnedResponse Raw response returned from the server. 153 * @param {object} settings Settings for the Ajax request. 154 * @param {jqXHR} settings.xml jQuery XMLHttpRequest object. 155 * @param {string} settings.status Status of the request: 'success', 'notmodified', 'nocontent', 'error', 156 * 'timeout', 'abort', or 'parsererror'. 157 * @param {object} settings.parsed Parsed response object. 158 */ 159 delAfter: null, 160 161 /** 162 * Callback that's run before an item gets dim'd. 163 * 164 * Allows to cancel the request. 165 * 166 * @callback wpList~dimBefore 167 * @param {object} settings Settings for the Ajax request. 168 * @returns {object|boolean} Settings for the Ajax request or false to abort. 169 */ 170 dimBefore: null, 171 172 /** 173 * Callback that's run after an item got dim'd. 174 * 175 * @callback wpList~dimAfter 176 * @param {XML} returnedResponse Raw response returned from the server. 177 * @param {object} settings Settings for the Ajax request. 178 * @param {jqXHR} settings.xml jQuery XMLHttpRequest object. 179 * @param {string} settings.status Status of the request: 'success', 'notmodified', 'nocontent', 'error', 180 * 'timeout', 'abort', or 'parsererror'. 181 * @param {object} settings.parsed Parsed response object. 182 */ 183 dimAfter: null 18 184 }, 19 185 20 nonce: function(e,s) { 21 var url = wpAjax.unserialize(e.attr('href')); 22 return s.nonce || url._ajax_nonce || $('#' + s.element + ' input[name="_ajax_nonce"]').val() || url._wpnonce || $('#' + s.element + ' input[name="_wpnonce"]').val() || 0; 186 /** 187 * Finds a nonce. 188 * 189 * 1. Nonce in settings. 190 * 2. `_ajax_nonce` value in element's href attribute. 191 * 3. `_ajax_nonce` input field that is a descendant of element. 192 * 4. `_wpnonce` value in element's href attribute. 193 * 5. `_wpnonce` input field that is a descendant of element. 194 * 6. 0 if none can be found. 195 * 196 * @param {jQuery} element Element that triggered the request. 197 * @param {object} settings Settings for the Ajax request. 198 * @returns {string|number} Nonce 199 */ 200 nonce: function( element, settings ) { 201 var url = wpAjax.unserialize( element.attr( 'href' ) ), 202 $element = $( '#' + settings.element ); 203 204 return settings.nonce || url._ajax_nonce || $element.find( 'input[name="_ajax_nonce"]' ).val() || url._wpnonce || $element.find( 'input[name="_wpnonce"]' ).val() || 0; 23 205 }, 24 206 25 207 /** 26 208 * Extract list item data from a DOM element. 27 209 * 28 * @param {HTMLElement} e The DOM element. 29 * @param {string} t 30 * @return {array} 210 * Example 1: data-wp-lists="delete:the-comment-list:comment-{comment_ID}:66cc66:unspam=1" 211 * Example 2: data-wp-lists="dim:the-comment-list:comment-{comment_ID}:unapproved:e7e7d3:e7e7d3:new=approved" 212 * 213 * Returns an unassociated array with the following data: 214 * data[0] - Data identifier: 'list', 'add', 'delete', or 'dim'. 215 * data[1] - ID of the corresponding list. If data[0] is 'list', the type of list ('comment', 'category', etc). 216 * data[2] - ID of the parent element of all inputs necessary for the request. 217 * data[3] - Hex color to be used in this request. If data[0] is 'dim', dim class. 218 * data[4] - Additional arguments in query syntax that are added to the request. Example: 'post_id=1234'. 219 * If data[0] is 'dim', dim add color. 220 * data[5] - Only available if data[0] is 'dim', dim delete color. 221 * data[6] - Only available if data[0] is 'dim', additional arguments in query syntax that are added to the request. 222 * 223 * Result for Example 1: 224 * data[0] - delete 225 * data[1] - the-comment-list 226 * data[2] - comment-{comment_ID} 227 * data[3] - 66cc66 228 * data[4] - unspam=1 229 * 230 * @param {HTMLElement} element The DOM element. 231 * @param {string} type The type of data to look for: 'list', 'add', 'delete', or 'dim'. 232 * @returns {Array} 31 233 */ 32 parseData: function( e,t) {33 var d = [], wpListsData;234 parseData: function( element, type ) { 235 var data = [], wpListsData; 34 236 35 237 try { 36 wpListsData = $( e).attr('data-wp-lists') || '';37 wpListsData = wpListsData.match( new RegExp(t+':[\\S]+'));238 wpListsData = $( element ).data( 'wp-lists' ) || ''; 239 wpListsData = wpListsData.match( new RegExp( type + ':[\\S]+' ) ); 38 240 39 if ( wpListsData ) 40 d = wpListsData[0].split(':'); 41 } catch(r) {} 241 if ( wpListsData ) { 242 data = wpListsData[0].split( ':' ); 243 } 244 } catch( error ) {} 42 245 43 return d ;246 return data; 44 247 }, 45 248 46 pre: function(e,s,a) { 47 var bg, r; 249 /** 250 * Calls a confirm callback to verify the action that is about to be performed. 251 * 252 * @param {HTMLElement} list The DOM element. 253 * @param {object} settings Settings for this list. 254 * @param {string} action The type of action to perform: 'add', 'delete', or 'dim'. 255 * @returns {object|boolean} Settings if confirmed, false if not. 256 */ 257 pre: function( list, settings, action ) { 258 var $element, backgroundColor, confirmed; 48 259 49 s = $.extend( {}, this.wpList.settings, {260 settings = $.extend( {}, this.wpList.settings, { 50 261 element: null, 51 nonce: 0, 52 target: e.get(0) 53 }, s || {} ); 54 55 if ( $.isFunction( s.confirm ) ) { 56 if ( 'add' != a ) { 57 bg = $('#' + s.element).css('backgroundColor'); 58 $('#' + s.element).css('backgroundColor', '#FF9966'); 262 nonce: 0, 263 target: list.get( 0 ) 264 }, settings || {} ); 265 266 if ( $.isFunction( settings.confirm ) ) { 267 $element = $( '#' + settings.element ); 268 269 if ( 'add' !== action ) { 270 backgroundColor = $element.css( 'backgroundColor' ); 271 $element.css( 'backgroundColor', '#ff9966' ); 59 272 } 60 r = s.confirm.call(this, e, s, a, bg);61 273 62 if ( 'add' != a ) 63 $('#' + s.element).css('backgroundColor', bg ); 274 confirmed = settings.confirm.call( this, list, settings, action, backgroundColor ); 64 275 65 if ( !r ) 276 if ( 'add' !== action ) { 277 $element.css( 'backgroundColor', backgroundColor ); 278 } 279 280 if ( ! confirmed ) { 66 281 return false; 282 } 67 283 } 68 284 69 return s ;285 return settings; 70 286 }, 71 287 72 ajaxAdd: function( e, s ) { 73 e = $(e); 74 s = s || {}; 75 var list = this, data = wpList.parseData(e,'add'), es, valid, formData, res, rres; 76 77 s = wpList.pre.call( list, e, s, 'add' ); 288 /** 289 * Adds an item to the list via AJAX. 290 * 291 * @param {HTMLElement} element The DOM element. 292 * @param {object} settings Settings for this list. 293 * @returns {boolean} 294 */ 295 ajaxAdd: function( element, settings ) { 296 var list = this, 297 $element = $( element ), 298 data = wpList.parseData( $element, 'add' ), 299 formValues, formData, parsedResponse, returnedResponse; 78 300 79 s.element = data[2] || e.attr( 'id' ) || s.element || null; 301 settings = settings || {}; 302 settings = wpList.pre.call( list, $element, settings, 'add' ); 80 303 81 if ( data[3] ) 82 s.addColor = '#' + data[3]; 83 else 84 s.addColor = s.addColor || '#FFFF33'; 304 settings.element = data[2] || $element.prop( 'id' ) || settings.element || null; 305 settings.addColor = data[3] ? '#' + data[3] : settings.addColor; 85 306 86 if ( ! s )307 if ( ! settings ) 87 308 return false; 88 309 89 if ( !e.is('[id="' + s.element + '-submit"]') ) 90 return !wpList.add.call( list, e, s ); 310 if ( ! $element.is( '[id="' + settings.element + '-submit"]' ) ) { 311 return ! wpList.add.call( list, $element, settings ); 312 } 91 313 92 if ( ! s.element )314 if ( ! settings.element ) { 93 315 return true; 316 } 94 317 95 s.action = 'add-' + s.what; 96 97 s.nonce = wpList.nonce(e,s); 98 99 es = $('#' + s.element + ' :input').not('[name="_ajax_nonce"], [name="_wpnonce"], [name="action"]'); 100 valid = wpAjax.validateForm( '#' + s.element ); 318 settings.action = 'add-' + settings.what; 319 settings.nonce = wpList.nonce( $element, settings ); 101 320 102 if ( ! valid )321 if ( ! wpAjax.validateForm( '#' + settings.element ) ) { 103 322 return false; 323 } 324 325 settings.data = $.param( $.extend( { 326 _ajax_nonce: settings.nonce, 327 action: settings.action 328 }, wpAjax.unserialize( data[4] || '' ) ) ); 104 329 105 s.data = $.param( $.extend( { _ajax_nonce: s.nonce, action: s.action }, wpAjax.unserialize( data[4] || '' ) ));106 formData = $.isFunction(es.fieldSerialize) ? es.fieldSerialize() :es.serialize();330 formValues = $( '#' + settings.element + ' :input' ).not( '[name="_ajax_nonce"], [name="_wpnonce"], [name="action"]' ); 331 formData = $.isFunction( formValues.fieldSerialize ) ? formValues.fieldSerialize() : formValues.serialize(); 107 332 108 if ( formData ) 109 s.data += '&' + formData; 333 if ( formData ) { 334 settings.data += '&' + formData; 335 } 110 336 111 if ( $.isFunction( s.addBefore) ) {112 s = s.addBefore(s );113 if ( ! s )337 if ( $.isFunction( settings.addBefore ) ) { 338 settings = settings.addBefore( settings ); 339 if ( ! settings ) { 114 340 return true; 341 } 115 342 } 116 343 117 if ( ! s.data.match(/_ajax_nonce=[a-f0-9]+/) )344 if ( ! settings.data.match( /_ajax_nonce=[a-f0-9]+/ ) ) { 118 345 return true; 346 } 119 347 120 s.success = function(r) { 121 res = wpAjax.parseAjaxResponse(r, s.response, s.element); 122 123 rres = r; 348 settings.success = function( response ) { 349 parsedResponse = wpAjax.parseAjaxResponse( response, settings.response, settings.element ); 350 returnedResponse = response; 124 351 125 if ( ! res || res.errors )352 if ( ! parsedResponse || parsedResponse.errors ) { 126 353 return false; 354 } 127 355 128 if ( true === res )356 if ( true === parsedResponse ) { 129 357 return true; 358 } 130 359 131 jQuery.each( res.responses, function() {132 wpList.add.call( list, this.data, $.extend( {}, s , { // this.firstChild.nodevalue133 pos : this.position || 0,134 id: this.id || 0,135 oldId: this.oldId || null360 $.each( parsedResponse.responses, function() { 361 wpList.add.call( list, this.data, $.extend( {}, settings, { // this.firstChild.nodevalue 362 position: this.position || 0, 363 id: this.id || 0, 364 oldId: this.oldId || null 136 365 } ) ); 137 366 } ); 138 367 139 368 list.wpList.recolor(); 140 $( list).trigger( 'wpListAddEnd', [s, list.wpList ] );141 wpList.clear.call( list,'#' + s.element);369 $( list ).trigger( 'wpListAddEnd', [ settings, list.wpList ] ); 370 wpList.clear.call( list, '#' + settings.element ); 142 371 }; 143 372 144 s.complete = function(x, st) { 145 if ( $.isFunction(s.addAfter) ) { 146 var _s = $.extend( { xml: x, status: st, parsed: res }, s ); 147 s.addAfter( rres, _s ); 373 settings.complete = function( jqXHR, status ) { 374 if ( $.isFunction( settings.addAfter ) ) { 375 settings.addAfter( returnedResponse, $.extend( { xml: jqXHR, status: status, parsed: parsedResponse }, settings ) ); 148 376 } 149 377 }; 150 378 151 $.ajax( s );379 $.ajax( settings ); 152 380 return false; 153 381 }, 154 382 155 383 /** 156 384 * Delete an item in the list via AJAX. 157 385 * 158 * @param {HTMLElement} eA DOM element containing item data.159 * @param {Object} s160 * @return {boolean}386 * @param {HTMLElement} element A DOM element containing item data. 387 * @param {object} settings Settings for this list. 388 * @returns {boolean} 161 389 */ 162 ajaxDel: function( e, s ) { 163 e = $(e); 164 s = s || {}; 165 var list = this, data = wpList.parseData(e,'delete'), element, res, rres; 166 167 s = wpList.pre.call( list, e, s, 'delete' ); 390 ajaxDel: function( element, settings ) { 391 var list = this, 392 $element = $( element ), 393 data = wpList.parseData( $element, 'delete' ), 394 $eventTarget, parsedResponse, returnedResponse; 168 395 169 s.element = data[2] || s.element || null; 396 settings = settings || {}; 397 settings = wpList.pre.call( list, $element, settings, 'delete' ); 170 398 171 if ( data[3] ) 172 s.delColor = '#' + data[3]; 173 else 174 s.delColor = s.delColor || '#faa'; 399 settings.element = data[2] || settings.element || null; 400 settings.delColor = data[3] ? '#' + data[3] : settings.delColor; 175 401 176 if ( ! s || !s.element )402 if ( ! settings || ! settings.element ) { 177 403 return false; 404 } 178 405 179 s.action = 'delete-' + s.what; 180 181 s.nonce = wpList.nonce(e,s); 406 settings.action = 'delete-' + settings.what; 407 settings.nonce = wpList.nonce( $element, settings ); 182 408 183 s.data = $.extend( 184 { action: s.action, id: s.element.split('-').pop(), _ajax_nonce: s.nonce }, 185 wpAjax.unserialize( data[4] || '' ) 186 ); 187 188 if ( $.isFunction(s.delBefore) ) { 189 s = s.delBefore( s, list ); 190 if ( !s ) 409 settings.data = $.extend( { 410 _ajax_nonce: settings.nonce, 411 action: settings.action, 412 id: settings.element.split( '-' ).pop() 413 }, wpAjax.unserialize( data[4] || '' ) ); 414 415 if ( $.isFunction( settings.delBefore) ) { 416 settings = settings.delBefore( settings, list ); 417 if ( ! settings ) { 191 418 return true; 419 } 192 420 } 193 421 194 if ( ! s.data._ajax_nonce )422 if ( ! settings.data._ajax_nonce ) { 195 423 return true; 424 } 196 425 197 element = $('#' + s.element);426 $eventTarget = $( '#' + settings.element ); 198 427 199 if ( 'none' != 200 element.css( 'backgroundColor',s.delColor ).fadeOut( 350, function(){428 if ( 'none' !== settings.delColor ) { 429 $eventTarget.css( 'backgroundColor', settings.delColor ).fadeOut( 350, function(){ 201 430 list.wpList.recolor(); 202 $( list).trigger( 'wpListDelEnd', [s, list.wpList ] );431 $( list ).trigger( 'wpListDelEnd', [ settings, list.wpList ] ); 203 432 }); 204 433 } else { 205 434 list.wpList.recolor(); 206 $( list).trigger( 'wpListDelEnd', [s, list.wpList ] );435 $( list ).trigger( 'wpListDelEnd', [ settings, list.wpList ] ); 207 436 } 208 437 209 s.success = function(r) { 210 res = wpAjax.parseAjaxResponse(r, s.response, s.element); 211 rres = r; 212 213 if ( !res || res.errors ) { 214 element.stop().stop().css( 'backgroundColor', '#faa' ).show().queue( function() { list.wpList.recolor(); $(this).dequeue(); } ); 438 settings.success = function( response ) { 439 parsedResponse = wpAjax.parseAjaxResponse( response, settings.response, settings.element ); 440 returnedResponse = response; 441 wpList.clear.call( list, '#' + settings.element ); 442 443 if ( ! parsedResponse || parsedResponse.errors ) { 444 $eventTarget.stop().stop().css( 'backgroundColor', '#faa' ).show().queue( function() { 445 list.wpList.recolor(); 446 $( this ).dequeue(); 447 } ); 215 448 return false; 216 449 } 217 450 }; 218 451 219 s.complete = function(x, st) { 220 if ( $.isFunction(s.delAfter) ) { 221 element.queue( function() { 222 var _s = $.extend( { xml: x, status: st, parsed: res }, s ); 223 s.delAfter( rres, _s ); 452 settings.complete = function( jqXHR, status ) { 453 if ( $.isFunction( settings.delAfter ) ) { 454 $eventTarget.queue( function() { 455 settings.delAfter( returnedResponse, $.extend( { xml: jqXHR, status: status, parsed: parsedResponse }, settings ) ); 224 456 }).dequeue(); 225 457 } 226 458 }; 227 459 228 $.ajax( s );460 $.ajax( settings ); 229 461 return false; 230 462 }, 231 463 232 ajaxDim: function( e, s ) { 233 if ( $(e).parent().css('display') == 'none' ) // Prevent hidden links from being clicked by hotkeys 234 return false; 235 236 e = $(e); 237 s = s || {}; 238 239 var list = this, data = wpList.parseData(e,'dim'), element, isClass, color, dimColor, res, rres; 240 241 s = wpList.pre.call( list, e, s, 'dim' ); 464 /** 465 * Dim an item in the list via AJAX. 466 * 467 * @param {HTMLElement} element A DOM element containing item data. 468 * @param {object} settings Settings for this list. 469 * @returns {boolean} 470 */ 471 ajaxDim: function( element, settings ) { 472 var list = this, 473 $element = $( element ), 474 data = wpList.parseData( $element, 'dim' ), 475 $eventTarget, isClass, color, dimColor, parsedResponse, returnedResponse; 242 476 243 s.element = data[2] || s.element || null; 244 s.dimClass = data[3] || s.dimClass || null; 477 // Prevent hidden links from being clicked by hotkeys. 478 if ( 'none' === $element.parent().css( 'display' ) ) { 479 return false; 480 } 245 481 246 if ( data[4] ) 247 s.dimAddColor = '#' + data[4]; 248 else 249 s.dimAddColor = s.dimAddColor || '#FFFF33'; 482 settings = settings || {}; 483 settings = wpList.pre.call( list, $element, settings, 'dim' ); 250 484 251 if ( data[5] )252 s.dimDelColor = '#' + data[5];253 else254 s.dimDelColor = s.dimDelColor || '#FF3333';485 settings.element = data[2] || settings.element || null; 486 settings.dimClass = data[3] || settings.dimClass || null; 487 settings.dimAddColor = data[4] ? '#' + data[4] : settings.dimAddColor; 488 settings.dimDelColor = data[5] ? '#' + data[5] : settings.dimDelColor; 255 489 256 if ( ! s || !s.element || !s.dimClass )490 if ( ! settings || ! settings.element || ! settings.dimClass ) { 257 491 return true; 492 } 258 493 259 s.action = 'dim-' + s.what; 260 261 s.nonce = wpList.nonce(e,s); 494 settings.action = 'dim-' + settings.what; 495 settings.nonce = wpList.nonce( $element, settings ); 262 496 263 s.data = $.extend( 264 { action: s.action, id: s.element.split('-').pop(), dimClass: s.dimClass, _ajax_nonce : s.nonce }, 265 wpAjax.unserialize( data[6] || '' ) 266 ); 267 268 if ( $.isFunction(s.dimBefore) ) { 269 s = s.dimBefore( s ); 270 if ( !s ) 497 settings.data = $.extend( { 498 _ajax_nonce : settings.nonce, 499 action: settings.action, 500 id: settings.element.split( '-' ).pop(), 501 dimClass: settings.dimClass 502 }, wpAjax.unserialize( data[6] || '' ) ); 503 504 if ( $.isFunction( settings.dimBefore ) ) { 505 settings = settings.dimBefore( settings ); 506 if ( ! settings ) { 271 507 return true; 508 } 272 509 } 273 510 274 element = $('#' + s.element);275 isClass = element.toggleClass(s.dimClass).is('.' + s.dimClass);276 color = wpList.getColor( element );277 element.toggleClass( s.dimClass );278 dimColor = isClass ? s.dimAddColor : s.dimDelColor;511 $eventTarget = $( '#' + settings.element ); 512 isClass = $eventTarget.toggleClass( settings.dimClass ).is( '.' + settings.dimClass ); 513 color = wpList.getColor( $eventTarget ); 514 dimColor = isClass ? settings.dimAddColor : settings.dimDelColor; 515 $eventTarget.toggleClass( settings.dimClass ); 279 516 280 if ( 'none' != dimColor ) {281 element517 if ( 'none' !== dimColor ) { 518 $eventTarget 282 519 .animate( { backgroundColor: dimColor }, 'fast' ) 283 .queue( function() { element.toggleClass(s.dimClass); $(this).dequeue(); } ) 284 .animate( { backgroundColor: color }, { complete: function() { 285 $(this).css( 'backgroundColor', '' ); 286 $(list).trigger( 'wpListDimEnd', [ s, list.wpList ] ); 520 .queue( function() { $eventTarget.toggleClass( settings.dimClass); $( this ).dequeue(); } ) 521 .animate( { backgroundColor: color }, { 522 complete: function() { 523 $( this ).css( 'backgroundColor', '' ); 524 $( list ).trigger( 'wpListDimEnd', [ settings, list.wpList ] ); 287 525 } 288 526 }); 289 527 } else { 290 $( list).trigger( 'wpListDimEnd', [s, list.wpList ] );528 $( list ).trigger( 'wpListDimEnd', [ settings, list.wpList ] ); 291 529 } 292 530 293 if ( ! s.data._ajax_nonce )531 if ( ! settings.data._ajax_nonce ) { 294 532 return true; 533 } 295 534 296 s.success = function(r) { 297 res = wpAjax.parseAjaxResponse(r, s.response, s.element); 298 rres = r; 299 300 if ( !res || res.errors ) { 301 element.stop().stop().css( 'backgroundColor', '#FF3333' )[isClass?'removeClass':'addClass'](s.dimClass).show().queue( function() { list.wpList.recolor(); $(this).dequeue(); } ); 535 settings.success = function( response ) { 536 parsedResponse = wpAjax.parseAjaxResponse( response, settings.response, settings.element); 537 returnedResponse = response; 538 539 if ( ! parsedResponse || parsedResponse.errors ) { 540 $eventTarget.stop().stop().css( 'backgroundColor', '#ff3333' )[ isClass ? 'removeClass' : 'addClass' ]( settings.dimClass ).show().queue( function() { 541 list.wpList.recolor(); 542 $( this ).dequeue(); 543 } ); 302 544 return false; 303 545 } 304 546 }; 305 547 306 s.complete = function(x, st) { 307 if ( $.isFunction(s.dimAfter) ) { 308 element.queue( function() { 309 var _s = $.extend( { xml: x, status: st, parsed: res }, s ); 310 s.dimAfter( rres, _s ); 311 }).dequeue(); 548 settings.complete = function( jqXHR, status ) { 549 if ( $.isFunction( settings.dimAfter ) ) { 550 $eventTarget.queue( function() { 551 settings.dimAfter( returnedResponse, $.extend( { xml: jqXHR, status: status, parsed: parsedResponse }, settings ) ); 552 } ).dequeue(); 312 553 } 313 554 }; 314 555 315 $.ajax( s );556 $.ajax( settings ); 316 557 return false; 317 558 }, 318 559 319 getColor: function( el ) { 320 var color = jQuery(el).css('backgroundColor'); 321 322 return color || '#ffffff'; 560 /** 561 * Returns the background color of the passed element. 562 * 563 * @param {jQuery|string} element Element to check. 564 * @returns {string} Background color value in HEX. Default: '#ffffff'. 565 */ 566 getColor: function( element ) { 567 return $( element ).css( 'backgroundColor' ) || '#ffffff'; 323 568 }, 324 569 325 add: function( e, s ) { 326 if ( 'string' == typeof e ) { 327 e = $( $.trim( e ) ); // Trim leading whitespaces 328 } else { 329 e = $( e ); 330 } 331 332 var list = $(this), old = false, _s = { pos: 0, id: 0, oldId: null }, ba, ref, color; 570 /** 571 * Adds something. 572 * 573 * @param {HTMLElement} element A DOM element containing item data. 574 * @param {object} settings Settings for this list. 575 * @returns {boolean} 576 */ 577 add: function( element, settings ) { 578 var $list = $( this ), 579 $element = $( element ), 580 old = false, 581 position, reference; 333 582 334 if ( 'string' == typeof s ) 335 s = { what: s }; 583 if ( 'string' === typeof settings ) { 584 settings = { what: settings }; 585 } 336 586 337 s = $.extend(_s, this.wpList.settings, s);587 settings = $.extend( { position: 0, id: 0, oldId: null }, this.wpList.settings, settings ); 338 588 339 if ( ! e.length || !s.what )589 if ( ! $element.length || ! settings.what ) { 340 590 return false; 591 } 341 592 342 if ( s.oldId ) 343 old = $('#' + s.what + '-' + s.oldId); 593 if ( settings.oldId ) { 594 old = $( '#' + settings.what + '-' + settings.oldId ); 595 } 344 596 345 if ( s.id && ( s.id != s.oldId || !old || !old.length ) ) 346 $('#' + s.what + '-' + s.id).remove(); 597 if ( settings.id && ( settings.id !== settings.oldId || ! old || ! old.length ) ) { 598 $( '#' + settings.what + '-' + settings.id ).remove(); 599 } 347 600 348 601 if ( old && old.length ) { 349 old.before( e);602 old.before( $element ); 350 603 old.remove(); 351 } else if ( isNaN(s.pos) ) {352 ba = 'after';353 604 354 if ( '-' == s.pos.substr(0,1) ) { 355 s.pos = s.pos.substr(1); 356 ba = 'before'; 605 } else if ( isNaN( settings.position ) ) { 606 position = 'after'; 607 608 if ( '-' === settings.position.substr( 0, 1 ) ) { 609 settings.position = settings.position.substr( 1 ); 610 position = 'before'; 357 611 } 358 612 359 ref = list.find( '#' + s.pos);613 reference = $list.find( '#' + settings.position ); 360 614 361 if ( 1 === ref.length ) 362 ref[ba](e); 363 else 364 list.append(e); 615 if ( 1 === reference.length ) { 616 reference[ position ]( $element ); 617 } else { 618 $list.append( $element ); 619 } 365 620 366 } else if ( 'comment' != s .what || 0 === $('#' + s.element).length ) {367 if ( s .pos< 0 ) {368 list.prepend(e);621 } else if ( 'comment' != settings.what || 0 === $( '#' + settings.element ).length ) { 622 if ( settings.position < 0 ) { 623 $list.prepend( $element ); 369 624 } else { 370 list.append(e);625 $list.append( $element ); 371 626 } 372 627 } 373 628 374 if ( s.alt ) { 375 if ( ( list.children(':visible').index( e[0] ) + s.altOffset ) % 2 ) { e.removeClass( s.alt ); } 376 else { e.addClass( s.alt ); } 629 if ( settings.alt ) { 630 $element.toggleClass( settings.alt, ( $list.children(':visible').index( $element[0] ) + settings.altOffset ) % 2 ); 377 631 } 378 632 379 if ( 'none' != s.addColor ) { 380 color = wpList.getColor( e ); 381 e.css( 'backgroundColor', s.addColor ).animate( { backgroundColor: color }, { complete: function() { $(this).css( 'backgroundColor', '' ); } } ); 633 if ( 'none' !== settings.addColor ) { 634 $element.css( 'backgroundColor', settings.addColor ).animate( { backgroundColor: wpList.getColor( $element ) }, { complete: function() { 635 $( this ).css( 'backgroundColor', '' ); 636 } } ); 382 637 } 383 list.each( function() { this.wpList.process( e ); } );384 return e;385 },386 638 387 clear: function(e) { 388 var list = this, t, tag; 639 // Add event handlers. 640 $list.each( function( index, list ) { 641 list.wpList.process( $element ); 642 } ); 389 643 390 e = $(e); 644 return $element; 645 }, 391 646 392 if ( list.wpList && e.parents( '#' + list.id ).length ) 647 /** 648 * Clears all input fields within the element passed. 649 * 650 * @param {string} elementId ID of the element to check, including leading #. 651 */ 652 clear: function( elementId ) { 653 var list = this, 654 $element = $( elementId ), 655 type, tagName; 656 657 // Bail if we're within the list. 658 if ( list.wpList && $element.parents( '#' + list.id ).length ) { 393 659 return; 660 } 394 661 395 e.find(':input').each( function() { 396 if ( $(this).parents('.form-no-clear').length ) 662 // Check each input field. 663 $element.find( ':input' ).each( function( index, input ) { 664 665 // Bail if the form was marked to not to be cleared. 666 if ( $( input ).parents( '.form-no-clear' ).length ) { 397 667 return; 668 } 669 670 type = input.type.toLowerCase(); 671 tagName = input.tagName.toLowerCase(); 398 672 399 t = this.type.toLowerCase();400 tag = this.tagName.toLowerCase();673 if ( 'text' === type || 'password' === type || 'textarea' === tagName ) { 674 input.value = ''; 401 675 402 if ( 'text' == t || 'password' == t || 'textarea' == tag )403 this.value = '';404 else if ( 'checkbox' == t || 'radio' == t ) 405 this.checked = false;406 else if ( 'select' == tag )407 this.selectedIndex = null;676 } else if ( 'checkbox' === type || 'radio' === type ) { 677 input.checked = false; 678 679 } else if ( 'select' === tagName ) { 680 input.selectedIndex = null; 681 } 408 682 }); 409 683 }, 410 684 411 process: function(el) { 412 var list = this, 413 $el = $(el || document); 685 /** 686 * Registers event handlers to add, delete, and dim items. 687 * 688 * @param {string} elementId 689 */ 690 process: function( elementId ) { 691 var list = this, 692 $element = $( elementId || document ); 414 693 415 $el .delegate( 'form[data-wp-lists^="add:' + list.id + ':"]', 'submit', function(){416 return list.wpList.add( this);694 $element.on( 'submit', 'form[data-wp-lists^="add:' + list.id + ':"]', function() { 695 return list.wpList.add( this ); 417 696 }); 418 697 419 $el .delegate( 'a[data-wp-lists^="add:' + list.id + ':"], input[data-wp-lists^="add:' + list.id + ':"]', 'click', function(){420 return list.wpList.add( this);698 $element.on( 'click', 'a[data-wp-lists^="add:' + list.id + ':"], input[data-wp-lists^="add:' + list.id + ':"]', function() { 699 return list.wpList.add( this ); 421 700 }); 422 701 423 $el .delegate( '[data-wp-lists^="delete:' + list.id + ':"]', 'click', function(){424 return list.wpList.del( this);702 $element.on( 'click', '[data-wp-lists^="delete:' + list.id + ':"]', function() { 703 return list.wpList.del( this ); 425 704 }); 426 705 427 $el .delegate( '[data-wp-lists^="dim:' + list.id + ':"]', 'click', function(){428 return list.wpList.dim( this);706 $element.on( 'click', '[data-wp-lists^="dim:' + list.id + ':"]', function() { 707 return list.wpList.dim( this ); 429 708 }); 430 709 }, 431 710 711 /** 712 * Updates list item background colors. 713 */ 432 714 recolor: function() { 433 var list = this, items, eo; 715 var list = this, 716 evenOdd = [':even',':odd'], 717 items; 434 718 435 if ( !list.wpList.settings.alt ) 719 // Bail if there is no alternate class name specified. 720 if ( ! list.wpList.settings.alt ) { 436 721 return; 722 } 437 723 438 items = $('.list-item:visible', list); 439 440 if ( !items.length ) 441 items = $(list).children(':visible'); 724 items = $( '.list-item:visible', list ); 442 725 443 eo = [':even',':odd']; 726 if ( ! items.length ) { 727 items = $( list ).children( ':visible' ); 728 } 444 729 445 if ( list.wpList.settings.altOffset % 2 ) 446 eo.reverse(); 730 if ( list.wpList.settings.altOffset % 2 ) { 731 evenOdd.reverse(); 732 } 447 733 448 items.filter(eo[0]).addClass(list.wpList.settings.alt).end().filter(eo[1]).removeClass(list.wpList.settings.alt); 734 items.filter( evenOdd[0] ).addClass( list.wpList.settings.alt ).end(); 735 items.filter( evenOdd[1] ).removeClass( list.wpList.settings.alt ); 449 736 }, 450 737 738 /** 739 * Sets up `process()` and `recolor()` functions. 740 */ 451 741 init: function() { 452 var lists= this;742 var $list = this; 453 743 454 lists.wpList.process = function(a) {455 lists.each( function() {456 this.wpList.process( a);744 $list.wpList.process = function() { 745 $list.each( function( index, element ) { 746 this.wpList.process( element ); 457 747 } ); 458 748 }; 459 749 460 lists.wpList.recolor = function() {461 lists.each( function() {750 $list.wpList.recolor = function() { 751 $list.each( function() { 462 752 this.wpList.recolor(); 463 753 } ); 464 754 }; 465 755 } 466 756 }; 467 757 758 /** 759 * Initializes wpList object. 760 * 761 * @param {Object} settings 762 * @param {string} settings.url URL for ajax calls. Default: ajaxurl. 763 * @param {string} settings.type The HTTP method to use for Ajax requests. Default: 'POST'. 764 * @param {string} settings.response ID of the element the parsed ajax response will be stored in. 765 * Default: 'ajax-response'. 766 * 767 * @param {string} settings.what Default: ''. 768 * @param {string} settings.alt CSS class name for alternate styling. Default: 'alternate'. 769 * @param {number} settings.altOffset Offset to start alternate styling from. Default: 0. 770 * @param {string} settings.addColor Hex code or 'none' to disable animation. Default: '#ffff33'. 771 * @param {string} settings.delColor Hex code or 'none' to disable animation. Default: '#faafaa'. 772 * @param {string} settings.dimAddColor Hex code or 'none' to disable animation. Default: '#ffff33'. 773 * @param {string} settings.dimDelColor Hex code or 'none' to disable animation. Default: '#ff3333'. 774 * 775 * @param {wpList~confirm} settings.confirm Callback that's run before a request is made. Default: null. 776 * @param {wpList~addBefore} settings.addBefore Callback that's run before an item gets added to the list. 777 * Default: null. 778 * @param {wpList~addAfter} settings.addAfter Callback that's run after an item got added to the list. 779 * Default: null. 780 * @param {wpList~delBefore} settings.delBefore Callback that's run before an item gets deleted from the list. 781 * Default: null. 782 * @param {wpList~delAfter} settings.delAfter Callback that's run after an item got deleted from the list. 783 * Default: null. 784 * @param {wpList~dimBefore} settings.dimBefore Callback that's run before an item gets dim'd. Default: null. 785 * @param {wpList~dimAfter} settings.dimAfter Callback that's run after an item got dim'd. Default: null. 786 * @returns {$.fn} 787 */ 468 788 $.fn.wpList = function( settings ) { 469 this.each( function() { 470 var _this = this; 789 this.each( function( index, list ) { 790 list.wpList = { 791 settings: $.extend( {}, wpList.settings, { what: wpList.parseData( list, 'list' )[1] || '' }, settings ) 792 }; 471 793 472 this.wpList = { settings: $.extend( {}, wpList.settings, { what: wpList.parseData(this,'list')[1] || '' }, settings ) }; 473 $.each( fs, function(i,f) { _this.wpList[i] = function( e, s ) { return wpList[f].call( _this, e, s ); }; } ); 794 $.each( functions, function( func, callback ) { 795 list.wpList[ func ] = function( element, setting ) { 796 return wpList[ callback ].call( list, element, setting ); 797 }; 798 } ); 474 799 } ); 475 800 476 wpList.init.call(this); 477 801 wpList.init.call( this ); 478 802 this.wpList.process(); 479 803 480 804 return this;