kube 6.5.2.0

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 (48) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/CHANGELOG.md +31 -0
  4. data/Gemfile +2 -0
  5. data/README.md +158 -0
  6. data/app/assets/javascripts/kube.js +2201 -0
  7. data/app/assets/stylesheets/kube.scss +13 -0
  8. data/app/assets/stylesheets/kube/_components.scss +25 -0
  9. data/app/assets/stylesheets/kube/_mixins.scss +8 -0
  10. data/app/assets/stylesheets/kube/_properties.scss +178 -0
  11. data/app/assets/stylesheets/kube/_variables.scss +10 -0
  12. data/app/assets/stylesheets/kube/all.scss +14 -0
  13. data/app/assets/stylesheets/kube/components/_animation.scss +95 -0
  14. data/app/assets/stylesheets/kube/components/_breadcrumbs.scss +37 -0
  15. data/app/assets/stylesheets/kube/components/_buttons.scss +166 -0
  16. data/app/assets/stylesheets/kube/components/_colors.scss +28 -0
  17. data/app/assets/stylesheets/kube/components/_dropdown.scss +51 -0
  18. data/app/assets/stylesheets/kube/components/_forms.scss +259 -0
  19. data/app/assets/stylesheets/kube/components/_grid.scss +68 -0
  20. data/app/assets/stylesheets/kube/components/_icons.scss +51 -0
  21. data/app/assets/stylesheets/kube/components/_labels.scss +116 -0
  22. data/app/assets/stylesheets/kube/components/_messages.scss +49 -0
  23. data/app/assets/stylesheets/kube/components/_modal.scss +55 -0
  24. data/app/assets/stylesheets/kube/components/_offcanvas.scss +26 -0
  25. data/app/assets/stylesheets/kube/components/_pagination.scss +91 -0
  26. data/app/assets/stylesheets/kube/components/_positioning.scss +77 -0
  27. data/app/assets/stylesheets/kube/components/_print.scss +41 -0
  28. data/app/assets/stylesheets/kube/components/_reset.scss +48 -0
  29. data/app/assets/stylesheets/kube/components/_sizing.scss +107 -0
  30. data/app/assets/stylesheets/kube/components/_tables.scss +77 -0
  31. data/app/assets/stylesheets/kube/components/_tabs.scss +43 -0
  32. data/app/assets/stylesheets/kube/components/_typography.scss +325 -0
  33. data/app/assets/stylesheets/kube/components/_utils.scss +139 -0
  34. data/app/assets/stylesheets/kube/mixins/_breakpoints.scss +27 -0
  35. data/app/assets/stylesheets/kube/mixins/_buttons.scss +29 -0
  36. data/app/assets/stylesheets/kube/mixins/_flex.scss +97 -0
  37. data/app/assets/stylesheets/kube/mixins/_fonts.scss +27 -0
  38. data/app/assets/stylesheets/kube/mixins/_gradients.scss +28 -0
  39. data/app/assets/stylesheets/kube/mixins/_grid.scss +54 -0
  40. data/app/assets/stylesheets/kube/mixins/_labels.scss +10 -0
  41. data/app/assets/stylesheets/kube/mixins/_utils.scss +60 -0
  42. data/kube.gemspec +23 -0
  43. data/lib/generators/kube/install/install_generator.rb +13 -0
  44. data/lib/generators/kube/install/templates/kube_properties.scss +178 -0
  45. data/lib/kube.rb +5 -0
  46. data/lib/kube/engine.rb +6 -0
  47. data/lib/kube/version.rb +11 -0
  48. metadata +110 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bff4afc4b2a1af6285fabc0f89b59dea6b0c4ddd
