[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

title

Body

[close]

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

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


Generated: Sat Nov 23 20:47:33 2019 Cross-referenced by PHPXref 0.7