You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

897 lines
30 KiB

9 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. /*!
  2. * # Semantic UI 2.1.0 - Tab
  3. * http://github.com/semantic-org/semantic-ui/
  4. *
  5. *
  6. * Copyright 2015 Contributors
  7. * Released under the MIT license
  8. * http://opensource.org/licenses/MIT
  9. *
  10. */
  11. ;(function ($, window, document, undefined) {
  12. "use strict";
  13. $.fn.tab = function(parameters) {
  14. var
  15. // use window context if none specified
  16. $allModules = $.isFunction(this)
  17. ? $(window)
  18. : $(this),
  19. moduleSelector = $allModules.selector || '',
  20. time = new Date().getTime(),
  21. performance = [],
  22. query = arguments[0],
  23. methodInvoked = (typeof query == 'string'),
  24. queryArguments = [].slice.call(arguments, 1),
  25. initializedHistory = false,
  26. returnedValue
  27. ;
  28. $allModules
  29. .each(function() {
  30. var
  31. settings = ( $.isPlainObject(parameters) )
  32. ? $.extend(true, {}, $.fn.tab.settings, parameters)
  33. : $.extend({}, $.fn.tab.settings),
  34. className = settings.className,
  35. metadata = settings.metadata,
  36. selector = settings.selector,
  37. error = settings.error,
  38. eventNamespace = '.' + settings.namespace,
  39. moduleNamespace = 'module-' + settings.namespace,
  40. $module = $(this),
  41. $context,
  42. $tabs,
  43. cache = {},
  44. firstLoad = true,
  45. recursionDepth = 0,
  46. element = this,
  47. instance = $module.data(moduleNamespace),
  48. activeTabPath,
  49. parameterArray,
  50. module,
  51. historyEvent
  52. ;
  53. module = {
  54. initialize: function() {
  55. module.debug('Initializing tab menu item', $module);
  56. module.fix.callbacks();
  57. module.determineTabs();
  58. module.debug('Determining tabs', settings.context, $tabs);
  59. // set up automatic routing
  60. if(settings.auto) {
  61. module.set.auto();
  62. }
  63. module.bind.events();
  64. if(settings.history && !initializedHistory) {
  65. module.initializeHistory();
  66. initializedHistory = true;
  67. }
  68. module.instantiate();
  69. },
  70. instantiate: function () {
  71. module.verbose('Storing instance of module', module);
  72. instance = module;
  73. $module
  74. .data(moduleNamespace, module)
  75. ;
  76. },
  77. destroy: function() {
  78. module.debug('Destroying tabs', $module);
  79. $module
  80. .removeData(moduleNamespace)
  81. .off(eventNamespace)
  82. ;
  83. },
  84. bind: {
  85. events: function() {
  86. // if using $.tab dont add events
  87. if( !$.isWindow( element ) ) {
  88. module.debug('Attaching tab activation events to element', $module);
  89. $module
  90. .on('click' + eventNamespace, module.event.click)
  91. ;
  92. }
  93. }
  94. },
  95. determineTabs: function() {
  96. var
  97. $reference
  98. ;
  99. // determine tab context
  100. if(settings.context === 'parent') {
  101. if($module.closest(selector.ui).length > 0) {
  102. $reference = $module.closest(selector.ui);
  103. module.verbose('Using closest UI element as parent', $reference);
  104. }
  105. else {
  106. $reference = $module;
  107. }
  108. $context = $reference.parent();
  109. module.verbose('Determined parent element for creating context', $context);
  110. }
  111. else if(settings.context) {
  112. $context = $(settings.context);
  113. module.verbose('Using selector for tab context', settings.context, $context);
  114. }
  115. else {
  116. $context = $('body');
  117. }
  118. // find tabs
  119. if(settings.childrenOnly) {
  120. $tabs = $context.children(selector.tabs);
  121. module.debug('Searching tab context children for tabs', $context, $tabs);
  122. }
  123. else {
  124. $tabs = $context.find(selector.tabs);
  125. module.debug('Searching tab context for tabs', $context, $tabs);
  126. }
  127. },
  128. fix: {
  129. callbacks: function() {
  130. if( $.isPlainObject(parameters) && (parameters.onTabLoad || parameters.onTabInit) ) {
  131. if(parameters.onTabLoad) {
  132. parameters.onLoad = parameters.onTabLoad;
  133. delete parameters.onTabLoad;
  134. module.error(error.legacyLoad, parameters.onLoad);
  135. }
  136. if(parameters.onTabInit) {
  137. parameters.onFirstLoad = parameters.onTabInit;
  138. delete parameters.onTabInit;
  139. module.error(error.legacyInit, parameters.onFirstLoad);
  140. }
  141. settings = $.extend(true, {}, $.fn.tab.settings, parameters);
  142. }
  143. }
  144. },
  145. initializeHistory: function() {
  146. module.debug('Initializing page state');
  147. if( $.address === undefined ) {
  148. module.error(error.state);
  149. return false;
  150. }
  151. else {
  152. if(settings.historyType == 'state') {
  153. module.debug('Using HTML5 to manage state');
  154. if(settings.path !== false) {
  155. $.address
  156. .history(true)
  157. .state(settings.path)
  158. ;
  159. }
  160. else {
  161. module.error(error.path);
  162. return false;
  163. }
  164. }
  165. $.address
  166. .bind('change', module.event.history.change)
  167. ;
  168. }
  169. },
  170. event: {
  171. click: function(event) {
  172. var
  173. tabPath = $(this).data(metadata.tab)
  174. ;
  175. if(tabPath !== undefined) {
  176. if(settings.history) {
  177. module.verbose('Updating page state', event);
  178. $.address.value(tabPath);
  179. }
  180. else {
  181. module.verbose('Changing tab', event);
  182. module.changeTab(tabPath);
  183. }
  184. event.preventDefault();
  185. }
  186. else {
  187. module.debug('No tab specified');
  188. }
  189. },
  190. history: {
  191. change: function(event) {
  192. var
  193. tabPath = event.pathNames.join('/') || module.get.initialPath(),
  194. pageTitle = settings.templates.determineTitle(tabPath) || false
  195. ;
  196. module.performance.display();
  197. module.debug('History change event', tabPath, event);
  198. historyEvent = event;
  199. if(tabPath !== undefined) {
  200. module.changeTab(tabPath);
  201. }
  202. if(pageTitle) {
  203. $.address.title(pageTitle);
  204. }
  205. }
  206. }
  207. },
  208. refresh: function() {
  209. if(activeTabPath) {
  210. module.debug('Refreshing tab', activeTabPath);
  211. module.changeTab(activeTabPath);
  212. }
  213. },
  214. cache: {
  215. read: function(cacheKey) {
  216. return (cacheKey !== undefined)
  217. ? cache[cacheKey]
  218. : false
  219. ;
  220. },
  221. add: function(cacheKey, content) {
  222. cacheKey = cacheKey || activeTabPath;
  223. module.debug('Adding cached content for', cacheKey);
  224. cache[cacheKey] = content;
  225. },
  226. remove: function(cacheKey) {
  227. cacheKey = cacheKey || activeTabPath;
  228. module.debug('Removing cached content for', cacheKey);
  229. delete cache[cacheKey];
  230. }
  231. },
  232. set: {
  233. auto: function() {
  234. var
  235. url = (typeof settings.path == 'string')
  236. ? settings.path.replace(/\/$/, '') + '/{$tab}'
  237. : '/{$tab}'
  238. ;
  239. module.verbose('Setting up automatic tab retrieval from server', url);
  240. if($.isPlainObject(settings.apiSettings)) {
  241. settings.apiSettings.url = url;
  242. }
  243. else {
  244. settings.apiSettings = {
  245. url: url
  246. };
  247. }
  248. },
  249. loading: function(tabPath) {
  250. var
  251. $tab = module.get.tabElement(tabPath),
  252. isLoading = $tab.hasClass(className.loading)
  253. ;
  254. if(!isLoading) {
  255. module.verbose('Setting loading state for', $tab);
  256. $tab
  257. .addClass(className.loading)
  258. .siblings($tabs)
  259. .removeClass(className.active + ' ' + className.loading)
  260. ;
  261. if($tab.length > 0) {
  262. settings.onRequest.call($tab[0], tabPath);
  263. }
  264. }
  265. },
  266. state: function(state) {
  267. $.address.value(state);
  268. }
  269. },
  270. changeTab: function(tabPath) {
  271. var
  272. pushStateAvailable = (window.history && window.history.pushState),
  273. shouldIgnoreLoad = (pushStateAvailable && settings.ignoreFirstLoad && firstLoad),
  274. remoteContent = (settings.auto || $.isPlainObject(settings.apiSettings) ),
  275. // only add default path if not remote content
  276. pathArray = (remoteContent && !shouldIgnoreLoad)
  277. ? module.utilities.pathToArray(tabPath)
  278. : module.get.defaultPathArray(tabPath)
  279. ;
  280. tabPath = module.utilities.arrayToPath(pathArray);
  281. $.each(pathArray, function(index, tab) {
  282. var
  283. currentPathArray = pathArray.slice(0, index + 1),
  284. currentPath = module.utilities.arrayToPath(currentPathArray),
  285. isTab = module.is.tab(currentPath),
  286. isLastIndex = (index + 1 == pathArray.length),
  287. $tab = module.get.tabElement(currentPath),
  288. $anchor,
  289. nextPathArray,
  290. nextPath,
  291. isLastTab
  292. ;
  293. module.verbose('Looking for tab', tab);
  294. if(isTab) {
  295. module.verbose('Tab was found', tab);
  296. // scope up
  297. activeTabPath = currentPath;
  298. parameterArray = module.utilities.filterArray(pathArray, currentPathArray);
  299. if(isLastIndex) {
  300. isLastTab = true;
  301. }
  302. else {
  303. nextPathArray = pathArray.slice(0, index + 2);
  304. nextPath = module.utilities.arrayToPath(nextPathArray);
  305. isLastTab = ( !module.is.tab(nextPath) );
  306. if(isLastTab) {
  307. module.verbose('Tab parameters found', nextPathArray);
  308. }
  309. }
  310. if(isLastTab && remoteContent) {
  311. if(!shouldIgnoreLoad) {
  312. module.activate.navigation(currentPath);
  313. module.fetch.content(currentPath, tabPath);
  314. }
  315. else {
  316. module.debug('Ignoring remote content on first tab load', currentPath);
  317. firstLoad = false;
  318. module.cache.add(tabPath, $tab.html());
  319. module.activate.all(currentPath);
  320. settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
  321. settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
  322. }
  323. return false;
  324. }
  325. else {
  326. module.debug('Opened local tab', currentPath);
  327. module.activate.all(currentPath);
  328. if( !module.cache.read(currentPath) ) {
  329. module.cache.add(currentPath, true);
  330. module.debug('First time tab loaded calling tab init');
  331. settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
  332. }
  333. settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
  334. }
  335. }
  336. else if(tabPath.search('/') == -1 && tabPath !== '') {
  337. // look for in page anchor
  338. $anchor = $('#' + tabPath + ', a[name="' + tabPath + '"]');
  339. currentPath = $anchor.closest('[data-tab]').data(metadata.tab);
  340. $tab = module.get.tabElement(currentPath);
  341. // if anchor exists use parent tab
  342. if($anchor && $anchor.length > 0 && currentPath) {
  343. module.debug('Anchor link used, opening parent tab', $tab, $anchor);
  344. if( !$tab.hasClass(className.active) ) {
  345. setTimeout(function() {
  346. module.scrollTo($anchor);
  347. }, 0);
  348. }
  349. module.activate.all(currentPath);
  350. if( !module.cache.read(currentPath) ) {
  351. module.cache.add(currentPath, true);
  352. module.debug('First time tab loaded calling tab init');
  353. settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
  354. }
  355. settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
  356. return false;
  357. }
  358. }
  359. else {
  360. module.error(error.missingTab, $module, $context, currentPath);
  361. return false;
  362. }
  363. });
  364. },
  365. scrollTo: function($element) {
  366. var
  367. scrollOffset = ($element && $element.length > 0)
  368. ? $element.offset().top
  369. : false
  370. ;
  371. if(scrollOffset !== false) {
  372. module.debug('Forcing scroll to an in-page link in a hidden tab', scrollOffset, $element);
  373. $(document).scrollTop(scrollOffset);
  374. }
  375. },
  376. update: {
  377. content: function(tabPath, html, evaluateScripts) {
  378. var
  379. $tab = module.get.tabElement(tabPath),
  380. tab = $tab[0]
  381. ;
  382. evaluateScripts = (evaluateScripts !== undefined)
  383. ? evaluateScripts
  384. : settings.evaluateScripts
  385. ;
  386. if(evaluateScripts) {
  387. module.debug('Updating HTML and evaluating inline scripts', tabPath, html);
  388. $tab.html(html);
  389. }
  390. else {
  391. module.debug('Updating HTML', tabPath, html);
  392. tab.innerHTML = html;
  393. }
  394. }
  395. },
  396. fetch: {
  397. content: function(tabPath, fullTabPath) {
  398. var
  399. $tab = module.get.tabElement(tabPath),
  400. apiSettings = {
  401. dataType : 'html',
  402. encodeParameters : false,
  403. on : 'now',
  404. cache : settings.alwaysRefresh,
  405. headers : {
  406. 'X-Remote': true
  407. },
  408. onSuccess : function(response) {
  409. module.cache.add(fullTabPath, response);
  410. module.update.content(tabPath, response);
  411. if(tabPath == activeTabPath) {
  412. module.debug('Content loaded', tabPath);
  413. module.activate.tab(tabPath);
  414. }
  415. else {
  416. module.debug('Content loaded in background', tabPath);
  417. }
  418. settings.onFirstLoad.call($tab[0], tabPath, parameterArray, historyEvent);
  419. settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent);
  420. },
  421. urlData: {
  422. tab: fullTabPath
  423. }
  424. },
  425. request = $tab.api('get request') || false,
  426. existingRequest = ( request && request.state() === 'pending' ),
  427. requestSettings,
  428. cachedContent
  429. ;
  430. fullTabPath = fullTabPath || tabPath;
  431. cachedContent = module.cache.read(fullTabPath);
  432. if(settings.cache && cachedContent) {
  433. module.activate.tab(tabPath);
  434. module.debug('Adding cached content', fullTabPath);
  435. if(settings.evaluateScripts == 'once') {
  436. module.update.content(tabPath, cachedContent, false);
  437. }
  438. else {
  439. module.update.content(tabPath, cachedContent);
  440. }
  441. settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent);
  442. }
  443. else if(existingRequest) {
  444. module.set.loading(tabPath);
  445. module.debug('Content is already loading', fullTabPath);
  446. }
  447. else if($.api !== undefined) {
  448. requestSettings = $.extend(true, {}, settings.apiSettings, apiSettings);
  449. module.debug('Retrieving remote content', fullTabPath, requestSettings);
  450. module.set.loading(tabPath);
  451. $tab.api(requestSettings);
  452. }
  453. else {
  454. module.error(error.api);
  455. }
  456. }
  457. },
  458. activate: {
  459. all: function(tabPath) {
  460. module.activate.tab(tabPath);
  461. module.activate.navigation(tabPath);
  462. },
  463. tab: function(tabPath) {
  464. var
  465. $tab = module.get.tabElement(tabPath),
  466. isActive = $tab.hasClass(className.active)
  467. ;
  468. module.verbose('Showing tab content for', $tab);
  469. if(!isActive) {
  470. $tab
  471. .addClass(className.active)
  472. .siblings($tabs)
  473. .removeClass(className.active + ' ' + className.loading)
  474. ;
  475. if($tab.length > 0) {
  476. settings.onVisible.call($tab[0], tabPath);
  477. }
  478. }
  479. },
  480. navigation: function(tabPath) {
  481. var
  482. $navigation = module.get.navElement(tabPath),
  483. isActive = $navigation.hasClass(className.active)
  484. ;
  485. module.verbose('Activating tab navigation for', $navigation, tabPath);
  486. if(!isActive) {
  487. $navigation
  488. .addClass(className.active)
  489. .siblings($allModules)
  490. .removeClass(className.active + ' ' + className.loading)
  491. ;
  492. }
  493. }
  494. },
  495. deactivate: {
  496. all: function() {
  497. module.deactivate.navigation();
  498. module.deactivate.tabs();
  499. },
  500. navigation: function() {
  501. $allModules
  502. .removeClass(className.active)
  503. ;
  504. },
  505. tabs: function() {
  506. $tabs
  507. .removeClass(className.active + ' ' + className.loading)
  508. ;
  509. }
  510. },
  511. is: {
  512. tab: function(tabName) {
  513. return (tabName !== undefined)
  514. ? ( module.get.tabElement(tabName).length > 0 )
  515. : false
  516. ;
  517. }
  518. },
  519. get: {
  520. initialPath: function() {
  521. return $allModules.eq(0).data(metadata.tab) || $tabs.eq(0).data(metadata.tab);
  522. },
  523. path: function() {
  524. return $.address.value();
  525. },
  526. // adds default tabs to tab path
  527. defaultPathArray: function(tabPath) {
  528. return module.utilities.pathToArray( module.get.defaultPath(tabPath) );
  529. },
  530. defaultPath: function(tabPath) {
  531. var
  532. $defaultNav = $allModules.filter('[data-' + metadata.tab + '^="' + tabPath + '/"]').eq(0),
  533. defaultTab = $defaultNav.data(metadata.tab) || false
  534. ;
  535. if( defaultTab ) {
  536. module.debug('Found default tab', defaultTab);
  537. if(recursionDepth < settings.maxDepth) {
  538. recursionDepth++;
  539. return module.get.defaultPath(defaultTab);
  540. }
  541. module.error(error.recursion);
  542. }
  543. else {
  544. module.debug('No default tabs found for', tabPath, $tabs);
  545. }
  546. recursionDepth = 0;
  547. return tabPath;
  548. },
  549. navElement: function(tabPath) {
  550. tabPath = tabPath || activeTabPath;
  551. return $allModules.filter('[data-' + metadata.tab + '="' + tabPath + '"]');
  552. },
  553. tabElement: function(tabPath) {
  554. var
  555. $fullPathTab,
  556. $simplePathTab,
  557. tabPathArray,
  558. lastTab
  559. ;
  560. tabPath = tabPath || activeTabPath;
  561. tabPathArray = module.utilities.pathToArray(tabPath);
  562. lastTab = module.utilities.last(tabPathArray);
  563. $fullPathTab = $tabs.filter('[data-' + metadata.tab + '="' + tabPath + '"]');
  564. $simplePathTab = $tabs.filter('[data-' + metadata.tab + '="' + lastTab + '"]');
  565. return ($fullPathTab.length > 0)
  566. ? $fullPathTab
  567. : $simplePathTab
  568. ;
  569. },
  570. tab: function() {
  571. return activeTabPath;
  572. }
  573. },
  574. utilities: {
  575. filterArray: function(keepArray, removeArray) {
  576. return $.grep(keepArray, function(keepValue) {
  577. return ( $.inArray(keepValue, removeArray) == -1);
  578. });
  579. },
  580. last: function(array) {
  581. return $.isArray(array)
  582. ? array[ array.length - 1]
  583. : false
  584. ;
  585. },
  586. pathToArray: function(pathName) {
  587. if(pathName === undefined) {
  588. pathName = activeTabPath;
  589. }
  590. return typeof pathName == 'string'
  591. ? pathName.split('/')
  592. : [pathName]
  593. ;
  594. },
  595. arrayToPath: function(pathArray) {
  596. return $.isArray(pathArray)
  597. ? pathArray.join('/')
  598. : false
  599. ;
  600. }
  601. },
  602. setting: function(name, value) {
  603. module.debug('Changing setting', name, value);
  604. if( $.isPlainObject(name) ) {
  605. $.extend(true, settings, name);
  606. }
  607. else if(value !== undefined) {
  608. settings[name] = value;
  609. }
  610. else {
  611. return settings[name];
  612. }
  613. },
  614. internal: function(name, value) {
  615. if( $.isPlainObject(name) ) {
  616. $.extend(true, module, name);
  617. }
  618. else if(value !== undefined) {
  619. module[name] = value;
  620. }
  621. else {
  622. return module[name];
  623. }
  624. },
  625. debug: function() {
  626. if(settings.debug) {
  627. if(settings.performance) {
  628. module.performance.log(arguments);
  629. }
  630. else {
  631. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  632. module.debug.apply(console, arguments);
  633. }
  634. }
  635. },
  636. verbose: function() {
  637. if(settings.verbose && settings.debug) {
  638. if(settings.performance) {
  639. module.performance.log(arguments);
  640. }
  641. else {
  642. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  643. module.verbose.apply(console, arguments);
  644. }
  645. }
  646. },
  647. error: function() {
  648. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  649. module.error.apply(console, arguments);
  650. },
  651. performance: {
  652. log: function(message) {
  653. var
  654. currentTime,
  655. executionTime,
  656. previousTime
  657. ;
  658. if(settings.performance) {
  659. currentTime = new Date().getTime();
  660. previousTime = time || currentTime;
  661. executionTime = currentTime - previousTime;
  662. time = currentTime;
  663. performance.push({
  664. 'Name' : message[0],
  665. 'Arguments' : [].slice.call(message, 1) || '',
  666. 'Element' : element,
  667. 'Execution Time' : executionTime
  668. });
  669. }
  670. clearTimeout(module.performance.timer);
  671. module.performance.timer = setTimeout(module.performance.display, 500);
  672. },
  673. display: function() {
  674. var
  675. title = settings.name + ':',
  676. totalTime = 0
  677. ;
  678. time = false;
  679. clearTimeout(module.performance.timer);
  680. $.each(performance, function(index, data) {
  681. totalTime += data['Execution Time'];
  682. });
  683. title += ' ' + totalTime + 'ms';
  684. if(moduleSelector) {
  685. title += ' \'' + moduleSelector + '\'';
  686. }
  687. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  688. console.groupCollapsed(title);
  689. if(console.table) {
  690. console.table(performance);
  691. }
  692. else {
  693. $.each(performance, function(index, data) {
  694. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  695. });
  696. }
  697. console.groupEnd();
  698. }
  699. performance = [];
  700. }
  701. },
  702. invoke: function(query, passedArguments, context) {
  703. var
  704. object = instance,
  705. maxDepth,
  706. found,
  707. response
  708. ;
  709. passedArguments = passedArguments || queryArguments;
  710. context = element || context;
  711. if(typeof query == 'string' && object !== undefined) {
  712. query = query.split(/[\. ]/);
  713. maxDepth = query.length - 1;
  714. $.each(query, function(depth, value) {
  715. var camelCaseValue = (depth != maxDepth)
  716. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  717. : query
  718. ;
  719. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  720. object = object[camelCaseValue];
  721. }
  722. else if( object[camelCaseValue] !== undefined ) {
  723. found = object[camelCaseValue];
  724. return false;
  725. }
  726. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  727. object = object[value];
  728. }
  729. else if( object[value] !== undefined ) {
  730. found = object[value];
  731. return false;
  732. }
  733. else {
  734. module.error(error.method, query);
  735. return false;
  736. }
  737. });
  738. }
  739. if ( $.isFunction( found ) ) {
  740. response = found.apply(context, passedArguments);
  741. }
  742. else if(found !== undefined) {
  743. response = found;
  744. }
  745. if($.isArray(returnedValue)) {
  746. returnedValue.push(response);
  747. }
  748. else if(returnedValue !== undefined) {
  749. returnedValue = [returnedValue, response];
  750. }
  751. else if(response !== undefined) {
  752. returnedValue = response;
  753. }
  754. return found;
  755. }
  756. };
  757. if(methodInvoked) {
  758. if(instance === undefined) {
  759. module.initialize();
  760. }
  761. module.invoke(query);
  762. }
  763. else {
  764. if(instance !== undefined) {
  765. instance.invoke('destroy');
  766. }
  767. module.initialize();
  768. }
  769. })
  770. ;
  771. return (returnedValue !== undefined)
  772. ? returnedValue
  773. : this
  774. ;
  775. };
  776. // shortcut for tabbed content with no defined navigation
  777. $.tab = function() {
  778. $(window).tab.apply(this, arguments);
  779. };
  780. $.fn.tab.settings = {
  781. name : 'Tab',
  782. namespace : 'tab',
  783. debug : false,
  784. verbose : false,
  785. performance : true,
  786. auto : false, // uses pjax style endpoints fetching content from same url with remote-content headers
  787. history : false, // use browser history
  788. historyType : 'hash', // #/ or html5 state
  789. path : false, // base path of url
  790. context : false, // specify a context that tabs must appear inside
  791. childrenOnly : false, // use only tabs that are children of context
  792. maxDepth : 25, // max depth a tab can be nested
  793. alwaysRefresh : false, // load tab content new every tab click
  794. cache : true, // cache the content requests to pull locally
  795. ignoreFirstLoad : false, // don't load remote content on first load
  796. apiSettings : false, // settings for api call
  797. evaluateScripts : 'once', // whether inline scripts should be parsed (true/false/once). Once will not re-evaluate on cached content
  798. onFirstLoad : function(tabPath, parameterArray, historyEvent) {}, // called first time loaded
  799. onLoad : function(tabPath, parameterArray, historyEvent) {}, // called on every load
  800. onVisible : function(tabPath, parameterArray, historyEvent) {}, // called every time tab visible
  801. onRequest : function(tabPath, parameterArray, historyEvent) {}, // called ever time a tab beings loading remote content
  802. templates : {
  803. determineTitle: function(tabArray) {} // returns page title for path
  804. },
  805. error: {
  806. api : 'You attempted to load content without API module',
  807. method : 'The method you called is not defined',
  808. missingTab : 'Activated tab cannot be found. Tabs are case-sensitive.',
  809. noContent : 'The tab you specified is missing a content url.',
  810. path : 'History enabled, but no path was specified',
  811. recursion : 'Max recursive depth reached',
  812. legacyInit : 'onTabInit has been renamed to onFirstLoad in 2.0, please adjust your code.',
  813. legacyLoad : 'onTabLoad has been renamed to onLoad in 2.0. Please adjust your code',
  814. state : 'History requires Asual\'s Address library <https://github.com/asual/jquery-address>'
  815. },
  816. metadata : {
  817. tab : 'tab',
  818. loaded : 'loaded',
  819. promise: 'promise'
  820. },
  821. className : {
  822. loading : 'loading',
  823. active : 'active'
  824. },
  825. selector : {
  826. tabs : '.ui.tab',
  827. ui : '.ui'
  828. }
  829. };
  830. })( jQuery, window , document );