/*! * Ace v1.3.2 */ if (typeof jQuery === 'undefined') { throw new Error('Ace\'s JavaScript requires jQuery') } /** Required. Ace's Basic File to Initiliaze Different Parts and Some 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 document.documentElement);//(('ontouchstart' in document.documentElement) || (window.DocumentTouch && document instanceof DocumentTouch)); //sometimes we try to use 'tap' event instead of 'click' if jquery mobile plugin is available ace['click_event'] = ace.vars['touch'] && $.fn.tap ? 'tap' : 'click'; //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']; })(jQuery); jQuery(function($) { basics(); enableSidebar(); enableAjax(); handleScrollbars(); dropdownAutoPos(); navbarHelpers(); sidebarTooltips(); scrollTopBtn(); someBrowserFix(); bsCollapseToggle(); smallDeviceDropdowns(); //////////////////////////// function basics() { // 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'] = !!$.support.transition.end } function enableSidebar() { //initiate sidebar function var $sidebar = $('.sidebar'); if($.fn.ace_sidebar) $sidebar.ace_sidebar(); if($.fn.ace_sidebar_scroll) $sidebar.ace_sidebar_scroll({ //'scroll_style': 'scroll-dark scroll-thin', 'scroll_to_active': true, //scroll to selected item? (one time only on page load) 'include_shortcuts': true, //true = include shortcut buttons in the scrollbars 'include_toggle': false || ace.vars['safari'] || ace.vars['ios_safari'], //true = include toggle button in the scrollbars '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 'outside': false//true && ace.vars['touch'] //used in first approach only, true means the scrollbars should be outside of the sidebar }); if($.fn.ace_sidebar_hover) $sidebar.ace_sidebar_hover({ 'sub_hover_delay': 750, 'sub_scroll_style': 'no-track scroll-thin scroll-margin scroll-visible' }); } function enableAjax() { //Load content via ajax if($.fn.ace_ajax) { $('[data-ajax-content=true]').ace_ajax({ 'close_active': true, '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/ajax.html#page/gallery to > /ajax/gallery.html and load it if(path.match(/(\/ajax\/)(ajax\.html)?/)) return path.replace(/(\/ajax\/)(ajax\.html)?/, '/ajax/'+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(/\//, "="); }, 'default_url': 'page/index'//default hash }) } } ///////////////////////////// function handleScrollbars() { //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'); }); } } function dropdownAutoPos() { //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'); }); } function navbarHelpers() { //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') } }); } function sidebarTooltips() { //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: '<div class="tooltip '+tooltip_class+'"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>' }); }); //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: '<div class="tooltip tooltip-error"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>' }); */ } function scrollTopBtn() { //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; }); } } function someBrowserFix() { //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']); } } function bsCollapseToggle() { //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 function smallDeviceDropdowns() { if(ace.vars['old_ie']) return; $('.ace-nav > li') .on('shown.bs.dropdown.navbar', function(e) { adjustNavbarDropdown.call(this); }) .on('hidden.bs.dropdown.navbar', 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); } var self = this; $(window) .off('resize.navbar.dropdown') .one('resize.navbar.dropdown', function() { $(self).triggerHandler('shown.bs.dropdown.navbar'); }) } //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', ''); } } }) //some functions ace.helper.redraw = function(elem, force) { 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.boolAttr = function(elem, attr) { return elem.getAttribute(attr) === "true"; } ace.helper.intAttr = function(elem, attr) { return parseInt(elem.getAttribute(attr)) || 0; } ace.helper.scrollTop = function() { return document.scrollTop || document.documentElement.scrollTop || document.body.scrollTop //return $(window).scrollTop(); } ace.helper.winHeight = function() { return window.innerHeight || document.documentElement.clientHeight; //return $(window).innerHeight(); } ace.helper.camelCase = function(str) { return str.replace(/-([\da-z])/gi, function(match, chr) { return chr ? chr.toUpperCase() : ''; }); } ace.helper.removeStyle = 'removeProperty' in document.documentElement.style ? function(elem, prop) { elem.style.removeProperty(prop) } : function(elem, prop) { elem.style[ace.helper.camelCase(prop)] = '' } ace.helper.hasClass = 'classList' in document.documentElement ? function(elem, className) { return elem.classList.contains(className); } : function(elem, className) { return elem.className.indexOf(className) > -1; } ;/** <b>Load content via Ajax </b>. For more information please refer to documentation #basics/ajax */ (function($ , undefined) { var ajax_loaded_scripts = {} function AceAjax(contentArea, options) { var $contentArea = $(contentArea); var self = this; var content_url = options.content_url || false var default_url = options.default_url || false; var loading_icon = options.loading_icon || 'fa-spinner fa-2x orange'; var loading_text = options.loading_text || ''; var update_breadcrumbs = options.update_breadcrumbs || options.update_breadcrumbs === undefined; var update_title = options.update_title || options.update_breadcrumbs === undefined; var update_active = options.update_active || options.update_breadcrumbs === undefined; var close_active = options.close_active || false; var max_load_wait = options.max_load_wait || false; var working = false; this.loadUrl = function(hash) { var url = false; hash = hash.replace(/^(\#\!)?\#/, ''); if(typeof content_url === 'function') url = content_url(hash); if(typeof url === 'string') this.getUrl(url, hash, false); } this.getUrl = function(url, hash, manual_trigger) { if(working) { return; } var event $contentArea.trigger(event = $.Event('ajaxloadstart'), {url: url, hash: hash}) if (event.isDefaultPrevented()) return; self.startLoading(); $.ajax({ 'url': url }) .error(function() { $contentArea.trigger('ajaxloaderror', {url: url, hash: hash}); self.stopLoading(true); }) .done(function(result) { $contentArea.trigger('ajaxloaddone', {url: url, hash: hash}); var link_element = null, link_text = '';; if(typeof update_active === 'function') { link_element = update_active.call(null, hash, url); } else if(update_active === true) { 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') || close_active ) $class += ' open'; $(this).removeClass($class); if(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) $this.ace_sidebar_scroll('scroll_to_active');//first time only }) } } } ///////// if(typeof update_breadcrumbs === 'function') { link_text = update_breadcrumbs.call(null, hash, url, link_element); } else if(update_breadcrumbs === true && link_element != null && link_element.length > 0) { link_text = updateBreadcrumbs(link_element); } ///////// //convert "title" and "link" tags to "div" tags for later processing result = String(result) .replace(/<(title|link)([\s\>])/gi,'<div class="hidden ajax-append-$1"$2') .replace(/<\/(title|link)\>/gi,'</div>') $contentArea.empty().html(result); $contentArea.css('opacity', 0.6); //remove previous stylesheets inserted via ajax 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('<link />', {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 update_title === 'function') { update_title.call(null, hash, url, link_text); } else if(update_title === true) { updateTitle(link_text); } if( !manual_trigger ) { $('html,body').animate({scrollTop: 0}, 250); } ////////////////////// $contentArea.trigger('ajaxloadcomplete', {url: url, hash: hash}); ////////////////////// self.stopLoading(); }) } /////////////////////// var loadTimer = null; this.startLoading = function() { if(working) return; working = true; $contentArea .css('opacity', 0.25) .prevAll('.ajax-loading-overlay').remove(); $('<div class="ajax-loading-overlay"><i class="ajax-loading-icon fa fa-spin '+loading_icon+'"></i> '+loading_text+'</div>').insertBefore(contentArea); if(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); }, max_load_wait * 1000); } this.stopLoading = function(stopNow) { if(stopNow === true) { working = false; $contentArea .css('opacity', 1) .prevAll('.ajax-loading-overlay').remove(); if(loadTimer != null) { clearTimeout(loadTimer); loadTimer = null; } } else { $contentArea.css('opacity', 0.75) $contentArea.one('ajaxscriptsloaded', function() { self.stopLoading(true); }) } } /////////////////////// 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 = $('<li class="active"></li>').appendTo(breadcrumbs); li.text(text); link_text = text; } else { var li = $('<li><a /></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) { $.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; self.loadUrl(hash); }).trigger('hashchange.ace_ajax', [true]); var hash = $.trim(window.location.hash); if(!hash && default_url) window.location.hash = default_url; }//AceAjax $.fn.aceAjax = $.fn.ace_ajax = function (option, value, value2) { 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(value2 != undefined) method_call = data[option](value, value2); else method_call = data[option](value); } }); return (method_call === undefined) ? $set : method_call; } })(window.jQuery); ;/** <b>Custom drag event for touch devices</b> used in scrollbars. For better touch event handling and extra options a more advanced solution such as <u>Hammer.js</u> 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);;/** <b>Sidebar functions</b>. Collapsing/expanding, toggling mobile view menu and other sidebar functions. */ (function($ , undefined) { var sidebar_count = 0; function Sidebar(sidebar, options) { 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) ) var duration = options.duration || ace.helper.intAttr(sidebar, 'data-submenu-duration') ||300;//transition duration //some vars this.minimized = false;//will be initiated later this.collapsible = false;//... this.horizontal = false;//... this.mobile_view = false;// 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; } this.ref = function() { //return a reference to self return this; } var toggleIcon = function(minimized) { 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(minimized !== undefined) { if(minimized) icon.removeClass(icon1).addClass(icon2); else icon.removeClass(icon2).addClass(icon1); } else { icon.toggleClass(icon1).toggleClass(icon2); } } } 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 button this.toggleMenu = function(toggle_btn, save) { if(this.collapsible) return; //var minimized = this.$sidebar.hasClass('menu-min'); this.minimized = !this.minimized; try { //toggle_btn can also be a param to indicate saving to cookie or not?! if toggle_btn === false, it won't be saved ace.settings.sidebar_collapsed(sidebar, this.minimized, !(toggle_btn === false || save === false));//@ ace-extra.js } catch(e) { if(this.minimized) this.$sidebar.addClass('menu-min'); else this.$sidebar.removeClass('menu-min'); } if( !toggle_btn ) { toggle_btn = findToggleBtn(); } if(toggle_btn) { toggleIcon.call(toggle_btn, this.minimized); } //force redraw for ie8 if(ace.vars['old_ie']) ace.helper.redraw(sidebar); } 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); } //collapse/expand in 2nd mobile style this.toggleResponsive = function(toggle_btn) { 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); } this.minimized = !this.$sidebar.hasClass('responsive-min'); this.$sidebar.toggleClass('responsive-min responsive-max'); 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 icon.toggleClass(icon1).toggleClass(icon2); } } $(document).triggerHandler('settings.ace', ['sidebar_collapsed' , this.minimized]); } //some helper functions 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? } this.is_mobile_view = function() { var toggle return ((toggle = $('.menu-toggler[data-target="#'+(this.$sidebar.attr('id')||'')+'"]').get(0)) != null) && toggle.scrollHeight > 0 } //toggling submenu 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 ) {//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, duration, false); } }) } if( sub_hidden ) {//being shown now self.show(sub, 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, 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, wait) { if(wait !== false) { if(submenu_working) return false; submenu_working = true; } $duration = $duration || duration; var $sub = $(sub); var event; $sub.trigger(event = $.Event('show.ace.submenu')) if (event.isDefaultPrevented()) return false; $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 ... if( $duration > 0 ) { $sub.css({height: sub.scrollHeight, 'transition-property': 'height', 'transition-duration': ($duration/1000)+'s'}) } 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(wait !== false) submenu_working = false; } if( $duration > 0 && !!$.support.transition.end ) { $sub.one($.support.transition.end, complete); } else 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, wait) { if(wait !== false) { if(submenu_working) return false; submenu_working = true; } $duration = $duration || duration; var $sub = $(sub); var event; $sub.trigger(event = $.Event('hide.ace.submenu')) if (event.isDefaultPrevented()) return false; $sub.css({ height: sub.scrollHeight, overflow: 'hidden', display: 'block' }) .parent().removeClass('open'); sub.offsetHeight; //forces the "sub" to re-consider the new 'height' before transition if( $duration > 0 ) { $sub.css({'height': 0, 'transition-property': 'height', 'transition-duration': ($duration/1000)+'s'}); } 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(wait !== false) submenu_working = false; } if( $duration > 0 && !!$.support.transition.end ) { $sub.one($.support.transition.end, complete); } else 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 || 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 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') }//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'); 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.removeClass('display'); btn.removeClass('display'); $(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') ) { $(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); } } }) /** .on('shown.bs.collapse.sidebar hidden.bs.collapse.sidebar', '.sidebar[data-auto-hide=true]', function(e){ var click_event = ace.click_event+'.ace.autohide'; var sidebar = this; if(e.type == 'shown') { $(document).on(click_event, function(ev) { if( sidebar == ev.target || $.contains(sidebar, ev.target) ) { ev.stopPropagation(); return; } $(sidebar).collapse('hide'); $(document).off(click_event); }) } else $(document).off(click_event); }); */ $.fn.ace_sidebar = function (option, value) { 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 method_call = data[option](value); } }); return (method_call === undefined) ? $set : method_call; }; })(window.jQuery); ;/** <b>Scrollbars for sidebar</b>. This approach can <span class="text-danger">only</span> be used on <u>fixed</u> sidebar. It doesn't use <u>"overflow:hidden"</u> CSS property and therefore can be used with <u>.hover</u> 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 ace_sidebar = $sidebar.ace_sidebar('ref'); $sidebar.attr('data-sidebar-scroll', 'true'); var nav = $nav.get(0); if(!nav) return; var scroll_div = null, scroll_content = null, scroll_content_div = null, bar = null, track = null, ace_scroll = null; var scroll_to_active = settings.scroll_to_active || ace.helper.boolAttr(sidebar, 'data-scroll-to-active') || false, include_shortcuts = settings.include_shortcuts || ace.helper.boolAttr(sidebar, 'data-scroll-include-shortcuts') || false, include_toggle = settings.include_toggle || ace.helper.boolAttr(sidebar, 'data-scroll-include-toggle') || false, smooth_scroll = settings.smooth_scroll || ace.helper.intAttr(sidebar, 'data-scroll-smooth') || false, scrollbars_outside = settings.outside || ace.helper.boolAttr(sidebar, 'data-scroll-outside') || false, scroll_style = settings.scroll_style || $sidebar.attr('data-scroll-style') || '', only_if_fixed = true; var lockAnyway = settings.mousewheel_lock || ace.helper.boolAttr(sidebar, 'data-mousewheel-lock') || false; 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 - ( include_toggle ? 0 : $toggle.outerHeight() ); } 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('<div class="nav-wrap-up pos-rel" />'); $nav.after('<div><div></div></div>'); $nav.wrap('<div class="nav-wrap" />'); if(!include_toggle) $toggle.css({'z-index': 1}); if(!include_shortcuts) $shortcuts.css({'z-index': 99}); scroll_div = $nav.parent().next() .ace_scroll({ size: available_height(), //reset: true, mouseWheelLock: true, hoverReset: false, dragEvent: true, styleClass: scroll_style, touchDrag: false//disable touch drag event on scrollbars, we'll add a custom one later }) .closest('.ace-scroll').addClass('nav-scroll'); ace_scroll = scroll_div.data('ace_scroll'); scroll_content = scroll_div.find('.scroll-content').eq(0); scroll_content_div = scroll_content.find(' > div').eq(0); track = $(ace_scroll.get_track()); bar = track.find('.scroll-bar').eq(0); if(include_shortcuts && $shortcuts.length != 0) { $nav.parent().prepend($shortcuts).wrapInner('<div />'); $nav = $nav.parent(); } if(include_toggle && $toggle.length != 0) { $nav.append($toggle); $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 } $nav.css({position: 'relative'}); if( scrollbars_outside === true ) scroll_div.addClass('scrollout'); nav = $nav.get(0); nav.style.top = 0; scroll_content.on('scroll.nav', function() { nav.style.top = (-1 * this.scrollTop) + 'px'; }); //mousewheel library available? $nav.on(!!$.event.special.mousewheel ? 'mousewheel.ace_scroll' : 'mousewheel.ace_scroll DOMMouseScroll.ace_scroll', function(event){ if( !self.is_scrolling || !ace_scroll.is_active() ) { return !lockAnyway; } //transfer $nav's mousewheel event to scrollbars return scroll_div.trigger(event); }); $nav.on('mouseenter.ace_scroll', function() { track.addClass('scroll-hover'); }).on('mouseleave.ace_scroll', function() { track.removeClass('scroll-hover'); }); /** $(document.body).on('touchmove.nav', function(event) { if( self.is_scrolling && $.contains(sidebar, event.target) ) { event.preventDefault(); return false; } }) */ //you can also use swipe event in a similar way //swipe.nav var content = scroll_content.get(0); $nav.on('ace_drag.nav', function(event) { if( !self.is_scrolling || !ace_scroll.is_active() ) { event.retval.cancel = true; return; } //if submenu hover is being scrolled let's cancel sidebar scroll! if( $(event.target).closest('.can-scroll').length != 0 ) { event.retval.cancel = true; return; } if(event.direction == 'up' || event.direction == 'down') { ace_scroll.move_bar(true); var distance = event.dy; distance = parseInt(Math.min($avail_height, distance)) if(Math.abs(distance) > 2) distance = distance * 2; if(distance != 0) { content.scrollTop = content.scrollTop + distance; nav.style.top = (-1 * content.scrollTop) + 'px'; } } }); //for drag only if(smooth_scroll) { $nav .on('touchstart.nav MSPointerDown.nav pointerdown.nav', function(event) { $nav.css('transition-property', 'none'); bar.css('transition-property', 'none'); }) .on('touchend.nav touchcancel.nav MSPointerUp.nav MSPointerCancel.nav pointerup.nav pointercancel.nav', function(event) { $nav.css('transition-property', 'top'); bar.css('transition-property', 'top'); }); } if(old_safari && !include_toggle) { var toggle = $toggle.get(0); if(toggle) scroll_content.on('scroll.safari', function() { ace.helper.redraw(toggle); }); } _initiated = true; //if the active item is not visible, scroll down so that it becomes visible //only the first time, on page load if(on_page_load == true) { self.reset();//try resetting at first if( scroll_to_active ) { self.scroll_to_active(); } scroll_to_active = false; } if( typeof smooth_scroll === 'number' && smooth_scroll > 0) { $nav.css({'transition-property': 'top', 'transition-duration': (smooth_scroll / 1000).toFixed(2)+'s'}) bar.css({'transition-property': 'top', 'transition-duration': (smooth_scroll / 1500).toFixed(2)+'s'}) scroll_div .on('drag.start', function(e) { e.stopPropagation(); $nav.css('transition-property', 'none') }) .on('drag.end', function(e) { e.stopPropagation(); $nav.css('transition-property', 'top') }); } if(ace.vars['android']) { //force hide address bar, because its changes don't trigger window resize and become kinda ugly var val = ace.helper.scrollTop(); if(val < 2) { window.scrollTo( val, 0 ); setTimeout( function() { self.reset(); }, 20 ); } var last_height = ace.helper.winHeight() , new_height; $(window).on('scroll.ace_scroll', function() { if(self.is_scrolling && ace_scroll.is_active()) { new_height = ace.helper.winHeight(); if(new_height != last_height) { last_height = new_height; self.reset(); } } }); } } this.scroll_to_active = function() { if( !ace_scroll || !ace_scroll.is_active() ) return; try { //sometimes there's no active item or not 'offsetTop' property var $active; var vars = ace_sidebar['vars']() var nav_list = $sidebar.find('.nav-list') if(vars['minimized'] && !vars['collapsible']) { $active = nav_list.find('> .active') } else { $active = $nav.find('> .active.hover') if($active.length == 0) $active = $nav.find('.active:not(.open)') } var top = $active.outerHeight(); nav_list = nav_list.get(0); var active = $active.get(0); while(active != nav_list) { top += active.offsetTop; active = active.parentNode; } var scroll_amount = top - scroll_div.height(); if(scroll_amount > 0) { nav.style.top = -scroll_amount + 'px'; scroll_content.scrollTop(scroll_amount); } }catch(e){} } this.reset = function(recalc) { if(recalc === true) { this.sidebar_fixed = is_element_pos(sidebar, 'fixed'); } if( !this.sidebar_fixed ) { this.disable(); return;//eligible?? } //return if we want scrollbars only on "fixed" sidebar and sidebar is not "fixed" yet! if( !_initiated ) initiate(); //initiate scrollbars if not yet var vars = ace_sidebar['vars'](); //enable if: //menu is not collapsible mode (responsive navbar-collapse mode which has default browser scrollbar) //menu is not horizontal or horizontal but mobile view (which is not navbar-collapse) //and available height is less than nav's height var enable_scroll = !vars['collapsible'] && !vars['horizontal'] && ($avail_height = available_height()) < ($content_height = nav.clientHeight); //we don't use nav.scrollHeight here, because hover submenus are considered in calculating scrollHeight despite position=absolute! this.is_scrolling = true; if( enable_scroll ) { scroll_content_div.css({height: $content_height, width: 8}); scroll_div.prev().css({'max-height' : $avail_height}) ace_scroll.update({size: $avail_height}) ace_scroll.enable(); ace_scroll.reset(); } if( !enable_scroll || !ace_scroll.is_active() ) { if(this.is_scrolling) this.disable(); } else { $sidebar.addClass('sidebar-scroll'); } //return this.is_scrolling; } this.disable = function() { this.is_scrolling = false; if(scroll_div) { scroll_div.css({'height' : '', 'max-height' : ''}); scroll_content_div.css({height: '', width: ''});//otherwise it will have height and takes up some space even when invisible scroll_div.prev().css({'max-height' : ''}) ace_scroll.disable(); } if(parseInt(nav.style.top) < 0 && smooth_scroll && $.support.transition.end) { $nav.one($.support.transition.end, function() { $sidebar.removeClass('sidebar-scroll'); $nav.off('.trans'); }); } else { $sidebar.removeClass('sidebar-scroll'); } nav.style.top = 0; } this.prehide = function(height_change) { if(!this.is_scrolling || ace_sidebar.get('minimized')) return;//when minimized submenu's toggle should have no effect if(content_height() + height_change < available_height()) { this.disable(); } else if(height_change < 0) { //if content height is decreasing //let's move nav down while a submenu is being hidden var scroll_top = scroll_content.scrollTop() + height_change if(scroll_top < 0) return; nav.style.top = (-1 * scroll_top) + 'px'; } } this._reset = function(recalc) { if(recalc === true) { this.sidebar_fixed = is_element_pos(sidebar, 'fixed'); } if(ace.vars['webkit']) setTimeout(function() { self.reset() } , 0); else this.reset(); } this.set_hover = function() { if(track) track.addClass('scroll-hover'); } this.get = function(name) { if(this.hasOwnProperty(name)) return this[name]; } this.set = function(name, value) { if(this.hasOwnProperty(name)) this[name] = value; } this.ref = function() { //return a reference to self return this; } this.updateStyle = function(styleClass) { if(ace_scroll == null) return; ace_scroll.update({styleClass: styleClass}); } //change scrollbar size after a submenu is hidden/shown //but don't change if sidebar is minimized $sidebar.on('hidden.ace.submenu.sidebar_scroll shown.ace.submenu.sidebar_scroll', '.submenu', function(e) { e.stopPropagation(); if( !ace_sidebar.get('minimized') ) { //webkit has a little bit of a glitch!!! self._reset(); if( e.type == 'shown' ) self.set_hover(); } }); initiate(true);//true = on_page_load } //reset on document and window changes $(document).on('settings.ace.sidebar_scroll', function(ev, event_name, event_val){ $('.sidebar[data-sidebar-scroll=true]').each(function() { var $this = $(this); var sidebar_scroll = $this.ace_sidebar_scroll('ref'); if( event_name == 'sidebar_collapsed' && is_element_pos(this, 'fixed') ) { if( $this.attr('data-sidebar-hover') == 'true' ) $this.ace_sidebar_hover('reset'); sidebar_scroll._reset(); } else if( event_name === 'sidebar_fixed' || event_name === 'navbar_fixed' ) { var is_scrolling = sidebar_scroll.get('is_scrolling'); var sidebar_fixed = is_element_pos(this, 'fixed') sidebar_scroll.set('sidebar_fixed', sidebar_fixed); if(sidebar_fixed && !is_scrolling) { sidebar_scroll._reset(); } else if( !sidebar_fixed ) { sidebar_scroll.disable(); } } }); }); $(window).on('resize.ace.sidebar_scroll', function(){ $('.sidebar[data-sidebar-scroll=true]').each(function() { var $this = $(this); if( $this.attr('data-sidebar-hover') == 'true' ) $this.ace_sidebar_hover('reset'); ///////////// var sidebar_scroll = $(this).ace_sidebar_scroll('ref'); var sidebar_fixed = is_element_pos(this, 'fixed') sidebar_scroll.set('sidebar_fixed', sidebar_fixed); sidebar_scroll._reset(); }); }) ///////////////////////////////////////////// if(!$.fn.ace_sidebar_scroll) $.fn.ace_sidebar_scroll = function (option, value) { var method_call; var $set = this.each(function () { var $this = $(this); var data = $this.data('ace_sidebar_scroll'); var options = typeof option === 'object' && option; if (!data) $this.data('ace_sidebar_scroll', (data = new Sidebar_Scroll(this, options))); if (typeof option === 'string' && typeof data[option] === 'function') { method_call = data[option](value); } }); return (method_call === undefined) ? $set : method_call; }; })(window.jQuery);;/** <b>Submenu hover adjustment</b>. Automatically move up a submenu to fit into screen when some part of it goes beneath window. Pass a "true" value as an argument and submenu will have native browser scrollbars when necessary. */ (function($ , undefined) { if( ace.vars['very_old_ie'] ) return; //ignore IE7 & below var hasTouch = ace.vars['touch']; var nativeScroll = ace.vars['old_ie'] || hasTouch; 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 } $(window).on('resize.sidebar.ace_hover', function() { $('.sidebar[data-sidebar-hover=true]').ace_sidebar_hover('update_vars').ace_sidebar_hover('reset'); }) $(document).on('settings.ace.ace_hover', function(e, event_name, event_val) { if(event_name == 'sidebar_collapsed') $('.sidebar[data-sidebar-hover=true]').ace_sidebar_hover('reset'); else if(event_name == 'navbar_fixed') $('.sidebar[data-sidebar-hover=true]').ace_sidebar_hover('update_vars'); }) var sidebars = []; function Sidebar_Hover(sidebar , settings) { var self = this; var $sidebar = $(sidebar), nav_list = $sidebar.find('.nav-list').get(0); $sidebar.attr('data-sidebar-hover', 'true'); sidebars.push($sidebar); var sidebar_vars = {}; var old_ie = ace.vars['old_ie']; var hover_delay = settings.sub_hover_delay || ace.helper.intAttr(sidebar, 'data-sub-hover-delay') || 750; var scroll_style = settings.sub_scroll_style || $sidebar.attr('data-sub-scroll-style') || 'no-track scroll-thin'; var scroll_right = false; //scroll style class if(hasTouch) hover_delay = parseInt(Math.max(hover_delay, 2500));//for touch device, delay is at least 2.5sec var $window = $(window); //navbar used for adding extra offset from top when adjusting submenu var $navbar = $('.navbar').eq(0); var navbar_fixed = $navbar.css('position') == 'fixed'; this.update_vars = function() { navbar_fixed = $navbar.css('position') == 'fixed'; } self.dirty = false; //on window resize or sidebar expand/collapse a previously "pulled up" submenu should be reset back to its default position //for example if "pulled up" in "responsive-min" mode, in "fullmode" should not remain "pulled up" this.reset = function() { if( self.dirty == false ) return; self.dirty = false;//so don't reset is not called multiple times in a row! $sidebar.find('.submenu').each(function() { var $sub = $(this), li = $sub.parent(); $sub.css({'top': '', 'bottom': '', 'max-height': ''}); if($sub.hasClass('ace-scroll')) { $sub.ace_scroll('disable'); } else { $sub.removeClass('sub-scroll'); } if( is_element_pos(this, 'absolute') ) $sub.addClass('can-scroll'); else $sub.removeClass('can-scroll'); li.removeClass('pull_up').find('.menu-text:first').css('margin-top', ''); }) $sidebar.find('.hover-show').removeClass('hover-show hover-shown hover-flip'); } this.updateStyle = function(newStyle) { scroll_style = newStyle; $sidebar.find('.submenu.ace-scroll').ace_scroll('update', {styleClass: newStyle}); } this.changeDir = function(dir) { scroll_right = (dir === 'right'); } //update submenu scrollbars on submenu hide & show var lastScrollHeight = -1; //hide scrollbars if it's going to be not needed anymore! if(!nativeScroll) $sidebar.on('hide.ace.submenu.sidebar_hover', '.submenu', function(e) { if(lastScrollHeight < 1) return; e.stopPropagation(); var $sub = $(this).closest('.ace-scroll.can-scroll'); if($sub.length == 0 || !is_element_pos($sub[0], 'absolute')) return; if($sub[0].scrollHeight - this.scrollHeight < lastScrollHeight) { $sub.ace_scroll('disable'); } }); //reset scrollbars if(!nativeScroll) $sidebar.on('shown.ace.submenu.sidebar_hover hidden.ace.submenu.sidebar_hover', '.submenu', function(e) { if(lastScrollHeight < 1) return; var $sub = $(this).closest('.ace-scroll.can-scroll'); if($sub.length == 0 || !is_element_pos($sub[0], 'absolute') ) return; var sub_h = $sub[0].scrollHeight; if(lastScrollHeight > 14 && sub_h - lastScrollHeight > 4) { $sub.ace_scroll('enable').ace_scroll('reset');//don't update track position } else { $sub.ace_scroll('disable'); } }); /////////////////////// var currentScroll = -1; //some mobile browsers don't have mouseenter var event_1 = !hasTouch ? 'mouseenter.sub_hover' : 'touchstart.sub_hover';// pointerdown.sub_hover'; var event_2 = !hasTouch ? 'mouseleave.sub_hover' : 'touchend.sub_hover touchcancel.sub_hover';// pointerup.sub_hover pointercancel.sub_hover'; $sidebar.on(event_1, '.nav-list li, .sidebar-shortcuts', function (e) { sidebar_vars = $sidebar.ace_sidebar('vars'); //ignore if collapsible mode (mobile view .navbar-collapse) so it doesn't trigger submenu movements //or return if horizontal but not mobile_view (style 1&3) if( sidebar_vars['collapsible'] /**|| sidebar_vars['horizontal']*/ ) return; var $this = $(this); var shortcuts = false; var has_hover = $this.hasClass('hover'); var sub = $this.find('> .submenu').get(0); if( !(sub || ((this.parentNode == nav_list || has_hover || (shortcuts = $this.hasClass('sidebar-shortcuts'))) /**&& sidebar_vars['minimized']*/)) ) { if(sub) $(sub).removeClass('can-scroll'); return;//include .compact and .hover state as well? } var target_element = sub, is_abs = false; if( !target_element && this.parentNode == nav_list ) target_element = $this.find('> a > .menu-text').get(0); if( !target_element && shortcuts ) target_element = $this.find('.sidebar-shortcuts-large').get(0); if( (!target_element || !(is_abs = is_element_pos(target_element, 'absolute'))) && !has_hover ) { if(sub) $(sub).removeClass('can-scroll'); return; } var sub_hide = getSubHide(this); //var show_sub = false; if(sub) { if(is_abs) { self.dirty = true; var newScroll = ace.helper.scrollTop(); //if submenu is becoming visible for first time or document has been scrolled, then adjust menu if( !sub_hide.is_visible() || (!hasTouch && newScroll != currentScroll) || old_ie ) { //try to move/adjust submenu if the parent is a li.hover or if submenu is minimized //if( is_element_pos(sub, 'absolute') ) {//for example in small device .hover > .submenu may not be absolute anymore! $(sub).addClass('can-scroll'); //show_sub = true; if(!old_ie && !hasTouch) adjust_submenu.call(this, sub); else { //because ie8 needs some time for submenu to be displayed and real value of sub.scrollHeight be kicked in var that = this; setTimeout(function() { adjust_submenu.call(that, sub) }, 0) } //} //else $(sub).removeClass('can-scroll'); } currentScroll = newScroll; } else { $(sub).removeClass('can-scroll'); } } //if(show_sub) sub_hide.show(); }).on(event_2, '.nav-list li, .sidebar-shortcuts', function (e) { sidebar_vars = $sidebar.ace_sidebar('vars'); if( sidebar_vars['collapsible'] /**|| sidebar_vars['horizontal']*/ ) return; if( !$(this).hasClass('hover-show') ) return; getSubHide(this).hideDelay(); }); function subHide(li_sub) { var self = li_sub, $self = $(self); var timer = null; var visible = false; this.show = function() { if(timer != null) clearTimeout(timer); timer = null; $self.addClass('hover-show hover-shown'); visible = true; //let's hide .hover-show elements that are not .hover-shown anymore (i.e. marked for hiding in hideDelay) for(var i = 0; i < sidebars.length ; i++) { sidebars[i].find('.hover-show').not('.hover-shown').each(function() { getSubHide(this).hide(); }) } } this.hide = function() { visible = false; $self.removeClass('hover-show hover-shown hover-flip'); if(timer != null) clearTimeout(timer); timer = null; var sub = $self.find('> .submenu').get(0); if(sub) getSubScroll(sub, 'hide'); } this.hideDelay = function(callback) { if(timer != null) clearTimeout(timer); $self.removeClass('hover-shown');//somehow marked for hiding timer = setTimeout(function() { visible = false; $self.removeClass('hover-show hover-flip'); timer = null; var sub = $self.find('> .submenu').get(0); if(sub) getSubScroll(sub, 'hide'); if(typeof callback === 'function') callback.call(this); }, hover_delay); } this.is_visible = function() { return visible; } } function getSubHide(el) { var sub_hide = $(el).data('subHide'); if(!sub_hide) $(el).data('subHide', (sub_hide = new subHide(el))); return sub_hide; } function getSubScroll(el, func) { var sub_scroll = $(el).data('ace_scroll'); if(!sub_scroll) return false; if(typeof func === 'string') { sub_scroll[func](); return true; } return sub_scroll; } function adjust_submenu(sub) { var $li = $(this); var $sub = $(sub); sub.style.top = ''; sub.style.bottom = ''; var menu_text = null if( sidebar_vars['minimized'] && (menu_text = $li.find('.menu-text').get(0)) ) { //2nd level items don't have .menu-text menu_text.style.marginTop = ''; } var scroll = ace.helper.scrollTop(); var navbar_height = 0; var $scroll = scroll; if( navbar_fixed ) { navbar_height = sidebar.offsetTop;//$navbar.height(); $scroll += navbar_height + 1; //let's avoid our submenu from going below navbar //because of chrome z-index stacking issue and firefox's normal .submenu over fixed .navbar flicker issue } var off = $li.offset(); off.top = parseInt(off.top); var extra = 0, parent_height; sub.style.maxHeight = '';//otherwise scrollHeight won't be consistent in consecutive calls!? var sub_h = sub.scrollHeight; var parent_height = $li.height(); if(menu_text) { extra = parent_height; off.top += extra; } var sub_bottom = parseInt(off.top + sub_h) var move_up = 0; var winh = $window.height(); //if the bottom of menu is going to go below visible window var top_space = parseInt(off.top - $scroll - extra);//available space on top var win_space = winh;//available window space var horizontal = sidebar_vars['horizontal'], horizontal_sub = false; if(horizontal && this.parentNode == nav_list) { move_up = 0;//don't move up first level submenu in horizontal mode off.top += $li.height(); horizontal_sub = true;//first level submenu } if(!horizontal_sub && (move_up = (sub_bottom - (winh + scroll))) >= 0 ) { //don't move up more than available space move_up = move_up < top_space ? move_up : top_space; //move it up a bit more if there's empty space if(move_up == 0) move_up = 20; if(top_space - move_up > 10) { move_up += parseInt(Math.min(25, top_space - move_up)); } //move it down if submenu's bottom is going above parent LI if(off.top + (parent_height - extra) > (sub_bottom - move_up)) { move_up -= (off.top + (parent_height - extra) - (sub_bottom - move_up)); } if(move_up > 0) { sub.style.top = -(move_up) + 'px'; if( menu_text ) { menu_text.style.marginTop = -(move_up) + 'px'; } } } if(move_up < 0) move_up = 0;//when it goes below var pull_up = move_up > 0 && move_up > parent_height - 20; if(pull_up) { $li.addClass('pull_up'); } else $li.removeClass('pull_up'); //flip submenu if out of window width if(horizontal) { if($li.parent().parent().hasClass('hover-flip')) $li.addClass('hover-flip');//if a parent is already flipped, flip it then! else { var sub_off = $sub.offset(); var sub_w = $sub.width(); var win_w = $window.width(); if(sub_off.left + sub_w > win_w) { $li.addClass('hover-flip'); } } } //don't add scrollbars if it contains .hover menus var has_hover = $li.hasClass('hover') && !sidebar_vars['mobile_view']; if(has_hover && $sub.find('> li > .submenu').length > 0) return; //if( ) { var scroll_height = (win_space - (off.top - scroll)) + (move_up); //if after scroll, the submenu is above parent LI, then move it down var tmp = move_up - scroll_height; if(tmp > 0 && tmp < parent_height) scroll_height += parseInt(Math.max(parent_height, parent_height - tmp)); scroll_height -= 5; if(scroll_height < 90) { return; } var ace_scroll = false; if(!nativeScroll) { ace_scroll = getSubScroll(sub); if(ace_scroll == false) { $sub.ace_scroll({ //hideOnIdle: true, observeContent: true, detached: true, updatePos: false, reset: true, mouseWheelLock: true, styleClass: scroll_style }); ace_scroll = getSubScroll(sub); var track = ace_scroll.get_track(); if(track) { //detach it from body and insert it after submenu for better and cosistent positioning $sub.after(track); } } ace_scroll.update({size: scroll_height}); } else { $sub .addClass('sub-scroll') .css('max-height', (scroll_height)+'px') } lastScrollHeight = scroll_height; if(!nativeScroll && ace_scroll) { if(scroll_height > 14 && sub_h - scroll_height > 4) { ace_scroll.enable() ace_scroll.reset(); } else { ace_scroll.disable(); } ////////////////////////////////// var track = ace_scroll.get_track(); if(track) { track.style.top = -(move_up - extra - 1) + 'px'; var off = $sub.position(); var left = off.left if( !scroll_right ) { left += ($sub.outerWidth() - ace_scroll.track_size()); } else { left += 2; } track.style.left = parseInt(left) + 'px'; if(horizontal_sub) {//first level submenu track.style.left = parseInt(left - 2) + 'px'; track.style.top = parseInt(off.top) + (menu_text ? extra - 2 : 0) + 'px'; } } } //} //again force redraw for safari! if( ace.vars['safari'] ) { ace.helper.redraw(sub) } } } ///////////////////////////////////////////// $.fn.ace_sidebar_hover = function (option, value) { var method_call; var $set = this.each(function () { var $this = $(this); var data = $this.data('ace_sidebar_hover'); var options = typeof option === 'object' && option; if (!data) $this.data('ace_sidebar_hover', (data = new Sidebar_Hover(this, options))); if (typeof option === 'string' && typeof data[option] === 'function') { method_call = data[option](value); } }); return (method_call === undefined) ? $set : method_call; }; })(window.jQuery); ;/** <b>Widget boxes</b> */ (function($ , undefined) { var Widget_Box = function(box, options) { this.$box = $(box); var that = this; //this.options = $.extend({}, $.fn.widget_box.defaults, options); this.reload = function() { var $box = this.$box; var $remove_position = false; if($box.css('position') == 'static') { $remove_position = true; $box.addClass('position-relative'); } $box.append('<div class="widget-box-overlay"><i class="'+ ace.vars['icon'] + 'loading-icon fa fa-spinner fa-spin fa-2x white"></i></div>'); $box.one('reloaded.ace.widget', function() { $box.find('.widget-box-overlay').remove(); if($remove_position) $box.removeClass('position-relative'); }); } this.close = function() { var $box = this.$box; var closeSpeed = 300; $box.fadeOut(closeSpeed , function(){ $box.trigger('closed.ace.widget'); $box.remove(); } ) } this.toggle = function(type, button) { var $box = this.$box; var $body = $box.find('.widget-body'); var $icon = null; var event_name = typeof type !== 'undefined' ? type : ($box.hasClass('collapsed') ? 'show' : 'hide'); var event_complete_name = event_name == 'show' ? 'shown' : 'hidden'; if(typeof button === 'undefined') { button = $box.find('> .widget-header a[data-action=collapse]').eq(0); if(button.length == 0) button = null; } if(button) { $icon = button.find(ace.vars['.icon']).eq(0); 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' } } var expandSpeed = 250; var collapseSpeed = 200; if( event_name == 'show' ) { if($icon) $icon.removeClass($icon_down).addClass($icon_up); $body.hide(); $box.removeClass('collapsed'); $body.slideDown(expandSpeed, function(){ $box.trigger(event_complete_name+'.ace.widget') }) } else { if($icon) $icon.removeClass($icon_up).addClass($icon_down); $body.slideUp(collapseSpeed, function(){ $box.addClass('collapsed') $box.trigger(event_complete_name+'.ace.widget') } ); } } this.hide = function() { this.toggle('hide'); } this.show = function() { this.toggle('show'); } this.fullscreen = function() { var $icon = this.$box.find('> .widget-header a[data-action=fullscreen]').find(ace.vars['.icon']).eq(0); var $icon_expand = null var $icon_compress = null if( ($icon_expand = $icon.attr('data-icon1')) ) { $icon_compress = $icon.attr('data-icon2') } else { $icon_expand = 'fa-expand'; $icon_compress = 'fa-compress'; } if(!this.$box.hasClass('fullscreen')) { $icon.removeClass($icon_expand).addClass($icon_compress); this.$box.addClass('fullscreen'); applyScrollbars(this.$box, true); } else { $icon.addClass($icon_expand).removeClass($icon_compress); this.$box.removeClass('fullscreen'); applyScrollbars(this.$box, false); } this.$box.trigger('fullscreened.ace.widget') } } $.fn.widget_box = function (option, value) { var method_call; var $set = this.each(function () { var $this = $(this); var data = $this.data('widget_box'); var options = typeof option === 'object' && option; if (!data) $this.data('widget_box', (data = new Widget_Box(this, options))); if (typeof option === 'string') method_call = data[option](value); }); return (method_call === undefined) ? $set : method_call; }; $(document).on('click.ace.widget', '.widget-header a[data-action]', function (ev) { ev.preventDefault(); var $this = $(this); var $box = $this.closest('.widget-box'); if( $box.length == 0 || $box.hasClass('ui-sortable-helper') ) return; var $widget_box = $box.data('widget_box'); if (!$widget_box) { $box.data('widget_box', ($widget_box = new Widget_Box($box.get(0)))); } var $action = $this.data('action'); if($action == 'collapse') { var event_name = $box.hasClass('collapsed') ? 'show' : 'hide'; var event $box.trigger(event = $.Event(event_name+'.ace.widget')) if (event.isDefaultPrevented()) return $widget_box.toggle(event_name, $this); } else if($action == 'close') { var event $box.trigger(event = $.Event('close.ace.widget')) if (event.isDefaultPrevented()) return $widget_box.close(); } else if($action == 'reload') { $this.blur(); var event $box.trigger(event = $.Event('reload.ace.widget')) if (event.isDefaultPrevented()) return $widget_box.reload(); } else if($action == 'fullscreen') { var event $box.trigger(event = $.Event('fullscreen.ace.widget')) if (event.isDefaultPrevented()) return $widget_box.fullscreen(); } else if($action == 'settings') { $box.trigger('setting.ace.widget') } }); function applyScrollbars($widget, enable) { var $main = $widget.find('.widget-main'); $(window).off('resize.widget.scroll'); //IE8 has an unresolvable issue!!! re-scrollbaring with unknown values?! var nativeScrollbars = ace.vars['old_ie'] || ace.vars['touch']; if(enable) { var ace_scroll = $main.data('ace_scroll'); if( ace_scroll ) { $main.data('save_scroll', {size: ace_scroll['size'], lock: ace_scroll['lock'], lock_anyway: ace_scroll['lock_anyway']}); } var size = $widget.height() - $widget.find('.widget-header').height() - 10;//extra paddings size = parseInt(size); $main.css('min-height', size); if( !nativeScrollbars ) { if( ace_scroll ) { $main.ace_scroll('update', {'size': size, 'mouseWheelLock': true, 'lockAnyway': true}); } else { $main.ace_scroll({'size': size, 'mouseWheelLock': true, 'lockAnyway': true}); } $main.ace_scroll('enable').ace_scroll('reset'); } else { if( ace_scroll ) $main.ace_scroll('disable'); $main.css('max-height', size).addClass('overflow-scroll'); } $(window) .on('resize.widget.scroll', function() { var size = $widget.height() - $widget.find('.widget-header').height() - 10;//extra paddings size = parseInt(size); $main.css('min-height', size); if( !nativeScrollbars ) { $main.ace_scroll('update', {'size': size}).ace_scroll('reset'); } else { $main.css('max-height', size).addClass('overflow-scroll'); } }); } else { $main.css('min-height', ''); var saved_scroll = $main.data('save_scroll'); if(saved_scroll) { $main .ace_scroll('update', {'size': saved_scroll['size'], 'mouseWheelLock': saved_scroll['lock'], 'lockAnyway': saved_scroll['lock_anyway']}) .ace_scroll('enable') .ace_scroll('reset'); } if( !nativeScrollbars ) { if(!saved_scroll) $main.ace_scroll('disable'); } else { $main.css('max-height', '').removeClass('overflow-scroll'); } } } })(window.jQuery);;/** <b>Settings box</b>. It's good for demo only. You don't need this. */ (function($ , undefined) { $('#ace-settings-btn').on(ace.click_event, function(e){ e.preventDefault(); $(this).toggleClass('open'); $('#ace-settings-box').toggleClass('open'); }) $('#ace-settings-navbar').on('click', function(){ ace.settings.navbar_fixed(null, this.checked);//@ ace-extra.js //$(window).triggerHandler('resize.navbar'); //force redraw? //if(ace.vars['webkit']) ace.helper.redraw(document.body); }).each(function(){this.checked = ace.settings.is('navbar', 'fixed')}) $('#ace-settings-sidebar').on('click', function(){ ace.settings.sidebar_fixed(null, this.checked);//@ ace-extra.js //if(ace.vars['webkit']) ace.helper.redraw(document.body); }).each(function(){this.checked = ace.settings.is('sidebar', 'fixed')}) $('#ace-settings-breadcrumbs').on('click', function(){ ace.settings.breadcrumbs_fixed(null, this.checked);//@ ace-extra.js //if(ace.vars['webkit']) ace.helper.redraw(document.body); }).each(function(){this.checked = ace.settings.is('breadcrumbs', 'fixed')}) $('#ace-settings-add-container').on('click', function(){ ace.settings.main_container_fixed(null, this.checked);//@ ace-extra.js //if(ace.vars['webkit']) ace.helper.redraw(document.body); }).each(function(){this.checked = ace.settings.is('main-container', 'fixed')}) $('#ace-settings-compact').on('click', function(){ if(this.checked) { $('#sidebar').addClass('compact'); var hover = $('#ace-settings-hover'); if( hover.length > 0 ) { hover.removeAttr('checked').trigger('click'); } } else { $('#sidebar').removeClass('compact'); $('#sidebar[data-sidebar-scroll=true]').ace_sidebar_scroll('reset') } if(ace.vars['old_ie']) ace.helper.redraw($('#sidebar')[0], true); })/*.removeAttr('checked')*/ $('#ace-settings-highlight').on('click', function(){ if(this.checked) $('#sidebar .nav-list > li').addClass('highlight'); else $('#sidebar .nav-list > li').removeClass('highlight'); if(ace.vars['old_ie']) ace.helper.redraw($('#sidebar')[0]); })/*.removeAttr('checked')*/ $('#ace-settings-hover').on('click', function(){ if($('#sidebar').hasClass('h-sidebar')) return; if(this.checked) { $('#sidebar li').addClass('hover') .filter('.open').removeClass('open').find('> .submenu').css('display', 'none'); //and remove .open items } else { $('#sidebar li.hover').removeClass('hover'); var compact = $('#ace-settings-compact'); if( compact.length > 0 && compact.get(0).checked ) { compact.trigger('click'); } } $('.sidebar[data-sidebar-hover=true]').ace_sidebar_hover('reset') $('.sidebar[data-sidebar-scroll=true]').ace_sidebar_scroll('reset') if(ace.vars['old_ie']) ace.helper.redraw($('#sidebar')[0]); })/*.removeAttr('checked')*/ })(jQuery);;/** <b>RTL</b> (right-to-left direction for Arabic, Hebrew, Persian languages). It's good for demo only. You should hard code RTL-specific changes inside your HTML/server-side code. Dynamically switching to RTL using Javascript is not a good idea. Please refer to documentation for more info. */ (function($ , undefined) { //Switching to RTL (right to left) Mode $('#ace-settings-rtl').removeAttr('checked').on('click', function(){ switch_direction(); }); //>>> you should hard code changes inside HTML for RTL direction //you shouldn't use this function to switch direction //this is only for dynamically switching for demonstration //take a look at this function to see what changes should be made //also take a look at docs for some tips var switch_direction = function() { if($('#ace-rtl-stylesheet').length == 0) { //let's load RTL stylesheet only when needed! var ace_style = $('head').find('link.ace-main-stylesheet'); if(ace_style.length == 0) { ace_style = $('head').find('link[href*="/ace.min.css"],link[href*="/ace-part2.min.css"]'); if(ace_style.length == 0) { ace_style = $('head').find('link[href*="/ace.css"],link[href*="/ace-part2.css"]'); } } var ace_skins = $('head').find('link#ace-skins-stylesheet'); var stylesheet_url = ace_style.first().attr('href').replace(/(\.min)?\.css$/i , '-rtl$1.css'); $.ajax({ 'url': stylesheet_url }).done(function() { var new_link = jQuery('<link />', {type : 'text/css', rel: 'stylesheet', 'id': 'ace-rtl-stylesheet'}) if(ace_skins.length > 0) { new_link.insertAfter(ace_skins); } else if(ace_style.length > 0){ new_link.insertAfter(ace_style.last()); } else new_link.appendTo('head'); new_link.attr('href', stylesheet_url); //we set "href" after insertion, for IE to work applyChanges(); }) } else { applyChanges(); } ///////////////////////// function applyChanges() { var $body = $(document.body); $body .toggleClass('rtl') //toggle pull-right class on dropdown-menu .find('.dropdown-menu:not(.datepicker-dropdown,.colorpicker)').toggleClass('dropdown-menu-right') .end() //swap pull-left & pull-right .find('.pull-right:not(.dropdown-menu,blockquote,.profile-skills .pull-right)').removeClass('pull-right').addClass('tmp-rtl-pull-right') .end() .find('.pull-left:not(.dropdown-submenu,.profile-skills .pull-left)').removeClass('pull-left').addClass('pull-right') .end() .find('.tmp-rtl-pull-right').removeClass('tmp-rtl-pull-right').addClass('pull-left') .end() .find('.chosen-select').toggleClass('chosen-rtl').next().toggleClass('chosen-rtl'); function swap_classes(class1, class2) { $body .find('.'+class1).removeClass(class1).addClass('tmp-rtl-'+class1) .end() .find('.'+class2).removeClass(class2).addClass(class1) .end() .find('.tmp-rtl-'+class1).removeClass('tmp-rtl-'+class1).addClass(class2) } swap_classes('align-left', 'align-right'); swap_classes('no-padding-left', 'no-padding-right'); swap_classes('arrowed', 'arrowed-right'); swap_classes('arrowed-in', 'arrowed-in-right'); swap_classes('tabs-left', 'tabs-right'); swap_classes('messagebar-item-left', 'messagebar-item-right');//for inbox page $('.modal.aside-vc').ace_aside('flip').ace_aside('insideContainer'); //mirror all icons and attributes that have a "fa-*-right|left" attrobute $('.fa').each(function() { if(this.className.match(/ui-icon/) || $(this).closest('.fc-button').length > 0) return; //skip mirroring icons of plugins that have built in RTL support var l = this.attributes.length; for(var i = 0 ; i < l ; i++) { var val = this.attributes[i].value; if(val.match(/fa\-(?:[\w\-]+)\-left/)) this.attributes[i].value = val.replace(/fa\-([\w\-]+)\-(left)/i , 'fa-$1-right') else if(val.match(/fa\-(?:[\w\-]+)\-right/)) this.attributes[i].value = val.replace(/fa\-([\w\-]+)\-(right)/i , 'fa-$1-left') } }); //browsers are incosistent with horizontal scroll and RTL //so let's make our scrollbars LTR and wrap the content inside RTL var rtl = $body.hasClass('rtl'); if(rtl) { $('.scroll-hz').addClass('make-ltr') .find('.scroll-content') .wrapInner('<div class="make-rtl" />'); $('.sidebar[data-sidebar-hover=true]').ace_sidebar_hover('changeDir', 'right'); } else { //remove the wrap $('.scroll-hz').removeClass('make-ltr') .find('.make-rtl').children().unwrap(); $('.sidebar[data-sidebar-hover=true]').ace_sidebar_hover('changeDir', 'left'); } if($.fn.ace_scroll) $('.scroll-hz').ace_scroll('reset') //to reset scrollLeft //redraw the traffic pie chart on homepage with a different parameter try { var placeholder = $('#piechart-placeholder'); if(placeholder.length > 0) { var pos = $(document.body).hasClass('rtl') ? 'nw' : 'ne';//draw on north-west or north-east? placeholder.data('draw').call(placeholder.get(0) , placeholder, placeholder.data('chart'), pos); } }catch(e) {} ace.helper.redraw(document.body, true); } } })(jQuery); ;/** <b>Select a different skin</b>. It's good for demo only. You should hard code skin-specific changes inside your HTML/server-side code. Please refer to documentation for more info. */ (function($ , undefined) { try { $('#skin-colorpicker').ace_colorpicker({'auto_pos': false}); } catch(e) {} $('#skin-colorpicker').on('change', function(){ var skin_class = $(this).find('option:selected').data('skin'); if($('#ace-skins-stylesheet').length == 0) { //let's load skins stylesheet only when needed! var ace_style = $('head').find('link.ace-main-stylesheet'); if(ace_style.length == 0) { ace_style = $('head').find('link[href*="/ace.min.css"],link[href*="/ace-part2.min.css"]'); if(ace_style.length == 0) { ace_style = $('head').find('link[href*="/ace.css"],link[href*="/ace-part2.css"]'); } } var stylesheet_url = ace_style.first().attr('href').replace(/(\.min)?\.css$/i , '-skins$1.css'); $.ajax({ 'url': stylesheet_url }).done(function() { var new_link = jQuery('<link />', {type : 'text/css', rel: 'stylesheet', 'id': 'ace-skins-stylesheet'}) if(ace_style.length > 0){ new_link.insertAfter(ace_style.last()); } else new_link.appendTo('head'); new_link.attr('href', stylesheet_url); //we set "href" after insertion, for IE to work applyChanges(skin_class); }) } else { applyChanges(skin_class); } function applyChanges(skin_class) { //skin cookie tip var body = $(document.body); body.removeClass('no-skin skin-1 skin-2 skin-3'); //if(skin_class != 'skin-0') { body.addClass(skin_class); ace.data.set('skin', skin_class); //save the selected skin to cookies //which can later be used by your server side app to set the skin //for example: <body class="<?php echo $_COOKIE['ace_skin']; ?>" //} else ace.data.remove('skin'); var skin3_colors = ['red', 'blue', 'green', '']; //undo skin-1 $('.ace-nav > li.grey').removeClass('dark'); //undo skin-2 $('.ace-nav > li').removeClass('no-border margin-1'); $('.ace-nav > li:not(:last-child)').removeClass('light-pink').find('> a > '+ace.vars['.icon']).removeClass('pink').end().eq(0).find('.badge').removeClass('badge-warning'); $('.sidebar-shortcuts .btn') .removeClass('btn-pink btn-white') .find(ace.vars['.icon']).removeClass('white'); //undo skin-3 $('.ace-nav > li.grey').removeClass('red').find('.badge').removeClass('badge-yellow'); $('.sidebar-shortcuts .btn').removeClass('btn-primary btn-white') var i = 0; $('.sidebar-shortcuts .btn').each(function() { $(this).find(ace.vars['.icon']).removeClass(skin3_colors[i++]); }) var skin0_buttons = ['btn-success', 'btn-info', 'btn-warning', 'btn-danger']; if(skin_class == 'no-skin') { var i = 0; $('.sidebar-shortcuts .btn').each(function() { $(this).attr('class', 'btn ' + skin0_buttons[i++%4]); }) $('.sidebar[data-sidebar-scroll=true]').ace_sidebar_scroll('updateStyle', ''); $('.sidebar[data-sidebar-hover=true]').ace_sidebar_hover('updateStyle', 'no-track scroll-thin'); } else if(skin_class == 'skin-1') { $('.ace-nav > li.grey').addClass('dark'); var i = 0; $('.sidebar-shortcuts') .find('.btn').each(function() { $(this).attr('class', 'btn ' + skin0_buttons[i++%4]); }) $('.sidebar[data-sidebar-scroll=true]').ace_sidebar_scroll('updateStyle', 'scroll-white no-track'); $('.sidebar[data-sidebar-hover=true]').ace_sidebar_hover('updateStyle', 'no-track scroll-thin scroll-white'); } else if(skin_class == 'skin-2') { $('.ace-nav > li').addClass('no-border margin-1'); $('.ace-nav > li:not(:last-child)').addClass('light-pink').find('> a > '+ace.vars['.icon']).addClass('pink').end().eq(0).find('.badge').addClass('badge-warning'); $('.sidebar-shortcuts .btn').attr('class', 'btn btn-white btn-pink') .find(ace.vars['.icon']).addClass('white'); $('.sidebar[data-sidebar-scroll=true]').ace_sidebar_scroll('updateStyle', 'scroll-white no-track'); $('.sidebar[data-sidebar-hover=true]').ace_sidebar_hover('updateStyle', 'no-track scroll-thin scroll-white'); } //skin-3 //change shortcut buttons classes, this should be hard-coded if you want to choose this skin else if(skin_class == 'skin-3') { body.addClass('no-skin');//because skin-3 has many parts of no-skin as well $('.ace-nav > li.grey').addClass('red').find('.badge').addClass('badge-yellow'); var i = 0; $('.sidebar-shortcuts .btn').each(function() { $(this).attr('class', 'btn btn-primary btn-white'); $(this).find(ace.vars['.icon']).addClass(skin3_colors[i++]); }) $('.sidebar[data-sidebar-scroll=true]').ace_sidebar_scroll('updateStyle', 'scroll-dark no-track'); $('.sidebar[data-sidebar-hover=true]').ace_sidebar_hover('updateStyle', 'no-track scroll-thin'); } //some sizing differences may be there in skins, so reset scrollbar size $('.sidebar[data-sidebar-scroll=true]').ace_sidebar_scroll('reset') //$('.sidebar[data-sidebar-hover=true]').ace_sidebar_hover('reset') if(ace.vars['old_ie']) ace.helper.redraw(document.body, true); } }) })(jQuery);;/** 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>. <u><i class="glyphicon glyphicon-flash"></i> You don't need this. Used for demo only</u> */ (function($ , undefined) { //***default action for reload in this demo //you should remove this and add your own handler for each specific .widget-box //when data is finished loading or processing is done you can call $box.trigger('reloaded.ace.widget') $(document).on('reload.ace.widget', '.widget-box', function (ev) { var $box = $(this); //trigger the reloaded event to remove the spinner icon after 1-2 seconds setTimeout(function() { $box.trigger('reloaded.ace.widget'); }, parseInt(Math.random() * 1000 + 1000)); }); //you may want to do something like this: /** $('#my-widget-box').on('reload.ace.widget', function(){ //load new data here //and when finished trigger "reloaded" event $(this).trigger('reloaded.ace.widget'); }); */ })(window.jQuery);;/** The autocomplete dropdown when typing inside search box. <u><i class="glyphicon glyphicon-flash"></i> You don't need this. Used for demo only</u> */ (function($ , undefined) { 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"] try { $('#nav-search-input').bs_typeahead({ source: ace.vars['US_STATES'], updater:function (item) { //when an item is selected from dropdown menu, focus back to input element $('#nav-search-input').focus(); return item; } }); } catch(e) {} })(window.jQuery);