mirror of
https://github.com/gtbu/Typesetter-5.3-p8.git
synced 2024-11-28 17:09:12 +01:00
1811 lines
38 KiB
JavaScript
1811 lines
38 KiB
JavaScript
/*global $gp:false, gpui:false, gplinks:false, gpinputs:false isadmin:false, gpBase:false, strip_from:false, gpRem:false, gpBLink:false */
|
||
/*jshint forin:true, noarg:true, noempty:true, eqeqeq:true, bitwise:true, strict:true, undef:true, unused:true, curly:true, browser:true, jquery:true, indent:4, maxerr:100, newcap:false, white:false*/
|
||
//"use strict";
|
||
|
||
var gp_editor = false;
|
||
|
||
$gp.curr_edit_id = null;
|
||
$gp.interface = []; // storage for editing interfaces
|
||
$gp.cached = {};
|
||
$gp.defaults = {};
|
||
$gp.editors = []; // storage for editing objects
|
||
|
||
|
||
/**
|
||
* Get the coordinates for positioning editable area overlays
|
||
*
|
||
*/
|
||
$gp.Coords = function(area){
|
||
if( area.hasClass('inner_size') ){
|
||
area = area.children().first();
|
||
}
|
||
var loc = area.offset();
|
||
loc.w = area.outerWidth();
|
||
loc.h = area.outerHeight();
|
||
return loc;
|
||
};
|
||
|
||
|
||
/**
|
||
* Create a <div> in the #gp_admin_html space
|
||
*
|
||
*/
|
||
$gp.div = function(id,div_class){
|
||
var div = $('#'+id);
|
||
div_class = div_class || '';
|
||
if( div.length === 0 ){
|
||
div = $('<div id="'+id+'" class="'+div_class+'"></div>').appendTo('#gp_admin_html');
|
||
}
|
||
return div;
|
||
};
|
||
|
||
|
||
/**
|
||
* Dynamically load inline editing
|
||
*
|
||
*/
|
||
$gp.links.inline_edit_generic = function(evt,arg){
|
||
|
||
evt.preventDefault();
|
||
|
||
var area_id = $gp.AreaId( $(this) );
|
||
|
||
$gp.LoadEditor(this.href, area_id, arg);
|
||
|
||
|
||
//show editor when a edit link is clicked in the
|
||
var $target = $(evt.target);
|
||
if( $target.closest('.panel_tabs').length && typeof(gp_editing) != 'undefined' ){
|
||
if( $target.data('mode') == 'extra' ){
|
||
gp_editing.is_extra_mode = true;
|
||
}else{
|
||
gp_editing.is_extra_mode = false;
|
||
}
|
||
gp_editing.ShowEditor();
|
||
}
|
||
}
|
||
|
||
$gp._loadingEditor = false;
|
||
$gp.LoadEditor = function(href, area_id, arg){
|
||
|
||
area_id = area_id || 0;
|
||
|
||
if( area_id === $gp.curr_edit_id ){
|
||
return;
|
||
}
|
||
|
||
if( $gp._loadingEditor ){
|
||
console.log('editor still loading');
|
||
return;
|
||
}
|
||
|
||
$gp._loadingEditor = true;
|
||
|
||
//first time editing, get default $gp.links, $gp.inputs, $gp.response
|
||
if( typeof(gp_editing) == 'undefined' ){
|
||
$gp.defaults['links'] = $gp.Properties($gp.links);
|
||
$gp.defaults['inputs'] = $gp.Properties($gp.inputs);
|
||
$gp.defaults['response'] = $gp.Properties($gp.response);
|
||
}
|
||
|
||
|
||
$gp.CacheInterface(function(){
|
||
|
||
//set the current editing interface aside so the new one can be created
|
||
if( typeof(gp_editing) !== 'undefined' ){
|
||
if( gp_editing.RestoreCached(area_id) ){
|
||
$gp._loadingEditor = false;
|
||
return;
|
||
}
|
||
}else{
|
||
$gp.LoadStyle('/include/css/inline_edit.css');
|
||
$gp.LoadStyle('/include/css/manage_sections.css');
|
||
// $gp.LoadStyle('/include/css/manage_sections_compact.css'); // alternative compact style
|
||
}
|
||
|
||
$gp.curr_edit_id = area_id;
|
||
var $edit_div = $gp.CurrentDiv();
|
||
|
||
$gp.DefinedObjects();
|
||
$gp.loading();
|
||
|
||
|
||
//legacy inline editing support
|
||
//can also be used for development/troubleshooting
|
||
if( typeof(gplinks[arg]) === 'function' ){
|
||
gplinks[arg].call(this,arg,evt);
|
||
$gp._loadingEditor = false;
|
||
return;
|
||
}
|
||
|
||
var script = strip_from(href,'#');
|
||
script += '&gpreq=json&defined_objects='+$gp.DefinedObjects();
|
||
|
||
if( arg != 'manage_sections' ){
|
||
script += '&cmd=inlineedit&area_id='+area_id+'§ion='+$edit_div.data('gp-section');
|
||
}
|
||
|
||
|
||
//get the new editor
|
||
$.getScript( script,function(data){
|
||
if( data === 'false' ){
|
||
alert($gp.error);
|
||
$gp.loaded();
|
||
$gp._loadingEditor = false;
|
||
return;
|
||
}
|
||
|
||
if( typeof(gp_editor.wake) == 'function' ){
|
||
gp_editor.wake();
|
||
}
|
||
$gp._loadingEditor = false;
|
||
});
|
||
|
||
});
|
||
};
|
||
|
||
/**
|
||
* Get object properties
|
||
*
|
||
*/
|
||
$gp.Properties = function(obj){
|
||
var properties = [];
|
||
for( var i in obj ){
|
||
if( obj.hasOwnProperty(i) ){
|
||
properties.push(i);
|
||
}
|
||
}
|
||
return properties;
|
||
}
|
||
|
||
|
||
/**
|
||
* Get the current editing div
|
||
*
|
||
*/
|
||
$gp.CurrentDiv = function(){
|
||
return $('#ExtraEditArea'+$gp.curr_edit_id);
|
||
}
|
||
|
||
|
||
/**
|
||
* Cache the current editing interface
|
||
*
|
||
*/
|
||
$gp.CacheInterface = function(callback){
|
||
|
||
|
||
$gp.CurrentDiv().removeClass('gp_edit_current');
|
||
|
||
|
||
//if gp_editing is not defined then we don't have anything to cache yet
|
||
if( typeof(gp_editing) == 'undefined' ){
|
||
callback.call();
|
||
return;
|
||
}
|
||
|
||
|
||
//only continue if we can save
|
||
gp_editing.SaveChanges(function(){
|
||
|
||
|
||
if( typeof(gp_editor.sleep) == 'function' ){
|
||
gp_editor.sleep();
|
||
}
|
||
|
||
|
||
$gp.interface[$gp.curr_edit_id] = $('#ck_area_wrap').children().detach();
|
||
$gp.editors[$gp.curr_edit_id] = gp_editor;
|
||
|
||
|
||
//cache $gp.links that were defined by the current gp_editor
|
||
$gp.cached[$gp.curr_edit_id] = {};
|
||
$gp.CacheObjects( 'links' );
|
||
$gp.CacheObjects( 'inputs' );
|
||
$gp.CacheObjects( 'response' );
|
||
|
||
|
||
$('.cktabs .ckeditor_control.selected').removeClass('selected');
|
||
|
||
callback.call();
|
||
});
|
||
}
|
||
|
||
|
||
/**
|
||
* Cache $gp.links, $gp.inputs and $gp.Response
|
||
* ?? gpresponse, gplinks, gpinputs ??
|
||
*/
|
||
$gp.CacheObjects = function(type, cache_loc){
|
||
|
||
var from = $gp[type];
|
||
$gp.cached[$gp.curr_edit_id][type] = {};
|
||
|
||
for( var i in from ){
|
||
if( !from.hasOwnProperty(i) ){
|
||
continue;
|
||
}
|
||
|
||
if( $gp.defaults[type].indexOf(i) > -1 ){
|
||
continue;
|
||
}
|
||
$gp.cached[$gp.curr_edit_id][type][i] = from[i];
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Restore $gp.links, $gp.inputs and $gp.Response
|
||
* ?? gpresponse, gplinks, gpinputs ??
|
||
*/
|
||
$gp.RestoreObjects = function(type, id){
|
||
|
||
var from = $gp.cached[id][type];
|
||
|
||
for( var i in from ){
|
||
if( !from.hasOwnProperty(i) ){
|
||
continue;
|
||
}
|
||
$gp[type][i] = from[i];
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Send to the server which javascript objects are already defined
|
||
*
|
||
*/
|
||
$gp.defined_objects = [];
|
||
$gp.DefinedObjects = function(){
|
||
|
||
//get all objects the first time
|
||
if( typeof(gp_editing) == 'undefined' ){
|
||
for( var i in window ) {
|
||
if( typeof(window[i]) != 'object' ){
|
||
continue;
|
||
}
|
||
$gp.defined_objects.push(i);
|
||
}
|
||
}
|
||
|
||
//compare with $gp.defined_objects
|
||
var objects = [];
|
||
for( var i in window ) {
|
||
if( typeof(window[i]) != 'object' ){
|
||
continue;
|
||
}
|
||
if( $gp.defined_objects.indexOf(i) != -1 ){
|
||
continue;
|
||
}
|
||
objects.push(i);
|
||
}
|
||
|
||
return objects.join(',');
|
||
}
|
||
|
||
|
||
/**
|
||
* Remote Browse
|
||
* @param object evt Event object
|
||
*
|
||
*/
|
||
$gp.links.remote = function(evt){
|
||
evt.preventDefault();
|
||
var src = $gp.jPrep(this.href,'gpreq=body');
|
||
|
||
//can remote install
|
||
if( gpRem ){
|
||
var pathArray = window.location.href.split( '/' );
|
||
var url = pathArray[0] + '//' + pathArray[2]+gpBase;
|
||
if( window.location.href.indexOf('index.php') > 0 ){
|
||
url += '/index.php';
|
||
}
|
||
|
||
src += '&inUrl='+encodeURIComponent(url)
|
||
+ '&gpRem='+encodeURIComponent(gpRem);
|
||
}
|
||
|
||
//40px margin + 17px*2 border + 20px padding + 10 (extra padding) = approx 130
|
||
// var height = $gp.$win.height() - 130;
|
||
|
||
var opts = {context:'iframe',width:780};
|
||
|
||
var iframe = '<iframe src="'+src+'" frameborder="0" />';
|
||
$gp.AdminBoxC(iframe,opts);
|
||
};
|
||
|
||
|
||
/**
|
||
* Add stylesheets to the current document
|
||
* @param string file
|
||
* @param bool already_prefixed
|
||
*/
|
||
$gp.LoadStyle = function(file, already_prefixed){
|
||
|
||
var time = req_time || new Date().getTime();
|
||
file = already_prefixed ? file : gpBase+file;
|
||
file = file+'?t='+time;
|
||
|
||
|
||
//already loaded?
|
||
if( $('link[href="'+file+'"]').length ){
|
||
return;
|
||
}
|
||
|
||
//href set after appending to head so that it works properly in IE
|
||
$('<link rel="stylesheet" type="text/css" />')
|
||
.appendTo('head')
|
||
.attr({'href':file});
|
||
};
|
||
|
||
/**
|
||
* Show content (data) in #gp_admin_box
|
||
* This is used instead of colorbox for admin content
|
||
* - this box resizes without javascript calls (height)
|
||
* - less animation
|
||
*/
|
||
$gp.AdminBoxC = function(data, options){
|
||
$gp.CloseAdminBox();
|
||
if( data === '' ){
|
||
return false;
|
||
}
|
||
|
||
if( typeof(options) == 'string' ){
|
||
options = {context:options};
|
||
}else if( typeof(options) == 'undefined' ){
|
||
options = {};
|
||
}
|
||
|
||
options = $.extend({
|
||
context : '',
|
||
width : 680,
|
||
zIndex: 11000
|
||
},
|
||
options);
|
||
|
||
/*
|
||
var win_width = $gp.$win.width();
|
||
var box_width = Math.max(660, Math.round(win_width*0.70));
|
||
*/
|
||
var box_width = options.width;
|
||
|
||
$gp.div('gp_admin_box1')
|
||
.css({
|
||
'zIndex' : options.zIndex
|
||
})
|
||
.stop(true,true)
|
||
.fadeTo(0,0) //fade in from transparent
|
||
.fadeTo((options.replaceBox ? 0 : 200), 0.2);
|
||
|
||
$gp.div('gp_admin_box')
|
||
.css({
|
||
'zIndex' : options.zIndex,
|
||
})
|
||
.stop(true,true)
|
||
.fadeIn((options.replaceBox ? 0 : 400))
|
||
.html('<a class="gp_admin_box_close" data-cmd="admin_box_close"></a>'
|
||
+ '<div id="gp_admin_boxc" class="' + (options.context || '') + '" '
|
||
+ 'style="width:' + box_width + 'px">'
|
||
+ '</div>')
|
||
.find('#gp_admin_boxc')
|
||
.html(data)
|
||
.find('input:visible').first()
|
||
.trigger('focus');
|
||
|
||
$('.messages').detach();
|
||
|
||
//close on escape key
|
||
$gp.$doc.on('keyup.abox',function(e) {
|
||
if( e.keyCode == 27 ){
|
||
$gp.CloseAdminBox();
|
||
}
|
||
});
|
||
|
||
return true;
|
||
};
|
||
|
||
|
||
/**
|
||
* Close gp_admin_box
|
||
*
|
||
*/
|
||
$gp.CloseAdminBox = function(evt){
|
||
if( evt ){
|
||
evt.preventDefault();
|
||
}
|
||
|
||
$gp.$doc.off('keyup.abox');
|
||
|
||
$('#gp_admin_box1').fadeOut();
|
||
$('#gp_admin_box').fadeOut(300,function(){
|
||
|
||
//move contents back to document if they came from an inline element
|
||
//remove other content
|
||
var boxc = $('#gp_admin_boxc');
|
||
if( boxc.hasClass('inline') ){
|
||
$('#gp_admin_boxc').children().appendTo('#gp_hidden');
|
||
}else{
|
||
$('#gp_admin_boxc').children().remove();
|
||
}
|
||
|
||
});
|
||
if( typeof($.fn.colorbox) !== 'undefined' ){
|
||
$.fn.colorbox.close();
|
||
}
|
||
};
|
||
$gp.links.admin_box_close = $gp.inputs.admin_box_close = $gp.CloseAdminBox;
|
||
|
||
|
||
/**
|
||
* Save admin user settings
|
||
*
|
||
*/
|
||
$gp.SaveGPUI = function(){
|
||
if( !isadmin ){
|
||
return;
|
||
}
|
||
var data = 'cmd=SaveGPUI';
|
||
$.each(gpui,function(i,value){
|
||
data += '&gpui_'+i+'='+value;
|
||
});
|
||
|
||
var url = gpBLink+'/Admin/Preferences';
|
||
$gp.postC( url, data);
|
||
};
|
||
|
||
|
||
/**
|
||
* Drop down menus
|
||
*
|
||
*/
|
||
$gp.links.dd_menu = function(evt){
|
||
|
||
evt.preventDefault();
|
||
evt.stopPropagation();
|
||
|
||
$('.messages').detach(); //remove messages since we can't set the z-index properly
|
||
var that = this;
|
||
var $list = $(this).parent().find('.dd_list');
|
||
|
||
//display the list and add other handlers
|
||
$list.show();
|
||
|
||
//scroll to show selected
|
||
var $selected = $list.find('.selected');
|
||
if( $selected.length ){
|
||
var $ul = $list.find('ul').first();
|
||
var pos = $list.find('.selected').prev().prev().prev().position();
|
||
if( pos ){
|
||
$ul.scrollTop( pos.top + $ul.scrollTop() );
|
||
}
|
||
}
|
||
|
||
|
||
//hide the list and remove handlers
|
||
$('body').on('click.gp_select',function(evt){
|
||
$list.hide();
|
||
$list.off('.gp_select');
|
||
$('body').off('.gp_select');
|
||
|
||
//stop propogation if it's a click on the current menu so it will remain hidden
|
||
if( $(evt.target).closest(that).length ){
|
||
evt.stopPropagation();
|
||
}
|
||
});
|
||
|
||
};
|
||
|
||
|
||
/**
|
||
* A simple tab method for switching content area visibility
|
||
*
|
||
*/
|
||
$gp.links.tabs = function(evt){
|
||
|
||
evt.preventDefault();
|
||
var $this = $(this);
|
||
$this.siblings('a').removeClass('selected').each(function(b,c){
|
||
if( c.hash ){
|
||
$(c.hash).hide()
|
||
.find('input[type=submit],button[type=submit]').prop('disabled',true);
|
||
}
|
||
});
|
||
|
||
if( this.hash ){
|
||
$this.addClass('selected');
|
||
$(this.hash).show()
|
||
.find('input[type=submit],button[type=submit]').prop('disabled',false);
|
||
}
|
||
};
|
||
|
||
|
||
|
||
/**
|
||
* Use jQuery's Ajax functions to load javascripts and call callback when complete
|
||
* @depredated 2.0.2 Keep for Simple Slideshow Plugin
|
||
*
|
||
*/
|
||
$gp.Loaded = {};
|
||
$gp.LoadScripts = function(scripts,callback,relative_path){
|
||
|
||
var script_count = scripts.length,
|
||
d=new Date(),
|
||
t=d.getTime(),
|
||
base='';
|
||
|
||
relative_path = relative_path||false;
|
||
|
||
if( relative_path ){
|
||
base = gpBase;
|
||
}
|
||
|
||
//use $.each to prevent Array.prototype.xxxx from affecting the for loop
|
||
$.each(scripts,function(i,script){
|
||
script = base+script;
|
||
if( $gp.Loaded[script] ){
|
||
sload();
|
||
}else{
|
||
$gp.Loaded[script] = true;
|
||
$.getScript( $gp.jPrep(script,'t='+t), function(){
|
||
sload();
|
||
});
|
||
}
|
||
});
|
||
|
||
function sload(){
|
||
script_count--;
|
||
if(script_count === 0){
|
||
if( typeof(callback) === 'function' ){
|
||
callback.call(this);
|
||
}
|
||
}
|
||
}
|
||
|
||
};
|
||
|
||
|
||
|
||
/**
|
||
* Refresh the current page
|
||
* ie doesn't handle href="" the same way as other browsers
|
||
*/
|
||
$gp.links.gp_refresh = function(evt){
|
||
evt.preventDefault();
|
||
$gp.Reload();
|
||
};
|
||
|
||
|
||
/**
|
||
* Change the display of the admin toolbar
|
||
*
|
||
*/
|
||
$gp.links.toggle_panel = function(evt){
|
||
var c,panel = $('#simplepanel');
|
||
evt.preventDefault();
|
||
|
||
var classes = '';
|
||
|
||
if( panel.hasClass('minb') ){
|
||
classes = '';
|
||
c = 0;
|
||
}else if( panel.hasClass('compact') ){
|
||
classes = 'minb toggledmin';
|
||
c = 3;
|
||
}else{
|
||
classes = 'compact';
|
||
c = 1;
|
||
}
|
||
if( !panel.hasClass('toggledmin') ){
|
||
panel.off('mouseenter touchstart').on('mouseenter touchstart',function(event){panel.off(event).removeClass('toggledmin');});
|
||
}
|
||
panel.attr('class','keep_viewable '+classes);
|
||
|
||
gpui.cmpct = c;
|
||
$gp.SaveGPUI();
|
||
};
|
||
|
||
|
||
|
||
/**
|
||
* Handle clicks on headers within the main admin toolbar
|
||
*
|
||
*/
|
||
$gp.links.toplink = function(){
|
||
|
||
//must not be compact
|
||
var $this = $(this);
|
||
var $panel = $('#simplepanel');
|
||
if( $panel.hasClass('compact') ){
|
||
return;
|
||
}
|
||
|
||
var b = $this.next();
|
||
gpui.vis = !(b.is(':visible') && (b.height() > 0));
|
||
|
||
//hide visible areas
|
||
$panel.find('.panelgroup2:visible').slideUp(300);
|
||
|
||
if( gpui.vis ){
|
||
gpui.vis = $this.data('arg');
|
||
b.slideDown(300);
|
||
}
|
||
|
||
|
||
$gp.SaveGPUI();
|
||
};
|
||
|
||
|
||
|
||
/**
|
||
* Collapsible area
|
||
*
|
||
*/
|
||
$gp.links.collapsible = function(){
|
||
var area = $(this).parent();
|
||
|
||
//only show one
|
||
if( area.hasClass('one') && area.hasClass('gp_collapsed') ){
|
||
area.parent().find('.head').addClass('gp_collapsed');
|
||
area.parent().find('.collapsearea').slideUp(300);
|
||
area.removeClass('gp_collapsed').next().slideDown(300);
|
||
//ability to show multiple
|
||
}else{
|
||
area.toggleClass('gp_collapsed').next().slideToggle(300);
|
||
}
|
||
|
||
};
|
||
|
||
|
||
/**
|
||
* Load content in #gp_admin_box
|
||
* @deprecated 2.5, use data-cmd="gpabox" instead
|
||
*
|
||
*/
|
||
$gp.links.ajax_box = $gp.links.admin_box = function(evt){
|
||
alert(' "ajax_box" and "admin_box" are deprecated link arguments. Use gpabox instead.');
|
||
evt.preventDefault();
|
||
$gp.loading();
|
||
var href = $gp.jPrep(this.href,'gpreq=flush');
|
||
$.get(href,'',function(data){
|
||
$gp.AdminBoxC(data);
|
||
$gp.loaded();
|
||
},'html');
|
||
};
|
||
|
||
|
||
/**
|
||
* Load content for #gp_admin_box
|
||
* This method allows for other actions to be sent to the client in addition to admin_box content
|
||
*/
|
||
$gp.links.gpabox = function(evt){
|
||
evt.preventDefault();
|
||
$gp.loading();
|
||
var href = $gp.jPrep(this.href)+'&gpx_content=gpabox';
|
||
var this_context = this;
|
||
$.getJSON(href,function(data,textStatus,jqXHR){
|
||
$gp.Response.call(this_context,data,textStatus,jqXHR);
|
||
});
|
||
|
||
};
|
||
|
||
|
||
/**
|
||
* Add a table row
|
||
*
|
||
*/
|
||
$gp.links.add_table_row = function(evt){
|
||
var $tr = $(this).closest('tr');
|
||
var $new_row = $tr.closest('tbody').find('tr').first().clone();
|
||
$new_row.find('.class_only').remove();
|
||
$new_row.find('input').val('').attr('value','');
|
||
$new_row.find('textarea').val('').text('');
|
||
$tr.before($new_row);
|
||
}
|
||
|
||
/**
|
||
* Remove a table row
|
||
*
|
||
*/
|
||
$gp.links.rm_table_row = function(evt){
|
||
var $this = $(this);
|
||
if( $this.closest('tbody').find('.rm_table_row').length < 2 ){
|
||
return;
|
||
}
|
||
$this.closest('tr').remove();
|
||
}
|
||
|
||
|
||
/**
|
||
* POST a link (without ajax)
|
||
*
|
||
*/
|
||
$gp.links.post = function(evt){
|
||
evt.preventDefault();
|
||
|
||
var query = strip_to(this.search,'?');
|
||
var params = ParseQuery(query);
|
||
params.verified = this.dataset.nonce;
|
||
|
||
var form = document.createElement('form');
|
||
|
||
form.method = 'POST';
|
||
form.action = this.pathname;
|
||
|
||
|
||
for( const [name, value] of Object.entries(params) ){
|
||
var element = document.createElement('input');
|
||
element.type = 'hidden';
|
||
element.name = name;
|
||
element.value = value;
|
||
form.appendChild(element);
|
||
}
|
||
|
||
document.body.appendChild(form);
|
||
|
||
form.submit();
|
||
}
|
||
|
||
function ParseQuery(queryString) {
|
||
var query = {};
|
||
var pairs = (queryString[0] === '?' ? queryString.substr(1) : queryString).split('&');
|
||
for (var i = 0; i < pairs.length; i++) {
|
||
var pair = pairs[i].split('=');
|
||
query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || '');
|
||
}
|
||
return query;
|
||
}
|
||
|
||
|
||
/**
|
||
* Post a gpabox request
|
||
*
|
||
*/
|
||
$gp.inputs.gpabox = function(){
|
||
return $gp.post(this,'gpx_content=gpabox');
|
||
};
|
||
|
||
|
||
/**
|
||
* Toggle the "checked" class on the parent of a checkbox when clicked
|
||
*
|
||
*/
|
||
$gp.inputs.gpcheck = function(){
|
||
if( this.checked ){
|
||
$(this).parent().addClass('checked');
|
||
}else{
|
||
$(this).parent().removeClass('checked');
|
||
}
|
||
};
|
||
|
||
|
||
/**
|
||
* Check or uncheck all checkboxes in a form
|
||
*
|
||
*/
|
||
$gp.inputs.check_all = function(){
|
||
$(this).closest('form').find('input[type=checkbox]').prop('checked',this.checked);
|
||
};
|
||
|
||
|
||
/**
|
||
* Send form using cookiecmd
|
||
*
|
||
*/
|
||
$gp.inputs.cnreq = function(evt){
|
||
evt.preventDefault();
|
||
var query = $(this.form).serialize();
|
||
$gp.SetCookieCmd(query);
|
||
//$gp.Cookie('cookie_cmd',encodeURIComponent(query),1);
|
||
window.location = strip_from(strip_from(this.form.action,'#'),'?');
|
||
};
|
||
|
||
|
||
/**
|
||
* Escape special html characters in a string similar to php's htmlspecialchars() function
|
||
*
|
||
*/
|
||
$gp.htmlchars = function(str){
|
||
str = str || '';
|
||
return $('<a>').text(str).html();
|
||
};
|
||
|
||
|
||
/**
|
||
* Redirect the user's browser to a url
|
||
*
|
||
*/
|
||
$gp.response.location = function(obj){
|
||
window.setTimeout(function(){
|
||
window.location = obj.SELECTOR;
|
||
},obj.CONTENT);
|
||
window.setInterval(function(){
|
||
$('#redir-countdown').text($('#redir-countdown').text() - 1);
|
||
}, 1000);
|
||
};
|
||
|
||
|
||
/**
|
||
* toggle the isPrivate class for the <html> element
|
||
* obj.SELECTOR must evaluate as true or false
|
||
*
|
||
*/
|
||
$gp.response.toggle_vis_class = function(obj){
|
||
$('html').toggleClass('isPrivate', !!obj.SELECTOR);
|
||
};
|
||
|
||
|
||
/**
|
||
* Get the edit area id
|
||
*
|
||
*/
|
||
$gp.AreaId = function( $node ){
|
||
|
||
var area_id = $node.data('gp-area-id');
|
||
|
||
if( typeof(area_id) != 'undefined' ){
|
||
return parseInt(area_id);
|
||
}
|
||
|
||
//ExtraEditArea6
|
||
//ExtraEditLink6
|
||
var area_id = $node.attr('id');
|
||
if( typeof(area_id) != 'undefined' ){
|
||
return parseInt($node.attr('id').substr(13));
|
||
}
|
||
|
||
}
|
||
|
||
|
||
/**
|
||
* Expand sub lists
|
||
*
|
||
*/
|
||
$gp.links.expand = function(){
|
||
|
||
var list = $(this).siblings('ul');
|
||
|
||
if( list.css('display') == 'block' ){
|
||
return;
|
||
}
|
||
|
||
list.css('display','block');
|
||
|
||
$(document).one('click',function(evt){
|
||
list.css('display','');
|
||
});
|
||
|
||
}
|
||
|
||
/**
|
||
* Indicate if there's an extra area that is a draft
|
||
*
|
||
*/
|
||
$gp.IndicateDraft = function(){
|
||
|
||
$('.gp_extra_edit').removeClass('msg_publish_draft');
|
||
|
||
$('.editable_area').each(function(){
|
||
if( $(this).data('draft') == 1 ){
|
||
$('.gp_extra_edit').addClass('msg_publish_draft');
|
||
return false;
|
||
}
|
||
});
|
||
}
|
||
|
||
|
||
/**
|
||
* Onload
|
||
*
|
||
*/
|
||
$(function(){
|
||
|
||
$gp.$win = $(window);
|
||
$gp.$doc = $(document);
|
||
|
||
//add return value to form
|
||
$gp.$doc.on('mousedown','form',function(){
|
||
var $this = $(this);
|
||
|
||
if( $this.data('gpForms') === 'checked' ){
|
||
return;
|
||
}
|
||
|
||
if( typeof(this['return']) !== 'undefined' ){
|
||
console.log('return');
|
||
this['return'].value = window.location; //set the return path
|
||
}
|
||
|
||
$this.data('gpForms','checked');
|
||
});
|
||
|
||
if( !isadmin || (typeof(gp_bodyashtml) !== 'undefined') ){
|
||
return;
|
||
}
|
||
|
||
$('body, html').addClass('gpAdmin');
|
||
|
||
$gp.IndicateDraft();
|
||
|
||
window.setTimeout(function(){
|
||
EditOutlines();
|
||
UIEffects();
|
||
},1);
|
||
|
||
|
||
/**
|
||
* Update character counts
|
||
*
|
||
*/
|
||
$gp.$doc.on('keyup keypress paste change', '.show_character_count textarea', function(){
|
||
$(this).parent().find('.character_count span').html( this.value.length );
|
||
});
|
||
|
||
|
||
/**
|
||
* Editable area outline
|
||
*
|
||
*/
|
||
function EditOutlines(){
|
||
var timeout = false, overlay, lnk_span=false, edit_area, highlight_box, fixed_pos = false;
|
||
|
||
overlay = $gp.div('gp_edit_overlay');
|
||
overlay.on('click', function(evt){
|
||
|
||
//if a link is clicked, prevent the overlay from being shown right away
|
||
var target = $(evt.target);
|
||
if( target.filter('a').length > 0 ){
|
||
if( target.hasClass('gp_overlay_close') ){
|
||
evt.preventDefault();
|
||
}
|
||
if( edit_area){
|
||
edit_area.addClass('gp_no_overlay');
|
||
}
|
||
}
|
||
HideOverlay();
|
||
|
||
}).on('mouseleave touchend',function(){
|
||
StartOverlayHide();
|
||
}).on('mouseenter touchstart',function(){
|
||
if( timeout ){
|
||
window.clearTimeout(timeout);
|
||
}
|
||
});
|
||
|
||
//show the edit link when hovering over an editable area
|
||
// using mouseenter to show link an area filled with an iframe
|
||
$('.editable_area').on('mousemove.gp mouseenter.gp touchstart.gp',function(e){
|
||
if( timeout ){
|
||
window.clearTimeout(timeout);
|
||
}
|
||
|
||
var new_area = $(this);
|
||
|
||
// don't show overlay
|
||
// - for an area that is being edited
|
||
// - if we've already shown it
|
||
if( new_area.hasClass('gp_no_overlay') || new_area.hasClass('gp_editing') ){
|
||
return;
|
||
}
|
||
|
||
if( new_area.parent().closest('.editable_area').length > 0 ){
|
||
e.stopPropagation();
|
||
// trigger a substitute event, plugin JS can listen to
|
||
new_area.trigger("admin:" + e.type);
|
||
}
|
||
|
||
//area han't changed, so just show the span
|
||
if( lnk_span && edit_area && new_area.attr('id') === edit_area.attr('id') ){
|
||
lnk_span.show();
|
||
return;
|
||
}
|
||
|
||
rmNoOverlay(edit_area);
|
||
|
||
edit_area = new_area;
|
||
|
||
AreaOverlay(edit_area);
|
||
|
||
}).on('mouseleave touchend',function(){
|
||
StartOverlayHide();
|
||
rmNoOverlay(edit_area);
|
||
});
|
||
|
||
$gp.$win.on('scroll', function(){
|
||
SpanPosition();
|
||
});
|
||
|
||
|
||
function rmNoOverlay(edit_area){
|
||
|
||
if( !edit_area ){
|
||
return;
|
||
}
|
||
edit_area.removeClass('gp_no_overlay');
|
||
}
|
||
|
||
/**
|
||
* Make sure the span for the current edit area is within the viewable window
|
||
*
|
||
*/
|
||
function SpanPosition(){
|
||
|
||
if( !lnk_span || fixed_pos ){
|
||
return;
|
||
}
|
||
|
||
var off = lnk_span.offset(),
|
||
pos = lnk_span.position(),
|
||
top = $gp.$win.scrollTop(),
|
||
diff = Math.max(0,top - (off.top - pos.top));
|
||
|
||
lnk_span.stop(true,true).animate({'top':diff});
|
||
}
|
||
|
||
|
||
function StartOverlayHide(){
|
||
if( timeout ){
|
||
window.clearTimeout(timeout);
|
||
}
|
||
|
||
timeout = window.setTimeout(
|
||
function(){
|
||
HideOverlay();
|
||
},200);
|
||
}
|
||
|
||
function HideOverlay(){
|
||
|
||
//hide links
|
||
if( lnk_span ){
|
||
lnk_span
|
||
.stop(true,true)
|
||
.hide(500,function(){
|
||
ResetMenu();
|
||
});
|
||
}
|
||
|
||
fixed_pos = false;
|
||
|
||
|
||
//hide the box
|
||
var box = overlay.find('div');
|
||
box.stop(true,true).fadeOut();
|
||
}
|
||
|
||
|
||
/**
|
||
* Display the edit links and overlay that outlines an editable area
|
||
*
|
||
*/
|
||
function AreaOverlay(edit_area){
|
||
var id,loc,width;
|
||
|
||
id = edit_area.attr('id');
|
||
if( !id ){
|
||
return;
|
||
}
|
||
|
||
id = id.substr(13); //edit_area is always ExtraEditArea#
|
||
|
||
//get the edit links
|
||
var edit_links = $('#ExtraEditLnks'+id).children();
|
||
if( edit_links.length === 0 ){
|
||
edit_links = $('#ExtraEditLink'+id);
|
||
if( edit_links.length === 0 ){
|
||
return;
|
||
}
|
||
}
|
||
|
||
//edit area location
|
||
loc = $gp.Coords(edit_area);
|
||
overlay.show().css({'top':(loc.top-3),'left':(loc.left-2),'width':(loc.w+6)});
|
||
|
||
if( !lnk_span ){
|
||
lnk_span = $('<span>');
|
||
highlight_box = $('<div>');
|
||
overlay.html(highlight_box).append(lnk_span);
|
||
}else{
|
||
lnk_span.stop(true,true).show().removeClass('gp_hover');
|
||
}
|
||
|
||
highlight_box.stop(true,true).hide().css({'height':(loc.h+5),'width':(loc.w+4)});
|
||
|
||
SpanPosition();
|
||
|
||
//add the edit links
|
||
edit_links = edit_links.clone(true)
|
||
.removeClass('ExtraEditLink');
|
||
|
||
//
|
||
lnk_span.html('<a class="gp_overlay_expand fa fa-pencil"></a>')
|
||
.append(edit_links);
|
||
|
||
|
||
ResetMenu();
|
||
}
|
||
|
||
/**
|
||
* Reset Context Menu
|
||
*
|
||
*/
|
||
function ResetMenu(){
|
||
fixed_pos = false;
|
||
lnk_span
|
||
.css({'left':'auto','top':0,'right':0,'position':'absolute'})
|
||
.removeClass('gp_hover')
|
||
.off('mouseenter touchstart')
|
||
.one('mouseenter touchstart',function(){
|
||
if( edit_area.hasClass('gp_no_overlay') ){
|
||
return;
|
||
}
|
||
ShowMenu();
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Display the editable area options
|
||
*
|
||
*/
|
||
function ShowMenu(){
|
||
lnk_span
|
||
.addClass('gp_hover')
|
||
.stop(true,true)
|
||
.show();
|
||
|
||
//show the overlay
|
||
highlight_box.stop(true,true).fadeIn();
|
||
}
|
||
|
||
|
||
/**
|
||
* Left click to show menu
|
||
* This may not always work. Some template/user js may cancel event bubbling
|
||
* Clicking on links still works
|
||
*
|
||
*/
|
||
$gp.$doc.on('click.gp','.editable_area, #gp_edit_overlay',function(evt){
|
||
if( ShowableMenu(evt) ){
|
||
MenuPos(evt);
|
||
}
|
||
});
|
||
|
||
|
||
/**
|
||
* Position link at cursor
|
||
*
|
||
*/
|
||
function MenuPos(evt){
|
||
|
||
fixed_pos = true;
|
||
var left = evt.pageX-$gp.$win.scrollLeft();
|
||
var diff = left + lnk_span.width() - $gp.$win.width();
|
||
var top = evt.pageY - $gp.$win.scrollTop();
|
||
|
||
if( diff > 0 ){
|
||
left -= diff;
|
||
}
|
||
|
||
lnk_span.show().stop(true,true).css({'top':top,'left':left,'right':'auto','position':'fixed'});
|
||
}
|
||
|
||
|
||
/**
|
||
* Return true if we can show the Typesetter context menu
|
||
*
|
||
*/
|
||
function ShowableMenu(evt){
|
||
|
||
if( evt.ctrlKey || evt.altKey || evt.shiftKey ){
|
||
return;
|
||
}
|
||
|
||
if( !edit_area || edit_area.hasClass('gp_editing') || edit_area.hasClass('gp_no_overlay') || !lnk_span ){
|
||
return;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
} /* end EditOutlines */
|
||
|
||
|
||
function UIEffects(){
|
||
|
||
if( !$('html').hasClass('admin_body') ){
|
||
SimpleDrag('#simplepanel .toolbar, #simplepanel .toolbar a', '#simplepanel', 'fixed', function(newpos){
|
||
gpui.tx = newpos.left;
|
||
gpui.ty = newpos.top;
|
||
$gp.SaveGPUI();
|
||
},true);
|
||
}
|
||
|
||
|
||
//keep expanding areas within the viewable window
|
||
$('.in_window').parent().on('mouseenter touchstart',function(){
|
||
var $this = $(this);
|
||
var panel = $this.children('.in_window').css({'right':'auto','left':'100%','top':0});
|
||
window.setTimeout(function(){
|
||
var pos = panel.offset();
|
||
var right = pos.left + panel.width();
|
||
var bottom = pos.top + panel.height();
|
||
|
||
|
||
if( right > $gp.$win.width() + $gp.$win.scrollLeft() ){
|
||
panel.css({'right':'100%','left':'auto'});
|
||
}
|
||
|
||
var winbottom = $gp.$win.height() + $gp.$win.scrollTop();
|
||
if( bottom > winbottom ){
|
||
var diff = winbottom + - bottom - 10;
|
||
panel.css({'top':diff});
|
||
}
|
||
},1);
|
||
});
|
||
|
||
}
|
||
|
||
|
||
/**
|
||
* Reduce a list of titles by search criteria entered in gpsearch areas
|
||
*
|
||
*/
|
||
$(document).on('keyup','input.gpsearch',function(){
|
||
var search = this.value.toLowerCase();
|
||
$(this.form).find('.gp_scrolllist > div > *').each(function(){
|
||
var $this = $(this);
|
||
if( $this.text().toLowerCase().indexOf(search) == -1 ){
|
||
$this.addClass('filtered');
|
||
}else{
|
||
$this.removeClass('filtered');
|
||
}
|
||
});
|
||
});
|
||
|
||
|
||
/**
|
||
* Configuration -> Settings
|
||
* Disable minifyjs when combinejs is unchecked
|
||
*
|
||
*/
|
||
function CheckCombineJs(){
|
||
var checked = $('#admincontent_inner input[type="checkbox"][name="combinejs"]').prop("checked");
|
||
$('#admincontent_inner input[type="checkbox"][name="minifyjs"]').prop("disabled", !checked);
|
||
}
|
||
|
||
$('#admincontent_inner input[type="checkbox"][name="combinejs"]').on('change', CheckCombineJs);
|
||
CheckCombineJs();
|
||
|
||
|
||
/**
|
||
* Modifier key names based on UI language and OS
|
||
*
|
||
*/
|
||
$gp.mod_keys = /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform) ?
|
||
{
|
||
// Apple
|
||
ctrlKey: '˄ control',
|
||
shiftKey: '⇑ shift',
|
||
altKey: '⌥ option',
|
||
metaKey: '⌘ command'
|
||
} :
|
||
{
|
||
// others
|
||
ctrlKey: gplang.ctrlKey,
|
||
shiftKey: '⇑ ' + gplang.shiftKey,
|
||
altKey: gplang.altKey,
|
||
metaKey: 'Meta'
|
||
};
|
||
|
||
|
||
/**
|
||
* Get visual representation of modifier keys in a <span>
|
||
* @param array of keys, possible values: ctrlKey, shiftKey, altKey, metaKey
|
||
* @return html
|
||
*
|
||
*/
|
||
$gp.GetModkeys = function(mod_keys){
|
||
if( !mod_keys.length ){
|
||
return '';
|
||
}
|
||
var html = '';
|
||
$.each(mod_keys, function(i, k){
|
||
html += '<kbd class="keyboard-key">' + $gp.mod_keys[k] + '</kbd> + ';
|
||
});
|
||
return '<span class="show_modkeys">' + html + '</span>';
|
||
};
|
||
|
||
|
||
/**
|
||
* Insert modifier keys pepresentation to an element
|
||
* @param stringa valid jQuery selector
|
||
* @param string 'before' or 'after''
|
||
* @param array of keys, modifier keys and regular key, e.g. ['ctrlKey','H'], optional
|
||
*
|
||
*/
|
||
$gp.InsertModkeys = function(selector, where, mod_keys){
|
||
$(selector).siblings('.show_modkeys').remove();
|
||
if( typeof(mod_keys) == 'undefined' ){
|
||
// get from hideAdminUIcfg
|
||
var mod_keys = hideAdminUIcfg.hotkey_modkeys;
|
||
}
|
||
|
||
var modkeys_html = $gp.GetModkeys(mod_keys);
|
||
if( where == 'before' ){
|
||
$(modkeys_html).insertBefore(selector);
|
||
}else{
|
||
$(modkeys_html).insertAfter(selector);
|
||
}
|
||
};
|
||
|
||
|
||
/**
|
||
* Get hotkey hint
|
||
* @param array of keys, modifier keys and regular key, e.g. ['ctrlKey','H']
|
||
* @return string e.g. for title attr
|
||
*
|
||
*/
|
||
$gp.GetHotkeyHint = function(keys){
|
||
var hint = '';
|
||
if( typeof(keys) == 'undefinded' || !keys.length ){
|
||
return '';
|
||
}
|
||
$.each(keys, function(i, k){
|
||
switch(k){
|
||
case 'ctrlKey':
|
||
case 'shiftKey':
|
||
case 'altKey':
|
||
case 'metaKey':
|
||
hint += '[' + $gp.mod_keys[k] + ']+';
|
||
break;
|
||
default:
|
||
hint += '[' + k + ']';
|
||
break;
|
||
}
|
||
});
|
||
return hint;
|
||
};
|
||
|
||
|
||
/*
|
||
* Hide Admin UI
|
||
* Configuration -> Settings
|
||
* input capture hotkey combination
|
||
*/
|
||
|
||
$('#admin_ui_hotkey').on('focus', function(){
|
||
$(this).select();
|
||
}).on('keydown', function(evt){
|
||
var key_stroke = $.inArray(evt.key, ['Control', 'Shift', 'Alt', 'AltGraph', 'Meta']) != -1 ? '' : evt.key.toUpperCase();
|
||
var key_which = $.inArray(evt.key, ['Control', 'Shift', 'Alt', 'AltGraph', 'Meta']) != -1 ? '' : evt.which;
|
||
|
||
var mod_keys = [];
|
||
evt.ctrlKey && mod_keys.push('ctrlKey');
|
||
evt.shiftKey && mod_keys.push('shiftKey');
|
||
evt.altKey && mod_keys.push('altKey');
|
||
evt.metaKey && mod_keys.push('metaKey');
|
||
|
||
// show the modifier keys
|
||
$gp.InsertModkeys('#admin_ui_hotkey', 'before', mod_keys);
|
||
|
||
var key_code =
|
||
(evt.ctrlKey ? 'ctrlKey+' : '') +
|
||
(evt.shiftKey ? 'shiftKey+' : '') +
|
||
(evt.altKey ? 'altKey+' : '') +
|
||
(evt.metaKey ? 'metaKey+' : '') +
|
||
key_which;
|
||
|
||
if( key_stroke == '' ||
|
||
key_stroke == ' ' ||
|
||
key_stroke == 'DEAD' ||
|
||
key_stroke == 'DELETE' ||
|
||
key_stroke == 'BACKSPACE'
|
||
){
|
||
key_stroke = '';
|
||
key_code = '';
|
||
}
|
||
$(this).val(key_stroke);
|
||
$('#admin_ui_hotkey_code').val(key_code);
|
||
evt.stopPropagation();
|
||
evt.preventDefault();
|
||
|
||
}).on('keyup', function(evt){
|
||
var code_val = $('#admin_ui_hotkey_code').val();
|
||
var has_modifier_key = /ctrlKey\+|shiftKey\+|altKey\+|metaKey\+/g.test(code_val);
|
||
if( code_val == '' || !has_modifier_key ){
|
||
$(this).val('');
|
||
$('#admin_ui_hotkey_code').val('');
|
||
$gp.InsertModkeys('#admin_ui_hotkey', 'before', []);
|
||
}
|
||
});
|
||
|
||
// make the input smaller and show the modifier keys on load
|
||
if( $('#admin_ui_hotkey').length ){
|
||
$('#admin_ui_hotkey').width(96);
|
||
$gp.InsertModkeys('#admin_ui_hotkey', 'before');
|
||
}
|
||
|
||
}); /* end on DOM ready */
|
||
|
||
|
||
|
||
/**
|
||
* Hide Admin UI
|
||
*
|
||
*/
|
||
$gp.HideAdminUI = {
|
||
|
||
init: function(){
|
||
|
||
$gp.HideAdminUI.hotkey_hint = '';
|
||
if( hideAdminUIcfg.hotkey != '' && hideAdminUIcfg.hotkey_code != '' ){
|
||
var hotkey_arr = hideAdminUIcfg.hotkey_modkeys;
|
||
hotkey_arr.push(hideAdminUIcfg.hotkey);
|
||
$gp.HideAdminUI.hotkey_hint = ' ' + $gp.GetHotkeyHint(hotkey_arr);
|
||
}
|
||
|
||
$('<div class="show-admin-ui" '
|
||
+ 'title="' + gplang.ShowAdminUI + $gp.HideAdminUI.hotkey_hint + '"'
|
||
+ '><i class="fa fa-window-restore"></i></div>')
|
||
.on('click', function(){
|
||
$gp.HideAdminUI.toggle(false);
|
||
}).appendTo('body');
|
||
|
||
$('.admin-link-hide-ui')
|
||
.attr('title', $('.admin-link-hide-ui').attr('title') + $gp.HideAdminUI.hotkey_hint);
|
||
|
||
if( hideAdminUIcfg.autohide_below ){
|
||
$gp.HideAdminUI.ww = $gp.$win.width();
|
||
$gp.$win.on('load', function(evt){
|
||
var ww = $gp.$win.width();
|
||
if( ww < hideAdminUIcfg.autohide_below ){
|
||
$gp.HideAdminUI.toggle(true);
|
||
$gp.HideAdminUI.ww = ww;
|
||
}
|
||
}).on('resize', function(evt){
|
||
var ww = $gp.$win.width();
|
||
var threshold = hideAdminUIcfg.autohide_below;
|
||
if( ww < threshold && $gp.HideAdminUI.ww >= threshold ){
|
||
$gp.HideAdminUI.toggle(true);
|
||
$gp.HideAdminUI.ww = ww;
|
||
}else if( ww >= threshold && $gp.HideAdminUI.ww < threshold ){
|
||
$gp.HideAdminUI.toggle(false);
|
||
$gp.HideAdminUI.ww = ww;
|
||
}
|
||
});
|
||
}
|
||
|
||
if( hideAdminUIcfg.hotkey_which != '' ){
|
||
$gp.$doc.on('keydown.hideAdminUI', function(evt){
|
||
var modkeys_pressed = true;
|
||
$.each(hideAdminUIcfg.hotkey_modkeys, function(i, key){
|
||
if( evt[key] === false ){
|
||
modkeys_pressed = false;
|
||
return false;
|
||
}
|
||
});
|
||
if( modkeys_pressed && evt.which == hideAdminUIcfg.hotkey_which ){
|
||
evt.preventDefault();
|
||
$gp.HideAdminUI.toggle();
|
||
}
|
||
if( evt.which == 27 ){ /* 27 [Esc] key always exits hidden state */
|
||
$gp.HideAdminUI.toggle(false);
|
||
}
|
||
});
|
||
}
|
||
},
|
||
|
||
toggle: function(show_hide){
|
||
if( typeof(show_hide) == 'boolean' ){
|
||
$("html").toggleClass("override_admin_style", show_hide);
|
||
}else{
|
||
$("html").toggleClass("override_admin_style");
|
||
}
|
||
},
|
||
|
||
};
|
||
|
||
|
||
|
||
/**
|
||
* A simple drag function for use with Typesetter admin areas
|
||
* Works with absolute and fixed positioned elements
|
||
* Different from other drag script in that the mouse will not trigger any mouseover/mousenter events because the drag box will be under the mouse
|
||
*
|
||
* @param string selector
|
||
* @param string drag_area
|
||
* @param string positioning (absolute,relative,fixed)
|
||
* @param function callback_done function to call once the drag 'n drop is done
|
||
*/
|
||
function SimpleDrag(selector, drag_area, positioning, callback_done){
|
||
|
||
var tolerance = -10;
|
||
var $drag_area = $(drag_area);
|
||
|
||
|
||
//dragging
|
||
$gp.$doc.off('mousedown.sdrag',selector).on('mousedown.sdrag',selector,function(e){
|
||
|
||
if( e.which != 1 ){
|
||
return;
|
||
}
|
||
|
||
var box, click_offsetx, click_offsety;
|
||
e.preventDefault();
|
||
if( $drag_area.length < 1 ){
|
||
return;
|
||
}
|
||
init();
|
||
function init(){
|
||
var pos = $drag_area.offset();
|
||
click_offsetx = e.clientX - pos.left + $gp.$win.scrollLeft();
|
||
click_offsety = e.clientY - pos.top + $gp.$win.scrollTop();
|
||
}
|
||
|
||
|
||
$gp.$doc.on('mousemove.sdrag',function(e){
|
||
|
||
//initiate the box
|
||
if( !box ){
|
||
var pos = $drag_area.offset();
|
||
var w = $drag_area.width();
|
||
var h = $drag_area.height();
|
||
box = $gp.div('admin_drag_box')
|
||
.css({'top':pos.top,'left':pos.left,'width':w,'height':h});
|
||
}
|
||
|
||
box.css({'left':Math.max(tolerance,e.clientX - click_offsetx),'top': Math.max(tolerance,e.clientY - click_offsety)});
|
||
e.preventDefault();
|
||
|
||
return false;
|
||
});
|
||
|
||
|
||
|
||
$gp.$doc.off('mouseup.sdrag').on('mouseup.sdrag',function(e){
|
||
var newposleft,newpostop,pos_obj;
|
||
$gp.$doc.off('mousemove.sdrag mouseup.sdrag');
|
||
|
||
if( !box ){
|
||
return false;
|
||
}
|
||
e.preventDefault();
|
||
|
||
//clean
|
||
box.remove();
|
||
box = false;
|
||
|
||
//new
|
||
newposleft = e.clientX - click_offsetx;
|
||
newpostop = e.clientY - click_offsety;
|
||
//newposleft = Math.max(0,e.clientX - click_offsetx);
|
||
//newpostop = Math.max(0,e.clientY - click_offsety);
|
||
|
||
//add scroll back in for absolute position
|
||
if( positioning === 'absolute' ){
|
||
newposleft += $gp.$win.scrollLeft();
|
||
newpostop += $gp.$win.scrollTop();
|
||
}
|
||
|
||
newposleft = Math.max(tolerance,newposleft);
|
||
newpostop = Math.max(tolerance,newpostop);
|
||
|
||
|
||
pos_obj = {'left':newposleft,'top': newpostop};
|
||
|
||
$drag_area.css(pos_obj).data({'gp_left':newposleft,'gp_top':newpostop});
|
||
|
||
if( typeof(callback_done) === 'function' ){
|
||
callback_done.call($drag_area,pos_obj,e);
|
||
}
|
||
|
||
$drag_area.trigger('dragstop');
|
||
return false;
|
||
});
|
||
|
||
return false;
|
||
});
|
||
|
||
|
||
|
||
if( $drag_area.css('position') === 'fixed' || $drag_area.parent().css('position') === 'fixed' ){
|
||
KeepViewable( $drag_area.addClass('keep_viewable') ,true);
|
||
}
|
||
|
||
function KeepViewable($elem,init){
|
||
|
||
if( !$elem.hasClass('keep_viewable') ){
|
||
return;
|
||
}
|
||
|
||
var gp_left
|
||
, css = {}
|
||
, pos = $elem.position();
|
||
|
||
|
||
//move back to the right if $elem has been moved left
|
||
if( init ){
|
||
$elem.data({'gp_left':pos.left,'gp_top':pos.top});
|
||
}else if( gp_left = $elem.data('gp_left') ){
|
||
pos.left = css.left = gp_left;
|
||
pos.top = css.top = $elem.data('gp_top');
|
||
}
|
||
|
||
var width = $elem.width();
|
||
|
||
|
||
//keep the top of the area from being placed too high in the window
|
||
var winbottom = $gp.$win.height();
|
||
if( pos.top < tolerance ){
|
||
css.top = tolerance;
|
||
|
||
//keep the top of the area from being placed too low
|
||
}else if( pos.top > winbottom ){
|
||
css.top = winbottom + 2*tolerance; //tolerance is negative
|
||
}
|
||
|
||
|
||
//right
|
||
var checkright = $gp.$win.width() - width - tolerance;
|
||
if( pos.left > checkright ){
|
||
css.left = checkright;
|
||
}
|
||
|
||
if( css.left || css.top ){
|
||
$elem.css(css);
|
||
}
|
||
}
|
||
|
||
$gp.$win.on('resize', function(){
|
||
$('.keep_viewable').each(function(){
|
||
KeepViewable($(this),false);
|
||
});
|
||
});
|
||
|
||
}
|
||
|
||
|
||
/**
|
||
* Initialize functionality for the rename/details dialog
|
||
*
|
||
*/
|
||
$gp.response.renameprep = function(){
|
||
|
||
|
||
var $form = $('#gp_rename_form');
|
||
var old_title = $('#old_title').val().toLowerCase();
|
||
var $new_title = $form.find('input.new_title').on('keyup change',ShowRedirect);
|
||
var space_char = $('#gp_space_char').val();
|
||
|
||
|
||
$('input:disabled').each(function(a,b){
|
||
$(b).fadeTo(400,0.6);
|
||
});
|
||
|
||
$('input.title_label').on('keyup change', SyncSlug).trigger('change');
|
||
|
||
$gp.links.showmore = function(){
|
||
$('#gp_rename_table tr').css('display','table-row');
|
||
$(this).parent().remove();
|
||
};
|
||
|
||
/**
|
||
* Toggle synchronization/customization of a field
|
||
*
|
||
*/
|
||
$gp.links.ToggleSync = function(evt){
|
||
var td = $(this).closest('td');
|
||
var vis = td.find('a:visible');
|
||
|
||
td.find('a').show();
|
||
vis.hide();
|
||
|
||
vis = td.find('a:visible');
|
||
|
||
if( vis.length ){
|
||
if( vis.hasClass('slug_edit') ){
|
||
td.find('input').addClass('sync_label').prop('readonly',true).fadeTo(400,0.6);
|
||
SyncSlug();
|
||
}else{
|
||
td.find('input').removeClass('sync_label').prop('readonly',false).fadeTo(400,1);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Show the redirct option if the new slug doesn't match the old slug
|
||
*
|
||
*/
|
||
function ShowRedirect(){
|
||
var new_val = $new_title.val().replace(/ /g,space_char).toLowerCase();
|
||
|
||
if( new_val !== old_title ){
|
||
$('#gp_rename_redirect').show(500);
|
||
}else{
|
||
$('#gp_rename_redirect').hide(300);
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Update the value of the slug/url field with the title
|
||
*
|
||
*/
|
||
function SyncSlug(){
|
||
|
||
var label = $('input.title_label').val();
|
||
|
||
|
||
$new_title.filter('.sync_label').val( LabelToSlug(label) );
|
||
|
||
$('input.browser_title.sync_label').val(label);
|
||
|
||
ShowRedirect();
|
||
|
||
return true;
|
||
}
|
||
|
||
|
||
/**
|
||
* Convert a label to a slug
|
||
*
|
||
*/
|
||
function LabelToSlug(str){
|
||
|
||
// Remove control characters
|
||
str = str.replace(/[\x00-\x1F\x7F]/g,'');
|
||
|
||
//illegal characters
|
||
//str = str.replace(/("|'|\?|\*|:|#)/g,'');
|
||
str = str.replace(/(\?|\*|:|#)/g,'');
|
||
|
||
//after removing tags, unescape special characters
|
||
str = strip_tags(str);
|
||
|
||
str = SlugSlashes(str);
|
||
|
||
//all spaces should be underscores
|
||
return str.replace(/ /g,space_char);
|
||
}
|
||
|
||
/**
|
||
* Remove html tags from a string
|
||
*
|
||
*/
|
||
function strip_tags(str){
|
||
return str.replace(/(<(\/?[a-zA-Z0-9][^<>]*)>)/ig,"");
|
||
}
|
||
|
||
|
||
/**
|
||
* Take care of slashes and periods
|
||
*
|
||
*/
|
||
function SlugSlashes(str){
|
||
|
||
//replace \
|
||
str = str.replace(/[\\]/g,'/');
|
||
|
||
//remove trailing "/."
|
||
str = str.replace(/^\.+[\/\/]/,'/');
|
||
|
||
//remove trailing "/."
|
||
str = str.replace(/[\/\/]\.+$/,'/');
|
||
|
||
//remove any "/./"
|
||
str = str.replace(/[\/\/]\.+[\/\/]/g,'/');
|
||
|
||
//remove consecutive slashes
|
||
str = str.replace(/[\/\/]+/g,'/');
|
||
|
||
if( str === '.' ){
|
||
return '';
|
||
}
|
||
|
||
//left trim /
|
||
str = str.replace(/^\/\/*/g,'');
|
||
|
||
return str;
|
||
}
|
||
|
||
};
|