aboutsummaryrefslogtreecommitdiffstats
path: root/data/lib/form-serialize.js
blob: 52f157263c202f2a0c3dd833453b10d5006060f5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// PROBABLY COMPLETELY USELESS FOR THERE IS NOW
// https://developer.mozilla.org/en/DOM/XMLHttpRequest/FormData
// STORING IT HERE JUST TO BE SURE AND BEFORE FURTHER INVESTIGATION.

/**
 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