fomantic-ui-sass 2.6.4

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