html form management library
Revisión | c65a0f3d65419a1aa2933f23ab37670c5b55ed31 (tree) |
---|---|
Tiempo | 2018-05-21 10:27:17 |
Autor | frostbane <frostbane@prog...> |
Commiter | frostbane |
Merge with release/0.0.1
@@ -52,9 +52,9 @@ | ||
52 | 52 | }, |
53 | 53 | |
54 | 54 | jsDocConfig = { |
55 | - sable :{ | |
55 | + sable :{ | |
56 | 56 | src :[ |
57 | - './src/microcheck.js', | |
57 | + './src/microform.js', | |
58 | 58 | //'./README.md', |
59 | 59 | ], |
60 | 60 | options :{ |
@@ -68,16 +68,19 @@ | ||
68 | 68 | uglifyConfig = { |
69 | 69 | release :{ |
70 | 70 | options :{ |
71 | - preserveComments :function(node, comment){ | |
72 | - // preserve comments that start with a bang | |
73 | - return /^!/.test(comment.value); | |
71 | + output :{ | |
72 | + comments :function(node, comment){ | |
73 | + // preserve comments that start with a bang | |
74 | + return /^!/.test(comment.value); | |
75 | + }, | |
76 | + | |
74 | 77 | }, |
75 | - mangle :true, | |
76 | - compress :true, | |
78 | + mangle :true, | |
79 | + compress :true, | |
77 | 80 | }, |
78 | 81 | |
79 | 82 | files :{ |
80 | - './bin/microform/microform.js' :[ | |
83 | + './bin/microform/microformelements.js' :[ | |
81 | 84 | './src/microform.js', |
82 | 85 | ], |
83 | 86 | }, |
@@ -138,19 +141,19 @@ | ||
138 | 141 | /* */// ------------------------------------------------ // |
139 | 142 | |
140 | 143 | [ |
141 | - { | |
142 | - target :"test", | |
143 | - commands :[ | |
144 | - "jxunit:test", | |
145 | - ], | |
146 | - }, | |
147 | - { | |
148 | - summary :"test the minified source", | |
149 | - target :"test_min", | |
150 | - commands :[ | |
151 | - "jxunit:test_min", | |
152 | - ], | |
153 | - }, | |
144 | + // { | |
145 | + // target :"test", | |
146 | + // commands :[ | |
147 | + // "jxunit:test", | |
148 | + // ], | |
149 | + // }, | |
150 | + // { | |
151 | + // summary :"test the minified source", | |
152 | + // target :"test_min", | |
153 | + // commands :[ | |
154 | + // "jxunit:test_min", | |
155 | + // ], | |
156 | + // }, | |
154 | 157 | { |
155 | 158 | summary :"prepare the src dir for publish", |
156 | 159 | target :"release", |
@@ -158,7 +161,7 @@ | ||
158 | 161 | "uglify:release", |
159 | 162 | "copy:release", |
160 | 163 | "jsdoc:sable", |
161 | - "jxunit:test_min", | |
164 | + // "jxunit:test_min", | |
162 | 165 | ], |
163 | 166 | }, |
164 | 167 | { |
@@ -64,7 +64,7 @@ | ||
64 | 64 | This product includes software developed by `Frostbane Ac`. |
65 | 65 | ``` |
66 | 66 | |
67 | -4. Neither the name of micro-form nor the names of its | |
67 | +4. Neither the name of micro-formelements nor the names of its | |
68 | 68 | contributors may be used to endorse or promote products derived from |
69 | 69 | this software without specific prior written permission. |
70 | 70 |
@@ -3,32 +3,32 @@ | ||
3 | 3 | |
4 | 4 | ## private ## |
5 | 5 | |
6 | -_String_ **MicroForm.__getJSON(**_Object_ data**)** | |
6 | +_String_ **MicroForm.__getJSON(** _Object_ data **)** | |
7 | 7 | |
8 | 8 | > get the `JSON` of the specified form's element-value pair |
9 | 9 | |
10 | -_String_ **MicroForm.__sha512(**_String_ data**)** | |
10 | +_String_ **MicroForm.__sha512(** _String_ data **)** | |
11 | 11 | |
12 | 12 | > solve for the sha512 sum of the data string |
13 | 13 | |
14 | -_null_ **MicroForm.__saveHash(**_String_ formName, _String_ hash**)** | |
14 | +_null_ **MicroForm.__saveHash(** _String_ formName, _String_ hash **)** | |
15 | 15 | |
16 | 16 | > save the hash |
17 | 17 | |
18 | 18 | |
19 | 19 | ## public ## |
20 | 20 | |
21 | -_null_ **MicroForm.init(**_null_**)** | |
21 | +_null_ **MicroForm.init(** _null_ **)** | |
22 | 22 | |
23 | 23 | > calculate and save the hash of all forms that have no hash |
24 | 24 | |
25 | -_null_ **MicroForm.init(**_String_ formName**)** | |
25 | +_null_ **MicroForm.init(** _String_ formName **)** | |
26 | 26 | |
27 | 27 | > calculate and save the hash of the specified formName if it has no hash |
28 | 28 | > |
29 | 29 | > use `MicroForm.hash()` to replace the saved hash |
30 | 30 | |
31 | -_[]_ **MicroForm.get(**_null_**)** | |
31 | +_[]_ **MicroForm.get(** _null_ **)** | |
32 | 32 | |
33 | 33 | > get all available form names |
34 | 34 |
@@ -36,7 +36,7 @@ | ||
36 | 36 | [form1name, form2name, ..., formNname] |
37 | 37 | ``` |
38 | 38 | |
39 | -_{}_ **MicroForm.get(**_String_ formName**)** | |
39 | +_{}_ **MicroForm.get(** _String_ formName **)** | |
40 | 40 | |
41 | 41 | > get element-value pair `object` of the specified form |
42 | 42 | > |
@@ -44,12 +44,12 @@ | ||
44 | 44 | |
45 | 45 | ``` |
46 | 46 | { |
47 | - formName : { | |
48 | - element1name: element1value, | |
49 | - element2name: element2value, | |
50 | - ..., | |
51 | - elementNname: elementNvalue, | |
52 | - } | |
47 | + formName : { | |
48 | + element1name: element1value, | |
49 | + element2name: element2value, | |
50 | + ..., | |
51 | + elementNname: elementNvalue, | |
52 | + } | |
53 | 53 | } |
54 | 54 | ``` |
55 | 55 |
@@ -57,7 +57,7 @@ | ||
57 | 57 | undefined |
58 | 58 | ``` |
59 | 59 | |
60 | -_[]_ **MicroForm.get(**_String[]_ formName**)** | |
60 | +_[]_ **MicroForm.get(** _String[]_ formName **)** | |
61 | 61 | |
62 | 62 | > get element-value pair `object` of the specified form |
63 | 63 | > |
@@ -65,26 +65,26 @@ | ||
65 | 65 | |
66 | 66 | ``` |
67 | 67 | [ |
68 | - { | |
69 | - form1Name : { | |
70 | - element1name: element1value, | |
71 | - element2name: element2value, | |
72 | - ..., | |
73 | - elementNname: elementNvalue, | |
74 | - }, | |
75 | - { | |
76 | - form2Name : { | |
77 | - element1name: element1value, | |
78 | - element2name: element2value, | |
79 | - ..., | |
80 | - elementNname: elementNvalue, | |
81 | - } | |
82 | - }, | |
83 | - undefined, | |
68 | + { | |
69 | + form1Name : { | |
70 | + element1name: element1value, | |
71 | + element2name: element2value, | |
72 | + ..., | |
73 | + elementNname: elementNvalue, | |
74 | + }, | |
75 | + { | |
76 | + form2Name : { | |
77 | + element1name: element1value, | |
78 | + element2name: element2value, | |
79 | + ..., | |
80 | + elementNname: elementNvalue, | |
81 | + } | |
82 | + }, | |
83 | + undefined, | |
84 | 84 | ] |
85 | 85 | ``` |
86 | 86 | |
87 | -_null_ **MicroForm.setForm(**_String_ formName, _Object_ elementValueMap**)** | |
87 | +_null_ **MicroForm.setForm(** _String_ formName, _Object_ elementValueMap **)** | |
88 | 88 | |
89 | 89 | > set the value of the specified form's elements |
90 | 90 | > |
@@ -97,7 +97,7 @@ | ||
97 | 97 | {element1name: element1value,}); |
98 | 98 | ``` |
99 | 99 | |
100 | -_null_ **MicroForm.set(**_Object_ form**)** | |
100 | +_null_ **MicroForm.set(** _Object_ form **)** | |
101 | 101 | |
102 | 102 | > set the value of the specified form's elements |
103 | 103 | > |
@@ -111,13 +111,17 @@ | ||
111 | 111 | }); |
112 | 112 | ``` |
113 | 113 | |
114 | -_null_ **MicroForm.hash(**_String_ formName**)** | |
114 | +_null_ **MicroForm.hash(** _String_ formName **)** | |
115 | 115 | |
116 | 116 | > calculate and save the specified form's hash |
117 | 117 | |
118 | -_bool_ **MicroForm.hasChanged(**_String_ formName**)** | |
118 | +_bool_ **MicroForm.hasChanged( **_String_ formName **)** | |
119 | 119 | |
120 | 120 | > calculate the specified form's hash and compare it with the saved hash |
121 | 121 | > |
122 | 122 | > returns `true` if there is no saved hash or the saved hash is not the same with the calculated hash |
123 | 123 | |
124 | +_[]_ **MicroForm.validate(** _String_ formName **)** | |
125 | + | |
126 | +> check if the form is valid, has duplicate names, etc. | |
127 | + |
@@ -6,7 +6,7 @@ | ||
6 | 6 | "default" : { |
7 | 7 | "outputSourceFiles": true |
8 | 8 | }, |
9 | - "applicationName": "micro-form", | |
9 | + "applicationName": "micro-formelements", | |
10 | 10 | "disqus" : "", |
11 | 11 | "googleAnalytics": "", |
12 | 12 | "openGraph" : { |
@@ -1,17 +1,20 @@ | ||
1 | 1 | { |
2 | - "name" : "micro-form", | |
2 | + "name" : "micro-formelements", | |
3 | 3 | "version" : "v0.0.1", |
4 | - "description" : "Form processing library", | |
4 | + "description" : "Form element data processing library", | |
5 | 5 | "repository" : { |
6 | 6 | "type": "hg", |
7 | - "url" : "https://bitbucket.org/frostbane/micro-form" | |
7 | + "url" : "https://bitbucket.org/frostbane/micro-formelement" | |
8 | 8 | }, |
9 | - "main" : "./microform.js", | |
9 | + "main" : "./microformelements.js", | |
10 | 10 | "license" : "SEE LICENSE IN LICENSE.md", |
11 | 11 | "keywords" : [ |
12 | 12 | "micro-form", |
13 | + "micro-formelements", | |
13 | 14 | "form-micro", |
14 | - "form", | |
15 | + "formelements-micro", | |
16 | + "form elements", | |
17 | + "form" | |
15 | 18 | ], |
16 | 19 | "devDependencies": { |
17 | 20 | "requirejs" : "2.3.5", |
@@ -1,128 +1,947 @@ | ||
1 | -/*! | |
2 | - .. ┌ -: . | |
3 | - ([]▄▄├]▄▄▄¿┐`, | |
4 | - .¡ ,. D{}▓███████████░█∩^} = | |
5 | - ,▓¼ .▐▓▓█████████████▓██▓▓, (▓ | |
6 | - █▌╕. ─@╣████████████████████▄─ ./▀' | |
7 | - :▓█▌Ç... └ '└▓██████████████████████Ö'` .. '└`'┌ | |
8 | - \ g█████▄Ü┌ C g██████████████████████████╗─ ² ² t▄▓██ù- `╞ | |
9 | - ¡ Å╠█▌╠█▓▓▓▓▌N@▌| ╓██████████████████████████▌ .╣▓▓▓▓▓▓▓]▐╙ÅÅ∩! | |
10 | - ` ` ╫½┌▀▀▀▀▀▀░╫▌┘ ▀▀▀▀▀██████████████████▀█▀C :╝▀▀▀▀▀▀▀. `: | |
11 | - L ─ⁿ'``' ─ ''' ─█████████████████▌─█= ╞º'`'º── | |
12 | - ..Å╫█╛. ~ | |
13 | - ╔▄▄▓██▓▄¿ . | |
14 | - - ]:├╣██▀▀▀▀▀▒Q¿.¿{ )= | |
15 | - <─Ω╚█░▓███'──h⌂▓██╡██▌Ü─4 | |
16 | - `┌ ▐▓█▄▓██╟≤¡yQ▄███▓█▌▐▓M | |
17 | - ^. └▀▀▄▓██▄▒▄▄╬▄████▀ └▀╙` | |
18 | - «-'''█▓▓█▓██▓██▓▓██└``'⌐ | |
19 | - #╛ µ:▓▄;xφ(⌠ █ | |
20 | - ╗µ ~╙'` `┌█╣ | |
21 | - ╝Ñ. '' ' L▀▀ | |
22 | - ~ , | |
23 | - ^ | |
24 | - ÷ ─. | |
25 | - N. ∩ts ) | |
26 | - ∩ ²⌠ ` ─ | |
27 | - (@ ~▒▒ . | |
28 | - ` └▀/ .>▀▀ : | |
29 | - ⌐ ,⌐ | |
30 | - | |
31 | - | |
32 | - Form processing library | |
33 | - Version 0.0.1 | |
34 | - Copyright (c) 2018 Frostbane Ac | |
35 | - See LICENSE.md. | |
36 | - www.??.com | |
37 | - | |
38 | - | |
39 | - */ | |
40 | - | |
41 | -/* | |
42 | - * 2018.05.17 | |
43 | - * frostbane | |
44 | - * | |
45 | - * | |
46 | - * | |
47 | - */ | |
48 | - | |
49 | -// todo fix globals | |
50 | -/* global | |
51 | -isInt, | |
52 | -isFloat, | |
53 | -format, | |
54 | -getDecimalCount, | |
55 | -trim, | |
56 | -define | |
57 | - */ | |
58 | - | |
59 | -/* jshint | |
60 | -bitwise: false, | |
61 | -maxlen: 180 | |
62 | - */ | |
63 | - | |
64 | -(function(global, factory){ | |
65 | - "use strict"; | |
66 | - | |
67 | - if(typeof define === typeof function(){} && define.amd !== undefined){ | |
68 | - define(function(){ | |
69 | - return factory; | |
70 | - }); | |
71 | - }else if(typeof exports !== typeof undefined && global.exports !== exports){ | |
72 | - module.exports = factory; | |
73 | - }else{ | |
74 | - global.MicroForm = factory; | |
75 | - } | |
76 | - | |
77 | -}(this, (function(){ | |
78 | - "use strict"; | |
79 | - | |
80 | - var __getJSON = function(data){ | |
81 | - }; | |
82 | - | |
83 | - var __sha512sum = function(data){ | |
84 | - }; | |
85 | - | |
86 | - var __saveHash = function(formName, hash){ | |
87 | - } | |
88 | - | |
89 | - var __init = function(formName){ | |
90 | - if(formName === undefined || formName === null || formName.trim() === ""){ | |
91 | - }else{ | |
92 | - } | |
93 | - } | |
94 | - | |
95 | - var __get = function(formName){ | |
96 | - if(formName === undefined || formName === null || formName.trim() === ""){ | |
97 | - }else{ | |
98 | - } | |
99 | - | |
100 | - if(typeof formName === typeof ""){ | |
101 | - } | |
102 | - | |
103 | - if(formName instanceof []){ | |
104 | - } | |
105 | - } | |
106 | - | |
107 | - var __set = function(formName, data){ | |
108 | - if(typeof formName == typeof ""){ | |
109 | - } | |
110 | - else{ | |
111 | - } | |
112 | - } | |
113 | - | |
114 | - var __hash = function(formName){ | |
115 | - } | |
116 | - | |
117 | - var __hasChanged = function(formName){ | |
118 | - } | |
119 | - | |
120 | - return { | |
121 | - init :__init, | |
122 | - get :__get, | |
123 | - set :__set, | |
124 | - hash :__hash, | |
125 | - hasChanged :__hasChanged, | |
126 | - }; | |
127 | - | |
128 | -}()))); | |
1 | +/*! | |
2 | + .. ┌ -: . | |
3 | + ([]▄▄├]▄▄▄¿┐`, | |
4 | + .¡ ,. D{}▓███████████░█∩^} = | |
5 | + ,▓¼ .▐▓▓█████████████▓██▓▓, (▓ | |
6 | + █▌╕. ─@╣████████████████████▄─ ./▀' | |
7 | + :▓█▌Ç... └ '└▓██████████████████████Ö'` .. '└`'┌ | |
8 | + \ g█████▄Ü┌ C g██████████████████████████╗─ ² ² t▄▓██ù- `╞ | |
9 | + ¡ Å╠█▌╠█▓▓▓▓▌N@▌| ╓██████████████████████████▌ .╣▓▓▓▓▓▓▓]▐╙ÅÅ∩! | |
10 | + ` ` ╫½┌▀▀▀▀▀▀░╫▌┘ ▀▀▀▀▀██████████████████▀█▀C :╝▀▀▀▀▀▀▀. `: | |
11 | + L ─ⁿ'``' ─ ''' ─█████████████████▌─█= ╞º'`'º── | |
12 | + ..Å╫█╛. ~ | |
13 | + ╔▄▄▓██▓▄¿ . | |
14 | + - ]:├╣██▀▀▀▀▀▒Q¿.¿{ )= | |
15 | + <─Ω╚█░▓███'──h⌂▓██╡██▌Ü─4 | |
16 | + `┌ ▐▓█▄▓██╟≤¡yQ▄███▓█▌▐▓M | |
17 | + ^. └▀▀▄▓██▄▒▄▄╬▄████▀ └▀╙` | |
18 | + «-'''█▓▓█▓██▓██▓▓██└``'⌐ | |
19 | + #╛ µ:▓▄;xφ(⌠ █ | |
20 | + ╗µ ~╙'` `┌█╣ | |
21 | + ╝Ñ. '' ' L▀▀ | |
22 | + ~ , | |
23 | + ^ | |
24 | + ÷ ─. | |
25 | + N. ∩ts ) | |
26 | + ∩ ²⌠ ` ─ | |
27 | + (@ ~▒▒ . | |
28 | + ` └▀/ .>▀▀ : | |
29 | + ⌐ ,⌐ | |
30 | + | |
31 | + | |
32 | + Form element data processing library | |
33 | + Version 0.0.1 | |
34 | + Copyright (c) 2018 Frostbane Ac | |
35 | + See LICENSE.md. | |
36 | + www.??.com | |
37 | + | |
38 | + | |
39 | + */ | |
40 | + | |
41 | +/* | |
42 | + * 2018.05.17 | |
43 | + * frostbane | |
44 | + * | |
45 | + * | |
46 | + * | |
47 | + */ | |
48 | + | |
49 | +/* global | |
50 | +isInt, | |
51 | +isFloat, | |
52 | +format, | |
53 | +getDecimalCount, | |
54 | +trim, | |
55 | +define | |
56 | + */ | |
57 | + | |
58 | +/* jshint | |
59 | +bitwise: false, | |
60 | +maxparams: 6, | |
61 | +maxlen: 180 | |
62 | + */ | |
63 | + | |
64 | +(function(global, factory){ | |
65 | + "use strict"; | |
66 | + | |
67 | + if(typeof define === typeof function(){} && define.amd !== undefined){ | |
68 | + define(function(){ | |
69 | + return factory; | |
70 | + }); | |
71 | + }else if(typeof exports !== typeof undefined && global.exports !== exports){ | |
72 | + module.exports = factory; | |
73 | + }else{ | |
74 | + global.MicroFormElements = factory; | |
75 | + } | |
76 | + | |
77 | +}(this, (function(){ | |
78 | + "use strict"; | |
79 | + | |
80 | + /** | |
81 | + * convert `data` to `JSON` string | |
82 | + * | |
83 | + * @param {Object} data | |
84 | + * @returns {String} JSON | |
85 | + * @private | |
86 | + */ | |
87 | + var __getJSON = function(data){ | |
88 | + return JSON.stringify(data); | |
89 | + }; | |
90 | + | |
91 | + /** | |
92 | + * @summary | |
93 | + * Solve for the sha512 sum of the specified `data` string | |
94 | + * | |
95 | + * @description | |
96 | + * A JavaScript implementation of the Secure Hash Algorithm, SHA-512, as defined | |
97 | + * in FIPS 180-2 | |
98 | + * Version 2.2 Copyright Anonymous Contributor, Paul Johnston 2000 - 2009. | |
99 | + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet | |
100 | + * Distributed under the BSD License | |
101 | + * See http://pajhome.org.uk/crypt/md5 for details. | |
102 | + * | |
103 | + * @param {String} data | |
104 | + * @returns {String} hash | |
105 | + * | |
106 | + * @private | |
107 | + */ | |
108 | + var __sha512sum = function(data){ | |
109 | + /* | |
110 | + * Configurable variables. You may need to tweak these to be compatible with | |
111 | + * the server-side, but the defaults work in most cases. | |
112 | + */ | |
113 | + var hexcase = 0; | |
114 | + /* hex output format. 0 - lowercase; 1 - uppercase */ | |
115 | + var b64pad = ""; | |
116 | + /* base-64 pad character. "=" for strict RFC compliance */ | |
117 | + | |
118 | + /* | |
119 | + * These are the functions you'll usually want to call | |
120 | + * They take string arguments and return either hex or base-64 encoded strings | |
121 | + */ | |
122 | + function hex_sha512(s){ return rstr2hex(rstr_sha512(str2rstr_utf8(s))); } | |
123 | + | |
124 | + function b64_sha512(s){ return rstr2b64(rstr_sha512(str2rstr_utf8(s))); } | |
125 | + | |
126 | + function any_sha512(s, e){ return rstr2any(rstr_sha512(str2rstr_utf8(s)), e);} | |
127 | + | |
128 | + function hex_hmac_sha512(k, d){ return rstr2hex(rstr_hmac_sha512(str2rstr_utf8(k), str2rstr_utf8(d))); } | |
129 | + | |
130 | + function b64_hmac_sha512(k, d){ return rstr2b64(rstr_hmac_sha512(str2rstr_utf8(k), str2rstr_utf8(d))); } | |
131 | + | |
132 | + function any_hmac_sha512(k, d, e){ return rstr2any(rstr_hmac_sha512(str2rstr_utf8(k), str2rstr_utf8(d)), e);} | |
133 | + | |
134 | + /* | |
135 | + * Perform a simple self-test to see if the VM is working | |
136 | + */ | |
137 | + function sha512_vm_test(){ | |
138 | + return hex_sha512("abc").toLowerCase() === | |
139 | + "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" + | |
140 | + "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"; | |
141 | + } | |
142 | + | |
143 | + /* | |
144 | + * Calculate the SHA-512 of a raw string | |
145 | + */ | |
146 | + function rstr_sha512(s){ | |
147 | + return binb2rstr(binb_sha512(rstr2binb(s), s.length * 8)); | |
148 | + } | |
149 | + | |
150 | + /* | |
151 | + * Calculate the HMAC-SHA-512 of a key and some data (raw strings) | |
152 | + */ | |
153 | + function rstr_hmac_sha512(key, data){ | |
154 | + var bkey = rstr2binb(key); | |
155 | + if(bkey.length > 32) bkey = binb_sha512(bkey, key.length * 8); | |
156 | + | |
157 | + var ipad = new Array(32), | |
158 | + opad = new Array(32); | |
159 | + | |
160 | + for(var i = 0; i < 32; i++){ | |
161 | + ipad[i] = bkey[i] ^ 0x36363636; | |
162 | + opad[i] = bkey[i] ^ 0x5C5C5C5C; | |
163 | + } | |
164 | + | |
165 | + var hash = binb_sha512(ipad.concat(rstr2binb(data)), 1024 + data.length * 8); | |
166 | + return binb2rstr(binb_sha512(opad.concat(hash), 1024 + 512)); | |
167 | + } | |
168 | + | |
169 | + /* | |
170 | + * Convert a raw string to a hex string | |
171 | + */ | |
172 | + function rstr2hex(input){ | |
173 | + try{ hexcase }catch(e){ hexcase = 0; } | |
174 | + | |
175 | + var hex_tab = hexcase ? | |
176 | + "0123456789ABCDEF" : | |
177 | + "0123456789abcdef"; | |
178 | + | |
179 | + var output = ""; | |
180 | + var x; | |
181 | + | |
182 | + for(var i = 0; i < input.length; i++){ | |
183 | + x = input.charCodeAt(i); | |
184 | + output += hex_tab.charAt((x >>> 4) & 0x0F) + | |
185 | + hex_tab.charAt(x & 0x0F); | |
186 | + } | |
187 | + | |
188 | + return output; | |
189 | + } | |
190 | + | |
191 | + /* | |
192 | + * Convert a raw string to a base-64 string | |
193 | + */ | |
194 | + function rstr2b64(input){ | |
195 | + try{ b64pad }catch(e){ b64pad = ''; } | |
196 | + | |
197 | + var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | |
198 | + var output = ""; | |
199 | + | |
200 | + var len = input.length; | |
201 | + | |
202 | + for(var i = 0; i < len; i += 3){ | |
203 | + var triplet = (input.charCodeAt(i) << 16) | |
204 | + | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) | |
205 | + | (i + 2 < len ? input.charCodeAt(i + 2) : 0); | |
206 | + | |
207 | + for(var j = 0; j < 4; j++){ | |
208 | + if(i * 8 + j * 6 > input.length * 8) output += b64pad; | |
209 | + else output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F); | |
210 | + } | |
211 | + } | |
212 | + | |
213 | + return output; | |
214 | + } | |
215 | + | |
216 | + /* | |
217 | + * Convert a raw string to an arbitrary string encoding | |
218 | + */ | |
219 | + function rstr2any(input, encoding){ | |
220 | + var divisor = encoding.length; | |
221 | + var i, j, q, x, quotient; | |
222 | + | |
223 | + /* Convert to an array of 16-bit big-endian values, forming the dividend */ | |
224 | + var dividend = new Array(Math.ceil(input.length / 2)); | |
225 | + for(i = 0; i < dividend.length; i++){ | |
226 | + dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1); | |
227 | + } | |
228 | + | |
229 | + /* | |
230 | + * Repeatedly perform a long division. The binary array forms the dividend, | |
231 | + * the length of the encoding is the divisor. Once computed, the quotient | |
232 | + * forms the dividend for the next step. All remainders are stored for later | |
233 | + * use. | |
234 | + */ | |
235 | + var full_length = | |
236 | + Math.ceil(input.length * 8 / (Math.log(encoding.length) / Math.log(2))); | |
237 | + | |
238 | + var remainders = new Array(full_length); | |
239 | + | |
240 | + for(j = 0; j < full_length; j++){ | |
241 | + quotient = []; | |
242 | + x = 0; | |
243 | + | |
244 | + for(i = 0; i < dividend.length; i++){ | |
245 | + x = (x << 16) + dividend[i]; | |
246 | + q = Math.floor(x / divisor); | |
247 | + x -= q * divisor; | |
248 | + | |
249 | + if(quotient.length > 0 || q > 0) | |
250 | + quotient[quotient.length] = q; | |
251 | + } | |
252 | + | |
253 | + remainders[j] = x; | |
254 | + dividend = quotient; | |
255 | + } | |
256 | + | |
257 | + /* Convert the remainders to the output string */ | |
258 | + var output = ""; | |
259 | + for(i = remainders.length - 1; i >= 0; i--) | |
260 | + output += encoding.charAt(remainders[i]); | |
261 | + | |
262 | + return output; | |
263 | + } | |
264 | + | |
265 | + /* | |
266 | + * Encode a string as utf-8. | |
267 | + * For efficiency, this assumes the input is valid utf-16. | |
268 | + */ | |
269 | + function str2rstr_utf8(input){ | |
270 | + var output = ""; | |
271 | + var i = -1; | |
272 | + var x, y; | |
273 | + | |
274 | + while(++i < input.length){ | |
275 | + /* Decode utf-16 surrogate pairs */ | |
276 | + x = input.charCodeAt(i); | |
277 | + y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0; | |
278 | + if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF){ | |
279 | + x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF); | |
280 | + i++; | |
281 | + } | |
282 | + | |
283 | + /* Encode output as utf-8 */ | |
284 | + if(x <= 0x7F) | |
285 | + output += String.fromCharCode(x); | |
286 | + else if(x <= 0x7FF) | |
287 | + output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F), | |
288 | + 0x80 | ( x & 0x3F)); | |
289 | + else if(x <= 0xFFFF) | |
290 | + output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), | |
291 | + 0x80 | ((x >>> 6 ) & 0x3F), | |
292 | + 0x80 | ( x & 0x3F)); | |
293 | + else if(x <= 0x1FFFFF) | |
294 | + output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), | |
295 | + 0x80 | ((x >>> 12) & 0x3F), | |
296 | + 0x80 | ((x >>> 6 ) & 0x3F), | |
297 | + 0x80 | ( x & 0x3F)); | |
298 | + } | |
299 | + | |
300 | + return output; | |
301 | + } | |
302 | + | |
303 | + /* | |
304 | + * Encode a string as utf-16 | |
305 | + */ | |
306 | + function str2rstr_utf16le(input){ | |
307 | + var output = ""; | |
308 | + | |
309 | + for(var i = 0; i < input.length; i++) | |
310 | + output += String.fromCharCode(input.charCodeAt(i) & 0xFF, | |
311 | + (input.charCodeAt(i) >>> 8) & 0xFF); | |
312 | + | |
313 | + return output; | |
314 | + } | |
315 | + | |
316 | + function str2rstr_utf16be(input){ | |
317 | + var output = ""; | |
318 | + | |
319 | + for(var i = 0; i < input.length; i++) | |
320 | + output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF, | |
321 | + input.charCodeAt(i) & 0xFF); | |
322 | + | |
323 | + return output; | |
324 | + } | |
325 | + | |
326 | + /* | |
327 | + * Convert a raw string to an array of big-endian words | |
328 | + * Characters >255 have their high-byte silently ignored. | |
329 | + */ | |
330 | + function rstr2binb(input){ | |
331 | + var output = new Array(input.length >> 2); | |
332 | + | |
333 | + for(var i = 0; i < output.length; i++) | |
334 | + output[i] = 0; | |
335 | + | |
336 | + for(var j = 0; j < input.length * 8; j += 8) | |
337 | + output[j >> 5] |= (input.charCodeAt(j / 8) & 0xFF) << (24 - j % 32); | |
338 | + | |
339 | + return output; | |
340 | + } | |
341 | + | |
342 | + /* | |
343 | + * Convert an array of big-endian words to a string | |
344 | + */ | |
345 | + function binb2rstr(input){ | |
346 | + var output = ""; | |
347 | + | |
348 | + for(var i = 0; i < input.length * 32; i += 8) | |
349 | + output += String.fromCharCode((input[i >> 5] >>> (24 - i % 32)) & 0xFF); | |
350 | + | |
351 | + return output; | |
352 | + } | |
353 | + | |
354 | + /* | |
355 | + * Calculate the SHA-512 of an array of big-endian dwords, and a bit length | |
356 | + */ | |
357 | + var sha512_k; | |
358 | + | |
359 | + function binb_sha512(x, len){ | |
360 | + if(sha512_k === undefined){ | |
361 | + | |
362 | + //SHA512 constants | |
363 | + sha512_k = new Array( | |
364 | + new Int64(0x428a2f98, -685199838), new Int64(0x71374491, 0x23ef65cd), | |
365 | + new Int64(-1245643825, -330482897), new Int64(-373957723, -2121671748), | |
366 | + new Int64(0x3956c25b, -213338824), new Int64(0x59f111f1, -1241133031), | |
367 | + new Int64(-1841331548, -1357295717), new Int64(-1424204075, -630357736), | |
368 | + new Int64(-670586216, -1560083902), new Int64(0x12835b01, 0x45706fbe), | |
369 | + new Int64(0x243185be, 0x4ee4b28c), new Int64(0x550c7dc3, -704662302), | |
370 | + new Int64(0x72be5d74, -226784913), new Int64(-2132889090, 0x3b1696b1), | |
371 | + new Int64(-1680079193, 0x25c71235), new Int64(-1046744716, -815192428), | |
372 | + new Int64(-459576895, -1628353838), new Int64(-272742522, 0x384f25e3), | |
373 | + new Int64(0xfc19dc6, -1953704523), new Int64(0x240ca1cc, 0x77ac9c65), | |
374 | + new Int64(0x2de92c6f, 0x592b0275), new Int64(0x4a7484aa, 0x6ea6e483), | |
375 | + new Int64(0x5cb0a9dc, -1119749164), new Int64(0x76f988da, -2096016459), | |
376 | + new Int64(-1740746414, -295247957), new Int64(-1473132947, 0x2db43210), | |
377 | + new Int64(-1341970488, -1728372417), new Int64(-1084653625, -1091629340), | |
378 | + new Int64(-958395405, 0x3da88fc2), new Int64(-710438585, -1828018395), | |
379 | + new Int64(0x6ca6351, -536640913), new Int64(0x14292967, 0xa0e6e70), | |
380 | + new Int64(0x27b70a85, 0x46d22ffc), new Int64(0x2e1b2138, 0x5c26c926), | |
381 | + new Int64(0x4d2c6dfc, 0x5ac42aed), new Int64(0x53380d13, -1651133473), | |
382 | + new Int64(0x650a7354, -1951439906), new Int64(0x766a0abb, 0x3c77b2a8), | |
383 | + new Int64(-2117940946, 0x47edaee6), new Int64(-1838011259, 0x1482353b), | |
384 | + new Int64(-1564481375, 0x4cf10364), new Int64(-1474664885, -1136513023), | |
385 | + new Int64(-1035236496, -789014639), new Int64(-949202525, 0x654be30), | |
386 | + new Int64(-778901479, -688958952), new Int64(-694614492, 0x5565a910), | |
387 | + new Int64(-200395387, 0x5771202a), new Int64(0x106aa070, 0x32bbd1b8), | |
388 | + new Int64(0x19a4c116, -1194143544), new Int64(0x1e376c08, 0x5141ab53), | |
389 | + new Int64(0x2748774c, -544281703), new Int64(0x34b0bcb5, -509917016), | |
390 | + new Int64(0x391c0cb3, -976659869), new Int64(0x4ed8aa4a, -482243893), | |
391 | + new Int64(0x5b9cca4f, 0x7763e373), new Int64(0x682e6ff3, -692930397), | |
392 | + new Int64(0x748f82ee, 0x5defb2fc), new Int64(0x78a5636f, 0x43172f60), | |
393 | + new Int64(-2067236844, -1578062990), new Int64(-1933114872, 0x1a6439ec), | |
394 | + new Int64(-1866530822, 0x23631e28), new Int64(-1538233109, -561857047), | |
395 | + new Int64(-1090935817, -1295615723), new Int64(-965641998, -479046869), | |
396 | + new Int64(-903397682, -366583396), new Int64(-779700025, 0x21c0c207), | |
397 | + new Int64(-354779690, -840897762), new Int64(-176337025, -294727304), | |
398 | + new Int64(0x6f067aa, 0x72176fba), new Int64(0xa637dc5, -1563912026), | |
399 | + new Int64(0x113f9804, -1090974290), new Int64(0x1b710b35, 0x131c471b), | |
400 | + new Int64(0x28db77f5, 0x23047d84), new Int64(0x32caab7b, 0x40c72493), | |
401 | + new Int64(0x3c9ebe0a, 0x15c9bebc), new Int64(0x431d67c4, -1676669620), | |
402 | + new Int64(0x4cc5d4be, -885112138), new Int64(0x597f299c, -60457430), | |
403 | + new Int64(0x5fcb6fab, 0x3ad6faec), new Int64(0x6c44198c, 0x4a475817)); | |
404 | + } | |
405 | + | |
406 | + //Initial hash values | |
407 | + var H = new Array( | |
408 | + new Int64(0x6a09e667, -205731576), | |
409 | + new Int64(-1150833019, -2067093701), | |
410 | + new Int64(0x3c6ef372, -23791573), | |
411 | + new Int64(-1521486534, 0x5f1d36f1), | |
412 | + new Int64(0x510e527f, -1377402159), | |
413 | + new Int64(-1694144372, 0x2b3e6c1f), | |
414 | + new Int64(0x1f83d9ab, -79577749), | |
415 | + new Int64(0x5be0cd19, 0x137e2179)); | |
416 | + | |
417 | + var T1 = new Int64(0, 0), | |
418 | + T2 = new Int64(0, 0), | |
419 | + a = new Int64(0, 0), | |
420 | + b = new Int64(0, 0), | |
421 | + c = new Int64(0, 0), | |
422 | + d = new Int64(0, 0), | |
423 | + e = new Int64(0, 0), | |
424 | + f = new Int64(0, 0), | |
425 | + g = new Int64(0, 0), | |
426 | + h = new Int64(0, 0), | |
427 | + //Temporary variables not specified by the document | |
428 | + s0 = new Int64(0, 0), | |
429 | + s1 = new Int64(0, 0), | |
430 | + Ch = new Int64(0, 0), | |
431 | + Maj = new Int64(0, 0), | |
432 | + r1 = new Int64(0, 0), | |
433 | + r2 = new Int64(0, 0), | |
434 | + r3 = new Int64(0, 0); | |
435 | + var j, i; | |
436 | + var W = new Array(80); | |
437 | + for(i = 0; i < 80; i++) | |
438 | + W[i] = new Int64(0, 0); | |
439 | + | |
440 | + // append padding to the source string. The format is described in the FIPS. | |
441 | + x[len >> 5] |= 0x80 << (24 - (len & 0x1f)); | |
442 | + x[((len + 128 >> 10) << 5) + 31] = len; | |
443 | + | |
444 | + //32 dwords is the block size | |
445 | + for(i = 0; i < x.length; i += 32){ | |
446 | + int64copy(a, H[0]); | |
447 | + int64copy(b, H[1]); | |
448 | + int64copy(c, H[2]); | |
449 | + int64copy(d, H[3]); | |
450 | + int64copy(e, H[4]); | |
451 | + int64copy(f, H[5]); | |
452 | + int64copy(g, H[6]); | |
453 | + int64copy(h, H[7]); | |
454 | + | |
455 | + for(j = 0; j < 16; j++){ | |
456 | + W[j].h = x[i + 2 * j]; | |
457 | + W[j].l = x[i + 2 * j + 1]; | |
458 | + } | |
459 | + | |
460 | + for(j = 16; j < 80; j++){ | |
461 | + //sigma1 | |
462 | + int64rrot(r1, W[j - 2], 19); | |
463 | + int64revrrot(r2, W[j - 2], 29); | |
464 | + int64shr(r3, W[j - 2], 6); | |
465 | + s1.l = r1.l ^ r2.l ^ r3.l; | |
466 | + s1.h = r1.h ^ r2.h ^ r3.h; | |
467 | + //sigma0 | |
468 | + int64rrot(r1, W[j - 15], 1); | |
469 | + int64rrot(r2, W[j - 15], 8); | |
470 | + int64shr(r3, W[j - 15], 7); | |
471 | + s0.l = r1.l ^ r2.l ^ r3.l; | |
472 | + s0.h = r1.h ^ r2.h ^ r3.h; | |
473 | + | |
474 | + int64add4(W[j], s1, W[j - 7], s0, W[j - 16]); | |
475 | + } | |
476 | + | |
477 | + for(j = 0; j < 80; j++){ | |
478 | + //Ch | |
479 | + Ch.l = (e.l & f.l) ^ (~e.l & g.l); | |
480 | + Ch.h = (e.h & f.h) ^ (~e.h & g.h); | |
481 | + | |
482 | + //Sigma1 | |
483 | + int64rrot(r1, e, 14); | |
484 | + int64rrot(r2, e, 18); | |
485 | + int64revrrot(r3, e, 9); | |
486 | + s1.l = r1.l ^ r2.l ^ r3.l; | |
487 | + s1.h = r1.h ^ r2.h ^ r3.h; | |
488 | + | |
489 | + //Sigma0 | |
490 | + int64rrot(r1, a, 28); | |
491 | + int64revrrot(r2, a, 2); | |
492 | + int64revrrot(r3, a, 7); | |
493 | + s0.l = r1.l ^ r2.l ^ r3.l; | |
494 | + s0.h = r1.h ^ r2.h ^ r3.h; | |
495 | + | |
496 | + //Maj | |
497 | + Maj.l = (a.l & b.l) ^ (a.l & c.l) ^ (b.l & c.l); | |
498 | + Maj.h = (a.h & b.h) ^ (a.h & c.h) ^ (b.h & c.h); | |
499 | + | |
500 | + int64add5(T1, h, s1, Ch, sha512_k[j], W[j]); | |
501 | + int64add(T2, s0, Maj); | |
502 | + | |
503 | + int64copy(h, g); | |
504 | + int64copy(g, f); | |
505 | + int64copy(f, e); | |
506 | + int64add(e, d, T1); | |
507 | + int64copy(d, c); | |
508 | + int64copy(c, b); | |
509 | + int64copy(b, a); | |
510 | + int64add(a, T1, T2); | |
511 | + } | |
512 | + int64add(H[0], H[0], a); | |
513 | + int64add(H[1], H[1], b); | |
514 | + int64add(H[2], H[2], c); | |
515 | + int64add(H[3], H[3], d); | |
516 | + int64add(H[4], H[4], e); | |
517 | + int64add(H[5], H[5], f); | |
518 | + int64add(H[6], H[6], g); | |
519 | + int64add(H[7], H[7], h); | |
520 | + } | |
521 | + | |
522 | + //represent the hash as an array of 32-bit dwords | |
523 | + var hash = new Array(16); | |
524 | + | |
525 | + for(i = 0; i < 8; i++){ | |
526 | + hash[2 * i] = H[i].h; | |
527 | + hash[2 * i + 1] = H[i].l; | |
528 | + } | |
529 | + | |
530 | + return hash; | |
531 | + } | |
532 | + | |
533 | + //A constructor for 64-bit numbers | |
534 | + function Int64(_h, _l){ | |
535 | + return { | |
536 | + h :_h, | |
537 | + l :_l, | |
538 | + //toString :int64toString, | |
539 | + }; | |
540 | + } | |
541 | + | |
542 | + //Copies src into dst, assuming both are 64-bit numbers | |
543 | + function int64copy(dst, src){ | |
544 | + dst.h = src.h; | |
545 | + dst.l = src.l; | |
546 | + } | |
547 | + | |
548 | + //Right-rotates a 64-bit number by shift | |
549 | + //Won't handle cases of shift>=32 | |
550 | + //The function revrrot() is for that | |
551 | + function int64rrot(dst, x, shift){ | |
552 | + dst.l = (x.l >>> shift) | (x.h << (32 - shift)); | |
553 | + dst.h = (x.h >>> shift) | (x.l << (32 - shift)); | |
554 | + } | |
555 | + | |
556 | + //Reverses the dwords of the source and then rotates right by shift. | |
557 | + //This is equivalent to rotation by 32+shift | |
558 | + function int64revrrot(dst, x, shift){ | |
559 | + dst.l = (x.h >>> shift) | (x.l << (32 - shift)); | |
560 | + dst.h = (x.l >>> shift) | (x.h << (32 - shift)); | |
561 | + } | |
562 | + | |
563 | + //Bitwise-shifts right a 64-bit number by shift | |
564 | + //Won't handle shift>=32, but it's never needed in SHA512 | |
565 | + function int64shr(dst, x, shift){ | |
566 | + dst.l = (x.l >>> shift) | (x.h << (32 - shift)); | |
567 | + dst.h = (x.h >>> shift); | |
568 | + } | |
569 | + | |
570 | + //Adds two 64-bit numbers | |
571 | + //Like the original implementation, does not rely on 32-bit operations | |
572 | + function int64add(dst, x, y){ | |
573 | + var w0 = (x.l & 0xffff) + (y.l & 0xffff); | |
574 | + var w1 = (x.l >>> 16) + (y.l >>> 16) + (w0 >>> 16); | |
575 | + var w2 = (x.h & 0xffff) + (y.h & 0xffff) + (w1 >>> 16); | |
576 | + var w3 = (x.h >>> 16) + (y.h >>> 16) + (w2 >>> 16); | |
577 | + dst.l = (w0 & 0xffff) | (w1 << 16); | |
578 | + dst.h = (w2 & 0xffff) | (w3 << 16); | |
579 | + } | |
580 | + | |
581 | + //Same, except with 4 addends. Works faster than adding them one by one. | |
582 | + function int64add4(dst, a, b, c, d){ | |
583 | + var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff); | |
584 | + var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (w0 >>> 16); | |
585 | + var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (w1 >>> 16); | |
586 | + var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (w2 >>> 16); | |
587 | + dst.l = (w0 & 0xffff) | (w1 << 16); | |
588 | + dst.h = (w2 & 0xffff) | (w3 << 16); | |
589 | + } | |
590 | + | |
591 | + //Same, except with 5 addends | |
592 | + function int64add5(dst, a, b, c, d, e){ | |
593 | + var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff) + (e.l & 0xffff); | |
594 | + var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (e.l >>> 16) + (w0 >>> 16); | |
595 | + var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (e.h & 0xffff) + (w1 >>> 16); | |
596 | + var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (e.h >>> 16) + (w2 >>> 16); | |
597 | + dst.l = (w0 & 0xffff) | (w1 << 16); | |
598 | + dst.h = (w2 & 0xffff) | (w3 << 16); | |
599 | + } | |
600 | + | |
601 | + return hex_sha512(data); | |
602 | + }; | |
603 | + | |
604 | + /** | |
605 | + * get the hash of the current values of the form `formName` | |
606 | + * | |
607 | + * @param {String} formName | |
608 | + * @returns {String} hash value | |
609 | + * @private | |
610 | + */ | |
611 | + var __getHash = function(formName){ | |
612 | + var data = __get(formName), | |
613 | + json = __getJSON(data), | |
614 | + hash = __sha512sum(json); | |
615 | + | |
616 | + return hash; | |
617 | + }; | |
618 | + | |
619 | + /** | |
620 | + * save `hash` as the specified form's hash | |
621 | + * | |
622 | + * @param {String} formName | |
623 | + * @param {String} hash | |
624 | + * @private | |
625 | + */ | |
626 | + var __saveHash = function(formName, hash){ | |
627 | + if(!__formExists(formName)) | |
628 | + return; | |
629 | + | |
630 | + document.forms[formName].setAttribute("data-microform-hash", hash); | |
631 | + }; | |
632 | + | |
633 | + /** | |
634 | + * checks if the form `formName` exists | |
635 | + * | |
636 | + * @param {String} formName | |
637 | + * @returns {boolean} | |
638 | + * @private | |
639 | + */ | |
640 | + var __formExists = function(formName){ | |
641 | + return document.forms[formName] !== undefined; | |
642 | + }; | |
643 | + | |
644 | + /** | |
645 | + * @summary | |
646 | + * get the values of the specified form | |
647 | + * | |
648 | + * @description | |
649 | + * returns `undefined` if the form does not exist | |
650 | + * | |
651 | + * @param {String} formName | |
652 | + * @returns {undefined|Object} | |
653 | + * | |
654 | + * @private | |
655 | + */ | |
656 | + var __getElements = function(formName){ | |
657 | + var $pushArray = function(obj, name, value){ | |
658 | + if(obj.hasOwnProperty(name)){ | |
659 | + obj[name].push(value); | |
660 | + }else{ | |
661 | + obj[name] = [value]; | |
662 | + } | |
663 | + }; | |
664 | + | |
665 | + var $push = function(obj, name, value){ | |
666 | + if(obj.hasOwnProperty(name)){ | |
667 | + obj[name] = obj[name] instanceof Array ? | |
668 | + obj[name] : | |
669 | + [obj[name]]; | |
670 | + | |
671 | + obj[name].push(value); | |
672 | + }else{ | |
673 | + obj[name] = value; | |
674 | + } | |
675 | + }; | |
676 | + | |
677 | + var $getElement = function(cur, el, i){ | |
678 | + var name = el.name; | |
679 | + | |
680 | + if(name === undefined || name === null || el.name.trim() === "") | |
681 | + return cur; | |
682 | + | |
683 | + var node = el.nodeName.toUpperCase(), | |
684 | + value = el.value; | |
685 | + | |
686 | + switch(node){ | |
687 | + case 'INPUT': | |
688 | + switch(el.type){ | |
689 | + case 'text': // fall through | |
690 | + case 'hidden': // fall through | |
691 | + case 'password': // fall through | |
692 | + case 'button': // fall through | |
693 | + case 'reset': // fall through | |
694 | + case 'submit': | |
695 | + $push(cur, name, value); | |
696 | + break; | |
697 | + case 'checkbox': // fall through | |
698 | + case 'radio': | |
699 | + if(el.checked) | |
700 | + $push(cur, name, value); | |
701 | + break; | |
702 | + case 'file': | |
703 | + break; | |
704 | + } | |
705 | + break; | |
706 | + case 'TEXTAREA': | |
707 | + $push(cur, name, value); | |
708 | + break; | |
709 | + case 'SELECT': | |
710 | + switch(el.type){ | |
711 | + case 'select-one': | |
712 | + $push(cur, name, value); | |
713 | + break; | |
714 | + case 'select-multiple':{ | |
715 | + var sel = Array.prototype | |
716 | + .slice | |
717 | + .call(el.options) | |
718 | + .filter(function(opt){ | |
719 | + return opt.selected; | |
720 | + }) | |
721 | + .map(function(opt){ | |
722 | + return opt.value; | |
723 | + }); | |
724 | + $pushArray(cur, name, sel); | |
725 | + } | |
726 | + break; | |
727 | + } | |
728 | + break; | |
729 | + case 'BUTTON': | |
730 | + switch(el.type){ | |
731 | + case 'reset': // fall through: | |
732 | + case 'submit': // fall through: | |
733 | + case 'button': | |
734 | + $push(cur, name, value); | |
735 | + break; | |
736 | + } | |
737 | + break; | |
738 | + } | |
739 | + | |
740 | + return cur; | |
741 | + }; | |
742 | + | |
743 | + if(!__formExists(formName)) | |
744 | + return undefined; | |
745 | + | |
746 | + var form = document.forms[formName], | |
747 | + elements = Array.prototype | |
748 | + .slice | |
749 | + .call(form.elements), | |
750 | + obj = {}; | |
751 | + | |
752 | + obj[formName] = elements.reduce($getElement, {}); | |
753 | + | |
754 | + return obj; | |
755 | + }; | |
756 | + | |
757 | + /** | |
758 | + * @summary | |
759 | + * calculate and save the hash | |
760 | + * | |
761 | + * @description | |
762 | + * calculate and save the hash of the specified form `formName` or | |
763 | + * calculate and save the hash of all forms if `formName` is null | |
764 | + * | |
765 | + * @static | |
766 | + * @member | |
767 | + * @memberOf MicroForm | |
768 | + * | |
769 | + * @param {String} formName | |
770 | + * @public | |
771 | + * | |
772 | + * @name init | |
773 | + * | |
774 | + * @example | |
775 | + * // calculate and save the hashes of all available forms | |
776 | + * MicroForm.init(); | |
777 | + * | |
778 | + * @example | |
779 | + * // calculate and save the hash of a single form | |
780 | + * // same as `MicroForm.hash` | |
781 | + * MicroForm.init("userinfo"); | |
782 | + * | |
783 | + * @see MicroForm.hash | |
784 | + */ | |
785 | + var __init = function(formName){ | |
786 | + if(formName === undefined || | |
787 | + formName === null || | |
788 | + (typeof formName === typeof "" && formName.trim() === "")){ | |
789 | + | |
790 | + Array.prototype | |
791 | + .slice | |
792 | + .call(document.forms) | |
793 | + .map(function(f){ | |
794 | + __hash(f.name); | |
795 | + }); | |
796 | + }else{ | |
797 | + __hash(formName); | |
798 | + } | |
799 | + }; | |
800 | + | |
801 | + /** | |
802 | + * @description | |
803 | + * returns all available forms if no parameter is passed | |
804 | + * | |
805 | + * returns the form values as an object of the specified form or | |
806 | + * array of forms | |
807 | + * | |
808 | + * @param {null|String|Array.<String>} formName | |
809 | + * @returns {Object|Array.<String>} | |
810 | + * @public | |
811 | + * | |
812 | + * @name get | |
813 | + * @member | |
814 | + * @memberOf MicroForm | |
815 | + * | |
816 | + * @example | |
817 | + * // get string array names of all forms | |
818 | + * var forms = Microform.get(); | |
819 | + * | |
820 | + * @example | |
821 | + * // get data of a form | |
822 | + * var userData = MicroForm.get("userInfo"); | |
823 | + * | |
824 | + * @example | |
825 | + * // get data of multiple forms | |
826 | + * var formData = MicroForm.get(["userInfo", "jobInfo", "requestForm"]); | |
827 | + * | |
828 | + */ | |
829 | + var __get = function(formName){ | |
830 | + if(formName === undefined || formName === null || | |
831 | + (typeof formName === typeof "" && formName.trim() === "")){ | |
832 | + | |
833 | + return Array.prototype | |
834 | + .slice | |
835 | + .call(document.forms) | |
836 | + .map(function(f){ | |
837 | + return f.name; | |
838 | + }); | |
839 | + } | |
840 | + | |
841 | + if(typeof formName === typeof ""){ | |
842 | + return __getElements(formName); | |
843 | + } | |
844 | + | |
845 | + if(formName instanceof Array){ | |
846 | + return formName.map(function(f){ | |
847 | + return __getElements(f); | |
848 | + }); | |
849 | + } | |
850 | + | |
851 | + return undefined; | |
852 | + }; | |
853 | + | |
854 | + var __set = function(formName, data){ | |
855 | + console.error("set method unimplemented"); | |
856 | + | |
857 | + if(typeof formName === typeof ""){ | |
858 | + } | |
859 | + else{ | |
860 | + } | |
861 | + }; | |
862 | + | |
863 | + /** | |
864 | + * @summary | |
865 | + * calculate and save the hash of the specified form `formName` | |
866 | + * | |
867 | + * @name hash | |
868 | + * | |
869 | + * @static | |
870 | + * @member | |
871 | + * @memberOf MicroForm | |
872 | + * | |
873 | + * @param {String} formName name of the form to calculate from | |
874 | + * | |
875 | + * @public | |
876 | + * | |
877 | + * @see MicroForm.init | |
878 | + * | |
879 | + * @example | |
880 | + * // save the hash of the current values of the form | |
881 | + * MicroForm.hash("userinfo"); | |
882 | + */ | |
883 | + var __hash = function(formName){ | |
884 | + if(formName === undefined || | |
885 | + formName === null || | |
886 | + typeof formName !== typeof "" || | |
887 | + formName.trim() === "" || !__formExists(formName)){ | |
888 | + return; | |
889 | + } | |
890 | + | |
891 | + var hash = __getHash(formName); | |
892 | + | |
893 | + __saveHash(formName, hash); | |
894 | + | |
895 | + return hash; | |
896 | + }; | |
897 | + | |
898 | + /** | |
899 | + * @summary | |
900 | + * checks if the form values has changed | |
901 | + * | |
902 | + * @description | |
903 | + * if the form `formName` does not exist or is null `false` is | |
904 | + * returned | |
905 | + * | |
906 | + * @param {String} formName | |
907 | + * @returns {boolean} | |
908 | + * | |
909 | + * @public | |
910 | + * | |
911 | + * @static | |
912 | + * @member | |
913 | + * @memberOf MicroForm | |
914 | + * | |
915 | + * @name hasChanged | |
916 | + * | |
917 | + * @example | |
918 | + * if (MicroForm.hasChanged("userinfo")) | |
919 | + * updateUser(); | |
920 | + * | |
921 | + */ | |
922 | + var __hasChanged = function(formName){ | |
923 | + if(formName === undefined || | |
924 | + formName === null || | |
925 | + typeof formName !== typeof "" || | |
926 | + formName.trim() === "" || !__formExists(formName)){ | |
927 | + return false; | |
928 | + } | |
929 | + | |
930 | + var savedHash = document.forms[formName].dataset.microformHash, | |
931 | + currentHash = __getHash(formName); | |
932 | + | |
933 | + return currentHash !== savedHash; | |
934 | + }; | |
935 | + | |
936 | + /** | |
937 | + * @class MicroForm | |
938 | + */ | |
939 | + return { | |
940 | + init :__init, | |
941 | + get :__get, | |
942 | + set :__set, | |
943 | + hash :__hash, | |
944 | + hasChanged :__hasChanged, | |
945 | + }; | |
946 | + | |
947 | +}()))); |
@@ -0,0 +1,115 @@ | ||
1 | +<!-- | |
2 | + untitled.html | |
3 | + | |
4 | + Copyright 2018 Frostbane Ac <frostbane@programmer.net> | |
5 | + | |
6 | + This program is free software; you can redistribute it and/or modify | |
7 | + it under the terms of the GNU General Public License as published by | |
8 | + the Free Software Foundation; either version 2 of the License, or | |
9 | + (at your option) any later version. | |
10 | + | |
11 | + This program is distributed in the hope that it will be useful, | |
12 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | + GNU General Public License for more details. | |
15 | + | |
16 | + You should have received a copy of the GNU General Public License | |
17 | + along with this program; if not, write to the Free Software | |
18 | + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
19 | + MA 02110-1301, USA. | |
20 | + | |
21 | + | |
22 | +--> | |
23 | + | |
24 | +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" | |
25 | + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |
26 | +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | |
27 | + | |
28 | +<head> | |
29 | + <title>untitled</title> | |
30 | + <meta http-equiv="content-type" content="text/html;charset=utf-8" /> | |
31 | + <meta name="generator" content="Geany 1.24" /> | |
32 | +</head> | |
33 | + | |
34 | +<body> | |
35 | + | |
36 | +<div> | |
37 | + <form name="user"> | |
38 | + <label>name <input type="text" name="username" id="username" value="ac" /></label> | |
39 | + <label>id <input type="text" name="id" id="userid" value="003" /></label> | |
40 | + <fieldset> | |
41 | + <legend>sex</legend> | |
42 | + <label><input type="radio" name="sex" value="M" />M</label> | |
43 | + <label><input type="radio" name="sex" value="F" />F</label> | |
44 | + </fieldset> | |
45 | + <label>status <select name="status"> | |
46 | + <option value="single">single</option> | |
47 | + <option value="married">married</option> | |
48 | + <option value="divorced">divorced</option> | |
49 | + <option value="widow">widow</option> | |
50 | + </select></label> | |
51 | + <buttton name="validate">check</buttton> | |
52 | + <input type="button" value="submit" /> | |
53 | + </form> | |
54 | +</div> | |
55 | + | |
56 | +<div> | |
57 | + <form name="skills"> | |
58 | + <div> | |
59 | + <label>skill <input type="text" name="skillname[]" value="maya" /></label> | |
60 | + <label>description <textarea name="description[]" cols="30" rows="3">model | |
61 | +rig | |
62 | +animate | |
63 | +dynamics</textarea></label> | |
64 | + <label>phase | |
65 | + <select name="skillphase" multiple> | |
66 | + <option value="pre production">pre production</option> | |
67 | + <option value="examination">examination</option> | |
68 | + <option value="development">development</option> | |
69 | + <option value="production">production</option> | |
70 | + <option value="release">release</option> | |
71 | + <option value="post production">post production</option> | |
72 | + <option value="sales">sales</option> | |
73 | + </select> | |
74 | + </label> | |
75 | + </div> | |
76 | + <div> | |
77 | + <label>skill <input type="text" name="skillname[]" value="vue" /></label> | |
78 | + <label>description <textarea name="description[]" cols="30" rows="3">environment</textarea></label> | |
79 | + <label>phase | |
80 | + <select name="skillphase" multiple> | |
81 | + <option value="pre production">pre production</option> | |
82 | + <option value="examination">examination</option> | |
83 | + <option value="development">development</option> | |
84 | + <option value="production">production</option> | |
85 | + <option value="release">release</option> | |
86 | + <option value="post production">post production</option> | |
87 | + <option value="sales">sales</option> | |
88 | + </select> | |
89 | + </label> | |
90 | + </div> | |
91 | + <div> | |
92 | + <label>skill <input type="text" name="skillname[]" value="fusion" /></label> | |
93 | + <label>description <textarea name="description[]" cols="30" rows="3"></textarea></label> | |
94 | + <label>phase | |
95 | + <select name="skillphase" multiple> | |
96 | + <option value="pre production">pre production</option> | |
97 | + <option value="examination">examination</option> | |
98 | + <option value="development">development</option> | |
99 | + <option value="production">production</option> | |
100 | + <option value="release">release</option> | |
101 | + <option value="post production">post production</option> | |
102 | + <option value="sales">sales</option> | |
103 | + </select> | |
104 | + </label> | |
105 | + </div> | |
106 | + <input type="button" value="submit" /> | |
107 | + </form> | |
108 | +</div> | |
109 | + | |
110 | +<div style="display:none !important;"> | |
111 | + <script type="text/javascript" src="../src/microform.js"></script> | |
112 | +</div> | |
113 | +</body> | |
114 | + | |
115 | +</html> |