diff options
Diffstat (limited to 'offline-submit/form-serialization.js')
-rw-r--r-- | offline-submit/form-serialization.js | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/offline-submit/form-serialization.js b/offline-submit/form-serialization.js new file mode 100644 index 0000000..d7c4d07 --- /dev/null +++ b/offline-submit/form-serialization.js @@ -0,0 +1,129 @@ +/* ------------------------------------------------------------------ */ + +/** + * @param f : Form|HTMLFormElement + * @return string + */ +function serializeForm(f) +{ + var gotSubmit = false; + + /** + * @param o + */ + function serializeControl(o) + { + /* HTML 4.01: Controls that are disabled cannot be successful. */ + if (!o.disabled) + { + /* + * 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) + { + 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); + } + } + } + } + + 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 ""; +} + +/* ------------------------------------------------------------------ */ + +// esc(), getFeature() and isMethod() are user-defined, of course, but you +// probably get the idea.. |