aboutsummaryrefslogtreecommitdiffstats
path: root/offline-submit/form-serialization.js
diff options
context:
space:
mode:
Diffstat (limited to 'offline-submit/form-serialization.js')
-rw-r--r--offline-submit/form-serialization.js129
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..