hatemile 2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/CODE_OF_CONDUCT.md +46 -0
  3. data/Gemfile +9 -0
  4. data/LICENSE +202 -0
  5. data/Rakefile +64 -0
  6. data/hatemile.gemspec +37 -0
  7. data/lib/hatemile/accessible_association.rb +62 -0
  8. data/lib/hatemile/accessible_css.rb +43 -0
  9. data/lib/hatemile/accessible_display.rb +178 -0
  10. data/lib/hatemile/accessible_event.rb +95 -0
  11. data/lib/hatemile/accessible_form.rb +101 -0
  12. data/lib/hatemile/accessible_navigation.rb +82 -0
  13. data/lib/hatemile/helper.rb +58 -0
  14. data/lib/hatemile/implementation/accessible_association_implementation.rb +346 -0
  15. data/lib/hatemile/implementation/accessible_css_implementation.rb +772 -0
  16. data/lib/hatemile/implementation/accessible_display_implementation.rb +1362 -0
  17. data/lib/hatemile/implementation/accessible_event_implementation.rb +278 -0
  18. data/lib/hatemile/implementation/accessible_form_implementation.rb +386 -0
  19. data/lib/hatemile/implementation/accessible_navigation_implementation.rb +561 -0
  20. data/lib/hatemile/util/common_functions.rb +106 -0
  21. data/lib/hatemile/util/configure.rb +92 -0
  22. data/lib/hatemile/util/css/rcp/rcp_declaration.rb +77 -0
  23. data/lib/hatemile/util/css/rcp/rcp_parser.rb +115 -0
  24. data/lib/hatemile/util/css/rcp/rcp_rule.rb +86 -0
  25. data/lib/hatemile/util/css/style_sheet_declaration.rb +59 -0
  26. data/lib/hatemile/util/css/style_sheet_parser.rb +43 -0
  27. data/lib/hatemile/util/css/style_sheet_rule.rb +73 -0
  28. data/lib/hatemile/util/html/html_dom_element.rb +234 -0
  29. data/lib/hatemile/util/html/html_dom_node.rb +131 -0
  30. data/lib/hatemile/util/html/html_dom_parser.rb +150 -0
  31. data/lib/hatemile/util/html/html_dom_text_node.rb +43 -0
  32. data/lib/hatemile/util/html/nokogiri/nokogiri_html_dom_element.rb +302 -0
  33. data/lib/hatemile/util/html/nokogiri/nokogiri_html_dom_node.rb +112 -0
  34. data/lib/hatemile/util/html/nokogiri/nokogiri_html_dom_parser.rb +208 -0
  35. data/lib/hatemile/util/html/nokogiri/nokogiri_html_dom_text_node.rb +83 -0
  36. data/lib/hatemile/util/id_generator.rb +53 -0
  37. data/lib/js/common.js +98 -0
  38. data/lib/js/eventlistener.js +36 -0
  39. data/lib/js/include.js +292 -0
  40. data/lib/js/scriptlist_validation_fields.js +13 -0
  41. data/lib/js/validation.js +205 -0
  42. data/lib/locale/en-US.yml +388 -0
  43. data/lib/locale/pt-BR.yml +389 -0
  44. data/lib/skippers.xml +6 -0
  45. data/lib/symbols.xml +40 -0
  46. data/test/locale/en-US.yml +5 -0
  47. data/test/locale/pt-BR.yml +4 -0
  48. data/test/test_accessible_association_implementation.rb +258 -0
  49. data/test/test_accessible_css_implementation.rb +518 -0
  50. data/test/test_accessible_display_implementation.rb +873 -0
  51. data/test/test_accessible_form_implementation.rb +283 -0
  52. data/test/test_accessible_navigation_implementation.rb +228 -0
  53. data/test/test_common_functions.rb +128 -0
  54. data/test/test_configure.rb +73 -0
  55. data/test/test_nokogiri_html_dom_element.rb +586 -0
  56. data/test/test_nokogiri_html_dom_parser.rb +363 -0
  57. data/test/test_nokogiri_html_dom_text_node.rb +225 -0
  58. data/test/test_rcp_declaration.rb +103 -0
  59. data/test/test_rcp_parser.rb +86 -0
  60. data/test/test_rcp_rule.rb +89 -0
  61. metadata +199 -0
