@ntlab/ntjs-assets 2.0.2 → 2.0.4

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 (241) hide show
  1. package/assets/js/bootstrap-icons/bootstrap-icons.svg +1 -1
  2. package/assets/js/bootstrap-icons/folder-plus.svg +2 -2
  3. package/assets/js/bootstrap-icons/font/bootstrap-icons.css +1981 -0
  4. package/assets/js/bootstrap-icons/font/bootstrap-icons.json +1955 -0
  5. package/assets/js/bootstrap-icons/font/bootstrap-icons.min.css +5 -0
  6. package/assets/js/bootstrap-icons/font/bootstrap-icons.scss +1993 -0
  7. package/assets/js/bootstrap-icons/font/fonts/bootstrap-icons.woff +0 -0
  8. package/assets/js/bootstrap-icons/font/fonts/bootstrap-icons.woff2 +0 -0
  9. package/assets/js/bootstrap-icons/postcard-heart-fill.svg +1 -1
  10. package/assets/js/bootstrap-icons/trash.svg +2 -2
  11. package/assets/js/cropper/cropper.common.js +3253 -0
  12. package/assets/js/cropper/cropper.css +166 -236
  13. package/assets/js/cropper/cropper.esm.js +3251 -0
  14. package/assets/js/cropper/cropper.js +2499 -2237
  15. package/assets/js/cropper/cropper.min.css +5 -5
  16. package/assets/js/cropper/cropper.min.js +5 -5
  17. package/assets/js/jquery/jquery.js +840 -1045
  18. package/assets/js/jquery/jquery.min.js +2 -2
  19. package/assets/js/jquery/jquery.min.map +1 -1
  20. package/assets/js/jquery/jquery.slim.js +834 -1039
  21. package/assets/js/jquery/jquery.slim.min.js +2 -2
  22. package/assets/js/jquery/jquery.slim.min.map +1 -1
  23. package/assets/js/popper.js/cjs/enums.js +1 -1
  24. package/assets/js/popper.js/cjs/popper-base.js +12 -170
  25. package/assets/js/popper.js/cjs/popper-base.js.map +1 -1
  26. package/assets/js/popper.js/cjs/popper-lite.js +14 -184
  27. package/assets/js/popper.js/cjs/popper-lite.js.map +1 -1
  28. package/assets/js/popper.js/cjs/popper.js +14 -197
  29. package/assets/js/popper.js/cjs/popper.js.map +1 -1
  30. package/assets/js/popper.js/esm/createPopper.js +6 -66
  31. package/assets/js/popper.js/esm/modifiers/arrow.js +1 -12
  32. package/assets/js/popper.js/esm/modifiers/computeStyles.js +2 -14
  33. package/assets/js/popper.js/esm/utils/computeAutoPlacement.js +0 -4
  34. package/assets/js/popper.js/esm/utils/userAgent.js +1 -1
  35. package/assets/js/popper.js/umd/enums.js +1 -1
  36. package/assets/js/popper.js/umd/enums.min.js +1 -1
  37. package/assets/js/popper.js/umd/popper-base.js +12 -170
  38. package/assets/js/popper.js/umd/popper-base.js.map +1 -1
  39. package/assets/js/popper.js/umd/popper-base.min.js +2 -2
  40. package/assets/js/popper.js/umd/popper-base.min.js.map +1 -1
  41. package/assets/js/popper.js/umd/popper-lite.js +14 -184
  42. package/assets/js/popper.js/umd/popper-lite.js.map +1 -1
  43. package/assets/js/popper.js/umd/popper-lite.min.js +2 -2
  44. package/assets/js/popper.js/umd/popper-lite.min.js.map +1 -1
  45. package/assets/js/popper.js/umd/popper.js +14 -197
  46. package/assets/js/popper.js/umd/popper.js.map +1 -1
  47. package/assets/js/popper.js/umd/popper.min.js +2 -2
  48. package/assets/js/popper.js/umd/popper.min.js.map +1 -1
  49. package/assets/js/semantic-ui/components/accordion.css +196 -74
  50. package/assets/js/semantic-ui/components/accordion.js +570 -591
  51. package/assets/js/semantic-ui/components/accordion.min.css +4 -4
  52. package/assets/js/semantic-ui/components/accordion.min.js +6 -6
  53. package/assets/js/semantic-ui/components/ad.css +40 -51
  54. package/assets/js/semantic-ui/components/ad.min.css +4 -4
  55. package/assets/js/semantic-ui/components/api.js +1154 -1117
  56. package/assets/js/semantic-ui/components/api.min.js +6 -6
  57. package/assets/js/semantic-ui/components/breadcrumb.css +7 -7
  58. package/assets/js/semantic-ui/components/breadcrumb.min.css +4 -4
  59. package/assets/js/semantic-ui/components/button.css +895 -1227
  60. package/assets/js/semantic-ui/components/button.min.css +4 -4
  61. package/assets/js/semantic-ui/components/calendar.css +60 -33
  62. package/assets/js/semantic-ui/components/calendar.js +1952 -1575
  63. package/assets/js/semantic-ui/components/calendar.min.css +4 -4
  64. package/assets/js/semantic-ui/components/calendar.min.js +6 -6
  65. package/assets/js/semantic-ui/components/card.css +1004 -441
  66. package/assets/js/semantic-ui/components/card.min.css +4 -4
  67. package/assets/js/semantic-ui/components/checkbox.css +275 -303
  68. package/assets/js/semantic-ui/components/checkbox.js +863 -855
  69. package/assets/js/semantic-ui/components/checkbox.min.css +4 -4
  70. package/assets/js/semantic-ui/components/checkbox.min.js +6 -6
  71. package/assets/js/semantic-ui/components/comment.css +45 -63
  72. package/assets/js/semantic-ui/components/comment.min.css +4 -4
  73. package/assets/js/semantic-ui/components/container.css +98 -4
  74. package/assets/js/semantic-ui/components/container.min.css +4 -4
  75. package/assets/js/semantic-ui/components/dimmer.css +95 -196
  76. package/assets/js/semantic-ui/components/dimmer.js +698 -717
  77. package/assets/js/semantic-ui/components/dimmer.min.css +4 -4
  78. package/assets/js/semantic-ui/components/dimmer.min.js +6 -6
  79. package/assets/js/semantic-ui/components/divider.css +75 -93
  80. package/assets/js/semantic-ui/components/divider.min.css +4 -4
  81. package/assets/js/semantic-ui/components/dropdown.css +490 -413
  82. package/assets/js/semantic-ui/components/dropdown.js +4203 -4068
  83. package/assets/js/semantic-ui/components/dropdown.min.css +4 -4
  84. package/assets/js/semantic-ui/components/dropdown.min.js +6 -6
  85. package/assets/js/semantic-ui/components/embed.css +27 -38
  86. package/assets/js/semantic-ui/components/embed.js +647 -673
  87. package/assets/js/semantic-ui/components/embed.min.css +4 -4
  88. package/assets/js/semantic-ui/components/embed.min.js +6 -6
  89. package/assets/js/semantic-ui/components/emoji.css +11156 -9192
  90. package/assets/js/semantic-ui/components/emoji.min.css +3 -3
  91. package/assets/js/semantic-ui/components/feed.css +56 -78
  92. package/assets/js/semantic-ui/components/feed.min.css +4 -4
  93. package/assets/js/semantic-ui/components/flag.css +1037 -929
  94. package/assets/js/semantic-ui/components/flag.min.css +4 -4
  95. package/assets/js/semantic-ui/components/flyout.css +552 -0
  96. package/assets/js/semantic-ui/components/flyout.js +1567 -0
  97. package/assets/js/semantic-ui/components/flyout.min.css +9 -0
  98. package/assets/js/semantic-ui/components/flyout.min.js +11 -0
  99. package/assets/js/semantic-ui/components/form.css +536 -530
  100. package/assets/js/semantic-ui/components/form.js +2037 -1945
  101. package/assets/js/semantic-ui/components/form.min.css +4 -4
  102. package/assets/js/semantic-ui/components/form.min.js +6 -6
  103. package/assets/js/semantic-ui/components/grid.css +218 -345
  104. package/assets/js/semantic-ui/components/grid.min.css +4 -4
  105. package/assets/js/semantic-ui/components/header.css +137 -154
  106. package/assets/js/semantic-ui/components/header.min.css +4 -4
  107. package/assets/js/semantic-ui/components/icon.css +3000 -2750
  108. package/assets/js/semantic-ui/components/icon.min.css +4 -4
  109. package/assets/js/semantic-ui/components/image.css +54 -49
  110. package/assets/js/semantic-ui/components/image.min.css +4 -4
  111. package/assets/js/semantic-ui/components/input.css +1081 -227
  112. package/assets/js/semantic-ui/components/input.min.css +4 -4
  113. package/assets/js/semantic-ui/components/item.css +91 -138
  114. package/assets/js/semantic-ui/components/item.min.css +4 -4
  115. package/assets/js/semantic-ui/components/label.css +470 -481
  116. package/assets/js/semantic-ui/components/label.min.css +4 -4
  117. package/assets/js/semantic-ui/components/list.css +93 -114
  118. package/assets/js/semantic-ui/components/list.min.css +4 -4
  119. package/assets/js/semantic-ui/components/loader.css +452 -536
  120. package/assets/js/semantic-ui/components/loader.min.css +4 -4
  121. package/assets/js/semantic-ui/components/menu.css +408 -510
  122. package/assets/js/semantic-ui/components/menu.min.css +9 -1
  123. package/assets/js/semantic-ui/components/message.css +188 -213
  124. package/assets/js/semantic-ui/components/message.min.css +4 -4
  125. package/assets/js/semantic-ui/components/modal.css +174 -166
  126. package/assets/js/semantic-ui/components/modal.js +1558 -1146
  127. package/assets/js/semantic-ui/components/modal.min.css +4 -4
  128. package/assets/js/semantic-ui/components/modal.min.js +6 -6
  129. package/assets/js/semantic-ui/components/nag.css +183 -41
  130. package/assets/js/semantic-ui/components/nag.js +527 -467
  131. package/assets/js/semantic-ui/components/nag.min.css +4 -4
  132. package/assets/js/semantic-ui/components/nag.min.js +6 -6
  133. package/assets/js/semantic-ui/components/placeholder.css +62 -76
  134. package/assets/js/semantic-ui/components/placeholder.min.css +4 -4
  135. package/assets/js/semantic-ui/components/popup.css +681 -312
  136. package/assets/js/semantic-ui/components/popup.js +1470 -1463
  137. package/assets/js/semantic-ui/components/popup.min.css +4 -4
  138. package/assets/js/semantic-ui/components/popup.min.js +6 -6
  139. package/assets/js/semantic-ui/components/progress.css +149 -217
  140. package/assets/js/semantic-ui/components/progress.js +945 -1002
  141. package/assets/js/semantic-ui/components/progress.min.css +4 -4
  142. package/assets/js/semantic-ui/components/progress.min.js +6 -6
  143. package/assets/js/semantic-ui/components/rail.css +17 -22
  144. package/assets/js/semantic-ui/components/rail.min.css +3 -3
  145. package/assets/js/semantic-ui/components/rating.css +89 -184
  146. package/assets/js/semantic-ui/components/rating.js +509 -521
  147. package/assets/js/semantic-ui/components/rating.min.css +4 -4
  148. package/assets/js/semantic-ui/components/rating.min.js +6 -6
  149. package/assets/js/semantic-ui/components/reset.css +12 -17
  150. package/assets/js/semantic-ui/components/reset.min.css +4 -4
  151. package/assets/js/semantic-ui/components/reveal.css +46 -85
  152. package/assets/js/semantic-ui/components/reveal.min.css +4 -4
  153. package/assets/js/semantic-ui/components/search.css +157 -96
  154. package/assets/js/semantic-ui/components/search.js +1522 -1479
  155. package/assets/js/semantic-ui/components/search.min.css +4 -4
  156. package/assets/js/semantic-ui/components/search.min.js +6 -6
  157. package/assets/js/semantic-ui/components/segment.css +317 -249
  158. package/assets/js/semantic-ui/components/segment.min.css +4 -4
  159. package/assets/js/semantic-ui/components/shape.css +16 -32
  160. package/assets/js/semantic-ui/components/shape.js +763 -812
  161. package/assets/js/semantic-ui/components/shape.min.css +4 -4
  162. package/assets/js/semantic-ui/components/shape.min.js +6 -6
  163. package/assets/js/semantic-ui/components/sidebar.css +128 -216
  164. package/assets/js/semantic-ui/components/sidebar.js +1042 -1003
  165. package/assets/js/semantic-ui/components/sidebar.min.css +4 -4
  166. package/assets/js/semantic-ui/components/sidebar.min.js +6 -6
  167. package/assets/js/semantic-ui/components/site.css +123 -48
  168. package/assets/js/semantic-ui/components/site.js +438 -478
  169. package/assets/js/semantic-ui/components/site.min.css +4 -4
  170. package/assets/js/semantic-ui/components/site.min.js +6 -6
  171. package/assets/js/semantic-ui/components/slider.css +133 -141
  172. package/assets/js/semantic-ui/components/slider.js +1312 -1274
  173. package/assets/js/semantic-ui/components/slider.min.css +9 -1
  174. package/assets/js/semantic-ui/components/slider.min.js +6 -6
  175. package/assets/js/semantic-ui/components/state.js +640 -659
  176. package/assets/js/semantic-ui/components/state.min.js +6 -6
  177. package/assets/js/semantic-ui/components/statistic.css +83 -124
  178. package/assets/js/semantic-ui/components/statistic.min.css +4 -4
  179. package/assets/js/semantic-ui/components/step.css +118 -184
  180. package/assets/js/semantic-ui/components/step.min.css +4 -4
  181. package/assets/js/semantic-ui/components/sticky.css +3 -8
  182. package/assets/js/semantic-ui/components/sticky.js +849 -892
  183. package/assets/js/semantic-ui/components/sticky.min.css +4 -4
  184. package/assets/js/semantic-ui/components/sticky.min.js +6 -6
  185. package/assets/js/semantic-ui/components/tab.css +16 -20
  186. package/assets/js/semantic-ui/components/tab.js +896 -941
  187. package/assets/js/semantic-ui/components/tab.min.css +4 -4
  188. package/assets/js/semantic-ui/components/tab.min.js +6 -6
  189. package/assets/js/semantic-ui/components/table.css +2073 -884
  190. package/assets/js/semantic-ui/components/table.min.css +4 -4
  191. package/assets/js/semantic-ui/components/text.css +51 -30
  192. package/assets/js/semantic-ui/components/text.min.css +4 -4
  193. package/assets/js/semantic-ui/components/toast.css +200 -137
  194. package/assets/js/semantic-ui/components/toast.js +912 -832
  195. package/assets/js/semantic-ui/components/toast.min.css +4 -4
  196. package/assets/js/semantic-ui/components/toast.min.js +6 -6
  197. package/assets/js/semantic-ui/components/transition.css +371 -1282
  198. package/assets/js/semantic-ui/components/transition.js +999 -1074
  199. package/assets/js/semantic-ui/components/transition.min.css +4 -4
  200. package/assets/js/semantic-ui/components/transition.min.js +6 -6
  201. package/assets/js/semantic-ui/components/visibility.js +1215 -1247
  202. package/assets/js/semantic-ui/components/visibility.min.js +6 -6
  203. package/assets/js/semantic-ui/semantic.css +43777 -37429
  204. package/assets/js/semantic-ui/semantic.js +29152 -26694
  205. package/assets/js/semantic-ui/semantic.min.css +6 -399
  206. package/assets/js/semantic-ui/semantic.min.js +6 -6
  207. package/assets/js/semantic-ui/themes/basic/assets/fonts/icons.woff2 +0 -0
  208. package/assets/js/semantic-ui/themes/default/assets/fonts/Lato-Bold.woff +0 -0
  209. package/assets/js/semantic-ui/themes/default/assets/fonts/Lato-Bold.woff2 +0 -0
  210. package/assets/js/semantic-ui/themes/default/assets/fonts/Lato-BoldItalic.woff +0 -0
  211. package/assets/js/semantic-ui/themes/default/assets/fonts/Lato-BoldItalic.woff2 +0 -0
  212. package/assets/js/semantic-ui/themes/default/assets/fonts/Lato-Italic.woff +0 -0
  213. package/assets/js/semantic-ui/themes/default/assets/fonts/Lato-Italic.woff2 +0 -0
  214. package/assets/js/semantic-ui/themes/default/assets/fonts/Lato-Regular.woff +0 -0
  215. package/assets/js/semantic-ui/themes/default/assets/fonts/Lato-Regular.woff2 +0 -0
  216. package/assets/js/semantic-ui/themes/default/assets/fonts/LatoLatin-Bold.woff +0 -0
  217. package/assets/js/semantic-ui/themes/default/assets/fonts/LatoLatin-Bold.woff2 +0 -0
  218. package/assets/js/semantic-ui/themes/default/assets/fonts/LatoLatin-BoldItalic.woff +0 -0
  219. package/assets/js/semantic-ui/themes/default/assets/fonts/LatoLatin-BoldItalic.woff2 +0 -0
  220. package/assets/js/semantic-ui/themes/default/assets/fonts/LatoLatin-Italic.woff +0 -0
  221. package/assets/js/semantic-ui/themes/default/assets/fonts/LatoLatin-Italic.woff2 +0 -0
  222. package/assets/js/semantic-ui/themes/default/assets/fonts/LatoLatin-Regular.woff +0 -0
  223. package/assets/js/semantic-ui/themes/default/assets/fonts/LatoLatin-Regular.woff2 +0 -0
  224. package/assets/js/semantic-ui/themes/default/assets/fonts/brand-icons.woff +0 -0
  225. package/assets/js/semantic-ui/themes/default/assets/fonts/brand-icons.woff2 +0 -0
  226. package/assets/js/semantic-ui/themes/default/assets/fonts/icons.woff +0 -0
  227. package/assets/js/semantic-ui/themes/default/assets/fonts/icons.woff2 +0 -0
  228. package/assets/js/semantic-ui/themes/default/assets/fonts/outline-icons.woff +0 -0
  229. package/assets/js/semantic-ui/themes/default/assets/fonts/outline-icons.woff2 +0 -0
  230. package/assets/js/semantic-ui/themes/famfamfam/assets/images/flags.png +0 -0
  231. package/assets/js/semantic-ui/themes/github/assets/fonts/octicons.woff2 +0 -0
  232. package/assets/js/socket.io/socket.io.esm.min.js +3 -3
  233. package/assets/js/socket.io/socket.io.esm.min.js.map +1 -1
  234. package/assets/js/socket.io/socket.io.js +988 -1143
  235. package/assets/js/socket.io/socket.io.js.map +1 -1
  236. package/assets/js/socket.io/socket.io.min.js +3 -3
  237. package/assets/js/socket.io/socket.io.min.js.map +1 -1
  238. package/assets/js/socket.io/socket.io.msgpack.min.js +3 -3
  239. package/assets/js/socket.io/socket.io.msgpack.min.js.map +1 -1
  240. package/cdn.json +19 -4
  241. package/package.json +1 -1
