fomantic-ui 2.9.1-beta.17 → 2.9.1-beta.19

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