mirror of
https://github.com/fergalmoran/dss.git
synced 2026-03-26 15:37:18 +00:00
Mostly working ;)
This commit is contained in:
139
static/js/app/appv2.js
Normal file
139
static/js/app/appv2.js
Normal file
@@ -0,0 +1,139 @@
|
||||
// Generated by CoffeeScript 1.4.0
|
||||
(function() {
|
||||
|
||||
this.DssApplication = (function(Backbone, Marionette) {
|
||||
var App, sidebarView;
|
||||
App = new Marionette.Application();
|
||||
App.vent.on("routing:started", function() {
|
||||
var enablePushState, pushState;
|
||||
console.log("App(vent): routing:started");
|
||||
enablePushState = true;
|
||||
pushState = !!(enablePushState && window.history && window.history.pushState);
|
||||
Backbone.history.start({
|
||||
pushState: pushState,
|
||||
hashChange: true
|
||||
});
|
||||
return true;
|
||||
});
|
||||
App.addRegions({
|
||||
headerRegion: "#header",
|
||||
fullContentRegion: "#full-content",
|
||||
contentRegion: {
|
||||
selector: "#content"
|
||||
},
|
||||
footerRegion: "#footer",
|
||||
sidebarRegion: "#sidebar"
|
||||
});
|
||||
App.addInitializer(function() {
|
||||
console.log("App: routing starting");
|
||||
App.Router = new DssRouter();
|
||||
return App.vent.trigger("routing:started");
|
||||
});
|
||||
App.addInitializer(function() {
|
||||
$(document).on("click", "a[href]:not([data-bypass])", function(evt) {
|
||||
var href, root;
|
||||
href = {
|
||||
prop: $(this).prop("href"),
|
||||
attr: $(this).attr("href")
|
||||
};
|
||||
root = location.protocol + "//" + location.host + (App.root || '/');
|
||||
if (href.prop.slice(0, root.length) === root) {
|
||||
evt.preventDefault();
|
||||
App.Router.navigate(href.attr, true);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return true;
|
||||
});
|
||||
App.addInitializer(function() {
|
||||
this.listenTo(vent, "app:login", function() {
|
||||
console.log("App(vent): app:login");
|
||||
utils.modal("/dlg/LoginView");
|
||||
return true;
|
||||
});
|
||||
this.listenTo(vent, "app:donate", function() {
|
||||
console.log("App: donate");
|
||||
utils.modal("/dlg/Donate");
|
||||
return true;
|
||||
});
|
||||
this.listenTo(vent, "mix:favourite", function(model) {
|
||||
console.log("App(vent): mix:favourite");
|
||||
model.save('favourited', !model.get('favourited'), {
|
||||
patch: true
|
||||
});
|
||||
return true;
|
||||
});
|
||||
this.listenTo(vent, "mix:like", function(model, id, success, favourite) {
|
||||
console.log("App(vent): mix:like");
|
||||
model.save('liked', !model.get('liked'), {
|
||||
patch: true
|
||||
});
|
||||
return true;
|
||||
});
|
||||
this.listenTo(vent, "mix:delete", function(model) {
|
||||
console.log("App(vent): mix:like");
|
||||
return utils.messageBox("/dlg/DeleteMixConfirm", {
|
||||
yes: function() {
|
||||
console.log("Controller: mixDeleteYES!!");
|
||||
mix.destroy();
|
||||
return Backbone.history.navigate("/", {
|
||||
trigger: true
|
||||
});
|
||||
},
|
||||
no: function() {
|
||||
return console.log("Controller: mixDeleteNO!!");
|
||||
}
|
||||
});
|
||||
});
|
||||
this.listenTo(vent, "user:follow", function(model) {
|
||||
var target, user,
|
||||
_this = this;
|
||||
console.log("App(vent): user:follow");
|
||||
user = new UserItem({
|
||||
id: com.podnoms.settings.currentUser
|
||||
});
|
||||
target = com.podnoms.settings.urlRoot + "user/" + model.get("id") + "/";
|
||||
user.fetch({
|
||||
success: function() {
|
||||
var f, newFollowers;
|
||||
if (!model.get("is_following")) {
|
||||
newFollowers = user.get("following").concat([target]);
|
||||
user.save({
|
||||
"following": newFollowers,
|
||||
"is_following": true,
|
||||
patch: true
|
||||
});
|
||||
model.set("is_following", true);
|
||||
} else {
|
||||
f = user.get("following");
|
||||
f.splice(f.indexOf(target), 1);
|
||||
user.save({
|
||||
"following": f,
|
||||
"is_following": false,
|
||||
patch: true
|
||||
});
|
||||
model.set("is_following", false);
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
});
|
||||
return this.listenTo(vent, "mix:share", function(mode, model) {
|
||||
console.log("App(vent): mix:share (" + mode + ")");
|
||||
if (mode === "facebook") {
|
||||
social.sharePageToFacebook(model);
|
||||
} else if (mode === "twitter") {
|
||||
social.sharePageToTwitter(model);
|
||||
} else if (mode === "embed") {
|
||||
social.generateEmbedCode(model);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
});
|
||||
App.headerRegion.show(new HeaderView());
|
||||
sidebarView = new SidebarView();
|
||||
App.sidebarRegion.show(sidebarView);
|
||||
return App;
|
||||
})(Backbone, Marionette);
|
||||
|
||||
}).call(this);
|
||||
17
static/js/lib/ace/ace/ace.auto-container.js
Normal file
17
static/js/lib/ace/ace/ace.auto-container.js
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
<b>Auto Container</b> Adds .container when window size is above 1140px.
|
||||
In Bootstrap you should stick with fixed width breakpoints.
|
||||
You can use this feature to enable fixed container only when window size is above 1140px
|
||||
*/
|
||||
ace.auto_container = function($) {
|
||||
$(window).on('resize.auto_container', function() {
|
||||
var enable = ace.vars.window['width'] > 1140 ? true : false;
|
||||
try {
|
||||
ace.settings.main_container_fixed(enable, false, false);
|
||||
} catch(e) {
|
||||
if(enable) $('.main-container,.navbar-container').addClass('container');
|
||||
else $('.main-container,.navbar-container').removeClass('container');
|
||||
$(document).trigger('settings.ace', ['main_container_fixed' , enable]);
|
||||
}
|
||||
}).triggerHandler('resize.auto_container');
|
||||
}
|
||||
80
static/js/lib/ace/ace/ace.auto-padding.js
Normal file
80
static/js/lib/ace/ace/ace.auto-padding.js
Normal file
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
<b>Auto content padding on fixed navbar & breadcrumbs</b>.
|
||||
Navbar's content and height is often predictable and when navbar is fixed we can add appropriate padding to content area using CSS.
|
||||
|
||||
But when navbar is fixed and its content size and height is not predictable we may need to add the necessary padding to content area dynamically using Javascript.
|
||||
|
||||
It's not often needed and you can have good results using CSS3 media queries to add necessary paddings based on window size.
|
||||
*/
|
||||
ace.auto_padding = function($) {
|
||||
var navbar = $('.navbar').eq(0);
|
||||
var navbar_container = $('.navbar-container').eq(0);
|
||||
|
||||
var sidebar = $('.sidebar').eq(0);
|
||||
|
||||
var main_container = $('.main-container').get(0);
|
||||
|
||||
var breadcrumbs = $('.breadcrumbs').eq(0);
|
||||
var page_content = $('.page-content').get(0);
|
||||
|
||||
var default_padding = 8
|
||||
|
||||
if(navbar.length > 0) {
|
||||
$(window).on('resize.padding', function() {
|
||||
if( navbar.css('position') == 'fixed' ) {
|
||||
var padding1 = !ace.vars['nav_collapse'] ? navbar.outerHeight() : navbar_container.outerHeight();
|
||||
padding1 = parseInt(padding1);
|
||||
main_container.style.paddingTop = padding1 + 'px';
|
||||
|
||||
if(ace.vars['non_auto_fixed'] && sidebar.length > 0) {
|
||||
if(sidebar.css('position') == 'fixed') {
|
||||
sidebar.get(0).style.top = padding1 + 'px';
|
||||
}
|
||||
else sidebar.get(0).style.top = '';
|
||||
}
|
||||
|
||||
if( breadcrumbs.length > 0 ) {
|
||||
if(breadcrumbs.css('position') == 'fixed') {
|
||||
var padding2 = default_padding + breadcrumbs.outerHeight() + parseInt(breadcrumbs.css('margin-top'));
|
||||
padding2 = parseInt(padding2);
|
||||
page_content.style['paddingTop'] = padding2 + 'px';
|
||||
|
||||
if(ace.vars['non_auto_fixed']) breadcrumbs.get(0).style.top = padding1 + 'px';
|
||||
} else {
|
||||
page_content.style.paddingTop = '';
|
||||
if(ace.vars['non_auto_fixed']) breadcrumbs.get(0).style.top = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
main_container.style.paddingTop = '';
|
||||
page_content.style.paddingTop = '';
|
||||
|
||||
if(ace.vars['non_auto_fixed']) {
|
||||
if(sidebar.length > 0) {
|
||||
sidebar.get(0).style.top = '';
|
||||
}
|
||||
if(breadcrumbs.length > 0) {
|
||||
breadcrumbs.get(0).style.top = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
}).triggerHandler('resize.padding');
|
||||
|
||||
$(document).on('settings.ace', function(ev, event_name, event_val) {
|
||||
if(event_name == 'navbar_fixed' || event_name == 'breadcrumbs_fixed') {
|
||||
if(ace.vars['webkit']) {
|
||||
//force new 'css position' values to kick in
|
||||
navbar.get(0).offsetHeight;
|
||||
if(breadcrumbs.length > 0) breadcrumbs.get(0).offsetHeight;
|
||||
}
|
||||
$(window).triggerHandler('resize.padding');
|
||||
}
|
||||
});
|
||||
|
||||
/**$('#skin-colorpicker').on('change', function() {
|
||||
$(window).triggerHandler('resize.padding');
|
||||
});*/
|
||||
}
|
||||
|
||||
}
|
||||
19
static/js/lib/ace/ace/ace.autohide-sidebar.js
Normal file
19
static/js/lib/ace/ace/ace.autohide-sidebar.js
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
<b>Autohide mobile view menu</b>. Automatically hide the sidebar in mobile view (default style) when clicked/tapped outside of it.
|
||||
*/
|
||||
ace.auto_hide_sidebar = function($) {
|
||||
$(document).on(ace.click_event+'.ace.hide', function(e) {
|
||||
var toggler = $('#menu-toggler');
|
||||
if( toggler.length == 0 || toggler[0].scrollHeight == 0 || !toggler.hasClass('display') ) return;
|
||||
//toggle button is not visible, so we are not in mobile view, or the sidebar is not displayed, so return
|
||||
|
||||
var sidebar = $('#sidebar');
|
||||
if( $.contains(sidebar[0], e.target) ) {
|
||||
e.stopPropagation();
|
||||
return;
|
||||
}
|
||||
|
||||
sidebar.removeClass('display');
|
||||
toggler.removeClass('display');
|
||||
})
|
||||
}
|
||||
301
static/js/lib/ace/ace/ace.js
Normal file
301
static/js/lib/ace/ace/ace.js
Normal file
@@ -0,0 +1,301 @@
|
||||
/**
|
||||
Required. Ace's Basic File to Initiliaze Different Parts & Some Variables.
|
||||
*/
|
||||
if( !('ace' in window) ) window['ace'] = {}
|
||||
if( !('helper' in window['ace']) ) window['ace'].helper = {}
|
||||
if( !('vars' in window['ace']) ) {
|
||||
window['ace'].vars = {
|
||||
'icon' : ' ace-icon ',
|
||||
'.icon' : '.ace-icon'
|
||||
}
|
||||
}
|
||||
ace.vars['touch'] = 'ontouchstart' in document.documentElement;
|
||||
|
||||
|
||||
jQuery(function($) {
|
||||
//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-8])(_\d)+ like Mac OS X/i) && !agent.match(/CriOS/i)
|
||||
|
||||
ace.vars['non_auto_fixed'] = ace.vars['android'] || ace.vars['ios_safari'];
|
||||
// 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'] = 'transition' in document.body.style || 'WebkitTransition' in document.body.style || 'MozTransition' in document.body.style || 'OTransition' in document.body.style
|
||||
|
||||
/////////////////////////////
|
||||
|
||||
//a list of available functions with their arguments
|
||||
// >>> null means enable
|
||||
// >>> false means disable
|
||||
// >>> array means function arguments
|
||||
var available_functions = {
|
||||
'general_vars' : null,//general_vars should come first
|
||||
|
||||
'handle_side_menu' : null,
|
||||
'add_touch_drag' : null,
|
||||
|
||||
'sidebar_scrollable' : [
|
||||
//true, //enable only if sidebar is fixed , for 2nd approach only
|
||||
true //scroll to selected item? (one time only on page load)
|
||||
,true //true = include shortcut buttons in the scrollbars
|
||||
,false || ace.vars['safari'] || ace.vars['ios_safari'] //true = include toggle button in the scrollbars
|
||||
,200 //> 0 means smooth_scroll, time in ms, used in first approach only, better to be almost the same amount as submenu transition time
|
||||
,false//true && ace.vars['touch'] //used in first approach only, true means the scrollbars should be outside of the sidebar
|
||||
],
|
||||
|
||||
'sidebar_hoverable' : null,//automatically move up a submenu, if some part of it goes out of window
|
||||
|
||||
'general_things' : null,
|
||||
|
||||
'widget_boxes' : null,
|
||||
'widget_reload_handler' : null,
|
||||
|
||||
'settings_box' : null,//settings box
|
||||
'settings_rtl' : null,
|
||||
'settings_skin' : null,
|
||||
|
||||
'enable_searchbox_autocomplete' : null,
|
||||
|
||||
'auto_hide_sidebar' : null,//disable?
|
||||
'auto_padding' : null,//disable
|
||||
'auto_container' : null//disable
|
||||
};
|
||||
|
||||
//enable these functions with related params
|
||||
for(var func_name in available_functions) {
|
||||
if(!(func_name in ace)) continue;
|
||||
|
||||
var args = available_functions[func_name];
|
||||
if(args === false) continue;//don't run this function
|
||||
|
||||
else if(args == null) args = [jQuery];
|
||||
else if(args instanceof String) args = [jQuery, args];
|
||||
else if(args instanceof Array) args.unshift(jQuery);//prepend jQuery
|
||||
|
||||
ace[func_name].apply(null, args);
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
|
||||
|
||||
ace.general_vars = function($) {
|
||||
var minimized_menu_class = 'menu-min';
|
||||
var responsive_min_class = 'responsive-min';
|
||||
var horizontal_menu_class = 'h-sidebar';
|
||||
|
||||
var sidebar = $('#sidebar').eq(0);
|
||||
//differnet mobile menu styles
|
||||
ace.vars['mobile_style'] = 1;//default responsive mode with toggle button inside navbar
|
||||
if(sidebar.hasClass('responsive') && !$('#menu-toggler').hasClass('navbar-toggle')) ace.vars['mobile_style'] = 2;//toggle button behind sidebar
|
||||
else if(sidebar.hasClass(responsive_min_class)) ace.vars['mobile_style'] = 3;//minimized menu
|
||||
else if(sidebar.hasClass('navbar-collapse')) ace.vars['mobile_style'] = 4;//collapsible (bootstrap style)
|
||||
|
||||
//update some basic variables
|
||||
$(window).on('resize.ace.vars' , function(){
|
||||
ace.vars['window'] = {width: parseInt($(this).width()), height: parseInt($(this).height())}
|
||||
ace.vars['mobile_view'] = ace.vars['mobile_style'] < 4 && ace.helper.mobile_view();
|
||||
ace.vars['collapsible'] = !ace.vars['mobile_view'] && ace.helper.collapsible();
|
||||
ace.vars['nav_collapse'] = (ace.vars['collapsible'] || ace.vars['mobile_view']) && $('#navbar').hasClass('navbar-collapse');
|
||||
|
||||
var sidebar = $(document.getElementById('sidebar'));
|
||||
ace.vars['minimized'] =
|
||||
(!ace.vars['collapsible'] && sidebar.hasClass(minimized_menu_class))
|
||||
||
|
||||
(ace.vars['mobile_style'] == 3 && ace.vars['mobile_view'] && sidebar.hasClass(responsive_min_class))
|
||||
|
||||
ace.vars['horizontal'] = !(ace.vars['mobile_view'] || ace.vars['collapsible']) && sidebar.hasClass(horizontal_menu_class)
|
||||
}).triggerHandler('resize.ace.vars');
|
||||
}
|
||||
|
||||
//
|
||||
ace.general_things = function($) {
|
||||
//add scrollbars for user dropdowns
|
||||
var has_scroll = !!$.fn.ace_scroll;
|
||||
if(has_scroll) $('.dropdown-content').ace_scroll({reset: false, mouseWheelLock: true})
|
||||
/**
|
||||
//add scrollbars to body
|
||||
if(has_scroll) $('body').ace_scroll({size: ace.helper.winHeight()})
|
||||
$('body').css('position', 'static')
|
||||
*/
|
||||
|
||||
//reset scrolls bars on window resize
|
||||
$(window).on('resize.reset_scroll', function() {
|
||||
/**
|
||||
//reset body scrollbars
|
||||
if(has_scroll) $('body').ace_scroll('update', {size : ace.helper.winHeight()})
|
||||
*/
|
||||
if(has_scroll) $('.ace-scroll').ace_scroll('reset');
|
||||
});
|
||||
$(document).on('settings.ace.reset_scroll', function(e, name) {
|
||||
if(name == 'sidebar_collapsed' && has_scroll) $('.ace-scroll').ace_scroll('reset');
|
||||
});
|
||||
|
||||
|
||||
//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');
|
||||
});
|
||||
|
||||
|
||||
//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();
|
||||
}
|
||||
});
|
||||
|
||||
//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]);
|
||||
});
|
||||
|
||||
|
||||
//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>'
|
||||
});*/
|
||||
|
||||
|
||||
|
||||
|
||||
//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() {
|
||||
if(ace.helper.scrollTop() > parseInt(ace.helper.winHeight() / 4)) {
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//chrome and webkit have a problem here when resizing from 460px 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' , function(){
|
||||
ace.helper.redraw(ace_nav);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//some functions
|
||||
ace.helper.collapsible = function() {
|
||||
var toggle
|
||||
return (document.querySelector('#sidebar.navbar-collapse') != null)
|
||||
&& ((toggle = document.querySelector('.navbar-toggle[data-target*=".sidebar"]')) != null)
|
||||
&& toggle.scrollHeight > 0
|
||||
//sidebar is collapsible and collapse button is visible?
|
||||
}
|
||||
ace.helper.mobile_view = function() {
|
||||
var toggle
|
||||
return ((toggle = document.getElementById('menu-toggler')) != null && toggle.scrollHeight > 0)
|
||||
}
|
||||
|
||||
ace.helper.redraw = function(elem) {
|
||||
var saved_val = elem.style['display'];
|
||||
elem.style.display = 'none';
|
||||
elem.offsetHeight;
|
||||
elem.style.display = saved_val;
|
||||
}
|
||||
|
||||
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.body.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; }
|
||||
592
static/js/lib/ace/ace/ace.onpage-help.js
Normal file
592
static/js/lib/ace/ace/ace.onpage-help.js
Normal file
@@ -0,0 +1,592 @@
|
||||
jQuery(function($) {
|
||||
var help = null;
|
||||
$(window).on('hashchange.start_help', function(e) {
|
||||
if(help == null && window.location.hash == '#help') {
|
||||
help = new ace.Onpage_Help($)
|
||||
help.init()
|
||||
help.disable();
|
||||
|
||||
//add #help tag to links to enable help
|
||||
$(document).on('click.start_help', '.sidebar .nav-list a', function() {
|
||||
var href = $(this).attr('href');
|
||||
if( !href.match(/\#help$/) ) $(this).attr('href', href+'#help');
|
||||
});
|
||||
}
|
||||
}).triggerHandler('hashchange.start_help');
|
||||
|
||||
|
||||
//some buttons inside demo pages to launch help
|
||||
$(document).on(ace.click_event, '.btn-display-help', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
if(help == null) {
|
||||
help = new ace.Onpage_Help($)
|
||||
help.init()
|
||||
help.disable();
|
||||
|
||||
//
|
||||
$('#ace-toggle-onpage-help').trigger('click');
|
||||
}
|
||||
|
||||
var section = $(this).attr('href');
|
||||
help.show_help(section);
|
||||
});
|
||||
});
|
||||
|
||||
ace.Onpage_Help = function($) {
|
||||
if( !window.Node ) window.Node = {
|
||||
ELEMENT_NODE: 1,
|
||||
ATTRIBUTE_NODE: 2,
|
||||
TEXT_NODE: 3,
|
||||
COMMENT_NODE: 8
|
||||
};
|
||||
|
||||
var $base = ace.vars['base'] || '../..';
|
||||
|
||||
var section_start = {};
|
||||
var section_end = {};
|
||||
var rects = {};
|
||||
|
||||
var created = false;
|
||||
var active = false;
|
||||
|
||||
var self = this;
|
||||
var settings = {}
|
||||
var ovfx = '';
|
||||
var container = null;
|
||||
|
||||
var body_h, body_w;
|
||||
|
||||
var captureFocus = function() {
|
||||
if(!container) return;
|
||||
var scroll = -1;
|
||||
//like bootstrap modal
|
||||
$(document)
|
||||
.off('focusin.ace.help') //remove any previously attached handler
|
||||
.on('focusin.ace.help', function (e) {
|
||||
if (!( container[0] == e.target || $.contains(container[0], e.target) )) {
|
||||
container.focus();
|
||||
}
|
||||
|
||||
if(e.target == document && scroll > -1) {
|
||||
//when window regains focus and container is focused, it scrolls to bottom
|
||||
//so we put it back to its place
|
||||
$('body,html').scrollTop(scroll);
|
||||
scroll = -1;
|
||||
}
|
||||
})
|
||||
|
||||
$(window).on('blur.ace.help', function(){
|
||||
scroll = $(window).scrollTop();
|
||||
});
|
||||
}
|
||||
var releaseFocus = function() {
|
||||
$(document).off('focusin.ace.help');
|
||||
$(window).off('blur.ace.help');
|
||||
}
|
||||
|
||||
this.enable = function() {
|
||||
if(active) return;
|
||||
|
||||
active = true;
|
||||
settings['navbar'] = ace.settings.is('navbar', 'fixed')
|
||||
settings['sidebar'] = ace.settings.is('sidebar', 'fixed')
|
||||
settings['breadcrumbs'] = ace.settings.is('breadcrumbs', 'fixed')
|
||||
|
||||
ace.settings.navbar_fixed(false , false);//disable fixed navbar, sidebar, etc
|
||||
|
||||
if( !created ) {
|
||||
this.init();
|
||||
created = true;
|
||||
}
|
||||
$('.ace-onpage-help-backdrop, .ace-onpage-help').removeClass('hidden');
|
||||
|
||||
ovfx = document.body.style.overflowX;
|
||||
document.body.style.overflowX = 'hidden';//hide body:overflow-x
|
||||
$('#btn-scroll-up').css('z-index', 1000000);
|
||||
|
||||
$(window).triggerHandler('resize.onpage_help');
|
||||
captureFocus();
|
||||
}
|
||||
|
||||
this.disable = function() {
|
||||
|
||||
active = false;
|
||||
$('.ace-onpage-help-backdrop, .ace-onpage-help').addClass('hidden');
|
||||
|
||||
document.body.style.overflowX = ovfx;//restore body:overflow-x
|
||||
$('#btn-scroll-up').css('z-index', '');
|
||||
|
||||
//restore fixed state of navbar, sidebar, etc
|
||||
if( settings['breadcrumbs'] ) {
|
||||
ace.settings.breadcrumbs_fixed(true, false, false);
|
||||
}
|
||||
if( settings['sidebar'] ) {
|
||||
ace.settings.sidebar_fixed(true, false, false);
|
||||
}
|
||||
if( settings['navbar'] ) {
|
||||
ace.settings.navbar_fixed(true, false, false);
|
||||
}
|
||||
|
||||
releaseFocus();
|
||||
}
|
||||
|
||||
this.is_active = function() {
|
||||
return active;
|
||||
}
|
||||
this.show_help = function(section) {
|
||||
launch_help_modal(section, true);
|
||||
}
|
||||
|
||||
|
||||
this.init = function() {
|
||||
container = $('<div class="ace-onpage-help-container" tabindex="-1" />').appendTo('body');
|
||||
|
||||
container
|
||||
.append('<div class="ace-onpage-help-backdrop" />')
|
||||
.append('\<div class="ace-settings-container ace-help-container">\
|
||||
<div id="ace-toggle-onpage-help" class="btn btn-app btn-xs btn-info ace-settings-btn ace-toggle-onpage-help">\
|
||||
<i class="ace-toggle-help-text ace-icon fa fa-question bigger-150"></i>\
|
||||
</div>\
|
||||
</div>');
|
||||
|
||||
$(document).on('settings.ace.help', function(ev, event_name, event_val) {
|
||||
if(event_name == 'main_container_fixed') {
|
||||
if(event_val) container.addClass('container');
|
||||
else container.removeClass('container');
|
||||
}
|
||||
}).triggerHandler('settings.ace.help', ['main_container_fixed', $('.main-container').hasClass('container')])
|
||||
|
||||
|
||||
$('#ace-toggle-onpage-help').on('click', function(e) {
|
||||
if(active) {
|
||||
self.disable();
|
||||
}
|
||||
else {
|
||||
self.enable();
|
||||
}
|
||||
$(this).find('.ace-toggle-help-text').removeClass('ace-toggle-help-text');
|
||||
$(this).toggleClass('btn-grey btn-info').parent().toggleClass('active');
|
||||
e.preventDefault();
|
||||
})
|
||||
|
||||
//find all comments
|
||||
var comments = $('*').contents().filter(function(){ return this.nodeType == Node.COMMENT_NODE; })
|
||||
$(comments).each(function() {
|
||||
var match
|
||||
if( (match = $.trim(this.data).match(/#section\s*:\s*([\w\-\.\/]+)/i)) ) {
|
||||
var section_name = match[1];
|
||||
if( !(section_name in section_start) ) section_start[ section_name ] = this;
|
||||
}
|
||||
if( (match = $.trim(this.data).match(/\/section\s*:\s*([\w\-\.\/]+)/i)) ) {
|
||||
var section_name = match[1];
|
||||
if( !(section_name in section_end) ) section_end[ section_name ] = this;
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
//update to correct position and size
|
||||
$(window).on('resize.onpage_help', function() {
|
||||
if(!active) return;
|
||||
body_h = document.body.scrollHeight - 2;
|
||||
body_w = document.body.scrollWidth - 2;
|
||||
|
||||
//we first calculate all positions
|
||||
//because if we calculate one position and then change DOM,
|
||||
//next position calculation will become slow on Webkit, because it tries to re-calculate things
|
||||
//i.e. batch call all and save offsets and scrollWidth, etc and then use them later in highlight_section
|
||||
//Firefox doesn't have such issue
|
||||
for(var name in section_start) {
|
||||
if(section_start.hasOwnProperty(name)) {
|
||||
save_section_position(name);
|
||||
}
|
||||
}
|
||||
for(var name in section_start) {
|
||||
if(section_start.hasOwnProperty(name)) {
|
||||
highlight_section(name);
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
//$('.alert').on('closed.bs.alert', function() {
|
||||
//$(window).triggerHandler('resize.onpage_help');
|
||||
//});
|
||||
|
||||
created = true;
|
||||
}
|
||||
|
||||
|
||||
function save_section_position(name) {
|
||||
if( !(name in section_start) || !(name in section_end) ) return;
|
||||
|
||||
var node = section_start[name];
|
||||
var start = $(node).next().eq(0);
|
||||
var end = $(section_end[name]).prev().eq(0);
|
||||
|
||||
var start_hidden = start.is(':hidden');
|
||||
var end_hidden = end.is(':hidden');
|
||||
if( start_hidden && end_hidden ) {
|
||||
rects[name] = {is_hidden: true}
|
||||
return;
|
||||
}
|
||||
|
||||
if(start_hidden) start = end;
|
||||
else if(end_hidden) end = start;
|
||||
|
||||
//get the start and end position of our rectangle to be drawn!
|
||||
var off1 = start.offset();
|
||||
var off2 = end.offset();
|
||||
if( !off1 || !off2 ) {
|
||||
rects[name] = {is_hidden: true}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var x1, y1, x2, y2, w2, h2;
|
||||
if(off1.left < off2.left) {
|
||||
x1 = parseInt(off1.left);
|
||||
x2 = parseInt(off2.left);
|
||||
w2 = parseInt(end.outerWidth());
|
||||
} else {
|
||||
x1 = parseInt(off2.left);
|
||||
x2 = parseInt(off1.left);
|
||||
w2 = parseInt(start.outerWidth());
|
||||
}
|
||||
|
||||
if(off1.top < off2.top) {
|
||||
y1 = parseInt(off1.top);
|
||||
y2 = parseInt(off2.top);
|
||||
h2 = parseInt(end.outerHeight());
|
||||
} else {
|
||||
y1 = parseInt(off2.top);
|
||||
y2 = parseInt(off1.top);
|
||||
h2 = parseInt(start.outerHeight());
|
||||
}
|
||||
|
||||
x1 -= 1;
|
||||
y1 -= 1;
|
||||
x2 += 1;
|
||||
y2 += 1;
|
||||
|
||||
var width = x2 + w2 - x1, height = y2 + h2 - y1;
|
||||
|
||||
//if out of window rect
|
||||
if(x1 + width < 2 || x1 > body_w || y1 + height < 2 || y1 > body_h ) {
|
||||
rects[name] = {is_hidden: true}
|
||||
return;
|
||||
}
|
||||
|
||||
rects[name] = {
|
||||
left: x1,
|
||||
top: y1,
|
||||
width: width,
|
||||
height: height
|
||||
}
|
||||
}
|
||||
|
||||
function highlight_section(name) {
|
||||
if( !(name in rects) || !container ) return;
|
||||
|
||||
var div = container.find('.ace-onpage-help[data-section="'+name+'"]').eq(0);
|
||||
if(div.length == 0) {
|
||||
div = $('<a class="ace-onpage-help" href="#" />').appendTo(container);
|
||||
div.attr('data-section', name);
|
||||
|
||||
div.on(ace.click_event, function(e) {
|
||||
e.preventDefault();
|
||||
launch_help_modal(name);
|
||||
});
|
||||
}
|
||||
|
||||
var rect = rects[name];
|
||||
if(rect.is_hidden) {
|
||||
div.addClass('hidden');
|
||||
return;
|
||||
}
|
||||
|
||||
div.css({
|
||||
left: rect.left,
|
||||
top: rect.top,
|
||||
width: rect.width,
|
||||
height: rect.height
|
||||
});
|
||||
|
||||
|
||||
div.removeClass('hidden');
|
||||
div.removeClass('smaller smallest');
|
||||
if(rect.height < 55 || rect.width < 55) {
|
||||
div.addClass('smallest');
|
||||
}
|
||||
else if(rect.height < 75 || rect.width < 75) {
|
||||
div.addClass('smaller');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
var nav_list = [];
|
||||
var nav_pos = -1;
|
||||
var mbody = null, mbody_scroll = null;
|
||||
|
||||
function launch_help_modal(name, save_to_list) {
|
||||
name = name.replace(/^#/g, '');
|
||||
|
||||
var modal = $('#onpage-help-modal');
|
||||
if(modal.length == 0) {
|
||||
modal = $('<div id="onpage-help-modal" class="modal onpage-help-modal" tabindex="-1" role="dialog" aria-labelledby="HelpModalDialog" aria-hidden="true">\
|
||||
<div class="modal-dialog modal-lg">\
|
||||
<div class="modal-content">\
|
||||
<div class="modal-header">\
|
||||
<div class="pull-right modal-buttons">\
|
||||
<button aria-hidden="true" data-goup="modal" type="button" class="disabled btn btn-white btn-success btn-sm"><i class="ace-icon fa fa-level-up fa-flip-horizontal bigger-125 icon-only"></i></button>\
|
||||
\
|
||||
<button aria-hidden="true" data-goback="modal" type="button" class="disabled btn btn-white btn-info btn-sm"><i class="ace-icon fa fa-arrow-left icon-only"></i></button>\
|
||||
<button aria-hidden="true" data-goforward="modal" type="button" class="disabled btn btn-white btn-info btn-sm"><i class="ace-icon fa fa-arrow-right icon-only"></i></button>\
|
||||
\
|
||||
<button aria-hidden="true" data-dismiss="modal" class="btn btn-white btn-danger btn-sm" type="button"><i class="ace-icon fa fa-times icon-only"></i></button>\
|
||||
</div>\
|
||||
<h4 class="modal-title">Help Dialog/ <small></small></h4>\
|
||||
</div>\
|
||||
<div class="modal-body"> <div class="onpage-help-content"></div> </div>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>').appendTo('body');
|
||||
|
||||
mbody = modal.find('.modal-body');
|
||||
modal.css({'overflow' : 'hidden'})
|
||||
|
||||
mbody.ace_scroll({hoverReset: false, size: $(window).innerHeight() - 150, lockAnyway: true, styleClass: 'scroll-margin scroll-dark'})
|
||||
|
||||
$('#onpage-help-modal')
|
||||
.on('show.bs.modal', function() {
|
||||
releaseFocus();
|
||||
})
|
||||
.on('hidden.bs.modal', function() {
|
||||
captureFocus();
|
||||
});
|
||||
|
||||
$(document).on('shown.ace.widget hidden.ace.widget', '.help-content .widget-box', function() {
|
||||
mbody.ace_scroll('reset');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
if( !modal.hasClass('in') ) {
|
||||
if(document.body.lastChild != modal.get(0)) $(document.body).append(modal);//move it to become the last element of body
|
||||
modal.modal('show');
|
||||
var diff = parseInt(modal.find('.modal-dialog').css('margin-top'));
|
||||
diff = diff + 110 + parseInt(diff / 2);
|
||||
mbody.ace_scroll('update', { size: $(window).innerHeight() - diff });
|
||||
}
|
||||
|
||||
modal.find('.modal-title').wrapInner("<span class='hidden' />").append('<i class="fa fa-spinner fa-spin blue bigger-125"></i>');
|
||||
var content = $('.onpage-help-content');
|
||||
content.addClass('hidden')
|
||||
|
||||
$(document.body).removeClass('modal-open');
|
||||
if(name.indexOf('file:') >= 0) {
|
||||
var parts = name.match(/file\:(.*)\:(.+)/i);
|
||||
if(parts.length == 3) display_codeview(parts[2], parts[1], false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
var url = name.replace(/\..*$/g, '')
|
||||
var parts = url.split('/');
|
||||
if(parts.length == 1) {
|
||||
if(url.length == 0) url = 'intro';
|
||||
url = url+'/index.html';
|
||||
}
|
||||
else if(parts.length > 1) {
|
||||
url = url+'.html';
|
||||
}
|
||||
|
||||
|
||||
$.ajax({url: $base+"/docs/sections/" + url, dataType: 'text'})
|
||||
.done(function(result) {
|
||||
var find1 = 'data-id="#'+name+'"';
|
||||
var pos1 = result.indexOf(find1);
|
||||
|
||||
var tname = name;
|
||||
if(pos1 == -1) {
|
||||
//if no data-id="#something.part" go for data-id="#something" instead
|
||||
var tpos
|
||||
var tfind1
|
||||
if((tpos = tname.lastIndexOf('.')) > -1) {
|
||||
tname = tname.substr(0, tpos);
|
||||
tfind1 = 'data-id="#'+tname+'"';
|
||||
pos1 = result.indexOf(tfind1);
|
||||
pos1 += tfind1.length + 1
|
||||
}
|
||||
}
|
||||
else pos1 += find1.length + 1
|
||||
|
||||
|
||||
var pos2 = result.indexOf("</h", pos1);
|
||||
modal.find('.modal-title').addClass('blue').html( result.substring(pos1, pos2) );
|
||||
|
||||
|
||||
find1 = '<!-- #section:'+name+' -->';
|
||||
pos1 = result.indexOf(find1);
|
||||
pos2 = result.indexOf('<!-- /section:'+name+' -->', pos1);
|
||||
|
||||
|
||||
result = result.substring(pos1 + find1.length + 1, pos2);
|
||||
result = result.replace(/\<pre(?:\s+)data\-language=["'](?:html|javascript|php)["']\>([\S|\s]+?)\<\/pre\>/ig, function(a, b){
|
||||
return a.replace(b , b.replace(/\</g , '<').replace(/\>/g , '>'));
|
||||
});
|
||||
content.empty().append(result);
|
||||
|
||||
content
|
||||
.find('.info-section').each(function() {
|
||||
var header = $(this).prevAll('.info-title').eq(0);
|
||||
if(header.length == 0) return false;
|
||||
|
||||
header = header.addClass('widget-title').wrap('<div class="widget-header" />')
|
||||
.parent().append('<div class="widget-toolbar no-border">\
|
||||
<a href="#" data-action="collapse">\
|
||||
<i data-icon-hide="fa-minus" data-icon-show="fa-plus" class="ace-icon fa fa-plus"></i>\
|
||||
</a>\
|
||||
</div>').closest('.widget-header');
|
||||
|
||||
$(this).wrap('<div class="widget-box transparent collapsed"><div class="widget-body"><div class="widget-main"></div></div></div>');
|
||||
$(this).closest('.widget-box').prepend(header);
|
||||
});
|
||||
|
||||
content.removeClass('hidden');
|
||||
|
||||
content.find('span.thumbnail img').each(function() {
|
||||
var src = $(this).attr('src');
|
||||
$(this)
|
||||
.attr('src', $base+"/docs/" + src)
|
||||
.one('load', function() {
|
||||
mbody.ace_scroll('reset');
|
||||
});
|
||||
});
|
||||
|
||||
Rainbow.color(content.get(0), function(){
|
||||
mbody.ace_scroll('reset');
|
||||
});
|
||||
|
||||
//save history list
|
||||
add_to_nav_list(name, save_to_list);
|
||||
|
||||
var pos = -1;
|
||||
if((pos = name.lastIndexOf('.')) > -1) {
|
||||
name = name.substr(0, pos);
|
||||
modal.find('button[data-goup=modal]').removeClass('disabled').attr('data-url', name);
|
||||
}
|
||||
else {
|
||||
modal.find('button[data-goup=modal]').addClass('disabled').blur();
|
||||
}
|
||||
|
||||
})
|
||||
.fail(function() {
|
||||
modal.find('.modal-title').find('.fa-spin').remove().end().find('.hidden').children().unwrap();
|
||||
mbody.ace_scroll('reset');
|
||||
});
|
||||
}//launch_help_modal
|
||||
|
||||
$(document).on(ace.click_event, '.help-content > .widget-box > .widget-header > .info-title', function(e) {
|
||||
var widget_box = $(this).closest('.widget-box').widget_box('toggle');
|
||||
});
|
||||
$(document).on(ace.click_event, '.help-more', function(e) {
|
||||
e.preventDefault();
|
||||
var href = $(this).attr('href');
|
||||
launch_help_modal(href);
|
||||
});
|
||||
|
||||
|
||||
function add_to_nav_list(name, save_to_list) {
|
||||
if(save_to_list !== false) {
|
||||
if(nav_list.length > 0) {
|
||||
nav_list = nav_list.slice(0, nav_pos + 1);
|
||||
}
|
||||
if(nav_list[nav_list.length - 1] != name) {
|
||||
nav_list.push(name);
|
||||
nav_pos = nav_list.length - 1;
|
||||
}
|
||||
}
|
||||
|
||||
var modal = $('#onpage-help-modal');
|
||||
if(nav_pos == 0){
|
||||
modal.find('button[data-goback=modal]').addClass('disabled').blur();
|
||||
}
|
||||
else {
|
||||
modal.find('button[data-goback=modal]').removeClass('disabled');
|
||||
}
|
||||
|
||||
if(nav_pos == nav_list.length - 1){
|
||||
modal.find('button[data-goforward=modal]').addClass('disabled').blur();
|
||||
}
|
||||
else {
|
||||
modal.find('button[data-goforward=modal]').removeClass('disabled');
|
||||
}
|
||||
}
|
||||
|
||||
$(document).on(ace.click_event, 'button[data-goforward=modal]', function() {
|
||||
if(nav_pos < nav_list.length - 1) {
|
||||
nav_pos++;
|
||||
launch_help_modal(nav_list[nav_pos], false);
|
||||
}
|
||||
});
|
||||
$(document).on(ace.click_event, 'button[data-goback=modal]', function() {
|
||||
if(nav_pos > 0) {
|
||||
nav_pos--;
|
||||
launch_help_modal(nav_list[nav_pos], false);
|
||||
}
|
||||
});
|
||||
$(document).on(ace.click_event, 'button[data-goup=modal]', function() {
|
||||
var $this = $(this), url;
|
||||
if( $this.hasClass('disabled') || !(url = $this.attr('data-url')) ) return;
|
||||
|
||||
launch_help_modal(url , true)
|
||||
});
|
||||
|
||||
|
||||
$(document).on(ace.click_event, '.open-file[data-open-file]', function() {
|
||||
$('#onpage-help-modal').find('.modal-title').wrapInner("<span class='hidden' />").append('<i class="fa fa-spinner fa-spin blue bigger-125"></i>');
|
||||
$('.onpage-help-content').addClass('hidden')
|
||||
|
||||
var url = $(this).text();
|
||||
var language = $(this).attr('data-open-file');
|
||||
display_codeview(url, language, true);
|
||||
});
|
||||
|
||||
|
||||
function display_codeview(url, language, save_to_list) {
|
||||
$.ajax({url: $base+'/'+url, dataType:'text'})
|
||||
.done(function(content) {
|
||||
if(language != 'json') {
|
||||
if(language != 'css') {
|
||||
//replace each tab character with two spaces (only those that start at a new line)
|
||||
content = content.replace(/\n[\t]{1,}/g, function(p, q) {
|
||||
return p.replace(/\t/g, " ");
|
||||
});
|
||||
} else {
|
||||
content = content.replace(/\t/g , " ")
|
||||
}
|
||||
}
|
||||
else {
|
||||
language = '';
|
||||
content = JSON.stringify(JSON.parse(content), null, 2);
|
||||
}
|
||||
|
||||
var modal = $('#onpage-help-modal');
|
||||
add_to_nav_list('file:'+language+':'+url, save_to_list);
|
||||
modal.find('button[data-goup=modal]').addClass('disabled').blur();
|
||||
|
||||
content = content.replace(/\>/g, '>').replace(/\</g, '<')
|
||||
Rainbow.color(content, language, function(highlighted_code) {
|
||||
modal.find('.modal-title').html(url).wrapInner('<code />');;
|
||||
$('.onpage-help-content').removeClass('hidden').empty().html(highlighted_code).wrapInner('<pre data-language="'+language+'" />');
|
||||
modal.find('.modal-body').ace_scroll('reset');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
17
static/js/lib/ace/ace/ace.searchbox-autocomplete.js
Normal file
17
static/js/lib/ace/ace/ace.searchbox-autocomplete.js
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
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>
|
||||
*/
|
||||
ace.enable_searchbox_autocomplete = function($) {
|
||||
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').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) {}
|
||||
}
|
||||
101
static/js/lib/ace/ace/ace.settings-rtl.js
Normal file
101
static/js/lib/ace/ace/ace.settings-rtl.js
Normal file
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
<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.
|
||||
*/
|
||||
|
||||
|
||||
ace.settings_rtl = function($) {
|
||||
//Switching to RTL (right to left) Mode
|
||||
$('#ace-settings-rtl').removeAttr('checked').on('click', function(){
|
||||
ace.switch_direction(jQuery);
|
||||
});
|
||||
}
|
||||
|
||||
//>>> 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
|
||||
ace.switch_direction = function($) {
|
||||
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
|
||||
|
||||
//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" />');
|
||||
}
|
||||
else {
|
||||
//remove the wrap
|
||||
$('.scroll-hz').removeClass('make-ltr')
|
||||
.find('.make-rtl').children().unwrap();
|
||||
}
|
||||
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) {}
|
||||
|
||||
|
||||
//force redraw(because of webkit)
|
||||
/**setTimeout(function() {
|
||||
ace.helper.redraw(document.body);
|
||||
ace.helper.redraw($('.main-content').get(0));
|
||||
}, 10);*/
|
||||
}
|
||||
94
static/js/lib/ace/ace/ace.settings-skin.js
Normal file
94
static/js/lib/ace/ace/ace.settings-skin.js
Normal file
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
<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.
|
||||
*/
|
||||
|
||||
ace.settings_skin = function($) {
|
||||
try {
|
||||
$('#skin-colorpicker').ace_colorpicker();
|
||||
} catch(e) {}
|
||||
|
||||
$('#skin-colorpicker').on('change', function(){
|
||||
var skin_class = $(this).find('option:selected').data('skin');
|
||||
//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]);
|
||||
})
|
||||
}
|
||||
|
||||
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]);
|
||||
})
|
||||
}
|
||||
|
||||
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');
|
||||
}
|
||||
|
||||
//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++]);
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
//some sizing differences may be there in skins, so reset scrollbar size
|
||||
if('sidebar_scroll' in ace.helper) ace.helper.sidebar_scroll.reset();
|
||||
|
||||
});
|
||||
}
|
||||
85
static/js/lib/ace/ace/ace.settings.js
Normal file
85
static/js/lib/ace/ace/ace.settings.js
Normal file
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
<b>Settings box</b>. It's good for demo only. You don't need this.
|
||||
*/
|
||||
ace.settings_box = function($) {
|
||||
$('#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(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(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(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(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').removeAttr('checked').on('click', function(){
|
||||
if(this.checked) {
|
||||
$('#sidebar').addClass('compact');
|
||||
var hover = $('#ace-settings-hover');
|
||||
if( hover.length > 0 && !hover.get(0).checked ) {
|
||||
hover.removeAttr('checked').trigger('click');
|
||||
}
|
||||
}
|
||||
else {
|
||||
$('#sidebar').removeClass('compact');
|
||||
if('sidebar_scroll' in ace.helper) ace.helper.sidebar_scroll.reset();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$('#ace-settings-highlight').removeAttr('checked').on('click', function(){
|
||||
if(this.checked) $('#sidebar .nav-list > li').addClass('highlight');
|
||||
else $('#sidebar .nav-list > li').removeClass('highlight');
|
||||
});
|
||||
|
||||
|
||||
$('#ace-settings-hover').removeAttr('checked').on('click', function(){
|
||||
if($('.sidebar').hasClass('h-sidebar')) return;
|
||||
if(this.checked) {
|
||||
ace.vars['no-scroll'] = true;
|
||||
|
||||
$('#sidebar li').addClass('hover')
|
||||
.filter('.open').removeClass('open').find('> .submenu').css('display', 'none');
|
||||
//and remove .open items
|
||||
}
|
||||
else {
|
||||
ace.vars['no-scroll'] = false;
|
||||
$('#sidebar li.hover').removeClass('hover');
|
||||
|
||||
var compact = $('#ace-settings-compact');
|
||||
if( compact.length > 0 && compact.get(0).checked ) {
|
||||
compact.trigger('click');
|
||||
}
|
||||
|
||||
if('sidebar_hover' in ace.helper) ace.helper.sidebar_hover.reset();
|
||||
}
|
||||
|
||||
if('sidebar_scroll' in ace.helper) ace.helper.sidebar_scroll.reset();
|
||||
});
|
||||
|
||||
}
|
||||
355
static/js/lib/ace/ace/ace.sidebar-scroll-1.js
Normal file
355
static/js/lib/ace/ace/ace.sidebar-scroll-1.js
Normal file
@@ -0,0 +1,355 @@
|
||||
/**
|
||||
<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.
|
||||
*/
|
||||
|
||||
ace.sidebar_scrollable = function($ , scroll_to_active, include_shortcuts, include_toggle, smooth_scroll, scrollbars_outside) {
|
||||
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 $sidebar = $('.sidebar'),
|
||||
$navbar = $('.navbar'),
|
||||
$nav = $sidebar.find('.nav-list'),
|
||||
$toggle = $sidebar.find('.sidebar-toggle'),
|
||||
$shortcuts = $sidebar.find('.sidebar-shortcuts'),
|
||||
$window = $(window),
|
||||
|
||||
sidebar = $sidebar.get(0),
|
||||
nav = $nav.get(0);
|
||||
|
||||
if(!sidebar || !nav) return;
|
||||
|
||||
|
||||
var scroll_div = null,
|
||||
scroll_content = null,
|
||||
scroll_content_div = null,
|
||||
bar = null,
|
||||
ace_scroll = null;
|
||||
|
||||
var is_scrolling = false,
|
||||
_initiated = false;
|
||||
|
||||
var scroll_to_active = scroll_to_active || false,
|
||||
include_shortcuts = include_shortcuts || false,
|
||||
include_toggle = include_toggle || false,
|
||||
only_if_fixed = true;
|
||||
|
||||
var is_sidebar_fixed =
|
||||
'getComputedStyle' in window ?
|
||||
//sidebar.offsetHeight is used to force redraw and recalculate 'sidebar.style.position' esp for webkit!
|
||||
function() { sidebar.offsetHeight; return window.getComputedStyle(sidebar).position == 'fixed' }
|
||||
:
|
||||
function() { sidebar.offsetHeight; return $sidebar.css('position') == 'fixed' }
|
||||
//sometimes when navbar is fixed, sidebar automatically becomes fixed without needing ".sidebar-fixed" class
|
||||
//currently when mobile_style == 1
|
||||
|
||||
var $avail_height, $content_height;
|
||||
var sidebar_fixed = is_sidebar_fixed(),
|
||||
horizontal = $sidebar.hasClass('h-sidebar');
|
||||
|
||||
|
||||
var scrollbars = ace.helper.sidebar_scroll = {
|
||||
available_height: function() {
|
||||
//available window space
|
||||
var offset = $nav.parent().offset();//because `$nav.offset()` considers the "scrolled top" amount as well
|
||||
if(sidebar_fixed) offset.top -= ace.helper.scrollTop();
|
||||
|
||||
return $window.innerHeight() - offset.top - ( include_toggle ? 0 : $toggle.outerHeight() );
|
||||
},
|
||||
content_height: function() {
|
||||
return nav.scrollHeight;
|
||||
},
|
||||
initiate: function(on_page_load) {
|
||||
if( _initiated ) return;
|
||||
if( !sidebar_fixed ) return;//eligible??
|
||||
//return if we want scrollbars only on "fixed" sidebar and sidebar is not "fixed" yet!
|
||||
|
||||
//initiate once
|
||||
$nav.wrap('<div style="position: relative;" />');
|
||||
$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: scrollbars.available_height(),
|
||||
reset: true,
|
||||
mouseWheelLock: true,
|
||||
hoverReset: false,
|
||||
dragEvent: true,
|
||||
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);
|
||||
bar = scroll_div.find('.scroll-bar').eq(0);
|
||||
|
||||
if(include_shortcuts) {
|
||||
$nav.parent().prepend($shortcuts).wrapInner('<div />');
|
||||
$nav = $nav.parent();
|
||||
}
|
||||
if(include_toggle) {
|
||||
$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';
|
||||
});
|
||||
$nav.on('mousewheel.ace_scroll DOMMouseScroll.ace_scroll', function(event){
|
||||
//transfer $nav's mousewheel event to scrollbars
|
||||
return scroll_div.trigger(event);
|
||||
});
|
||||
|
||||
|
||||
//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(!is_scrolling) return;
|
||||
|
||||
if(event.direction == 'up' || event.direction == 'down') {
|
||||
//event.stopPropagation();
|
||||
|
||||
ace_scroll.move_bar(true);
|
||||
move_nav = false;//update "nav.style.top" here no need to do this on('scroll.nav')!
|
||||
|
||||
var distance = event.dy;
|
||||
|
||||
//distance = parseInt(Math.min($avail_height, distance))
|
||||
if(Math.abs(distance) > 20) 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('ace_dragStart.nav', function(event) {
|
||||
event.stopPropagation();
|
||||
|
||||
$nav.css('transition-property', 'none');
|
||||
bar.css('transition-property', 'none');
|
||||
}).on('ace_dragEnd.nav', function(event) {
|
||||
event.stopPropagation();
|
||||
|
||||
$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) {
|
||||
scrollbars.reset();//try resetting at first
|
||||
|
||||
if( scroll_to_active && ace_scroll.is_active() ) {
|
||||
var $active;
|
||||
|
||||
var nav_list = $sidebar.find('.nav-list')
|
||||
if(ace.vars['minimized'] && !ace.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);
|
||||
}
|
||||
}
|
||||
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() {
|
||||
scrollbars.reset();
|
||||
}, 20 );
|
||||
}
|
||||
|
||||
var last_height = ace.helper.winHeight() , new_height;
|
||||
$(window).on('scroll.ace_scroll', function() {
|
||||
if(is_scrolling && ace_scroll.is_active()) {
|
||||
new_height = ace.helper.winHeight();
|
||||
if(new_height != last_height) {
|
||||
last_height = new_height;
|
||||
scrollbars.reset();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
if( !sidebar_fixed ) {
|
||||
scrollbars.disable();
|
||||
return;//eligible??
|
||||
}
|
||||
//return if we want scrollbars only on "fixed" sidebar and sidebar is not "fixed" yet!
|
||||
|
||||
if( !_initiated ) scrollbars.initiate();
|
||||
//initiate scrollbars if not yet
|
||||
|
||||
|
||||
|
||||
|
||||
//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 = !ace.vars['collapsible']
|
||||
&& (!horizontal || (horizontal && ace.vars['mobile_view']))
|
||||
&& ($avail_height = scrollbars.available_height()) < ($content_height = nav.scrollHeight);
|
||||
|
||||
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}).enable().reset();
|
||||
}
|
||||
if( !enable_scroll || !ace_scroll.is_active() ) {
|
||||
if(is_scrolling) scrollbars.disable();
|
||||
}
|
||||
else $sidebar.addClass('sidebar-scroll');
|
||||
|
||||
//return is_scrolling;
|
||||
},
|
||||
disable : function() {
|
||||
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 && ace.vars['transition']) {
|
||||
$nav.one('transitionend.trans webkitTransitionEnd.trans mozTransitionEnd.trans oTransitionEnd.trans', function() {
|
||||
$sidebar.removeClass('sidebar-scroll');
|
||||
$nav.off('.trans');
|
||||
});
|
||||
} else {
|
||||
$sidebar.removeClass('sidebar-scroll');
|
||||
}
|
||||
|
||||
nav.style.top = 0;
|
||||
},
|
||||
prehide: function(height_change) {
|
||||
if(!is_scrolling || ace.vars['minimized']) return;
|
||||
|
||||
if(scrollbars.content_height() + height_change < scrollbars.available_height()) {
|
||||
scrollbars.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';
|
||||
}
|
||||
}
|
||||
}
|
||||
scrollbars.initiate(true);//true = on_page_load
|
||||
|
||||
//reset on document and window changes
|
||||
$(document).on('settings.ace.scroll', function(ev, event_name, event_val){
|
||||
if( event_name == 'sidebar_collapsed' && sidebar_fixed ) {
|
||||
scrollbars.reset();
|
||||
}
|
||||
else if( event_name === 'sidebar_fixed' || event_name === 'navbar_fixed' ) {
|
||||
//sidebar_fixed = event_val;
|
||||
sidebar_fixed = is_sidebar_fixed()
|
||||
|
||||
if(sidebar_fixed && !is_scrolling) {
|
||||
scrollbars.reset();
|
||||
}
|
||||
else if( !sidebar_fixed ) {
|
||||
scrollbars.disable();
|
||||
}
|
||||
}
|
||||
});
|
||||
$window.on('resize.ace.scroll', function(){
|
||||
sidebar_fixed = is_sidebar_fixed()
|
||||
scrollbars.reset();
|
||||
})
|
||||
|
||||
|
||||
//change scrollbar size after a submenu is hidden/shown
|
||||
//but don't change if sidebar is minimized
|
||||
$sidebar.on('hidden.ace.submenu shown.ace.submenu', '.submenu', function(e) {
|
||||
e.stopPropagation();
|
||||
|
||||
if(!ace.vars['minimized']) {
|
||||
//webkit has a little bit of a glitch!!!
|
||||
if(ace.vars['webkit']) setTimeout(function() { scrollbars.reset() } , 0);
|
||||
else scrollbars.reset();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
229
static/js/lib/ace/ace/ace.sidebar-scroll-2.js
Normal file
229
static/js/lib/ace/ace/ace.sidebar-scroll-2.js
Normal file
@@ -0,0 +1,229 @@
|
||||
/**
|
||||
<b>Scrollbars for sidebar</b>. This approach can be used on fixed or normal sidebar.
|
||||
It uses <u>"overflow:hidden"</u> so you can't use <u>.hover</u> submenus and it will be disabled when sidebar is minimized.
|
||||
It may also be marginally (negligibily) faster especially when resizing browser window.
|
||||
*/
|
||||
|
||||
ace.sidebar_scrollable = function($ , only_if_fixed, scroll_to_active, include_shortcuts, include_toggle) {
|
||||
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 $sidebar = $('.sidebar'),
|
||||
$navbar = $('.navbar'),
|
||||
$nav = $sidebar.find('.nav-list'),
|
||||
$toggle = $sidebar.find('.sidebar-toggle'),
|
||||
$shortcuts = $sidebar.find('.sidebar-shortcuts'),
|
||||
$window = $(window),
|
||||
|
||||
sidebar = $sidebar.get(0),
|
||||
nav = $nav.get(0);
|
||||
|
||||
if(!sidebar || !nav) return;
|
||||
|
||||
if( $sidebar.find('li.hover').length > 0 ) ace.vars['no-scroll'] = true;
|
||||
|
||||
var scroll_div = null,
|
||||
scroll_content = null,
|
||||
scroll_content_div = null,
|
||||
bar = null,
|
||||
ace_scroll = null;
|
||||
|
||||
var is_scrolling = false,
|
||||
_initiated = false;
|
||||
|
||||
var scroll_to_active = scroll_to_active || false,
|
||||
include_shortcuts = include_shortcuts || false,
|
||||
include_toggle = include_toggle || false,
|
||||
only_if_fixed = only_if_fixed && true;
|
||||
|
||||
var is_sidebar_fixed =
|
||||
'getComputedStyle' in window ?
|
||||
//sidebar.offsetHeight is used to force redraw and recalculate 'sidebar.style.position' esp for webkit!
|
||||
function() { sidebar.offsetHeight; return window.getComputedStyle(sidebar).position == 'fixed' }
|
||||
:
|
||||
function() { sidebar.offsetHeight; return $sidebar.css('position') == 'fixed' }
|
||||
//sometimes when navbar is fixed, sidebar automatically becomes fixed without needing ".sidebar-fixed" class
|
||||
//currently when mobile_style == 1
|
||||
|
||||
var $avail_height, $content_height;
|
||||
var sidebar_fixed = is_sidebar_fixed(),
|
||||
horizontal = $sidebar.hasClass('h-sidebar');
|
||||
|
||||
|
||||
var scrollbars = ace.helper.sidebar_scroll = {
|
||||
available_height: function() {
|
||||
//available window space
|
||||
var offset = $nav.parent().offset();//because `$nav.offset()` considers the "scrolled top" amount as well
|
||||
if(sidebar_fixed) offset.top -= ace.helper.scrollTop();
|
||||
|
||||
return $window.innerHeight() - offset.top - ( include_toggle ? 0 : $toggle.outerHeight() );
|
||||
},
|
||||
content_height: function() {
|
||||
return nav.scrollHeight;
|
||||
},
|
||||
initiate: function(on_page_load) {
|
||||
if( _initiated ) return;
|
||||
if( (only_if_fixed && !sidebar_fixed) || ace.vars['no-scroll'] === true ) return;//eligible??
|
||||
//return if we want scrollbars only on "fixed" sidebar and sidebar is not "fixed" yet!
|
||||
|
||||
//initiate once
|
||||
$nav.wrap('<div />');
|
||||
if(include_shortcuts) $nav.parent().prepend($shortcuts);
|
||||
if(include_toggle) $nav.parent().append($toggle);
|
||||
|
||||
scroll_div = $nav.parent()
|
||||
.ace_scroll({
|
||||
size: scrollbars.available_height(),
|
||||
reset: true,
|
||||
mouseWheelLock: true,
|
||||
hoverReset: false
|
||||
})
|
||||
.closest('.ace-scroll').addClass('nav-scroll');
|
||||
|
||||
ace_scroll = scroll_div.data('ace_scroll');
|
||||
|
||||
scroll_content = scroll_div.find('.scroll-content').eq(0);
|
||||
|
||||
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) {
|
||||
scrollbars.reset();//try resetting at first
|
||||
|
||||
if( scroll_to_active && ace_scroll.is_active() ) {
|
||||
var $active;
|
||||
|
||||
var nav_list = $sidebar.find('.nav-list')
|
||||
if(ace.vars['minimized'] && !ace.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) {
|
||||
scroll_content.scrollTop(scroll_amount);
|
||||
}
|
||||
}
|
||||
scroll_to_active = false;
|
||||
}
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
if( (only_if_fixed && !sidebar_fixed) || ace.vars['no-scroll'] === true ) {
|
||||
scrollbars.disable();
|
||||
return;//eligible??
|
||||
}
|
||||
//return if we want scrollbars only on "fixed" sidebar and sidebar is not "fixed" yet!
|
||||
|
||||
if( !_initiated ) scrollbars.initiate();
|
||||
//initiate scrollbars if not yet
|
||||
|
||||
$sidebar.addClass('sidebar-scroll');
|
||||
|
||||
|
||||
//enable if:
|
||||
//menu is not minimized
|
||||
//menu is not collapsible mode (responsive navbar-collapse mode which has default browser scroller)
|
||||
//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 = !ace.vars['minimized'] && !ace.vars['collapsible']
|
||||
&& (!horizontal || (horizontal && ace.vars['mobile_view']))
|
||||
&& ($avail_height = scrollbars.available_height()) < ($content_height = nav.parentNode.scrollHeight);
|
||||
|
||||
is_scrolling = true;
|
||||
if( enable_scroll && ace_scroll ) {
|
||||
//scroll_content_div.css({height: $content_height, width: 8});
|
||||
//scroll_div.prev().css({'max-height' : $avail_height})
|
||||
ace_scroll.update({size: $avail_height}).enable().reset();
|
||||
}
|
||||
if( !enable_scroll || !ace_scroll.is_active() ) {
|
||||
if(is_scrolling) scrollbars.disable();
|
||||
}
|
||||
//return is_scrolling;
|
||||
},
|
||||
disable : function() {
|
||||
is_scrolling = false;
|
||||
if(ace_scroll) ace_scroll.disable();
|
||||
|
||||
$sidebar.removeClass('sidebar-scroll');
|
||||
},
|
||||
prehide: function(height_change) {
|
||||
if( !is_scrolling || ace.vars['minimized'] ) return;
|
||||
|
||||
if(scrollbars.content_height() + height_change < scrollbars.available_height()) {
|
||||
scrollbars.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;
|
||||
|
||||
scroll_content.scrollTop(scroll_top);
|
||||
}
|
||||
}
|
||||
}
|
||||
scrollbars.initiate(true);//true = on_page_load
|
||||
|
||||
//reset on document and window changes
|
||||
$(document).on('settings.ace.scroll', function(ev, event_name, event_val){
|
||||
if( event_name == 'sidebar_collapsed' ) {
|
||||
if(event_val == true) scrollbars.disable();//disable scroll if collapsed
|
||||
else scrollbars.reset();
|
||||
}
|
||||
else if( event_name === 'sidebar_fixed' || event_name === 'navbar_fixed' ) {
|
||||
//sidebar_fixed = event_val;
|
||||
sidebar_fixed = is_sidebar_fixed()
|
||||
|
||||
if(sidebar_fixed && !is_scrolling) {
|
||||
scrollbars.reset();
|
||||
}
|
||||
else if(!sidebar_fixed && only_if_fixed) {
|
||||
scrollbars.disable();
|
||||
}
|
||||
}
|
||||
});
|
||||
$window.on('resize.ace.scroll', function(){
|
||||
sidebar_fixed = is_sidebar_fixed()
|
||||
scrollbars.reset();
|
||||
})
|
||||
|
||||
|
||||
//change scrollbar size after a submenu is hidden/shown
|
||||
//but don't change if sidebar is minimized
|
||||
$sidebar.on('hidden.ace.submenu shown.ace.submenu', '.submenu', function(e) {
|
||||
e.stopPropagation();
|
||||
|
||||
if(!ace.vars['minimized']) {
|
||||
//webkit has a little bit of a glitch!!!
|
||||
if(ace.vars['webkit']) setTimeout(function() { scrollbars.reset() } , 0);
|
||||
else scrollbars.reset();
|
||||
}
|
||||
});
|
||||
}
|
||||
155
static/js/lib/ace/ace/ace.sidebar.js
Normal file
155
static/js/lib/ace/ace/ace.sidebar.js
Normal file
@@ -0,0 +1,155 @@
|
||||
/**
|
||||
<b>Sidebar functions</b>. Collapsing/expanding, toggling mobile view menu and other sidebar functions.
|
||||
*/
|
||||
|
||||
ace.handle_side_menu = function($) {
|
||||
var sidebar = $('.sidebar').eq(0);
|
||||
|
||||
$(document).on(ace.click_event+'.ace.menu', '#menu-toggler', function(){
|
||||
sidebar.toggleClass('display');
|
||||
$(this).toggleClass('display');
|
||||
|
||||
if( $(this).hasClass('display') && 'sidebar_scroll' in ace.helper )
|
||||
{
|
||||
ace.helper.sidebar_scroll.reset();
|
||||
}
|
||||
|
||||
return false;
|
||||
})
|
||||
//sidebar collapse/expand button
|
||||
.on(ace.click_event+'.ace.menu', '.sidebar-collapse', function(){
|
||||
if(ace.vars['collapsible'] || ace.vars['horizontal']) return;
|
||||
|
||||
//var minimized = sidebar.hasClass('menu-min');
|
||||
ace.vars['minimized'] = !ace.vars['minimized'];
|
||||
ace.settings.sidebar_collapsed.call(this, ace.vars['minimized']);//@ ace-extra.js
|
||||
//ace.settings.sidebar_collapsed(ace.vars['minimized']);
|
||||
})
|
||||
//this button is used in `mobile_style = 3` responsive menu style to expand minimized sidebar
|
||||
.on(ace.click_event+'.ace.menu', '.sidebar-expand', function(){
|
||||
|
||||
if( ace.vars['minimized'] /**sidebar.hasClass('menu-min')*/ ) {
|
||||
ace.settings.sidebar_collapsed.call(this, false , false);
|
||||
//unminimize (remove .menu-min) but don't save changes to cookies
|
||||
}
|
||||
|
||||
var icon = $(this).find(ace.vars['.icon']);
|
||||
var $icon1 = icon.attr('data-icon1');//the icon for expanded state
|
||||
var $icon2 = icon.attr('data-icon2');//the icon for collapsed state
|
||||
if( sidebar.hasClass('responsive-min') ) {
|
||||
icon.removeClass($icon1).addClass($icon2);
|
||||
sidebar.removeClass('responsive-min');
|
||||
sidebar.addClass('display responsive-max');
|
||||
|
||||
ace.vars['minimized'] = false
|
||||
}
|
||||
else {
|
||||
icon.removeClass($icon2).addClass($icon1);
|
||||
sidebar.removeClass('display responsive-max');
|
||||
sidebar.addClass('responsive-min');
|
||||
|
||||
ace.vars['minimized'] = true
|
||||
}
|
||||
|
||||
$(document).triggerHandler('settings.ace', ['sidebar_collapsed' , ace.vars['minimized']]);
|
||||
});
|
||||
|
||||
|
||||
|
||||
//ios safari only has a bit of a problem not navigating to link address when scrolling down
|
||||
var ios_fix = ace.vars['ios_safari'];//navigator.userAgent.match(/OS (5|6|7)(_\d)+ like Mac OS X/i);
|
||||
//toggling submenu
|
||||
$(document).on(ace.click_event+'.ace.submenu', '.sidebar .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 = ace.vars['minimized'] && !ace.vars['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( ev.target != text && !$.contains(text , ev.target) ) {//not clicking on the text or its children
|
||||
ev.preventDefault();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//some browsers need to be forced
|
||||
if(ios_fix && link_element.attr('data-link') !== 'false') {//specify data-link attribute to ignore this
|
||||
//ios safari only has a bit of a problem not navigating to link address when scrolling down
|
||||
//please see issues section
|
||||
document.location = link_element.attr('href');
|
||||
ev.preventDefault();
|
||||
return false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var sub = link_element.siblings('.submenu').get(0);
|
||||
if(!sub) return false;
|
||||
|
||||
var height_change = 0;//the amount of height change in .nav-list
|
||||
var duration = 250;//transition duration
|
||||
|
||||
var parent_ul = sub.parentNode.parentNode;
|
||||
if
|
||||
(
|
||||
( minimized && parent_ul == nav_list )
|
||||
||
|
||||
( $(sub.parentNode).hasClass('hover') && !ace.vars['collapsible'] )
|
||||
)
|
||||
{
|
||||
ev.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
//if not open and visible, let's open it and make it visible
|
||||
if( sub.scrollHeight == 0 ) {
|
||||
$(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;
|
||||
ace.submenu.hide(this, duration);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
var toggle = 0;
|
||||
if( (toggle = ace.submenu.toggle(sub , duration)) == 1 ) {
|
||||
//== 1 means submenu is being shown
|
||||
//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;
|
||||
} else if(toggle == -1) {
|
||||
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
|
||||
if (height_change != 0 && 'sidebar_scroll' in ace.helper) {
|
||||
ace.helper.sidebar_scroll.prehide(height_change);
|
||||
}
|
||||
|
||||
ev.preventDefault();
|
||||
return false;
|
||||
})
|
||||
}
|
||||
111
static/js/lib/ace/ace/ace.submenu-1.js
Normal file
111
static/js/lib/ace/ace/ace.submenu-1.js
Normal file
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
<b>Toggle sidebar submenus</b>. This approach uses <u>CSS3</u> transitions.
|
||||
It's a bit smoother but the transition does not work on IE9 and below and it is sometimes glitchy on Android's default browser.
|
||||
*/
|
||||
|
||||
//CSS3 transition version, no animation on IE9 and below
|
||||
ace.submenu = {
|
||||
show : function(sub, 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');
|
||||
|
||||
if( duration > 0 ) {
|
||||
$sub.css({height: sub.scrollHeight,
|
||||
'transition-property': 'height',
|
||||
'transition-duration': (duration/1000)+'s'})
|
||||
}
|
||||
|
||||
var complete = function(ev) {
|
||||
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(ace.vars['transition']) $sub.off('.trans');
|
||||
$sub.trigger($.Event('shown.ace.submenu'))
|
||||
}
|
||||
if( duration > 0 && ace.vars['transition'] ) {
|
||||
$sub.one('transitionend.trans webkitTransitionEnd.trans mozTransitionEnd.trans oTransitionEnd.trans', complete);
|
||||
}
|
||||
else complete();
|
||||
|
||||
//there is sometimes a glitch, so maybe retry
|
||||
if(ace.vars['android']) {
|
||||
setTimeout(function() {
|
||||
$sub.css({overflow:'', height: ''});
|
||||
}, duration + 10);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
,
|
||||
hide : function(sub, 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'
|
||||
})
|
||||
.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) {
|
||||
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(ace.vars['transition']) $sub.off('.trans');
|
||||
$sub.trigger($.Event('hidden.ace.submenu'))
|
||||
}
|
||||
if( duration > 0 && ace.vars['transition'] ) {
|
||||
$sub.one('transitionend.trans webkitTransitionEnd.trans mozTransitionEnd.trans oTransitionEnd.trans', complete);
|
||||
}
|
||||
else complete();
|
||||
|
||||
|
||||
//there is sometimes a glitch, so maybe retry
|
||||
if(ace.vars['android']) {
|
||||
setTimeout(function() {
|
||||
$sub.css({display: 'none', overflow:'', height: ''})
|
||||
}, duration + 10);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
,
|
||||
toggle : function(element, duration) {
|
||||
if( element.scrollHeight == 0 ) {//if an element is hidden scrollHeight becomes 0
|
||||
if(ace.submenu.show(element, duration)) return 1;
|
||||
} else {
|
||||
if(ace.submenu.hide(element, duration)) return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
74
static/js/lib/ace/ace/ace.submenu-2.js
Normal file
74
static/js/lib/ace/ace/ace.submenu-2.js
Normal file
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
<b>Toggle sidebar submenus</b>. This approach uses <u>jQuery</u> animation and works on all browsers.
|
||||
*/
|
||||
|
||||
ace.submenu = {
|
||||
show : function(sub, 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 < 992px and .sidebar.navbar-collapse.menu-min
|
||||
|
||||
var complete = function() {
|
||||
$sub
|
||||
.css({overflow:'', height:''})
|
||||
|
||||
if(ace.vars.webkit) ace.helper.redraw(sub);//little webkit issue, force redraw ;)
|
||||
|
||||
$sub.trigger($.Event('shown.ace.submenu'))
|
||||
}
|
||||
|
||||
$sub.parent().addClass('open');
|
||||
if(duration > 0) {
|
||||
$sub.animate({height:sub.scrollHeight} , {
|
||||
duration: duration,
|
||||
complete: complete
|
||||
})
|
||||
} else complete();
|
||||
|
||||
return true;
|
||||
}
|
||||
,
|
||||
hide : function(sub, duration) {
|
||||
var $sub = $(sub);
|
||||
|
||||
var event;
|
||||
$sub.trigger(event = $.Event('hide.ace.submenu'))
|
||||
if (event.isDefaultPrevented()) return false;
|
||||
|
||||
var complete = function() {
|
||||
$sub
|
||||
.css({display:'none', overflow:'', height:''})
|
||||
.removeClass('nav-show').addClass('nav-hide')//only for window < @grid-float-breakpoint and .navbar-collapse.menu-min
|
||||
|
||||
$sub.trigger($.Event('hidden.ace.submenu'))
|
||||
}
|
||||
|
||||
$sub
|
||||
.css({overflow:'hidden', height:sub.scrollHeight})
|
||||
.parent().removeClass('open');
|
||||
|
||||
if(duration > 0) {
|
||||
$sub.animate({height:0}, {
|
||||
duration: duration,
|
||||
complete: complete
|
||||
})
|
||||
} else complete();
|
||||
|
||||
return true;
|
||||
}
|
||||
,
|
||||
toggle : function(element, duration) {
|
||||
if( element.scrollHeight == 0 ) {//if an element is hidden scrollHeight is 0
|
||||
if(ace.submenu.show(element, duration)) return 1;
|
||||
} else {
|
||||
if(ace.submenu.hide(element, duration)) return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
173
static/js/lib/ace/ace/ace.submenu-hover.js
Normal file
173
static/js/lib/ace/ace/ace.submenu-hover.js
Normal file
@@ -0,0 +1,173 @@
|
||||
/**
|
||||
<b>Submenu hover adjustment</b>. Automatically move up a submenu to fit into screen when some part of it goes beneath window.
|
||||
*/
|
||||
|
||||
ace.sidebar_hoverable = function($) {
|
||||
if( !('querySelector' in document) || !('removeProperty' in document.body.style) ) return;
|
||||
//ignore IE8 & below
|
||||
|
||||
//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"
|
||||
ace.helper.sidebar_hover = {
|
||||
reset : function() {
|
||||
$sidebar.find('.submenu').each(function() {
|
||||
var sub = this, li = this.parentNode;
|
||||
if(sub) {
|
||||
sub.style.removeProperty('top')
|
||||
sub.style.removeProperty('bottom');
|
||||
|
||||
var menu_text = li.querySelector('.menu-text');
|
||||
if(menu_text) {
|
||||
menu_text.style.removeProperty('margin-top')
|
||||
}
|
||||
}
|
||||
|
||||
if( li.className.lastIndexOf('_up') >= 0 ) {//has .pull_up
|
||||
$(li).removeClass('pull_up');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var is_navbar_fixed =
|
||||
'getComputedStyle' in window ?
|
||||
//navbar.offsetHeight is used to force redraw and recalculate 'sidebar.style.position' esp for webkit!
|
||||
function() { navbar.offsetHeight; return window.getComputedStyle(navbar).position == 'fixed' }
|
||||
:
|
||||
function() { navbar.offsetHeight; return $navbar.css('position') == 'fixed' }
|
||||
$(window).on('resize.ace_hover', function() {
|
||||
navbar_fixed = is_navbar_fixed();
|
||||
ace.helper.sidebar_hover.reset();
|
||||
})
|
||||
$(document).on('settings.ace.hover', function(e, event_name, event_val) {
|
||||
if(event_name == 'sidebar_collapsed') ace.helper.sidebar_hover.reset();
|
||||
else if(event_name == 'navbar_fixed') navbar_fixed = event_val;
|
||||
})
|
||||
|
||||
///////////////////////////////////////////////
|
||||
var $sidebar = $('.sidebar').eq(0),
|
||||
sidebar = $sidebar.get(0),
|
||||
nav_list = $sidebar.find('.nav-list').get(0);
|
||||
|
||||
var $navbar = $('.navbar').eq(0),
|
||||
navbar = $navbar.get(0),
|
||||
horizontal = $sidebar.hasClass('h-sidebar'),
|
||||
|
||||
navbar_fixed = $navbar.css('position') == 'fixed';
|
||||
|
||||
$sidebar.find('.submenu').parent().addClass('hsub');//add .hsub (has-sub) class
|
||||
|
||||
//some mobile browsers don't have mouseenter
|
||||
$sidebar.on('mouseenter.ace_hover', '.nav-list li.hsub', function (e) {
|
||||
//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( ace.vars['collapsible'] || (horizontal && !ace.vars['mobile_view']) ) return;
|
||||
|
||||
var sub = this.querySelector('.submenu');
|
||||
if(sub) {
|
||||
//try to move/adjust submenu if the parent is a li.hover
|
||||
if( ace.helper.hasClass(this, 'hover') ) {
|
||||
|
||||
adjust_submenu.call(this, sub);
|
||||
}
|
||||
//or if submenu is minimized
|
||||
else if( this.parentNode == nav_list && ace.vars['minimized'] ) {
|
||||
|
||||
adjust_submenu.call(this, sub);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
var $diff = 50;
|
||||
function adjust_submenu(sub) {
|
||||
var $sub = $(sub);
|
||||
sub.style.removeProperty('top')
|
||||
sub.style.removeProperty('bottom');
|
||||
|
||||
var menu_text = null
|
||||
if( ace.vars['minimized'] && (menu_text = sub.parentNode.querySelector('.menu-text')) ) {
|
||||
//2nd level items don't have .menu-text
|
||||
menu_text.style.removeProperty('margin-top')
|
||||
}
|
||||
|
||||
var off = $sub.offset();
|
||||
var scroll = ace.helper.scrollTop();
|
||||
var pull_up = false;
|
||||
|
||||
var $scroll = scroll
|
||||
if( navbar_fixed ) {
|
||||
$scroll += navbar.clientHeight + 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 sub_h = sub.scrollHeight;
|
||||
if(menu_text) {
|
||||
sub_h += 40;
|
||||
off.top -= 40;
|
||||
}
|
||||
var sub_bottom = parseInt(off.top + sub_h)
|
||||
|
||||
var diff
|
||||
//if the bottom of menu is going to go below visible window
|
||||
if( (diff = sub_bottom - (window.innerHeight + scroll - 50)) > 0 ) {
|
||||
|
||||
//if it needs to be moved top a lot! use bottom unless it makes it go out of window top
|
||||
if(sub_h - diff < $diff && off.top - diff > $scroll ) {
|
||||
sub.style.top = 'auto';
|
||||
sub.style.bottom = '-10px';
|
||||
|
||||
if( menu_text ) {
|
||||
//menu_text.style.marginTop = -(sub_h - 10)+'px';
|
||||
menu_text.style.marginTop = -(sub_h - 50)+'px';// -10 - 40 for the above extra 40
|
||||
pull_up = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//when top of menu goes out of browser window's top or below fixed navbar
|
||||
if( off.top - diff < $scroll ) {
|
||||
diff = off.top - $scroll;
|
||||
}
|
||||
|
||||
//when bottom of menu goes above bottom of parent LI
|
||||
/** else */
|
||||
if(sub_bottom - diff < off.top + $diff) {
|
||||
diff -= $diff;
|
||||
}
|
||||
|
||||
var at_least = menu_text ? 40 : 20;//it we are going to move up less than at_least, then ignore
|
||||
if( diff > at_least ) {
|
||||
sub.style.top = -(diff) + 'px';
|
||||
if( menu_text ) {
|
||||
menu_text.style.marginTop = -(diff) + 'px';
|
||||
pull_up = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//pull_up means, pull the menu up a little bit, and some styling may need to change
|
||||
var pos = this.className.lastIndexOf('pull_up');//pull_up
|
||||
if (pull_up) {
|
||||
if (pos == -1)
|
||||
this.className = this.className + ' pull_up';
|
||||
} else {
|
||||
if (pos >= 0)
|
||||
this.className = this.className.replace(/(^|\s)pull_up($|\s)/ , '');
|
||||
}
|
||||
|
||||
|
||||
//again force redraw for safari!
|
||||
if( ace.vars['safari'] ) {
|
||||
ace.helper.redraw(sub)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
117
static/js/lib/ace/ace/ace.touch-drag.js
Normal file
117
static/js/lib/ace/ace/ace.touch-drag.js
Normal file
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
<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
|
||||
*
|
||||
*/
|
||||
ace.add_touch_drag = function($) {
|
||||
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 = {}
|
||||
start.origin.trigger({
|
||||
'type': 'ace_drag',
|
||||
//'start': start.coords,
|
||||
//'stop': stop.coords,
|
||||
'direction': direction,
|
||||
'dx': dx,
|
||||
'dy': dy,
|
||||
'retval': retval
|
||||
})
|
||||
|
||||
// prevent scrolling?
|
||||
//if(retval.cancel === true || event.cancel === undefined) {
|
||||
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;
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
220
static/js/lib/ace/ace/ace.widget-box.js
Normal file
220
static/js/lib/ace/ace/ace.widget-box.js
Normal file
@@ -0,0 +1,220 @@
|
||||
/**
|
||||
<b>Widget boxes</b>
|
||||
*/
|
||||
ace.widget_boxes = function($) {
|
||||
//bootstrap collapse component icon toggle
|
||||
$(document).on('hide.bs.collapse show.bs.collapse', function (ev) {
|
||||
var hidden_id = ev.target.getAttribute('id')
|
||||
$('[href*="#'+ hidden_id+'"]').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
|
||||
}
|
||||
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
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 $body_inner = $body.find('.widget-body-inner')
|
||||
if($body_inner.length == 0) {
|
||||
$body = $body.wrapInner('<div class="widget-body-inner"></div>').find(':first-child').eq(0);
|
||||
} else $body = $body_inner.eq(0);
|
||||
|
||||
|
||||
var expandSpeed = 300;
|
||||
var collapseSpeed = 200;
|
||||
|
||||
if( event_name == 'show' ) {
|
||||
if($icon) $icon.removeClass($icon_down).addClass($icon_up);
|
||||
$box.removeClass('collapsed');
|
||||
$body.slideUp(0 , function(){//do it once
|
||||
$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');
|
||||
}
|
||||
else {
|
||||
$icon.addClass($icon_expand).removeClass($icon_compress);
|
||||
this.$box.removeClass('fullscreen');
|
||||
}
|
||||
|
||||
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')
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
27
static/js/lib/ace/ace/ace.widget-on-reload.js
Normal file
27
static/js/lib/ace/ace/ace.widget-on-reload.js
Normal file
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
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>
|
||||
*/
|
||||
|
||||
ace.widget_reload_handler = function($) {
|
||||
//***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');
|
||||
});
|
||||
*/
|
||||
}
|
||||
109
static/js/lib/ace/ace/elements.colorpicker.js
Normal file
109
static/js/lib/ace/ace/elements.colorpicker.js
Normal file
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
<b>Custom color picker element</b>. Converts html select elements to a dropdown color picker.
|
||||
*/
|
||||
(function($ , undefined) {
|
||||
var Ace_Colorpicker = function(element, option) {
|
||||
var options = $.extend({}, $.fn.ace_colorpicker.defaults, option);
|
||||
|
||||
var $element = $(element);
|
||||
var color_list = '';
|
||||
var color_selected = '';
|
||||
var selection = null;
|
||||
var color_array = [];
|
||||
|
||||
$element.addClass('hide').find('option').each(function() {
|
||||
var $class = 'colorpick-btn';
|
||||
var color = this.value.replace(/[^\w\s,#\(\)\.]/g, '');
|
||||
if(this.value != color) this.value = color;
|
||||
if(this.selected) {
|
||||
$class += ' selected';
|
||||
color_selected = color;
|
||||
}
|
||||
color_array.push(color)
|
||||
color_list += '<li><a class="'+$class+'" href="#" style="background-color:'+color+';" data-color="'+color+'"></a></li>';
|
||||
}).
|
||||
end()
|
||||
.on('change.color', function(){
|
||||
$element.next().find('.btn-colorpicker').css('background-color', this.value);
|
||||
})
|
||||
.after('<div class="dropdown dropdown-colorpicker">\
|
||||
<a data-toggle="dropdown" class="dropdown-toggle" '+(options.auto_pos ? 'data-position="auto"' : '')+' href="#"><span class="btn-colorpicker" style="background-color:'+color_selected+'"></span></a><ul class="dropdown-menu'+(options.caret? ' dropdown-caret' : '')+(options.pull_right ? ' dropdown-menu-right' : '')+'">'+color_list+'</ul></div>')
|
||||
|
||||
|
||||
var dropdown = $element.next().find('.dropdown-menu')
|
||||
dropdown.on(ace.click_event, function(e) {
|
||||
var a = $(e.target);
|
||||
if(!a.is('.colorpick-btn')) return false;
|
||||
|
||||
if(selection) selection.removeClass('selected');
|
||||
selection = a;
|
||||
selection.addClass('selected');
|
||||
var color = selection.data('color');
|
||||
|
||||
$element.val(color).trigger('change');
|
||||
|
||||
e.preventDefault();
|
||||
return true;//to hide dropdown
|
||||
})
|
||||
selection = $element.next().find('a.selected');
|
||||
|
||||
this.pick = function(index, insert) {
|
||||
if(typeof index === 'number') {
|
||||
if(index >= color_array.length) return;
|
||||
element.selectedIndex = index;
|
||||
dropdown.find('a:eq('+index+')').trigger(ace.click_event);
|
||||
}
|
||||
else if(typeof index === 'string') {
|
||||
var color = index.replace(/[^\w\s,#\(\)\.]/g, '');
|
||||
index = color_array.indexOf(color);
|
||||
//add this color if it doesn't exist
|
||||
if(index == -1 && insert === true) {
|
||||
color_array.push(color);
|
||||
|
||||
$('<option />')
|
||||
.appendTo($element)
|
||||
.val(color);
|
||||
|
||||
$('<li><a class="colorpick-btn" href="#"></a></li>')
|
||||
.appendTo(dropdown)
|
||||
.find('a')
|
||||
.css('background-color', color)
|
||||
.data('color', color);
|
||||
|
||||
index = color_array.length - 1;
|
||||
}
|
||||
if(index == -1) return;
|
||||
dropdown.find('a:eq('+index+')').trigger(ace.click_event);
|
||||
}
|
||||
}
|
||||
|
||||
this.destroy = function() {
|
||||
$element.removeClass('hide').off('change.color')
|
||||
.next().remove();
|
||||
color_array = [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$.fn.ace_colorpicker = function(option, value) {
|
||||
var retval;
|
||||
|
||||
var $set = this.each(function () {
|
||||
var $this = $(this);
|
||||
var data = $this.data('ace_colorpicker');
|
||||
var options = typeof option === 'object' && option;
|
||||
|
||||
if (!data) $this.data('ace_colorpicker', (data = new Ace_Colorpicker(this, options)));
|
||||
if (typeof option === 'string') retval = data[option](value);
|
||||
});
|
||||
|
||||
return (retval === undefined) ? $set : retval;
|
||||
}
|
||||
|
||||
$.fn.ace_colorpicker.defaults = {
|
||||
'pull_right' : false,
|
||||
'caret': true,
|
||||
'auto_pos': true
|
||||
}
|
||||
|
||||
})(window.jQuery);
|
||||
553
static/js/lib/ace/ace/elements.fileinput.js
Normal file
553
static/js/lib/ace/ace/elements.fileinput.js
Normal file
@@ -0,0 +1,553 @@
|
||||
/**
|
||||
<b>Ace file input element</b>. Custom, simple file input element to style browser's default file input.
|
||||
*/
|
||||
(function($ , undefined) {
|
||||
var multiplible = 'multiple' in document.createElement('INPUT');
|
||||
var hasFileList = 'FileList' in window;//file list enabled in modern browsers
|
||||
var hasFileReader = 'FileReader' in window;
|
||||
var hasFile = 'File' in window;
|
||||
|
||||
var Ace_File_Input = function(element , settings) {
|
||||
var self = this;
|
||||
this.settings = $.extend({}, $.fn.ace_file_input.defaults, settings);
|
||||
|
||||
this.$element = $(element);
|
||||
this.element = element;
|
||||
this.disabled = false;
|
||||
this.can_reset = true;
|
||||
|
||||
|
||||
this.$element
|
||||
.off('change.ace_inner_call')
|
||||
.on('change.ace_inner_call', function(e , ace_inner_call){
|
||||
if(ace_inner_call === true) return;//this change event is called from above drop event and extra checkings are taken care of there
|
||||
return handle_on_change.call(self);
|
||||
//if(ret === false) e.preventDefault();
|
||||
});
|
||||
|
||||
var parent_label = this.$element.closest('label').css({'display':'block'})
|
||||
var tagName = parent_label.length == 0 ? 'label' : 'span';//if not inside a "LABEL" tag, use "LABEL" tag, otherwise use "SPAN"
|
||||
this.$element.wrap('<'+tagName+' class="ace-file-input" />');
|
||||
|
||||
this.apply_settings();
|
||||
this.reset_input_field();//for firefox as it keeps selected file after refresh
|
||||
}
|
||||
Ace_File_Input.error = {
|
||||
'FILE_LOAD_FAILED' : 1,
|
||||
'IMAGE_LOAD_FAILED' : 2,
|
||||
'THUMBNAIL_FAILED' : 3
|
||||
};
|
||||
|
||||
|
||||
Ace_File_Input.prototype.apply_settings = function() {
|
||||
var self = this;
|
||||
|
||||
this.multi = this.$element.attr('multiple') && multiplible;
|
||||
this.well_style = this.settings.style == 'well';
|
||||
|
||||
if(this.well_style) this.$element.parent().addClass('ace-file-multiple');
|
||||
else this.$element.parent().removeClass('ace-file-multiple');
|
||||
|
||||
|
||||
this.$element.parent().find(':not(input[type=file])').remove();//remove all except our input, good for when changing settings
|
||||
this.$element.after('<span class="ace-file-container" data-title="'+this.settings.btn_choose+'"><span class="ace-file-name" data-title="'+this.settings.no_file+'">'+(this.settings.no_icon ? '<i class="'+ ace.vars['icon'] + this.settings.no_icon+'"></i>' : '')+'</span></span>');
|
||||
this.$label = this.$element.next();
|
||||
this.$container = this.$element.closest('.ace-file-input');
|
||||
|
||||
var remove_btn = !!this.settings.icon_remove;
|
||||
if(remove_btn) {
|
||||
var btn =
|
||||
$('<a class="remove" href="#"><i class="'+ ace.vars['icon'] + this.settings.icon_remove+'"></i></a>')
|
||||
.appendTo(this.$element.parent());
|
||||
|
||||
btn.on(ace.click_event, function(e){
|
||||
e.preventDefault();
|
||||
if( !self.can_reset ) return false;
|
||||
|
||||
var ret = true;
|
||||
if(self.settings.before_remove) ret = self.settings.before_remove.call(self.element);
|
||||
if(!ret) return false;
|
||||
|
||||
var r = self.reset_input();
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if(this.settings.droppable && hasFileList) {
|
||||
enable_drop_functionality.call(this);
|
||||
}
|
||||
}
|
||||
|
||||
Ace_File_Input.prototype.show_file_list = function($files) {
|
||||
var files = typeof $files === "undefined" ? this.$element.data('ace_input_files') : $files;
|
||||
if(!files || files.length == 0) return;
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
if(this.well_style) {
|
||||
this.$label.find('.ace-file-name').remove();
|
||||
if(!this.settings.btn_change) this.$label.addClass('hide-placeholder');
|
||||
}
|
||||
this.$label.attr('data-title', this.settings.btn_change).addClass('selected');
|
||||
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
var filename = typeof files[i] === "string" ? files[i] : $.trim( files[i].name );
|
||||
var index = filename.lastIndexOf("\\") + 1;
|
||||
if(index == 0)index = filename.lastIndexOf("/") + 1;
|
||||
filename = filename.substr(index);
|
||||
|
||||
var fileIcon = 'fa fa-file';
|
||||
var format = 'file';
|
||||
|
||||
if((/\.(jpe?g|png|gif|svg|bmp|tiff?)$/i).test(filename)) {
|
||||
fileIcon = 'fa fa-picture-o file-image';
|
||||
format = 'image';
|
||||
}
|
||||
else if((/\.(mpe?g|flv|mov|avi|swf|mp4|mkv|webm|wmv|3gp)$/i).test(filename)) {
|
||||
fileIcon = 'fa fa-film file-video';
|
||||
format = 'video';
|
||||
}
|
||||
else if((/\.(mp3|ogg|wav|wma|amr|aac)$/i).test(filename)) {
|
||||
fileIcon = 'fa fa-music file-audio';
|
||||
format = 'audio';
|
||||
}
|
||||
|
||||
|
||||
if(!this.well_style) this.$label.find('.ace-file-name').attr({'data-title':filename}).find(ace.vars['.icon']).attr('class', ace.vars['icon'] + fileIcon);
|
||||
else {
|
||||
this.$label.append('<span class="ace-file-name" data-title="'+filename+'"><i class="'+ ace.vars['icon'] + fileIcon+'"></i></span>');
|
||||
var type = $.trim(files[i].type);
|
||||
var can_preview = hasFileReader && this.settings.thumbnail
|
||||
&&
|
||||
( (type.length > 0 && type.match('image')) || (type.length == 0 && format == 'image') )//the second one is for Android's default browser which gives an empty text for file.type
|
||||
if(can_preview) {
|
||||
var self = this;
|
||||
$.when(preview_image.call(this, files[i])).fail(function(result){
|
||||
//called on failure to load preview
|
||||
if(self.settings.preview_error) self.settings.preview_error.call(self, filename, result.code);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Ace_File_Input.prototype.reset_input = function() {
|
||||
this.reset_input_ui();
|
||||
this.reset_input_field();
|
||||
}
|
||||
|
||||
Ace_File_Input.prototype.reset_input_ui = function() {
|
||||
this.$label.attr({'data-title':this.settings.btn_choose, 'class':'ace-file-container'})
|
||||
.find('.ace-file-name:first').attr({'data-title':this.settings.no_file , 'class':'ace-file-name'})
|
||||
.find(ace.vars['.icon']).attr('class', ace.vars['icon'] + this.settings.no_icon)
|
||||
.prev('img').remove();
|
||||
if(!this.settings.no_icon) this.$label.find(ace.vars['.icon']).remove();
|
||||
|
||||
this.$label.find('.ace-file-name').not(':first').remove();
|
||||
|
||||
this.reset_input_data();
|
||||
}
|
||||
Ace_File_Input.prototype.reset_input_field = function() {
|
||||
//http://stackoverflow.com/questions/1043957/clearing-input-type-file-using-jquery/13351234#13351234
|
||||
this.$element.wrap('<form>').parent().get(0).reset();
|
||||
this.$element.unwrap();
|
||||
|
||||
//strangely when reset is called on this temporary inner form
|
||||
//only **IE9/10** trigger 'reset' on the outer form as well
|
||||
//and as we have mentioned to reset input on outer form reset
|
||||
//it causes infinite recusrsion by coming back to reset_input_field
|
||||
//thus calling reset again and again and again
|
||||
//so because when "reset" button of outer form is hit, file input is automatically reset
|
||||
//we just reset_input_ui to avoid recursion
|
||||
}
|
||||
Ace_File_Input.prototype.reset_input_data = function() {
|
||||
if(this.$element.data('ace_input_files')) {
|
||||
this.$element.removeData('ace_input_files');
|
||||
this.$element.removeData('ace_input_method');
|
||||
}
|
||||
}
|
||||
|
||||
Ace_File_Input.prototype.enable_reset = function(can_reset) {
|
||||
this.can_reset = can_reset;
|
||||
}
|
||||
|
||||
Ace_File_Input.prototype.disable = function() {
|
||||
this.disabled = true;
|
||||
this.$element.attr('disabled', 'disabled').addClass('disabled');
|
||||
}
|
||||
Ace_File_Input.prototype.enable = function() {
|
||||
this.disabled = false;
|
||||
this.$element.removeAttr('disabled').removeClass('disabled');
|
||||
}
|
||||
|
||||
Ace_File_Input.prototype.files = function() {
|
||||
return $(this).data('ace_input_files') || null;
|
||||
}
|
||||
Ace_File_Input.prototype.method = function() {
|
||||
return $(this).data('ace_input_method') || '';
|
||||
}
|
||||
|
||||
Ace_File_Input.prototype.update_settings = function(new_settings) {
|
||||
this.settings = $.extend({}, this.settings, new_settings);
|
||||
this.apply_settings();
|
||||
}
|
||||
|
||||
Ace_File_Input.prototype.loading = function(is_loading) {
|
||||
if(is_loading === false) {
|
||||
this.$container.find('.ace-file-overlay').remove();
|
||||
this.element.removeAttribute('readonly');
|
||||
}
|
||||
else {
|
||||
var inside = typeof is_loading === 'string' ? is_loading : '<i class="overlay-content fa fa-spin fa-spinner orange2 fa-2x"></i>';
|
||||
var loader = this.$container.find('.ace-file-overlay');
|
||||
if(loader.length == 0) {
|
||||
loader = $('<div class="ace-file-overlay"></div>').appendTo(this.$container);
|
||||
loader.on('click tap', function(e) {
|
||||
e.stopImmediatePropagation();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
|
||||
this.element.setAttribute('readonly' , 'true');//for IE
|
||||
}
|
||||
loader.empty().append(inside);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
var enable_drop_functionality = function() {
|
||||
var self = this;
|
||||
var dropbox = this.$element.parent();
|
||||
dropbox
|
||||
.off('dragenter')
|
||||
.on('dragenter', function(e){
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
})
|
||||
.off('dragover')
|
||||
.on('dragover', function(e){
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
})
|
||||
.off('drop')
|
||||
.on('drop', function(e){
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
var dt = e.originalEvent.dataTransfer;
|
||||
var file_list = dt.files;
|
||||
if(!self.multi && file_list.length > 1) {//single file upload, but dragged multiple files
|
||||
var tmpfiles = [];
|
||||
tmpfiles.push(file_list[0]);
|
||||
file_list = tmpfiles;//keep only first file
|
||||
}
|
||||
|
||||
|
||||
file_list = processFiles.call(self, file_list, true);//true means files have been selected, not dropped
|
||||
if(file_list === false) return false;
|
||||
|
||||
self.$element.data('ace_input_method', 'drop');
|
||||
self.$element.data('ace_input_files', file_list);//save files data to be used later by user
|
||||
|
||||
self.show_file_list(file_list);
|
||||
|
||||
self.$element.triggerHandler('change' , [true]);//true means ace_inner_call
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
var handle_on_change = function() {
|
||||
var file_list = this.element.files || [this.element.value];/** make it an array */
|
||||
|
||||
file_list = processFiles.call(this, file_list, false);//false means files have been selected, not dropped
|
||||
if(file_list === false) return false;
|
||||
|
||||
this.$element.data('ace_input_method', 'select');
|
||||
this.$element.data('ace_input_files', file_list);
|
||||
|
||||
this.show_file_list(file_list);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
var preview_image = function(file) {
|
||||
var self = this;
|
||||
var $span = self.$label.find('.ace-file-name:last');//it should be out of onload, otherwise all onloads may target the same span because of delays
|
||||
|
||||
var deferred = new $.Deferred
|
||||
var reader = new FileReader();
|
||||
reader.onload = function (e) {
|
||||
$span.prepend("<img class='middle' style='display:none;' />");
|
||||
var img = $span.find('img:last').get(0);
|
||||
|
||||
$(img).one('load', function() {
|
||||
//if image loaded successfully
|
||||
var size = 50;
|
||||
if(self.settings.thumbnail == 'large') size = 150;
|
||||
else if(self.settings.thumbnail == 'fit') size = $span.width();
|
||||
$span.addClass(size > 50 ? 'large' : '');
|
||||
|
||||
var thumb = get_thumbnail(img, size, file.type);
|
||||
if(thumb == null) {
|
||||
//if making thumbnail fails
|
||||
$(this).remove();
|
||||
deferred.reject({code:Ace_File_Input.error['THUMBNAIL_FAILED']});
|
||||
return;
|
||||
}
|
||||
|
||||
var w = thumb.w, h = thumb.h;
|
||||
if(self.settings.thumbnail == 'small') {w=h=size;};
|
||||
$(img).css({'background-image':'url('+thumb.src+')' , width:w, height:h})
|
||||
.data('thumb', thumb.src)
|
||||
.attr({src:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg=='})
|
||||
.show()
|
||||
|
||||
///////////////////
|
||||
deferred.resolve();
|
||||
}).one('error', function() {
|
||||
//for example when a file has image extenstion, but format is something else
|
||||
$span.find('img').remove();
|
||||
deferred.reject({code:Ace_File_Input.error['IMAGE_LOAD_FAILED']});
|
||||
});
|
||||
|
||||
img.src = e.target.result;
|
||||
}
|
||||
reader.onerror = function (e) {
|
||||
deferred.reject({code:Ace_File_Input.error['FILE_LOAD_FAILED']});
|
||||
}
|
||||
reader.readAsDataURL(file);
|
||||
|
||||
return deferred.promise();
|
||||
}
|
||||
|
||||
var get_thumbnail = function(img, size, type) {
|
||||
var w = img.width, h = img.height;
|
||||
|
||||
//**IE10** is not giving correct width using img.width so we use $(img).width()
|
||||
w = w > 0 ? w : $(img).width()
|
||||
h = h > 0 ? h : $(img).height()
|
||||
|
||||
if(w > size || h > size) {
|
||||
if(w > h) {
|
||||
h = parseInt(size/w * h);
|
||||
w = size;
|
||||
} else {
|
||||
w = parseInt(size/h * w);
|
||||
h = size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var dataURL
|
||||
try {
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.width = w; canvas.height = h;
|
||||
var context = canvas.getContext('2d');
|
||||
context.drawImage(img, 0, 0, img.width, img.height, 0, 0, w, h);
|
||||
dataURL = canvas.toDataURL(/*type == 'image/jpeg' ? type : 'image/png', 10*/)
|
||||
} catch(e) {
|
||||
dataURL = null;
|
||||
}
|
||||
if(! dataURL) return null;
|
||||
|
||||
|
||||
//there was only one image that failed in firefox completely randomly! so let's double check things
|
||||
if( !( /^data\:image\/(png|jpe?g|gif);base64,[0-9A-Za-z\+\/\=]+$/.test(dataURL)) ) dataURL = null;
|
||||
if(! dataURL) return null;
|
||||
|
||||
|
||||
return {src: dataURL, w:w, h:h};
|
||||
}
|
||||
|
||||
|
||||
|
||||
var processFiles = function(file_list, dropped) {
|
||||
var ret = checkFileList.call(this, file_list, dropped);
|
||||
if(ret === -1) {
|
||||
this.reset_input();
|
||||
return false;
|
||||
}
|
||||
if( !ret || ret.length == 0 ) {
|
||||
if( !this.$element.data('ace_input_files') ) this.reset_input();
|
||||
//if nothing selected before, reset because of the newly unacceptable (ret=false||length=0) selection
|
||||
//otherwise leave the previous selection intact?!!!
|
||||
return false;
|
||||
}
|
||||
if (ret instanceof Array || (hasFileList && ret instanceof FileList)) file_list = ret;
|
||||
|
||||
|
||||
ret = true;
|
||||
if(this.settings.before_change) ret = this.settings.before_change.call(this.element, file_list, dropped);
|
||||
if(ret === -1) {
|
||||
this.reset_input();
|
||||
return false;
|
||||
}
|
||||
if(!ret || ret.length == 0) {
|
||||
if( !this.$element.data('ace_input_files') ) this.reset_input();
|
||||
return false;
|
||||
}
|
||||
|
||||
//inside before_change you can return a modified File Array as result
|
||||
if (ret instanceof Array || (hasFileList && ret instanceof FileList)) file_list = ret;
|
||||
|
||||
return file_list;
|
||||
}
|
||||
|
||||
|
||||
var getExtRegex = function(ext) {
|
||||
if(!ext) return null;
|
||||
if(typeof ext === 'string') ext = [ext];
|
||||
if(ext.length == 0) return null;
|
||||
return new RegExp("\.(?:"+ext.join('|')+")$", "i");
|
||||
}
|
||||
var getMimeRegex = function(mime) {
|
||||
if(!mime) return null;
|
||||
if(typeof mime === 'string') mime = [mime];
|
||||
if(mime.length == 0) return null;
|
||||
return new RegExp("^(?:"+mime.join('|').replace(/\//g, "\\/")+")$", "i");
|
||||
}
|
||||
var checkFileList = function(files, dropped) {
|
||||
var allowExt = getExtRegex(this.settings.allowExt);
|
||||
|
||||
var denyExt = getExtRegex(this.settings.denyExt);
|
||||
|
||||
var allowMime = getMimeRegex(this.settings.allowMime);
|
||||
|
||||
var denyMime = getMimeRegex(this.settings.denyMime);
|
||||
|
||||
var maxSize = this.settings.maxSize || false;
|
||||
|
||||
if( !(allowExt || denyExt || allowMime || denyMime || maxSize) ) return true;//no checking required
|
||||
|
||||
|
||||
var safe_files = [];
|
||||
var error_list = {}
|
||||
for(var f = 0; f < files.length; f++) {
|
||||
var file = files[f];
|
||||
|
||||
//file is either a string(file name) or a File object
|
||||
var filename = !hasFile ? file : file.name;
|
||||
if( allowExt && !allowExt.test(filename) ) {
|
||||
//extension not matching whitelist, so drop it
|
||||
if(!('ext' in error_list)) error_list['ext'] = [];
|
||||
error_list['ext'].push(filename);
|
||||
|
||||
continue;
|
||||
} else if( denyExt && denyExt.test(filename) ) {
|
||||
//extension is matching blacklist, so drop it
|
||||
if(!('ext' in error_list)) error_list['ext'] = [];
|
||||
error_list['ext'].push(filename);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
var type;
|
||||
if( !hasFile ) {
|
||||
//in browsers that don't support FileReader API
|
||||
safe_files.push(file);
|
||||
continue;
|
||||
}
|
||||
else if((type = $.trim(file.type)).length > 0) {
|
||||
//there is a mimetype for file so let's check against are rules
|
||||
if( allowMime && !allowMime.test(type) ) {
|
||||
//mimeType is not matching whitelist, so drop it
|
||||
if(!('mime' in error_list)) error_list['mime'] = [];
|
||||
error_list['mime'].push(filename);
|
||||
continue;
|
||||
}
|
||||
else if( denyMime && denyMime.test(type) ) {
|
||||
//mimeType is matching blacklist, so drop it
|
||||
if(!('mime' in error_list)) error_list['mime'] = [];
|
||||
error_list['mime'].push(filename);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if( maxSize && file.size > maxSize ) {
|
||||
//file size is not acceptable
|
||||
if(!('size' in error_list)) error_list['size'] = [];
|
||||
error_list['size'].push(filename);
|
||||
continue;
|
||||
}
|
||||
|
||||
safe_files.push(file)
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(safe_files.length == files.length) return files;//return original file list if all are valid
|
||||
|
||||
/////////
|
||||
var error_count = {'ext': 0, 'mime': 0, 'size': 0}
|
||||
if( 'ext' in error_list ) error_count['ext'] = error_list['ext'].length;
|
||||
if( 'mime' in error_list ) error_count['mime'] = error_list['mime'].length;
|
||||
if( 'size' in error_list ) error_count['size'] = error_list['size'].length;
|
||||
|
||||
var event
|
||||
this.$element.trigger(
|
||||
event = new $.Event('file.error.ace'),
|
||||
{
|
||||
'file_count': files.length,
|
||||
'invalid_count' : files.length - safe_files.length,
|
||||
'error_list' : error_list,
|
||||
'error_count' : error_count,
|
||||
'dropped': dropped
|
||||
}
|
||||
);
|
||||
if ( event.isDefaultPrevented() ) return -1;//it will reset input
|
||||
//////////
|
||||
|
||||
return safe_files;//return safe_files
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////
|
||||
$.fn.ace_file_input = function (option,value) {
|
||||
var retval;
|
||||
|
||||
var $set = this.each(function () {
|
||||
var $this = $(this);
|
||||
var data = $this.data('ace_file_input');
|
||||
var options = typeof option === 'object' && option;
|
||||
|
||||
if (!data) $this.data('ace_file_input', (data = new Ace_File_Input(this, options)));
|
||||
if (typeof option === 'string') retval = data[option](value);
|
||||
});
|
||||
|
||||
return (retval === undefined) ? $set : retval;
|
||||
};
|
||||
|
||||
|
||||
$.fn.ace_file_input.defaults = {
|
||||
style: false,
|
||||
no_file: 'No File ...',
|
||||
no_icon: 'fa fa-upload',
|
||||
btn_choose: 'Choose',
|
||||
btn_change: 'Change',
|
||||
icon_remove: 'fa fa-times',
|
||||
droppable: false,
|
||||
thumbnail: false,//large, fit, small
|
||||
|
||||
allowExt: null,
|
||||
denyExt: null,
|
||||
allowMime: null,
|
||||
denyMime: null,
|
||||
maxSize: false,
|
||||
|
||||
//callbacks
|
||||
before_change: null,
|
||||
before_remove: null,
|
||||
preview_error: null
|
||||
}
|
||||
|
||||
|
||||
})(window.jQuery);
|
||||
441
static/js/lib/ace/ace/elements.scroller.js
Normal file
441
static/js/lib/ace/ace/elements.scroller.js
Normal file
@@ -0,0 +1,441 @@
|
||||
/**
|
||||
<b>Ace custom scroller</b>. It is not as feature-rich as plugins such as NiceScroll but it's good enough for most cases.
|
||||
*/
|
||||
(function($ , undefined) {
|
||||
var Ace_Scroll = function(element , _settings) {
|
||||
var self = this;
|
||||
var settings = $.extend({}, $.fn.ace_scroll.defaults, _settings);
|
||||
|
||||
this.size = 0;
|
||||
this.$element = $(element);
|
||||
this.element = element;
|
||||
|
||||
var vertical = true;
|
||||
|
||||
var disabled = false;
|
||||
var active = false;
|
||||
var created = false;
|
||||
|
||||
var $content_wrap = null, content_wrap = null;
|
||||
var $track = null, $bar = null, track = null, bar = null;
|
||||
var bar_style = null;
|
||||
|
||||
var bar_size = 0, bar_pos = 0, bar_max_pos = 0, bar_size_2 = 0, move_bar = true;
|
||||
var reset_once = false;
|
||||
|
||||
var css_pos,
|
||||
css_size,
|
||||
max_css_size,
|
||||
client_size,
|
||||
scroll_direction,
|
||||
scroll_size;
|
||||
|
||||
var ratio = 1;
|
||||
var inline_style = false;
|
||||
var mouse_track = false;
|
||||
var mouse_release_target = 'onmouseup' in window ? window : 'html';
|
||||
var dragEvent = settings.dragEvent || false;
|
||||
|
||||
var trigger_scroll = _settings.scrollEvent || false;
|
||||
|
||||
this.create = function(_settings) {
|
||||
if(created) return;
|
||||
//if(disabled) return;
|
||||
if(_settings) settings = $.extend({}, $.fn.ace_scroll.defaults, _settings);
|
||||
|
||||
this.size = parseInt(this.$element.attr('data-size')) || settings.size || 200;
|
||||
vertical = !settings['horizontal'];
|
||||
|
||||
css_pos = vertical ? 'top' : 'left';//'left' for horizontal
|
||||
css_size = vertical ? 'height' : 'width';//'width' for horizontal
|
||||
max_css_size = vertical ? 'maxHeight' : 'maxWidth';
|
||||
|
||||
client_size = vertical ? 'clientHeight' : 'clientWidth';
|
||||
scroll_direction = vertical ? 'scrollTop' : 'scrollLeft';
|
||||
scroll_size = vertical ? 'scrollHeight' : 'scrollWidth';
|
||||
|
||||
|
||||
|
||||
this.$element.addClass('ace-scroll '+((vertical? '' : ' scroll-hz') + (settings.styleClass ? ' '+settings.styleClass : '')));
|
||||
if(this.$element.css('position') == 'static') {
|
||||
inline_style = this.element.style.position;
|
||||
this.element.style.position = 'relative';
|
||||
} else inline_style = false;
|
||||
|
||||
this.$element.wrapInner('<div class="scroll-content" />');
|
||||
this.$element.prepend('<div class="scroll-track"><div class="scroll-bar"></div></div>');
|
||||
|
||||
$content_wrap = this.$element.find('.scroll-content').eq(0);
|
||||
if(!vertical) $content_wrap.wrapInner('<div />');
|
||||
|
||||
content_wrap = $content_wrap.get(0);
|
||||
|
||||
$track = this.$element.find('.scroll-track').eq(0);
|
||||
$bar = $track.find('.scroll-bar').eq(0);
|
||||
track = $track.get(0);
|
||||
bar = $bar.get(0);
|
||||
bar_style = bar.style;
|
||||
|
||||
$track.hide();
|
||||
|
||||
|
||||
//if(!touchDrag) {
|
||||
$track.on('mousedown', mouse_down_track);
|
||||
$bar.on('mousedown', mouse_down_bar);
|
||||
//}
|
||||
|
||||
$content_wrap.on('scroll', function() {
|
||||
if(move_bar) {
|
||||
bar_pos = parseInt(Math.round(this[scroll_direction] * ratio));
|
||||
bar_style[css_pos] = bar_pos + 'px';
|
||||
}
|
||||
move_bar = false;
|
||||
if(trigger_scroll) this.$element.trigger('scroll', [content_wrap]);
|
||||
})
|
||||
|
||||
if(settings.mouseWheel) {
|
||||
var lock = settings.mouseWheelLock;
|
||||
var lock_anyway = !settings.lockAnyway;
|
||||
|
||||
this.$element.on('mousewheel.ace_scroll DOMMouseScroll.ace_scroll', function(event) {
|
||||
if(disabled) return;
|
||||
if(!active) return lock_anyway;
|
||||
|
||||
if(mouse_track) {
|
||||
mouse_track = false;
|
||||
$('html').off('.ace_scroll')
|
||||
$(mouse_release_target).off('.ace_scroll');
|
||||
if(dragEvent) self.$element.trigger('drag.end');
|
||||
}
|
||||
|
||||
var delta = event.originalEvent.detail < 0 || event.originalEvent.wheelDelta > 0 ? 1 : -1
|
||||
var scrollEnd = false//have we reached the end of scrolling?
|
||||
|
||||
var clientSize = content_wrap[client_size], scrollAmount = content_wrap[scroll_direction];
|
||||
if( !lock ) {
|
||||
if(delta == -1) scrollEnd = (content_wrap[scroll_size] <= scrollAmount + clientSize);
|
||||
else scrollEnd = (scrollAmount == 0);
|
||||
}
|
||||
|
||||
self.move_bar(true);
|
||||
|
||||
var step = parseInt(Math.round(Math.min(Math.max(clientSize / 8 , 54)) , self.size )) + 1;
|
||||
content_wrap[scroll_direction] = scrollAmount - (delta * step);
|
||||
|
||||
return scrollEnd && lock_anyway;
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//swipe not available yet
|
||||
var touchDrag = ace.vars['touch'] && 'ace_drag' in $.event.special && settings.touchDrag //&& !settings.touchSwipe;
|
||||
//add drag event for touch devices to scroll
|
||||
if(touchDrag/** || ($.fn.swipe && settings.touchSwipe)*/) {
|
||||
var dir = '', event_name = touchDrag ? 'ace_drag' : 'swipe';
|
||||
this.$element.on(event_name + '.ace_scroll', function(event) {
|
||||
dir = event.direction;
|
||||
if( (vertical && (dir == 'up' || dir == 'down'))
|
||||
||
|
||||
(!vertical && (dir == 'left' || dir == 'right'))
|
||||
)
|
||||
{
|
||||
var distance = vertical ? event.dy : event.dx;
|
||||
|
||||
if(distance != 0) {
|
||||
if(Math.abs(distance) > 20 && touchDrag) distance = distance * 2;
|
||||
|
||||
self.move_bar(true);
|
||||
content_wrap[scroll_direction] = content_wrap[scroll_direction] + distance;
|
||||
}
|
||||
|
||||
//if(event.retval) event.retval['cancel'] = true;//prevents document scroll
|
||||
}
|
||||
//else if(event.retval) event.retval['cancel'] = false;//allows document scroll
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
if(settings.hoverReset) {
|
||||
//some mobile browsers don't have mouseenter
|
||||
this.$element.on('mouseenter.ace_scroll touchstart.ace_scroll', function() {
|
||||
self.reset();
|
||||
})
|
||||
}
|
||||
|
||||
if(!vertical) $content_wrap.children(0).css(css_size, this.size);//the extra wrapper
|
||||
$content_wrap.css(max_css_size , this.size);
|
||||
|
||||
disabled = false;
|
||||
created = true;
|
||||
}
|
||||
this.is_active = function() {
|
||||
return active;
|
||||
}
|
||||
this.is_enabled = function() {
|
||||
return !disabled;
|
||||
}
|
||||
this.move_bar = function($move) {
|
||||
move_bar = $move;
|
||||
}
|
||||
|
||||
this.reset = function() {
|
||||
if(disabled) return;// this;
|
||||
if(!created) this.create();
|
||||
|
||||
var content_size = vertical ? content_wrap[scroll_size] : this.size;
|
||||
if( (vertical && content_size == 0) || (!vertical && this.element.scrollWidth == 0) ) {
|
||||
//elemen is hidden
|
||||
//this.$element.addClass('scroll-hidden');
|
||||
this.$element.removeClass('scroll-active')
|
||||
return;// this;
|
||||
}
|
||||
|
||||
|
||||
var available_space = vertical ? this.size : content_wrap.clientWidth;
|
||||
|
||||
if(!vertical) $content_wrap.children(0).css(css_size, this.size);//the extra wrapper
|
||||
$content_wrap.css(max_css_size , this.size);
|
||||
|
||||
if(content_size > available_space) {
|
||||
active = true;
|
||||
$track.css(css_size, available_space).show();
|
||||
|
||||
ratio = parseFloat((available_space / content_size).toFixed(5))
|
||||
|
||||
bar_size = parseInt(Math.round(available_space * ratio));
|
||||
bar_size_2 = parseInt(Math.round(bar_size / 2));
|
||||
|
||||
bar_max_pos = available_space - bar_size;
|
||||
bar_pos = parseInt(Math.round(content_wrap[scroll_direction] * ratio));
|
||||
|
||||
bar_style[css_size] = bar_size + 'px';
|
||||
bar_style[css_pos] = bar_pos + 'px';
|
||||
|
||||
this.$element.addClass('scroll-active')
|
||||
|
||||
if(!reset_once) {
|
||||
//this.$element.removeClass('scroll-hidden');
|
||||
if(settings.reset) {
|
||||
//reset scrollbar to zero position at first
|
||||
content_wrap[scroll_direction] = 0;
|
||||
bar_style[css_pos] = 0;
|
||||
}
|
||||
reset_once = true;
|
||||
}
|
||||
} else {
|
||||
active = false;
|
||||
$track.hide();
|
||||
this.$element.removeClass('scroll-active');
|
||||
$content_wrap.css(max_css_size , '');
|
||||
}
|
||||
|
||||
return;// this;
|
||||
}
|
||||
this.disable = function() {
|
||||
content_wrap[scroll_direction] = 0;
|
||||
bar_style[css_pos] = 0;
|
||||
|
||||
disabled = true;
|
||||
active = false;
|
||||
$track.hide();
|
||||
|
||||
this.$element.removeClass('scroll-active');
|
||||
$content_wrap.css(max_css_size , '');
|
||||
|
||||
return this;
|
||||
}
|
||||
this.enable = function() {
|
||||
disabled = false;
|
||||
this.reset();
|
||||
|
||||
return this;
|
||||
}
|
||||
this.destroy = function() {
|
||||
active = false;
|
||||
disabled = false;
|
||||
created = false;
|
||||
|
||||
this.$element.removeClass('ace-scroll scroll-hz'+(settings.extraClass ? ' '+settings.extraClass : ''));
|
||||
this.$element.off('.ace_scroll')
|
||||
|
||||
if(!vertical) {
|
||||
//remove the extra wrapping div
|
||||
$content_wrap.find('> div').children().unwrap();
|
||||
}
|
||||
$content_wrap.children().unwrap();
|
||||
$content_wrap.remove();
|
||||
|
||||
$track.remove();
|
||||
|
||||
if(inline_style !== false) this.element.style.position = inline_style;
|
||||
|
||||
return this;
|
||||
}
|
||||
this.modify = function(_settings) {
|
||||
if(_settings) settings = $.extend({}, $.fn.ace_scroll.defaults, _settings);
|
||||
|
||||
this.destroy();
|
||||
this.create();
|
||||
this.reset();
|
||||
|
||||
return this;
|
||||
}
|
||||
this.update = function(_settings) {
|
||||
//if(_settings) settings = $.extend({}, $.fn.ace_scroll.defaults, _settings);
|
||||
this.size = _settings.size;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
this.update_scroll = function() {
|
||||
move_bar = false;
|
||||
bar_style[css_pos] = bar_pos + 'px';
|
||||
content_wrap[scroll_direction] = parseInt(Math.round(bar_pos / ratio));
|
||||
}
|
||||
|
||||
function mouse_down_track(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
var track_offset = $track.offset();
|
||||
var track_pos = track_offset[css_pos];//top for vertical, left for horizontal
|
||||
var mouse_pos = vertical ? e.pageY : e.pageX;
|
||||
|
||||
if(mouse_pos > track_pos + bar_pos) {
|
||||
bar_pos = mouse_pos - track_pos - bar_size + bar_size_2;
|
||||
if(bar_pos > bar_max_pos) {
|
||||
bar_pos = bar_max_pos;
|
||||
}
|
||||
}
|
||||
else {
|
||||
bar_pos = mouse_pos - track_pos - bar_size_2;
|
||||
if(bar_pos < 0) bar_pos = 0;
|
||||
}
|
||||
|
||||
self.update_scroll()
|
||||
}
|
||||
|
||||
var mouse_pos1 = -1, mouse_pos2 = -1;
|
||||
function mouse_down_bar(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
if(vertical) {
|
||||
mouse_pos2 = mouse_pos1 = e.pageY;
|
||||
} else {
|
||||
mouse_pos2 = mouse_pos1 = e.pageX;
|
||||
}
|
||||
|
||||
mouse_track = true;
|
||||
$('html').off('mousemove.ace_scroll').on('mousemove.ace_scroll', mouse_move_bar)
|
||||
$(mouse_release_target).off('mouseup.ace_scroll').on('mouseup.ace_scroll', mouse_up_bar);
|
||||
|
||||
$track.addClass('active');
|
||||
if(dragEvent) self.$element.trigger('drag.start');
|
||||
}
|
||||
function mouse_move_bar(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
if(vertical) {
|
||||
mouse_pos2 = e.pageY;
|
||||
} else {
|
||||
mouse_pos2 = e.pageX;
|
||||
}
|
||||
|
||||
|
||||
if(mouse_pos2 - mouse_pos1 + bar_pos > bar_max_pos) {
|
||||
mouse_pos2 = mouse_pos1 + bar_max_pos - bar_pos;
|
||||
} else if(mouse_pos2 - mouse_pos1 + bar_pos < 0) {
|
||||
mouse_pos2 = mouse_pos1 - bar_pos;
|
||||
}
|
||||
bar_pos = bar_pos + (mouse_pos2 - mouse_pos1);
|
||||
|
||||
mouse_pos1 = mouse_pos2;
|
||||
|
||||
if(bar_pos < 0) {
|
||||
bar_pos = 0;
|
||||
}
|
||||
else if(bar_pos > bar_max_pos) {
|
||||
bar_pos = bar_max_pos;
|
||||
}
|
||||
|
||||
self.update_scroll()
|
||||
}
|
||||
function mouse_up_bar(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
mouse_track = false;
|
||||
$('html').off('.ace_scroll')
|
||||
$(mouse_release_target).off('.ace_scroll');
|
||||
|
||||
$track.removeClass('active');
|
||||
if(dragEvent) self.$element.trigger('drag.end');
|
||||
}
|
||||
|
||||
this.create();
|
||||
this.reset();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
$.fn.ace_scroll = function (option,value) {
|
||||
var retval;
|
||||
|
||||
var $set = this.each(function () {
|
||||
var $this = $(this);
|
||||
var data = $this.data('ace_scroll');
|
||||
var options = typeof option === 'object' && option;
|
||||
|
||||
if (!data) $this.data('ace_scroll', (data = new Ace_Scroll(this, options)));
|
||||
//else if(typeof options == 'object') data['modify'](options);
|
||||
if (typeof option === 'string') retval = data[option](value);
|
||||
});
|
||||
|
||||
return (retval === undefined) ? $set : retval;
|
||||
};
|
||||
|
||||
|
||||
$.fn.ace_scroll.defaults = {
|
||||
'size' : 200,
|
||||
'horizontal': false,
|
||||
'mouseWheel': true,
|
||||
'mouseWheelLock': false,
|
||||
'lockAnyway': false,
|
||||
'styleClass' : false,
|
||||
|
||||
'hoverReset': true //reset scrollbar sizes on mouse hover because of possible sizing changes
|
||||
,
|
||||
'reset': false //true= set scrollTop = 0
|
||||
,
|
||||
'dragEvent': false
|
||||
,
|
||||
'touchDrag': true
|
||||
,
|
||||
'touchSwipe': false
|
||||
,
|
||||
'scrollEvent': false //trigger scroll event
|
||||
/**
|
||||
,
|
||||
'track' : true,
|
||||
'show' : false,
|
||||
'dark': false,
|
||||
'alwaysVisible': false,
|
||||
'margin': false,
|
||||
'thin': false,
|
||||
'position': 'right'
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
$(document).on('ace.settings.ace_scroll', function(e, name) {
|
||||
if(name == 'sidebar_collapsed') $('.ace-scroll').scroller('reset');
|
||||
});
|
||||
$(window).on('resize.ace_scroll', function() {
|
||||
$('.ace-scroll').scroller('reset');
|
||||
});
|
||||
*/
|
||||
|
||||
})(window.jQuery);
|
||||
104
static/js/lib/ace/ace/elements.spinner.js
Normal file
104
static/js/lib/ace/ace/elements.spinner.js
Normal file
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
<b>Spinner</b>. A wrapper for FuelUX spinner element.
|
||||
It's just a wrapper so you still need to include FuelUX spinner script first.
|
||||
*/
|
||||
(function($ , undefined) {
|
||||
//a wrapper for fuelux spinner
|
||||
function Ace_Spinner(element , options) {
|
||||
var max = options.max
|
||||
max = (''+max).length
|
||||
var width = parseInt(Math.max((max * 20 + 40) , 90))
|
||||
|
||||
var $element = $(element);
|
||||
$element.addClass('spinner-input form-control').wrap('<div class="ace-spinner">')
|
||||
|
||||
var $parent_div = $element.closest('.ace-spinner').spinner(options).wrapInner("<div class='input-group'></div>")
|
||||
var $spinner = $parent_div.data('spinner');
|
||||
|
||||
if(options.on_sides)
|
||||
{
|
||||
$element
|
||||
.before('<div class="spinner-buttons input-group-btn">\
|
||||
<button type="button" class="btn spinner-down btn-xs '+options.btn_down_class+'">\
|
||||
<i class="'+ ace.vars['icon'] + options.icon_down+'"></i>\
|
||||
</button>\
|
||||
</div>')
|
||||
.after('<div class="spinner-buttons input-group-btn">\
|
||||
<button type="button" class="btn spinner-up btn-xs '+options.btn_up_class+'">\
|
||||
<i class="'+ ace.vars['icon'] + options.icon_up+'"></i>\
|
||||
</button>\
|
||||
</div>');
|
||||
|
||||
$parent_div.addClass('touch-spinner')
|
||||
$parent_div.css('width' , width+'px')
|
||||
}
|
||||
else {
|
||||
$element
|
||||
.after('<div class="spinner-buttons input-group-btn">\
|
||||
<button type="button" class="btn spinner-up btn-xs '+options.btn_up_class+'">\
|
||||
<i class="'+ ace.vars['icon'] + options.icon_up+'"></i>\
|
||||
</button>\
|
||||
<button type="button" class="btn spinner-down btn-xs '+options.btn_down_class+'">\
|
||||
<i class="'+ ace.vars['icon'] + options.icon_down+'"></i>\
|
||||
</button>\
|
||||
</div>')
|
||||
|
||||
if(ace.vars['touch'] || options.touch_spinner) {
|
||||
$parent_div.addClass('touch-spinner')
|
||||
$parent_div.css('width' , width+'px')
|
||||
}
|
||||
else {
|
||||
$element.next().addClass('btn-group-vertical');
|
||||
$parent_div.css('width' , width+'px')
|
||||
}
|
||||
}
|
||||
|
||||
$element.on('mousewheel.spinner DOMMouseScroll.spinner', function(event){
|
||||
var delta = event.originalEvent.detail < 0 || event.originalEvent.wheelDelta > 0 ? 1 : -1
|
||||
$spinner.step(delta > 0);
|
||||
$spinner.triggerChangedEvent();
|
||||
return false
|
||||
})
|
||||
|
||||
$parent_div.on('changed', function(){
|
||||
$element.trigger('change')//trigger the input's change event
|
||||
});
|
||||
|
||||
this._call = function(name, arg) {
|
||||
$spinner[name](arg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$.fn.ace_spinner = function(option, value) {
|
||||
var retval;
|
||||
|
||||
var $set = this.each(function() {
|
||||
var $this = $(this);
|
||||
var data = $this.data('ace_spinner');
|
||||
var options = typeof option === 'object' && option;
|
||||
|
||||
if (!data) {
|
||||
options = $.extend({}, $.fn.ace_spinner.defaults, option);
|
||||
$this.data('ace_spinner', (data = new Ace_Spinner(this, options)));
|
||||
}
|
||||
if (typeof option === 'string') retval = data._call(option, value);
|
||||
});
|
||||
|
||||
return (retval === undefined) ? $set : retval;
|
||||
}
|
||||
|
||||
$.fn.ace_spinner.defaults = {
|
||||
'icon_up' : 'fa fa-chevron-up',
|
||||
'icon_down': 'fa fa-chevron-down',
|
||||
|
||||
'on_sides': false,
|
||||
'btn_up_class': '',
|
||||
'btn_down_class' : '',
|
||||
|
||||
'max' : 999,
|
||||
'touch_spinner': false
|
||||
}
|
||||
|
||||
|
||||
})(window.jQuery);
|
||||
38
static/js/lib/ace/ace/elements.treeview.js
Normal file
38
static/js/lib/ace/ace/elements.treeview.js
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
<b>Treeview</b>. A wrapper for FuelUX treeview element.
|
||||
It's just a wrapper so you still need to include FuelUX treeview script first.
|
||||
*/
|
||||
(function($ , undefined) {
|
||||
var $options = {
|
||||
'open-icon' : ace.vars['icon'] + 'fa fa-folder-open',
|
||||
'close-icon' : ace.vars['icon'] + 'fa fa-folder',
|
||||
'selectable' : true,
|
||||
'selected-icon' : ace.vars['icon'] + 'fa fa-check',
|
||||
'unselected-icon' : ace.vars['icon'] + 'fa fa-times'
|
||||
}
|
||||
|
||||
$.fn.ace_tree = function(options) {
|
||||
$options = $.extend({}, $options, options)
|
||||
this.each(function() {
|
||||
var $this = $(this);
|
||||
$this.html('<div class="tree-folder" style="display:none;">\
|
||||
<div class="tree-folder-header">\
|
||||
<i class="'+ ace.vars['icon'] + $options['close-icon']+'"></i>\
|
||||
<div class="tree-folder-name"></div>\
|
||||
</div>\
|
||||
<div class="tree-folder-content"></div>\
|
||||
<div class="tree-loader" style="display:none"></div>\
|
||||
</div>\
|
||||
<div class="tree-item" style="display:none;">\
|
||||
'+($options['unselected-icon'] == null ? '' : '<i class="'+ ace.vars['icon'] + $options['unselected-icon']+'"></i>')+'\
|
||||
<div class="tree-item-name"></div>\
|
||||
</div>');
|
||||
$this.addClass($options['selectable'] == true ? 'tree-selectable' : 'tree-unselectable');
|
||||
|
||||
$this.tree($options);
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
})(window.jQuery);
|
||||
340
static/js/lib/ace/ace/elements.typeahead.js
Normal file
340
static/js/lib/ace/ace/elements.typeahead.js
Normal file
@@ -0,0 +1,340 @@
|
||||
/**
|
||||
<b>Bootstrap 2 typeahead plugin.</b> With Bootstrap <u>3</u> it's been dropped in favor of a more advanced separate plugin.
|
||||
Pretty good for simple cases such as autocomplete feature of the search box and required for <u class="text-danger">Tag input</u> plugin.
|
||||
*/
|
||||
|
||||
/* =============================================================
|
||||
* bootstrap-typeahead.js v2.3.2
|
||||
* http://twitter.github.com/bootstrap/javascript.html#typeahead
|
||||
* =============================================================
|
||||
* Copyright 2012 Twitter, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ============================================================ */
|
||||
|
||||
|
||||
!function($){
|
||||
|
||||
"use strict"; // jshint ;_;
|
||||
|
||||
|
||||
/* TYPEAHEAD PUBLIC CLASS DEFINITION
|
||||
* ================================= */
|
||||
|
||||
var Typeahead = function (element, options) {
|
||||
this.$element = $(element)
|
||||
this.options = $.extend({}, $.fn.typeahead.defaults, options)
|
||||
this.matcher = this.options.matcher || this.matcher
|
||||
this.sorter = this.options.sorter || this.sorter
|
||||
this.highlighter = this.options.highlighter || this.highlighter
|
||||
this.updater = this.options.updater || this.updater
|
||||
this.source = this.options.source
|
||||
this.$menu = $(this.options.menu)
|
||||
this.shown = false
|
||||
this.listen()
|
||||
}
|
||||
|
||||
Typeahead.prototype = {
|
||||
|
||||
constructor: Typeahead
|
||||
|
||||
, select: function () {
|
||||
var val = this.$menu.find('.active').attr('data-value')
|
||||
this.$element
|
||||
.val(this.updater(val))
|
||||
.change()
|
||||
return this.hide()
|
||||
}
|
||||
|
||||
, updater: function (item) {
|
||||
return item
|
||||
}
|
||||
|
||||
, show: function () {
|
||||
var pos = $.extend({}, this.$element.position(), {
|
||||
height: this.$element[0].offsetHeight
|
||||
})
|
||||
|
||||
this.$menu
|
||||
.insertAfter(this.$element)
|
||||
.css({
|
||||
top: pos.top + pos.height
|
||||
, left: pos.left
|
||||
})
|
||||
.show()
|
||||
|
||||
this.shown = true
|
||||
return this
|
||||
}
|
||||
|
||||
, hide: function () {
|
||||
this.$menu.hide()
|
||||
this.shown = false
|
||||
return this
|
||||
}
|
||||
|
||||
, lookup: function (event) {
|
||||
var items
|
||||
|
||||
this.query = this.$element.val()
|
||||
|
||||
if (!this.query || this.query.length < this.options.minLength) {
|
||||
return this.shown ? this.hide() : this
|
||||
}
|
||||
|
||||
items = $.isFunction(this.source) ? this.source(this.query, $.proxy(this.process, this)) : this.source
|
||||
|
||||
return items ? this.process(items) : this
|
||||
}
|
||||
|
||||
, process: function (items) {
|
||||
var that = this
|
||||
|
||||
items = $.grep(items, function (item) {
|
||||
return that.matcher(item)
|
||||
})
|
||||
|
||||
items = this.sorter(items)
|
||||
|
||||
if (!items.length) {
|
||||
return this.shown ? this.hide() : this
|
||||
}
|
||||
|
||||
return this.render(items.slice(0, this.options.items)).show()
|
||||
}
|
||||
|
||||
, matcher: function (item) {
|
||||
return ~item.toLowerCase().indexOf(this.query.toLowerCase())
|
||||
}
|
||||
|
||||
, sorter: function (items) {
|
||||
var beginswith = []
|
||||
, caseSensitive = []
|
||||
, caseInsensitive = []
|
||||
, item
|
||||
|
||||
while (item = items.shift()) {
|
||||
if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item)
|
||||
else if (~item.indexOf(this.query)) caseSensitive.push(item)
|
||||
else caseInsensitive.push(item)
|
||||
}
|
||||
|
||||
return beginswith.concat(caseSensitive, caseInsensitive)
|
||||
}
|
||||
|
||||
, highlighter: function (item) {
|
||||
var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
|
||||
return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
|
||||
return '<strong>' + match + '</strong>'
|
||||
})
|
||||
}
|
||||
|
||||
, render: function (items) {
|
||||
var that = this
|
||||
|
||||
items = $(items).map(function (i, item) {
|
||||
i = $(that.options.item).attr('data-value', item)
|
||||
i.find('a').html(that.highlighter(item))
|
||||
return i[0]
|
||||
})
|
||||
|
||||
items.first().addClass('active')
|
||||
this.$menu.html(items)
|
||||
return this
|
||||
}
|
||||
|
||||
, next: function (event) {
|
||||
var active = this.$menu.find('.active').removeClass('active')
|
||||
, next = active.next()
|
||||
|
||||
if (!next.length) {
|
||||
next = $(this.$menu.find('li')[0])
|
||||
}
|
||||
|
||||
next.addClass('active')
|
||||
}
|
||||
|
||||
, prev: function (event) {
|
||||
var active = this.$menu.find('.active').removeClass('active')
|
||||
, prev = active.prev()
|
||||
|
||||
if (!prev.length) {
|
||||
prev = this.$menu.find('li').last()
|
||||
}
|
||||
|
||||
prev.addClass('active')
|
||||
}
|
||||
|
||||
, listen: function () {
|
||||
this.$element
|
||||
.on('focus', $.proxy(this.focus, this))
|
||||
.on('blur', $.proxy(this.blur, this))
|
||||
.on('keypress', $.proxy(this.keypress, this))
|
||||
.on('keyup', $.proxy(this.keyup, this))
|
||||
|
||||
if (this.eventSupported('keydown')) {
|
||||
this.$element.on('keydown', $.proxy(this.keydown, this))
|
||||
}
|
||||
|
||||
this.$menu
|
||||
.on('click', $.proxy(this.click, this))
|
||||
.on('mouseenter', 'li', $.proxy(this.mouseenter, this))
|
||||
.on('mouseleave', 'li', $.proxy(this.mouseleave, this))
|
||||
}
|
||||
|
||||
, eventSupported: function(eventName) {
|
||||
var isSupported = eventName in this.$element
|
||||
if (!isSupported) {
|
||||
this.$element.setAttribute(eventName, 'return;')
|
||||
isSupported = typeof this.$element[eventName] === 'function'
|
||||
}
|
||||
return isSupported
|
||||
}
|
||||
|
||||
, move: function (e) {
|
||||
if (!this.shown) return
|
||||
|
||||
switch(e.keyCode) {
|
||||
case 9: // tab
|
||||
case 13: // enter
|
||||
case 27: // escape
|
||||
e.preventDefault()
|
||||
break
|
||||
|
||||
case 38: // up arrow
|
||||
e.preventDefault()
|
||||
this.prev()
|
||||
break
|
||||
|
||||
case 40: // down arrow
|
||||
e.preventDefault()
|
||||
this.next()
|
||||
break
|
||||
}
|
||||
|
||||
e.stopPropagation()
|
||||
}
|
||||
|
||||
, keydown: function (e) {
|
||||
this.suppressKeyPressRepeat = ~$.inArray(e.keyCode, [40,38,9,13,27])
|
||||
this.move(e)
|
||||
}
|
||||
|
||||
, keypress: function (e) {
|
||||
if (this.suppressKeyPressRepeat) return
|
||||
this.move(e)
|
||||
}
|
||||
|
||||
, keyup: function (e) {
|
||||
switch(e.keyCode) {
|
||||
case 40: // down arrow
|
||||
case 38: // up arrow
|
||||
case 16: // shift
|
||||
case 17: // ctrl
|
||||
case 18: // alt
|
||||
break
|
||||
|
||||
case 9: // tab
|
||||
case 13: // enter
|
||||
if (!this.shown) return
|
||||
this.select()
|
||||
break
|
||||
|
||||
case 27: // escape
|
||||
if (!this.shown) return
|
||||
this.hide()
|
||||
break
|
||||
|
||||
default:
|
||||
this.lookup()
|
||||
}
|
||||
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
}
|
||||
|
||||
, focus: function (e) {
|
||||
this.focused = true
|
||||
}
|
||||
|
||||
, blur: function (e) {
|
||||
this.focused = false
|
||||
if (!this.mousedover && this.shown) this.hide()
|
||||
}
|
||||
|
||||
, click: function (e) {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
this.select()
|
||||
this.$element.focus()
|
||||
}
|
||||
|
||||
, mouseenter: function (e) {
|
||||
this.mousedover = true
|
||||
this.$menu.find('.active').removeClass('active')
|
||||
$(e.currentTarget).addClass('active')
|
||||
}
|
||||
|
||||
, mouseleave: function (e) {
|
||||
this.mousedover = false
|
||||
if (!this.focused && this.shown) this.hide()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* TYPEAHEAD PLUGIN DEFINITION
|
||||
* =========================== */
|
||||
|
||||
var old = $.fn.typeahead
|
||||
|
||||
$.fn.typeahead = function (option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('typeahead')
|
||||
, options = typeof option == 'object' && option
|
||||
if (!data) $this.data('typeahead', (data = new Typeahead(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.typeahead.defaults = {
|
||||
source: []
|
||||
, items: 8
|
||||
, menu: '<ul class="typeahead dropdown-menu"></ul>'
|
||||
, item: '<li><a href="#"></a></li>'
|
||||
, minLength: 1
|
||||
}
|
||||
|
||||
$.fn.typeahead.Constructor = Typeahead
|
||||
|
||||
|
||||
/* TYPEAHEAD NO CONFLICT
|
||||
* =================== */
|
||||
|
||||
$.fn.typeahead.noConflict = function () {
|
||||
$.fn.typeahead = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
/* TYPEAHEAD DATA-API
|
||||
* ================== */
|
||||
|
||||
$(document).on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
|
||||
var $this = $(this)
|
||||
if ($this.data('typeahead')) return
|
||||
$this.typeahead($this.data())
|
||||
})
|
||||
|
||||
}(window.jQuery);
|
||||
35
static/js/lib/ace/ace/elements.wizard.js
Normal file
35
static/js/lib/ace/ace/elements.wizard.js
Normal file
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
<b>Wizard</b>. A wrapper for FuelUX wizard element.
|
||||
It's just a wrapper so you still need to include FuelUX wizard script first.
|
||||
*/
|
||||
(function($ , undefined) {
|
||||
$.fn.ace_wizard = function(options) {
|
||||
|
||||
this.each(function() {
|
||||
var $this = $(this);
|
||||
$this.wizard();
|
||||
|
||||
var buttons = $this.siblings('.wizard-actions').eq(0);
|
||||
var $wizard = $this.data('wizard');
|
||||
$wizard.$prevBtn.remove();
|
||||
$wizard.$nextBtn.remove();
|
||||
|
||||
$wizard.$prevBtn = buttons.find('.btn-prev').eq(0).on(ace.click_event, function(){
|
||||
$wizard.previous();
|
||||
}).attr('disabled', 'disabled');
|
||||
$wizard.$nextBtn = buttons.find('.btn-next').eq(0).on(ace.click_event, function(){
|
||||
$wizard.next();
|
||||
}).removeAttr('disabled');
|
||||
$wizard.nextText = $wizard.$nextBtn.text();
|
||||
|
||||
var step = options && ((options.selectedItem && options.selectedItem.step) || options.step);
|
||||
if(step) {
|
||||
$wizard.currentStep = step;
|
||||
$wizard.setState();
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
})(window.jQuery);
|
||||
321
static/js/lib/ace/ace/elements.wysiwyg.js
Normal file
321
static/js/lib/ace/ace/elements.wysiwyg.js
Normal file
@@ -0,0 +1,321 @@
|
||||
/**
|
||||
<b>Wysiwyg</b>. A wrapper for Bootstrap wyswiwyg plugin.
|
||||
It's just a wrapper so you still need to include Bootstrap wysiwyg script first.
|
||||
*/
|
||||
(function($ , undefined) {
|
||||
$.fn.ace_wysiwyg = function($options , undefined) {
|
||||
var options = $.extend( {
|
||||
speech_button:true,
|
||||
wysiwyg:{}
|
||||
}, $options);
|
||||
|
||||
var color_values = [
|
||||
'#ac725e','#d06b64','#f83a22','#fa573c','#ff7537','#ffad46',
|
||||
'#42d692','#16a765','#7bd148','#b3dc6c','#fbe983','#fad165',
|
||||
'#92e1c0','#9fe1e7','#9fc6e7','#4986e7','#9a9cff','#b99aff',
|
||||
'#c2c2c2','#cabdbf','#cca6ac','#f691b2','#cd74e6','#a47ae2',
|
||||
'#444444'
|
||||
]
|
||||
|
||||
var button_defaults =
|
||||
{
|
||||
'font' : {
|
||||
values:['Arial', 'Courier', 'Comic Sans MS', 'Helvetica', 'Open Sans', 'Tahoma', 'Verdana'],
|
||||
icon:'fa fa-font',
|
||||
title:'Font'
|
||||
},
|
||||
'fontSize' : {
|
||||
values:{5:'Huge', 3:'Normal', 1:'Small'},
|
||||
icon:'fa fa-text-height',
|
||||
title:'Font Size'
|
||||
},
|
||||
'bold' : {
|
||||
icon : 'fa fa-bold',
|
||||
title : 'Bold (Ctrl/Cmd+B)'
|
||||
},
|
||||
'italic' : {
|
||||
icon : 'fa fa-italic',
|
||||
title : 'Italic (Ctrl/Cmd+I)'
|
||||
},
|
||||
'strikethrough' : {
|
||||
icon : 'fa fa-strikethrough',
|
||||
title : 'Strikethrough'
|
||||
},
|
||||
'underline' : {
|
||||
icon : 'fa fa-underline',
|
||||
title : 'Underline'
|
||||
},
|
||||
'insertunorderedlist' : {
|
||||
icon : 'fa fa-list-ul',
|
||||
title : 'Bullet list'
|
||||
},
|
||||
'insertorderedlist' : {
|
||||
icon : 'fa fa-list-ol',
|
||||
title : 'Number list'
|
||||
},
|
||||
'outdent' : {
|
||||
icon : 'fa fa-outdent',
|
||||
title : 'Reduce indent (Shift+Tab)'
|
||||
},
|
||||
'indent' : {
|
||||
icon : 'fa fa-indent',
|
||||
title : 'Indent (Tab)'
|
||||
},
|
||||
'justifyleft' : {
|
||||
icon : 'fa fa-align-left',
|
||||
title : 'Align Left (Ctrl/Cmd+L)'
|
||||
},
|
||||
'justifycenter' : {
|
||||
icon : 'fa fa-align-center',
|
||||
title : 'Center (Ctrl/Cmd+E)'
|
||||
},
|
||||
'justifyright' : {
|
||||
icon : 'fa fa-align-right',
|
||||
title : 'Align Right (Ctrl/Cmd+R)'
|
||||
},
|
||||
'justifyfull' : {
|
||||
icon : 'fa fa-align-justify',
|
||||
title : 'Justify (Ctrl/Cmd+J)'
|
||||
},
|
||||
'createLink' : {
|
||||
icon : 'fa fa-link',
|
||||
title : 'Hyperlink',
|
||||
button_text : 'Add',
|
||||
placeholder : 'URL',
|
||||
button_class : 'btn-primary'
|
||||
},
|
||||
'unlink' : {
|
||||
icon : 'fa fa-chain-broken',
|
||||
title : 'Remove Hyperlink'
|
||||
},
|
||||
'insertImage' : {
|
||||
icon : 'fa fa-picture-o',
|
||||
title : 'Insert picture',
|
||||
button_text : '<i class="'+ ace.vars['icon'] + 'fa fa-file"></i> Choose Image …',
|
||||
placeholder : 'Image URL',
|
||||
button_insert : 'Insert',
|
||||
button_class : 'btn-success',
|
||||
button_insert_class : 'btn-primary',
|
||||
choose_file: true //show the choose file button?
|
||||
},
|
||||
'foreColor' : {
|
||||
values : color_values,
|
||||
title : 'Change Color'
|
||||
},
|
||||
'backColor' : {
|
||||
values : color_values,
|
||||
title : 'Change Background Color'
|
||||
},
|
||||
'undo' : {
|
||||
icon : 'fa fa-undo',
|
||||
title : 'Undo (Ctrl/Cmd+Z)'
|
||||
},
|
||||
'redo' : {
|
||||
icon : 'fa fa-repeat',
|
||||
title : 'Redo (Ctrl/Cmd+Y)'
|
||||
},
|
||||
'viewSource' : {
|
||||
icon : 'fa fa-code',
|
||||
title : 'View Source'
|
||||
}
|
||||
}
|
||||
|
||||
var toolbar_buttons =
|
||||
options.toolbar ||
|
||||
[
|
||||
'font',
|
||||
null,
|
||||
'fontSize',
|
||||
null,
|
||||
'bold',
|
||||
'italic',
|
||||
'strikethrough',
|
||||
'underline',
|
||||
null,
|
||||
'insertunorderedlist',
|
||||
'insertorderedlist',
|
||||
'outdent',
|
||||
'indent',
|
||||
null,
|
||||
'justifyleft',
|
||||
'justifycenter',
|
||||
'justifyright',
|
||||
'justifyfull',
|
||||
null,
|
||||
'createLink',
|
||||
'unlink',
|
||||
null,
|
||||
'insertImage',
|
||||
null,
|
||||
'foreColor',
|
||||
null,
|
||||
'undo',
|
||||
'redo',
|
||||
null,
|
||||
'viewSource'
|
||||
]
|
||||
|
||||
|
||||
this.each(function() {
|
||||
var toolbar = ' <div class="wysiwyg-toolbar btn-toolbar center"> <div class="btn-group"> ';
|
||||
|
||||
for(var tb in toolbar_buttons) if(toolbar_buttons.hasOwnProperty(tb)) {
|
||||
var button = toolbar_buttons[tb];
|
||||
if(button === null){
|
||||
toolbar += ' </div> <div class="btn-group"> ';
|
||||
continue;
|
||||
}
|
||||
|
||||
if(typeof button == "string" && button in button_defaults) {
|
||||
button = button_defaults[button];
|
||||
button.name = toolbar_buttons[tb];
|
||||
} else if(typeof button == "object" && button.name in button_defaults) {
|
||||
button = $.extend(button_defaults[button.name] , button);
|
||||
}
|
||||
else continue;
|
||||
|
||||
var className = "className" in button ? button.className : 'btn-default';
|
||||
switch(button.name) {
|
||||
case 'font':
|
||||
toolbar += ' <a class="btn btn-sm '+className+' dropdown-toggle" data-toggle="dropdown" title="'+button.title+'"><i class="'+ ace.vars['icon'] + button.icon+'"></i><i class="' + ace.vars['icon'] + 'fa fa-angle-down icon-on-right"></i></a> ';
|
||||
toolbar += ' <ul class="dropdown-menu dropdown-light dropdown-caret">';
|
||||
for(var font in button.values)
|
||||
if(button.values.hasOwnProperty(font))
|
||||
toolbar += ' <li><a data-edit="fontName ' + button.values[font] +'" style="font-family:\''+ button.values[font] +'\'">'+button.values[font] + '</a></li> '
|
||||
toolbar += ' </ul>';
|
||||
break;
|
||||
|
||||
case 'fontSize':
|
||||
toolbar += ' <a class="btn btn-sm '+className+' dropdown-toggle" data-toggle="dropdown" title="'+button.title+'"><i class="'+ ace.vars['icon'] + button.icon+'"></i> <i class="'+ ace.vars['icon'] + 'fa fa-angle-down icon-on-right"></i></a> ';
|
||||
toolbar += ' <ul class="dropdown-menu dropdown-light dropdown-caret"> ';
|
||||
for(var size in button.values)
|
||||
if(button.values.hasOwnProperty(size))
|
||||
toolbar += ' <li><a data-edit="fontSize '+size+'"><font size="'+size+'">'+ button.values[size] +'</font></a></li> '
|
||||
toolbar += ' </ul> ';
|
||||
break;
|
||||
|
||||
case 'createLink':
|
||||
toolbar += ' <div class="btn-group"> <a class="btn btn-sm '+className+' dropdown-toggle" data-toggle="dropdown" title="'+button.title+'"><i class="'+ ace.vars['icon'] + button.icon+'"></i></a> ';
|
||||
toolbar += ' <div class="dropdown-menu dropdown-caret dropdown-menu-right">\
|
||||
<div class="input-group">\
|
||||
<input class="form-control" placeholder="'+button.placeholder+'" type="text" data-edit="'+button.name+'" />\
|
||||
<span class="input-group-btn">\
|
||||
<button class="btn btn-sm '+button.button_class+'" type="button">'+button.button_text+'</button>\
|
||||
</span>\
|
||||
</div>\
|
||||
</div> </div>';
|
||||
break;
|
||||
|
||||
case 'insertImage':
|
||||
toolbar += ' <div class="btn-group"> <a class="btn btn-sm '+className+' dropdown-toggle" data-toggle="dropdown" title="'+button.title+'"><i class="'+ ace.vars['icon'] + button.icon+'"></i></a> ';
|
||||
toolbar += ' <div class="dropdown-menu dropdown-caret dropdown-menu-right">\
|
||||
<div class="input-group">\
|
||||
<input class="form-control" placeholder="'+button.placeholder+'" type="text" data-edit="'+button.name+'" />\
|
||||
<span class="input-group-btn">\
|
||||
<button class="btn btn-sm '+button.button_insert_class+'" type="button">'+button.button_insert+'</button>\
|
||||
</span>\
|
||||
</div>';
|
||||
if( button.choose_file && 'FileReader' in window ) toolbar +=
|
||||
'<div class="space-2"></div>\
|
||||
<label class="center block no-margin-bottom">\
|
||||
<button class="btn btn-sm '+button.button_class+' wysiwyg-choose-file" type="button">'+button.button_text+'</button>\
|
||||
<input type="file" data-edit="'+button.name+'" />\
|
||||
</label>'
|
||||
toolbar += ' </div> </div>';
|
||||
break;
|
||||
|
||||
case 'foreColor':
|
||||
case 'backColor':
|
||||
toolbar += ' <select class="hide wysiwyg_colorpicker" title="'+button.title+'"> ';
|
||||
for(var color in button.values)
|
||||
toolbar += ' <option value="'+button.values[color]+'">'+button.values[color]+'</option> ';
|
||||
toolbar += ' </select> ';
|
||||
toolbar += ' <input style="display:none;" disabled class="hide" type="text" data-edit="'+button.name+'" /> ';
|
||||
break;
|
||||
|
||||
case 'viewSource':
|
||||
toolbar += ' <a class="btn btn-sm '+className+'" data-view="source" title="'+button.title+'"><i class="'+ ace.vars['icon'] + button.icon+'"></i></a> ';
|
||||
break;
|
||||
default:
|
||||
toolbar += ' <a class="btn btn-sm '+className+'" data-edit="'+button.name+'" title="'+button.title+'"><i class="'+ ace.vars['icon'] + button.icon+'"></i></a> ';
|
||||
break;
|
||||
}
|
||||
}
|
||||
toolbar += ' </div> ';
|
||||
////////////
|
||||
var speech_input;
|
||||
if (options.speech_button && 'onwebkitspeechchange' in (speech_input = document.createElement('input'))) {
|
||||
toolbar += ' <input class="wysiwyg-speech-input" type="text" data-edit="inserttext" x-webkit-speech />';
|
||||
}
|
||||
speech_input = null;
|
||||
////////////
|
||||
toolbar += ' </div> ';
|
||||
|
||||
|
||||
//if we have a function to decide where to put the toolbar, then call that
|
||||
if(options.toolbar_place) toolbar = options.toolbar_place.call(this, toolbar);
|
||||
//otherwise put it just before our DIV
|
||||
else toolbar = $(this).before(toolbar).prev();
|
||||
|
||||
toolbar.find('a[title]').tooltip({animation:false, container:'body'});
|
||||
toolbar.find('.dropdown-menu input[type=text]').on('click', function() {return false})
|
||||
.on('change', function() {$(this).closest('.dropdown-menu').siblings('.dropdown-toggle').dropdown('toggle')})
|
||||
.on('keydown', function (e) {
|
||||
if(e.which == 27) {
|
||||
this.value = '';
|
||||
$(this).change();
|
||||
}
|
||||
else if(e.which == 13) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
$(this).change();
|
||||
}
|
||||
});
|
||||
|
||||
toolbar.find('input[type=file]').prev().on(ace.click_event, function (e) {
|
||||
$(this).next().click();
|
||||
});
|
||||
toolbar.find('.wysiwyg_colorpicker').each(function() {
|
||||
$(this).ace_colorpicker({pull_right:true}).change(function(){
|
||||
$(this).nextAll('input').eq(0).val(this.value).change();
|
||||
}).next().find('.btn-colorpicker').tooltip({title: this.title, animation:false, container:'body'})
|
||||
});
|
||||
|
||||
|
||||
var self = $(this);
|
||||
//view source
|
||||
var view_source = false;
|
||||
toolbar.find('a[data-view=source]').on('click', function(e){
|
||||
e.preventDefault();
|
||||
|
||||
if(!view_source) {
|
||||
$('<textarea />')
|
||||
.css({'width':self.outerWidth(), 'height':self.outerHeight()})
|
||||
.val(self.html())
|
||||
.insertAfter(self)
|
||||
self.hide();
|
||||
|
||||
$(this).addClass('active');
|
||||
}
|
||||
else {
|
||||
var textarea = self.next();
|
||||
self.html(textarea.val()).show();
|
||||
textarea.remove();
|
||||
|
||||
$(this).removeClass('active');
|
||||
}
|
||||
|
||||
view_source = !view_source;
|
||||
});
|
||||
|
||||
|
||||
var $options = $.extend({}, { activeToolbarClass: 'active' , toolbarSelector : toolbar }, options.wysiwyg || {})
|
||||
$(this).wysiwyg( $options );
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
})(window.jQuery);
|
||||
|
||||
1
static/js/lib/ace/ace/readme
Normal file
1
static/js/lib/ace/ace/readme
Normal file
@@ -0,0 +1 @@
|
||||
To build a custom JS file please open path/to/ace/build/js.html in your browser.
|
||||
31
static/js/lib/ace/ace/scripts.json
Normal file
31
static/js/lib/ace/ace/scripts.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"elements.scroller.js" : true,
|
||||
"elements.colorpicker.js" : true,
|
||||
"elements.fileinput.js" : true,
|
||||
"elements.typeahead.js" : true,
|
||||
"elements.wysiwyg.js" : true,
|
||||
"elements.spinner.js" : true,
|
||||
"elements.treeview.js" : true,
|
||||
"elements.wizard.js" : true,
|
||||
|
||||
|
||||
"ace.js" : true,
|
||||
"ace.touch-drag.js" : true,
|
||||
"ace.sidebar.js" : true,
|
||||
"ace.submenu-1.js" : true,
|
||||
"ace.sidebar-scroll-1.js" : true,
|
||||
"ace.submenu-hover.js" : true,
|
||||
|
||||
"ace.widget-box.js" : true,
|
||||
|
||||
"ace.settings.js" : true,
|
||||
"ace.settings-rtl.js" : true,
|
||||
"ace.settings-skin.js" : true,
|
||||
|
||||
"ace.widget-on-reload.js" : true,
|
||||
"ace.searchbox-autocomplete.js" : true,
|
||||
|
||||
"ace.autohide-sidebar.js" : false,
|
||||
"ace.auto-padding.js" : false,
|
||||
"ace.auto-container.js" : false
|
||||
}
|
||||
29
static/js/lib/ace/date-time/bootstrap-datetimepicker.min.js
vendored
Normal file
29
static/js/lib/ace/date-time/bootstrap-datetimepicker.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
15
static/js/lib/ace/date-time/locales/bootstrap-datepicker.ar.js
vendored
Normal file
15
static/js/lib/ace/date-time/locales/bootstrap-datepicker.ar.js
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Arabic translation for bootstrap-datepicker
|
||||
* Mohammed Alshehri <alshehri866@gmail.com>
|
||||
*/
|
||||
;(function($){
|
||||
$.fn.datepicker.dates['ar'] = {
|
||||
days: ["الأحد", "الاثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت", "الأحد"],
|
||||
daysShort: ["أحد", "اثنين", "ثلاثاء", "أربعاء", "خميس", "جمعة", "سبت", "أحد"],
|
||||
daysMin: ["ح", "ن", "ث", "ع", "خ", "ج", "س", "ح"],
|
||||
months: ["يناير", "فبراير", "مارس", "أبريل", "مايو", "يونيو", "يوليو", "أغسطس", "سبتمبر", "أكتوبر", "نوفمبر", "ديسمبر"],
|
||||
monthsShort: ["يناير", "فبراير", "مارس", "أبريل", "مايو", "يونيو", "يوليو", "أغسطس", "سبتمبر", "أكتوبر", "نوفمبر", "ديسمبر"],
|
||||
today: "هذا اليوم",
|
||||
rtl: true
|
||||
};
|
||||
}(jQuery));
|
||||
12
static/js/lib/ace/date-time/locales/bootstrap-datepicker.az.js
vendored
Normal file
12
static/js/lib/ace/date-time/locales/bootstrap-datepicker.az.js
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
// Azerbaijani
|
||||
;(function($){
|
||||
$.fn.datepicker.dates['az'] = {
|
||||
days: ["Bazar", "Bazar ertəsi", "Çərşənbə axşamı", "Çərşənbə", "Cümə axşamı", "Cümə", "Şənbə", "Bazar"],
|
||||
daysShort: ["B.", "B.e", "Ç.a", "Ç.", "C.a", "C.", "Ş.", "B."],
|
||||
daysMin: ["B.", "B.e", "Ç.a", "Ç.", "C.a", "C.", "Ş.", "B."],
|
||||
months: ["Yanvar", "Fevral", "Mart", "Aprel", "May", "İyun", "İyul", "Avqust", "Sentyabr", "Oktyabr", "Noyabr", "Dekabr"],
|
||||
monthsShort: ["Yan", "Fev", "Mar", "Apr", "May", "İyun", "İyul", "Avq", "Sen", "Okt", "Noy", "Dek"],
|
||||
today: "Bu gün",
|
||||
weekStart: 1
|
||||
};
|
||||
}(jQuery));
|
||||
14
static/js/lib/ace/date-time/locales/bootstrap-datepicker.cy.js
vendored
Normal file
14
static/js/lib/ace/date-time/locales/bootstrap-datepicker.cy.js
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Welsh translation for bootstrap-datepicker
|
||||
* S. Morris <s.morris@bangor.ac.uk>
|
||||
*/
|
||||
;(function($){
|
||||
$.fn.datepicker.dates['cy'] = {
|
||||
days: ["Sul", "Llun", "Mawrth", "Mercher", "Iau", "Gwener", "Sadwrn", "Sul"],
|
||||
daysShort: ["Sul", "Llu", "Maw", "Mer", "Iau", "Gwe", "Sad", "Sul"],
|
||||
daysMin: ["Su", "Ll", "Ma", "Me", "Ia", "Gwe", "Sa", "Su"],
|
||||
months: ["Ionawr", "Chewfror", "Mawrth", "Ebrill", "Mai", "Mehefin", "Gorfennaf", "Awst", "Medi", "Hydref", "Tachwedd", "Rhagfyr"],
|
||||
monthsShort: ["Ion", "Chw", "Maw", "Ebr", "Mai", "Meh", "Gor", "Aws", "Med", "Hyd", "Tach", "Rha"],
|
||||
today: "Heddiw"
|
||||
};
|
||||
}(jQuery));
|
||||
18
static/js/lib/ace/date-time/locales/bootstrap-datepicker.et.js
vendored
Normal file
18
static/js/lib/ace/date-time/locales/bootstrap-datepicker.et.js
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Estonian translation for bootstrap-datepicker
|
||||
* Ando Roots <https://github.com/anroots>
|
||||
* Fixes by Illimar Tambek <<https://github.com/ragulka>
|
||||
*/
|
||||
;(function($){
|
||||
$.fn.datepicker.dates['et'] = {
|
||||
days: ["Pühapäev", "Esmaspäev", "Teisipäev", "Kolmapäev", "Neljapäev", "Reede", "Laupäev", "Pühapäev"],
|
||||
daysShort: ["Pühap", "Esmasp", "Teisip", "Kolmap", "Neljap", "Reede", "Laup", "Pühap"],
|
||||
daysMin: ["P", "E", "T", "K", "N", "R", "L", "P"],
|
||||
months: ["Jaanuar", "Veebruar", "Märts", "Aprill", "Mai", "Juuni", "Juuli", "August", "September", "Oktoober", "November", "Detsember"],
|
||||
monthsShort: ["Jaan", "Veebr", "Märts", "Apr", "Mai", "Juuni", "Juuli", "Aug", "Sept", "Okt", "Nov", "Dets"],
|
||||
today: "Täna",
|
||||
clear: "Tühjenda",
|
||||
weekStart: 1,
|
||||
format: "dd.mm.yyyy"
|
||||
};
|
||||
}(jQuery));
|
||||
17
static/js/lib/ace/date-time/locales/bootstrap-datepicker.fa.js
vendored
Normal file
17
static/js/lib/ace/date-time/locales/bootstrap-datepicker.fa.js
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Persian translation for bootstrap-datepicker
|
||||
* Mostafa Rokooie <mostafa.rokooie@gmail.com>
|
||||
*/
|
||||
;(function($){
|
||||
$.fn.datepicker.dates['fa'] = {
|
||||
days: ["یکشنبه", "دوشنبه", "سهشنبه", "چهارشنبه", "پنجشنبه", "جمعه", "شنبه", "یکشنبه"],
|
||||
daysShort: ["یک", "دو", "سه", "چهار", "پنج", "جمعه", "شنبه", "یک"],
|
||||
daysMin: ["ی", "د", "س", "چ", "پ", "ج", "ش", "ی"],
|
||||
months: ["ژانویه", "فوریه", "مارس", "آوریل", "مه", "ژوئن", "ژوئیه", "اوت", "سپتامبر", "اکتبر", "نوامبر", "دسامبر"],
|
||||
monthsShort: ["ژان", "فور", "مار", "آور", "مه", "ژون", "ژوی", "اوت", "سپت", "اکت", "نوا", "دسا"],
|
||||
today: "امروز",
|
||||
clear: "پاک کن",
|
||||
weekStart: 1,
|
||||
format: "yyyy/mm/dd"
|
||||
};
|
||||
}(jQuery));
|
||||
11
static/js/lib/ace/date-time/locales/bootstrap-datepicker.gl.js
vendored
Normal file
11
static/js/lib/ace/date-time/locales/bootstrap-datepicker.gl.js
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
;(function($){
|
||||
$.fn.datepicker.dates['gl'] = {
|
||||
days: ["Domingo", "Luns", "Martes", "Mércores", "Xoves", "Venres", "Sábado", "Domingo"],
|
||||
daysShort: ["Dom", "Lun", "Mar", "Mér", "Xov", "Ven", "Sáb", "Dom"],
|
||||
daysMin: ["Do", "Lu", "Ma", "Me", "Xo", "Ve", "Sa", "Do"],
|
||||
months: ["Xaneiro", "Febreiro", "Marzo", "Abril", "Maio", "Xuño", "Xullo", "Agosto", "Setembro", "Outubro", "Novembro", "Decembro"],
|
||||
monthsShort: ["Xan", "Feb", "Mar", "Abr", "Mai", "Xun", "Xul", "Ago", "Sep", "Out", "Nov", "Dec"],
|
||||
today: "Hoxe",
|
||||
clear: "Limpar"
|
||||
};
|
||||
}(jQuery));
|
||||
17
static/js/lib/ace/date-time/locales/bootstrap-datepicker.ka.js
vendored
Normal file
17
static/js/lib/ace/date-time/locales/bootstrap-datepicker.ka.js
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Georgian translation for bootstrap-datepicker
|
||||
* Levan Melikishvili <levani0101@yahoo.com>
|
||||
*/
|
||||
;(function($){
|
||||
$.fn.datepicker.dates['ka'] = {
|
||||
days: ["კვირა", "ორშაბათი", "სამშაბათი", "ოთხშაბათი", "ხუთშაბათი", "პარასკევი", "შაბათი", "კვირა"],
|
||||
daysShort: ["კვი", "ორშ", "სამ", "ოთხ", "ხუთ", "პარ", "შაბ", "კვი"],
|
||||
daysMin: ["კვ", "ორ", "სა", "ოთ", "ხუ", "პა", "შა", "კვ"],
|
||||
months: ["იანვარი", "თებერვალი", "მარტი", "აპრილი", "მაისი", "ივნისი", "ივლისი", "აგვისტო", "სექტემბერი", "ოქტომები", "ნოემბერი", "დეკემბერი"],
|
||||
monthsShort: ["იან", "თებ", "მარ", "აპრ", "მაი", "ივნ", "ივლ", "აგვ", "სექ", "ოქტ", "ნოე", "დეკ"],
|
||||
today: "დღეს",
|
||||
clear: "გასუფთავება",
|
||||
weekStart: 1,
|
||||
format: "dd.mm.yyyy"
|
||||
};
|
||||
}(jQuery));
|
||||
15
static/js/lib/ace/date-time/locales/bootstrap-datepicker.kk.js
vendored
Normal file
15
static/js/lib/ace/date-time/locales/bootstrap-datepicker.kk.js
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Kazakh translation for bootstrap-datepicker
|
||||
* Yerzhan Tolekov <era.tolekov@gmail.com>
|
||||
*/
|
||||
;(function($){
|
||||
$.fn.datepicker.dates['kk'] = {
|
||||
days: ["Жексенбі", "Дүйсенбі", "Сейсенбі", "Сәрсенбі", "Бейсенбі", "Жұма", "Сенбі", "Жексенбі"],
|
||||
daysShort: ["Жек", "Дүй", "Сей", "Сәр", "Бей", "Жұм", "Сен", "Жек"],
|
||||
daysMin: ["Жк", "Дс", "Сс", "Ср", "Бс", "Жм", "Сн", "Жк"],
|
||||
months: ["Қаңтар", "Ақпан", "Наурыз", "Сәуір", "Мамыр", "Маусым", "Шілде", "Тамыз", "Қыркүйек", "Қазан", "Қараша", "Желтоқсан"],
|
||||
monthsShort: ["Қаң", "Ақп", "Нау", "Сәу", "Мамыр", "Мау", "Шлд", "Тмз", "Қыр", "Қзн", "Қар", "Жел"],
|
||||
today: "Бүгін",
|
||||
weekStart: 1
|
||||
};
|
||||
}(jQuery));
|
||||
15
static/js/lib/ace/date-time/locales/bootstrap-datepicker.mk.js
vendored
Normal file
15
static/js/lib/ace/date-time/locales/bootstrap-datepicker.mk.js
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Macedonian translation for bootstrap-datepicker
|
||||
* Marko Aleksic <psybaron@gmail.com>
|
||||
*/
|
||||
;(function($){
|
||||
$.fn.datepicker.dates['mk'] = {
|
||||
days: ["Недела", "Понеделник", "Вторник", "Среда", "Четврток", "Петок", "Сабота", "Недела"],
|
||||
daysShort: ["Нед", "Пон", "Вто", "Сре", "Чет", "Пет", "Саб", "Нед"],
|
||||
daysMin: ["Не", "По", "Вт", "Ср", "Че", "Пе", "Са", "Не"],
|
||||
months: ["Јануари", "Февруари", "Март", "Април", "Мај", "Јуни", "Јули", "Август", "Септември", "Октомври", "Ноември", "Декември"],
|
||||
monthsShort: ["Јан", "Фев", "Мар", "Апр", "Мај", "Јун", "Јул", "Авг", "Сеп", "Окт", "Ное", "Дек"],
|
||||
today: "Денес",
|
||||
format: "dd.mm.yyyy"
|
||||
};
|
||||
}(jQuery));
|
||||
17
static/js/lib/ace/date-time/locales/bootstrap-datepicker.nl-BE.js
vendored
Normal file
17
static/js/lib/ace/date-time/locales/bootstrap-datepicker.nl-BE.js
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Belgium-Dutch translation for bootstrap-datepicker
|
||||
* Julien Poulin <poulin_julien@hotmail.com>
|
||||
*/
|
||||
;(function($){
|
||||
$.fn.datepicker.dates['nl-BE'] = {
|
||||
days: ["Zondag", "Maandag", "Dinsdag", "Woensdag", "Donderdag", "Vrijdag", "Zaterdag", "Zondag"],
|
||||
daysShort: ["Zo", "Ma", "Di", "Wo", "Do", "Vr", "Za", "Zo"],
|
||||
daysMin: ["Zo", "Ma", "Di", "Wo", "Do", "Vr", "Za", "Zo"],
|
||||
months: ["Januari", "Februari", "Maart", "April", "Mei", "Juni", "Juli", "Augustus", "September", "Oktober", "November", "December"],
|
||||
monthsShort: ["Jan", "Feb", "Mrt", "Apr", "Mei", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"],
|
||||
today: "Vandaag",
|
||||
clear: "Leegmaken",
|
||||
weekStart: 1,
|
||||
format: "dd/mm/yyyy"
|
||||
};
|
||||
}(jQuery));
|
||||
16
static/js/lib/ace/date-time/locales/bootstrap-datepicker.no.js
vendored
Normal file
16
static/js/lib/ace/date-time/locales/bootstrap-datepicker.no.js
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Norwegian translation for bootstrap-datepicker
|
||||
**/
|
||||
;(function($){
|
||||
$.fn.datepicker.dates['no'] = {
|
||||
days: ['Søndag','Mandag','Tirsdag','Onsdag','Torsdag','Fredag','Lørdag'],
|
||||
daysShort: ['Søn','Man','Tir','Ons','Tor','Fre','Lør'],
|
||||
daysMin: ['Sø','Ma','Ti','On','To','Fr','Lø'],
|
||||
months: ['Januar','Februar','Mars','April','Mai','Juni','Juli','August','September','Oktober','November','Desember'],
|
||||
monthsShort: ['Jan','Feb','Mar','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Des'],
|
||||
today: 'I dag',
|
||||
clear: 'Nullstill',
|
||||
weekStart: 1,
|
||||
format: 'dd.mm.yyyy'
|
||||
};
|
||||
}(jQuery));
|
||||
15
static/js/lib/ace/date-time/locales/bootstrap-datepicker.sq.js
vendored
Normal file
15
static/js/lib/ace/date-time/locales/bootstrap-datepicker.sq.js
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Albanian translation for bootstrap-datepicker
|
||||
* Tomor Pupovci <http://www.github.com/ttomor>
|
||||
*/
|
||||
;(function($){
|
||||
$.fn.datepicker.dates['sq'] = {
|
||||
days: ["E Diel", "E Hënë", "E martē", "E mërkurë", "E Enjte", "E Premte", "E Shtunë", "E Diel"],
|
||||
daysShort: ["Die", "Hën", "Mar", "Mër", "Enj", "Pre", "Shtu", "Die"],
|
||||
daysMin: ["Di", "Hë", "Ma", "Më", "En", "Pr", "Sht", "Di"],
|
||||
months: ["Janar", "Shkurt", "Mars", "Prill", "Maj", "Qershor", "Korrik", "Gusht", "Shtator", "Tetor", "Nëntor", "Dhjetor"],
|
||||
monthsShort: ["Jan", "Shk", "Mar", "Pri", "Maj", "Qer", "Korr", "Gu", "Sht", "Tet", "Nën", "Dhjet"],
|
||||
today: "Sot"
|
||||
};
|
||||
}(jQuery));
|
||||
|
||||
15
static/js/lib/ace/date-time/locales/bootstrap-datepicker.ua.js
vendored
Normal file
15
static/js/lib/ace/date-time/locales/bootstrap-datepicker.ua.js
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Ukrainian translation for bootstrap-datepicker
|
||||
* Igor Polynets
|
||||
*/
|
||||
;(function($){
|
||||
$.fn.datepicker.dates['ua'] = {
|
||||
days: ["Неділя", "Понеділок", "Вівторок", "Середа", "Четвер", "П'ятница", "Субота", "Неділя"],
|
||||
daysShort: ["Нед", "Пнд", "Втр", "Срд", "Чтв", "Птн", "Суб", "Нед"],
|
||||
daysMin: ["Нд", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Нд"],
|
||||
months: ["Cічень", "Лютий", "Березень", "Квітень", "Травень", "Червень", "Липень", "Серпень", "Вересень", "Жовтень", "Листопад", "Грудень"],
|
||||
monthsShort: ["Січ", "Лют", "Бер", "Кві", "Тра", "Чер", "Лип", "Сер", "Вер", "Жов", "Лис", "Гру"],
|
||||
today: "Сьогодні",
|
||||
weekStart: 1
|
||||
};
|
||||
}(jQuery));
|
||||
16
static/js/lib/ace/date-time/locales/bootstrap-datepicker.vi.js
vendored
Normal file
16
static/js/lib/ace/date-time/locales/bootstrap-datepicker.vi.js
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Vietnamese translation for bootstrap-datepicker
|
||||
* An Vo <https://github.com/anvoz/>
|
||||
*/
|
||||
;(function($){
|
||||
$.fn.datepicker.dates['vi'] = {
|
||||
days: ["Chủ nhật", "Thứ hai", "Thứ ba", "Thứ tư", "Thứ năm", "Thứ sáu", "Thứ bảy", "Chủ nhật"],
|
||||
daysShort: ["CN", "Thứ 2", "Thứ 3", "Thứ 4", "Thứ 5", "Thứ 6", "Thứ 7", "CN"],
|
||||
daysMin: ["CN", "T2", "T3", "T4", "T5", "T6", "T7", "CN"],
|
||||
months: ["Tháng 1", "Tháng 2", "Tháng 3", "Tháng 4", "Tháng 5", "Tháng 6", "Tháng 7", "Tháng 8", "Tháng 9", "Tháng 10", "Tháng 11", "Tháng 12"],
|
||||
monthsShort: ["Th1", "Th2", "Th3", "Th4", "Th5", "Th6", "Th7", "Th8", "Th9", "Th10", "Th11", "Th12"],
|
||||
today: "Hôm nay",
|
||||
clear: "Xóa",
|
||||
format: "dd/mm/yyyy"
|
||||
};
|
||||
}(jQuery));
|
||||
178
static/js/lib/ace/fuelux/data/fuelux.tree-sample-demo-data.js
Normal file
178
static/js/lib/ace/fuelux/data/fuelux.tree-sample-demo-data.js
Normal file
@@ -0,0 +1,178 @@
|
||||
var DataSourceTree = function(options) {
|
||||
this._data = options.data;
|
||||
this._delay = options.delay;
|
||||
}
|
||||
|
||||
DataSourceTree.prototype.data = function(options, callback) {
|
||||
var self = this;
|
||||
var $data = null;
|
||||
|
||||
if(!("name" in options) && !("type" in options)){
|
||||
$data = this._data;//the root tree
|
||||
callback({ data: $data });
|
||||
return;
|
||||
}
|
||||
else if("type" in options && options.type == "folder") {
|
||||
if("additionalParameters" in options && "children" in options.additionalParameters)
|
||||
$data = options.additionalParameters.children;
|
||||
else $data = {}//no data
|
||||
}
|
||||
|
||||
if($data != null)//this setTimeout is only for mimicking some random delay
|
||||
setTimeout(function(){callback({ data: $data });} , parseInt(Math.random() * 500) + 200);
|
||||
|
||||
//we have used static data here
|
||||
//but you can retrieve your data dynamically from a server using ajax call
|
||||
//checkout examples/treeview.html and examples/treeview.js for more info
|
||||
};
|
||||
|
||||
var tree_data = {
|
||||
'for-sale' : {name: 'For Sale', type: 'folder'} ,
|
||||
'vehicles' : {name: 'Vehicles', type: 'folder'} ,
|
||||
'rentals' : {name: 'Rentals', type: 'folder'} ,
|
||||
'real-estate' : {name: 'Real Estate', type: 'folder'} ,
|
||||
'pets' : {name: 'Pets', type: 'folder'} ,
|
||||
'tickets' : {name: 'Tickets', type: 'item'} ,
|
||||
'services' : {name: 'Services', type: 'item'} ,
|
||||
'personals' : {name: 'Personals', type: 'item'}
|
||||
}
|
||||
tree_data['for-sale']['additionalParameters'] = {
|
||||
'children' : {
|
||||
'appliances' : {name: 'Appliances', type: 'item'},
|
||||
'arts-crafts' : {name: 'Arts & Crafts', type: 'item'},
|
||||
'clothing' : {name: 'Clothing', type: 'item'},
|
||||
'computers' : {name: 'Computers', type: 'item'},
|
||||
'jewelry' : {name: 'Jewelry', type: 'item'},
|
||||
'office-business' : {name: 'Office & Business', type: 'item'},
|
||||
'sports-fitness' : {name: 'Sports & Fitness', type: 'item'}
|
||||
}
|
||||
}
|
||||
tree_data['vehicles']['additionalParameters'] = {
|
||||
'children' : {
|
||||
'cars' : {name: 'Cars', type: 'folder'},
|
||||
'motorcycles' : {name: 'Motorcycles', type: 'item'},
|
||||
'boats' : {name: 'Boats', type: 'item'}
|
||||
}
|
||||
}
|
||||
tree_data['vehicles']['additionalParameters']['children']['cars']['additionalParameters'] = {
|
||||
'children' : {
|
||||
'classics' : {name: 'Classics', type: 'item'},
|
||||
'convertibles' : {name: 'Convertibles', type: 'item'},
|
||||
'coupes' : {name: 'Coupes', type: 'item'},
|
||||
'hatchbacks' : {name: 'Hatchbacks', type: 'item'},
|
||||
'hybrids' : {name: 'Hybrids', type: 'item'},
|
||||
'suvs' : {name: 'SUVs', type: 'item'},
|
||||
'sedans' : {name: 'Sedans', type: 'item'},
|
||||
'trucks' : {name: 'Trucks', type: 'item'}
|
||||
}
|
||||
}
|
||||
|
||||
tree_data['rentals']['additionalParameters'] = {
|
||||
'children' : {
|
||||
'apartments-rentals' : {name: 'Apartments', type: 'item'},
|
||||
'office-space-rentals' : {name: 'Office Space', type: 'item'},
|
||||
'vacation-rentals' : {name: 'Vacation Rentals', type: 'item'}
|
||||
}
|
||||
}
|
||||
tree_data['real-estate']['additionalParameters'] = {
|
||||
'children' : {
|
||||
'apartments' : {name: 'Apartments', type: 'item'},
|
||||
'villas' : {name: 'Villas', type: 'item'},
|
||||
'plots' : {name: 'Plots', type: 'item'}
|
||||
}
|
||||
}
|
||||
tree_data['pets']['additionalParameters'] = {
|
||||
'children' : {
|
||||
'cats' : {name: 'Cats', type: 'item'},
|
||||
'dogs' : {name: 'Dogs', type: 'item'},
|
||||
'horses' : {name: 'Horses', type: 'item'},
|
||||
'reptiles' : {name: 'Reptiles', type: 'item'}
|
||||
}
|
||||
}
|
||||
|
||||
var treeDataSource = new DataSourceTree({data: tree_data});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var ace_icon = ace.vars['icon'];
|
||||
//class="'+ace_icon+' fa fa-file-text grey"
|
||||
//becomes
|
||||
//class="ace-icon fa fa-file-text grey"
|
||||
var tree_data_2 = {
|
||||
'pictures' : {name: 'Pictures', type: 'folder', 'icon-class':'red'} ,
|
||||
'music' : {name: 'Music', type: 'folder', 'icon-class':'orange'} ,
|
||||
'video' : {name: 'Video', type: 'folder', 'icon-class':'blue'} ,
|
||||
'documents' : {name: 'Documents', type: 'folder', 'icon-class':'green'} ,
|
||||
'backup' : {name: 'Backup', type: 'folder'} ,
|
||||
'readme' : {name: '<i class="'+ace_icon+' fa fa-file-text grey"></i> ReadMe.txt', type: 'item'},
|
||||
'manual' : {name: '<i class="'+ace_icon+' fa fa-book blue"></i> Manual.html', type: 'item'}
|
||||
}
|
||||
tree_data_2['music']['additionalParameters'] = {
|
||||
'children' : [
|
||||
{name: '<i class="'+ace_icon+' fa fa-music blue"></i> song1.ogg', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-music blue"></i> song2.ogg', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-music blue"></i> song3.ogg', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-music blue"></i> song4.ogg', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-music blue"></i> song5.ogg', type: 'item'}
|
||||
]
|
||||
}
|
||||
tree_data_2['video']['additionalParameters'] = {
|
||||
'children' : [
|
||||
{name: '<i class="'+ace_icon+' fa fa-film blue"></i> movie1.avi', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-film blue"></i> movie2.avi', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-film blue"></i> movie3.avi', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-film blue"></i> movie4.avi', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-film blue"></i> movie5.avi', type: 'item'}
|
||||
]
|
||||
}
|
||||
tree_data_2['pictures']['additionalParameters'] = {
|
||||
'children' : {
|
||||
'wallpapers' : {name: 'Wallpapers', type: 'folder', 'icon-class':'pink'},
|
||||
'camera' : {name: 'Camera', type: 'folder', 'icon-class':'pink'}
|
||||
}
|
||||
}
|
||||
tree_data_2['pictures']['additionalParameters']['children']['wallpapers']['additionalParameters'] = {
|
||||
'children' : [
|
||||
{name: '<i class="'+ace_icon+' fa fa-picture-o green"></i> wallpaper1.jpg', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-picture-o green"></i> wallpaper2.jpg', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-picture-o green"></i> wallpaper3.jpg', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-picture-o green"></i> wallpaper4.jpg', type: 'item'}
|
||||
]
|
||||
}
|
||||
tree_data_2['pictures']['additionalParameters']['children']['camera']['additionalParameters'] = {
|
||||
'children' : [
|
||||
{name: '<i class="'+ace_icon+' fa fa-picture-o green"></i> photo1.jpg', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-picture-o green"></i> photo2.jpg', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-picture-o green"></i> photo3.jpg', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-picture-o green"></i> photo4.jpg', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-picture-o green"></i> photo5.jpg', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-picture-o green"></i> photo6.jpg', type: 'item'}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
tree_data_2['documents']['additionalParameters'] = {
|
||||
'children' : [
|
||||
{name: '<i class="'+ace_icon+' fa fa-file-text red"></i> document1.pdf', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-file-text grey"></i> document2.doc', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-file-text grey"></i> document3.doc', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-file-text red"></i> document4.pdf', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-file-text grey"></i> document5.doc', type: 'item'}
|
||||
]
|
||||
}
|
||||
|
||||
tree_data_2['backup']['additionalParameters'] = {
|
||||
'children' : [
|
||||
{name: '<i class="'+ace_icon+' fa fa-archive brown"></i> backup1.zip', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-archive brown"></i> backup2.zip', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-archive brown"></i> backup3.zip', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-archive brown"></i> backup4.zip', type: 'item'}
|
||||
]
|
||||
}
|
||||
var treeDataSource2 = new DataSourceTree({data: tree_data_2});
|
||||
6
static/js/lib/ace/jquery-ui.custom.min.js
vendored
Normal file
6
static/js/lib/ace/jquery-ui.custom.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
7
static/js/lib/ace/jquery-ui.min.js
vendored
Normal file
7
static/js/lib/ace/jquery-ui.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
200
static/js/lib/ace/jquery.easy-pie-chart-older.js
Normal file
200
static/js/lib/ace/jquery.easy-pie-chart-older.js
Normal file
@@ -0,0 +1,200 @@
|
||||
// Generated by CoffeeScript 1.6.3
|
||||
/*
|
||||
Easy pie chart is a jquery plugin to display simple animated pie charts for only one value
|
||||
|
||||
Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
|
||||
and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
|
||||
|
||||
Built on top of the jQuery library (http://jquery.com)
|
||||
|
||||
@source: http://github.com/rendro/easy-pie-chart/
|
||||
@autor: Robert Fleischmann
|
||||
@version: 1.2.5
|
||||
|
||||
Inspired by: http://dribbble.com/shots/631074-Simple-Pie-Charts-II?list=popular&offset=210
|
||||
Thanks to Philip Thrasher for the jquery plugin boilerplate for coffee script
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
$.easyPieChart = function(el, options) {
|
||||
var addScaleLine, animateLine, drawLine, easeInOutQuad, rAF, renderBackground, renderScale, renderTrack,
|
||||
_this = this;
|
||||
this.el = el;
|
||||
this.$el = $(el);
|
||||
this.$el.data("easyPieChart", this);
|
||||
this.init = function() {
|
||||
var percent, scaleBy;
|
||||
_this.options = $.extend({}, $.easyPieChart.defaultOptions, options);
|
||||
percent = parseInt(_this.$el.data('percent'), 10);
|
||||
_this.percentage = 0;
|
||||
_this.canvas = $("<canvas width='" + _this.options.size + "' height='" + _this.options.size + "'></canvas>").get(0);
|
||||
_this.$el.append(_this.canvas);
|
||||
if (typeof G_vmlCanvasManager !== "undefined" && G_vmlCanvasManager !== null) {
|
||||
G_vmlCanvasManager.initElement(_this.canvas);
|
||||
}
|
||||
_this.ctx = _this.canvas.getContext('2d');
|
||||
if (window.devicePixelRatio > 1) {
|
||||
scaleBy = window.devicePixelRatio;
|
||||
$(_this.canvas).css({
|
||||
width: _this.options.size,
|
||||
height: _this.options.size
|
||||
});
|
||||
_this.canvas.width *= scaleBy;
|
||||
_this.canvas.height *= scaleBy;
|
||||
_this.ctx.scale(scaleBy, scaleBy);
|
||||
}
|
||||
_this.ctx.translate(_this.options.size / 2, _this.options.size / 2);
|
||||
_this.ctx.rotate(_this.options.rotate * Math.PI / 180);
|
||||
_this.$el.addClass('easyPieChart');
|
||||
_this.$el.css({
|
||||
width: _this.options.size,
|
||||
height: _this.options.size,
|
||||
lineHeight: "" + _this.options.size + "px"
|
||||
});
|
||||
_this.update(percent);
|
||||
return _this;
|
||||
};
|
||||
this.update = function(percent) {
|
||||
percent = parseFloat(percent) || 0;
|
||||
if (_this.options.animate === false) {
|
||||
drawLine(percent);
|
||||
} else {
|
||||
if (_this.options.delay) {
|
||||
animateLine(_this.percentage, 0);
|
||||
setTimeout(function() {
|
||||
return animateLine(_this.percentage, percent);
|
||||
}, _this.options.delay);
|
||||
} else {
|
||||
animateLine(_this.percentage, percent);
|
||||
}
|
||||
}
|
||||
return _this;
|
||||
};
|
||||
renderScale = function() {
|
||||
var i, _i, _results;
|
||||
_this.ctx.fillStyle = _this.options.scaleColor;
|
||||
_this.ctx.lineWidth = 1;
|
||||
_results = [];
|
||||
for (i = _i = 0; _i <= 24; i = ++_i) {
|
||||
_results.push(addScaleLine(i));
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
addScaleLine = function(i) {
|
||||
var offset;
|
||||
offset = i % 6 === 0 ? 0 : _this.options.size * 0.017;
|
||||
_this.ctx.save();
|
||||
_this.ctx.rotate(i * Math.PI / 12);
|
||||
_this.ctx.fillRect(_this.options.size / 2 - offset, 0, -_this.options.size * 0.05 + offset, 1);
|
||||
_this.ctx.restore();
|
||||
};
|
||||
renderTrack = function() {
|
||||
var offset;
|
||||
offset = _this.options.size / 2 - _this.options.lineWidth / 2;
|
||||
if (_this.options.scaleColor !== false) {
|
||||
offset -= _this.options.size * 0.08;
|
||||
}
|
||||
_this.ctx.beginPath();
|
||||
_this.ctx.arc(0, 0, offset, 0, Math.PI * 2, true);
|
||||
_this.ctx.closePath();
|
||||
_this.ctx.strokeStyle = _this.options.trackColor;
|
||||
_this.ctx.lineWidth = _this.options.lineWidth;
|
||||
_this.ctx.stroke();
|
||||
};
|
||||
renderBackground = function() {
|
||||
if (_this.options.scaleColor !== false) {
|
||||
renderScale();
|
||||
}
|
||||
if (_this.options.trackColor !== false) {
|
||||
renderTrack();
|
||||
}
|
||||
};
|
||||
drawLine = function(percent) {
|
||||
var offset;
|
||||
renderBackground();
|
||||
_this.ctx.strokeStyle = $.isFunction(_this.options.barColor) ? _this.options.barColor(percent) : _this.options.barColor;
|
||||
_this.ctx.lineCap = _this.options.lineCap;
|
||||
_this.ctx.lineWidth = _this.options.lineWidth;
|
||||
offset = _this.options.size / 2 - _this.options.lineWidth / 2;
|
||||
if (_this.options.scaleColor !== false) {
|
||||
offset -= _this.options.size * 0.08;
|
||||
}
|
||||
_this.ctx.save();
|
||||
_this.ctx.rotate(-Math.PI / 2);
|
||||
_this.ctx.beginPath();
|
||||
_this.ctx.arc(0, 0, offset, 0, Math.PI * 2 * percent / 100, false);
|
||||
_this.ctx.stroke();
|
||||
_this.ctx.restore();
|
||||
};
|
||||
rAF = (function() {
|
||||
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) {
|
||||
return window.setTimeout(callback, 1000 / 60);
|
||||
};
|
||||
})();
|
||||
animateLine = function(from, to) {
|
||||
var anim, startTime;
|
||||
_this.options.onStart.call(_this);
|
||||
_this.percentage = to;
|
||||
Date.now || (Date.now = function() {
|
||||
return +(new Date);
|
||||
});
|
||||
startTime = Date.now();
|
||||
anim = function() {
|
||||
var currentValue, process;
|
||||
process = Math.min(Date.now() - startTime, _this.options.animate);
|
||||
_this.ctx.clearRect(-_this.options.size / 2, -_this.options.size / 2, _this.options.size, _this.options.size);
|
||||
renderBackground.call(_this);
|
||||
currentValue = [easeInOutQuad(process, from, to - from, _this.options.animate)];
|
||||
_this.options.onStep.call(_this, currentValue);
|
||||
drawLine.call(_this, currentValue);
|
||||
if (process >= _this.options.animate) {
|
||||
return _this.options.onStop.call(_this, currentValue, to);
|
||||
} else {
|
||||
return rAF(anim);
|
||||
}
|
||||
};
|
||||
rAF(anim);
|
||||
};
|
||||
easeInOutQuad = function(t, b, c, d) {
|
||||
var easeIn, easing;
|
||||
easeIn = function(t) {
|
||||
return Math.pow(t, 2);
|
||||
};
|
||||
easing = function(t) {
|
||||
if (t < 1) {
|
||||
return easeIn(t);
|
||||
} else {
|
||||
return 2 - easeIn((t / 2) * -2 + 2);
|
||||
}
|
||||
};
|
||||
t /= d / 2;
|
||||
return c / 2 * easing(t) + b;
|
||||
};
|
||||
return this.init();
|
||||
};
|
||||
$.easyPieChart.defaultOptions = {
|
||||
barColor: '#ef1e25',
|
||||
trackColor: '#f2f2f2',
|
||||
scaleColor: '#dfe0e0',
|
||||
lineCap: 'round',
|
||||
rotate: 0,
|
||||
size: 110,
|
||||
lineWidth: 3,
|
||||
animate: false,
|
||||
delay: false,
|
||||
onStart: $.noop,
|
||||
onStop: $.noop,
|
||||
onStep: $.noop
|
||||
};
|
||||
$.fn.easyPieChart = function(options) {
|
||||
return $.each(this, function(i, el) {
|
||||
var $el, instanceOptions;
|
||||
$el = $(el);
|
||||
if (!$el.data('easyPieChart')) {
|
||||
instanceOptions = $.extend({}, options, $el.data());
|
||||
return $el.data('easyPieChart', new $.easyPieChart(el, instanceOptions));
|
||||
}
|
||||
});
|
||||
};
|
||||
return void 0;
|
||||
})(jQuery);
|
||||
9
static/js/lib/ace/jquery.easypiechart.min.js
vendored
Normal file
9
static/js/lib/ace/jquery.easypiechart.min.js
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
/**!
|
||||
* easyPieChart
|
||||
* Lightweight plugin to render simple, animated and retina optimized pie charts
|
||||
*
|
||||
* @license
|
||||
* @author Robert Fleischmann <rendro87@gmail.com> (http://robert-fleischmann.de)
|
||||
* @version 2.1.5
|
||||
**/
|
||||
(function(a,b){if(typeof exports==="object"){module.exports=b(require("jquery"))}else{if(typeof define==="function"&&define.amd){define(["jquery"],b)}else{b(a.jQuery)}}}(this,function(c){var a=function(e,n){var l;var f=document.createElement("canvas");e.appendChild(f);if(typeof(G_vmlCanvasManager)!=="undefined"){G_vmlCanvasManager.initElement(f)}var m=f.getContext("2d");f.width=f.height=n.size;var k=1;if(window.devicePixelRatio>1){k=window.devicePixelRatio;f.style.width=f.style.height=[n.size,"px"].join("");f.width=f.height=n.size*k;m.scale(k,k)}m.translate(n.size/2,n.size/2);m.rotate((-1/2+n.rotate/180)*Math.PI);var i=(n.size-n.lineWidth)/2;if(n.scaleColor&&n.scaleLength){i-=n.scaleLength+2}Date.now=Date.now||function(){return +(new Date())};var j=function(q,o,r){r=Math.min(Math.max(-1,r||0),1);var p=r<=0?true:false;m.beginPath();m.arc(0,0,i,0,Math.PI*2*r,p);m.strokeStyle=q;m.lineWidth=o;m.stroke()};var d=function(){var q;var p;m.lineWidth=1;m.fillStyle=n.scaleColor;m.save();for(var o=24;o>0;--o){if(o%6===0){p=n.scaleLength;q=0}else{p=n.scaleLength*0.6;q=n.scaleLength-p}m.fillRect(-n.size/2+q,0,p,1);m.rotate(Math.PI/12)}m.restore()};var h=(function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(o){window.setTimeout(o,1000/60)}}());var g=function(){if(n.scaleColor){d()}if(n.trackColor){j(n.trackColor,n.lineWidth,1)}};this.getCanvas=function(){return f};this.getCtx=function(){return m};this.clear=function(){m.clearRect(n.size/-2,n.size/-2,n.size,n.size)};this.draw=function(p){if(!!n.scaleColor||!!n.trackColor){if(m.getImageData&&m.putImageData){if(!l){g();l=m.getImageData(0,0,n.size*k,n.size*k)}else{m.putImageData(l,0,0)}}else{this.clear();g()}}else{this.clear()}m.lineCap=n.lineCap;var o;if(typeof(n.barColor)==="function"){o=n.barColor(p)}else{o=n.barColor}j(o,n.lineWidth,p/100)}.bind(this);this.animate=function(r,q){var o=Date.now();n.onStart(r,q);var p=function(){var t=Math.min(Date.now()-o,n.animate.duration);var s=n.easing(this,t,r,q-r,n.animate.duration);this.draw(s);n.onStep(r,q,s);if(t>=n.animate.duration){n.onStop(r,q)}else{h(p)}}.bind(this);h(p)}.bind(this)};var b=function(g,h){var d={barColor:"#ef1e25",trackColor:"#f9f9f9",scaleColor:"#dfe0e0",scaleLength:5,lineCap:"round",lineWidth:3,size:110,rotate:0,animate:{duration:1000,enabled:true},easing:function(k,l,j,n,m){l=l/(m/2);if(l<1){return n/2*l*l+j}return -n/2*((--l)*(l-2)-1)+j},onStart:function(k,j){return},onStep:function(l,k,j){return},onStop:function(k,j){return}};if(typeof(a)!=="undefined"){d.renderer=a}else{if(typeof(SVGRenderer)!=="undefined"){d.renderer=SVGRenderer}else{throw new Error("Please load either the SVG- or the CanvasRenderer")}}var e={};var f=0;var i=function(){this.el=g;this.options=e;for(var j in d){if(d.hasOwnProperty(j)){e[j]=h&&typeof(h[j])!=="undefined"?h[j]:d[j];if(typeof(e[j])==="function"){e[j]=e[j].bind(this)}}}if(typeof(e.easing)==="string"&&typeof(jQuery)!=="undefined"&&jQuery.isFunction(jQuery.easing[e.easing])){e.easing=jQuery.easing[e.easing]}else{e.easing=d.easing}if(typeof(e.animate)==="number"){e.animate={duration:e.animate,enabled:true}}if(typeof(e.animate)==="boolean"&&!e.animate){e.animate={duration:1000,enabled:e.animate}}this.renderer=new e.renderer(g,e);this.renderer.draw(f);if(g.dataset&&g.dataset.percent){this.update(parseFloat(g.dataset.percent))}else{if(g.getAttribute&&g.getAttribute("data-percent")){this.update(parseFloat(g.getAttribute("data-percent")))}}g.style.width=g.style.height=e.size+"px";g.style.lineHeight=(e.size-1)+"px"}.bind(this);this.update=function(j){j=parseFloat(j);if(e.animate.enabled){this.renderer.animate(f,j)}else{this.renderer.draw(j)}f=j;return this}.bind(this);this.disableAnimation=function(){e.animate.enabled=false;return this};this.enableAnimation=function(){e.animate.enabled=true;return this};i()};c.fn.easyPieChart=function(d){return this.each(function(){var e;if(!c.data(this,"easyPieChart")){e=c.extend({},d,c(this).data());c.data(this,"easyPieChart",new b(this,e))}})}}));
|
||||
15
static/js/lib/ace/jquery.knob-older.min.js
vendored
Normal file
15
static/js/lib/ace/jquery.knob-older.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
4
static/js/lib/ace/jquery.min.js
vendored
Normal file
4
static/js/lib/ace/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
4
static/js/lib/ace/jquery1x.min.js
vendored
Normal file
4
static/js/lib/ace/jquery1x.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1160
static/js/lib/ace/uncompressed/date-time/bootstrap-datetimepicker.js
vendored
Normal file
1160
static/js/lib/ace/uncompressed/date-time/bootstrap-datetimepicker.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,178 @@
|
||||
var DataSourceTree = function(options) {
|
||||
this._data = options.data;
|
||||
this._delay = options.delay;
|
||||
}
|
||||
|
||||
DataSourceTree.prototype.data = function(options, callback) {
|
||||
var self = this;
|
||||
var $data = null;
|
||||
|
||||
if(!("name" in options) && !("type" in options)){
|
||||
$data = this._data;//the root tree
|
||||
callback({ data: $data });
|
||||
return;
|
||||
}
|
||||
else if("type" in options && options.type == "folder") {
|
||||
if("additionalParameters" in options && "children" in options.additionalParameters)
|
||||
$data = options.additionalParameters.children;
|
||||
else $data = {}//no data
|
||||
}
|
||||
|
||||
if($data != null)//this setTimeout is only for mimicking some random delay
|
||||
setTimeout(function(){callback({ data: $data });} , parseInt(Math.random() * 500) + 200);
|
||||
|
||||
//we have used static data here
|
||||
//but you can retrieve your data dynamically from a server using ajax call
|
||||
//checkout examples/treeview.html and examples/treeview.js for more info
|
||||
};
|
||||
|
||||
var tree_data = {
|
||||
'for-sale' : {name: 'For Sale', type: 'folder'} ,
|
||||
'vehicles' : {name: 'Vehicles', type: 'folder'} ,
|
||||
'rentals' : {name: 'Rentals', type: 'folder'} ,
|
||||
'real-estate' : {name: 'Real Estate', type: 'folder'} ,
|
||||
'pets' : {name: 'Pets', type: 'folder'} ,
|
||||
'tickets' : {name: 'Tickets', type: 'item'} ,
|
||||
'services' : {name: 'Services', type: 'item'} ,
|
||||
'personals' : {name: 'Personals', type: 'item'}
|
||||
}
|
||||
tree_data['for-sale']['additionalParameters'] = {
|
||||
'children' : {
|
||||
'appliances' : {name: 'Appliances', type: 'item'},
|
||||
'arts-crafts' : {name: 'Arts & Crafts', type: 'item'},
|
||||
'clothing' : {name: 'Clothing', type: 'item'},
|
||||
'computers' : {name: 'Computers', type: 'item'},
|
||||
'jewelry' : {name: 'Jewelry', type: 'item'},
|
||||
'office-business' : {name: 'Office & Business', type: 'item'},
|
||||
'sports-fitness' : {name: 'Sports & Fitness', type: 'item'}
|
||||
}
|
||||
}
|
||||
tree_data['vehicles']['additionalParameters'] = {
|
||||
'children' : {
|
||||
'cars' : {name: 'Cars', type: 'folder'},
|
||||
'motorcycles' : {name: 'Motorcycles', type: 'item'},
|
||||
'boats' : {name: 'Boats', type: 'item'}
|
||||
}
|
||||
}
|
||||
tree_data['vehicles']['additionalParameters']['children']['cars']['additionalParameters'] = {
|
||||
'children' : {
|
||||
'classics' : {name: 'Classics', type: 'item'},
|
||||
'convertibles' : {name: 'Convertibles', type: 'item'},
|
||||
'coupes' : {name: 'Coupes', type: 'item'},
|
||||
'hatchbacks' : {name: 'Hatchbacks', type: 'item'},
|
||||
'hybrids' : {name: 'Hybrids', type: 'item'},
|
||||
'suvs' : {name: 'SUVs', type: 'item'},
|
||||
'sedans' : {name: 'Sedans', type: 'item'},
|
||||
'trucks' : {name: 'Trucks', type: 'item'}
|
||||
}
|
||||
}
|
||||
|
||||
tree_data['rentals']['additionalParameters'] = {
|
||||
'children' : {
|
||||
'apartments-rentals' : {name: 'Apartments', type: 'item'},
|
||||
'office-space-rentals' : {name: 'Office Space', type: 'item'},
|
||||
'vacation-rentals' : {name: 'Vacation Rentals', type: 'item'}
|
||||
}
|
||||
}
|
||||
tree_data['real-estate']['additionalParameters'] = {
|
||||
'children' : {
|
||||
'apartments' : {name: 'Apartments', type: 'item'},
|
||||
'villas' : {name: 'Villas', type: 'item'},
|
||||
'plots' : {name: 'Plots', type: 'item'}
|
||||
}
|
||||
}
|
||||
tree_data['pets']['additionalParameters'] = {
|
||||
'children' : {
|
||||
'cats' : {name: 'Cats', type: 'item'},
|
||||
'dogs' : {name: 'Dogs', type: 'item'},
|
||||
'horses' : {name: 'Horses', type: 'item'},
|
||||
'reptiles' : {name: 'Reptiles', type: 'item'}
|
||||
}
|
||||
}
|
||||
|
||||
var treeDataSource = new DataSourceTree({data: tree_data});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var ace_icon = ace.vars['icon'];
|
||||
//class="'+ace_icon+' fa fa-file-text grey"
|
||||
//becomes
|
||||
//class="ace-icon fa fa-file-text grey"
|
||||
var tree_data_2 = {
|
||||
'pictures' : {name: 'Pictures', type: 'folder', 'icon-class':'red'} ,
|
||||
'music' : {name: 'Music', type: 'folder', 'icon-class':'orange'} ,
|
||||
'video' : {name: 'Video', type: 'folder', 'icon-class':'blue'} ,
|
||||
'documents' : {name: 'Documents', type: 'folder', 'icon-class':'green'} ,
|
||||
'backup' : {name: 'Backup', type: 'folder'} ,
|
||||
'readme' : {name: '<i class="'+ace_icon+' fa fa-file-text grey"></i> ReadMe.txt', type: 'item'},
|
||||
'manual' : {name: '<i class="'+ace_icon+' fa fa-book blue"></i> Manual.html', type: 'item'}
|
||||
}
|
||||
tree_data_2['music']['additionalParameters'] = {
|
||||
'children' : [
|
||||
{name: '<i class="'+ace_icon+' fa fa-music blue"></i> song1.ogg', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-music blue"></i> song2.ogg', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-music blue"></i> song3.ogg', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-music blue"></i> song4.ogg', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-music blue"></i> song5.ogg', type: 'item'}
|
||||
]
|
||||
}
|
||||
tree_data_2['video']['additionalParameters'] = {
|
||||
'children' : [
|
||||
{name: '<i class="'+ace_icon+' fa fa-film blue"></i> movie1.avi', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-film blue"></i> movie2.avi', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-film blue"></i> movie3.avi', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-film blue"></i> movie4.avi', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-film blue"></i> movie5.avi', type: 'item'}
|
||||
]
|
||||
}
|
||||
tree_data_2['pictures']['additionalParameters'] = {
|
||||
'children' : {
|
||||
'wallpapers' : {name: 'Wallpapers', type: 'folder', 'icon-class':'pink'},
|
||||
'camera' : {name: 'Camera', type: 'folder', 'icon-class':'pink'}
|
||||
}
|
||||
}
|
||||
tree_data_2['pictures']['additionalParameters']['children']['wallpapers']['additionalParameters'] = {
|
||||
'children' : [
|
||||
{name: '<i class="'+ace_icon+' fa fa-picture-o green"></i> wallpaper1.jpg', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-picture-o green"></i> wallpaper2.jpg', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-picture-o green"></i> wallpaper3.jpg', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-picture-o green"></i> wallpaper4.jpg', type: 'item'}
|
||||
]
|
||||
}
|
||||
tree_data_2['pictures']['additionalParameters']['children']['camera']['additionalParameters'] = {
|
||||
'children' : [
|
||||
{name: '<i class="'+ace_icon+' fa fa-picture-o green"></i> photo1.jpg', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-picture-o green"></i> photo2.jpg', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-picture-o green"></i> photo3.jpg', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-picture-o green"></i> photo4.jpg', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-picture-o green"></i> photo5.jpg', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-picture-o green"></i> photo6.jpg', type: 'item'}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
tree_data_2['documents']['additionalParameters'] = {
|
||||
'children' : [
|
||||
{name: '<i class="'+ace_icon+' fa fa-file-text red"></i> document1.pdf', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-file-text grey"></i> document2.doc', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-file-text grey"></i> document3.doc', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-file-text red"></i> document4.pdf', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-file-text grey"></i> document5.doc', type: 'item'}
|
||||
]
|
||||
}
|
||||
|
||||
tree_data_2['backup']['additionalParameters'] = {
|
||||
'children' : [
|
||||
{name: '<i class="'+ace_icon+' fa fa-archive brown"></i> backup1.zip', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-archive brown"></i> backup2.zip', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-archive brown"></i> backup3.zip', type: 'item'},
|
||||
{name: '<i class="'+ace_icon+' fa fa-archive brown"></i> backup4.zip', type: 'item'}
|
||||
]
|
||||
}
|
||||
var treeDataSource2 = new DataSourceTree({data: tree_data_2});
|
||||
13235
static/js/lib/ace/uncompressed/jqGrid/jquery.jqGrid.js
Normal file
13235
static/js/lib/ace/uncompressed/jqGrid/jquery.jqGrid.js
Normal file
File diff suppressed because it is too large
Load Diff
5687
static/js/lib/ace/uncompressed/jquery-ui.custom.js
vendored
Normal file
5687
static/js/lib/ace/uncompressed/jquery-ui.custom.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
15008
static/js/lib/ace/uncompressed/jquery-ui.js
vendored
Normal file
15008
static/js/lib/ace/uncompressed/jquery-ui.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
362
static/js/lib/ace/uncompressed/jquery.easypiechart.js
Normal file
362
static/js/lib/ace/uncompressed/jquery.easypiechart.js
Normal file
@@ -0,0 +1,362 @@
|
||||
/**!
|
||||
* easyPieChart
|
||||
* Lightweight plugin to render simple, animated and retina optimized pie charts
|
||||
*
|
||||
* @license
|
||||
* @author Robert Fleischmann <rendro87@gmail.com> (http://robert-fleischmann.de)
|
||||
* @version 2.1.5
|
||||
**/
|
||||
|
||||
(function(root, factory) {
|
||||
if(typeof exports === 'object') {
|
||||
module.exports = factory(require('jquery'));
|
||||
}
|
||||
else if(typeof define === 'function' && define.amd) {
|
||||
define(['jquery'], factory);
|
||||
}
|
||||
else {
|
||||
factory(root.jQuery);
|
||||
}
|
||||
}(this, function($) {
|
||||
|
||||
/**
|
||||
* Renderer to render the chart on a canvas object
|
||||
* @param {DOMElement} el DOM element to host the canvas (root of the plugin)
|
||||
* @param {object} options options object of the plugin
|
||||
*/
|
||||
var CanvasRenderer = function(el, options) {
|
||||
var cachedBackground;
|
||||
var canvas = document.createElement('canvas');
|
||||
|
||||
el.appendChild(canvas);
|
||||
|
||||
if (typeof(G_vmlCanvasManager) !== 'undefined') {
|
||||
G_vmlCanvasManager.initElement(canvas);
|
||||
}
|
||||
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
canvas.width = canvas.height = options.size;
|
||||
|
||||
// canvas on retina devices
|
||||
var scaleBy = 1;
|
||||
if (window.devicePixelRatio > 1) {
|
||||
scaleBy = window.devicePixelRatio;
|
||||
canvas.style.width = canvas.style.height = [options.size, 'px'].join('');
|
||||
canvas.width = canvas.height = options.size * scaleBy;
|
||||
ctx.scale(scaleBy, scaleBy);
|
||||
}
|
||||
|
||||
// move 0,0 coordinates to the center
|
||||
ctx.translate(options.size / 2, options.size / 2);
|
||||
|
||||
// rotate canvas -90deg
|
||||
ctx.rotate((-1 / 2 + options.rotate / 180) * Math.PI);
|
||||
|
||||
var radius = (options.size - options.lineWidth) / 2;
|
||||
if (options.scaleColor && options.scaleLength) {
|
||||
radius -= options.scaleLength + 2; // 2 is the distance between scale and bar
|
||||
}
|
||||
|
||||
// IE polyfill for Date
|
||||
Date.now = Date.now || function() {
|
||||
return +(new Date());
|
||||
};
|
||||
|
||||
/**
|
||||
* Draw a circle around the center of the canvas
|
||||
* @param {strong} color Valid CSS color string
|
||||
* @param {number} lineWidth Width of the line in px
|
||||
* @param {number} percent Percentage to draw (float between -1 and 1)
|
||||
*/
|
||||
var drawCircle = function(color, lineWidth, percent) {
|
||||
percent = Math.min(Math.max(-1, percent || 0), 1);
|
||||
var isNegative = percent <= 0 ? true : false;
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.arc(0, 0, radius, 0, Math.PI * 2 * percent, isNegative);
|
||||
|
||||
ctx.strokeStyle = color;
|
||||
ctx.lineWidth = lineWidth;
|
||||
|
||||
ctx.stroke();
|
||||
};
|
||||
|
||||
/**
|
||||
* Draw the scale of the chart
|
||||
*/
|
||||
var drawScale = function() {
|
||||
var offset;
|
||||
var length;
|
||||
|
||||
ctx.lineWidth = 1;
|
||||
ctx.fillStyle = options.scaleColor;
|
||||
|
||||
ctx.save();
|
||||
for (var i = 24; i > 0; --i) {
|
||||
if (i % 6 === 0) {
|
||||
length = options.scaleLength;
|
||||
offset = 0;
|
||||
} else {
|
||||
length = options.scaleLength * 0.6;
|
||||
offset = options.scaleLength - length;
|
||||
}
|
||||
ctx.fillRect(-options.size/2 + offset, 0, length, 1);
|
||||
ctx.rotate(Math.PI / 12);
|
||||
}
|
||||
ctx.restore();
|
||||
};
|
||||
|
||||
/**
|
||||
* Request animation frame wrapper with polyfill
|
||||
* @return {function} Request animation frame method or timeout fallback
|
||||
*/
|
||||
var reqAnimationFrame = (function() {
|
||||
return window.requestAnimationFrame ||
|
||||
window.webkitRequestAnimationFrame ||
|
||||
window.mozRequestAnimationFrame ||
|
||||
function(callback) {
|
||||
window.setTimeout(callback, 1000 / 60);
|
||||
};
|
||||
}());
|
||||
|
||||
/**
|
||||
* Draw the background of the plugin including the scale and the track
|
||||
*/
|
||||
var drawBackground = function() {
|
||||
if(options.scaleColor) drawScale();
|
||||
if(options.trackColor) drawCircle(options.trackColor, options.lineWidth, 1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Canvas accessor
|
||||
*/
|
||||
this.getCanvas = function() {
|
||||
return canvas;
|
||||
};
|
||||
|
||||
/**
|
||||
* Canvas 2D context 'ctx' accessor
|
||||
*/
|
||||
this.getCtx = function() {
|
||||
return ctx;
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear the complete canvas
|
||||
*/
|
||||
this.clear = function() {
|
||||
ctx.clearRect(options.size / -2, options.size / -2, options.size, options.size);
|
||||
};
|
||||
|
||||
/**
|
||||
* Draw the complete chart
|
||||
* @param {number} percent Percent shown by the chart between -100 and 100
|
||||
*/
|
||||
this.draw = function(percent) {
|
||||
// do we need to render a background
|
||||
if (!!options.scaleColor || !!options.trackColor) {
|
||||
// getImageData and putImageData are supported
|
||||
if (ctx.getImageData && ctx.putImageData) {
|
||||
if (!cachedBackground) {
|
||||
drawBackground();
|
||||
cachedBackground = ctx.getImageData(0, 0, options.size * scaleBy, options.size * scaleBy);
|
||||
} else {
|
||||
ctx.putImageData(cachedBackground, 0, 0);
|
||||
}
|
||||
} else {
|
||||
this.clear();
|
||||
drawBackground();
|
||||
}
|
||||
} else {
|
||||
this.clear();
|
||||
}
|
||||
|
||||
ctx.lineCap = options.lineCap;
|
||||
|
||||
// if barcolor is a function execute it and pass the percent as a value
|
||||
var color;
|
||||
if (typeof(options.barColor) === 'function') {
|
||||
color = options.barColor(percent);
|
||||
} else {
|
||||
color = options.barColor;
|
||||
}
|
||||
|
||||
// draw bar
|
||||
drawCircle(color, options.lineWidth, percent / 100);
|
||||
}.bind(this);
|
||||
|
||||
/**
|
||||
* Animate from some percent to some other percentage
|
||||
* @param {number} from Starting percentage
|
||||
* @param {number} to Final percentage
|
||||
*/
|
||||
this.animate = function(from, to) {
|
||||
var startTime = Date.now();
|
||||
options.onStart(from, to);
|
||||
var animation = function() {
|
||||
var process = Math.min(Date.now() - startTime, options.animate.duration);
|
||||
var currentValue = options.easing(this, process, from, to - from, options.animate.duration);
|
||||
this.draw(currentValue);
|
||||
options.onStep(from, to, currentValue);
|
||||
if (process >= options.animate.duration) {
|
||||
options.onStop(from, to);
|
||||
} else {
|
||||
reqAnimationFrame(animation);
|
||||
}
|
||||
}.bind(this);
|
||||
|
||||
reqAnimationFrame(animation);
|
||||
}.bind(this);
|
||||
};
|
||||
|
||||
var EasyPieChart = function(el, opts) {
|
||||
var defaultOptions = {
|
||||
barColor: '#ef1e25',
|
||||
trackColor: '#f9f9f9',
|
||||
scaleColor: '#dfe0e0',
|
||||
scaleLength: 5,
|
||||
lineCap: 'round',
|
||||
lineWidth: 3,
|
||||
size: 110,
|
||||
rotate: 0,
|
||||
animate: {
|
||||
duration: 1000,
|
||||
enabled: true
|
||||
},
|
||||
easing: function (x, t, b, c, d) { // more can be found here: http://gsgd.co.uk/sandbox/jquery/easing/
|
||||
t = t / (d/2);
|
||||
if (t < 1) {
|
||||
return c / 2 * t * t + b;
|
||||
}
|
||||
return -c/2 * ((--t)*(t-2) - 1) + b;
|
||||
},
|
||||
onStart: function(from, to) {
|
||||
return;
|
||||
},
|
||||
onStep: function(from, to, currentValue) {
|
||||
return;
|
||||
},
|
||||
onStop: function(from, to) {
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// detect present renderer
|
||||
if (typeof(CanvasRenderer) !== 'undefined') {
|
||||
defaultOptions.renderer = CanvasRenderer;
|
||||
} else if (typeof(SVGRenderer) !== 'undefined') {
|
||||
defaultOptions.renderer = SVGRenderer;
|
||||
} else {
|
||||
throw new Error('Please load either the SVG- or the CanvasRenderer');
|
||||
}
|
||||
|
||||
var options = {};
|
||||
var currentValue = 0;
|
||||
|
||||
/**
|
||||
* Initialize the plugin by creating the options object and initialize rendering
|
||||
*/
|
||||
var init = function() {
|
||||
this.el = el;
|
||||
this.options = options;
|
||||
|
||||
// merge user options into default options
|
||||
for (var i in defaultOptions) {
|
||||
if (defaultOptions.hasOwnProperty(i)) {
|
||||
options[i] = opts && typeof(opts[i]) !== 'undefined' ? opts[i] : defaultOptions[i];
|
||||
if (typeof(options[i]) === 'function') {
|
||||
options[i] = options[i].bind(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check for jQuery easing
|
||||
if (typeof(options.easing) === 'string' && typeof(jQuery) !== 'undefined' && jQuery.isFunction(jQuery.easing[options.easing])) {
|
||||
options.easing = jQuery.easing[options.easing];
|
||||
} else {
|
||||
options.easing = defaultOptions.easing;
|
||||
}
|
||||
|
||||
// process earlier animate option to avoid bc breaks
|
||||
if (typeof(options.animate) === 'number') {
|
||||
options.animate = {
|
||||
duration: options.animate,
|
||||
enabled: true
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof(options.animate) === 'boolean' && !options.animate) {
|
||||
options.animate = {
|
||||
duration: 1000,
|
||||
enabled: options.animate
|
||||
};
|
||||
}
|
||||
|
||||
// create renderer
|
||||
this.renderer = new options.renderer(el, options);
|
||||
|
||||
// initial draw
|
||||
this.renderer.draw(currentValue);
|
||||
|
||||
// initial update
|
||||
if (el.dataset && el.dataset.percent) {
|
||||
this.update(parseFloat(el.dataset.percent));
|
||||
} else if (el.getAttribute && el.getAttribute('data-percent')) {
|
||||
this.update(parseFloat(el.getAttribute('data-percent')));
|
||||
}
|
||||
|
||||
el.style['width'] = el.style['height'] = options.size + 'px';//ACE
|
||||
el.style['lineHeight'] = (options.size - 1) + 'px';//ACE
|
||||
}.bind(this);
|
||||
|
||||
/**
|
||||
* Update the value of the chart
|
||||
* @param {number} newValue Number between 0 and 100
|
||||
* @return {object} Instance of the plugin for method chaining
|
||||
*/
|
||||
this.update = function(newValue) {
|
||||
newValue = parseFloat(newValue);
|
||||
if (options.animate.enabled) {
|
||||
this.renderer.animate(currentValue, newValue);
|
||||
} else {
|
||||
this.renderer.draw(newValue);
|
||||
}
|
||||
currentValue = newValue;
|
||||
return this;
|
||||
}.bind(this);
|
||||
|
||||
/**
|
||||
* Disable animation
|
||||
* @return {object} Instance of the plugin for method chaining
|
||||
*/
|
||||
this.disableAnimation = function() {
|
||||
options.animate.enabled = false;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Enable animation
|
||||
* @return {object} Instance of the plugin for method chaining
|
||||
*/
|
||||
this.enableAnimation = function() {
|
||||
options.animate.enabled = true;
|
||||
return this;
|
||||
};
|
||||
|
||||
init();
|
||||
};
|
||||
|
||||
$.fn.easyPieChart = function(options) {
|
||||
return this.each(function() {
|
||||
var instanceOptions;
|
||||
|
||||
if (!$.data(this, 'easyPieChart')) {
|
||||
instanceOptions = $.extend({}, options, $(this).data());
|
||||
$.data(this, 'easyPieChart', new EasyPieChart(this, instanceOptions));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
}));
|
||||
9111
static/js/lib/ace/uncompressed/jquery.js
vendored
Normal file
9111
static/js/lib/ace/uncompressed/jquery.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
485
static/js/lib/ace/uncompressed/jquery.nestable.js
Normal file
485
static/js/lib/ace/uncompressed/jquery.nestable.js
Normal file
@@ -0,0 +1,485 @@
|
||||
/*!
|
||||
* Nestable jQuery Plugin - Copyright (c) 2012 David Bushell - http://dbushell.com/
|
||||
* Dual-licensed under the BSD or MIT licenses
|
||||
*/
|
||||
;(function($, window, document, undefined)
|
||||
{
|
||||
var hasTouch = 'ontouchstart' in document.documentElement;
|
||||
|
||||
/**
|
||||
* Detect CSS pointer-events property
|
||||
* events are normally disabled on the dragging element to avoid conflicts
|
||||
* https://github.com/ausi/Feature-detection-technique-for-pointer-events/blob/master/modernizr-pointerevents.js
|
||||
*/
|
||||
var hasPointerEvents = (function()
|
||||
{
|
||||
var el = document.createElement('div'),
|
||||
docEl = document.documentElement;
|
||||
if (!('pointerEvents' in el.style)) {
|
||||
return false;
|
||||
}
|
||||
el.style.pointerEvents = 'auto';
|
||||
el.style.pointerEvents = 'x';
|
||||
docEl.appendChild(el);
|
||||
var supports = window.getComputedStyle && window.getComputedStyle(el, '').pointerEvents === 'auto';
|
||||
docEl.removeChild(el);
|
||||
return !!supports;
|
||||
})();
|
||||
|
||||
var eStart = hasTouch ? 'touchstart' : 'mousedown',
|
||||
eMove = hasTouch ? 'touchmove' : 'mousemove',
|
||||
eEnd = hasTouch ? 'touchend' : 'mouseup';
|
||||
eCancel = hasTouch ? 'touchcancel' : 'mouseup';
|
||||
|
||||
var defaults = {
|
||||
listNodeName : 'ol',
|
||||
itemNodeName : 'li',
|
||||
rootClass : 'dd',
|
||||
listClass : 'dd-list',
|
||||
itemClass : 'dd-item',
|
||||
dragClass : 'dd-dragel',
|
||||
handleClass : 'dd-handle',
|
||||
collapsedClass : 'dd-collapsed',
|
||||
placeClass : 'dd-placeholder',
|
||||
noDragClass : 'dd-nodrag',
|
||||
emptyClass : 'dd-empty',
|
||||
expandBtnHTML : '<button data-action="expand" type="button">Expand</button>',
|
||||
collapseBtnHTML : '<button data-action="collapse" type="button">Collapse</button>',
|
||||
group : 0,
|
||||
maxDepth : 5,
|
||||
threshold : 20
|
||||
};
|
||||
|
||||
function Plugin(element, options)
|
||||
{
|
||||
this.w = $(window);
|
||||
this.el = $(element);
|
||||
this.options = $.extend({}, defaults, options);
|
||||
this.init();
|
||||
}
|
||||
|
||||
Plugin.prototype = {
|
||||
|
||||
init: function()
|
||||
{
|
||||
var list = this;
|
||||
|
||||
list.reset();
|
||||
|
||||
list.el.data('nestable-group', this.options.group);
|
||||
|
||||
list.placeEl = $('<div class="' + list.options.placeClass + '"/>');
|
||||
|
||||
$.each(this.el.find(list.options.itemNodeName), function(k, el) {
|
||||
list.setParent($(el));
|
||||
});
|
||||
|
||||
list.el.on('click', 'button', function(e) {
|
||||
if (list.dragEl || (!hasTouch && e.button !== 0)) {
|
||||
return;
|
||||
}
|
||||
var target = $(e.currentTarget),
|
||||
action = target.data('action'),
|
||||
item = target.parent(list.options.itemNodeName);
|
||||
if (action === 'collapse') {
|
||||
list.collapseItem(item);
|
||||
}
|
||||
if (action === 'expand') {
|
||||
list.expandItem(item);
|
||||
}
|
||||
});
|
||||
|
||||
var onStartEvent = function(e)
|
||||
{
|
||||
var handle = $(e.target);
|
||||
if (!handle.hasClass(list.options.handleClass)) {
|
||||
if (handle.closest('.' + list.options.noDragClass).length) {
|
||||
return;
|
||||
}
|
||||
handle = handle.closest('.' + list.options.handleClass);
|
||||
}
|
||||
if (!handle.length || list.dragEl || (!hasTouch && e.button !== 0) || (hasTouch && e.touches.length !== 1)) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
list.dragStart(hasTouch ? e.touches[0] : e);
|
||||
};
|
||||
|
||||
var onMoveEvent = function(e)
|
||||
{
|
||||
if (list.dragEl) {
|
||||
e.preventDefault();
|
||||
list.dragMove(hasTouch ? e.touches[0] : e);
|
||||
}
|
||||
};
|
||||
|
||||
var onEndEvent = function(e)
|
||||
{
|
||||
if (list.dragEl) {
|
||||
e.preventDefault();
|
||||
list.dragStop(hasTouch ? e.touches[0] : e);
|
||||
}
|
||||
};
|
||||
|
||||
if (hasTouch) {
|
||||
list.el[0].addEventListener(eStart, onStartEvent, false);
|
||||
window.addEventListener(eMove, onMoveEvent, false);
|
||||
window.addEventListener(eEnd, onEndEvent, false);
|
||||
window.addEventListener(eCancel, onEndEvent, false);
|
||||
} else {
|
||||
list.el.on(eStart, onStartEvent);
|
||||
list.w.on(eMove, onMoveEvent);
|
||||
list.w.on(eEnd, onEndEvent);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
serialize: function()
|
||||
{
|
||||
var data,
|
||||
depth = 0,
|
||||
list = this;
|
||||
step = function(level, depth)
|
||||
{
|
||||
var array = [ ],
|
||||
items = level.children(list.options.itemNodeName);
|
||||
items.each(function()
|
||||
{
|
||||
var li = $(this),
|
||||
item = $.extend({}, li.data()),
|
||||
sub = li.children(list.options.listNodeName);
|
||||
if (sub.length) {
|
||||
item.children = step(sub, depth + 1);
|
||||
}
|
||||
array.push(item);
|
||||
});
|
||||
return array;
|
||||
};
|
||||
data = step(list.el.find(list.options.listNodeName).first(), depth);
|
||||
return data;
|
||||
},
|
||||
|
||||
serialise: function()
|
||||
{
|
||||
return this.serialize();
|
||||
},
|
||||
|
||||
reset: function()
|
||||
{
|
||||
this.mouse = {
|
||||
offsetX : 0,
|
||||
offsetY : 0,
|
||||
startX : 0,
|
||||
startY : 0,
|
||||
lastX : 0,
|
||||
lastY : 0,
|
||||
nowX : 0,
|
||||
nowY : 0,
|
||||
distX : 0,
|
||||
distY : 0,
|
||||
dirAx : 0,
|
||||
dirX : 0,
|
||||
dirY : 0,
|
||||
lastDirX : 0,
|
||||
lastDirY : 0,
|
||||
distAxX : 0,
|
||||
distAxY : 0
|
||||
};
|
||||
this.moving = false;
|
||||
this.dragEl = null;
|
||||
this.dragRootEl = null;
|
||||
this.dragDepth = 0;
|
||||
this.hasNewRoot = false;
|
||||
this.pointEl = null;
|
||||
},
|
||||
|
||||
expandItem: function(li)
|
||||
{
|
||||
li.removeClass(this.options.collapsedClass);
|
||||
li.children('[data-action="expand"]').hide();
|
||||
li.children('[data-action="collapse"]').show();
|
||||
li.children(this.options.listNodeName).show();
|
||||
},
|
||||
|
||||
collapseItem: function(li)
|
||||
{
|
||||
var lists = li.children(this.options.listNodeName);
|
||||
if (lists.length) {
|
||||
li.addClass(this.options.collapsedClass);
|
||||
li.children('[data-action="collapse"]').hide();
|
||||
li.children('[data-action="expand"]').show();
|
||||
li.children(this.options.listNodeName).hide();
|
||||
}
|
||||
},
|
||||
|
||||
expandAll: function()
|
||||
{
|
||||
var list = this;
|
||||
list.el.find(list.options.itemNodeName).each(function() {
|
||||
list.expandItem($(this));
|
||||
});
|
||||
},
|
||||
|
||||
collapseAll: function()
|
||||
{
|
||||
var list = this;
|
||||
list.el.find(list.options.itemNodeName).each(function() {
|
||||
list.collapseItem($(this));
|
||||
});
|
||||
},
|
||||
|
||||
setParent: function(li)
|
||||
{
|
||||
if (li.children(this.options.listNodeName).length) {
|
||||
li.prepend($(this.options.expandBtnHTML));
|
||||
li.prepend($(this.options.collapseBtnHTML));
|
||||
}
|
||||
li.children('[data-action="expand"]').hide();
|
||||
},
|
||||
|
||||
unsetParent: function(li)
|
||||
{
|
||||
li.removeClass(this.options.collapsedClass);
|
||||
li.children('[data-action]').remove();
|
||||
li.children(this.options.listNodeName).remove();
|
||||
},
|
||||
|
||||
dragStart: function(e)
|
||||
{
|
||||
var mouse = this.mouse,
|
||||
target = $(e.target),
|
||||
dragItem = target.closest(this.options.itemNodeName);
|
||||
|
||||
this.placeEl.css('height', dragItem.height());
|
||||
|
||||
mouse.offsetX = e.offsetX !== undefined ? e.offsetX : e.pageX - target.offset().left;
|
||||
mouse.offsetY = e.offsetY !== undefined ? e.offsetY : e.pageY - target.offset().top;
|
||||
mouse.startX = mouse.lastX = e.pageX;
|
||||
mouse.startY = mouse.lastY = e.pageY;
|
||||
|
||||
this.dragRootEl = this.el;
|
||||
|
||||
this.dragEl = $(document.createElement(this.options.listNodeName)).addClass(this.options.listClass + ' ' + this.options.dragClass);
|
||||
this.dragEl.css('width', dragItem.width());
|
||||
|
||||
// fix for zepto.js
|
||||
//dragItem.after(this.placeEl).detach().appendTo(this.dragEl);
|
||||
dragItem.after(this.placeEl);
|
||||
dragItem[0].parentNode.removeChild(dragItem[0]);
|
||||
dragItem.appendTo(this.dragEl);
|
||||
|
||||
$(document.body).append(this.dragEl);
|
||||
this.dragEl.css({
|
||||
'left' : e.pageX - mouse.offsetX,
|
||||
'top' : e.pageY - mouse.offsetY
|
||||
});
|
||||
// total depth of dragging item
|
||||
var i, depth,
|
||||
items = this.dragEl.find(this.options.itemNodeName);
|
||||
for (i = 0; i < items.length; i++) {
|
||||
depth = $(items[i]).parents(this.options.listNodeName).length;
|
||||
if (depth > this.dragDepth) {
|
||||
this.dragDepth = depth;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
dragStop: function(e)
|
||||
{
|
||||
// fix for zepto.js
|
||||
//this.placeEl.replaceWith(this.dragEl.children(this.options.itemNodeName + ':first').detach());
|
||||
var el = this.dragEl.children(this.options.itemNodeName).first();
|
||||
el[0].parentNode.removeChild(el[0]);
|
||||
this.placeEl.replaceWith(el);
|
||||
|
||||
this.dragEl.remove();
|
||||
this.el.trigger('change');
|
||||
if (this.hasNewRoot) {
|
||||
this.dragRootEl.trigger('change');
|
||||
}
|
||||
this.reset();
|
||||
},
|
||||
|
||||
dragMove: function(e)
|
||||
{
|
||||
var list, parent, prev, next, depth,
|
||||
opt = this.options,
|
||||
mouse = this.mouse;
|
||||
|
||||
this.dragEl.css({
|
||||
'left' : e.pageX - mouse.offsetX,
|
||||
'top' : e.pageY - mouse.offsetY
|
||||
});
|
||||
|
||||
// mouse position last events
|
||||
mouse.lastX = mouse.nowX;
|
||||
mouse.lastY = mouse.nowY;
|
||||
// mouse position this events
|
||||
mouse.nowX = e.pageX;
|
||||
mouse.nowY = e.pageY;
|
||||
// distance mouse moved between events
|
||||
mouse.distX = mouse.nowX - mouse.lastX;
|
||||
mouse.distY = mouse.nowY - mouse.lastY;
|
||||
// direction mouse was moving
|
||||
mouse.lastDirX = mouse.dirX;
|
||||
mouse.lastDirY = mouse.dirY;
|
||||
// direction mouse is now moving (on both axis)
|
||||
mouse.dirX = mouse.distX === 0 ? 0 : mouse.distX > 0 ? 1 : -1;
|
||||
mouse.dirY = mouse.distY === 0 ? 0 : mouse.distY > 0 ? 1 : -1;
|
||||
// axis mouse is now moving on
|
||||
var newAx = Math.abs(mouse.distX) > Math.abs(mouse.distY) ? 1 : 0;
|
||||
|
||||
// do nothing on first move
|
||||
if (!mouse.moving) {
|
||||
mouse.dirAx = newAx;
|
||||
mouse.moving = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// calc distance moved on this axis (and direction)
|
||||
if (mouse.dirAx !== newAx) {
|
||||
mouse.distAxX = 0;
|
||||
mouse.distAxY = 0;
|
||||
} else {
|
||||
mouse.distAxX += Math.abs(mouse.distX);
|
||||
if (mouse.dirX !== 0 && mouse.dirX !== mouse.lastDirX) {
|
||||
mouse.distAxX = 0;
|
||||
}
|
||||
mouse.distAxY += Math.abs(mouse.distY);
|
||||
if (mouse.dirY !== 0 && mouse.dirY !== mouse.lastDirY) {
|
||||
mouse.distAxY = 0;
|
||||
}
|
||||
}
|
||||
mouse.dirAx = newAx;
|
||||
|
||||
/**
|
||||
* move horizontal
|
||||
*/
|
||||
if (mouse.dirAx && mouse.distAxX >= opt.threshold) {
|
||||
// reset move distance on x-axis for new phase
|
||||
mouse.distAxX = 0;
|
||||
prev = this.placeEl.prev(opt.itemNodeName);
|
||||
// increase horizontal level if previous sibling exists and is not collapsed
|
||||
if (mouse.distX > 0 && prev.length && !prev.hasClass(opt.collapsedClass)) {
|
||||
// cannot increase level when item above is collapsed
|
||||
list = prev.find(opt.listNodeName).last();
|
||||
// check if depth limit has reached
|
||||
depth = this.placeEl.parents(opt.listNodeName).length;
|
||||
if (depth + this.dragDepth <= opt.maxDepth) {
|
||||
// create new sub-level if one doesn't exist
|
||||
if (!list.length) {
|
||||
list = $('<' + opt.listNodeName + '/>').addClass(opt.listClass);
|
||||
list.append(this.placeEl);
|
||||
prev.append(list);
|
||||
this.setParent(prev);
|
||||
} else {
|
||||
// else append to next level up
|
||||
list = prev.children(opt.listNodeName).last();
|
||||
list.append(this.placeEl);
|
||||
}
|
||||
}
|
||||
}
|
||||
// decrease horizontal level
|
||||
if (mouse.distX < 0) {
|
||||
// we can't decrease a level if an item preceeds the current one
|
||||
next = this.placeEl.next(opt.itemNodeName);
|
||||
if (!next.length) {
|
||||
parent = this.placeEl.parent();
|
||||
this.placeEl.closest(opt.itemNodeName).after(this.placeEl);
|
||||
if (!parent.children().length) {
|
||||
this.unsetParent(parent.parent());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var isEmpty = false;
|
||||
|
||||
// find list item under cursor
|
||||
if (!hasPointerEvents) {
|
||||
this.dragEl[0].style.visibility = 'hidden';
|
||||
}
|
||||
this.pointEl = $(document.elementFromPoint(e.pageX - document.body.scrollLeft, e.pageY - (window.pageYOffset || document.documentElement.scrollTop)));
|
||||
if (!hasPointerEvents) {
|
||||
this.dragEl[0].style.visibility = 'visible';
|
||||
}
|
||||
if (this.pointEl.hasClass(opt.handleClass)) {
|
||||
this.pointEl = this.pointEl.parent(opt.itemNodeName);
|
||||
}
|
||||
if (this.pointEl.hasClass(opt.emptyClass)) {
|
||||
isEmpty = true;
|
||||
}
|
||||
else if (!this.pointEl.length || !this.pointEl.hasClass(opt.itemClass)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// find parent list of item under cursor
|
||||
var pointElRoot = this.pointEl.closest('.' + opt.rootClass),
|
||||
isNewRoot = this.dragRootEl.data('nestable-id') !== pointElRoot.data('nestable-id');
|
||||
|
||||
/**
|
||||
* move vertical
|
||||
*/
|
||||
if (!mouse.dirAx || isNewRoot || isEmpty) {
|
||||
// check if groups match if dragging over new root
|
||||
if (isNewRoot && opt.group !== pointElRoot.data('nestable-group')) {
|
||||
return;
|
||||
}
|
||||
// check depth limit
|
||||
depth = this.dragDepth - 1 + this.pointEl.parents(opt.listNodeName).length;
|
||||
if (depth > opt.maxDepth) {
|
||||
return;
|
||||
}
|
||||
var before = e.pageY < (this.pointEl.offset().top + this.pointEl.height() / 2);
|
||||
parent = this.placeEl.parent();
|
||||
// if empty create new list to replace empty placeholder
|
||||
if (isEmpty) {
|
||||
list = $(document.createElement(opt.listNodeName)).addClass(opt.listClass);
|
||||
list.append(this.placeEl);
|
||||
this.pointEl.replaceWith(list);
|
||||
}
|
||||
else if (before) {
|
||||
this.pointEl.before(this.placeEl);
|
||||
}
|
||||
else {
|
||||
this.pointEl.after(this.placeEl);
|
||||
}
|
||||
if (!parent.children().length) {
|
||||
this.unsetParent(parent.parent());
|
||||
}
|
||||
if (!this.dragRootEl.find(opt.itemNodeName).length) {
|
||||
this.dragRootEl.append('<div class="' + opt.emptyClass + '"/>');
|
||||
}
|
||||
// parent root list has changed
|
||||
if (isNewRoot) {
|
||||
this.dragRootEl = pointElRoot;
|
||||
this.hasNewRoot = this.el[0] !== this.dragRootEl[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$.fn.nestable = function(params)
|
||||
{
|
||||
var lists = this,
|
||||
retval = this;
|
||||
|
||||
lists.each(function()
|
||||
{
|
||||
var plugin = $(this).data("nestable");
|
||||
|
||||
if (!plugin) {
|
||||
$(this).data("nestable", new Plugin(this, params));
|
||||
$(this).data("nestable-id", new Date().getTime());
|
||||
} else {
|
||||
if (typeof params === 'string' && typeof plugin[params] === 'function') {
|
||||
retval = plugin[params]();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return retval || lists;
|
||||
};
|
||||
|
||||
})(window.jQuery || window.Zepto, window, document);
|
||||
10337
static/js/lib/ace/uncompressed/jquery1x.js
vendored
Normal file
10337
static/js/lib/ace/uncompressed/jquery1x.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user