Seditio Source
Root |
./othercms/b2evolution_7.2.3/rsc/js/functions.js
/**
 * This file is DEPRECATED. It is left here only so that old plugins can load the functions they need for their toolbars
 *
 * This file is part of the evoCore framework - {@link http://evocore.net/}
 * See also {@link https://github.com/b2evolution/b2evolution}.
 */


/**
 * Opens a window, centers it and makes sure it gets focus.
 *
 * Used to open popup window in BACK-office and FRONT-office:
 *  - _cronjob_list.view.php: ctrl=crontab, to execute cronjob in new window
 *  - _file.class.php: for url of file view
 *  - _file_list.inc.php: to open directory
 *  - system.ctrl.php: to view phpinfo
 */
function pop_up_window( href, target, width, height, params )
{
if( typeof(width) == 'undefined' )
{
width = 750;
}

if( typeof(height) == 'undefined' )
{
height = 550;
}

var left = (screen.width - width) / 2;
var top = (screen.height - height) / 2;

if( typeof(params) == 'undefined' )
{
params = 'scrollbars=yes, status=yes, resizable=yes, menubar=yes';
}

params = 'width=' + width + ', height=' + height + ', ' + 'left=' + left + ', top=' + top + ', ' + params;

// Open window:
opened = window.open( href, target, params );

// Bring to front!
opened.focus();

if( typeof(openedWindows) == 'undefined' )
{
openedWindows = new Array(opened);
}
else
{
openedWindows.push(opened);
}

// Tell the caller there is no need to process href="" :
return false;
}


// deprecated but left for old plugins:
function textarea_replace_selection( myField, snippet, target_document )
{
textarea_wrap_selection( myField, snippet, '', 1, target_document );
}

/**
 * Textarea insertion code.
 *
 * Used on FRONT-office (EDITING) and BACK-office in the following files:
 *  - By each plugin that works with textarea content of post or comment, to insert a code inside content by click event of toolbar button
 *  - _file_list.inc.php: ???
 *  - src/evo_links.js: to insert inline tag like this [image:123:caption text]
 *
 * @var element
 * @var text
 * @var text
 * @var boolean
 * @var document (needs only be passed from a popup window as window.opener.document)
 */
function textarea_wrap_selection( myField, before, after, replace, target_document )
{
target_document = target_document || document;

var hook_params = {
'element': myField,
'before': before,
'after': after,
'replace': replace,
'target_document': target_document
};

// First try, if a JavaScript callback is registered to handle this.
// E.g. the tinymce_plugin uses registers "wrap_selection_for_itemform_post_content"
//      to replace the (non-)selection
if( b2evo_Callbacks.trigger_callback( "wrap_selection_for_"+myField.id, hook_params ) )
{
return;
}

if( window.opener && ( typeof window.opener != "undefined" ) )
{
try
{ // Try find object 'b2evo_Callbacks' on window.opener to avoid halt error when page was opened from other domain
if( window.opener.b2evo_Callbacks &&
( typeof window.opener.b2evo_Callbacks != "undefined" ) &&
window.opener.b2evo_Callbacks.trigger_callback( "wrap_selection_for_"+myField.id, hook_params ) )
{ // callback in opener document (e.g. "Files" popup)
return;
}
}
catch( e )
{ // Catch an error of the cross-domain restriction
// Ignore this error because it dies when browser has no permission to access to other domain windows
}
}

if( window.parent
&& ( typeof window.parent != "undefined" )
&& window.parent.b2evo_Callbacks
&& ( typeof window.parent.b2evo_Callbacks != "undefined" ) )
{ // callback in parent document (e.g. "Links" iframe)
if( window.parent.b2evo_Callbacks.trigger_callback( "wrap_selection_for_"+myField.id, hook_params ) )
{
return;
}
}

// Basic handling:
if( target_document.selection )
{ // IE support:
myField.focus();
sel = target_document.selection.createRange();
if( replace )
{
sel.text = before + after;
}
else
{
sel.text = before + sel.text + after;
}
myField.focus();
}
else if( myField.selectionStart || myField.selectionStart == '0' )
{ // MOZILLA/NETSCAPE support:
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
var cursorPos;

var scrollTop, scrollLeft;
if( myField.type == 'textarea' && typeof myField.scrollTop != 'undefined' )
{ // remember old position
scrollTop = myField.scrollTop;
scrollLeft = myField.scrollLeft;
}

if( replace )
{
myField.value = myField.value.substring( 0, startPos)
+ before
+ after
+ myField.value.substring( endPos, myField.value.length);
cursorPos = startPos + before.length + after.length;
}
else
{
myField.value = myField.value.substring( 0, startPos)
+ before
+ myField.value.substring(startPos, endPos)
+ after
+ myField.value.substring( endPos, myField.value.length);
cursorPos = endPos + before.length + after.length;
}

if( typeof scrollTop != 'undefined' )
{ // scroll to old position
myField.scrollTop = scrollTop;
myField.scrollLeft = scrollLeft;
}

myField.focus();
myField.selectionStart = cursorPos;
myField.selectionEnd = cursorPos;
}
else
{ // Default browser support:
myField.value += before + after;
myField.focus();
}
}

