diff options
author | Matěj Cepl <mcepl@redhat.com> | 2010-01-13 00:21:23 +0100 |
---|---|---|
committer | Matěj Cepl <mcepl@redhat.com> | 2010-01-13 00:21:23 +0100 |
commit | 875a60dba09cf984e84c1531254d2c11dc0fe1ac (patch) | |
tree | 896532df41e88e1cff974aab0afcce58ac14250d /offline-submit/form-serialization.js | |
parent | dc94b62a881ca46f46a39d8f6af2cd4659861be6 (diff) | |
download | bugzilla-triage-875a60dba09cf984e84c1531254d2c11dc0fe1ac.tar.gz |
New version of form-serialization code
Diffstat (limited to 'offline-submit/form-serialization.js')
-rw-r--r-- | offline-submit/form-serialization.js | 144 |
1 files changed, 118 insertions, 26 deletions
diff --git a/offline-submit/form-serialization.js b/offline-submit/form-serialization.js index 70c9ae0..d7c4d07 100644 --- a/offline-submit/form-serialization.js +++ b/offline-submit/form-serialization.js @@ -1,37 +1,129 @@ +/* ------------------------------------------------------------------ */ + /** - * (C) Thomas 'PointedEars' Lahn, 2009, released under GPLv3 - * - * Retrieves the data to send in the request, and optionally the request - * method, from an (X)HTML form. TODO: select[multiple] elements - * - * @param f : HTMLFormElement - * @param bUseFormMethod: optional boolean - * If <code>true</code>, the form's request method becomes the - * <code>HTTPRequest</code> object's request method. The default - * is <code>false</code>. - * @return boolean + * @param f : Form|HTMLFormElement + * @return string */ -getDataFromForm = function(f, bUseFormMethod) { - var result = false, es, len; +function serializeForm(f) +{ + var gotSubmit = false; - if (f && (es = f.elements) && (len = es.length)) + /** + * @param o + */ + function serializeControl(o) { - if (bUseFormMethod) this.method = f.method; - - var aData = []; - - for (var i = 0; i < len; i++) + /* HTML 4.01: Controls that are disabled cannot be successful. */ + if (!o.disabled) { - var o = es[i]; - if (o.name) + /* + * If a form contains more than one submit button, + * only the activated submit button is successful. + * (here: the first one) + */ + var isSubmit = /(^|\s)(submit|image)(\s|$)/i.test(o.type); + if (!gotSubmit || !isSubmit) { - aData.push(esc(o.name) + "=" + esc(o.value != "" ? o.value : "")); + if (isSubmit) gotSubmit = true; + + /* + * For menus, the control name is provided by a SELECT element + * and values are provided by OPTION elements. Only selected + * options may be successful. When no options are selected, + * the control is not successful and neither the name nor any + * values are submitted to the server when the form is submitted. + */ + var m = /(^|\s)(select(-one)?|undefined)(\s|$)/i.exec(o.type); + if (m) + { + /* select-one */ + if (m[3]) + { + if (o.selectedIndex > -1) + { + items.add(o.name, o.options[o.selectedIndex].value); + } + } + + /* select */ + else if (m[2]) + { + for (var i = 0, opts = o.options, len = opts && opts.length; + i < len; i++) + { + var opt = opts[i]; + if (opt.selected) + { + items.add(o.name, opt.value); + } + } + } + } + + /* + * All "on" checkboxes may be successful. + * For radio buttons that share the same value of the + * name attribute, only the "on" radio button may be successful. + */ + else if (!/(^|\s)file|reset(\s|$)/i.test(o.type) + && !(/(^|\s)object(\s|$)/i.test(o.tagName) && o.declare) + && !/(^|\s)(checkbox|radio)(\s|$)/i.test(o.type) + || o.checked) + { + items.add(o.name, o.value); + } } } + } - this.data = aData.join("&"); - result = true; + var es = getFeature(f, "elements"); + if (es) + { + var items = []; + + items.add = function(sName, sValue) { + var s = esc(sName) + "=" + esc(sValue); + this.push(s); + }; + + if (!isMethod(items, "push")) + { + items.push = function() { + for (var i = 0, len = arguments.length; i < len; i++) + { + items[items.length] = arguments[i]; + } + }; + } + + for (var i = 0, len = es.length; i < len; i++) + { + var e = es[i]; + + /* + * Elements with the same name create a NodeList object, + * however options of select objects are also indexable in Gecko. + */ + if (typeof e[0] != "undefined" && typeof e.options == "undefined") + { + for (var j = 0, len2 = e.length; j < len2; j++) + { + serializeControl(e[j]); + } + } + else + { + serializeControl(e); + } + } + + return items.join("&"); } + + return ""; +} + +/* ------------------------------------------------------------------ */ - return result; -}; +// esc(), getFeature() and isMethod() are user-defined, of course, but you +// probably get the idea.. |