rails-active-ui 0.3.0 → 0.3.2

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 (197) hide show
  1. checksums.yaml +4 -4
  2. data/app/javascript/ui/controllers/turbo_modal_controller.js +36 -0
  3. data/config/importmap.rb +1 -0
  4. data/formantic-ui/components/accordion.css +369 -0
  5. data/formantic-ui/components/accordion.js +595 -0
  6. data/formantic-ui/components/accordion.min.css +9 -0
  7. data/formantic-ui/components/accordion.min.js +11 -0
  8. data/formantic-ui/components/ad.css +264 -0
  9. data/formantic-ui/components/ad.min.css +10 -0
  10. data/formantic-ui/components/api.js +1225 -0
  11. data/formantic-ui/components/api.min.js +11 -0
  12. data/formantic-ui/components/breadcrumb.css +135 -0
  13. data/formantic-ui/components/breadcrumb.min.css +9 -0
  14. data/formantic-ui/components/button.css +4058 -0
  15. data/formantic-ui/components/button.min.css +9 -0
  16. data/formantic-ui/components/calendar.css +327 -0
  17. data/formantic-ui/components/calendar.js +2045 -0
  18. data/formantic-ui/components/calendar.min.css +9 -0
  19. data/formantic-ui/components/calendar.min.js +11 -0
  20. data/formantic-ui/components/card.css +1881 -0
  21. data/formantic-ui/components/card.min.css +9 -0
  22. data/formantic-ui/components/checkbox.css +785 -0
  23. data/formantic-ui/components/checkbox.js +888 -0
  24. data/formantic-ui/components/checkbox.min.css +9 -0
  25. data/formantic-ui/components/checkbox.min.js +11 -0
  26. data/formantic-ui/components/comment.css +283 -0
  27. data/formantic-ui/components/comment.min.css +9 -0
  28. data/formantic-ui/components/container.css +300 -0
  29. data/formantic-ui/components/container.min.css +9 -0
  30. data/formantic-ui/components/dimmer.css +367 -0
  31. data/formantic-ui/components/dimmer.js +732 -0
  32. data/formantic-ui/components/dimmer.min.css +9 -0
  33. data/formantic-ui/components/dimmer.min.js +11 -0
  34. data/formantic-ui/components/divider.css +287 -0
  35. data/formantic-ui/components/divider.min.css +9 -0
  36. data/formantic-ui/components/dropdown.css +2087 -0
  37. data/formantic-ui/components/dropdown.js +4432 -0
  38. data/formantic-ui/components/dropdown.min.css +9 -0
  39. data/formantic-ui/components/dropdown.min.js +11 -0
  40. data/formantic-ui/components/embed.css +155 -0
  41. data/formantic-ui/components/embed.js +688 -0
  42. data/formantic-ui/components/embed.min.css +9 -0
  43. data/formantic-ui/components/embed.min.js +11 -0
  44. data/formantic-ui/components/emoji.css +15311 -0
  45. data/formantic-ui/components/emoji.min.css +9 -0
  46. data/formantic-ui/components/feed.css +799 -0
  47. data/formantic-ui/components/feed.min.css +9 -0
  48. data/formantic-ui/components/flag.css +1149 -0
  49. data/formantic-ui/components/flag.min.css +9 -0
  50. data/formantic-ui/components/flyout.css +546 -0
  51. data/formantic-ui/components/flyout.js +1551 -0
  52. data/formantic-ui/components/flyout.min.css +9 -0
  53. data/formantic-ui/components/flyout.min.js +11 -0
  54. data/formantic-ui/components/form.css +1885 -0
  55. data/formantic-ui/components/form.js +2199 -0
  56. data/formantic-ui/components/form.min.css +9 -0
  57. data/formantic-ui/components/form.min.js +11 -0
  58. data/formantic-ui/components/grid.css +1952 -0
  59. data/formantic-ui/components/grid.min.css +9 -0
  60. data/formantic-ui/components/header.css +778 -0
  61. data/formantic-ui/components/header.min.css +9 -0
  62. data/formantic-ui/components/icon.css +7066 -0
  63. data/formantic-ui/components/icon.min.css +9 -0
  64. data/formantic-ui/components/image.css +315 -0
  65. data/formantic-ui/components/image.min.css +9 -0
  66. data/formantic-ui/components/input.css +1566 -0
  67. data/formantic-ui/components/input.min.css +9 -0
  68. data/formantic-ui/components/item.css +534 -0
  69. data/formantic-ui/components/item.min.css +9 -0
  70. data/formantic-ui/components/label.css +2114 -0
  71. data/formantic-ui/components/label.min.css +9 -0
  72. data/formantic-ui/components/list.css +955 -0
  73. data/formantic-ui/components/list.min.css +9 -0
  74. data/formantic-ui/components/loader.css +787 -0
  75. data/formantic-ui/components/loader.min.css +9 -0
  76. data/formantic-ui/components/menu.css +2131 -0
  77. data/formantic-ui/components/menu.min.css +9 -0
  78. data/formantic-ui/components/message.css +619 -0
  79. data/formantic-ui/components/message.min.css +9 -0
  80. data/formantic-ui/components/modal.css +779 -0
  81. data/formantic-ui/components/modal.js +1637 -0
  82. data/formantic-ui/components/modal.min.css +9 -0
  83. data/formantic-ui/components/modal.min.js +11 -0
  84. data/formantic-ui/components/nag.css +290 -0
  85. data/formantic-ui/components/nag.js +566 -0
  86. data/formantic-ui/components/nag.min.css +9 -0
  87. data/formantic-ui/components/nag.min.js +11 -0
  88. data/formantic-ui/components/placeholder.css +228 -0
  89. data/formantic-ui/components/placeholder.min.css +9 -0
  90. data/formantic-ui/components/popup.css +1184 -0
  91. data/formantic-ui/components/popup.js +1561 -0
  92. data/formantic-ui/components/popup.min.css +9 -0
  93. data/formantic-ui/components/popup.min.js +11 -0
  94. data/formantic-ui/components/progress.css +761 -0
  95. data/formantic-ui/components/progress.js +979 -0
  96. data/formantic-ui/components/progress.min.css +9 -0
  97. data/formantic-ui/components/progress.min.js +11 -0
  98. data/formantic-ui/components/rail.css +147 -0
  99. data/formantic-ui/components/rail.min.css +9 -0
  100. data/formantic-ui/components/rating.css +414 -0
  101. data/formantic-ui/components/rating.js +540 -0
  102. data/formantic-ui/components/rating.min.css +9 -0
  103. data/formantic-ui/components/rating.min.js +11 -0
  104. data/formantic-ui/components/reset.css +386 -0
  105. data/formantic-ui/components/reset.min.css +9 -0
  106. data/formantic-ui/components/reveal.css +277 -0
  107. data/formantic-ui/components/reveal.min.css +9 -0
  108. data/formantic-ui/components/search.css +541 -0
  109. data/formantic-ui/components/search.js +1641 -0
  110. data/formantic-ui/components/search.min.css +9 -0
  111. data/formantic-ui/components/search.min.js +11 -0
  112. data/formantic-ui/components/segment.css +1053 -0
  113. data/formantic-ui/components/segment.min.css +9 -0
  114. data/formantic-ui/components/shape.css +144 -0
  115. data/formantic-ui/components/shape.js +797 -0
  116. data/formantic-ui/components/shape.min.css +9 -0
  117. data/formantic-ui/components/shape.min.js +11 -0
  118. data/formantic-ui/components/sidebar.css +539 -0
  119. data/formantic-ui/components/sidebar.js +1054 -0
  120. data/formantic-ui/components/sidebar.min.css +9 -0
  121. data/formantic-ui/components/sidebar.min.js +11 -0
  122. data/formantic-ui/components/site.css +286 -0
  123. data/formantic-ui/components/site.js +455 -0
  124. data/formantic-ui/components/site.min.css +9 -0
  125. data/formantic-ui/components/site.min.js +11 -0
  126. data/formantic-ui/components/slider.css +926 -0
  127. data/formantic-ui/components/slider.js +1546 -0
  128. data/formantic-ui/components/slider.min.css +9 -0
  129. data/formantic-ui/components/slider.min.js +11 -0
  130. data/formantic-ui/components/state.js +697 -0
  131. data/formantic-ui/components/state.min.js +11 -0
  132. data/formantic-ui/components/statistic.css +586 -0
  133. data/formantic-ui/components/statistic.min.css +9 -0
  134. data/formantic-ui/components/step.css +1538 -0
  135. data/formantic-ui/components/step.min.css +9 -0
  136. data/formantic-ui/components/sticky.css +73 -0
  137. data/formantic-ui/components/sticky.js +917 -0
  138. data/formantic-ui/components/sticky.min.css +9 -0
  139. data/formantic-ui/components/sticky.min.js +11 -0
  140. data/formantic-ui/components/tab.css +84 -0
  141. data/formantic-ui/components/tab.js +967 -0
  142. data/formantic-ui/components/tab.min.css +9 -0
  143. data/formantic-ui/components/tab.min.js +11 -0
  144. data/formantic-ui/components/table.css +3473 -0
  145. data/formantic-ui/components/table.min.css +9 -0
  146. data/formantic-ui/components/text.css +155 -0
  147. data/formantic-ui/components/text.min.css +9 -0
  148. data/formantic-ui/components/toast.css +751 -0
  149. data/formantic-ui/components/toast.js +964 -0
  150. data/formantic-ui/components/toast.min.css +9 -0
  151. data/formantic-ui/components/toast.min.js +11 -0
  152. data/formantic-ui/components/transition.css +1148 -0
  153. data/formantic-ui/components/transition.js +1034 -0
  154. data/formantic-ui/components/transition.min.css +9 -0
  155. data/formantic-ui/components/transition.min.js +11 -0
  156. data/formantic-ui/components/visibility.js +1292 -0
  157. data/formantic-ui/components/visibility.min.js +11 -0
  158. data/formantic-ui/semantic.css +78485 -0
  159. data/formantic-ui/semantic.js +31036 -0
  160. data/formantic-ui/semantic.min.css +11 -0
  161. data/formantic-ui/semantic.min.js +11 -0
  162. data/formantic-ui/themes/basic/assets/fonts/LICENSE.txt +91 -0
  163. data/formantic-ui/themes/basic/assets/fonts/icons.woff +0 -0
  164. data/formantic-ui/themes/basic/assets/fonts/icons.woff2 +0 -0
  165. data/formantic-ui/themes/default/assets/fonts/LICENSE_Lato.txt +94 -0
  166. data/formantic-ui/themes/default/assets/fonts/LICENSE_icons.txt +165 -0
  167. data/formantic-ui/themes/default/assets/fonts/Lato-Bold.woff +0 -0
  168. data/formantic-ui/themes/default/assets/fonts/Lato-Bold.woff2 +0 -0
  169. data/formantic-ui/themes/default/assets/fonts/Lato-BoldItalic.woff +0 -0
  170. data/formantic-ui/themes/default/assets/fonts/Lato-BoldItalic.woff2 +0 -0
  171. data/formantic-ui/themes/default/assets/fonts/Lato-Italic.woff +0 -0
  172. data/formantic-ui/themes/default/assets/fonts/Lato-Italic.woff2 +0 -0
  173. data/formantic-ui/themes/default/assets/fonts/Lato-Regular.woff +0 -0
  174. data/formantic-ui/themes/default/assets/fonts/Lato-Regular.woff2 +0 -0
  175. data/formantic-ui/themes/default/assets/fonts/LatoLatin-Bold.woff +0 -0
  176. data/formantic-ui/themes/default/assets/fonts/LatoLatin-Bold.woff2 +0 -0
  177. data/formantic-ui/themes/default/assets/fonts/LatoLatin-BoldItalic.woff +0 -0
  178. data/formantic-ui/themes/default/assets/fonts/LatoLatin-BoldItalic.woff2 +0 -0
  179. data/formantic-ui/themes/default/assets/fonts/LatoLatin-Italic.woff +0 -0
  180. data/formantic-ui/themes/default/assets/fonts/LatoLatin-Italic.woff2 +0 -0
  181. data/formantic-ui/themes/default/assets/fonts/LatoLatin-Regular.woff +0 -0
  182. data/formantic-ui/themes/default/assets/fonts/LatoLatin-Regular.woff2 +0 -0
  183. data/formantic-ui/themes/default/assets/fonts/brand-icons.woff +0 -0
  184. data/formantic-ui/themes/default/assets/fonts/brand-icons.woff2 +0 -0
  185. data/formantic-ui/themes/default/assets/fonts/icons.woff +0 -0
  186. data/formantic-ui/themes/default/assets/fonts/icons.woff2 +0 -0
  187. data/formantic-ui/themes/default/assets/fonts/outline-icons.woff +0 -0
  188. data/formantic-ui/themes/default/assets/fonts/outline-icons.woff2 +0 -0
  189. data/formantic-ui/themes/famfamfam/assets/images/flags.png +0 -0
  190. data/formantic-ui/themes/github/assets/fonts/LICENSE.txt +94 -0
  191. data/formantic-ui/themes/github/assets/fonts/octicons.woff +0 -0
  192. data/formantic-ui/themes/github/assets/fonts/octicons.woff2 +0 -0
  193. data/formantic-ui/themes/material/assets/fonts/LICENSE.txt +202 -0
  194. data/formantic-ui/themes/material/assets/fonts/icons.woff +0 -0
  195. data/formantic-ui/themes/material/assets/fonts/icons.woff2 +0 -0
  196. data/lib/ui/version.rb +1 -1
  197. metadata +194 -1
