rails-active-ui 0.1.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 (167) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +6 -0
  3. data/app/assets/stylesheets.css +73555 -0
  4. data/app/components/accordion_component.rb +34 -0
  5. data/app/components/ad_component.rb +28 -0
  6. data/app/components/api_component.rb +24 -0
  7. data/app/components/breadcrumb_component.rb +26 -0
  8. data/app/components/button_component.rb +49 -0
  9. data/app/components/calendar_component.rb +34 -0
  10. data/app/components/card_component.rb +56 -0
  11. data/app/components/checkbox_component.rb +41 -0
  12. data/app/components/column_component.rb +62 -0
  13. data/app/components/comment_component.rb +45 -0
  14. data/app/components/concerns/alignable.rb +21 -0
  15. data/app/components/concerns/attachable.rb +16 -0
  16. data/app/components/concerns/orientable.rb +21 -0
  17. data/app/components/concerns/positionable.rb +21 -0
  18. data/app/components/concerns/sizeable.rb +18 -0
  19. data/app/components/container_component.rb +23 -0
  20. data/app/components/dimmer_component.rb +30 -0
  21. data/app/components/divider_component.rb +30 -0
  22. data/app/components/dropdown_component.rb +63 -0
  23. data/app/components/embed_component.rb +32 -0
  24. data/app/components/emoji_component.rb +15 -0
  25. data/app/components/feed_component.rb +22 -0
  26. data/app/components/flag_component.rb +15 -0
  27. data/app/components/flyout_component.rb +41 -0
  28. data/app/components/form_component.rb +39 -0
  29. data/app/components/grid_component.rb +85 -0
  30. data/app/components/h_stack_component.rb +67 -0
  31. data/app/components/header_component.rb +60 -0
  32. data/app/components/icon_component.rb +41 -0
  33. data/app/components/image_component.rb +46 -0
  34. data/app/components/input_component.rb +52 -0
  35. data/app/components/item_component.rb +39 -0
  36. data/app/components/item_group_component.rb +30 -0
  37. data/app/components/label_component.rb +49 -0
  38. data/app/components/link_component.rb +23 -0
  39. data/app/components/list_component.rb +39 -0
  40. data/app/components/loader_component.rb +33 -0
  41. data/app/components/menu_component.rb +64 -0
  42. data/app/components/menu_item_component.rb +52 -0
  43. data/app/components/message_component.rb +54 -0
  44. data/app/components/modal_component.rb +50 -0
  45. data/app/components/nag_component.rb +25 -0
  46. data/app/components/overlay_component.rb +16 -0
  47. data/app/components/placeholder_component.rb +39 -0
  48. data/app/components/popup_component.rb +31 -0
  49. data/app/components/progress_component.rb +48 -0
  50. data/app/components/pusher_component.rb +18 -0
  51. data/app/components/rail_component.rb +31 -0
  52. data/app/components/rating_component.rb +41 -0
  53. data/app/components/reset_component.rb +12 -0
  54. data/app/components/reveal_component.rb +39 -0
  55. data/app/components/row_component.rb +39 -0
  56. data/app/components/search_component.rb +44 -0
  57. data/app/components/segment_component.rb +57 -0
  58. data/app/components/segment_group_component.rb +36 -0
  59. data/app/components/shape_component.rb +25 -0
  60. data/app/components/sidebar_component.rb +33 -0
  61. data/app/components/site_component.rb +12 -0
  62. data/app/components/slider_component.rb +46 -0
  63. data/app/components/state_component.rb +25 -0
  64. data/app/components/statistic_component.rb +43 -0
  65. data/app/components/step_component.rb +56 -0
  66. data/app/components/step_group_component.rb +38 -0
  67. data/app/components/sticky_component.rb +22 -0
  68. data/app/components/sub_header_component.rb +15 -0
  69. data/app/components/sub_menu_component.rb +24 -0
  70. data/app/components/tab_component.rb +24 -0
  71. data/app/components/table_cell_component.rb +60 -0
  72. data/app/components/table_component.rb +160 -0
  73. data/app/components/table_row_component.rb +43 -0
  74. data/app/components/text_component.rb +73 -0
  75. data/app/components/toast_component.rb +36 -0
  76. data/app/components/transition_component.rb +32 -0
  77. data/app/components/v_stack_component.rb +31 -0
  78. data/app/components/visibility_component.rb +22 -0
  79. data/app/helpers/component_helper.rb +109 -0
  80. data/app/helpers/fui_helper.rb +53 -0
  81. data/app/javascript/accordion.js +547 -0
  82. data/app/javascript/accordion.min.js +11 -0
  83. data/app/javascript/api.js +1112 -0
  84. data/app/javascript/api.min.js +11 -0
  85. data/app/javascript/calendar.js +1960 -0
  86. data/app/javascript/calendar.min.js +11 -0
  87. data/app/javascript/checkbox.js +819 -0
  88. data/app/javascript/checkbox.min.js +11 -0
  89. data/app/javascript/dimmer.js +686 -0
  90. data/app/javascript/dimmer.min.js +11 -0
  91. data/app/javascript/dropdown.js +4019 -0
  92. data/app/javascript/dropdown.min.js +11 -0
  93. data/app/javascript/embed.js +646 -0
  94. data/app/javascript/embed.min.js +11 -0
  95. data/app/javascript/flyout.js +1405 -0
  96. data/app/javascript/flyout.min.js +11 -0
  97. data/app/javascript/form.js +2070 -0
  98. data/app/javascript/form.min.js +11 -0
  99. data/app/javascript/jquery.js +10716 -0
  100. data/app/javascript/jquery.min.js +2 -0
  101. data/app/javascript/modal.js +1507 -0
  102. data/app/javascript/modal.min.js +11 -0
  103. data/app/javascript/nag.js +522 -0
  104. data/app/javascript/nag.min.js +11 -0
  105. data/app/javascript/popup.js +1457 -0
  106. data/app/javascript/popup.min.js +11 -0
  107. data/app/javascript/progress.js +922 -0
  108. data/app/javascript/progress.min.js +11 -0
  109. data/app/javascript/rating.js +496 -0
  110. data/app/javascript/rating.min.js +11 -0
  111. data/app/javascript/search.js +1519 -0
  112. data/app/javascript/search.min.js +11 -0
  113. data/app/javascript/shape.js +721 -0
  114. data/app/javascript/shape.min.js +11 -0
  115. data/app/javascript/sidebar.js +952 -0
  116. data/app/javascript/sidebar.min.js +11 -0
  117. data/app/javascript/site.js +415 -0
  118. data/app/javascript/site.min.js +11 -0
  119. data/app/javascript/slider.js +1449 -0
  120. data/app/javascript/slider.min.js +11 -0
  121. data/app/javascript/state.js +653 -0
  122. data/app/javascript/state.min.js +11 -0
  123. data/app/javascript/sticky.js +852 -0
  124. data/app/javascript/sticky.min.js +11 -0
  125. data/app/javascript/tab.js +867 -0
  126. data/app/javascript/tab.min.js +11 -0
  127. data/app/javascript/toast.js +916 -0
  128. data/app/javascript/toast.min.js +11 -0
  129. data/app/javascript/transition.js +955 -0
  130. data/app/javascript/transition.min.js +11 -0
  131. data/app/javascript/ui/controllers/fui_accordion_controller.js +45 -0
  132. data/app/javascript/ui/controllers/fui_api_controller.js +80 -0
  133. data/app/javascript/ui/controllers/fui_calendar_controller.js +66 -0
  134. data/app/javascript/ui/controllers/fui_checkbox_controller.js +48 -0
  135. data/app/javascript/ui/controllers/fui_dimmer_controller.js +45 -0
  136. data/app/javascript/ui/controllers/fui_dropdown_controller.js +68 -0
  137. data/app/javascript/ui/controllers/fui_embed_controller.js +49 -0
  138. data/app/javascript/ui/controllers/fui_flyout_controller.js +49 -0
  139. data/app/javascript/ui/controllers/fui_form_controller.js +62 -0
  140. data/app/javascript/ui/controllers/fui_modal_controller.js +61 -0
  141. data/app/javascript/ui/controllers/fui_nag_controller.js +52 -0
  142. data/app/javascript/ui/controllers/fui_popup_controller.js +58 -0
  143. data/app/javascript/ui/controllers/fui_progress_controller.js +60 -0
  144. data/app/javascript/ui/controllers/fui_rating_controller.js +49 -0
  145. data/app/javascript/ui/controllers/fui_search_controller.js +76 -0
  146. data/app/javascript/ui/controllers/fui_shape_controller.js +45 -0
  147. data/app/javascript/ui/controllers/fui_sidebar_controller.js +48 -0
  148. data/app/javascript/ui/controllers/fui_site_controller.js +29 -0
  149. data/app/javascript/ui/controllers/fui_slider_controller.js +53 -0
  150. data/app/javascript/ui/controllers/fui_state_controller.js +63 -0
  151. data/app/javascript/ui/controllers/fui_sticky_controller.js +50 -0
  152. data/app/javascript/ui/controllers/fui_tab_controller.js +57 -0
  153. data/app/javascript/ui/controllers/fui_toast_controller.js +60 -0
  154. data/app/javascript/ui/controllers/fui_transition_controller.js +60 -0
  155. data/app/javascript/ui/controllers/fui_visibility_controller.js +55 -0
  156. data/app/javascript/ui/index.js +114 -0
  157. data/app/javascript/visibility.js +1196 -0
  158. data/app/javascript/visibility.min.js +11 -0
  159. data/app/lib/component.rb +63 -0
  160. data/config/importmap.rb +27 -0
  161. data/config/initializers/ruby_template_handler.rb +31 -0
  162. data/config/routes.rb +2 -0
  163. data/lib/tasks/ui_tasks.rake +4 -0
  164. data/lib/ui/engine.rb +27 -0
  165. data/lib/ui/version.rb +3 -0
  166. data/lib/ui.rb +6 -0
  167. metadata +220 -0