/**
 * Replace substring in textarea.
 *
 * Used on FRONT-office (EDITING) and BACK-office in the following files:
 *  - src/evo_links.js: to remove inline tag like this [image:123:caption text]
 *
 * @var element
 * @var text
 * @var text
 * @var document (needs only be passed from a popup window as window.opener.document)
 */
function textarea_str_replace( myField, search, replace, target_document )
{
target_document = target_document || document;

var hook_params = {
'element': myField,
'search': search,
'replace': replace,
'target_document': target_document
};

// First try, if a JavaScript callback is registered to handle this.
// E.g. the tinymce_plugin uses registers "wrap_selection_for_itemform_post_content"
//      to replace the (non-)selection
if( b2evo_Callbacks.trigger_callback( 'str_replace_for_' + myField.id, hook_params ) )
{
return;
}

if( window.opener && ( typeof window.opener != 'undefined' ) )
{
try
{ // Try find object 'b2evo_Callbacks' on window.opener to avoid halt error when page was opened from other domain
if( window.opener.b2evo_Callbacks &&
   ( typeof window.opener.b2evo_Callbacks != 'undefined' ) &&
   window.opener.b2evo_Callbacks.trigger_callback( 'str_replace_for_' + myField.id, hook_params ) )
{ // callback in opener document (e.g. "Files" popup)
return;
}
}
catch( e )
{ // Catch an error of the cross-domain restriction
// Ignore this error because it dies when browser has no permission to access to other domain windows
}
}

if( window.parent &&
   ( typeof window.parent != 'undefined' ) &&
   window.parent.b2evo_Callbacks &&
   ( typeof window.parent.b2evo_Callbacks != 'undefined' ) )
{ // callback in parent document (e.g. "Links" iframe)
if( window.parent.b2evo_Callbacks.trigger_callback( 'str_replace_for_' + myField.id, hook_params ) )
{
return;
}
}

// Replace substring with new value
myField.value = myField.value.replace( search, replace );
myField.focus();
}


/**
 * Open or close a filter area (by use of CSS style).
 *
 * You have to define a div with id clickdiv_<ID> and a img with clickimg_<ID>,
 * where <ID> is the first param to the function.
 *
 * Used to expand/collapse a filter area of Results table on FRONT-office and BACK-office in the following files:
 *  - _uiwidget.class.php
 *
 * @param string html id of the element to toggle
 * @param string Force toggle action: 'collapse', 'expand'
 * @return false
 */
