rails-active-ui 0.2.2 → 0.3.1

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 (226) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/datatables.css +15 -0
  3. data/app/assets/stylesheets.css +5 -1
  4. data/app/blocks/resource_list_block.rb +153 -0
  5. data/app/components/back_button_component.rb +34 -0
  6. data/app/components/button_component.rb +4 -2
  7. data/app/components/button_to_component.rb +3 -4
  8. data/app/components/column_component.rb +1 -1
  9. data/app/components/container_component.rb +1 -1
  10. data/app/components/dropdown_component.rb +8 -2
  11. data/app/components/grid_component.rb +5 -1
  12. data/app/components/link_to_component.rb +23 -0
  13. data/app/components/menu_item_component.rb +5 -1
  14. data/app/components/message_component.rb +3 -1
  15. data/app/components/modal_component.rb +23 -3
  16. data/app/components/paragraph_component.rb +13 -0
  17. data/app/components/row_component.rb +1 -1
  18. data/app/components/table_row_component.rb +3 -5
  19. data/app/components/template_component.rb +13 -0
  20. data/app/helpers/component_helper.rb +122 -76
  21. data/app/helpers/fui_helper.rb +37 -0
  22. data/app/javascript/datatables.js +10 -0
  23. data/app/javascript/ui/controllers/fui_datatable_controller.js +35 -0
  24. data/app/javascript/ui/controllers/fui_dropdown_controller.js +8 -1
  25. data/app/javascript/ui/controllers/fui_item_list_controller.js +40 -0
  26. data/app/javascript/ui/controllers/navigation_controller.js +23 -0
  27. data/app/javascript/ui/index.js +11 -0
  28. data/app/lib/component.rb +1 -1
  29. data/config/importmap.rb +3 -0
  30. data/config/initializers/ruby_template_handler.rb +4 -1
  31. data/formantic-ui/components/accordion.css +369 -0
  32. data/formantic-ui/components/accordion.js +595 -0
  33. data/formantic-ui/components/accordion.min.css +9 -0
  34. data/formantic-ui/components/accordion.min.js +11 -0
  35. data/formantic-ui/components/ad.css +264 -0
  36. data/formantic-ui/components/ad.min.css +10 -0
  37. data/formantic-ui/components/api.js +1225 -0
  38. data/formantic-ui/components/api.min.js +11 -0
  39. data/formantic-ui/components/breadcrumb.css +135 -0
  40. data/formantic-ui/components/breadcrumb.min.css +9 -0
  41. data/formantic-ui/components/button.css +4058 -0
  42. data/formantic-ui/components/button.min.css +9 -0
  43. data/formantic-ui/components/calendar.css +327 -0
  44. data/formantic-ui/components/calendar.js +2045 -0
  45. data/formantic-ui/components/calendar.min.css +9 -0
  46. data/formantic-ui/components/calendar.min.js +11 -0
  47. data/formantic-ui/components/card.css +1881 -0
  48. data/formantic-ui/components/card.min.css +9 -0
  49. data/formantic-ui/components/checkbox.css +785 -0
  50. data/formantic-ui/components/checkbox.js +888 -0
  51. data/formantic-ui/components/checkbox.min.css +9 -0
  52. data/formantic-ui/components/checkbox.min.js +11 -0
  53. data/formantic-ui/components/comment.css +283 -0
  54. data/formantic-ui/components/comment.min.css +9 -0
  55. data/formantic-ui/components/container.css +300 -0
  56. data/formantic-ui/components/container.min.css +9 -0
  57. data/formantic-ui/components/dimmer.css +367 -0
  58. data/formantic-ui/components/dimmer.js +732 -0
  59. data/formantic-ui/components/dimmer.min.css +9 -0
  60. data/formantic-ui/components/dimmer.min.js +11 -0
  61. data/formantic-ui/components/divider.css +287 -0
  62. data/formantic-ui/components/divider.min.css +9 -0
  63. data/formantic-ui/components/dropdown.css +2087 -0
  64. data/formantic-ui/components/dropdown.js +4432 -0
  65. data/formantic-ui/components/dropdown.min.css +9 -0
  66. data/formantic-ui/components/dropdown.min.js +11 -0
  67. data/formantic-ui/components/embed.css +155 -0
  68. data/formantic-ui/components/embed.js +688 -0
  69. data/formantic-ui/components/embed.min.css +9 -0
  70. data/formantic-ui/components/embed.min.js +11 -0
  71. data/formantic-ui/components/emoji.css +15311 -0
  72. data/formantic-ui/components/emoji.min.css +9 -0
  73. data/formantic-ui/components/feed.css +799 -0
  74. data/formantic-ui/components/feed.min.css +9 -0
  75. data/formantic-ui/components/flag.css +1149 -0
  76. data/formantic-ui/components/flag.min.css +9 -0
  77. data/formantic-ui/components/flyout.css +546 -0
  78. data/formantic-ui/components/flyout.js +1551 -0
  79. data/formantic-ui/components/flyout.min.css +9 -0
  80. data/formantic-ui/components/flyout.min.js +11 -0
  81. data/formantic-ui/components/form.css +1885 -0
  82. data/formantic-ui/components/form.js +2199 -0
  83. data/formantic-ui/components/form.min.css +9 -0
  84. data/formantic-ui/components/form.min.js +11 -0
  85. data/formantic-ui/components/grid.css +1952 -0
  86. data/formantic-ui/components/grid.min.css +9 -0
  87. data/formantic-ui/components/header.css +778 -0
  88. data/formantic-ui/components/header.min.css +9 -0
  89. data/formantic-ui/components/icon.css +7066 -0
  90. data/formantic-ui/components/icon.min.css +9 -0
  91. data/formantic-ui/components/image.css +315 -0
  92. data/formantic-ui/components/image.min.css +9 -0
  93. data/formantic-ui/components/input.css +1566 -0
  94. data/formantic-ui/components/input.min.css +9 -0
  95. data/formantic-ui/components/item.css +534 -0
  96. data/formantic-ui/components/item.min.css +9 -0
  97. data/formantic-ui/components/label.css +2114 -0
  98. data/formantic-ui/components/label.min.css +9 -0
  99. data/formantic-ui/components/list.css +955 -0
  100. data/formantic-ui/components/list.min.css +9 -0
  101. data/formantic-ui/components/loader.css +787 -0
  102. data/formantic-ui/components/loader.min.css +9 -0
  103. data/formantic-ui/components/menu.css +2131 -0
  104. data/formantic-ui/components/menu.min.css +9 -0
  105. data/formantic-ui/components/message.css +619 -0
  106. data/formantic-ui/components/message.min.css +9 -0
  107. data/formantic-ui/components/modal.css +779 -0
  108. data/formantic-ui/components/modal.js +1637 -0
  109. data/formantic-ui/components/modal.min.css +9 -0
  110. data/formantic-ui/components/modal.min.js +11 -0
  111. data/formantic-ui/components/nag.css +290 -0
  112. data/formantic-ui/components/nag.js +566 -0
  113. data/formantic-ui/components/nag.min.css +9 -0
  114. data/formantic-ui/components/nag.min.js +11 -0
  115. data/formantic-ui/components/placeholder.css +228 -0
  116. data/formantic-ui/components/placeholder.min.css +9 -0
  117. data/formantic-ui/components/popup.css +1184 -0
  118. data/formantic-ui/components/popup.js +1561 -0
  119. data/formantic-ui/components/popup.min.css +9 -0
  120. data/formantic-ui/components/popup.min.js +11 -0
  121. data/formantic-ui/components/progress.css +761 -0
  122. data/formantic-ui/components/progress.js +979 -0
  123. data/formantic-ui/components/progress.min.css +9 -0
  124. data/formantic-ui/components/progress.min.js +11 -0
  125. data/formantic-ui/components/rail.css +147 -0
  126. data/formantic-ui/components/rail.min.css +9 -0
  127. data/formantic-ui/components/rating.css +414 -0
  128. data/formantic-ui/components/rating.js +540 -0
  129. data/formantic-ui/components/rating.min.css +9 -0
  130. data/formantic-ui/components/rating.min.js +11 -0
  131. data/formantic-ui/components/reset.css +386 -0
  132. data/formantic-ui/components/reset.min.css +9 -0
  133. data/formantic-ui/components/reveal.css +277 -0
  134. data/formantic-ui/components/reveal.min.css +9 -0
  135. data/formantic-ui/components/search.css +541 -0
  136. data/formantic-ui/components/search.js +1641 -0
  137. data/formantic-ui/components/search.min.css +9 -0
  138. data/formantic-ui/components/search.min.js +11 -0
  139. data/formantic-ui/components/segment.css +1053 -0
  140. data/formantic-ui/components/segment.min.css +9 -0
  141. data/formantic-ui/components/shape.css +144 -0
  142. data/formantic-ui/components/shape.js +797 -0
  143. data/formantic-ui/components/shape.min.css +9 -0
  144. data/formantic-ui/components/shape.min.js +11 -0
  145. data/formantic-ui/components/sidebar.css +539 -0
  146. data/formantic-ui/components/sidebar.js +1054 -0
  147. data/formantic-ui/components/sidebar.min.css +9 -0
  148. data/formantic-ui/components/sidebar.min.js +11 -0
  149. data/formantic-ui/components/site.css +286 -0
  150. data/formantic-ui/components/site.js +455 -0
  151. data/formantic-ui/components/site.min.css +9 -0
  152. data/formantic-ui/components/site.min.js +11 -0
  153. data/formantic-ui/components/slider.css +926 -0
  154. data/formantic-ui/components/slider.js +1546 -0
  155. data/formantic-ui/components/slider.min.css +9 -0
  156. data/formantic-ui/components/slider.min.js +11 -0
  157. data/formantic-ui/components/state.js +697 -0
  158. data/formantic-ui/components/state.min.js +11 -0
  159. data/formantic-ui/components/statistic.css +586 -0
  160. data/formantic-ui/components/statistic.min.css +9 -0
  161. data/formantic-ui/components/step.css +1538 -0
  162. data/formantic-ui/components/step.min.css +9 -0
  163. data/formantic-ui/components/sticky.css +73 -0
  164. data/formantic-ui/components/sticky.js +917 -0
  165. data/formantic-ui/components/sticky.min.css +9 -0
  166. data/formantic-ui/components/sticky.min.js +11 -0
  167. data/formantic-ui/components/tab.css +84 -0
  168. data/formantic-ui/components/tab.js +967 -0
  169. data/formantic-ui/components/tab.min.css +9 -0
  170. data/formantic-ui/components/tab.min.js +11 -0
  171. data/formantic-ui/components/table.css +3473 -0
  172. data/formantic-ui/components/table.min.css +9 -0
  173. data/formantic-ui/components/text.css +155 -0
  174. data/formantic-ui/components/text.min.css +9 -0
  175. data/formantic-ui/components/toast.css +751 -0
  176. data/formantic-ui/components/toast.js +964 -0
  177. data/formantic-ui/components/toast.min.css +9 -0
  178. data/formantic-ui/components/toast.min.js +11 -0
  179. data/formantic-ui/components/transition.css +1148 -0
  180. data/formantic-ui/components/transition.js +1034 -0
  181. data/formantic-ui/components/transition.min.css +9 -0
  182. data/formantic-ui/components/transition.min.js +11 -0
  183. data/formantic-ui/components/visibility.js +1292 -0
  184. data/formantic-ui/components/visibility.min.js +11 -0
  185. data/formantic-ui/semantic.css +78485 -0
  186. data/formantic-ui/semantic.js +31036 -0
  187. data/formantic-ui/semantic.min.css +11 -0
  188. data/formantic-ui/semantic.min.js +11 -0
  189. data/formantic-ui/themes/basic/assets/fonts/LICENSE.txt +91 -0
  190. data/formantic-ui/themes/basic/assets/fonts/icons.woff +0 -0
  191. data/formantic-ui/themes/basic/assets/fonts/icons.woff2 +0 -0
  192. data/formantic-ui/themes/default/assets/fonts/LICENSE_Lato.txt +94 -0
  193. data/formantic-ui/themes/default/assets/fonts/LICENSE_icons.txt +165 -0
  194. data/formantic-ui/themes/default/assets/fonts/Lato-Bold.woff +0 -0
  195. data/formantic-ui/themes/default/assets/fonts/Lato-Bold.woff2 +0 -0
  196. data/formantic-ui/themes/default/assets/fonts/Lato-BoldItalic.woff +0 -0
  197. data/formantic-ui/themes/default/assets/fonts/Lato-BoldItalic.woff2 +0 -0
  198. data/formantic-ui/themes/default/assets/fonts/Lato-Italic.woff +0 -0
  199. data/formantic-ui/themes/default/assets/fonts/Lato-Italic.woff2 +0 -0
  200. data/formantic-ui/themes/default/assets/fonts/Lato-Regular.woff +0 -0
  201. data/formantic-ui/themes/default/assets/fonts/Lato-Regular.woff2 +0 -0
  202. data/formantic-ui/themes/default/assets/fonts/LatoLatin-Bold.woff +0 -0
  203. data/formantic-ui/themes/default/assets/fonts/LatoLatin-Bold.woff2 +0 -0
  204. data/formantic-ui/themes/default/assets/fonts/LatoLatin-BoldItalic.woff +0 -0
  205. data/formantic-ui/themes/default/assets/fonts/LatoLatin-BoldItalic.woff2 +0 -0
  206. data/formantic-ui/themes/default/assets/fonts/LatoLatin-Italic.woff +0 -0
  207. data/formantic-ui/themes/default/assets/fonts/LatoLatin-Italic.woff2 +0 -0
  208. data/formantic-ui/themes/default/assets/fonts/LatoLatin-Regular.woff +0 -0
  209. data/formantic-ui/themes/default/assets/fonts/LatoLatin-Regular.woff2 +0 -0
  210. data/formantic-ui/themes/default/assets/fonts/brand-icons.woff +0 -0
  211. data/formantic-ui/themes/default/assets/fonts/brand-icons.woff2 +0 -0
  212. data/formantic-ui/themes/default/assets/fonts/icons.woff +0 -0
  213. data/formantic-ui/themes/default/assets/fonts/icons.woff2 +0 -0
  214. data/formantic-ui/themes/default/assets/fonts/outline-icons.woff +0 -0
  215. data/formantic-ui/themes/default/assets/fonts/outline-icons.woff2 +0 -0
  216. data/formantic-ui/themes/famfamfam/assets/images/flags.png +0 -0
  217. data/formantic-ui/themes/github/assets/fonts/LICENSE.txt +94 -0
  218. data/formantic-ui/themes/github/assets/fonts/octicons.woff +0 -0
  219. data/formantic-ui/themes/github/assets/fonts/octicons.woff2 +0 -0
  220. data/formantic-ui/themes/material/assets/fonts/LICENSE.txt +202 -0
  221. data/formantic-ui/themes/material/assets/fonts/icons.woff +0 -0
  222. data/formantic-ui/themes/material/assets/fonts/icons.woff2 +0 -0
  223. data/lib/ui/engine.rb +7 -2
  224. data/lib/ui/version.rb +1 -1
  225. metadata +205 -7
  226. data/app/components/link_component.rb +0 -23