@@ -0,0 +1,98 @@
1
+ isEmpty = function(value) {
2
+ if ((value === undefined) ||
3
+ (value === false) ||
4
+ (value === null)) {
5
+ return true;
6
+ } else if ((typeof value === typeof '') ||
7
+ (typeof value === typeof [])) {
8
+ if (value.length === 0) {
9
+ return true;
10
+ }
11
+ }
12
+ return false;
13
+ };
14
+
15
+ var __exports, __base;
16
+ __exports = this;
17
+ __exports.hatemile || (__exports.hatemile = {});
18
+ (__base = __exports.hatemile).util || (__base.util = {});
19
+ __exports.hatemile.util.CommonFunctions = {
20
+ count: 0,
21
+ generateId: function(element, prefix) {
22
+ if (!element.hasAttribute('id')) {
23
+ element.setAttribute('id', prefix + this.count.toString());
24
+ this.count++;
25
+ }
26
+ },
27
+ setListAttributes: function(element1, element2, attributes) {
28
+ var attribute, _i, _len;
29
+ for (_i = 0, _len = attributes.length; _i < _len; _i++) {
30
+ attribute = attributes[_i];
31
+ if (element1.hasAttribute(attribute)) {
32
+ element2.setAttribute(attribute, element1.getAttribute(attribute));
33
+ }
34
+ }
35
+ },
36
+ increaseInList: function(list, stringToIncrease) {
37
+ if (!(isEmpty(list) || isEmpty(stringToIncrease))) {
38
+ if (this.inList(list, stringToIncrease)) {
39
+ return list;
40
+ } else {
41
+ return list + ' ' + stringToIncrease;
42
+ }
43
+ } else if (isEmpty(list)) {
44
+ return stringToIncrease;
45
+ } else {
46
+ return list;
47
+ }
48
+ },
49
+ inList: function(list, stringToSearch) {
50
+ var array, item, _i, _len;
51
+ if (!(isEmpty(list) || isEmpty(stringToSearch))) {
52
+ array = list.split(new RegExp('[ \n\t\r]+'));
53
+ for (_i = 0, _len = array.length; _i < _len; _i++) {
54
+ item = array[_i];
55
+ if (item === stringToSearch) {
56
+ return true;
57
+ }
58
+ }
59
+ }
60
+ return false;
61
+ }
62
+ };
63
+
64
+ var addEventHandler = function(element, typeEvent, typeDataEvent, typeFix, eventHandler) {
65
+ var attribute, found;
66
+ if (!hasEvent(element, typeEvent, typeDataEvent, typeFix)) {
67
+ found = false;
68
+ attribute = element.getAttribute(typeDataEvent);
69
+ if (!hasEvent(element, typeEvent)) {
70
+ element['liston' + typeEvent] = [];
71
+ element['on' + typeEvent] = function(event) {
72
+ var addedEvent, _i, _len, _ref;
73
+ _ref = element['liston' + typeEvent];
74
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
75
+ addedEvent = _ref[_i];
76
+ addedEvent(event);
77
+ }
78
+ };
79
+ } else {
80
+ found = __exports.hatemile.util.CommonFunctions.inList(attribute, typeFix);
81
+ }
82
+ if (!found) {
83
+ element['liston' + typeEvent].push(eventHandler);
84
+ attribute = __exports.hatemile.util.CommonFunctions.increaseInList(attribute, typeFix);
85
+ element.setAttribute(typeDataEvent, attribute);
86
+ }
87
+ }
88
+ };
89
+
90
+ var hasEvent = function(element, typeEvent, typeDataEvent, typeFix) {
91
+ var attribute;
92
+ if (isEmpty(typeDataEvent) || isEmpty(typeFix)) {
93
+ return (!isEmpty(element['on' + typeEvent])) || ((!isEmpty(element.eventListenerList)) && (!isEmpty(element.eventListenerList[typeEvent])));
94
+ } else {
95
+ attribute = element.getAttribute(typeDataEvent);
96
+ return (hasEvent(element, typeEvent) && (!element.hasAttribute(typeDataEvent))) || __exports.hatemile.util.CommonFunctions.inList(attribute, typeFix);
97
+ }
98
+ };
@@ -0,0 +1,36 @@
1
+ if (!Element.prototype.eventListenerList) {
2
+ Element.prototype.eventListenerList = {};
3
+ Element.prototype.__eventListenerListAdded = false;
4
+
5
+ Element.prototype.__addEventListener = Element.prototype.addEventListener;
6
+ Element.prototype.addEventListener = function() {
7
+ if (!this.__eventListenerListAdded) {
8
+ this.eventListenerList = {};
9
+ this.__eventListenerListAdded = true;
10
+ }
11
+ if (!this.eventListenerList[arguments[0]]) {
12
+ this.eventListenerList[arguments[0]] = [];
13
+ }
14
+ this.eventListenerList[arguments[0]].push(arguments[1]);
15
+ return (this.__addEventListener.apply(this, arguments));
16
+ };
17
+
18
+ Element.prototype.__removeEventListener = Element.prototype.removeEventListener;
19
+ Element.prototype.removeEventListener = function() {
20
+ var found = false;
21
+ if (!this.eventListenerList[arguments[0]]) {
22
+ this.eventListenerList[arguments[0]] = [];
23
+ }
24
+ var key;
25
+ for (key in this.eventListenerList[arguments[0]]) {
26
+ found = this.eventListenerList[arguments[0]][key] === arguments[1];
27
+ if (found) {
28
+ break;
29
+ }
30
+ }
31
+ if (found) {
32
+ this.eventListenerList[arguments[0]].splice(key, 1);
33
+ }
34
+ return (this.__removeEventListener.apply(this, arguments));
35
+ };
36
+ }
@@ -0,0 +1,292 @@
1
+ __exports.__aria_grabbed__elements__ = [];
2
+ __exports.__aria_dropeffect__elements__ = [];
3
+
4
+ enterPressed = function(keyCode) {
5
+ var enter1, enter2;
6
+ enter1 = '\n'.charCodeAt(0);
7
+ enter2 = '\r'.charCodeAt(0);
8
+ return (keyCode === enter1) || (keyCode === enter2);
9
+ };
10
+
11
+ keyboardAccess = function(element) {
12
+ var tag;
13
+ if (!element.hasAttribute('tabindex')) {
14
+ tag = element.tagName.toUpperCase();
15
+ if ((tag === 'A') && (!element.hasAttribute('href'))) {
16
+ element.setAttribute('tabindex', '0');
17
+ } else if ((tag !== 'INPUT') && (tag !== 'BUTTON') && (tag !== 'SELECT') && (tag !== 'TEXTAREA')) {
18
+ element.setAttribute('tabindex', '0');
19
+ }
20
+ }
21
+ };
22
+
23
+ clearDropEffect = function() {
24
+ var activeEvents, dragEvents, droppedElement, droppedElements, hoverEvents, _i, _len;
25
+ droppedElements = __exports.__aria_dropeffect__elements__;
26
+ for (_i = 0, _len = droppedElements.length; _i < _len; _i++) {
27
+ droppedElement = droppedElements[_i];
28
+ dragEvents = (!hasEvent(droppedElement, 'keydown', 'data-keydownadded', 'drag')) && (!hasEvent(droppedElement, 'keyup', 'data-keyupadded', 'drag'));
29
+ activeEvents = (!droppedElement.hasAttribute('data-keypressadded')) && (!hasEvent(droppedElement, 'keydown', 'data-keydownadded', 'active')) && (!hasEvent(droppedElement, 'keyup', 'data-keyupadded', 'active'));
30
+ hoverEvents = (!hasEvent(droppedElement, 'focus', 'data-focusadded', 'hover')) && (!hasEvent(droppedElement, 'blur', 'data-bluradded', 'hover'));
31
+ droppedElement.setAttribute('aria-dropeffect', 'none');
32
+ if (droppedElement.hasAttribute('tabindex') && dragEvents && activeEvents && hoverEvents) {
33
+ droppedElement.removeAttribute('tabindex');
34
+ }
35
+ }
36
+ };
37
+
38
+ generateDropEffect = function() {
39
+ var ariaDropEffect, dropEffect, droppedElement, droppedElements, effectAllowed, _i, _len;
40
+ dropEffect = __exports.__dragEventDataTransfer__.dropEffect;
41
+ effectAllowed = __exports.__dragEventDataTransfer__.effectAllowed;
42
+ if ((dropEffect === 'none') || ((dropEffect !== 'copy') && (dropEffect !== 'link') && (dropEffect !== 'move'))) {
43
+ if ((effectAllowed === 'copyLink') || (effectAllowed === 'copyMove') || (effectAllowed === 'linkMove') || (effectAllowed === 'all')) {
44
+ ariaDropEffect = 'popup';
45
+ } else if ((effectAllowed === 'copy') || (effectAllowed === 'move') || (effectAllowed === 'link')) {
46
+ ariaDropEffect = effectAllowed;
47
+ } else {
48
+ ariaDropEffect = 'move';
49
+ }
50
+ } else {
51
+ ariaDropEffect = dropEffect;
52
+ }
53
+ droppedElements = __exports.__aria_dropeffect__elements__;
54
+ for (_i = 0, _len = droppedElements.length; _i < _len; _i++) {
55
+ droppedElement = droppedElements[_i];
56
+ if (hasEvent(droppedElement, 'drop')) {
57
+ droppedElement.setAttribute('aria-dropeffect', ariaDropEffect);
58
+ }
59
+ keyboardAccess(droppedElement);
60
+ }
61
+ };
62
+
63
+ executeMouseEvent = function(type, element, event) {
64
+ executeEvent(element, createMouseEvent(type, element, event));
65
+ };
66
+
67
+ executeDragEvent = function(type, element, event) {
68
+ if (isEmpty(__exports.__dragEventDataTransfer__)) {
69
+ __exports.__dragEventDataTransfer__ = {
70
+ 'files': null,
71
+ 'types': null,
72
+ 'effectAllowed': 'uninitialized',
73
+ 'dropEffect': 'none'
74
+ };
75
+ __exports.__dragEventDataTransfer__.setDragImage = function() {
76
+ };
77
+ __exports.__dragEventDataTransfer__.addElement = function() {
78
+ };
79
+ __exports.__dragEventDataTransfer__._data = {};
80
+ __exports.__dragEventDataTransfer__.setData = function(format, data) {
81
+ __exports.__dragEventDataTransfer__._data[format] = data;
82
+ };
83
+ __exports.__dragEventDataTransfer__.getData = function(format) {
84
+ return __exports.__dragEventDataTransfer__._data[format];
85
+ };
86
+ __exports.__dragEventDataTransfer__.clearData = function(format) {
87
+ if (isEmpty(format)) {
88
+ __exports.__dragEventDataTransfer__._data = {};
89
+ } else {
90
+ __exports.__dragEventDataTransfer__._data[format] = void 0;
91
+ }
92
+ };
93
+ }
94
+ executeEvent(element, createDragEvent(type, element, event));
95
+ };
96
+
97
+ executeEvent = function(element, event) {
98
+ var error, handlerEvent, listenerEvent, _i, _len, _ref;
99
+ if (hasEvent(element, event.type)) {
100
+ try {
101
+ if (!isEmpty(element.dispatchEvent)) {
102
+ element.dispatchEvent(event);
103
+ } else {
104
+ handlerEvent = element['on' + event.type];
105
+ if (!isEmpty(handlerEvent)) {
106
+ handlerEvent(event);
107
+ }
108
+ if ((!isEmpty(element.eventListenerList)) && (!isEmpty(element.eventListenerList[event.type]))) {
109
+ _ref = element.eventListenerList[event.type];
110
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
111
+ listenerEvent = _ref[_i];
112
+ listenerEvent(event);
113
+ }
114
+ }
115
+ }
116
+ } catch (_error) {
117
+ error = _error;
118
+ }
119
+ }
120
+ };
121
+
122
+ createMouseEvent = function(type, element, event) {
123
+ var data, mouseEvent;
124
+ data = {
125
+ 'view': event.view,
126
+ 'bubbles': true,
127
+ 'cancelable': true,
128
+ 'target': element,
129
+ 'altKey': event.altKey,
130
+ 'ctrlKey': event.ctrlKey,
131
+ 'cancelBubble': false,
132
+ 'isTrusted': true,
133
+ 'metaKey': false,
134
+ 'shiftKey': event.shiftKey,
135
+ 'clientX': 0,
136
+ 'clientY': 0,
137
+ 'pageX': 0,
138
+ 'pageY': 0,
139
+ 'screenX': 0,
140
+ 'screenY': 0
141
+ };
142
+ if (isEmpty(Event)) {
143
+ mouseEvent = data;
144
+ mouseEvent.type = type;
145
+ } else {
146
+ mouseEvent = new Event(type, data);
147
+ }
148
+ mouseEvent.preventDefault = function() {
149
+ return event.preventDefault();
150
+ };
151
+ mouseEvent.stopImmediatePropagation = function() {
152
+ return event.stopImmediatePropagation();
153
+ };
154
+ mouseEvent.stopPropagation = function() {
155
+ return event.stopPropagation();
156
+ };
157
+ return mouseEvent;
158
+ };
159
+
160
+ createDragEvent = function(type, element, event) {
161
+ var dragEvent;
162
+ dragEvent = createMouseEvent(type, element, event);
163
+ dragEvent.dataTransfer = __exports.__dragEventDataTransfer__;
164
+ return dragEvent;
165
+ };
166
+
167
+ fixActiveInElement = function(element) {
168
+ if (element.tagName.toUpperCase() !== 'A') {
169
+ addEventHandler(element, 'keypress', 'data-keypressadded', 'active', function(event) {
170
+ if (enterPressed(event.keyCode)) {
171
+ if (hasEvent(element, 'click')) {
172
+ executeMouseEvent('click', element, event);
173
+ } else if (hasEvent(element, 'dblclick')) {
174
+ executeMouseEvent('dblclick', element, event);
175
+ }
176
+ }
177
+ });
178
+ }
179
+ addEventHandler(element, 'keyup', 'data-keyupadded', 'active', function(event) {
180
+ if (enterPressed(event.keyCode)) {
181
+ executeMouseEvent('mouseup', element, event);
182
+ }
183
+ });
184
+ addEventHandler(element, 'keydown', 'data-keydownadded', 'active', function(event) {
185
+ if (enterPressed(event.keyCode)) {
186
+ executeMouseEvent('mousedown', element, event);
187
+ }
188
+ });
189
+ };
190
+
191
+ fixHoverInElement = function(element) {
192
+ addEventHandler(element, 'focus', 'data-focusadded', 'hover', function(event) {
193
+ executeMouseEvent('mouseover', element, event);
194
+ });
195
+ addEventHandler(element, 'blur', 'data-bluradded', 'hover', function(event) {
196
+ executeMouseEvent('mouseout', element, event);
197
+ });
198
+ };
199
+
200
+ fixDragInElement = function(element) {
201
+ if ((!hasEvent(element, 'keydown', 'data-keydownadded', 'drag')) && (!hasEvent(element, 'keyup', 'data-keyupadded', 'drag'))) {
202
+ addEventHandler(element, 'keydown', 'data-keydownadded', 'drag', function(event) {
203
+ var grabbedElement, grabbedElements, _i, _len;
204
+ if ((event.keyCode === ' '.charCodeAt(0)) && (!element.hasAttribute('data-keypressed'))) {
205
+ grabbedElements = __exports.__aria_grabbed__elements__;
206
+ for (_i = 0, _len = grabbedElements.length; _i < _len; _i++) {
207
+ grabbedElement = grabbedElements[_i];
208
+ grabbedElement.setAttribute('aria-grabbed', 'false');
209
+ executeDragEvent('dragend', grabbedElement, event);
210
+ }
211
+ element.setAttribute('aria-grabbed', 'true');
212
+ element.setAttribute('data-keypressed', 'true');
213
+ __exports.__aria_grabbed__elements__ = [element];
214
+ executeDragEvent('dragstart', element, event);
215
+ executeDragEvent('drag', element, event);
216
+ generateDropEffect();
217
+ }
218
+ });
219
+ addEventHandler(element, 'keyup', 'data-keyupadded', 'drag', function(event) {
220
+ element.removeAttribute('data-keypressed');
221
+ });
222
+ }
223
+ };
224
+
225
+ fixDropInElement = function(element) {
226
+ __exports.__aria_dropeffect__elements__.push(element);
227
+ addEventHandler(element, 'focus', 'data-focusadded', 'drop', function(event) {
228
+ if (!isEmpty(__exports.__aria_grabbed__elements__)) {
229
+ executeDragEvent('dragenter', element, event);
230
+ executeDragEvent('dragover', element, event);
231
+ generateDropEffect();
232
+ }
233
+ });
234
+ addEventHandler(element, 'blur', 'data-bluradded', 'drop', function(event) {
235
+ if (!isEmpty(__exports.__aria_grabbed__elements__)) {
236
+ executeDragEvent('dragleave', element, event);
237
+ generateDropEffect();
238
+ }
239
+ });
240
+ if ((!hasEvent(element, 'keydown', 'data-keydownadded', 'drop')) && (!hasEvent(element, 'keyup', 'data-keyupadded', 'drop'))) {
241
+ addEventHandler(element, 'keydown', 'data-keydownadded', 'drop', function(event) {
242
+ var grabbedElement, grabbedElements, _i, _len;
243
+ if ((enterPressed(event.keyCode)) && (!element.hasAttribute('data-keypressed')) && (!isEmpty(__exports.__aria_grabbed__elements__))) {
244
+ element.setAttribute('data-keypressed', 'true');
245
+ if (hasEvent(element, 'drop')) {
246
+ grabbedElements = __exports.__aria_grabbed__elements__;
247
+ for (_i = 0, _len = grabbedElements.length; _i < _len; _i++) {
248
+ grabbedElement = grabbedElements[_i];
249
+ grabbedElement.setAttribute('aria-grabbed', 'false');
250
+ executeDragEvent('dragend', grabbedElement, event);
251
+ }
252
+ __exports.__aria_grabbed__elements__ = [];
253
+ clearDropEffect();
254
+ }
255
+ executeDragEvent('drop', element, event);
256
+ }
257
+ });
258
+ addEventHandler(element, 'keyup', 'data-keyupadded', 'drop', function(event) {
259
+ element.removeAttribute('data-keypressed');
260
+ });
261
+ }
262
+ };
263
+
264
+ addEventHandler(document.documentElement, 'keypress', 'data-keypressadded', 'active', function(event) {
265
+ var grabbedElement, grabbedElements, _i, _len;
266
+ if (event.keyCode === 27) {
267
+ grabbedElements = __exports.__aria_grabbed__elements__;
268
+ for (_i = 0, _len = grabbedElements.length; _i < _len; _i++) {
269
+ grabbedElement = grabbedElements[_i];
270
+ grabbedElement.setAttribute('aria-grabbed', 'false');
271
+ executeDragEvent('dragend', grabbedElement, event);
272
+ }
273
+ __exports.__aria_grabbed__elements__ = [];
274
+ clearDropEffect();
275
+ }
276
+ });
277
+
278
+ for (var i = 0, length = activeElements.length; i < length; i++) {
279
+ fixActiveInElement(document.getElementById(activeElements[i]));
280
+ }
281
+
282
+ for (var i = 0, length = hoverElements.length; i < length; i++) {
283
+ fixHoverInElement(document.getElementById(hoverElements[i]));
284
+ }
285
+
286
+ for (var i = 0, length = dragElements.length; i < length; i++) {
287
+ fixDragInElement(document.getElementById(dragElements[i]));
288
+ }
289
+
290
+ for (var i = 0, length = dropElements.length; i < length; i++) {
291
+ fixDropInElement(document.getElementById(dropElements[i]));
292
+ }
@@ -0,0 +1,13 @@
1
+ var hatemileValidationList = {
2
+ 'required_fields': [],
3
+ 'pattern_fields': [],
4
+ 'fields_with_length': [],
5
+ 'range_fields': [],
6
+ 'week_fields': [],
7
+ 'month_fields': [],
8
+ 'datetime_fields': [],
9
+ 'time_fields': [],
10
+ 'date_fields': [],
11
+ 'email_fields': [],
12
+ 'url_fields': []
13
+ };
@@ -0,0 +1,205 @@
1
+ var DATA_IGNORE = 'data-ignoreaccessibilityfix';
2
+ var DATA_EVENT_CHANGE_ADDED = 'data-changeadded';
3
+ var DATA_INVALID_URL = 'data-invalidurl';
4
+ var DATA_INVALID_EMAIL = 'data-invalidemail';
5
+ var DATA_INVALID_RANGE = 'data-invalidrange';
6
+ var DATA_INVALID_LENGTH = 'data-invalidlength';
7
+ var DATA_INVALID_PATTERN = 'data-invalidpattern';
8
+ var DATA_INVALID_REQUIRED = 'data-invalidrequired';
9
+ var DATA_INVALID_DATE = 'data-invaliddate';
10
+ var DATA_INVALID_TIME = 'data-invalidtime';
11
+ var DATA_INVALID_DATETIME = 'data-invaliddatetime';
12
+ var DATA_INVALID_MONTH = 'data-invalidmonth';
13
+ var DATA_INVALID_WEEK = 'data-invalidweek';
14
+ var VALIDATION_TYPE = 'type';
15
+ var VALIDATION_REQUIRED = 'required';
16
+ var VALIDATION_PATTERN = 'pattern';
17
+ var VALIDATION_LENGTH = 'length';
18
+
19
+ var isValid = function (field) {
20
+ if (field.hasAttribute(DATA_INVALID_URL)) {
21
+ return false;
22
+ } else if (field.hasAttribute(DATA_INVALID_EMAIL)) {
23
+ return false;
24
+ } else if (field.hasAttribute(DATA_INVALID_RANGE)) {
25
+ return false;
26
+ } else if (field.hasAttribute(DATA_INVALID_LENGTH)) {
27
+ return false;
28
+ } else if (field.hasAttribute(DATA_INVALID_PATTERN)) {
29
+ return false;
30
+ } else if (field.hasAttribute(DATA_INVALID_REQUIRED)) {
31
+ return false;
32
+ } else if (field.hasAttribute(DATA_INVALID_DATE)) {
33
+ return false;
34
+ } else if (field.hasAttribute(DATA_INVALID_TIME)) {
35
+ return false;
36
+ } else if (field.hasAttribute(DATA_INVALID_DATETIME)) {
37
+ return false;
38
+ } else if (field.hasAttribute(DATA_INVALID_MONTH)) {
39
+ return false;
40
+ } else if (field.hasAttribute(DATA_INVALID_WEEK)) {
41
+ return false;
42
+ } else {
43
+ return true;
44
+ }
45
+ };
46
+
47
+ var validateNow = function (field, dataInvalid, validateFunction) {
48
+ if (validateFunction(field)) {
49
+ if (field.hasAttribute(dataInvalid)) {
50
+ field.removeAttribute(dataInvalid);
51
+ if ((field.hasAttribute('aria-invalid')) && (isValid(field))) {
52
+ field.removeAttribute('aria-invalid');
53
+ }
54
+ }
55
+ } else {
56
+ field.setAttribute(dataInvalid, 'true');
57
+ field.setAttribute('aria-invalid', 'true');
58
+ }
59
+ };
60
+
61
+ var validate = function (idField, dataInvalid, typeFix, validateFunction) {
62
+ var field = document.getElementById(idField);
63
+ validateNow(field, dataInvalid, validateFunction);
64
+ addEventHandler(field, 'change', DATA_EVENT_CHANGE_ADDED, typeFix, function (event) {
65
+ return validateNow(field, dataInvalid, validateFunction);
66
+ });
67
+ };
68
+
69
+ var isValidRegularExpression = function (value, pattern) {
70
+ var regularExpression;
71
+ regularExpression = new RegExp(pattern);
72
+ return regularExpression.test(value);
73
+ };
74
+
75
+ var isValidURL = function (field) {
76
+ return isEmpty(field.value) || isValidRegularExpression(field.value, '([a-zA-Z][a-zA-Z0-9\\+\\.\\-]*):(\\/\\/)?(?:(?:(?:[a-zA-Z0-9_\\.' + '\\-\\+!$&\'\\(\\)*\\+,;=]|%[0-9a-f]{2})+:)*(?:[a-zA-Z0-9_\\.\\-\\+' + '%!$&\'\\(\\)*\\+,;=]|%[0-9a-f]{2})+@)?(?:(?:[a-z0-9\\-\\.]|%' + '[0-9a-f]{2})+|(?:\\[(?:[0-9a-f]{0,4}:)*(?:[0-9a-f]{0,4})\\]))' + '(?::[0-9]+)?(?:[\\/|\\?](?:[a-zA-Z0-9_#!:\\.\\?\\+=&@!$\'~*,;\\/' + '\\(\\)\\[\\]\\-]|%[0-9a-f]{2})*)?');
77
+ };
78
+
79
+ var isValidEmail = function (field) {
80
+ var regularExpression;
81
+ regularExpression = '(?:[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&' + '\'*+\/=?^_`{|}~-]+)*|"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21' + '\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*")' + '@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*' + '[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}' + '(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:' + '[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|' + '\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])';
82
+ if (field.hasAttribute('multiple')) {
83
+ regularExpression = regularExpression + "( *, *" + regularExpression + ")*";
84
+ }
85
+ return isEmpty(field.value) || isValidRegularExpression(field.value, "^(" + regularExpression + ")?$");
86
+ };
87
+
88
+ var isValidDate = function (field) {
89
+ return isEmpty(field.value) || isValidRegularExpression(field.value, '^([0-9]{2}((((' + '[02468][048])|([13579][26]))-(02)-((0[1-9])|([12][0-9])))|' + '(([0-9]{2})-((02-((0[1-9])|(1[0-9])|(2[0-8])))|(((0[469])|(11))-' + '((0[1-9])|([12][0-9])|(30)))|(((0[13578])|(10)|(12))-((0[1-9])|' + '([12][0-9])|(3[01])))))))?$');
90
+ };
91
+
92
+ var isValidTime = function (field) {
93
+ return isEmpty(field.value) || isValidRegularExpression(field.value, '^((([01][0-9])|' + '(2[0-3])):[0-5][0-9])?$');
94
+ };
95
+
96
+ var isValidDateTime = function (field) {
97
+ return isEmpty(field.value) || isValidRegularExpression(field.value, '^([0-9]{2}((((' + '[02468][048])|([13579][26]))-(02)-((0[1-9])|([12][0-9])))|' + '(([0-9]{2})-((02-((0[1-9])|(1[0-9])|(2[0-8])))|(((0[469])|(11))-' + '((0[1-9])|([12][0-9])|(30)))|(((0[13578])|(10)|(12))-((0[1-9])|' + '([12][0-9])|(3[01]))))))T(([01][0-9])|(2[0-3])):[0-5][0-9]((:[0-5]' + '[0-9].[0-9])|(Z))?)?$');
98
+ };
99
+
100
+ var isValidMonth = function (field) {
101
+ return isEmpty(field.value) || isValidRegularExpression(field.value, '^([0-9]{4}-' + '((0[1-9])|(1[0-2])))?$');
102
+ };
103
+
104
+ var isValidWeek = function (field) {
105
+ return isEmpty(field.value) || isValidRegularExpression(field.value, '^([0-9]{4}-W' + '((0[1-9])|([1-4][0-9])|(5[0-3])))?$');
106
+ };
107
+
108
+ var isValidRange = function (field) {
109
+ var maxValue, minValue, value;
110
+ if (!isEmpty(field.value)) {
111
+ if (!isValidRegularExpression(field.value, '^[-+]?[0-9]+([.,][0-9]+)?$')) {
112
+ return false;
113
+ }
114
+ value = parseFloat(field.value);
115
+ if (field.hasAttribute('min') || field.hasAttribute('aria-valuemin')) {
116
+ if (field.hasAttribute('min')) {
117
+ minValue = parseFloat(field.getAttribute('min'));
118
+ } else if (field.hasAttribute('aria-valuemin')) {
119
+ minValue = parseFloat(field.getAttribute('aria-valuemin'));
120
+ }
121
+ if (value < minValue) {
122
+ return false;
123
+ }
124
+ }
125
+ if (field.hasAttribute('max') || field.hasAttribute('aria-valuemax')) {
126
+ if (field.hasAttribute('max')) {
127
+ maxValue = parseFloat(field.getAttribute('max'));
128
+ } else if (field.hasAttribute('aria-valuemax')) {
129
+ maxValue = parseFloat(field.getAttribute('aria-valuemax'));
130
+ }
131
+ if (value > maxValue) {
132
+ return false;
133
+ }
134
+ }
135
+ }
136
+ return true;
137
+ };
138
+
139
+ var isValidLength = function (field) {
140
+ if (field.hasAttribute('minlength')) {
141
+ if (field.value.length < parseInt(field.getAttribute('minlength'))) {
142
+ return false;
143
+ }
144
+ }
145
+ if (field.hasAttribute('maxlength')) {
146
+ if (field.value.length > parseInt(field.getAttribute('maxlength'))) {
147
+ return false;
148
+ }
149
+ }
150
+ return true;
151
+ };
152
+
153
+ var isValidPattern = function (field) {
154
+ return isValidRegularExpression(field.value, field.getAttribute('pattern'));
155
+ };
156
+
157
+ var isValidRequired = function (field) {
158
+ return !isEmpty(field.value);
159
+ };
160
+
161
+ window.addEventListener('load', function() {
162
+ for (var i = 0, length = hatemileValidationList.required_fields.length; i < length; i++) {
163
+ validate(hatemileValidationList.required_fields[i], DATA_INVALID_REQUIRED, VALIDATION_REQUIRED, isValidRequired);
164
+ }
165
+
166
+ for (var i = 0, length = hatemileValidationList.pattern_fields.length; i < length; i++) {
167
+ validate(hatemileValidationList.pattern_fields[i], DATA_INVALID_PATTERN, VALIDATION_PATTERN, isValidPattern);
168
+ }
169
+
170
+ for (var i = 0, length = hatemileValidationList.fields_with_length.length; i < length; i++) {
171
+ validate(hatemileValidationList.fields_with_length[i], DATA_INVALID_LENGTH, VALIDATION_LENGTH, isValidLength);
172
+ }
173
+
174
+ for (var i = 0, length = hatemileValidationList.range_fields.length; i < length; i++) {
175
+ validate(hatemileValidationList.range_fields[i], DATA_INVALID_RANGE, VALIDATION_TYPE, isValidRange);
176
+ }
177
+
178
+ for (var i = 0, length = hatemileValidationList.week_fields.length; i < length; i++) {
179
+ validate(hatemileValidationList.week_fields[i], DATA_INVALID_WEEK, VALIDATION_TYPE, isValidWeek);
180
+ }
181
+
182
+ for (var i = 0, length = hatemileValidationList.month_fields.length; i < length; i++) {
183
+ validate(hatemileValidationList.month_fields[i], DATA_INVALID_MONTH, VALIDATION_TYPE, isValidMonth);
184
+ }
185
+
186
+ for (var i = 0, length = hatemileValidationList.datetime_fields.length; i < length; i++) {
187
+ validate(hatemileValidationList.datetime_fields[i], DATA_INVALID_DATETIME, VALIDATION_TYPE, isValidDateTime);
188
+ }
189
+
190
+ for (var i = 0, length = hatemileValidationList.time_fields.length; i < length; i++) {
191
+ validate(hatemileValidationList.time_fields[i], DATA_INVALID_TIME, VALIDATION_TYPE, isValidTime);
192
+ }
193
+
194
+ for (var i = 0, length = hatemileValidationList.date_fields.length; i < length; i++) {
195
+ validate(hatemileValidationList.date_fields[i], DATA_INVALID_DATE, VALIDATION_TYPE, isValidDate);
196
+ }
197
+
198
+ for (var i = 0, length = hatemileValidationList.email_fields.length; i < length; i++) {
199
+ validate(hatemileValidationList.email_fields[i], DATA_INVALID_EMAIL, VALIDATION_TYPE, isValidEmail);
200
+ }
201
+
202
+ for (var i = 0, length = hatemileValidationList.url_fields.length; i < length; i++) {
203
+ validate(hatemileValidationList.url_fields[i], DATA_INVALID_URL, VALIDATION_TYPE, isValidURL);
204
+ }
205
+ });