r80504 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r80503‎ | r80504 | r80505 >
Date:18:25, 18 January 2011
Author:werdna
Status:ok (Comments)
Tags:
Comment:
Modified paths:
  • /trunk/phase3/resources/Resources.php (modified) (history)
  • /trunk/phase3/resources/jquery/jquery.form.js (added) (history)

Diff [purge]

Index: trunk/phase3/resources/jquery/jquery.form.js
@@ -0,0 +1,791 @@
 2+/*!
 3+ * jQuery Form Plugin
 4+ * version: 2.52 (07-DEC-2010)
 5+ * @requires jQuery v1.3.2 or later
 6+ *
 7+ * Examples and documentation at: http://malsup.com/jquery/form/
 8+ * Dual licensed under the MIT and GPL licenses:
 9+ * http://www.opensource.org/licenses/mit-license.php
 10+ * http://www.gnu.org/licenses/gpl.html
 11+ */
 12+;(function($) {
 13+
 14+/*
 15+ Usage Note:
 16+ -----------
 17+ Do not use both ajaxSubmit and ajaxForm on the same form. These
 18+ functions are intended to be exclusive. Use ajaxSubmit if you want
 19+ to bind your own submit handler to the form. For example,
 20+
 21+ $(document).ready(function() {
 22+ $('#myForm').bind('submit', function(e) {
 23+ e.preventDefault(); // <-- important
 24+ $(this).ajaxSubmit({
 25+ target: '#output'
 26+ });
 27+ });
 28+ });
 29+
 30+ Use ajaxForm when you want the plugin to manage all the event binding
 31+ for you. For example,
 32+
 33+ $(document).ready(function() {
 34+ $('#myForm').ajaxForm({
 35+ target: '#output'
 36+ });
 37+ });
 38+
 39+ When using ajaxForm, the ajaxSubmit function will be invoked for you
 40+ at the appropriate time.
 41+*/
 42+
 43+/**
 44+ * ajaxSubmit() provides a mechanism for immediately submitting
 45+ * an HTML form using AJAX.
 46+ */
 47+$.fn.ajaxSubmit = function(options) {
 48+ // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
 49+ if (!this.length) {
 50+ log('ajaxSubmit: skipping submit process - no element selected');
 51+ return this;
 52+ }
 53+
 54+ if (typeof options == 'function') {
 55+ options = { success: options };
 56+ }
 57+
 58+ var action = this.attr('action');
 59+ var url = (typeof action === 'string') ? $.trim(action) : '';
 60+ if (url) {
 61+ // clean url (don't include hash vaue)
 62+ url = (url.match(/^([^#]+)/)||[])[1];
 63+ }
 64+ url = url || window.location.href || '';
 65+
 66+ options = $.extend(true, {
 67+ url: url,
 68+ type: this.attr('method') || 'GET',
 69+ iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
 70+ }, options);
 71+
 72+ // hook for manipulating the form data before it is extracted;
 73+ // convenient for use with rich editors like tinyMCE or FCKEditor
 74+ var veto = {};
 75+ this.trigger('form-pre-serialize', [this, options, veto]);
 76+ if (veto.veto) {
 77+ log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
 78+ return this;
 79+ }
 80+
 81+ // provide opportunity to alter form data before it is serialized
 82+ if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
 83+ log('ajaxSubmit: submit aborted via beforeSerialize callback');
 84+ return this;
 85+ }
 86+
 87+ var n,v,a = this.formToArray(options.semantic);
 88+ if (options.data) {
 89+ options.extraData = options.data;
 90+ for (n in options.data) {
 91+ if(options.data[n] instanceof Array) {
 92+ for (var k in options.data[n]) {
 93+ a.push( { name: n, value: options.data[n][k] } );
 94+ }
 95+ }
 96+ else {
 97+ v = options.data[n];
 98+ v = $.isFunction(v) ? v() : v; // if value is fn, invoke it
 99+ a.push( { name: n, value: v } );
 100+ }
 101+ }
 102+ }
 103+
 104+ // give pre-submit callback an opportunity to abort the submit
 105+ if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
 106+ log('ajaxSubmit: submit aborted via beforeSubmit callback');
 107+ return this;
 108+ }
 109+
 110+ // fire vetoable 'validate' event
 111+ this.trigger('form-submit-validate', [a, this, options, veto]);
 112+ if (veto.veto) {
 113+ log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
 114+ return this;
 115+ }
 116+
 117+ var q = $.param(a);
 118+
 119+ if (options.type.toUpperCase() == 'GET') {
 120+ options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
 121+ options.data = null; // data is null for 'get'
 122+ }
 123+ else {
 124+ options.data = q; // data is the query string for 'post'
 125+ }
 126+
 127+ var $form = this, callbacks = [];
 128+ if (options.resetForm) {
 129+ callbacks.push(function() { $form.resetForm(); });
 130+ }
 131+ if (options.clearForm) {
 132+ callbacks.push(function() { $form.clearForm(); });
 133+ }
 134+
 135+ // perform a load on the target only if dataType is not provided
 136+ if (!options.dataType && options.target) {
 137+ var oldSuccess = options.success || function(){};
 138+ callbacks.push(function(data) {
 139+ var fn = options.replaceTarget ? 'replaceWith' : 'html';
 140+ $(options.target)[fn](data).each(oldSuccess, arguments);
 141+ });
 142+ }
 143+ else if (options.success) {
 144+ callbacks.push(options.success);
 145+ }
 146+
 147+ options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
 148+ var context = options.context || options; // jQuery 1.4+ supports scope context
 149+ for (var i=0, max=callbacks.length; i < max; i++) {
 150+ callbacks[i].apply(context, [data, status, xhr || $form, $form]);
 151+ }
 152+ };
 153+
 154+ // are there files to upload?
 155+ var fileInputs = $('input:file', this).length > 0;
 156+ var mp = 'multipart/form-data';
 157+ var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);
 158+
 159+ // options.iframe allows user to force iframe mode
 160+ // 06-NOV-09: now defaulting to iframe mode if file input is detected
 161+ if (options.iframe !== false && (fileInputs || options.iframe || multipart)) {
 162+ // hack to fix Safari hang (thanks to Tim Molendijk for this)
 163+ // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
 164+ if (options.closeKeepAlive) {
 165+ $.get(options.closeKeepAlive, fileUpload);
 166+ }
 167+ else {
 168+ fileUpload();
 169+ }
 170+ }
 171+ else {
 172+ $.ajax(options);
 173+ }
 174+
 175+ // fire 'notify' event
 176+ this.trigger('form-submit-notify', [this, options]);
 177+ return this;
 178+
 179+
 180+ // private function for handling file uploads (hat tip to YAHOO!)
 181+ function fileUpload() {
 182+ var form = $form[0];
 183+
 184+ if ($(':input[name=submit],:input[id=submit]', form).length) {
 185+ // if there is an input with a name or id of 'submit' then we won't be
 186+ // able to invoke the submit fn on the form (at least not x-browser)
 187+ alert('Error: Form elements must not have name or id of "submit".');
 188+ return;
 189+ }
 190+
 191+ var s = $.extend(true, {}, $.ajaxSettings, options);
 192+ s.context = s.context || s;
 193+ var id = 'jqFormIO' + (new Date().getTime()), fn = '_'+id;
 194+ window[fn] = function() {
 195+ var f = $io.data('form-plugin-onload');
 196+ if (f) {
 197+ f();
 198+ window[fn] = undefined;
 199+ try { delete window[fn]; } catch(e){}
 200+ }
 201+ }
 202+ var $io = $('<iframe id="' + id + '" name="' + id + '" src="'+ s.iframeSrc +'" onload="window[\'_\'+this.id]()" />');
 203+ var io = $io[0];
 204+
 205+ $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
 206+
 207+ var xhr = { // mock object
 208+ aborted: 0,
 209+ responseText: null,
 210+ responseXML: null,
 211+ status: 0,
 212+ statusText: 'n/a',
 213+ getAllResponseHeaders: function() {},
 214+ getResponseHeader: function() {},
 215+ setRequestHeader: function() {},
 216+ abort: function() {
 217+ this.aborted = 1;
 218+ $io.attr('src', s.iframeSrc); // abort op in progress
 219+ }
 220+ };
 221+
 222+ var g = s.global;
 223+ // trigger ajax global events so that activity/block indicators work like normal
 224+ if (g && ! $.active++) {
 225+ $.event.trigger("ajaxStart");
 226+ }
 227+ if (g) {
 228+ $.event.trigger("ajaxSend", [xhr, s]);
 229+ }
 230+
 231+ if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
 232+ if (s.global) {
 233+ $.active--;
 234+ }
 235+ return;
 236+ }
 237+ if (xhr.aborted) {
 238+ return;
 239+ }
 240+
 241+ var cbInvoked = false;
 242+ var timedOut = 0;
 243+
 244+ // add submitting element to data if we know it
 245+ var sub = form.clk;
 246+ if (sub) {
 247+ var n = sub.name;
 248+ if (n && !sub.disabled) {
 249+ s.extraData = s.extraData || {};
 250+ s.extraData[n] = sub.value;
 251+ if (sub.type == "image") {
 252+ s.extraData[n+'.x'] = form.clk_x;
 253+ s.extraData[n+'.y'] = form.clk_y;
 254+ }
 255+ }
 256+ }
 257+
 258+ // take a breath so that pending repaints get some cpu time before the upload starts
 259+ function doSubmit() {
 260+ // make sure form attrs are set
 261+ var t = $form.attr('target'), a = $form.attr('action');
 262+
 263+ // update form attrs in IE friendly way
 264+ form.setAttribute('target',id);
 265+ if (form.getAttribute('method') != 'POST') {
 266+ form.setAttribute('method', 'POST');
 267+ }
 268+ if (form.getAttribute('action') != s.url) {
 269+ form.setAttribute('action', s.url);
 270+ }
 271+
 272+ // ie borks in some cases when setting encoding
 273+ if (! s.skipEncodingOverride) {
 274+ $form.attr({
 275+ encoding: 'multipart/form-data',
 276+ enctype: 'multipart/form-data'
 277+ });
 278+ }
 279+
 280+ // support timout
 281+ if (s.timeout) {
 282+ setTimeout(function() { timedOut = true; cb(); }, s.timeout);
 283+ }
 284+
 285+ // add "extra" data to form if provided in options
 286+ var extraInputs = [];
 287+ try {
 288+ if (s.extraData) {
 289+ for (var n in s.extraData) {
 290+ extraInputs.push(
 291+ $('<input type="hidden" name="'+n+'" value="'+s.extraData[n]+'" />')
 292+ .appendTo(form)[0]);
 293+ }
 294+ }
 295+
 296+ // add iframe to doc and submit the form
 297+ $io.appendTo('body');
 298+ $io.data('form-plugin-onload', cb);
 299+ form.submit();
 300+ }
 301+ finally {
 302+ // reset attrs and remove "extra" input elements
 303+ form.setAttribute('action',a);
 304+ if(t) {
 305+ form.setAttribute('target', t);
 306+ } else {
 307+ $form.removeAttr('target');
 308+ }
 309+ $(extraInputs).remove();
 310+ }
 311+ }
 312+
 313+ if (s.forceSync) {
 314+ doSubmit();
 315+ }
 316+ else {
 317+ setTimeout(doSubmit, 10); // this lets dom updates render
 318+ }
 319+
 320+ var data, doc, domCheckCount = 50;
 321+
 322+ function cb() {
 323+ if (cbInvoked) {
 324+ return;
 325+ }
 326+
 327+ $io.removeData('form-plugin-onload');
 328+
 329+ var ok = true;
 330+ try {
 331+ if (timedOut) {
 332+ throw 'timeout';
 333+ }
 334+ // extract the server response from the iframe
 335+ doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
 336+
 337+ var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
 338+ log('isXml='+isXml);
 339+ if (!isXml && window.opera && (doc.body == null || doc.body.innerHTML == '')) {
 340+ if (--domCheckCount) {
 341+ // in some browsers (Opera) the iframe DOM is not always traversable when
 342+ // the onload callback fires, so we loop a bit to accommodate
 343+ log('requeing onLoad callback, DOM not available');
 344+ setTimeout(cb, 250);
 345+ return;
 346+ }
 347+ // let this fall through because server response could be an empty document
 348+ //log('Could not access iframe DOM after mutiple tries.');
 349+ //throw 'DOMException: not available';
 350+ }
 351+
 352+ //log('response detected');
 353+ cbInvoked = true;
 354+ xhr.responseText = doc.documentElement ? doc.documentElement.innerHTML : null;
 355+ xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
 356+ xhr.getResponseHeader = function(header){
 357+ var headers = {'content-type': s.dataType};
 358+ return headers[header];
 359+ };
 360+
 361+ var scr = /(json|script)/.test(s.dataType);
 362+ if (scr || s.textarea) {
 363+ // see if user embedded response in textarea
 364+ var ta = doc.getElementsByTagName('textarea')[0];
 365+ if (ta) {
 366+ xhr.responseText = ta.value;
 367+ }
 368+ else if (scr) {
 369+ // account for browsers injecting pre around json response
 370+ var pre = doc.getElementsByTagName('pre')[0];
 371+ var b = doc.getElementsByTagName('body')[0];
 372+ if (pre) {
 373+ xhr.responseText = pre.textContent;
 374+ }
 375+ else if (b) {
 376+ xhr.responseText = b.innerHTML;
 377+ }
 378+ }
 379+ }
 380+ else if (s.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
 381+ xhr.responseXML = toXml(xhr.responseText);
 382+ }
 383+ data = $.httpData(xhr, s.dataType);
 384+ }
 385+ catch(e){
 386+ log('error caught:',e);
 387+ ok = false;
 388+ xhr.error = e;
 389+ $.handleError(s, xhr, 'error', e);
 390+ }
 391+
 392+ if (xhr.aborted) {
 393+ log('upload aborted');
 394+ ok = false;
 395+ }
 396+
 397+ // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
 398+ if (ok) {
 399+ s.success.call(s.context, data, 'success', xhr);
 400+ if (g) {
 401+ $.event.trigger("ajaxSuccess", [xhr, s]);
 402+ }
 403+ }
 404+ if (g) {
 405+ $.event.trigger("ajaxComplete", [xhr, s]);
 406+ }
 407+ if (g && ! --$.active) {
 408+ $.event.trigger("ajaxStop");
 409+ }
 410+ if (s.complete) {
 411+ s.complete.call(s.context, xhr, ok ? 'success' : 'error');
 412+ }
 413+
 414+ // clean up
 415+ setTimeout(function() {
 416+ $io.removeData('form-plugin-onload');
 417+ $io.remove();
 418+ xhr.responseXML = null;
 419+ }, 100);
 420+ }
 421+
 422+ function toXml(s, doc) {
 423+ if (window.ActiveXObject) {
 424+ doc = new ActiveXObject('Microsoft.XMLDOM');
 425+ doc.async = 'false';
 426+ doc.loadXML(s);
 427+ }
 428+ else {
 429+ doc = (new DOMParser()).parseFromString(s, 'text/xml');
 430+ }
 431+ return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
 432+ }
 433+ }
 434+};
 435+
 436+/**
 437+ * ajaxForm() provides a mechanism for fully automating form submission.
 438+ *
 439+ * The advantages of using this method instead of ajaxSubmit() are:
 440+ *
 441+ * 1: This method will include coordinates for <input type="image" /> elements (if the element
 442+ * is used to submit the form).
 443+ * 2. This method will include the submit element's name/value data (for the element that was
 444+ * used to submit the form).
 445+ * 3. This method binds the submit() method to the form for you.
 446+ *
 447+ * The options argument for ajaxForm works exactly as it does for ajaxSubmit. ajaxForm merely
 448+ * passes the options argument along after properly binding events for submit elements and
 449+ * the form itself.
 450+ */
 451+$.fn.ajaxForm = function(options) {
 452+ // in jQuery 1.3+ we can fix mistakes with the ready state
 453+ if (this.length === 0) {
 454+ var o = { s: this.selector, c: this.context };
 455+ if (!$.isReady && o.s) {
 456+ log('DOM not ready, queuing ajaxForm');
 457+ $(function() {
 458+ $(o.s,o.c).ajaxForm(options);
 459+ });
 460+ return this;
 461+ }
 462+ // is your DOM ready? http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
 463+ log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
 464+ return this;
 465+ }
 466+
 467+ return this.ajaxFormUnbind().bind('submit.form-plugin', function(e) {
 468+ if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
 469+ e.preventDefault();
 470+ $(this).ajaxSubmit(options);
 471+ }
 472+ }).bind('click.form-plugin', function(e) {
 473+ var target = e.target;
 474+ var $el = $(target);
 475+ if (!($el.is(":submit,input:image"))) {
 476+ // is this a child element of the submit el? (ex: a span within a button)
 477+ var t = $el.closest(':submit');
 478+ if (t.length == 0) {
 479+ return;
 480+ }
 481+ target = t[0];
 482+ }
 483+ var form = this;
 484+ form.clk = target;
 485+ if (target.type == 'image') {
 486+ if (e.offsetX != undefined) {
 487+ form.clk_x = e.offsetX;
 488+ form.clk_y = e.offsetY;
 489+ } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
 490+ var offset = $el.offset();
 491+ form.clk_x = e.pageX - offset.left;
 492+ form.clk_y = e.pageY - offset.top;
 493+ } else {
 494+ form.clk_x = e.pageX - target.offsetLeft;
 495+ form.clk_y = e.pageY - target.offsetTop;
 496+ }
 497+ }
 498+ // clear form vars
 499+ setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
 500+ });
 501+};
 502+
 503+// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
 504+$.fn.ajaxFormUnbind = function() {
 505+ return this.unbind('submit.form-plugin click.form-plugin');
 506+};
 507+
 508+/**
 509+ * formToArray() gathers form element data into an array of objects that can
 510+ * be passed to any of the following ajax functions: $.get, $.post, or load.
 511+ * Each object in the array has both a 'name' and 'value' property. An example of
 512+ * an array for a simple login form might be:
 513+ *
 514+ * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
 515+ *
 516+ * It is this array that is passed to pre-submit callback functions provided to the
 517+ * ajaxSubmit() and ajaxForm() methods.
 518+ */
 519+$.fn.formToArray = function(semantic) {
 520+ var a = [];
 521+ if (this.length === 0) {
 522+ return a;
 523+ }
 524+
 525+ var form = this[0];
 526+ var els = semantic ? form.getElementsByTagName('*') : form.elements;
 527+ if (!els) {
 528+ return a;
 529+ }
 530+
 531+ var i,j,n,v,el,max,jmax;
 532+ for(i=0, max=els.length; i < max; i++) {
 533+ el = els[i];
 534+ n = el.name;
 535+ if (!n) {
 536+ continue;
 537+ }
 538+
 539+ if (semantic && form.clk && el.type == "image") {
 540+ // handle image inputs on the fly when semantic == true
 541+ if(!el.disabled && form.clk == el) {
 542+ a.push({name: n, value: $(el).val()});
 543+ a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
 544+ }
 545+ continue;
 546+ }
 547+
 548+ v = $.fieldValue(el, true);
 549+ if (v && v.constructor == Array) {
 550+ for(j=0, jmax=v.length; j < jmax; j++) {
 551+ a.push({name: n, value: v[j]});
 552+ }
 553+ }
 554+ else if (v !== null && typeof v != 'undefined') {
 555+ a.push({name: n, value: v});
 556+ }
 557+ }
 558+
 559+ if (!semantic && form.clk) {
 560+ // input type=='image' are not found in elements array! handle it here
 561+ var $input = $(form.clk), input = $input[0];
 562+ n = input.name;
 563+ if (n && !input.disabled && input.type == 'image') {
 564+ a.push({name: n, value: $input.val()});
 565+ a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
 566+ }
 567+ }
 568+ return a;
 569+};
 570+
 571+/**
 572+ * Serializes form data into a 'submittable' string. This method will return a string
 573+ * in the format: name1=value1&amp;name2=value2
 574+ */
 575+$.fn.formSerialize = function(semantic) {
 576+ //hand off to jQuery.param for proper encoding
 577+ return $.param(this.formToArray(semantic));
 578+};
 579+
 580+/**
 581+ * Serializes all field elements in the jQuery object into a query string.
 582+ * This method will return a string in the format: name1=value1&amp;name2=value2
 583+ */
 584+$.fn.fieldSerialize = function(successful) {
 585+ var a = [];
 586+ this.each(function() {
 587+ var n = this.name;
 588+ if (!n) {
 589+ return;
 590+ }
 591+ var v = $.fieldValue(this, successful);
 592+ if (v && v.constructor == Array) {
 593+ for (var i=0,max=v.length; i < max; i++) {
 594+ a.push({name: n, value: v[i]});
 595+ }
 596+ }
 597+ else if (v !== null && typeof v != 'undefined') {
 598+ a.push({name: this.name, value: v});
 599+ }
 600+ });
 601+ //hand off to jQuery.param for proper encoding
 602+ return $.param(a);
 603+};
 604+
 605+/**
 606+ * Returns the value(s) of the element in the matched set. For example, consider the following form:
 607+ *
 608+ * <form><fieldset>
 609+ * <input name="A" type="text" />
 610+ * <input name="A" type="text" />
 611+ * <input name="B" type="checkbox" value="B1" />
 612+ * <input name="B" type="checkbox" value="B2"/>
 613+ * <input name="C" type="radio" value="C1" />
 614+ * <input name="C" type="radio" value="C2" />
 615+ * </fieldset></form>
 616+ *
 617+ * var v = $(':text').fieldValue();
 618+ * // if no values are entered into the text inputs
 619+ * v == ['','']
 620+ * // if values entered into the text inputs are 'foo' and 'bar'
 621+ * v == ['foo','bar']
 622+ *
 623+ * var v = $(':checkbox').fieldValue();
 624+ * // if neither checkbox is checked
 625+ * v === undefined
 626+ * // if both checkboxes are checked
 627+ * v == ['B1', 'B2']
 628+ *
 629+ * var v = $(':radio').fieldValue();
 630+ * // if neither radio is checked
 631+ * v === undefined
 632+ * // if first radio is checked
 633+ * v == ['C1']
 634+ *
 635+ * The successful argument controls whether or not the field element must be 'successful'
 636+ * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
 637+ * The default value of the successful argument is true. If this value is false the value(s)
 638+ * for each element is returned.
 639+ *
 640+ * Note: This method *always* returns an array. If no valid value can be determined the
 641+ * array will be empty, otherwise it will contain one or more values.
 642+ */
 643+$.fn.fieldValue = function(successful) {
 644+ for (var val=[], i=0, max=this.length; i < max; i++) {
 645+ var el = this[i];
 646+ var v = $.fieldValue(el, successful);
 647+ if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) {
 648+ continue;
 649+ }
 650+ v.constructor == Array ? $.merge(val, v) : val.push(v);
 651+ }
 652+ return val;
 653+};
 654+
 655+/**
 656+ * Returns the value of the field element.
 657+ */
 658+$.fieldValue = function(el, successful) {
 659+ var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
 660+ if (successful === undefined) {
 661+ successful = true;
 662+ }
 663+
 664+ if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
 665+ (t == 'checkbox' || t == 'radio') && !el.checked ||
 666+ (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
 667+ tag == 'select' && el.selectedIndex == -1)) {
 668+ return null;
 669+ }
 670+
 671+ if (tag == 'select') {
 672+ var index = el.selectedIndex;
 673+ if (index < 0) {
 674+ return null;
 675+ }
 676+ var a = [], ops = el.options;
 677+ var one = (t == 'select-one');
 678+ var max = (one ? index+1 : ops.length);
 679+ for(var i=(one ? index : 0); i < max; i++) {
 680+ var op = ops[i];
 681+ if (op.selected) {
 682+ var v = op.value;
 683+ if (!v) { // extra pain for IE...
 684+ v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
 685+ }
 686+ if (one) {
 687+ return v;
 688+ }
 689+ a.push(v);
 690+ }
 691+ }
 692+ return a;
 693+ }
 694+ return $(el).val();
 695+};
 696+
 697+/**
 698+ * Clears the form data. Takes the following actions on the form's input fields:
 699+ * - input text fields will have their 'value' property set to the empty string
 700+ * - select elements will have their 'selectedIndex' property set to -1
 701+ * - checkbox and radio inputs will have their 'checked' property set to false
 702+ * - inputs of type submit, button, reset, and hidden will *not* be effected
 703+ * - button elements will *not* be effected
 704+ */
 705+$.fn.clearForm = function() {
 706+ return this.each(function() {
 707+ $('input,select,textarea', this).clearFields();
 708+ });
 709+};
 710+
 711+/**
 712+ * Clears the selected form elements.
 713+ */
 714+$.fn.clearFields = $.fn.clearInputs = function() {
 715+ return this.each(function() {
 716+ var t = this.type, tag = this.tagName.toLowerCase();
 717+ if (t == 'text' || t == 'password' || tag == 'textarea') {
 718+ this.value = '';
 719+ }
 720+ else if (t == 'checkbox' || t == 'radio') {
 721+ this.checked = false;
 722+ }
 723+ else if (tag == 'select') {
 724+ this.selectedIndex = -1;
 725+ }
 726+ });
 727+};
 728+
 729+/**
 730+ * Resets the form data. Causes all form elements to be reset to their original value.
 731+ */
 732+$.fn.resetForm = function() {
 733+ return this.each(function() {
 734+ // guard against an input with the name of 'reset'
 735+ // note that IE reports the reset function as an 'object'
 736+ if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) {
 737+ this.reset();
 738+ }
 739+ });
 740+};
 741+
 742+/**
 743+ * Enables or disables any matching elements.
 744+ */
 745+$.fn.enable = function(b) {
 746+ if (b === undefined) {
 747+ b = true;
 748+ }
 749+ return this.each(function() {
 750+ this.disabled = !b;
 751+ });
 752+};
 753+
 754+/**
 755+ * Checks/unchecks any matching checkboxes or radio buttons and
 756+ * selects/deselects and matching option elements.
 757+ */
 758+$.fn.selected = function(select) {
 759+ if (select === undefined) {
 760+ select = true;
 761+ }
 762+ return this.each(function() {
 763+ var t = this.type;
 764+ if (t == 'checkbox' || t == 'radio') {
 765+ this.checked = select;
 766+ }
 767+ else if (this.tagName.toLowerCase() == 'option') {
 768+ var $sel = $(this).parent('select');
 769+ if (select && $sel[0] && $sel[0].type == 'select-one') {
 770+ // deselect all other options
 771+ $sel.find('option').selected(false);
 772+ }
 773+ this.selected = select;
 774+ }
 775+ });
 776+};
 777+
 778+// helper fn for console logging
 779+// set $.fn.ajaxSubmit.debug to true to enable debug logging
 780+function log() {
 781+ if ($.fn.ajaxSubmit.debug) {
 782+ var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
 783+ if (window.console && window.console.log) {
 784+ window.console.log(msg);
 785+ }
 786+ else if (window.opera && window.opera.postError) {
 787+ window.opera.postError(msg);
 788+ }
 789+ }
 790+};
 791+
 792+})(jQuery);
Index: trunk/phase3/resources/Resources.php
@@ -63,6 +63,9 @@
6464 'jquery.expandableField' => array(
6565 'scripts' => 'resources/jquery/jquery.expandableField.js',
6666 ),
 67+ 'jquery.form' => array(
 68+ 'scripts' => 'resources/jquery/jquery.form.js',
 69+ ),
6770 'jquery.highlightText' => array(
6871 'scripts' => 'resources/jquery/jquery.highlightText.js',
6972 ),

Follow-up revisions

RevisionCommit summaryAuthorDate
r80506svn:eol-style=nativewerdna18:31, 18 January 2011

Comments

#Comment by Reedy (talk | contribs)   18:26, 18 January 2011

svn:eol-style native? :P

#Comment by Krinkle (talk | contribs)   07:43, 26 May 2011

Was this fixed ?

#Comment by Krinkle (talk | contribs)   07:44, 26 May 2011

Yep, in r80506. I've associated the follow-up now.

Status & tagging log