function toggle_filter_area( filter_name, force_toggle_action )
{
// Find objects to toggle:
var clickdiv = jQuery( '#clickdiv_' + filter_name );
var clickimg = jQuery( '#clickimg_' + filter_name );
if( clickdiv.length == 0 || clickimg.length == 0 )
{
alert( 'ID ' + filter_name + ' not found!' );
return false;
}

if( clickimg.hasClass( 'fa' ) || clickimg.hasClass( 'glyphicon' ) )
{ // Fontawesome icon | Glyph bootstrap icon
if( clickimg.data( 'toggle' ) != '' && clickimg.data( 'toggle' ) != undefined )
{ // This icon has a class name to toggle
var icon_prefix = ( clickimg.hasClass( 'fa' ) ? 'fa' : 'glyphicon' );
if( clickimg.data( 'toggle-orig-class' ) == undefined )
{ // Store original class name in data
clickimg.data( 'toggle-orig-class', clickimg.attr( 'class' ).replace( new RegExp( '^' + icon_prefix + ' (.+)$', 'g' ), '$1' ) );
}
if( clickimg.hasClass( clickimg.data( 'toggle-orig-class' ) ) )
{ // Replace original class name with exnpanded
clickimg.removeClass( clickimg.data( 'toggle-orig-class' ) )
.addClass( icon_prefix + '-' + clickimg.data( 'toggle' ) );
}
else
{ // Revert back original class
clickimg.removeClass( icon_prefix + '-' + clickimg.data( 'toggle' ) )
.addClass( clickimg.data( 'toggle-orig-class' ) );
}
}
}
else
{ // Sprite icon
var xy = clickimg.css( 'background-position' ).match( /-*\d+/g );
// Shift background position to the right/left to the one icon in the sprite
clickimg.css( 'background-position', ( parseInt( xy[0] ) + ( !clickdiv.is( ':hidden' ) ? 16 : - 16 ) ) + 'px ' + parseInt( xy[1] ) + 'px' );
}

var toggle_action = typeof( force_toggle_action ) == 'undefined'
? ( clickdiv.is( ':hidden' ) ? 'expand' : 'collapse' )
: force_toggle_action;

if( toggle_action == 'collapse' )
{ // Hide/collapse filters:
clickdiv.slideUp( 500 );
}
else if( toggle_action == 'expand' )
{ // Show/expand filters
clickdiv.slideDown( 500 );
}

if( typeof( force_toggle_action ) == 'undefined' && toggle_action == 'expand' )
{ // Collapse other opened filter areas on expand current filter area:
jQuery( '#clickdiv_'+filter_name ).closest( '.filters' ).find( '[id^=clickdiv_]' ).each( function()
{
if( jQuery( this ).is( ':visible' ) && jQuery( this ).attr( 'id' ) != 'clickdiv_' + filter_name )
{ // Collapse only different opened area:
toggle_filter_area( jQuery( this ).attr( 'id' ).substr( 9 ), 'collapse' )
}
} );
}

return false;
}


/*
 * Javascript callback handling, for helping plugins to interact in Javascript.
 *
 * This is, so one plugin (e.g. the tinymce_plugin) can say that it handles insertion of raw
 * content into a specific element ("itemform_post_content" in this case):
 *
 * <code>
 * if( typeof b2evo_Callbacks == "object" )
 * { // add a callback, that lets us insert the
 *   b2evo_Callbacks.register_callback( "wrap_selection_for_itemform_post_content", function(value) {
 *       tinyMCE.execCommand( "mceInsertRawHTML", false, value );
 *       return true;
 *     } );
 * }
 * </code>
 *
 * and others (e.g. the smilies_plugin or the youtube_plugin) should first try to use this
 * callback to insert the HTML:
 *
 * if( typeof b2evo_Callbacks == 'object' )
 * { // see if there's a callback registered that should handle this:
 * if( b2evo_Callbacks.trigger_callback("wrap_selection_for_"+b2evoCanvas.id, tag) )
 * {
 * return;
 * }
 * }
 */
function b2evo_Callbacks()
{
this.eventHandlers = new Array();
};

b2evo_Callbacks.prototype = {
register_callback : function( event, f, single_event ) {
if( typeof this.eventHandlers[event] == "undefined" )
{
this.eventHandlers[event] = new Array();
}
if( typeof( single_event ) != 'undefined' && single_event )
{ // Use only single last registered event:
this.eventHandlers[event][0] = f;
}
else
{ // Keep all registered events:
this.eventHandlers[event][this.eventHandlers[event].length] = f;
}
},

/**
* @param String event name
* @param mixed argument1
* @param mixed argument2
* ...
* @return boolean true, if any callback returned true
*                 null, if no callback registered
*/
trigger_callback : function( event, args ) {
if( typeof this.eventHandlers[event] == "undefined" )
{
return null;
}

var r = false;

// copy arguments and build function param string for eval():
var cb_args = '';
var cb_arguments = arguments;
for( var i = 1; i < arguments.length; i++ ) {
cb_args += "cb_arguments[" + i + "], ";
}
if( cb_args.length )
{ // remove last ", ":
cb_args = cb_args.substring( 0, cb_args.length - 2 );
}

// eval() for each registered callback:
for( var i = 0; i < this.eventHandlers[event].length; i++ )
{
var f = this.eventHandlers[event][i];
r = eval( "f("+cb_args+");" ) || r;
}

return r;
}
};

var b2evo_Callbacks = new b2evo_Callbacks();


/**
 * Display alert message in top-right corner
 *
 * Used on FRONT-office and BACK-office in the following file:
 *  - _comment_js.funcs.php
 *
 * @param string Message
 */