@@ -1,1000 +1,955 @@
1
1
  /*!
2
- * # Fomantic-UI - Tab
3
- * http://github.com/fomantic/Fomantic-UI/
2
+ * # Fomantic-UI 2.9.2 - Tab
3
+ * https://github.com/fomantic/Fomantic-UI/
4
4
  *
5
5
  *
6
6
  * Released under the MIT license
7
- * http://opensource.org/licenses/MIT
7
+ * https://opensource.org/licenses/MIT
8
8
  *
9
9
  */
10
10
 
11
- ;(function ($, window, document, undefined) {
12
-
13
- 'use strict';
14
-
15
- $.isWindow = $.isWindow || function(obj) {
16
- return obj != null && obj === obj.window;
17
- };
18
- $.isFunction = $.isFunction || function(obj) {
19
- return typeof obj === "function" && typeof obj.nodeType !== "number";
20
- };
21
-
22
- window = (typeof window != 'undefined' && window.Math == Math)
23
- ? window
24
- : (typeof self != 'undefined' && self.Math == Math)
25
- ? self
26
- : Function('return this')()
27
- ;
28
-
29
- $.fn.tab = function(parameters) {
30
-
31
- var
32
- // use window context if none specified
33
- $allModules = $.isFunction(this)
34
- ? $(window)
35
- : $(this),
36
-
37
- moduleSelector = $allModules.selector || '',
38
- time = new Date().getTime(),
39
- performance = [],
40
-
41
- query = arguments[0],
42
- methodInvoked = (typeof query == 'string'),
43
- queryArguments = [].slice.call(arguments, 1),
44
-
45
- initializedHistory = false,
46
- returnedValue
47
- ;
48
-
49
- $allModules
50
- .each(function() {
51
- var
11
+ (function ($, window, document) {
12
+ 'use strict';
13
+
14
+ function isWindow(obj) {
15
+ return obj !== null && obj === obj.window;
16
+ }
17
+
18
+ function isFunction(obj) {
19
+ return typeof obj === 'function' && typeof obj.nodeType !== 'number';
20
+ }
21
+
22
+ window = window !== undefined && window.Math === Math
23
+ ? window
24
+ : globalThis;
25
+
26
+ $.fn.tab = function (parameters) {
27
+ var
28
+ // use window context if none specified
29
+ $allModules = isFunction(this)
30
+ ? $(window)
31
+ : $(this),
32
+ $document = $(document),
33
+ moduleSelector = $allModules.selector || '',
34
+ time = Date.now(),
35
+ performance = [],
36
+
37
+ query = arguments[0],
38
+ methodInvoked = typeof query === 'string',
39
+ queryArguments = [].slice.call(arguments, 1),
40
+
41
+ initializedHistory = false,
42
+ returnedValue
43
+ ;
44
+
45
+ $allModules.each(function () {
46
+ var
47
+ settings = $.isPlainObject(parameters)
48
+ ? $.extend(true, {}, $.fn.tab.settings, parameters)
49
+ : $.extend({}, $.fn.tab.settings),
50
+
51
+ className = settings.className,
52
+ metadata = settings.metadata,
53
+ selector = settings.selector,
54
+ error = settings.error,
55
+ regExp = settings.regExp,
56
+
57
+ eventNamespace = '.' + settings.namespace,
58
+ moduleNamespace = 'module-' + settings.namespace,
59
+
60
+ $module = $(this),
61
+ $context,
62
+ $tabs,
63
+
64
+ cache = {},
65
+ firstLoad = true,
66
+ recursionDepth = 0,
67
+ element = this,
68
+ instance = $module.data(moduleNamespace),
69
+
70
+ activeTabPath,
71
+ parameterArray,
72
+ module,
73
+
74
+ historyEvent
75
+ ;
52
76
 
53
- settings = ( $.isPlainObject(parameters) )
54
- ? $.extend(true, {}, $.fn.tab.settings, parameters)
55
- : $.extend({}, $.fn.tab.settings),
77
+ module = {
78
+
79
+ initialize: function () {
80
+ module.debug('Initializing tab menu item', $module);
81
+ module.determineTabs();
82
+
83
+ module.debug('Determining tabs', settings.context, $tabs);
84
+ // set up automatic routing
85
+ if (settings.auto) {
86
+ module.set.auto();
87
+ }
88
+ module.bind.events();
89
+
90
+ if (settings.history && !initializedHistory) {
91
+ module.initializeHistory();
92
+ initializedHistory = true;
93
+ }
94
+
95
+ var activeTab = module.determine.activeTab();
96
+ if (settings.autoTabActivation && instance === undefined && activeTab === null) {
97
+ activeTab = settings.autoTabActivation === true ? module.get.initialPath() : settings.autoTabActivation;
98
+ module.debug('No active tab detected, setting tab active', activeTab);
99
+ module.changeTab(activeTab);
100
+ }
101
+ if (activeTab !== null && settings.history) {
102
+ var autoUpdate = $.address.autoUpdate();
103
+ $.address.autoUpdate(false);
104
+ $.address.value(activeTab);
105
+ $.address.autoUpdate(autoUpdate);
106
+ }
107
+
108
+ module.instantiate();
109
+ },
56
110
 
57
- className = settings.className,
58
- metadata = settings.metadata,
59
- selector = settings.selector,
60
- error = settings.error,
61
- regExp = settings.regExp,
111
+ instantiate: function () {
112
+ module.verbose('Storing instance of module', module);
113
+ instance = module;
114
+ $module
115
+ .data(moduleNamespace, module)
116
+ ;
117
+ },
62
118
 
63
- eventNamespace = '.' + settings.namespace,
64
- moduleNamespace = 'module-' + settings.namespace,
119
+ destroy: function () {
120
+ module.debug('Destroying tabs', $module);
121
+ $module
122
+ .removeData(moduleNamespace)
123
+ .off(eventNamespace)
124
+ ;
125
+ },
65
126
 
66
- $module = $(this),
67
- $context,
68
- $tabs,
127
+ bind: {
128
+ events: function () {
129
+ // if using $.tab don't add events
130
+ if (!isWindow(element)) {
131
+ module.debug('Attaching tab activation events to element', $module);
132
+ $module
133
+ .on('click' + eventNamespace, module.event.click)
134
+ ;
135
+ }
136
+ },
137
+ },
69
138
 
70
- cache = {},
71
- firstLoad = true,
72
- recursionDepth = 0,
73
- element = this,
74
- instance = $module.data(moduleNamespace),
139
+ determineTabs: function () {
140
+ var
141
+ $reference
142
+ ;
143
+
144
+ // determine tab context
145
+ if (settings.context === 'parent') {
146
+ if ($module.closest(selector.ui).length > 0) {
147
+ $reference = $module.closest(selector.ui);
148
+ module.verbose('Using closest UI element as parent', $reference);
149
+ } else {
150
+ $reference = $module;
151
+ }
152
+ $context = $reference.parent();
153
+ module.verbose('Determined parent element for creating context', $context);
154
+ } else if (settings.context) {
155
+ $context = [window, document].indexOf(settings.context) < 0 ? $document.find(settings.context) : $(settings.context);
156
+ module.verbose('Using selector for tab context', settings.context, $context);
157
+ } else {
158
+ $context = $('body');
159
+ }
160
+ // find tabs
161
+ if (settings.childrenOnly) {
162
+ $tabs = $context.children(selector.tabs);
163
+ module.debug('Searching tab context children for tabs', $context, $tabs);
164
+ } else {
165
+ $tabs = $context.find(selector.tabs);
166
+ module.debug('Searching tab context for tabs', $context, $tabs);
167
+ }
168
+ },
75
169
 
76
- activeTabPath,
77
- parameterArray,
78
- module,
170
+ initializeHistory: function () {
171
+ module.debug('Initializing page state');
172
+ if ($.address === undefined) {
173
+ module.error(error.state);
174
+
175
+ return false;
176
+ }
177
+ if (settings.historyType === 'state') {
178
+ module.debug('Using HTML5 to manage state');
179
+ if (settings.path !== false) {
180
+ $.address
181
+ .history(true)
182
+ .state(settings.path)
183
+ ;
184
+ $(window).trigger('popstate');
185
+ } else {
186
+ module.error(error.path);
187
+
188
+ return false;
189
+ }
190
+ }
191
+ $.address
192
+ .bind('change', module.event.history.change)
193
+ ;
194
+ },
79
195
 
80
- historyEvent
196
+ event: {
197
+ click: function (event) {
198
+ var
199
+ tabPath = $(this).data(metadata.tab)
200
+ ;
201
+ if (tabPath !== undefined) {
202
+ if (settings.history) {
203
+ module.verbose('Updating page state', event);
204
+ $.address.value(tabPath);
205
+ } else {
206
+ module.verbose('Changing tab', event);
207
+ module.changeTab(tabPath);
208
+ }
209
+ event.preventDefault();
210
+ } else {
211
+ module.debug('No tab specified');
212
+ }
213
+ },
214
+ history: {
215
+ change: function (event) {
216
+ var
217
+ tabPath = event.pathNames.join('/') || module.get.initialPath(),
218
+ pageTitle = settings.templates.determineTitle(tabPath) || false
219
+ ;
220
+ module.performance.display();
221
+ module.debug('History change event', tabPath, event);
222
+ historyEvent = event;
223
+ if (tabPath !== undefined) {
224
+ module.changeTab(tabPath);
225
+ }
226
+ if (pageTitle) {
227
+ $.address.title(pageTitle);
228
+ }
229
+ },
230
+ },
231
+ },
81
232
 
82
- ;
233
+ refresh: function () {
234
+ if (activeTabPath) {
235
+ module.debug('Refreshing tab', activeTabPath);
236
+ module.changeTab(activeTabPath);
237
+ }
238
+ },
83
239
 
84
- module = {
240
+ cache: {
241
+
242
+ read: function (cacheKey) {
243
+ return cacheKey !== undefined
244
+ ? cache[cacheKey]
245
+ : false;
246
+ },
247
+ add: function (cacheKey, content) {
248
+ cacheKey = cacheKey || activeTabPath;
249
+ module.debug('Adding cached content for', cacheKey);
250
+ cache[cacheKey] = content;
251
+ },
252
+ remove: function (cacheKey) {
253
+ cacheKey = cacheKey || activeTabPath;
254
+ module.debug('Removing cached content for', cacheKey);
255
+ delete cache[cacheKey];
256
+ },
257
+ },
85
258
 
86
- initialize: function() {
87
- module.debug('Initializing tab menu item', $module);
88
- module.fix.callbacks();
89
- module.determineTabs();
259
+ escape: {
260
+ string: function (text) {
261
+ text = String(text);
90
262
 
91
- module.debug('Determining tabs', settings.context, $tabs);
92
- // set up automatic routing
93
- if(settings.auto) {
94
- module.set.auto();
95
- }
96
- module.bind.events();
263
+ return text.replace(regExp.escape, '\\$&');
264
+ },
265
+ },
97
266
 
98
- if(settings.history && !initializedHistory) {
99
- module.initializeHistory();
100
- initializedHistory = true;
101
- }
267
+ set: {
268
+ auto: function () {
269
+ var
270
+ url = typeof settings.path === 'string'
271
+ ? settings.path.replace(/\/$/, '') + '/{$tab}'
272
+ : '/{$tab}'
273
+ ;
274
+ module.verbose('Setting up automatic tab retrieval from server', url);
275
+ if ($.isPlainObject(settings.apiSettings)) {
276
+ settings.apiSettings.url = url;
277
+ } else {
278
+ settings.apiSettings = {
279
+ url: url,
280
+ };
281
+ }
282
+ },
283
+ loading: function (tabPath) {
284
+ var
285
+ $tab = module.get.tabElement(tabPath),
286
+ isLoading = $tab.hasClass(className.loading)
287
+ ;
288
+ if (!isLoading) {
289
+ module.verbose('Setting loading state for', $tab);
290
+ $tab
291
+ .addClass(className.loading)
292
+ .siblings($tabs)
293
+ .removeClass(className.active + ' ' + className.loading)
294
+ ;
295
+ if ($tab.length > 0) {
296
+ settings.onRequest.call($tab[0], tabPath);
297
+ }
298
+ }
299
+ },
300
+ state: function (state) {
301
+ $.address.value(state);
302
+ },
303
+ },
102
304
 
103
- if(instance === undefined && module.determine.activeTab() == null) {
104
- module.debug('No active tab detected, setting first tab active', module.get.initialPath());
105
- module.changeTab(module.get.initialPath());
106
- };
305
+ changeTab: function (tabPath) {
306
+ var
307
+ pushStateAvailable = window.history && window.history.pushState,
308
+ shouldIgnoreLoad = pushStateAvailable && settings.ignoreFirstLoad && firstLoad,
309
+ remoteContent = settings.auto || $.isPlainObject(settings.apiSettings),
310
+ // only add default path if not remote content
311
+ pathArray = remoteContent && !shouldIgnoreLoad
312
+ ? module.utilities.pathToArray(tabPath)
313
+ : module.get.defaultPathArray(tabPath)
314
+ ;
315
+ tabPath = module.utilities.arrayToPath(pathArray);
316
+ $.each(pathArray, function (index, tab) {
317
+ var
318
+ currentPathArray = pathArray.slice(0, index + 1),
319
+ currentPath = module.utilities.arrayToPath(currentPathArray),
320
+
321
+ isTab = module.is.tab(currentPath),
322
+ isLastIndex = index + 1 === pathArray.length,
323
+
324
+ $tab = module.get.tabElement(currentPath),
325
+ $anchor,
326
+ nextPathArray,
327
+ nextPath,
328
+ isLastTab
329
+ ;
330
+ module.verbose('Looking for tab', tab);
331
+ if (isTab) {
332
+ module.verbose('Tab was found', tab);
333
+ // scope up
334
+ activeTabPath = currentPath;
335
+ parameterArray = module.utilities.filterArray(pathArray, currentPathArray);
336
+
337
+ if (isLastIndex) {
338
+ isLastTab = true;
339
+ } else {
340
+ nextPathArray = pathArray.slice(0, index + 2);
341
+ nextPath = module.utilities.arrayToPath(nextPathArray);
342
+ isLastTab = !module.is.tab(nextPath);
343
+ if (isLastTab) {
344
+ module.verbose('Tab parameters found', nextPathArray);
345
+ }
346
+ }
347
+ if (settings.onBeforeChange.call(element, currentPath) === false) {
348
+ module.debug('onBeforeChange returned false, cancelling tab change', $tab);
349
+
350
+ return false;
351
+ }
352
+ if (isLastTab && remoteContent) {
353
+ if (!shouldIgnoreLoad) {
354
+ module.activate.navigation(currentPath);
355
+ module.fetch.content(currentPath, tabPath);
356
+ } else {
357
+ module.debug('Ignoring remote content on first tab load', currentPath);
358
+ firstLoad = false;
359
+ module.cache.add(tabPath, $tab.html());
360
+ module.activate.all(currentPath);
361
+ settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
362
+ settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
363
+ }
364
+
365
+ return false;
366
+ }
367
+
368
+ module.debug('Opened local tab', currentPath);
369
+ module.activate.all(currentPath);
370
+ if (!module.cache.read(currentPath)) {
371
+ module.cache.add(currentPath, true);
372
+ module.debug('First time tab loaded calling tab init');
373
+ settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
374
+ }
375
+ settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
376
+ } else if (tabPath.search('/') === -1 && tabPath !== '') {
377
+ // look for in page anchor
378
+ tabPath = module.escape.string(tabPath);
379
+ $anchor = $('#' + tabPath + ', a[name="' + tabPath + '"]');
380
+ currentPath = $anchor.closest('[data-tab]').data(metadata.tab);
381
+ $tab = module.get.tabElement(currentPath);
382
+ // if anchor exists use parent tab
383
+ if ($anchor && $anchor.length > 0 && currentPath) {
384
+ module.debug('Anchor link used, opening parent tab', $tab, $anchor);
385
+ if (settings.onBeforeChange.call(element, currentPath) === false) {
386
+ module.debug('onBeforeChange returned false, cancelling tab change', $tab);
387
+
388
+ return false;
389
+ }
390
+ if (!$tab.hasClass(className.active)) {
391
+ setTimeout(function () {
392
+ module.scrollTo($anchor);
393
+ }, 0);
394
+ }
395
+ module.activate.all(currentPath);
396
+ if (!module.cache.read(currentPath)) {
397
+ module.cache.add(currentPath, true);
398
+ module.debug('First time tab loaded calling tab init');
399
+ settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
400
+ }
401
+ settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
402
+
403
+ return false;
404
+ }
405
+ } else {
406
+ module.error(error.missingTab, $module, $context, currentPath);
407
+
408
+ return false;
409
+ }
410
+ });
411
+ },
107
412
 
108
- module.instantiate();
109
- },
413
+ scrollTo: function ($element) {
414
+ var
415
+ scrollOffset = $element && $element.length > 0
416
+ ? $element.offset().top
417
+ : false
418
+ ;
419
+ if (scrollOffset !== false) {
420
+ module.debug('Forcing scroll to an in-page link in a hidden tab', scrollOffset, $element);
421
+ $document.scrollTop(scrollOffset);
422
+ }
423
+ },
110
424
 
111
- instantiate: function () {
112
- module.verbose('Storing instance of module', module);
113
- instance = module;
114
- $module
115
- .data(moduleNamespace, module)
116
- ;
117
- },
425
+ update: {
426
+ content: function (tabPath, html, evaluateScripts) {
427
+ var
428
+ $tab = module.get.tabElement(tabPath),
429
+ tab = $tab[0]
430
+ ;
431
+ evaluateScripts = evaluateScripts !== undefined
432
+ ? evaluateScripts
433
+ : settings.evaluateScripts;
434
+ if (typeof settings.cacheType === 'string' && settings.cacheType.toLowerCase() === 'dom' && typeof html !== 'string') {
435
+ $tab
436
+ .empty()
437
+ .append($(html).clone(true))
438
+ ;
439
+ } else {
440
+ if (evaluateScripts) {
441
+ module.debug('Updating HTML and evaluating inline scripts', tabPath, html);
442
+ $tab.html(html);
443
+ } else {
444
+ module.debug('Updating HTML', tabPath, html);
445
+ tab.innerHTML = html;
446
+ }
447
+ }
448
+ },
449
+ },
118
450
 
119
- destroy: function() {
120
- module.debug('Destroying tabs', $module);
121
- $module
122
- .removeData(moduleNamespace)
123
- .off(eventNamespace)
124
- ;
125
- },
451
+ fetch: {
452
+
453
+ content: function (tabPath, fullTabPath) {
454
+ var
455
+ $tab = module.get.tabElement(tabPath),
456
+ apiSettings = {
457
+ dataType: 'html',
458
+ encodeParameters: false,
459
+ on: 'now',
460
+ cache: settings.alwaysRefresh,
461
+ headers: {
462
+ 'X-Remote': true,
463
+ },
464
+ onSuccess: function (response) {
465
+ if (settings.cacheType === 'response') {
466
+ module.cache.add(fullTabPath, response);
467
+ }
468
+ module.update.content(tabPath, response);
469
+ if (tabPath == activeTabPath) {
470
+ module.debug('Content loaded', tabPath);
471
+ module.activate.tab(tabPath);
472
+ } else {
473
+ module.debug('Content loaded in background', tabPath);
474
+ }
475
+ settings.onFirstLoad.call($tab[0], tabPath, parameterArray, historyEvent);
476
+ settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent);
477
+
478
+ if (settings.loadOnce) {
479
+ module.cache.add(fullTabPath, true);
480
+ } else if (typeof settings.cacheType === 'string' && settings.cacheType.toLowerCase() === 'dom' && $tab.children().length > 0) {
481
+ setTimeout(function () {
482
+ var
483
+ $clone = $tab.children().clone(true)
484
+ ;
485
+ $clone = $clone.not('script');
486
+ module.cache.add(fullTabPath, $clone);
487
+ }, 0);
488
+ } else {
489
+ module.cache.add(fullTabPath, $tab.html());
490
+ }
491
+ },
492
+ urlData: {
493
+ tab: fullTabPath,
494
+ },
495
+ },
496
+ request = $tab.api('get request') || false,
497
+ existingRequest = request && request.state() === 'pending',
498
+ requestSettings,
499
+ cachedContent
500
+ ;
501
+
502
+ fullTabPath = fullTabPath || tabPath;
503
+ cachedContent = module.cache.read(fullTabPath);
504
+
505
+ if (settings.cache && cachedContent) {
506
+ module.activate.tab(tabPath);
507
+ module.debug('Adding cached content', fullTabPath);
508
+ if (!settings.loadOnce) {
509
+ if (settings.evaluateScripts === 'once') {
510
+ module.update.content(tabPath, cachedContent, false);
511
+ } else {
512
+ module.update.content(tabPath, cachedContent);
513
+ }
514
+ }
515
+ settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent);
516
+ } else if (existingRequest) {
517
+ module.set.loading(tabPath);
518
+ module.debug('Content is already loading', fullTabPath);
519
+ } else if ($.api !== undefined) {
520
+ requestSettings = $.extend(true, {}, settings.apiSettings, apiSettings);
521
+ module.debug('Retrieving remote content', fullTabPath, requestSettings);
522
+ module.set.loading(tabPath);
523
+ $tab.api(requestSettings);
524
+ } else {
525
+ module.error(error.api);
526
+ }
527
+ },
528
+ },
126
529
 
127
- bind: {
128
- events: function() {
129
- // if using $.tab don't add events
130
- if( !$.isWindow( element ) ) {
131
- module.debug('Attaching tab activation events to element', $module);
132
- $module
133
- .on('click' + eventNamespace, module.event.click)
134
- ;
135
- }
136
- }
137
- },
530
+ activate: {
531
+ all: function (tabPath) {
532
+ module.activate.tab(tabPath);
533
+ module.activate.navigation(tabPath);
534
+ },
535
+ tab: function (tabPath) {
536
+ var
537
+ $tab = module.get.tabElement(tabPath),
538
+ $deactiveTabs = settings.deactivate === 'siblings'
539
+ ? $tab.siblings($tabs)
540
+ : $tabs.not($tab),
541
+ isActive = $tab.hasClass(className.active)
542
+ ;
543
+ module.verbose('Showing tab content for', $tab);
544
+ if (!isActive) {
545
+ $tab
546
+ .addClass(className.active)
547
+ ;
548
+ $deactiveTabs
549
+ .removeClass(className.active + ' ' + className.loading)
550
+ ;
551
+ if ($tab.length > 0) {
552
+ settings.onVisible.call($tab[0], tabPath);
553
+ }
554
+ }
555
+ },
556
+ navigation: function (tabPath) {
557
+ var
558
+ $navigation = module.get.navElement(tabPath),
559
+ $deactiveNavigation = settings.deactivate === 'siblings'
560
+ ? $navigation.siblings($allModules)
561
+ : $allModules.not($navigation),
562
+ isActive = $navigation.hasClass(className.active)
563
+ ;
564
+ module.verbose('Activating tab navigation for', $navigation, tabPath);
565
+ if (!isActive) {
566
+ $navigation
567
+ .addClass(className.active)
568
+ ;
569
+ $deactiveNavigation
570
+ .removeClass(className.active + ' ' + className.loading)
571
+ ;
572
+ }
573
+ },
574
+ },
138
575
 
139
- determineTabs: function() {
140
- var
141
- $reference
142
- ;
576
+ deactivate: {
577
+ all: function () {
578
+ module.deactivate.navigation();
579
+ module.deactivate.tabs();
580
+ },
581
+ navigation: function () {
582
+ $allModules
583
+ .removeClass(className.active)
584
+ ;
585
+ },
586
+ tabs: function () {
587
+ $tabs
588
+ .removeClass(className.active + ' ' + className.loading)
589
+ ;
590
+ },
591
+ },
143
592
 
144
- // determine tab context
145
- if(settings.context === 'parent') {
146
- if($module.closest(selector.ui).length > 0) {
147
- $reference = $module.closest(selector.ui);
148
- module.verbose('Using closest UI element as parent', $reference);
149
- }
150
- else {
151
- $reference = $module;
152
- }
153
- $context = $reference.parent();
154
- module.verbose('Determined parent element for creating context', $context);
155
- }
156
- else if(settings.context) {
157
- $context = $(settings.context);
158
- module.verbose('Using selector for tab context', settings.context, $context);
159
- }
160
- else {
161
- $context = $('body');
162
- }
163
- // find tabs
164
- if(settings.childrenOnly) {
165
- $tabs = $context.children(selector.tabs);
166
- module.debug('Searching tab context children for tabs', $context, $tabs);
167
- }
168
- else {
169
- $tabs = $context.find(selector.tabs);
170
- module.debug('Searching tab context for tabs', $context, $tabs);
171
- }
172
- },
593
+ is: {
594
+ tab: function (tabName) {
595
+ return tabName !== undefined
596
+ ? module.get.tabElement(tabName).length > 0
597
+ : false;
598
+ },
599
+ },
173
600
 
174
- fix: {
175
- callbacks: function() {
176
- if( $.isPlainObject(parameters) && (parameters.onTabLoad || parameters.onTabInit) ) {
177
- if(parameters.onTabLoad) {
178
- parameters.onLoad = parameters.onTabLoad;
179
- delete parameters.onTabLoad;
180
- module.error(error.legacyLoad, parameters.onLoad);
181
- }
182
- if(parameters.onTabInit) {
183
- parameters.onFirstLoad = parameters.onTabInit;
184
- delete parameters.onTabInit;
185
- module.error(error.legacyInit, parameters.onFirstLoad);
186
- }
187
- settings = $.extend(true, {}, $.fn.tab.settings, parameters);
188
- }
189
- }
190
- },
601
+ get: {
602
+ initialPath: function () {
603
+ return $allModules.eq(0).data(metadata.tab) || $tabs.eq(0).data(metadata.tab);
604
+ },
605
+ path: function () {
606
+ return $.address.value();
607
+ },
608
+ // adds default tabs to tab path
609
+ defaultPathArray: function (tabPath) {
610
+ return module.utilities.pathToArray(module.get.defaultPath(tabPath));
611
+ },
612
+ defaultPath: function (tabPath) {
613
+ var
614
+ $defaultNav = $allModules.filter('[data-' + metadata.tab + '^="' + module.escape.string(tabPath) + '/"]').eq(0),
615
+ defaultTab = $defaultNav.data(metadata.tab) || false
616
+ ;
617
+ if (defaultTab) {
618
+ module.debug('Found default tab', defaultTab);
619
+ if (recursionDepth < settings.maxDepth) {
620
+ recursionDepth++;
621
+
622
+ return module.get.defaultPath(defaultTab);
623
+ }
624
+ module.error(error.recursion);
625
+ } else {
626
+ module.debug('No default tabs found for', tabPath, $tabs);
627
+ }
628
+ recursionDepth = 0;
629
+
630
+ return tabPath;
631
+ },
632
+ navElement: function (tabPath) {
633
+ tabPath = tabPath || activeTabPath;
634
+
635
+ return $allModules.filter('[data-' + metadata.tab + '="' + module.escape.string(tabPath) + '"]');
636
+ },
637
+ tabElement: function (tabPath) {
638
+ var
639
+ $fullPathTab,
640
+ $simplePathTab,
641
+ tabPathArray,
642
+ lastTab
643
+ ;
644
+ tabPath = tabPath || activeTabPath;
645
+ tabPathArray = module.utilities.pathToArray(tabPath);
646
+ lastTab = module.utilities.last(tabPathArray);
647
+ $fullPathTab = $tabs.filter('[data-' + metadata.tab + '="' + module.escape.string(tabPath) + '"]');
648
+ $simplePathTab = $tabs.filter('[data-' + metadata.tab + '="' + module.escape.string(lastTab) + '"]');
649
+
650
+ return $fullPathTab.length > 0
651
+ ? $fullPathTab
652
+ : $simplePathTab;
653
+ },
654
+ tab: function () {
655
+ return activeTabPath;
656
+ },
657
+ },
191
658
 
192
- initializeHistory: function() {
193
- module.debug('Initializing page state');
194
- if( $.address === undefined ) {
195
- module.error(error.state);
196
- return false;
197
- }
198
- else {
199
- if(settings.historyType == 'state') {
200
- module.debug('Using HTML5 to manage state');
201
- if(settings.path !== false) {
202
- $.address
203
- .history(true)
204
- .state(settings.path)
205
- ;
206
- }
207
- else {
208
- module.error(error.path);
209
- return false;
210
- }
211
- }
212
- $.address
213
- .bind('change', module.event.history.change)
214
- ;
215
- }
216
- },
659
+ determine: {
660
+ activeTab: function () {
661
+ var activeTab = null;
217
662
 
218
- event: {
219
- click: function(event) {
220
- var
221
- tabPath = $(this).data(metadata.tab)
222
- ;
223
- if(tabPath !== undefined) {
224
- if(settings.history) {
225
- module.verbose('Updating page state', event);
226
- $.address.value(tabPath);
227
- }
228
- else {
229
- module.verbose('Changing tab', event);
230
- module.changeTab(tabPath);
231
- }
232
- event.preventDefault();
233
- }
234
- else {
235
- module.debug('No tab specified');
236
- }
237
- },
238
- history: {
239
- change: function(event) {
240
- var
241
- tabPath = event.pathNames.join('/') || module.get.initialPath(),
242
- pageTitle = settings.templates.determineTitle(tabPath) || false
243
- ;
244
- module.performance.display();
245
- module.debug('History change event', tabPath, event);
246
- historyEvent = event;
247
- if(tabPath !== undefined) {
248
- module.changeTab(tabPath);
249
- }
250
- if(pageTitle) {
251
- $.address.title(pageTitle);
252
- }
253
- }
254
- }
255
- },
663
+ $tabs.each(function (_index, tab) {
664
+ var $tab = $(tab);
256
665
 
257
- refresh: function() {
258
- if(activeTabPath) {
259
- module.debug('Refreshing tab', activeTabPath);
260
- module.changeTab(activeTabPath);
261
- }
262
- },
666
+ if ($tab.hasClass(className.active)) {
667
+ var
668
+ tabPath = $(this).data(metadata.tab),
669
+ $anchor = $allModules.filter('[data-' + metadata.tab + '="' + module.escape.string(tabPath) + '"]')
670
+ ;
263
671
 
264
- cache: {
672
+ if ($anchor.hasClass(className.active)) {
673
+ activeTab = tabPath;
674
+ }
675
+ }
676
+ });
265
677
 
266
- read: function(cacheKey) {
267
- return (cacheKey !== undefined)
268
- ? cache[cacheKey]
269
- : false
270
- ;
271
- },
272
- add: function(cacheKey, content) {
273
- cacheKey = cacheKey || activeTabPath;
274
- module.debug('Adding cached content for', cacheKey);
275
- cache[cacheKey] = content;
276
- },
277
- remove: function(cacheKey) {
278
- cacheKey = cacheKey || activeTabPath;
279
- module.debug('Removing cached content for', cacheKey);
280
- delete cache[cacheKey];
281
- }
282
- },
678
+ return activeTab;
679
+ },
680
+ },
283
681
 
284
- escape: {
285
- string: function(text) {
286
- text = String(text);
287
- return text.replace(regExp.escape, '\\$&');
288
- }
289
- },
682
+ utilities: {
683
+ filterArray: function (keepArray, removeArray) {
684
+ return $.grep(keepArray, function (keepValue) {
685
+ return $.inArray(keepValue, removeArray) === -1;
686
+ });
687
+ },
688
+ last: function (array) {
689
+ return Array.isArray(array)
690
+ ? array[array.length - 1]
691
+ : false;
692
+ },
693
+ pathToArray: function (pathName) {
694
+ if (pathName === undefined) {
695
+ pathName = activeTabPath;
696
+ }
697
+
698
+ return typeof pathName === 'string'
699
+ ? pathName.split('/')
700
+ : [pathName];
701
+ },
702
+ arrayToPath: function (pathArray) {
703
+ return Array.isArray(pathArray)
704
+ ? pathArray.join('/')
705
+ : false;
706
+ },
707
+ },
290
708
 
291
- set: {
292
- auto: function() {
293
- var
294
- url = (typeof settings.path == 'string')
295
- ? settings.path.replace(/\/$/, '') + '/{$tab}'
296
- : '/{$tab}'
297
- ;
298
- module.verbose('Setting up automatic tab retrieval from server', url);
299
- if($.isPlainObject(settings.apiSettings)) {
300
- settings.apiSettings.url = url;
301
- }
302
- else {
303
- settings.apiSettings = {
304
- url: url
305
- };
306
- }
307
- },
308
- loading: function(tabPath) {
309
- var
310
- $tab = module.get.tabElement(tabPath),
311
- isLoading = $tab.hasClass(className.loading)
312
- ;
313
- if(!isLoading) {
314
- module.verbose('Setting loading state for', $tab);
315
- $tab
316
- .addClass(className.loading)
317
- .siblings($tabs)
318
- .removeClass(className.active + ' ' + className.loading)
319
- ;
320
- if($tab.length > 0) {
321
- settings.onRequest.call($tab[0], tabPath);
322
- }
709
+ setting: function (name, value) {
710
+ module.debug('Changing setting', name, value);
711
+ if ($.isPlainObject(name)) {
712
+ $.extend(true, settings, name);
713
+ } else if (value !== undefined) {
714
+ if ($.isPlainObject(settings[name])) {
715
+ $.extend(true, settings[name], value);
716
+ } else {
717
+ settings[name] = value;
718
+ }
719
+ } else {
720
+ return settings[name];
721
+ }
722
+ },
723
+ internal: function (name, value) {
724
+ if ($.isPlainObject(name)) {
725
+ $.extend(true, module, name);
726
+ } else if (value !== undefined) {
727
+ module[name] = value;
728
+ } else {
729
+ return module[name];
730
+ }
731
+ },
732
+ debug: function () {
733
+ if (!settings.silent && settings.debug) {
734
+ if (settings.performance) {
735
+ module.performance.log(arguments);
736
+ } else {
737
+ module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
738
+ module.debug.apply(console, arguments);
739
+ }
740
+ }
741
+ },
742
+ verbose: function () {
743
+ if (!settings.silent && settings.verbose && settings.debug) {
744
+ if (settings.performance) {
745
+ module.performance.log(arguments);
746
+ } else {
747
+ module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
748
+ module.verbose.apply(console, arguments);
749
+ }
750
+ }
751
+ },
752
+ error: function () {
753
+ if (!settings.silent) {
754
+ module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
755
+ module.error.apply(console, arguments);
756
+ }
757
+ },
758
+ performance: {
759
+ log: function (message) {
760
+ var
761
+ currentTime,
762
+ executionTime,
763
+ previousTime
764
+ ;
765
+ if (settings.performance) {
766
+ currentTime = Date.now();
767
+ previousTime = time || currentTime;
768
+ executionTime = currentTime - previousTime;
769
+ time = currentTime;
770
+ performance.push({
771
+ Name: message[0],
772
+ Arguments: [].slice.call(message, 1) || '',
773
+ Element: element,
774
+ 'Execution Time': executionTime,
775
+ });
776
+ }
777
+ clearTimeout(module.performance.timer);
778
+ module.performance.timer = setTimeout(module.performance.display, 500);
779
+ },
780
+ display: function () {
781
+ var
782
+ title = settings.name + ':',
783
+ totalTime = 0
784
+ ;
785
+ time = false;
786
+ clearTimeout(module.performance.timer);
787
+ $.each(performance, function (index, data) {
788
+ totalTime += data['Execution Time'];
789
+ });
790
+ title += ' ' + totalTime + 'ms';
791
+ if (moduleSelector) {
792
+ title += ' \'' + moduleSelector + '\'';
793
+ }
794
+ if (performance.length > 0) {
795
+ console.groupCollapsed(title);
796
+ if (console.table) {
797
+ console.table(performance);
798
+ } else {
799
+ $.each(performance, function (index, data) {
800
+ console.log(data.Name + ': ' + data['Execution Time'] + 'ms');
801
+ });
802
+ }
803
+ console.groupEnd();
804
+ }
805
+ performance = [];
806
+ },
807
+ },
808
+ invoke: function (query, passedArguments, context) {
809
+ var
810
+ object = instance,
811
+ maxDepth,
812
+ found,
813
+ response
814
+ ;
815
+ passedArguments = passedArguments || queryArguments;
816
+ context = context || element;
817
+ if (typeof query === 'string' && object !== undefined) {
818
+ query = query.split(/[ .]/);
819
+ maxDepth = query.length - 1;
820
+ $.each(query, function (depth, value) {
821
+ var camelCaseValue = depth !== maxDepth
822
+ ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
823
+ : query
824
+ ;
825
+ if ($.isPlainObject(object[camelCaseValue]) && (depth !== maxDepth)) {
826
+ object = object[camelCaseValue];
827
+ } else if (object[camelCaseValue] !== undefined) {
828
+ found = object[camelCaseValue];
829
+
830
+ return false;
831
+ } else if ($.isPlainObject(object[value]) && (depth !== maxDepth)) {
832
+ object = object[value];
833
+ } else if (object[value] !== undefined) {
834
+ found = object[value];
835
+
836
+ return false;
837
+ } else {
838
+ module.error(error.method, query);
839
+
840
+ return false;
841
+ }
842
+ });
843
+ }
844
+ if (isFunction(found)) {
845
+ response = found.apply(context, passedArguments);
846
+ } else if (found !== undefined) {
847
+ response = found;
848
+ }
849
+ if (Array.isArray(returnedValue)) {
850
+ returnedValue.push(response);
851
+ } else if (returnedValue !== undefined) {
852
+ returnedValue = [returnedValue, response];
853
+ } else if (response !== undefined) {
854
+ returnedValue = response;
855
+ }
856
+
857
+ return found;
858
+ },
859
+ };
860
+ if (methodInvoked) {
861
+ if (instance === undefined) {
862
+ module.initialize();
863
+ }
864
+ module.invoke(query);
865
+ } else {
866
+ if (instance !== undefined) {
867
+ instance.invoke('destroy');
868
+ }
869
+ module.initialize();
323
870
  }
324
- },
325
- state: function(state) {
326
- $.address.value(state);
327
- }
328
- },
871
+ });
329
872
 
330
- changeTab: function(tabPath) {
331
- var
332
- pushStateAvailable = (window.history && window.history.pushState),
333
- shouldIgnoreLoad = (pushStateAvailable && settings.ignoreFirstLoad && firstLoad),
334
- remoteContent = (settings.auto || $.isPlainObject(settings.apiSettings) ),
335
- // only add default path if not remote content
336
- pathArray = (remoteContent && !shouldIgnoreLoad)
337
- ? module.utilities.pathToArray(tabPath)
338
- : module.get.defaultPathArray(tabPath)
339
- ;
340
- tabPath = module.utilities.arrayToPath(pathArray);
341
- $.each(pathArray, function(index, tab) {
342
- var
343
- currentPathArray = pathArray.slice(0, index + 1),
344
- currentPath = module.utilities.arrayToPath(currentPathArray),
873
+ return returnedValue !== undefined
874
+ ? returnedValue
875
+ : this;
876
+ };
345
877
 
346
- isTab = module.is.tab(currentPath),
347
- isLastIndex = (index + 1 == pathArray.length),
878
+ // shortcut for tabbed content with no defined navigation
879
+ $.tab = function () {
880
+ $(window).tab.apply(this, arguments);
881
+ };
348
882
 
349
- $tab = module.get.tabElement(currentPath),
350
- $anchor,
351
- nextPathArray,
352
- nextPath,
353
- isLastTab
354
- ;
355
- module.verbose('Looking for tab', tab);
356
- if(isTab) {
357
- module.verbose('Tab was found', tab);
358
- // scope up
359
- activeTabPath = currentPath;
360
- parameterArray = module.utilities.filterArray(pathArray, currentPathArray);
361
-
362
- if(isLastIndex) {
363
- isLastTab = true;
364
- }
365
- else {
366
- nextPathArray = pathArray.slice(0, index + 2);
367
- nextPath = module.utilities.arrayToPath(nextPathArray);
368
- isLastTab = ( !module.is.tab(nextPath) );
369
- if(isLastTab) {
370
- module.verbose('Tab parameters found', nextPathArray);
371
- }
372
- }
373
- if(isLastTab && remoteContent) {
374
- if(!shouldIgnoreLoad) {
375
- module.activate.navigation(currentPath);
376
- module.fetch.content(currentPath, tabPath);
377
- }
378
- else {
379
- module.debug('Ignoring remote content on first tab load', currentPath);
380
- firstLoad = false;
381
- module.cache.add(tabPath, $tab.html());
382
- module.activate.all(currentPath);
383
- settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
384
- settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
385
- }
386
- return false;
387
- }
388
- else {
389
- module.debug('Opened local tab', currentPath);
390
- module.activate.all(currentPath);
391
- if( !module.cache.read(currentPath) ) {
392
- module.cache.add(currentPath, true);
393
- module.debug('First time tab loaded calling tab init');
394
- settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
395
- }
396
- settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
397
- }
883
+ $.fn.tab.settings = {
398
884
 
399
- }
400
- else if(tabPath.search('/') == -1 && tabPath !== '') {
401
- // look for in page anchor
402
- tabPath = module.escape.string(tabPath);
403
- $anchor = $('#' + tabPath + ', a[name="' + tabPath + '"]');
404
- currentPath = $anchor.closest('[data-tab]').data(metadata.tab);
405
- $tab = module.get.tabElement(currentPath);
406
- // if anchor exists use parent tab
407
- if($anchor && $anchor.length > 0 && currentPath) {
408
- module.debug('Anchor link used, opening parent tab', $tab, $anchor);
409
- if( !$tab.hasClass(className.active) ) {
410
- setTimeout(function() {
411
- module.scrollTo($anchor);
412
- }, 0);
413
- }
414
- module.activate.all(currentPath);
415
- if( !module.cache.read(currentPath) ) {
416
- module.cache.add(currentPath, true);
417
- module.debug('First time tab loaded calling tab init');
418
- settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
419
- }
420
- settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
421
- return false;
422
- }
423
- }
424
- else {
425
- module.error(error.missingTab, $module, $context, currentPath);
426
- return false;
427
- }
428
- });
429
- },
885
+ name: 'Tab',
886
+ namespace: 'tab',
430
887
 
431
- scrollTo: function($element) {
432
- var
433
- scrollOffset = ($element && $element.length > 0)
434
- ? $element.offset().top
435
- : false
436
- ;
437
- if(scrollOffset !== false) {
438
- module.debug('Forcing scroll to an in-page link in a hidden tab', scrollOffset, $element);
439
- $(document).scrollTop(scrollOffset);
440
- }
441
- },
888
+ silent: false,
889
+ debug: false,
890
+ verbose: false,
891
+ performance: true,
442
892
 
443
- update: {
444
- content: function(tabPath, html, evaluateScripts) {
445
- var
446
- $tab = module.get.tabElement(tabPath),
447
- tab = $tab[0]
448
- ;
449
- evaluateScripts = (evaluateScripts !== undefined)
450
- ? evaluateScripts
451
- : settings.evaluateScripts
452
- ;
453
- if(typeof settings.cacheType == 'string' && settings.cacheType.toLowerCase() == 'dom' && typeof html !== 'string') {
454
- $tab
455
- .empty()
456
- .append($(html).clone(true))
457
- ;
458
- }
459
- else {
460
- if(evaluateScripts) {
461
- module.debug('Updating HTML and evaluating inline scripts', tabPath, html);
462
- $tab.html(html);
463
- }
464
- else {
465
- module.debug('Updating HTML', tabPath, html);
466
- tab.innerHTML = html;
467
- }
468
- }
469
- }
470
- },
893
+ auto: false, // uses pjax style endpoints fetching content from same url with remote-content headers
894
+ history: false, // use browser history
895
+ historyType: 'hash', // #/ or html5 state
896
+ path: false, // base path of url
471
897
 
472
- fetch: {
898
+ context: false, // specify a context that tabs must appear inside
899
+ childrenOnly: false, // use only tabs that are children of context
900
+ maxDepth: 25, // max depth a tab can be nested
473
901
 
474
- content: function(tabPath, fullTabPath) {
475
- var
476
- $tab = module.get.tabElement(tabPath),
477
- apiSettings = {
478
- dataType : 'html',
479
- encodeParameters : false,
480
- on : 'now',
481
- cache : settings.alwaysRefresh,
482
- headers : {
483
- 'X-Remote': true
484
- },
485
- onSuccess : function(response) {
486
- if(settings.cacheType == 'response') {
487
- module.cache.add(fullTabPath, response);
488
- }
489
- module.update.content(tabPath, response);
490
- if(tabPath == activeTabPath) {
491
- module.debug('Content loaded', tabPath);
492
- module.activate.tab(tabPath);
493
- }
494
- else {
495
- module.debug('Content loaded in background', tabPath);
496
- }
497
- settings.onFirstLoad.call($tab[0], tabPath, parameterArray, historyEvent);
498
- settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent);
499
-
500
- if(settings.loadOnce) {
501
- module.cache.add(fullTabPath, true);
502
- }
503
- else if(typeof settings.cacheType == 'string' && settings.cacheType.toLowerCase() == 'dom' && $tab.children().length > 0) {
504
- setTimeout(function() {
505
- var
506
- $clone = $tab.children().clone(true)
507
- ;
508
- $clone = $clone.not('script');
509
- module.cache.add(fullTabPath, $clone);
510
- }, 0);
511
- }
512
- else {
513
- module.cache.add(fullTabPath, $tab.html());
514
- }
515
- },
516
- urlData: {
517
- tab: fullTabPath
518
- }
519
- },
520
- request = $tab.api('get request') || false,
521
- existingRequest = ( request && request.state() === 'pending' ),
522
- requestSettings,
523
- cachedContent
524
- ;
902
+ deactivate: 'siblings', // whether tabs should deactivate sibling menu elements or all elements initialized together
525
903
 
526
- fullTabPath = fullTabPath || tabPath;
527
- cachedContent = module.cache.read(fullTabPath);
904
+ alwaysRefresh: false, // load tab content new every tab click
905
+ cache: true, // cache the content requests to pull locally
906
+ loadOnce: false, // Whether tab data should only be loaded once when using remote content
907
+ cacheType: 'response', // Whether to cache exact response, or to html cache contents after scripts execute
908
+ ignoreFirstLoad: false, // don't load remote content on first load
528
909
 
910
+ apiSettings: false, // settings for api call
911
+ evaluateScripts: 'once', // whether inline scripts should be parsed (true/false/once). Once will not re-evaluate on cached content
912
+ autoTabActivation: true, // whether a non existing active tab will auto activate the first available tab
529
913
 
530
- if(settings.cache && cachedContent) {
531
- module.activate.tab(tabPath);
532
- module.debug('Adding cached content', fullTabPath);
533
- if(!settings.loadOnce) {
534
- if(settings.evaluateScripts == 'once') {
535
- module.update.content(tabPath, cachedContent, false);
536
- }
537
- else {
538
- module.update.content(tabPath, cachedContent);
539
- }
540
- }
541
- settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent);
542
- }
543
- else if(existingRequest) {
544
- module.set.loading(tabPath);
545
- module.debug('Content is already loading', fullTabPath);
546
- }
547
- else if($.api !== undefined) {
548
- requestSettings = $.extend(true, {}, settings.apiSettings, apiSettings);
549
- module.debug('Retrieving remote content', fullTabPath, requestSettings);
550
- module.set.loading(tabPath);
551
- $tab.api(requestSettings);
552
- }
553
- else {
554
- module.error(error.api);
555
- }
556
- }
557
- },
914
+ onFirstLoad: function (tabPath, parameterArray, historyEvent) {}, // called first time loaded
915
+ onLoad: function (tabPath, parameterArray, historyEvent) {}, // called on every load
916
+ onVisible: function (tabPath, parameterArray, historyEvent) {}, // called every time tab visible
917
+ onRequest: function (tabPath, parameterArray, historyEvent) {}, // called ever time a tab beings loading remote content
918
+ onBeforeChange: function (tabPath) {}, // called before a tab is about to be changed. Returning false will cancel the tab change
558
919
 
559
- activate: {
560
- all: function(tabPath) {
561
- module.activate.tab(tabPath);
562
- module.activate.navigation(tabPath);
563
- },
564
- tab: function(tabPath) {
565
- var
566
- $tab = module.get.tabElement(tabPath),
567
- $deactiveTabs = (settings.deactivate == 'siblings')
568
- ? $tab.siblings($tabs)
569
- : $tabs.not($tab),
570
- isActive = $tab.hasClass(className.active)
571
- ;
572
- module.verbose('Showing tab content for', $tab);
573
- if(!isActive) {
574
- $tab
575
- .addClass(className.active)
576
- ;
577
- $deactiveTabs
578
- .removeClass(className.active + ' ' + className.loading)
579
- ;
580
- if($tab.length > 0) {
581
- settings.onVisible.call($tab[0], tabPath);
582
- }
583
- }
584
- },
585
- navigation: function(tabPath) {
586
- var
587
- $navigation = module.get.navElement(tabPath),
588
- $deactiveNavigation = (settings.deactivate == 'siblings')
589
- ? $navigation.siblings($allModules)
590
- : $allModules.not($navigation),
591
- isActive = $navigation.hasClass(className.active)
592
- ;
593
- module.verbose('Activating tab navigation for', $navigation, tabPath);
594
- if(!isActive) {
595
- $navigation
596
- .addClass(className.active)
597
- ;
598
- $deactiveNavigation
599
- .removeClass(className.active + ' ' + className.loading)
600
- ;
601
- }
602
- }
920
+ templates: {
921
+ determineTitle: function (tabArray) {}, // returns page title for path
603
922
  },
604
923
 
605
- deactivate: {
606
- all: function() {
607
- module.deactivate.navigation();
608
- module.deactivate.tabs();
609
- },
610
- navigation: function() {
611
- $allModules
612
- .removeClass(className.active)
613
- ;
614
- },
615
- tabs: function() {
616
- $tabs
617
- .removeClass(className.active + ' ' + className.loading)
618
- ;
619
- }
924
+ error: {
925
+ api: 'You attempted to load content without API module',
926
+ method: 'The method you called is not defined',
927
+ missingTab: 'Activated tab cannot be found. Tabs are case-sensitive.',
928
+ noContent: 'The tab you specified is missing a content url.',
929
+ path: 'History enabled, but no path was specified',
930
+ recursion: 'Max recursive depth reached',
931
+ state: 'History requires Asual\'s Address library <https://github.com/asual/jquery-address>',
620
932
  },
621
933
 
622
- is: {
623
- tab: function(tabName) {
624
- return (tabName !== undefined)
625
- ? ( module.get.tabElement(tabName).length > 0 )
626
- : false
627
- ;
628
- }
934
+ regExp: {
935
+ escape: /[\s#$()*+,.:=?@[\\\]^{|}-]/g,
629
936
  },
630
937
 
631
- get: {
632
- initialPath: function() {
633
- return $allModules.eq(0).data(metadata.tab) || $tabs.eq(0).data(metadata.tab);
634
- },
635
- path: function() {
636
- return $.address.value();
637
- },
638
- // adds default tabs to tab path
639
- defaultPathArray: function(tabPath) {
640
- return module.utilities.pathToArray( module.get.defaultPath(tabPath) );
641
- },
642
- defaultPath: function(tabPath) {
643
- var
644
- $defaultNav = $allModules.filter('[data-' + metadata.tab + '^="' + module.escape.string(tabPath) + '/"]').eq(0),
645
- defaultTab = $defaultNav.data(metadata.tab) || false
646
- ;
647
- if( defaultTab ) {
648
- module.debug('Found default tab', defaultTab);
649
- if(recursionDepth < settings.maxDepth) {
650
- recursionDepth++;
651
- return module.get.defaultPath(defaultTab);
652
- }
653
- module.error(error.recursion);
654
- }
655
- else {
656
- module.debug('No default tabs found for', tabPath, $tabs);
657
- }
658
- recursionDepth = 0;
659
- return tabPath;
660
- },
661
- navElement: function(tabPath) {
662
- tabPath = tabPath || activeTabPath;
663
- return $allModules.filter('[data-' + metadata.tab + '="' + module.escape.string(tabPath) + '"]');
664
- },
665
- tabElement: function(tabPath) {
666
- var
667
- $fullPathTab,
668
- $simplePathTab,
669
- tabPathArray,
670
- lastTab
671
- ;
672
- tabPath = tabPath || activeTabPath;
673
- tabPathArray = module.utilities.pathToArray(tabPath);
674
- lastTab = module.utilities.last(tabPathArray);
675
- $fullPathTab = $tabs.filter('[data-' + metadata.tab + '="' + module.escape.string(tabPath) + '"]');
676
- $simplePathTab = $tabs.filter('[data-' + metadata.tab + '="' + module.escape.string(lastTab) + '"]');
677
- return ($fullPathTab.length > 0)
678
- ? $fullPathTab
679
- : $simplePathTab
680
- ;
681
- },
682
- tab: function() {
683
- return activeTabPath;
684
- }
938
+ metadata: {
939
+ tab: 'tab',
940
+ loaded: 'loaded',
941
+ promise: 'promise',
685
942
  },
686
943
 
687
- determine: {
688
- activeTab: function() {
689
- var activeTab = null;
690
-
691
- $tabs.each(function(_index, tab) {
692
- var $tab = $(tab);
693
-
694
- if( $tab.hasClass(className.active) ) {
695
- var
696
- tabPath = $(this).data(metadata.tab),
697
- $anchor = $allModules.filter('[data-' + metadata.tab + '="' + module.escape.string(tabPath) + '"]')
698
- ;
699
-
700
- if( $anchor.hasClass(className.active) ) {
701
- activeTab = tabPath;
702
- }
703
- }
704
- });
705
-
706
- return activeTab;
707
- }
944
+ className: {
945
+ loading: 'loading',
946
+ active: 'active',
708
947
  },
709
948
 
710
- utilities: {
711
- filterArray: function(keepArray, removeArray) {
712
- return $.grep(keepArray, function(keepValue) {
713
- return ( $.inArray(keepValue, removeArray) == -1);
714
- });
715
- },
716
- last: function(array) {
717
- return Array.isArray(array)
718
- ? array[ array.length - 1]
719
- : false
720
- ;
721
- },
722
- pathToArray: function(pathName) {
723
- if(pathName === undefined) {
724
- pathName = activeTabPath;
725
- }
726
- return typeof pathName == 'string'
727
- ? pathName.split('/')
728
- : [pathName]
729
- ;
730
- },
731
- arrayToPath: function(pathArray) {
732
- return Array.isArray(pathArray)
733
- ? pathArray.join('/')
734
- : false
735
- ;
736
- }
949
+ selector: {
950
+ tabs: '.ui.tab',
951
+ ui: '.ui',
737
952
  },
738
953
 
739
- setting: function(name, value) {
740
- module.debug('Changing setting', name, value);
741
- if( $.isPlainObject(name) ) {
742
- $.extend(true, settings, name);
743
- }
744
- else if(value !== undefined) {
745
- if($.isPlainObject(settings[name])) {
746
- $.extend(true, settings[name], value);
747
- }
748
- else {
749
- settings[name] = value;
750
- }
751
- }
752
- else {
753
- return settings[name];
754
- }
755
- },
756
- internal: function(name, value) {
757
- if( $.isPlainObject(name) ) {
758
- $.extend(true, module, name);
759
- }
760
- else if(value !== undefined) {
761
- module[name] = value;
762
- }
763
- else {
764
- return module[name];
765
- }
766
- },
767
- debug: function() {
768
- if(!settings.silent && settings.debug) {
769
- if(settings.performance) {
770
- module.performance.log(arguments);
771
- }
772
- else {
773
- module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
774
- module.debug.apply(console, arguments);
775
- }
776
- }
777
- },
778
- verbose: function() {
779
- if(!settings.silent && settings.verbose && settings.debug) {
780
- if(settings.performance) {
781
- module.performance.log(arguments);
782
- }
783
- else {
784
- module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
785
- module.verbose.apply(console, arguments);
786
- }
787
- }
788
- },
789
- error: function() {
790
- if(!settings.silent) {
791
- module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
792
- module.error.apply(console, arguments);
793
- }
794
- },
795
- performance: {
796
- log: function(message) {
797
- var
798
- currentTime,
799
- executionTime,
800
- previousTime
801
- ;
802
- if(settings.performance) {
803
- currentTime = new Date().getTime();
804
- previousTime = time || currentTime;
805
- executionTime = currentTime - previousTime;
806
- time = currentTime;
807
- performance.push({
808
- 'Name' : message[0],
809
- 'Arguments' : [].slice.call(message, 1) || '',
810
- 'Element' : element,
811
- 'Execution Time' : executionTime
812
- });
813
- }
814
- clearTimeout(module.performance.timer);
815
- module.performance.timer = setTimeout(module.performance.display, 500);
816
- },
817
- display: function() {
818
- var
819
- title = settings.name + ':',
820
- totalTime = 0
821
- ;
822
- time = false;
823
- clearTimeout(module.performance.timer);
824
- $.each(performance, function(index, data) {
825
- totalTime += data['Execution Time'];
826
- });
827
- title += ' ' + totalTime + 'ms';
828
- if(moduleSelector) {
829
- title += ' \'' + moduleSelector + '\'';
830
- }
831
- if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
832
- console.groupCollapsed(title);
833
- if(console.table) {
834
- console.table(performance);
835
- }
836
- else {
837
- $.each(performance, function(index, data) {
838
- console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
839
- });
840
- }
841
- console.groupEnd();
842
- }
843
- performance = [];
844
- }
845
- },
846
- invoke: function(query, passedArguments, context) {
847
- var
848
- object = instance,
849
- maxDepth,
850
- found,
851
- response
852
- ;
853
- passedArguments = passedArguments || queryArguments;
854
- context = element || context;
855
- if(typeof query == 'string' && object !== undefined) {
856
- query = query.split(/[\. ]/);
857
- maxDepth = query.length - 1;
858
- $.each(query, function(depth, value) {
859
- var camelCaseValue = (depth != maxDepth)
860
- ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
861
- : query
862
- ;
863
- if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
864
- object = object[camelCaseValue];
865
- }
866
- else if( object[camelCaseValue] !== undefined ) {
867
- found = object[camelCaseValue];
868
- return false;
869
- }
870
- else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
871
- object = object[value];
872
- }
873
- else if( object[value] !== undefined ) {
874
- found = object[value];
875
- return false;
876
- }
877
- else {
878
- module.error(error.method, query);
879
- return false;
880
- }
881
- });
882
- }
883
- if ( $.isFunction( found ) ) {
884
- response = found.apply(context, passedArguments);
885
- }
886
- else if(found !== undefined) {
887
- response = found;
888
- }
889
- if(Array.isArray(returnedValue)) {
890
- returnedValue.push(response);
891
- }
892
- else if(returnedValue !== undefined) {
893
- returnedValue = [returnedValue, response];
894
- }
895
- else if(response !== undefined) {
896
- returnedValue = response;
897
- }
898
- return found;
899
- }
900
- };
901
- if(methodInvoked) {
902
- if(instance === undefined) {
903
- module.initialize();
904
- }
905
- module.invoke(query);
906
- }
907
- else {
908
- if(instance !== undefined) {
909
- instance.invoke('destroy');
910
- }
911
- module.initialize();
912
- }
913
- })
914
- ;
915
- return (returnedValue !== undefined)
916
- ? returnedValue
917
- : this
918
- ;
919
-
920
- };
921
-
922
- // shortcut for tabbed content with no defined navigation
923
- $.tab = function() {
924
- $(window).tab.apply(this, arguments);
925
- };
926
-
927
- $.fn.tab.settings = {
928
-
929
- name : 'Tab',
930
- namespace : 'tab',
931
-
932
- silent : false,
933
- debug : false,
934
- verbose : false,
935
- performance : true,
936
-
937
- auto : false, // uses pjax style endpoints fetching content from same url with remote-content headers
938
- history : false, // use browser history
939
- historyType : 'hash', // #/ or html5 state
940
- path : false, // base path of url
941
-
942
- context : false, // specify a context that tabs must appear inside
943
- childrenOnly : false, // use only tabs that are children of context
944
- maxDepth : 25, // max depth a tab can be nested
945
-
946
- deactivate : 'siblings', // whether tabs should deactivate sibling menu elements or all elements initialized together
947
-
948
- alwaysRefresh : false, // load tab content new every tab click
949
- cache : true, // cache the content requests to pull locally
950
- loadOnce : false, // Whether tab data should only be loaded once when using remote content
951
- cacheType : 'response', // Whether to cache exact response, or to html cache contents after scripts execute
952
- ignoreFirstLoad : false, // don't load remote content on first load
953
-
954
- apiSettings : false, // settings for api call
955
- evaluateScripts : 'once', // whether inline scripts should be parsed (true/false/once). Once will not re-evaluate on cached content
956
-
957
- onFirstLoad : function(tabPath, parameterArray, historyEvent) {}, // called first time loaded
958
- onLoad : function(tabPath, parameterArray, historyEvent) {}, // called on every load
959
- onVisible : function(tabPath, parameterArray, historyEvent) {}, // called every time tab visible
960
- onRequest : function(tabPath, parameterArray, historyEvent) {}, // called ever time a tab beings loading remote content
961
-
962
- templates : {
963
- determineTitle: function(tabArray) {} // returns page title for path
964
- },
965
-
966
- error: {
967
- api : 'You attempted to load content without API module',
968
- method : 'The method you called is not defined',
969
- missingTab : 'Activated tab cannot be found. Tabs are case-sensitive.',
970
- noContent : 'The tab you specified is missing a content url.',
971
- path : 'History enabled, but no path was specified',
972
- recursion : 'Max recursive depth reached',
973
- legacyInit : 'onTabInit has been renamed to onFirstLoad in 2.0, please adjust your code.',
974
- legacyLoad : 'onTabLoad has been renamed to onLoad in 2.0. Please adjust your code',
975
- state : 'History requires Asual\'s Address library <https://github.com/asual/jquery-address>'
976
- },
977
-
978
- regExp : {
979
- escape : /[-[\]{}()*+?.,\\^$|#\s:=@]/g
980
- },
981
-
982
- metadata : {
983
- tab : 'tab',
984
- loaded : 'loaded',
985
- promise: 'promise'
986
- },
987
-
988
- className : {
989
- loading : 'loading',
990
- active : 'active'
991
- },
992
-
993
- selector : {
994
- tabs : '.ui.tab',
995
- ui : '.ui'
996
- }
997
-
998
- };
999
-
1000
- })( jQuery, window, document );
954
+ };
955
+ })(jQuery, window, document);