aboutsummaryrefslogtreecommitdiffstats
path: root/data/lib/form-serialize.js
diff options
context:
space:
mode:
authorMatěj Cepl <mcepl@redhat.com>2011-09-08 14:09:13 +0200
committerMatěj Cepl <mcepl@redhat.com>2011-10-30 11:19:19 +0100
commitaf97090e70bec513cd381e38a4e23aaa68935cda (patch)
tree3a9d3e9008200c19f1eafc9d00fb7456281c0a88 /data/lib/form-serialize.js
parent8da686bda435ab9ec996cc04a396609c44a1c451 (diff)
downloadbugzilla-triage-af97090e70bec513cd381e38a4e23aaa68935cda.tar.gz
Origins of yet another form serialization library.
Diffstat (limited to 'data/lib/form-serialize.js')
-rw-r--r--data/lib/form-serialize.js145
1 files changed, 145 insertions, 0 deletions
diff --git a/data/lib/form-serialize.js b/data/lib/form-serialize.js
new file mode 100644
index 0000000..0a46a56
--- /dev/null
+++ b/data/lib/form-serialize.js
@@ -0,0 +1,145 @@
+/**
+ interface HTMLFormElement {
+ string getDataSetString(); raises FileException
+ string toJSONString(); raises FileException
+};
+ */
+
+/*
+
+Step three: Encode the form data set
+ The form data set is then encoded according to the content type
+ specified by the enctype attribute of the FORM element.
+Step four: Submit the encoded form data set
+ Finally, the encoded data is sent to the processing agent
+ designated by the action attribute using the protocol specified
+ by the method attribute.
+
+This specification does not specify all valid submission methods
+or content types that may be used with forms. However, HTML 4
+user agents must support the established conventions in the
+following cases:
+
+ - If the method is "get" and the action is an HTTP URI, the user
+ agent takes the value of action, appends a `?' to it, then
+ appends the form data set, encoded using the
+ "application/x-www-form-urlencoded" content type. The user
+ agent then traverses the link to this URI. In this scenario,
+ form data are restricted to ASCII codes.
+ - If the method is "post" and the action is an HTTP URI, the
+ user agent conducts an HTTP "post" transaction using the value
+ of the action attribute and a message created according to the
+ content type specified by the enctype attribute.
+ - For any other value of action or method, behavior is unspecified.
+ */
+
+// Yes, I read http://perfectionkills.com/whats-wrong-with-extending-the-dom/
+// FIXME the original interface had "raises FileException" ... why and where?
+if (!HTMLFormElement.prototype.getDataSetString) {
+ function () {
+ // Static variables
+ var gotSubmit = false;
+ /**
+ * Generate string with application/x-www-form-urlencoded type value
+ *
+ * LIMITATIONS: no HTML5 input elements
+ */
+ //# Processing form data algorithm (authoritative, HTML 4.01, 17.13.3):
+ // FIXME Check
+ // https://groups.google.com/forum/#!topic/comp.lang.javascript/PkoAEvKoI1o
+ // https://developer.mozilla.org/en/DOM/HTMLFormElement
+ // https://developer.mozilla.org/en/HTML/Element/input#attr-type
+ // FIXME also process form.enctype and form.method
+ HTMLFormElement.prototype.getDataSetString = function getDataSetString() {
+
+ //# Step one: Identify the successful controls
+ var succesfulControls = Array.filter(this.elements, function (element) {
+ //# Controls that are disabled cannot be successful.
+ if (element.disabled) {
+ return false;
+ }
+
+ // Possible element types
+ // text|password|checkbox|radio|submit|reset|file|hidden|image|button
+ var elementType = element.type.toLowerCase().trim();
+
+ //# A successful control must be defined within a FORM
+ //# element and must have a control name.
+ if (!element.name) {
+ return false;
+ }
+
+ //# If a form contains more than one submit button, only the
+ //# activated submit button is successful.
+ if ((elementType == "submit") || (elementType == "image")) {
+ if (gotSubmit) {
+ return false;
+ }
+ else {
+ gotSubmit = true;
+ return true;
+ }
+ }
+
+ //# 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.
+ if ((["checkbox", "radio"].indexOf(elementType) != -1) &&
+ element.checked) {
+ return true;
+ }
+
+ /*
+ 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) { return 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 selectList = ["select-one", "select-multiple", "select"];
+ if (selectList.indexOf(elementType) != -1) {
+ return true;
+ }
+
+ if (!((element.tagName.toLowerCase().trim() == "object") &&
+ (element.declare))) { // FIXME .declare attribute is obsolete in HTML5
+ return true;
+ }
+
+ //# The current value of a file select is a list of one or
+ //# more file names. Upon submission of the form, the contents of
+ //# each file are submitted with the rest of the form data. The
+ //# file contents are packaged according to the form's content
+ //# type.
+ if (["file", "reset"].indexOf(elementType) != -1) {
+ }
+
+ // FIXME Probably not applicable ... bugzilla form doesn't have any
+ // file selects.
+
+ //# The current value of an object control is determined by
+ //# the object's implementation.
+ });
+
+ // Step two: Build a form data set
+ // A form data set is a sequence of control-name/current-value
+ // pairs constructed from successful controls
+ var formDataSet = "";
+ succesfulControls.forEach(function (control) {
+ // FIXME algorithm is more complicated because e.g., for menus
+ // name is SELECT and value OPTION.
+ // Alternative: previous command should be actually .map() instead
+ // of filter.
+ formDataSet += "&" + control.name + "=" + control.value;
+ });
+ // FIXME odřízni první "&", které tam nepatří
+
+ };
+ }();
+} // end of if-not-defined