@@ -0,0 +1,1292 @@
1
+ /*!
2
+ * # Fomantic-UI 2.9.4 - Visibility
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.visibility = function (parameters) {
23
+ var
24
+ $allModules = $(this),
25
+
26
+ time = Date.now(),
27
+ performance = [],
28
+
29
+ query = arguments[0],
30
+ methodInvoked = typeof query === 'string',
31
+ queryArguments = [].slice.call(arguments, 1),
32
+ contextCheck = function (context, win) {
33
+ var $context;
34
+ if ([window, document].indexOf(context) >= 0) {
35
+ $context = $(context);
36
+ } else {
37
+ $context = $(win.document).find(context);
38
+ if ($context.length === 0) {
39
+ $context = win.frameElement ? contextCheck(context, win.parent) : window;
40
+ }
41
+ }
42
+
43
+ return $context;
44
+ },
45
+ returnedValue,
46
+
47
+ moduleCount = $allModules.length,
48
+ loadedCount = 0
49
+ ;
50
+
51
+ $allModules.each(function () {
52
+ var
53
+ settings = $.isPlainObject(parameters)
54
+ ? $.extend(true, {}, $.fn.visibility.settings, parameters)
55
+ : $.extend({}, $.fn.visibility.settings),
56
+
57
+ className = settings.className,
58
+ namespace = settings.namespace,
59
+ error = settings.error,
60
+ metadata = settings.metadata,
61
+
62
+ eventNamespace = '.' + namespace,
63
+ moduleNamespace = 'module-' + namespace,
64
+
65
+ $window = $(window),
66
+
67
+ $module = $(this),
68
+ $context = contextCheck(settings.context, window),
69
+
70
+ $placeholder,
71
+
72
+ instance = $module.data(moduleNamespace),
73
+
74
+ element = this,
75
+ disabled = false,
76
+
77
+ contextObserver,
78
+ observer,
79
+ module
80
+ ;
81
+
82
+ module = {
83
+
84
+ initialize: function () {
85
+ module.debug('Initializing', settings);
86
+
87
+ module.setup.cache();
88
+
89
+ if (module.should.trackChanges()) {
90
+ if (settings.type === 'image') {
91
+ module.setup.image();
92
+ }
93
+ if (settings.type === 'fixed') {
94
+ module.setup.fixed();
95
+ }
96
+
97
+ if (settings.observeChanges) {
98
+ module.observeChanges();
99
+ }
100
+ module.bind.events();
101
+ }
102
+
103
+ module.save.position();
104
+ if (!module.is.visible()) {
105
+ module.error(error.visible, $module);
106
+ }
107
+
108
+ if (settings.initialCheck) {
109
+ module.checkVisibility();
110
+ }
111
+ module.instantiate();
112
+ },
113
+
114
+ instantiate: function () {
115
+ module.debug('Storing instance', module);
116
+ $module
117
+ .data(moduleNamespace, module)
118
+ ;
119
+ instance = module;
120
+ },
121
+
122
+ destroy: function () {
123
+ module.verbose('Destroying previous module');
124
+ if (observer) {
125
+ observer.disconnect();
126
+ }
127
+ if (contextObserver) {
128
+ contextObserver.disconnect();
129
+ }
130
+ $window
131
+ .off('load' + eventNamespace, module.event.load)
132
+ .off('resize' + eventNamespace, module.event.resize)
133
+ ;
134
+ $context
135
+ .off('scroll' + eventNamespace, module.event.scroll)
136
+ .off('scrollchange' + eventNamespace, module.event.scrollchange)
137
+ ;
138
+ if (settings.type === 'fixed') {
139
+ module.resetFixed();
140
+ module.remove.placeholder();
141
+ }
142
+ $module
143
+ .off(eventNamespace)
144
+ .removeData(moduleNamespace)
145
+ ;
146
+ },
147
+
148
+ observeChanges: function () {
149
+ if ('MutationObserver' in window) {
150
+ contextObserver = new MutationObserver(module.event.contextChanged);
151
+ observer = new MutationObserver(module.event.changed);
152
+ contextObserver.observe(document, {
153
+ childList: true,
154
+ subtree: true,
155
+ });
156
+ observer.observe(element, {
157
+ childList: true,
158
+ subtree: true,
159
+ });
160
+ module.debug('Setting up mutation observer', observer);
161
+ }
162
+ },
163
+
164
+ bind: {
165
+ events: function () {
166
+ module.verbose('Binding visibility events to scroll and resize');
167
+ if (settings.refreshOnLoad) {
168
+ $window
169
+ .on('load' + eventNamespace, module.event.load)
170
+ ;
171
+ }
172
+ $window
173
+ .on('resize' + eventNamespace, module.event.resize)
174
+ ;
175
+ // pub/sub pattern
176
+ $context
177
+ .off('scroll' + eventNamespace)
178
+ .on('scroll' + eventNamespace, module.event.scroll)
179
+ .on('scrollchange' + eventNamespace, module.event.scrollchange)
180
+ ;
181
+ },
182
+ },
183
+
184
+ event: {
185
+ changed: function (mutations) {
186
+ module.verbose('DOM tree modified, updating visibility calculations');
187
+ module.timer = setTimeout(function () {
188
+ module.verbose('DOM tree modified, updating sticky menu');
189
+ module.refresh();
190
+ }, 100);
191
+ },
192
+ contextChanged: function (mutations) {
193
+ [].forEach.call(mutations, function (mutation) {
194
+ if (mutation.removedNodes) {
195
+ [].forEach.call(mutation.removedNodes, function (node) {
196
+ if (node === element || $(node).find(element).length > 0) {
197
+ module.debug('Element removed from DOM, tearing down events');
198
+ module.destroy();
199
+ }
200
+ });
201
+ }
202
+ });
203
+ },
204
+ resize: function () {
205
+ module.debug('Window resized');
206
+ if (settings.refreshOnResize) {
207
+ requestAnimationFrame(module.refresh);
208
+ }
209
+ },
210
+ load: function () {
211
+ module.debug('Page finished loading');
212
+ requestAnimationFrame(module.refresh);
213
+ },
214
+ // publishes scrollchange event on one scroll
215
+ scroll: function () {
216
+ if (settings.throttle) {
217
+ clearTimeout(module.timer);
218
+ module.timer = setTimeout(function () {
219
+ $context.triggerHandler('scrollchange' + eventNamespace, [$context.scrollTop()]);
220
+ }, settings.throttle);
221
+ } else {
222
+ requestAnimationFrame(function () {
223
+ $context.triggerHandler('scrollchange' + eventNamespace, [$context.scrollTop()]);
224
+ });
225
+ }
226
+ },
227
+ // subscribes to scrollchange
228
+ scrollchange: function (event, scrollPosition) {
229
+ module.checkVisibility(scrollPosition);
230
+ },
231
+ },
232
+
233
+ precache: function (images, callback) {
234
+ if (!Array.isArray(images)) {
235
+ images = [images];
236
+ }
237
+ var
238
+ imagesLength = images.length,
239
+ loadedCounter = 0,
240
+ cache = [],
241
+ cacheImage = document.createElement('img'),
242
+ handleLoad = function () {
243
+ loadedCounter++;
244
+ if (loadedCounter >= images.length) {
245
+ if (isFunction(callback)) {
246
+ callback();
247
+ }
248
+ }
249
+ }
250
+ ;
251
+ while (imagesLength--) {
252
+ cacheImage = document.createElement('img');
253
+ cacheImage.addEventListener('load', handleLoad);
254
+ cacheImage.addEventListener('error', handleLoad);
255
+ cacheImage.src = images[imagesLength];
256
+ cache.push(cacheImage);
257
+ }
258
+ },
259
+
260
+ enableCallbacks: function () {
261
+ module.debug('Allowing callbacks to occur');
262
+ disabled = false;
263
+ },
264
+
265
+ disableCallbacks: function () {
266
+ module.debug('Disabling all callbacks temporarily');
267
+ disabled = true;
268
+ },
269
+
270
+ should: {
271
+ trackChanges: function () {
272
+ if (methodInvoked) {
273
+ module.debug('One time query, no need to bind events');
274
+
275
+ return false;
276
+ }
277
+ module.debug('Callbacks being attached');
278
+
279
+ return true;
280
+ },
281
+ },
282
+
283
+ setup: {
284
+ cache: function () {
285
+ module.cache = {
286
+ occurred: {},
287
+ screen: {},
288
+ element: {},
289
+ };
290
+ },
291
+ image: function () {
292
+ var
293
+ src = $module.data(metadata.src)
294
+ ;
295
+ if (src) {
296
+ module.verbose('Lazy loading image', src);
297
+ settings.once = true;
298
+ settings.observeChanges = false;
299
+
300
+ // show when top visible
301
+ settings.onOnScreen = function () {
302
+ module.debug('Image on screen', element);
303
+ module.precache(src, function () {
304
+ module.set.image(src, function () {
305
+ loadedCount++;
306
+ if (loadedCount === moduleCount) {
307
+ settings.onAllLoaded.call(this);
308
+ }
309
+ settings.onLoad.call(this);
310
+ });
311
+ });
312
+ };
313
+ }
314
+ },
315
+ fixed: function () {
316
+ module.debug('Setting up fixed');
317
+ settings.once = false;
318
+ settings.observeChanges = false;
319
+ settings.initialCheck = true;
320
+ settings.refreshOnLoad = true;
321
+ if (!parameters.transition) {
322
+ settings.transition = false;
323
+ }
324
+ module.create.placeholder();
325
+ module.debug('Added placeholder', $placeholder);
326
+ settings.onTopPassed = function () {
327
+ module.debug('Element passed, adding fixed position', $module);
328
+ module.show.placeholder();
329
+ module.set.fixed();
330
+ if (settings.transition) {
331
+ if ($.fn.transition !== undefined) {
332
+ $module.transition(settings.transition, settings.duration);
333
+ }
334
+ }
335
+ };
336
+ settings.onTopPassedReverse = function () {
337
+ module.debug('Element returned to position, removing fixed', $module);
338
+ module.hide.placeholder();
339
+ module.remove.fixed();
340
+ };
341
+ },
342
+ },
343
+
344
+ create: {
345
+ placeholder: function () {
346
+ module.verbose('Creating fixed position placeholder');
347
+ $placeholder = $module
348
+ .clone(false)
349
+ .css('display', 'none')
350
+ .addClass(className.placeholder)
351
+ .insertAfter($module)
352
+ ;
353
+ },
354
+ },
355
+
356
+ show: {
357
+ placeholder: function () {
358
+ module.verbose('Showing placeholder');
359
+ $placeholder
360
+ .css('display', 'block')
361
+ .css('visibility', 'hidden')
362
+ ;
363
+ },
364
+ },
365
+ hide: {
366
+ placeholder: function () {
367
+ module.verbose('Hiding placeholder');
368
+ $placeholder
369
+ .css('display', 'none')
370
+ .css('visibility', '')
371
+ ;
372
+ },
373
+ },
374
+
375
+ set: {
376
+ fixed: function () {
377
+ module.verbose('Setting element to fixed position');
378
+ $module
379
+ .addClass(className.fixed)
380
+ .css({
381
+ position: 'fixed',
382
+ top: settings.offset + 'px',
383
+ left: 'auto',
384
+ zIndex: settings.zIndex,
385
+ })
386
+ ;
387
+ settings.onFixed.call(element);
388
+ },
389
+ image: function (src, callback) {
390
+ $module
391
+ .attr('src', src)
392
+ ;
393
+ if (settings.transition) {
394
+ if ($.fn.transition !== undefined) {
395
+ if ($module.hasClass(className.visible)) {
396
+ module.debug('Transition already occurred on this image, skipping animation');
397
+
398
+ return;
399
+ }
400
+ $module.transition(settings.transition, settings.duration, callback);
401
+ } else {
402
+ $module.fadeIn(settings.duration, callback);
403
+ }
404
+ } else {
405
+ $module.show();
406
+ }
407
+ },
408
+ },
409
+
410
+ is: {
411
+ onScreen: function () {
412
+ var
413
+ calculations = module.get.elementCalculations()
414
+ ;
415
+
416
+ return calculations.onScreen;
417
+ },
418
+ offScreen: function () {
419
+ var
420
+ calculations = module.get.elementCalculations()
421
+ ;
422
+
423
+ return calculations.offScreen;
424
+ },
425
+ visible: function () {
426
+ if (module.cache && module.cache.element) {
427
+ return !(module.cache.element.width === 0 && module.cache.element.offset.top === 0);
428
+ }
429
+
430
+ return false;
431
+ },
432
+ verticallyScrollableContext: function () {
433
+ var
434
+ overflowY = $context[0] !== window
435
+ ? $context.css('overflow-y')
436
+ : false
437
+ ;
438
+
439
+ return overflowY === 'auto' || overflowY === 'scroll';
440
+ },
441
+ horizontallyScrollableContext: function () {
442
+ var
443
+ overflowX = $context[0] !== window
444
+ ? $context.css('overflow-x')
445
+ : false
446
+ ;
447
+
448
+ return overflowX === 'auto' || overflowX === 'scroll';
449
+ },
450
+ },
451
+
452
+ refresh: function () {
453
+ module.debug('Refreshing constants (width/height)');
454
+ if (settings.type === 'fixed') {
455
+ module.resetFixed();
456
+ }
457
+ module.reset();
458
+ module.save.position();
459
+ if (settings.checkOnRefresh) {
460
+ module.checkVisibility();
461
+ }
462
+ settings.onRefresh.call(element);
463
+ },
464
+
465
+ resetFixed: function () {
466
+ module.remove.fixed();
467
+ module.remove.occurred();
468
+ },
469
+
470
+ reset: function () {
471
+ module.verbose('Resetting all cached values');
472
+ if ($.isPlainObject(module.cache)) {
473
+ module.cache.screen = {};
474
+ module.cache.element = {};
475
+ }
476
+ },
477
+
478
+ checkVisibility: function (scroll) {
479
+ module.verbose('Checking visibility of element', module.cache.element);
480
+
481
+ if (!disabled && module.is.visible()) {
482
+ // save scroll position
483
+ module.save.scroll(scroll);
484
+
485
+ // update calculations derived from scroll
486
+ module.save.calculations();
487
+
488
+ // percentage
489
+ module.passed();
490
+
491
+ // reverse (must be first)
492
+ module.passingReverse();
493
+ module.topVisibleReverse();
494
+ module.bottomVisibleReverse();
495
+ module.topPassedReverse();
496
+ module.bottomPassedReverse();
497
+
498
+ // one time
499
+ module.onScreen();
500
+ module.offScreen();
501
+ module.passing();
502
+ module.topVisible();
503
+ module.bottomVisible();
504
+ module.topPassed();
505
+ module.bottomPassed();
506
+
507
+ // on update callback
508
+ if (settings.onUpdate) {
509
+ settings.onUpdate.call(element, module.get.elementCalculations());
510
+ }
511
+ }
512
+ },
513
+
514
+ passed: function (amount, newCallback) {
515
+ var
516
+ calculations = module.get.elementCalculations()
517
+ ;
518
+ // assign callback
519
+ if (amount && newCallback) {
520
+ settings.onPassed[amount] = newCallback;
521
+ } else if (amount !== undefined) {
522
+ return module.get.pixelsPassed(amount) > calculations.pixelsPassed;
523
+ } else if (calculations.passing) {
524
+ $.each(settings.onPassed, function (amount, callback) {
525
+ if (calculations.bottomVisible || calculations.pixelsPassed > module.get.pixelsPassed(amount)) {
526
+ module.execute(callback, amount);
527
+ } else if (!settings.once) {
528
+ module.remove.occurred(callback);
529
+ }
530
+ });
531
+ }
532
+ },
533
+
534
+ onScreen: function (newCallback) {
535
+ var
536
+ calculations = module.get.elementCalculations(),
537
+ callback = newCallback || settings.onOnScreen,
538
+ callbackName = 'onScreen'
539
+ ;
540
+ if (newCallback) {
541
+ module.debug('Adding callback for onScreen', newCallback);
542
+ settings.onOnScreen = newCallback;
543
+ }
544
+ if (calculations.onScreen) {
545
+ module.execute(callback, callbackName);
546
+ } else if (!settings.once) {
547
+ module.remove.occurred(callbackName);
548
+ }
549
+ if (newCallback !== undefined) {
550
+ return calculations.onOnScreen;
551
+ }
552
+ },
553
+
554
+ offScreen: function (newCallback) {
555
+ var
556
+ calculations = module.get.elementCalculations(),
557
+ callback = newCallback || settings.onOffScreen,
558
+ callbackName = 'offScreen'
559
+ ;
560
+ if (newCallback) {
561
+ module.debug('Adding callback for offScreen', newCallback);
562
+ settings.onOffScreen = newCallback;
563
+ }
564
+ if (calculations.offScreen) {
565
+ module.execute(callback, callbackName);
566
+ } else if (!settings.once) {
567
+ module.remove.occurred(callbackName);
568
+ }
569
+ if (newCallback !== undefined) {
570
+ return calculations.onOffScreen;
571
+ }
572
+ },
573
+
574
+ passing: function (newCallback) {
575
+ var
576
+ calculations = module.get.elementCalculations(),
577
+ callback = newCallback || settings.onPassing,
578
+ callbackName = 'passing'
579
+ ;
580
+ if (newCallback) {
581
+ module.debug('Adding callback for passing', newCallback);
582
+ settings.onPassing = newCallback;
583
+ }
584
+ if (calculations.passing) {
585
+ module.execute(callback, callbackName);
586
+ } else if (!settings.once) {
587
+ module.remove.occurred(callbackName);
588
+ }
589
+ if (newCallback !== undefined) {
590
+ return calculations.passing;
591
+ }
592
+ },
593
+
594
+ topVisible: function (newCallback) {
595
+ var
596
+ calculations = module.get.elementCalculations(),
597
+ callback = newCallback || settings.onTopVisible,
598
+ callbackName = 'topVisible'
599
+ ;
600
+ if (newCallback) {
601
+ module.debug('Adding callback for top visible', newCallback);
602
+ settings.onTopVisible = newCallback;
603
+ }
604
+ if (calculations.topVisible) {
605
+ module.execute(callback, callbackName);
606
+ } else if (!settings.once) {
607
+ module.remove.occurred(callbackName);
608
+ }
609
+ if (newCallback === undefined) {
610
+ return calculations.topVisible;
611
+ }
612
+ },
613
+
614
+ bottomVisible: function (newCallback) {
615
+ var
616
+ calculations = module.get.elementCalculations(),
617
+ callback = newCallback || settings.onBottomVisible,
618
+ callbackName = 'bottomVisible'
619
+ ;
620
+ if (newCallback) {
621
+ module.debug('Adding callback for bottom visible', newCallback);
622
+ settings.onBottomVisible = newCallback;
623
+ }
624
+ if (calculations.bottomVisible) {
625
+ module.execute(callback, callbackName);
626
+ } else if (!settings.once) {
627
+ module.remove.occurred(callbackName);
628
+ }
629
+ if (newCallback === undefined) {
630
+ return calculations.bottomVisible;
631
+ }
632
+ },
633
+
634
+ topPassed: function (newCallback) {
635
+ var
636
+ calculations = module.get.elementCalculations(),
637
+ callback = newCallback || settings.onTopPassed,
638
+ callbackName = 'topPassed'
639
+ ;
640
+ if (newCallback) {
641
+ module.debug('Adding callback for top passed', newCallback);
642
+ settings.onTopPassed = newCallback;
643
+ }
644
+ if (calculations.topPassed) {
645
+ module.execute(callback, callbackName);
646
+ } else if (!settings.once) {
647
+ module.remove.occurred(callbackName);
648
+ }
649
+ if (newCallback === undefined) {
650
+ return calculations.topPassed;
651
+ }
652
+ },
653
+
654
+ bottomPassed: function (newCallback) {
655
+ var
656
+ calculations = module.get.elementCalculations(),
657
+ callback = newCallback || settings.onBottomPassed,
658
+ callbackName = 'bottomPassed'
659
+ ;
660
+ if (newCallback) {
661
+ module.debug('Adding callback for bottom passed', newCallback);
662
+ settings.onBottomPassed = newCallback;
663
+ }
664
+ if (calculations.bottomPassed) {
665
+ module.execute(callback, callbackName);
666
+ } else if (!settings.once) {
667
+ module.remove.occurred(callbackName);
668
+ }
669
+ if (newCallback === undefined) {
670
+ return calculations.bottomPassed;
671
+ }
672
+ },
673
+
674
+ passingReverse: function (newCallback) {
675
+ var
676
+ calculations = module.get.elementCalculations(),
677
+ callback = newCallback || settings.onPassingReverse,
678
+ callbackName = 'passingReverse'
679
+ ;
680
+ if (newCallback) {
681
+ module.debug('Adding callback for passing reverse', newCallback);
682
+ settings.onPassingReverse = newCallback;
683
+ }
684
+ if (!calculations.passing) {
685
+ if (module.get.occurred('passing')) {
686
+ module.execute(callback, callbackName);
687
+ }
688
+ } else if (!settings.once) {
689
+ module.remove.occurred(callbackName);
690
+ }
691
+ if (newCallback !== undefined) {
692
+ return !calculations.passing;
693
+ }
694
+ },
695
+
696
+ topVisibleReverse: function (newCallback) {
697
+ var
698
+ calculations = module.get.elementCalculations(),
699
+ callback = newCallback || settings.onTopVisibleReverse,
700
+ callbackName = 'topVisibleReverse'
701
+ ;
702
+ if (newCallback) {
703
+ module.debug('Adding callback for top visible reverse', newCallback);
704
+ settings.onTopVisibleReverse = newCallback;
705
+ }
706
+ if (!calculations.topVisible) {
707
+ if (module.get.occurred('topVisible')) {
708
+ module.execute(callback, callbackName);
709
+ }
710
+ } else if (!settings.once) {
711
+ module.remove.occurred(callbackName);
712
+ }
713
+ if (newCallback === undefined) {
714
+ return !calculations.topVisible;
715
+ }
716
+ },
717
+
718
+ bottomVisibleReverse: function (newCallback) {
719
+ var
720
+ calculations = module.get.elementCalculations(),
721
+ callback = newCallback || settings.onBottomVisibleReverse,
722
+ callbackName = 'bottomVisibleReverse'
723
+ ;
724
+ if (newCallback) {
725
+ module.debug('Adding callback for bottom visible reverse', newCallback);
726
+ settings.onBottomVisibleReverse = newCallback;
727
+ }
728
+ if (!calculations.bottomVisible) {
729
+ if (module.get.occurred('bottomVisible')) {
730
+ module.execute(callback, callbackName);
731
+ }
732
+ } else if (!settings.once) {
733
+ module.remove.occurred(callbackName);
734
+ }
735
+ if (newCallback === undefined) {
736
+ return !calculations.bottomVisible;
737
+ }
738
+ },
739
+
740
+ topPassedReverse: function (newCallback) {
741
+ var
742
+ calculations = module.get.elementCalculations(),
743
+ callback = newCallback || settings.onTopPassedReverse,
744
+ callbackName = 'topPassedReverse'
745
+ ;
746
+ if (newCallback) {
747
+ module.debug('Adding callback for top passed reverse', newCallback);
748
+ settings.onTopPassedReverse = newCallback;
749
+ }
750
+ if (!calculations.topPassed) {
751
+ if (module.get.occurred('topPassed')) {
752
+ module.execute(callback, callbackName);
753
+ }
754
+ } else if (!settings.once) {
755
+ module.remove.occurred(callbackName);
756
+ }
757
+ if (newCallback === undefined) {
758
+ return !calculations.onTopPassed;
759
+ }
760
+ },
761
+
762
+ bottomPassedReverse: function (newCallback) {
763
+ var
764
+ calculations = module.get.elementCalculations(),
765
+ callback = newCallback || settings.onBottomPassedReverse,
766
+ callbackName = 'bottomPassedReverse'
767
+ ;
768
+ if (newCallback) {
769
+ module.debug('Adding callback for bottom passed reverse', newCallback);
770
+ settings.onBottomPassedReverse = newCallback;
771
+ }
772
+ if (!calculations.bottomPassed) {
773
+ if (module.get.occurred('bottomPassed')) {
774
+ module.execute(callback, callbackName);
775
+ }
776
+ } else if (!settings.once) {
777
+ module.remove.occurred(callbackName);
778
+ }
779
+ if (newCallback === undefined) {
780
+ return !calculations.bottomPassed;
781
+ }
782
+ },
783
+
784
+ execute: function (callback, callbackName) {
785
+ var
786
+ calculations = module.get.elementCalculations(),
787
+ screen = module.get.screenCalculations()
788
+ ;
789
+ callback = callback || false;
790
+ if (callback) {
791
+ if (settings.continuous) {
792
+ module.debug('Callback being called continuously', callbackName, calculations);
793
+ callback.call(element, calculations, screen);
794
+ } else if (!module.get.occurred(callbackName)) {
795
+ module.debug('Conditions met', callbackName, calculations);
796
+ callback.call(element, calculations, screen);
797
+ }
798
+ }
799
+ module.save.occurred(callbackName);
800
+ },
801
+
802
+ remove: {
803
+ fixed: function () {
804
+ module.debug('Removing fixed position');
805
+ $module
806
+ .removeClass(className.fixed)
807
+ .css({
808
+ position: '',
809
+ top: '',
810
+ left: '',
811
+ zIndex: '',
812
+ })
813
+ ;
814
+ settings.onUnfixed.call(element);
815
+ },
816
+ placeholder: function () {
817
+ module.debug('Removing placeholder content');
818
+ if ($placeholder) {
819
+ $placeholder.remove();
820
+ }
821
+ },
822
+ occurred: function (callback) {
823
+ if (callback) {
824
+ var
825
+ occurred = module.cache.occurred
826
+ ;
827
+ if (occurred[callback] !== undefined && occurred[callback] === true) {
828
+ module.debug('Callback can now be called again', callback);
829
+ module.cache.occurred[callback] = false;
830
+ }
831
+ } else {
832
+ module.cache.occurred = {};
833
+ }
834
+ },
835
+ },
836
+
837
+ save: {
838
+ calculations: function () {
839
+ module.verbose('Saving all calculations necessary to determine positioning');
840
+ module.save.direction();
841
+ module.save.screenCalculations();
842
+ module.save.elementCalculations();
843
+ },
844
+ occurred: function (callback) {
845
+ if (callback) {
846
+ if (module.cache.occurred[callback] === undefined || (module.cache.occurred[callback] !== true)) {
847
+ module.verbose('Saving callback occurred', callback);
848
+ module.cache.occurred[callback] = true;
849
+ }
850
+ }
851
+ },
852
+ scroll: function (scrollPosition) {
853
+ scrollPosition = scrollPosition + settings.offset || $context.scrollTop() + settings.offset;
854
+ module.cache.scroll = scrollPosition;
855
+ },
856
+ direction: function () {
857
+ var
858
+ scroll = module.get.scroll(),
859
+ lastScroll = module.get.lastScroll(),
860
+ direction
861
+ ;
862
+ if (scroll > lastScroll && lastScroll) {
863
+ direction = 'down';
864
+ } else if (scroll < lastScroll && lastScroll) {
865
+ direction = 'up';
866
+ } else {
867
+ direction = 'static';
868
+ }
869
+ module.cache.direction = direction;
870
+
871
+ return module.cache.direction;
872
+ },
873
+ elementPosition: function () {
874
+ var
875
+ element = module.cache.element,
876
+ screen = module.get.screenSize()
877
+ ;
878
+ module.verbose('Saving element position');
879
+ // (quicker than $.extend)
880
+ element.fits = element.height < screen.height;
881
+ element.offset = $module.offset();
882
+ element.width = $module.outerWidth();
883
+ element.height = $module.outerHeight();
884
+ // compensate for scroll in context
885
+ if (module.is.verticallyScrollableContext()) {
886
+ element.offset.top += $context.scrollTop() - $context.offset().top;
887
+ }
888
+ if (module.is.horizontallyScrollableContext()) {
889
+ element.offset.left += $context.scrollLeft() - $context.offset().left;
890
+ }
891
+ // store
892
+ module.cache.element = element;
893
+
894
+ return element;
895
+ },
896
+ elementCalculations: function () {
897
+ var
898
+ screen = module.get.screenCalculations(),
899
+ element = module.get.elementPosition()
900
+ ;
901
+ // offset
902
+ if (settings.includeMargin) {
903
+ element.margin = {};
904
+ element.margin.top = parseInt($module.css('margin-top'), 10);
905
+ element.margin.bottom = parseInt($module.css('margin-bottom'), 10);
906
+ element.top = element.offset.top - element.margin.top;
907
+ element.bottom = element.offset.top + element.height + element.margin.bottom;
908
+ } else {
909
+ element.top = element.offset.top;
910
+ element.bottom = element.offset.top + element.height;
911
+ }
912
+
913
+ // visibility
914
+ element.topPassed = screen.top >= element.top;
915
+ element.bottomPassed = screen.top >= element.bottom;
916
+ element.topVisible = (screen.bottom >= element.top) && !element.topPassed;
917
+ element.bottomVisible = (screen.bottom >= element.bottom) && !element.bottomPassed;
918
+ element.pixelsPassed = 0;
919
+ element.percentagePassed = 0;
920
+
921
+ // meta calculations
922
+ element.onScreen = (element.topVisible || element.passing) && !element.bottomPassed;
923
+ element.passing = element.topPassed && !element.bottomPassed;
924
+ element.offScreen = !element.onScreen;
925
+
926
+ // passing calculations
927
+ if (element.passing) {
928
+ element.pixelsPassed = screen.top - element.top;
929
+ element.percentagePassed = (screen.top - element.top) / element.height;
930
+ }
931
+ module.cache.element = element;
932
+ module.verbose('Updated element calculations', element);
933
+
934
+ return element;
935
+ },
936
+ screenCalculations: function () {
937
+ var
938
+ scroll = module.get.scroll()
939
+ ;
940
+ module.save.direction();
941
+ module.cache.screen.top = scroll;
942
+ module.cache.screen.bottom = scroll + module.cache.screen.height;
943
+
944
+ return module.cache.screen;
945
+ },
946
+ screenSize: function () {
947
+ module.verbose('Saving window position');
948
+ module.cache.screen = {
949
+ height: $context.height(),
950
+ };
951
+ },
952
+ position: function () {
953
+ module.save.screenSize();
954
+ module.save.elementPosition();
955
+ },
956
+ },
957
+
958
+ get: {
959
+ pixelsPassed: function (amount) {
960
+ var
961
+ element = module.get.elementCalculations()
962
+ ;
963
+ if (amount.search('%') > -1) {
964
+ return element.height * (parseInt(amount, 10) / 100);
965
+ }
966
+
967
+ return parseInt(amount, 10);
968
+ },
969
+ occurred: function (callback) {
970
+ return module.cache.occurred !== undefined
971
+ ? module.cache.occurred[callback] || false
972
+ : false;
973
+ },
974
+ direction: function () {
975
+ if (module.cache.direction === undefined) {
976
+ module.save.direction();
977
+ }
978
+
979
+ return module.cache.direction;
980
+ },
981
+ elementPosition: function () {
982
+ if (module.cache.element === undefined) {
983
+ module.save.elementPosition();
984
+ }
985
+
986
+ return module.cache.element;
987
+ },
988
+ elementCalculations: function () {
989
+ if (module.cache.element === undefined) {
990
+ module.save.elementCalculations();
991
+ }
992
+
993
+ return module.cache.element;
994
+ },
995
+ screenCalculations: function () {
996
+ if (module.cache.screen === undefined) {
997
+ module.save.screenCalculations();
998
+ }
999
+
1000
+ return module.cache.screen;
1001
+ },
1002
+ screenSize: function () {
1003
+ if (module.cache.screen === undefined) {
1004
+ module.save.screenSize();
1005
+ }
1006
+
1007
+ return module.cache.screen;
1008
+ },
1009
+ scroll: function () {
1010
+ if (module.cache.scroll === undefined) {
1011
+ module.save.scroll();
1012
+ }
1013
+
1014
+ return module.cache.scroll;
1015
+ },
1016
+ lastScroll: function () {
1017
+ if (module.cache.screen === undefined) {
1018
+ module.debug('First scroll event, no last scroll could be found');
1019
+
1020
+ return false;
1021
+ }
1022
+
1023
+ return module.cache.screen.top;
1024
+ },
1025
+ },
1026
+
1027
+ setting: function (name, value) {
1028
+ if ($.isPlainObject(name)) {
1029
+ $.extend(true, settings, name);
1030
+ } else if (value !== undefined) {
1031
+ settings[name] = value;
1032
+ } else {
1033
+ return settings[name];
1034
+ }
1035
+ },
1036
+ internal: function (name, value) {
1037
+ if ($.isPlainObject(name)) {
1038
+ $.extend(true, module, name);
1039
+ } else if (value !== undefined) {
1040
+ module[name] = value;
1041
+ } else {
1042
+ return module[name];
1043
+ }
1044
+ },
1045
+ debug: function () {
1046
+ if (!settings.silent && settings.debug) {
1047
+ if (settings.performance) {
1048
+ module.performance.log(arguments);
1049
+ } else {
1050
+ module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
1051
+ module.debug.apply(console, arguments);
1052
+ }
1053
+ }
1054
+ },
1055
+ verbose: function () {
1056
+ if (!settings.silent && settings.verbose && settings.debug) {
1057
+ if (settings.performance) {
1058
+ module.performance.log(arguments);
1059
+ } else {
1060
+ module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
1061
+ module.verbose.apply(console, arguments);
1062
+ }
1063
+ }
1064
+ },
1065
+ error: function () {
1066
+ if (!settings.silent) {
1067
+ module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
1068
+ module.error.apply(console, arguments);
1069
+ }
1070
+ },
1071
+ performance: {
1072
+ log: function (message) {
1073
+ var
1074
+ currentTime,
1075
+ executionTime,
1076
+ previousTime
1077
+ ;
1078
+ if (settings.performance) {
1079
+ currentTime = Date.now();
1080
+ previousTime = time || currentTime;
1081
+ executionTime = currentTime - previousTime;
1082
+ time = currentTime;
1083
+ performance.push({
1084
+ Name: message[0],
1085
+ Arguments: [].slice.call(message, 1) || '',
1086
+ Element: element,
1087
+ 'Execution Time': executionTime,
1088
+ });
1089
+ }
1090
+ clearTimeout(module.performance.timer);
1091
+ module.performance.timer = setTimeout(function () {
1092
+ module.performance.display();
1093
+ }, 500);
1094
+ },
1095
+ display: function () {
1096
+ var
1097
+ title = settings.name + ':',
1098
+ totalTime = 0
1099
+ ;
1100
+ time = false;
1101
+ clearTimeout(module.performance.timer);
1102
+ $.each(performance, function (index, data) {
1103
+ totalTime += data['Execution Time'];
1104
+ });
1105
+ title += ' ' + totalTime + 'ms';
1106
+ if (performance.length > 0) {
1107
+ console.groupCollapsed(title);
1108
+ if (console.table) {
1109
+ console.table(performance);
1110
+ } else {
1111
+ $.each(performance, function (index, data) {
1112
+ console.log(data.Name + ': ' + data['Execution Time'] + 'ms');
1113
+ });
1114
+ }
1115
+ console.groupEnd();
1116
+ }
1117
+ performance = [];
1118
+ },
1119
+ },
1120
+ invoke: function (query, passedArguments, context) {
1121
+ var
1122
+ object = instance,
1123
+ maxDepth,
1124
+ found,
1125
+ response
1126
+ ;
1127
+ passedArguments = passedArguments || queryArguments;
1128
+ context = context || element;
1129
+ if (typeof query === 'string' && object !== undefined) {
1130
+ query = query.split(/[ .]/);
1131
+ maxDepth = query.length - 1;
1132
+ $.each(query, function (depth, value) {
1133
+ var camelCaseValue = depth !== maxDepth
1134
+ ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
1135
+ : query
1136
+ ;
1137
+ if ($.isPlainObject(object[camelCaseValue]) && (depth !== maxDepth)) {
1138
+ object = object[camelCaseValue];
1139
+ } else if (object[camelCaseValue] !== undefined) {
1140
+ found = object[camelCaseValue];
1141
+
1142
+ return false;
1143
+ } else if ($.isPlainObject(object[value]) && (depth !== maxDepth)) {
1144
+ object = object[value];
1145
+ } else if (object[value] !== undefined) {
1146
+ found = object[value];
1147
+
1148
+ return false;
1149
+ } else {
1150
+ module.error(error.method, query);
1151
+
1152
+ return false;
1153
+ }
1154
+ });
1155
+ }
1156
+ if (isFunction(found)) {
1157
+ response = found.apply(context, passedArguments);
1158
+ } else if (found !== undefined) {
1159
+ response = found;
1160
+ }
1161
+ if (Array.isArray(returnedValue)) {
1162
+ returnedValue.push(response);
1163
+ } else if (returnedValue !== undefined) {
1164
+ returnedValue = [returnedValue, response];
1165
+ } else if (response !== undefined) {
1166
+ returnedValue = response;
1167
+ }
1168
+
1169
+ return found;
1170
+ },
1171
+ };
1172
+
1173
+ if (methodInvoked) {
1174
+ if (instance === undefined) {
1175
+ module.initialize();
1176
+ }
1177
+ instance.save.scroll();
1178
+ instance.save.calculations();
1179
+ module.invoke(query);
1180
+ } else {
1181
+ if (instance !== undefined) {
1182
+ instance.invoke('destroy');
1183
+ }
1184
+ module.initialize();
1185
+ }
1186
+ });
1187
+
1188
+ return returnedValue !== undefined
1189
+ ? returnedValue
1190
+ : this;
1191
+ };
1192
+
1193
+ $.fn.visibility.settings = {
1194
+
1195
+ name: 'Visibility',
1196
+ namespace: 'visibility',
1197
+
1198
+ debug: false,
1199
+ verbose: false,
1200
+ performance: true,
1201
+
1202
+ // whether to use mutation observers to follow changes
1203
+ observeChanges: true,
1204
+
1205
+ // check position immediately on init
1206
+ initialCheck: true,
1207
+
1208
+ // whether to refresh calculations after all page images load
1209
+ refreshOnLoad: true,
1210
+
1211
+ // whether to refresh calculations after page resize event
1212
+ refreshOnResize: true,
1213
+
1214
+ // should call callbacks on refresh event (resize, etc)
1215
+ checkOnRefresh: true,
1216
+
1217
+ // callback should only occur one time
1218
+ once: true,
1219
+
1220
+ // callback should fire continuously when evaluates to true
1221
+ continuous: false,
1222
+
1223
+ // offset to use with scroll top
1224
+ offset: 0,
1225
+
1226
+ // whether to include margin in elements position
1227
+ includeMargin: false,
1228
+
1229
+ // scroll context for visibility checks
1230
+ context: window,
1231
+
1232
+ // visibility check delay in ms (defaults to animationFrame)
1233
+ throttle: false,
1234
+
1235
+ // special visibility type (image, fixed)
1236
+ type: false,
1237
+
1238
+ // z-index to use with visibility 'fixed'
1239
+ zIndex: '10',
1240
+
1241
+ // image only animation settings
1242
+ transition: 'fade in',
1243
+ duration: 1000,
1244
+
1245
+ // array of callbacks for percentage
1246
+ onPassed: {},
1247
+
1248
+ // standard callbacks
1249
+ onOnScreen: false,
1250
+ onOffScreen: false,
1251
+ onPassing: false,
1252
+ onTopVisible: false,
1253
+ onBottomVisible: false,
1254
+ onTopPassed: false,
1255
+ onBottomPassed: false,
1256
+
1257
+ // reverse callbacks
1258
+ onPassingReverse: false,
1259
+ onTopVisibleReverse: false,
1260
+ onBottomVisibleReverse: false,
1261
+ onTopPassedReverse: false,
1262
+ onBottomPassedReverse: false,
1263
+
1264
+ // special callbacks for image
1265
+ onLoad: function () {},
1266
+ onAllLoaded: function () {},
1267
+
1268
+ // special callbacks for fixed position
1269
+ onFixed: function () {},
1270
+ onUnfixed: function () {},
1271
+
1272
+ // utility callbacks
1273
+ onUpdate: false, // disabled by default for performance
1274
+ onRefresh: function () {},
1275
+
1276
+ metadata: {
1277
+ src: 'src',
1278
+ },
1279
+
1280
+ className: {
1281
+ fixed: 'fixed',
1282
+ placeholder: 'constraint',
1283
+ visible: 'visible',
1284
+ },
1285
+
1286
+ error: {
1287
+ method: 'The method you called is not defined.',
1288
+ visible: 'Element is hidden, you must call refresh after element becomes visible',
1289
+ },
1290
+
1291
+ };
1292
+ })(jQuery, window, document);