@@ -0,0 +1,1405 @@
1
+ /*!
2
+ * # Fomantic-UI 2.9.4 - Flyout
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 isFunction(obj) {
15
+ return typeof obj === 'function' && typeof obj.nodeType !== 'number';
16
+ }
17
+
18
+ window = window !== undefined && window.Math === Math
19
+ ? window
20
+ : globalThis;
21
+
22
+ $.fn.flyout = function (...args) {
23
+ const $window = $(window);
24
+ const $document = $(document);
25
+ const $head = $('head');
26
+ const $body = $('body');
27
+ const $allModules = isFunction(this)
28
+ ? $body
29
+ : $(this);
30
+
31
+ let time = Date.now();
32
+ let performance = [];
33
+
34
+ const parameters = args[0];
35
+ const methodInvoked = typeof parameters === 'string';
36
+ const queryArguments = args.slice(1);
37
+ const contextCheck = function (context, win) {
38
+ let $context;
39
+ if ([window, document].includes(context)) {
40
+ $context = $body;
41
+ } else {
42
+ $context = $(win.document).find(context);
43
+ if ($context.length === 0) {
44
+ $context = win.frameElement ? contextCheck(context, win.parent) : $body;
45
+ }
46
+ }
47
+
48
+ return $context;
49
+ };
50
+ let returnedValue;
51
+
52
+ $allModules.each(function () {
53
+ let settings = $.isPlainObject(parameters)
54
+ ? $.extend(true, {}, $.fn.flyout.settings, parameters)
55
+ : $.extend({}, $.fn.flyout.settings);
56
+
57
+ const selector = settings.selector;
58
+ let className = settings.className;
59
+ let namespace = settings.namespace;
60
+ let fields = settings.fields;
61
+ const regExp = settings.regExp;
62
+ let error = settings.error;
63
+
64
+ const eventNamespace = '.' + namespace;
65
+ const moduleNamespace = 'module-' + namespace;
66
+
67
+ let $module = $(this);
68
+ let $context = contextCheck(settings.context, window);
69
+ let $closeIcon = $module.find(selector.close);
70
+ let $inputs;
71
+ let $focusedElement;
72
+
73
+ let $flyouts = $module.children(selector.flyout);
74
+ let $pusher = $context.children(selector.pusher);
75
+ let $style;
76
+
77
+ const isFlyoutComponent = $module.hasClass('flyout');
78
+
79
+ let element = this;
80
+ let instance = isFlyoutComponent ? $module.data(moduleNamespace) : undefined;
81
+
82
+ let ignoreRepeatedEvents = false;
83
+ const isBody = $context[0] === $body[0];
84
+ let initialBodyMargin = '';
85
+ let initialBodyMarginInt = 0;
86
+ let tempBodyMargin = 0;
87
+ let hadScrollbar = false;
88
+ let windowRefocused = false;
89
+
90
+ let elementNamespace;
91
+ let id;
92
+ let observer;
93
+ let observeAttributes = false;
94
+ let currentScroll;
95
+
96
+ const module = {
97
+
98
+ initialize: function () {
99
+ module.debug('Initializing flyout', parameters);
100
+
101
+ module.create.id();
102
+ if (!isFlyoutComponent) {
103
+ module.create.flyout();
104
+ if (!isFunction(settings.onHidden)) {
105
+ settings.onHidden = function () {
106
+ module.destroy();
107
+ $module.remove();
108
+ };
109
+ }
110
+ if (!settings.autoShow) {
111
+ settings.autoShow = true;
112
+ }
113
+ }
114
+ $module.addClass(settings.class);
115
+ if (settings.title !== '') {
116
+ $module.find(selector.header).html(module.helpers.escape(settings.title, settings)).addClass(settings.classTitle);
117
+ }
118
+ if (settings.content !== '') {
119
+ $module.find(selector.content).html(module.helpers.escape(settings.content, settings)).addClass(settings.classContent);
120
+ }
121
+ if (module.has.configActions()) {
122
+ let $actions = $module.find(selector.actions).addClass(settings.classActions);
123
+ if ($actions.length === 0) {
124
+ $actions = $('<div/>', { class: className.actions + ' ' + (settings.classActions || '') }).appendTo($module);
125
+ } else {
126
+ $actions.empty();
127
+ }
128
+ for (const el of settings.actions) {
129
+ const icon = el[fields.icon]
130
+ ? '<i ' + (el[fields.text] ? 'aria-hidden="true"' : '') + ' class="' + module.helpers.escape(el[fields.icon]) + ' icon"></i>'
131
+ : '';
132
+ const text = module.helpers.escape(el[fields.text] || '', settings);
133
+ const cls = module.helpers.escape(el[fields.class] || '');
134
+ const click = el[fields.click] && isFunction(el[fields.click])
135
+ ? el[fields.click]
136
+ : function () {};
137
+ const elementRef = element;
138
+ const $moduleRef = $module;
139
+ $actions.append($('<button/>', {
140
+ html: icon + text,
141
+ 'aria-label': (el[fields.text] || el[fields.icon] || '').replace(/<[^>]+(>|$)/g, ''),
142
+ class: className.button + ' ' + cls,
143
+ on: {
144
+ click: function () {
145
+ if (click.call(elementRef, $moduleRef) === false) {
146
+ return;
147
+ }
148
+ module.hide();
149
+ },
150
+ },
151
+ }));
152
+ }
153
+ }
154
+
155
+ // avoids locking rendering if initialized in onReady
156
+ if (settings.delaySetup) {
157
+ requestAnimationFrame(module.setup.layout);
158
+ } else {
159
+ module.setup.layout();
160
+ }
161
+
162
+ requestAnimationFrame(function () {
163
+ module.setup.cache();
164
+ });
165
+
166
+ if (module.get.direction() === 'left' || module.get.direction() === 'right') {
167
+ module.setup.heights();
168
+ module.bind.resize();
169
+ }
170
+ module.bind.events();
171
+ module.observeChanges();
172
+ module.instantiate();
173
+
174
+ if (settings.autoShow) {
175
+ module.show();
176
+ }
177
+ },
178
+
179
+ instantiate: function () {
180
+ module.verbose('Storing instance of module', module);
181
+ instance = module;
182
+ $module
183
+ .data(moduleNamespace, instance);
184
+ },
185
+
186
+ create: {
187
+ flyout: function () {
188
+ module.verbose('Programmatically create flyout', $context);
189
+ $module = $('<div/>', { class: className.flyout, role: 'dialog', 'aria-modal': settings.dimPage });
190
+ if (settings.closeIcon) {
191
+ $closeIcon = $('<i/>', {
192
+ class: className.close,
193
+ role: 'button',
194
+ tabindex: 0,
195
+ 'aria-label': settings.text.close,
196
+ });
197
+ $module.append($closeIcon);
198
+ }
199
+ if (settings.title !== '') {
200
+ const titleId = '_' + module.get.id() + 'title';
201
+ $module.attr('aria-labelledby', titleId);
202
+ $('<div/>', { class: className.header, id: titleId }).appendTo($module);
203
+ }
204
+ if (settings.content !== '') {
205
+ const descId = '_' + module.get.id() + 'desc';
206
+ $module.attr('aria-describedby', descId);
207
+ $('<div/>', { class: className.content, id: descId }).appendTo($module);
208
+ }
209
+ if (module.has.configActions()) {
210
+ $('<div/>', { class: className.actions }).appendTo($module);
211
+ }
212
+ $module.prependTo($context);
213
+ element = $module[0];
214
+ },
215
+ id: function () {
216
+ id = (Math.random().toString(16) + '000000000').slice(2, 10);
217
+ elementNamespace = '.' + id;
218
+ module.verbose('Creating unique id for element', id);
219
+ },
220
+ },
221
+
222
+ destroy: function () {
223
+ if (observer) {
224
+ observer.disconnect();
225
+ }
226
+ module.verbose('Destroying previous module for', $module);
227
+ $module
228
+ .off(eventNamespace)
229
+ .removeData(moduleNamespace);
230
+ $closeIcon.off(elementNamespace);
231
+ if ($inputs) {
232
+ $inputs.off(elementNamespace);
233
+ }
234
+ // bound by uuid
235
+ $context.off(elementNamespace);
236
+ $window.off(elementNamespace);
237
+ $document.off(elementNamespace);
238
+ },
239
+
240
+ event: {
241
+ keyboard: function (event) {
242
+ const keyCode = event.which;
243
+ if (keyCode === settings.keys.escape) {
244
+ if (settings.closable) {
245
+ module.debug('Escape key pressed hiding flyout');
246
+ module.hide();
247
+ } else {
248
+ module.debug('Escape key pressed, but closable is set to false');
249
+ }
250
+ event.preventDefault();
251
+ }
252
+ },
253
+ resize: function () {
254
+ module.setup.heights();
255
+ },
256
+ focus: function () {
257
+ windowRefocused = true;
258
+ },
259
+ click: function (event) {
260
+ if (windowRefocused && document.activeElement !== event.target && module.is.visible() && settings.autofocus && settings.dimPage && $(document.activeElement).closest(selector.flyout).length === 0) {
261
+ requestAnimationFrame(module.set.autofocus);
262
+ }
263
+ windowRefocused = false;
264
+ },
265
+ clickaway: function (event) {
266
+ if (settings.closable) {
267
+ const clickedInPusher = $pusher.find(event.target).length > 0 || $pusher.is(event.target);
268
+ const clickedContext = $context.is(event.target);
269
+ if (clickedInPusher) {
270
+ module.verbose('User clicked on dimmed page');
271
+ module.hide();
272
+ }
273
+ if (clickedContext) {
274
+ module.verbose('User clicked on dimmable context (scaled out page)');
275
+ module.hide();
276
+ }
277
+ }
278
+ },
279
+ close: function (event) {
280
+ module.hide();
281
+ },
282
+ closeKeyUp: function (event) {
283
+ const keyCode = event.which;
284
+ if (keyCode === settings.keys.enter || keyCode === settings.keys.space) {
285
+ module.hide();
286
+ }
287
+ },
288
+ inputKeyDown: {
289
+ first: function (event) {
290
+ const keyCode = event.which;
291
+ if (keyCode === settings.keys.tab && event.shiftKey) {
292
+ $inputs.last().trigger('focus');
293
+ event.preventDefault();
294
+ }
295
+ },
296
+ last: function (event) {
297
+ const keyCode = event.which;
298
+ if (keyCode === settings.keys.tab && !event.shiftKey) {
299
+ $inputs.first().trigger('focus');
300
+ event.preventDefault();
301
+ }
302
+ },
303
+ },
304
+ approve: function (event) {
305
+ if (ignoreRepeatedEvents || settings.onApprove.call(module.element, $(this)) === false) {
306
+ module.verbose('Approve callback returned false cancelling close');
307
+
308
+ return;
309
+ }
310
+ ignoreRepeatedEvents = true;
311
+ module.hide(function () {
312
+ ignoreRepeatedEvents = false;
313
+ });
314
+ },
315
+ deny: function (event) {
316
+ if (ignoreRepeatedEvents || settings.onDeny.call(module.element, $(this)) === false) {
317
+ module.verbose('Deny callback returned false cancelling close');
318
+
319
+ return;
320
+ }
321
+ ignoreRepeatedEvents = true;
322
+ module.hide(function () {
323
+ ignoreRepeatedEvents = false;
324
+ });
325
+ },
326
+ touch: function (event) {
327
+ // event.stopPropagation();
328
+ },
329
+ containScroll: function (event) {
330
+ if (element.scrollTop <= 0) {
331
+ element.scrollTop = 1;
332
+ }
333
+ if ((element.scrollTop + element.offsetHeight) >= element.scrollHeight) {
334
+ element.scrollTop = element.scrollHeight - element.offsetHeight - 1;
335
+ }
336
+ },
337
+ scroll: function (event) {
338
+ if ($(event.target).closest(selector.flyout).length === 0) {
339
+ event.preventDefault();
340
+ }
341
+ },
342
+ },
343
+
344
+ bind: {
345
+ resize: function () {
346
+ module.verbose('Adding resize event to window', $window);
347
+ $window.on('resize' + elementNamespace, module.event.resize);
348
+ },
349
+ events: function () {
350
+ module.verbose('Attaching events');
351
+ $module
352
+ .on('click' + eventNamespace, selector.close, module.event.close)
353
+ .on('click' + eventNamespace, selector.approve, module.event.approve)
354
+ .on('click' + eventNamespace, selector.deny, module.event.deny);
355
+ $closeIcon
356
+ .on('keyup' + elementNamespace, module.event.closeKeyUp);
357
+ $window
358
+ .on('focus' + elementNamespace, module.event.focus);
359
+ $context
360
+ .on('click' + elementNamespace, module.event.click);
361
+ },
362
+ clickaway: function () {
363
+ module.verbose('Adding clickaway events to context', $context);
364
+ $context
365
+ .on('click' + elementNamespace, module.event.clickaway)
366
+ .on('touchend' + elementNamespace, module.event.clickaway);
367
+ },
368
+ scrollLock: function () {
369
+ if (settings.scrollLock) {
370
+ module.debug('Disabling page scroll');
371
+ hadScrollbar = module.has.scrollbar();
372
+ if (hadScrollbar) {
373
+ module.save.bodyMargin();
374
+ module.set.bodyMargin();
375
+ }
376
+ $context.addClass(className.locked);
377
+ }
378
+ module.verbose('Adding events to contain flyout scroll');
379
+ $document
380
+ .on('touchmove' + elementNamespace, module.event.touch);
381
+ $module
382
+ .on('scroll' + eventNamespace, module.event.containScroll);
383
+ },
384
+ },
385
+ unbind: {
386
+ clickaway: function () {
387
+ module.verbose('Removing clickaway events from context', $context);
388
+ $context.off(elementNamespace);
389
+ },
390
+ scrollLock: function () {
391
+ module.verbose('Removing scroll lock from page');
392
+ if (hadScrollbar) {
393
+ module.restore.bodyMargin();
394
+ }
395
+ $context.removeClass(className.locked);
396
+ $document.off(elementNamespace);
397
+ $module.off('scroll' + eventNamespace);
398
+ },
399
+ },
400
+
401
+ add: {
402
+ inlineCSS: function () {
403
+ const width = module.cache.width || $module.outerWidth();
404
+ const height = module.cache.height || $module.outerHeight();
405
+ const isRTL = module.is.rtl();
406
+ const direction = module.get.direction();
407
+ const distance = {
408
+ left: width,
409
+ right: -width,
410
+ top: height,
411
+ bottom: -height,
412
+ };
413
+ let style;
414
+
415
+ if (isRTL) {
416
+ module.verbose('RTL detected, flipping widths');
417
+ distance.left = -width;
418
+ distance.right = width;
419
+ }
420
+
421
+ style = '<style>';
422
+
423
+ if (direction === 'left' || direction === 'right') {
424
+ module.debug('Adding CSS rules for animation distance', width);
425
+ style += ''
426
+ + ' .ui.visible.' + direction + '.flyout ~ .fixed,'
427
+ + ' .ui.visible.' + direction + '.flyout ~ .pusher {'
428
+ + ' transform: translate3d(' + distance[direction] + 'px, 0, 0);'
429
+ + ' }';
430
+ } else if (direction === 'top' || direction === 'bottom') {
431
+ style += ''
432
+ + ' .ui.visible.' + direction + '.flyout ~ .fixed,'
433
+ + ' .ui.visible.' + direction + '.flyout ~ .pusher {'
434
+ + ' transform: translate3d(0, ' + distance[direction] + 'px, 0);'
435
+ + ' }';
436
+ }
437
+
438
+ style += '</style>';
439
+ $style = $(style)
440
+ .appendTo($head);
441
+ module.debug('Adding sizing css to head', $style);
442
+ },
443
+ keyboardShortcuts: function () {
444
+ module.verbose('Adding keyboard shortcuts');
445
+ $document
446
+ .on('keydown' + eventNamespace, module.event.keyboard);
447
+ },
448
+ },
449
+ observeChanges: function () {
450
+ observer = new MutationObserver(function (mutations) {
451
+ const collectNodes = function (parent) {
452
+ const nodes = [];
453
+ for (const c of parent) {
454
+ nodes.push(...collectNodes(c.childNodes), c);
455
+ }
456
+
457
+ return nodes;
458
+ };
459
+ let shouldRefreshInputs = false;
460
+ let ignoreAutofocus = true;
461
+ mutations.every(function (mutation) {
462
+ if (mutation.type === 'attributes') {
463
+ if (observeAttributes && (mutation.attributeName === 'disabled' || $(mutation.target).find(':input').addBack(':input').filter(':visible').length > 0)) {
464
+ shouldRefreshInputs = true;
465
+ }
466
+ } else {
467
+ // mutationobserver only provides the parent nodes,
468
+ // so let's collect all childs as well to find nested inputs
469
+ const $addedInputs = $(collectNodes(mutation.addedNodes)).filter('a[href], [tabindex], :input:enabled').filter(':visible');
470
+ const $removedInputs = $(collectNodes(mutation.removedNodes)).filter('a[href], [tabindex], :input');
471
+ if ($addedInputs.length > 0 || $removedInputs.length > 0) {
472
+ shouldRefreshInputs = true;
473
+ if ($addedInputs.filter(':input').length > 0 || $removedInputs.filter(':input').length > 0) {
474
+ ignoreAutofocus = false;
475
+ }
476
+ }
477
+ }
478
+
479
+ return !shouldRefreshInputs;
480
+ });
481
+
482
+ if (shouldRefreshInputs) {
483
+ module.refreshInputs(ignoreAutofocus);
484
+ }
485
+ });
486
+ observer.observe(element, {
487
+ attributeFilter: ['class', 'disabled'],
488
+ attributes: true,
489
+ childList: true,
490
+ subtree: true,
491
+ });
492
+ module.debug('Setting up mutation observer', observer);
493
+ },
494
+ refresh: function () {
495
+ module.verbose('Refreshing selector cache');
496
+ $context = contextCheck(settings.context, window);
497
+ module.refreshFlyouts();
498
+ $pusher = $context.children(selector.pusher);
499
+ module.clear.cache();
500
+ },
501
+
502
+ refreshFlyouts: function () {
503
+ module.verbose('Refreshing other flyouts');
504
+ $flyouts = $context.children(selector.flyout);
505
+ },
506
+
507
+ refreshInputs: function (ignoreAutofocus) {
508
+ if ($inputs) {
509
+ $inputs
510
+ .off('keydown' + elementNamespace);
511
+ }
512
+ if (!settings.dimPage) {
513
+ return;
514
+ }
515
+ $inputs = $module.find('a[href], [tabindex], :input:enabled').filter(':visible').filter(function () {
516
+ return $(this).closest('.disabled').length === 0;
517
+ });
518
+ if ($inputs.filter(':input').length === 0) {
519
+ $inputs = $module.add($inputs);
520
+ $module.attr('tabindex', -1);
521
+ } else {
522
+ $module.removeAttr('tabindex');
523
+ }
524
+ $inputs.first()
525
+ .on('keydown' + elementNamespace, module.event.inputKeyDown.first);
526
+ $inputs.last()
527
+ .on('keydown' + elementNamespace, module.event.inputKeyDown.last);
528
+ if (!ignoreAutofocus && settings.autofocus && $inputs.filter(':focus').length === 0) {
529
+ module.set.autofocus();
530
+ }
531
+ },
532
+
533
+ setup: {
534
+ cache: function () {
535
+ module.cache = {
536
+ width: $module.outerWidth(),
537
+ height: $module.outerHeight(),
538
+ };
539
+ },
540
+ layout: function () {
541
+ if ($context.children(selector.pusher).length === 0) {
542
+ module.debug('Adding wrapper element for flyout');
543
+ module.error(error.pusher);
544
+ $pusher = $('<div class="pusher" />');
545
+ $context
546
+ .children()
547
+ .not(selector.omitted)
548
+ .not($flyouts)
549
+ .wrapAll($pusher);
550
+ module.refresh();
551
+ }
552
+ if ($module.nextAll(selector.pusher).length === 0 || $module.nextAll(selector.pusher)[0] !== $pusher[0]) {
553
+ module.debug('Moved flyout to correct parent element');
554
+ module.error(error.movedFlyout, element);
555
+ $module.detach().prependTo($context);
556
+ module.refresh();
557
+ }
558
+ if (module.is.mobile()) {
559
+ $module.addClass(className.fullscreen);
560
+ }
561
+ module.clear.cache();
562
+ module.set.pushable();
563
+ module.set.direction();
564
+ },
565
+ heights: function () {
566
+ module.debug('Setting up heights', $module);
567
+ const $header = $module.children(selector.header);
568
+ const $content = $module.children(selector.content);
569
+ const $actions = $module.children(selector.actions);
570
+ const newContentHeight = ($context.height() || 0) - ($header.outerHeight() || 0) - ($actions.outerHeight() || 0);
571
+ if (newContentHeight > 0) {
572
+ $content.css('min-height', String(newContentHeight) + 'px');
573
+ }
574
+ },
575
+ },
576
+
577
+ attachEvents: function (selector, event) {
578
+ const $toggle = $(selector);
579
+ event = isFunction(module[event])
580
+ ? module[event]
581
+ : module.toggle;
582
+ if ($toggle.length > 0) {
583
+ module.debug('Attaching flyout events to element', selector, event);
584
+ $toggle
585
+ .on('click' + eventNamespace, event);
586
+ } else {
587
+ module.error(error.notFound, selector);
588
+ }
589
+ },
590
+
591
+ show: function (callback) {
592
+ callback = isFunction(callback)
593
+ ? callback
594
+ : function () {};
595
+ if (module.is.hidden()) {
596
+ if (settings.onShow.call(element) === false) {
597
+ module.verbose('Show callback returned false cancelling show');
598
+
599
+ return;
600
+ }
601
+ module.refresh();
602
+ if (module.othersActive()) {
603
+ module.debug('Other flyouts currently visible');
604
+ if (settings.exclusive) {
605
+ module.hideOthers();
606
+ } else {
607
+ ignoreRepeatedEvents = false;
608
+ }
609
+ }
610
+ module.set.dimmerStyles();
611
+ module.set.observeAttributes(false);
612
+ module.pushPage(function () {
613
+ callback.call(element);
614
+ settings.onVisible.call(element);
615
+ if (settings.keyboardShortcuts) {
616
+ module.add.keyboardShortcuts();
617
+ }
618
+ module.save.focus();
619
+ module.refreshInputs();
620
+ requestAnimationFrame(module.set.observeAttributes);
621
+ });
622
+ settings.onChange.call(element);
623
+ } else {
624
+ module.debug('Flyout is already visible');
625
+ }
626
+ },
627
+
628
+ hide: function (callback) {
629
+ callback = isFunction(callback)
630
+ ? callback
631
+ : function () {};
632
+ if (settings.onHide.call(element, $(this)) === false) {
633
+ module.verbose('Hide callback returned false cancelling hide');
634
+ ignoreRepeatedEvents = false;
635
+
636
+ return false;
637
+ }
638
+ if (module.is.visible() || module.is.animating()) {
639
+ module.debug('Hiding flyout', callback);
640
+ module.refreshFlyouts();
641
+ module.set.observeAttributes(false);
642
+ module.pullPage(function () {
643
+ callback.call(element);
644
+ if (isFunction(settings.onHidden)) {
645
+ settings.onHidden.call(element);
646
+ }
647
+ module.restore.focus();
648
+ });
649
+ settings.onChange.call(element);
650
+ }
651
+ },
652
+
653
+ othersAnimating: function () {
654
+ return $flyouts.not($module).filter('.' + className.animating).length > 0;
655
+ },
656
+ othersVisible: function () {
657
+ return $flyouts.not($module).filter('.' + className.visible).length > 0;
658
+ },
659
+ othersActive: function () {
660
+ return module.othersVisible() || module.othersAnimating();
661
+ },
662
+
663
+ hideOthers: function (callback = function () {}) {
664
+ const $otherFlyouts = $flyouts.not($module).filter('.' + className.visible);
665
+ const flyoutCount = $otherFlyouts.length;
666
+ let callbackCount = 0;
667
+ $otherFlyouts
668
+ .flyout('hide', function () {
669
+ callbackCount++;
670
+ if (callbackCount === flyoutCount && isFunction(callback)) {
671
+ callback();
672
+ }
673
+ });
674
+ },
675
+
676
+ toggle: function () {
677
+ module.verbose('Determining toggled direction');
678
+ if (module.is.hidden()) {
679
+ module.show();
680
+ } else {
681
+ module.hide();
682
+ }
683
+ },
684
+
685
+ pushPage: function (callback) {
686
+ callback = isFunction(callback)
687
+ ? callback
688
+ : function () {};
689
+ module.set.overlay();
690
+ if (settings.returnScroll) {
691
+ currentScroll = (isBody ? $window : $context).scrollTop();
692
+ }
693
+ module.bind.scrollLock();
694
+ const animate = function () {
695
+ module.bind.clickaway();
696
+ module.add.inlineCSS();
697
+ module.set.animating();
698
+ module.set.visible();
699
+ };
700
+ const dim = function () {
701
+ module.set.dimmed();
702
+ };
703
+ const transitionEnd = function (event) {
704
+ if (event.target === $module[0]) {
705
+ $module.off('transitionend' + elementNamespace, transitionEnd);
706
+ module.remove.animating();
707
+ callback.call(element);
708
+ }
709
+ };
710
+ $module.off('transitionend' + elementNamespace);
711
+ $module.on('transitionend' + elementNamespace, transitionEnd);
712
+ requestAnimationFrame(animate);
713
+ if (settings.dimPage && !module.othersVisible()) {
714
+ requestAnimationFrame(dim);
715
+ }
716
+ },
717
+
718
+ pullPage: function (callback) {
719
+ callback = isFunction(callback)
720
+ ? callback
721
+ : function () {};
722
+ module.verbose('Removing context push state', module.get.direction());
723
+
724
+ module.unbind.clickaway();
725
+ if (!module.othersActive()) {
726
+ module.unbind.scrollLock();
727
+ if (settings.keyboardShortcuts) {
728
+ module.remove.keyboardShortcuts();
729
+ }
730
+ }
731
+
732
+ const animate = function () {
733
+ module.set.overlay();
734
+ module.set.animating();
735
+ if (settings.dimPage && !module.othersVisible()) {
736
+ module.set.closing();
737
+ }
738
+ module.remove.visible();
739
+ };
740
+ const transitionEnd = function (event) {
741
+ if (event.target === $module[0]) {
742
+ $module.off('transitionend' + elementNamespace, transitionEnd);
743
+ module.remove.animating();
744
+ module.remove.closing();
745
+ module.remove.overlay();
746
+ module.remove.inlineCSS();
747
+ if (settings.returnScroll) {
748
+ module.scrollBack();
749
+ }
750
+ if (settings.dimPage && !module.othersVisible()) {
751
+ $pusher.removeClass(className.dimmed);
752
+ }
753
+ callback.call(element);
754
+ }
755
+ };
756
+ $module.off('transitionend' + elementNamespace);
757
+ $module.on('transitionend' + elementNamespace, transitionEnd);
758
+ requestAnimationFrame(animate);
759
+ },
760
+
761
+ scrollToTop: function () {
762
+ module.verbose('Scrolling to top of page to avoid animation issues');
763
+ $module.scrollTop(0);
764
+ (isBody ? $window : $context)[0].scrollTo(0, 0);
765
+ },
766
+
767
+ scrollBack: function () {
768
+ module.verbose('Scrolling back to original page position');
769
+ (isBody ? $window : $context)[0].scrollTo(0, currentScroll);
770
+ },
771
+
772
+ clear: {
773
+ cache: function () {
774
+ module.verbose('Clearing cached dimensions');
775
+ module.cache = {};
776
+ },
777
+ },
778
+
779
+ set: {
780
+ observeAttributes: function (state) {
781
+ observeAttributes = state !== false;
782
+ },
783
+ autofocus: function () {
784
+ const $autofocus = $inputs.filter('[autofocus]');
785
+ const $rawInputs = $inputs.filter(':input');
786
+ const $input = ($autofocus.length > 0
787
+ ? $autofocus
788
+ : ($rawInputs.length > 0
789
+ ? $rawInputs
790
+ : $module)
791
+ ).first();
792
+ $input.trigger('focus');
793
+ },
794
+ dimmerStyles: function () {
795
+ if (settings.blurring) {
796
+ $pusher.addClass(className.blurring);
797
+ } else {
798
+ $pusher.removeClass(className.blurring);
799
+ }
800
+ },
801
+ bodyMargin: function () {
802
+ const position = module.can.leftBodyScrollbar() ? 'left' : 'right';
803
+ $context.css((isBody ? 'margin-' : 'padding-') + position, tempBodyMargin + 'px');
804
+ $context.find(selector.bodyFixed.replace('right', position)).each(function () {
805
+ const el = $(this);
806
+ const attribute = el.css('position') === 'fixed' ? 'padding-' + position : position;
807
+ el.css(attribute, 'calc(' + el.css(attribute) + ' + ' + tempBodyMargin + 'px)');
808
+ });
809
+ },
810
+
811
+ // container
812
+ pushed: function () {
813
+ $context.addClass(className.pushed);
814
+ },
815
+ pushable: function () {
816
+ $context.addClass(className.pushable);
817
+ },
818
+
819
+ // pusher
820
+ dimmed: function () {
821
+ $pusher.addClass(className.dimmed);
822
+ },
823
+
824
+ // flyout
825
+ active: function () {
826
+ $module.addClass(className.active);
827
+ },
828
+ animating: function () {
829
+ $module.addClass(className.animating);
830
+ },
831
+ closing: function () {
832
+ $pusher.addClass(className.closing);
833
+ },
834
+ direction: function (direction = module.get.direction()) {
835
+ $module.addClass(className[direction]);
836
+ },
837
+ visible: function () {
838
+ $module.addClass(className.visible);
839
+ },
840
+ overlay: function () {
841
+ $module.addClass(className.overlay);
842
+ },
843
+ },
844
+ remove: {
845
+
846
+ inlineCSS: function () {
847
+ module.debug('Removing inline css styles', $style);
848
+ if ($style && $style.length > 0) {
849
+ $style.remove();
850
+ }
851
+ },
852
+ keyboardShortcuts: function () {
853
+ module.verbose('Removing keyboard shortcuts');
854
+ $document
855
+ .off('keydown' + eventNamespace);
856
+ },
857
+
858
+ // context
859
+ pushed: function () {
860
+ $context.removeClass(className.pushed);
861
+ },
862
+ pushable: function () {
863
+ $context.removeClass(className.pushable);
864
+ },
865
+
866
+ // flyout
867
+ active: function () {
868
+ $module.removeClass(className.active);
869
+ },
870
+ animating: function () {
871
+ $module.removeClass(className.animating);
872
+ },
873
+ closing: function () {
874
+ $pusher.removeClass(className.closing);
875
+ },
876
+ direction: function (direction = module.get.direction()) {
877
+ $module.removeClass(className[direction]);
878
+ },
879
+ visible: function () {
880
+ $module.removeClass(className.visible);
881
+ },
882
+ overlay: function () {
883
+ $module.removeClass(className.overlay);
884
+ },
885
+ },
886
+
887
+ get: {
888
+ direction: function () {
889
+ if ($module.hasClass(className.top)) {
890
+ return className.top;
891
+ }
892
+ if ($module.hasClass(className.right)) {
893
+ return className.right;
894
+ }
895
+ if ($module.hasClass(className.bottom)) {
896
+ return className.bottom;
897
+ }
898
+
899
+ return className.left;
900
+ },
901
+ id: function () {
902
+ return id;
903
+ },
904
+ element: function () {
905
+ return $module;
906
+ },
907
+ settings: function () {
908
+ return settings;
909
+ },
910
+ },
911
+
912
+ can: {
913
+ leftBodyScrollbar: function () {
914
+ if (module.cache.leftBodyScrollbar === undefined) {
915
+ module.cache.leftBodyScrollbar = module.is.rtl() && ((module.is.iframe && !module.is.firefox()) || module.is.safari());
916
+ }
917
+
918
+ return module.cache.leftBodyScrollbar;
919
+ },
920
+ },
921
+
922
+ save: {
923
+ focus: function () {
924
+ const $activeElement = $(document.activeElement);
925
+ const inCurrentFlyout = $activeElement.closest($module).length > 0;
926
+ if (!inCurrentFlyout) {
927
+ $focusedElement = $(document.activeElement).trigger('blur');
928
+ }
929
+ },
930
+ bodyMargin: function () {
931
+ initialBodyMargin = $context.css((isBody ? 'margin-' : 'padding-') + (module.can.leftBodyScrollbar() ? 'left' : 'right'));
932
+ initialBodyMarginInt = Number.parseInt(initialBodyMargin.replace(/[^\d.]/g, ''), 10);
933
+ const bodyScrollbarWidth = isBody ? window.innerWidth - document.documentElement.clientWidth : $context[0].offsetWidth - $context[0].clientWidth;
934
+ tempBodyMargin = initialBodyMarginInt + bodyScrollbarWidth;
935
+ },
936
+ },
937
+
938
+ is: {
939
+ safari: function () {
940
+ if (module.cache.isSafari === undefined) {
941
+ module.cache.isSafari = /constructor/i.test(window.HTMLElement) || !!window.ApplePaySession;
942
+ }
943
+
944
+ return module.cache.isSafari;
945
+ },
946
+ firefox: function () {
947
+ if (module.cache.isFirefox === undefined) {
948
+ module.cache.isFirefox = !!window.InstallTrigger;
949
+ }
950
+
951
+ return module.cache.isFirefox;
952
+ },
953
+ iframe: function () {
954
+ return !(window.self === window.top);
955
+ },
956
+ mobile: function () {
957
+ const userAgent = navigator.userAgent;
958
+ const isMobile = userAgent.match(regExp.mobile);
959
+ if (isMobile) {
960
+ module.verbose('Browser was found to be mobile', userAgent);
961
+
962
+ return true;
963
+ }
964
+
965
+ module.verbose('Browser is not mobile, using regular transition', userAgent);
966
+
967
+ return false;
968
+ },
969
+ hidden: function () {
970
+ return !module.is.visible();
971
+ },
972
+ visible: function () {
973
+ return $module.hasClass(className.visible);
974
+ },
975
+ animating: function () {
976
+ return $context.hasClass(className.animating);
977
+ },
978
+ rtl: function () {
979
+ if (module.cache.isRTL === undefined) {
980
+ module.cache.isRTL = $module.attr('dir') === 'rtl' || $module.css('direction') === 'rtl' || $body.attr('dir') === 'rtl' || $body.css('direction') === 'rtl' || $context.attr('dir') === 'rtl' || $context.css('direction') === 'rtl';
981
+ }
982
+
983
+ return module.cache.isRTL;
984
+ },
985
+ },
986
+
987
+ has: {
988
+ configActions: function () {
989
+ return Array.isArray(settings.actions) && settings.actions.length > 0;
990
+ },
991
+ scrollbar: function () {
992
+ return isBody || $context.css('overflow-y') !== 'hidden';
993
+ },
994
+ },
995
+
996
+ restore: {
997
+ focus: function () {
998
+ if ($focusedElement && $focusedElement.length > 0 && settings.restoreFocus) {
999
+ $focusedElement.trigger('focus');
1000
+ }
1001
+ },
1002
+ bodyMargin: function () {
1003
+ const position = module.can.leftBodyScrollbar() ? 'left' : 'right';
1004
+ $context.css((isBody ? 'margin-' : 'padding-') + position, initialBodyMarginInt === 0 ? '' : initialBodyMargin);
1005
+ $context.find(selector.bodyFixed.replace('right', position)).each(function () {
1006
+ const el = $(this);
1007
+ const attribute = el.css('position') === 'fixed' ? 'padding-' + position : position;
1008
+ el.css(attribute, '');
1009
+ });
1010
+ },
1011
+ },
1012
+
1013
+ helpers: {
1014
+ escape: function (string, settings) {
1015
+ if (settings !== undefined && settings.preserveHTML) {
1016
+ return string;
1017
+ }
1018
+
1019
+ const escapeMap = {
1020
+ '"': '&quot;',
1021
+ '&': '&amp;',
1022
+ "'": '&apos;',
1023
+ '<': '&lt;',
1024
+ '>': '&gt;',
1025
+ };
1026
+
1027
+ return String(string).replace(/["&'<>]/g, (chr) => escapeMap[chr]);
1028
+ },
1029
+ },
1030
+
1031
+ setting: function (name, value) {
1032
+ module.debug('Changing setting', name, value);
1033
+ if ($.isPlainObject(name)) {
1034
+ $.extend(true, settings, name);
1035
+ } else if (value !== undefined) {
1036
+ if ($.isPlainObject(settings[name])) {
1037
+ $.extend(true, settings[name], value);
1038
+ } else {
1039
+ settings[name] = value;
1040
+ }
1041
+ } else {
1042
+ return settings[name];
1043
+ }
1044
+ },
1045
+ internal: function (name, value) {
1046
+ if ($.isPlainObject(name)) {
1047
+ $.extend(true, module, name);
1048
+ } else if (value !== undefined) {
1049
+ module[name] = value;
1050
+ } else {
1051
+ return module[name];
1052
+ }
1053
+ },
1054
+ debug: function (...args) {
1055
+ if (!settings.silent && settings.debug) {
1056
+ if (settings.performance) {
1057
+ module.performance.log(args);
1058
+ } else {
1059
+ module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
1060
+ module.debug.apply(console, args);
1061
+ }
1062
+ }
1063
+ },
1064
+ verbose: function (...args) {
1065
+ if (!settings.silent && settings.verbose && settings.debug) {
1066
+ if (settings.performance) {
1067
+ module.performance.log(args);
1068
+ } else {
1069
+ module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
1070
+ module.verbose.apply(console, args);
1071
+ }
1072
+ }
1073
+ },
1074
+ error: function (...args) {
1075
+ if (!settings.silent) {
1076
+ module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
1077
+ module.error.apply(console, args);
1078
+ }
1079
+ },
1080
+ performance: {
1081
+ log: function (message) {
1082
+ let currentTime;
1083
+ let executionTime;
1084
+ let previousTime;
1085
+ if (settings.performance) {
1086
+ currentTime = Date.now();
1087
+ previousTime = time || currentTime;
1088
+ executionTime = currentTime - previousTime;
1089
+ time = currentTime;
1090
+ performance.push({
1091
+ Name: message[0],
1092
+ Arguments: message.slice(1),
1093
+ Element: element,
1094
+ 'Execution Time': executionTime,
1095
+ });
1096
+ }
1097
+ clearTimeout(module.performance.timer);
1098
+ module.performance.timer = setTimeout(function () {
1099
+ module.performance.display();
1100
+ }, 500);
1101
+ },
1102
+ display: function () {
1103
+ let title = settings.name + ':';
1104
+ let totalTime = 0;
1105
+ time = false;
1106
+ clearTimeout(module.performance.timer);
1107
+ $.each(performance, function (index, data) {
1108
+ totalTime += data['Execution Time'];
1109
+ });
1110
+ title += ' ' + totalTime + 'ms';
1111
+ if (performance.length > 0) {
1112
+ console.groupCollapsed(title);
1113
+ console.table(performance);
1114
+ console.groupEnd();
1115
+ }
1116
+ performance = [];
1117
+ },
1118
+ },
1119
+ invoke: function (query, passedArguments = queryArguments, context = element) {
1120
+ let object = instance;
1121
+ let maxDepth;
1122
+ let found;
1123
+ let response;
1124
+ if (typeof query === 'string' && object !== undefined) {
1125
+ query = query.split(/[ .]/);
1126
+ maxDepth = query.length - 1;
1127
+ $.each(query, function (depth, value) {
1128
+ const camelCaseValue = depth !== maxDepth
1129
+ ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
1130
+ : query;
1131
+ if ($.isPlainObject(object[camelCaseValue]) && (depth !== maxDepth)) {
1132
+ object = object[camelCaseValue];
1133
+ } else if (object[camelCaseValue] !== undefined) {
1134
+ found = object[camelCaseValue];
1135
+
1136
+ return false;
1137
+ } else if ($.isPlainObject(object[value]) && (depth !== maxDepth)) {
1138
+ object = object[value];
1139
+ } else if (object[value] !== undefined) {
1140
+ found = object[value];
1141
+
1142
+ return false;
1143
+ } else {
1144
+ module.error(error.method, query);
1145
+
1146
+ return false;
1147
+ }
1148
+ });
1149
+ }
1150
+ if (isFunction(found)) {
1151
+ response = found.apply(context, passedArguments);
1152
+ } else if (found !== undefined) {
1153
+ response = found;
1154
+ }
1155
+ if (Array.isArray(returnedValue)) {
1156
+ returnedValue.push(response);
1157
+ } else if (returnedValue !== undefined) {
1158
+ returnedValue = [returnedValue, response];
1159
+ } else if (response !== undefined) {
1160
+ returnedValue = response;
1161
+ }
1162
+
1163
+ return found;
1164
+ },
1165
+ };
1166
+
1167
+ if (methodInvoked) {
1168
+ if (instance === undefined) {
1169
+ if (isFunction(settings.templates[parameters])) {
1170
+ settings.autoShow = true;
1171
+ settings.className.flyout = settings.className.template;
1172
+ settings = $.extend(true, {}, settings, settings.templates[parameters].apply(module, queryArguments));
1173
+
1174
+ // reassign shortcuts
1175
+ className = settings.className;
1176
+ namespace = settings.namespace;
1177
+ fields = settings.fields;
1178
+ error = settings.error;
1179
+ }
1180
+ module.initialize();
1181
+ }
1182
+ if (!isFunction(settings.templates[parameters])) {
1183
+ module.invoke(parameters);
1184
+ }
1185
+ } else {
1186
+ if (instance !== undefined) {
1187
+ instance.invoke('destroy');
1188
+ }
1189
+ module.initialize();
1190
+ returnedValue = $module;
1191
+ }
1192
+ });
1193
+
1194
+ return returnedValue !== undefined
1195
+ ? returnedValue
1196
+ : this;
1197
+ };
1198
+ $.flyout = $.fn.flyout;
1199
+
1200
+ $.fn.flyout.settings = {
1201
+
1202
+ name: 'Flyout',
1203
+ namespace: 'flyout',
1204
+
1205
+ silent: false,
1206
+ debug: false,
1207
+ verbose: false,
1208
+ performance: true,
1209
+
1210
+ context: 'body',
1211
+ exclusive: false,
1212
+ closable: true,
1213
+ autofocus: true,
1214
+ restoreFocus: true,
1215
+ dimPage: true,
1216
+ scrollLock: false,
1217
+ returnScroll: false,
1218
+ delaySetup: false,
1219
+ autoShow: false,
1220
+
1221
+ keyboardShortcuts: true,
1222
+
1223
+ // dynamic content
1224
+ title: '',
1225
+ content: '',
1226
+ class: '',
1227
+ classTitle: '',
1228
+ classContent: '',
1229
+ classActions: '',
1230
+ closeIcon: false,
1231
+ actions: false,
1232
+ preserveHTML: false,
1233
+
1234
+ fields: {
1235
+ class: 'class',
1236
+ text: 'text',
1237
+ icon: 'icon',
1238
+ click: 'click',
1239
+ },
1240
+
1241
+ onChange: function () {},
1242
+ onShow: function () {},
1243
+ onHide: function () {
1244
+ return true;
1245
+ },
1246
+
1247
+ onHidden: false,
1248
+ onVisible: function () {},
1249
+
1250
+ onApprove: function () {},
1251
+ onDeny: function () {},
1252
+
1253
+ keys: {
1254
+ space: 32,
1255
+ enter: 13,
1256
+ escape: 27,
1257
+ tab: 9,
1258
+ },
1259
+
1260
+ className: {
1261
+ flyout: 'ui flyout',
1262
+ close: 'close icon',
1263
+ header: 'ui header',
1264
+ content: 'content',
1265
+ actions: 'actions',
1266
+ active: 'active',
1267
+ animating: 'animating',
1268
+ blurring: 'blurring',
1269
+ closing: 'closing',
1270
+ dimmed: 'dimmed',
1271
+ locked: 'locked',
1272
+ pushable: 'pushable',
1273
+ pushed: 'pushed',
1274
+ right: 'right',
1275
+ top: 'top',
1276
+ left: 'left',
1277
+ bottom: 'bottom',
1278
+ visible: 'visible',
1279
+ overlay: 'overlay',
1280
+ fullscreen: 'fullscreen',
1281
+ template: 'ui flyout',
1282
+ button: 'ui button',
1283
+ ok: 'positive',
1284
+ cancel: 'negative',
1285
+ prompt: 'ui fluid input',
1286
+ },
1287
+
1288
+ selector: {
1289
+ bodyFixed: '> .ui.fixed.menu, > .ui.right.toast-container, > .ui.right.sidebar, > .ui.right.flyout, > .ui.fixed.nag, > .ui.fixed.nag > .close',
1290
+ fixed: '.fixed',
1291
+ omitted: 'script, link, style, .ui.modal, .ui.dimmer, .ui.nag, .ui.fixed',
1292
+ pusher: '.pusher',
1293
+ flyout: '.ui.flyout',
1294
+ header: '.ui.header',
1295
+ content: '.content',
1296
+ actions: '.actions',
1297
+ close: '.close',
1298
+ approve: '.actions .positive, .actions .approve, .actions .ok',
1299
+ deny: '.actions .negative, .actions .deny, .actions .cancel',
1300
+ },
1301
+
1302
+ regExp: {
1303
+ mobile: /Mobile|iP(hone|od|ad)|Android|BlackBerry|IEMobile|Kindle|NetFront|Silk-Accelerated|(hpw|web)OS|Fennec|Minimo|Opera M(obi|ini)|Blazer|Dolfin|Dolphin|Skyfire|Zune/g,
1304
+ },
1305
+
1306
+ error: {
1307
+ method: 'The method you called is not defined.',
1308
+ pusher: 'Had to add pusher element. For optimal performance make sure body content is inside a pusher element',
1309
+ movedFlyout: 'Had to move flyout. For optimal performance make sure flyout and pusher are direct children of your body tag',
1310
+ notFound: 'There were no elements that matched the specified selector',
1311
+ },
1312
+
1313
+ text: {
1314
+ ok: 'Ok',
1315
+ cancel: 'Cancel',
1316
+ close: 'Close',
1317
+ },
1318
+ };
1319
+
1320
+ $.fn.flyout.settings.templates = {
1321
+ getArguments: function (queryArguments) {
1322
+ if ($.isPlainObject(queryArguments[0])) {
1323
+ return $.extend({
1324
+ handler: function () {},
1325
+ content: '',
1326
+ title: '',
1327
+ }, queryArguments[0]);
1328
+ }
1329
+ if (!isFunction(queryArguments[queryArguments.length - 1])) {
1330
+ queryArguments.push(function () {});
1331
+ }
1332
+
1333
+ return {
1334
+ handler: queryArguments.pop(),
1335
+ content: queryArguments.pop() || '',
1336
+ title: queryArguments.pop() || '',
1337
+ };
1338
+ },
1339
+ alert: function (...args) {
1340
+ const settings = this.get.settings();
1341
+ args = settings.templates.getArguments(args);
1342
+
1343
+ return {
1344
+ title: args.title,
1345
+ content: args.content,
1346
+ actions: [{
1347
+ text: settings.text.ok,
1348
+ class: settings.className.ok,
1349
+ click: args.handler,
1350
+ }],
1351
+ };
1352
+ },
1353
+ confirm: function (...args) {
1354
+ const settings = this.get.settings();
1355
+ args = settings.templates.getArguments(args);
1356
+
1357
+ return {
1358
+ title: args.title,
1359
+ content: args.content,
1360
+ actions: [{
1361
+ text: settings.text.ok,
1362
+ class: settings.className.ok,
1363
+ click: function () {
1364
+ args.handler(true);
1365
+ },
1366
+ }, {
1367
+ text: settings.text.cancel,
1368
+ class: settings.className.cancel,
1369
+ click: function () {
1370
+ args.handler(false);
1371
+ },
1372
+ }],
1373
+ };
1374
+ },
1375
+ prompt: function (...args) {
1376
+ const $this = this;
1377
+ const settings = this.get.settings();
1378
+ args = settings.templates.getArguments(args);
1379
+ const input = $($.parseHTML(args.content)).filter('.ui.input');
1380
+ if (input.length === 0) {
1381
+ args.content += '<p><div class="' + settings.className.prompt + '"><input placeholder="' + this.helpers.escape(args.placeholder || '') + '" type="text" value="' + this.helpers.escape(args.defaultValue || '') + '"></div></p>';
1382
+ }
1383
+
1384
+ return {
1385
+ title: args.title,
1386
+ content: args.content,
1387
+ actions: [{
1388
+ text: settings.text.ok,
1389
+ class: settings.className.ok,
1390
+ click: function () {
1391
+ const settings = $this.get.settings();
1392
+ const inputField = $this.get.element().find(settings.selector.prompt)[0];
1393
+ args.handler($(inputField).val());
1394
+ },
1395
+ }, {
1396
+ text: settings.text.cancel,
1397
+ class: settings.className.cancel,
1398
+ click: function () {
1399
+ args.handler(null);
1400
+ },
1401
+ }],
1402
+ };
1403
+ },
1404
+ };
1405
+ })(jQuery, window, document);