@@ -0,0 +1,1225 @@
1
+ /*!
2
+ * # Fomantic-UI 2.9.4 - API
3
+ * https://github.com/fomantic/Fomantic-UI/
4
+ *
5
+ *
6
+ * Released under the MIT license
7
+ * https://opensource.org/licenses/MIT
8
+ *
9
+ */
10
+
11
+ (function ($, window, document) {
12
+ 'use strict';
13
+
14
+ function isWindow(obj) {
15
+ return obj !== null && obj === obj.window;
16
+ }
17
+
18
+ function isFunction(obj) {
19
+ return typeof obj === 'function' && typeof obj.nodeType !== 'number';
20
+ }
21
+
22
+ window = window !== undefined && window.Math === Math
23
+ ? window
24
+ : globalThis;
25
+
26
+ $.fn.api = function (parameters) {
27
+ var
28
+ // use window context if none specified
29
+ $allModules = isFunction(this)
30
+ ? $(window)
31
+ : $(this),
32
+ time = Date.now(),
33
+ performance = [],
34
+
35
+ query = arguments[0],
36
+ methodInvoked = typeof query === 'string',
37
+ queryArguments = [].slice.call(arguments, 1),
38
+ contextCheck = function (context, win) {
39
+ var $context;
40
+ if ([window, document].indexOf(context) >= 0) {
41
+ $context = $(context);
42
+ } else {
43
+ $context = $(win.document).find(context);
44
+ if ($context.length === 0) {
45
+ $context = win.frameElement ? contextCheck(context, win.parent) : window;
46
+ }
47
+ }
48
+
49
+ return $context;
50
+ },
51
+ returnedValue
52
+ ;
53
+
54
+ $allModules.each(function () {
55
+ var
56
+ settings = $.isPlainObject(parameters)
57
+ ? $.extend(true, {}, $.fn.api.settings, parameters)
58
+ : $.extend({}, $.fn.api.settings),
59
+
60
+ // internal aliases
61
+ regExp = settings.regExp,
62
+ namespace = settings.namespace,
63
+ metadata = settings.metadata,
64
+ selector = settings.selector,
65
+ error = settings.error,
66
+ className = settings.className,
67
+
68
+ // define namespaces for modules
69
+ eventNamespace = '.' + namespace,
70
+ moduleNamespace = 'module-' + namespace,
71
+
72
+ // element that creates request
73
+ $module = $(this),
74
+ $form = $module.closest(selector.form),
75
+
76
+ // context used for state
77
+ $context = settings.stateContext ? contextCheck(settings.stateContext, window) : $module,
78
+
79
+ // request details
80
+ ajaxSettings,
81
+ requestSettings,
82
+ url,
83
+ data,
84
+ requestStartTime,
85
+ originalData,
86
+
87
+ // standard module
88
+ element = this,
89
+ context = $context[0],
90
+ instance = $module.data(moduleNamespace),
91
+ module
92
+ ;
93
+
94
+ module = {
95
+
96
+ initialize: function () {
97
+ if (!methodInvoked) {
98
+ originalData = settings.data;
99
+ module.bind.events();
100
+ }
101
+ module.instantiate();
102
+ },
103
+
104
+ instantiate: function () {
105
+ module.verbose('Storing instance of module', module);
106
+ instance = module;
107
+ $module
108
+ .data(moduleNamespace, instance)
109
+ ;
110
+ },
111
+
112
+ destroy: function () {
113
+ module.verbose('Destroying previous module for', element);
114
+ $module
115
+ .removeData(moduleNamespace)
116
+ .off(eventNamespace)
117
+ ;
118
+ },
119
+
120
+ bind: {
121
+ events: function () {
122
+ var
123
+ triggerEvent = module.get.event()
124
+ ;
125
+ if (triggerEvent) {
126
+ module.verbose('Attaching API events to element', triggerEvent);
127
+ $module
128
+ .on(triggerEvent + eventNamespace, module.event.trigger)
129
+ ;
130
+ } else if (settings.on === 'now') {
131
+ module.debug('Querying API endpoint immediately');
132
+ module.query();
133
+ }
134
+ },
135
+ },
136
+
137
+ decode: {
138
+ json: function (response) {
139
+ if (response !== undefined && typeof response === 'string') {
140
+ try {
141
+ response = JSON.parse(response);
142
+ } catch (e) {
143
+ // isn't json string
144
+ }
145
+ }
146
+
147
+ return response;
148
+ },
149
+ },
150
+
151
+ read: {
152
+ cachedResponse: function (url) {
153
+ var
154
+ response
155
+ ;
156
+ if (window.Storage === undefined) {
157
+ module.error(error.noStorage);
158
+
159
+ return;
160
+ }
161
+ response = sessionStorage.getItem(url + module.get.normalizedData());
162
+ module.debug('Using cached response', url, settings.data, response);
163
+ response = module.decode.json(response);
164
+
165
+ return response;
166
+ },
167
+ },
168
+ write: {
169
+ cachedResponse: function (url, response) {
170
+ if (window.Storage === undefined) {
171
+ module.error(error.noStorage);
172
+
173
+ return;
174
+ }
175
+ if ($.isPlainObject(response)) {
176
+ response = JSON.stringify(response);
177
+ }
178
+ sessionStorage.setItem(url + module.get.normalizedData(), response);
179
+ module.verbose('Storing cached response for url', url, settings.data, response);
180
+ },
181
+ },
182
+
183
+ query: function () {
184
+ if (module.is.disabled()) {
185
+ module.debug('Element is disabled API request aborted');
186
+
187
+ return;
188
+ }
189
+
190
+ if (module.is.loading()) {
191
+ if (settings.interruptRequests) {
192
+ module.debug('Interrupting previous request');
193
+ module.abort();
194
+ } else {
195
+ module.debug('Cancelling request, previous request is still pending');
196
+
197
+ return;
198
+ }
199
+ }
200
+
201
+ // pass element metadata to url (value, text)
202
+ if (settings.defaultData) {
203
+ $.extend(true, settings.urlData, module.get.defaultData());
204
+ }
205
+
206
+ // Add form content
207
+ if (settings.serializeForm) {
208
+ settings.data = module.add.formData(originalData || settings.data);
209
+ }
210
+
211
+ // call beforesend and get any settings changes
212
+ requestSettings = module.get.settings();
213
+
214
+ // check if before send cancelled request
215
+ if (requestSettings === false) {
216
+ module.cancelled = true;
217
+ module.error(error.beforeSend);
218
+
219
+ return;
220
+ }
221
+
222
+ module.cancelled = false;
223
+
224
+ // get url
225
+ url = module.get.templatedURL();
226
+
227
+ if (!url && !module.is.mocked()) {
228
+ module.error(error.missingURL);
229
+
230
+ return;
231
+ }
232
+
233
+ // replace variables
234
+ url = module.add.urlData(url);
235
+ // missing url parameters
236
+ if (!url && !module.is.mocked()) {
237
+ return;
238
+ }
239
+
240
+ requestSettings.url = settings.base + url;
241
+
242
+ // look for jQuery ajax parameters in settings
243
+ ajaxSettings = $.extend(true, {}, settings, {
244
+ type: settings.method || settings.type,
245
+ data: data,
246
+ url: settings.base + url,
247
+ beforeSend: settings.beforeXHR,
248
+ success: function () {},
249
+ failure: function () {},
250
+ complete: function () {},
251
+ });
252
+
253
+ module.debug('Querying URL', ajaxSettings.url);
254
+ module.verbose('Using AJAX settings', ajaxSettings);
255
+ if (settings.cache === 'local' && module.read.cachedResponse(url)) {
256
+ module.debug('Response returned from local cache');
257
+ module.request = module.create.request();
258
+ module.request.resolveWith(context, [module.read.cachedResponse(url)]);
259
+
260
+ return;
261
+ }
262
+
263
+ if (!settings.throttle) {
264
+ module.debug('Sending request', data, ajaxSettings.method);
265
+ module.send.request();
266
+ } else {
267
+ if (!settings.throttleFirstRequest && !module.timer) {
268
+ module.debug('Sending request', data, ajaxSettings.method);
269
+ module.send.request();
270
+ module.timer = setTimeout(function () {}, settings.throttle);
271
+ } else {
272
+ module.debug('Throttling request', settings.throttle);
273
+ clearTimeout(module.timer);
274
+ module.timer = setTimeout(function () {
275
+ if (module.timer) {
276
+ delete module.timer;
277
+ }
278
+ module.debug('Sending throttled request', data, ajaxSettings.method);
279
+ module.send.request();
280
+ }, settings.throttle);
281
+ }
282
+ }
283
+ },
284
+
285
+ should: {
286
+ removeError: function () {
287
+ return settings.hideError === true || (settings.hideError === 'auto' && !module.is.form());
288
+ },
289
+ },
290
+
291
+ is: {
292
+ disabled: function () {
293
+ return $module.filter(selector.disabled).length > 0;
294
+ },
295
+ expectingJSON: function () {
296
+ return settings.dataType === 'json' || settings.dataType === 'jsonp';
297
+ },
298
+ form: function () {
299
+ return $module.is('form') || $context.is('form');
300
+ },
301
+ mocked: function () {
302
+ return settings.mockResponse || settings.mockResponseAsync || settings.response || settings.responseAsync;
303
+ },
304
+ input: function () {
305
+ return $module.is('input');
306
+ },
307
+ loading: function () {
308
+ return module.request
309
+ ? module.request.state() === 'pending'
310
+ : false;
311
+ },
312
+ abortedRequest: function (xhr) {
313
+ if (xhr && xhr.readyState !== undefined && xhr.readyState === 0) {
314
+ module.verbose('XHR request determined to be aborted');
315
+
316
+ return true;
317
+ }
318
+
319
+ module.verbose('XHR request was not aborted');
320
+
321
+ return false;
322
+ },
323
+ validResponse: function (response) {
324
+ if (!module.is.expectingJSON() || !isFunction(settings.successTest)) {
325
+ module.verbose('Response is not JSON, skipping validation', settings.successTest, response);
326
+
327
+ return true;
328
+ }
329
+ module.debug('Checking JSON returned success', settings.successTest, response);
330
+ if (settings.successTest(response)) {
331
+ module.debug('Response passed success test', response);
332
+
333
+ return true;
334
+ }
335
+
336
+ module.debug('Response failed success test', response);
337
+
338
+ return false;
339
+ },
340
+ },
341
+
342
+ was: {
343
+ cancelled: function () {
344
+ return module.cancelled || false;
345
+ },
346
+ successful: function () {
347
+ return module.request && module.request.state() === 'resolved';
348
+ },
349
+ failure: function () {
350
+ return module.request && module.request.state() === 'rejected';
351
+ },
352
+ complete: function () {
353
+ return module.request && (module.request.state() === 'resolved' || module.request.state() === 'rejected');
354
+ },
355
+ },
356
+
357
+ add: {
358
+ urlData: function (url, urlData) {
359
+ var
360
+ requiredVariables,
361
+ optionalVariables
362
+ ;
363
+ if (url) {
364
+ requiredVariables = url.match(regExp.required);
365
+ optionalVariables = url.match(regExp.optional);
366
+ urlData = urlData || settings.urlData;
367
+ if (requiredVariables) {
368
+ module.debug('Looking for required URL variables', requiredVariables);
369
+ $.each(requiredVariables, function (index, templatedString) {
370
+ var
371
+ // allow legacy {$var} style
372
+ variable = templatedString.indexOf('$') !== -1
373
+ ? templatedString.slice(2, -1)
374
+ : templatedString.slice(1, -1),
375
+ value = $.isPlainObject(urlData) && urlData[variable] !== undefined
376
+ ? urlData[variable]
377
+ : ($module.data(variable) !== undefined
378
+ ? $module.data(variable)
379
+ : ($context.data(variable) !== undefined // eslint-disable-line unicorn/no-nested-ternary
380
+ ? $context.data(variable)
381
+ : urlData[variable]))
382
+ ;
383
+ // remove value
384
+ if (value === undefined) {
385
+ module.error(error.requiredParameter, variable, url);
386
+ url = false;
387
+
388
+ return false;
389
+ }
390
+
391
+ module.verbose('Found required variable', variable, value);
392
+ value = settings.encodeParameters
393
+ ? module.get.urlEncodedValue(value)
394
+ : value;
395
+ url = url.replace(templatedString, value);
396
+ });
397
+ }
398
+ if (optionalVariables) {
399
+ module.debug('Looking for optional URL variables', requiredVariables);
400
+ $.each(optionalVariables, function (index, templatedString) {
401
+ var
402
+ // allow legacy {/$var} style
403
+ variable = templatedString.indexOf('$') !== -1
404
+ ? templatedString.slice(3, -1)
405
+ : templatedString.slice(2, -1),
406
+ value = $.isPlainObject(urlData) && urlData[variable] !== undefined
407
+ ? urlData[variable]
408
+ : ($module.data(variable) !== undefined
409
+ ? $module.data(variable)
410
+ : ($context.data(variable) !== undefined // eslint-disable-line unicorn/no-nested-ternary
411
+ ? $context.data(variable)
412
+ : urlData[variable]))
413
+ ;
414
+ // optional replacement
415
+ if (value !== undefined) {
416
+ module.verbose('Optional variable Found', variable, value);
417
+ url = url.replace(templatedString, value);
418
+ } else {
419
+ module.verbose('Optional variable not found', variable);
420
+ // remove preceding slash if set
421
+ url = url.indexOf('/' + templatedString) !== -1
422
+ ? url.replace('/' + templatedString, '')
423
+ : url.replace(templatedString, '');
424
+ }
425
+ });
426
+ }
427
+ }
428
+
429
+ return url;
430
+ },
431
+ formData: function (data) {
432
+ var
433
+ formData = {},
434
+ hasOtherData,
435
+ useFormDataApi = settings.serializeForm === 'formdata'
436
+ ;
437
+ data = data || originalData || settings.data;
438
+ hasOtherData = $.isPlainObject(data);
439
+
440
+ if (useFormDataApi) {
441
+ formData = new FormData($form[0]);
442
+ settings.processData = settings.processData !== undefined ? settings.processData : false;
443
+ settings.contentType = settings.contentType !== undefined ? settings.contentType : false;
444
+ } else {
445
+ var
446
+ formArray = $form.serializeArray(),
447
+ pushes = {},
448
+ pushValues = {},
449
+ build = function (base, key, value) {
450
+ base[key] = value;
451
+
452
+ return base;
453
+ }
454
+ ;
455
+ // add files
456
+ $.each($('input[type="file"]', $form), function (i, tag) {
457
+ $.each($(tag)[0].files, function (j, file) {
458
+ formArray.push({ name: tag.name, value: file });
459
+ });
460
+ });
461
+ $.each(formArray, function (i, el) {
462
+ if (!regExp.validate.test(el.name)) {
463
+ return;
464
+ }
465
+ var
466
+ isCheckbox = $('[name="' + el.name + '"]', $form).attr('type') === 'checkbox',
467
+ floatValue = parseFloat(el.value),
468
+ value = (isCheckbox && el.value === 'on')
469
+ || el.value === 'true'
470
+ || (String(floatValue) === el.value
471
+ ? floatValue
472
+ : (el.value === 'false' ? false : el.value)),
473
+ nameKeys = el.name.match(regExp.key) || [],
474
+ pushKey = el.name.replace(/\[]$/, '')
475
+ ;
476
+ if (!(pushKey in pushes)) {
477
+ pushes[pushKey] = 0;
478
+ pushValues[pushKey] = value;
479
+ } else if (Array.isArray(pushValues[pushKey])) {
480
+ pushValues[pushKey].push(value);
481
+ } else {
482
+ pushValues[pushKey] = [pushValues[pushKey], value];
483
+ }
484
+ if (pushKey.indexOf('[]') === -1) {
485
+ value = pushValues[pushKey];
486
+ }
487
+
488
+ while (nameKeys.length > 0) {
489
+ var k = nameKeys.pop();
490
+
491
+ if (k === '' && !Array.isArray(value)) { // foo[]
492
+ value = build([], pushes[pushKey]++, value);
493
+ } else if (regExp.fixed.test(k)) { // foo[n]
494
+ value = build([], k, value);
495
+ } else if (regExp.named.test(k)) { // foo; foo[bar]
496
+ value = build({}, k, value);
497
+ }
498
+ }
499
+ formData = $.extend(true, formData, value);
500
+ });
501
+ }
502
+
503
+ if (hasOtherData) {
504
+ module.debug('Extending existing data with form data', data, formData);
505
+ if (useFormDataApi) {
506
+ $.each(Object.keys(data), function (i, el) {
507
+ formData.append(el, data[el]);
508
+ });
509
+ data = formData;
510
+ } else {
511
+ data = $.extend(true, {}, data, formData);
512
+ }
513
+ } else {
514
+ module.debug('Adding form data', formData);
515
+ data = formData;
516
+ }
517
+
518
+ return data;
519
+ },
520
+ },
521
+
522
+ send: {
523
+ request: function () {
524
+ module.set.loading();
525
+ module.request = module.create.request();
526
+ if (module.is.mocked()) {
527
+ module.mockedXHR = module.create.mockedXHR();
528
+ } else {
529
+ module.xhr = module.create.xhr();
530
+ }
531
+ settings.onRequest.call(context, module.request, module.xhr);
532
+ },
533
+ },
534
+
535
+ event: {
536
+ trigger: function (event) {
537
+ module.query();
538
+ if (event.type === 'submit' || event.type === 'click') {
539
+ event.preventDefault();
540
+ }
541
+ },
542
+ xhr: {
543
+ always: function () {
544
+ // nothing special
545
+ },
546
+ done: function (response, textStatus, xhr) {
547
+ var
548
+ context = this,
549
+ elapsedTime = Date.now() - requestStartTime,
550
+ timeLeft = settings.loadingDuration - elapsedTime,
551
+ translatedResponse = isFunction(settings.onResponse)
552
+ ? (module.is.expectingJSON() && !settings.rawResponse
553
+ ? settings.onResponse.call(context, $.extend(true, {}, response))
554
+ : settings.onResponse.call(context, response))
555
+ : false
556
+ ;
557
+ timeLeft = timeLeft > 0
558
+ ? timeLeft
559
+ : 0;
560
+ if (translatedResponse) {
561
+ module.debug('Modified API response in onResponse callback', settings.onResponse, translatedResponse, response);
562
+ response = translatedResponse;
563
+ }
564
+ if (timeLeft > 0) {
565
+ module.debug('Response completed early delaying state change by', timeLeft);
566
+ }
567
+ setTimeout(function () {
568
+ if (module.is.validResponse(response)) {
569
+ module.request.resolveWith(context, [response, xhr]);
570
+ } else {
571
+ module.request.rejectWith(context, [xhr, 'invalid']);
572
+ }
573
+ }, timeLeft);
574
+ },
575
+ fail: function (xhr, status, httpMessage) {
576
+ var
577
+ context = this,
578
+ elapsedTime = Date.now() - requestStartTime,
579
+ timeLeft = settings.loadingDuration - elapsedTime
580
+ ;
581
+ timeLeft = timeLeft > 0
582
+ ? timeLeft
583
+ : 0;
584
+ if (timeLeft > 0) {
585
+ module.debug('Response completed early delaying state change by', timeLeft);
586
+ }
587
+ setTimeout(function () {
588
+ if (module.is.abortedRequest(xhr)) {
589
+ module.request.rejectWith(context, [xhr, 'aborted', httpMessage]);
590
+ } else {
591
+ module.request.rejectWith(context, [xhr, 'error', status, httpMessage]);
592
+ }
593
+ }, timeLeft);
594
+ },
595
+ },
596
+ request: {
597
+ done: function (response, xhr) {
598
+ module.debug('Successful API Response', response);
599
+ if (settings.cache === 'local' && url) {
600
+ module.write.cachedResponse(url, response);
601
+ module.debug('Saving server response locally', module.cache);
602
+ }
603
+ settings.onSuccess.call(context, response, $module, xhr);
604
+ },
605
+ complete: function (firstParameter, secondParameter) {
606
+ var
607
+ xhr,
608
+ response
609
+ ;
610
+ // have to guess callback parameters based on request success
611
+ if (module.was.successful()) {
612
+ response = firstParameter;
613
+ xhr = secondParameter;
614
+ } else {
615
+ xhr = firstParameter;
616
+ response = module.get.responseFromXHR(xhr);
617
+ }
618
+ module.remove.loading();
619
+ settings.onComplete.call(context, response, $module, xhr);
620
+ },
621
+ fail: function (xhr, status, httpMessage) {
622
+ var
623
+ // pull response from xhr if available
624
+ response = module.get.responseFromXHR(xhr),
625
+ errorMessage = module.get.errorFromRequest(response, status, httpMessage)
626
+ ;
627
+ if (status === 'aborted') {
628
+ module.debug('XHR Aborted (Most likely caused by page navigation or CORS Policy)', status, httpMessage);
629
+ settings.onAbort.call(context, status, $module, xhr);
630
+
631
+ return true;
632
+ }
633
+ if (status === 'invalid') {
634
+ module.debug('JSON did not pass success test. A server-side error has most likely occurred', response);
635
+ } else if (status === 'error') {
636
+ if (xhr !== undefined) {
637
+ module.debug('XHR produced a server error', status, httpMessage);
638
+ // make sure we have an error to display to console
639
+ if ((xhr.status < 200 || xhr.status >= 300) && httpMessage !== undefined && httpMessage !== '') {
640
+ module.error(error.statusMessage + httpMessage, ajaxSettings.url);
641
+ }
642
+ settings.onError.call(context, errorMessage, $module, xhr);
643
+ }
644
+ }
645
+
646
+ if (settings.errorDuration && status !== 'aborted') {
647
+ module.debug('Adding error state');
648
+ module.set.error();
649
+ if (module.should.removeError()) {
650
+ setTimeout(function () {
651
+ module.remove.error();
652
+ }, settings.errorDuration);
653
+ }
654
+ }
655
+ module.debug('API Request failed', errorMessage, xhr);
656
+ settings.onFailure.call(context, response, $module, xhr);
657
+ },
658
+ },
659
+ },
660
+
661
+ create: {
662
+
663
+ request: function () {
664
+ // api request promise
665
+ return $.Deferred()
666
+ .always(module.event.request.complete)
667
+ .done(module.event.request.done)
668
+ .fail(module.event.request.fail)
669
+ ;
670
+ },
671
+
672
+ mockedXHR: function () {
673
+ var
674
+ // xhr does not simulate these properties of xhr but must return them
675
+ textStatus = false,
676
+ status = false,
677
+ httpMessage = false,
678
+ responder = settings.mockResponse || settings.response,
679
+ asyncResponder = settings.mockResponseAsync || settings.responseAsync,
680
+ asyncCallback,
681
+ response,
682
+ mockedXHR
683
+ ;
684
+
685
+ mockedXHR = $.Deferred()
686
+ .always(module.event.xhr.complete)
687
+ .done(module.event.xhr.done)
688
+ .fail(module.event.xhr.fail)
689
+ ;
690
+
691
+ if (responder) {
692
+ if (isFunction(responder)) {
693
+ module.debug('Using specified synchronous callback', responder);
694
+ response = responder.call(context, requestSettings);
695
+ } else {
696
+ module.debug('Using settings specified response', responder);
697
+ response = responder;
698
+ }
699
+ // simulating response
700
+ mockedXHR.resolveWith(context, [response, textStatus, { responseText: response }]);
701
+ } else if (isFunction(asyncResponder)) {
702
+ asyncCallback = function (response) {
703
+ module.debug('Async callback returned response', response);
704
+
705
+ if (response) {
706
+ mockedXHR.resolveWith(context, [response, textStatus, { responseText: response }]);
707
+ } else {
708
+ mockedXHR.rejectWith(context, [{ responseText: response }, status, httpMessage]);
709
+ }
710
+ };
711
+ module.debug('Using specified async response callback', asyncResponder);
712
+ asyncResponder.call(context, requestSettings, asyncCallback);
713
+ }
714
+
715
+ return mockedXHR;
716
+ },
717
+
718
+ xhr: function () {
719
+ var
720
+ xhr
721
+ ;
722
+ // ajax request promise
723
+ xhr = $.ajax(ajaxSettings)
724
+ .always(module.event.xhr.always)
725
+ .done(module.event.xhr.done)
726
+ .fail(module.event.xhr.fail)
727
+ ;
728
+ module.verbose('Created server request', xhr, ajaxSettings);
729
+
730
+ return xhr;
731
+ },
732
+ },
733
+
734
+ set: {
735
+ error: function () {
736
+ module.verbose('Adding error state to element', $context);
737
+ $context.addClass(className.error);
738
+ },
739
+ loading: function () {
740
+ module.verbose('Adding loading state to element', $context);
741
+ $context.addClass(className.loading);
742
+ requestStartTime = Date.now();
743
+ },
744
+ },
745
+
746
+ remove: {
747
+ error: function () {
748
+ module.verbose('Removing error state from element', $context);
749
+ $context.removeClass(className.error);
750
+ },
751
+ loading: function () {
752
+ module.verbose('Removing loading state from element', $context);
753
+ $context.removeClass(className.loading);
754
+ },
755
+ },
756
+
757
+ get: {
758
+ normalizedData: function () {
759
+ return typeof settings.data === 'string' ? settings.data : JSON.stringify(settings.data, Object.keys(settings.data).sort());
760
+ },
761
+ responseFromXHR: function (xhr) {
762
+ return $.isPlainObject(xhr)
763
+ ? (module.is.expectingJSON()
764
+ ? module.decode.json(xhr.responseText)
765
+ : xhr.responseText)
766
+ : false;
767
+ },
768
+ errorFromRequest: function (response, status, httpMessage) {
769
+ return $.isPlainObject(response) && response.error !== undefined
770
+ ? response.error // use json error message
771
+ : (settings.error[status] !== undefined // use server error message
772
+ ? settings.error[status]
773
+ : httpMessage);
774
+ },
775
+ request: function () {
776
+ return module.request || false;
777
+ },
778
+ xhr: function () {
779
+ return module.xhr || false;
780
+ },
781
+ settings: function () {
782
+ var
783
+ runSettings
784
+ ;
785
+ runSettings = settings.beforeSend.call($module, settings);
786
+ if (runSettings) {
787
+ if (runSettings.success !== undefined) {
788
+ module.debug('Legacy success callback detected', runSettings);
789
+ module.error(error.legacyParameters, runSettings.success);
790
+ runSettings.onSuccess = runSettings.success;
791
+ }
792
+ if (runSettings.failure !== undefined) {
793
+ module.debug('Legacy failure callback detected', runSettings);
794
+ module.error(error.legacyParameters, runSettings.failure);
795
+ runSettings.onFailure = runSettings.failure;
796
+ }
797
+ if (runSettings.complete !== undefined) {
798
+ module.debug('Legacy complete callback detected', runSettings);
799
+ module.error(error.legacyParameters, runSettings.complete);
800
+ runSettings.onComplete = runSettings.complete;
801
+ }
802
+ }
803
+ if (runSettings === undefined) {
804
+ module.error(error.noReturnedValue);
805
+ }
806
+ if (runSettings === false) {
807
+ return runSettings;
808
+ }
809
+
810
+ return runSettings !== undefined
811
+ ? $.extend(true, {}, runSettings)
812
+ : $.extend(true, {}, settings);
813
+ },
814
+ urlEncodedValue: function (value) {
815
+ var
816
+ decodedValue = window.decodeURIComponent(value),
817
+ encodedValue = window.encodeURIComponent(value),
818
+ alreadyEncoded = decodedValue !== value
819
+ ;
820
+ if (alreadyEncoded) {
821
+ module.debug('URL value is already encoded, avoiding double encoding', value);
822
+
823
+ return value;
824
+ }
825
+ module.verbose('Encoding value using encodeURIComponent', value, encodedValue);
826
+
827
+ return encodedValue;
828
+ },
829
+ defaultData: function () {
830
+ var
831
+ data = {}
832
+ ;
833
+ if (!isWindow(element)) {
834
+ if (module.is.input()) {
835
+ data.value = $module.val();
836
+ } else if (!module.is.form()) {
837
+ data.text = $module.text();
838
+ }
839
+ }
840
+
841
+ return data;
842
+ },
843
+ event: function () {
844
+ if (isWindow(element) || settings.on === 'now') {
845
+ module.debug('API called without element, no events attached');
846
+
847
+ return false;
848
+ }
849
+ if (settings.on === 'auto') {
850
+ if ($module.is('input')) {
851
+ return element.oninput !== undefined
852
+ ? 'input'
853
+ : (element.onpropertychange !== undefined
854
+ ? 'propertychange'
855
+ : 'keyup');
856
+ }
857
+ if ($module.is('form')) {
858
+ return 'submit';
859
+ }
860
+
861
+ return 'click';
862
+ }
863
+
864
+ return settings.on;
865
+ },
866
+ templatedURL: function (action) {
867
+ action = action || settings.action || $module.data(metadata.action) || false;
868
+ url = settings.url || $module.data(metadata.url) || false;
869
+ if (url) {
870
+ module.debug('Using specified url', url);
871
+
872
+ return url;
873
+ }
874
+ if (action) {
875
+ module.debug('Looking up url for action', action, settings.api);
876
+ if (settings.api[action] === undefined && !module.is.mocked()) {
877
+ module.error(error.missingAction, settings.action, settings.api);
878
+
879
+ return;
880
+ }
881
+ url = settings.api[action];
882
+ } else if (module.is.form()) {
883
+ url = $module.attr('action') || $context.attr('action') || false;
884
+ module.debug('No url or action specified, defaulting to form action', url);
885
+ }
886
+
887
+ return url;
888
+ },
889
+ },
890
+
891
+ abort: function () {
892
+ var
893
+ xhr = module.get.xhr()
894
+ ;
895
+ if (xhr && xhr.state() !== 'resolved') {
896
+ module.debug('Cancelling API request');
897
+ xhr.abort();
898
+ }
899
+ },
900
+
901
+ // reset state
902
+ reset: function () {
903
+ module.remove.error();
904
+ module.remove.loading();
905
+ },
906
+
907
+ setting: function (name, value) {
908
+ module.debug('Changing setting', name, value);
909
+ if ($.isPlainObject(name)) {
910
+ $.extend(true, settings, name);
911
+ } else if (value !== undefined) {
912
+ if ($.isPlainObject(settings[name])) {
913
+ $.extend(true, settings[name], value);
914
+ } else {
915
+ settings[name] = value;
916
+ }
917
+ } else {
918
+ return settings[name];
919
+ }
920
+ },
921
+ internal: function (name, value) {
922
+ if ($.isPlainObject(name)) {
923
+ $.extend(true, module, name);
924
+ } else if (value !== undefined) {
925
+ module[name] = value;
926
+ } else {
927
+ return module[name];
928
+ }
929
+ },
930
+ debug: function () {
931
+ if (!settings.silent && settings.debug) {
932
+ if (settings.performance) {
933
+ module.performance.log(arguments);
934
+ } else {
935
+ module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
936
+ module.debug.apply(console, arguments);
937
+ }
938
+ }
939
+ },
940
+ verbose: function () {
941
+ if (!settings.silent && settings.verbose && settings.debug) {
942
+ if (settings.performance) {
943
+ module.performance.log(arguments);
944
+ } else {
945
+ module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
946
+ module.verbose.apply(console, arguments);
947
+ }
948
+ }
949
+ },
950
+ error: function () {
951
+ if (!settings.silent) {
952
+ module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
953
+ module.error.apply(console, arguments);
954
+ }
955
+ },
956
+ performance: {
957
+ log: function (message) {
958
+ var
959
+ currentTime,
960
+ executionTime,
961
+ previousTime
962
+ ;
963
+ if (settings.performance) {
964
+ currentTime = Date.now();
965
+ previousTime = time || currentTime;
966
+ executionTime = currentTime - previousTime;
967
+ time = currentTime;
968
+ performance.push({
969
+ Name: message[0],
970
+ Arguments: [].slice.call(message, 1) || '',
971
+ // 'Element' : element,
972
+ 'Execution Time': executionTime,
973
+ });
974
+ }
975
+ clearTimeout(module.performance.timer);
976
+ module.performance.timer = setTimeout(function () {
977
+ module.performance.display();
978
+ }, 500);
979
+ },
980
+ display: function () {
981
+ var
982
+ title = settings.name + ':',
983
+ totalTime = 0
984
+ ;
985
+ time = false;
986
+ clearTimeout(module.performance.timer);
987
+ $.each(performance, function (index, data) {
988
+ totalTime += data['Execution Time'];
989
+ });
990
+ title += ' ' + totalTime + 'ms';
991
+ if (performance.length > 0) {
992
+ console.groupCollapsed(title);
993
+ if (console.table) {
994
+ console.table(performance);
995
+ } else {
996
+ $.each(performance, function (index, data) {
997
+ console.log(data.Name + ': ' + data['Execution Time'] + 'ms');
998
+ });
999
+ }
1000
+ console.groupEnd();
1001
+ }
1002
+ performance = [];
1003
+ },
1004
+ },
1005
+ invoke: function (query, passedArguments, context) {
1006
+ var
1007
+ object = instance,
1008
+ maxDepth,
1009
+ found,
1010
+ response
1011
+ ;
1012
+ passedArguments = passedArguments || queryArguments;
1013
+ context = context || element;
1014
+ if (typeof query === 'string' && object !== undefined) {
1015
+ query = query.split(/[ .]/);
1016
+ maxDepth = query.length - 1;
1017
+ $.each(query, function (depth, value) {
1018
+ var camelCaseValue = depth !== maxDepth
1019
+ ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
1020
+ : query
1021
+ ;
1022
+ if ($.isPlainObject(object[camelCaseValue]) && (depth !== maxDepth)) {
1023
+ object = object[camelCaseValue];
1024
+ } else if (object[camelCaseValue] !== undefined) {
1025
+ found = object[camelCaseValue];
1026
+
1027
+ return false;
1028
+ } else if ($.isPlainObject(object[value]) && (depth !== maxDepth)) {
1029
+ object = object[value];
1030
+ } else if (object[value] !== undefined) {
1031
+ found = object[value];
1032
+
1033
+ return false;
1034
+ } else {
1035
+ module.error(error.method, query);
1036
+
1037
+ return false;
1038
+ }
1039
+ });
1040
+ }
1041
+ if (isFunction(found)) {
1042
+ response = found.apply(context, passedArguments);
1043
+ } else if (found !== undefined) {
1044
+ response = found;
1045
+ }
1046
+ if (Array.isArray(returnedValue)) {
1047
+ returnedValue.push(response);
1048
+ } else if (returnedValue !== undefined) {
1049
+ returnedValue = [returnedValue, response];
1050
+ } else if (response !== undefined) {
1051
+ returnedValue = response;
1052
+ }
1053
+
1054
+ return found;
1055
+ },
1056
+ };
1057
+
1058
+ if (methodInvoked) {
1059
+ if (instance === undefined) {
1060
+ module.initialize();
1061
+ }
1062
+ module.invoke(query);
1063
+ } else {
1064
+ if (instance !== undefined) {
1065
+ instance.invoke('destroy');
1066
+ }
1067
+ module.initialize();
1068
+ }
1069
+ });
1070
+
1071
+ return returnedValue !== undefined
1072
+ ? returnedValue
1073
+ : this;
1074
+ };
1075
+ $.api = $.fn.api;
1076
+
1077
+ $.api.settings = {
1078
+
1079
+ name: 'API',
1080
+ namespace: 'api',
1081
+
1082
+ debug: false,
1083
+ verbose: false,
1084
+ performance: true,
1085
+
1086
+ // object containing all templates endpoints
1087
+ api: {},
1088
+
1089
+ // whether to cache responses
1090
+ cache: true,
1091
+
1092
+ // whether new requests should abort previous requests
1093
+ interruptRequests: true,
1094
+
1095
+ // event binding
1096
+ on: 'auto',
1097
+
1098
+ // context for applying state classes
1099
+ stateContext: false,
1100
+
1101
+ // duration for loading state
1102
+ loadingDuration: 0,
1103
+
1104
+ // whether to hide errors after a period of time
1105
+ hideError: 'auto',
1106
+
1107
+ // duration for error state
1108
+ errorDuration: 2000,
1109
+
1110
+ // whether parameters should be encoded with encodeURIComponent
1111
+ encodeParameters: true,
1112
+
1113
+ // API action to use
1114
+ action: false,
1115
+
1116
+ // templated URL to use
1117
+ url: false,
1118
+
1119
+ // base URL to apply to all endpoints
1120
+ base: '',
1121
+
1122
+ // data that will
1123
+ urlData: {},
1124
+
1125
+ // whether to add default data to url data
1126
+ defaultData: true,
1127
+
1128
+ // whether to serialize closest form
1129
+ // use true to convert complex named keys like a[b][1][c][] into a nested object
1130
+ // use 'formdata' for formdata web api
1131
+ serializeForm: false,
1132
+
1133
+ // how long to wait before request should occur
1134
+ throttle: 0,
1135
+
1136
+ // whether to throttle first request or only repeated
1137
+ throttleFirstRequest: true,
1138
+
1139
+ // standard ajax settings
1140
+ method: 'get',
1141
+ data: {},
1142
+ dataType: 'json',
1143
+
1144
+ // mock response
1145
+ mockResponse: false,
1146
+ mockResponseAsync: false,
1147
+
1148
+ // aliases for mock
1149
+ response: false,
1150
+ responseAsync: false,
1151
+
1152
+ // whether onResponse should work with response value without force converting into an object
1153
+ rawResponse: true,
1154
+
1155
+ // callbacks before request
1156
+ beforeSend: function (settings) {
1157
+ return settings;
1158
+ },
1159
+ beforeXHR: function (xhr) {},
1160
+ onRequest: function (promise, xhr) {},
1161
+
1162
+ // after request
1163
+ onResponse: false, // function(response) { },
1164
+
1165
+ // response was successful, if JSON passed validation
1166
+ onSuccess: function (response, $module) {},
1167
+
1168
+ // request finished without aborting
1169
+ onComplete: function (response, $module) {},
1170
+
1171
+ // failed JSON success test
1172
+ onFailure: function (response, $module) {},
1173
+
1174
+ // server error
1175
+ onError: function (errorMessage, $module) {},
1176
+
1177
+ // request aborted
1178
+ onAbort: function (errorMessage, $module) {},
1179
+
1180
+ successTest: false,
1181
+
1182
+ // errors
1183
+ error: {
1184
+ beforeSend: 'The before send function has aborted the request',
1185
+ error: 'There was an error with your request',
1186
+ exitConditions: 'API Request Aborted. Exit conditions met',
1187
+ JSONParse: 'JSON could not be parsed during error handling',
1188
+ legacyParameters: 'You are using legacy API success callback names',
1189
+ method: 'The method you called is not defined',
1190
+ missingAction: 'API action used but no url was defined',
1191
+ missingURL: 'No URL specified for api event',
1192
+ noReturnedValue: 'The beforeSend callback must return a settings object, beforeSend ignored.',
1193
+ noStorage: 'Caching responses locally requires session storage',
1194
+ parseError: 'There was an error parsing your request',
1195
+ requiredParameter: 'Missing a required URL parameter: ',
1196
+ statusMessage: 'Server gave an error: ',
1197
+ timeout: 'Your request timed out',
1198
+ },
1199
+
1200
+ regExp: {
1201
+ required: /{\$*[\da-z]+}/gi,
1202
+ optional: /{\/\$*[\da-z]+}/gi,
1203
+ validate: /^[_a-z][\w-]*(?:\[[\w-]*])*$/i,
1204
+ key: /[\w-]+|(?=\[])/gi,
1205
+ push: /^$/,
1206
+ fixed: /^\d+$/,
1207
+ named: /^[\w-]+$/i,
1208
+ },
1209
+
1210
+ className: {
1211
+ loading: 'loading',
1212
+ error: 'error',
1213
+ },
1214
+
1215
+ selector: {
1216
+ disabled: '.disabled',
1217
+ form: 'form',
1218
+ },
1219
+
1220
+ metadata: {
1221
+ action: 'action',
1222
+ url: 'url',
1223
+ },
1224
+ };
1225
+ })(jQuery, window, document);