fomantic-ui-sass 2.8.8.1 → 2.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/app/assets/fonts/semantic-ui/Lato-Bold.woff +0 -0
  4. data/app/assets/fonts/semantic-ui/Lato-Bold.woff2 +0 -0
  5. data/app/assets/fonts/semantic-ui/Lato-BoldItalic.woff +0 -0
  6. data/app/assets/fonts/semantic-ui/Lato-BoldItalic.woff2 +0 -0
  7. data/app/assets/fonts/semantic-ui/Lato-Italic.woff +0 -0
  8. data/app/assets/fonts/semantic-ui/Lato-Italic.woff2 +0 -0
  9. data/app/assets/fonts/semantic-ui/Lato-Regular.woff +0 -0
  10. data/app/assets/fonts/semantic-ui/Lato-Regular.woff2 +0 -0
  11. data/app/assets/fonts/semantic-ui/LatoLatin-Bold.woff +0 -0
  12. data/app/assets/fonts/semantic-ui/LatoLatin-Bold.woff2 +0 -0
  13. data/app/assets/fonts/semantic-ui/LatoLatin-BoldItalic.woff +0 -0
  14. data/app/assets/fonts/semantic-ui/LatoLatin-BoldItalic.woff2 +0 -0
  15. data/app/assets/fonts/semantic-ui/LatoLatin-Italic.woff +0 -0
  16. data/app/assets/fonts/semantic-ui/LatoLatin-Italic.woff2 +0 -0
  17. data/app/assets/fonts/semantic-ui/LatoLatin-Regular.woff +0 -0
  18. data/app/assets/fonts/semantic-ui/LatoLatin-Regular.woff2 +0 -0
  19. data/app/assets/fonts/semantic-ui/brand-icons.eot +0 -0
  20. data/app/assets/fonts/semantic-ui/brand-icons.svg +41 -6
  21. data/app/assets/fonts/semantic-ui/brand-icons.ttf +0 -0
  22. data/app/assets/fonts/semantic-ui/brand-icons.woff +0 -0
  23. data/app/assets/fonts/semantic-ui/brand-icons.woff2 +0 -0
  24. data/app/assets/fonts/semantic-ui/icons.eot +0 -0
  25. data/app/assets/fonts/semantic-ui/icons.svg +245 -7
  26. data/app/assets/fonts/semantic-ui/icons.ttf +0 -0
  27. data/app/assets/fonts/semantic-ui/icons.woff +0 -0
  28. data/app/assets/fonts/semantic-ui/icons.woff2 +0 -0
  29. data/app/assets/fonts/semantic-ui/outline-icons.eot +0 -0
  30. data/app/assets/fonts/semantic-ui/outline-icons.svg +2 -2
  31. data/app/assets/fonts/semantic-ui/outline-icons.ttf +0 -0
  32. data/app/assets/fonts/semantic-ui/outline-icons.woff +0 -0
  33. data/app/assets/fonts/semantic-ui/outline-icons.woff2 +0 -0
  34. data/app/assets/javascripts/semantic-ui/accordion.js +569 -590
  35. data/app/assets/javascripts/semantic-ui/api.js +1153 -1116
  36. data/app/assets/javascripts/semantic-ui/calendar.js +1941 -1698
  37. data/app/assets/javascripts/semantic-ui/checkbox.js +862 -854
  38. data/app/assets/javascripts/semantic-ui/dimmer.js +697 -713
  39. data/app/assets/javascripts/semantic-ui/dropdown.js +4196 -4192
  40. data/app/assets/javascripts/semantic-ui/embed.js +646 -672
  41. data/app/assets/javascripts/semantic-ui/flyout.js +1579 -0
  42. data/app/assets/javascripts/semantic-ui/form.js +2024 -2000
  43. data/app/assets/javascripts/semantic-ui/modal.js +1546 -1384
  44. data/app/assets/javascripts/semantic-ui/nag.js +521 -527
  45. data/app/assets/javascripts/semantic-ui/popup.js +1457 -1463
  46. data/app/assets/javascripts/semantic-ui/progress.js +970 -995
  47. data/app/assets/javascripts/semantic-ui/rating.js +508 -520
  48. data/app/assets/javascripts/semantic-ui/search.js +1521 -1508
  49. data/app/assets/javascripts/semantic-ui/shape.js +784 -811
  50. data/app/assets/javascripts/semantic-ui/sidebar.js +1061 -1002
  51. data/app/assets/javascripts/semantic-ui/site.js +437 -477
  52. data/app/assets/javascripts/semantic-ui/slider.js +1311 -1297
  53. data/app/assets/javascripts/semantic-ui/state.js +639 -658
  54. data/app/assets/javascripts/semantic-ui/sticky.js +848 -891
  55. data/app/assets/javascripts/semantic-ui/tab.js +895 -941
  56. data/app/assets/javascripts/semantic-ui/toast.js +911 -851
  57. data/app/assets/javascripts/semantic-ui/transition.js +1049 -1073
  58. data/app/assets/javascripts/semantic-ui/visibility.js +1214 -1246
  59. data/app/assets/stylesheets/semantic-ui/collections/_breadcrumb.scss +7 -7
  60. data/app/assets/stylesheets/semantic-ui/collections/_form.scss +389 -407
  61. data/app/assets/stylesheets/semantic-ui/collections/_grid.scss +203 -345
  62. data/app/assets/stylesheets/semantic-ui/collections/_menu.scss +372 -501
  63. data/app/assets/stylesheets/semantic-ui/collections/_message.scss +154 -226
  64. data/app/assets/stylesheets/semantic-ui/collections/_table.scss +2065 -880
  65. data/app/assets/stylesheets/semantic-ui/elements/_button.scss +867 -1232
  66. data/app/assets/stylesheets/semantic-ui/elements/_container.scss +101 -6
  67. data/app/assets/stylesheets/semantic-ui/elements/_divider.scss +75 -93
  68. data/app/assets/stylesheets/semantic-ui/elements/_emoji.scss +11148 -9190
  69. data/app/assets/stylesheets/semantic-ui/elements/_flag.scss +1037 -929
  70. data/app/assets/stylesheets/semantic-ui/elements/_header.scss +124 -146
  71. data/app/assets/stylesheets/semantic-ui/elements/_icon.scss +2728 -2759
  72. data/app/assets/stylesheets/semantic-ui/elements/_image.scss +41 -65
  73. data/app/assets/stylesheets/semantic-ui/elements/_input.scss +982 -163
  74. data/app/assets/stylesheets/semantic-ui/elements/_label.scss +432 -479
  75. data/app/assets/stylesheets/semantic-ui/elements/_list.scss +80 -101
  76. data/app/assets/stylesheets/semantic-ui/elements/_loader.scss +452 -540
  77. data/app/assets/stylesheets/semantic-ui/elements/_placeholder.scss +56 -76
  78. data/app/assets/stylesheets/semantic-ui/elements/_rail.scss +17 -22
  79. data/app/assets/stylesheets/semantic-ui/elements/_reveal.scss +46 -85
  80. data/app/assets/stylesheets/semantic-ui/elements/_segment.scss +263 -255
  81. data/app/assets/stylesheets/semantic-ui/elements/_step.scss +106 -179
  82. data/app/assets/stylesheets/semantic-ui/elements/_text.scss +33 -33
  83. data/app/assets/stylesheets/semantic-ui/globals/_reset.scss +14 -18
  84. data/app/assets/stylesheets/semantic-ui/globals/_site.scss +132 -48
  85. data/app/assets/stylesheets/semantic-ui/modules/_accordion.scss +196 -74
  86. data/app/assets/stylesheets/semantic-ui/modules/_calendar.scss +43 -29
  87. data/app/assets/stylesheets/semantic-ui/modules/_checkbox.scss +210 -280
  88. data/app/assets/stylesheets/semantic-ui/modules/_dimmer.scss +78 -182
  89. data/app/assets/stylesheets/semantic-ui/modules/_dropdown.scss +339 -423
  90. data/app/assets/stylesheets/semantic-ui/modules/_embed.scss +24 -35
  91. data/app/assets/stylesheets/semantic-ui/modules/_flyout.scss +546 -0
  92. data/app/assets/stylesheets/semantic-ui/modules/_modal.scss +150 -153
  93. data/app/assets/stylesheets/semantic-ui/modules/_nag.scss +55 -65
  94. data/app/assets/stylesheets/semantic-ui/modules/_popup.scss +530 -310
  95. data/app/assets/stylesheets/semantic-ui/modules/_progress.scss +108 -213
  96. data/app/assets/stylesheets/semantic-ui/modules/_rating.scss +88 -168
  97. data/app/assets/stylesheets/semantic-ui/modules/_search.scss +73 -102
  98. data/app/assets/stylesheets/semantic-ui/modules/_shape.scss +16 -32
  99. data/app/assets/stylesheets/semantic-ui/modules/_sidebar.scss +126 -215
  100. data/app/assets/stylesheets/semantic-ui/modules/_slider.scss +110 -138
  101. data/app/assets/stylesheets/semantic-ui/modules/_sticky.scss +3 -7
  102. data/app/assets/stylesheets/semantic-ui/modules/_tab.scss +16 -20
  103. data/app/assets/stylesheets/semantic-ui/modules/_toast.scss +111 -141
  104. data/app/assets/stylesheets/semantic-ui/modules/_transition.scss +371 -1282
  105. data/app/assets/stylesheets/semantic-ui/views/_ad.scss +39 -50
  106. data/app/assets/stylesheets/semantic-ui/views/_card.scss +949 -458
  107. data/app/assets/stylesheets/semantic-ui/views/_comment.scss +44 -62
  108. data/app/assets/stylesheets/semantic-ui/views/_feed.scss +50 -72
  109. data/app/assets/stylesheets/semantic-ui/views/_item.scss +89 -136
  110. data/app/assets/stylesheets/semantic-ui/views/_statistic.scss +78 -119
  111. data/lib/fomantic/ui/sass/version.rb +2 -2
  112. data/tasks/converter.rb +1 -1
  113. metadata +21 -3
@@ -1,1313 +1,1281 @@
1
1
  /*!
2
2
  * # Fomantic-UI - Visibility
3
- * http://github.com/fomantic/Fomantic-UI/
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);