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,917 @@
1
+ /*!
2
+ * # Fomantic-UI 2.9.4 - Sticky
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.sticky = function (parameters) {
23
+ var
24
+ $allModules = $(this),
25
+ $document = $(document),
26
+
27
+ time = Date.now(),
28
+ performance = [],
29
+
30
+ query = arguments[0],
31
+ methodInvoked = typeof query === 'string',
32
+ queryArguments = [].slice.call(arguments, 1),
33
+ contextCheck = function (context, win) {
34
+ var $context;
35
+ if ([window, document].indexOf(context) >= 0) {
36
+ $context = $(context);
37
+ } else {
38
+ $context = $(win.document).find(context);
39
+ if ($context.length === 0) {
40
+ $context = win.frameElement ? contextCheck(context, win.parent) : window;
41
+ }
42
+ }
43
+
44
+ return $context;
45
+ },
46
+ returnedValue
47
+ ;
48
+
49
+ $allModules.each(function () {
50
+ var
51
+ settings = $.isPlainObject(parameters)
52
+ ? $.extend(true, {}, $.fn.sticky.settings, parameters)
53
+ : $.extend({}, $.fn.sticky.settings),
54
+
55
+ className = settings.className,
56
+ namespace = settings.namespace,
57
+ error = settings.error,
58
+
59
+ eventNamespace = '.' + namespace,
60
+ moduleNamespace = 'module-' + namespace,
61
+
62
+ $module = $(this),
63
+ $window = $(window),
64
+ $scroll = contextCheck(settings.scrollContext, window),
65
+ $container,
66
+ $context,
67
+
68
+ instance = $module.data(moduleNamespace),
69
+
70
+ element = this,
71
+
72
+ documentObserver,
73
+ observer,
74
+ module
75
+ ;
76
+
77
+ module = {
78
+
79
+ initialize: function () {
80
+ module.determineContainer();
81
+ module.determineContext();
82
+ module.verbose('Initializing sticky', settings, $container);
83
+
84
+ module.save.positions();
85
+ module.checkErrors();
86
+ module.bind.events();
87
+
88
+ if (settings.observeChanges) {
89
+ module.observeChanges();
90
+ }
91
+ module.instantiate();
92
+ },
93
+
94
+ instantiate: function () {
95
+ module.verbose('Storing instance of module', module);
96
+ instance = module;
97
+ $module
98
+ .data(moduleNamespace, module)
99
+ ;
100
+ },
101
+
102
+ destroy: function () {
103
+ module.verbose('Destroying previous instance');
104
+ module.reset();
105
+ if (documentObserver) {
106
+ documentObserver.disconnect();
107
+ }
108
+ if (observer) {
109
+ observer.disconnect();
110
+ }
111
+ $window
112
+ .off('load' + eventNamespace, module.event.load)
113
+ .off('resize' + eventNamespace, module.event.resize)
114
+ ;
115
+ $scroll
116
+ .off('scrollchange' + eventNamespace, module.event.scrollchange)
117
+ ;
118
+ $module.removeData(moduleNamespace);
119
+ },
120
+
121
+ observeChanges: function () {
122
+ if ('MutationObserver' in window) {
123
+ documentObserver = new MutationObserver(module.event.documentChanged);
124
+ observer = new MutationObserver(module.event.changed);
125
+ documentObserver.observe(document, {
126
+ childList: true,
127
+ subtree: true,
128
+ });
129
+ observer.observe(element, {
130
+ childList: true,
131
+ subtree: true,
132
+ });
133
+ observer.observe($context[0], {
134
+ childList: true,
135
+ subtree: true,
136
+ });
137
+ module.debug('Setting up mutation observer', observer);
138
+ }
139
+ },
140
+
141
+ determineContainer: function () {
142
+ $container = settings.container ? contextCheck(settings.container, window) : $module.offsetParent();
143
+ },
144
+
145
+ determineContext: function () {
146
+ $context = settings.context ? contextCheck(settings.context, window) : $container;
147
+ if ($context.length === 0) {
148
+ module.error(error.invalidContext, settings.context, $module);
149
+ }
150
+ },
151
+
152
+ checkErrors: function () {
153
+ if (module.is.hidden()) {
154
+ module.error(error.visible, $module);
155
+ }
156
+ if (module.cache.element.height > module.cache.context.height) {
157
+ module.reset();
158
+ module.error(error.elementSize, $module);
159
+ }
160
+ },
161
+
162
+ bind: {
163
+ events: function () {
164
+ $window
165
+ .on('load' + eventNamespace, module.event.load)
166
+ .on('resize' + eventNamespace, module.event.resize)
167
+ ;
168
+ // pub/sub pattern
169
+ $scroll
170
+ .off('scroll' + eventNamespace)
171
+ .on('scroll' + eventNamespace, module.event.scroll)
172
+ .on('scrollchange' + eventNamespace, module.event.scrollchange)
173
+ ;
174
+ },
175
+ },
176
+
177
+ event: {
178
+ changed: function (mutations) {
179
+ clearTimeout(module.timer);
180
+ module.timer = setTimeout(function () {
181
+ module.verbose('DOM tree modified, updating sticky menu', mutations);
182
+ module.refresh();
183
+ }, 100);
184
+ },
185
+ documentChanged: function (mutations) {
186
+ [].forEach.call(mutations, function (mutation) {
187
+ if (mutation.removedNodes) {
188
+ [].forEach.call(mutation.removedNodes, function (node) {
189
+ if (node === element || $(node).find(element).length > 0) {
190
+ module.debug('Element removed from DOM, tearing down events');
191
+ module.destroy();
192
+ }
193
+ });
194
+ }
195
+ });
196
+ },
197
+ load: function () {
198
+ module.verbose('Page contents finished loading');
199
+ requestAnimationFrame(module.refresh);
200
+ },
201
+ resize: function () {
202
+ module.verbose('Window resized');
203
+ requestAnimationFrame(module.refresh);
204
+ },
205
+ scroll: function () {
206
+ requestAnimationFrame(function () {
207
+ $scroll.triggerHandler('scrollchange' + eventNamespace, $scroll.scrollTop());
208
+ });
209
+ },
210
+ scrollchange: function (event, scrollPosition) {
211
+ module.stick(scrollPosition);
212
+ settings.onScroll.call(element);
213
+ },
214
+ },
215
+
216
+ refresh: function (hardRefresh) {
217
+ module.reset();
218
+ if (!settings.context) {
219
+ module.determineContext();
220
+ }
221
+ if (hardRefresh) {
222
+ module.determineContainer();
223
+ }
224
+ module.save.positions();
225
+ module.stick();
226
+ settings.onReposition.call(element);
227
+ },
228
+
229
+ supports: {
230
+ sticky: function () {
231
+ var
232
+ $element = $('<div/>')
233
+ ;
234
+ $element.addClass(className.supported);
235
+
236
+ return $element.css('position').match('sticky');
237
+ },
238
+ },
239
+
240
+ save: {
241
+ lastScroll: function (scroll) {
242
+ module.lastScroll = scroll;
243
+ },
244
+ elementScroll: function (scroll) {
245
+ module.elementScroll = scroll;
246
+ },
247
+ positions: function () {
248
+ var
249
+ scrollContext = {
250
+ height: $scroll.height(),
251
+ },
252
+ element = {
253
+ margin: {
254
+ top: parseInt($module.css('margin-top'), 10),
255
+ bottom: parseInt($module.css('margin-bottom'), 10),
256
+ },
257
+ offset: $module.offset(),
258
+ width: $module.outerWidth(),
259
+ height: $module.outerHeight(),
260
+ },
261
+ context = {
262
+ offset: $context.offset(),
263
+ height: $context.outerHeight(),
264
+ }
265
+ ;
266
+ if (!module.is.standardScroll()) {
267
+ module.debug('Non-standard scroll. Removing scroll offset from element offset');
268
+
269
+ scrollContext.top = $scroll.scrollTop();
270
+ scrollContext.left = $scroll.scrollLeft();
271
+
272
+ element.offset.top += scrollContext.top;
273
+ context.offset.top += scrollContext.top;
274
+ element.offset.left += scrollContext.left;
275
+ context.offset.left += scrollContext.left;
276
+ }
277
+ module.cache = {
278
+ fits: (element.height + settings.offset) <= scrollContext.height,
279
+ sameHeight: element.height === context.height,
280
+ scrollContext: {
281
+ height: scrollContext.height,
282
+ },
283
+ element: {
284
+ margin: element.margin,
285
+ top: element.offset.top - element.margin.top,
286
+ left: element.offset.left,
287
+ width: element.width,
288
+ height: element.height,
289
+ bottom: element.offset.top + element.height,
290
+ },
291
+ context: {
292
+ top: context.offset.top,
293
+ height: context.height,
294
+ bottom: context.offset.top + context.height,
295
+ },
296
+ };
297
+ module.set.containerSize();
298
+
299
+ module.stick();
300
+ module.debug('Caching element positions', module.cache);
301
+ },
302
+ },
303
+
304
+ get: {
305
+ direction: function (scroll) {
306
+ var
307
+ direction = 'down'
308
+ ;
309
+ scroll = scroll || $scroll.scrollTop();
310
+ if (module.lastScroll && module.lastScroll > scroll) {
311
+ direction = 'up';
312
+ }
313
+
314
+ return direction;
315
+ },
316
+ scrollChange: function (scroll) {
317
+ scroll = scroll || $scroll.scrollTop();
318
+
319
+ return module.lastScroll
320
+ ? scroll - module.lastScroll
321
+ : 0;
322
+ },
323
+ currentElementScroll: function () {
324
+ if (module.elementScroll) {
325
+ return module.elementScroll;
326
+ }
327
+
328
+ return module.is.top()
329
+ ? Math.abs(parseInt($module.css('top'), 10)) || 0
330
+ : Math.abs(parseInt($module.css('bottom'), 10)) || 0;
331
+ },
332
+
333
+ elementScroll: function (scroll) {
334
+ scroll = scroll || $scroll.scrollTop();
335
+ var
336
+ element = module.cache.element,
337
+ scrollContext = module.cache.scrollContext,
338
+ delta = module.get.scrollChange(scroll),
339
+ maxScroll = element.height - scrollContext.height + settings.offset,
340
+ elementScroll = module.get.currentElementScroll(),
341
+ possibleScroll = elementScroll + delta
342
+ ;
343
+ if (module.cache.fits || possibleScroll < 0) {
344
+ elementScroll = 0;
345
+ } else if (possibleScroll > maxScroll) {
346
+ elementScroll = maxScroll;
347
+ } else {
348
+ elementScroll = possibleScroll;
349
+ }
350
+
351
+ return elementScroll;
352
+ },
353
+ },
354
+
355
+ remove: {
356
+ lastScroll: function () {
357
+ delete module.lastScroll;
358
+ },
359
+ elementScroll: function () {
360
+ delete module.elementScroll;
361
+ },
362
+ minimumSize: function () {
363
+ $container
364
+ .css('min-height', '')
365
+ ;
366
+ },
367
+ offset: function () {
368
+ $module.css('margin-top', '');
369
+ },
370
+ },
371
+
372
+ set: {
373
+ offset: function () {
374
+ module.verbose('Setting offset on element', settings.offset);
375
+ $module
376
+ .css('margin-top', settings.offset)
377
+ ;
378
+ },
379
+ containerSize: function () {
380
+ var
381
+ tagName = $container[0].tagName
382
+ ;
383
+ if (tagName === 'HTML' || tagName === 'body') {
384
+ module.determineContainer();
385
+ } else {
386
+ var tallestHeight = Math.max(module.cache.context.height, module.cache.element.height);
387
+ if (tallestHeight - $container.outerHeight() > settings.jitter) {
388
+ module.debug('Context is taller than container. Specifying exact height for container', module.cache.context.height);
389
+ $container.css({
390
+ height: tallestHeight,
391
+ });
392
+ } else {
393
+ $container.css({
394
+ height: '',
395
+ });
396
+ }
397
+ if (Math.abs($container.outerHeight() - module.cache.context.height) > settings.jitter) {
398
+ module.debug('Context has padding, specifying exact height for container', module.cache.context.height);
399
+ $container.css({
400
+ height: module.cache.context.height,
401
+ });
402
+ }
403
+ }
404
+ },
405
+ minimumSize: function () {
406
+ var
407
+ element = module.cache.element
408
+ ;
409
+ $container
410
+ .css('min-height', element.height)
411
+ ;
412
+ },
413
+ scroll: function (scroll) {
414
+ module.debug('Setting scroll on element', scroll);
415
+ if (module.elementScroll === scroll) {
416
+ return;
417
+ }
418
+ if (module.is.top()) {
419
+ $module
420
+ .css('bottom', '')
421
+ .css('top', -scroll + 'px')
422
+ ;
423
+ }
424
+ if (module.is.bottom()) {
425
+ $module
426
+ .css('top', '')
427
+ .css('bottom', scroll + 'px')
428
+ ;
429
+ }
430
+ },
431
+ size: function () {
432
+ if (module.cache.element.height !== 0 && module.cache.element.width !== 0) {
433
+ element.style.setProperty('width', module.cache.element.width + 'px', 'important');
434
+ element.style.setProperty('height', module.cache.element.height + 'px', 'important');
435
+ }
436
+ },
437
+ },
438
+
439
+ is: {
440
+ standardScroll: function () {
441
+ return $scroll[0] === window;
442
+ },
443
+ top: function () {
444
+ return $module.hasClass(className.top);
445
+ },
446
+ bottom: function () {
447
+ return $module.hasClass(className.bottom);
448
+ },
449
+ initialPosition: function () {
450
+ return !module.is.fixed() && !module.is.bound();
451
+ },
452
+ hidden: function () {
453
+ return !$module.is(':visible');
454
+ },
455
+ bound: function () {
456
+ return $module.hasClass(className.bound);
457
+ },
458
+ fixed: function () {
459
+ return $module.hasClass(className.fixed);
460
+ },
461
+ },
462
+
463
+ stick: function (scrollPosition) {
464
+ var
465
+ cachedPosition = scrollPosition || $scroll.scrollTop(),
466
+ cache = module.cache,
467
+ fits = cache.fits,
468
+ sameHeight = cache.sameHeight,
469
+ element = cache.element,
470
+ scrollContext = cache.scrollContext,
471
+ context = cache.context,
472
+ offset = module.is.bottom() && settings.pushing
473
+ ? settings.bottomOffset
474
+ : settings.offset,
475
+ scroll = {
476
+ top: cachedPosition + offset,
477
+ bottom: cachedPosition + offset + scrollContext.height,
478
+ },
479
+ elementScroll = fits
480
+ ? 0
481
+ : module.get.elementScroll(scroll.top),
482
+
483
+ // shorthand
484
+ doesntFit = !fits,
485
+ elementVisible = element.height !== 0
486
+ ;
487
+ if (elementVisible && !sameHeight) {
488
+ if (module.is.initialPosition()) {
489
+ if (scroll.top >= context.bottom) {
490
+ module.debug('Initial element position is bottom of container');
491
+ module.bindBottom();
492
+ } else if (scroll.top > element.top) {
493
+ if ((element.height + scroll.top - elementScroll) >= context.bottom && element.height < context.height) {
494
+ module.debug('Initial element position is bottom of container');
495
+ module.bindBottom();
496
+ } else {
497
+ module.debug('Initial element position is fixed');
498
+ module.fixTop();
499
+ }
500
+ }
501
+ } else if (module.is.fixed()) {
502
+ if (module.is.top()) {
503
+ if (scroll.top <= element.top) {
504
+ module.debug('Fixed element reached top of container');
505
+ module.setInitialPosition();
506
+ } else if ((element.height + scroll.top - elementScroll) >= context.bottom) {
507
+ module.debug('Fixed element reached bottom of container');
508
+ module.bindBottom();
509
+ } else if (doesntFit) { // scroll element if larger than screen
510
+ module.set.scroll(elementScroll);
511
+ module.save.lastScroll(scroll.top);
512
+ module.save.elementScroll(elementScroll);
513
+ }
514
+ } else if (module.is.bottom()) {
515
+ if ((scroll.bottom - element.height) <= element.top) { // top edge
516
+ module.debug('Bottom fixed rail has reached top of container');
517
+ module.setInitialPosition();
518
+ } else if (scroll.bottom >= context.bottom) { // bottom edge
519
+ module.debug('Bottom fixed rail has reached bottom of container');
520
+ module.bindBottom();
521
+ } else if (doesntFit) { // scroll element if larger than screen
522
+ module.set.scroll(elementScroll);
523
+ module.save.lastScroll(scroll.top);
524
+ module.save.elementScroll(elementScroll);
525
+ }
526
+ }
527
+ } else if (module.is.bottom()) {
528
+ if (scroll.top <= element.top) {
529
+ module.debug('Jumped from bottom fixed to top fixed, most likely used home/end button');
530
+ module.setInitialPosition();
531
+ } else {
532
+ if (settings.pushing) {
533
+ if (module.is.bound() && scroll.bottom <= context.bottom) {
534
+ module.debug('Fixing bottom attached element to bottom of browser.');
535
+ module.fixBottom();
536
+ }
537
+ } else {
538
+ if (module.is.bound() && (scroll.top <= context.bottom - element.height)) {
539
+ module.debug('Fixing bottom attached element to top of browser.');
540
+ module.fixTop();
541
+ }
542
+ }
543
+ }
544
+ }
545
+ }
546
+ },
547
+
548
+ bindTop: function () {
549
+ module.debug('Binding element to top of parent container');
550
+ module.remove.offset();
551
+ if (settings.setSize) {
552
+ module.set.size();
553
+ }
554
+ $module
555
+ .css({
556
+ left: '',
557
+ top: '',
558
+ marginBottom: '',
559
+ })
560
+ .removeClass(className.fixed)
561
+ .removeClass(className.bottom)
562
+ .addClass(className.bound)
563
+ .addClass(className.top)
564
+ ;
565
+ settings.onTop.call(element);
566
+ settings.onUnstick.call(element);
567
+ },
568
+ bindBottom: function () {
569
+ module.debug('Binding element to bottom of parent container');
570
+ module.remove.offset();
571
+ if (settings.setSize) {
572
+ module.set.size();
573
+ }
574
+ $module
575
+ .css({
576
+ left: '',
577
+ top: '',
578
+ })
579
+ .removeClass(className.fixed)
580
+ .removeClass(className.top)
581
+ .addClass(className.bound)
582
+ .addClass(className.bottom)
583
+ ;
584
+ settings.onBottom.call(element);
585
+ settings.onUnstick.call(element);
586
+ },
587
+
588
+ setInitialPosition: function () {
589
+ module.debug('Returning to initial position');
590
+ module.unfix();
591
+ module.unbind();
592
+ },
593
+
594
+ fixTop: function () {
595
+ module.debug('Fixing element to top of page');
596
+ if (settings.setSize) {
597
+ module.set.size();
598
+ }
599
+ module.set.minimumSize();
600
+ module.set.offset();
601
+ $module
602
+ .css({
603
+ left: module.cache.element.left,
604
+ bottom: '',
605
+ marginBottom: '',
606
+ })
607
+ .removeClass(className.bound)
608
+ .removeClass(className.bottom)
609
+ .addClass(className.fixed)
610
+ .addClass(className.top)
611
+ ;
612
+ settings.onStick.call(element);
613
+ },
614
+
615
+ fixBottom: function () {
616
+ module.debug('Sticking element to bottom of page');
617
+ if (settings.setSize) {
618
+ module.set.size();
619
+ }
620
+ module.set.minimumSize();
621
+ module.set.offset();
622
+ $module
623
+ .css({
624
+ left: module.cache.element.left,
625
+ bottom: '',
626
+ marginBottom: '',
627
+ })
628
+ .removeClass(className.bound)
629
+ .removeClass(className.top)
630
+ .addClass(className.fixed)
631
+ .addClass(className.bottom)
632
+ ;
633
+ settings.onStick.call(element);
634
+ },
635
+
636
+ unbind: function () {
637
+ if (module.is.bound()) {
638
+ module.debug('Removing container bound position on element');
639
+ module.remove.offset();
640
+ $module
641
+ .removeClass(className.bound)
642
+ .removeClass(className.top)
643
+ .removeClass(className.bottom)
644
+ ;
645
+ }
646
+ },
647
+
648
+ unfix: function () {
649
+ if (module.is.fixed()) {
650
+ module.debug('Removing fixed position on element');
651
+ module.remove.minimumSize();
652
+ module.remove.offset();
653
+ $module
654
+ .removeClass(className.fixed)
655
+ .removeClass(className.top)
656
+ .removeClass(className.bottom)
657
+ ;
658
+ settings.onUnstick.call(element);
659
+ }
660
+ },
661
+
662
+ reset: function () {
663
+ module.debug('Resetting elements position');
664
+ module.unbind();
665
+ module.unfix();
666
+ module.resetCSS();
667
+ module.remove.offset();
668
+ module.remove.lastScroll();
669
+ },
670
+
671
+ resetCSS: function () {
672
+ $module
673
+ .css({
674
+ width: '',
675
+ height: '',
676
+ })
677
+ ;
678
+ $container
679
+ .css({
680
+ height: '',
681
+ })
682
+ ;
683
+ },
684
+
685
+ setting: function (name, value) {
686
+ if ($.isPlainObject(name)) {
687
+ $.extend(true, settings, name);
688
+ } else if (value !== undefined) {
689
+ settings[name] = value;
690
+ } else {
691
+ return settings[name];
692
+ }
693
+ },
694
+ internal: function (name, value) {
695
+ if ($.isPlainObject(name)) {
696
+ $.extend(true, module, name);
697
+ } else if (value !== undefined) {
698
+ module[name] = value;
699
+ } else {
700
+ return module[name];
701
+ }
702
+ },
703
+ debug: function () {
704
+ if (!settings.silent && settings.debug) {
705
+ if (settings.performance) {
706
+ module.performance.log(arguments);
707
+ } else {
708
+ module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
709
+ module.debug.apply(console, arguments);
710
+ }
711
+ }
712
+ },
713
+ verbose: function () {
714
+ if (!settings.silent && settings.verbose && settings.debug) {
715
+ if (settings.performance) {
716
+ module.performance.log(arguments);
717
+ } else {
718
+ module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
719
+ module.verbose.apply(console, arguments);
720
+ }
721
+ }
722
+ },
723
+ error: function () {
724
+ if (!settings.silent) {
725
+ module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
726
+ module.error.apply(console, arguments);
727
+ }
728
+ },
729
+ performance: {
730
+ log: function (message) {
731
+ var
732
+ currentTime,
733
+ executionTime,
734
+ previousTime
735
+ ;
736
+ if (settings.performance) {
737
+ currentTime = Date.now();
738
+ previousTime = time || currentTime;
739
+ executionTime = currentTime - previousTime;
740
+ time = currentTime;
741
+ performance.push({
742
+ Name: message[0],
743
+ Arguments: [].slice.call(message, 1) || '',
744
+ Element: element,
745
+ 'Execution Time': executionTime,
746
+ });
747
+ }
748
+ clearTimeout(module.performance.timer);
749
+ module.performance.timer = setTimeout(function () {
750
+ module.performance.display();
751
+ }, 0);
752
+ },
753
+ display: function () {
754
+ var
755
+ title = settings.name + ':',
756
+ totalTime = 0
757
+ ;
758
+ time = false;
759
+ clearTimeout(module.performance.timer);
760
+ $.each(performance, function (index, data) {
761
+ totalTime += data['Execution Time'];
762
+ });
763
+ title += ' ' + totalTime + 'ms';
764
+ if (performance.length > 0) {
765
+ console.groupCollapsed(title);
766
+ if (console.table) {
767
+ console.table(performance);
768
+ } else {
769
+ $.each(performance, function (index, data) {
770
+ console.log(data.Name + ': ' + data['Execution Time'] + 'ms');
771
+ });
772
+ }
773
+ console.groupEnd();
774
+ }
775
+ performance = [];
776
+ },
777
+ },
778
+ invoke: function (query, passedArguments, context) {
779
+ var
780
+ object = instance,
781
+ maxDepth,
782
+ found,
783
+ response
784
+ ;
785
+ passedArguments = passedArguments || queryArguments;
786
+ context = context || element;
787
+ if (typeof query === 'string' && object !== undefined) {
788
+ query = query.split(/[ .]/);
789
+ maxDepth = query.length - 1;
790
+ $.each(query, function (depth, value) {
791
+ var camelCaseValue = depth !== maxDepth
792
+ ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
793
+ : query
794
+ ;
795
+ if ($.isPlainObject(object[camelCaseValue]) && (depth !== maxDepth)) {
796
+ object = object[camelCaseValue];
797
+ } else if (object[camelCaseValue] !== undefined) {
798
+ found = object[camelCaseValue];
799
+
800
+ return false;
801
+ } else if ($.isPlainObject(object[value]) && (depth !== maxDepth)) {
802
+ object = object[value];
803
+ } else if (object[value] !== undefined) {
804
+ found = object[value];
805
+
806
+ return false;
807
+ } else {
808
+ module.error(error.method, query);
809
+
810
+ return false;
811
+ }
812
+ });
813
+ }
814
+ if (isFunction(found)) {
815
+ response = found.apply(context, passedArguments);
816
+ } else if (found !== undefined) {
817
+ response = found;
818
+ }
819
+ if (Array.isArray(returnedValue)) {
820
+ returnedValue.push(response);
821
+ } else if (returnedValue !== undefined) {
822
+ returnedValue = [returnedValue, response];
823
+ } else if (response !== undefined) {
824
+ returnedValue = response;
825
+ }
826
+
827
+ return found;
828
+ },
829
+ };
830
+
831
+ if (methodInvoked) {
832
+ if (instance === undefined) {
833
+ module.initialize();
834
+ }
835
+ module.invoke(query);
836
+ } else {
837
+ if (instance !== undefined) {
838
+ instance.invoke('destroy');
839
+ }
840
+ module.initialize();
841
+ }
842
+ });
843
+
844
+ return returnedValue !== undefined
845
+ ? returnedValue
846
+ : this;
847
+ };
848
+
849
+ $.fn.sticky.settings = {
850
+
851
+ name: 'Sticky',
852
+ namespace: 'sticky',
853
+
854
+ silent: false,
855
+ debug: false,
856
+ verbose: true,
857
+ performance: true,
858
+
859
+ // whether to stick in the opposite direction on scroll up
860
+ pushing: false,
861
+
862
+ context: false,
863
+ container: false,
864
+
865
+ // Context to watch scroll events
866
+ scrollContext: window,
867
+
868
+ // Offset to adjust scroll
869
+ offset: 0,
870
+
871
+ // Offset to adjust scroll when attached to bottom of screen
872
+ bottomOffset: 0,
873
+
874
+ // will only set container height if difference between context and container is larger than this number
875
+ jitter: 5,
876
+
877
+ // set width of sticky element when it is fixed to page (used to make sure 100% width is maintained if no fixed size set)
878
+ setSize: true,
879
+
880
+ // Whether to automatically observe changes with Mutation Observers
881
+ observeChanges: false,
882
+
883
+ // Called when position is recalculated
884
+ onReposition: function () {},
885
+
886
+ // Called on each scroll
887
+ onScroll: function () {},
888
+
889
+ // Called when element is stuck to viewport
890
+ onStick: function () {},
891
+
892
+ // Called when element is unstuck from viewport
893
+ onUnstick: function () {},
894
+
895
+ // Called when element reaches top of context
896
+ onTop: function () {},
897
+
898
+ // Called when element reaches bottom of context
899
+ onBottom: function () {},
900
+
901
+ error: {
902
+ visible: 'Element is hidden, you must call refresh after element becomes visible. Use silent setting to suppress this warning in production.',
903
+ method: 'The method you called is not defined.',
904
+ invalidContext: 'Context specified does not exist',
905
+ elementSize: 'Sticky element is larger than its container, cannot create sticky.',
906
+ },
907
+
908
+ className: {
909
+ bound: 'bound',
910
+ fixed: 'fixed',
911
+ supported: 'native',
912
+ top: 'top',
913
+ bottom: 'bottom',
914
+ },
915
+
916
+ };
917
+ })(jQuery, window, document);