/*! * Ace v1.3.5 */ if (typeof jQuery === 'undefined') { throw new Error('Ace\'s JavaScript requires jQuery') } /** Required. Ace's Basic File to Initiliaze Different Parts and Some Variables. */ //document ready function jQuery(function($) { try { ace.demo.init(); } catch(e) {} }); //some basic variables (function(undefined) { if( !('ace' in window) ) window['ace'] = {} if( !('helper' in window['ace']) ) window['ace'].helper = {} if( !('vars' in window['ace']) ) window['ace'].vars = {} window['ace'].vars['icon'] = ' ace-icon '; window['ace'].vars['.icon'] = '.ace-icon'; ace.vars['touch'] = ('ontouchstart' in window);//(('ontouchstart' in document.documentElement) || (window.DocumentTouch && document instanceof DocumentTouch)); //sometimes the only good way to work around browser's pecularities is to detect them using user-agents //though it's not accurate var agent = navigator.userAgent ace.vars['webkit'] = !!agent.match(/AppleWebKit/i) ace.vars['safari'] = !!agent.match(/Safari/i) && !agent.match(/Chrome/i); ace.vars['android'] = ace.vars['safari'] && !!agent.match(/Android/i) ace.vars['ios_safari'] = !!agent.match(/OS ([4-9])(_\d)+ like Mac OS X/i) && !agent.match(/CriOS/i) ace.vars['ie'] = window.navigator.msPointerEnabled || (document.all && document.querySelector);//8-11 ace.vars['old_ie'] = document.all && !document.addEventListener;//8 and below ace.vars['very_old_ie'] = document.all && !document.querySelector;//7 and below ace.vars['firefox'] = 'MozAppearance' in document.documentElement.style; ace.vars['non_auto_fixed'] = ace.vars['android'] || ace.vars['ios_safari']; //sometimes we try to use 'tap' event instead of 'click' if jquery mobile plugin is available ace['click_event'] = ace.vars['touch'] && jQuery.fn.tap ? 'tap' : 'click'; })(); (function($ , undefined) { ace.demo = { functions: {}, init: function(initAnyway) { //initAnyway used to make sure the call is from our RequireJS app and not a document ready event! var initAnyway = !!initAnyway && true; if(typeof requirejs !== "undefined" && !initAnyway) return; for(var func in ace.demo.functions) if(ace.demo.functions.hasOwnProperty(func)) { ace.demo.functions[func](); } } } ace.demo.functions.basics = function() { // for android and ios we don't use "top:auto" when breadcrumbs is fixed if(ace.vars['non_auto_fixed']) { $('body').addClass('mob-safari'); } ace.vars['transition'] = ace.vars['animation'] || !!$.support.transition; } ace.demo.functions.enableSidebar = function() { //initiate sidebar function var $sidebar = $('.sidebar'); if($.fn.ace_sidebar) $sidebar.ace_sidebar(); if($.fn.ace_sidebar_scroll) $sidebar.ace_sidebar_scroll({ //for other options please see documentation 'include_toggle': false || ace.vars['safari'] || ace.vars['ios_safari'] //true = include toggle button in the scrollbars }); if($.fn.ace_sidebar_hover) $sidebar.ace_sidebar_hover({ 'sub_hover_delay': 750, 'sub_scroll_style': 'no-track scroll-thin scroll-margin scroll-visible' }); } //Load content via ajax ace.demo.functions.enableDemoAjax = function() { if(!$.fn.ace_ajax) return; if(window.Pace) { window.paceOptions = { ajax: true, document: true, eventLag: false // disabled //elements: {selectors: ['.page-content-area']} } } var demo_ajax_options = { 'close_active': true, close_mobile_menu: '#sidebar', close_dropdowns: true, 'default_url': 'page/index',//default hash 'content_url': function(hash) { //***NOTE*** //this is for Ace demo only, you should change it to return a valid URL //please refer to documentation for more info if( !hash.match(/^page\//) ) return false; var path = document.location.pathname; //for example in Ace HTML demo version we convert /ajax/index.html#page/gallery to > /ajax/content/gallery.html and load it if(path.match(/(\/ajax\/)(index\.html)?/)) return path.replace(/(\/ajax\/)(index\.html)?/, '/ajax/content/'+hash.replace(/^page\//, '')+'.html') ; //for example in Ace PHP demo version we convert "ajax.php#page/dashboard" to "ajax.php?page=dashboard" and load it return path + "?" + hash.replace(/\//, "="); } } //for IE9 and below we exclude PACE loader (using conditional IE comments) //for other browsers we use the following extra ajax loader options if(window.Pace) { demo_ajax_options['loading_overlay'] = 'body';//the opaque overlay is applied to 'body' } //initiate ajax loading on this element( which is .page-content-area[data-ajax-content=true] in Ace's demo) $('[data-ajax-content=true]').ace_ajax(demo_ajax_options) //if general error happens and ajax is working, let's stop loading icon & PACE $(window).on('error.ace_ajax', function() { $('[data-ajax-content=true]').each(function() { var $this = $(this); if( $this.ace_ajax('working') ) { if(window.Pace && Pace.running) Pace.stop(); $this.ace_ajax('stopLoading', true); } }) }) } ///////////////////////////// ace.demo.functions.handleScrollbars = function() { //add scrollbars for navbar dropdowns var has_scroll = !!$.fn.ace_scroll; if(has_scroll) $('.dropdown-content').ace_scroll({reset: false, mouseWheelLock: true}) //reset scrolls bars on window resize if(has_scroll && !ace.vars['old_ie']) {//IE has an issue with widget fullscreen on ajax?!!! $(window).on('resize.reset_scroll', function() { $('.ace-scroll:not(.scroll-disabled)').not(':hidden').ace_scroll('reset'); }); if(has_scroll) $(document).on('settings.ace.reset_scroll', function(e, name) { if(name == 'sidebar_collapsed') $('.ace-scroll:not(.scroll-disabled)').not(':hidden').ace_scroll('reset'); }); } } ace.demo.functions.dropdownAutoPos = function() { //change a dropdown to "dropup" depending on its position $(document).on('click.dropdown.pos', '.dropdown-toggle[data-position="auto"]', function() { var offset = $(this).offset(); var parent = $(this.parentNode); if ( parseInt(offset.top + $(this).height()) + 50 > (ace.helper.scrollTop() + ace.helper.winHeight() - parent.find('.dropdown-menu').eq(0).height()) ) parent.addClass('dropup'); else parent.removeClass('dropup'); }); } ace.demo.functions.navbarHelpers = function() { //prevent dropdowns from hiding when a from is clicked /**$(document).on('click', '.dropdown-navbar form', function(e){ e.stopPropagation(); });*/ //disable navbar icon animation upon click $('.ace-nav [class*="icon-animated-"]').closest('a').one('click', function(){ var icon = $(this).find('[class*="icon-animated-"]').eq(0); var $match = icon.attr('class').match(/icon\-animated\-([\d\w]+)/); icon.removeClass($match[0]); }); //prevent dropdowns from hiding when a tab is selected $(document).on('click', '.dropdown-navbar .nav-tabs', function(e){ e.stopPropagation(); var $this , href var that = e.target if( ($this = $(e.target).closest('[data-toggle=tab]')) && $this.length > 0) { $this.tab('show'); e.preventDefault(); $(window).triggerHandler('resize.navbar.dropdown') } }); } ace.demo.functions.sidebarTooltips = function() { //tooltip in sidebar items $('.sidebar .nav-list .badge[title],.sidebar .nav-list .badge[title]').each(function() { var tooltip_class = $(this).attr('class').match(/tooltip\-(?:\w+)/); tooltip_class = tooltip_class ? tooltip_class[0] : 'tooltip-error'; $(this).tooltip({ 'placement': function (context, source) { var offset = $(source).offset(); if( parseInt(offset.left) < parseInt(document.body.scrollWidth / 2) ) return 'right'; return 'left'; }, container: 'body', template: '
' }); }); //or something like this if items are dynamically inserted /** $('.sidebar').tooltip({ 'placement': function (context, source) { var offset = $(source).offset(); if( parseInt(offset.left) < parseInt(document.body.scrollWidth / 2) ) return 'right'; return 'left'; }, selector: '.nav-list .badge[title],.nav-list .label[title]', container: 'body', template: '
' }); */ } ace.demo.functions.scrollTopBtn = function() { //the scroll to top button var scroll_btn = $('.btn-scroll-up'); if(scroll_btn.length > 0) { var is_visible = false; $(window).on('scroll.scroll_btn', function() { var scroll = ace.helper.scrollTop(); var h = ace.helper.winHeight(); var body_sH = document.body.scrollHeight; if(scroll > parseInt(h / 4) || (scroll > 0 && body_sH >= h && h + scroll >= body_sH - 1)) {//|| for smaller pages, when reached end of page if(!is_visible) { scroll_btn.addClass('display'); is_visible = true; } } else { if(is_visible) { scroll_btn.removeClass('display'); is_visible = false; } } }).triggerHandler('scroll.scroll_btn'); scroll_btn.on(ace.click_event, function(){ var duration = Math.min(500, Math.max(100, parseInt(ace.helper.scrollTop() / 3))); $('html,body').animate({scrollTop: 0}, duration); return false; }); } } ace.demo.functions.someBrowserFix = function() { //chrome and webkit have a problem here when resizing from 479px to more //we should force them redraw the navbar! if( ace.vars['webkit'] ) { var ace_nav = $('.ace-nav').get(0); if( ace_nav ) $(window).on('resize.webkit_fix' , function(){ ace.helper.redraw(ace_nav); }); } //fix an issue with ios safari, when an element is fixed and an input receives focus if(ace.vars['ios_safari']) { $(document).on('ace.settings.ios_fix', function(e, event_name, event_val) { if(event_name != 'navbar_fixed') return; $(document).off('focus.ios_fix blur.ios_fix', 'input,textarea,.wysiwyg-editor'); if(event_val == true) { $(document).on('focus.ios_fix', 'input,textarea,.wysiwyg-editor', function() { $(window).on('scroll.ios_fix', function() { var navbar = $('#navbar').get(0); if(navbar) ace.helper.redraw(navbar); }); }).on('blur.ios_fix', 'input,textarea,.wysiwyg-editor', function() { $(window).off('scroll.ios_fix'); }) } }).triggerHandler('ace.settings.ios_fix', ['navbar_fixed', $('#navbar').css('position') == 'fixed']); } } ace.demo.functions.bsCollapseToggle = function() { //bootstrap collapse component icon toggle $(document).on('hide.bs.collapse show.bs.collapse', function (ev) { var panel_id = ev.target.getAttribute('id') var panel = $('a[href*="#'+ panel_id+'"]'); if(panel.length == 0) panel = $('a[data-target*="#'+ panel_id+'"]'); if(panel.length == 0) return; panel.find(ace.vars['.icon']).each(function(){ var $icon = $(this) var $match var $icon_down = null var $icon_up = null if( ($icon_down = $icon.attr('data-icon-show')) ) { $icon_up = $icon.attr('data-icon-hide') } else if( $match = $icon.attr('class').match(/fa\-(.*)\-(up|down)/) ) { $icon_down = 'fa-'+$match[1]+'-down' $icon_up = 'fa-'+$match[1]+'-up' } if($icon_down) { if(ev.type == 'show') $icon.removeClass($icon_down).addClass($icon_up) else $icon.removeClass($icon_up).addClass($icon_down) return false;//ignore other icons that match, one is enough } }); }) } //in small devices display navbar dropdowns like modal boxes ace.demo.functions.smallDeviceDropdowns = function() { if(ace.vars['old_ie']) return; $(document) .on('shown.bs.dropdown.navbar', '.ace-nav > li.dropdown-modal', function(e) { adjustNavbarDropdown.call(this); var self = this; $(window).on('resize.navbar.dropdown', function() { adjustNavbarDropdown.call(self); }) }) .on('hidden.bs.dropdown.navbar', '.ace-nav > li.dropdown-modal', function(e) { $(window).off('resize.navbar.dropdown'); resetNavbarDropdown.call(this); }) function adjustNavbarDropdown() { var $sub = $(this).find('> .dropdown-menu'); if( $sub.css('position') == 'fixed' ) { var win_width = parseInt($(window).width()); var offset_w = win_width > 320 ? 60 : (win_width > 240 ? 40 : 30); var avail_width = parseInt(win_width) - offset_w; var avail_height = parseInt($(window).height()) - 30; var width = parseInt(Math.min(avail_width , 320)); //we set 'width' here for text wrappings and spacings to take effect before calculating scrollHeight $sub.css('width', width); var tabbed = false; var extra_parts = 0; var dropdown_content = $sub.find('.tab-pane.active .dropdown-content.ace-scroll'); if(dropdown_content.length == 0) dropdown_content = $sub.find('.dropdown-content.ace-scroll'); else tabbed = true; var parent_menu = dropdown_content.closest('.dropdown-menu'); var scrollHeight = $sub[0].scrollHeight; if(dropdown_content.length == 1) { //sometimes there's no scroll-content, for example in detached scrollbars var content = dropdown_content.find('.scroll-content')[0]; if(content) { scrollHeight = content.scrollHeight; } extra_parts += parent_menu.find('.dropdown-header').outerHeight(); extra_parts += parent_menu.find('.dropdown-footer').outerHeight(); var tab_content = parent_menu.closest('.tab-content'); if( tab_content.length != 0 ) { extra_parts += tab_content.siblings('.nav-tabs').eq(0).height(); } } var height = parseInt(Math.min(avail_height , 480, scrollHeight + extra_parts)); var left = parseInt(Math.abs((avail_width + offset_w - width)/2)); var top = parseInt(Math.abs((avail_height + 30 - height)/2)); var zindex = parseInt($sub.css('z-index')) || 0; $sub.css({'height': height, 'left': left, 'right': 'auto', 'top': top - (!tabbed ? 1 : 3)}); if(dropdown_content.length == 1) { if(!ace.vars['touch']) { dropdown_content.ace_scroll('update', {size: height - extra_parts}).ace_scroll('enable').ace_scroll('reset'); } else { dropdown_content .ace_scroll('disable').css('max-height', height - extra_parts).addClass('overflow-scroll'); } } $sub.css('height', height + (!tabbed ? 2 : 7));//for bottom border adjustment and tab content paddings if($sub.hasClass('user-menu')) { $sub.css('height', '');//because of user-info hiding/showing at different widths, which changes above 'scrollHeight', so we remove it! //user menu is re-positioned in small widths //but we need to re-position again in small heights as well (modal mode) var user_info = $(this).find('.user-info'); if(user_info.length == 1 && user_info.css('position') == 'fixed') { user_info.css({'left': left, 'right': 'auto', 'top': top, 'width': width - 2, 'max-width': width - 2, 'z-index': zindex + 1}); } else user_info.css({'left': '', 'right': '', 'top': '', 'width': '', 'max-width': '', 'z-index': ''}); } //dropdown's z-index is limited by parent .navbar's z-index (which doesn't make sense because dropdowns are fixed!) //so for example when in 'content-slider' page, fixed modal toggle buttons go above are dropdowns //so we increase navbar's z-index to fix this! $(this).closest('.navbar.navbar-fixed-top').css('z-index', zindex); } else { if($sub.length != 0) resetNavbarDropdown.call(this, $sub); } } //reset scrollbars and user menu function resetNavbarDropdown($sub) { $sub = $sub || $(this).find('> .dropdown-menu'); if($sub.length > 0) { $sub .css({'width': '', 'height': '', 'left': '', 'right': '', 'top': ''}) .find('.dropdown-content').each(function() { if(ace.vars['touch']) { $(this).css('max-height', '').removeClass('overflow-scroll'); } var size = parseInt($(this).attr('data-size') || 0) || $.fn.ace_scroll.defaults.size; $(this).ace_scroll('update', {size: size}).ace_scroll('enable').ace_scroll('reset'); }) if( $sub.hasClass('user-menu') ) { var user_info = $(this).find('.user-info') .css({'left': '', 'right': '', 'top': '', 'width': '', 'max-width': '', 'z-index': ''}); } } $(this).closest('.navbar').css('z-index', ''); } } })(jQuery); //some ace helper functions (function($$ , undefined) {//$$ is ace.helper $$.unCamelCase = function(str) { return str.replace(/([a-z])([A-Z])/g, function(match, c1, c2){ return c1+'-'+c2.toLowerCase() }) } $$.strToVal = function(str) { var res = str.match(/^(?:(true)|(false)|(null)|(\-?[\d]+(?:\.[\d]+)?)|(\[.*\]|\{.*\}))$/i); var val = str; if(res) { if(res[1]) val = true; else if(res[2]) val = false; else if(res[3]) val = null; else if(res[4]) val = parseFloat(str); else if(res[5]) { try { val = JSON.parse(str) } catch (err) {} } } return val; } $$.getAttrSettings = function(elem, attr_list, prefix) { if(!elem) return; var list_type = attr_list instanceof Array ? 1 : 2; //attr_list can be Array or Object(key/value) var prefix = prefix ? prefix.replace(/([^\-])$/ , '$1-') : ''; prefix = 'data-' + prefix; var settings = {} for(var li in attr_list) if(attr_list.hasOwnProperty(li)) { var name = list_type == 1 ? attr_list[li] : li; var attr_val, attr_name = $$.unCamelCase(name.replace(/[^A-Za-z0-9]{1,}/g , '-')).toLowerCase() if( ! ((attr_val = elem.getAttribute(prefix + attr_name)) ) ) continue; settings[name] = $$.strToVal(attr_val); } return settings; } $$.scrollTop = function() { return document.scrollTop || document.documentElement.scrollTop || document.body.scrollTop } $$.winHeight = function() { return window.innerHeight || document.documentElement.clientHeight; } $$.redraw = function(elem, force) { if(!elem) return; var saved_val = elem.style['display']; elem.style.display = 'none'; elem.offsetHeight; if(force !== true) { elem.style.display = saved_val; } else { //force redraw for example in old IE setTimeout(function() { elem.style.display = saved_val; }, 10); } } })(ace.helper);;/** Load content via Ajax . For more information please refer to documentation #basics/ajax */ (function($ , undefined) { var ajax_loaded_scripts = {} function AceAjax(contentArea, settings) { var $contentArea = $(contentArea); var self = this; $contentArea.attr('data-ajax-content', 'true'); //get a list of 'data-*' attributes that override 'defaults' and 'settings' var attrib_values = ace.helper.getAttrSettings(contentArea, $.fn.ace_ajax.defaults); this.settings = $.extend({}, $.fn.ace_ajax.defaults, settings, attrib_values); var working = false; var $overlay = $();//empty set this.force_reload = false;//set jQuery ajax's cache option to 'false' to reload content this.loadUrl = function(hash, cache, manual_trigger) { var url = false; hash = hash.replace(/^(\#\!)?\#/, ''); this.force_reload = (cache === false) if(typeof this.settings.content_url === 'function') url = this.settings.content_url(hash); if(typeof url === 'string') this.getUrl(url, hash, manual_trigger); } this.loadAddr = function(url, hash, cache) { this.force_reload = (cache === false); this.getUrl(url, hash, false); } this.reload = function() { var hash = $.trim(window.location.hash); if(!hash && this.settings.default_url) hash = this.settings.default_url; this.loadUrl(hash, false); } this.post = function(url, data, updateView, extraParams) { var url = url || $.trim(location.href.replace(location.hash,'')); if(!url) return; var data = data || {} var updateView = updateView || false; this.getUrl(url, null, false, 'POST', data, updateView, extraParams); } this.getUrl = function(url, hash, manual_trigger, method, data, updateView, extraParams) { if(working) { return; } var method = method || 'GET'; var updateView = (method == 'GET') || (method == 'POST' && updateView == true) var data = data || null; var event $contentArea.trigger(event = $.Event('ajaxloadstart'), {url: url, hash: hash, method: method, data: data}) if (event.isDefaultPrevented()) return; self.startLoading(); var ajax_params = method == 'GET' ? {'url': url, 'cache': !this.force_reload} : {'url': url, 'method' : 'POST', 'data': data} if(method == 'POST' && typeof extraParams == 'object') ajax_params = $.extend({}, ajax_params, extraParams); $.ajax(ajax_params) .error(function() { $contentArea.trigger('ajaxloaderror', {url: url, hash: hash, method: method, data: data}); self.stopLoading(true); }) .done(function(result) { $contentArea.trigger('ajaxloaddone', {url: url, hash: hash, method: method, data: data}); if(method == 'POST') { var event $contentArea.trigger(event = $.Event('ajaxpostdone', {url: url, data: data, result: result})) if( event.isDefaultPrevented() ) updateView = false; } var link_element = null, link_text = ''; if(typeof self.settings.update_active === 'function') { link_element = self.settings.update_active.call(null, hash, url, method, updateView); } else if(self.settings.update_active === true && hash) { link_element = $('a[data-url="'+hash+'"]'); if(link_element.length > 0) { var nav = link_element.closest('.nav'); if(nav.length > 0) { nav.find('.active').each(function(){ var $class = 'active'; if( $(this).hasClass('hover') || self.settings.close_active ) $class += ' open'; $(this).removeClass($class); if(self.settings.close_active) { $(this).find(' > .submenu').css('display', ''); } }) var active_li = link_element.closest('li').addClass('active').parents('.nav li').addClass('active open'); nav.closest('.sidebar[data-sidebar-scroll=true]').each(function() { var $this = $(this); $this.ace_sidebar_scroll('reset'); if(manual_trigger == true) $this.ace_sidebar_scroll('scroll_to_active');//first time only }) } } } ///////// if(typeof self.settings.update_breadcrumbs === 'function') { link_text = self.settings.update_breadcrumbs.call(null, hash, url, link_element, method, updateView); } else if(self.settings.update_breadcrumbs === true && link_element != null && link_element.length > 0) { link_text = updateBreadcrumbs(link_element); } ///////// $overlay.addClass('content-loaded').detach(); if(updateView) { //convert "title" and "link" tags to "div" tags for later processing result = String(result) .replace(/<(title|link)([\s\>])/gi,'') $contentArea.empty().html(result); } $(self.settings.loading_overlay || $contentArea).append($overlay); //remove previous stylesheets inserted via ajax if(updateView) setTimeout(function() { $('head').find('link.ace-ajax-stylesheet').remove(); var main_selectors = ['link.ace-main-stylesheet', 'link#main-ace-style', 'link[href*="/ace.min.css"]', 'link[href*="/ace.css"]'] var ace_style = []; for(var m = 0; m < main_selectors.length; m++) { ace_style = $('head').find(main_selectors[m]).first(); if(ace_style.length > 0) break; } $contentArea.find('.ajax-append-link').each(function(e) { var $link = $(this); if ( $link.attr('href') ) { var new_link = jQuery('', {type : 'text/css', rel: 'stylesheet', 'class': 'ace-ajax-stylesheet'}) if( ace_style.length > 0 ) new_link.insertBefore(ace_style); else new_link.appendTo('head'); new_link.attr('href', $link.attr('href'));//we set "href" after insertion, for IE to work } $link.remove(); }) }, 10); ////////////////////// if(typeof self.settings.update_title === 'function') { self.settings.update_title.call(null, hash, url, link_text, method, updateView); } else if(self.settings.update_title === true && method == 'GET') { updateTitle(link_text); } if( !manual_trigger && updateView ) { $('html,body').animate({scrollTop: 0}, 250); } ////////////////////// $contentArea.trigger('ajaxloadcomplete', {url: url, hash: hash, method: method, data:data}); ////////////////////// //if result contains call to "loadScripts" then don't stopLoading now var re = /\.(?:\s*)ace(?:_a|A)jax(?:\s*)\((?:\s*)(?:\'|\")loadScripts(?:\'|\")/; if(result.match(re)) self.stopLoading(); else self.stopLoading(true); }) } /////////////////////// var fixPos = false; var loadTimer = null; this.startLoading = function() { if(working) return; working = true; if(!this.settings.loading_overlay && $contentArea.css('position') == 'static') { $contentArea.css('position', 'relative');//for correct icon positioning fixPos = true; } $overlay.remove(); $overlay = $('
'+this.settings.loading_text+'
') if(this.settings.loading_overlay == 'body') $('body').append($overlay.addClass('ajax-overlay-body')); else if(this.settings.loading_overlay) $(this.settings.loading_overlay).append($overlay); else $contentArea.append($overlay); if(this.settings.max_load_wait !== false) loadTimer = setTimeout(function() { loadTimer = null; if(!working) return; var event $contentArea.trigger(event = $.Event('ajaxloadlong')) if (event.isDefaultPrevented()) return; self.stopLoading(true); }, this.settings.max_load_wait * 1000); } this.stopLoading = function(stopNow) { if(stopNow === true) { working = false; $overlay.remove(); if(fixPos) { $contentArea.css('position', '');//restore previous 'position' value fixPos = false; } if(loadTimer != null) { clearTimeout(loadTimer); loadTimer = null; } } else { $overlay.addClass('almost-loaded'); $contentArea.one('ajaxscriptsloaded.inner_call', function() { self.stopLoading(true); /** if(window.Pace && Pace.running == true) { Pace.off('done'); Pace.once('done', function() { self.stopLoading(true) }) } else self.stopLoading(true); */ }) } } this.working = function() { return working; } /////////////////////// function updateBreadcrumbs(link_element) { var link_text = ''; //update breadcrumbs var breadcrumbs = $('.breadcrumb'); if(breadcrumbs.length > 0 && breadcrumbs.is(':visible')) { breadcrumbs.find('> li:not(:first-child)').remove(); var i = 0; link_element.parents('.nav li').each(function() { var link = $(this).find('> a'); var link_clone = link.clone(); link_clone.find('i,.fa,.glyphicon,.ace-icon,.menu-icon,.badge,.label').remove(); var text = link_clone.text(); link_clone.remove(); var href = link.attr('href'); if(i == 0) { var li = $('
  • ').appendTo(breadcrumbs); li.text(text); link_text = text; } else { var li = $('
  • ').insertAfter(breadcrumbs.find('> li:first-child')); li.find('a').attr('href', href).text(text); } i++; }) } return link_text; } function updateTitle(link_text) { var $title = $contentArea.find('.ajax-append-title'); if($title.length > 0) { document.title = $title.text(); $title.remove(); } else if(link_text.length > 0) { var extra = $.trim(String(document.title).replace(/^(.*)[\-]/, ''));//for example like " - Ace Admin" if(extra) extra = ' - ' + extra; link_text = $.trim(link_text) + extra; } } this.loadScripts = function(scripts, callback) { var scripts = scripts || []; $.ajaxPrefilter('script', function(opts) {opts.cache = true}); setTimeout(function() { //let's keep a list of loaded scripts so that we don't load them more than once! function finishLoading() { if(typeof callback === 'function') callback(); $('.btn-group[data-toggle="buttons"] > .btn').button(); $contentArea.trigger('ajaxscriptsloaded'); } //var deferreds = []; var deferred_count = 0;//deferreds count var resolved = 0; for(var i = 0; i < scripts.length; i++) if(scripts[i]) { (function() { var script_name = "js-"+scripts[i].replace(/[^\w\d\-]/g, '-').replace(/\-\-/g, '-'); if( ajax_loaded_scripts[script_name] !== true ) deferred_count++; })() } function nextScript(index) { index += 1; if(index < scripts.length) loadScript(index); else { finishLoading(); } } function loadScript(index) { index = index || 0; if(!scripts[index]) {//could be null sometimes return nextScript(index); } var script_name = "js-"+scripts[index].replace(/[^\w\d\-]/g, '-').replace(/\-\-/g, '-'); //only load scripts that are not loaded yet! if( ajax_loaded_scripts[script_name] !== true ) { $.getScript(scripts[index]) .done(function() { ajax_loaded_scripts[script_name] = true; }) //.fail(function() { //}) .complete(function() { resolved++; if(resolved >= deferred_count && working) { finishLoading(); } else { nextScript(index); } }) } else {//script previoisly loaded nextScript(index); } } if (deferred_count > 0) { loadScript(); } else { finishLoading(); } }, 10) } ///////////////// $(window) .off('hashchange.ace_ajax') .on('hashchange.ace_ajax', function(e, manual_trigger) { var hash = $.trim(window.location.hash); if(!hash || hash.length == 0) return; if(self.settings.close_mobile_menu) { try {$(self.settings.close_mobile_menu).ace_sidebar('mobileHide')} catch(e){} } if(self.settings.close_dropdowns) { $('.dropdown.open .dropdown-toggle').dropdown('toggle'); } self.loadUrl(hash, null, manual_trigger); }).trigger('hashchange.ace_ajax', [true]); var hash = $.trim(window.location.hash); if(!hash && this.settings.default_url) window.location.hash = this.settings.default_url; }//AceAjax $.fn.aceAjax = $.fn.ace_ajax = function (option, value, value2, value3, value4) { var method_call; var $set = this.each(function () { var $this = $(this); var data = $this.data('ace_ajax'); var options = typeof option === 'object' && option; if (!data) $this.data('ace_ajax', (data = new AceAjax(this, options))); if (typeof option === 'string' && typeof data[option] === 'function') { if(value4 !== undefined) method_call = data[option](value, value2, value3, value4); else if(value3 !== undefined) method_call = data[option](value, value2, value3); else if(value2 !== undefined) method_call = data[option](value, value2); else method_call = data[option](value); } }); return (method_call === undefined) ? $set : method_call; } $.fn.aceAjax.defaults = $.fn.ace_ajax.defaults = { content_url: false, default_url: false, loading_icon: 'fa fa-spin fa-spinner fa-2x orange', loading_text: '', loading_overlay: null, update_breadcrumbs: true, update_title: true, update_active: true, close_active: false, max_load_wait: false, close_mobile_menu: false, close_dropdowns: false } })(window.jQuery); ;/** Custom drag event for touch devices used in scrollbars. For better touch event handling and extra options a more advanced solution such as Hammer.js is recommended. */ //based on but not dependent on jQuery mobile /* * jQuery Mobile v1.3.2 * http://jquerymobile.com * * Copyright 2010, 2013 jQuery Foundation, Inc. and other contributors * Released under the MIT license. * http://jquery.org/license * */ (function($ , undefined) { if(!ace.vars['touch']) return; var touchStartEvent = "touchstart MSPointerDown pointerdown",// : "mousedown", touchStopEvent = "touchend touchcancel MSPointerUp MSPointerCancel pointerup pointercancel",// : "mouseup", touchMoveEvent = "touchmove MSPointerMove MSPointerHover pointermove";// : "mousemove"; $.event.special.ace_drag = { setup: function() { var min_threshold = 0; var $this = $(this); $this.on(touchStartEvent, function(event) { var data = event.originalEvent.touches ? event.originalEvent.touches[ 0 ] : event, start = { //time: Date.now(), coords: [ data.pageX, data.pageY ], origin: $(event.target) }, stop; //start.origin.trigger({'type' : 'ace_dragStart', 'start':(start || [-1,-1])}); var direction = false, dx = 0, dy = 0; function moveHandler(event) { if (!start) { return; } var data = event.originalEvent.touches ? event.originalEvent.touches[ 0 ] : event; stop = { coords: [ data.pageX, data.pageY ] }; // prevent scrolling //if ( Math.abs(start.coords[1] - stop.coords[1]) > 0 || Math.abs(start.coords[0] - stop.coords[01]) > 0 ) { //event.preventDefault(); //} if (start && stop) { dx = 0; dy = 0; direction = ( Math.abs(dy = start.coords[ 1 ] - stop.coords[ 1 ]) > min_threshold && Math.abs(dx = start.coords[ 0 ] - stop.coords[ 0 ]) <= Math.abs(dy) ) ? (dy > 0 ? 'up' : 'down') : ( Math.abs(dx = start.coords[ 0 ] - stop.coords[ 0 ]) > min_threshold && Math.abs( dy ) <= Math.abs(dx) ) ? (dx > 0 ? 'left' : 'right') : false; if( direction !== false ) { var retval = {cancel: false} start.origin.trigger({ 'type': 'ace_drag', //'start': start.coords, //'stop': stop.coords, 'direction': direction, 'dx': dx, 'dy': dy, 'retval': retval }) // prevent document scrolling unless retval.cancel == true if( retval.cancel == false ) event.preventDefault(); } } start.coords[0] = stop.coords[0]; start.coords[1] = stop.coords[1]; } $this .on(touchMoveEvent, moveHandler) .one(touchStopEvent, function(event) { $this.off(touchMoveEvent, moveHandler); //start.origin.trigger({'type' : 'ace_dragEnd', 'stop':(stop || [-1,-1])}); start = stop = undefined; }); }); } } })(window.jQuery);;/** Sidebar functions. Collapsing/expanding, toggling mobile view menu and other sidebar functions. */ (function($ , undefined) { var sidebar_count = 0; function Sidebar(sidebar, settings) { var self = this; this.$sidebar = $(sidebar); this.$sidebar.attr('data-sidebar', 'true'); if( !this.$sidebar.attr('id') ) this.$sidebar.attr( 'id' , 'id-sidebar-'+(++sidebar_count) ) //get a list of 'data-*' attributes that override 'defaults' and 'settings' var attrib_values = ace.helper.getAttrSettings(sidebar, $.fn.ace_sidebar.defaults, 'sidebar-'); this.settings = $.extend({}, $.fn.ace_sidebar.defaults, settings, attrib_values); //some vars this.minimized = false;//will be initialized later this.collapsible = false;//... this.horizontal = false;//... this.mobile_view = false;// //return an array containing sidebar state variables this.vars = function() { return {'minimized': this.minimized, 'collapsible': this.collapsible, 'horizontal': this.horizontal, 'mobile_view': this.mobile_view} } this.get = function(name) { if(this.hasOwnProperty(name)) return this[name]; } this.set = function(name, value) { if(this.hasOwnProperty(name)) this[name] = value; } //return a reference to self (sidebar instance) this.ref = function() { return this; } //toggle icon for sidebar collapse/expand button var toggleIcon = function(minimized, save) { var icon = $(this).find(ace.vars['.icon']), icon1, icon2; if(icon.length > 0) { icon1 = icon.attr('data-icon1');//the icon for expanded state icon2 = icon.attr('data-icon2');//the icon for collapsed state if(typeof minimized !== "undefined") { if(minimized) icon.removeClass(icon1).addClass(icon2); else icon.removeClass(icon2).addClass(icon1); } else { icon.toggleClass(icon1).toggleClass(icon2); } try { if(save !== false) ace.settings.saveState(icon.get(0)); } catch(e) {} } } //if not specified, find the toggle button related to this sidebar var findToggleBtn = function() { var toggle_btn = self.$sidebar.find('.sidebar-collapse'); if(toggle_btn.length == 0) toggle_btn = $('.sidebar-collapse[data-target="#'+(self.$sidebar.attr('id')||'')+'"]'); if(toggle_btn.length != 0) toggle_btn = toggle_btn[0]; else toggle_btn = null; return toggle_btn; } //collapse/expand sidebar this.toggleMenu = function(toggle_btn, save) { if(this.collapsible) return; this.minimized = !this.minimized; var save = !(toggle_btn === false || save === false); if(this.minimized) this.$sidebar.addClass('menu-min'); else this.$sidebar.removeClass('menu-min'); try { if(save) ace.settings.saveState(sidebar, 'class', 'menu-min', this.minimized); } catch(e) {} if( !toggle_btn ) { toggle_btn = findToggleBtn(); } if(toggle_btn) { toggleIcon.call(toggle_btn, this.minimized, save); } //force redraw for ie8 if(ace.vars['old_ie']) ace.helper.redraw(sidebar); $(document).trigger('settings.ace', ['sidebar_collapsed' , this.minimized, sidebar, save]); } this.collapse = function(toggle_btn, save) { if(this.collapsible) return; this.minimized = false; this.toggleMenu(toggle_btn, save); } this.expand = function(toggle_btn, save) { if(this.collapsible) return; this.minimized = true; this.toggleMenu(toggle_btn, save); } this.showResponsive = function() { this.$sidebar.removeClass(responsive_min_class).removeClass(responsive_max_class); } //collapse/expand in 2nd mobile style this.toggleResponsive = function(toggle_btn, showMenu) { if( !this.mobile_view || this.mobile_style != 3 ) return; if( this.$sidebar.hasClass('menu-min') ) { //remove menu-min because it interferes with responsive-max this.$sidebar.removeClass('menu-min'); var btn = findToggleBtn(); if(btn) toggleIcon.call(btn); } var showMenu = typeof showMenu !== 'undefined' ? showMenu : this.$sidebar.hasClass(responsive_min_class); if(showMenu) { this.$sidebar.addClass(responsive_max_class).removeClass(responsive_min_class); } else { this.$sidebar.removeClass(responsive_max_class).addClass(responsive_min_class); } this.minimized = !showMenu; if( !toggle_btn ) { toggle_btn = this.$sidebar.find('.sidebar-expand'); if(toggle_btn.length == 0) toggle_btn = $('.sidebar-expand[data-target="#'+(this.$sidebar.attr('id')||'')+'"]'); if(toggle_btn.length != 0) toggle_btn = toggle_btn[0]; else toggle_btn = null; } if(toggle_btn) { var icon = $(toggle_btn).find(ace.vars['.icon']), icon1, icon2; if(icon.length > 0) { icon1 = icon.attr('data-icon1');//the icon for expanded state icon2 = icon.attr('data-icon2');//the icon for collapsed state if(!showMenu) icon.removeClass(icon2).addClass(icon1); else icon.removeClass(icon1).addClass(icon2); } } $(document).triggerHandler('settings.ace', ['sidebar_collapsed' , this.minimized]); } //some helper functions //determine if we have 4th mobile style responsive sidebar and we are in mobile view this.is_collapsible = function() { var toggle return (this.$sidebar.hasClass('navbar-collapse')) && ((toggle = $('.navbar-toggle[data-target="#'+(this.$sidebar.attr('id')||'')+'"]').get(0)) != null) && toggle.scrollHeight > 0 //sidebar is collapsible and collapse button is visible? } //determine if we are in mobile view this.is_mobile_view = function() { var toggle return ((toggle = $('.menu-toggler[data-target="#'+(this.$sidebar.attr('id')||'')+'"]').get(0)) != null) && toggle.scrollHeight > 0 } //toggling (show/hide) submenu elements this.$sidebar.on(ace.click_event+'.ace.submenu', '.nav-list', function (ev) { var nav_list = this; //check to see if we have clicked on an element which is inside a .dropdown-toggle element?! //if so, it means we should toggle a submenu var link_element = $(ev.target).closest('a'); if(!link_element || link_element.length == 0) return;//return if not clicked inside a link element var minimized = self.minimized && !self.collapsible; //if .sidebar is .navbar-collapse and in small device mode, then let minimized be uneffective if( !link_element.hasClass('dropdown-toggle') ) {//it doesn't have a submenu return //just one thing before we return //if sidebar is collapsed(minimized) and we click on a first level menu item //and the click is on the icon, not on the menu text then let's cancel event and cancel navigation //Good for touch devices, that when the icon is tapped to see the menu text, navigation is cancelled //navigation is only done when menu text is tapped if( ace.click_event == 'tap' && minimized && link_element.get(0).parentNode.parentNode == nav_list )//only level-1 links { var text = link_element.find('.menu-text').get(0); if( text != null && ev.target != text && !$.contains(text , ev.target) ) {//not clicking on the text or its children ev.preventDefault(); return false; } } //ios safari only has a bit of a problem not navigating to link address when scrolling down //specify data-link attribute to ignore this if(ace.vars['ios_safari'] && link_element.attr('data-link') !== 'false') { //only ios safari has a bit of a problem not navigating to link address when scrolling down //please see issues section in documentation document.location = link_element.attr('href'); ev.preventDefault(); return false; } return; } ev.preventDefault(); var sub = link_element.siblings('.submenu').get(0); if(!sub) return false; var $sub = $(sub); var height_change = 0;//the amount of height change in .nav-list var parent_ul = sub.parentNode.parentNode; if ( ( minimized && parent_ul == nav_list ) || ( ( $sub.parent().hasClass('hover') && $sub.css('position') == 'absolute' ) && !self.collapsible ) ) { return false; } var sub_hidden = (sub.scrollHeight == 0) //if not open and visible, let's open it and make it visible if( sub_hidden && self.settings.hide_open_subs ) {//being shown now $(parent_ul).find('> .open > .submenu').each(function() { //close all other open submenus except for the active one if(this != sub && !$(this.parentNode).hasClass('active')) { height_change -= this.scrollHeight; self.hide(this, self.settings.duration, false); } }) } if( sub_hidden ) {//being shown now self.show(sub, self.settings.duration); //if a submenu is being shown and another one previously started to hide, then we may need to update/hide scrollbars //but if no previous submenu is being hidden, then no need to check if we need to hide the scrollbars in advance if(height_change != 0) height_change += sub.scrollHeight;//we need new updated 'scrollHeight' here } else { self.hide(sub, self.settings.duration); height_change -= sub.scrollHeight; //== -1 means submenu is being hidden } //hide scrollbars if content is going to be small enough that scrollbars is not needed anymore //do this almost before submenu hiding begins //but when minimized submenu's toggle should have no effect if (height_change != 0) { if(self.$sidebar.attr('data-sidebar-scroll') == 'true' && !self.minimized) self.$sidebar.ace_sidebar_scroll('prehide', height_change) } return false; }) var submenu_working = false; this.show = function(sub, $duration, shouldWait) { //'shouldWait' indicates whether to wait for previous transition (submenu toggle) to be complete or not? shouldWait = (shouldWait !== false); if(shouldWait && submenu_working) return false; var $sub = $(sub); var event; $sub.trigger(event = $.Event('show.ace.submenu')) if (event.isDefaultPrevented()) { return false; } if(shouldWait) submenu_working = true; $duration = typeof $duration !== 'undefined' ? $duration : this.settings.duration; $sub.css({ height: 0, overflow: 'hidden', display: 'block' }) .removeClass('nav-hide').addClass('nav-show')//only for window < @grid-float-breakpoint and .navbar-collapse.menu-min .parent().addClass('open'); sub.scrollTop = 0;//this is for submenu_hover when sidebar is minimized and a submenu is scrollTop'ed using scrollbars ... var complete = function(ev, trigger) { ev && ev.stopPropagation(); $sub .css({'transition-property': '', 'transition-duration': '', overflow:'', height: ''}) //if(ace.vars['webkit']) ace.helper.redraw(sub);//little Chrome issue, force redraw ;) if(trigger !== false) $sub.trigger($.Event('shown.ace.submenu')) if(shouldWait) submenu_working = false; } var finalHeight = sub.scrollHeight; if($duration == 0 || finalHeight == 0 || !$.support.transition.end) { //(if duration is zero || element is hidden (scrollHeight == 0) || CSS3 transitions are not available) complete(); } else { $sub .css({ 'height': finalHeight, 'transition-property': 'height', 'transition-duration': ($duration/1000)+'s' } ) .one($.support.transition.end, complete); //there is sometimes a glitch, so maybe retry if(ace.vars['android'] ) { setTimeout(function() { complete(null, false); ace.helper.redraw(sub); }, $duration + 20); } } return true; } this.hide = function(sub, $duration, shouldWait) { //'shouldWait' indicates whether to wait for previous transition (submenu toggle) to be complete or not? shouldWait = (shouldWait !== false); if(shouldWait && submenu_working) return false; var $sub = $(sub); var event; $sub.trigger(event = $.Event('hide.ace.submenu')) if (event.isDefaultPrevented()) { return false; } if(shouldWait) submenu_working = true; $duration = typeof $duration !== 'undefined' ? $duration : this.settings.duration; var initialHeight = sub.scrollHeight; $sub.css({ height: initialHeight, overflow: 'hidden', display: 'block' }) .parent().removeClass('open'); sub.offsetHeight; //forces the "sub" to re-consider the new 'height' before transition var complete = function(ev, trigger) { ev && ev.stopPropagation(); $sub .css({display: 'none', overflow:'', height: '', 'transition-property': '', 'transition-duration': ''}) .removeClass('nav-show').addClass('nav-hide')//only for window < @grid-float-breakpoint and .navbar-collapse.menu-min if(trigger !== false) $sub.trigger($.Event('hidden.ace.submenu')) if(shouldWait) submenu_working = false; } if( $duration == 0 || initialHeight == 0 || !$.support.transition.end) { //(if duration is zero || element is hidden (scrollHeight == 0) || CSS3 transitions are not available) complete(); } else { $sub .css({ 'height': 0, 'transition-property': 'height', 'transition-duration': ($duration/1000)+'s' } ) .one($.support.transition.end, complete); //there is sometimes a glitch, so maybe retry if(ace.vars['android'] ) { setTimeout(function() { complete(null, false); ace.helper.redraw(sub); }, $duration + 20); } } return true; } this.toggle = function(sub, $duration) { $duration = $duration || self.settings.duration; if( sub.scrollHeight == 0 ) {//if an element is hidden scrollHeight becomes 0 if( this.show(sub, $duration) ) return 1; } else { if( this.hide(sub, $duration) ) return -1; } return 0; } //sidebar vars var minimized_menu_class = 'menu-min'; var responsive_min_class = 'responsive-min'; var responsive_max_class = 'responsive-max'; var horizontal_menu_class = 'h-sidebar'; var sidebar_mobile_style = function() { //differnet mobile menu styles this.mobile_style = 1;//default responsive mode with toggle button inside navbar if(this.$sidebar.hasClass('responsive') && !$('.menu-toggler[data-target="#'+this.$sidebar.attr('id')+'"]').hasClass('navbar-toggle')) this.mobile_style = 2;//toggle button behind sidebar else if(this.$sidebar.hasClass(responsive_min_class)) this.mobile_style = 3;//minimized menu else if(this.$sidebar.hasClass('navbar-collapse')) this.mobile_style = 4;//collapsible (bootstrap style) } sidebar_mobile_style.call(self); function update_vars() { this.mobile_view = this.mobile_style < 4 && this.is_mobile_view(); this.collapsible = !this.mobile_view && this.is_collapsible(); this.minimized = (!this.collapsible && this.$sidebar.hasClass(minimized_menu_class)) || (this.mobile_style == 3 && this.mobile_view && this.$sidebar.hasClass(responsive_min_class)) this.horizontal = !(this.mobile_view || this.collapsible) && this.$sidebar.hasClass(horizontal_menu_class) } //update some basic variables $(window).on('resize.sidebar.vars' , function(){ update_vars.call(self); }).triggerHandler('resize.sidebar.vars') this.mobileToggle = function(showMenu) { var showMenu = typeof showMenu === "undefined" ? undefined : showMenu; if(this.mobile_view) { if(this.mobile_style == 1 || this.mobile_style == 2) { this.toggleMobile(null, showMenu); } else if(this.mobile_style == 3) { this.toggleResponsive(null, showMenu); } } else if(this.collapsible) { this.toggleCollapsible(null, showMenu); } } this.mobileShow = function() { this.mobileToggle(true); } this.mobileHide = function() { this.mobileToggle(false); } this.toggleMobile = function(toggle_btn, showMenu) { if(!(this.mobile_style == 1 || this.mobile_style == 2)) return; var showMenu = typeof showMenu !== 'undefined' ? showMenu : !this.$sidebar.hasClass('display'); if(!toggle_btn) { toggle_btn = $('.menu-toggler[data-target="#'+(this.$sidebar.attr('id')||'')+'"]'); if(toggle_btn.length != 0) toggle_btn = toggle_btn[0]; else toggle_btn = null; } if(showMenu) { this.$sidebar.addClass('display'); if(toggle_btn) $(toggle_btn).addClass('display'); } else { this.$sidebar.removeClass('display'); if(toggle_btn) $(toggle_btn).removeClass('display'); } } this.toggleCollapsible = function(toggle_btn, showMenu) { if(this.mobile_style != 4) return; var showMenu = typeof showMenu !== 'undefined' ? showMenu : !this.$sidebar.hasClass('in'); if(showMenu) { this.$sidebar.collapse('show'); } else { this.$sidebar.removeClass('display'); this.$sidebar.collapse('hide'); } } }//end of Sidebar //sidebar events //menu-toggler $(document) .on(ace.click_event+'.ace.menu', '.menu-toggler', function(e){ var btn = $(this); var sidebar = $(btn.attr('data-target')); if(sidebar.length == 0) return; e.preventDefault(); //sidebar.toggleClass('display'); //btn.toggleClass('display'); sidebar.ace_sidebar('toggleMobile', this); var click_event = ace.click_event+'.ace.autohide'; var auto_hide = sidebar.attr('data-auto-hide') === 'true'; if( btn.hasClass('display') ) { //hide menu if clicked outside of it! if(auto_hide) { $(document).on(click_event, function(ev) { if( sidebar.get(0) == ev.target || $.contains(sidebar.get(0), ev.target) ) { ev.stopPropagation(); return; } sidebar.ace_sidebar('toggleMobile', this, false); $(document).off(click_event); }) } if(sidebar.attr('data-sidebar-scroll') == 'true') sidebar.ace_sidebar_scroll('reset'); } else { if(auto_hide) $(document).off(click_event); } return false; }) //sidebar collapse/expand button .on(ace.click_event+'.ace.menu', '.sidebar-collapse', function(e){ var target = $(this).attr('data-target'), $sidebar = null; if(target) $sidebar = $(target); if($sidebar == null || $sidebar.length == 0) $sidebar = $(this).closest('.sidebar'); if($sidebar.length == 0) return; e.preventDefault(); $sidebar.ace_sidebar('toggleMenu', this); }) //this button is used in `mobile_style = 3` responsive menu style to expand minimized sidebar .on(ace.click_event+'.ace.menu', '.sidebar-expand', function(e){ var target = $(this).attr('data-target'), $sidebar = null; if(target) $sidebar = $(target); if($sidebar == null || $sidebar.length == 0) $sidebar = $(this).closest('.sidebar'); if($sidebar.length == 0) return; var btn = this; e.preventDefault(); $sidebar.ace_sidebar('toggleResponsive', this); var click_event = ace.click_event+'.ace.autohide'; if($sidebar.attr('data-auto-hide') === 'true') { if( $sidebar.hasClass(responsive_max_class) ) { $(document).on(click_event, function(ev) { if( $sidebar.get(0) == ev.target || $.contains($sidebar.get(0), ev.target) ) { ev.stopPropagation(); return; } $sidebar.ace_sidebar('toggleResponsive', btn); $(document).off(click_event); }) } else { $(document).off(click_event); } } }) $.fn.ace_sidebar = function (option, value, value2) { var method_call; var $set = this.each(function () { var $this = $(this); var data = $this.data('ace_sidebar'); var options = typeof option === 'object' && option; if (!data) $this.data('ace_sidebar', (data = new Sidebar(this, options))); if (typeof option === 'string' && typeof data[option] === 'function') { if(value instanceof Array) method_call = data[option].apply(data, value); else if(value2 !== undefined) method_call = data[option](value, value2); else method_call = data[option](value); } }); return (method_call === undefined) ? $set : method_call; }; $.fn.ace_sidebar.defaults = { 'duration': 300, 'hide_open_subs': true } })(window.jQuery); ;/** Scrollbars for sidebar. This approach can only be used on fixed sidebar. It doesn't use "overflow:hidden" CSS property and therefore can be used with .hover submenus and minimized sidebar. Except when in mobile view and menu toggle button is not in the navbar. */ (function($ , undefined) { //if( !$.fn.ace_scroll ) return; var old_safari = ace.vars['safari'] && navigator.userAgent.match(/version\/[1-5]/i) //NOTE //Safari on windows has not been updated for a long time. //And it has a problem when sidebar is fixed & scrollable and there is a CSS3 animation inside page content. //Very probably windows users of safari have migrated to another browser by now! var is_element_pos = 'getComputedStyle' in window ? //el.offsetHeight is used to force redraw and recalculate 'el.style.position' esp. for webkit! function(el, pos) { el.offsetHeight; return window.getComputedStyle(el).position == pos } : function(el, pos) { el.offsetHeight; return $(el).css('position') == pos } function Sidebar_Scroll(sidebar , settings) { var self = this; var $window = $(window); var $sidebar = $(sidebar), $nav = $sidebar.find('.nav-list'), $toggle = $sidebar.find('.sidebar-toggle').eq(0), $shortcuts = $sidebar.find('.sidebar-shortcuts').eq(0); var nav = $nav.get(0); if(!nav) return; var attrib_values = ace.helper.getAttrSettings(sidebar, $.fn.ace_sidebar_scroll.defaults); this.settings = $.extend({}, $.fn.ace_sidebar_scroll.defaults, settings, attrib_values); var scroll_to_active = self.settings.scroll_to_active; var ace_sidebar = $sidebar.ace_sidebar('ref'); $sidebar.attr('data-sidebar-scroll', 'true'); var scroll_div = null, scroll_content = null, scroll_content_div = null, bar = null, track = null, ace_scroll = null; this.is_scrolling = false; var _initiated = false; this.sidebar_fixed = is_element_pos(sidebar, 'fixed'); var $avail_height, $content_height; var available_height = function() { //available window space var offset = $nav.parent().offset();//because `$nav.offset()` considers the "scrolled top" amount as well if(self.sidebar_fixed) offset.top -= ace.helper.scrollTop(); return $window.innerHeight() - offset.top - ( self.settings.include_toggle ? 0 : $toggle.outerHeight() ) + 1; } var content_height = function() { return nav.clientHeight;//we don't use nav.scrollHeight here, because hover submenus are considered in calculating scrollHeight despite position=absolute! } var initiate = function(on_page_load) { if( _initiated ) return; if( !self.sidebar_fixed ) return;//eligible?? //return if we want scrollbars only on "fixed" sidebar and sidebar is not "fixed" yet! //initiate once $nav.wrap('