function evoAlert( message )
{
var previous_alerts = jQuery( '.b2evo_alert' );
if( previous_alerts.length > 0 )
{ // Clear previous alerts
previous_alerts.remove();
}

jQuery( 'body' ).append( '<div class="b2evo_alert">' + message + '</div>' );
setTimeout( function()
{ // Hide alert after 3 seconds
jQuery( '.b2evo_alert' ).fadeOut( {
complete: function() { jQuery( this ).remove(); }
} );
}, 3000 );

if( !evo_alert_events_initialized )
{ // Initialize events only one time
evo_alert_events_initialized = true;
jQuery( document ).on( 'click', '.b2evo_alert', function(){
jQuery( this ).remove();
} );
}
}
evo_alert_events_initialized = false;


function debounce( func, wait, immediate )
{
var timeout, result;
return function() {
var context = this, args = arguments, later, callNow;
later = function() {
timeout = null;
if( !immediate )
{
result = func.apply( context, args );
}
};
callNow = immediate && !timeout;
clearTimeout( timeout );
timeout = setTimeout( later, wait );
if( callNow )
{
result = func.apply( context, args );
}
return result;
};
};


/**
 * Initialize onclick event for each button with attribute "data-func"
 *
 * Used only by plugins for toolbar buttons. FRONT-office and BACK-office.
 */
jQuery( document ).ready( function()
{
jQuery( document ).on( 'click', '[data-func]', function()
{
var func_args = jQuery( this ).data( 'func' ).match( /([^\\|]|\\\|)+/g );
var func_name = func_args[0];
func_args.splice( 0, 1 );
for( var i = 0; i < func_args.length; i++ )
{
if( func_args[ i ].indexOf( 'b2evoCanvas' ) > -1 )
{ // Replace special param with global object
func_args[ i ] = window[ func_args[ i ] ];
}
else if( func_args[ i ] == ' ' )
{ // Fix an empty param
func_args[ i ] = '';
}
else
{ // Back escaped delimiter
func_args[ i ] = func_args[ i ].replace( /\\\|/g, '|' );
}
}

if( jQuery( this ).closest( '.disabled[class*=_toolbar]' ).length > 0 )
{ // Deny action when toolbar is disabled:
return false;
}

// Execute the function of this element:
window[ func_name ].apply( null, func_args );

// Prevent default event:
return false;
} );

// Enable/Disable plugin toolbars depending on selected plugins for current edit form:
function change_plugin_toolbar_activity( this_obj )
{
var prefix = this_obj.data( 'prefix' ) ? this_obj.data( 'prefix' ) : '';
var toolbar_obj = jQuery( '.' + prefix + this_obj.val() + '_toolbar' );
if( toolbar_obj.length == 0 )
{ // Skip this function if plugin has no toolbar
return true;
}

if( this_obj.is( ':checked' ) )
{ // Enable toolbar:
toolbar_obj.removeClass( 'disabled' );
toolbar_obj.find( 'input[type=button]' ).prop( 'disabled', false );
}
else
{ // Disable toolbar:
toolbar_obj.addClass( 'disabled' );
toolbar_obj.find( 'input[type=button]' ).prop( 'disabled', true );
}
}
jQuery( 'input[type=checkbox][name="renderers[]"]' ).each( function() { change_plugin_toolbar_activity( jQuery( this ) ) } );
jQuery( 'input[type=checkbox][name="renderers[]"]' ).on( 'click', function() { change_plugin_toolbar_activity( jQuery( this ) ) } );
jQuery( '.plugin-toolbar' ).on( 'click', function() {
var toolbar_obj = jQuery( this );
if( toolbar_obj.hasClass( 'disabled' ) )
{
var plugin_id = jQuery( this ).attr( 'data-plugin-toolbar' );
if( plugin_id )
{
plugin_id = plugin_id.replace( '_toolbar', '' );
if( plugin_id.indexOf( 'meta_' ) === 0 )
{
plugin_id = plugin_id.replace( 'meta_', '' );
var checkbox_obj = jQuery( 'input[type=checkbox][id="meta_renderer_' + plugin_id + '"]' );
}
else
{
var checkbox_obj = jQuery( 'input[type=checkbox][id="renderer_' + plugin_id + '"]' );
}

if(  checkbox_obj.length > 0 )
{
checkbox_obj.prop( 'checked', true );
change_plugin_toolbar_activity( checkbox_obj );
}
}
}

} );
} );