4
+ data.tar.gz: c7510b0fb7edebd111bc5239d44550fec8b42d16
5
+ SHA512:
6
+ metadata.gz: 5ac777385f67ea53764d9407132a9a4b7fe5895b1acf5ed190b13a0922efa639c57837fb6efaf69e5e55d3b73903b538d7a3d68145c1f76ee900d0d04de66104
7
+ data.tar.gz: 13961d1a19a677a423227df5d1bb4b56c051ab507879390424a36de15019f79edaa660cdae1f2bba3496bfc0d96220ad4f3e2841eb6af7b8b36fa94b39d14e2c
@@ -0,0 +1,3 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
@@ -0,0 +1,31 @@
1
+ # Changelog
2
+
3
+ The Kube gem matches the source library version for major, minor and patch numbers.
4
+ We reserve the last number, the revision for gem releases.
5
+
6
+ As an example, with Kube framework V6.5.2 this gem will have the following properties:
7
+
8
+ ```ruby
9
+ Kube::Version::Compact
10
+ => 6.5.2.0
11
+ ```
12
+
13
+ If we release a revision to our code in between Kube framework releases:
14
+
15
+ ```ruby
16
+ Kube::Version::Compact
17
+ => 6.5.2.1
18
+
19
+ Kube::Version::Revision
20
+ => 1
21
+ ```
22
+
23
+ A matching revision entry will appear in this CHANGELOG to explain the changes.
24
+
25
+ ## Unreleased
26
+
27
+ (nothing)
28
+
29
+ ## 6.5.2.0
30
+
31
+ - Initial release.
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
@@ -0,0 +1,158 @@
1
+ # Kube
2
+
3
+ The Kube gem wraps the Imperavi Kube CSS & JS framework (hereafter Kube framework) for the Rails asset pipeline.
4
+
5
+ In order to make the variables available at runtime I decided to convert the majority of the SASS variables to CSS Custom Properties. In doing so you can now get and set CSS Custom Property values using Javascript. Unfortunately I couldn't find an acceptable workaround for the remaining 5 SASS variables that are used to generate the grid. However, I didn't find this particularly necessary in my projects anyway.
6
+
7
+ CSS Custom Properties permit the declaration and usage of cascading variables in stylesheets. [caniuse.com](https://caniuse.com/#feat=css-variables) reports global support at 72.2%. The main exceptions are Internet Explorer and Opera Mini. Edge 15 has partial support but only due to there being bugs present, so expect this will be fixed soon and full support will be present in that browser too.
8
+
9
+ ### Please Note
10
+
11
+ Imperavi's [original version](https://github.com/imperavi/kube) of this framework boasts support for latest Chrome, Firefox, Safari and Opera; and Microsoft Edge and Internet Explorer 11. The changes I have made using CSS Custom Properties affects this support.
12
+
13
+ Please consult [caniuse.com](https://caniuse.com/#feat=css-variables) when making your decision about whether this gem is appropriate for your product.
14
+
15
+ ## Versioning
16
+
17
+ The Kube gem matches the source library version for major, minor and patch numbers.
18
+ We reserve the last number, the revision for gem releases.
19
+
20
+ As an example, with Kube framework V6.5.2 this gem will have the following properties:
21
+
22
+ ```ruby
23
+ Kube::Version::Compact
24
+ => 6.5.2.0
25
+ ```
26
+
27
+ If we release a revision to our code in between Kube framework releases:
28
+
29
+ ```ruby
30
+ Kube::Version::Compact
31
+ => 6.5.2.1
32
+
33
+ Kube::Version::Revision
34
+ => 1
35
+ ```
36
+
37
+ A matching release number will a list of changes will appear in `CHANGELOG.md`.
38
+
39
+ ## Installation
40
+
41
+ To install add the line to your Gemfile:
42
+
43
+ ```
44
+ gem 'kube', '6.5.2.0'
45
+ ```
46
+
47
+ And `bundle`.
48
+
49
+ ## Dependencies
50
+
51
+ **Rails 5.1+**
52
+ The Rails JavaScript helpers have been rewritten and published in a new gem called `rails-ujs`. They now they use vanilla JavaScript, so jQuery is not a dependency of Rails anymore. Since Kube relies on it, install it with ```bin/yarn add jquery``` or via ```gem 'jquery-rails'``` and add ```//= require jquery``` to ```application.js```.
53
+
54
+ **NOTE:** Ensure that the `sass-rails` gem is present in your Gemfile.
55
+
56
+ ## Adding the Kube javascript
57
+
58
+ Add the following to your application.js:
59
+
60
+ ```js
61
+ # app/assets/javascripts/application.js
62
+ //= require jquery3
63
+ //= require kube
64
+ ```
65
+
66
+ ## Adding the Kube stylesheet
67
+
68
+ Import Kube styles in `application.scss`:
69
+
70
+ ```css
71
+ @import "kube/all";
72
+ ```
73
+
74
+ **NOTE:** If you have just generated a new Rails application, it may come with a `.css` file instead. If this file exists, it will be served instead of Sass, so remove it.
75
+
76
+ ```
77
+ $ mv app/assets/stylesheets/application.css app/assets/stylesheets/application.scss
78
+ ```
79
+
80
+ If you don't want to use the default Kube styles and want control over fonts, colors, padding, margins etc., you can set your own values by changing the CSS Custom Properties.
81
+
82
+ Use the built in Kube installer to copy the Kube properties scss file:
83
+
84
+ ```
85
+ $ rails generate kube:install
86
+ ```
87
+
88
+ This will create `app/assets/stylesheets/_kube_properties.scss`.
89
+
90
+ Import this file into your `application.scss` and switch from using `kube/all` to just `kube`:
91
+
92
+ ```css
93
+ @import "kube_properties";
94
+ @import "kube";
95
+ ```
96
+ If you take a look at `_kube_properties.scss` you see that all CSS Custom Properties are set under the `:root` pseudo-selector rule. This effectively make them global.
97
+
98
+ You can now set the value of any property and it will be used at runtime by the browser.
99
+
100
+ In addition you can access and change CSS Custom Properties at runtime in the browser using Javascript.
101
+
102
+ To get a custom property value set on the root element, get the styles applied to `document.documentElement`:
103
+
104
+ ```js
105
+ var rootStyles = getComputedStyle(document.documentElement);
106
+ var defaultColor = rootStyles.getPropertyValue('--color-text');
107
+ ```
108
+
109
+ Since these are runtime properties, values can be updated dynamically:
110
+
111
+ ```js
112
+ document.documentElement.style.setProperty('--color-text', '#c80');
113
+ ```
114
+
115
+ The change will be effectively immediately in the browser.
116
+
117
+ ## About the grid variables
118
+
119
+ The grid variables are still declared in SASS. To change these use the following setup in your `application.scss` file:
120
+
121
+ ```css
122
+ // Import the Kube SASS variables and override one or more values:
123
+ @import "kube/variables";
124
+
125
+ // BREAKPOINTS
126
+ $sm: 768px;
127
+ $md: 1024px;
128
+ $lg: 1200px;
129
+
130
+ // GRID
131
+ $grid-columns: 12;
132
+ $grid-gutter: 2%;
133
+
134
+ // Import the Kube CSS Custom Properties:
135
+ @import "kube/properties";
136
+ // or if you have installed the _kube_properties.scss:
137
+ // @import "kube_properties";
138
+
139
+ // Import the rest of Kube:
140
+ @import "kube/mixins";
141
+ @import "kube/components";
142
+ ```
143
+
144
+ ## Acknowledgements
145
+
146
+ Kube framework is made by and copyright [Imperavi LLC](https://imperavi.com/kube).
147
+
148
+ This gem was written and is maintained by [Jurgen Jocubeit](https://github.com/JurgenJocubeit).
149
+
150
+ ## License
151
+
152
+ Kube framework is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
153
+
154
+ This gem is also available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
155
+
156
+ ## Copyright
157
+
158
+ Copyright 2017 Jurgen Jocubeit
@@ -0,0 +1,2201 @@
1
+ /*
2
+ Kube. CSS & JS Framework
3
+ Version 6.5.2
4
+ Updated: February 2, 2017
5
+
6
+ http://imperavi.com/kube/
7
+
8
+ Copyright (c) 2009-2017, Imperavi LLC.
9
+ License: MIT
10
+ */
11
+ if (typeof jQuery === 'undefined') {throw new Error('Kube\'s requires jQuery')};
12
+ ;(function($) { var version = $.fn.jquery.split('.'); if (version[0] == 1 && version[1] < 8) {throw new Error('Kube\'s requires at least jQuery v1.8'); }})(jQuery);
13
+
14
+ ;(function()
15
+ {
16
+ // Inherits
17
+ Function.prototype.inherits = function(parent)
18
+ {
19
+ var F = function () {};
20
+ F.prototype = parent.prototype;
21
+ var f = new F();
22
+
23
+ for (var prop in this.prototype) f[prop] = this.prototype[prop];
24
+ this.prototype = f;
25
+ this.prototype.super = parent.prototype;
26
+ };
27
+
28
+ // Core Class
29
+ var Kube = function(element, options)
30
+ {
31
+ options = (typeof options === 'object') ? options : {};
32
+
33
+ this.$element = $(element);
34
+ this.opts = $.extend(true, this.defaults, $.fn[this.namespace].options, this.$element.data(), options);
35
+ this.$target = (typeof this.opts.target === 'string') ? $(this.opts.target) : null;
36
+ };
37
+
38
+ // Core Functionality
39
+ Kube.prototype = {
40
+ getInstance: function()
41
+ {
42
+ return this.$element.data('fn.' + this.namespace);
43
+ },
44
+ hasTarget: function()
45
+ {
46
+ return !(this.$target === null);
47
+ },
48
+ callback: function(type)
49
+ {
50
+ var args = [].slice.call(arguments).splice(1);
51
+
52
+ // on element callback
53
+ if (this.$element)
54
+ {
55
+ args = this._fireCallback($._data(this.$element[0], 'events'), type, this.namespace, args);
56
+ }
57
+
58
+ // on target callback
59
+ if (this.$target)
60
+ {
61
+ args = this._fireCallback($._data(this.$target[0], 'events'), type, this.namespace, args);
62
+ }
63
+
64
+ // opts callback
65
+ if (this.opts && this.opts.callbacks && $.isFunction(this.opts.callbacks[type]))
66
+ {
67
+ return this.opts.callbacks[type].apply(this, args);
68
+ }
69
+
70
+ return args;
71
+ },
72
+ _fireCallback: function(events, type, eventNamespace, args)
73
+ {
74
+ if (events && typeof events[type] !== 'undefined')
75
+ {
76
+ var len = events[type].length;
77
+ for (var i = 0; i < len; i++)
78
+ {
79
+ var namespace = events[type][i].namespace;
80
+ if (namespace === eventNamespace)
81
+ {
82
+ var value = events[type][i].handler.apply(this, args);
83
+ }
84
+ }
85
+ }
86
+
87
+ return (typeof value === 'undefined') ? args : value;
88
+ }
89
+ };
90
+
91
+ // Scope
92
+ window.Kube = Kube;
93
+
94
+ })();
95
+ /**
96
+ * @library Kube Plugin
97
+ * @author Imperavi LLC
98
+ * @license MIT
99
+ */
100
+ (function(Kube)
101
+ {
102
+ Kube.Plugin = {
103
+ create: function(classname, pluginname)
104
+ {
105
+ pluginname = (typeof pluginname === 'undefined') ? classname.toLowerCase() : pluginname;
106
+
107
+ $.fn[pluginname] = function(method, options)
108
+ {
109
+ var args = Array.prototype.slice.call(arguments, 1);
110
+ var name = 'fn.' + pluginname;
111
+ var val = [];
112
+
113
+ this.each(function()
114
+ {
115
+ var $this = $(this), data = $this.data(name);
116
+ options = (typeof method === 'object') ? method : options;
117
+
118
+ if (!data)
119
+ {
120
+ // Initialization
121
+ $this.data(name, {});
122
+ $this.data(name, (data = new Kube[classname](this, options)));
123
+ }
124
+
125
+ // Call methods
126
+ if (typeof method === 'string')
127
+ {
128
+ if ($.isFunction(data[method]))
129
+ {
130
+ var methodVal = data[method].apply(data, args);
131
+ if (methodVal !== undefined)
132
+ {
133
+ val.push(methodVal);
134
+ }
135
+ }
136
+ else
137
+ {
138
+ $.error('No such method "' + method + '" for ' + classname);
139
+ }
140
+ }
141
+
142
+ });
143
+
144
+ return (val.length === 0 || val.length === 1) ? ((val.length === 0) ? this : val[0]) : val;
145
+ };
146
+
147
+ $.fn[pluginname].options = {};
148
+
149
+ return this;
150
+ },
151
+ autoload: function(pluginname)
152
+ {
153
+ var arr = pluginname.split(',');
154
+ var len = arr.length;
155
+
156
+ for (var i = 0; i < len; i++)
157
+ {
158
+ var name = arr[i].toLowerCase().split(',').map(function(s) { return s.trim() }).join(',');
159
+ this.autoloadQueue.push(name);
160
+ }
161
+
162
+ return this;
163
+ },
164
+ autoloadQueue: [],
165
+ startAutoload: function()
166
+ {
167
+ if (!window.MutationObserver || this.autoloadQueue.length === 0)
168
+ {
169
+ return;
170
+ }
171
+
172
+ var self = this;
173
+ var observer = new MutationObserver(function(mutations)
174
+ {
175
+ mutations.forEach(function(mutation)
176
+ {
177
+ var newNodes = mutation.addedNodes;
178
+ if (newNodes.length === 0 || (newNodes.length === 1 && newNodes.nodeType === 3))
179
+ {
180
+ return;
181
+ }
182
+
183
+ self.startAutoloadOnce();
184
+ });
185
+ });
186
+
187
+ // pass in the target node, as well as the observer options
188
+ observer.observe(document, {
189
+ subtree: true,
190
+ childList: true
191
+ });
192
+ },
193
+ startAutoloadOnce: function()
194
+ {
195
+ var self = this;
196
+ var $nodes = $('[data-component]').not('[data-loaded]');
197
+ $nodes.each(function()
198
+ {
199
+ var $el = $(this);
200
+ var pluginname = $el.data('component');
201
+
202
+ if (self.autoloadQueue.indexOf(pluginname) !== -1)
203
+ {
204
+ $el.attr('data-loaded', true);
205
+ $el[pluginname]();
206
+ }
207
+ });
208
+
209
+ },
210
+ watch: function()
211
+ {
212
+ Kube.Plugin.startAutoloadOnce();
213
+ Kube.Plugin.startAutoload();
214
+ }
215
+ };
216
+
217
+ $(window).on('load', function()
218
+ {
219
+ Kube.Plugin.watch();
220
+ });
221
+
222
+ }(Kube));
223
+ /**
224
+ * @library Kube Animation
225
+ * @author Imperavi LLC
226
+ * @license MIT
227
+ */
228
+ (function(Kube)
229
+ {
230
+ Kube.Animation = function(element, effect, callback)
231
+ {
232
+ this.namespace = 'animation';
233
+ this.defaults = {};
234
+
235
+ // Parent Constructor
236
+ Kube.apply(this, arguments);
237
+
238
+ // Initialization
239
+ this.effect = effect;
240
+ this.completeCallback = (typeof callback === 'undefined') ? false : callback;
241
+ this.prefixes = ['', '-moz-', '-o-animation-', '-webkit-'];
242
+ this.queue = [];
243
+
244
+ this.start();
245
+ };
246
+
247
+ Kube.Animation.prototype = {
248
+ start: function()
249
+ {
250
+ if (this.isSlideEffect()) this.setElementHeight();
251
+
252
+ this.addToQueue();
253
+ this.clean();
254
+ this.animate();
255
+ },
256
+ addToQueue: function()
257
+ {
258
+ this.queue.push(this.effect);
259
+ },
260
+ setElementHeight: function()
261
+ {
262
+ this.$element.height(this.$element.height());
263
+ },
264
+ removeElementHeight: function()
265
+ {
266
+ this.$element.css('height', '');
267
+ },
268
+ isSlideEffect: function()
269
+ {
270
+ return (this.effect === 'slideDown' || this.effect === 'slideUp');
271
+ },
272
+ isHideableEffect: function()
273
+ {
274
+ var effects = ['fadeOut', 'slideUp', 'flipOut', 'zoomOut', 'slideOutUp', 'slideOutRight', 'slideOutLeft'];
275
+
276
+ return ($.inArray(this.effect, effects) !== -1);
277
+ },
278
+ isToggleEffect: function()
279
+ {
280
+ return (this.effect === 'show' || this.effect === 'hide');
281
+ },
282
+ storeHideClasses: function()
283
+ {
284
+ if (this.$element.hasClass('hide-sm')) this.$element.data('hide-sm-class', true);
285
+ else if (this.$element.hasClass('hide-md')) this.$element.data('hide-md-class', true);
286
+ },
287
+ revertHideClasses: function()
288
+ {
289
+ if (this.$element.data('hide-sm-class')) this.$element.addClass('hide-sm').removeData('hide-sm-class');
290
+ else if (this.$element.data('hide-md-class')) this.$element.addClass('hide-md').removeData('hide-md-class');
291
+ else this.$element.addClass('hide');
292
+ },
293
+ removeHideClass: function()
294
+ {
295
+ if (this.$element.data('hide-sm-class')) this.$element.removeClass('hide-sm');
296
+ else if (this.$element.data('hide-md-class')) this.$element.removeClass('hide-md');
297
+ else this.$element.removeClass('hide');
298
+ },
299
+ animate: function()
300
+ {
301
+ this.storeHideClasses();
302
+ if (this.isToggleEffect())
303
+ {
304
+ return this.makeSimpleEffects();
305
+ }
306
+
307
+ this.$element.addClass('kubeanimated');
308
+ this.$element.addClass(this.queue[0]);
309
+ this.removeHideClass();
310
+
311
+ var _callback = (this.queue.length > 1) ? null : this.completeCallback;
312
+ this.complete('AnimationEnd', $.proxy(this.makeComplete, this), _callback);
313
+ },
314
+ makeSimpleEffects: function()
315
+ {
316
+ if (this.effect === 'show') this.removeHideClass();
317
+ else if (this.effect === 'hide') this.revertHideClasses();
318
+
319
+ if (typeof this.completeCallback === 'function') this.completeCallback(this);
320
+ },
321
+ makeComplete: function()
322
+ {
323
+ if (this.$element.hasClass(this.queue[0]))
324
+ {
325
+ this.clean();
326
+ this.queue.shift();
327
+
328
+ if (this.queue.length) this.animate();
329
+ }
330
+ },
331
+ complete: function(type, make, callback)
332
+ {
333
+ var event = type.toLowerCase() + ' webkit' + type + ' o' + type + ' MS' + type;
334
+
335
+ this.$element.one(event, $.proxy(function()
336
+ {
337
+ if (typeof make === 'function') make();
338
+ if (this.isHideableEffect()) this.revertHideClasses();
339
+ if (this.isSlideEffect()) this.removeElementHeight();
340
+ if (typeof callback === 'function') callback(this);
341
+
342
+ this.$element.off(event);
343
+
344
+ }, this));
345
+ },
346
+ clean: function()
347
+ {
348
+ this.$element.removeClass('kubeanimated').removeClass(this.queue[0]);
349
+ }
350
+ };
351
+
352
+ // Inheritance
353
+ Kube.Animation.inherits(Kube);
354
+
355
+ }(Kube));
356
+
357
+ // Plugin
358
+ (function($)
359
+ {
360
+ $.fn.animation = function(effect, callback)
361
+ {
362
+ var name = 'fn.animation';
363
+
364
+ return this.each(function()
365
+ {
366
+ var $this = $(this), data = $this.data(name);
367
+
368
+ $this.data(name, {});
369
+ $this.data(name, (data = new Kube.Animation(this, effect, callback)));
370
+ });
371
+ };
372
+
373
+ $.fn.animation.options = {};
374
+
375
+ })(jQuery);
376
+ /**
377
+ * @library Kube Detect
378
+ * @author Imperavi LLC
379
+ * @license MIT
380
+ */
381
+ (function(Kube)
382
+ {
383
+ Kube.Detect = function() {};
384
+
385
+ Kube.Detect.prototype = {
386
+ isMobile: function()
387
+ {
388
+ return /(iPhone|iPod|BlackBerry|Android)/.test(navigator.userAgent);
389
+ },
390
+ isDesktop: function()
391
+ {
392
+ return !/(iPhone|iPod|iPad|BlackBerry|Android)/.test(navigator.userAgent);
393
+ },
394
+ isMobileScreen: function()
395
+ {
396
+ return ($(window).width() <= 768);
397
+ },
398
+ isTabletScreen: function()
399
+ {
400
+ return ($(window).width() >= 768 && $(window).width() <= 1024);
401
+ },
402
+ isDesktopScreen: function()
403
+ {
404
+ return ($(window).width() > 1024);
405
+ }
406
+ };
407
+
408
+
409
+ }(Kube));
410
+ /**
411
+ * @library Kube FormData
412
+ * @author Imperavi LLC
413
+ * @license MIT
414
+ */
415
+ (function(Kube)
416
+ {
417
+ Kube.FormData = function(app)
418
+ {
419
+ this.opts = app.opts;
420
+ };
421
+
422
+ Kube.FormData.prototype = {
423
+ set: function(data)
424
+ {
425
+ this.data = data;
426
+ },
427
+ get: function(formdata)
428
+ {
429
+ this.formdata = formdata;
430
+
431
+ if (this.opts.appendForms) this.appendForms();
432
+ if (this.opts.appendFields) this.appendFields();
433
+
434
+ return this.data;
435
+ },
436
+ appendFields: function()
437
+ {
438
+ var $fields = $(this.opts.appendFields);
439
+ if ($fields.length === 0)
440
+ {
441
+ return;
442
+ }
443
+
444
+ var self = this;
445
+ var str = '';
446
+
447
+ if (this.formdata)
448
+ {
449
+ $fields.each(function()
450
+ {
451
+ self.data.append($(this).attr('name'), $(this).val());
452
+ });
453
+ }
454
+ else
455
+ {
456
+ $fields.each(function()
457
+ {
458
+ str += '&' + $(this).attr('name') + '=' + $(this).val();
459
+ });
460
+
461
+ this.data = (this.data === '') ? str.replace(/^&/, '') : this.data + str;
462
+ }
463
+ },
464
+ appendForms: function()
465
+ {
466
+ var $forms = $(this.opts.appendForms);
467
+ if ($forms.length === 0)
468
+ {
469
+ return;
470
+ }
471
+
472
+ if (this.formdata)
473
+ {
474
+ var self = this;
475
+ var formsData = $(this.opts.appendForms).serializeArray();
476
+ $.each(formsData, function(i,s)
477
+ {
478
+ self.data.append(s.name, s.value);
479
+ });
480
+ }
481
+ else
482
+ {
483
+ var str = $forms.serialize();
484
+
485
+ this.data = (this.data === '') ? str : this.data + '&' + str;
486
+ }
487
+ }
488
+ };
489
+
490
+
491
+ }(Kube));
492
+ /**
493
+ * @library Kube Response
494
+ * @author Imperavi LLC
495
+ * @license MIT
496
+ */
497
+ (function(Kube)
498
+ {
499
+ Kube.Response = function(app) {};
500
+
501
+ Kube.Response.prototype = {
502
+ parse: function(str)
503
+ {
504
+ if (str === '') return false;
505
+
506
+ var obj = {};
507
+
508
+ try {
509
+ obj = JSON.parse(str);
510
+ } catch (e) {
511
+ return false;
512
+ }
513
+
514
+ if (obj[0] !== undefined)
515
+ {
516
+ for (var item in obj)
517
+ {
518
+ this.parseItem(obj[item]);
519
+ }
520
+ }
521
+ else
522
+ {
523
+ this.parseItem(obj);
524
+ }
525
+
526
+ return obj;
527
+ },
528
+ parseItem: function(item)
529
+ {
530
+ if (item.type === 'value')
531
+ {
532
+ $.each(item.data, $.proxy(function(key, val)
533
+ {
534
+ val = (val === null || val === false) ? 0 : val;
535
+ val = (val === true) ? 1 : val;
536
+
537
+ $(key).val(val);
538
+
539
+ }, this));
540
+ }
541
+ else if (item.type === 'html')
542
+ {
543
+ $.each(item.data, $.proxy(function(key, val)
544
+ {
545
+ val = (val === null || val === false) ? '' : val;
546
+
547
+ $(key).html(this.stripslashes(val));
548
+
549
+ }, this));
550
+ }
551
+ else if (item.type === 'addClass')
552
+ {
553
+ $.each(item.data, function(key, val)
554
+ {
555
+ $(key).addClass(val);
556
+ });
557
+ }
558
+ else if (item.type === 'removeClass')
559
+ {
560
+ $.each(item.data, function(key, val)
561
+ {
562
+ $(key).removeClass(val);
563
+ });
564
+ }
565
+ else if (item.type === 'command')
566
+ {
567
+ $.each(item.data, function(key, val)
568
+ {
569
+ $(val)[key]();
570
+ });
571
+ }
572
+ else if (item.type === 'animation')
573
+ {
574
+ $.each(item.data, function(key, data)
575
+ {
576
+ data.opts = (typeof data.opts === 'undefined') ? {} : data.opts;
577
+
578
+ $(key).animation(data.name, data.opts);
579
+ });
580
+ }
581
+ else if (item.type === 'location')
582
+ {
583
+ top.location.href = item.data;
584
+ }
585
+ else if (item.type === 'notify')
586
+ {
587
+ $.notify(item.data);
588
+ }
589
+
590
+ return item;
591
+ },
592
+ stripslashes: function(str)
593
+ {
594
+ return (str+'').replace(/\0/g, '0').replace(/\\([\\'"])/g, '$1');
595
+ }
596
+ };
597
+
598
+
599
+ }(Kube));
600
+ /**
601
+ * @library Kube Utils
602
+ * @author Imperavi LLC
603
+ * @license MIT
604
+ */
605
+ (function(Kube)
606
+ {
607
+ Kube.Utils = function() {};
608
+
609
+ Kube.Utils.prototype = {
610
+ disableBodyScroll: function()
611
+ {
612
+ var $body = $('html');
613
+ var windowWidth = window.innerWidth;
614
+
615
+ if (!windowWidth)
616
+ {
617
+ var documentElementRect = document.documentElement.getBoundingClientRect();
618
+ windowWidth = documentElementRect.right - Math.abs(documentElementRect.left);
619
+ }
620
+
621
+ var isOverflowing = document.body.clientWidth < windowWidth;
622
+ var scrollbarWidth = this.measureScrollbar();
623
+
624
+ $body.css('overflow', 'hidden');
625
+ if (isOverflowing) $body.css('padding-right', scrollbarWidth);
626
+ },
627
+ measureScrollbar: function()
628
+ {
629
+ var $body = $('body');
630
+ var scrollDiv = document.createElement('div');
631
+ scrollDiv.className = 'scrollbar-measure';
632
+
633
+ $body.append(scrollDiv);
634
+ var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
635
+ $body[0].removeChild(scrollDiv);
636
+ return scrollbarWidth;
637
+ },
638
+ enableBodyScroll: function()
639
+ {
640
+ $('html').css({ 'overflow': '', 'padding-right': '' });
641
+ }
642
+ };
643
+
644
+
645
+ }(Kube));
646
+ /**
647
+ * @library Kube Message
648
+ * @author Imperavi LLC
649
+ * @license MIT
650
+ */
651
+ (function(Kube)
652
+ {
653
+ Kube.Message = function(element, options)
654
+ {
655
+ this.namespace = 'message';
656
+ this.defaults = {
657
+ closeSelector: '.close',
658
+ closeEvent: 'click',
659
+ animationOpen: 'fadeIn',
660
+ animationClose: 'fadeOut',
661
+ callbacks: ['open', 'opened', 'close', 'closed']
662
+ };
663
+
664
+ // Parent Constructor
665
+ Kube.apply(this, arguments);
666
+
667
+ // Initialization
668
+ this.start();
669
+ };
670
+
671
+ // Functionality
672
+ Kube.Message.prototype = {
673
+ start: function()
674
+ {
675
+ this.$close = this.$element.find(this.opts.closeSelector);
676
+ this.$close.on(this.opts.closeEvent + '.' + this.namespace, $.proxy(this.close, this));
677
+ this.$element.addClass('open');
678
+ },
679
+ stop: function()
680
+ {
681
+ this.$close.off('.' + this.namespace);
682
+ this.$element.removeClass('open');
683
+ },
684
+ open: function(e)
685
+ {
686
+ if (e) e.preventDefault();
687
+
688
+ if (!this.isOpened())
689
+ {
690
+ this.callback('open');
691
+ this.$element.animation(this.opts.animationOpen, $.proxy(this.onOpened, this));
692
+ }
693
+ },
694
+ isOpened: function()
695
+ {
696
+ return this.$element.hasClass('open');
697
+ },
698
+ onOpened: function()
699
+ {
700
+ this.callback('opened');
701
+ this.$element.addClass('open');
702
+ },
703
+ close: function(e)
704
+ {
705
+ if (e) e.preventDefault();
706
+
707
+ if (this.isOpened())
708
+ {
709
+ this.callback('close');
710
+ this.$element.animation(this.opts.animationClose, $.proxy(this.onClosed, this));
711
+ }
712
+ },
713
+ onClosed: function()
714
+ {
715
+ this.callback('closed');
716
+ this.$element.removeClass('open');
717
+ }
718
+ };
719
+
720
+ // Inheritance
721
+ Kube.Message.inherits(Kube);
722
+
723
+ // Plugin
724
+ Kube.Plugin.create('Message');
725
+ Kube.Plugin.autoload('Message');
726
+
727
+ }(Kube));
728
+ /**
729
+ * @library Kube Sticky
730
+ * @author Imperavi LLC
731
+ * @license MIT
732
+ */
733
+ (function(Kube)
734
+ {
735
+ Kube.Sticky = function(element, options)
736
+ {
737
+ this.namespace = 'sticky';
738
+ this.defaults = {
739
+ classname: 'fixed',
740
+ offset: 0, // pixels
741
+ callbacks: ['fixed', 'unfixed']
742
+ };
743
+
744
+ // Parent Constructor
745
+ Kube.apply(this, arguments);
746
+
747
+ // Initialization
748
+ this.start();
749
+ };
750
+
751
+ // Functionality
752
+ Kube.Sticky.prototype = {
753
+ start: function()
754
+ {
755
+ this.offsetTop = this.getOffsetTop();
756
+
757
+ this.load();
758
+ $(window).scroll($.proxy(this.load, this));
759
+ },
760
+ getOffsetTop: function()
761
+ {
762
+ return this.$element.offset().top;
763
+ },
764
+ load: function()
765
+ {
766
+ return (this.isFix()) ? this.fixed() : this.unfixed();
767
+ },
768
+ isFix: function()
769
+ {
770
+ return ($(window).scrollTop() > (this.offsetTop + this.opts.offset));
771
+ },
772
+ fixed: function()
773
+ {
774
+ this.$element.addClass(this.opts.classname).css('top', this.opts.offset + 'px');
775
+ this.callback('fixed');
776
+ },
777
+ unfixed: function()
778
+ {
779
+ this.$element.removeClass(this.opts.classname).css('top', '');
780
+ this.callback('unfixed');
781
+ }
782
+ };
783
+
784
+ // Inheritance
785
+ Kube.Sticky.inherits(Kube);
786
+
787
+ // Plugin
788
+ Kube.Plugin.create('Sticky');
789
+ Kube.Plugin.autoload('Sticky');
790
+
791
+ }(Kube));
792
+ /**
793
+ * @library Kube Toggleme
794
+ * @author Imperavi LLC
795
+ * @license MIT
796
+ */
797
+ (function(Kube)
798
+ {
799
+ Kube.Toggleme = function(element, options)
800
+ {
801
+ this.namespace = 'toggleme';
802
+ this.defaults = {
803
+ toggleEvent: 'click',
804
+ target: null,
805
+ text: '',
806
+ animationOpen: 'slideDown',
807
+ animationClose: 'slideUp',
808
+ callbacks: ['open', 'opened', 'close', 'closed']
809
+ };
810
+
811
+ // Parent Constructor
812
+ Kube.apply(this, arguments);
813
+
814
+ // Initialization
815
+ this.start();
816
+ };
817
+
818
+ // Functionality
819
+ Kube.Toggleme.prototype = {
820
+ start: function()
821
+ {
822
+ if (!this.hasTarget()) return;
823
+
824
+ this.$element.on(this.opts.toggleEvent + '.' + this.namespace, $.proxy(this.toggle, this));
825
+ },
826
+ stop: function()
827
+ {
828
+ this.$element.off('.' + this.namespace);
829
+ this.revertText();
830
+ },
831
+ toggle: function(e)
832
+ {
833
+ if (this.isOpened()) this.close(e);
834
+ else this.open(e);
835
+ },
836
+ open: function(e)
837
+ {
838
+ if (e) e.preventDefault();
839
+
840
+ if (!this.isOpened())
841
+ {
842
+ this.storeText();
843
+ this.callback('open');
844
+ this.$target.animation('slideDown', $.proxy(this.onOpened, this));
845
+
846
+ // changes the text of $element with a less delay to smooth
847
+ setTimeout($.proxy(this.replaceText, this), 100);
848
+ }
849
+ },
850
+ close: function(e)
851
+ {
852
+ if (e) e.preventDefault();
853
+
854
+ if (this.isOpened())
855
+ {
856
+ this.callback('close');
857
+ this.$target.animation('slideUp', $.proxy(this.onClosed, this));
858
+ }
859
+ },
860
+ isOpened: function()
861
+ {
862
+ return (this.$target.hasClass('open'));
863
+ },
864
+ onOpened: function()
865
+ {
866
+ this.$target.addClass('open');
867
+ this.callback('opened');
868
+ },
869
+ onClosed: function()
870
+ {
871
+ this.$target.removeClass('open');
872
+ this.revertText();
873
+ this.callback('closed');
874
+ },
875
+ storeText: function()
876
+ {
877
+ this.$element.data('replacement-text', this.$element.html());
878
+ },
879
+ revertText: function()
880
+ {
881
+ var text = this.$element.data('replacement-text');
882
+ if (text) this.$element.html(text);
883
+
884
+ this.$element.removeData('replacement-text');
885
+ },
886
+ replaceText: function()
887
+ {
888
+ if (this.opts.text !== '')
889
+ {
890
+ this.$element.html(this.opts.text);
891
+ }
892
+ }
893
+ };
894
+
895
+ // Inheritance
896
+ Kube.Toggleme.inherits(Kube);
897
+
898
+ // Plugin
899
+ Kube.Plugin.create('Toggleme');
900
+ Kube.Plugin.autoload('Toggleme');
901
+
902
+ }(Kube));
903
+ /**
904
+ * @library Kube Offcanvas
905
+ * @author Imperavi LLC
906
+ * @license MIT
907
+ */
908
+ (function(Kube)
909
+ {
910
+ Kube.Offcanvas = function(element, options)
911
+ {
912
+ this.namespace = 'offcanvas';
913
+ this.defaults = {
914
+ target: null, // selector
915
+ push: true, // boolean
916
+ width: '250px', // string
917
+ direction: 'left', // string: left or right
918
+ toggleEvent: 'click',
919
+ clickOutside: true, // boolean
920
+ animationOpen: 'slideInLeft',
921
+ animationClose: 'slideOutLeft',
922
+ callbacks: ['open', 'opened', 'close', 'closed']
923
+ };
924
+
925
+ // Parent Constructor
926
+ Kube.apply(this, arguments);
927
+
928
+ // Services
929
+ this.utils = new Kube.Utils();
930
+ this.detect = new Kube.Detect();
931
+
932
+ // Initialization
933
+ this.start();
934
+ };
935
+
936
+ // Functionality
937
+ Kube.Offcanvas.prototype = {
938
+ start: function()
939
+ {
940
+ if (!this.hasTarget()) return;
941
+
942
+ this.buildTargetWidth();
943
+ this.buildAnimationDirection();
944
+
945
+ this.$close = this.getCloseLink();
946
+ this.$element.on(this.opts.toggleEvent + '.' + this.namespace, $.proxy(this.toggle, this));
947
+ this.$target.addClass('offcanvas');
948
+ },
949
+ stop: function()
950
+ {
951
+ this.closeAll();
952
+
953
+ this.$element.off('.' + this.namespace);
954
+ this.$close.off('.' + this.namespace);
955
+ $(document).off('.' + this.namespace);
956
+ },
957
+ toggle: function(e)
958
+ {
959
+ if (this.isOpened()) this.close(e);
960
+ else this.open(e);
961
+ },
962
+ buildTargetWidth: function()
963
+ {
964
+ this.opts.width = ($(window).width() < parseInt(this.opts.width)) ? '100%' : this.opts.width;
965
+ },
966
+ buildAnimationDirection: function()
967
+ {
968
+ if (this.opts.direction === 'right')
969
+ {
970
+ this.opts.animationOpen = 'slideInRight';
971
+ this.opts.animationClose = 'slideOutRight';
972
+ }
973
+ },
974
+ getCloseLink: function()
975
+ {
976
+ return this.$target.find('.close');
977
+ },
978
+ open: function(e)
979
+ {
980
+ if (e) e.preventDefault();
981
+
982
+ if (!this.isOpened())
983
+ {
984
+ this.closeAll();
985
+ this.callback('open');
986
+
987
+ this.$target.addClass('offcanvas-' + this.opts.direction);
988
+ this.$target.css('width', this.opts.width);
989
+
990
+ this.pushBody();
991
+
992
+ this.$target.animation(this.opts.animationOpen, $.proxy(this.onOpened, this));
993
+ }
994
+ },
995
+ closeAll: function()
996
+ {
997
+ var $elms = $(document).find('.offcanvas');
998
+ if ($elms.length !== 0)
999
+ {
1000
+ $elms.each(function()
1001
+ {
1002
+ var $el = $(this);
1003
+
1004
+ if ($el.hasClass('open'))
1005
+ {
1006
+ $el.css('width', '').animation('hide');
1007
+ $el.removeClass('open offcanvas-left offcanvas-right');
1008
+ }
1009
+
1010
+ });
1011
+
1012
+ $(document).off('.' + this.namespace);
1013
+ $('body').css('left', '');
1014
+ }
1015
+ },
1016
+ close: function(e)
1017
+ {
1018
+ if (e)
1019
+ {
1020
+ var $el = $(e.target);
1021
+ var isTag = ($el[0].tagName === 'A' || $el[0].tagName === 'BUTTON');
1022
+ if (isTag && $el.closest('.offcanvas').length !== 0 && !$el.hasClass('close'))
1023
+ {
1024
+ return;
1025
+ }
1026
+
1027
+ e.preventDefault();
1028
+ }
1029
+
1030
+ if (this.isOpened())
1031
+ {
1032
+ this.utils.enableBodyScroll();
1033
+ this.callback('close');
1034
+ this.pullBody();
1035
+ this.$target.animation(this.opts.animationClose, $.proxy(this.onClosed, this));
1036
+ }
1037
+ },
1038
+ isOpened: function()
1039
+ {
1040
+ return (this.$target.hasClass('open'));
1041
+ },
1042
+ onOpened: function()
1043
+ {
1044
+ if (this.opts.clickOutside) $(document).on('click.' + this.namespace, $.proxy(this.close, this));
1045
+ if (this.detect.isMobileScreen()) $('html').addClass('no-scroll');
1046
+
1047
+ $(document).on('keyup.' + this.namespace, $.proxy(this.handleKeyboard, this));
1048
+ this.$close.on('click.' + this.namespace, $.proxy(this.close, this));
1049
+
1050
+ this.utils.disableBodyScroll();
1051
+ this.$target.addClass('open');
1052
+ this.callback('opened');
1053
+ },
1054
+ onClosed: function()
1055
+ {
1056
+ if (this.detect.isMobileScreen()) $('html').removeClass('no-scroll');
1057
+
1058
+ this.$target.css('width', '').removeClass('offcanvas-' + this.opts.direction);
1059
+
1060
+ this.$close.off('.' + this.namespace);
1061
+ $(document).off('.' + this.namespace);
1062
+
1063
+ this.$target.removeClass('open');
1064
+ this.callback('closed');
1065
+ },
1066
+ handleKeyboard: function(e)
1067
+ {
1068
+ if (e.which === 27) this.close();
1069
+ },
1070
+ pullBody: function()
1071
+ {
1072
+ if (this.opts.push)
1073
+ {
1074
+ $('body').animate({ left: 0 }, 350, function() { $(this).removeClass('offcanvas-push-body'); });
1075
+ }
1076
+ },
1077
+ pushBody: function()
1078
+ {
1079
+ if (this.opts.push)
1080
+ {
1081
+ var properties = (this.opts.direction === 'left') ? { 'left': this.opts.width } : { 'left': '-' + this.opts.width };
1082
+ $('body').addClass('offcanvas-push-body').animate(properties, 200);
1083
+ }
1084
+ }
1085
+ };
1086
+
1087
+ // Inheritance
1088
+ Kube.Offcanvas.inherits(Kube);
1089
+
1090
+ // Plugin
1091
+ Kube.Plugin.create('Offcanvas');
1092
+ Kube.Plugin.autoload('Offcanvas');
1093
+
1094
+ }(Kube));
1095
+ /**
1096
+ * @library Kube Collapse
1097
+ * @author Imperavi LLC
1098
+ * @license MIT
1099
+ */
1100
+ (function(Kube)
1101
+ {
1102
+ Kube.Collapse = function(element, options)
1103
+ {
1104
+ this.namespace = 'collapse';
1105
+ this.defaults = {
1106
+ target: null,
1107
+ toggle: true,
1108
+ active: false, // string (hash = tab id selector)
1109
+ toggleClass: 'collapse-toggle',
1110
+ boxClass: 'collapse-box',
1111
+ callbacks: ['open', 'opened', 'close', 'closed'],
1112
+
1113
+ // private
1114
+ hashes: [],
1115
+ currentHash: false,
1116
+ currentItem: false
1117
+ };
1118
+
1119
+ // Parent Constructor
1120
+ Kube.apply(this, arguments);
1121
+
1122
+ // Initialization
1123
+ this.start();
1124
+ };
1125
+
1126
+ // Functionality
1127
+ Kube.Collapse.prototype = {
1128
+ start: function()
1129
+ {
1130
+ // items
1131
+ this.$items = this.getItems();
1132
+ this.$items.each($.proxy(this.loadItems, this));
1133
+
1134
+ // boxes
1135
+ this.$boxes = this.getBoxes();
1136
+
1137
+ // active
1138
+ this.setActiveItem();
1139
+ },
1140
+ getItems: function()
1141
+ {
1142
+ return this.$element.find('.' + this.opts.toggleClass);
1143
+ },
1144
+ getBoxes: function()
1145
+ {
1146
+ return this.$element.find('.' + this.opts.boxClass);
1147
+ },
1148
+ loadItems: function(i, el)
1149
+ {
1150
+ var item = this.getItem(el);
1151
+
1152
+ // set item identificator
1153
+ item.$el.attr('rel', item.hash);
1154
+
1155
+ // active
1156
+ if (!$(item.hash).hasClass('hide'))
1157
+ {
1158
+ this.opts.currentItem = item;
1159
+ this.opts.active = item.hash;
1160
+
1161
+ item.$el.addClass('active');
1162
+ }
1163
+
1164
+ // event
1165
+ item.$el.on('click.collapse', $.proxy(this.toggle, this));
1166
+
1167
+ },
1168
+ setActiveItem: function()
1169
+ {
1170
+ if (this.opts.active !== false)
1171
+ {
1172
+ this.opts.currentItem = this.getItemBy(this.opts.active);
1173
+ this.opts.active = this.opts.currentItem.hash;
1174
+ }
1175
+
1176
+ if (this.opts.currentItem !== false)
1177
+ {
1178
+ this.addActive(this.opts.currentItem);
1179
+ this.opts.currentItem.$box.removeClass('hide');
1180
+ }
1181
+ },
1182
+ addActive: function(item)
1183
+ {
1184
+ item.$box.removeClass('hide').addClass('open');
1185
+ item.$el.addClass('active');
1186
+
1187
+ if (item.$caret !== false) item.$caret.removeClass('down').addClass('up');
1188
+ if (item.$parent !== false) item.$parent.addClass('active');
1189
+
1190
+ this.opts.currentItem = item;
1191
+ },
1192
+ removeActive: function(item)
1193
+ {
1194
+ item.$box.removeClass('open');
1195
+ item.$el.removeClass('active');
1196
+
1197
+ if (item.$caret !== false) item.$caret.addClass('down').removeClass('up');
1198
+ if (item.$parent !== false) item.$parent.removeClass('active');
1199
+
1200
+ this.opts.currentItem = false;
1201
+ },
1202
+ toggle: function(e)
1203
+ {
1204
+ if (e) e.preventDefault();
1205
+
1206
+ var target = $(e.target).closest('.' + this.opts.toggleClass).get(0) || e.target;
1207
+ var item = this.getItem(target);
1208
+
1209
+ if (this.isOpened(item.hash)) this.close(item.hash);
1210
+ else this.open(e)
1211
+ },
1212
+ openAll: function()
1213
+ {
1214
+ this.$items.addClass('active');
1215
+ this.$boxes.addClass('open').removeClass('hide');
1216
+ },
1217
+ open: function(e, push)
1218
+ {
1219
+ if (typeof e === 'undefined') return;
1220
+ if (typeof e === 'object') e.preventDefault();
1221
+
1222
+ var target = $(e.target).closest('.' + this.opts.toggleClass).get(0) || e.target;
1223
+ var item = (typeof e === 'object') ? this.getItem(target) : this.getItemBy(e);
1224
+
1225
+ if (item.$box.hasClass('open'))
1226
+ {
1227
+ return;
1228
+ }
1229
+
1230
+ if (this.opts.toggle) this.closeAll();
1231
+
1232
+ this.callback('open', item);
1233
+ this.addActive(item);
1234
+
1235
+ item.$box.animation('slideDown', $.proxy(this.onOpened, this));
1236
+ },
1237
+ onOpened: function()
1238
+ {
1239
+ this.callback('opened', this.opts.currentItem);
1240
+ },
1241
+ closeAll: function()
1242
+ {
1243
+ this.$items.removeClass('active').closest('li').removeClass('active');
1244
+ this.$boxes.removeClass('open').addClass('hide');
1245
+ },
1246
+ close: function(num)
1247
+ {
1248
+ var item = this.getItemBy(num);
1249
+
1250
+ this.callback('close', item);
1251
+
1252
+ this.opts.currentItem = item;
1253
+
1254
+ item.$box.animation('slideUp', $.proxy(this.onClosed, this));
1255
+ },
1256
+ onClosed: function()
1257
+ {
1258
+ var item = this.opts.currentItem;
1259
+
1260
+ this.removeActive(item);
1261
+ this.callback('closed', item);
1262
+ },
1263
+ isOpened: function(hash)
1264
+ {
1265
+ return $(hash).hasClass('open');
1266
+ },
1267
+ getItem: function(element)
1268
+ {
1269
+ var item = {};
1270
+
1271
+ item.$el = $(element);
1272
+ item.hash = item.$el.attr('href');
1273
+ item.$box = $(item.hash);
1274
+
1275
+ var $parent = item.$el.parent();
1276
+ item.$parent = ($parent[0].tagName === 'LI') ? $parent : false;
1277
+
1278
+ var $caret = item.$el.find('.caret');
1279
+ item.$caret = ($caret.length !== 0) ? $caret : false;
1280
+
1281
+ return item;
1282
+ },
1283
+ getItemBy: function(num)
1284
+ {
1285
+ var element = (typeof num === 'number') ? this.$items.eq(num-1) : this.$element.find('[rel="' + num + '"]');
1286
+
1287
+ return this.getItem(element);
1288
+ }
1289
+ };
1290
+
1291
+ // Inheritance
1292
+ Kube.Collapse.inherits(Kube);
1293
+
1294
+ // Plugin
1295
+ Kube.Plugin.create('Collapse');
1296
+ Kube.Plugin.autoload('Collapse');
1297
+
1298
+ }(Kube));
1299
+ /**
1300
+ * @library Kube Dropdown
1301
+ * @author Imperavi LLC
1302
+ * @license MIT
1303
+ */
1304
+ (function(Kube)
1305
+ {
1306
+ Kube.Dropdown = function(element, options)
1307
+ {
1308
+ this.namespace = 'dropdown';
1309
+ this.defaults = {
1310
+ target: null,
1311
+ toggleEvent: 'click',
1312
+ height: false, // integer
1313
+ width: false, // integer
1314
+ animationOpen: 'slideDown',
1315
+ animationClose: 'slideUp',
1316
+ caretUp: false,
1317
+ callbacks: ['open', 'opened', 'close', 'closed']
1318
+ };
1319
+
1320
+ // Parent Constructor
1321
+ Kube.apply(this, arguments);
1322
+
1323
+ // Services
1324
+ this.utils = new Kube.Utils();
1325
+ this.detect = new Kube.Detect();
1326
+
1327
+ // Initialization
1328
+ this.start();
1329
+ };
1330
+
1331
+ // Functionality
1332
+ Kube.Dropdown.prototype = {
1333
+ start: function()
1334
+ {
1335
+ this.buildClose();
1336
+ this.buildCaret();
1337
+
1338
+ if (this.detect.isMobile()) this.buildMobileAnimation();
1339
+
1340
+ this.$target.addClass('hide');
1341
+ this.$element.on(this.opts.toggleEvent + '.' + this.namespace, $.proxy(this.toggle, this));
1342
+
1343
+ },
1344
+ stop: function()
1345
+ {
1346
+ this.$element.off('.' + this.namespace);
1347
+ this.$target.removeClass('open').addClass('hide');
1348
+ this.disableEvents();
1349
+ },
1350
+ buildMobileAnimation: function()
1351
+ {
1352
+ this.opts.animationOpen = 'fadeIn';
1353
+ this.opts.animationClose = 'fadeOut';
1354
+ },
1355
+ buildClose: function()
1356
+ {
1357
+ this.$close = this.$target.find('.close');
1358
+ },
1359
+ buildCaret: function()
1360
+ {
1361
+ this.$caret = this.getCaret();
1362
+ this.buildCaretPosition();
1363
+ },
1364
+ buildCaretPosition: function()
1365
+ {
1366
+ var height = this.$element.offset().top + this.$element.innerHeight() + this.$target.innerHeight();
1367
+
1368
+ if ($(document).height() > height)
1369
+ {
1370
+ return;
1371
+ }
1372
+
1373
+ this.opts.caretUp = true;
1374
+ this.$caret.addClass('up');
1375
+ },
1376
+ getCaret: function()
1377
+ {
1378
+ return this.$element.find('.caret');
1379
+ },
1380
+ toggleCaretOpen: function()
1381
+ {
1382
+ if (this.opts.caretUp) this.$caret.removeClass('up').addClass('down');
1383
+ else this.$caret.removeClass('down').addClass('up');
1384
+ },
1385
+ toggleCaretClose: function()
1386
+ {
1387
+ if (this.opts.caretUp) this.$caret.removeClass('down').addClass('up');
1388
+ else this.$caret.removeClass('up').addClass('down');
1389
+ },
1390
+ toggle: function(e)
1391
+ {
1392
+ if (this.isOpened()) this.close(e);
1393
+ else this.open(e);
1394
+ },
1395
+ open: function(e)
1396
+ {
1397
+ if (e) e.preventDefault();
1398
+
1399
+ this.callback('open');
1400
+ $('.dropdown').removeClass('open').addClass('hide');
1401
+
1402
+ if (this.opts.height) this.$target.css('min-height', this.opts.height + 'px');
1403
+ if (this.opts.width) this.$target.width(this.opts.width);
1404
+
1405
+ this.setPosition();
1406
+ this.toggleCaretOpen();
1407
+
1408
+ this.$target.animation(this.opts.animationOpen, $.proxy(this.onOpened, this));
1409
+ },
1410
+ close: function(e)
1411
+ {
1412
+ if (!this.isOpened())
1413
+ {
1414
+ return;
1415
+ }
1416
+
1417
+ if (e)
1418
+ {
1419
+ if (this.shouldNotBeClosed(e.target))
1420
+ {
1421
+ return;
1422
+ }
1423
+
1424
+ e.preventDefault();
1425
+ }
1426
+
1427
+ this.utils.enableBodyScroll();
1428
+ this.callback('close');
1429
+ this.toggleCaretClose();
1430
+
1431
+ this.$target.animation(this.opts.animationClose, $.proxy(this.onClosed, this));
1432
+ },
1433
+ onClosed: function()
1434
+ {
1435
+ this.$target.removeClass('open');
1436
+ this.disableEvents();
1437
+ this.callback('closed');
1438
+ },
1439
+ onOpened: function()
1440
+ {
1441
+ this.$target.addClass('open');
1442
+ this.enableEvents();
1443
+ this.callback('opened');
1444
+ },
1445
+ isOpened: function()
1446
+ {
1447
+ return (this.$target.hasClass('open'));
1448
+ },
1449
+ enableEvents: function()
1450
+ {
1451
+ if (this.detect.isDesktop())
1452
+ {
1453
+ this.$target.on('mouseover.' + this.namespace, $.proxy(this.utils.disableBodyScroll, this.utils))
1454
+ .on('mouseout.' + this.namespace, $.proxy(this.utils.enableBodyScroll, this.utils));
1455
+ }
1456
+
1457
+ $(document).on('scroll.' + this.namespace, $.proxy(this.setPosition, this));
1458
+ $(window).on('resize.' + this.namespace, $.proxy(this.setPosition, this));
1459
+ $(document).on('click.' + this.namespace + ' touchstart.' + this.namespace, $.proxy(this.close, this));
1460
+ $(document).on('keydown.' + this.namespace, $.proxy(this.handleKeyboard, this));
1461
+ this.$target.find('[data-action="dropdown-close"]').on('click.' + this.namespace, $.proxy(this.close, this));
1462
+ },
1463
+ disableEvents: function()
1464
+ {
1465
+ this.$target.off('.' + this.namespace);
1466
+ $(document).off('.' + this.namespace);
1467
+ $(window).off('.' + this.namespace);
1468
+ },
1469
+ handleKeyboard: function(e)
1470
+ {
1471
+ if (e.which === 27) this.close(e);
1472
+ },
1473
+ shouldNotBeClosed: function(el)
1474
+ {
1475
+ if ($(el).attr('data-action') === 'dropdown-close' || el === this.$close[0])
1476
+ {
1477
+ return false;
1478
+ }
1479
+ else if ($(el).closest('.dropdown').length === 0)
1480
+ {
1481
+ return false;
1482
+ }
1483
+
1484
+ return true;
1485
+ },
1486
+ isNavigationFixed: function()
1487
+ {
1488
+ return (this.$element.closest('.fixed').length !== 0);
1489
+ },
1490
+ getPlacement: function(height)
1491
+ {
1492
+ return ($(document).height() < height) ? 'top' : 'bottom';
1493
+ },
1494
+ getOffset: function(position)
1495
+ {
1496
+ return (this.isNavigationFixed()) ? this.$element.position() : this.$element.offset();
1497
+ },
1498
+ getPosition: function()
1499
+ {
1500
+ return (this.isNavigationFixed()) ? 'fixed' : 'absolute';
1501
+ },
1502
+ setPosition: function()
1503
+ {
1504
+ if (this.detect.isMobile())
1505
+ {
1506
+ this.$target.addClass('dropdown-mobile');
1507
+ return;
1508
+ }
1509
+
1510
+ var position = this.getPosition();
1511
+ var coords = this.getOffset(position);
1512
+ var height = this.$target.innerHeight();
1513
+ var width = this.$target.innerWidth();
1514
+ var placement = this.getPlacement(coords.top + height + this.$element.innerHeight());
1515
+ var leftFix = ($(window).width() < (coords.left + width)) ? (width - this.$element.innerWidth()) : 0;
1516
+ var top, left = coords.left - leftFix;
1517
+
1518
+ if (placement === 'bottom')
1519
+ {
1520
+ if (!this.isOpened()) this.$caret.removeClass('up').addClass('down');
1521
+
1522
+ this.opts.caretUp = false;
1523
+ top = coords.top + this.$element.outerHeight() + 1;
1524
+ }
1525
+ else
1526
+ {
1527
+ this.opts.animationOpen = 'show';
1528
+ this.opts.animationClose = 'hide';
1529
+
1530
+ if (!this.isOpened()) this.$caret.addClass('up').removeClass('down');
1531
+
1532
+ this.opts.caretUp = true;
1533
+ top = coords.top - height - 1;
1534
+ }
1535
+
1536
+ this.$target.css({ position: position, top: top + 'px', left: left + 'px' });
1537
+ }
1538
+ };
1539
+
1540
+ // Inheritance
1541
+ Kube.Dropdown.inherits(Kube);
1542
+
1543
+ // Plugin
1544
+ Kube.Plugin.create('Dropdown');
1545
+ Kube.Plugin.autoload('Dropdown');
1546
+
1547
+ }(Kube));
1548
+ /**
1549
+ * @library Kube Tabs
1550
+ * @author Imperavi LLC
1551
+ * @license MIT
1552
+ */
1553
+ (function(Kube)
1554
+ {
1555
+ Kube.Tabs = function(element, options)
1556
+ {
1557
+ this.namespace = 'tabs';
1558
+ this.defaults = {
1559
+ equals: false,
1560
+ active: false, // string (hash = tab id selector)
1561
+ live: false, // class selector
1562
+ hash: true, //boolean
1563
+ callbacks: ['init', 'next', 'prev', 'open', 'opened', 'close', 'closed']
1564
+ };
1565
+
1566
+ // Parent Constructor
1567
+ Kube.apply(this, arguments);
1568
+
1569
+ // Initialization
1570
+ this.start();
1571
+ };
1572
+
1573
+ // Functionality
1574
+ Kube.Tabs.prototype = {
1575
+ start: function()
1576
+ {
1577
+ if (this.opts.live !== false) this.buildLiveTabs();
1578
+
1579
+ this.tabsCollection = [];
1580
+ this.hashesCollection = [];
1581
+ this.currentHash = [];
1582
+ this.currentItem = false;
1583
+
1584
+ // items
1585
+ this.$items = this.getItems();
1586
+ this.$items.each($.proxy(this.loadItems, this));
1587
+
1588
+ // tabs
1589
+ this.$tabs = this.getTabs();
1590
+
1591
+ // location hash
1592
+ this.currentHash = this.getLocationHash();
1593
+
1594
+ // close all
1595
+ this.closeAll();
1596
+
1597
+ // active & height
1598
+ this.setActiveItem();
1599
+ this.setItemHeight();
1600
+
1601
+ // callback
1602
+ this.callback('init');
1603
+
1604
+ },
1605
+ getTabs: function()
1606
+ {
1607
+ return $(this.tabsCollection).map(function()
1608
+ {
1609
+ return this.toArray();
1610
+ });
1611
+ },
1612
+ getItems: function()
1613
+ {
1614
+ return this.$element.find('a');
1615
+ },
1616
+ loadItems: function(i, el)
1617
+ {
1618
+ var item = this.getItem(el);
1619
+
1620
+ // set item identificator
1621
+ item.$el.attr('rel', item.hash);
1622
+
1623
+ // collect item
1624
+ this.collectItem(item);
1625
+
1626
+ // active
1627
+ if (item.$parent.hasClass('active'))
1628
+ {
1629
+ this.currentItem = item;
1630
+ this.opts.active = item.hash;
1631
+ }
1632
+
1633
+ // event
1634
+ item.$el.on('click.tabs', $.proxy(this.open, this));
1635
+
1636
+ },
1637
+ collectItem: function(item)
1638
+ {
1639
+ this.tabsCollection.push(item.$tab);
1640
+ this.hashesCollection.push(item.hash);
1641
+ },
1642
+ buildLiveTabs: function()
1643
+ {
1644
+ var $layers = $(this.opts.live);
1645
+
1646
+ if ($layers.length === 0)
1647
+ {
1648
+ return;
1649
+ }
1650
+
1651
+ this.$liveTabsList = $('<ul />');
1652
+ $layers.each($.proxy(this.buildLiveItem, this));
1653
+
1654
+ this.$element.html('').append(this.$liveTabsList);
1655
+
1656
+ },
1657
+ buildLiveItem: function(i, tab)
1658
+ {
1659
+ var $tab = $(tab);
1660
+ var $li = $('<li />');
1661
+ var $a = $('<a />');
1662
+ var index = i + 1;
1663
+
1664
+ $tab.attr('id', this.getLiveItemId($tab, index));
1665
+
1666
+ var hash = '#' + $tab.attr('id');
1667
+ var title = this.getLiveItemTitle($tab);
1668
+
1669
+ $a.attr('href', hash).attr('rel', hash).text(title);
1670
+ $li.append($a);
1671
+
1672
+ this.$liveTabsList.append($li);
1673
+ },
1674
+ getLiveItemId: function($tab, index)
1675
+ {
1676
+ return (typeof $tab.attr('id') === 'undefined') ? this.opts.live.replace('.', '') + index : $tab.attr('id');
1677
+ },
1678
+ getLiveItemTitle: function($tab)
1679
+ {
1680
+ return (typeof $tab.attr('data-title') === 'undefined') ? $tab.attr('id') : $tab.attr('data-title');
1681
+ },
1682
+ setActiveItem: function()
1683
+ {
1684
+ if (this.currentHash)
1685
+ {
1686
+ this.currentItem = this.getItemBy(this.currentHash);
1687
+ this.opts.active = this.currentHash;
1688
+ }
1689
+ else if (this.opts.active === false)
1690
+ {
1691
+ this.currentItem = this.getItem(this.$items.first());
1692
+ this.opts.active = this.currentItem.hash;
1693
+ }
1694
+
1695
+ this.addActive(this.currentItem);
1696
+ },
1697
+ addActive: function(item)
1698
+ {
1699
+ item.$parent.addClass('active');
1700
+ item.$tab.removeClass('hide').addClass('open');
1701
+
1702
+ this.currentItem = item;
1703
+ },
1704
+ removeActive: function(item)
1705
+ {
1706
+ item.$parent.removeClass('active');
1707
+ item.$tab.addClass('hide').removeClass('open');
1708
+
1709
+ this.currentItem = false;
1710
+ },
1711
+ next: function(e)
1712
+ {
1713
+ if (e) e.preventDefault();
1714
+
1715
+ var item = this.getItem(this.fetchElement('next'));
1716
+
1717
+ this.open(item.hash);
1718
+ this.callback('next', item);
1719
+
1720
+ },
1721
+ prev: function(e)
1722
+ {
1723
+ if (e) e.preventDefault();
1724
+
1725
+ var item = this.getItem(this.fetchElement('prev'));
1726
+
1727
+ this.open(item.hash);
1728
+ this.callback('prev', item);
1729
+ },
1730
+ fetchElement: function(type)
1731
+ {
1732
+ var element;
1733
+ if (this.currentItem !== false)
1734
+ {
1735
+ // prev or next
1736
+ element = this.currentItem.$parent[type]().find('a');
1737
+
1738
+ if (element.length === 0)
1739
+ {
1740
+ return;
1741
+ }
1742
+ }
1743
+ else
1744
+ {
1745
+ // first
1746
+ element = this.$items[0];
1747
+ }
1748
+
1749
+ return element;
1750
+ },
1751
+ open: function(e, push)
1752
+ {
1753
+ if (typeof e === 'undefined') return;
1754
+ if (typeof e === 'object') e.preventDefault();
1755
+
1756
+ var item = (typeof e === 'object') ? this.getItem(e.target) : this.getItemBy(e);
1757
+ this.closeAll();
1758
+
1759
+ this.callback('open', item);
1760
+ this.addActive(item);
1761
+
1762
+ // push state (doesn't need to push at the start)
1763
+ this.pushStateOpen(push, item);
1764
+ this.callback('opened', item);
1765
+ },
1766
+ pushStateOpen: function(push, item)
1767
+ {
1768
+ if (push !== false && this.opts.hash !== false)
1769
+ {
1770
+ history.pushState(false, false, item.hash);
1771
+ }
1772
+ },
1773
+ close: function(num)
1774
+ {
1775
+ var item = this.getItemBy(num);
1776
+
1777
+ if (!item.$parent.hasClass('active'))
1778
+ {
1779
+ return;
1780
+ }
1781
+
1782
+ this.callback('close', item);
1783
+ this.removeActive(item);
1784
+ this.pushStateClose();
1785
+ this.callback('closed', item);
1786
+
1787
+ },
1788
+ pushStateClose: function()
1789
+ {
1790
+ if (this.opts.hash !== false)
1791
+ {
1792
+ history.pushState(false, false, ' ');
1793
+ }
1794
+ },
1795
+ closeAll: function()
1796
+ {
1797
+ this.$tabs.removeClass('open').addClass('hide');
1798
+ this.$items.parent().removeClass('active');
1799
+ },
1800
+ getItem: function(element)
1801
+ {
1802
+ var item = {};
1803
+
1804
+ item.$el = $(element);
1805
+ item.hash = item.$el.attr('href');
1806
+ item.$parent = item.$el.parent();
1807
+ item.$tab = $(item.hash);
1808
+
1809
+ return item;
1810
+ },
1811
+ getItemBy: function(num)
1812
+ {
1813
+ var element = (typeof num === 'number') ? this.$items.eq(num-1) : this.$element.find('[rel="' + num + '"]');
1814
+
1815
+ return this.getItem(element);
1816
+ },
1817
+ getLocationHash: function()
1818
+ {
1819
+ if (this.opts.hash === false)
1820
+ {
1821
+ return false;
1822
+ }
1823
+
1824
+ return (this.isHash()) ? top.location.hash : false;
1825
+ },
1826
+ isHash: function()
1827
+ {
1828
+ return !(top.location.hash === '' || $.inArray(top.location.hash, this.hashesCollection) === -1);
1829
+ },
1830
+ setItemHeight: function()
1831
+ {
1832
+ if (this.opts.equals)
1833
+ {
1834
+ var minHeight = this.getItemMaxHeight() + 'px';
1835
+ this.$tabs.css('min-height', minHeight);
1836
+ }
1837
+ },
1838
+ getItemMaxHeight: function()
1839
+ {
1840
+ var max = 0;
1841
+ this.$tabs.each(function()
1842
+ {
1843
+ var h = $(this).height();
1844
+ max = h > max ? h : max;
1845
+ });
1846
+
1847
+ return max;
1848
+ }
1849
+ };
1850
+
1851
+ // Inheritance
1852
+ Kube.Tabs.inherits(Kube);
1853
+
1854
+ // Plugin
1855
+ Kube.Plugin.create('Tabs');
1856
+ Kube.Plugin.autoload('Tabs');
1857
+
1858
+ }(Kube));
1859
+ /**
1860
+ * @library Kube Modal
1861
+ * @author Imperavi LLC
1862
+ * @license MIT
1863
+ */
1864
+ (function($)
1865
+ {
1866
+ $.modalcurrent = null;
1867
+ $.modalwindow = function(options)
1868
+ {
1869
+ var opts = $.extend({}, options, { show: true });
1870
+ var $element = $('<span />');
1871
+
1872
+ $element.modal(opts);
1873
+ };
1874
+
1875
+ })(jQuery);
1876
+
1877
+ (function(Kube)
1878
+ {
1879
+ Kube.Modal = function(element, options)
1880
+ {
1881
+ this.namespace = 'modal';
1882
+ this.defaults = {
1883
+ target: null,
1884
+ show: false,
1885
+ url: false,
1886
+ header: false,
1887
+ width: '600px', // string
1888
+ height: false, // or string
1889
+ maxHeight: false,
1890
+ position: 'center', // top or center
1891
+ overlay: true,
1892
+ appendForms: false,
1893
+ appendFields: false,
1894
+ animationOpen: 'show',
1895
+ animationClose: 'hide',
1896
+ callbacks: ['open', 'opened', 'close', 'closed']
1897
+ };
1898
+
1899
+ // Parent Constructor
1900
+ Kube.apply(this, arguments);
1901
+
1902
+ // Services
1903
+ this.utils = new Kube.Utils();
1904
+ this.detect = new Kube.Detect();
1905
+
1906
+ // Initialization
1907
+ this.start();
1908
+ };
1909
+
1910
+ // Functionality
1911
+ Kube.Modal.prototype = {
1912
+ start: function()
1913
+ {
1914
+ if (!this.hasTarget())
1915
+ {
1916
+ return;
1917
+ }
1918
+
1919
+ if (this.opts.show) this.load();
1920
+ else this.$element.on('click.' + this.namespace, $.proxy(this.load, this));
1921
+ },
1922
+ buildModal: function()
1923
+ {
1924
+ this.$modal = this.$target.find('.modal');
1925
+ this.$header = this.$target.find('.modal-header');
1926
+ this.$close = this.$target.find('.close');
1927
+ this.$body = this.$target.find('.modal-body');
1928
+ },
1929
+ buildOverlay: function()
1930
+ {
1931
+ if (this.opts.overlay === false)
1932
+ {
1933
+ return;
1934
+ }
1935
+
1936
+ if ($('#modal-overlay').length !== 0)
1937
+ {
1938
+ this.$overlay = $('#modal-overlay');
1939
+ }
1940
+ else
1941
+ {
1942
+ this.$overlay = $('<div id="modal-overlay">').addClass('hide');
1943
+ $('body').prepend(this.$overlay);
1944
+ }
1945
+
1946
+ this.$overlay.addClass('overlay');
1947
+ },
1948
+ buildHeader: function()
1949
+ {
1950
+ if (this.opts.header) this.$header.html(this.opts.header);
1951
+ },
1952
+ load: function(e)
1953
+ {
1954
+ this.buildModal();
1955
+ this.buildOverlay();
1956
+ this.buildHeader();
1957
+
1958
+ if (this.opts.url) this.buildContent();
1959
+ else this.open(e);
1960
+ },
1961
+ open: function(e)
1962
+ {
1963
+ if (e) e.preventDefault();
1964
+
1965
+ if (this.isOpened())
1966
+ {
1967
+ return;
1968
+ }
1969
+
1970
+ if (this.detect.isMobile()) this.opts.width = '96%';
1971
+ if (this.opts.overlay) this.$overlay.removeClass('hide');
1972
+
1973
+ this.$target.removeClass('hide');
1974
+ this.$modal.removeClass('hide');
1975
+
1976
+ this.enableEvents();
1977
+ this.findActions();
1978
+
1979
+ this.resize();
1980
+ $(window).on('resize.' + this.namespace, $.proxy(this.resize, this));
1981
+
1982
+ if (this.detect.isDesktop()) this.utils.disableBodyScroll();
1983
+
1984
+ // enter
1985
+ this.$modal.find('input[type=text],input[type=url],input[type=email]').on('keydown.' + this.namespace, $.proxy(this.handleEnter, this));
1986
+
1987
+ this.callback('open');
1988
+ this.$modal.animation(this.opts.animationOpen, $.proxy(this.onOpened, this));
1989
+ },
1990
+ close: function(e)
1991
+ {
1992
+ if (!this.$modal || !this.isOpened())
1993
+ {
1994
+ return;
1995
+ }
1996
+
1997
+ if (e)
1998
+ {
1999
+ if (this.shouldNotBeClosed(e.target))
2000
+ {
2001
+ return;
2002
+ }
2003
+
2004
+ e.preventDefault();
2005
+ }
2006
+
2007
+ this.callback('close');
2008
+ this.disableEvents();
2009
+
2010
+ this.$modal.animation(this.opts.animationClose, $.proxy(this.onClosed, this));
2011
+
2012
+ if (this.opts.overlay) this.$overlay.animation(this.opts.animationClose);
2013
+ },
2014
+ onOpened: function()
2015
+ {
2016
+ this.$modal.addClass('open');
2017
+ this.callback('opened');
2018
+
2019
+ $.modalcurrent = this;
2020
+ },
2021
+ onClosed: function()
2022
+ {
2023
+ this.callback('closed');
2024
+
2025
+ this.$target.addClass('hide');
2026
+ this.$modal.removeClass('open');
2027
+
2028
+ if (this.detect.isDesktop()) this.utils.enableBodyScroll();
2029
+
2030
+ this.$body.css('height', '');
2031
+ $.modalcurrent = null;
2032
+ },
2033
+ isOpened: function()
2034
+ {
2035
+ return (this.$modal.hasClass('open'));
2036
+ },
2037
+ getData: function()
2038
+ {
2039
+ var formdata = new Kube.FormData(this);
2040
+ formdata.set('');
2041
+
2042
+ return formdata.get();
2043
+ },
2044
+ buildContent: function()
2045
+ {
2046
+ $.ajax({
2047
+ url: this.opts.url + '?' + new Date().getTime(),
2048
+ cache: false,
2049
+ type: 'post',
2050
+ data: this.getData(),
2051
+ success: $.proxy(function(data)
2052
+ {
2053
+ this.$body.html(data);
2054
+ this.open();
2055
+
2056
+ }, this)
2057
+ });
2058
+ },
2059
+ buildWidth: function()
2060
+ {
2061
+ var width = this.opts.width;
2062
+ var top = '2%';
2063
+ var bottom = '2%';
2064
+ var percent = width.match(/%$/);
2065
+
2066
+ if ((parseInt(this.opts.width) > $(window).width()) && !percent)
2067
+ {
2068
+ width = '96%';
2069
+ }
2070
+ else if (!percent)
2071
+ {
2072
+ top = '16px';
2073
+ bottom = '16px';
2074
+ }
2075
+
2076
+ this.$modal.css({ 'width': width, 'margin-top': top, 'margin-bottom': bottom });
2077
+
2078
+ },
2079
+ buildPosition: function()
2080
+ {
2081
+ if (this.opts.position !== 'center')
2082
+ {
2083
+ return;
2084
+ }
2085
+
2086
+ var windowHeight = $(window).height();
2087
+ var height = this.$modal.outerHeight();
2088
+ var top = (windowHeight/2 - height/2) + 'px';
2089
+
2090
+ if (this.detect.isMobile()) top = '2%';
2091
+ else if (height > windowHeight) top = '16px';
2092
+
2093
+ this.$modal.css('margin-top', top);
2094
+ },
2095
+ buildHeight: function()
2096
+ {
2097
+ var windowHeight = $(window).height();
2098
+
2099
+ if (this.opts.maxHeight)
2100
+ {
2101
+ var padding = parseInt(this.$body.css('padding-top')) + parseInt(this.$body.css('padding-bottom'));
2102
+ var margin = parseInt(this.$modal.css('margin-top')) + parseInt(this.$modal.css('margin-bottom'));
2103
+ var height = windowHeight - this.$header.innerHeight() - padding - margin;
2104
+
2105
+ this.$body.height(height);
2106
+ }
2107
+ else if (this.opts.height !== false)
2108
+ {
2109
+ this.$body.css('height', this.opts.height);
2110
+ }
2111
+
2112
+ var modalHeight = this.$modal.outerHeight();
2113
+ if (modalHeight > windowHeight)
2114
+ {
2115
+ this.opts.animationOpen = 'show';
2116
+ this.opts.animationClose = 'hide';
2117
+ }
2118
+ },
2119
+ resize: function()
2120
+ {
2121
+ this.buildWidth();
2122
+ this.buildPosition();
2123
+ this.buildHeight();
2124
+ },
2125
+ enableEvents: function()
2126
+ {
2127
+ this.$close.on('click.' + this.namespace, $.proxy(this.close, this));
2128
+ $(document).on('keyup.' + this.namespace, $.proxy(this.handleEscape, this));
2129
+ this.$target.on('click.' + this.namespace, $.proxy(this.close, this));
2130
+ },
2131
+ disableEvents: function()
2132
+ {
2133
+ this.$close.off('.' + this.namespace);
2134
+ $(document).off('.' + this.namespace);
2135
+ this.$target.off('.' + this.namespace);
2136
+ $(window).off('.' + this.namespace);
2137
+ },
2138
+ findActions: function()
2139
+ {
2140
+ this.$body.find('[data-action="modal-close"]').on('mousedown.' + this.namespace, $.proxy(this.close, this));
2141
+ },
2142
+ setHeader: function(header)
2143
+ {
2144
+ this.$header.html(header);
2145
+ },
2146
+ setContent: function(content)
2147
+ {
2148
+ this.$body.html(content);
2149
+ },
2150
+ setWidth: function(width)
2151
+ {
2152
+ this.opts.width = width;
2153
+ this.resize();
2154
+ },
2155
+ getModal: function()
2156
+ {
2157
+ return this.$modal;
2158
+ },
2159
+ getBody: function()
2160
+ {
2161
+ return this.$body;
2162
+ },
2163
+ getHeader: function()
2164
+ {
2165
+ return this.$header;
2166
+ },
2167
+ handleEnter: function(e)
2168
+ {
2169
+ if (e.which === 13)
2170
+ {
2171
+ e.preventDefault();
2172
+ this.close(false);
2173
+ }
2174
+ },
2175
+ handleEscape: function(e)
2176
+ {
2177
+ return (e.which === 27) ? this.close(false) : true;
2178
+ },
2179
+ shouldNotBeClosed: function(el)
2180
+ {
2181
+ if ($(el).attr('data-action') === 'modal-close' || el === this.$close[0])
2182
+ {
2183
+ return false;
2184
+ }
2185
+ else if ($(el).closest('.modal').length === 0)
2186
+ {
2187
+ return false;
2188
+ }
2189
+
2190
+ return true;
2191
+ }
2192
+ };
2193
+
2194
+ // Inheritance
2195
+ Kube.Modal.inherits(Kube);
2196
+
2197
+ // Plugin
2198
+ Kube.Plugin.create('Modal');
2199
+ Kube.Plugin.autoload('Modal');
2200
+
2201
+ }(Kube));