ace.js 97 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179
  1. /*!
  2. * Ace v1.3.2
  3. */
  4. if (typeof jQuery === 'undefined') { throw new Error('Ace\'s JavaScript requires jQuery') }
  5. /**
  6. Required. Ace's Basic File to Initiliaze Different Parts and Some Variables.
  7. */
  8. (function($ , undefined) {
  9. if( !('ace' in window) ) window['ace'] = {}
  10. if( !('helper' in window['ace']) ) window['ace'].helper = {}
  11. if( !('vars' in window['ace']) ) window['ace'].vars = {}
  12. window['ace'].vars['icon'] = ' ace-icon ';
  13. window['ace'].vars['.icon'] = '.ace-icon';
  14. ace.vars['touch'] = ('ontouchstart' in document.documentElement);//(('ontouchstart' in document.documentElement) || (window.DocumentTouch && document instanceof DocumentTouch));
  15. //sometimes we try to use 'tap' event instead of 'click' if jquery mobile plugin is available
  16. ace['click_event'] = ace.vars['touch'] && $.fn.tap ? 'tap' : 'click';
  17. //sometimes the only good way to work around browser's pecularities is to detect them using user-agents
  18. //though it's not accurate
  19. var agent = navigator.userAgent
  20. ace.vars['webkit'] = !!agent.match(/AppleWebKit/i)
  21. ace.vars['safari'] = !!agent.match(/Safari/i) && !agent.match(/Chrome/i);
  22. ace.vars['android'] = ace.vars['safari'] && !!agent.match(/Android/i)
  23. ace.vars['ios_safari'] = !!agent.match(/OS ([4-9])(_\d)+ like Mac OS X/i) && !agent.match(/CriOS/i)
  24. ace.vars['ie'] = window.navigator.msPointerEnabled || (document.all && document.querySelector);//8-11
  25. ace.vars['old_ie'] = document.all && !document.addEventListener;//8 and below
  26. ace.vars['very_old_ie'] = document.all && !document.querySelector;//7 and below
  27. ace.vars['firefox'] = 'MozAppearance' in document.documentElement.style;
  28. ace.vars['non_auto_fixed'] = ace.vars['android'] || ace.vars['ios_safari'];
  29. })(jQuery);
  30. jQuery(function($) {
  31. basics();
  32. enableSidebar();
  33. enableAjax();
  34. handleScrollbars();
  35. dropdownAutoPos();
  36. navbarHelpers();
  37. sidebarTooltips();
  38. scrollTopBtn();
  39. someBrowserFix();
  40. bsCollapseToggle();
  41. smallDeviceDropdowns();
  42. ////////////////////////////
  43. function basics() {
  44. // for android and ios we don't use "top:auto" when breadcrumbs is fixed
  45. if(ace.vars['non_auto_fixed']) {
  46. $('body').addClass('mob-safari');
  47. }
  48. ace.vars['transition'] = !!$.support.transition.end
  49. }
  50. function enableSidebar() {
  51. //initiate sidebar function
  52. var $sidebar = $('.sidebar');
  53. if($.fn.ace_sidebar) $sidebar.ace_sidebar();
  54. if($.fn.ace_sidebar_scroll) $sidebar.ace_sidebar_scroll({
  55. //'scroll_style': 'scroll-dark scroll-thin',
  56. 'scroll_to_active': true, //scroll to selected item? (one time only on page load)
  57. 'include_shortcuts': true, //true = include shortcut buttons in the scrollbars
  58. 'include_toggle': false || ace.vars['safari'] || ace.vars['ios_safari'], //true = include toggle button in the scrollbars
  59. 'smooth_scroll': 150, //> 0 means smooth_scroll, time in ms, used in first approach only, better to be almost half the amount of submenu transition time
  60. 'outside': false//true && ace.vars['touch'] //used in first approach only, true means the scrollbars should be outside of the sidebar
  61. });
  62. if($.fn.ace_sidebar_hover) $sidebar.ace_sidebar_hover({
  63. 'sub_hover_delay': 750,
  64. 'sub_scroll_style': 'no-track scroll-thin scroll-margin scroll-visible'
  65. });
  66. }
  67. function enableAjax() {
  68. //Load content via ajax
  69. if($.fn.ace_ajax) {
  70. $('[data-ajax-content=true]').ace_ajax({
  71. 'close_active': true,
  72. 'content_url': function(hash) {
  73. //***NOTE***
  74. //this is for Ace demo only, you should change it to return a valid URL
  75. //please refer to documentation for more info
  76. if( !hash.match(/^page\//) ) return false;
  77. var path = document.location.pathname;
  78. //for example in Ace HTML demo version we convert /ajax/ajax.html#page/gallery to > /ajax/gallery.html and load it
  79. if(path.match(/(\/ajax\/)(ajax\.html)?/))
  80. return path.replace(/(\/ajax\/)(ajax\.html)?/, '/ajax/'+hash.replace(/^page\//, '')+'.html') ;
  81. //for example in Ace PHP demo version we convert "ajax.php#page/dashboard" to "ajax.php?page=dashboard" and load it
  82. return path + "?" + hash.replace(/\//, "=");
  83. },
  84. 'default_url': 'page/index'//default hash
  85. })
  86. }
  87. }
  88. /////////////////////////////
  89. function handleScrollbars() {
  90. //add scrollbars for navbar dropdowns
  91. var has_scroll = !!$.fn.ace_scroll;
  92. if(has_scroll) $('.dropdown-content').ace_scroll({reset: false, mouseWheelLock: true})
  93. //reset scrolls bars on window resize
  94. if(has_scroll && !ace.vars['old_ie']) {//IE has an issue with widget fullscreen on ajax?!!!
  95. $(window).on('resize.reset_scroll', function() {
  96. $('.ace-scroll:not(.scroll-disabled)').not(':hidden').ace_scroll('reset');
  97. });
  98. if(has_scroll) $(document).on('settings.ace.reset_scroll', function(e, name) {
  99. if(name == 'sidebar_collapsed') $('.ace-scroll:not(.scroll-disabled)').not(':hidden').ace_scroll('reset');
  100. });
  101. }
  102. }
  103. function dropdownAutoPos() {
  104. //change a dropdown to "dropup" depending on its position
  105. $(document).on('click.dropdown.pos', '.dropdown-toggle[data-position="auto"]', function() {
  106. var offset = $(this).offset();
  107. var parent = $(this.parentNode);
  108. if ( parseInt(offset.top + $(this).height()) + 50
  109. >
  110. (ace.helper.scrollTop() + ace.helper.winHeight() - parent.find('.dropdown-menu').eq(0).height())
  111. ) parent.addClass('dropup');
  112. else parent.removeClass('dropup');
  113. });
  114. }
  115. function navbarHelpers() {
  116. //prevent dropdowns from hiding when a from is clicked
  117. /**$(document).on('click', '.dropdown-navbar form', function(e){
  118. e.stopPropagation();
  119. });*/
  120. //disable navbar icon animation upon click
  121. $('.ace-nav [class*="icon-animated-"]').closest('a').one('click', function(){
  122. var icon = $(this).find('[class*="icon-animated-"]').eq(0);
  123. var $match = icon.attr('class').match(/icon\-animated\-([\d\w]+)/);
  124. icon.removeClass($match[0]);
  125. });
  126. //prevent dropdowns from hiding when a tab is selected
  127. $(document).on('click', '.dropdown-navbar .nav-tabs', function(e){
  128. e.stopPropagation();
  129. var $this , href
  130. var that = e.target
  131. if( ($this = $(e.target).closest('[data-toggle=tab]')) && $this.length > 0) {
  132. $this.tab('show');
  133. e.preventDefault();
  134. $(window).triggerHandler('resize.navbar.dropdown')
  135. }
  136. });
  137. }
  138. function sidebarTooltips() {
  139. //tooltip in sidebar items
  140. $('.sidebar .nav-list .badge[title],.sidebar .nav-list .badge[title]').each(function() {
  141. var tooltip_class = $(this).attr('class').match(/tooltip\-(?:\w+)/);
  142. tooltip_class = tooltip_class ? tooltip_class[0] : 'tooltip-error';
  143. $(this).tooltip({
  144. 'placement': function (context, source) {
  145. var offset = $(source).offset();
  146. if( parseInt(offset.left) < parseInt(document.body.scrollWidth / 2) ) return 'right';
  147. return 'left';
  148. },
  149. container: 'body',
  150. template: '<div class="tooltip '+tooltip_class+'"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
  151. });
  152. });
  153. //or something like this if items are dynamically inserted
  154. /**
  155. $('.sidebar').tooltip({
  156. 'placement': function (context, source) {
  157. var offset = $(source).offset();
  158. if( parseInt(offset.left) < parseInt(document.body.scrollWidth / 2) ) return 'right';
  159. return 'left';
  160. },
  161. selector: '.nav-list .badge[title],.nav-list .label[title]',
  162. container: 'body',
  163. template: '<div class="tooltip tooltip-error"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
  164. });
  165. */
  166. }
  167. function scrollTopBtn() {
  168. //the scroll to top button
  169. var scroll_btn = $('.btn-scroll-up');
  170. if(scroll_btn.length > 0) {
  171. var is_visible = false;
  172. $(window).on('scroll.scroll_btn', function() {
  173. var scroll = ace.helper.scrollTop();
  174. var h = ace.helper.winHeight();
  175. var body_sH = document.body.scrollHeight;
  176. if(scroll > parseInt(h / 4) || (scroll > 0 && body_sH >= h && h + scroll >= body_sH - 1)) {//|| for smaller pages, when reached end of page
  177. if(!is_visible) {
  178. scroll_btn.addClass('display');
  179. is_visible = true;
  180. }
  181. } else {
  182. if(is_visible) {
  183. scroll_btn.removeClass('display');
  184. is_visible = false;
  185. }
  186. }
  187. }).triggerHandler('scroll.scroll_btn');
  188. scroll_btn.on(ace.click_event, function(){
  189. var duration = Math.min(500, Math.max(100, parseInt(ace.helper.scrollTop() / 3)));
  190. $('html,body').animate({scrollTop: 0}, duration);
  191. return false;
  192. });
  193. }
  194. }
  195. function someBrowserFix() {
  196. //chrome and webkit have a problem here when resizing from 479px to more
  197. //we should force them redraw the navbar!
  198. if( ace.vars['webkit'] ) {
  199. var ace_nav = $('.ace-nav').get(0);
  200. if( ace_nav ) $(window).on('resize.webkit_fix' , function(){
  201. ace.helper.redraw(ace_nav);
  202. });
  203. }
  204. //fix an issue with ios safari, when an element is fixed and an input receives focus
  205. if(ace.vars['ios_safari']) {
  206. $(document).on('ace.settings.ios_fix', function(e, event_name, event_val) {
  207. if(event_name != 'navbar_fixed') return;
  208. $(document).off('focus.ios_fix blur.ios_fix', 'input,textarea,.wysiwyg-editor');
  209. if(event_val == true) {
  210. $(document).on('focus.ios_fix', 'input,textarea,.wysiwyg-editor', function() {
  211. $(window).on('scroll.ios_fix', function() {
  212. var navbar = $('#navbar').get(0);
  213. if(navbar) ace.helper.redraw(navbar);
  214. });
  215. }).on('blur.ios_fix', 'input,textarea,.wysiwyg-editor', function() {
  216. $(window).off('scroll.ios_fix');
  217. })
  218. }
  219. }).triggerHandler('ace.settings.ios_fix', ['navbar_fixed', $('#navbar').css('position') == 'fixed']);
  220. }
  221. }
  222. function bsCollapseToggle() {
  223. //bootstrap collapse component icon toggle
  224. $(document).on('hide.bs.collapse show.bs.collapse', function (ev) {
  225. var panel_id = ev.target.getAttribute('id')
  226. var panel = $('a[href*="#'+ panel_id+'"]');
  227. if(panel.length == 0) panel = $('a[data-target*="#'+ panel_id+'"]');
  228. if(panel.length == 0) return;
  229. panel.find(ace.vars['.icon']).each(function(){
  230. var $icon = $(this)
  231. var $match
  232. var $icon_down = null
  233. var $icon_up = null
  234. if( ($icon_down = $icon.attr('data-icon-show')) ) {
  235. $icon_up = $icon.attr('data-icon-hide')
  236. }
  237. else if( $match = $icon.attr('class').match(/fa\-(.*)\-(up|down)/) ) {
  238. $icon_down = 'fa-'+$match[1]+'-down'
  239. $icon_up = 'fa-'+$match[1]+'-up'
  240. }
  241. if($icon_down) {
  242. if(ev.type == 'show') $icon.removeClass($icon_down).addClass($icon_up)
  243. else $icon.removeClass($icon_up).addClass($icon_down)
  244. return false;//ignore other icons that match, one is enough
  245. }
  246. });
  247. })
  248. }
  249. //in small devices display navbar dropdowns like modal boxes
  250. function smallDeviceDropdowns() {
  251. if(ace.vars['old_ie']) return;
  252. $('.ace-nav > li')
  253. .on('shown.bs.dropdown.navbar', function(e) {
  254. adjustNavbarDropdown.call(this);
  255. })
  256. .on('hidden.bs.dropdown.navbar', function(e) {
  257. $(window).off('resize.navbar.dropdown');
  258. resetNavbarDropdown.call(this);
  259. })
  260. function adjustNavbarDropdown() {
  261. var $sub = $(this).find('> .dropdown-menu');
  262. if( $sub.css('position') == 'fixed' ) {
  263. var win_width = parseInt($(window).width());
  264. var offset_w = win_width > 320 ? 60 : (win_width > 240 ? 40 : 30);
  265. var avail_width = parseInt(win_width) - offset_w;
  266. var avail_height = parseInt($(window).height()) - 30;
  267. var width = parseInt(Math.min(avail_width , 320));
  268. //we set 'width' here for text wrappings and spacings to take effect before calculating scrollHeight
  269. $sub.css('width', width);
  270. var tabbed = false;
  271. var extra_parts = 0;
  272. var dropdown_content = $sub.find('.tab-pane.active .dropdown-content.ace-scroll');
  273. if(dropdown_content.length == 0) dropdown_content = $sub.find('.dropdown-content.ace-scroll');
  274. else tabbed = true;
  275. var parent_menu = dropdown_content.closest('.dropdown-menu');
  276. var scrollHeight = $sub[0].scrollHeight;
  277. if(dropdown_content.length == 1) {
  278. //sometimes there's no scroll-content, for example in detached scrollbars
  279. var content = dropdown_content.find('.scroll-content')[0];
  280. if(content) {
  281. scrollHeight = content.scrollHeight;
  282. }
  283. extra_parts += parent_menu.find('.dropdown-header').outerHeight();
  284. extra_parts += parent_menu.find('.dropdown-footer').outerHeight();
  285. var tab_content = parent_menu.closest('.tab-content');
  286. if( tab_content.length != 0 ) {
  287. extra_parts += tab_content.siblings('.nav-tabs').eq(0).height();
  288. }
  289. }
  290. var height = parseInt(Math.min(avail_height , 480, scrollHeight + extra_parts));
  291. var left = parseInt(Math.abs((avail_width + offset_w - width)/2));
  292. var top = parseInt(Math.abs((avail_height + 30 - height)/2));
  293. var zindex = parseInt($sub.css('z-index')) || 0;
  294. $sub.css({'height': height, 'left': left, 'right': 'auto', 'top': top - (!tabbed ? 1 : 3)});
  295. if(dropdown_content.length == 1) {
  296. if(!ace.vars['touch']) {
  297. dropdown_content.ace_scroll('update', {size: height - extra_parts}).ace_scroll('enable').ace_scroll('reset');
  298. }
  299. else {
  300. dropdown_content
  301. .ace_scroll('disable').css('max-height', height - extra_parts).addClass('overflow-scroll');
  302. }
  303. }
  304. $sub.css('height', height + (!tabbed ? 2 : 7));//for bottom border adjustment and tab content paddings
  305. if($sub.hasClass('user-menu')) {
  306. $sub.css('height', '');//because of user-info hiding/showing at different widths, which changes above 'scrollHeight', so we remove it!
  307. //user menu is re-positioned in small widths
  308. //but we need to re-position again in small heights as well (modal mode)
  309. var user_info = $(this).find('.user-info');
  310. if(user_info.length == 1 && user_info.css('position') == 'fixed') {
  311. user_info.css({'left': left, 'right': 'auto', 'top': top, 'width': width - 2, 'max-width': width - 2, 'z-index': zindex + 1});
  312. }
  313. else user_info.css({'left': '', 'right': '', 'top': '', 'width': '', 'max-width': '', 'z-index': ''});
  314. }
  315. //dropdown's z-index is limited by parent .navbar's z-index (which doesn't make sense because dropdowns are fixed!)
  316. //so for example when in 'content-slider' page, fixed modal toggle buttons go above are dropdowns
  317. //so we increase navbar's z-index to fix this!
  318. $(this).closest('.navbar.navbar-fixed-top').css('z-index', zindex);
  319. }
  320. else {
  321. if($sub.length != 0) resetNavbarDropdown.call(this, $sub);
  322. }
  323. var self = this;
  324. $(window)
  325. .off('resize.navbar.dropdown')
  326. .one('resize.navbar.dropdown', function() {
  327. $(self).triggerHandler('shown.bs.dropdown.navbar');
  328. })
  329. }
  330. //reset scrollbars and user menu
  331. function resetNavbarDropdown($sub) {
  332. $sub = $sub || $(this).find('> .dropdown-menu');
  333. if($sub.length > 0) {
  334. $sub
  335. .css({'width': '', 'height': '', 'left': '', 'right': '', 'top': ''})
  336. .find('.dropdown-content').each(function() {
  337. if(ace.vars['touch']) {
  338. $(this).css('max-height', '').removeClass('overflow-scroll');
  339. }
  340. var size = parseInt($(this).attr('data-size') || 0) || $.fn.ace_scroll.defaults.size;
  341. $(this).ace_scroll('update', {size: size}).ace_scroll('enable').ace_scroll('reset');
  342. })
  343. if( $sub.hasClass('user-menu') ) {
  344. var user_info =
  345. $(this).find('.user-info')
  346. .css({'left': '', 'right': '', 'top': '', 'width': '', 'max-width': '', 'z-index': ''});
  347. }
  348. }
  349. $(this).closest('.navbar').css('z-index', '');
  350. }
  351. }
  352. })
  353. //some functions
  354. ace.helper.redraw = function(elem, force) {
  355. var saved_val = elem.style['display'];
  356. elem.style.display = 'none';
  357. elem.offsetHeight;
  358. if(force !== true) {
  359. elem.style.display = saved_val;
  360. }
  361. else {
  362. //force redraw for example in old IE
  363. setTimeout(function() {
  364. elem.style.display = saved_val;
  365. }, 10);
  366. }
  367. }
  368. ace.helper.boolAttr = function(elem, attr) {
  369. return elem.getAttribute(attr) === "true";
  370. }
  371. ace.helper.intAttr = function(elem, attr) {
  372. return parseInt(elem.getAttribute(attr)) || 0;
  373. }
  374. ace.helper.scrollTop = function() {
  375. return document.scrollTop || document.documentElement.scrollTop || document.body.scrollTop
  376. //return $(window).scrollTop();
  377. }
  378. ace.helper.winHeight = function() {
  379. return window.innerHeight || document.documentElement.clientHeight;
  380. //return $(window).innerHeight();
  381. }
  382. ace.helper.camelCase = function(str) {
  383. return str.replace(/-([\da-z])/gi, function(match, chr) {
  384. return chr ? chr.toUpperCase() : '';
  385. });
  386. }
  387. ace.helper.removeStyle =
  388. 'removeProperty' in document.documentElement.style
  389. ?
  390. function(elem, prop) { elem.style.removeProperty(prop) }
  391. :
  392. function(elem, prop) { elem.style[ace.helper.camelCase(prop)] = '' }
  393. ace.helper.hasClass =
  394. 'classList' in document.documentElement
  395. ?
  396. function(elem, className) { return elem.classList.contains(className); }
  397. :
  398. function(elem, className) { return elem.className.indexOf(className) > -1; }
  399. ;/**
  400. <b>Load content via Ajax </b>. For more information please refer to documentation #basics/ajax
  401. */
  402. (function($ , undefined) {
  403. var ajax_loaded_scripts = {}
  404. function AceAjax(contentArea, options) {
  405. var $contentArea = $(contentArea);
  406. var self = this;
  407. var content_url = options.content_url || false
  408. var default_url = options.default_url || false;
  409. var loading_icon = options.loading_icon || 'fa-spinner fa-2x orange';
  410. var loading_text = options.loading_text || '';
  411. var update_breadcrumbs = options.update_breadcrumbs || options.update_breadcrumbs === undefined;
  412. var update_title = options.update_title || options.update_breadcrumbs === undefined;
  413. var update_active = options.update_active || options.update_breadcrumbs === undefined;
  414. var close_active = options.close_active || false;
  415. var max_load_wait = options.max_load_wait || false;
  416. var working = false;
  417. this.loadUrl = function(hash) {
  418. var url = false;
  419. hash = hash.replace(/^(\#\!)?\#/, '');
  420. if(typeof content_url === 'function') url = content_url(hash);
  421. if(typeof url === 'string') this.getUrl(url, hash, false);
  422. }
  423. this.getUrl = function(url, hash, manual_trigger) {
  424. if(working) {
  425. return;
  426. }
  427. var event
  428. $contentArea.trigger(event = $.Event('ajaxloadstart'), {url: url, hash: hash})
  429. if (event.isDefaultPrevented()) return;
  430. self.startLoading();
  431. $.ajax({
  432. 'url': url
  433. })
  434. .error(function() {
  435. $contentArea.trigger('ajaxloaderror', {url: url, hash: hash});
  436. self.stopLoading(true);
  437. })
  438. .done(function(result) {
  439. $contentArea.trigger('ajaxloaddone', {url: url, hash: hash});
  440. var link_element = null, link_text = '';;
  441. if(typeof update_active === 'function') {
  442. link_element = update_active.call(null, hash, url);
  443. }
  444. else if(update_active === true) {
  445. link_element = $('a[data-url="'+hash+'"]');
  446. if(link_element.length > 0) {
  447. var nav = link_element.closest('.nav');
  448. if(nav.length > 0) {
  449. nav.find('.active').each(function(){
  450. var $class = 'active';
  451. if( $(this).hasClass('hover') || close_active ) $class += ' open';
  452. $(this).removeClass($class);
  453. if(close_active) {
  454. $(this).find(' > .submenu').css('display', '');
  455. }
  456. })
  457. var active_li = link_element.closest('li').addClass('active').parents('.nav li').addClass('active open');
  458. nav.closest('.sidebar[data-sidebar-scroll=true]').each(function() {
  459. var $this = $(this);
  460. $this.ace_sidebar_scroll('reset');
  461. if(manual_trigger) $this.ace_sidebar_scroll('scroll_to_active');//first time only
  462. })
  463. }
  464. }
  465. }
  466. /////////
  467. if(typeof update_breadcrumbs === 'function') {
  468. link_text = update_breadcrumbs.call(null, hash, url, link_element);
  469. }
  470. else if(update_breadcrumbs === true && link_element != null && link_element.length > 0) {
  471. link_text = updateBreadcrumbs(link_element);
  472. }
  473. /////////
  474. //convert "title" and "link" tags to "div" tags for later processing
  475. result = String(result)
  476. .replace(/<(title|link)([\s\>])/gi,'<div class="hidden ajax-append-$1"$2')
  477. .replace(/<\/(title|link)\>/gi,'</div>')
  478. $contentArea.empty().html(result);
  479. $contentArea.css('opacity', 0.6);
  480. //remove previous stylesheets inserted via ajax
  481. setTimeout(function() {
  482. $('head').find('link.ace-ajax-stylesheet').remove();
  483. var main_selectors = ['link.ace-main-stylesheet', 'link#main-ace-style', 'link[href*="/ace.min.css"]', 'link[href*="/ace.css"]']
  484. var ace_style = [];
  485. for(var m = 0; m < main_selectors.length; m++) {
  486. ace_style = $('head').find(main_selectors[m]).first();
  487. if(ace_style.length > 0) break;
  488. }
  489. $contentArea.find('.ajax-append-link').each(function(e) {
  490. var $link = $(this);
  491. if ( $link.attr('href') ) {
  492. var new_link = jQuery('<link />', {type : 'text/css', rel: 'stylesheet', 'class': 'ace-ajax-stylesheet'})
  493. if( ace_style.length > 0 ) new_link.insertBefore(ace_style);
  494. else new_link.appendTo('head');
  495. new_link.attr('href', $link.attr('href'));//we set "href" after insertion, for IE to work
  496. }
  497. $link.remove();
  498. })
  499. }, 10);
  500. //////////////////////
  501. if(typeof update_title === 'function') {
  502. update_title.call(null, hash, url, link_text);
  503. }
  504. else if(update_title === true) {
  505. updateTitle(link_text);
  506. }
  507. if( !manual_trigger ) {
  508. $('html,body').animate({scrollTop: 0}, 250);
  509. }
  510. //////////////////////
  511. $contentArea.trigger('ajaxloadcomplete', {url: url, hash: hash});
  512. //////////////////////
  513. self.stopLoading();
  514. })
  515. }
  516. ///////////////////////
  517. var loadTimer = null;
  518. this.startLoading = function() {
  519. if(working) return;
  520. working = true;
  521. $contentArea
  522. .css('opacity', 0.25)
  523. .prevAll('.ajax-loading-overlay').remove();
  524. $('<div class="ajax-loading-overlay"><i class="ajax-loading-icon fa fa-spin '+loading_icon+'"></i> '+loading_text+'</div>').insertBefore(contentArea);
  525. if(max_load_wait !== false)
  526. loadTimer = setTimeout(function() {
  527. loadTimer = null;
  528. if(!working) return;
  529. var event
  530. $contentArea.trigger(event = $.Event('ajaxloadlong'))
  531. if (event.isDefaultPrevented()) return;
  532. self.stopLoading(true);
  533. }, max_load_wait * 1000);
  534. }
  535. this.stopLoading = function(stopNow) {
  536. if(stopNow === true) {
  537. working = false;
  538. $contentArea
  539. .css('opacity', 1)
  540. .prevAll('.ajax-loading-overlay').remove();
  541. if(loadTimer != null) {
  542. clearTimeout(loadTimer);
  543. loadTimer = null;
  544. }
  545. }
  546. else {
  547. $contentArea.css('opacity', 0.75)
  548. $contentArea.one('ajaxscriptsloaded', function() {
  549. self.stopLoading(true);
  550. })
  551. }
  552. }
  553. ///////////////////////
  554. function updateBreadcrumbs(link_element) {
  555. var link_text = '';
  556. //update breadcrumbs
  557. var breadcrumbs = $('.breadcrumb');
  558. if(breadcrumbs.length > 0 && breadcrumbs.is(':visible')) {
  559. breadcrumbs.find('> li:not(:first-child)').remove();
  560. var i = 0;
  561. link_element.parents('.nav li').each(function() {
  562. var link = $(this).find('> a');
  563. var link_clone = link.clone();
  564. link_clone.find('i,.fa,.glyphicon,.ace-icon,.menu-icon,.badge,.label').remove();
  565. var text = link_clone.text();
  566. link_clone.remove();
  567. var href = link.attr('href');
  568. if(i == 0) {
  569. var li = $('<li class="active"></li>').appendTo(breadcrumbs);
  570. li.text(text);
  571. link_text = text;
  572. }
  573. else {
  574. var li = $('<li><a /></li>').insertAfter(breadcrumbs.find('> li:first-child'));
  575. li.find('a').attr('href', href).text(text);
  576. }
  577. i++;
  578. })
  579. }
  580. return link_text;
  581. }
  582. function updateTitle(link_text) {
  583. var $title = $contentArea.find('.ajax-append-title');
  584. if($title.length > 0) {
  585. document.title = $title.text();
  586. $title.remove();
  587. }
  588. else if(link_text.length > 0) {
  589. var extra = $.trim(String(document.title).replace(/^(.*)[\-]/, ''));//for example like " - Ace Admin"
  590. if(extra) extra = ' - ' + extra;
  591. link_text = $.trim(link_text) + extra;
  592. }
  593. }
  594. this.loadScripts = function(scripts, callback) {
  595. $.ajaxPrefilter('script', function(opts) {opts.cache = true});
  596. setTimeout(function() {
  597. //let's keep a list of loaded scripts so that we don't load them more than once!
  598. function finishLoading() {
  599. if(typeof callback === 'function') callback();
  600. $('.btn-group[data-toggle="buttons"] > .btn').button();
  601. $contentArea.trigger('ajaxscriptsloaded');
  602. }
  603. //var deferreds = [];
  604. var deferred_count = 0;//deferreds count
  605. var resolved = 0;
  606. for(var i = 0; i < scripts.length; i++) if(scripts[i]) {
  607. (function() {
  608. var script_name = "js-"+scripts[i].replace(/[^\w\d\-]/g, '-').replace(/\-\-/g, '-');
  609. if( ajax_loaded_scripts[script_name] !== true ) deferred_count++;
  610. })()
  611. }
  612. function nextScript(index) {
  613. index += 1;
  614. if(index < scripts.length) loadScript(index);
  615. else {
  616. finishLoading();
  617. }
  618. }
  619. function loadScript(index) {
  620. index = index || 0;
  621. if(!scripts[index]) {//could be null sometimes
  622. return nextScript(index);
  623. }
  624. var script_name = "js-"+scripts[index].replace(/[^\w\d\-]/g, '-').replace(/\-\-/g, '-');
  625. //only load scripts that are not loaded yet!
  626. if( ajax_loaded_scripts[script_name] !== true ) {
  627. $.getScript(scripts[index])
  628. .done(function() {
  629. ajax_loaded_scripts[script_name] = true;
  630. })
  631. //.fail(function() {
  632. //})
  633. .complete(function() {
  634. resolved++;
  635. if(resolved >= deferred_count && working) {
  636. finishLoading();
  637. }
  638. else {
  639. nextScript(index);
  640. }
  641. })
  642. }
  643. else {//script previoisly loaded
  644. nextScript(index);
  645. }
  646. }
  647. if (deferred_count > 0) {
  648. loadScript();
  649. }
  650. else {
  651. finishLoading();
  652. }
  653. }, 10)
  654. }
  655. /////////////////
  656. $(window)
  657. .off('hashchange.ace_ajax')
  658. .on('hashchange.ace_ajax', function(e, manual_trigger) {
  659. var hash = $.trim(window.location.hash);
  660. if(!hash || hash.length == 0) return;
  661. self.loadUrl(hash);
  662. }).trigger('hashchange.ace_ajax', [true]);
  663. var hash = $.trim(window.location.hash);
  664. if(!hash && default_url) window.location.hash = default_url;
  665. }//AceAjax
  666. $.fn.aceAjax = $.fn.ace_ajax = function (option, value, value2) {
  667. var method_call;
  668. var $set = this.each(function () {
  669. var $this = $(this);
  670. var data = $this.data('ace_ajax');
  671. var options = typeof option === 'object' && option;
  672. if (!data) $this.data('ace_ajax', (data = new AceAjax(this, options)));
  673. if (typeof option === 'string' && typeof data[option] === 'function') {
  674. if(value2 != undefined) method_call = data[option](value, value2);
  675. else method_call = data[option](value);
  676. }
  677. });
  678. return (method_call === undefined) ? $set : method_call;
  679. }
  680. })(window.jQuery);
  681. ;/**
  682. <b>Custom drag event for touch devices</b> used in scrollbars.
  683. For better touch event handling and extra options a more advanced solution such as <u>Hammer.js</u> is recommended.
  684. */
  685. //based on but not dependent on jQuery mobile
  686. /*
  687. * jQuery Mobile v1.3.2
  688. * http://jquerymobile.com
  689. *
  690. * Copyright 2010, 2013 jQuery Foundation, Inc. and other contributors
  691. * Released under the MIT license.
  692. * http://jquery.org/license
  693. *
  694. */
  695. (function($ , undefined) {
  696. if(!ace.vars['touch']) return;
  697. var touchStartEvent = "touchstart MSPointerDown pointerdown",// : "mousedown",
  698. touchStopEvent = "touchend touchcancel MSPointerUp MSPointerCancel pointerup pointercancel",// : "mouseup",
  699. touchMoveEvent = "touchmove MSPointerMove MSPointerHover pointermove";// : "mousemove";
  700. $.event.special.ace_drag = {
  701. setup: function() {
  702. var min_threshold = 0;
  703. var $this = $(this);
  704. $this.on(touchStartEvent, function(event) {
  705. var data = event.originalEvent.touches ?
  706. event.originalEvent.touches[ 0 ] :
  707. event,
  708. start = {
  709. //time: Date.now(),
  710. coords: [ data.pageX, data.pageY ],
  711. origin: $(event.target)
  712. },
  713. stop;
  714. //start.origin.trigger({'type' : 'ace_dragStart', 'start':(start || [-1,-1])});
  715. var direction = false, dx = 0, dy = 0;
  716. function moveHandler(event) {
  717. if (!start) {
  718. return;
  719. }
  720. var data = event.originalEvent.touches ?
  721. event.originalEvent.touches[ 0 ] :
  722. event;
  723. stop = {
  724. coords: [ data.pageX, data.pageY ]
  725. };
  726. // prevent scrolling
  727. //if ( Math.abs(start.coords[1] - stop.coords[1]) > 0 || Math.abs(start.coords[0] - stop.coords[01]) > 0 ) {
  728. //event.preventDefault();
  729. //}
  730. if (start && stop) {
  731. dx = 0;
  732. dy = 0;
  733. direction =
  734. (
  735. Math.abs(dy = start.coords[ 1 ] - stop.coords[ 1 ]) > min_threshold
  736. &&
  737. Math.abs(dx = start.coords[ 0 ] - stop.coords[ 0 ]) <= Math.abs(dy)
  738. )
  739. ?
  740. (dy > 0 ? 'up' : 'down')
  741. :
  742. (
  743. Math.abs(dx = start.coords[ 0 ] - stop.coords[ 0 ]) > min_threshold
  744. &&
  745. Math.abs( dy ) <= Math.abs(dx)
  746. )
  747. ?
  748. (dx > 0 ? 'left' : 'right')
  749. :
  750. false;
  751. if( direction !== false ) {
  752. var retval = {cancel: false}
  753. start.origin.trigger({
  754. 'type': 'ace_drag',
  755. //'start': start.coords,
  756. //'stop': stop.coords,
  757. 'direction': direction,
  758. 'dx': dx,
  759. 'dy': dy,
  760. 'retval': retval
  761. })
  762. // prevent document scrolling unless retval.cancel == true
  763. if( retval.cancel == false ) event.preventDefault();
  764. }
  765. }
  766. start.coords[0] = stop.coords[0];
  767. start.coords[1] = stop.coords[1];
  768. }
  769. $this
  770. .on(touchMoveEvent, moveHandler)
  771. .one(touchStopEvent, function(event) {
  772. $this.off(touchMoveEvent, moveHandler);
  773. //start.origin.trigger({'type' : 'ace_dragEnd', 'stop':(stop || [-1,-1])});
  774. start = stop = undefined;
  775. });
  776. });
  777. }
  778. }
  779. })(window.jQuery);;/**
  780. <b>Sidebar functions</b>. Collapsing/expanding, toggling mobile view menu and other sidebar functions.
  781. */
  782. (function($ , undefined) {
  783. var sidebar_count = 0;
  784. function Sidebar(sidebar, options) {
  785. var self = this;
  786. this.$sidebar = $(sidebar);
  787. this.$sidebar.attr('data-sidebar', 'true');
  788. if( !this.$sidebar.attr('id') ) this.$sidebar.attr( 'id' , 'id-sidebar-'+(++sidebar_count) )
  789. var duration = options.duration || ace.helper.intAttr(sidebar, 'data-submenu-duration') ||300;//transition duration
  790. //some vars
  791. this.minimized = false;//will be initiated later
  792. this.collapsible = false;//...
  793. this.horizontal = false;//...
  794. this.mobile_view = false;//
  795. this.vars = function() {
  796. return {'minimized': this.minimized, 'collapsible': this.collapsible, 'horizontal': this.horizontal, 'mobile_view': this.mobile_view}
  797. }
  798. this.get = function(name) {
  799. if(this.hasOwnProperty(name)) return this[name];
  800. }
  801. this.set = function(name, value) {
  802. if(this.hasOwnProperty(name)) this[name] = value;
  803. }
  804. this.ref = function() {
  805. //return a reference to self
  806. return this;
  807. }
  808. var toggleIcon = function(minimized) {
  809. var icon = $(this).find(ace.vars['.icon']), icon1, icon2;
  810. if(icon.length > 0) {
  811. icon1 = icon.attr('data-icon1');//the icon for expanded state
  812. icon2 = icon.attr('data-icon2');//the icon for collapsed state
  813. if(minimized !== undefined) {
  814. if(minimized) icon.removeClass(icon1).addClass(icon2);
  815. else icon.removeClass(icon2).addClass(icon1);
  816. }
  817. else {
  818. icon.toggleClass(icon1).toggleClass(icon2);
  819. }
  820. }
  821. }
  822. var findToggleBtn = function() {
  823. var toggle_btn = self.$sidebar.find('.sidebar-collapse');
  824. if(toggle_btn.length == 0) toggle_btn = $('.sidebar-collapse[data-target="#'+(self.$sidebar.attr('id')||'')+'"]');
  825. if(toggle_btn.length != 0) toggle_btn = toggle_btn[0];
  826. else toggle_btn = null;
  827. return toggle_btn;
  828. }
  829. //collapse/expand button
  830. this.toggleMenu = function(toggle_btn, save) {
  831. if(this.collapsible) return;
  832. //var minimized = this.$sidebar.hasClass('menu-min');
  833. this.minimized = !this.minimized;
  834. try {
  835. //toggle_btn can also be a param to indicate saving to cookie or not?! if toggle_btn === false, it won't be saved
  836. ace.settings.sidebar_collapsed(sidebar, this.minimized, !(toggle_btn === false || save === false));//@ ace-extra.js
  837. } catch(e) {
  838. if(this.minimized)
  839. this.$sidebar.addClass('menu-min');
  840. else this.$sidebar.removeClass('menu-min');
  841. }
  842. if( !toggle_btn ) {
  843. toggle_btn = findToggleBtn();
  844. }
  845. if(toggle_btn) {
  846. toggleIcon.call(toggle_btn, this.minimized);
  847. }
  848. //force redraw for ie8
  849. if(ace.vars['old_ie']) ace.helper.redraw(sidebar);
  850. }
  851. this.collapse = function(toggle_btn, save) {
  852. if(this.collapsible) return;
  853. this.minimized = false;
  854. this.toggleMenu(toggle_btn, save);
  855. }
  856. this.expand = function(toggle_btn, save) {
  857. if(this.collapsible) return;
  858. this.minimized = true;
  859. this.toggleMenu(toggle_btn, save);
  860. }
  861. //collapse/expand in 2nd mobile style
  862. this.toggleResponsive = function(toggle_btn) {
  863. if(!this.mobile_view || this.mobile_style != 3) return;
  864. if( this.$sidebar.hasClass('menu-min') ) {
  865. //remove menu-min because it interferes with responsive-max
  866. this.$sidebar.removeClass('menu-min');
  867. var btn = findToggleBtn();
  868. if(btn) toggleIcon.call(btn);
  869. }
  870. this.minimized = !this.$sidebar.hasClass('responsive-min');
  871. this.$sidebar.toggleClass('responsive-min responsive-max');
  872. if( !toggle_btn ) {
  873. toggle_btn = this.$sidebar.find('.sidebar-expand');
  874. if(toggle_btn.length == 0) toggle_btn = $('.sidebar-expand[data-target="#'+(this.$sidebar.attr('id')||'')+'"]');
  875. if(toggle_btn.length != 0) toggle_btn = toggle_btn[0];
  876. else toggle_btn = null;
  877. }
  878. if(toggle_btn) {
  879. var icon = $(toggle_btn).find(ace.vars['.icon']), icon1, icon2;
  880. if(icon.length > 0) {
  881. icon1 = icon.attr('data-icon1');//the icon for expanded state
  882. icon2 = icon.attr('data-icon2');//the icon for collapsed state
  883. icon.toggleClass(icon1).toggleClass(icon2);
  884. }
  885. }
  886. $(document).triggerHandler('settings.ace', ['sidebar_collapsed' , this.minimized]);
  887. }
  888. //some helper functions
  889. this.is_collapsible = function() {
  890. var toggle
  891. return (this.$sidebar.hasClass('navbar-collapse'))
  892. && ((toggle = $('.navbar-toggle[data-target="#'+(this.$sidebar.attr('id')||'')+'"]').get(0)) != null)
  893. && toggle.scrollHeight > 0
  894. //sidebar is collapsible and collapse button is visible?
  895. }
  896. this.is_mobile_view = function() {
  897. var toggle
  898. return ((toggle = $('.menu-toggler[data-target="#'+(this.$sidebar.attr('id')||'')+'"]').get(0)) != null)
  899. && toggle.scrollHeight > 0
  900. }
  901. //toggling submenu
  902. this.$sidebar.on(ace.click_event+'.ace.submenu', '.nav-list', function (ev) {
  903. var nav_list = this;
  904. //check to see if we have clicked on an element which is inside a .dropdown-toggle element?!
  905. //if so, it means we should toggle a submenu
  906. var link_element = $(ev.target).closest('a');
  907. if(!link_element || link_element.length == 0) return;//return if not clicked inside a link element
  908. var minimized = self.minimized && !self.collapsible;
  909. //if .sidebar is .navbar-collapse and in small device mode, then let minimized be uneffective
  910. if( !link_element.hasClass('dropdown-toggle') ) {//it doesn't have a submenu return
  911. //just one thing before we return
  912. //if sidebar is collapsed(minimized) and we click on a first level menu item
  913. //and the click is on the icon, not on the menu text then let's cancel event and cancel navigation
  914. //Good for touch devices, that when the icon is tapped to see the menu text, navigation is cancelled
  915. //navigation is only done when menu text is tapped
  916. if( ace.click_event == 'tap'
  917. &&
  918. minimized
  919. &&
  920. link_element.get(0).parentNode.parentNode == nav_list )//only level-1 links
  921. {
  922. var text = link_element.find('.menu-text').get(0);
  923. if( text != null && ev.target != text && !$.contains(text , ev.target) ) {//not clicking on the text or its children
  924. ev.preventDefault();
  925. return false;
  926. }
  927. }
  928. //ios safari only has a bit of a problem not navigating to link address when scrolling down
  929. //specify data-link attribute to ignore this
  930. if(ace.vars['ios_safari'] && link_element.attr('data-link') !== 'false') {
  931. //only ios safari has a bit of a problem not navigating to link address when scrolling down
  932. //please see issues section in documentation
  933. document.location = link_element.attr('href');
  934. ev.preventDefault();
  935. return false;
  936. }
  937. return;
  938. }
  939. ev.preventDefault();
  940. var sub = link_element.siblings('.submenu').get(0);
  941. if(!sub) return false;
  942. var $sub = $(sub);
  943. var height_change = 0;//the amount of height change in .nav-list
  944. var parent_ul = sub.parentNode.parentNode;
  945. if
  946. (
  947. ( minimized && parent_ul == nav_list )
  948. ||
  949. ( ( $sub.parent().hasClass('hover') && $sub.css('position') == 'absolute' ) && !self.collapsible )
  950. )
  951. {
  952. return false;
  953. }
  954. var sub_hidden = (sub.scrollHeight == 0)
  955. //if not open and visible, let's open it and make it visible
  956. if( sub_hidden ) {//being shown now
  957. $(parent_ul).find('> .open > .submenu').each(function() {
  958. //close all other open submenus except for the active one
  959. if(this != sub && !$(this.parentNode).hasClass('active')) {
  960. height_change -= this.scrollHeight;
  961. self.hide(this, duration, false);
  962. }
  963. })
  964. }
  965. if( sub_hidden ) {//being shown now
  966. self.show(sub, duration);
  967. //if a submenu is being shown and another one previously started to hide, then we may need to update/hide scrollbars
  968. //but if no previous submenu is being hidden, then no need to check if we need to hide the scrollbars in advance
  969. if(height_change != 0) height_change += sub.scrollHeight;//we need new updated 'scrollHeight' here
  970. } else {
  971. self.hide(sub, duration);
  972. height_change -= sub.scrollHeight;
  973. //== -1 means submenu is being hidden
  974. }
  975. //hide scrollbars if content is going to be small enough that scrollbars is not needed anymore
  976. //do this almost before submenu hiding begins
  977. //but when minimized submenu's toggle should have no effect
  978. if (height_change != 0) {
  979. if(self.$sidebar.attr('data-sidebar-scroll') == 'true' && !self.minimized)
  980. self.$sidebar.ace_sidebar_scroll('prehide', height_change)
  981. }
  982. return false;
  983. })
  984. var submenu_working = false;
  985. this.show = function(sub, $duration, wait) {
  986. if(wait !== false) {
  987. if(submenu_working) return false;
  988. submenu_working = true;
  989. }
  990. $duration = $duration || duration;
  991. var $sub = $(sub);
  992. var event;
  993. $sub.trigger(event = $.Event('show.ace.submenu'))
  994. if (event.isDefaultPrevented()) return false;
  995. $sub.css({
  996. height: 0,
  997. overflow: 'hidden',
  998. display: 'block'
  999. })
  1000. .removeClass('nav-hide').addClass('nav-show')//only for window < @grid-float-breakpoint and .navbar-collapse.menu-min
  1001. .parent().addClass('open');
  1002. sub.scrollTop = 0;//this is for submenu_hover when sidebar is minimized and a submenu is scrollTop'ed using scrollbars ...
  1003. if( $duration > 0 ) {
  1004. $sub.css({height: sub.scrollHeight,
  1005. 'transition-property': 'height',
  1006. 'transition-duration': ($duration/1000)+'s'})
  1007. }
  1008. var complete = function(ev, trigger) {
  1009. ev && ev.stopPropagation();
  1010. $sub
  1011. .css({'transition-property': '', 'transition-duration': '', overflow:'', height: ''})
  1012. //if(ace.vars['webkit']) ace.helper.redraw(sub);//little Chrome issue, force redraw ;)
  1013. if(trigger !== false) $sub.trigger($.Event('shown.ace.submenu'))
  1014. if(wait !== false) submenu_working = false;
  1015. }
  1016. if( $duration > 0 && !!$.support.transition.end ) {
  1017. $sub.one($.support.transition.end, complete);
  1018. }
  1019. else complete();
  1020. //there is sometimes a glitch, so maybe retry
  1021. if(ace.vars['android']) {
  1022. setTimeout(function() {
  1023. complete(null, false);
  1024. ace.helper.redraw(sub);
  1025. }, $duration + 20);
  1026. }
  1027. return true;
  1028. }
  1029. this.hide = function(sub, $duration, wait) {
  1030. if(wait !== false) {
  1031. if(submenu_working) return false;
  1032. submenu_working = true;
  1033. }
  1034. $duration = $duration || duration;
  1035. var $sub = $(sub);
  1036. var event;
  1037. $sub.trigger(event = $.Event('hide.ace.submenu'))
  1038. if (event.isDefaultPrevented()) return false;
  1039. $sub.css({
  1040. height: sub.scrollHeight,
  1041. overflow: 'hidden',
  1042. display: 'block'
  1043. })
  1044. .parent().removeClass('open');
  1045. sub.offsetHeight;
  1046. //forces the "sub" to re-consider the new 'height' before transition
  1047. if( $duration > 0 ) {
  1048. $sub.css({'height': 0,
  1049. 'transition-property': 'height',
  1050. 'transition-duration': ($duration/1000)+'s'});
  1051. }
  1052. var complete = function(ev, trigger) {
  1053. ev && ev.stopPropagation();
  1054. $sub
  1055. .css({display: 'none', overflow:'', height: '', 'transition-property': '', 'transition-duration': ''})
  1056. .removeClass('nav-show').addClass('nav-hide')//only for window < @grid-float-breakpoint and .navbar-collapse.menu-min
  1057. if(trigger !== false) $sub.trigger($.Event('hidden.ace.submenu'))
  1058. if(wait !== false) submenu_working = false;
  1059. }
  1060. if( $duration > 0 && !!$.support.transition.end ) {
  1061. $sub.one($.support.transition.end, complete);
  1062. }
  1063. else complete();
  1064. //there is sometimes a glitch, so maybe retry
  1065. if(ace.vars['android']) {
  1066. setTimeout(function() {
  1067. complete(null, false);
  1068. ace.helper.redraw(sub);
  1069. }, $duration + 20);
  1070. }
  1071. return true;
  1072. }
  1073. this.toggle = function(sub, $duration) {
  1074. $duration = $duration || duration;
  1075. if( sub.scrollHeight == 0 ) {//if an element is hidden scrollHeight becomes 0
  1076. if( this.show(sub, $duration) ) return 1;
  1077. } else {
  1078. if( this.hide(sub, $duration) ) return -1;
  1079. }
  1080. return 0;
  1081. }
  1082. //sidebar vars
  1083. var minimized_menu_class = 'menu-min';
  1084. var responsive_min_class = 'responsive-min';
  1085. var horizontal_menu_class = 'h-sidebar';
  1086. var sidebar_mobile_style = function() {
  1087. //differnet mobile menu styles
  1088. this.mobile_style = 1;//default responsive mode with toggle button inside navbar
  1089. if(this.$sidebar.hasClass('responsive') && !$('.menu-toggler[data-target="#'+this.$sidebar.attr('id')+'"]').hasClass('navbar-toggle')) this.mobile_style = 2;//toggle button behind sidebar
  1090. else if(this.$sidebar.hasClass(responsive_min_class)) this.mobile_style = 3;//minimized menu
  1091. else if(this.$sidebar.hasClass('navbar-collapse')) this.mobile_style = 4;//collapsible (bootstrap style)
  1092. }
  1093. sidebar_mobile_style.call(self);
  1094. function update_vars() {
  1095. this.mobile_view = this.mobile_style < 4 && this.is_mobile_view();
  1096. this.collapsible = !this.mobile_view && this.is_collapsible();
  1097. this.minimized =
  1098. (!this.collapsible && this.$sidebar.hasClass(minimized_menu_class))
  1099. ||
  1100. (this.mobile_style == 3 && this.mobile_view && this.$sidebar.hasClass(responsive_min_class))
  1101. this.horizontal = !(this.mobile_view || this.collapsible) && this.$sidebar.hasClass(horizontal_menu_class)
  1102. }
  1103. //update some basic variables
  1104. $(window).on('resize.sidebar.vars' , function(){
  1105. update_vars.call(self);
  1106. }).triggerHandler('resize.sidebar.vars')
  1107. }//end of Sidebar
  1108. //sidebar events
  1109. //menu-toggler
  1110. $(document)
  1111. .on(ace.click_event+'.ace.menu', '.menu-toggler', function(e){
  1112. var btn = $(this);
  1113. var sidebar = $(btn.attr('data-target'));
  1114. if(sidebar.length == 0) return;
  1115. e.preventDefault();
  1116. sidebar.toggleClass('display');
  1117. btn.toggleClass('display');
  1118. var click_event = ace.click_event+'.ace.autohide';
  1119. var auto_hide = sidebar.attr('data-auto-hide') === 'true';
  1120. if( btn.hasClass('display') ) {
  1121. //hide menu if clicked outside of it!
  1122. if(auto_hide) {
  1123. $(document).on(click_event, function(ev) {
  1124. if( sidebar.get(0) == ev.target || $.contains(sidebar.get(0), ev.target) ) {
  1125. ev.stopPropagation();
  1126. return;
  1127. }
  1128. sidebar.removeClass('display');
  1129. btn.removeClass('display');
  1130. $(document).off(click_event);
  1131. })
  1132. }
  1133. if(sidebar.attr('data-sidebar-scroll') == 'true') sidebar.ace_sidebar_scroll('reset');
  1134. }
  1135. else {
  1136. if(auto_hide) $(document).off(click_event);
  1137. }
  1138. return false;
  1139. })
  1140. //sidebar collapse/expand button
  1141. .on(ace.click_event+'.ace.menu', '.sidebar-collapse', function(e){
  1142. var target = $(this).attr('data-target'), $sidebar = null;
  1143. if(target) $sidebar = $(target);
  1144. if($sidebar == null || $sidebar.length == 0) $sidebar = $(this).closest('.sidebar');
  1145. if($sidebar.length == 0) return;
  1146. e.preventDefault();
  1147. $sidebar.ace_sidebar('toggleMenu', this);
  1148. })
  1149. //this button is used in `mobile_style = 3` responsive menu style to expand minimized sidebar
  1150. .on(ace.click_event+'.ace.menu', '.sidebar-expand', function(e){
  1151. var target = $(this).attr('data-target'), $sidebar = null;
  1152. if(target) $sidebar = $(target);
  1153. if($sidebar == null || $sidebar.length == 0) $sidebar = $(this).closest('.sidebar');
  1154. if($sidebar.length == 0) return;
  1155. var btn = this;
  1156. e.preventDefault();
  1157. $sidebar.ace_sidebar('toggleResponsive', this);
  1158. var click_event = ace.click_event+'.ace.autohide';
  1159. if($sidebar.attr('data-auto-hide') === 'true') {
  1160. if( $sidebar.hasClass('responsive-max') ) {
  1161. $(document).on(click_event, function(ev) {
  1162. if( $sidebar.get(0) == ev.target || $.contains($sidebar.get(0), ev.target) ) {
  1163. ev.stopPropagation();
  1164. return;
  1165. }
  1166. $sidebar.ace_sidebar('toggleResponsive', btn);
  1167. $(document).off(click_event);
  1168. })
  1169. }
  1170. else {
  1171. $(document).off(click_event);
  1172. }
  1173. }
  1174. })
  1175. /**
  1176. .on('shown.bs.collapse.sidebar hidden.bs.collapse.sidebar', '.sidebar[data-auto-hide=true]', function(e){
  1177. var click_event = ace.click_event+'.ace.autohide';
  1178. var sidebar = this;
  1179. if(e.type == 'shown') {
  1180. $(document).on(click_event, function(ev) {
  1181. if( sidebar == ev.target || $.contains(sidebar, ev.target) ) {
  1182. ev.stopPropagation();
  1183. return;
  1184. }
  1185. $(sidebar).collapse('hide');
  1186. $(document).off(click_event);
  1187. })
  1188. }
  1189. else $(document).off(click_event);
  1190. });
  1191. */
  1192. $.fn.ace_sidebar = function (option, value) {
  1193. var method_call;
  1194. var $set = this.each(function () {
  1195. var $this = $(this);
  1196. var data = $this.data('ace_sidebar');
  1197. var options = typeof option === 'object' && option;
  1198. if (!data) $this.data('ace_sidebar', (data = new Sidebar(this, options)));
  1199. if (typeof option === 'string' && typeof data[option] === 'function') {
  1200. if(value instanceof Array) method_call = data[option].apply(data, value);
  1201. else method_call = data[option](value);
  1202. }
  1203. });
  1204. return (method_call === undefined) ? $set : method_call;
  1205. };
  1206. })(window.jQuery);
  1207. ;/**
  1208. <b>Scrollbars for sidebar</b>. This approach can <span class="text-danger">only</span> be used on <u>fixed</u> sidebar.
  1209. It doesn't use <u>"overflow:hidden"</u> CSS property and therefore can be used with <u>.hover</u> submenus and minimized sidebar.
  1210. Except when in mobile view and menu toggle button is not in the navbar.
  1211. */
  1212. (function($ , undefined) {
  1213. //if( !$.fn.ace_scroll ) return;
  1214. var old_safari = ace.vars['safari'] && navigator.userAgent.match(/version\/[1-5]/i)
  1215. //NOTE
  1216. //Safari on windows has not been updated for a long time.
  1217. //And it has a problem when sidebar is fixed & scrollable and there is a CSS3 animation inside page content.
  1218. //Very probably windows users of safari have migrated to another browser by now!
  1219. var is_element_pos =
  1220. 'getComputedStyle' in window ?
  1221. //el.offsetHeight is used to force redraw and recalculate 'el.style.position' esp. for webkit!
  1222. function(el, pos) { el.offsetHeight; return window.getComputedStyle(el).position == pos }
  1223. :
  1224. function(el, pos) { el.offsetHeight; return $(el).css('position') == pos }
  1225. function Sidebar_Scroll(sidebar , settings) {
  1226. var self = this;
  1227. var $window = $(window);
  1228. var $sidebar = $(sidebar),
  1229. $nav = $sidebar.find('.nav-list'),
  1230. $toggle = $sidebar.find('.sidebar-toggle').eq(0),
  1231. $shortcuts = $sidebar.find('.sidebar-shortcuts').eq(0);
  1232. var ace_sidebar = $sidebar.ace_sidebar('ref');
  1233. $sidebar.attr('data-sidebar-scroll', 'true');
  1234. var nav = $nav.get(0);
  1235. if(!nav) return;
  1236. var scroll_div = null,
  1237. scroll_content = null,
  1238. scroll_content_div = null,
  1239. bar = null,
  1240. track = null,
  1241. ace_scroll = null;
  1242. var scroll_to_active = settings.scroll_to_active || ace.helper.boolAttr(sidebar, 'data-scroll-to-active') || false,
  1243. include_shortcuts = settings.include_shortcuts || ace.helper.boolAttr(sidebar, 'data-scroll-include-shortcuts') || false,
  1244. include_toggle = settings.include_toggle || ace.helper.boolAttr(sidebar, 'data-scroll-include-toggle') || false,
  1245. smooth_scroll = settings.smooth_scroll || ace.helper.intAttr(sidebar, 'data-scroll-smooth') || false,
  1246. scrollbars_outside = settings.outside || ace.helper.boolAttr(sidebar, 'data-scroll-outside') || false,
  1247. scroll_style = settings.scroll_style || $sidebar.attr('data-scroll-style') || '',
  1248. only_if_fixed = true;
  1249. var lockAnyway = settings.mousewheel_lock || ace.helper.boolAttr(sidebar, 'data-mousewheel-lock') || false;
  1250. this.is_scrolling = false;
  1251. var _initiated = false;
  1252. this.sidebar_fixed = is_element_pos(sidebar, 'fixed');
  1253. var $avail_height, $content_height;
  1254. var available_height = function() {
  1255. //available window space
  1256. var offset = $nav.parent().offset();//because `$nav.offset()` considers the "scrolled top" amount as well
  1257. if(self.sidebar_fixed) offset.top -= ace.helper.scrollTop();
  1258. return $window.innerHeight() - offset.top - ( include_toggle ? 0 : $toggle.outerHeight() );
  1259. }
  1260. var content_height = function() {
  1261. return nav.clientHeight;//we don't use nav.scrollHeight here, because hover submenus are considered in calculating scrollHeight despite position=absolute!
  1262. }
  1263. var initiate = function(on_page_load) {
  1264. if( _initiated ) return;
  1265. if( !self.sidebar_fixed ) return;//eligible??
  1266. //return if we want scrollbars only on "fixed" sidebar and sidebar is not "fixed" yet!
  1267. //initiate once
  1268. $nav.wrap('<div class="nav-wrap-up pos-rel" />');
  1269. $nav.after('<div><div></div></div>');
  1270. $nav.wrap('<div class="nav-wrap" />');
  1271. if(!include_toggle) $toggle.css({'z-index': 1});
  1272. if(!include_shortcuts) $shortcuts.css({'z-index': 99});
  1273. scroll_div = $nav.parent().next()
  1274. .ace_scroll({
  1275. size: available_height(),
  1276. //reset: true,
  1277. mouseWheelLock: true,
  1278. hoverReset: false,
  1279. dragEvent: true,
  1280. styleClass: scroll_style,
  1281. touchDrag: false//disable touch drag event on scrollbars, we'll add a custom one later
  1282. })
  1283. .closest('.ace-scroll').addClass('nav-scroll');
  1284. ace_scroll = scroll_div.data('ace_scroll');
  1285. scroll_content = scroll_div.find('.scroll-content').eq(0);
  1286. scroll_content_div = scroll_content.find(' > div').eq(0);
  1287. track = $(ace_scroll.get_track());
  1288. bar = track.find('.scroll-bar').eq(0);
  1289. if(include_shortcuts && $shortcuts.length != 0) {
  1290. $nav.parent().prepend($shortcuts).wrapInner('<div />');
  1291. $nav = $nav.parent();
  1292. }
  1293. if(include_toggle && $toggle.length != 0) {
  1294. $nav.append($toggle);
  1295. $nav.closest('.nav-wrap').addClass('nav-wrap-t');//it just helps to remove toggle button's top border and restore li:last-child's bottom border
  1296. }
  1297. $nav.css({position: 'relative'});
  1298. if( scrollbars_outside === true ) scroll_div.addClass('scrollout');
  1299. nav = $nav.get(0);
  1300. nav.style.top = 0;
  1301. scroll_content.on('scroll.nav', function() {
  1302. nav.style.top = (-1 * this.scrollTop) + 'px';
  1303. });
  1304. //mousewheel library available?
  1305. $nav.on(!!$.event.special.mousewheel ? 'mousewheel.ace_scroll' : 'mousewheel.ace_scroll DOMMouseScroll.ace_scroll', function(event){
  1306. if( !self.is_scrolling || !ace_scroll.is_active() ) {
  1307. return !lockAnyway;
  1308. }
  1309. //transfer $nav's mousewheel event to scrollbars
  1310. return scroll_div.trigger(event);
  1311. });
  1312. $nav.on('mouseenter.ace_scroll', function() {
  1313. track.addClass('scroll-hover');
  1314. }).on('mouseleave.ace_scroll', function() {
  1315. track.removeClass('scroll-hover');
  1316. });
  1317. /**
  1318. $(document.body).on('touchmove.nav', function(event) {
  1319. if( self.is_scrolling && $.contains(sidebar, event.target) ) {
  1320. event.preventDefault();
  1321. return false;
  1322. }
  1323. })
  1324. */
  1325. //you can also use swipe event in a similar way //swipe.nav
  1326. var content = scroll_content.get(0);
  1327. $nav.on('ace_drag.nav', function(event) {
  1328. if( !self.is_scrolling || !ace_scroll.is_active() ) {
  1329. event.retval.cancel = true;
  1330. return;
  1331. }
  1332. //if submenu hover is being scrolled let's cancel sidebar scroll!
  1333. if( $(event.target).closest('.can-scroll').length != 0 ) {
  1334. event.retval.cancel = true;
  1335. return;
  1336. }
  1337. if(event.direction == 'up' || event.direction == 'down') {
  1338. ace_scroll.move_bar(true);
  1339. var distance = event.dy;
  1340. distance = parseInt(Math.min($avail_height, distance))
  1341. if(Math.abs(distance) > 2) distance = distance * 2;
  1342. if(distance != 0) {
  1343. content.scrollTop = content.scrollTop + distance;
  1344. nav.style.top = (-1 * content.scrollTop) + 'px';
  1345. }
  1346. }
  1347. });
  1348. //for drag only
  1349. if(smooth_scroll) {
  1350. $nav
  1351. .on('touchstart.nav MSPointerDown.nav pointerdown.nav', function(event) {
  1352. $nav.css('transition-property', 'none');
  1353. bar.css('transition-property', 'none');
  1354. })
  1355. .on('touchend.nav touchcancel.nav MSPointerUp.nav MSPointerCancel.nav pointerup.nav pointercancel.nav', function(event) {
  1356. $nav.css('transition-property', 'top');
  1357. bar.css('transition-property', 'top');
  1358. });
  1359. }
  1360. if(old_safari && !include_toggle) {
  1361. var toggle = $toggle.get(0);
  1362. if(toggle) scroll_content.on('scroll.safari', function() {
  1363. ace.helper.redraw(toggle);
  1364. });
  1365. }
  1366. _initiated = true;
  1367. //if the active item is not visible, scroll down so that it becomes visible
  1368. //only the first time, on page load
  1369. if(on_page_load == true) {
  1370. self.reset();//try resetting at first
  1371. if( scroll_to_active ) {
  1372. self.scroll_to_active();
  1373. }
  1374. scroll_to_active = false;
  1375. }
  1376. if( typeof smooth_scroll === 'number' && smooth_scroll > 0) {
  1377. $nav.css({'transition-property': 'top', 'transition-duration': (smooth_scroll / 1000).toFixed(2)+'s'})
  1378. bar.css({'transition-property': 'top', 'transition-duration': (smooth_scroll / 1500).toFixed(2)+'s'})
  1379. scroll_div
  1380. .on('drag.start', function(e) {
  1381. e.stopPropagation();
  1382. $nav.css('transition-property', 'none')
  1383. })
  1384. .on('drag.end', function(e) {
  1385. e.stopPropagation();
  1386. $nav.css('transition-property', 'top')
  1387. });
  1388. }
  1389. if(ace.vars['android']) {
  1390. //force hide address bar, because its changes don't trigger window resize and become kinda ugly
  1391. var val = ace.helper.scrollTop();
  1392. if(val < 2) {
  1393. window.scrollTo( val, 0 );
  1394. setTimeout( function() {
  1395. self.reset();
  1396. }, 20 );
  1397. }
  1398. var last_height = ace.helper.winHeight() , new_height;
  1399. $(window).on('scroll.ace_scroll', function() {
  1400. if(self.is_scrolling && ace_scroll.is_active()) {
  1401. new_height = ace.helper.winHeight();
  1402. if(new_height != last_height) {
  1403. last_height = new_height;
  1404. self.reset();
  1405. }
  1406. }
  1407. });
  1408. }
  1409. }
  1410. this.scroll_to_active = function() {
  1411. if( !ace_scroll || !ace_scroll.is_active() ) return;
  1412. try {
  1413. //sometimes there's no active item or not 'offsetTop' property
  1414. var $active;
  1415. var vars = ace_sidebar['vars']()
  1416. var nav_list = $sidebar.find('.nav-list')
  1417. if(vars['minimized'] && !vars['collapsible']) {
  1418. $active = nav_list.find('> .active')
  1419. }
  1420. else {
  1421. $active = $nav.find('> .active.hover')
  1422. if($active.length == 0) $active = $nav.find('.active:not(.open)')
  1423. }
  1424. var top = $active.outerHeight();
  1425. nav_list = nav_list.get(0);
  1426. var active = $active.get(0);
  1427. while(active != nav_list) {
  1428. top += active.offsetTop;
  1429. active = active.parentNode;
  1430. }
  1431. var scroll_amount = top - scroll_div.height();
  1432. if(scroll_amount > 0) {
  1433. nav.style.top = -scroll_amount + 'px';
  1434. scroll_content.scrollTop(scroll_amount);
  1435. }
  1436. }catch(e){}
  1437. }
  1438. this.reset = function(recalc) {
  1439. if(recalc === true) {
  1440. this.sidebar_fixed = is_element_pos(sidebar, 'fixed');
  1441. }
  1442. if( !this.sidebar_fixed ) {
  1443. this.disable();
  1444. return;//eligible??
  1445. }
  1446. //return if we want scrollbars only on "fixed" sidebar and sidebar is not "fixed" yet!
  1447. if( !_initiated ) initiate();
  1448. //initiate scrollbars if not yet
  1449. var vars = ace_sidebar['vars']();
  1450. //enable if:
  1451. //menu is not collapsible mode (responsive navbar-collapse mode which has default browser scrollbar)
  1452. //menu is not horizontal or horizontal but mobile view (which is not navbar-collapse)
  1453. //and available height is less than nav's height
  1454. var enable_scroll = !vars['collapsible'] && !vars['horizontal']
  1455. && ($avail_height = available_height()) < ($content_height = nav.clientHeight);
  1456. //we don't use nav.scrollHeight here, because hover submenus are considered in calculating scrollHeight despite position=absolute!
  1457. this.is_scrolling = true;
  1458. if( enable_scroll ) {
  1459. scroll_content_div.css({height: $content_height, width: 8});
  1460. scroll_div.prev().css({'max-height' : $avail_height})
  1461. ace_scroll.update({size: $avail_height})
  1462. ace_scroll.enable();
  1463. ace_scroll.reset();
  1464. }
  1465. if( !enable_scroll || !ace_scroll.is_active() ) {
  1466. if(this.is_scrolling) this.disable();
  1467. }
  1468. else {
  1469. $sidebar.addClass('sidebar-scroll');
  1470. }
  1471. //return this.is_scrolling;
  1472. }
  1473. this.disable = function() {
  1474. this.is_scrolling = false;
  1475. if(scroll_div) {
  1476. scroll_div.css({'height' : '', 'max-height' : ''});
  1477. scroll_content_div.css({height: '', width: ''});//otherwise it will have height and takes up some space even when invisible
  1478. scroll_div.prev().css({'max-height' : ''})
  1479. ace_scroll.disable();
  1480. }
  1481. if(parseInt(nav.style.top) < 0 && smooth_scroll && $.support.transition.end) {
  1482. $nav.one($.support.transition.end, function() {
  1483. $sidebar.removeClass('sidebar-scroll');
  1484. $nav.off('.trans');
  1485. });
  1486. } else {
  1487. $sidebar.removeClass('sidebar-scroll');
  1488. }
  1489. nav.style.top = 0;
  1490. }
  1491. this.prehide = function(height_change) {
  1492. if(!this.is_scrolling || ace_sidebar.get('minimized')) return;//when minimized submenu's toggle should have no effect
  1493. if(content_height() + height_change < available_height()) {
  1494. this.disable();
  1495. }
  1496. else if(height_change < 0) {
  1497. //if content height is decreasing
  1498. //let's move nav down while a submenu is being hidden
  1499. var scroll_top = scroll_content.scrollTop() + height_change
  1500. if(scroll_top < 0) return;
  1501. nav.style.top = (-1 * scroll_top) + 'px';
  1502. }
  1503. }
  1504. this._reset = function(recalc) {
  1505. if(recalc === true) {
  1506. this.sidebar_fixed = is_element_pos(sidebar, 'fixed');
  1507. }
  1508. if(ace.vars['webkit'])
  1509. setTimeout(function() { self.reset() } , 0);
  1510. else this.reset();
  1511. }
  1512. this.set_hover = function() {
  1513. if(track) track.addClass('scroll-hover');
  1514. }
  1515. this.get = function(name) {
  1516. if(this.hasOwnProperty(name)) return this[name];
  1517. }
  1518. this.set = function(name, value) {
  1519. if(this.hasOwnProperty(name)) this[name] = value;
  1520. }
  1521. this.ref = function() {
  1522. //return a reference to self
  1523. return this;
  1524. }
  1525. this.updateStyle = function(styleClass) {
  1526. if(ace_scroll == null) return;
  1527. ace_scroll.update({styleClass: styleClass});
  1528. }
  1529. //change scrollbar size after a submenu is hidden/shown
  1530. //but don't change if sidebar is minimized
  1531. $sidebar.on('hidden.ace.submenu.sidebar_scroll shown.ace.submenu.sidebar_scroll', '.submenu', function(e) {
  1532. e.stopPropagation();
  1533. if( !ace_sidebar.get('minimized') ) {
  1534. //webkit has a little bit of a glitch!!!
  1535. self._reset();
  1536. if( e.type == 'shown' ) self.set_hover();
  1537. }
  1538. });
  1539. initiate(true);//true = on_page_load
  1540. }
  1541. //reset on document and window changes
  1542. $(document).on('settings.ace.sidebar_scroll', function(ev, event_name, event_val){
  1543. $('.sidebar[data-sidebar-scroll=true]').each(function() {
  1544. var $this = $(this);
  1545. var sidebar_scroll = $this.ace_sidebar_scroll('ref');
  1546. if( event_name == 'sidebar_collapsed' && is_element_pos(this, 'fixed') ) {
  1547. if( $this.attr('data-sidebar-hover') == 'true' ) $this.ace_sidebar_hover('reset');
  1548. sidebar_scroll._reset();
  1549. }
  1550. else if( event_name === 'sidebar_fixed' || event_name === 'navbar_fixed' ) {
  1551. var is_scrolling = sidebar_scroll.get('is_scrolling');
  1552. var sidebar_fixed = is_element_pos(this, 'fixed')
  1553. sidebar_scroll.set('sidebar_fixed', sidebar_fixed);
  1554. if(sidebar_fixed && !is_scrolling) {
  1555. sidebar_scroll._reset();
  1556. }
  1557. else if( !sidebar_fixed ) {
  1558. sidebar_scroll.disable();
  1559. }
  1560. }
  1561. });
  1562. });
  1563. $(window).on('resize.ace.sidebar_scroll', function(){
  1564. $('.sidebar[data-sidebar-scroll=true]').each(function() {
  1565. var $this = $(this);
  1566. if( $this.attr('data-sidebar-hover') == 'true' ) $this.ace_sidebar_hover('reset');
  1567. /////////////
  1568. var sidebar_scroll = $(this).ace_sidebar_scroll('ref');
  1569. var sidebar_fixed = is_element_pos(this, 'fixed')
  1570. sidebar_scroll.set('sidebar_fixed', sidebar_fixed);
  1571. sidebar_scroll._reset();
  1572. });
  1573. })
  1574. /////////////////////////////////////////////
  1575. if(!$.fn.ace_sidebar_scroll)
  1576. $.fn.ace_sidebar_scroll = function (option, value) {
  1577. var method_call;
  1578. var $set = this.each(function () {
  1579. var $this = $(this);
  1580. var data = $this.data('ace_sidebar_scroll');
  1581. var options = typeof option === 'object' && option;
  1582. if (!data) $this.data('ace_sidebar_scroll', (data = new Sidebar_Scroll(this, options)));
  1583. if (typeof option === 'string' && typeof data[option] === 'function') {
  1584. method_call = data[option](value);
  1585. }
  1586. });
  1587. return (method_call === undefined) ? $set : method_call;
  1588. };
  1589. })(window.jQuery);;/**
  1590. <b>Submenu hover adjustment</b>. Automatically move up a submenu to fit into screen when some part of it goes beneath window.
  1591. Pass a "true" value as an argument and submenu will have native browser scrollbars when necessary.
  1592. */
  1593. (function($ , undefined) {
  1594. if( ace.vars['very_old_ie'] ) return;
  1595. //ignore IE7 & below
  1596. var hasTouch = ace.vars['touch'];
  1597. var nativeScroll = ace.vars['old_ie'] || hasTouch;
  1598. var is_element_pos =
  1599. 'getComputedStyle' in window ?
  1600. //el.offsetHeight is used to force redraw and recalculate 'el.style.position' esp. for webkit!
  1601. function(el, pos) { el.offsetHeight; return window.getComputedStyle(el).position == pos }
  1602. :
  1603. function(el, pos) { el.offsetHeight; return $(el).css('position') == pos }
  1604. $(window).on('resize.sidebar.ace_hover', function() {
  1605. $('.sidebar[data-sidebar-hover=true]').ace_sidebar_hover('update_vars').ace_sidebar_hover('reset');
  1606. })
  1607. $(document).on('settings.ace.ace_hover', function(e, event_name, event_val) {
  1608. if(event_name == 'sidebar_collapsed') $('.sidebar[data-sidebar-hover=true]').ace_sidebar_hover('reset');
  1609. else if(event_name == 'navbar_fixed') $('.sidebar[data-sidebar-hover=true]').ace_sidebar_hover('update_vars');
  1610. })
  1611. var sidebars = [];
  1612. function Sidebar_Hover(sidebar , settings) {
  1613. var self = this;
  1614. var $sidebar = $(sidebar), nav_list = $sidebar.find('.nav-list').get(0);
  1615. $sidebar.attr('data-sidebar-hover', 'true');
  1616. sidebars.push($sidebar);
  1617. var sidebar_vars = {};
  1618. var old_ie = ace.vars['old_ie'];
  1619. var hover_delay = settings.sub_hover_delay || ace.helper.intAttr(sidebar, 'data-sub-hover-delay') || 750;
  1620. var scroll_style = settings.sub_scroll_style || $sidebar.attr('data-sub-scroll-style') || 'no-track scroll-thin';
  1621. var scroll_right = false;
  1622. //scroll style class
  1623. if(hasTouch) hover_delay = parseInt(Math.max(hover_delay, 2500));//for touch device, delay is at least 2.5sec
  1624. var $window = $(window);
  1625. //navbar used for adding extra offset from top when adjusting submenu
  1626. var $navbar = $('.navbar').eq(0);
  1627. var navbar_fixed = $navbar.css('position') == 'fixed';
  1628. this.update_vars = function() {
  1629. navbar_fixed = $navbar.css('position') == 'fixed';
  1630. }
  1631. self.dirty = false;
  1632. //on window resize or sidebar expand/collapse a previously "pulled up" submenu should be reset back to its default position
  1633. //for example if "pulled up" in "responsive-min" mode, in "fullmode" should not remain "pulled up"
  1634. this.reset = function() {
  1635. if( self.dirty == false ) return;
  1636. self.dirty = false;//so don't reset is not called multiple times in a row!
  1637. $sidebar.find('.submenu').each(function() {
  1638. var $sub = $(this), li = $sub.parent();
  1639. $sub.css({'top': '', 'bottom': '', 'max-height': ''});
  1640. if($sub.hasClass('ace-scroll')) {
  1641. $sub.ace_scroll('disable');
  1642. }
  1643. else {
  1644. $sub.removeClass('sub-scroll');
  1645. }
  1646. if( is_element_pos(this, 'absolute') ) $sub.addClass('can-scroll');
  1647. else $sub.removeClass('can-scroll');
  1648. li.removeClass('pull_up').find('.menu-text:first').css('margin-top', '');
  1649. })
  1650. $sidebar.find('.hover-show').removeClass('hover-show hover-shown hover-flip');
  1651. }
  1652. this.updateStyle = function(newStyle) {
  1653. scroll_style = newStyle;
  1654. $sidebar.find('.submenu.ace-scroll').ace_scroll('update', {styleClass: newStyle});
  1655. }
  1656. this.changeDir = function(dir) {
  1657. scroll_right = (dir === 'right');
  1658. }
  1659. //update submenu scrollbars on submenu hide & show
  1660. var lastScrollHeight = -1;
  1661. //hide scrollbars if it's going to be not needed anymore!
  1662. if(!nativeScroll)
  1663. $sidebar.on('hide.ace.submenu.sidebar_hover', '.submenu', function(e) {
  1664. if(lastScrollHeight < 1) return;
  1665. e.stopPropagation();
  1666. var $sub = $(this).closest('.ace-scroll.can-scroll');
  1667. if($sub.length == 0 || !is_element_pos($sub[0], 'absolute')) return;
  1668. if($sub[0].scrollHeight - this.scrollHeight < lastScrollHeight) {
  1669. $sub.ace_scroll('disable');
  1670. }
  1671. });
  1672. //reset scrollbars
  1673. if(!nativeScroll)
  1674. $sidebar.on('shown.ace.submenu.sidebar_hover hidden.ace.submenu.sidebar_hover', '.submenu', function(e) {
  1675. if(lastScrollHeight < 1) return;
  1676. var $sub = $(this).closest('.ace-scroll.can-scroll');
  1677. if($sub.length == 0 || !is_element_pos($sub[0], 'absolute') ) return;
  1678. var sub_h = $sub[0].scrollHeight;
  1679. if(lastScrollHeight > 14 && sub_h - lastScrollHeight > 4) {
  1680. $sub.ace_scroll('enable').ace_scroll('reset');//don't update track position
  1681. }
  1682. else {
  1683. $sub.ace_scroll('disable');
  1684. }
  1685. });
  1686. ///////////////////////
  1687. var currentScroll = -1;
  1688. //some mobile browsers don't have mouseenter
  1689. var event_1 = !hasTouch ? 'mouseenter.sub_hover' : 'touchstart.sub_hover';// pointerdown.sub_hover';
  1690. var event_2 = !hasTouch ? 'mouseleave.sub_hover' : 'touchend.sub_hover touchcancel.sub_hover';// pointerup.sub_hover pointercancel.sub_hover';
  1691. $sidebar.on(event_1, '.nav-list li, .sidebar-shortcuts', function (e) {
  1692. sidebar_vars = $sidebar.ace_sidebar('vars');
  1693. //ignore if collapsible mode (mobile view .navbar-collapse) so it doesn't trigger submenu movements
  1694. //or return if horizontal but not mobile_view (style 1&3)
  1695. if( sidebar_vars['collapsible'] /**|| sidebar_vars['horizontal']*/ ) return;
  1696. var $this = $(this);
  1697. var shortcuts = false;
  1698. var has_hover = $this.hasClass('hover');
  1699. var sub = $this.find('> .submenu').get(0);
  1700. if( !(sub || ((this.parentNode == nav_list || has_hover || (shortcuts = $this.hasClass('sidebar-shortcuts'))) /**&& sidebar_vars['minimized']*/)) ) {
  1701. if(sub) $(sub).removeClass('can-scroll');
  1702. return;//include .compact and .hover state as well?
  1703. }
  1704. var target_element = sub, is_abs = false;
  1705. if( !target_element && this.parentNode == nav_list ) target_element = $this.find('> a > .menu-text').get(0);
  1706. if( !target_element && shortcuts ) target_element = $this.find('.sidebar-shortcuts-large').get(0);
  1707. if( (!target_element || !(is_abs = is_element_pos(target_element, 'absolute'))) && !has_hover ) {
  1708. if(sub) $(sub).removeClass('can-scroll');
  1709. return;
  1710. }
  1711. var sub_hide = getSubHide(this);
  1712. //var show_sub = false;
  1713. if(sub) {
  1714. if(is_abs) {
  1715. self.dirty = true;
  1716. var newScroll = ace.helper.scrollTop();
  1717. //if submenu is becoming visible for first time or document has been scrolled, then adjust menu
  1718. if( !sub_hide.is_visible() || (!hasTouch && newScroll != currentScroll) || old_ie ) {
  1719. //try to move/adjust submenu if the parent is a li.hover or if submenu is minimized
  1720. //if( is_element_pos(sub, 'absolute') ) {//for example in small device .hover > .submenu may not be absolute anymore!
  1721. $(sub).addClass('can-scroll');
  1722. //show_sub = true;
  1723. if(!old_ie && !hasTouch) adjust_submenu.call(this, sub);
  1724. else {
  1725. //because ie8 needs some time for submenu to be displayed and real value of sub.scrollHeight be kicked in
  1726. var that = this;
  1727. setTimeout(function() { adjust_submenu.call(that, sub) }, 0)
  1728. }
  1729. //}
  1730. //else $(sub).removeClass('can-scroll');
  1731. }
  1732. currentScroll = newScroll;
  1733. }
  1734. else {
  1735. $(sub).removeClass('can-scroll');
  1736. }
  1737. }
  1738. //if(show_sub)
  1739. sub_hide.show();
  1740. }).on(event_2, '.nav-list li, .sidebar-shortcuts', function (e) {
  1741. sidebar_vars = $sidebar.ace_sidebar('vars');
  1742. if( sidebar_vars['collapsible'] /**|| sidebar_vars['horizontal']*/ ) return;
  1743. if( !$(this).hasClass('hover-show') ) return;
  1744. getSubHide(this).hideDelay();
  1745. });
  1746. function subHide(li_sub) {
  1747. var self = li_sub, $self = $(self);
  1748. var timer = null;
  1749. var visible = false;
  1750. this.show = function() {
  1751. if(timer != null) clearTimeout(timer);
  1752. timer = null;
  1753. $self.addClass('hover-show hover-shown');
  1754. visible = true;
  1755. //let's hide .hover-show elements that are not .hover-shown anymore (i.e. marked for hiding in hideDelay)
  1756. for(var i = 0; i < sidebars.length ; i++)
  1757. {
  1758. sidebars[i].find('.hover-show').not('.hover-shown').each(function() {
  1759. getSubHide(this).hide();
  1760. })
  1761. }
  1762. }
  1763. this.hide = function() {
  1764. visible = false;
  1765. $self.removeClass('hover-show hover-shown hover-flip');
  1766. if(timer != null) clearTimeout(timer);
  1767. timer = null;
  1768. var sub = $self.find('> .submenu').get(0);
  1769. if(sub) getSubScroll(sub, 'hide');
  1770. }
  1771. this.hideDelay = function(callback) {
  1772. if(timer != null) clearTimeout(timer);
  1773. $self.removeClass('hover-shown');//somehow marked for hiding
  1774. timer = setTimeout(function() {
  1775. visible = false;
  1776. $self.removeClass('hover-show hover-flip');
  1777. timer = null;
  1778. var sub = $self.find('> .submenu').get(0);
  1779. if(sub) getSubScroll(sub, 'hide');
  1780. if(typeof callback === 'function') callback.call(this);
  1781. }, hover_delay);
  1782. }
  1783. this.is_visible = function() {
  1784. return visible;
  1785. }
  1786. }
  1787. function getSubHide(el) {
  1788. var sub_hide = $(el).data('subHide');
  1789. if(!sub_hide) $(el).data('subHide', (sub_hide = new subHide(el)));
  1790. return sub_hide;
  1791. }
  1792. function getSubScroll(el, func) {
  1793. var sub_scroll = $(el).data('ace_scroll');
  1794. if(!sub_scroll) return false;
  1795. if(typeof func === 'string') {
  1796. sub_scroll[func]();
  1797. return true;
  1798. }
  1799. return sub_scroll;
  1800. }
  1801. function adjust_submenu(sub) {
  1802. var $li = $(this);
  1803. var $sub = $(sub);
  1804. sub.style.top = '';
  1805. sub.style.bottom = '';
  1806. var menu_text = null
  1807. if( sidebar_vars['minimized'] && (menu_text = $li.find('.menu-text').get(0)) ) {
  1808. //2nd level items don't have .menu-text
  1809. menu_text.style.marginTop = '';
  1810. }
  1811. var scroll = ace.helper.scrollTop();
  1812. var navbar_height = 0;
  1813. var $scroll = scroll;
  1814. if( navbar_fixed ) {
  1815. navbar_height = sidebar.offsetTop;//$navbar.height();
  1816. $scroll += navbar_height + 1;
  1817. //let's avoid our submenu from going below navbar
  1818. //because of chrome z-index stacking issue and firefox's normal .submenu over fixed .navbar flicker issue
  1819. }
  1820. var off = $li.offset();
  1821. off.top = parseInt(off.top);
  1822. var extra = 0, parent_height;
  1823. sub.style.maxHeight = '';//otherwise scrollHeight won't be consistent in consecutive calls!?
  1824. var sub_h = sub.scrollHeight;
  1825. var parent_height = $li.height();
  1826. if(menu_text) {
  1827. extra = parent_height;
  1828. off.top += extra;
  1829. }
  1830. var sub_bottom = parseInt(off.top + sub_h)
  1831. var move_up = 0;
  1832. var winh = $window.height();
  1833. //if the bottom of menu is going to go below visible window
  1834. var top_space = parseInt(off.top - $scroll - extra);//available space on top
  1835. var win_space = winh;//available window space
  1836. var horizontal = sidebar_vars['horizontal'], horizontal_sub = false;
  1837. if(horizontal && this.parentNode == nav_list) {
  1838. move_up = 0;//don't move up first level submenu in horizontal mode
  1839. off.top += $li.height();
  1840. horizontal_sub = true;//first level submenu
  1841. }
  1842. if(!horizontal_sub && (move_up = (sub_bottom - (winh + scroll))) >= 0 ) {
  1843. //don't move up more than available space
  1844. move_up = move_up < top_space ? move_up : top_space;
  1845. //move it up a bit more if there's empty space
  1846. if(move_up == 0) move_up = 20;
  1847. if(top_space - move_up > 10) {
  1848. move_up += parseInt(Math.min(25, top_space - move_up));
  1849. }
  1850. //move it down if submenu's bottom is going above parent LI
  1851. if(off.top + (parent_height - extra) > (sub_bottom - move_up)) {
  1852. move_up -= (off.top + (parent_height - extra) - (sub_bottom - move_up));
  1853. }
  1854. if(move_up > 0) {
  1855. sub.style.top = -(move_up) + 'px';
  1856. if( menu_text ) {
  1857. menu_text.style.marginTop = -(move_up) + 'px';
  1858. }
  1859. }
  1860. }
  1861. if(move_up < 0) move_up = 0;//when it goes below
  1862. var pull_up = move_up > 0 && move_up > parent_height - 20;
  1863. if(pull_up) {
  1864. $li.addClass('pull_up');
  1865. }
  1866. else $li.removeClass('pull_up');
  1867. //flip submenu if out of window width
  1868. if(horizontal) {
  1869. if($li.parent().parent().hasClass('hover-flip')) $li.addClass('hover-flip');//if a parent is already flipped, flip it then!
  1870. else {
  1871. var sub_off = $sub.offset();
  1872. var sub_w = $sub.width();
  1873. var win_w = $window.width();
  1874. if(sub_off.left + sub_w > win_w) {
  1875. $li.addClass('hover-flip');
  1876. }
  1877. }
  1878. }
  1879. //don't add scrollbars if it contains .hover menus
  1880. var has_hover = $li.hasClass('hover') && !sidebar_vars['mobile_view'];
  1881. if(has_hover && $sub.find('> li > .submenu').length > 0) return;
  1882. //if( ) {
  1883. var scroll_height = (win_space - (off.top - scroll)) + (move_up);
  1884. //if after scroll, the submenu is above parent LI, then move it down
  1885. var tmp = move_up - scroll_height;
  1886. if(tmp > 0 && tmp < parent_height) scroll_height += parseInt(Math.max(parent_height, parent_height - tmp));
  1887. scroll_height -= 5;
  1888. if(scroll_height < 90) {
  1889. return;
  1890. }
  1891. var ace_scroll = false;
  1892. if(!nativeScroll) {
  1893. ace_scroll = getSubScroll(sub);
  1894. if(ace_scroll == false) {
  1895. $sub.ace_scroll({
  1896. //hideOnIdle: true,
  1897. observeContent: true,
  1898. detached: true,
  1899. updatePos: false,
  1900. reset: true,
  1901. mouseWheelLock: true,
  1902. styleClass: scroll_style
  1903. });
  1904. ace_scroll = getSubScroll(sub);
  1905. var track = ace_scroll.get_track();
  1906. if(track) {
  1907. //detach it from body and insert it after submenu for better and cosistent positioning
  1908. $sub.after(track);
  1909. }
  1910. }
  1911. ace_scroll.update({size: scroll_height});
  1912. }
  1913. else {
  1914. $sub
  1915. .addClass('sub-scroll')
  1916. .css('max-height', (scroll_height)+'px')
  1917. }
  1918. lastScrollHeight = scroll_height;
  1919. if(!nativeScroll && ace_scroll) {
  1920. if(scroll_height > 14 && sub_h - scroll_height > 4) {
  1921. ace_scroll.enable()
  1922. ace_scroll.reset();
  1923. }
  1924. else {
  1925. ace_scroll.disable();
  1926. }
  1927. //////////////////////////////////
  1928. var track = ace_scroll.get_track();
  1929. if(track) {
  1930. track.style.top = -(move_up - extra - 1) + 'px';
  1931. var off = $sub.position();
  1932. var left = off.left
  1933. if( !scroll_right ) {
  1934. left += ($sub.outerWidth() - ace_scroll.track_size());
  1935. }
  1936. else {
  1937. left += 2;
  1938. }
  1939. track.style.left = parseInt(left) + 'px';
  1940. if(horizontal_sub) {//first level submenu
  1941. track.style.left = parseInt(left - 2) + 'px';
  1942. track.style.top = parseInt(off.top) + (menu_text ? extra - 2 : 0) + 'px';
  1943. }
  1944. }
  1945. }
  1946. //}
  1947. //again force redraw for safari!
  1948. if( ace.vars['safari'] ) {
  1949. ace.helper.redraw(sub)
  1950. }
  1951. }
  1952. }
  1953. /////////////////////////////////////////////
  1954. $.fn.ace_sidebar_hover = function (option, value) {
  1955. var method_call;
  1956. var $set = this.each(function () {
  1957. var $this = $(this);
  1958. var data = $this.data('ace_sidebar_hover');
  1959. var options = typeof option === 'object' && option;
  1960. if (!data) $this.data('ace_sidebar_hover', (data = new Sidebar_Hover(this, options)));
  1961. if (typeof option === 'string' && typeof data[option] === 'function') {
  1962. method_call = data[option](value);
  1963. }
  1964. });
  1965. return (method_call === undefined) ? $set : method_call;
  1966. };
  1967. })(window.jQuery);
  1968. ;/**
  1969. <b>Widget boxes</b>
  1970. */
  1971. (function($ , undefined) {
  1972. var Widget_Box = function(box, options) {
  1973. this.$box = $(box);
  1974. var that = this;
  1975. //this.options = $.extend({}, $.fn.widget_box.defaults, options);
  1976. this.reload = function() {
  1977. var $box = this.$box;
  1978. var $remove_position = false;
  1979. if($box.css('position') == 'static') {
  1980. $remove_position = true;
  1981. $box.addClass('position-relative');
  1982. }
  1983. $box.append('<div class="widget-box-overlay"><i class="'+ ace.vars['icon'] + 'loading-icon fa fa-spinner fa-spin fa-2x white"></i></div>');
  1984. $box.one('reloaded.ace.widget', function() {
  1985. $box.find('.widget-box-overlay').remove();
  1986. if($remove_position) $box.removeClass('position-relative');
  1987. });
  1988. }
  1989. this.close = function() {
  1990. var $box = this.$box;
  1991. var closeSpeed = 300;
  1992. $box.fadeOut(closeSpeed , function(){
  1993. $box.trigger('closed.ace.widget');
  1994. $box.remove();
  1995. }
  1996. )
  1997. }
  1998. this.toggle = function(type, button) {
  1999. var $box = this.$box;
  2000. var $body = $box.find('.widget-body');
  2001. var $icon = null;
  2002. var event_name = typeof type !== 'undefined' ? type : ($box.hasClass('collapsed') ? 'show' : 'hide');
  2003. var event_complete_name = event_name == 'show' ? 'shown' : 'hidden';
  2004. if(typeof button === 'undefined') {
  2005. button = $box.find('> .widget-header a[data-action=collapse]').eq(0);
  2006. if(button.length == 0) button = null;
  2007. }
  2008. if(button) {
  2009. $icon = button.find(ace.vars['.icon']).eq(0);
  2010. var $match
  2011. var $icon_down = null
  2012. var $icon_up = null
  2013. if( ($icon_down = $icon.attr('data-icon-show')) ) {
  2014. $icon_up = $icon.attr('data-icon-hide')
  2015. }
  2016. else if( $match = $icon.attr('class').match(/fa\-(.*)\-(up|down)/) ) {
  2017. $icon_down = 'fa-'+$match[1]+'-down'
  2018. $icon_up = 'fa-'+$match[1]+'-up'
  2019. }
  2020. }
  2021. var expandSpeed = 250;
  2022. var collapseSpeed = 200;
  2023. if( event_name == 'show' ) {
  2024. if($icon) $icon.removeClass($icon_down).addClass($icon_up);
  2025. $body.hide();
  2026. $box.removeClass('collapsed');
  2027. $body.slideDown(expandSpeed, function(){
  2028. $box.trigger(event_complete_name+'.ace.widget')
  2029. })
  2030. }
  2031. else {
  2032. if($icon) $icon.removeClass($icon_up).addClass($icon_down);
  2033. $body.slideUp(collapseSpeed, function(){
  2034. $box.addClass('collapsed')
  2035. $box.trigger(event_complete_name+'.ace.widget')
  2036. }
  2037. );
  2038. }
  2039. }
  2040. this.hide = function() {
  2041. this.toggle('hide');
  2042. }
  2043. this.show = function() {
  2044. this.toggle('show');
  2045. }
  2046. this.fullscreen = function() {
  2047. var $icon = this.$box.find('> .widget-header a[data-action=fullscreen]').find(ace.vars['.icon']).eq(0);
  2048. var $icon_expand = null
  2049. var $icon_compress = null
  2050. if( ($icon_expand = $icon.attr('data-icon1')) ) {
  2051. $icon_compress = $icon.attr('data-icon2')
  2052. }
  2053. else {
  2054. $icon_expand = 'fa-expand';
  2055. $icon_compress = 'fa-compress';
  2056. }
  2057. if(!this.$box.hasClass('fullscreen')) {
  2058. $icon.removeClass($icon_expand).addClass($icon_compress);
  2059. this.$box.addClass('fullscreen');
  2060. applyScrollbars(this.$box, true);
  2061. }
  2062. else {
  2063. $icon.addClass($icon_expand).removeClass($icon_compress);
  2064. this.$box.removeClass('fullscreen');
  2065. applyScrollbars(this.$box, false);
  2066. }
  2067. this.$box.trigger('fullscreened.ace.widget')
  2068. }
  2069. }
  2070. $.fn.widget_box = function (option, value) {
  2071. var method_call;
  2072. var $set = this.each(function () {
  2073. var $this = $(this);
  2074. var data = $this.data('widget_box');
  2075. var options = typeof option === 'object' && option;
  2076. if (!data) $this.data('widget_box', (data = new Widget_Box(this, options)));
  2077. if (typeof option === 'string') method_call = data[option](value);
  2078. });
  2079. return (method_call === undefined) ? $set : method_call;
  2080. };
  2081. $(document).on('click.ace.widget', '.widget-header a[data-action]', function (ev) {
  2082. ev.preventDefault();
  2083. var $this = $(this);
  2084. var $box = $this.closest('.widget-box');
  2085. if( $box.length == 0 || $box.hasClass('ui-sortable-helper') ) return;
  2086. var $widget_box = $box.data('widget_box');
  2087. if (!$widget_box) {
  2088. $box.data('widget_box', ($widget_box = new Widget_Box($box.get(0))));
  2089. }
  2090. var $action = $this.data('action');
  2091. if($action == 'collapse') {
  2092. var event_name = $box.hasClass('collapsed') ? 'show' : 'hide';
  2093. var event
  2094. $box.trigger(event = $.Event(event_name+'.ace.widget'))
  2095. if (event.isDefaultPrevented()) return
  2096. $widget_box.toggle(event_name, $this);
  2097. }
  2098. else if($action == 'close') {
  2099. var event
  2100. $box.trigger(event = $.Event('close.ace.widget'))
  2101. if (event.isDefaultPrevented()) return
  2102. $widget_box.close();
  2103. }
  2104. else if($action == 'reload') {
  2105. $this.blur();
  2106. var event
  2107. $box.trigger(event = $.Event('reload.ace.widget'))
  2108. if (event.isDefaultPrevented()) return
  2109. $widget_box.reload();
  2110. }
  2111. else if($action == 'fullscreen') {
  2112. var event
  2113. $box.trigger(event = $.Event('fullscreen.ace.widget'))
  2114. if (event.isDefaultPrevented()) return
  2115. $widget_box.fullscreen();
  2116. }
  2117. else if($action == 'settings') {
  2118. $box.trigger('setting.ace.widget')
  2119. }
  2120. });
  2121. function applyScrollbars($widget, enable) {
  2122. var $main = $widget.find('.widget-main');
  2123. $(window).off('resize.widget.scroll');
  2124. //IE8 has an unresolvable issue!!! re-scrollbaring with unknown values?!
  2125. var nativeScrollbars = ace.vars['old_ie'] || ace.vars['touch'];
  2126. if(enable) {
  2127. var ace_scroll = $main.data('ace_scroll');
  2128. if( ace_scroll ) {
  2129. $main.data('save_scroll', {size: ace_scroll['size'], lock: ace_scroll['lock'], lock_anyway: ace_scroll['lock_anyway']});
  2130. }
  2131. var size = $widget.height() - $widget.find('.widget-header').height() - 10;//extra paddings
  2132. size = parseInt(size);
  2133. $main.css('min-height', size);
  2134. if( !nativeScrollbars ) {
  2135. if( ace_scroll ) {
  2136. $main.ace_scroll('update', {'size': size, 'mouseWheelLock': true, 'lockAnyway': true});
  2137. }
  2138. else {
  2139. $main.ace_scroll({'size': size, 'mouseWheelLock': true, 'lockAnyway': true});
  2140. }
  2141. $main.ace_scroll('enable').ace_scroll('reset');
  2142. }
  2143. else {
  2144. if( ace_scroll ) $main.ace_scroll('disable');
  2145. $main.css('max-height', size).addClass('overflow-scroll');
  2146. }
  2147. $(window)
  2148. .on('resize.widget.scroll', function() {
  2149. var size = $widget.height() - $widget.find('.widget-header').height() - 10;//extra paddings
  2150. size = parseInt(size);
  2151. $main.css('min-height', size);
  2152. if( !nativeScrollbars ) {
  2153. $main.ace_scroll('update', {'size': size}).ace_scroll('reset');
  2154. }
  2155. else {
  2156. $main.css('max-height', size).addClass('overflow-scroll');
  2157. }
  2158. });
  2159. }
  2160. else {
  2161. $main.css('min-height', '');
  2162. var saved_scroll = $main.data('save_scroll');
  2163. if(saved_scroll) {
  2164. $main
  2165. .ace_scroll('update', {'size': saved_scroll['size'], 'mouseWheelLock': saved_scroll['lock'], 'lockAnyway': saved_scroll['lock_anyway']})
  2166. .ace_scroll('enable')
  2167. .ace_scroll('reset');
  2168. }
  2169. if( !nativeScrollbars ) {
  2170. if(!saved_scroll) $main.ace_scroll('disable');
  2171. }
  2172. else {
  2173. $main.css('max-height', '').removeClass('overflow-scroll');
  2174. }
  2175. }
  2176. }
  2177. })(window.jQuery);;/**
  2178. <b>Settings box</b>. It's good for demo only. You don't need this.
  2179. */
  2180. (function($ , undefined) {
  2181. $('#ace-settings-btn').on(ace.click_event, function(e){
  2182. e.preventDefault();
  2183. $(this).toggleClass('open');
  2184. $('#ace-settings-box').toggleClass('open');
  2185. })
  2186. $('#ace-settings-navbar').on('click', function(){
  2187. ace.settings.navbar_fixed(null, this.checked);//@ ace-extra.js
  2188. //$(window).triggerHandler('resize.navbar');
  2189. //force redraw?
  2190. //if(ace.vars['webkit']) ace.helper.redraw(document.body);
  2191. }).each(function(){this.checked = ace.settings.is('navbar', 'fixed')})
  2192. $('#ace-settings-sidebar').on('click', function(){
  2193. ace.settings.sidebar_fixed(null, this.checked);//@ ace-extra.js
  2194. //if(ace.vars['webkit']) ace.helper.redraw(document.body);
  2195. }).each(function(){this.checked = ace.settings.is('sidebar', 'fixed')})
  2196. $('#ace-settings-breadcrumbs').on('click', function(){
  2197. ace.settings.breadcrumbs_fixed(null, this.checked);//@ ace-extra.js
  2198. //if(ace.vars['webkit']) ace.helper.redraw(document.body);
  2199. }).each(function(){this.checked = ace.settings.is('breadcrumbs', 'fixed')})
  2200. $('#ace-settings-add-container').on('click', function(){
  2201. ace.settings.main_container_fixed(null, this.checked);//@ ace-extra.js
  2202. //if(ace.vars['webkit']) ace.helper.redraw(document.body);
  2203. }).each(function(){this.checked = ace.settings.is('main-container', 'fixed')})
  2204. $('#ace-settings-compact').on('click', function(){
  2205. if(this.checked) {
  2206. $('#sidebar').addClass('compact');
  2207. var hover = $('#ace-settings-hover');
  2208. if( hover.length > 0 ) {
  2209. hover.removeAttr('checked').trigger('click');
  2210. }
  2211. }
  2212. else {
  2213. $('#sidebar').removeClass('compact');
  2214. $('#sidebar[data-sidebar-scroll=true]').ace_sidebar_scroll('reset')
  2215. }
  2216. if(ace.vars['old_ie']) ace.helper.redraw($('#sidebar')[0], true);
  2217. })/*.removeAttr('checked')*/
  2218. $('#ace-settings-highlight').on('click', function(){
  2219. if(this.checked) $('#sidebar .nav-list > li').addClass('highlight');
  2220. else $('#sidebar .nav-list > li').removeClass('highlight');
  2221. if(ace.vars['old_ie']) ace.helper.redraw($('#sidebar')[0]);
  2222. })/*.removeAttr('checked')*/
  2223. $('#ace-settings-hover').on('click', function(){
  2224. if($('#sidebar').hasClass('h-sidebar')) return;
  2225. if(this.checked) {
  2226. $('#sidebar li').addClass('hover')
  2227. .filter('.open').removeClass('open').find('> .submenu').css('display', 'none');
  2228. //and remove .open items
  2229. }
  2230. else {
  2231. $('#sidebar li.hover').removeClass('hover');
  2232. var compact = $('#ace-settings-compact');
  2233. if( compact.length > 0 && compact.get(0).checked ) {
  2234. compact.trigger('click');
  2235. }
  2236. }
  2237. $('.sidebar[data-sidebar-hover=true]').ace_sidebar_hover('reset')
  2238. $('.sidebar[data-sidebar-scroll=true]').ace_sidebar_scroll('reset')
  2239. if(ace.vars['old_ie']) ace.helper.redraw($('#sidebar')[0]);
  2240. })/*.removeAttr('checked')*/
  2241. })(jQuery);;/**
  2242. <b>RTL</b> (right-to-left direction for Arabic, Hebrew, Persian languages).
  2243. It's good for demo only.
  2244. You should hard code RTL-specific changes inside your HTML/server-side code.
  2245. Dynamically switching to RTL using Javascript is not a good idea.
  2246. Please refer to documentation for more info.
  2247. */
  2248. (function($ , undefined) {
  2249. //Switching to RTL (right to left) Mode
  2250. $('#ace-settings-rtl').removeAttr('checked').on('click', function(){
  2251. switch_direction();
  2252. });
  2253. //>>> you should hard code changes inside HTML for RTL direction
  2254. //you shouldn't use this function to switch direction
  2255. //this is only for dynamically switching for demonstration
  2256. //take a look at this function to see what changes should be made
  2257. //also take a look at docs for some tips
  2258. var switch_direction = function() {
  2259. if($('#ace-rtl-stylesheet').length == 0) {
  2260. //let's load RTL stylesheet only when needed!
  2261. var ace_style = $('head').find('link.ace-main-stylesheet');
  2262. if(ace_style.length == 0) {
  2263. ace_style = $('head').find('link[href*="/ace.min.css"],link[href*="/ace-part2.min.css"]');
  2264. if(ace_style.length == 0) {
  2265. ace_style = $('head').find('link[href*="/ace.css"],link[href*="/ace-part2.css"]');
  2266. }
  2267. }
  2268. var ace_skins = $('head').find('link#ace-skins-stylesheet');
  2269. var stylesheet_url = ace_style.first().attr('href').replace(/(\.min)?\.css$/i , '-rtl$1.css');
  2270. $.ajax({
  2271. 'url': stylesheet_url
  2272. }).done(function() {
  2273. var new_link = jQuery('<link />', {type : 'text/css', rel: 'stylesheet', 'id': 'ace-rtl-stylesheet'})
  2274. if(ace_skins.length > 0) {
  2275. new_link.insertAfter(ace_skins);
  2276. }
  2277. else if(ace_style.length > 0){
  2278. new_link.insertAfter(ace_style.last());
  2279. }
  2280. else new_link.appendTo('head');
  2281. new_link.attr('href', stylesheet_url);
  2282. //we set "href" after insertion, for IE to work
  2283. applyChanges();
  2284. })
  2285. }
  2286. else {
  2287. applyChanges();
  2288. }
  2289. /////////////////////////
  2290. function applyChanges() {
  2291. var $body = $(document.body);
  2292. $body
  2293. .toggleClass('rtl')
  2294. //toggle pull-right class on dropdown-menu
  2295. .find('.dropdown-menu:not(.datepicker-dropdown,.colorpicker)').toggleClass('dropdown-menu-right')
  2296. .end()
  2297. //swap pull-left & pull-right
  2298. .find('.pull-right:not(.dropdown-menu,blockquote,.profile-skills .pull-right)').removeClass('pull-right').addClass('tmp-rtl-pull-right')
  2299. .end()
  2300. .find('.pull-left:not(.dropdown-submenu,.profile-skills .pull-left)').removeClass('pull-left').addClass('pull-right')
  2301. .end()
  2302. .find('.tmp-rtl-pull-right').removeClass('tmp-rtl-pull-right').addClass('pull-left')
  2303. .end()
  2304. .find('.chosen-select').toggleClass('chosen-rtl').next().toggleClass('chosen-rtl');
  2305. function swap_classes(class1, class2) {
  2306. $body
  2307. .find('.'+class1).removeClass(class1).addClass('tmp-rtl-'+class1)
  2308. .end()
  2309. .find('.'+class2).removeClass(class2).addClass(class1)
  2310. .end()
  2311. .find('.tmp-rtl-'+class1).removeClass('tmp-rtl-'+class1).addClass(class2)
  2312. }
  2313. swap_classes('align-left', 'align-right');
  2314. swap_classes('no-padding-left', 'no-padding-right');
  2315. swap_classes('arrowed', 'arrowed-right');
  2316. swap_classes('arrowed-in', 'arrowed-in-right');
  2317. swap_classes('tabs-left', 'tabs-right');
  2318. swap_classes('messagebar-item-left', 'messagebar-item-right');//for inbox page
  2319. $('.modal.aside-vc').ace_aside('flip').ace_aside('insideContainer');
  2320. //mirror all icons and attributes that have a "fa-*-right|left" attrobute
  2321. $('.fa').each(function() {
  2322. if(this.className.match(/ui-icon/) || $(this).closest('.fc-button').length > 0) return;
  2323. //skip mirroring icons of plugins that have built in RTL support
  2324. var l = this.attributes.length;
  2325. for(var i = 0 ; i < l ; i++) {
  2326. var val = this.attributes[i].value;
  2327. if(val.match(/fa\-(?:[\w\-]+)\-left/))
  2328. this.attributes[i].value = val.replace(/fa\-([\w\-]+)\-(left)/i , 'fa-$1-right')
  2329. else if(val.match(/fa\-(?:[\w\-]+)\-right/))
  2330. this.attributes[i].value = val.replace(/fa\-([\w\-]+)\-(right)/i , 'fa-$1-left')
  2331. }
  2332. });
  2333. //browsers are incosistent with horizontal scroll and RTL
  2334. //so let's make our scrollbars LTR and wrap the content inside RTL
  2335. var rtl = $body.hasClass('rtl');
  2336. if(rtl) {
  2337. $('.scroll-hz').addClass('make-ltr')
  2338. .find('.scroll-content')
  2339. .wrapInner('<div class="make-rtl" />');
  2340. $('.sidebar[data-sidebar-hover=true]').ace_sidebar_hover('changeDir', 'right');
  2341. }
  2342. else {
  2343. //remove the wrap
  2344. $('.scroll-hz').removeClass('make-ltr')
  2345. .find('.make-rtl').children().unwrap();
  2346. $('.sidebar[data-sidebar-hover=true]').ace_sidebar_hover('changeDir', 'left');
  2347. }
  2348. if($.fn.ace_scroll) $('.scroll-hz').ace_scroll('reset') //to reset scrollLeft
  2349. //redraw the traffic pie chart on homepage with a different parameter
  2350. try {
  2351. var placeholder = $('#piechart-placeholder');
  2352. if(placeholder.length > 0) {
  2353. var pos = $(document.body).hasClass('rtl') ? 'nw' : 'ne';//draw on north-west or north-east?
  2354. placeholder.data('draw').call(placeholder.get(0) , placeholder, placeholder.data('chart'), pos);
  2355. }
  2356. }catch(e) {}
  2357. ace.helper.redraw(document.body, true);
  2358. }
  2359. }
  2360. })(jQuery);
  2361. ;/**
  2362. <b>Select a different skin</b>. It's good for demo only.
  2363. You should hard code skin-specific changes inside your HTML/server-side code.
  2364. Please refer to documentation for more info.
  2365. */
  2366. (function($ , undefined) {
  2367. try {
  2368. $('#skin-colorpicker').ace_colorpicker({'auto_pos': false});
  2369. } catch(e) {}
  2370. $('#skin-colorpicker').on('change', function(){
  2371. var skin_class = $(this).find('option:selected').data('skin');
  2372. if($('#ace-skins-stylesheet').length == 0) {
  2373. //let's load skins stylesheet only when needed!
  2374. var ace_style = $('head').find('link.ace-main-stylesheet');
  2375. if(ace_style.length == 0) {
  2376. ace_style = $('head').find('link[href*="/ace.min.css"],link[href*="/ace-part2.min.css"]');
  2377. if(ace_style.length == 0) {
  2378. ace_style = $('head').find('link[href*="/ace.css"],link[href*="/ace-part2.css"]');
  2379. }
  2380. }
  2381. var stylesheet_url = ace_style.first().attr('href').replace(/(\.min)?\.css$/i , '-skins$1.css');
  2382. $.ajax({
  2383. 'url': stylesheet_url
  2384. }).done(function() {
  2385. var new_link = jQuery('<link />', {type : 'text/css', rel: 'stylesheet', 'id': 'ace-skins-stylesheet'})
  2386. if(ace_style.length > 0){
  2387. new_link.insertAfter(ace_style.last());
  2388. }
  2389. else new_link.appendTo('head');
  2390. new_link.attr('href', stylesheet_url);
  2391. //we set "href" after insertion, for IE to work
  2392. applyChanges(skin_class);
  2393. })
  2394. }
  2395. else {
  2396. applyChanges(skin_class);
  2397. }
  2398. function applyChanges(skin_class) {
  2399. //skin cookie tip
  2400. var body = $(document.body);
  2401. body.removeClass('no-skin skin-1 skin-2 skin-3');
  2402. //if(skin_class != 'skin-0') {
  2403. body.addClass(skin_class);
  2404. ace.data.set('skin', skin_class);
  2405. //save the selected skin to cookies
  2406. //which can later be used by your server side app to set the skin
  2407. //for example: <body class="<?php echo $_COOKIE['ace_skin']; ?>"
  2408. //} else ace.data.remove('skin');
  2409. var skin3_colors = ['red', 'blue', 'green', ''];
  2410. //undo skin-1
  2411. $('.ace-nav > li.grey').removeClass('dark');
  2412. //undo skin-2
  2413. $('.ace-nav > li').removeClass('no-border margin-1');
  2414. $('.ace-nav > li:not(:last-child)').removeClass('light-pink').find('> a > '+ace.vars['.icon']).removeClass('pink').end().eq(0).find('.badge').removeClass('badge-warning');
  2415. $('.sidebar-shortcuts .btn')
  2416. .removeClass('btn-pink btn-white')
  2417. .find(ace.vars['.icon']).removeClass('white');
  2418. //undo skin-3
  2419. $('.ace-nav > li.grey').removeClass('red').find('.badge').removeClass('badge-yellow');
  2420. $('.sidebar-shortcuts .btn').removeClass('btn-primary btn-white')
  2421. var i = 0;
  2422. $('.sidebar-shortcuts .btn').each(function() {
  2423. $(this).find(ace.vars['.icon']).removeClass(skin3_colors[i++]);
  2424. })
  2425. var skin0_buttons = ['btn-success', 'btn-info', 'btn-warning', 'btn-danger'];
  2426. if(skin_class == 'no-skin') {
  2427. var i = 0;
  2428. $('.sidebar-shortcuts .btn').each(function() {
  2429. $(this).attr('class', 'btn ' + skin0_buttons[i++%4]);
  2430. })
  2431. $('.sidebar[data-sidebar-scroll=true]').ace_sidebar_scroll('updateStyle', '');
  2432. $('.sidebar[data-sidebar-hover=true]').ace_sidebar_hover('updateStyle', 'no-track scroll-thin');
  2433. }
  2434. else if(skin_class == 'skin-1') {
  2435. $('.ace-nav > li.grey').addClass('dark');
  2436. var i = 0;
  2437. $('.sidebar-shortcuts')
  2438. .find('.btn').each(function() {
  2439. $(this).attr('class', 'btn ' + skin0_buttons[i++%4]);
  2440. })
  2441. $('.sidebar[data-sidebar-scroll=true]').ace_sidebar_scroll('updateStyle', 'scroll-white no-track');
  2442. $('.sidebar[data-sidebar-hover=true]').ace_sidebar_hover('updateStyle', 'no-track scroll-thin scroll-white');
  2443. }
  2444. else if(skin_class == 'skin-2') {
  2445. $('.ace-nav > li').addClass('no-border margin-1');
  2446. $('.ace-nav > li:not(:last-child)').addClass('light-pink').find('> a > '+ace.vars['.icon']).addClass('pink').end().eq(0).find('.badge').addClass('badge-warning');
  2447. $('.sidebar-shortcuts .btn').attr('class', 'btn btn-white btn-pink')
  2448. .find(ace.vars['.icon']).addClass('white');
  2449. $('.sidebar[data-sidebar-scroll=true]').ace_sidebar_scroll('updateStyle', 'scroll-white no-track');
  2450. $('.sidebar[data-sidebar-hover=true]').ace_sidebar_hover('updateStyle', 'no-track scroll-thin scroll-white');
  2451. }
  2452. //skin-3
  2453. //change shortcut buttons classes, this should be hard-coded if you want to choose this skin
  2454. else if(skin_class == 'skin-3') {
  2455. body.addClass('no-skin');//because skin-3 has many parts of no-skin as well
  2456. $('.ace-nav > li.grey').addClass('red').find('.badge').addClass('badge-yellow');
  2457. var i = 0;
  2458. $('.sidebar-shortcuts .btn').each(function() {
  2459. $(this).attr('class', 'btn btn-primary btn-white');
  2460. $(this).find(ace.vars['.icon']).addClass(skin3_colors[i++]);
  2461. })
  2462. $('.sidebar[data-sidebar-scroll=true]').ace_sidebar_scroll('updateStyle', 'scroll-dark no-track');
  2463. $('.sidebar[data-sidebar-hover=true]').ace_sidebar_hover('updateStyle', 'no-track scroll-thin');
  2464. }
  2465. //some sizing differences may be there in skins, so reset scrollbar size
  2466. $('.sidebar[data-sidebar-scroll=true]').ace_sidebar_scroll('reset')
  2467. //$('.sidebar[data-sidebar-hover=true]').ace_sidebar_hover('reset')
  2468. if(ace.vars['old_ie']) ace.helper.redraw(document.body, true);
  2469. }
  2470. })
  2471. })(jQuery);;/**
  2472. The widget box reload button/event handler. You should use your own handler. An example is available at <i class="text-info">examples/widgets.html</i>.
  2473. <u><i class="glyphicon glyphicon-flash"></i> You don't need this. Used for demo only</u>
  2474. */
  2475. (function($ , undefined) {
  2476. //***default action for reload in this demo
  2477. //you should remove this and add your own handler for each specific .widget-box
  2478. //when data is finished loading or processing is done you can call $box.trigger('reloaded.ace.widget')
  2479. $(document).on('reload.ace.widget', '.widget-box', function (ev) {
  2480. var $box = $(this);
  2481. //trigger the reloaded event to remove the spinner icon after 1-2 seconds
  2482. setTimeout(function() {
  2483. $box.trigger('reloaded.ace.widget');
  2484. }, parseInt(Math.random() * 1000 + 1000));
  2485. });
  2486. //you may want to do something like this:
  2487. /**
  2488. $('#my-widget-box').on('reload.ace.widget', function(){
  2489. //load new data here
  2490. //and when finished trigger "reloaded" event
  2491. $(this).trigger('reloaded.ace.widget');
  2492. });
  2493. */
  2494. })(window.jQuery);;/**
  2495. The autocomplete dropdown when typing inside search box.
  2496. <u><i class="glyphicon glyphicon-flash"></i> You don't need this. Used for demo only</u>
  2497. */
  2498. (function($ , undefined) {
  2499. ace.vars['US_STATES'] = ["Alabama","Alaska","Arizona","Arkansas","California","Colorado","Connecticut","Delaware","Florida","Georgia","Hawaii","Idaho","Illinois","Indiana","Iowa","Kansas","Kentucky","Louisiana","Maine","Maryland","Massachusetts","Michigan","Minnesota","Mississippi","Missouri","Montana","Nebraska","Nevada","New Hampshire","New Jersey","New Mexico","New York","North Dakota","North Carolina","Ohio","Oklahoma","Oregon","Pennsylvania","Rhode Island","South Carolina","South Dakota","Tennessee","Texas","Utah","Vermont","Virginia","Washington","West Virginia","Wisconsin","Wyoming"]
  2500. try {
  2501. $('#nav-search-input').bs_typeahead({
  2502. source: ace.vars['US_STATES'],
  2503. updater:function (item) {
  2504. //when an item is selected from dropdown menu, focus back to input element
  2505. $('#nav-search-input').focus();
  2506. return item;
  2507. }
  2508. });
  2509. } catch(e) {}
  2510. })(window.jQuery);