fomantic-ui 2.9.1-beta.16 → 2.9.1-beta.18

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