fomantic-ui 2.9.1-beta.2 → 2.9.1-beta.20

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