Make WordPress Core

Changeset 25462


Ignore:
Timestamp:
09/16/2013 09:05:35 PM (11 years ago)
Author:
nacin
Message:

Update jQuery Form to 3.37.0 (unused in WP core).

props usermrpapa.
fixes #23944.

Location:
trunk/src/wp-includes
Files:
3 edited

Legend:

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

    r21592 r25462  
    11/*!
    22 * jQuery Form Plugin
    3  * version: 2.73 (03-MAY-2011)
    4  * @requires jQuery v1.3.2 or later
    5  *
     3 * version: 3.37.0-2013.07.11
     4 * @requires jQuery v1.5 or later
     5 * Copyright (c) 2013 M. Alsup
    66 * Examples and documentation at: http://malsup.com/jquery/form/
    7  * Dual licensed under the MIT and GPL licenses:
    8  *   http://www.opensource.org/licenses/mit-license.php
    9  *   http://www.gnu.org/licenses/gpl.html
    10  */
     7 * Project repository: https://github.com/malsup/form
     8 * Dual licensed under the MIT and GPL licenses.
     9 * https://github.com/malsup/form#copyright-and-license
     10 */
     11/*global ActiveXObject */
    1112;(function($) {
     13"use strict";
    1214
    1315/*
    14     Usage Note:
    15     -----------
    16     Do not use both ajaxSubmit and ajaxForm on the same form.  These
    17     functions are intended to be exclusive.  Use ajaxSubmit if you want
    18     to bind your own submit handler to the form.  For example,
    19 
    20     $(document).ready(function() {
    21         $('#myForm').bind('submit', function(e) {
    22             e.preventDefault(); // <-- important
    23             $(this).ajaxSubmit({
    24                 target: '#output'
    25             });
    26         });
    27     });
    28 
    29     Use ajaxForm when you want the plugin to manage all the event binding
    30     for you.  For example,
    31 
    32     $(document).ready(function() {
    33         $('#myForm').ajaxForm({
    34             target: '#output'
    35         });
    36     });
    37 
    38     When using ajaxForm, the ajaxSubmit function will be invoked for you
    39     at the appropriate time.
     16    Usage Note:
     17    -----------
     18    Do not use both ajaxSubmit and ajaxForm on the same form.  These
     19    functions are mutually exclusive.  Use ajaxSubmit if you want
     20    to bind your own submit handler to the form.  For example,
     21
     22    $(document).ready(function() {
     23        $('#myForm').on('submit', function(e) {
     24            e.preventDefault(); // <-- important
     25            $(this).ajaxSubmit({
     26                target: '#output'
     27            });
     28        });
     29    });
     30
     31    Use ajaxForm when you want the plugin to manage all the event binding
     32    for you.  For example,
     33
     34    $(document).ready(function() {
     35        $('#myForm').ajaxForm({
     36            target: '#output'
     37        });
     38    });
     39
     40    You can also use ajaxForm with delegation (requires jQuery v1.7+), so the
     41    form does not have to exist when you invoke ajaxForm:
     42
     43    $('#myForm').ajaxForm({
     44        delegation: true,
     45        target: '#output'
     46    });
     47
     48    When using ajaxForm, the ajaxSubmit function will be invoked for you
     49    at the appropriate time.
    4050*/
     51
     52/**
     53 * Feature detection
     54 */
     55var feature = {};
     56feature.fileapi = $("<input type='file'/>").get(0).files !== undefined;
     57feature.formdata = window.FormData !== undefined;
     58
     59var hasProp = !!$.fn.prop;
     60
     61// attr2 uses prop when it can but checks the return type for
     62// an expected string.  this accounts for the case where a form
     63// contains inputs with names like "action" or "method"; in those
     64// cases "prop" returns the element
     65$.fn.attr2 = function() {
     66    if ( ! hasProp )
     67        return this.attr.apply(this, arguments);
     68    var val = this.prop.apply(this, arguments);
     69    if ( ( val && val.jquery ) || typeof val === 'string' )
     70        return val;
     71    return this.attr.apply(this, arguments);
     72};
    4173
    4274/**
     
    4577 */
    4678$.fn.ajaxSubmit = function(options) {
    47     // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
    48     if (!this.length) {
    49         log('ajaxSubmit: skipping submit process - no element selected');
    50         return this;
    51     }
    52 
    53     if (typeof options == 'function') {
    54         options = { success: options };
    55     }
    56 
    57     var action = this.attr('action');
    58     var url = (typeof action === 'string') ? $.trim(action) : '';
    59     if (url) {
    60         // clean url (don't include hash vaue)
    61         url = (url.match(/^([^#]+)/)||[])[1];
    62     }
    63     url = url || window.location.href || '';
    64 
    65     options = $.extend(true, {
    66         url:  url,
    67         success: $.ajaxSettings.success,
    68         type: this[0].getAttribute('method') || 'GET', // IE7 massage (see issue 57)
    69         iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
    70     }, options);
    71 
    72     // hook for manipulating the form data before it is extracted;
    73     // convenient for use with rich editors like tinyMCE or FCKEditor
    74     var veto = {};
    75     this.trigger('form-pre-serialize', [this, options, veto]);
    76     if (veto.veto) {
    77         log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
    78         return this;
    79     }
    80 
    81     // provide opportunity to alter form data before it is serialized
    82     if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
    83         log('ajaxSubmit: submit aborted via beforeSerialize callback');
    84         return this;
    85     }
    86 
    87     var n,v,a = this.formToArray(options.semantic);
    88     if (options.data) {
    89         options.extraData = options.data;
    90         for (n in options.data) {
    91             if(options.data[n] instanceof Array) {
    92                 for (var k in options.data[n]) {
    93                     a.push( { name: n, value: options.data[n][k] } );
    94                 }
    95             }
    96             else {
    97                 v = options.data[n];
    98                 v = $.isFunction(v) ? v() : v; // if value is fn, invoke it
    99                 a.push( { name: n, value: v } );
    100             }
    101         }
    102     }
    103 
    104     // give pre-submit callback an opportunity to abort the submit
    105     if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
    106         log('ajaxSubmit: submit aborted via beforeSubmit callback');
    107         return this;
    108     }
    109 
    110     // fire vetoable 'validate' event
    111     this.trigger('form-submit-validate', [a, this, options, veto]);
    112     if (veto.veto) {
    113         log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
    114         return this;
    115     }
    116 
    117     var q = $.param(a);
    118 
    119     if (options.type.toUpperCase() == 'GET') {
    120         options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
    121         options.data = null;  // data is null for 'get'
    122     }
    123     else {
    124         options.data = q; // data is the query string for 'post'
    125     }
    126 
    127     var $form = this, callbacks = [];
    128     if (options.resetForm) {
    129         callbacks.push(function() { $form.resetForm(); });
    130     }
    131     if (options.clearForm) {
    132         callbacks.push(function() { $form.clearForm(); });
    133     }
    134 
    135     // perform a load on the target only if dataType is not provided
    136     if (!options.dataType && options.target) {
    137         var oldSuccess = options.success || function(){};
    138         callbacks.push(function(data) {
    139             var fn = options.replaceTarget ? 'replaceWith' : 'html';
    140             $(options.target)[fn](data).each(oldSuccess, arguments);
    141         });
    142     }
    143     else if (options.success) {
    144         callbacks.push(options.success);
    145     }
    146 
    147     options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
    148         var context = options.context || options;   // jQuery 1.4+ supports scope context
    149         for (var i=0, max=callbacks.length; i < max; i++) {
    150             callbacks[i].apply(context, [data, status, xhr || $form, $form]);
    151         }
    152     };
    153 
    154     // are there files to upload?
    155     var fileInputs = $('input:file', this).length > 0;
    156     var mp = 'multipart/form-data';
    157     var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);
    158 
    159     // options.iframe allows user to force iframe mode
    160     // 06-NOV-09: now defaulting to iframe mode if file input is detected
    161    if (options.iframe !== false && (fileInputs || options.iframe || multipart)) {
    162        // hack to fix Safari hang (thanks to Tim Molendijk for this)
    163        // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
    164        if (options.closeKeepAlive) {
    165            $.get(options.closeKeepAlive, fileUpload);
    166         }
    167        else {
    168            fileUpload();
    169         }
    170    }
    171    else {
    172         $.ajax(options);
    173    }
    174 
    175     // fire 'notify' event
    176     this.trigger('form-submit-notify', [this, options]);
    177     return this;
    178 
    179 
    180     // private function for handling file uploads (hat tip to YAHOO!)
    181     function fileUpload() {
    182         var form = $form[0];
    183 
    184         if ($(':input[name=submit],:input[id=submit]', form).length) {
    185             // if there is an input with a name or id of 'submit' then we won't be
    186             // able to invoke the submit fn on the form (at least not x-browser)
    187             alert('Error: Form elements must not have name or id of "submit".');
    188             return;
    189         }
    190 
    191         var s = $.extend(true, {}, $.ajaxSettings, options);
    192         s.context = s.context || s;
    193         var id = 'jqFormIO' + (new Date().getTime()), fn = '_'+id;
    194         var $io = $('<iframe id="' + id + '" name="' + id + '" src="'+ s.iframeSrc +'" />');
    195         var io = $io[0];
    196 
    197         $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
    198 
    199         var xhr = { // mock object
    200             aborted: 0,
    201             responseText: null,
    202             responseXML: null,
    203             status: 0,
    204             statusText: 'n/a',
    205             getAllResponseHeaders: function() {},
    206             getResponseHeader: function() {},
    207             setRequestHeader: function() {},
    208             abort: function(status) {
    209                 var e = (status === 'timeout' ? 'timeout' : 'aborted');
    210                 log('aborting upload... ' + e);
    211                 this.aborted = 1;
    212                 $io.attr('src', s.iframeSrc); // abort op in progress
    213                 xhr.error = e;
    214                 s.error && s.error.call(s.context, xhr, e, e);
    215                 g && $.event.trigger("ajaxError", [xhr, s, e]);
    216                 s.complete && s.complete.call(s.context, xhr, e);
    217             }
    218         };
    219 
    220         var g = s.global;
    221         // trigger ajax global events so that activity/block indicators work like normal
    222         if (g && ! $.active++) {
    223             $.event.trigger("ajaxStart");
    224         }
    225         if (g) {
    226             $.event.trigger("ajaxSend", [xhr, s]);
    227         }
    228 
    229         if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
    230             if (s.global) {
    231                 $.active--;
    232             }
    233             return;
    234         }
    235         if (xhr.aborted) {
    236             return;
    237         }
    238 
    239         var timedOut = 0, timeoutHandle;
    240 
    241         // add submitting element to data if we know it
    242         var sub = form.clk;
    243         if (sub) {
    244             var n = sub.name;
    245             if (n && !sub.disabled) {
    246                 s.extraData = s.extraData || {};
    247                 s.extraData[n] = sub.value;
    248                 if (sub.type == "image") {
    249                     s.extraData[n+'.x'] = form.clk_x;
    250                     s.extraData[n+'.y'] = form.clk_y;
    251                 }
    252             }
    253         }
    254 
    255         // take a breath so that pending repaints get some cpu time before the upload starts
    256         function doSubmit() {
    257             // make sure form attrs are set
    258             var t = $form.attr('target'), a = $form.attr('action');
    259 
    260             // update form attrs in IE friendly way
    261             form.setAttribute('target',id);
    262             if (form.getAttribute('method') != 'POST') {
    263                 form.setAttribute('method', 'POST');
    264             }
    265             if (form.getAttribute('action') != s.url) {
    266                 form.setAttribute('action', s.url);
    267             }
    268 
    269             // ie borks in some cases when setting encoding
    270             if (! s.skipEncodingOverride) {
    271                 $form.attr({
    272                     encoding: 'multipart/form-data',
    273                     enctype:  'multipart/form-data'
    274                 });
    275             }
    276 
    277             // support timout
    278             if (s.timeout) {
    279                 timeoutHandle = setTimeout(function() { timedOut = true; cb(true); }, s.timeout);
    280             }
    281 
    282             // add "extra" data to form if provided in options
    283             var extraInputs = [];
    284             try {
    285                 if (s.extraData) {
    286                     for (var n in s.extraData) {
    287                         extraInputs.push(
    288                             $('<input type="hidden" name="'+n+'" value="'+s.extraData[n]+'" />')
    289                                 .appendTo(form)[0]);
    290                     }
    291                 }
    292 
    293                 // add iframe to doc and submit the form
    294                 $io.appendTo('body');
    295                 io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
    296                 form.submit();
    297             }
    298             finally {
    299                 // reset attrs and remove "extra" input elements
    300                 form.setAttribute('action',a);
    301                 if(t) {
    302                     form.setAttribute('target', t);
    303                 } else {
    304                     $form.removeAttr('target');
    305                 }
    306                 $(extraInputs).remove();
    307             }
    308         }
    309 
    310         if (s.forceSync) {
    311             doSubmit();
    312         }
    313         else {
    314             setTimeout(doSubmit, 10); // this lets dom updates render
    315         }
    316 
    317         var data, doc, domCheckCount = 50, callbackProcessed;
    318 
    319         function cb(e) {
    320             if (xhr.aborted || callbackProcessed) {
    321                 return;
    322             }
    323             if (e === true && xhr) {
    324                 xhr.abort('timeout');
    325                 return;
    326             }
    327 
    328             var doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
    329             if (!doc || doc.location.href == s.iframeSrc) {
    330                 // response not received yet
    331                 if (!timedOut)
    332                     return;
    333             }
    334             io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);
    335 
    336             var ok = true;
    337             try {
    338                 if (timedOut) {
    339                     throw 'timeout';
    340                 }
    341 
    342                 var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
    343                 log('isXml='+isXml);
    344                 if (!isXml && window.opera && (doc.body == null || doc.body.innerHTML == '')) {
    345                     if (--domCheckCount) {
    346                         // in some browsers (Opera) the iframe DOM is not always traversable when
    347                         // the onload callback fires, so we loop a bit to accommodate
    348                         log('requeing onLoad callback, DOM not available');
    349                         setTimeout(cb, 250);
    350                         return;
    351                     }
    352                     // let this fall through because server response could be an empty document
    353                     //log('Could not access iframe DOM after mutiple tries.');
    354                     //throw 'DOMException: not available';
    355                 }
    356 
    357                 //log('response detected');
    358                 xhr.responseText = doc.body ? doc.body.innerHTML : doc.documentElement ? doc.documentElement.innerHTML : null;
    359                 xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
    360                 if (isXml)
    361                     s.dataType = 'xml';
    362                 xhr.getResponseHeader = function(header){
    363                     var headers = {'content-type': s.dataType};
    364                     return headers[header];
    365                 };
    366 
    367                 var scr = /(json|script|text)/.test(s.dataType);
    368                 if (scr || s.textarea) {
    369                     // see if user embedded response in textarea
    370                     var ta = doc.getElementsByTagName('textarea')[0];
    371                     if (ta) {
    372                         xhr.responseText = ta.value;
    373                     }
    374                     else if (scr) {
    375                         // account for browsers injecting pre around json response
    376                         var pre = doc.getElementsByTagName('pre')[0];
    377                         var b = doc.getElementsByTagName('body')[0];
    378                         if (pre) {
    379                             xhr.responseText = pre.textContent;
    380                         }
    381                         else if (b) {
    382                             xhr.responseText = b.innerHTML;
    383                         }
    384                     }
    385                 }
    386                 else if (s.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
    387                     xhr.responseXML = toXml(xhr.responseText);
    388                 }
    389 
    390                 data = httpData(xhr, s.dataType, s);
    391             }
    392             catch(e){
    393                 log('error caught:',e);
    394                 ok = false;
    395                 xhr.error = e;
    396                 s.error && s.error.call(s.context, xhr, 'error', e);
    397                 g && $.event.trigger("ajaxError", [xhr, s, e]);
    398             }
    399 
    400             if (xhr.aborted) {
    401                 log('upload aborted');
    402                 ok = false;
    403             }
    404 
    405             // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
    406             if (ok) {
    407                 s.success && s.success.call(s.context, data, 'success', xhr);
    408                 g && $.event.trigger("ajaxSuccess", [xhr, s]);
    409             }
    410 
    411             g && $.event.trigger("ajaxComplete", [xhr, s]);
    412 
    413             if (g && ! --$.active) {
    414                 $.event.trigger("ajaxStop");
    415             }
    416 
    417             s.complete && s.complete.call(s.context, xhr, ok ? 'success' : 'error');
    418 
    419             callbackProcessed = true;
    420             if (s.timeout)
    421                 clearTimeout(timeoutHandle);
    422 
    423             // clean up
    424             setTimeout(function() {
    425                 $io.removeData('form-plugin-onload');
    426                 $io.remove();
    427                 xhr.responseXML = null;
    428             }, 100);
    429         }
    430 
    431         var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+)
    432             if (window.ActiveXObject) {
    433                 doc = new ActiveXObject('Microsoft.XMLDOM');
    434                 doc.async = 'false';
    435                 doc.loadXML(s);
    436             }
    437             else {
    438                 doc = (new DOMParser()).parseFromString(s, 'text/xml');
    439             }
    440             return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null;
    441         };
    442         var parseJSON = $.parseJSON || function(s) {
    443             return window['eval']('(' + s + ')');
    444         };
    445 
    446         var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4
    447             var ct = xhr.getResponseHeader('content-type') || '',
    448                 xml = type === 'xml' || !type && ct.indexOf('xml') >= 0,
    449                 data = xml ? xhr.responseXML : xhr.responseText;
    450 
    451             if (xml && data.documentElement.nodeName === 'parsererror') {
    452                 $.error && $.error('parsererror');
    453             }
    454             if (s && s.dataFilter) {
    455                 data = s.dataFilter(data, type);
    456             }
    457             if (typeof data === 'string') {
    458                 if (type === 'json' || !type && ct.indexOf('json') >= 0) {
    459                     data = parseJSON(data);
    460                 } else if (type === "script" || !type && ct.indexOf("javascript") >= 0) {
    461                     $.globalEval(data);
    462                 }
    463             }
    464             return data;
    465         };
    466     }
     79    /*jshint scripturl:true */
     80
     81    // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
     82    if (!this.length) {
     83        log('ajaxSubmit: skipping submit process - no element selected');
     84        return this;
     85    }
     86
     87    var method, action, url, $form = this;
     88
     89    if (typeof options == 'function') {
     90        options = { success: options };
     91    }
     92    else if ( options === undefined ) {
     93        options = {};
     94    }
     95
     96    method = options.type || this.attr2('method');
     97    action = options.url  || this.attr2('action');
     98
     99    url = (typeof action === 'string') ? $.trim(action) : '';
     100    url = url || window.location.href || '';
     101    if (url) {
     102        // clean url (don't include hash vaue)
     103        url = (url.match(/^([^#]+)/)||[])[1];
     104    }
     105
     106    options = $.extend(true, {
     107        url:  url,
     108        success: $.ajaxSettings.success,
     109        type: method || 'GET',
     110        iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
     111    }, options);
     112
     113    // hook for manipulating the form data before it is extracted;
     114    // convenient for use with rich editors like tinyMCE or FCKEditor
     115    var veto = {};
     116    this.trigger('form-pre-serialize', [this, options, veto]);
     117    if (veto.veto) {
     118        log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
     119        return this;
     120    }
     121
     122    // provide opportunity to alter form data before it is serialized
     123    if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
     124        log('ajaxSubmit: submit aborted via beforeSerialize callback');
     125        return this;
     126    }
     127
     128    var traditional = options.traditional;
     129    if ( traditional === undefined ) {
     130        traditional = $.ajaxSettings.traditional;
     131    }
     132
     133    var elements = [];
     134    var qx, a = this.formToArray(options.semantic, elements);
     135    if (options.data) {
     136        options.extraData = options.data;
     137        qx = $.param(options.data, traditional);
     138    }
     139
     140    // give pre-submit callback an opportunity to abort the submit
     141    if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
     142        log('ajaxSubmit: submit aborted via beforeSubmit callback');
     143        return this;
     144    }
     145
     146    // fire vetoable 'validate' event
     147    this.trigger('form-submit-validate', [a, this, options, veto]);
     148    if (veto.veto) {
     149        log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
     150        return this;
     151    }
     152
     153    var q = $.param(a, traditional);
     154    if (qx) {
     155        q = ( q ? (q + '&' + qx) : qx );
     156    }
     157    if (options.type.toUpperCase() == 'GET') {
     158        options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
     159        options.data = null;  // data is null for 'get'
     160    }
     161    else {
     162        options.data = q; // data is the query string for 'post'
     163    }
     164
     165    var callbacks = [];
     166    if (options.resetForm) {
     167        callbacks.push(function() { $form.resetForm(); });
     168    }
     169    if (options.clearForm) {
     170        callbacks.push(function() { $form.clearForm(options.includeHidden); });
     171    }
     172
     173    // perform a load on the target only if dataType is not provided
     174    if (!options.dataType && options.target) {
     175        var oldSuccess = options.success || function(){};
     176        callbacks.push(function(data) {
     177            var fn = options.replaceTarget ? 'replaceWith' : 'html';
     178            $(options.target)[fn](data).each(oldSuccess, arguments);
     179        });
     180    }
     181    else if (options.success) {
     182        callbacks.push(options.success);
     183    }
     184
     185    options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
     186        var context = options.context || this ;    // jQuery 1.4+ supports scope context
     187        for (var i=0, max=callbacks.length; i < max; i++) {
     188            callbacks[i].apply(context, [data, status, xhr || $form, $form]);
     189        }
     190    };
     191
     192    if (options.error) {
     193        var oldError = options.error;
     194        options.error = function(xhr, status, error) {
     195            var context = options.context || this;
     196            oldError.apply(context, [xhr, status, error, $form]);
     197        };
     198    }
     199
     200     if (options.complete) {
     201        var oldComplete = options.complete;
     202        options.complete = function(xhr, status) {
     203            var context = options.context || this;
     204            oldComplete.apply(context, [xhr, status, $form]);
     205        };
     206    }
     207
     208    // are there files to upload?
     209
     210    // [value] (issue #113), also see comment:
     211    // https://github.com/malsup/form/commit/588306aedba1de01388032d5f42a60159eea9228#commitcomment-2180219
     212    var fileInputs = $('input[type=file]:enabled[value!=""]', this);
     213
     214    var hasFileInputs = fileInputs.length > 0;
     215    var mp = 'multipart/form-data';
     216    var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);
     217
     218    var fileAPI = feature.fileapi && feature.formdata;
     219    log("fileAPI :" + fileAPI);
     220    var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI;
     221
     222    var jqxhr;
     223
     224    // options.iframe allows user to force iframe mode
     225    // 06-NOV-09: now defaulting to iframe mode if file input is detected
     226    if (options.iframe !== false && (options.iframe || shouldUseFrame)) {
     227        // hack to fix Safari hang (thanks to Tim Molendijk for this)
     228        // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
     229        if (options.closeKeepAlive) {
     230            $.get(options.closeKeepAlive, function() {
     231                jqxhr = fileUploadIframe(a);
     232            });
     233        }
     234        else {
     235            jqxhr = fileUploadIframe(a);
     236        }
     237    }
     238    else if ((hasFileInputs || multipart) && fileAPI) {
     239        jqxhr = fileUploadXhr(a);
     240    }
     241    else {
     242        jqxhr = $.ajax(options);
     243    }
     244
     245    $form.removeData('jqxhr').data('jqxhr', jqxhr);
     246
     247    // clear element array
     248    for (var k=0; k < elements.length; k++)
     249        elements[k] = null;
     250
     251    // fire 'notify' event
     252    this.trigger('form-submit-notify', [this, options]);
     253    return this;
     254
     255    // utility fn for deep serialization
     256    function deepSerialize(extraData){
     257        var serialized = $.param(extraData, options.traditional).split('&');
     258        var len = serialized.length;
     259        var result = [];
     260        var i, part;
     261        for (i=0; i < len; i++) {
     262            // #252; undo param space replacement
     263            serialized[i] = serialized[i].replace(/\+/g,' ');
     264            part = serialized[i].split('=');
     265            // #278; use array instead of object storage, favoring array serializations
     266            result.push([decodeURIComponent(part[0]), decodeURIComponent(part[1])]);
     267        }
     268        return result;
     269    }
     270
     271     // XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz)
     272    function fileUploadXhr(a) {
     273        var formdata = new FormData();
     274
     275        for (var i=0; i < a.length; i++) {
     276            formdata.append(a[i].name, a[i].value);
     277        }
     278
     279        if (options.extraData) {
     280            var serializedData = deepSerialize(options.extraData);
     281            for (i=0; i < serializedData.length; i++)
     282                if (serializedData[i])
     283                    formdata.append(serializedData[i][0], serializedData[i][1]);
     284        }
     285
     286        options.data = null;
     287
     288        var s = $.extend(true, {}, $.ajaxSettings, options, {
     289            contentType: false,
     290            processData: false,
     291            cache: false,
     292            type: method || 'POST'
     293        });
     294
     295        if (options.uploadProgress) {
     296            // workaround because jqXHR does not expose upload property
     297            s.xhr = function() {
     298                var xhr = $.ajaxSettings.xhr();
     299                if (xhr.upload) {
     300                    xhr.upload.addEventListener('progress', function(event) {
     301                        var percent = 0;
     302                        var position = event.loaded || event.position; /*event.position is deprecated*/
     303                        var total = event.total;
     304                        if (event.lengthComputable) {
     305                            percent = Math.ceil(position / total * 100);
     306                        }
     307                        options.uploadProgress(event, position, total, percent);
     308                    }, false);
     309                }
     310                return xhr;
     311            };
     312        }
     313
     314        s.data = null;
     315            var beforeSend = s.beforeSend;
     316            s.beforeSend = function(xhr, o) {
     317                o.data = formdata;
     318                if(beforeSend)
     319                    beforeSend.call(this, xhr, o);
     320        };
     321        return $.ajax(s);
     322    }
     323
     324    // private function for handling file uploads (hat tip to YAHOO!)
     325    function fileUploadIframe(a) {
     326        var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle;
     327        var deferred = $.Deferred();
     328
     329        if (a) {
     330            // ensure that every serialized input is still enabled
     331            for (i=0; i < elements.length; i++) {
     332                el = $(elements[i]);
     333                if ( hasProp )
     334                    el.prop('disabled', false);
     335                else
     336                    el.removeAttr('disabled');
     337            }
     338        }
     339
     340        s = $.extend(true, {}, $.ajaxSettings, options);
     341        s.context = s.context || s;
     342        id = 'jqFormIO' + (new Date().getTime());
     343        if (s.iframeTarget) {
     344            $io = $(s.iframeTarget);
     345            n = $io.attr2('name');
     346            if (!n)
     347                 $io.attr2('name', id);
     348            else
     349                id = n;
     350        }
     351        else {
     352            $io = $('<iframe name="' + id + '" src="'+ s.iframeSrc +'" />');
     353            $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
     354        }
     355        io = $io[0];
     356
     357
     358        xhr = { // mock object
     359            aborted: 0,
     360            responseText: null,
     361            responseXML: null,
     362            status: 0,
     363            statusText: 'n/a',
     364            getAllResponseHeaders: function() {},
     365            getResponseHeader: function() {},
     366            setRequestHeader: function() {},
     367            abort: function(status) {
     368                var e = (status === 'timeout' ? 'timeout' : 'aborted');
     369                log('aborting upload... ' + e);
     370                this.aborted = 1;
     371
     372                try { // #214, #257
     373                    if (io.contentWindow.document.execCommand) {
     374                        io.contentWindow.document.execCommand('Stop');
     375                    }
     376                }
     377                catch(ignore) {}
     378
     379                $io.attr('src', s.iframeSrc); // abort op in progress
     380                xhr.error = e;
     381                if (s.error)
     382                    s.error.call(s.context, xhr, e, status);
     383                if (g)
     384                    $.event.trigger("ajaxError", [xhr, s, e]);
     385                if (s.complete)
     386                    s.complete.call(s.context, xhr, e);
     387            }
     388        };
     389
     390        g = s.global;
     391        // trigger ajax global events so that activity/block indicators work like normal
     392        if (g && 0 === $.active++) {
     393            $.event.trigger("ajaxStart");
     394        }
     395        if (g) {
     396            $.event.trigger("ajaxSend", [xhr, s]);
     397        }
     398
     399        if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
     400            if (s.global) {
     401                $.active--;
     402            }
     403            deferred.reject();
     404            return deferred;
     405        }
     406        if (xhr.aborted) {
     407            deferred.reject();
     408            return deferred;
     409        }
     410
     411        // add submitting element to data if we know it
     412        sub = form.clk;
     413        if (sub) {
     414            n = sub.name;
     415            if (n && !sub.disabled) {
     416                s.extraData = s.extraData || {};
     417                s.extraData[n] = sub.value;
     418                if (sub.type == "image") {
     419                    s.extraData[n+'.x'] = form.clk_x;
     420                    s.extraData[n+'.y'] = form.clk_y;
     421                }
     422            }
     423        }
     424
     425        var CLIENT_TIMEOUT_ABORT = 1;
     426        var SERVER_ABORT = 2;
     427               
     428        function getDoc(frame) {
     429            /* it looks like contentWindow or contentDocument do not
     430             * carry the protocol property in ie8, when running under ssl
     431             * frame.document is the only valid response document, since
     432             * the protocol is know but not on the other two objects. strange?
     433             * "Same origin policy" http://en.wikipedia.org/wiki/Same_origin_policy
     434             */
     435           
     436            var doc = null;
     437           
     438            // IE8 cascading access check
     439            try {
     440                if (frame.contentWindow) {
     441                    doc = frame.contentWindow.document;
     442                }
     443            } catch(err) {
     444                // IE8 access denied under ssl & missing protocol
     445                log('cannot get iframe.contentWindow document: ' + err);
     446            }
     447
     448            if (doc) { // successful getting content
     449                return doc;
     450            }
     451
     452            try { // simply checking may throw in ie8 under ssl or mismatched protocol
     453                doc = frame.contentDocument ? frame.contentDocument : frame.document;
     454            } catch(err) {
     455                // last attempt
     456                log('cannot get iframe.contentDocument: ' + err);
     457                doc = frame.document;
     458            }
     459            return doc;
     460        }
     461
     462        // Rails CSRF hack (thanks to Yvan Barthelemy)
     463        var csrf_token = $('meta[name=csrf-token]').attr('content');
     464        var csrf_param = $('meta[name=csrf-param]').attr('content');
     465        if (csrf_param && csrf_token) {
     466            s.extraData = s.extraData || {};
     467            s.extraData[csrf_param] = csrf_token;
     468        }
     469
     470        // take a breath so that pending repaints get some cpu time before the upload starts
     471        function doSubmit() {
     472            // make sure form attrs are set
     473            var t = $form.attr2('target'), a = $form.attr2('action');
     474
     475            // update form attrs in IE friendly way
     476            form.setAttribute('target',id);
     477            if (!method) {
     478                form.setAttribute('method', 'POST');
     479            }
     480            if (a != s.url) {
     481                form.setAttribute('action', s.url);
     482            }
     483
     484            // ie borks in some cases when setting encoding
     485            if (! s.skipEncodingOverride && (!method || /post/i.test(method))) {
     486                $form.attr({
     487                    encoding: 'multipart/form-data',
     488                    enctype:  'multipart/form-data'
     489                });
     490            }
     491
     492            // support timout
     493            if (s.timeout) {
     494                timeoutHandle = setTimeout(function() { timedOut = true; cb(CLIENT_TIMEOUT_ABORT); }, s.timeout);
     495            }
     496
     497            // look for server aborts
     498            function checkState() {
     499                try {
     500                    var state = getDoc(io).readyState;
     501                    log('state = ' + state);
     502                    if (state && state.toLowerCase() == 'uninitialized')
     503                        setTimeout(checkState,50);
     504                }
     505                catch(e) {
     506                    log('Server abort: ' , e, ' (', e.name, ')');
     507                    cb(SERVER_ABORT);
     508                    if (timeoutHandle)
     509                        clearTimeout(timeoutHandle);
     510                    timeoutHandle = undefined;
     511                }
     512            }
     513
     514            // add "extra" data to form if provided in options
     515            var extraInputs = [];
     516            try {
     517                if (s.extraData) {
     518                    for (var n in s.extraData) {
     519                        if (s.extraData.hasOwnProperty(n)) {
     520                           // if using the $.param format that allows for multiple values with the same name
     521                           if($.isPlainObject(s.extraData[n]) && s.extraData[n].hasOwnProperty('name') && s.extraData[n].hasOwnProperty('value')) {
     522                               extraInputs.push(
     523                               $('<input type="hidden" name="'+s.extraData[n].name+'">').val(s.extraData[n].value)
     524                                   .appendTo(form)[0]);
     525                           } else {
     526                               extraInputs.push(
     527                               $('<input type="hidden" name="'+n+'">').val(s.extraData[n])
     528                                   .appendTo(form)[0]);
     529                           }
     530                        }
     531                    }
     532                }
     533
     534                if (!s.iframeTarget) {
     535                    // add iframe to doc and submit the form
     536                    $io.appendTo('body');
     537                    if (io.attachEvent)
     538                        io.attachEvent('onload', cb);
     539                    else
     540                        io.addEventListener('load', cb, false);
     541                }
     542                setTimeout(checkState,15);
     543
     544                try {
     545                    form.submit();
     546                } catch(err) {
     547                    // just in case form has element with name/id of 'submit'
     548                    var submitFn = document.createElement('form').submit;
     549                    submitFn.apply(form);
     550                }
     551            }
     552            finally {
     553                // reset attrs and remove "extra" input elements
     554                form.setAttribute('action',a);
     555                if(t) {
     556                    form.setAttribute('target', t);
     557                } else {
     558                    $form.removeAttr('target');
     559                }
     560                $(extraInputs).remove();
     561            }
     562        }
     563
     564        if (s.forceSync) {
     565            doSubmit();
     566        }
     567        else {
     568            setTimeout(doSubmit, 10); // this lets dom updates render
     569        }
     570
     571        var data, doc, domCheckCount = 50, callbackProcessed;
     572
     573        function cb(e) {
     574            if (xhr.aborted || callbackProcessed) {
     575                return;
     576            }
     577           
     578            doc = getDoc(io);
     579            if(!doc) {
     580                log('cannot access response document');
     581                e = SERVER_ABORT;
     582            }
     583            if (e === CLIENT_TIMEOUT_ABORT && xhr) {
     584                xhr.abort('timeout');
     585                deferred.reject(xhr, 'timeout');
     586                return;
     587            }
     588            else if (e == SERVER_ABORT && xhr) {
     589                xhr.abort('server abort');
     590                deferred.reject(xhr, 'error', 'server abort');
     591                return;
     592            }
     593
     594            if (!doc || doc.location.href == s.iframeSrc) {
     595                // response not received yet
     596                if (!timedOut)
     597                    return;
     598            }
     599            if (io.detachEvent)
     600                io.detachEvent('onload', cb);
     601            else
     602                io.removeEventListener('load', cb, false);
     603
     604            var status = 'success', errMsg;
     605            try {
     606                if (timedOut) {
     607                    throw 'timeout';
     608                }
     609
     610                var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
     611                log('isXml='+isXml);
     612                if (!isXml && window.opera && (doc.body === null || !doc.body.innerHTML)) {
     613                    if (--domCheckCount) {
     614                        // in some browsers (Opera) the iframe DOM is not always traversable when
     615                        // the onload callback fires, so we loop a bit to accommodate
     616                        log('requeing onLoad callback, DOM not available');
     617                        setTimeout(cb, 250);
     618                        return;
     619                    }
     620                    // let this fall through because server response could be an empty document
     621                    //log('Could not access iframe DOM after mutiple tries.');
     622                    //throw 'DOMException: not available';
     623                }
     624
     625                //log('response detected');
     626                var docRoot = doc.body ? doc.body : doc.documentElement;
     627                xhr.responseText = docRoot ? docRoot.innerHTML : null;
     628                xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
     629                if (isXml)
     630                    s.dataType = 'xml';
     631                xhr.getResponseHeader = function(header){
     632                    var headers = {'content-type': s.dataType};
     633                    return headers[header];
     634                };
     635                // support for XHR 'status' & 'statusText' emulation :
     636                if (docRoot) {
     637                    xhr.status = Number( docRoot.getAttribute('status') ) || xhr.status;
     638                    xhr.statusText = docRoot.getAttribute('statusText') || xhr.statusText;
     639                }
     640
     641                var dt = (s.dataType || '').toLowerCase();
     642                var scr = /(json|script|text)/.test(dt);
     643                if (scr || s.textarea) {
     644                    // see if user embedded response in textarea
     645                    var ta = doc.getElementsByTagName('textarea')[0];
     646                    if (ta) {
     647                        xhr.responseText = ta.value;
     648                        // support for XHR 'status' & 'statusText' emulation :
     649                        xhr.status = Number( ta.getAttribute('status') ) || xhr.status;
     650                        xhr.statusText = ta.getAttribute('statusText') || xhr.statusText;
     651                    }
     652                    else if (scr) {
     653                        // account for browsers injecting pre around json response
     654                        var pre = doc.getElementsByTagName('pre')[0];
     655                        var b = doc.getElementsByTagName('body')[0];
     656                        if (pre) {
     657                            xhr.responseText = pre.textContent ? pre.textContent : pre.innerText;
     658                        }
     659                        else if (b) {
     660                            xhr.responseText = b.textContent ? b.textContent : b.innerText;
     661                        }
     662                    }
     663                }
     664                else if (dt == 'xml' && !xhr.responseXML && xhr.responseText) {
     665                    xhr.responseXML = toXml(xhr.responseText);
     666                }
     667
     668                try {
     669                    data = httpData(xhr, dt, s);
     670                }
     671                catch (err) {
     672                    status = 'parsererror';
     673                    xhr.error = errMsg = (err || status);
     674                }
     675            }
     676            catch (err) {
     677                log('error caught: ',err);
     678                status = 'error';
     679                xhr.error = errMsg = (err || status);
     680            }
     681
     682            if (xhr.aborted) {
     683                log('upload aborted');
     684                status = null;
     685            }
     686
     687            if (xhr.status) { // we've set xhr.status
     688                status = (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) ? 'success' : 'error';
     689            }
     690
     691            // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
     692            if (status === 'success') {
     693                if (s.success)
     694                    s.success.call(s.context, data, 'success', xhr);
     695                deferred.resolve(xhr.responseText, 'success', xhr);
     696                if (g)
     697                    $.event.trigger("ajaxSuccess", [xhr, s]);
     698            }
     699            else if (status) {
     700                if (errMsg === undefined)
     701                    errMsg = xhr.statusText;
     702                if (s.error)
     703                    s.error.call(s.context, xhr, status, errMsg);
     704                deferred.reject(xhr, 'error', errMsg);
     705                if (g)
     706                    $.event.trigger("ajaxError", [xhr, s, errMsg]);
     707            }
     708
     709            if (g)
     710                $.event.trigger("ajaxComplete", [xhr, s]);
     711
     712            if (g && ! --$.active) {
     713                $.event.trigger("ajaxStop");
     714            }
     715
     716            if (s.complete)
     717                s.complete.call(s.context, xhr, status);
     718
     719            callbackProcessed = true;
     720            if (s.timeout)
     721                clearTimeout(timeoutHandle);
     722
     723            // clean up
     724            setTimeout(function() {
     725                if (!s.iframeTarget)
     726                    $io.remove();
     727                xhr.responseXML = null;
     728            }, 100);
     729        }
     730
     731        var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+)
     732            if (window.ActiveXObject) {
     733                doc = new ActiveXObject('Microsoft.XMLDOM');
     734                doc.async = 'false';
     735                doc.loadXML(s);
     736            }
     737            else {
     738                doc = (new DOMParser()).parseFromString(s, 'text/xml');
     739            }
     740            return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null;
     741        };
     742        var parseJSON = $.parseJSON || function(s) {
     743            /*jslint evil:true */
     744            return window['eval']('(' + s + ')');
     745        };
     746
     747        var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4
     748
     749            var ct = xhr.getResponseHeader('content-type') || '',
     750                xml = type === 'xml' || !type && ct.indexOf('xml') >= 0,
     751                data = xml ? xhr.responseXML : xhr.responseText;
     752
     753            if (xml && data.documentElement.nodeName === 'parsererror') {
     754                if ($.error)
     755                    $.error('parsererror');
     756            }
     757            if (s && s.dataFilter) {
     758                data = s.dataFilter(data, type);
     759            }
     760            if (typeof data === 'string') {
     761                if (type === 'json' || !type && ct.indexOf('json') >= 0) {
     762                    data = parseJSON(data);
     763                } else if (type === "script" || !type && ct.indexOf("javascript") >= 0) {
     764                    $.globalEval(data);
     765                }
     766            }
     767            return data;
     768        };
     769
     770        return deferred;
     771    }
    467772};
    468773
     
    473778 *
    474779 * 1: This method will include coordinates for <input type="image" /> elements (if the element
    475  *  is used to submit the form).
     780 *    is used to submit the form).
    476781 * 2. This method will include the submit element's name/value data (for the element that was
    477  *  used to submit the form).
     782 *    used to submit the form).
    478783 * 3. This method binds the submit() method to the form for you.
    479784 *
     
    483788 */
    484789$.fn.ajaxForm = function(options) {
    485     // in jQuery 1.3+ we can fix mistakes with the ready state
    486     if (this.length === 0) {
    487         var o = { s: this.selector, c: this.context };
    488         if (!$.isReady && o.s) {
    489             log('DOM not ready, queuing ajaxForm');
    490             $(function() {
    491                 $(o.s,o.c).ajaxForm(options);
    492             });
    493             return this;
    494         }
    495         // is your DOM ready?  http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
    496         log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
    497         return this;
    498     }
    499 
    500     return this.ajaxFormUnbind().bind('submit.form-plugin', function(e) {
    501         if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
    502             e.preventDefault();
    503             $(this).ajaxSubmit(options);
    504         }
    505     }).bind('click.form-plugin', function(e) {
    506         var target = e.target;
    507         var $el = $(target);
    508         if (!($el.is(":submit,input:image"))) {
    509             // is this a child element of the submit el?  (ex: a span within a button)
    510             var t = $el.closest(':submit');
    511             if (t.length == 0) {
    512                 return;
    513             }
    514             target = t[0];
    515         }
    516         var form = this;
    517         form.clk = target;
    518         if (target.type == 'image') {
    519             if (e.offsetX != undefined) {
    520                 form.clk_x = e.offsetX;
    521                 form.clk_y = e.offsetY;
    522             } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
    523                 var offset = $el.offset();
    524                 form.clk_x = e.pageX - offset.left;
    525                 form.clk_y = e.pageY - offset.top;
    526             } else {
    527                 form.clk_x = e.pageX - target.offsetLeft;
    528                 form.clk_y = e.pageY - target.offsetTop;
    529             }
    530         }
    531         // clear form vars
    532         setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
    533     });
    534 };
     790    options = options || {};
     791    options.delegation = options.delegation && $.isFunction($.fn.on);
     792
     793    // in jQuery 1.3+ we can fix mistakes with the ready state
     794    if (!options.delegation && this.length === 0) {
     795        var o = { s: this.selector, c: this.context };
     796        if (!$.isReady && o.s) {
     797            log('DOM not ready, queuing ajaxForm');
     798            $(function() {
     799                $(o.s,o.c).ajaxForm(options);
     800            });
     801            return this;
     802        }
     803        // is your DOM ready?  http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
     804        log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
     805        return this;
     806    }
     807
     808    if ( options.delegation ) {
     809        $(document)
     810            .off('submit.form-plugin', this.selector, doAjaxSubmit)
     811            .off('click.form-plugin', this.selector, captureSubmittingElement)
     812            .on('submit.form-plugin', this.selector, options, doAjaxSubmit)
     813            .on('click.form-plugin', this.selector, options, captureSubmittingElement);
     814        return this;
     815    }
     816
     817    return this.ajaxFormUnbind()
     818        .bind('submit.form-plugin', options, doAjaxSubmit)
     819        .bind('click.form-plugin', options, captureSubmittingElement);
     820};
     821
     822// private event handlers
     823function doAjaxSubmit(e) {
     824    /*jshint validthis:true */
     825    var options = e.data;
     826    if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
     827        e.preventDefault();
     828        $(this).ajaxSubmit(options);
     829    }
     830}
     831
     832function captureSubmittingElement(e) {
     833    /*jshint validthis:true */
     834    var target = e.target;
     835    var $el = $(target);
     836    if (!($el.is("[type=submit],[type=image]"))) {
     837        // is this a child element of the submit el?  (ex: a span within a button)
     838        var t = $el.closest('[type=submit]');
     839        if (t.length === 0) {
     840            return;
     841        }
     842        target = t[0];
     843    }
     844    var form = this;
     845    form.clk = target;
     846    if (target.type == 'image') {
     847        if (e.offsetX !== undefined) {
     848            form.clk_x = e.offsetX;
     849            form.clk_y = e.offsetY;
     850        } else if (typeof $.fn.offset == 'function') {
     851            var offset = $el.offset();
     852            form.clk_x = e.pageX - offset.left;
     853            form.clk_y = e.pageY - offset.top;
     854        } else {
     855            form.clk_x = e.pageX - target.offsetLeft;
     856            form.clk_y = e.pageY - target.offsetTop;
     857        }
     858    }
     859    // clear form vars
     860    setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
     861}
     862
    535863
    536864// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
    537865$.fn.ajaxFormUnbind = function() {
    538     return this.unbind('submit.form-plugin click.form-plugin');
     866    return this.unbind('submit.form-plugin click.form-plugin');
    539867};
    540868
     
    550878 * ajaxSubmit() and ajaxForm() methods.
    551879 */
    552 $.fn.formToArray = function(semantic) {
    553     var a = [];
    554     if (this.length === 0) {
    555         return a;
    556     }
    557 
    558     var form = this[0];
    559     var els = semantic ? form.getElementsByTagName('*') : form.elements;
    560     if (!els) {
    561         return a;
    562     }
    563 
    564     var i,j,n,v,el,max,jmax;
    565     for(i=0, max=els.length; i < max; i++) {
    566         el = els[i];
    567         n = el.name;
    568         if (!n) {
    569             continue;
    570         }
    571 
    572         if (semantic && form.clk && el.type == "image") {
    573             // handle image inputs on the fly when semantic == true
    574             if(!el.disabled && form.clk == el) {
    575                 a.push({name: n, value: $(el).val()});
    576                 a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
    577             }
    578             continue;
    579         }
    580 
    581         v = $.fieldValue(el, true);
    582         if (v && v.constructor == Array) {
    583             for(j=0, jmax=v.length; j < jmax; j++) {
    584                 a.push({name: n, value: v[j]});
    585             }
    586         }
    587         else if (v !== null && typeof v != 'undefined') {
    588             a.push({name: n, value: v});
    589         }
    590     }
    591 
    592     if (!semantic && form.clk) {
    593         // input type=='image' are not found in elements array! handle it here
    594         var $input = $(form.clk), input = $input[0];
    595         n = input.name;
    596         if (n && !input.disabled && input.type == 'image') {
    597             a.push({name: n, value: $input.val()});
    598             a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
    599         }
    600     }
    601     return a;
     880$.fn.formToArray = function(semantic, elements) {
     881    var a = [];
     882    if (this.length === 0) {
     883        return a;
     884    }
     885
     886    var form = this[0];
     887    var els = semantic ? form.getElementsByTagName('*') : form.elements;
     888    if (!els) {
     889        return a;
     890    }
     891
     892    var i,j,n,v,el,max,jmax;
     893    for(i=0, max=els.length; i < max; i++) {
     894        el = els[i];
     895        n = el.name;
     896        if (!n || el.disabled) {
     897            continue;
     898        }
     899
     900        if (semantic && form.clk && el.type == "image") {
     901            // handle image inputs on the fly when semantic == true
     902            if(form.clk == el) {
     903                a.push({name: n, value: $(el).val(), type: el.type });
     904                a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
     905            }
     906            continue;
     907        }
     908
     909        v = $.fieldValue(el, true);
     910        if (v && v.constructor == Array) {
     911            if (elements)
     912                elements.push(el);
     913            for(j=0, jmax=v.length; j < jmax; j++) {
     914                a.push({name: n, value: v[j]});
     915            }
     916        }
     917        else if (feature.fileapi && el.type == 'file') {
     918            if (elements)
     919                elements.push(el);
     920            var files = el.files;
     921            if (files.length) {
     922                for (j=0; j < files.length; j++) {
     923                    a.push({name: n, value: files[j], type: el.type});
     924                }
     925            }
     926            else {
     927                // #180
     928                a.push({ name: n, value: '', type: el.type });
     929            }
     930        }
     931        else if (v !== null && typeof v != 'undefined') {
     932            if (elements)
     933                elements.push(el);
     934            a.push({name: n, value: v, type: el.type, required: el.required});
     935        }
     936    }
     937
     938    if (!semantic && form.clk) {
     939        // input type=='image' are not found in elements array! handle it here
     940        var $input = $(form.clk), input = $input[0];
     941        n = input.name;
     942        if (n && !input.disabled && input.type == 'image') {
     943            a.push({name: n, value: $input.val()});
     944            a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
     945        }
     946    }
     947    return a;
    602948};
    603949
     
    607953 */
    608954$.fn.formSerialize = function(semantic) {
    609     //hand off to jQuery.param for proper encoding
    610     return $.param(this.formToArray(semantic));
     955    //hand off to jQuery.param for proper encoding
     956    return $.param(this.formToArray(semantic));
    611957};
    612958
     
    616962 */
    617963$.fn.fieldSerialize = function(successful) {
    618     var a = [];
    619     this.each(function() {
    620         var n = this.name;
    621         if (!n) {
    622             return;
    623         }
    624         var v = $.fieldValue(this, successful);
    625         if (v && v.constructor == Array) {
    626             for (var i=0,max=v.length; i < max; i++) {
    627                 a.push({name: n, value: v[i]});
    628             }
    629         }
    630         else if (v !== null && typeof v != 'undefined') {
    631             a.push({name: this.name, value: v});
    632         }
    633     });
    634     //hand off to jQuery.param for proper encoding
    635     return $.param(a);
     964    var a = [];
     965    this.each(function() {
     966        var n = this.name;
     967        if (!n) {
     968            return;
     969        }
     970        var v = $.fieldValue(this, successful);
     971        if (v && v.constructor == Array) {
     972            for (var i=0,max=v.length; i < max; i++) {
     973                a.push({name: n, value: v[i]});
     974            }
     975        }
     976        else if (v !== null && typeof v != 'undefined') {
     977            a.push({name: this.name, value: v});
     978        }
     979    });
     980    //hand off to jQuery.param for proper encoding
     981    return $.param(a);
    636982};
    637983
     
    640986 *
    641987 *  <form><fieldset>
    642  *    <input name="A" type="text" />
    643  *    <input name="A" type="text" />
    644  *    <input name="B" type="checkbox" value="B1" />
    645  *    <input name="B" type="checkbox" value="B2"/>
    646  *    <input name="C" type="radio" value="C1" />
    647  *    <input name="C" type="radio" value="C2" />
     988 *      <input name="A" type="text" />
     989 *      <input name="A" type="text" />
     990 *      <input name="B" type="checkbox" value="B1" />
     991 *      <input name="B" type="checkbox" value="B2"/>
     992 *      <input name="C" type="radio" value="C1" />
     993 *      <input name="C" type="radio" value="C2" />
    648994 *  </fieldset></form>
    649995 *
    650  *  var v = $(':text').fieldValue();
     996 *  var v = $('input[type=text]').fieldValue();
    651997 *  // if no values are entered into the text inputs
    652998 *  v == ['','']
     
    6541000 *  v == ['foo','bar']
    6551001 *
    656  *  var v = $(':checkbox').fieldValue();
     1002 *  var v = $('input[type=checkbox]').fieldValue();
    6571003 *  // if neither checkbox is checked
    6581004 *  v === undefined
     
    6601006 *  v == ['B1', 'B2']
    6611007 *
    662  *  var v = $(':radio').fieldValue();
     1008 *  var v = $('input[type=radio]').fieldValue();
    6631009 *  // if neither radio is checked
    6641010 *  v === undefined
     
    6721018 *
    6731019 * Note: This method *always* returns an array.  If no valid value can be determined the
    674  *     array will be empty, otherwise it will contain one or more values.
     1020 *    array will be empty, otherwise it will contain one or more values.
    6751021 */
    6761022$.fn.fieldValue = function(successful) {
    677     for (var val=[], i=0, max=this.length; i < max; i++) {
    678         var el = this[i];
    679         var v = $.fieldValue(el, successful);
    680         if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) {
    681             continue;
    682         }
    683         v.constructor == Array ? $.merge(val, v) : val.push(v);
    684     }
    685     return val;
     1023    for (var val=[], i=0, max=this.length; i < max; i++) {
     1024        var el = this[i];
     1025        var v = $.fieldValue(el, successful);
     1026        if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) {
     1027            continue;
     1028        }
     1029        if (v.constructor == Array)
     1030            $.merge(val, v);
     1031        else
     1032            val.push(v);
     1033    }
     1034    return val;
    6861035};
    6871036
     
    6901039 */
    6911040$.fieldValue = function(el, successful) {
    692     var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
    693     if (successful === undefined) {
    694         successful = true;
    695     }
    696 
    697     if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
    698         (t == 'checkbox' || t == 'radio') && !el.checked ||
    699         (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
    700         tag == 'select' && el.selectedIndex == -1)) {
    701             return null;
    702     }
    703 
    704     if (tag == 'select') {
    705         var index = el.selectedIndex;
    706         if (index < 0) {
    707             return null;
    708         }
    709         var a = [], ops = el.options;
    710         var one = (t == 'select-one');
    711         var max = (one ? index+1 : ops.length);
    712         for(var i=(one ? index : 0); i < max; i++) {
    713             var op = ops[i];
    714             if (op.selected) {
    715                 var v = op.value;
    716                 if (!v) { // extra pain for IE...
    717                     v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
    718                 }
    719                 if (one) {
    720                     return v;
    721                 }
    722                 a.push(v);
    723             }
    724         }
    725         return a;
    726     }
    727     return $(el).val();
     1041    var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
     1042    if (successful === undefined) {
     1043        successful = true;
     1044    }
     1045
     1046    if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
     1047        (t == 'checkbox' || t == 'radio') && !el.checked ||
     1048        (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
     1049        tag == 'select' && el.selectedIndex == -1)) {
     1050            return null;
     1051    }
     1052
     1053    if (tag == 'select') {
     1054        var index = el.selectedIndex;
     1055        if (index < 0) {
     1056            return null;
     1057        }
     1058        var a = [], ops = el.options;
     1059        var one = (t == 'select-one');
     1060        var max = (one ? index+1 : ops.length);
     1061        for(var i=(one ? index : 0); i < max; i++) {
     1062            var op = ops[i];
     1063            if (op.selected) {
     1064                var v = op.value;
     1065                if (!v) { // extra pain for IE...
     1066                    v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
     1067                }
     1068                if (one) {
     1069                    return v;
     1070                }
     1071                a.push(v);
     1072            }
     1073        }
     1074        return a;
     1075    }
     1076    return $(el).val();
    7281077};
    7291078
     
    7361085 *  - button elements will *not* be effected
    7371086 */
    738 $.fn.clearForm = function() {
    739     return this.each(function() {
    740         $('input,select,textarea', this).clearFields();
    741     });
     1087$.fn.clearForm = function(includeHidden) {
     1088    return this.each(function() {
     1089        $('input,select,textarea', this).clearFields(includeHidden);
     1090    });
    7421091};
    7431092
     
    7451094 * Clears the selected form elements.
    7461095 */
    747 $.fn.clearFields = $.fn.clearInputs = function() {
    748     return this.each(function() {
    749         var t = this.type, tag = this.tagName.toLowerCase();
    750         if (t == 'text' || t == 'password' || tag == 'textarea') {
    751             this.value = '';
     1096$.fn.clearFields = $.fn.clearInputs = function(includeHidden) {
     1097    var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list
     1098    return this.each(function() {
     1099        var t = this.type, tag = this.tagName.toLowerCase();
     1100        if (re.test(t) || tag == 'textarea') {
     1101            this.value = '';
     1102        }
     1103        else if (t == 'checkbox' || t == 'radio') {
     1104            this.checked = false;
     1105        }
     1106        else if (tag == 'select') {
     1107            this.selectedIndex = -1;
     1108        }
     1109        else if (t == "file") {
     1110            if (/MSIE/.test(navigator.userAgent)) {
     1111                $(this).replaceWith($(this).clone(true));
     1112            } else {
     1113                $(this).val('');
     1114            }
    7521115        }
    753         else if (t == 'checkbox' || t == 'radio') {
    754             this.checked = false;
    755         }
    756         else if (tag == 'select') {
    757             this.selectedIndex = -1;
    758         }
    759     });
     1116        else if (includeHidden) {
     1117            // includeHidden can be the value true, or it can be a selector string
     1118            // indicating a special test; for example:
     1119            //  $('#myForm').clearForm('.special:hidden')
     1120            // the above would clean hidden inputs that have the class of 'special'
     1121            if ( (includeHidden === true && /hidden/.test(t)) ||
     1122                 (typeof includeHidden == 'string' && $(this).is(includeHidden)) )
     1123                this.value = '';
     1124        }
     1125    });
    7601126};
    7611127
     
    7641130 */
    7651131$.fn.resetForm = function() {
    766     return this.each(function() {
    767         // guard against an input with the name of 'reset'
    768         // note that IE reports the reset function as an 'object'
    769         if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) {
    770             this.reset();
    771         }
    772     });
     1132    return this.each(function() {
     1133        // guard against an input with the name of 'reset'
     1134        // note that IE reports the reset function as an 'object'
     1135        if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) {
     1136            this.reset();
     1137        }
     1138    });
    7731139};
    7741140
     
    7771143 */
    7781144$.fn.enable = function(b) {
    779     if (b === undefined) {
    780         b = true;
    781     }
    782     return this.each(function() {
    783         this.disabled = !b;
    784     });
     1145    if (b === undefined) {
     1146        b = true;
     1147    }
     1148    return this.each(function() {
     1149        this.disabled = !b;
     1150    });
    7851151};
    7861152
     
    7901156 */
    7911157$.fn.selected = function(select) {
    792     if (select === undefined) {
    793         select = true;
    794     }
    795     return this.each(function() {
    796         var t = this.type;
    797         if (t == 'checkbox' || t == 'radio') {
    798             this.checked = select;
    799         }
    800         else if (this.tagName.toLowerCase() == 'option') {
    801             var $sel = $(this).parent('select');
    802             if (select && $sel[0] && $sel[0].type == 'select-one') {
    803                 // deselect all other options
    804                 $sel.find('option').selected(false);
    805             }
    806             this.selected = select;
    807         }
    808     });
    809 };
     1158    if (select === undefined) {
     1159        select = true;
     1160    }
     1161    return this.each(function() {
     1162        var t = this.type;
     1163        if (t == 'checkbox' || t == 'radio') {
     1164            this.checked = select;
     1165        }
     1166        else if (this.tagName.toLowerCase() == 'option') {
     1167            var $sel = $(this).parent('select');
     1168            if (select && $sel[0] && $sel[0].type == 'select-one') {
     1169                // deselect all other options
     1170                $sel.find('option').selected(false);
     1171            }
     1172            this.selected = select;
     1173        }
     1174    });
     1175};
     1176
     1177// expose debug var
     1178$.fn.ajaxSubmit.debug = false;
    8101179
    8111180// helper fn for console logging
    812 // set $.fn.ajaxSubmit.debug to true to enable debug logging
    8131181function log() {
    814     if ($.fn.ajaxSubmit.debug) {
    815         var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
    816         if (window.console && window.console.log) {
    817             window.console.log(msg);
    818         }
    819         else if (window.opera && window.opera.postError) {
    820             window.opera.postError(msg);
    821         }
    822     }
    823 };
     1182    if (!$.fn.ajaxSubmit.debug)
     1183        return;
     1184    var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
     1185    if (window.console && window.console.log) {
     1186        window.console.log(msg);
     1187    }
     1188    else if (window.opera && window.opera.postError) {
     1189        window.opera.postError(msg);
     1190    }
     1191}
    8241192
    8251193})(jQuery);
  • trunk/src/wp-includes/js/jquery/jquery.form.min.js

    r21592 r25462  
    11/*!
    22 * jQuery Form Plugin
    3  * version: 2.73 (03-MAY-2011)
    4  * @requires jQuery v1.3.2 or later
    5  *
     3 * version: 3.37.0-2013.07.11
     4 * @requires jQuery v1.5 or later
     5 * Copyright (c) 2013 M. Alsup
    66 * Examples and documentation at: http://malsup.com/jquery/form/
    7  * Dual licensed under the MIT and GPL licenses:
    8  *   http://www.opensource.org/licenses/mit-license.php
    9  *   http://www.gnu.org/licenses/gpl.html
     7 * Project repository: https://github.com/malsup/form
     8 * Dual licensed under the MIT and GPL licenses.
     9 * https://github.com/malsup/form#copyright-and-license
    1010 */
    11 (function(b){b.fn.ajaxSubmit=function(t){if(!this.length){a("ajaxSubmit: skipping submit process - no element selected");return this}if(typeof t=="function"){t={success:t}}var h=this.attr("action");var d=(typeof h==="string")?b.trim(h):"";if(d){d=(d.match(/^([^#]+)/)||[])[1]}d=d||window.location.href||"";t=b.extend(true,{url:d,success:b.ajaxSettings.success,type:this[0].getAttribute("method")||"GET",iframeSrc:/^https/i.test(window.location.href||"")?"javascript:false":"about:blank"},t);var u={};this.trigger("form-pre-serialize",[this,t,u]);if(u.veto){a("ajaxSubmit: submit vetoed via form-pre-serialize trigger");return this}if(t.beforeSerialize&&t.beforeSerialize(this,t)===false){a("ajaxSubmit: submit aborted via beforeSerialize callback");return this}var f,p,m=this.formToArray(t.semantic);if(t.data){t.extraData=t.data;for(f in t.data){if(t.data[f] instanceof Array){for(var i in t.data[f]){m.push({name:f,value:t.data[f][i]})}}else{p=t.data[f];p=b.isFunction(p)?p():p;m.push({name:f,value:p})}}}if(t.beforeSubmit&&t.beforeSubmit(m,this,t)===false){a("ajaxSubmit: submit aborted via beforeSubmit callback");return this}this.trigger("form-submit-validate",[m,this,t,u]);if(u.veto){a("ajaxSubmit: submit vetoed via form-submit-validate trigger");return this}var c=b.param(m);if(t.type.toUpperCase()=="GET"){t.url+=(t.url.indexOf("?")>=0?"&":"?")+c;t.data=null}else{t.data=c}var s=this,l=[];if(t.resetForm){l.push(function(){s.resetForm()})}if(t.clearForm){l.push(function(){s.clearForm()})}if(!t.dataType&&t.target){var r=t.success||function(){};l.push(function(n){var k=t.replaceTarget?"replaceWith":"html";b(t.target)[k](n).each(r,arguments)})}else{if(t.success){l.push(t.success)}}t.success=function(w,n,x){var v=t.context||t;for(var q=0,k=l.length;q<k;q++){l[q].apply(v,[w,n,x||s,s])}};var g=b("input:file",this).length>0;var e="multipart/form-data";var j=(s.attr("enctype")==e||s.attr("encoding")==e);if(t.iframe!==false&&(g||t.iframe||j)){if(t.closeKeepAlive){b.get(t.closeKeepAlive,o)}else{o()}}else{b.ajax(t)}this.trigger("form-submit-notify",[this,t]);return this;function o(){var v=s[0];if(b(":input[name=submit],:input[id=submit]",v).length){alert('Error: Form elements must not have name or id of "submit".');return}var D=b.extend(true,{},b.ajaxSettings,t);D.context=D.context||D;var G="jqFormIO"+(new Date().getTime()),A="_"+G;var x=b('<iframe id="'+G+'" name="'+G+'" src="'+D.iframeSrc+'" />');var B=x[0];x.css({position:"absolute",top:"-1000px",left:"-1000px"});var y={aborted:0,responseText:null,responseXML:null,status:0,statusText:"n/a",getAllResponseHeaders:function(){},getResponseHeader:function(){},setRequestHeader:function(){},abort:function(n){var O=(n==="timeout"?"timeout":"aborted");a("aborting upload... "+O);this.aborted=1;x.attr("src",D.iframeSrc);y.error=O;D.error&&D.error.call(D.context,y,O,O);K&&b.event.trigger("ajaxError",[y,D,O]);D.complete&&D.complete.call(D.context,y,O)}};var K=D.global;if(K&&!b.active++){b.event.trigger("ajaxStart")}if(K){b.event.trigger("ajaxSend",[y,D])}if(D.beforeSend&&D.beforeSend.call(D.context,y,D)===false){if(D.global){b.active--}return}if(y.aborted){return}var J=0,C;var z=v.clk;if(z){var H=z.name;if(H&&!z.disabled){D.extraData=D.extraData||{};D.extraData[H]=z.value;if(z.type=="image"){D.extraData[H+".x"]=v.clk_x;D.extraData[H+".y"]=v.clk_y}}}function I(){var Q=s.attr("target"),O=s.attr("action");v.setAttribute("target",G);if(v.getAttribute("method")!="POST"){v.setAttribute("method","POST")}if(v.getAttribute("action")!=D.url){v.setAttribute("action",D.url)}if(!D.skipEncodingOverride){s.attr({encoding:"multipart/form-data",enctype:"multipart/form-data"})}if(D.timeout){C=setTimeout(function(){J=true;F(true)},D.timeout)}var P=[];try{if(D.extraData){for(var R in D.extraData){P.push(b('<input type="hidden" name="'+R+'" value="'+D.extraData[R]+'" />').appendTo(v)[0])}}x.appendTo("body");B.attachEvent?B.attachEvent("onload",F):B.addEventListener("load",F,false);v.submit()}finally{v.setAttribute("action",O);if(Q){v.setAttribute("target",Q)}else{s.removeAttr("target")}b(P).remove()}}if(D.forceSync){I()}else{setTimeout(I,10)}var M,N,L=50,w;function F(T){if(y.aborted||w){return}if(T===true&&y){y.abort("timeout");return}var S=B.contentWindow?B.contentWindow.document:B.contentDocument?B.contentDocument:B.document;if(!S||S.location.href==D.iframeSrc){if(!J){return}}B.detachEvent?B.detachEvent("onload",F):B.removeEventListener("load",F,false);var P=true;try{if(J){throw"timeout"}var U=D.dataType=="xml"||S.XMLDocument||b.isXMLDoc(S);a("isXml="+U);if(!U&&window.opera&&(S.body==null||S.body.innerHTML=="")){if(--L){a("requeing onLoad callback, DOM not available");setTimeout(F,250);return}}y.responseText=S.body?S.body.innerHTML:S.documentElement?S.documentElement.innerHTML:null;y.responseXML=S.XMLDocument?S.XMLDocument:S;if(U){D.dataType="xml"}y.getResponseHeader=function(W){var V={"content-type":D.dataType};return V[W]};var R=/(json|script|text)/.test(D.dataType);if(R||D.textarea){var O=S.getElementsByTagName("textarea")[0];if(O){y.responseText=O.value}else{if(R){var Q=S.getElementsByTagName("pre")[0];var n=S.getElementsByTagName("body")[0];if(Q){y.responseText=Q.textContent}else{if(n){y.responseText=n.innerHTML}}}}}else{if(D.dataType=="xml"&&!y.responseXML&&y.responseText!=null){y.responseXML=E(y.responseText)}}M=k(y,D.dataType,D)}catch(T){a("error caught:",T);P=false;y.error=T;D.error&&D.error.call(D.context,y,"error",T);K&&b.event.trigger("ajaxError",[y,D,T])}if(y.aborted){a("upload aborted");P=false}if(P){D.success&&D.success.call(D.context,M,"success",y);K&&b.event.trigger("ajaxSuccess",[y,D])}K&&b.event.trigger("ajaxComplete",[y,D]);if(K&&!--b.active){b.event.trigger("ajaxStop")}D.complete&&D.complete.call(D.context,y,P?"success":"error");w=true;if(D.timeout){clearTimeout(C)}setTimeout(function(){x.removeData("form-plugin-onload");x.remove();y.responseXML=null},100)}var E=b.parseXML||function(n,O){if(window.ActiveXObject){O=new ActiveXObject("Microsoft.XMLDOM");O.async="false";O.loadXML(n)}else{O=(new DOMParser()).parseFromString(n,"text/xml")}return(O&&O.documentElement&&O.documentElement.nodeName!="parsererror")?O:null};var q=b.parseJSON||function(n){return window["eval"]("("+n+")")};var k=function(S,Q,P){var O=S.getResponseHeader("content-type")||"",n=Q==="xml"||!Q&&O.indexOf("xml")>=0,R=n?S.responseXML:S.responseText;if(n&&R.documentElement.nodeName==="parsererror"){b.error&&b.error("parsererror")}if(P&&P.dataFilter){R=P.dataFilter(R,Q)}if(typeof R==="string"){if(Q==="json"||!Q&&O.indexOf("json")>=0){R=q(R)}else{if(Q==="script"||!Q&&O.indexOf("javascript")>=0){b.globalEval(R)}}}return R}}};b.fn.ajaxForm=function(c){if(this.length===0){var d={s:this.selector,c:this.context};if(!b.isReady&&d.s){a("DOM not ready, queuing ajaxForm");b(function(){b(d.s,d.c).ajaxForm(c)});return this}a("terminating; zero elements found by selector"+(b.isReady?"":" (DOM not ready)"));return this}return this.ajaxFormUnbind().bind("submit.form-plugin",function(f){if(!f.isDefaultPrevented()){f.preventDefault();b(this).ajaxSubmit(c)}}).bind("click.form-plugin",function(j){var i=j.target;var g=b(i);if(!(g.is(":submit,input:image"))){var f=g.closest(":submit");if(f.length==0){return}i=f[0]}var h=this;h.clk=i;if(i.type=="image"){if(j.offsetX!=undefined){h.clk_x=j.offsetX;h.clk_y=j.offsetY}else{if(typeof b.fn.offset=="function"){var k=g.offset();h.clk_x=j.pageX-k.left;h.clk_y=j.pageY-k.top}else{h.clk_x=j.pageX-i.offsetLeft;h.clk_y=j.pageY-i.offsetTop}}}setTimeout(function(){h.clk=h.clk_x=h.clk_y=null},100)})};b.fn.ajaxFormUnbind=function(){return this.unbind("submit.form-plugin click.form-plugin")};b.fn.formToArray=function(q){var p=[];if(this.length===0){return p}var d=this[0];var g=q?d.getElementsByTagName("*"):d.elements;if(!g){return p}var k,h,f,r,e,m,c;for(k=0,m=g.length;k<m;k++){e=g[k];f=e.name;if(!f){continue}if(q&&d.clk&&e.type=="image"){if(!e.disabled&&d.clk==e){p.push({name:f,value:b(e).val()});p.push({name:f+".x",value:d.clk_x},{name:f+".y",value:d.clk_y})}continue}r=b.fieldValue(e,true);if(r&&r.constructor==Array){for(h=0,c=r.length;h<c;h++){p.push({name:f,value:r[h]})}}else{if(r!==null&&typeof r!="undefined"){p.push({name:f,value:r})}}}if(!q&&d.clk){var l=b(d.clk),o=l[0];f=o.name;if(f&&!o.disabled&&o.type=="image"){p.push({name:f,value:l.val()});p.push({name:f+".x",value:d.clk_x},{name:f+".y",value:d.clk_y})}}return p};b.fn.formSerialize=function(c){return b.param(this.formToArray(c))};b.fn.fieldSerialize=function(d){var c=[];this.each(function(){var h=this.name;if(!h){return}var f=b.fieldValue(this,d);if(f&&f.constructor==Array){for(var g=0,e=f.length;g<e;g++){c.push({name:h,value:f[g]})}}else{if(f!==null&&typeof f!="undefined"){c.push({name:this.name,value:f})}}});return b.param(c)};b.fn.fieldValue=function(h){for(var g=[],e=0,c=this.length;e<c;e++){var f=this[e];var d=b.fieldValue(f,h);if(d===null||typeof d=="undefined"||(d.constructor==Array&&!d.length)){continue}d.constructor==Array?b.merge(g,d):g.push(d)}return g};b.fieldValue=function(c,j){var e=c.name,p=c.type,q=c.tagName.toLowerCase();if(j===undefined){j=true}if(j&&(!e||c.disabled||p=="reset"||p=="button"||(p=="checkbox"||p=="radio")&&!c.checked||(p=="submit"||p=="image")&&c.form&&c.form.clk!=c||q=="select"&&c.selectedIndex==-1)){return null}if(q=="select"){var k=c.selectedIndex;if(k<0){return null}var m=[],d=c.options;var g=(p=="select-one");var l=(g?k+1:d.length);for(var f=(g?k:0);f<l;f++){var h=d[f];if(h.selected){var o=h.value;if(!o){o=(h.attributes&&h.attributes.value&&!(h.attributes.value.specified))?h.text:h.value}if(g){return o}m.push(o)}}return m}return b(c).val()};b.fn.clearForm=function(){return this.each(function(){b("input,select,textarea",this).clearFields()})};b.fn.clearFields=b.fn.clearInputs=function(){return this.each(function(){var d=this.type,c=this.tagName.toLowerCase();if(d=="text"||d=="password"||c=="textarea"){this.value=""}else{if(d=="checkbox"||d=="radio"){this.checked=false}else{if(c=="select"){this.selectedIndex=-1}}}})};b.fn.resetForm=function(){return this.each(function(){if(typeof this.reset=="function"||(typeof this.reset=="object"&&!this.reset.nodeType)){this.reset()}})};b.fn.enable=function(c){if(c===undefined){c=true}return this.each(function(){this.disabled=!c})};b.fn.selected=function(c){if(c===undefined){c=true}return this.each(function(){var d=this.type;if(d=="checkbox"||d=="radio"){this.checked=c}else{if(this.tagName.toLowerCase()=="option"){var e=b(this).parent("select");if(c&&e[0]&&e[0].type=="select-one"){e.find("option").selected(false)}this.selected=c}}})};function a(){if(b.fn.ajaxSubmit.debug){var c="[jquery.form] "+Array.prototype.join.call(arguments,"");if(window.console&&window.console.log){window.console.log(c)}else{if(window.opera&&window.opera.postError){window.opera.postError(c)}}}}})(jQuery);
     11!function(a){"use strict";function b(b){var c=b.data;b.isDefaultPrevented()||(b.preventDefault(),a(this).ajaxSubmit(c))}function c(b){var c=b.target,d=a(c);if(!d.is("[type=submit],[type=image]")){var e=d.closest("[type=submit]");if(0===e.length)return;c=e[0]}var f=this;if(f.clk=c,"image"==c.type)if(void 0!==b.offsetX)f.clk_x=b.offsetX,f.clk_y=b.offsetY;else if("function"==typeof a.fn.offset){var g=d.offset();f.clk_x=b.pageX-g.left,f.clk_y=b.pageY-g.top}else f.clk_x=b.pageX-c.offsetLeft,f.clk_y=b.pageY-c.offsetTop;setTimeout(function(){f.clk=f.clk_x=f.clk_y=null},100)}function d(){if(a.fn.ajaxSubmit.debug){var b="[jquery.form] "+Array.prototype.join.call(arguments,"");window.console&&window.console.log?window.console.log(b):window.opera&&window.opera.postError&&window.opera.postError(b)}}var e={};e.fileapi=void 0!==a("<input type='file'/>").get(0).files,e.formdata=void 0!==window.FormData;var f=!!a.fn.prop;a.fn.attr2=function(){if(!f)return this.attr.apply(this,arguments);var a=this.prop.apply(this,arguments);return a&&a.jquery||"string"==typeof a?a:this.attr.apply(this,arguments)},a.fn.ajaxSubmit=function(b){function c(c){var d,e,f=a.param(c,b.traditional).split("&"),g=f.length,h=[];for(d=0;g>d;d++)f[d]=f[d].replace(/\+/g," "),e=f[d].split("="),h.push([decodeURIComponent(e[0]),decodeURIComponent(e[1])]);return h}function g(d){for(var e=new FormData,f=0;f<d.length;f++)e.append(d[f].name,d[f].value);if(b.extraData){var g=c(b.extraData);for(f=0;f<g.length;f++)g[f]&&e.append(g[f][0],g[f][1])}b.data=null;var h=a.extend(!0,{},a.ajaxSettings,b,{contentType:!1,processData:!1,cache:!1,type:i||"POST"});b.uploadProgress&&(h.xhr=function(){var c=a.ajaxSettings.xhr();return c.upload&&c.upload.addEventListener("progress",function(a){var c=0,d=a.loaded||a.position,e=a.total;a.lengthComputable&&(c=Math.ceil(100*(d/e))),b.uploadProgress(a,d,e,c)},!1),c}),h.data=null;var j=h.beforeSend;return h.beforeSend=function(a,b){b.data=e,j&&j.call(this,a,b)},a.ajax(h)}function h(c){function e(a){var b=null;try{a.contentWindow&&(b=a.contentWindow.document)}catch(c){d("cannot get iframe.contentWindow document: "+c)}if(b)return b;try{b=a.contentDocument?a.contentDocument:a.document}catch(c){d("cannot get iframe.contentDocument: "+c),b=a.document}return b}function g(){function b(){try{var a=e(r).readyState;d("state = "+a),a&&"uninitialized"==a.toLowerCase()&&setTimeout(b,50)}catch(c){d("Server abort: ",c," (",c.name,")"),h(A),w&&clearTimeout(w),w=void 0}}var c=l.attr2("target"),f=l.attr2("action");x.setAttribute("target",o),i||x.setAttribute("method","POST"),f!=m.url&&x.setAttribute("action",m.url),m.skipEncodingOverride||i&&!/post/i.test(i)||l.attr({encoding:"multipart/form-data",enctype:"multipart/form-data"}),m.timeout&&(w=setTimeout(function(){v=!0,h(z)},m.timeout));var g=[];try{if(m.extraData)for(var j in m.extraData)m.extraData.hasOwnProperty(j)&&(a.isPlainObject(m.extraData[j])&&m.extraData[j].hasOwnProperty("name")&&m.extraData[j].hasOwnProperty("value")?g.push(a('<input type="hidden" name="'+m.extraData[j].name+'">').val(m.extraData[j].value).appendTo(x)[0]):g.push(a('<input type="hidden" name="'+j+'">').val(m.extraData[j]).appendTo(x)[0]));m.iframeTarget||(q.appendTo("body"),r.attachEvent?r.attachEvent("onload",h):r.addEventListener("load",h,!1)),setTimeout(b,15);try{x.submit()}catch(k){var n=document.createElement("form").submit;n.apply(x)}}finally{x.setAttribute("action",f),c?x.setAttribute("target",c):l.removeAttr("target"),a(g).remove()}}function h(b){if(!s.aborted&&!F){if(E=e(r),E||(d("cannot access response document"),b=A),b===z&&s)return s.abort("timeout"),y.reject(s,"timeout"),void 0;if(b==A&&s)return s.abort("server abort"),y.reject(s,"error","server abort"),void 0;if(E&&E.location.href!=m.iframeSrc||v){r.detachEvent?r.detachEvent("onload",h):r.removeEventListener("load",h,!1);var c,f="success";try{if(v)throw"timeout";var g="xml"==m.dataType||E.XMLDocument||a.isXMLDoc(E);if(d("isXml="+g),!g&&window.opera&&(null===E.body||!E.body.innerHTML)&&--G)return d("requeing onLoad callback, DOM not available"),setTimeout(h,250),void 0;var i=E.body?E.body:E.documentElement;s.responseText=i?i.innerHTML:null,s.responseXML=E.XMLDocument?E.XMLDocument:E,g&&(m.dataType="xml"),s.getResponseHeader=function(a){var b={"content-type":m.dataType};return b[a]},i&&(s.status=Number(i.getAttribute("status"))||s.status,s.statusText=i.getAttribute("statusText")||s.statusText);var j=(m.dataType||"").toLowerCase(),k=/(json|script|text)/.test(j);if(k||m.textarea){var l=E.getElementsByTagName("textarea")[0];if(l)s.responseText=l.value,s.status=Number(l.getAttribute("status"))||s.status,s.statusText=l.getAttribute("statusText")||s.statusText;else if(k){var o=E.getElementsByTagName("pre")[0],p=E.getElementsByTagName("body")[0];o?s.responseText=o.textContent?o.textContent:o.innerText:p&&(s.responseText=p.textContent?p.textContent:p.innerText)}}else"xml"==j&&!s.responseXML&&s.responseText&&(s.responseXML=H(s.responseText));try{D=J(s,j,m)}catch(t){f="parsererror",s.error=c=t||f}}catch(t){d("error caught: ",t),f="error",s.error=c=t||f}s.aborted&&(d("upload aborted"),f=null),s.status&&(f=s.status>=200&&s.status<300||304===s.status?"success":"error"),"success"===f?(m.success&&m.success.call(m.context,D,"success",s),y.resolve(s.responseText,"success",s),n&&a.event.trigger("ajaxSuccess",[s,m])):f&&(void 0===c&&(c=s.statusText),m.error&&m.error.call(m.context,s,f,c),y.reject(s,"error",c),n&&a.event.trigger("ajaxError",[s,m,c])),n&&a.event.trigger("ajaxComplete",[s,m]),n&&!--a.active&&a.event.trigger("ajaxStop"),m.complete&&m.complete.call(m.context,s,f),F=!0,m.timeout&&clearTimeout(w),setTimeout(function(){m.iframeTarget||q.remove(),s.responseXML=null},100)}}}var j,k,m,n,o,q,r,s,t,u,v,w,x=l[0],y=a.Deferred();if(c)for(k=0;k<p.length;k++)j=a(p[k]),f?j.prop("disabled",!1):j.removeAttr("disabled");if(m=a.extend(!0,{},a.ajaxSettings,b),m.context=m.context||m,o="jqFormIO"+(new Date).getTime(),m.iframeTarget?(q=a(m.iframeTarget),u=q.attr2("name"),u?o=u:q.attr2("name",o)):(q=a('<iframe name="'+o+'" src="'+m.iframeSrc+'" />'),q.css({position:"absolute",top:"-1000px",left:"-1000px"})),r=q[0],s={aborted:0,responseText:null,responseXML:null,status:0,statusText:"n/a",getAllResponseHeaders:function(){},getResponseHeader:function(){},setRequestHeader:function(){},abort:function(b){var c="timeout"===b?"timeout":"aborted";d("aborting upload... "+c),this.aborted=1;try{r.contentWindow.document.execCommand&&r.contentWindow.document.execCommand("Stop")}catch(e){}q.attr("src",m.iframeSrc),s.error=c,m.error&&m.error.call(m.context,s,c,b),n&&a.event.trigger("ajaxError",[s,m,c]),m.complete&&m.complete.call(m.context,s,c)}},n=m.global,n&&0===a.active++&&a.event.trigger("ajaxStart"),n&&a.event.trigger("ajaxSend",[s,m]),m.beforeSend&&m.beforeSend.call(m.context,s,m)===!1)return m.global&&a.active--,y.reject(),y;if(s.aborted)return y.reject(),y;t=x.clk,t&&(u=t.name,u&&!t.disabled&&(m.extraData=m.extraData||{},m.extraData[u]=t.value,"image"==t.type&&(m.extraData[u+".x"]=x.clk_x,m.extraData[u+".y"]=x.clk_y)));var z=1,A=2,B=a("meta[name=csrf-token]").attr("content"),C=a("meta[name=csrf-param]").attr("content");C&&B&&(m.extraData=m.extraData||{},m.extraData[C]=B),m.forceSync?g():setTimeout(g,10);var D,E,F,G=50,H=a.parseXML||function(a,b){return window.ActiveXObject?(b=new ActiveXObject("Microsoft.XMLDOM"),b.async="false",b.loadXML(a)):b=(new DOMParser).parseFromString(a,"text/xml"),b&&b.documentElement&&"parsererror"!=b.documentElement.nodeName?b:null},I=a.parseJSON||function(a){return window.eval("("+a+")")},J=function(b,c,d){var e=b.getResponseHeader("content-type")||"",f="xml"===c||!c&&e.indexOf("xml")>=0,g=f?b.responseXML:b.responseText;return f&&"parsererror"===g.documentElement.nodeName&&a.error&&a.error("parsererror"),d&&d.dataFilter&&(g=d.dataFilter(g,c)),"string"==typeof g&&("json"===c||!c&&e.indexOf("json")>=0?g=I(g):("script"===c||!c&&e.indexOf("javascript")>=0)&&a.globalEval(g)),g};return y}if(!this.length)return d("ajaxSubmit: skipping submit process - no element selected"),this;var i,j,k,l=this;"function"==typeof b?b={success:b}:void 0===b&&(b={}),i=b.type||this.attr2("method"),j=b.url||this.attr2("action"),k="string"==typeof j?a.trim(j):"",k=k||window.location.href||"",k&&(k=(k.match(/^([^#]+)/)||[])[1]),b=a.extend(!0,{url:k,success:a.ajaxSettings.success,type:i||"GET",iframeSrc:/^https/i.test(window.location.href||"")?"javascript:false":"about:blank"},b);var m={};if(this.trigger("form-pre-serialize",[this,b,m]),m.veto)return d("ajaxSubmit: submit vetoed via form-pre-serialize trigger"),this;if(b.beforeSerialize&&b.beforeSerialize(this,b)===!1)return d("ajaxSubmit: submit aborted via beforeSerialize callback"),this;var n=b.traditional;void 0===n&&(n=a.ajaxSettings.traditional);var o,p=[],q=this.formToArray(b.semantic,p);if(b.data&&(b.extraData=b.data,o=a.param(b.data,n)),b.beforeSubmit&&b.beforeSubmit(q,this,b)===!1)return d("ajaxSubmit: submit aborted via beforeSubmit callback"),this;if(this.trigger("form-submit-validate",[q,this,b,m]),m.veto)return d("ajaxSubmit: submit vetoed via form-submit-validate trigger"),this;var r=a.param(q,n);o&&(r=r?r+"&"+o:o),"GET"==b.type.toUpperCase()?(b.url+=(b.url.indexOf("?")>=0?"&":"?")+r,b.data=null):b.data=r;var s=[];if(b.resetForm&&s.push(function(){l.resetForm()}),b.clearForm&&s.push(function(){l.clearForm(b.includeHidden)}),!b.dataType&&b.target){var t=b.success||function(){};s.push(function(c){var d=b.replaceTarget?"replaceWith":"html";a(b.target)[d](c).each(t,arguments)})}else b.success&&s.push(b.success);if(b.success=function(a,c,d){for(var e=b.context||this,f=0,g=s.length;g>f;f++)s[f].apply(e,[a,c,d||l,l])},b.error){var u=b.error;b.error=function(a,c,d){var e=b.context||this;u.apply(e,[a,c,d,l])}}if(b.complete){var v=b.complete;b.complete=function(a,c){var d=b.context||this;v.apply(d,[a,c,l])}}var w=a('input[type=file]:enabled[value!=""]',this),x=w.length>0,y="multipart/form-data",z=l.attr("enctype")==y||l.attr("encoding")==y,A=e.fileapi&&e.formdata;d("fileAPI :"+A);var B,C=(x||z)&&!A;b.iframe!==!1&&(b.iframe||C)?b.closeKeepAlive?a.get(b.closeKeepAlive,function(){B=h(q)}):B=h(q):B=(x||z)&&A?g(q):a.ajax(b),l.removeData("jqxhr").data("jqxhr",B);for(var D=0;D<p.length;D++)p[D]=null;return this.trigger("form-submit-notify",[this,b]),this},a.fn.ajaxForm=function(e){if(e=e||{},e.delegation=e.delegation&&a.isFunction(a.fn.on),!e.delegation&&0===this.length){var f={s:this.selector,c:this.context};return!a.isReady&&f.s?(d("DOM not ready, queuing ajaxForm"),a(function(){a(f.s,f.c).ajaxForm(e)}),this):(d("terminating; zero elements found by selector"+(a.isReady?"":" (DOM not ready)")),this)}return e.delegation?(a(document).off("submit.form-plugin",this.selector,b).off("click.form-plugin",this.selector,c).on("submit.form-plugin",this.selector,e,b).on("click.form-plugin",this.selector,e,c),this):this.ajaxFormUnbind().bind("submit.form-plugin",e,b).bind("click.form-plugin",e,c)},a.fn.ajaxFormUnbind=function(){return this.unbind("submit.form-plugin click.form-plugin")},a.fn.formToArray=function(b,c){var d=[];if(0===this.length)return d;var f=this[0],g=b?f.getElementsByTagName("*"):f.elements;if(!g)return d;var h,i,j,k,l,m,n;for(h=0,m=g.length;m>h;h++)if(l=g[h],j=l.name,j&&!l.disabled)if(b&&f.clk&&"image"==l.type)f.clk==l&&(d.push({name:j,value:a(l).val(),type:l.type}),d.push({name:j+".x",value:f.clk_x},{name:j+".y",value:f.clk_y}));else if(k=a.fieldValue(l,!0),k&&k.constructor==Array)for(c&&c.push(l),i=0,n=k.length;n>i;i++)d.push({name:j,value:k[i]});else if(e.fileapi&&"file"==l.type){c&&c.push(l);var o=l.files;if(o.length)for(i=0;i<o.length;i++)d.push({name:j,value:o[i],type:l.type});else d.push({name:j,value:"",type:l.type})}else null!==k&&"undefined"!=typeof k&&(c&&c.push(l),d.push({name:j,value:k,type:l.type,required:l.required}));if(!b&&f.clk){var p=a(f.clk),q=p[0];j=q.name,j&&!q.disabled&&"image"==q.type&&(d.push({name:j,value:p.val()}),d.push({name:j+".x",value:f.clk_x},{name:j+".y",value:f.clk_y}))}return d},a.fn.formSerialize=function(b){return a.param(this.formToArray(b))},a.fn.fieldSerialize=function(b){var c=[];return this.each(function(){var d=this.name;if(d){var e=a.fieldValue(this,b);if(e&&e.constructor==Array)for(var f=0,g=e.length;g>f;f++)c.push({name:d,value:e[f]});else null!==e&&"undefined"!=typeof e&&c.push({name:this.name,value:e})}}),a.param(c)},a.fn.fieldValue=function(b){for(var c=[],d=0,e=this.length;e>d;d++){var f=this[d],g=a.fieldValue(f,b);null===g||"undefined"==typeof g||g.constructor==Array&&!g.length||(g.constructor==Array?a.merge(c,g):c.push(g))}return c},a.fieldValue=function(b,c){var d=b.name,e=b.type,f=b.tagName.toLowerCase();if(void 0===c&&(c=!0),c&&(!d||b.disabled||"reset"==e||"button"==e||("checkbox"==e||"radio"==e)&&!b.checked||("submit"==e||"image"==e)&&b.form&&b.form.clk!=b||"select"==f&&-1==b.selectedIndex))return null;if("select"==f){var g=b.selectedIndex;if(0>g)return null;for(var h=[],i=b.options,j="select-one"==e,k=j?g+1:i.length,l=j?g:0;k>l;l++){var m=i[l];if(m.selected){var n=m.value;if(n||(n=m.attributes&&m.attributes.value&&!m.attributes.value.specified?m.text:m.value),j)return n;h.push(n)}}return h}return a(b).val()},a.fn.clearForm=function(b){return this.each(function(){a("input,select,textarea",this).clearFields(b)})},a.fn.clearFields=a.fn.clearInputs=function(b){var c=/^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i;return this.each(function(){var d=this.type,e=this.tagName.toLowerCase();c.test(d)||"textarea"==e?this.value="":"checkbox"==d||"radio"==d?this.checked=!1:"select"==e?this.selectedIndex=-1:"file"==d?/MSIE/.test(navigator.userAgent)?a(this).replaceWith(a(this).clone(!0)):a(this).val(""):b&&(b===!0&&/hidden/.test(d)||"string"==typeof b&&a(this).is(b))&&(this.value="")})},a.fn.resetForm=function(){return this.each(function(){("function"==typeof this.reset||"object"==typeof this.reset&&!this.reset.nodeType)&&this.reset()})},a.fn.enable=function(a){return void 0===a&&(a=!0),this.each(function(){this.disabled=!a})},a.fn.selected=function(b){return void 0===b&&(b=!0),this.each(function(){var c=this.type;if("checkbox"==c||"radio"==c)this.checked=b;else if("option"==this.tagName.toLowerCase()){var d=a(this).parent("select");b&&d[0]&&"select-one"==d[0].type&&d.find("option").selected(!1),this.selected=b}})},a.fn.ajaxSubmit.debug=!1}(jQuery);
  • trunk/src/wp-includes/script-loader.php

    r25246 r25462  
    183183
    184184    // deprecated, not used in core, most functionality is included in jQuery 1.3
    185     $scripts->add( 'jquery-form', "/wp-includes/js/jquery/jquery.form$suffix.js", array('jquery'), '2.73', 1 );
     185    $scripts->add( 'jquery-form', "/wp-includes/js/jquery/jquery.form$suffix.js", array('jquery'), '3.37.0', 1 );
    186186
    187187    // jQuery plugins
Note: See TracChangeset for help on using the changeset viewer.