@@ 17657-18598 (lines=942) @@ | ||
17654 | * |
|
17655 | */ |
|
17656 | ||
17657 | ;(function ($, window, document, undefined) { |
|
17658 | ||
17659 | "use strict"; |
|
17660 | ||
17661 | window = (typeof window != 'undefined' && window.Math == Math) |
|
17662 | ? window |
|
17663 | : (typeof self != 'undefined' && self.Math == Math) |
|
17664 | ? self |
|
17665 | : Function('return this')() |
|
17666 | ; |
|
17667 | ||
17668 | $.fn.tab = function(parameters) { |
|
17669 | ||
17670 | var |
|
17671 | // use window context if none specified |
|
17672 | $allModules = $.isFunction(this) |
|
17673 | ? $(window) |
|
17674 | : $(this), |
|
17675 | ||
17676 | moduleSelector = $allModules.selector || '', |
|
17677 | time = new Date().getTime(), |
|
17678 | performance = [], |
|
17679 | ||
17680 | query = arguments[0], |
|
17681 | methodInvoked = (typeof query == 'string'), |
|
17682 | queryArguments = [].slice.call(arguments, 1), |
|
17683 | ||
17684 | initializedHistory = false, |
|
17685 | returnedValue |
|
17686 | ; |
|
17687 | ||
17688 | $allModules |
|
17689 | .each(function() { |
|
17690 | var |
|
17691 | ||
17692 | settings = ( $.isPlainObject(parameters) ) |
|
17693 | ? $.extend(true, {}, $.fn.tab.settings, parameters) |
|
17694 | : $.extend({}, $.fn.tab.settings), |
|
17695 | ||
17696 | className = settings.className, |
|
17697 | metadata = settings.metadata, |
|
17698 | selector = settings.selector, |
|
17699 | error = settings.error, |
|
17700 | ||
17701 | eventNamespace = '.' + settings.namespace, |
|
17702 | moduleNamespace = 'module-' + settings.namespace, |
|
17703 | ||
17704 | $module = $(this), |
|
17705 | $context, |
|
17706 | $tabs, |
|
17707 | ||
17708 | cache = {}, |
|
17709 | firstLoad = true, |
|
17710 | recursionDepth = 0, |
|
17711 | element = this, |
|
17712 | instance = $module.data(moduleNamespace), |
|
17713 | ||
17714 | activeTabPath, |
|
17715 | parameterArray, |
|
17716 | module, |
|
17717 | ||
17718 | historyEvent |
|
17719 | ||
17720 | ; |
|
17721 | ||
17722 | module = { |
|
17723 | ||
17724 | initialize: function() { |
|
17725 | module.debug('Initializing tab menu item', $module); |
|
17726 | module.fix.callbacks(); |
|
17727 | module.determineTabs(); |
|
17728 | ||
17729 | module.debug('Determining tabs', settings.context, $tabs); |
|
17730 | // set up automatic routing |
|
17731 | if(settings.auto) { |
|
17732 | module.set.auto(); |
|
17733 | } |
|
17734 | module.bind.events(); |
|
17735 | ||
17736 | if(settings.history && !initializedHistory) { |
|
17737 | module.initializeHistory(); |
|
17738 | initializedHistory = true; |
|
17739 | } |
|
17740 | ||
17741 | module.instantiate(); |
|
17742 | }, |
|
17743 | ||
17744 | instantiate: function () { |
|
17745 | module.verbose('Storing instance of module', module); |
|
17746 | instance = module; |
|
17747 | $module |
|
17748 | .data(moduleNamespace, module) |
|
17749 | ; |
|
17750 | }, |
|
17751 | ||
17752 | destroy: function() { |
|
17753 | module.debug('Destroying tabs', $module); |
|
17754 | $module |
|
17755 | .removeData(moduleNamespace) |
|
17756 | .off(eventNamespace) |
|
17757 | ; |
|
17758 | }, |
|
17759 | ||
17760 | bind: { |
|
17761 | events: function() { |
|
17762 | // if using $.tab don't add events |
|
17763 | if( !$.isWindow( element ) ) { |
|
17764 | module.debug('Attaching tab activation events to element', $module); |
|
17765 | $module |
|
17766 | .on('click' + eventNamespace, module.event.click) |
|
17767 | ; |
|
17768 | } |
|
17769 | } |
|
17770 | }, |
|
17771 | ||
17772 | determineTabs: function() { |
|
17773 | var |
|
17774 | $reference |
|
17775 | ; |
|
17776 | ||
17777 | // determine tab context |
|
17778 | if(settings.context === 'parent') { |
|
17779 | if($module.closest(selector.ui).length > 0) { |
|
17780 | $reference = $module.closest(selector.ui); |
|
17781 | module.verbose('Using closest UI element as parent', $reference); |
|
17782 | } |
|
17783 | else { |
|
17784 | $reference = $module; |
|
17785 | } |
|
17786 | $context = $reference.parent(); |
|
17787 | module.verbose('Determined parent element for creating context', $context); |
|
17788 | } |
|
17789 | else if(settings.context) { |
|
17790 | $context = $(settings.context); |
|
17791 | module.verbose('Using selector for tab context', settings.context, $context); |
|
17792 | } |
|
17793 | else { |
|
17794 | $context = $('body'); |
|
17795 | } |
|
17796 | // find tabs |
|
17797 | if(settings.childrenOnly) { |
|
17798 | $tabs = $context.children(selector.tabs); |
|
17799 | module.debug('Searching tab context children for tabs', $context, $tabs); |
|
17800 | } |
|
17801 | else { |
|
17802 | $tabs = $context.find(selector.tabs); |
|
17803 | module.debug('Searching tab context for tabs', $context, $tabs); |
|
17804 | } |
|
17805 | }, |
|
17806 | ||
17807 | fix: { |
|
17808 | callbacks: function() { |
|
17809 | if( $.isPlainObject(parameters) && (parameters.onTabLoad || parameters.onTabInit) ) { |
|
17810 | if(parameters.onTabLoad) { |
|
17811 | parameters.onLoad = parameters.onTabLoad; |
|
17812 | delete parameters.onTabLoad; |
|
17813 | module.error(error.legacyLoad, parameters.onLoad); |
|
17814 | } |
|
17815 | if(parameters.onTabInit) { |
|
17816 | parameters.onFirstLoad = parameters.onTabInit; |
|
17817 | delete parameters.onTabInit; |
|
17818 | module.error(error.legacyInit, parameters.onFirstLoad); |
|
17819 | } |
|
17820 | settings = $.extend(true, {}, $.fn.tab.settings, parameters); |
|
17821 | } |
|
17822 | } |
|
17823 | }, |
|
17824 | ||
17825 | initializeHistory: function() { |
|
17826 | module.debug('Initializing page state'); |
|
17827 | if( $.address === undefined ) { |
|
17828 | module.error(error.state); |
|
17829 | return false; |
|
17830 | } |
|
17831 | else { |
|
17832 | if(settings.historyType == 'state') { |
|
17833 | module.debug('Using HTML5 to manage state'); |
|
17834 | if(settings.path !== false) { |
|
17835 | $.address |
|
17836 | .history(true) |
|
17837 | .state(settings.path) |
|
17838 | ; |
|
17839 | } |
|
17840 | else { |
|
17841 | module.error(error.path); |
|
17842 | return false; |
|
17843 | } |
|
17844 | } |
|
17845 | $.address |
|
17846 | .bind('change', module.event.history.change) |
|
17847 | ; |
|
17848 | } |
|
17849 | }, |
|
17850 | ||
17851 | event: { |
|
17852 | click: function(event) { |
|
17853 | var |
|
17854 | tabPath = $(this).data(metadata.tab) |
|
17855 | ; |
|
17856 | if(tabPath !== undefined) { |
|
17857 | if(settings.history) { |
|
17858 | module.verbose('Updating page state', event); |
|
17859 | $.address.value(tabPath); |
|
17860 | } |
|
17861 | else { |
|
17862 | module.verbose('Changing tab', event); |
|
17863 | module.changeTab(tabPath); |
|
17864 | } |
|
17865 | event.preventDefault(); |
|
17866 | } |
|
17867 | else { |
|
17868 | module.debug('No tab specified'); |
|
17869 | } |
|
17870 | }, |
|
17871 | history: { |
|
17872 | change: function(event) { |
|
17873 | var |
|
17874 | tabPath = event.pathNames.join('/') || module.get.initialPath(), |
|
17875 | pageTitle = settings.templates.determineTitle(tabPath) || false |
|
17876 | ; |
|
17877 | module.performance.display(); |
|
17878 | module.debug('History change event', tabPath, event); |
|
17879 | historyEvent = event; |
|
17880 | if(tabPath !== undefined) { |
|
17881 | module.changeTab(tabPath); |
|
17882 | } |
|
17883 | if(pageTitle) { |
|
17884 | $.address.title(pageTitle); |
|
17885 | } |
|
17886 | } |
|
17887 | } |
|
17888 | }, |
|
17889 | ||
17890 | refresh: function() { |
|
17891 | if(activeTabPath) { |
|
17892 | module.debug('Refreshing tab', activeTabPath); |
|
17893 | module.changeTab(activeTabPath); |
|
17894 | } |
|
17895 | }, |
|
17896 | ||
17897 | cache: { |
|
17898 | ||
17899 | read: function(cacheKey) { |
|
17900 | return (cacheKey !== undefined) |
|
17901 | ? cache[cacheKey] |
|
17902 | : false |
|
17903 | ; |
|
17904 | }, |
|
17905 | add: function(cacheKey, content) { |
|
17906 | cacheKey = cacheKey || activeTabPath; |
|
17907 | module.debug('Adding cached content for', cacheKey); |
|
17908 | cache[cacheKey] = content; |
|
17909 | }, |
|
17910 | remove: function(cacheKey) { |
|
17911 | cacheKey = cacheKey || activeTabPath; |
|
17912 | module.debug('Removing cached content for', cacheKey); |
|
17913 | delete cache[cacheKey]; |
|
17914 | } |
|
17915 | }, |
|
17916 | ||
17917 | set: { |
|
17918 | auto: function() { |
|
17919 | var |
|
17920 | url = (typeof settings.path == 'string') |
|
17921 | ? settings.path.replace(/\/$/, '') + '/{$tab}' |
|
17922 | : '/{$tab}' |
|
17923 | ; |
|
17924 | module.verbose('Setting up automatic tab retrieval from server', url); |
|
17925 | if($.isPlainObject(settings.apiSettings)) { |
|
17926 | settings.apiSettings.url = url; |
|
17927 | } |
|
17928 | else { |
|
17929 | settings.apiSettings = { |
|
17930 | url: url |
|
17931 | }; |
|
17932 | } |
|
17933 | }, |
|
17934 | loading: function(tabPath) { |
|
17935 | var |
|
17936 | $tab = module.get.tabElement(tabPath), |
|
17937 | isLoading = $tab.hasClass(className.loading) |
|
17938 | ; |
|
17939 | if(!isLoading) { |
|
17940 | module.verbose('Setting loading state for', $tab); |
|
17941 | $tab |
|
17942 | .addClass(className.loading) |
|
17943 | .siblings($tabs) |
|
17944 | .removeClass(className.active + ' ' + className.loading) |
|
17945 | ; |
|
17946 | if($tab.length > 0) { |
|
17947 | settings.onRequest.call($tab[0], tabPath); |
|
17948 | } |
|
17949 | } |
|
17950 | }, |
|
17951 | state: function(state) { |
|
17952 | $.address.value(state); |
|
17953 | } |
|
17954 | }, |
|
17955 | ||
17956 | changeTab: function(tabPath) { |
|
17957 | var |
|
17958 | pushStateAvailable = (window.history && window.history.pushState), |
|
17959 | shouldIgnoreLoad = (pushStateAvailable && settings.ignoreFirstLoad && firstLoad), |
|
17960 | remoteContent = (settings.auto || $.isPlainObject(settings.apiSettings) ), |
|
17961 | // only add default path if not remote content |
|
17962 | pathArray = (remoteContent && !shouldIgnoreLoad) |
|
17963 | ? module.utilities.pathToArray(tabPath) |
|
17964 | : module.get.defaultPathArray(tabPath) |
|
17965 | ; |
|
17966 | tabPath = module.utilities.arrayToPath(pathArray); |
|
17967 | $.each(pathArray, function(index, tab) { |
|
17968 | var |
|
17969 | currentPathArray = pathArray.slice(0, index + 1), |
|
17970 | currentPath = module.utilities.arrayToPath(currentPathArray), |
|
17971 | ||
17972 | isTab = module.is.tab(currentPath), |
|
17973 | isLastIndex = (index + 1 == pathArray.length), |
|
17974 | ||
17975 | $tab = module.get.tabElement(currentPath), |
|
17976 | $anchor, |
|
17977 | nextPathArray, |
|
17978 | nextPath, |
|
17979 | isLastTab |
|
17980 | ; |
|
17981 | module.verbose('Looking for tab', tab); |
|
17982 | if(isTab) { |
|
17983 | module.verbose('Tab was found', tab); |
|
17984 | // scope up |
|
17985 | activeTabPath = currentPath; |
|
17986 | parameterArray = module.utilities.filterArray(pathArray, currentPathArray); |
|
17987 | ||
17988 | if(isLastIndex) { |
|
17989 | isLastTab = true; |
|
17990 | } |
|
17991 | else { |
|
17992 | nextPathArray = pathArray.slice(0, index + 2); |
|
17993 | nextPath = module.utilities.arrayToPath(nextPathArray); |
|
17994 | isLastTab = ( !module.is.tab(nextPath) ); |
|
17995 | if(isLastTab) { |
|
17996 | module.verbose('Tab parameters found', nextPathArray); |
|
17997 | } |
|
17998 | } |
|
17999 | if(isLastTab && remoteContent) { |
|
18000 | if(!shouldIgnoreLoad) { |
|
18001 | module.activate.navigation(currentPath); |
|
18002 | module.fetch.content(currentPath, tabPath); |
|
18003 | } |
|
18004 | else { |
|
18005 | module.debug('Ignoring remote content on first tab load', currentPath); |
|
18006 | firstLoad = false; |
|
18007 | module.cache.add(tabPath, $tab.html()); |
|
18008 | module.activate.all(currentPath); |
|
18009 | settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent); |
|
18010 | settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent); |
|
18011 | } |
|
18012 | return false; |
|
18013 | } |
|
18014 | else { |
|
18015 | module.debug('Opened local tab', currentPath); |
|
18016 | module.activate.all(currentPath); |
|
18017 | if( !module.cache.read(currentPath) ) { |
|
18018 | module.cache.add(currentPath, true); |
|
18019 | module.debug('First time tab loaded calling tab init'); |
|
18020 | settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent); |
|
18021 | } |
|
18022 | settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent); |
|
18023 | } |
|
18024 | ||
18025 | } |
|
18026 | else if(tabPath.search('/') == -1 && tabPath !== '') { |
|
18027 | // look for in page anchor |
|
18028 | $anchor = $('#' + tabPath + ', a[name="' + tabPath + '"]'); |
|
18029 | currentPath = $anchor.closest('[data-tab]').data(metadata.tab); |
|
18030 | $tab = module.get.tabElement(currentPath); |
|
18031 | // if anchor exists use parent tab |
|
18032 | if($anchor && $anchor.length > 0 && currentPath) { |
|
18033 | module.debug('Anchor link used, opening parent tab', $tab, $anchor); |
|
18034 | if( !$tab.hasClass(className.active) ) { |
|
18035 | setTimeout(function() { |
|
18036 | module.scrollTo($anchor); |
|
18037 | }, 0); |
|
18038 | } |
|
18039 | module.activate.all(currentPath); |
|
18040 | if( !module.cache.read(currentPath) ) { |
|
18041 | module.cache.add(currentPath, true); |
|
18042 | module.debug('First time tab loaded calling tab init'); |
|
18043 | settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent); |
|
18044 | } |
|
18045 | settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent); |
|
18046 | return false; |
|
18047 | } |
|
18048 | } |
|
18049 | else { |
|
18050 | module.error(error.missingTab, $module, $context, currentPath); |
|
18051 | return false; |
|
18052 | } |
|
18053 | }); |
|
18054 | }, |
|
18055 | ||
18056 | scrollTo: function($element) { |
|
18057 | var |
|
18058 | scrollOffset = ($element && $element.length > 0) |
|
18059 | ? $element.offset().top |
|
18060 | : false |
|
18061 | ; |
|
18062 | if(scrollOffset !== false) { |
|
18063 | module.debug('Forcing scroll to an in-page link in a hidden tab', scrollOffset, $element); |
|
18064 | $(document).scrollTop(scrollOffset); |
|
18065 | } |
|
18066 | }, |
|
18067 | ||
18068 | update: { |
|
18069 | content: function(tabPath, html, evaluateScripts) { |
|
18070 | var |
|
18071 | $tab = module.get.tabElement(tabPath), |
|
18072 | tab = $tab[0] |
|
18073 | ; |
|
18074 | evaluateScripts = (evaluateScripts !== undefined) |
|
18075 | ? evaluateScripts |
|
18076 | : settings.evaluateScripts |
|
18077 | ; |
|
18078 | if(typeof settings.cacheType == 'string' && settings.cacheType.toLowerCase() == 'dom' && typeof html !== 'string') { |
|
18079 | $tab |
|
18080 | .empty() |
|
18081 | .append($(html).clone(true)) |
|
18082 | ; |
|
18083 | } |
|
18084 | else { |
|
18085 | if(evaluateScripts) { |
|
18086 | module.debug('Updating HTML and evaluating inline scripts', tabPath, html); |
|
18087 | $tab.html(html); |
|
18088 | } |
|
18089 | else { |
|
18090 | module.debug('Updating HTML', tabPath, html); |
|
18091 | tab.innerHTML = html; |
|
18092 | } |
|
18093 | } |
|
18094 | } |
|
18095 | }, |
|
18096 | ||
18097 | fetch: { |
|
18098 | ||
18099 | content: function(tabPath, fullTabPath) { |
|
18100 | var |
|
18101 | $tab = module.get.tabElement(tabPath), |
|
18102 | apiSettings = { |
|
18103 | dataType : 'html', |
|
18104 | encodeParameters : false, |
|
18105 | on : 'now', |
|
18106 | cache : settings.alwaysRefresh, |
|
18107 | headers : { |
|
18108 | 'X-Remote': true |
|
18109 | }, |
|
18110 | onSuccess : function(response) { |
|
18111 | if(settings.cacheType == 'response') { |
|
18112 | module.cache.add(fullTabPath, response); |
|
18113 | } |
|
18114 | module.update.content(tabPath, response); |
|
18115 | if(tabPath == activeTabPath) { |
|
18116 | module.debug('Content loaded', tabPath); |
|
18117 | module.activate.tab(tabPath); |
|
18118 | } |
|
18119 | else { |
|
18120 | module.debug('Content loaded in background', tabPath); |
|
18121 | } |
|
18122 | settings.onFirstLoad.call($tab[0], tabPath, parameterArray, historyEvent); |
|
18123 | settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent); |
|
18124 | ||
18125 | if(settings.loadOnce) { |
|
18126 | module.cache.add(fullTabPath, true); |
|
18127 | } |
|
18128 | else if(typeof settings.cacheType == 'string' && settings.cacheType.toLowerCase() == 'dom' && $tab.children().length > 0) { |
|
18129 | setTimeout(function() { |
|
18130 | var |
|
18131 | $clone = $tab.children().clone(true) |
|
18132 | ; |
|
18133 | $clone = $clone.not('script'); |
|
18134 | module.cache.add(fullTabPath, $clone); |
|
18135 | }, 0); |
|
18136 | } |
|
18137 | else { |
|
18138 | module.cache.add(fullTabPath, $tab.html()); |
|
18139 | } |
|
18140 | }, |
|
18141 | urlData: { |
|
18142 | tab: fullTabPath |
|
18143 | } |
|
18144 | }, |
|
18145 | request = $tab.api('get request') || false, |
|
18146 | existingRequest = ( request && request.state() === 'pending' ), |
|
18147 | requestSettings, |
|
18148 | cachedContent |
|
18149 | ; |
|
18150 | ||
18151 | fullTabPath = fullTabPath || tabPath; |
|
18152 | cachedContent = module.cache.read(fullTabPath); |
|
18153 | ||
18154 | ||
18155 | if(settings.cache && cachedContent) { |
|
18156 | module.activate.tab(tabPath); |
|
18157 | module.debug('Adding cached content', fullTabPath); |
|
18158 | if(!settings.loadOnce) { |
|
18159 | if(settings.evaluateScripts == 'once') { |
|
18160 | module.update.content(tabPath, cachedContent, false); |
|
18161 | } |
|
18162 | else { |
|
18163 | module.update.content(tabPath, cachedContent); |
|
18164 | } |
|
18165 | } |
|
18166 | settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent); |
|
18167 | } |
|
18168 | else if(existingRequest) { |
|
18169 | module.set.loading(tabPath); |
|
18170 | module.debug('Content is already loading', fullTabPath); |
|
18171 | } |
|
18172 | else if($.api !== undefined) { |
|
18173 | requestSettings = $.extend(true, {}, settings.apiSettings, apiSettings); |
|
18174 | module.debug('Retrieving remote content', fullTabPath, requestSettings); |
|
18175 | module.set.loading(tabPath); |
|
18176 | $tab.api(requestSettings); |
|
18177 | } |
|
18178 | else { |
|
18179 | module.error(error.api); |
|
18180 | } |
|
18181 | } |
|
18182 | }, |
|
18183 | ||
18184 | activate: { |
|
18185 | all: function(tabPath) { |
|
18186 | module.activate.tab(tabPath); |
|
18187 | module.activate.navigation(tabPath); |
|
18188 | }, |
|
18189 | tab: function(tabPath) { |
|
18190 | var |
|
18191 | $tab = module.get.tabElement(tabPath), |
|
18192 | $deactiveTabs = (settings.deactivate == 'siblings') |
|
18193 | ? $tab.siblings($tabs) |
|
18194 | : $tabs.not($tab), |
|
18195 | isActive = $tab.hasClass(className.active) |
|
18196 | ; |
|
18197 | module.verbose('Showing tab content for', $tab); |
|
18198 | if(!isActive) { |
|
18199 | $tab |
|
18200 | .addClass(className.active) |
|
18201 | ; |
|
18202 | $deactiveTabs |
|
18203 | .removeClass(className.active + ' ' + className.loading) |
|
18204 | ; |
|
18205 | if($tab.length > 0) { |
|
18206 | settings.onVisible.call($tab[0], tabPath); |
|
18207 | } |
|
18208 | } |
|
18209 | }, |
|
18210 | navigation: function(tabPath) { |
|
18211 | var |
|
18212 | $navigation = module.get.navElement(tabPath), |
|
18213 | $deactiveNavigation = (settings.deactivate == 'siblings') |
|
18214 | ? $navigation.siblings($allModules) |
|
18215 | : $allModules.not($navigation), |
|
18216 | isActive = $navigation.hasClass(className.active) |
|
18217 | ; |
|
18218 | module.verbose('Activating tab navigation for', $navigation, tabPath); |
|
18219 | if(!isActive) { |
|
18220 | $navigation |
|
18221 | .addClass(className.active) |
|
18222 | ; |
|
18223 | $deactiveNavigation |
|
18224 | .removeClass(className.active + ' ' + className.loading) |
|
18225 | ; |
|
18226 | } |
|
18227 | } |
|
18228 | }, |
|
18229 | ||
18230 | deactivate: { |
|
18231 | all: function() { |
|
18232 | module.deactivate.navigation(); |
|
18233 | module.deactivate.tabs(); |
|
18234 | }, |
|
18235 | navigation: function() { |
|
18236 | $allModules |
|
18237 | .removeClass(className.active) |
|
18238 | ; |
|
18239 | }, |
|
18240 | tabs: function() { |
|
18241 | $tabs |
|
18242 | .removeClass(className.active + ' ' + className.loading) |
|
18243 | ; |
|
18244 | } |
|
18245 | }, |
|
18246 | ||
18247 | is: { |
|
18248 | tab: function(tabName) { |
|
18249 | return (tabName !== undefined) |
|
18250 | ? ( module.get.tabElement(tabName).length > 0 ) |
|
18251 | : false |
|
18252 | ; |
|
18253 | } |
|
18254 | }, |
|
18255 | ||
18256 | get: { |
|
18257 | initialPath: function() { |
|
18258 | return $allModules.eq(0).data(metadata.tab) || $tabs.eq(0).data(metadata.tab); |
|
18259 | }, |
|
18260 | path: function() { |
|
18261 | return $.address.value(); |
|
18262 | }, |
|
18263 | // adds default tabs to tab path |
|
18264 | defaultPathArray: function(tabPath) { |
|
18265 | return module.utilities.pathToArray( module.get.defaultPath(tabPath) ); |
|
18266 | }, |
|
18267 | defaultPath: function(tabPath) { |
|
18268 | var |
|
18269 | $defaultNav = $allModules.filter('[data-' + metadata.tab + '^="' + tabPath + '/"]').eq(0), |
|
18270 | defaultTab = $defaultNav.data(metadata.tab) || false |
|
18271 | ; |
|
18272 | if( defaultTab ) { |
|
18273 | module.debug('Found default tab', defaultTab); |
|
18274 | if(recursionDepth < settings.maxDepth) { |
|
18275 | recursionDepth++; |
|
18276 | return module.get.defaultPath(defaultTab); |
|
18277 | } |
|
18278 | module.error(error.recursion); |
|
18279 | } |
|
18280 | else { |
|
18281 | module.debug('No default tabs found for', tabPath, $tabs); |
|
18282 | } |
|
18283 | recursionDepth = 0; |
|
18284 | return tabPath; |
|
18285 | }, |
|
18286 | navElement: function(tabPath) { |
|
18287 | tabPath = tabPath || activeTabPath; |
|
18288 | return $allModules.filter('[data-' + metadata.tab + '="' + tabPath + '"]'); |
|
18289 | }, |
|
18290 | tabElement: function(tabPath) { |
|
18291 | var |
|
18292 | $fullPathTab, |
|
18293 | $simplePathTab, |
|
18294 | tabPathArray, |
|
18295 | lastTab |
|
18296 | ; |
|
18297 | tabPath = tabPath || activeTabPath; |
|
18298 | tabPathArray = module.utilities.pathToArray(tabPath); |
|
18299 | lastTab = module.utilities.last(tabPathArray); |
|
18300 | $fullPathTab = $tabs.filter('[data-' + metadata.tab + '="' + tabPath + '"]'); |
|
18301 | $simplePathTab = $tabs.filter('[data-' + metadata.tab + '="' + lastTab + '"]'); |
|
18302 | return ($fullPathTab.length > 0) |
|
18303 | ? $fullPathTab |
|
18304 | : $simplePathTab |
|
18305 | ; |
|
18306 | }, |
|
18307 | tab: function() { |
|
18308 | return activeTabPath; |
|
18309 | } |
|
18310 | }, |
|
18311 | ||
18312 | utilities: { |
|
18313 | filterArray: function(keepArray, removeArray) { |
|
18314 | return $.grep(keepArray, function(keepValue) { |
|
18315 | return ( $.inArray(keepValue, removeArray) == -1); |
|
18316 | }); |
|
18317 | }, |
|
18318 | last: function(array) { |
|
18319 | return $.isArray(array) |
|
18320 | ? array[ array.length - 1] |
|
18321 | : false |
|
18322 | ; |
|
18323 | }, |
|
18324 | pathToArray: function(pathName) { |
|
18325 | if(pathName === undefined) { |
|
18326 | pathName = activeTabPath; |
|
18327 | } |
|
18328 | return typeof pathName == 'string' |
|
18329 | ? pathName.split('/') |
|
18330 | : [pathName] |
|
18331 | ; |
|
18332 | }, |
|
18333 | arrayToPath: function(pathArray) { |
|
18334 | return $.isArray(pathArray) |
|
18335 | ? pathArray.join('/') |
|
18336 | : false |
|
18337 | ; |
|
18338 | } |
|
18339 | }, |
|
18340 | ||
18341 | setting: function(name, value) { |
|
18342 | module.debug('Changing setting', name, value); |
|
18343 | if( $.isPlainObject(name) ) { |
|
18344 | $.extend(true, settings, name); |
|
18345 | } |
|
18346 | else if(value !== undefined) { |
|
18347 | if($.isPlainObject(settings[name])) { |
|
18348 | $.extend(true, settings[name], value); |
|
18349 | } |
|
18350 | else { |
|
18351 | settings[name] = value; |
|
18352 | } |
|
18353 | } |
|
18354 | else { |
|
18355 | return settings[name]; |
|
18356 | } |
|
18357 | }, |
|
18358 | internal: function(name, value) { |
|
18359 | if( $.isPlainObject(name) ) { |
|
18360 | $.extend(true, module, name); |
|
18361 | } |
|
18362 | else if(value !== undefined) { |
|
18363 | module[name] = value; |
|
18364 | } |
|
18365 | else { |
|
18366 | return module[name]; |
|
18367 | } |
|
18368 | }, |
|
18369 | debug: function() { |
|
18370 | if(!settings.silent && settings.debug) { |
|
18371 | if(settings.performance) { |
|
18372 | module.performance.log(arguments); |
|
18373 | } |
|
18374 | else { |
|
18375 | module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
|
18376 | module.debug.apply(console, arguments); |
|
18377 | } |
|
18378 | } |
|
18379 | }, |
|
18380 | verbose: function() { |
|
18381 | if(!settings.silent && settings.verbose && settings.debug) { |
|
18382 | if(settings.performance) { |
|
18383 | module.performance.log(arguments); |
|
18384 | } |
|
18385 | else { |
|
18386 | module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
|
18387 | module.verbose.apply(console, arguments); |
|
18388 | } |
|
18389 | } |
|
18390 | }, |
|
18391 | error: function() { |
|
18392 | if(!settings.silent) { |
|
18393 | module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); |
|
18394 | module.error.apply(console, arguments); |
|
18395 | } |
|
18396 | }, |
|
18397 | performance: { |
|
18398 | log: function(message) { |
|
18399 | var |
|
18400 | currentTime, |
|
18401 | executionTime, |
|
18402 | previousTime |
|
18403 | ; |
|
18404 | if(settings.performance) { |
|
18405 | currentTime = new Date().getTime(); |
|
18406 | previousTime = time || currentTime; |
|
18407 | executionTime = currentTime - previousTime; |
|
18408 | time = currentTime; |
|
18409 | performance.push({ |
|
18410 | 'Name' : message[0], |
|
18411 | 'Arguments' : [].slice.call(message, 1) || '', |
|
18412 | 'Element' : element, |
|
18413 | 'Execution Time' : executionTime |
|
18414 | }); |
|
18415 | } |
|
18416 | clearTimeout(module.performance.timer); |
|
18417 | module.performance.timer = setTimeout(module.performance.display, 500); |
|
18418 | }, |
|
18419 | display: function() { |
|
18420 | var |
|
18421 | title = settings.name + ':', |
|
18422 | totalTime = 0 |
|
18423 | ; |
|
18424 | time = false; |
|
18425 | clearTimeout(module.performance.timer); |
|
18426 | $.each(performance, function(index, data) { |
|
18427 | totalTime += data['Execution Time']; |
|
18428 | }); |
|
18429 | title += ' ' + totalTime + 'ms'; |
|
18430 | if(moduleSelector) { |
|
18431 | title += ' \'' + moduleSelector + '\''; |
|
18432 | } |
|
18433 | if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { |
|
18434 | console.groupCollapsed(title); |
|
18435 | if(console.table) { |
|
18436 | console.table(performance); |
|
18437 | } |
|
18438 | else { |
|
18439 | $.each(performance, function(index, data) { |
|
18440 | console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); |
|
18441 | }); |
|
18442 | } |
|
18443 | console.groupEnd(); |
|
18444 | } |
|
18445 | performance = []; |
|
18446 | } |
|
18447 | }, |
|
18448 | invoke: function(query, passedArguments, context) { |
|
18449 | var |
|
18450 | object = instance, |
|
18451 | maxDepth, |
|
18452 | found, |
|
18453 | response |
|
18454 | ; |
|
18455 | passedArguments = passedArguments || queryArguments; |
|
18456 | context = element || context; |
|
18457 | if(typeof query == 'string' && object !== undefined) { |
|
18458 | query = query.split(/[\. ]/); |
|
18459 | maxDepth = query.length - 1; |
|
18460 | $.each(query, function(depth, value) { |
|
18461 | var camelCaseValue = (depth != maxDepth) |
|
18462 | ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) |
|
18463 | : query |
|
18464 | ; |
|
18465 | if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { |
|
18466 | object = object[camelCaseValue]; |
|
18467 | } |
|
18468 | else if( object[camelCaseValue] !== undefined ) { |
|
18469 | found = object[camelCaseValue]; |
|
18470 | return false; |
|
18471 | } |
|
18472 | else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { |
|
18473 | object = object[value]; |
|
18474 | } |
|
18475 | else if( object[value] !== undefined ) { |
|
18476 | found = object[value]; |
|
18477 | return false; |
|
18478 | } |
|
18479 | else { |
|
18480 | module.error(error.method, query); |
|
18481 | return false; |
|
18482 | } |
|
18483 | }); |
|
18484 | } |
|
18485 | if ( $.isFunction( found ) ) { |
|
18486 | response = found.apply(context, passedArguments); |
|
18487 | } |
|
18488 | else if(found !== undefined) { |
|
18489 | response = found; |
|
18490 | } |
|
18491 | if($.isArray(returnedValue)) { |
|
18492 | returnedValue.push(response); |
|
18493 | } |
|
18494 | else if(returnedValue !== undefined) { |
|
18495 | returnedValue = [returnedValue, response]; |
|
18496 | } |
|
18497 | else if(response !== undefined) { |
|
18498 | returnedValue = response; |
|
18499 | } |
|
18500 | return found; |
|
18501 | } |
|
18502 | }; |
|
18503 | if(methodInvoked) { |
|
18504 | if(instance === undefined) { |
|
18505 | module.initialize(); |
|
18506 | } |
|
18507 | module.invoke(query); |
|
18508 | } |
|
18509 | else { |
|
18510 | if(instance !== undefined) { |
|
18511 | instance.invoke('destroy'); |
|
18512 | } |
|
18513 | module.initialize(); |
|
18514 | } |
|
18515 | }) |
|
18516 | ; |
|
18517 | return (returnedValue !== undefined) |
|
18518 | ? returnedValue |
|
18519 | : this |
|
18520 | ; |
|
18521 | ||
18522 | }; |
|
18523 | ||
18524 | // shortcut for tabbed content with no defined navigation |
|
18525 | $.tab = function() { |
|
18526 | $(window).tab.apply(this, arguments); |
|
18527 | }; |
|
18528 | ||
18529 | $.fn.tab.settings = { |
|
18530 | ||
18531 | name : 'Tab', |
|
18532 | namespace : 'tab', |
|
18533 | ||
18534 | silent : false, |
|
18535 | debug : false, |
|
18536 | verbose : false, |
|
18537 | performance : true, |
|
18538 | ||
18539 | auto : false, // uses pjax style endpoints fetching content from same url with remote-content headers |
|
18540 | history : false, // use browser history |
|
18541 | historyType : 'hash', // #/ or html5 state |
|
18542 | path : false, // base path of url |
|
18543 | ||
18544 | context : false, // specify a context that tabs must appear inside |
|
18545 | childrenOnly : false, // use only tabs that are children of context |
|
18546 | maxDepth : 25, // max depth a tab can be nested |
|
18547 | ||
18548 | deactivate : 'siblings', // whether tabs should deactivate sibling menu elements or all elements initialized together |
|
18549 | ||
18550 | alwaysRefresh : false, // load tab content new every tab click |
|
18551 | cache : true, // cache the content requests to pull locally |
|
18552 | loadOnce : false, // Whether tab data should only be loaded once when using remote content |
|
18553 | cacheType : 'response', // Whether to cache exact response, or to html cache contents after scripts execute |
|
18554 | ignoreFirstLoad : false, // don't load remote content on first load |
|
18555 | ||
18556 | apiSettings : false, // settings for api call |
|
18557 | evaluateScripts : 'once', // whether inline scripts should be parsed (true/false/once). Once will not re-evaluate on cached content |
|
18558 | ||
18559 | onFirstLoad : function(tabPath, parameterArray, historyEvent) {}, // called first time loaded |
|
18560 | onLoad : function(tabPath, parameterArray, historyEvent) {}, // called on every load |
|
18561 | onVisible : function(tabPath, parameterArray, historyEvent) {}, // called every time tab visible |
|
18562 | onRequest : function(tabPath, parameterArray, historyEvent) {}, // called ever time a tab beings loading remote content |
|
18563 | ||
18564 | templates : { |
|
18565 | determineTitle: function(tabArray) {} // returns page title for path |
|
18566 | }, |
|
18567 | ||
18568 | error: { |
|
18569 | api : 'You attempted to load content without API module', |
|
18570 | method : 'The method you called is not defined', |
|
18571 | missingTab : 'Activated tab cannot be found. Tabs are case-sensitive.', |
|
18572 | noContent : 'The tab you specified is missing a content url.', |
|
18573 | path : 'History enabled, but no path was specified', |
|
18574 | recursion : 'Max recursive depth reached', |
|
18575 | legacyInit : 'onTabInit has been renamed to onFirstLoad in 2.0, please adjust your code.', |
|
18576 | legacyLoad : 'onTabLoad has been renamed to onLoad in 2.0. Please adjust your code', |
|
18577 | state : 'History requires Asual\'s Address library <https://github.com/asual/jquery-address>' |
|
18578 | }, |
|
18579 | ||
18580 | metadata : { |
|
18581 | tab : 'tab', |
|
18582 | loaded : 'loaded', |
|
18583 | promise: 'promise' |
|
18584 | }, |
|
18585 | ||
18586 | className : { |
|
18587 | loading : 'loading', |
|
18588 | active : 'active' |
|
18589 | }, |
|
18590 | ||
18591 | selector : { |
|
18592 | tabs : '.ui.tab', |
|
18593 | ui : '.ui' |
|
18594 | } |
|
18595 | ||
18596 | }; |
|
18597 | ||
18598 | })( jQuery, window, document ); |
|
18599 | ||
18600 | /*! |
|
18601 | * # Semantic UI 2.2.11 - Transition |
@@ 11-952 (lines=942) @@ | ||
8 | * |
|
9 | */ |
|
10 | ||
11 | ;(function ($, window, document, undefined) { |
|
12 | ||
13 | "use strict"; |
|
14 | ||
15 | window = (typeof window != 'undefined' && window.Math == Math) |
|
16 | ? window |
|
17 | : (typeof self != 'undefined' && self.Math == Math) |
|
18 | ? self |
|
19 | : Function('return this')() |
|
20 | ; |
|
21 | ||
22 | $.fn.tab = function(parameters) { |
|
23 | ||
24 | var |
|
25 | // use window context if none specified |
|
26 | $allModules = $.isFunction(this) |
|
27 | ? $(window) |
|
28 | : $(this), |
|
29 | ||
30 | moduleSelector = $allModules.selector || '', |
|
31 | time = new Date().getTime(), |
|
32 | performance = [], |
|
33 | ||
34 | query = arguments[0], |
|
35 | methodInvoked = (typeof query == 'string'), |
|
36 | queryArguments = [].slice.call(arguments, 1), |
|
37 | ||
38 | initializedHistory = false, |
|
39 | returnedValue |
|
40 | ; |
|
41 | ||
42 | $allModules |
|
43 | .each(function() { |
|
44 | var |
|
45 | ||
46 | settings = ( $.isPlainObject(parameters) ) |
|
47 | ? $.extend(true, {}, $.fn.tab.settings, parameters) |
|
48 | : $.extend({}, $.fn.tab.settings), |
|
49 | ||
50 | className = settings.className, |
|
51 | metadata = settings.metadata, |
|
52 | selector = settings.selector, |
|
53 | error = settings.error, |
|
54 | ||
55 | eventNamespace = '.' + settings.namespace, |
|
56 | moduleNamespace = 'module-' + settings.namespace, |
|
57 | ||
58 | $module = $(this), |
|
59 | $context, |
|
60 | $tabs, |
|
61 | ||
62 | cache = {}, |
|
63 | firstLoad = true, |
|
64 | recursionDepth = 0, |
|
65 | element = this, |
|
66 | instance = $module.data(moduleNamespace), |
|
67 | ||
68 | activeTabPath, |
|
69 | parameterArray, |
|
70 | module, |
|
71 | ||
72 | historyEvent |
|
73 | ||
74 | ; |
|
75 | ||
76 | module = { |
|
77 | ||
78 | initialize: function() { |
|
79 | module.debug('Initializing tab menu item', $module); |
|
80 | module.fix.callbacks(); |
|
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 | module.instantiate(); |
|
96 | }, |
|
97 | ||
98 | instantiate: function () { |
|
99 | module.verbose('Storing instance of module', module); |
|
100 | instance = module; |
|
101 | $module |
|
102 | .data(moduleNamespace, module) |
|
103 | ; |
|
104 | }, |
|
105 | ||
106 | destroy: function() { |
|
107 | module.debug('Destroying tabs', $module); |
|
108 | $module |
|
109 | .removeData(moduleNamespace) |
|
110 | .off(eventNamespace) |
|
111 | ; |
|
112 | }, |
|
113 | ||
114 | bind: { |
|
115 | events: function() { |
|
116 | // if using $.tab don't add events |
|
117 | if( !$.isWindow( element ) ) { |
|
118 | module.debug('Attaching tab activation events to element', $module); |
|
119 | $module |
|
120 | .on('click' + eventNamespace, module.event.click) |
|
121 | ; |
|
122 | } |
|
123 | } |
|
124 | }, |
|
125 | ||
126 | determineTabs: function() { |
|
127 | var |
|
128 | $reference |
|
129 | ; |
|
130 | ||
131 | // determine tab context |
|
132 | if(settings.context === 'parent') { |
|
133 | if($module.closest(selector.ui).length > 0) { |
|
134 | $reference = $module.closest(selector.ui); |
|
135 | module.verbose('Using closest UI element as parent', $reference); |
|
136 | } |
|
137 | else { |
|
138 | $reference = $module; |
|
139 | } |
|
140 | $context = $reference.parent(); |
|
141 | module.verbose('Determined parent element for creating context', $context); |
|
142 | } |
|
143 | else if(settings.context) { |
|
144 | $context = $(settings.context); |
|
145 | module.verbose('Using selector for tab context', settings.context, $context); |
|
146 | } |
|
147 | else { |
|
148 | $context = $('body'); |
|
149 | } |
|
150 | // find tabs |
|
151 | if(settings.childrenOnly) { |
|
152 | $tabs = $context.children(selector.tabs); |
|
153 | module.debug('Searching tab context children for tabs', $context, $tabs); |
|
154 | } |
|
155 | else { |
|
156 | $tabs = $context.find(selector.tabs); |
|
157 | module.debug('Searching tab context for tabs', $context, $tabs); |
|
158 | } |
|
159 | }, |
|
160 | ||
161 | fix: { |
|
162 | callbacks: function() { |
|
163 | if( $.isPlainObject(parameters) && (parameters.onTabLoad || parameters.onTabInit) ) { |
|
164 | if(parameters.onTabLoad) { |
|
165 | parameters.onLoad = parameters.onTabLoad; |
|
166 | delete parameters.onTabLoad; |
|
167 | module.error(error.legacyLoad, parameters.onLoad); |
|
168 | } |
|
169 | if(parameters.onTabInit) { |
|
170 | parameters.onFirstLoad = parameters.onTabInit; |
|
171 | delete parameters.onTabInit; |
|
172 | module.error(error.legacyInit, parameters.onFirstLoad); |
|
173 | } |
|
174 | settings = $.extend(true, {}, $.fn.tab.settings, parameters); |
|
175 | } |
|
176 | } |
|
177 | }, |
|
178 | ||
179 | initializeHistory: function() { |
|
180 | module.debug('Initializing page state'); |
|
181 | if( $.address === undefined ) { |
|
182 | module.error(error.state); |
|
183 | return false; |
|
184 | } |
|
185 | else { |
|
186 | if(settings.historyType == 'state') { |
|
187 | module.debug('Using HTML5 to manage state'); |
|
188 | if(settings.path !== false) { |
|
189 | $.address |
|
190 | .history(true) |
|
191 | .state(settings.path) |
|
192 | ; |
|
193 | } |
|
194 | else { |
|
195 | module.error(error.path); |
|
196 | return false; |
|
197 | } |
|
198 | } |
|
199 | $.address |
|
200 | .bind('change', module.event.history.change) |
|
201 | ; |
|
202 | } |
|
203 | }, |
|
204 | ||
205 | event: { |
|
206 | click: function(event) { |
|
207 | var |
|
208 | tabPath = $(this).data(metadata.tab) |
|
209 | ; |
|
210 | if(tabPath !== undefined) { |
|
211 | if(settings.history) { |
|
212 | module.verbose('Updating page state', event); |
|
213 | $.address.value(tabPath); |
|
214 | } |
|
215 | else { |
|
216 | module.verbose('Changing tab', event); |
|
217 | module.changeTab(tabPath); |
|
218 | } |
|
219 | event.preventDefault(); |
|
220 | } |
|
221 | else { |
|
222 | module.debug('No tab specified'); |
|
223 | } |
|
224 | }, |
|
225 | history: { |
|
226 | change: function(event) { |
|
227 | var |
|
228 | tabPath = event.pathNames.join('/') || module.get.initialPath(), |
|
229 | pageTitle = settings.templates.determineTitle(tabPath) || false |
|
230 | ; |
|
231 | module.performance.display(); |
|
232 | module.debug('History change event', tabPath, event); |
|
233 | historyEvent = event; |
|
234 | if(tabPath !== undefined) { |
|
235 | module.changeTab(tabPath); |
|
236 | } |
|
237 | if(pageTitle) { |
|
238 | $.address.title(pageTitle); |
|
239 | } |
|
240 | } |
|
241 | } |
|
242 | }, |
|
243 | ||
244 | refresh: function() { |
|
245 | if(activeTabPath) { |
|
246 | module.debug('Refreshing tab', activeTabPath); |
|
247 | module.changeTab(activeTabPath); |
|
248 | } |
|
249 | }, |
|
250 | ||
251 | cache: { |
|
252 | ||
253 | read: function(cacheKey) { |
|
254 | return (cacheKey !== undefined) |
|
255 | ? cache[cacheKey] |
|
256 | : false |
|
257 | ; |
|
258 | }, |
|
259 | add: function(cacheKey, content) { |
|
260 | cacheKey = cacheKey || activeTabPath; |
|
261 | module.debug('Adding cached content for', cacheKey); |
|
262 | cache[cacheKey] = content; |
|
263 | }, |
|
264 | remove: function(cacheKey) { |
|
265 | cacheKey = cacheKey || activeTabPath; |
|
266 | module.debug('Removing cached content for', cacheKey); |
|
267 | delete cache[cacheKey]; |
|
268 | } |
|
269 | }, |
|
270 | ||
271 | set: { |
|
272 | auto: function() { |
|
273 | var |
|
274 | url = (typeof settings.path == 'string') |
|
275 | ? settings.path.replace(/\/$/, '') + '/{$tab}' |
|
276 | : '/{$tab}' |
|
277 | ; |
|
278 | module.verbose('Setting up automatic tab retrieval from server', url); |
|
279 | if($.isPlainObject(settings.apiSettings)) { |
|
280 | settings.apiSettings.url = url; |
|
281 | } |
|
282 | else { |
|
283 | settings.apiSettings = { |
|
284 | url: url |
|
285 | }; |
|
286 | } |
|
287 | }, |
|
288 | loading: function(tabPath) { |
|
289 | var |
|
290 | $tab = module.get.tabElement(tabPath), |
|
291 | isLoading = $tab.hasClass(className.loading) |
|
292 | ; |
|
293 | if(!isLoading) { |
|
294 | module.verbose('Setting loading state for', $tab); |
|
295 | $tab |
|
296 | .addClass(className.loading) |
|
297 | .siblings($tabs) |
|
298 | .removeClass(className.active + ' ' + className.loading) |
|
299 | ; |
|
300 | if($tab.length > 0) { |
|
301 | settings.onRequest.call($tab[0], tabPath); |
|
302 | } |
|
303 | } |
|
304 | }, |
|
305 | state: function(state) { |
|
306 | $.address.value(state); |
|
307 | } |
|
308 | }, |
|
309 | ||
310 | changeTab: function(tabPath) { |
|
311 | var |
|
312 | pushStateAvailable = (window.history && window.history.pushState), |
|
313 | shouldIgnoreLoad = (pushStateAvailable && settings.ignoreFirstLoad && firstLoad), |
|
314 | remoteContent = (settings.auto || $.isPlainObject(settings.apiSettings) ), |
|
315 | // only add default path if not remote content |
|
316 | pathArray = (remoteContent && !shouldIgnoreLoad) |
|
317 | ? module.utilities.pathToArray(tabPath) |
|
318 | : module.get.defaultPathArray(tabPath) |
|
319 | ; |
|
320 | tabPath = module.utilities.arrayToPath(pathArray); |
|
321 | $.each(pathArray, function(index, tab) { |
|
322 | var |
|
323 | currentPathArray = pathArray.slice(0, index + 1), |
|
324 | currentPath = module.utilities.arrayToPath(currentPathArray), |
|
325 | ||
326 | isTab = module.is.tab(currentPath), |
|
327 | isLastIndex = (index + 1 == pathArray.length), |
|
328 | ||
329 | $tab = module.get.tabElement(currentPath), |
|
330 | $anchor, |
|
331 | nextPathArray, |
|
332 | nextPath, |
|
333 | isLastTab |
|
334 | ; |
|
335 | module.verbose('Looking for tab', tab); |
|
336 | if(isTab) { |
|
337 | module.verbose('Tab was found', tab); |
|
338 | // scope up |
|
339 | activeTabPath = currentPath; |
|
340 | parameterArray = module.utilities.filterArray(pathArray, currentPathArray); |
|
341 | ||
342 | if(isLastIndex) { |
|
343 | isLastTab = true; |
|
344 | } |
|
345 | else { |
|
346 | nextPathArray = pathArray.slice(0, index + 2); |
|
347 | nextPath = module.utilities.arrayToPath(nextPathArray); |
|
348 | isLastTab = ( !module.is.tab(nextPath) ); |
|
349 | if(isLastTab) { |
|
350 | module.verbose('Tab parameters found', nextPathArray); |
|
351 | } |
|
352 | } |
|
353 | if(isLastTab && remoteContent) { |
|
354 | if(!shouldIgnoreLoad) { |
|
355 | module.activate.navigation(currentPath); |
|
356 | module.fetch.content(currentPath, tabPath); |
|
357 | } |
|
358 | else { |
|
359 | module.debug('Ignoring remote content on first tab load', currentPath); |
|
360 | firstLoad = false; |
|
361 | module.cache.add(tabPath, $tab.html()); |
|
362 | module.activate.all(currentPath); |
|
363 | settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent); |
|
364 | settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent); |
|
365 | } |
|
366 | return false; |
|
367 | } |
|
368 | else { |
|
369 | module.debug('Opened local tab', currentPath); |
|
370 | module.activate.all(currentPath); |
|
371 | if( !module.cache.read(currentPath) ) { |
|
372 | module.cache.add(currentPath, true); |
|
373 | module.debug('First time tab loaded calling tab init'); |
|
374 | settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent); |
|
375 | } |
|
376 | settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent); |
|
377 | } |
|
378 | ||
379 | } |
|
380 | else if(tabPath.search('/') == -1 && tabPath !== '') { |
|
381 | // look for in page anchor |
|
382 | $anchor = $('#' + tabPath + ', a[name="' + tabPath + '"]'); |
|
383 | currentPath = $anchor.closest('[data-tab]').data(metadata.tab); |
|
384 | $tab = module.get.tabElement(currentPath); |
|
385 | // if anchor exists use parent tab |
|
386 | if($anchor && $anchor.length > 0 && currentPath) { |
|
387 | module.debug('Anchor link used, opening parent tab', $tab, $anchor); |
|
388 | if( !$tab.hasClass(className.active) ) { |
|
389 | setTimeout(function() { |
|
390 | module.scrollTo($anchor); |
|
391 | }, 0); |
|
392 | } |
|
393 | module.activate.all(currentPath); |
|
394 | if( !module.cache.read(currentPath) ) { |
|
395 | module.cache.add(currentPath, true); |
|
396 | module.debug('First time tab loaded calling tab init'); |
|
397 | settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent); |
|
398 | } |
|
399 | settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent); |
|
400 | return false; |
|
401 | } |
|
402 | } |
|
403 | else { |
|
404 | module.error(error.missingTab, $module, $context, currentPath); |
|
405 | return false; |
|
406 | } |
|
407 | }); |
|
408 | }, |
|
409 | ||
410 | scrollTo: function($element) { |
|
411 | var |
|
412 | scrollOffset = ($element && $element.length > 0) |
|
413 | ? $element.offset().top |
|
414 | : false |
|
415 | ; |
|
416 | if(scrollOffset !== false) { |
|
417 | module.debug('Forcing scroll to an in-page link in a hidden tab', scrollOffset, $element); |
|
418 | $(document).scrollTop(scrollOffset); |
|
419 | } |
|
420 | }, |
|
421 | ||
422 | update: { |
|
423 | content: function(tabPath, html, evaluateScripts) { |
|
424 | var |
|
425 | $tab = module.get.tabElement(tabPath), |
|
426 | tab = $tab[0] |
|
427 | ; |
|
428 | evaluateScripts = (evaluateScripts !== undefined) |
|
429 | ? evaluateScripts |
|
430 | : settings.evaluateScripts |
|
431 | ; |
|
432 | if(typeof settings.cacheType == 'string' && settings.cacheType.toLowerCase() == 'dom' && typeof html !== 'string') { |
|
433 | $tab |
|
434 | .empty() |
|
435 | .append($(html).clone(true)) |
|
436 | ; |
|
437 | } |
|
438 | else { |
|
439 | if(evaluateScripts) { |
|
440 | module.debug('Updating HTML and evaluating inline scripts', tabPath, html); |
|
441 | $tab.html(html); |
|
442 | } |
|
443 | else { |
|
444 | module.debug('Updating HTML', tabPath, html); |
|
445 | tab.innerHTML = html; |
|
446 | } |
|
447 | } |
|
448 | } |
|
449 | }, |
|
450 | ||
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 | } |
|
473 | else { |
|
474 | module.debug('Content loaded in background', tabPath); |
|
475 | } |
|
476 | settings.onFirstLoad.call($tab[0], tabPath, parameterArray, historyEvent); |
|
477 | settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent); |
|
478 | ||
479 | if(settings.loadOnce) { |
|
480 | module.cache.add(fullTabPath, true); |
|
481 | } |
|
482 | else if(typeof settings.cacheType == 'string' && settings.cacheType.toLowerCase() == 'dom' && $tab.children().length > 0) { |
|
483 | setTimeout(function() { |
|
484 | var |
|
485 | $clone = $tab.children().clone(true) |
|
486 | ; |
|
487 | $clone = $clone.not('script'); |
|
488 | module.cache.add(fullTabPath, $clone); |
|
489 | }, 0); |
|
490 | } |
|
491 | else { |
|
492 | module.cache.add(fullTabPath, $tab.html()); |
|
493 | } |
|
494 | }, |
|
495 | urlData: { |
|
496 | tab: fullTabPath |
|
497 | } |
|
498 | }, |
|
499 | request = $tab.api('get request') || false, |
|
500 | existingRequest = ( request && request.state() === 'pending' ), |
|
501 | requestSettings, |
|
502 | cachedContent |
|
503 | ; |
|
504 | ||
505 | fullTabPath = fullTabPath || tabPath; |
|
506 | cachedContent = module.cache.read(fullTabPath); |
|
507 | ||
508 | ||
509 | if(settings.cache && cachedContent) { |
|
510 | module.activate.tab(tabPath); |
|
511 | module.debug('Adding cached content', fullTabPath); |
|
512 | if(!settings.loadOnce) { |
|
513 | if(settings.evaluateScripts == 'once') { |
|
514 | module.update.content(tabPath, cachedContent, false); |
|
515 | } |
|
516 | else { |
|
517 | module.update.content(tabPath, cachedContent); |
|
518 | } |
|
519 | } |
|
520 | settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent); |
|
521 | } |
|
522 | else if(existingRequest) { |
|
523 | module.set.loading(tabPath); |
|
524 | module.debug('Content is already loading', fullTabPath); |
|
525 | } |
|
526 | else if($.api !== undefined) { |
|
527 | requestSettings = $.extend(true, {}, settings.apiSettings, apiSettings); |
|
528 | module.debug('Retrieving remote content', fullTabPath, requestSettings); |
|
529 | module.set.loading(tabPath); |
|
530 | $tab.api(requestSettings); |
|
531 | } |
|
532 | else { |
|
533 | module.error(error.api); |
|
534 | } |
|
535 | } |
|
536 | }, |
|
537 | ||
538 | activate: { |
|
539 | all: function(tabPath) { |
|
540 | module.activate.tab(tabPath); |
|
541 | module.activate.navigation(tabPath); |
|
542 | }, |
|
543 | tab: function(tabPath) { |
|
544 | var |
|
545 | $tab = module.get.tabElement(tabPath), |
|
546 | $deactiveTabs = (settings.deactivate == 'siblings') |
|
547 | ? $tab.siblings($tabs) |
|
548 | : $tabs.not($tab), |
|
549 | isActive = $tab.hasClass(className.active) |
|
550 | ; |
|
551 | module.verbose('Showing tab content for', $tab); |
|
552 | if(!isActive) { |
|
553 | $tab |
|
554 | .addClass(className.active) |
|
555 | ; |
|
556 | $deactiveTabs |
|
557 | .removeClass(className.active + ' ' + className.loading) |
|
558 | ; |
|
559 | if($tab.length > 0) { |
|
560 | settings.onVisible.call($tab[0], tabPath); |
|
561 | } |
|
562 | } |
|
563 | }, |
|
564 | navigation: function(tabPath) { |
|
565 | var |
|
566 | $navigation = module.get.navElement(tabPath), |
|
567 | $deactiveNavigation = (settings.deactivate == 'siblings') |
|
568 | ? $navigation.siblings($allModules) |
|
569 | : $allModules.not($navigation), |
|
570 | isActive = $navigation.hasClass(className.active) |
|
571 | ; |
|
572 | module.verbose('Activating tab navigation for', $navigation, tabPath); |
|
573 | if(!isActive) { |
|
574 | $navigation |
|
575 | .addClass(className.active) |
|
576 | ; |
|
577 | $deactiveNavigation |
|
578 | .removeClass(className.active + ' ' + className.loading) |
|
579 | ; |
|
580 | } |
|
581 | } |
|
582 | }, |
|
583 | ||
584 | deactivate: { |
|
585 | all: function() { |
|
586 | module.deactivate.navigation(); |
|
587 | module.deactivate.tabs(); |
|
588 | }, |
|
589 | navigation: function() { |
|
590 | $allModules |
|
591 | .removeClass(className.active) |
|
592 | ; |
|
593 | }, |
|
594 | tabs: function() { |
|
595 | $tabs |
|
596 | .removeClass(className.active + ' ' + className.loading) |
|
597 | ; |
|
598 | } |
|
599 | }, |
|
600 | ||
601 | is: { |
|
602 | tab: function(tabName) { |
|
603 | return (tabName !== undefined) |
|
604 | ? ( module.get.tabElement(tabName).length > 0 ) |
|
605 | : false |
|
606 | ; |
|
607 | } |
|
608 | }, |
|
609 | ||
610 | get: { |
|
611 | initialPath: function() { |
|
612 | return $allModules.eq(0).data(metadata.tab) || $tabs.eq(0).data(metadata.tab); |
|
613 | }, |
|
614 | path: function() { |
|
615 | return $.address.value(); |
|
616 | }, |
|
617 | // adds default tabs to tab path |
|
618 | defaultPathArray: function(tabPath) { |
|
619 | return module.utilities.pathToArray( module.get.defaultPath(tabPath) ); |
|
620 | }, |
|
621 | defaultPath: function(tabPath) { |
|
622 | var |
|
623 | $defaultNav = $allModules.filter('[data-' + metadata.tab + '^="' + tabPath + '/"]').eq(0), |
|
624 | defaultTab = $defaultNav.data(metadata.tab) || false |
|
625 | ; |
|
626 | if( defaultTab ) { |
|
627 | module.debug('Found default tab', defaultTab); |
|
628 | if(recursionDepth < settings.maxDepth) { |
|
629 | recursionDepth++; |
|
630 | return module.get.defaultPath(defaultTab); |
|
631 | } |
|
632 | module.error(error.recursion); |
|
633 | } |
|
634 | else { |
|
635 | module.debug('No default tabs found for', tabPath, $tabs); |
|
636 | } |
|
637 | recursionDepth = 0; |
|
638 | return tabPath; |
|
639 | }, |
|
640 | navElement: function(tabPath) { |
|
641 | tabPath = tabPath || activeTabPath; |
|
642 | return $allModules.filter('[data-' + metadata.tab + '="' + tabPath + '"]'); |
|
643 | }, |
|
644 | tabElement: function(tabPath) { |
|
645 | var |
|
646 | $fullPathTab, |
|
647 | $simplePathTab, |
|
648 | tabPathArray, |
|
649 | lastTab |
|
650 | ; |
|
651 | tabPath = tabPath || activeTabPath; |
|
652 | tabPathArray = module.utilities.pathToArray(tabPath); |
|
653 | lastTab = module.utilities.last(tabPathArray); |
|
654 | $fullPathTab = $tabs.filter('[data-' + metadata.tab + '="' + tabPath + '"]'); |
|
655 | $simplePathTab = $tabs.filter('[data-' + metadata.tab + '="' + lastTab + '"]'); |
|
656 | return ($fullPathTab.length > 0) |
|
657 | ? $fullPathTab |
|
658 | : $simplePathTab |
|
659 | ; |
|
660 | }, |
|
661 | tab: function() { |
|
662 | return activeTabPath; |
|
663 | } |
|
664 | }, |
|
665 | ||
666 | utilities: { |
|
667 | filterArray: function(keepArray, removeArray) { |
|
668 | return $.grep(keepArray, function(keepValue) { |
|
669 | return ( $.inArray(keepValue, removeArray) == -1); |
|
670 | }); |
|
671 | }, |
|
672 | last: function(array) { |
|
673 | return $.isArray(array) |
|
674 | ? array[ array.length - 1] |
|
675 | : false |
|
676 | ; |
|
677 | }, |
|
678 | pathToArray: function(pathName) { |
|
679 | if(pathName === undefined) { |
|
680 | pathName = activeTabPath; |
|
681 | } |
|
682 | return typeof pathName == 'string' |
|
683 | ? pathName.split('/') |
|
684 | : [pathName] |
|
685 | ; |
|
686 | }, |
|
687 | arrayToPath: function(pathArray) { |
|
688 | return $.isArray(pathArray) |
|
689 | ? pathArray.join('/') |
|
690 | : false |
|
691 | ; |
|
692 | } |
|
693 | }, |
|
694 | ||
695 | setting: function(name, value) { |
|
696 | module.debug('Changing setting', name, value); |
|
697 | if( $.isPlainObject(name) ) { |
|
698 | $.extend(true, settings, name); |
|
699 | } |
|
700 | else if(value !== undefined) { |
|
701 | if($.isPlainObject(settings[name])) { |
|
702 | $.extend(true, settings[name], value); |
|
703 | } |
|
704 | else { |
|
705 | settings[name] = value; |
|
706 | } |
|
707 | } |
|
708 | else { |
|
709 | return settings[name]; |
|
710 | } |
|
711 | }, |
|
712 | internal: function(name, value) { |
|
713 | if( $.isPlainObject(name) ) { |
|
714 | $.extend(true, module, name); |
|
715 | } |
|
716 | else if(value !== undefined) { |
|
717 | module[name] = value; |
|
718 | } |
|
719 | else { |
|
720 | return module[name]; |
|
721 | } |
|
722 | }, |
|
723 | debug: function() { |
|
724 | if(!settings.silent && settings.debug) { |
|
725 | if(settings.performance) { |
|
726 | module.performance.log(arguments); |
|
727 | } |
|
728 | else { |
|
729 | module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
|
730 | module.debug.apply(console, arguments); |
|
731 | } |
|
732 | } |
|
733 | }, |
|
734 | verbose: function() { |
|
735 | if(!settings.silent && settings.verbose && settings.debug) { |
|
736 | if(settings.performance) { |
|
737 | module.performance.log(arguments); |
|
738 | } |
|
739 | else { |
|
740 | module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); |
|
741 | module.verbose.apply(console, arguments); |
|
742 | } |
|
743 | } |
|
744 | }, |
|
745 | error: function() { |
|
746 | if(!settings.silent) { |
|
747 | module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); |
|
748 | module.error.apply(console, arguments); |
|
749 | } |
|
750 | }, |
|
751 | performance: { |
|
752 | log: function(message) { |
|
753 | var |
|
754 | currentTime, |
|
755 | executionTime, |
|
756 | previousTime |
|
757 | ; |
|
758 | if(settings.performance) { |
|
759 | currentTime = new Date().getTime(); |
|
760 | previousTime = time || currentTime; |
|
761 | executionTime = currentTime - previousTime; |
|
762 | time = currentTime; |
|
763 | performance.push({ |
|
764 | 'Name' : message[0], |
|
765 | 'Arguments' : [].slice.call(message, 1) || '', |
|
766 | 'Element' : element, |
|
767 | 'Execution Time' : executionTime |
|
768 | }); |
|
769 | } |
|
770 | clearTimeout(module.performance.timer); |
|
771 | module.performance.timer = setTimeout(module.performance.display, 500); |
|
772 | }, |
|
773 | display: function() { |
|
774 | var |
|
775 | title = settings.name + ':', |
|
776 | totalTime = 0 |
|
777 | ; |
|
778 | time = false; |
|
779 | clearTimeout(module.performance.timer); |
|
780 | $.each(performance, function(index, data) { |
|
781 | totalTime += data['Execution Time']; |
|
782 | }); |
|
783 | title += ' ' + totalTime + 'ms'; |
|
784 | if(moduleSelector) { |
|
785 | title += ' \'' + moduleSelector + '\''; |
|
786 | } |
|
787 | if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { |
|
788 | console.groupCollapsed(title); |
|
789 | if(console.table) { |
|
790 | console.table(performance); |
|
791 | } |
|
792 | else { |
|
793 | $.each(performance, function(index, data) { |
|
794 | console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); |
|
795 | }); |
|
796 | } |
|
797 | console.groupEnd(); |
|
798 | } |
|
799 | performance = []; |
|
800 | } |
|
801 | }, |
|
802 | invoke: function(query, passedArguments, context) { |
|
803 | var |
|
804 | object = instance, |
|
805 | maxDepth, |
|
806 | found, |
|
807 | response |
|
808 | ; |
|
809 | passedArguments = passedArguments || queryArguments; |
|
810 | context = element || context; |
|
811 | if(typeof query == 'string' && object !== undefined) { |
|
812 | query = query.split(/[\. ]/); |
|
813 | maxDepth = query.length - 1; |
|
814 | $.each(query, function(depth, value) { |
|
815 | var camelCaseValue = (depth != maxDepth) |
|
816 | ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) |
|
817 | : query |
|
818 | ; |
|
819 | if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { |
|
820 | object = object[camelCaseValue]; |
|
821 | } |
|
822 | else if( object[camelCaseValue] !== undefined ) { |
|
823 | found = object[camelCaseValue]; |
|
824 | return false; |
|
825 | } |
|
826 | else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { |
|
827 | object = object[value]; |
|
828 | } |
|
829 | else if( object[value] !== undefined ) { |
|
830 | found = object[value]; |
|
831 | return false; |
|
832 | } |
|
833 | else { |
|
834 | module.error(error.method, query); |
|
835 | return false; |
|
836 | } |
|
837 | }); |
|
838 | } |
|
839 | if ( $.isFunction( found ) ) { |
|
840 | response = found.apply(context, passedArguments); |
|
841 | } |
|
842 | else if(found !== undefined) { |
|
843 | response = found; |
|
844 | } |
|
845 | if($.isArray(returnedValue)) { |
|
846 | returnedValue.push(response); |
|
847 | } |
|
848 | else if(returnedValue !== undefined) { |
|
849 | returnedValue = [returnedValue, response]; |
|
850 | } |
|
851 | else if(response !== undefined) { |
|
852 | returnedValue = response; |
|
853 | } |
|
854 | return found; |
|
855 | } |
|
856 | }; |
|
857 | if(methodInvoked) { |
|
858 | if(instance === undefined) { |
|
859 | module.initialize(); |
|
860 | } |
|
861 | module.invoke(query); |
|
862 | } |
|
863 | else { |
|
864 | if(instance !== undefined) { |
|
865 | instance.invoke('destroy'); |
|
866 | } |
|
867 | module.initialize(); |
|
868 | } |
|
869 | }) |
|
870 | ; |
|
871 | return (returnedValue !== undefined) |
|
872 | ? returnedValue |
|
873 | : this |
|
874 | ; |
|
875 | ||
876 | }; |
|
877 | ||
878 | // shortcut for tabbed content with no defined navigation |
|
879 | $.tab = function() { |
|
880 | $(window).tab.apply(this, arguments); |
|
881 | }; |
|
882 | ||
883 | $.fn.tab.settings = { |
|
884 | ||
885 | name : 'Tab', |
|
886 | namespace : 'tab', |
|
887 | ||
888 | silent : false, |
|
889 | debug : false, |
|
890 | verbose : false, |
|
891 | performance : true, |
|
892 | ||
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 |
|
897 | ||
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 |
|
901 | ||
902 | deactivate : 'siblings', // whether tabs should deactivate sibling menu elements or all elements initialized together |
|
903 | ||
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 |
|
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 | ||
913 | onFirstLoad : function(tabPath, parameterArray, historyEvent) {}, // called first time loaded |
|
914 | onLoad : function(tabPath, parameterArray, historyEvent) {}, // called on every load |
|
915 | onVisible : function(tabPath, parameterArray, historyEvent) {}, // called every time tab visible |
|
916 | onRequest : function(tabPath, parameterArray, historyEvent) {}, // called ever time a tab beings loading remote content |
|
917 | ||
918 | templates : { |
|
919 | determineTitle: function(tabArray) {} // returns page title for path |
|
920 | }, |
|
921 | ||
922 | error: { |
|
923 | api : 'You attempted to load content without API module', |
|
924 | method : 'The method you called is not defined', |
|
925 | missingTab : 'Activated tab cannot be found. Tabs are case-sensitive.', |
|
926 | noContent : 'The tab you specified is missing a content url.', |
|
927 | path : 'History enabled, but no path was specified', |
|
928 | recursion : 'Max recursive depth reached', |
|
929 | legacyInit : 'onTabInit has been renamed to onFirstLoad in 2.0, please adjust your code.', |
|
930 | legacyLoad : 'onTabLoad has been renamed to onLoad in 2.0. Please adjust your code', |
|
931 | state : 'History requires Asual\'s Address library <https://github.com/asual/jquery-address>' |
|
932 | }, |
|
933 | ||
934 | metadata : { |
|
935 | tab : 'tab', |
|
936 | loaded : 'loaded', |
|
937 | promise: 'promise' |
|
938 | }, |
|
939 | ||
940 | className : { |
|
941 | loading : 'loading', |
|
942 | active : 'active' |
|
943 | }, |
|
944 | ||
945 | selector : { |
|
946 | tabs : '.ui.tab', |
|
947 | ui : '.ui' |
|
948 | } |
|
949 | ||
950 | }; |
|
951 | ||
952 | })( jQuery, window, document ); |
|
953 |