WordPress.org

Make WordPress Core

Changeset 38599


Ignore:
Timestamp:
09/13/16 22:23:30 (13 months ago)
Author:
obenland
Message:

Make wpList easier to contribute to.

Uses more semantic variable names and adds function and inline documentation.

Props rommelxcastro for parallel work in #34917.
Fixes #36264.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/js/wp-lists.js

    r38050 r38599  
    11/* global ajaxurl, wpAjax */ 
    2 (function($) { 
    3 var fs = {add:'ajaxAdd',del:'ajaxDel',dim:'ajaxDim',process:'process',recolor:'recolor'}, wpList; 
    4  
     2 
     3/** 
     4 * @param {jQuery} $ jQuery object. 
     5 */ 
     6( function( $ ) { 
     7var functions = { 
     8    add:     'ajaxAdd', 
     9    del:     'ajaxDel', 
     10    dim:     'ajaxDim', 
     11    process: 'process', 
     12    recolor: 'recolor' 
     13}, wpList; 
     14 
     15/** 
     16 * @namespace 
     17 */ 
    518wpList = { 
     19 
     20    /** 
     21     * @member {object} 
     22     */ 
    623    settings: { 
    7         url: ajaxurl, type: 'POST', 
     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         */ 
    844        response: 'ajax-response', 
    945 
     46        /** 
     47         * The type of list. 
     48         * 
     49         * @member {string} 
     50         */ 
    1051        what: '', 
    11         alt: 'alternate', altOffset: 0, 
    12         addColor: null, delColor: null, dimAddColor: null, dimDelColor: null, 
    13  
     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         */ 
    14114        confirm: null, 
    15         addBefore: null, addAfter: null, 
    16         delBefore: null, delAfter: null, 
    17         dimBefore: null, dimAfter: null 
    18     }, 
    19  
    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; 
     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; 
    23209    }, 
    24210 
     
    26212     * Extract list item data from a DOM element. 
    27213     * 
    28      * @param  {HTMLElement} e The DOM element. 
    29      * @param  {string}      t 
    30      * @return {array} 
    31      */ 
    32     parseData: function(e,t) { 
    33         var d = [], wpListsData; 
     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; 
    34240 
    35241        try { 
    36             wpListsData = $(e).attr('data-wp-lists') || ''; 
    37             wpListsData = wpListsData.match(new RegExp(t+':[\\S]+')); 
    38  
    39             if ( wpListsData ) 
    40                 d = wpListsData[0].split(':'); 
    41         } catch(r) {} 
    42  
    43         return d; 
    44     }, 
    45  
    46     pre: function(e,s,a) { 
    47         var bg, r; 
    48  
    49         s = $.extend( {}, this.wpList.settings, { 
     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, { 
    50265            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'); 
    59             } 
    60             r = s.confirm.call(this, e, s, a, bg); 
    61  
    62             if ( 'add' != a ) 
    63                 $('#' + s.element).css('backgroundColor', bg ); 
    64  
    65             if ( !r ) 
     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 ) { 
    66285                return false; 
    67         } 
    68  
    69         return s; 
    70     }, 
    71  
    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' ); 
    78  
    79         s.element = data[2] || e.attr( 'id' ) || s.element || null; 
    80  
    81         if ( data[3] ) 
    82             s.addColor = '#' + data[3]; 
    83         else 
    84             s.addColor = s.addColor || '#FFFF33'; 
    85  
    86         if ( !s ) 
     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 ) { 
    87312            return false; 
    88  
    89         if ( !e.is('[id="' + s.element + '-submit"]') ) 
    90             return !wpList.add.call( list, e, s ); 
    91  
    92         if ( !s.element ) 
     313        } 
     314 
     315        if ( ! $element.is( '[id="' + settings.element + '-submit"]' ) ) { 
     316            return ! wpList.add.call( list, $element, settings ); 
     317        } 
     318 
     319        if ( ! settings.element ) { 
    93320            return true; 
    94  
    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 ); 
    101  
    102         if ( !valid ) 
     321        } 
     322 
     323        settings.action = 'add-' + settings.what; 
     324        settings.nonce  = wpList.nonce( $element, settings ); 
     325 
     326        if ( ! wpAjax.validateForm( '#' + settings.element ) ) { 
    103327            return false; 
    104  
    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(); 
    107  
    108         if ( formData ) 
    109             s.data += '&' + formData; 
    110  
    111         if ( $.isFunction(s.addBefore) ) { 
    112             s = s.addBefore( s ); 
    113             if ( !s ) 
     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 ) { 
    114346                return true; 
    115         } 
    116  
    117         if ( !s.data.match(/_ajax_nonce=[a-f0-9]+/) ) 
     347            } 
     348        } 
     349 
     350        if ( ! settings.data.match( /_ajax_nonce=[a-f0-9]+/ ) ) { 
    118351            return true; 
    119  
    120         s.success = function(r) { 
    121             res = wpAjax.parseAjaxResponse(r, s.response, s.element); 
    122  
    123             rres = r; 
    124  
    125             if ( !res || res.errors ) 
     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 ) { 
    126359                return false; 
    127  
    128             if ( true === res ) 
     360            } 
     361 
     362            if ( true === parsedResponse ) { 
    129363                return true; 
    130  
    131             jQuery.each( res.responses, function() { 
    132                 wpList.add.call( list, this.data, $.extend( {}, s, { // this.firstChild.nodevalue 
    133                     pos: this.position || 0, 
    134                     id: this.id || 0, 
    135                     oldId: this.oldId || null 
     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 
    136371                } ) ); 
    137372            } ); 
    138373 
    139374            list.wpList.recolor(); 
    140             $(list).trigger( 'wpListAddEnd', [ s, list.wpList ] ); 
    141             wpList.clear.call(list,'#' + s.element); 
     375            $( list ).trigger( 'wpListAddEnd', [ settings, list.wpList ] ); 
     376            wpList.clear.call( list, '#' + settings.element ); 
    142377        }; 
    143378 
    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 ); 
     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 ) ); 
    148386            } 
    149387        }; 
    150388 
    151         $.ajax( s ); 
     389        $.ajax( settings ); 
     390 
    152391        return false; 
    153392    }, 
     
    156395     * Delete an item in the list via AJAX. 
    157396     * 
    158      * @param  {HTMLElement} e A DOM element containing item data. 
    159      * @param  {Object}      s 
    160      * @return {boolean} 
    161      */ 
    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' ); 
    168  
    169         s.element = data[2] || s.element || null; 
    170  
    171         if ( data[3] ) 
    172             s.delColor = '#' + data[3]; 
    173         else 
    174             s.delColor = s.delColor || '#faa'; 
    175  
    176         if ( !s || !s.element ) 
     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 ) { 
    177414            return false; 
    178  
    179         s.action = 'delete-' + s.what; 
    180  
    181         s.nonce = wpList.nonce(e,s); 
    182  
    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 ) 
     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 ) { 
    191430                return true; 
    192         } 
    193  
    194         if ( !s.data._ajax_nonce ) 
     431            } 
     432        } 
     433 
     434        if ( ! settings.data._ajax_nonce ) { 
    195435            return true; 
    196  
    197         element = $('#' + s.element); 
    198  
    199         if ( 'none' != s.delColor ) { 
    200             element.css( 'backgroundColor', s.delColor ).fadeOut( 350, function(){ 
     436        } 
     437 
     438        $eventTarget = $( '#' + settings.element ); 
     439 
     440        if ( 'none' !== settings.delColor ) { 
     441            $eventTarget.css( 'backgroundColor', settings.delColor ).fadeOut( 350, function() { 
    201442                list.wpList.recolor(); 
    202                 $(list).trigger( 'wpListDelEnd', [ s, list.wpList ] ); 
    203             }); 
     443                $( list ).trigger( 'wpListDelEnd', [ settings, list.wpList ] ); 
     444            } ); 
    204445        } else { 
    205446            list.wpList.recolor(); 
    206             $(list).trigger( 'wpListDelEnd', [ s, list.wpList ] ); 
    207         } 
    208  
    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(); } ); 
     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 
    215460                return false; 
    216461            } 
    217462        }; 
    218463 
    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 ); 
    224                 }).dequeue(); 
     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(); 
    225473            } 
    226474        }; 
    227475 
    228         $.ajax( s ); 
     476        $.ajax( settings ); 
     477 
    229478        return false; 
    230479    }, 
    231480 
    232     ajaxDim: function( e, s ) { 
    233         if ( $(e).parent().css('display') == 'none' ) // Prevent hidden links from being clicked by hotkeys 
     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' ) ) { 
    234496            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' ); 
    242  
    243         s.element = data[2] || s.element || null; 
    244         s.dimClass =  data[3] || s.dimClass || null; 
    245  
    246         if ( data[4] ) 
    247             s.dimAddColor = '#' + data[4]; 
    248         else 
    249             s.dimAddColor = s.dimAddColor || '#FFFF33'; 
    250  
    251         if ( data[5] ) 
    252             s.dimDelColor = '#' + data[5]; 
    253         else 
    254             s.dimDelColor = s.dimDelColor || '#FF3333'; 
    255  
    256         if ( !s || !s.element || !s.dimClass ) 
     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 ) { 
    257508            return true; 
    258  
    259         s.action = 'dim-' + s.what; 
    260  
    261         s.nonce = wpList.nonce(e,s); 
    262  
    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 ) 
     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 ) { 
    271525                return true; 
    272         } 
    273  
    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; 
    279  
    280         if ( 'none' != dimColor ) { 
    281             element 
     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 
    282537                .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 ] ); 
     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 ] ); 
    287546                    } 
    288                 }); 
     547                } ); 
    289548        } else { 
    290             $(list).trigger( 'wpListDimEnd', [ s, list.wpList ] ); 
    291         } 
    292  
    293         if ( !s.data._ajax_nonce ) 
     549            $( list ).trigger( 'wpListDimEnd', [ settings, list.wpList ] ); 
     550        } 
     551 
     552        if ( ! settings.data._ajax_nonce ) { 
    294553            return true; 
    295  
    296         s.success = function(r) { 
    297             res = wpAjax.parseAjaxResponse(r, s.response, s.element); 
    298             rres = r; 
    299  
    300             if ( true === res ) { 
     554        } 
     555 
     556        settings.success = function( response ) { 
     557            parsedResponse   = wpAjax.parseAjaxResponse( response, settings.response, settings.element ); 
     558            returnedResponse = response; 
     559 
     560            if ( true === parsedResponse ) { 
    301561                return true; 
    302562            } 
    303563 
    304             if ( ! res || res.errors ) { 
    305                 element.stop().stop().css( 'backgroundColor', '#FF3333' )[isClass?'removeClass':'addClass'](s.dimClass).show().queue( function() { list.wpList.recolor(); $(this).dequeue(); } ); 
     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 
    306570                return false; 
    307571            } 
    308572 
    309             if ( 'undefined' !== typeof res.responses[0].supplemental.comment_link ) { 
    310                 var submittedOn = element.find( '.submitted-on' ), 
    311                     commentLink = submittedOn.find( 'a' ); 
     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' ); 
    312577 
    313578                // Comment is approved; link the date field. 
    314                 if ( '' !== res.responses[0].supplemental.comment_link ) { 
    315                     submittedOn.html( $('<a></a>').text( submittedOn.text() ).prop( 'href', res.responses[0].supplemental.comment_link ) ); 
     579                if ( '' !== parsedResponse.responses[0].supplemental.comment_link ) { 
     580                    $submittedOn.html( $('<a></a>').text( $submittedOn.text() ).prop( 'href', parsedResponse.responses[0].supplemental.comment_link ) ); 
    316581 
    317582                // Comment is not approved; unlink the date field. 
    318                 } else if ( commentLink.length ) { 
    319                     submittedOn.text( commentLink.text() ); 
     583                } else if ( $commentLink.length ) { 
     584                    $submittedOn.text( $commentLink.text() ); 
    320585                } 
    321586            } 
    322587        }; 
    323588 
    324         s.complete = function(x, st) { 
    325             if ( $.isFunction(s.dimAfter) ) { 
    326                 element.queue( function() { 
    327                     var _s = $.extend( { xml: x, status: st, parsed: res }, s ); 
    328                     s.dimAfter( rres, _s ); 
    329                 }).dequeue(); 
     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(); 
    330598            } 
    331599        }; 
    332600 
    333         $.ajax( s ); 
     601        $.ajax( settings ); 
     602 
    334603        return false; 
    335604    }, 
    336605 
    337     getColor: function( el ) { 
    338         var color = jQuery(el).css('backgroundColor'); 
    339  
    340         return color || '#ffffff'; 
    341     }, 
    342  
    343     add: function( e, s ) { 
    344         if ( 'string' == typeof e ) { 
    345             e = $( $.trim( e ) ); // Trim leading whitespaces 
    346         } else { 
    347             e = $( e ); 
    348         } 
    349  
    350         var list = $(this), old = false, _s = { pos: 0, id: 0, oldId: null }, ba, ref, color; 
    351  
    352         if ( 'string' == typeof s ) 
    353             s = { what: s }; 
    354  
    355         s = $.extend(_s, this.wpList.settings, s); 
    356  
    357         if ( !e.length || !s.what ) 
     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 ) { 
    358636            return false; 
    359  
    360         if ( s.oldId ) 
    361             old = $('#' + s.what + '-' + s.oldId); 
    362  
    363         if ( s.id && ( s.id != s.oldId || !old || !old.length ) ) 
    364             $('#' + s.what + '-' + s.id).remove(); 
     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        } 
    365646 
    366647        if ( old && old.length ) { 
    367             old.before(e); 
     648            old.before( $element ); 
    368649            old.remove(); 
    369         } else if ( isNaN(s.pos) ) { 
    370             ba = 'after'; 
    371  
    372             if ( '-' == s.pos.substr(0,1) ) { 
    373                 s.pos = s.pos.substr(1); 
    374                 ba = 'before'; 
    375             } 
    376  
    377             ref = list.find( '#' + s.pos ); 
    378  
    379             if ( 1 === ref.length ) 
    380                 ref[ba](e); 
    381             else 
    382                 list.append(e); 
    383  
    384         } else if ( 'comment' != s.what || 0 === $('#' + s.element).length ) { 
    385             if ( s.pos < 0 ) { 
    386                 list.prepend(e); 
     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 ); 
    387663            } else { 
    388                 list.append(e); 
    389             } 
    390         } 
    391  
    392         if ( s.alt ) { 
    393             if ( ( list.children(':visible').index( e[0] ) + s.altOffset ) % 2 ) { e.removeClass( s.alt ); } 
    394             else { e.addClass( s.alt ); } 
    395         } 
    396  
    397         if ( 'none' != s.addColor ) { 
    398             color = wpList.getColor( e ); 
    399             e.css( 'backgroundColor', s.addColor ).animate( { backgroundColor: color }, { complete: function() { $(this).css( 'backgroundColor', '' ); } } ); 
    400         } 
    401         list.each( function() { this.wpList.process( e ); } ); 
    402         return e; 
    403     }, 
    404  
    405     clear: function(e) { 
    406         var list = this, t, tag; 
    407  
    408         e = $(e); 
    409  
    410         if ( list.wpList && e.parents( '#' + list.id ).length ) 
     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 ) { 
    411707            return; 
    412  
    413         e.find(':input').each( function() { 
    414             if ( $(this).parents('.form-no-clear').length ) 
     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 ) { 
    415715                return; 
    416  
    417             t = this.type.toLowerCase(); 
    418             tag = this.tagName.toLowerCase(); 
    419  
    420             if ( 'text' == t || 'password' == t || 'textarea' == tag ) 
    421                 this.value = ''; 
    422             else if ( 'checkbox' == t || 'radio' == t ) 
    423                 this.checked = false; 
    424             else if ( 'select' == tag ) 
    425                 this.selectedIndex = null; 
    426         }); 
    427     }, 
    428  
    429     process: function(el) { 
    430         var list = this, 
    431             $el = $(el || document); 
    432  
    433         $el.delegate( 'form[data-wp-lists^="add:' + list.id + ':"]', 'submit', function(){ 
    434             return list.wpList.add(this); 
    435         }); 
    436  
    437         $el.delegate( 'a[data-wp-lists^="add:' + list.id + ':"], input[data-wp-lists^="add:' + list.id + ':"]', 'click', function(){ 
    438             return list.wpList.add(this); 
    439         }); 
    440  
    441         $el.delegate( '[data-wp-lists^="delete:' + list.id + ':"]', 'click', function(){ 
    442             return list.wpList.del(this); 
    443         }); 
    444  
    445         $el.delegate( '[data-wp-lists^="dim:' + list.id + ':"]', 'click', function(){ 
    446             return list.wpList.dim(this); 
    447         }); 
    448     }, 
    449  
     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     */ 
    450762    recolor: function() { 
    451         var list = this, items, eo; 
    452  
    453         if ( !list.wpList.settings.alt ) 
     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 ) { 
    454769            return; 
    455  
    456         items = $('.list-item:visible', list); 
    457  
    458         if ( !items.length ) 
    459             items = $(list).children(':visible'); 
    460  
    461         eo = [':even',':odd']; 
    462  
    463         if ( list.wpList.settings.altOffset % 2 ) 
    464             eo.reverse(); 
    465  
    466         items.filter(eo[0]).addClass(list.wpList.settings.alt).end().filter(eo[1]).removeClass(list.wpList.settings.alt); 
    467     }, 
    468  
     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     */ 
    469789    init: function() { 
    470         var lists = this; 
    471  
    472         lists.wpList.process = function(a) { 
    473             lists.each( function() { 
    474                 this.wpList.process(a); 
     790        var $list = this; 
     791 
     792        $list.wpList.process = function() { 
     793            $list.each( function( index, element ) { 
     794                this.wpList.process( element ); 
    475795            } ); 
    476796        }; 
    477797 
    478         lists.wpList.recolor = function() { 
    479             lists.each( function() { 
     798        $list.wpList.recolor = function() { 
     799            $list.each( function() { 
    480800                this.wpList.recolor(); 
    481801            } ); 
     
    484804}; 
    485805 
     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 */ 
    486836$.fn.wpList = function( settings ) { 
    487     this.each( function() { 
    488         var _this = this; 
    489  
    490         this.wpList = { settings: $.extend( {}, wpList.settings, { what: wpList.parseData(this,'list')[1] || '' }, settings ) }; 
    491         $.each( fs, function(i,f) { _this.wpList[i] = function( e, s ) { return wpList[f].call( _this, e, s ); }; } ); 
     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        } ); 
    492847    } ); 
    493848 
    494     wpList.init.call(this); 
    495  
     849    wpList.init.call( this ); 
    496850    this.wpList.process(); 
    497851 
    498852    return this; 
    499853}; 
    500  
    501 })(jQuery); 
     854} ) ( jQuery ); 
Note: See TracChangeset for help on using the changeset viewer.