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