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,1532 @@
1
+ /*!
2
+ * # Semantic UI - Popup
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.popup = function(parameters) {
23
+ var
24
+ $allModules = $(this),
25
+ $document = $(document),
26
+ $window = $(window),
27
+ $body = $('body'),
28
+
29
+ moduleSelector = $allModules.selector || '',
30
+
31
+ hasTouch = (true),
32
+ time = new Date().getTime(),
33
+ performance = [],
34
+
35
+ query = arguments[0],
36
+ methodInvoked = (typeof query == 'string'),
37
+ queryArguments = [].slice.call(arguments, 1),
38
+
39
+ returnedValue
40
+ ;
41
+ $allModules
42
+ .each(function() {
43
+ var
44
+ settings = ( $.isPlainObject(parameters) )
45
+ ? $.extend(true, {}, $.fn.popup.settings, parameters)
46
+ : $.extend({}, $.fn.popup.settings),
47
+
48
+ selector = settings.selector,
49
+ className = settings.className,
50
+ error = settings.error,
51
+ metadata = settings.metadata,
52
+ namespace = settings.namespace,
53
+
54
+ eventNamespace = '.' + settings.namespace,
55
+ moduleNamespace = 'module-' + namespace,
56
+
57
+ $module = $(this),
58
+ $context = $(settings.context),
59
+ $scrollContext = $(settings.scrollContext),
60
+ $boundary = $(settings.boundary),
61
+ $target = (settings.target)
62
+ ? $(settings.target)
63
+ : $module,
64
+
65
+ $popup,
66
+ $offsetParent,
67
+
68
+ searchDepth = 0,
69
+ triedPositions = false,
70
+ openedWithTouch = false,
71
+
72
+ element = this,
73
+ instance = $module.data(moduleNamespace),
74
+
75
+ documentObserver,
76
+ elementNamespace,
77
+ id,
78
+ module
79
+ ;
80
+
81
+ module = {
82
+
83
+ // binds events
84
+ initialize: function() {
85
+ module.debug('Initializing', $module);
86
+ module.createID();
87
+ module.bind.events();
88
+ if(!module.exists() && settings.preserve) {
89
+ module.create();
90
+ }
91
+ if(settings.observeChanges) {
92
+ module.observeChanges();
93
+ }
94
+ module.instantiate();
95
+ },
96
+
97
+ instantiate: function() {
98
+ module.verbose('Storing instance', module);
99
+ instance = module;
100
+ $module
101
+ .data(moduleNamespace, instance)
102
+ ;
103
+ },
104
+
105
+ observeChanges: function() {
106
+ if('MutationObserver' in window) {
107
+ documentObserver = new MutationObserver(module.event.documentChanged);
108
+ documentObserver.observe(document, {
109
+ childList : true,
110
+ subtree : true
111
+ });
112
+ module.debug('Setting up mutation observer', documentObserver);
113
+ }
114
+ },
115
+
116
+ refresh: function() {
117
+ if(settings.popup) {
118
+ $popup = $(settings.popup).eq(0);
119
+ }
120
+ else {
121
+ if(settings.inline) {
122
+ $popup = $target.nextAll(selector.popup).eq(0);
123
+ settings.popup = $popup;
124
+ }
125
+ }
126
+ if(settings.popup) {
127
+ $popup.addClass(className.loading);
128
+ $offsetParent = module.get.offsetParent();
129
+ $popup.removeClass(className.loading);
130
+ if(settings.movePopup && module.has.popup() && module.get.offsetParent($popup)[0] !== $offsetParent[0]) {
131
+ module.debug('Moving popup to the same offset parent as target');
132
+ $popup
133
+ .detach()
134
+ .appendTo($offsetParent)
135
+ ;
136
+ }
137
+ }
138
+ else {
139
+ $offsetParent = (settings.inline)
140
+ ? module.get.offsetParent($target)
141
+ : module.has.popup()
142
+ ? module.get.offsetParent($popup)
143
+ : $body
144
+ ;
145
+ }
146
+ if( $offsetParent.is('html') && $offsetParent[0] !== $body[0] ) {
147
+ module.debug('Setting page as offset parent');
148
+ $offsetParent = $body;
149
+ }
150
+ if( module.get.variation() ) {
151
+ module.set.variation();
152
+ }
153
+ },
154
+
155
+ reposition: function() {
156
+ module.refresh();
157
+ module.set.position();
158
+ },
159
+
160
+ destroy: function() {
161
+ module.debug('Destroying previous module');
162
+ if(documentObserver) {
163
+ documentObserver.disconnect();
164
+ }
165
+ // remove element only if was created dynamically
166
+ if($popup && !settings.preserve) {
167
+ module.removePopup();
168
+ }
169
+ // clear all timeouts
170
+ clearTimeout(module.hideTimer);
171
+ clearTimeout(module.showTimer);
172
+ // remove events
173
+ module.unbind.close();
174
+ module.unbind.events();
175
+ $module
176
+ .removeData(moduleNamespace)
177
+ ;
178
+ },
179
+
180
+ event: {
181
+ start: function(event) {
182
+ var
183
+ delay = ($.isPlainObject(settings.delay))
184
+ ? settings.delay.show
185
+ : settings.delay
186
+ ;
187
+ clearTimeout(module.hideTimer);
188
+ if(!openedWithTouch) {
189
+ module.showTimer = setTimeout(module.show, delay);
190
+ }
191
+ },
192
+ end: function() {
193
+ var
194
+ delay = ($.isPlainObject(settings.delay))
195
+ ? settings.delay.hide
196
+ : settings.delay
197
+ ;
198
+ clearTimeout(module.showTimer);
199
+ module.hideTimer = setTimeout(module.hide, delay);
200
+ },
201
+ touchstart: function(event) {
202
+ openedWithTouch = true;
203
+ module.show();
204
+ },
205
+ resize: function() {
206
+ if( module.is.visible() ) {
207
+ module.set.position();
208
+ }
209
+ },
210
+ documentChanged: function(mutations) {
211
+ [].forEach.call(mutations, function(mutation) {
212
+ if(mutation.removedNodes) {
213
+ [].forEach.call(mutation.removedNodes, function(node) {
214
+ if(node == element || $(node).find(element).length > 0) {
215
+ module.debug('Element removed from DOM, tearing down events');
216
+ module.destroy();
217
+ }
218
+ });
219
+ }
220
+ });
221
+ },
222
+ hideGracefully: function(event) {
223
+ var
224
+ $target = $(event.target),
225
+ isInDOM = $.contains(document.documentElement, event.target),
226
+ inPopup = ($target.closest(selector.popup).length > 0)
227
+ ;
228
+ // don't close on clicks inside popup
229
+ if(event && !inPopup && isInDOM) {
230
+ module.debug('Click occurred outside popup hiding popup');
231
+ module.hide();
232
+ }
233
+ else {
234
+ module.debug('Click was inside popup, keeping popup open');
235
+ }
236
+ }
237
+ },
238
+
239
+ // generates popup html from metadata
240
+ create: function() {
241
+ var
242
+ html = module.get.html(),
243
+ title = module.get.title(),
244
+ content = module.get.content()
245
+ ;
246
+
247
+ if(html || content || title) {
248
+ module.debug('Creating pop-up html');
249
+ if(!html) {
250
+ html = settings.templates.popup({
251
+ title : title,
252
+ content : content
253
+ });
254
+ }
255
+ $popup = $('<div/>')
256
+ .addClass(className.popup)
257
+ .data(metadata.activator, $module)
258
+ .html(html)
259
+ ;
260
+ if(settings.inline) {
261
+ module.verbose('Inserting popup element inline', $popup);
262
+ $popup
263
+ .insertAfter($module)
264
+ ;
265
+ }
266
+ else {
267
+ module.verbose('Appending popup element to body', $popup);
268
+ $popup
269
+ .appendTo( $context )
270
+ ;
271
+ }
272
+ module.refresh();
273
+ module.set.variation();
274
+
275
+ if(settings.hoverable) {
276
+ module.bind.popup();
277
+ }
278
+ settings.onCreate.call($popup, element);
279
+ }
280
+ else if($target.next(selector.popup).length !== 0) {
281
+ module.verbose('Pre-existing popup found');
282
+ settings.inline = true;
283
+ settings.popup = $target.next(selector.popup).data(metadata.activator, $module);
284
+ module.refresh();
285
+ if(settings.hoverable) {
286
+ module.bind.popup();
287
+ }
288
+ }
289
+ else if(settings.popup) {
290
+ $(settings.popup).data(metadata.activator, $module);
291
+ module.verbose('Used popup specified in settings');
292
+ module.refresh();
293
+ if(settings.hoverable) {
294
+ module.bind.popup();
295
+ }
296
+ }
297
+ else {
298
+ module.debug('No content specified skipping display', element);
299
+ }
300
+ },
301
+
302
+ createID: function() {
303
+ id = (Math.random().toString(16) + '000000000').substr(2, 8);
304
+ elementNamespace = '.' + id;
305
+ module.verbose('Creating unique id for element', id);
306
+ },
307
+
308
+ // determines popup state
309
+ toggle: function() {
310
+ module.debug('Toggling pop-up');
311
+ if( module.is.hidden() ) {
312
+ module.debug('Popup is hidden, showing pop-up');
313
+ module.unbind.close();
314
+ module.show();
315
+ }
316
+ else {
317
+ module.debug('Popup is visible, hiding pop-up');
318
+ module.hide();
319
+ }
320
+ },
321
+
322
+ show: function(callback) {
323
+ callback = callback || function(){};
324
+ module.debug('Showing pop-up', settings.transition);
325
+ if(module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) {
326
+ if( !module.exists() ) {
327
+ module.create();
328
+ }
329
+ if(settings.onShow.call($popup, element) === false) {
330
+ module.debug('onShow callback returned false, cancelling popup animation');
331
+ return;
332
+ }
333
+ else if(!settings.preserve && !settings.popup) {
334
+ module.refresh();
335
+ }
336
+ if( $popup && module.set.position() ) {
337
+ module.save.conditions();
338
+ if(settings.exclusive) {
339
+ module.hideAll();
340
+ }
341
+ module.animate.show(callback);
342
+ }
343
+ }
344
+ },
345
+
346
+
347
+ hide: function(callback) {
348
+ callback = callback || function(){};
349
+ if( module.is.visible() || module.is.animating() ) {
350
+ if(settings.onHide.call($popup, element) === false) {
351
+ module.debug('onHide callback returned false, cancelling popup animation');
352
+ return;
353
+ }
354
+ module.remove.visible();
355
+ module.unbind.close();
356
+ module.restore.conditions();
357
+ module.animate.hide(callback);
358
+ }
359
+ },
360
+
361
+ hideAll: function() {
362
+ $(selector.popup)
363
+ .filter('.' + className.popupVisible)
364
+ .each(function() {
365
+ $(this)
366
+ .data(metadata.activator)
367
+ .popup('hide')
368
+ ;
369
+ })
370
+ ;
371
+ },
372
+ exists: function() {
373
+ if(!$popup) {
374
+ return false;
375
+ }
376
+ if(settings.inline || settings.popup) {
377
+ return ( module.has.popup() );
378
+ }
379
+ else {
380
+ return ( $popup.closest($context).length >= 1 )
381
+ ? true
382
+ : false
383
+ ;
384
+ }
385
+ },
386
+
387
+ removePopup: function() {
388
+ if( module.has.popup() && !settings.popup) {
389
+ module.debug('Removing popup', $popup);
390
+ $popup.remove();
391
+ $popup = undefined;
392
+ settings.onRemove.call($popup, element);
393
+ }
394
+ },
395
+
396
+ save: {
397
+ conditions: function() {
398
+ module.cache = {
399
+ title: $module.attr('title')
400
+ };
401
+ if (module.cache.title) {
402
+ $module.removeAttr('title');
403
+ }
404
+ module.verbose('Saving original attributes', module.cache.title);
405
+ }
406
+ },
407
+ restore: {
408
+ conditions: function() {
409
+ if(module.cache && module.cache.title) {
410
+ $module.attr('title', module.cache.title);
411
+ module.verbose('Restoring original attributes', module.cache.title);
412
+ }
413
+ return true;
414
+ }
415
+ },
416
+ supports: {
417
+ svg: function() {
418
+ return (typeof SVGGraphicsElement !== 'undefined');
419
+ }
420
+ },
421
+ animate: {
422
+ show: function(callback) {
423
+ callback = $.isFunction(callback) ? callback : function(){};
424
+ if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
425
+ module.set.visible();
426
+ $popup
427
+ .transition({
428
+ animation : settings.transition + ' in',
429
+ queue : false,
430
+ debug : settings.debug,
431
+ verbose : settings.verbose,
432
+ duration : settings.duration,
433
+ onComplete : function() {
434
+ module.bind.close();
435
+ callback.call($popup, element);
436
+ settings.onVisible.call($popup, element);
437
+ }
438
+ })
439
+ ;
440
+ }
441
+ else {
442
+ module.error(error.noTransition);
443
+ }
444
+ },
445
+ hide: function(callback) {
446
+ callback = $.isFunction(callback) ? callback : function(){};
447
+ module.debug('Hiding pop-up');
448
+ if(settings.onHide.call($popup, element) === false) {
449
+ module.debug('onHide callback returned false, cancelling popup animation');
450
+ return;
451
+ }
452
+ if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
453
+ $popup
454
+ .transition({
455
+ animation : settings.transition + ' out',
456
+ queue : false,
457
+ duration : settings.duration,
458
+ debug : settings.debug,
459
+ verbose : settings.verbose,
460
+ onComplete : function() {
461
+ module.reset();
462
+ callback.call($popup, element);
463
+ settings.onHidden.call($popup, element);
464
+ }
465
+ })
466
+ ;
467
+ }
468
+ else {
469
+ module.error(error.noTransition);
470
+ }
471
+ }
472
+ },
473
+
474
+ change: {
475
+ content: function(html) {
476
+ $popup.html(html);
477
+ }
478
+ },
479
+
480
+ get: {
481
+ html: function() {
482
+ $module.removeData(metadata.html);
483
+ return $module.data(metadata.html) || settings.html;
484
+ },
485
+ title: function() {
486
+ $module.removeData(metadata.title);
487
+ return $module.data(metadata.title) || settings.title;
488
+ },
489
+ content: function() {
490
+ $module.removeData(metadata.content);
491
+ return $module.data(metadata.content) || settings.content || $module.attr('title');
492
+ },
493
+ variation: function() {
494
+ $module.removeData(metadata.variation);
495
+ return $module.data(metadata.variation) || settings.variation;
496
+ },
497
+ popup: function() {
498
+ return $popup;
499
+ },
500
+ popupOffset: function() {
501
+ return $popup.offset();
502
+ },
503
+ calculations: function() {
504
+ var
505
+ $popupOffsetParent = module.get.offsetParent($popup),
506
+ targetElement = $target[0],
507
+ isWindow = ($boundary[0] == window),
508
+ targetPosition = (settings.inline || (settings.popup && settings.movePopup))
509
+ ? $target.position()
510
+ : $target.offset(),
511
+ screenPosition = (isWindow)
512
+ ? { top: 0, left: 0 }
513
+ : $boundary.offset(),
514
+ calculations = {},
515
+ scroll = (isWindow)
516
+ ? { top: $window.scrollTop(), left: $window.scrollLeft() }
517
+ : { top: 0, left: 0},
518
+ screen
519
+ ;
520
+ calculations = {
521
+ // element which is launching popup
522
+ target : {
523
+ element : $target[0],
524
+ width : $target.outerWidth(),
525
+ height : $target.outerHeight(),
526
+ top : targetPosition.top,
527
+ left : targetPosition.left,
528
+ margin : {}
529
+ },
530
+ // popup itself
531
+ popup : {
532
+ width : $popup.outerWidth(),
533
+ height : $popup.outerHeight()
534
+ },
535
+ // offset container (or 3d context)
536
+ parent : {
537
+ width : $offsetParent.outerWidth(),
538
+ height : $offsetParent.outerHeight()
539
+ },
540
+ // screen boundaries
541
+ screen : {
542
+ top : screenPosition.top,
543
+ left : screenPosition.left,
544
+ scroll: {
545
+ top : scroll.top,
546
+ left : scroll.left
547
+ },
548
+ width : $boundary.width(),
549
+ height : $boundary.height()
550
+ }
551
+ };
552
+
553
+ // if popup offset context is not same as target, then adjust calculations
554
+ if($popupOffsetParent.get(0) !== $offsetParent.get(0)) {
555
+ var
556
+ popupOffset = $popupOffsetParent.offset()
557
+ ;
558
+ calculations.target.top -= popupOffset.top;
559
+ calculations.target.left -= popupOffset.left;
560
+ calculations.parent.width = $popupOffsetParent.outerWidth();
561
+ calculations.parent.height = $popupOffsetParent.outerHeight();
562
+ }
563
+
564
+ // add in container calcs if fluid
565
+ if( settings.setFluidWidth && module.is.fluid() ) {
566
+ calculations.container = {
567
+ width: $popup.parent().outerWidth()
568
+ };
569
+ calculations.popup.width = calculations.container.width;
570
+ }
571
+
572
+ // add in margins if inline
573
+ calculations.target.margin.top = (settings.inline)
574
+ ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-top'), 10)
575
+ : 0
576
+ ;
577
+ calculations.target.margin.left = (settings.inline)
578
+ ? module.is.rtl()
579
+ ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-right'), 10)
580
+ : parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-left'), 10)
581
+ : 0
582
+ ;
583
+ // calculate screen boundaries
584
+ screen = calculations.screen;
585
+ calculations.boundary = {
586
+ top : screen.top + screen.scroll.top,
587
+ bottom : screen.top + screen.scroll.top + screen.height,
588
+ left : screen.left + screen.scroll.left,
589
+ right : screen.left + screen.scroll.left + screen.width
590
+ };
591
+ return calculations;
592
+ },
593
+ id: function() {
594
+ return id;
595
+ },
596
+ startEvent: function() {
597
+ if(settings.on == 'hover') {
598
+ return 'mouseenter';
599
+ }
600
+ else if(settings.on == 'focus') {
601
+ return 'focus';
602
+ }
603
+ return false;
604
+ },
605
+ scrollEvent: function() {
606
+ return 'scroll';
607
+ },
608
+ endEvent: function() {
609
+ if(settings.on == 'hover') {
610
+ return 'mouseleave';
611
+ }
612
+ else if(settings.on == 'focus') {
613
+ return 'blur';
614
+ }
615
+ return false;
616
+ },
617
+ distanceFromBoundary: function(offset, calculations) {
618
+ var
619
+ distanceFromBoundary = {},
620
+ popup,
621
+ boundary
622
+ ;
623
+ calculations = calculations || module.get.calculations();
624
+
625
+ // shorthand
626
+ popup = calculations.popup;
627
+ boundary = calculations.boundary;
628
+
629
+ if(offset) {
630
+ distanceFromBoundary = {
631
+ top : (offset.top - boundary.top),
632
+ left : (offset.left - boundary.left),
633
+ right : (boundary.right - (offset.left + popup.width) ),
634
+ bottom : (boundary.bottom - (offset.top + popup.height) )
635
+ };
636
+ module.verbose('Distance from boundaries determined', offset, distanceFromBoundary);
637
+ }
638
+ return distanceFromBoundary;
639
+ },
640
+ offsetParent: function($element) {
641
+ var
642
+ element = ($element !== undefined)
643
+ ? $element[0]
644
+ : $target[0],
645
+ parentNode = element.parentNode,
646
+ $node = $(parentNode)
647
+ ;
648
+ if(parentNode) {
649
+ var
650
+ is2D = ($node.css('transform') === 'none'),
651
+ isStatic = ($node.css('position') === 'static'),
652
+ isBody = $node.is('body')
653
+ ;
654
+ while(parentNode && !isBody && isStatic && is2D) {
655
+ parentNode = parentNode.parentNode;
656
+ $node = $(parentNode);
657
+ is2D = ($node.css('transform') === 'none');
658
+ isStatic = ($node.css('position') === 'static');
659
+ isBody = $node.is('body');
660
+ }
661
+ }
662
+ return ($node && $node.length > 0)
663
+ ? $node
664
+ : $()
665
+ ;
666
+ },
667
+ positions: function() {
668
+ return {
669
+ 'top left' : false,
670
+ 'top center' : false,
671
+ 'top right' : false,
672
+ 'bottom left' : false,
673
+ 'bottom center' : false,
674
+ 'bottom right' : false,
675
+ 'left center' : false,
676
+ 'right center' : false
677
+ };
678
+ },
679
+ nextPosition: function(position) {
680
+ var
681
+ positions = position.split(' '),
682
+ verticalPosition = positions[0],
683
+ horizontalPosition = positions[1],
684
+ opposite = {
685
+ top : 'bottom',
686
+ bottom : 'top',
687
+ left : 'right',
688
+ right : 'left'
689
+ },
690
+ adjacent = {
691
+ left : 'center',
692
+ center : 'right',
693
+ right : 'left'
694
+ },
695
+ backup = {
696
+ 'top left' : 'top center',
697
+ 'top center' : 'top right',
698
+ 'top right' : 'right center',
699
+ 'right center' : 'bottom right',
700
+ 'bottom right' : 'bottom center',
701
+ 'bottom center' : 'bottom left',
702
+ 'bottom left' : 'left center',
703
+ 'left center' : 'top left'
704
+ },
705
+ adjacentsAvailable = (verticalPosition == 'top' || verticalPosition == 'bottom'),
706
+ oppositeTried = false,
707
+ adjacentTried = false,
708
+ nextPosition = false
709
+ ;
710
+ if(!triedPositions) {
711
+ module.verbose('All available positions available');
712
+ triedPositions = module.get.positions();
713
+ }
714
+
715
+ module.debug('Recording last position tried', position);
716
+ triedPositions[position] = true;
717
+
718
+ if(settings.prefer === 'opposite') {
719
+ nextPosition = [opposite[verticalPosition], horizontalPosition];
720
+ nextPosition = nextPosition.join(' ');
721
+ oppositeTried = (triedPositions[nextPosition] === true);
722
+ module.debug('Trying opposite strategy', nextPosition);
723
+ }
724
+ if((settings.prefer === 'adjacent') && adjacentsAvailable ) {
725
+ nextPosition = [verticalPosition, adjacent[horizontalPosition]];
726
+ nextPosition = nextPosition.join(' ');
727
+ adjacentTried = (triedPositions[nextPosition] === true);
728
+ module.debug('Trying adjacent strategy', nextPosition);
729
+ }
730
+ if(adjacentTried || oppositeTried) {
731
+ module.debug('Using backup position', nextPosition);
732
+ nextPosition = backup[position];
733
+ }
734
+ return nextPosition;
735
+ }
736
+ },
737
+
738
+ set: {
739
+ position: function(position, calculations) {
740
+
741
+ // exit conditions
742
+ if($target.length === 0 || $popup.length === 0) {
743
+ module.error(error.notFound);
744
+ return;
745
+ }
746
+ var
747
+ offset,
748
+ distanceAway,
749
+ target,
750
+ popup,
751
+ parent,
752
+ positioning,
753
+ popupOffset,
754
+ distanceFromBoundary
755
+ ;
756
+
757
+ calculations = calculations || module.get.calculations();
758
+ position = position || $module.data(metadata.position) || settings.position;
759
+
760
+ offset = $module.data(metadata.offset) || settings.offset;
761
+ distanceAway = settings.distanceAway;
762
+
763
+ // shorthand
764
+ target = calculations.target;
765
+ popup = calculations.popup;
766
+ parent = calculations.parent;
767
+
768
+ if(module.should.centerArrow(calculations)) {
769
+ module.verbose('Adjusting offset to center arrow on small target element');
770
+ if(position == 'top left' || position == 'bottom left') {
771
+ offset += (target.width / 2)
772
+ offset -= settings.arrowPixelsFromEdge;
773
+ }
774
+ if(position == 'top right' || position == 'bottom right') {
775
+ offset -= (target.width / 2)
776
+ offset += settings.arrowPixelsFromEdge;
777
+ }
778
+ }
779
+
780
+ if(target.width === 0 && target.height === 0 && !module.is.svg(target.element)) {
781
+ module.debug('Popup target is hidden, no action taken');
782
+ return false;
783
+ }
784
+
785
+ if(settings.inline) {
786
+ module.debug('Adding margin to calculation', target.margin);
787
+ if(position == 'left center' || position == 'right center') {
788
+ offset += target.margin.top;
789
+ distanceAway += -target.margin.left;
790
+ }
791
+ else if (position == 'top left' || position == 'top center' || position == 'top right') {
792
+ offset += target.margin.left;
793
+ distanceAway -= target.margin.top;
794
+ }
795
+ else {
796
+ offset += target.margin.left;
797
+ distanceAway += target.margin.top;
798
+ }
799
+ }
800
+
801
+ module.debug('Determining popup position from calculations', position, calculations);
802
+
803
+ if (module.is.rtl()) {
804
+ position = position.replace(/left|right/g, function (match) {
805
+ return (match == 'left')
806
+ ? 'right'
807
+ : 'left'
808
+ ;
809
+ });
810
+ module.debug('RTL: Popup position updated', position);
811
+ }
812
+
813
+ // if last attempt use specified last resort position
814
+ if(searchDepth == settings.maxSearchDepth && typeof settings.lastResort === 'string') {
815
+ position = settings.lastResort;
816
+ }
817
+
818
+ switch (position) {
819
+ case 'top left':
820
+ positioning = {
821
+ top : 'auto',
822
+ bottom : parent.height - target.top + distanceAway,
823
+ left : target.left + offset,
824
+ right : 'auto'
825
+ };
826
+ break;
827
+ case 'top center':
828
+ positioning = {
829
+ bottom : parent.height - target.top + distanceAway,
830
+ left : target.left + (target.width / 2) - (popup.width / 2) + offset,
831
+ top : 'auto',
832
+ right : 'auto'
833
+ };
834
+ break;
835
+ case 'top right':
836
+ positioning = {
837
+ bottom : parent.height - target.top + distanceAway,
838
+ right : parent.width - target.left - target.width - offset,
839
+ top : 'auto',
840
+ left : 'auto'
841
+ };
842
+ break;
843
+ case 'left center':
844
+ positioning = {
845
+ top : target.top + (target.height / 2) - (popup.height / 2) + offset,
846
+ right : parent.width - target.left + distanceAway,
847
+ left : 'auto',
848
+ bottom : 'auto'
849
+ };
850
+ break;
851
+ case 'right center':
852
+ positioning = {
853
+ top : target.top + (target.height / 2) - (popup.height / 2) + offset,
854
+ left : target.left + target.width + distanceAway,
855
+ bottom : 'auto',
856
+ right : 'auto'
857
+ };
858
+ break;
859
+ case 'bottom left':
860
+ positioning = {
861
+ top : target.top + target.height + distanceAway,
862
+ left : target.left + offset,
863
+ bottom : 'auto',
864
+ right : 'auto'
865
+ };
866
+ break;
867
+ case 'bottom center':
868
+ positioning = {
869
+ top : target.top + target.height + distanceAway,
870
+ left : target.left + (target.width / 2) - (popup.width / 2) + offset,
871
+ bottom : 'auto',
872
+ right : 'auto'
873
+ };
874
+ break;
875
+ case 'bottom right':
876
+ positioning = {
877
+ top : target.top + target.height + distanceAway,
878
+ right : parent.width - target.left - target.width - offset,
879
+ left : 'auto',
880
+ bottom : 'auto'
881
+ };
882
+ break;
883
+ }
884
+ if(positioning === undefined) {
885
+ module.error(error.invalidPosition, position);
886
+ }
887
+
888
+ module.debug('Calculated popup positioning values', positioning);
889
+
890
+ // tentatively place on stage
891
+ $popup
892
+ .css(positioning)
893
+ .removeClass(className.position)
894
+ .addClass(position)
895
+ .addClass(className.loading)
896
+ ;
897
+
898
+ popupOffset = module.get.popupOffset();
899
+
900
+ // see if any boundaries are surpassed with this tentative position
901
+ distanceFromBoundary = module.get.distanceFromBoundary(popupOffset, calculations);
902
+
903
+ if( module.is.offstage(distanceFromBoundary, position) ) {
904
+ module.debug('Position is outside viewport', position);
905
+ if(searchDepth < settings.maxSearchDepth) {
906
+ searchDepth++;
907
+ position = module.get.nextPosition(position);
908
+ module.debug('Trying new position', position);
909
+ return ($popup)
910
+ ? module.set.position(position, calculations)
911
+ : false
912
+ ;
913
+ }
914
+ else {
915
+ if(settings.lastResort) {
916
+ module.debug('No position found, showing with last position');
917
+ }
918
+ else {
919
+ module.debug('Popup could not find a position to display', $popup);
920
+ module.error(error.cannotPlace, element);
921
+ module.remove.attempts();
922
+ module.remove.loading();
923
+ module.reset();
924
+ settings.onUnplaceable.call($popup, element);
925
+ return false;
926
+ }
927
+ }
928
+ }
929
+ module.debug('Position is on stage', position);
930
+ module.remove.attempts();
931
+ module.remove.loading();
932
+ if( settings.setFluidWidth && module.is.fluid() ) {
933
+ module.set.fluidWidth(calculations);
934
+ }
935
+ return true;
936
+ },
937
+
938
+ fluidWidth: function(calculations) {
939
+ calculations = calculations || module.get.calculations();
940
+ module.debug('Automatically setting element width to parent width', calculations.parent.width);
941
+ $popup.css('width', calculations.container.width);
942
+ },
943
+
944
+ variation: function(variation) {
945
+ variation = variation || module.get.variation();
946
+ if(variation && module.has.popup() ) {
947
+ module.verbose('Adding variation to popup', variation);
948
+ $popup.addClass(variation);
949
+ }
950
+ },
951
+
952
+ visible: function() {
953
+ $module.addClass(className.visible);
954
+ }
955
+ },
956
+
957
+ remove: {
958
+ loading: function() {
959
+ $popup.removeClass(className.loading);
960
+ },
961
+ variation: function(variation) {
962
+ variation = variation || module.get.variation();
963
+ if(variation) {
964
+ module.verbose('Removing variation', variation);
965
+ $popup.removeClass(variation);
966
+ }
967
+ },
968
+ visible: function() {
969
+ $module.removeClass(className.visible);
970
+ },
971
+ attempts: function() {
972
+ module.verbose('Resetting all searched positions');
973
+ searchDepth = 0;
974
+ triedPositions = false;
975
+ }
976
+ },
977
+
978
+ bind: {
979
+ events: function() {
980
+ module.debug('Binding popup events to module');
981
+ if(settings.on == 'click') {
982
+ $module
983
+ .on('click' + eventNamespace, module.toggle)
984
+ ;
985
+ }
986
+ if(settings.on == 'hover' && hasTouch) {
987
+ $module
988
+ .on('touchstart' + eventNamespace, module.event.touchstart)
989
+ ;
990
+ }
991
+ if( module.get.startEvent() ) {
992
+ $module
993
+ .on(module.get.startEvent() + eventNamespace, module.event.start)
994
+ .on(module.get.endEvent() + eventNamespace, module.event.end)
995
+ ;
996
+ }
997
+ if(settings.target) {
998
+ module.debug('Target set to element', $target);
999
+ }
1000
+ $window.on('resize' + elementNamespace, module.event.resize);
1001
+ },
1002
+ popup: function() {
1003
+ module.verbose('Allowing hover events on popup to prevent closing');
1004
+ if( $popup && module.has.popup() ) {
1005
+ $popup
1006
+ .on('mouseenter' + eventNamespace, module.event.start)
1007
+ .on('mouseleave' + eventNamespace, module.event.end)
1008
+ ;
1009
+ }
1010
+ },
1011
+ close: function() {
1012
+ if(settings.hideOnScroll === true || (settings.hideOnScroll == 'auto' && settings.on != 'click')) {
1013
+ module.bind.closeOnScroll();
1014
+ }
1015
+ if(module.is.closable()) {
1016
+ module.bind.clickaway();
1017
+ }
1018
+ else if(settings.on == 'hover' && openedWithTouch) {
1019
+ module.bind.touchClose();
1020
+ }
1021
+ },
1022
+ closeOnScroll: function() {
1023
+ module.verbose('Binding scroll close event to document');
1024
+ $scrollContext
1025
+ .one(module.get.scrollEvent() + elementNamespace, module.event.hideGracefully)
1026
+ ;
1027
+ },
1028
+ touchClose: function() {
1029
+ module.verbose('Binding popup touchclose event to document');
1030
+ $document
1031
+ .on('touchstart' + elementNamespace, function(event) {
1032
+ module.verbose('Touched away from popup');
1033
+ module.event.hideGracefully.call(element, event);
1034
+ })
1035
+ ;
1036
+ },
1037
+ clickaway: function() {
1038
+ module.verbose('Binding popup close event to document');
1039
+ $document
1040
+ .on('click' + elementNamespace, function(event) {
1041
+ module.verbose('Clicked away from popup');
1042
+ module.event.hideGracefully.call(element, event);
1043
+ })
1044
+ ;
1045
+ }
1046
+ },
1047
+
1048
+ unbind: {
1049
+ events: function() {
1050
+ $window
1051
+ .off(elementNamespace)
1052
+ ;
1053
+ $module
1054
+ .off(eventNamespace)
1055
+ ;
1056
+ },
1057
+ close: function() {
1058
+ $document
1059
+ .off(elementNamespace)
1060
+ ;
1061
+ $scrollContext
1062
+ .off(elementNamespace)
1063
+ ;
1064
+ },
1065
+ },
1066
+
1067
+ has: {
1068
+ popup: function() {
1069
+ return ($popup && $popup.length > 0);
1070
+ }
1071
+ },
1072
+
1073
+ should: {
1074
+ centerArrow: function(calculations) {
1075
+ return !module.is.basic() && calculations.target.width <= (settings.arrowPixelsFromEdge * 2);
1076
+ },
1077
+ },
1078
+
1079
+ is: {
1080
+ closable: function() {
1081
+ if(settings.closable == 'auto') {
1082
+ if(settings.on == 'hover') {
1083
+ return false;
1084
+ }
1085
+ return true;
1086
+ }
1087
+ return settings.closable;
1088
+ },
1089
+ offstage: function(distanceFromBoundary, position) {
1090
+ var
1091
+ offstage = []
1092
+ ;
1093
+ // return boundaries that have been surpassed
1094
+ $.each(distanceFromBoundary, function(direction, distance) {
1095
+ if(distance < -settings.jitter) {
1096
+ module.debug('Position exceeds allowable distance from edge', direction, distance, position);
1097
+ offstage.push(direction);
1098
+ }
1099
+ });
1100
+ if(offstage.length > 0) {
1101
+ return true;
1102
+ }
1103
+ else {
1104
+ return false;
1105
+ }
1106
+ },
1107
+ svg: function(element) {
1108
+ return module.supports.svg() && (element instanceof SVGGraphicsElement);
1109
+ },
1110
+ basic: function() {
1111
+ return $module.hasClass(className.basic);
1112
+ },
1113
+ active: function() {
1114
+ return $module.hasClass(className.active);
1115
+ },
1116
+ animating: function() {
1117
+ return ($popup !== undefined && $popup.hasClass(className.animating) );
1118
+ },
1119
+ fluid: function() {
1120
+ return ($popup !== undefined && $popup.hasClass(className.fluid));
1121
+ },
1122
+ visible: function() {
1123
+ return ($popup !== undefined && $popup.hasClass(className.popupVisible));
1124
+ },
1125
+ dropdown: function() {
1126
+ return $module.hasClass(className.dropdown);
1127
+ },
1128
+ hidden: function() {
1129
+ return !module.is.visible();
1130
+ },
1131
+ rtl: function () {
1132
+ return $module.css('direction') == 'rtl';
1133
+ }
1134
+ },
1135
+
1136
+ reset: function() {
1137
+ module.remove.visible();
1138
+ if(settings.preserve) {
1139
+ if($.fn.transition !== undefined) {
1140
+ $popup
1141
+ .transition('remove transition')
1142
+ ;
1143
+ }
1144
+ }
1145
+ else {
1146
+ module.removePopup();
1147
+ }
1148
+ },
1149
+
1150
+ setting: function(name, value) {
1151
+ if( $.isPlainObject(name) ) {
1152
+ $.extend(true, settings, name);
1153
+ }
1154
+ else if(value !== undefined) {
1155
+ settings[name] = value;
1156
+ }
1157
+ else {
1158
+ return settings[name];
1159
+ }
1160
+ },
1161
+ internal: function(name, value) {
1162
+ if( $.isPlainObject(name) ) {
1163
+ $.extend(true, module, name);
1164
+ }
1165
+ else if(value !== undefined) {
1166
+ module[name] = value;
1167
+ }
1168
+ else {
1169
+ return module[name];
1170
+ }
1171
+ },
1172
+ debug: function() {
1173
+ if(!settings.silent && settings.debug) {
1174
+ if(settings.performance) {
1175
+ module.performance.log(arguments);
1176
+ }
1177
+ else {
1178
+ module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
1179
+ module.debug.apply(console, arguments);
1180
+ }
1181
+ }
1182
+ },
1183
+ verbose: function() {
1184
+ if(!settings.silent && settings.verbose && settings.debug) {
1185
+ if(settings.performance) {
1186
+ module.performance.log(arguments);
1187
+ }
1188
+ else {
1189
+ module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
1190
+ module.verbose.apply(console, arguments);
1191
+ }
1192
+ }
1193
+ },
1194
+ error: function() {
1195
+ if(!settings.silent) {
1196
+ module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
1197
+ module.error.apply(console, arguments);
1198
+ }
1199
+ },
1200
+ performance: {
1201
+ log: function(message) {
1202
+ var
1203
+ currentTime,
1204
+ executionTime,
1205
+ previousTime
1206
+ ;
1207
+ if(settings.performance) {
1208
+ currentTime = new Date().getTime();
1209
+ previousTime = time || currentTime;
1210
+ executionTime = currentTime - previousTime;
1211
+ time = currentTime;
1212
+ performance.push({
1213
+ 'Name' : message[0],
1214
+ 'Arguments' : [].slice.call(message, 1) || '',
1215
+ 'Element' : element,
1216
+ 'Execution Time' : executionTime
1217
+ });
1218
+ }
1219
+ clearTimeout(module.performance.timer);
1220
+ module.performance.timer = setTimeout(module.performance.display, 500);
1221
+ },
1222
+ display: function() {
1223
+ var
1224
+ title = settings.name + ':',
1225
+ totalTime = 0
1226
+ ;
1227
+ time = false;
1228
+ clearTimeout(module.performance.timer);
1229
+ $.each(performance, function(index, data) {
1230
+ totalTime += data['Execution Time'];
1231
+ });
1232
+ title += ' ' + totalTime + 'ms';
1233
+ if(moduleSelector) {
1234
+ title += ' \'' + moduleSelector + '\'';
1235
+ }
1236
+ if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
1237
+ console.groupCollapsed(title);
1238
+ if(console.table) {
1239
+ console.table(performance);
1240
+ }
1241
+ else {
1242
+ $.each(performance, function(index, data) {
1243
+ console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
1244
+ });
1245
+ }
1246
+ console.groupEnd();
1247
+ }
1248
+ performance = [];
1249
+ }
1250
+ },
1251
+ invoke: function(query, passedArguments, context) {
1252
+ var
1253
+ object = instance,
1254
+ maxDepth,
1255
+ found,
1256
+ response
1257
+ ;
1258
+ passedArguments = passedArguments || queryArguments;
1259
+ context = element || context;
1260
+ if(typeof query == 'string' && object !== undefined) {
1261
+ query = query.split(/[\. ]/);
1262
+ maxDepth = query.length - 1;
1263
+ $.each(query, function(depth, value) {
1264
+ var camelCaseValue = (depth != maxDepth)
1265
+ ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
1266
+ : query
1267
+ ;
1268
+ if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
1269
+ object = object[camelCaseValue];
1270
+ }
1271
+ else if( object[camelCaseValue] !== undefined ) {
1272
+ found = object[camelCaseValue];
1273
+ return false;
1274
+ }
1275
+ else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
1276
+ object = object[value];
1277
+ }
1278
+ else if( object[value] !== undefined ) {
1279
+ found = object[value];
1280
+ return false;
1281
+ }
1282
+ else {
1283
+ return false;
1284
+ }
1285
+ });
1286
+ }
1287
+ if ( $.isFunction( found ) ) {
1288
+ response = found.apply(context, passedArguments);
1289
+ }
1290
+ else if(found !== undefined) {
1291
+ response = found;
1292
+ }
1293
+ if($.isArray(returnedValue)) {
1294
+ returnedValue.push(response);
1295
+ }
1296
+ else if(returnedValue !== undefined) {
1297
+ returnedValue = [returnedValue, response];
1298
+ }
1299
+ else if(response !== undefined) {
1300
+ returnedValue = response;
1301
+ }
1302
+ return found;
1303
+ }
1304
+ };
1305
+
1306
+ if(methodInvoked) {
1307
+ if(instance === undefined) {
1308
+ module.initialize();
1309
+ }
1310
+ module.invoke(query);
1311
+ }
1312
+ else {
1313
+ if(instance !== undefined) {
1314
+ instance.invoke('destroy');
1315
+ }
1316
+ module.initialize();
1317
+ }
1318
+ })
1319
+ ;
1320
+
1321
+ return (returnedValue !== undefined)
1322
+ ? returnedValue
1323
+ : this
1324
+ ;
1325
+ };
1326
+
1327
+ $.fn.popup.settings = {
1328
+
1329
+ name : 'Popup',
1330
+
1331
+ // module settings
1332
+ silent : false,
1333
+ debug : false,
1334
+ verbose : false,
1335
+ performance : true,
1336
+ namespace : 'popup',
1337
+
1338
+ // whether it should use dom mutation observers
1339
+ observeChanges : true,
1340
+
1341
+ // callback only when element added to dom
1342
+ onCreate : function(){},
1343
+
1344
+ // callback before element removed from dom
1345
+ onRemove : function(){},
1346
+
1347
+ // callback before show animation
1348
+ onShow : function(){},
1349
+
1350
+ // callback after show animation
1351
+ onVisible : function(){},
1352
+
1353
+ // callback before hide animation
1354
+ onHide : function(){},
1355
+
1356
+ // callback when popup cannot be positioned in visible screen
1357
+ onUnplaceable : function(){},
1358
+
1359
+ // callback after hide animation
1360
+ onHidden : function(){},
1361
+
1362
+ // when to show popup
1363
+ on : 'hover',
1364
+
1365
+ // element to use to determine if popup is out of boundary
1366
+ boundary : window,
1367
+
1368
+ // whether to add touchstart events when using hover
1369
+ addTouchEvents : true,
1370
+
1371
+ // default position relative to element
1372
+ position : 'top left',
1373
+
1374
+ // name of variation to use
1375
+ variation : '',
1376
+
1377
+ // whether popup should be moved to context
1378
+ movePopup : true,
1379
+
1380
+ // element which popup should be relative to
1381
+ target : false,
1382
+
1383
+ // jq selector or element that should be used as popup
1384
+ popup : false,
1385
+
1386
+ // popup should remain inline next to activator
1387
+ inline : false,
1388
+
1389
+ // popup should be removed from page on hide
1390
+ preserve : false,
1391
+
1392
+ // popup should not close when being hovered on
1393
+ hoverable : false,
1394
+
1395
+ // explicitly set content
1396
+ content : false,
1397
+
1398
+ // explicitly set html
1399
+ html : false,
1400
+
1401
+ // explicitly set title
1402
+ title : false,
1403
+
1404
+ // whether automatically close on clickaway when on click
1405
+ closable : true,
1406
+
1407
+ // automatically hide on scroll
1408
+ hideOnScroll : 'auto',
1409
+
1410
+ // hide other popups on show
1411
+ exclusive : false,
1412
+
1413
+ // context to attach popups
1414
+ context : 'body',
1415
+
1416
+ // context for binding scroll events
1417
+ scrollContext : window,
1418
+
1419
+ // position to prefer when calculating new position
1420
+ prefer : 'opposite',
1421
+
1422
+ // specify position to appear even if it doesn't fit
1423
+ lastResort : false,
1424
+
1425
+ // number of pixels from edge of popup to pointing arrow center (used from centering)
1426
+ arrowPixelsFromEdge: 20,
1427
+
1428
+ // delay used to prevent accidental refiring of animations due to user error
1429
+ delay : {
1430
+ show : 50,
1431
+ hide : 70
1432
+ },
1433
+
1434
+ // whether fluid variation should assign width explicitly
1435
+ setFluidWidth : true,
1436
+
1437
+ // transition settings
1438
+ duration : 200,
1439
+ transition : 'scale',
1440
+
1441
+ // distance away from activating element in px
1442
+ distanceAway : 0,
1443
+
1444
+ // number of pixels an element is allowed to be "offstage" for a position to be chosen (allows for rounding)
1445
+ jitter : 2,
1446
+
1447
+ // offset on aligning axis from calculated position
1448
+ offset : 0,
1449
+
1450
+ // maximum times to look for a position before failing (9 positions total)
1451
+ maxSearchDepth : 15,
1452
+
1453
+ error: {
1454
+ invalidPosition : 'The position you specified is not a valid position',
1455
+ cannotPlace : 'Popup does not fit within the boundaries of the viewport',
1456
+ method : 'The method you called is not defined.',
1457
+ noTransition : 'This module requires ui transitions <https://github.com/Semantic-Org/UI-Transition>',
1458
+ notFound : 'The target or popup you specified does not exist on the page'
1459
+ },
1460
+
1461
+ metadata: {
1462
+ activator : 'activator',
1463
+ content : 'content',
1464
+ html : 'html',
1465
+ offset : 'offset',
1466
+ position : 'position',
1467
+ title : 'title',
1468
+ variation : 'variation'
1469
+ },
1470
+
1471
+ className : {
1472
+ active : 'active',
1473
+ basic : 'basic',
1474
+ animating : 'animating',
1475
+ dropdown : 'dropdown',
1476
+ fluid : 'fluid',
1477
+ loading : 'loading',
1478
+ popup : 'ui popup',
1479
+ position : 'top left center bottom right',
1480
+ visible : 'visible',
1481
+ popupVisible : 'visible'
1482
+ },
1483
+
1484
+ selector : {
1485
+ popup : '.ui.popup'
1486
+ },
1487
+
1488
+ templates: {
1489
+ escape: function(string) {
1490
+ var
1491
+ badChars = /[&<>"'`]/g,
1492
+ shouldEscape = /[&<>"'`]/,
1493
+ escape = {
1494
+ "&": "&amp;",
1495
+ "<": "&lt;",
1496
+ ">": "&gt;",
1497
+ '"': "&quot;",
1498
+ "'": "&#x27;",
1499
+ "`": "&#x60;"
1500
+ },
1501
+ escapedChar = function(chr) {
1502
+ return escape[chr];
1503
+ }
1504
+ ;
1505
+ if(shouldEscape.test(string)) {
1506
+ return string.replace(badChars, escapedChar);
1507
+ }
1508
+ return string;
1509
+ },
1510
+ popup: function(text) {
1511
+ var
1512
+ html = '',
1513
+ escape = $.fn.popup.settings.templates.escape
1514
+ ;
1515
+ if(typeof text !== undefined) {
1516
+ if(typeof text.title !== undefined && text.title) {
1517
+ text.title = escape(text.title);
1518
+ html += '<div class="header">' + text.title + '</div>';
1519
+ }
1520
+ if(typeof text.content !== undefined && text.content) {
1521
+ text.content = escape(text.content);
1522
+ html += '<div class="content">' + text.content + '</div>';
1523
+ }
1524
+ }
1525
+ return html;
1526
+ }
1527
+ }
1528
+
1529
+ };
1530
+
1531
+
1532
+ })( jQuery, window, document );