[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/js/jquery/ -> jquery.form.js (source)

   1  /*!
   2   * jQuery Form Plugin
   3   * version: 4.3.0
   4   * Requires jQuery v1.7.2 or later
   5   * Project repository: https://github.com/jquery-form/form
   6  
   7   * Copyright 2017 Kevin Morris
   8   * Copyright 2006 M. Alsup
   9  
  10   * Dual licensed under the LGPL-2.1+ or MIT licenses
  11   * https://github.com/jquery-form/form#license
  12  
  13   * This library is free software; you can redistribute it and/or
  14   * modify it under the terms of the GNU Lesser General Public
  15   * License as published by the Free Software Foundation; either
  16   * version 2.1 of the License, or (at your option) any later version.
  17   * This library is distributed in the hope that it will be useful,
  18   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  20   * Lesser General Public License for more details.
  21   */
  22  /* global ActiveXObject */
  23  
  24  /* eslint-disable */
  25  (function (factory) {
  26      if (typeof define === 'function' && define.amd) {
  27          // AMD. Register as an anonymous module.
  28          define(['jquery'], factory);
  29      } else if (typeof module === 'object' && module.exports) {
  30          // Node/CommonJS
  31          module.exports = function( root, jQuery ) {
  32              if (typeof jQuery === 'undefined') {
  33                  // require('jQuery') returns a factory that requires window to build a jQuery instance, we normalize how we use modules
  34                  // that require this pattern but the window provided is a noop if it's defined (how jquery works)
  35                  if (typeof window !== 'undefined') {
  36                      jQuery = require('jquery');
  37                  }
  38                  else {
  39                      jQuery = require('jquery')(root);
  40                  }
  41              }
  42              factory(jQuery);
  43              return jQuery;
  44          };
  45      } else {
  46          // Browser globals
  47          factory(jQuery);
  48      }
  49  
  50  }(function ($) {
  51  /* eslint-enable */
  52      'use strict';
  53  
  54      /*
  55          Usage Note:
  56          -----------
  57          Do not use both ajaxSubmit and ajaxForm on the same form. These
  58          functions are mutually exclusive. Use ajaxSubmit if you want
  59          to bind your own submit handler to the form. For example,
  60  
  61          $(document).ready(function() {
  62              $('#myForm').on('submit', function(e) {
  63                  e.preventDefault(); // <-- important
  64                  $(this).ajaxSubmit({
  65                      target: '#output'
  66                  });
  67              });
  68          });
  69  
  70          Use ajaxForm when you want the plugin to manage all the event binding
  71          for you. For example,
  72  
  73          $(document).ready(function() {
  74              $('#myForm').ajaxForm({
  75                  target: '#output'
  76              });
  77          });
  78  
  79          You can also use ajaxForm with delegation (requires jQuery v1.7+), so the
  80          form does not have to exist when you invoke ajaxForm:
  81  
  82          $('#myForm').ajaxForm({
  83              delegation: true,
  84              target: '#output'
  85          });
  86  
  87          When using ajaxForm, the ajaxSubmit function will be invoked for you
  88          at the appropriate time.
  89      */
  90  
  91      var rCRLF = /\r?\n/g;
  92  
  93      /**
  94       * Feature detection
  95       */
  96      var feature = {};
  97  
  98      feature.fileapi = $('<input type="file">').get(0).files !== undefined;
  99      feature.formdata = (typeof window.FormData !== 'undefined');
 100  
 101      var hasProp = !!$.fn.prop;
 102  
 103      // attr2 uses prop when it can but checks the return type for
 104      // an expected string. This accounts for the case where a form
 105      // contains inputs with names like "action" or "method"; in those
 106      // cases "prop" returns the element
 107      $.fn.attr2 = function() {
 108          if (!hasProp) {
 109              return this.attr.apply(this, arguments);
 110          }
 111  
 112          var val = this.prop.apply(this, arguments);
 113  
 114          if ((val && val.jquery) || typeof val === 'string') {
 115              return val;
 116          }
 117  
 118          return this.attr.apply(this, arguments);
 119      };
 120  
 121      /**
 122       * ajaxSubmit() provides a mechanism for immediately submitting
 123       * an HTML form using AJAX.
 124       *
 125       * @param    {object|string}    options        jquery.form.js parameters or custom url for submission
 126       * @param    {object}        data        extraData
 127       * @param    {string}        dataType    ajax dataType
 128       * @param    {function}        onSuccess    ajax success callback function
 129       */
 130      $.fn.ajaxSubmit = function(options, data, dataType, onSuccess) {
 131          // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
 132          if (!this.length) {
 133              log('ajaxSubmit: skipping submit process - no element selected');
 134  
 135              return this;
 136          }
 137  
 138          /* eslint consistent-this: ["error", "$form"] */
 139          var method, action, url, isMsie, iframeSrc, $form = this;
 140  
 141          if (typeof options === 'function') {
 142              options = {success: options};
 143  
 144          } else if (typeof options === 'string' || (options === false && arguments.length > 0)) {
 145              options = {
 146                  'url'      : options,
 147                  'data'     : data,
 148                  'dataType' : dataType
 149              };
 150  
 151              if (typeof onSuccess === 'function') {
 152                  options.success = onSuccess;
 153              }
 154  
 155          } else if (typeof options === 'undefined') {
 156              options = {};
 157          }
 158  
 159          method = options.method || options.type || this.attr2('method');
 160          action = options.url || this.attr2('action');
 161  
 162          url = (typeof action === 'string') ? $.trim(action) : '';
 163          url = url || window.location.href || '';
 164          if (url) {
 165              // clean url (don't include hash vaue)
 166              url = (url.match(/^([^#]+)/) || [])[1];
 167          }
 168          // IE requires javascript:false in https, but this breaks chrome >83 and goes against spec.
 169          // Instead of using javascript:false always, let's only apply it for IE.
 170          isMsie = /(MSIE|Trident)/.test(navigator.userAgent || '');
 171          iframeSrc = (isMsie && /^https/i.test(window.location.href || '')) ? 'javascript:false' : 'about:blank'; // eslint-disable-line no-script-url
 172  
 173          options = $.extend(true, {
 174              url       : url,
 175              success   : $.ajaxSettings.success,
 176              type      : method || $.ajaxSettings.type,
 177              iframeSrc : iframeSrc
 178          }, options);
 179  
 180          // hook for manipulating the form data before it is extracted;
 181          // convenient for use with rich editors like tinyMCE or FCKEditor
 182          var veto = {};
 183  
 184          this.trigger('form-pre-serialize', [this, options, veto]);
 185  
 186          if (veto.veto) {
 187              log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
 188  
 189              return this;
 190          }
 191  
 192          // provide opportunity to alter form data before it is serialized
 193          if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
 194              log('ajaxSubmit: submit aborted via beforeSerialize callback');
 195  
 196              return this;
 197          }
 198  
 199          var traditional = options.traditional;
 200  
 201          if (typeof traditional === 'undefined') {
 202              traditional = $.ajaxSettings.traditional;
 203          }
 204  
 205          var elements = [];
 206          var qx, a = this.formToArray(options.semantic, elements, options.filtering);
 207  
 208          if (options.data) {
 209              var optionsData = $.isFunction(options.data) ? options.data(a) : options.data;
 210  
 211              options.extraData = optionsData;
 212              qx = $.param(optionsData, traditional);
 213          }
 214  
 215          // give pre-submit callback an opportunity to abort the submit
 216          if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
 217              log('ajaxSubmit: submit aborted via beforeSubmit callback');
 218  
 219              return this;
 220          }
 221  
 222          // fire vetoable 'validate' event
 223          this.trigger('form-submit-validate', [a, this, options, veto]);
 224          if (veto.veto) {
 225              log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
 226  
 227              return this;
 228          }
 229  
 230          var q = $.param(a, traditional);
 231  
 232          if (qx) {
 233              q = (q ? (q + '&' + qx) : qx);
 234          }
 235  
 236          if (options.type.toUpperCase() === 'GET') {
 237              options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
 238              options.data = null;    // data is null for 'get'
 239          } else {
 240              options.data = q;        // data is the query string for 'post'
 241          }
 242  
 243          var callbacks = [];
 244  
 245          if (options.resetForm) {
 246              callbacks.push(function() {
 247                  $form.resetForm();
 248              });
 249          }
 250  
 251          if (options.clearForm) {
 252              callbacks.push(function() {
 253                  $form.clearForm(options.includeHidden);
 254              });
 255          }
 256  
 257          // perform a load on the target only if dataType is not provided
 258          if (!options.dataType && options.target) {
 259              var oldSuccess = options.success || function(){};
 260  
 261              callbacks.push(function(data, textStatus, jqXHR) {
 262                  var successArguments = arguments,
 263                      fn = options.replaceTarget ? 'replaceWith' : 'html';
 264  
 265                  $(options.target)[fn](data).each(function(){
 266                      oldSuccess.apply(this, successArguments);
 267                  });
 268              });
 269  
 270          } else if (options.success) {
 271              if ($.isArray(options.success)) {
 272                  $.merge(callbacks, options.success);
 273              } else {
 274                  callbacks.push(options.success);
 275              }
 276          }
 277  
 278          options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
 279              var context = options.context || this;        // jQuery 1.4+ supports scope context
 280  
 281              for (var i = 0, max = callbacks.length; i < max; i++) {
 282                  callbacks[i].apply(context, [data, status, xhr || $form, $form]);
 283              }
 284          };
 285  
 286          if (options.error) {
 287              var oldError = options.error;
 288  
 289              options.error = function(xhr, status, error) {
 290                  var context = options.context || this;
 291  
 292                  oldError.apply(context, [xhr, status, error, $form]);
 293              };
 294          }
 295  
 296          if (options.complete) {
 297              var oldComplete = options.complete;
 298  
 299              options.complete = function(xhr, status) {
 300                  var context = options.context || this;
 301  
 302                  oldComplete.apply(context, [xhr, status, $form]);
 303              };
 304          }
 305  
 306          // are there files to upload?
 307  
 308          // [value] (issue #113), also see comment:
 309          // https://github.com/malsup/form/commit/588306aedba1de01388032d5f42a60159eea9228#commitcomment-2180219
 310          var fileInputs = $('input[type=file]:enabled', this).filter(function() {
 311              return $(this).val() !== '';
 312          });
 313          var hasFileInputs = fileInputs.length > 0;
 314          var mp = 'multipart/form-data';
 315          var multipart = ($form.attr('enctype') === mp || $form.attr('encoding') === mp);
 316          var fileAPI = feature.fileapi && feature.formdata;
 317  
 318          log('fileAPI :' + fileAPI);
 319  
 320          var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI;
 321          var jqxhr;
 322  
 323          // options.iframe allows user to force iframe mode
 324          // 06-NOV-09: now defaulting to iframe mode if file input is detected
 325          if (options.iframe !== false && (options.iframe || shouldUseFrame)) {
 326              // hack to fix Safari hang (thanks to Tim Molendijk for this)
 327              // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
 328              if (options.closeKeepAlive) {
 329                  $.get(options.closeKeepAlive, function() {
 330                      jqxhr = fileUploadIframe(a);
 331                  });
 332  
 333              } else {
 334                  jqxhr = fileUploadIframe(a);
 335              }
 336  
 337          } else if ((hasFileInputs || multipart) && fileAPI) {
 338              jqxhr = fileUploadXhr(a);
 339  
 340          } else {
 341              jqxhr = $.ajax(options);
 342          }
 343  
 344          $form.removeData('jqxhr').data('jqxhr', jqxhr);
 345  
 346          // clear element array
 347          for (var k = 0; k < elements.length; k++) {
 348              elements[k] = null;
 349          }
 350  
 351          // fire 'notify' event
 352          this.trigger('form-submit-notify', [this, options]);
 353  
 354          return this;
 355  
 356          // utility fn for deep serialization
 357  		function deepSerialize(extraData) {
 358              var serialized = $.param(extraData, options.traditional).split('&');
 359              var len = serialized.length;
 360              var result = [];
 361              var i, part;
 362  
 363              for (i = 0; i < len; i++) {
 364                  // #252; undo param space replacement
 365                  serialized[i] = serialized[i].replace(/\+/g, ' ');
 366                  part = serialized[i].split('=');
 367                  // #278; use array instead of object storage, favoring array serializations
 368                  result.push([decodeURIComponent(part[0]), decodeURIComponent(part[1])]);
 369              }
 370  
 371              return result;
 372          }
 373  
 374          // XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz)
 375  		function fileUploadXhr(a) {
 376              var formdata = new FormData();
 377  
 378              for (var i = 0; i < a.length; i++) {
 379                  formdata.append(a[i].name, a[i].value);
 380              }
 381  
 382              if (options.extraData) {
 383                  var serializedData = deepSerialize(options.extraData);
 384  
 385                  for (i = 0; i < serializedData.length; i++) {
 386                      if (serializedData[i]) {
 387                          formdata.append(serializedData[i][0], serializedData[i][1]);
 388                      }
 389                  }
 390              }
 391  
 392              options.data = null;
 393  
 394              var s = $.extend(true, {}, $.ajaxSettings, options, {
 395                  contentType : false,
 396                  processData : false,
 397                  cache       : false,
 398                  type        : method || 'POST'
 399              });
 400  
 401              if (options.uploadProgress) {
 402                  // workaround because jqXHR does not expose upload property
 403                  s.xhr = function() {
 404                      var xhr = $.ajaxSettings.xhr();
 405  
 406                      if (xhr.upload) {
 407                          xhr.upload.addEventListener('progress', function(event) {
 408                              var percent = 0;
 409                              var position = event.loaded || event.position;            /* event.position is deprecated */
 410                              var total = event.total;
 411  
 412                              if (event.lengthComputable) {
 413                                  percent = Math.ceil(position / total * 100);
 414                              }
 415  
 416                              options.uploadProgress(event, position, total, percent);
 417                          }, false);
 418                      }
 419  
 420                      return xhr;
 421                  };
 422              }
 423  
 424              s.data = null;
 425  
 426              var beforeSend = s.beforeSend;
 427  
 428              s.beforeSend = function(xhr, o) {
 429                  // Send FormData() provided by user
 430                  if (options.formData) {
 431                      o.data = options.formData;
 432                  } else {
 433                      o.data = formdata;
 434                  }
 435  
 436                  if (beforeSend) {
 437                      beforeSend.call(this, xhr, o);
 438                  }
 439              };
 440  
 441              return $.ajax(s);
 442          }
 443  
 444          // private function for handling file uploads (hat tip to YAHOO!)
 445  		function fileUploadIframe(a) {
 446              var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle;
 447              var deferred = $.Deferred();
 448  
 449              // #341
 450              deferred.abort = function(status) {
 451                  xhr.abort(status);
 452              };
 453  
 454              if (a) {
 455                  // ensure that every serialized input is still enabled
 456                  for (i = 0; i < elements.length; i++) {
 457                      el = $(elements[i]);
 458                      if (hasProp) {
 459                          el.prop('disabled', false);
 460                      } else {
 461                          el.removeAttr('disabled');
 462                      }
 463                  }
 464              }
 465  
 466              s = $.extend(true, {}, $.ajaxSettings, options);
 467              s.context = s.context || s;
 468              id = 'jqFormIO' + new Date().getTime();
 469              var ownerDocument = form.ownerDocument;
 470              var $body = $form.closest('body');
 471  
 472              if (s.iframeTarget) {
 473                  $io = $(s.iframeTarget, ownerDocument);
 474                  n = $io.attr2('name');
 475                  if (!n) {
 476                      $io.attr2('name', id);
 477                  } else {
 478                      id = n;
 479                  }
 480  
 481              } else {
 482                  $io = $('<iframe name="' + id + '" src="' + s.iframeSrc + '" />', ownerDocument);
 483                  $io.css({position: 'absolute', top: '-1000px', left: '-1000px'});
 484              }
 485              io = $io[0];
 486  
 487  
 488              xhr = { // mock object
 489                  aborted               : 0,
 490                  responseText          : null,
 491                  responseXML           : null,
 492                  status                : 0,
 493                  statusText            : 'n/a',
 494                  getAllResponseHeaders : function() {},
 495                  getResponseHeader     : function() {},
 496                  setRequestHeader      : function() {},
 497                  abort                 : function(status) {
 498                      var e = (status === 'timeout' ? 'timeout' : 'aborted');
 499  
 500                      log('aborting upload... ' + e);
 501                      this.aborted = 1;
 502  
 503                      try { // #214, #257
 504                          if (io.contentWindow.document.execCommand) {
 505                              io.contentWindow.document.execCommand('Stop');
 506                          }
 507                      } catch (ignore) {}
 508  
 509                      $io.attr('src', s.iframeSrc); // abort op in progress
 510                      xhr.error = e;
 511                      if (s.error) {
 512                          s.error.call(s.context, xhr, e, status);
 513                      }
 514  
 515                      if (g) {
 516                          $.event.trigger('ajaxError', [xhr, s, e]);
 517                      }
 518  
 519                      if (s.complete) {
 520                          s.complete.call(s.context, xhr, e);
 521                      }
 522                  }
 523              };
 524  
 525              g = s.global;
 526              // trigger ajax global events so that activity/block indicators work like normal
 527              if (g && $.active++ === 0) {
 528                  $.event.trigger('ajaxStart');
 529              }
 530              if (g) {
 531                  $.event.trigger('ajaxSend', [xhr, s]);
 532              }
 533  
 534              if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
 535                  if (s.global) {
 536                      $.active--;
 537                  }
 538                  deferred.reject();
 539  
 540                  return deferred;
 541              }
 542  
 543              if (xhr.aborted) {
 544                  deferred.reject();
 545  
 546                  return deferred;
 547              }
 548  
 549              // add submitting element to data if we know it
 550              sub = form.clk;
 551              if (sub) {
 552                  n = sub.name;
 553                  if (n && !sub.disabled) {
 554                      s.extraData = s.extraData || {};
 555                      s.extraData[n] = sub.value;
 556                      if (sub.type === 'image') {
 557                          s.extraData[n + '.x'] = form.clk_x;
 558                          s.extraData[n + '.y'] = form.clk_y;
 559                      }
 560                  }
 561              }
 562  
 563              var CLIENT_TIMEOUT_ABORT = 1;
 564              var SERVER_ABORT = 2;
 565  
 566  			function getDoc(frame) {
 567                  /* it looks like contentWindow or contentDocument do not
 568                   * carry the protocol property in ie8, when running under ssl
 569                   * frame.document is the only valid response document, since
 570                   * the protocol is know but not on the other two objects. strange?
 571                   * "Same origin policy" http://en.wikipedia.org/wiki/Same_origin_policy
 572                   */
 573  
 574                  var doc = null;
 575  
 576                  // IE8 cascading access check
 577                  try {
 578                      if (frame.contentWindow) {
 579                          doc = frame.contentWindow.document;
 580                      }
 581                  } catch (err) {
 582                      // IE8 access denied under ssl & missing protocol
 583                      log('cannot get iframe.contentWindow document: ' + err);
 584                  }
 585  
 586                  if (doc) { // successful getting content
 587                      return doc;
 588                  }
 589  
 590                  try { // simply checking may throw in ie8 under ssl or mismatched protocol
 591                      doc = frame.contentDocument ? frame.contentDocument : frame.document;
 592                  } catch (err) {
 593                      // last attempt
 594                      log('cannot get iframe.contentDocument: ' + err);
 595                      doc = frame.document;
 596                  }
 597  
 598                  return doc;
 599              }
 600  
 601              // Rails CSRF hack (thanks to Yvan Barthelemy)
 602              var csrf_token = $('meta[name=csrf-token]').attr('content');
 603              var csrf_param = $('meta[name=csrf-param]').attr('content');
 604  
 605              if (csrf_param && csrf_token) {
 606                  s.extraData = s.extraData || {};
 607                  s.extraData[csrf_param] = csrf_token;
 608              }
 609  
 610              // take a breath so that pending repaints get some cpu time before the upload starts
 611  			function doSubmit() {
 612                  // make sure form attrs are set
 613                  var t = $form.attr2('target'),
 614                      a = $form.attr2('action'),
 615                      mp = 'multipart/form-data',
 616                      et = $form.attr('enctype') || $form.attr('encoding') || mp;
 617  
 618                  // update form attrs in IE friendly way
 619                  form.setAttribute('target', id);
 620                  if (!method || /post/i.test(method)) {
 621                      form.setAttribute('method', 'POST');
 622                  }
 623                  if (a !== s.url) {
 624                      form.setAttribute('action', s.url);
 625                  }
 626  
 627                  // ie borks in some cases when setting encoding
 628                  if (!s.skipEncodingOverride && (!method || /post/i.test(method))) {
 629                      $form.attr({
 630                          encoding : 'multipart/form-data',
 631                          enctype  : 'multipart/form-data'
 632                      });
 633                  }
 634  
 635                  // support timout
 636                  if (s.timeout) {
 637                      timeoutHandle = setTimeout(function() {
 638                          timedOut = true; cb(CLIENT_TIMEOUT_ABORT);
 639                      }, s.timeout);
 640                  }
 641  
 642                  // look for server aborts
 643  				function checkState() {
 644                      try {
 645                          var state = getDoc(io).readyState;
 646  
 647                          log('state = ' + state);
 648                          if (state && state.toLowerCase() === 'uninitialized') {
 649                              setTimeout(checkState, 50);
 650                          }
 651  
 652                      } catch (e) {
 653                          log('Server abort: ', e, ' (', e.name, ')');
 654                          cb(SERVER_ABORT);                // eslint-disable-line callback-return
 655                          if (timeoutHandle) {
 656                              clearTimeout(timeoutHandle);
 657                          }
 658                          timeoutHandle = undefined;
 659                      }
 660                  }
 661  
 662                  // add "extra" data to form if provided in options
 663                  var extraInputs = [];
 664  
 665                  try {
 666                      if (s.extraData) {
 667                          for (var n in s.extraData) {
 668                              if (s.extraData.hasOwnProperty(n)) {
 669                                  // if using the $.param format that allows for multiple values with the same name
 670                                  if ($.isPlainObject(s.extraData[n]) && s.extraData[n].hasOwnProperty('name') && s.extraData[n].hasOwnProperty('value')) {
 671                                      extraInputs.push(
 672                                          $('<input type="hidden" name="' + s.extraData[n].name + '">', ownerDocument).val(s.extraData[n].value)
 673                                              .appendTo(form)[0]);
 674                                  } else {
 675                                      extraInputs.push(
 676                                          $('<input type="hidden" name="' + n + '">', ownerDocument).val(s.extraData[n])
 677                                              .appendTo(form)[0]);
 678                                  }
 679                              }
 680                          }
 681                      }
 682  
 683                      if (!s.iframeTarget) {
 684                          // add iframe to doc and submit the form
 685                          $io.appendTo($body);
 686                      }
 687  
 688                      if (io.attachEvent) {
 689                          io.attachEvent('onload', cb);
 690                      } else {
 691                          io.addEventListener('load', cb, false);
 692                      }
 693  
 694                      setTimeout(checkState, 15);
 695  
 696                      try {
 697                          form.submit();
 698  
 699                      } catch (err) {
 700                          // just in case form has element with name/id of 'submit'
 701                          var submitFn = document.createElement('form').submit;
 702  
 703                          submitFn.apply(form);
 704                      }
 705  
 706                  } finally {
 707                      // reset attrs and remove "extra" input elements
 708                      form.setAttribute('action', a);
 709                      form.setAttribute('enctype', et); // #380
 710                      if (t) {
 711                          form.setAttribute('target', t);
 712                      } else {
 713                          $form.removeAttr('target');
 714                      }
 715                      $(extraInputs).remove();
 716                  }
 717              }
 718  
 719              if (s.forceSync) {
 720                  doSubmit();
 721              } else {
 722                  setTimeout(doSubmit, 10); // this lets dom updates render
 723              }
 724  
 725              var data, doc, domCheckCount = 50, callbackProcessed;
 726  
 727              function cb(e) {
 728                  if (xhr.aborted || callbackProcessed) {
 729                      return;
 730                  }
 731  
 732                  doc = getDoc(io);
 733                  if (!doc) {
 734                      log('cannot access response document');
 735                      e = SERVER_ABORT;
 736                  }
 737                  if (e === CLIENT_TIMEOUT_ABORT && xhr) {
 738                      xhr.abort('timeout');
 739                      deferred.reject(xhr, 'timeout');
 740  
 741                      return;
 742  
 743                  }
 744                  if (e === SERVER_ABORT && xhr) {
 745                      xhr.abort('server abort');
 746                      deferred.reject(xhr, 'error', 'server abort');
 747  
 748                      return;
 749                  }
 750  
 751                  if (!doc || doc.location.href === s.iframeSrc) {
 752                      // response not received yet
 753                      if (!timedOut) {
 754                          return;
 755                      }
 756                  }
 757  
 758                  if (io.detachEvent) {
 759                      io.detachEvent('onload', cb);
 760                  } else {
 761                      io.removeEventListener('load', cb, false);
 762                  }
 763  
 764                  var status = 'success', errMsg;
 765  
 766                  try {
 767                      if (timedOut) {
 768                          throw 'timeout';
 769                      }
 770  
 771                      var isXml = s.dataType === 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
 772  
 773                      log('isXml=' + isXml);
 774  
 775                      if (!isXml && window.opera && (doc.body === null || !doc.body.innerHTML)) {
 776                          if (--domCheckCount) {
 777                              // in some browsers (Opera) the iframe DOM is not always traversable when
 778                              // the onload callback fires, so we loop a bit to accommodate
 779                              log('requeing onLoad callback, DOM not available');
 780                              setTimeout(cb, 250);
 781  
 782                              return;
 783                          }
 784                          // let this fall through because server response could be an empty document
 785                          // log('Could not access iframe DOM after mutiple tries.');
 786                          // throw 'DOMException: not available';
 787                      }
 788  
 789                      // log('response detected');
 790                      var docRoot = doc.body ? doc.body : doc.documentElement;
 791  
 792                      xhr.responseText = docRoot ? docRoot.innerHTML : null;
 793                      xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
 794                      if (isXml) {
 795                          s.dataType = 'xml';
 796                      }
 797                      xhr.getResponseHeader = function(header){
 798                          var headers = {'content-type': s.dataType};
 799  
 800                          return headers[header.toLowerCase()];
 801                      };
 802                      // support for XHR 'status' & 'statusText' emulation :
 803                      if (docRoot) {
 804                          xhr.status = Number(docRoot.getAttribute('status')) || xhr.status;
 805                          xhr.statusText = docRoot.getAttribute('statusText') || xhr.statusText;
 806                      }
 807  
 808                      var dt = (s.dataType || '').toLowerCase();
 809                      var scr = /(json|script|text)/.test(dt);
 810  
 811                      if (scr || s.textarea) {
 812                          // see if user embedded response in textarea
 813                          var ta = doc.getElementsByTagName('textarea')[0];
 814  
 815                          if (ta) {
 816                              xhr.responseText = ta.value;
 817                              // support for XHR 'status' & 'statusText' emulation :
 818                              xhr.status = Number(ta.getAttribute('status')) || xhr.status;
 819                              xhr.statusText = ta.getAttribute('statusText') || xhr.statusText;
 820  
 821                          } else if (scr) {
 822                              // account for browsers injecting pre around json response
 823                              var pre = doc.getElementsByTagName('pre')[0];
 824                              var b = doc.getElementsByTagName('body')[0];
 825  
 826                              if (pre) {
 827                                  xhr.responseText = pre.textContent ? pre.textContent : pre.innerText;
 828                              } else if (b) {
 829                                  xhr.responseText = b.textContent ? b.textContent : b.innerText;
 830                              }
 831                          }
 832  
 833                      } else if (dt === 'xml' && !xhr.responseXML && xhr.responseText) {
 834                          xhr.responseXML = toXml(xhr.responseText);            // eslint-disable-line no-use-before-define
 835                      }
 836  
 837                      try {
 838                          data = httpData(xhr, dt, s);                        // eslint-disable-line no-use-before-define
 839  
 840                      } catch (err) {
 841                          status = 'parsererror';
 842                          xhr.error = errMsg = (err || status);
 843                      }
 844  
 845                  } catch (err) {
 846                      log('error caught: ', err);
 847                      status = 'error';
 848                      xhr.error = errMsg = (err || status);
 849                  }
 850  
 851                  if (xhr.aborted) {
 852                      log('upload aborted');
 853                      status = null;
 854                  }
 855  
 856                  if (xhr.status) { // we've set xhr.status
 857                      status = ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) ? 'success' : 'error';
 858                  }
 859  
 860                  // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
 861                  if (status === 'success') {
 862                      if (s.success) {
 863                          s.success.call(s.context, data, 'success', xhr);
 864                      }
 865  
 866                      deferred.resolve(xhr.responseText, 'success', xhr);
 867  
 868                      if (g) {
 869                          $.event.trigger('ajaxSuccess', [xhr, s]);
 870                      }
 871  
 872                  } else if (status) {
 873                      if (typeof errMsg === 'undefined') {
 874                          errMsg = xhr.statusText;
 875                      }
 876                      if (s.error) {
 877                          s.error.call(s.context, xhr, status, errMsg);
 878                      }
 879                      deferred.reject(xhr, 'error', errMsg);
 880                      if (g) {
 881                          $.event.trigger('ajaxError', [xhr, s, errMsg]);
 882                      }
 883                  }
 884  
 885                  if (g) {
 886                      $.event.trigger('ajaxComplete', [xhr, s]);
 887                  }
 888  
 889                  if (g && !--$.active) {
 890                      $.event.trigger('ajaxStop');
 891                  }
 892  
 893                  if (s.complete) {
 894                      s.complete.call(s.context, xhr, status);
 895                  }
 896  
 897                  callbackProcessed = true;
 898                  if (s.timeout) {
 899                      clearTimeout(timeoutHandle);
 900                  }
 901  
 902                  // clean up
 903                  setTimeout(function() {
 904                      if (!s.iframeTarget) {
 905                          $io.remove();
 906                      } else { // adding else to clean up existing iframe response.
 907                          $io.attr('src', s.iframeSrc);
 908                      }
 909                      xhr.responseXML = null;
 910                  }, 100);
 911              }
 912  
 913              var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+)
 914                  if (window.ActiveXObject) {
 915                      doc = new ActiveXObject('Microsoft.XMLDOM');
 916                      doc.async = 'false';
 917                      doc.loadXML(s);
 918  
 919                  } else {
 920                      doc = (new DOMParser()).parseFromString(s, 'text/xml');
 921                  }
 922  
 923                  return (doc && doc.documentElement && doc.documentElement.nodeName !== 'parsererror') ? doc : null;
 924              };
 925              var parseJSON = $.parseJSON || function(s) {
 926                  /* jslint evil:true */
 927                  return window['eval']('(' + s + ')');            // eslint-disable-line dot-notation
 928              };
 929  
 930              var httpData = function(xhr, type, s) { // mostly lifted from jq1.4.4
 931  
 932                  var ct = xhr.getResponseHeader('content-type') || '',
 933                      xml = ((type === 'xml' || !type) && ct.indexOf('xml') >= 0),
 934                      data = xml ? xhr.responseXML : xhr.responseText;
 935  
 936                  if (xml && data.documentElement.nodeName === 'parsererror') {
 937                      if ($.error) {
 938                          $.error('parsererror');
 939                      }
 940                  }
 941                  if (s && s.dataFilter) {
 942                      data = s.dataFilter(data, type);
 943                  }
 944                  if (typeof data === 'string') {
 945                      if ((type === 'json' || !type) && ct.indexOf('json') >= 0) {
 946                          data = parseJSON(data);
 947                      } else if ((type === 'script' || !type) && ct.indexOf('javascript') >= 0) {
 948                          $.globalEval(data);
 949                      }
 950                  }
 951  
 952                  return data;
 953              };
 954  
 955              return deferred;
 956          }
 957      };
 958  
 959      /**
 960       * ajaxForm() provides a mechanism for fully automating form submission.
 961       *
 962       * The advantages of using this method instead of ajaxSubmit() are:
 963       *
 964       * 1: This method will include coordinates for <input type="image"> elements (if the element
 965       *    is used to submit the form).
 966       * 2. This method will include the submit element's name/value data (for the element that was
 967       *    used to submit the form).
 968       * 3. This method binds the submit() method to the form for you.
 969       *
 970       * The options argument for ajaxForm works exactly as it does for ajaxSubmit. ajaxForm merely
 971       * passes the options argument along after properly binding events for submit elements and
 972       * the form itself.
 973       */
 974      $.fn.ajaxForm = function(options, data, dataType, onSuccess) {
 975          if (typeof options === 'string' || (options === false && arguments.length > 0)) {
 976              options = {
 977                  'url'      : options,
 978                  'data'     : data,
 979                  'dataType' : dataType
 980              };
 981  
 982              if (typeof onSuccess === 'function') {
 983                  options.success = onSuccess;
 984              }
 985          }
 986  
 987          options = options || {};
 988          options.delegation = options.delegation && $.isFunction($.fn.on);
 989  
 990          // in jQuery 1.3+ we can fix mistakes with the ready state
 991          if (!options.delegation && this.length === 0) {
 992              var o = {s: this.selector, c: this.context};
 993  
 994              if (!$.isReady && o.s) {
 995                  log('DOM not ready, queuing ajaxForm');
 996                  $(function() {
 997                      $(o.s, o.c).ajaxForm(options);
 998                  });
 999  
1000                  return this;
1001              }
1002  
1003              // is your DOM ready?  http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
1004              log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
1005  
1006              return this;
1007          }
1008  
1009          if (options.delegation) {
1010              $(document)
1011                  .off('submit.form-plugin', this.selector, doAjaxSubmit)
1012                  .off('click.form-plugin', this.selector, captureSubmittingElement)
1013                  .on('submit.form-plugin', this.selector, options, doAjaxSubmit)
1014                  .on('click.form-plugin', this.selector, options, captureSubmittingElement);
1015  
1016              return this;
1017          }
1018  
1019          if (options.beforeFormUnbind) {
1020              options.beforeFormUnbind(this, options);
1021          }
1022  
1023          return this.ajaxFormUnbind()
1024              .on('submit.form-plugin', options, doAjaxSubmit)
1025              .on('click.form-plugin', options, captureSubmittingElement);
1026      };
1027  
1028      // private event handlers
1029  	function doAjaxSubmit(e) {
1030          /* jshint validthis:true */
1031          var options = e.data;
1032  
1033          if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
1034              e.preventDefault();
1035              $(e.target).closest('form').ajaxSubmit(options); // #365
1036          }
1037      }
1038  
1039  	function captureSubmittingElement(e) {
1040          /* jshint validthis:true */
1041          var target = e.target;
1042          var $el = $(target);
1043  
1044          if (!$el.is('[type=submit],[type=image]')) {
1045              // is this a child element of the submit el?  (ex: a span within a button)
1046              var t = $el.closest('[type=submit]');
1047  
1048              if (t.length === 0) {
1049                  return;
1050              }
1051              target = t[0];
1052          }
1053  
1054          var form = target.form;
1055  
1056          form.clk = target;
1057  
1058          if (target.type === 'image') {
1059              if (typeof e.offsetX !== 'undefined') {
1060                  form.clk_x = e.offsetX;
1061                  form.clk_y = e.offsetY;
1062  
1063              } else if (typeof $.fn.offset === 'function') {
1064                  var offset = $el.offset();
1065  
1066                  form.clk_x = e.pageX - offset.left;
1067                  form.clk_y = e.pageY - offset.top;
1068  
1069              } else {
1070                  form.clk_x = e.pageX - target.offsetLeft;
1071                  form.clk_y = e.pageY - target.offsetTop;
1072              }
1073          }
1074          // clear form vars
1075          setTimeout(function() {
1076              form.clk = form.clk_x = form.clk_y = null;
1077          }, 100);
1078      }
1079  
1080  
1081      // ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
1082      $.fn.ajaxFormUnbind = function() {
1083          return this.off('submit.form-plugin click.form-plugin');
1084      };
1085  
1086      /**
1087       * formToArray() gathers form element data into an array of objects that can
1088       * be passed to any of the following ajax functions: $.get, $.post, or load.
1089       * Each object in the array has both a 'name' and 'value' property. An example of
1090       * an array for a simple login form might be:
1091       *
1092       * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
1093       *
1094       * It is this array that is passed to pre-submit callback functions provided to the
1095       * ajaxSubmit() and ajaxForm() methods.
1096       */
1097      $.fn.formToArray = function(semantic, elements, filtering) {
1098          var a = [];
1099  
1100          if (this.length === 0) {
1101              return a;
1102          }
1103  
1104          var form = this[0];
1105          var formId = this.attr('id');
1106          var els = (semantic || typeof form.elements === 'undefined') ? form.getElementsByTagName('*') : form.elements;
1107          var els2;
1108  
1109          if (els) {
1110              els = $.makeArray(els); // convert to standard array
1111          }
1112  
1113          // #386; account for inputs outside the form which use the 'form' attribute
1114          // FinesseRus: in non-IE browsers outside fields are already included in form.elements.
1115          if (formId && (semantic || /(Edge|Trident)\//.test(navigator.userAgent))) {
1116              els2 = $(':input[form="' + formId + '"]').get(); // hat tip @thet
1117              if (els2.length) {
1118                  els = (els || []).concat(els2);
1119              }
1120          }
1121  
1122          if (!els || !els.length) {
1123              return a;
1124          }
1125  
1126          if ($.isFunction(filtering)) {
1127              els = $.map(els, filtering);
1128          }
1129  
1130          var i, j, n, v, el, max, jmax;
1131  
1132          for (i = 0, max = els.length; i < max; i++) {
1133              el = els[i];
1134              n = el.name;
1135              if (!n || el.disabled) {
1136                  continue;
1137              }
1138  
1139              if (semantic && form.clk && el.type === 'image') {
1140                  // handle image inputs on the fly when semantic == true
1141                  if (form.clk === el) {
1142                      a.push({name: n, value: $(el).val(), type: el.type});
1143                      a.push({name: n + '.x', value: form.clk_x}, {name: n + '.y', value: form.clk_y});
1144                  }
1145                  continue;
1146              }
1147  
1148              v = $.fieldValue(el, true);
1149              if (v && v.constructor === Array) {
1150                  if (elements) {
1151                      elements.push(el);
1152                  }
1153                  for (j = 0, jmax = v.length; j < jmax; j++) {
1154                      a.push({name: n, value: v[j]});
1155                  }
1156  
1157              } else if (feature.fileapi && el.type === 'file') {
1158                  if (elements) {
1159                      elements.push(el);
1160                  }
1161  
1162                  var files = el.files;
1163  
1164                  if (files.length) {
1165                      for (j = 0; j < files.length; j++) {
1166                          a.push({name: n, value: files[j], type: el.type});
1167                      }
1168                  } else {
1169                      // #180
1170                      a.push({name: n, value: '', type: el.type});
1171                  }
1172  
1173              } else if (v !== null && typeof v !== 'undefined') {
1174                  if (elements) {
1175                      elements.push(el);
1176                  }
1177                  a.push({name: n, value: v, type: el.type, required: el.required});
1178              }
1179          }
1180  
1181          if (!semantic && form.clk) {
1182              // input type=='image' are not found in elements array! handle it here
1183              var $input = $(form.clk), input = $input[0];
1184  
1185              n = input.name;
1186  
1187              if (n && !input.disabled && input.type === 'image') {
1188                  a.push({name: n, value: $input.val()});
1189                  a.push({name: n + '.x', value: form.clk_x}, {name: n + '.y', value: form.clk_y});
1190              }
1191          }
1192  
1193          return a;
1194      };
1195  
1196      /**
1197       * Serializes form data into a 'submittable' string. This method will return a string
1198       * in the format: name1=value1&amp;name2=value2
1199       */
1200      $.fn.formSerialize = function(semantic) {
1201          // hand off to jQuery.param for proper encoding
1202          return $.param(this.formToArray(semantic));
1203      };
1204  
1205      /**
1206       * Serializes all field elements in the jQuery object into a query string.
1207       * This method will return a string in the format: name1=value1&amp;name2=value2
1208       */
1209      $.fn.fieldSerialize = function(successful) {
1210          var a = [];
1211  
1212          this.each(function() {
1213              var n = this.name;
1214  
1215              if (!n) {
1216                  return;
1217              }
1218  
1219              var v = $.fieldValue(this, successful);
1220  
1221              if (v && v.constructor === Array) {
1222                  for (var i = 0, max = v.length; i < max; i++) {
1223                      a.push({name: n, value: v[i]});
1224                  }
1225  
1226              } else if (v !== null && typeof v !== 'undefined') {
1227                  a.push({name: this.name, value: v});
1228              }
1229          });
1230  
1231          // hand off to jQuery.param for proper encoding
1232          return $.param(a);
1233      };
1234  
1235      /**
1236       * Returns the value(s) of the element in the matched set. For example, consider the following form:
1237       *
1238       *    <form><fieldset>
1239       *        <input name="A" type="text">
1240       *        <input name="A" type="text">
1241       *        <input name="B" type="checkbox" value="B1">
1242       *        <input name="B" type="checkbox" value="B2">
1243       *        <input name="C" type="radio" value="C1">
1244       *        <input name="C" type="radio" value="C2">
1245       *    </fieldset></form>
1246       *
1247       *    var v = $('input[type=text]').fieldValue();
1248       *    // if no values are entered into the text inputs
1249       *    v === ['','']
1250       *    // if values entered into the text inputs are 'foo' and 'bar'
1251       *    v === ['foo','bar']
1252       *
1253       *    var v = $('input[type=checkbox]').fieldValue();
1254       *    // if neither checkbox is checked
1255       *    v === undefined
1256       *    // if both checkboxes are checked
1257       *    v === ['B1', 'B2']
1258       *
1259       *    var v = $('input[type=radio]').fieldValue();
1260       *    // if neither radio is checked
1261       *    v === undefined
1262       *    // if first radio is checked
1263       *    v === ['C1']
1264       *
1265       * The successful argument controls whether or not the field element must be 'successful'
1266       * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
1267       * The default value of the successful argument is true. If this value is false the value(s)
1268       * for each element is returned.
1269       *
1270       * Note: This method *always* returns an array. If no valid value can be determined the
1271       *    array will be empty, otherwise it will contain one or more values.
1272       */
1273      $.fn.fieldValue = function(successful) {
1274          for (var val = [], i = 0, max = this.length; i < max; i++) {
1275              var el = this[i];
1276              var v = $.fieldValue(el, successful);
1277  
1278              if (v === null || typeof v === 'undefined' || (v.constructor === Array && !v.length)) {
1279                  continue;
1280              }
1281  
1282              if (v.constructor === Array) {
1283                  $.merge(val, v);
1284              } else {
1285                  val.push(v);
1286              }
1287          }
1288  
1289          return val;
1290      };
1291  
1292      /**
1293       * Returns the value of the field element.
1294       */
1295      $.fieldValue = function(el, successful) {
1296          var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
1297  
1298          if (typeof successful === 'undefined') {
1299              successful = true;
1300          }
1301  
1302          /* eslint-disable no-mixed-operators */
1303          if (successful && (!n || el.disabled || t === 'reset' || t === 'button' ||
1304              (t === 'checkbox' || t === 'radio') && !el.checked ||
1305              (t === 'submit' || t === 'image') && el.form && el.form.clk !== el ||
1306              tag === 'select' && el.selectedIndex === -1)) {
1307          /* eslint-enable no-mixed-operators */
1308              return null;
1309          }
1310  
1311          if (tag === 'select') {
1312              var index = el.selectedIndex;
1313  
1314              if (index < 0) {
1315                  return null;
1316              }
1317  
1318              var a = [], ops = el.options;
1319              var one = (t === 'select-one');
1320              var max = (one ? index + 1 : ops.length);
1321  
1322              for (var i = (one ? index : 0); i < max; i++) {
1323                  var op = ops[i];
1324  
1325                  if (op.selected && !op.disabled) {
1326                      var v = op.value;
1327  
1328                      if (!v) { // extra pain for IE...
1329                          v = (op.attributes && op.attributes.value && !(op.attributes.value.specified)) ? op.text : op.value;
1330                      }
1331  
1332                      if (one) {
1333                          return v;
1334                      }
1335  
1336                      a.push(v);
1337                  }
1338              }
1339  
1340              return a;
1341          }
1342  
1343          return $(el).val().replace(rCRLF, '\r\n');
1344      };
1345  
1346      /**
1347       * Clears the form data. Takes the following actions on the form's input fields:
1348       *  - input text fields will have their 'value' property set to the empty string
1349       *  - select elements will have their 'selectedIndex' property set to -1
1350       *  - checkbox and radio inputs will have their 'checked' property set to false
1351       *  - inputs of type submit, button, reset, and hidden will *not* be effected
1352       *  - button elements will *not* be effected
1353       */
1354      $.fn.clearForm = function(includeHidden) {
1355          return this.each(function() {
1356              $('input,select,textarea', this).clearFields(includeHidden);
1357          });
1358      };
1359  
1360      /**
1361       * Clears the selected form elements.
1362       */
1363      $.fn.clearFields = $.fn.clearInputs = function(includeHidden) {
1364          var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list
1365  
1366          return this.each(function() {
1367              var t = this.type, tag = this.tagName.toLowerCase();
1368  
1369              if (re.test(t) || tag === 'textarea') {
1370                  this.value = '';
1371  
1372              } else if (t === 'checkbox' || t === 'radio') {
1373                  this.checked = false;
1374  
1375              } else if (tag === 'select') {
1376                  this.selectedIndex = -1;
1377  
1378              } else if (t === 'file') {
1379                  if (/MSIE/.test(navigator.userAgent)) {
1380                      $(this).replaceWith($(this).clone(true));
1381                  } else {
1382                      $(this).val('');
1383                  }
1384  
1385              } else if (includeHidden) {
1386                  // includeHidden can be the value true, or it can be a selector string
1387                  // indicating a special test; for example:
1388                  // $('#myForm').clearForm('.special:hidden')
1389                  // the above would clean hidden inputs that have the class of 'special'
1390                  if ((includeHidden === true && /hidden/.test(t)) ||
1391                      (typeof includeHidden === 'string' && $(this).is(includeHidden))) {
1392                      this.value = '';
1393                  }
1394              }
1395          });
1396      };
1397  
1398  
1399      /**
1400       * Resets the form data or individual elements. Takes the following actions
1401       * on the selected tags:
1402       * - all fields within form elements will be reset to their original value
1403       * - input / textarea / select fields will be reset to their original value
1404       * - option / optgroup fields (for multi-selects) will defaulted individually
1405       * - non-multiple options will find the right select to default
1406       * - label elements will be searched against its 'for' attribute
1407       * - all others will be searched for appropriate children to default
1408       */
1409      $.fn.resetForm = function() {
1410          return this.each(function() {
1411              var el = $(this);
1412              var tag = this.tagName.toLowerCase();
1413  
1414              switch (tag) {
1415              case 'input':
1416                  this.checked = this.defaultChecked;
1417                  // fall through
1418  
1419              case 'textarea':
1420                  this.value = this.defaultValue;
1421  
1422                  return true;
1423  
1424              case 'option':
1425              case 'optgroup':
1426                  var select = el.parents('select');
1427  
1428                  if (select.length && select[0].multiple) {
1429                      if (tag === 'option') {
1430                          this.selected = this.defaultSelected;
1431                      } else {
1432                          el.find('option').resetForm();
1433                      }
1434                  } else {
1435                      select.resetForm();
1436                  }
1437  
1438                  return true;
1439  
1440              case 'select':
1441                  el.find('option').each(function(i) {                // eslint-disable-line consistent-return
1442                      this.selected = this.defaultSelected;
1443                      if (this.defaultSelected && !el[0].multiple) {
1444                          el[0].selectedIndex = i;
1445  
1446                          return false;
1447                      }
1448                  });
1449  
1450                  return true;
1451  
1452              case 'label':
1453                  var forEl = $(el.attr('for'));
1454                  var list = el.find('input,select,textarea');
1455  
1456                  if (forEl[0]) {
1457                      list.unshift(forEl[0]);
1458                  }
1459  
1460                  list.resetForm();
1461  
1462                  return true;
1463  
1464              case 'form':
1465                  // guard against an input with the name of 'reset'
1466                  // note that IE reports the reset function as an 'object'
1467                  if (typeof this.reset === 'function' || (typeof this.reset === 'object' && !this.reset.nodeType)) {
1468                      this.reset();
1469                  }
1470  
1471                  return true;
1472  
1473              default:
1474                  el.find('form,input,label,select,textarea').resetForm();
1475  
1476                  return true;
1477              }
1478          });
1479      };
1480  
1481      /**
1482       * Enables or disables any matching elements.
1483       */
1484      $.fn.enable = function(b) {
1485          if (typeof b === 'undefined') {
1486              b = true;
1487          }
1488  
1489          return this.each(function() {
1490              this.disabled = !b;
1491          });
1492      };
1493  
1494      /**
1495       * Checks/unchecks any matching checkboxes or radio buttons and
1496       * selects/deselects and matching option elements.
1497       */
1498      $.fn.selected = function(select) {
1499          if (typeof select === 'undefined') {
1500              select = true;
1501          }
1502  
1503          return this.each(function() {
1504              var t = this.type;
1505  
1506              if (t === 'checkbox' || t === 'radio') {
1507                  this.checked = select;
1508  
1509              } else if (this.tagName.toLowerCase() === 'option') {
1510                  var $sel = $(this).parent('select');
1511  
1512                  if (select && $sel[0] && $sel[0].type === 'select-one') {
1513                      // deselect all other options
1514                      $sel.find('option').selected(false);
1515                  }
1516  
1517                  this.selected = select;
1518              }
1519          });
1520      };
1521  
1522      // expose debug var
1523      $.fn.ajaxSubmit.debug = false;
1524  
1525      // helper fn for console logging
1526  	function log() {
1527          if (!$.fn.ajaxSubmit.debug) {
1528              return;
1529          }
1530  
1531          var msg = '[jquery.form] ' + Array.prototype.join.call(arguments, '');
1532  
1533          if (window.console && window.console.log) {
1534              window.console.log(msg);
1535  
1536          } else if (window.opera && window.opera.postError) {
1537              window.opera.postError(msg);
1538          }
1539      }
1540  }));


Generated : Wed Dec 25 08:20:01 2024 Cross-referenced by PHPXref