@ntlab/ntjs-assets 2.0.2 → 2.0.3

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