/************************************************/
/* IPB3 Javascript */
/* -------------------------------------------- */
/* ips.editor.js - Editor class */
/* (c) IPS, Inc 2008 */
/* -------------------------------------------- */
/* Author: Rikki Tissier (based on Matt's code) */
/************************************************/
var _editor = window.IPBoard;
var isRTL = ( isRTL ) ? isRTL : false;
/* ===================================================================================================== */
/* Values for the IPB text editor */
IPBoard.prototype.editor_values = $H({
'templates': $A(),
'colors_perrow': 8,
'colors': [ '000000' , 'A0522D' , '556B2F' , '006400' , '483D8B' , '000080' , '4B0082' , '2F4F4F' ,
'8B0000' , 'FF8C00' , '808000' , '008000' , '008080' , '0000FF' , '708090' , '696969' ,
'FF0000' , 'F4A460' , '9ACD32' , '2E8B57' , '48D1CC' , '4169E1' , '800080' , '808080' ,
'FF00FF' , 'FFA500' , 'FFFF00' , '00FF00' , '00FFFF' , '00BFFF' , '9932CC' , 'C0C0C0' ,
'FFC0CB' , 'F5DEB3' , 'FFFACD' , '98FB98' , 'AFEEEE' , 'ADD8E6' , 'DDA0DD' , 'FFFFFF'
],
// You can add new fonts here if you wish, HOWEVER, if you use
// non-standard fonts, users without those fonts on their computer
// will not see them. The default list below has the generally accepted
// safe fonts; add others at your own risk!
'primary_fonts': $H({ arial: "Arial",
arialblack: "Arial Black",
arialnarrow: "Arial Narrow",
bookantiqua: "Book Antiqua",
centurygothic: "Century Gothic",
comicsansms: "Comic Sans MS",
couriernew: "Courier New",
franklingothicmedium: "Franklin Gothic Medium",
garamond: "Garamond",
georgia: "Georgia",
impact: "Impact",
lucidaconsole: "Lucida Console",
lucidasansunicode: "Lucida Sans Unicode",
microsoftsansserif: "Microsoft Sans Serif",
palatinolinotype: "Palatino Linotype",
tahoma: "Tahoma",
timesnewroman: "Times New Roman",
trebuchetms: "Trebuchet MS",
verdana: "Verdana"
}),
'font_sizes': $A([ 1, 2, 3, 4, 5, 6, 7 ])
});
// =============================================================================================================//
// Class for RTE EDITOR which is inherited by main Editor class
_editor_rte = Class.create({
_identifyType: function()
{
Debug.write( "(Editor " + this.id + ") This is the RTE class" );
},
togglesource_pre_show_html: function()
{
},
togglesource_post_show_html: function()
{
},
editor_write_contents: function( text, do_init )
{
if ( ( Object.isUndefined(text) || text === false || text.blank() ) && Prototype.Browser.Gecko )
{
text = '
';
}
else if ( Object.isUndefined(text) || text === false )
{
text = '';
}
if ( this.editor_document && this.editor_document.initialized )
{
this.editor_document.body.innerHTML = text;
}
else
{
if ( do_init )
{
this.editor_document.designMode = 'on';
}
this.editor_document = this.editor_window.document;
this.editor_document.open( 'text/html', 'replace' );
this.editor_document.write( this.ips_frame_html.replace( '{:content:}', text ) );
this.editor_document.close();
if ( do_init )
{
this.editor_document.body.contentEditable = true;
this.editor_document.initialized = true;
}
}
},
removeformat: function(e)
{
this.apply_formatting( 'unlink' , false, false );
this.apply_formatting( 'removeformat', false, false );
/*this.apply_formatting( 'killword', false, false );*/
var text = this.get_selection();
if ( text )
{
text = this.strip_html( text );
text = this.strip_empty_html( text );
text = text.replace( /\r/g, "" );
text = text.replace( /\n/g, "
" );
text = text.replace( //g, "" );
text = text.replace( /<!--(.*?)-->/g, "" );
this.insert_text( text );
}
},
editor_get_contents: function()
{
return this.editor_document.body.innerHTML;
},
editor_set_content: function( init_text )
{
if( $( this.id + '_iframe' ) )
{
this.editor_box = $( this.id + '_iframe' );
}
else
{
// Create iframe
var iframe = new Element('iframe', { 'id': this.id + '_iframe', 'tabindex': 0 } );
if( Prototype.Browser.IE && window.location.protocol == 'https:' )
{
iframe.writeAttribute( 'src', this.options.file_path + '/index.html' );
}
// Insert into DOM
this.items['text_obj'].up().insert( iframe );
this.editor_box = iframe;
}
if( !Prototype.Browser.IE )
{
this.editor_box.setStyle( 'border: 1px inset' );
}
else
{
// Bug #17772
if( !Object.isUndefined( init_text ) && init_text != false )
{
init_text = init_text.replace( /§/g, "§");
}
}
//-----------------------------------------
// Is there a height in the cookies?
//-----------------------------------------
var test_height = ipb.Cookie.get( 'ips_rte_height' );
/*Debug.write( "Height is " + test_height );*/
if ( Object.isNumber( test_height ) && test_height > 50 )
{
this.items['text_obj'].setStyle( { height: test_height + 'px' } );
Debug.write( "Set text_obj height to " + test_height );
}
// Set up
var tobj_dims = this.items['text_obj'].getDimensions();
if( Object.isUndefined( tobj_dims ) || tobj_dims['height'] == 0 )
{
tobj_dims['height'] = 250;
}
//Debug.write( tobj_dims );
/*Debug.write( this.items['text_obj'].getDimensions()['height'] );*/
this.editor_box.setStyle( { width: '100%',
height: tobj_dims.height + 'px',
className: this.items['text_obj'].className
});
this.items['text_obj'].hide();
//---------
this.editor_window = this.editor_box.contentWindow;
this.editor_document = this.editor_window.document;
if ( ! this.items['text_obj'].value && ( init_text === false || Object.isUndefined( init_text ) ) )
{
/* Wipe editor */
this.editor_write_contents(false, true);
}
else
{
this.editor_write_contents( (Object.isUndefined( init_text ) || ! init_text ? this.items['text_obj'].value : init_text), true );
}
this.editor_document.editor_id = this.editor_id;
this.editor_window.editor_id = this.editor_id;
this.editor_window.has_focus = false;
// Go on.. cursor, flash you bastard
try
{
Debug.write( "Attempt to get focus" );
this.editor_check_focus();
// Sometimes moves the focus to the RTE
this.editor_document.execCommand("InsertHorizontalRule", false, null);
this.editor_document.execCommand("undo" , false, null);
}
catch(error)
{
Debug.write( "#011 " + error );
}
//-----------------------------------------
// Kill tags
//-----------------------------------------
//document.getElementById( this.editor_id + '_cmd_justifyfull' ).style.display = 'none';
},
apply_formatting: function(cmd, dialog, argument)
{
dialog = ( Object.isUndefined( dialog ) ? false : dialog);
argument = ( Object.isUndefined( argument ) ? true : argument);
if ( Prototype.Browser.IE && this.forum_fix_ie_newlines )
{
if ( cmd == 'justifyleft' || cmd == 'justifycenter' || cmd == 'justifyright' )
{
var _a = cmd.replace( "justify", "" );
this.wrap_tags_lite( "[" + _a + "]", "[/" + _a + "]" );
return true;
}
else if ( cmd == 'outdent' || cmd == 'indent' || cmd == 'insertorderedlist' || cmd == 'insertunorderedlist' )
{
this.editor_check_focus();
var sel = this.editor_document.selection;
var ts = this.editor_document.selection.createRange();
var t = ts.htmlText.replace(/
]*)>(.*)<\/p>/i, '$2');
if ( (sel.type == "Text" || sel.type == "None") )
{
ts.pasteHTML( t + "
\n" );
}
else
{
this.editor_document.body.innerHTML += "";
}
}
}
//alert( "Here" );
/*Debug.write( "Apply formatting selection is: " + this.get_selection() + ", cmd is " + cmd );*/
if( Prototype.Browser.IE && this._ie_cache != null )
{
this.editor_check_focus();
this._ie_cache.select();
}
this.editor_document.execCommand( cmd, dialog, argument );
this._ie_cache = null;
return false;
},
/* ! get_selection */
get_selection: function()
{
var rng = this._ie_cache ? this._ie_cache : this.editor_document.selection.createRange();
//Debug.write( 'get selection: ie_cache:' + this._ie_cache.htmlText + '.' );
if ( rng.htmlText )
{
Debug.write( 'htmlTest:' + rng.htmlText + '.' );
return rng.htmlText;
}
else
{
var rtn = '';
for (var i = 0; i < rng.length; i++)
{
rtn += rng.item(i).outerHTML;
}
}
return rtn;
},
editor_set_functions: function()
{
//Debug.write( this.editor_document );
Event.observe( this.editor_document, 'mouseup', this.events.editor_document_onmouseup.bindAsEventListener( this ) );
Event.observe( this.editor_document, 'keyup', this.events.editor_document_onkeyup.bindAsEventListener( this ) );
Event.observe( this.editor_document, 'keydown', this.events.editor_document_onkeydown.bindAsEventListener( this ) );
Event.observe( this.editor_window, 'blur', this.events.editor_window_onblur.bindAsEventListener( this ) );
Event.observe( this.editor_window, 'focus', this.events.editor_window_onfocus.bindAsEventListener( this ) );
},
set_context: function( cmd )
{
// Showing HTML?
if ( this._showing_html )
{
return false;
}
this.button_update.each( function(item)
{
//Debug.write( this.id + '_cmd_' + item );
var obj = $( this.id + '_cmd_' + item );
if( obj != null )
{
try {
var state = new String( this.editor_document.queryCommandState( item ) );
if( obj.readAttribute('state') != state )
{
obj.writeAttribute( 'state', new String( state ) );
this.set_button_context( obj, ( obj.readAttribute('cmd') == cmd ? 'mouseover' : 'mouseout' ) );
}
}
catch( error )
{
Debug.write( "#1 " + error );
}
}
}.bind(this) );
//-----------------------------------------
// Check and set font context
//-----------------------------------------
this.button_set_font_context();
//-----------------------------------------
// Check and set size context
//-----------------------------------------
this.button_set_size_context();
},
button_set_font_context: function( font_state )
{
changeto = '';
// Showing HTML?
if ( this._showing_html )
{
return false;
}
if( this.items['buttons']['fontname'] )
{
if( Object.isUndefined( font_state ) ){
font_state = this.editor_document.queryCommandValue('fontname') || '';
}
if( font_state.blank() ){
if ( !Prototype.Browser.IE && window.getComputedStyle )
{
font_state = this.editor_document.body.style.fontFamily;
}
} else if( font_state == null ){
font_state = '';
}
if( font_state != this.font_state )
{
this.font_state = font_state;
var fontword = font_state;
var commapos = fontword.indexOf(",");
if( commapos != -1 ){
fontword = fontword.substr(0, commapos);
}
fontword = fontword.toLowerCase();
changeto = '';
ipb.editor_values.get('primary_fonts').any( function(font){
if( font.value.toLowerCase() == fontword ){
changeto = font.value;
return true;
} else {
return false;
}
});
changeto = ( changeto == '' ) ? this.fontoptions['_default'] : changeto;
this.items['buttons']['fontname'].update( changeto );
}
}
},
button_set_size_context: function( size_state )
{
if( this.items['buttons']['fontsize'] )
{
if( Object.isUndefined( size_state ) ){
size_state = this.editor_document.queryCommandValue('fontsize');
}
if( size_state == null || size_state == '' )
{
if ( Prototype.Browser.Gecko )
{
size_state = this.convert_size( this.editor_document.body.style.fontSize, 0 );
if ( ! size_state )
{
size_state = '2';
}
}
}
changeto = '';
if ( size_state != this.size_state )
{
this.size_state = size_state;
ipb.editor_values.get('font_sizes').any( function(size){
if( parseInt( size ) == parseInt( this.size_state ) ){
changeto = size;
return true;
} else {
return false;
}
}.bind(this));
changeto = ( changeto == '' ) ? this.sizeoptions['_default'] : changeto;
this.items['buttons']['fontsize'].update( changeto );
}
}
},
/* ! insert_text */
insert_text: function(text)
{
Debug.write( "Inserting " + text + "." );
this.editor_check_focus();
if ( typeof( this.editor_document.selection ) != 'undefined'
&& this.editor_document.selection.type != 'Text'
&& this.editor_document.selection.type != 'None' )
{
this.editor_document.selection.clear();
}
var sel = this._ie_cache ? this._ie_cache : this.editor_document.selection.createRange();
sel.pasteHTML(text);
sel.select();
this._ie_cache = null;
},
/* ! insert_emoticon */
insert_emoticon: function( emo_id, emo_image, emo_code, event )
{
Debug.write( "Adding emoticon " + emo_code );
try
{
//this._ie_cache = null;
// INIT
var _emo_url = ipb.vars['emoticon_url'] + "/" + emo_image;
var _emo_html = '
';
this.wrap_tags_lite( " " + _emo_html, " ", false);
}
catch( error )
{
Debug.write( "#2 " + error );
//alert( error );
}
/*if ( this.emoticon_window_id != '' && typeof( this.emoticon_window_id ) != 'undefined' )
{
this.emoticon_window_id.focus();
}*/
},
togglesource: function( e, update )
{
Event.stop(e);
// Already showing?
if( this._showing_html )
{
if( update )
{
this.editor_document.initialized = false;
this.editor_write_contents( $( this.id + '_htmlsource' ).value, true );
//this.editor_document.body.innerHTML = $( this.id + '_htmlsource' ).value;
}
$( this.editor_box ).show();
$( this.items['controls'] ).show();
// Remove source editor
$( this.id + '_htmlsource' ).remove();
$( this.id + '_ts_controls' ).remove();
// Post process
//this.togglesource_post_show_html();
this._showing_html = false;
// Set context
this.editor_check_focus();
//this.set_context();
}
else
{
this._showing_html = true;
this.togglesource_pre_show_html();
// Create a new textarea
var textarea = new Element( 'textarea', { id: this.id + '_htmlsource', tabindex: 3 } );
textarea.className = this.items['text_obj'].className;
var dims = this.items['text_obj'].getDimensions();
/*textarea.setStyle('width: ' + dims.width + 'px; height: ' + dims.height + 'px;');*/
textarea.value = this.clean_html( this.editor_get_contents() );
// Build controls
var controlbar = ipb.editor_values.get('templates')['togglesource'].evaluate( { id: this.id } );
// Insert into page
$( this.items['text_obj'] ).insert( { after: textarea } );
$( textarea ).insert( { after: controlbar } );
// Hook up events
$( this.id + '_ts_update' ).writeAttribute('cmd', 'togglesource').writeAttribute('editor_id', this.id).observe('click', this.togglesource.bindAsEventListener( this, 1 ) );
$( this.id + '_ts_cancel' ).writeAttribute('cmd', 'togglesource').writeAttribute('editor_id', this.id).observe('click', this.togglesource.bindAsEventListener( this, 0 ) );
// Hide editor
$( this.items['controls'] ).hide();
$( this.editor_box ).hide();
// Set context
this.editor_check_focus();
//this.set_context();
}
},
update_for_form_submit: function()
{
Debug.write("Updating for submit");
this.items['text_obj'].value = this.editor_get_contents();
Debug.write( "Before: " + this.items['text_obj'].value );
// IE does crappy things. 3
if ( Prototype.Browser.IE )
{
this.items['text_obj'].value = this.items['text_obj'].value.replace( / /g, ' ' );
this.items['text_obj'].value = this.items['text_obj'].value.replace( /\s+?$/, '' );
}
// http://trac.webkit.org/changeset/47640
// Safari bug with execcommand and underline + strikethrough
if( Prototype.Browser.WebKit )
{
this.items['text_obj'].value = this.items['text_obj'].value.replace( /([^>]*)<\/span>/gi, "$1" );
this.items['text_obj'].value = this.items['text_obj'].value.replace( /([^>]*)<\/span>/gi, "$1" );
}
Debug.write( "After: " + this.items['text_obj'].value );
return true;
}
});
// =============================================================================================================//
// Class for STANDARD EDITOR which is inherited by main Editor class
_editor_std = Class.create({
_identifyType: function()
{
Debug.write( "(Editor " + this.id + ") This is the STD class" );
},
editor_set_content: function( init_text )
{
var iframe = this.items['text_obj'].up().down('iframe', 0);
if ( !Object.isUndefined( iframe ) )
{
var iframeDims = iframe.getDimensions();
$( this.items['text_obj'] ).setStyle( { 'width': iframeDims.width, 'height': iframeDims.height } ).show();
$( iframe ).setStyle( 'width: 0px; height: 0px; border: none;' );
}
this.editor_window = this.items['text_obj'];
this.editor_document = this.items['text_obj'];
this.editor_box = this.items['text_obj'];
if( !Object.isUndefined( init_text ) && init_text !== false )
{
this.editor_write_contents( init_text );
}
this.editor_document.editor_id = this.id;
this.editor_window.editor_id = this.id;
// Hide those pesky buttons we dont need
if( !Prototype.Browser.IE && $( this.id + '_cmd_spellcheck' ) ){
$( this.id + '_cmd_spellcheck').hide();
}
if( $(this.id + '_cmd_removeformat') ){
$( this.id + '_cmd_removeformat' ).hide();
}
if( $(this.id + '_cmd_togglesource' ) ){
$( this.id + '_cmd_togglesource' ).hide();
}
if( $(this.id + '_cmd_justifyfull' ) ){
$( this.id + '_cmd_justifyfull' ).hide();
}
if( $(this.id + '_cmd_outdent' ) ){
$( this.id + '_cmd_outdent' ).hide();
}
if( $(this.id + '_cmd_switcheditor' ) ){
$( this.id + '_cmd_switcheditor' ).hide();
}
},
editor_write_contents: function(text)
{
if ( text !== false )
{
this.items['text_obj'].value = text;
}
},
editor_get_contents: function()
{
return this.editor_document.value;
},
apply_formatting: function(cmd, dialog, argument)
{
/*Debug.write("Click");*/
switch (cmd)
{
case 'bold':
case 'italic':
case 'underline':
{
this.wrap_tags(cmd.substr(0, 1), false);
return;
}
case 'justifyleft':
case 'justifycenter':
case 'justifyright':
{
this.wrap_tags(cmd.substr(7), false);
return;
}
case 'indent':
{
this.wrap_tags(cmd, false);
return;
}
case 'createlink':
{
var sel = this.get_selection();
if (sel)
{
this.wrap_tags('url', argument);
}
else
{
this.wrap_tags('url', argument, argument);
}
return;
}
case 'fontname':
{
this.wrap_tags('font', argument);
return;
}
case 'fontsize':
{
this.wrap_tags('size', argument);
return;
}
case 'forecolor':
{
this.wrap_tags('color', argument);
return;
}
case 'backcolor':
{
this.wrap_tags('background', argument);
return;
}
case 'insertimage':
{
this.wrap_tags('img', false, argument);
return;
}
case 'strikethrough':
{
this.wrap_tags('s', false);
return;
}
case 'superscript':
{
this.wrap_tags('sup', false);
return;
}
case 'subscript':
{
this.wrap_tags('sub', false);
return;
}
case 'removeformat':
return;
}
},
editor_set_functions: function()
{
Event.observe( this.editor_document, 'keypress', this.events.editor_document_onkeypress.bindAsEventListener(this) );
Event.observe( this.editor_window, 'focus', this.events.editor_window_onfocus.bindAsEventListener( this ) );
Event.observe( this.editor_window, 'blur', this.events.editor_window_onblur.bindAsEventListener( this ) );
},
set_context: function()
{
//Debug.write('Set context');
},
get_selection: function()
{
if ( !Object.isUndefined( this.editor_document.selectionStart ) )
{
return this.editor_document.value.substr(this.editor_document.selectionStart, this.editor_document.selectionEnd - this.editor_document.selectionStart);
}
else if ( ( document.selection && document.selection.createRange ) || this._ie_cache )
{
return ( ! document.selection.createRange().text && this._ie_cache ) ? this._ie_cache.text : document.selection.createRange().text;
}
else if ( window.getSelection )
{
return window.getSelection() + '';
}
else
{
return false;
}
},
insert_text: function(text)
{
this.editor_check_focus();
if ( !Object.isUndefined( this.editor_document.selectionStart ) )
{
var open = this.editor_document.selectionStart + 0;
var st = this.editor_document.scrollTop;
var end = open + text.length;
/* Opera doesn't count the linebreaks properly for some reason */
if( Prototype.Browser.Opera )
{
var opera_len = text.match( /\n/g );
try
{
end += parseInt(opera_len.length);
}
catch(e)
{
Debug.write( "#3 " + e );
}
}
this.editor_document.value = this.editor_document.value.substr(0, this.editor_document.selectionStart) + text + this.editor_document.value.substr(this.editor_document.selectionEnd);
// Don't adjust selection if we're simply adding , etc
if ( ! text.match( new RegExp( "\\" + this.open_brace + "(\\S+?)" + "\\" + this.close_brace + "\\" + this.open_brace + "/(\\S+?)" + "\\" + this.close_brace ) ) )
{
this.editor_document.selectionStart = open;
this.editor_document.selectionEnd = end;
this.editor_document.scrollTop = st;
Debug.write("Insert 0");
}
else
{
// Only firefox seems to need this...
if( Prototype.Browser.Gecko ){
this.editor_document.scrollTop = st;
}
}
this.editor_document.setSelectionRange( open, end );
Debug.write("Insert 1");
}
else if ( ( document.selection && document.selection.createRange ) || this._ie_cache )
{
var sel = this._ie_cache ? this._ie_cache : document.selection.createRange();
sel.text = text.replace(/\r?\n/g, '\r\n');
sel.select();
Debug.write("Insert 2");
}
else
{
this.editor_document.value += text;
Debug.write("Insert 3");
}
this._ie_cache = null;
},
insert_emoticon: function( emo_id, emo_image, emo_code, event )
{
this.editor_check_focus();
emo_code = this.unhtmlspecialchars( emo_code );
this.wrap_tags_lite( " " + emo_code, " ");
/*if ( Prototype.Browser.IE )
{
if ( this.emoticon_window_id != '' && !Object.isUndefined( this.emoticon_window_id ) )
{
this.emoticon_window_id.focus();
}
}*/
},
insertorderedlist: function(e)
{
this.insertlist( 'ol');
},
insertunorderedlist: function(e)
{
this.insertlist( 'ul');
},
insertlist: function( list_type )
{
var open_tag;
var close_tag;
var item_open_tag = '';
var item_close_tag = '';
var regex = '';
var all_add = '';
if ( this.use_bbcode )
{
regex = new RegExp('([\r\n]+|^[\r\n]*)(?!\\[\\*\\]|\\[\\/?list)(?=[^\r\n])', 'gi');
open_tag = list_type == 'ol' ? '[list=1]\n' : '[list]\n';
close_tag = '[/list]';
item_open_tag = '[*]';
item_close_tag = '';
}
else
{
regex = new RegExp('([\r\n]+|^[\r\n]*)(?!|<\\/?ol|ul)(?=[^\r\n])', 'gi');
open_tag = list_type == 'ol' ? '\n' : '\n';
close_tag = list_type == 'ol' ? '
\n' : '\n';
}
if ( text = this.get_selection() )
{
text = open_tag + text.replace( regex, "\n" + item_open_tag + '$1' + item_close_tag ) + '\n' + close_tag;
if ( this.use_bbcode )
{
text = text.replace( new RegExp( '\\[\\*\\][\r\n]+', 'gi' ), item_open_tag );
}
this.insert_text( text );
}
else
{
// http://community.invisionpower.com/tracker/issue-19347-insert-list/
// Commenting this out fixes the above bug report
//if ( Prototype.Browser.Gecko )
//{
// //this.insert_text( open_tag + close_tag );
// this.insert_text( open_tag );
//
// /* SKINNOTE: use proper lang for these */
// while ( val = prompt( ipb.lang['editor_enter_list'], '') )
// {
// this.insert_text( item_open_tag + val + item_close_tag + '\n' );
// //all_add += item_open_tag + val + item_close_tag + '\n';
// }
// this.insert_text( close_tag );
//}
//else
//{
var to_insert = open_tag;
var listitems = '';
while ( val = prompt( ipb.lang['editor_enter_list'], '') )
{
listitems += item_open_tag + val + item_close_tag + '\n';
}
//this.insert_text( close_tag );
if( listitems )
{
to_insert += listitems;
to_insert += close_tag;
this.insert_text( to_insert );
}
//}
}
},
removeformat: function()
{
var text = this.get_selection();
if ( text )
{
text = this.strip_html( text );
this.insert_text( text );
}
},
unlink: function()
{
var text = this.get_selection();
var link_regex = '';
var link_text = '';
if ( text !== false )
{
if ( text.match( link_regex ) )
{
text = ( this.use_bbcode ) ? text.replace( /\[url=([^\]]+?)\]([^\[]+?)\[\/url\]/ig, "$2" )
: text.replace( /]+?)?>(.+?)<\/a>/ig, "$3" );
}
this.insert_text( text );
}
},
undo: function()
{
this.history_record_state( this.editor_get_contents() );
this.history_time_shift( -1 );
if ( ( text = this.history_fetch_recording() ) !== false )
{
this.editor_document.value = text;
}
},
redo: function()
{
this.history_time_shift( 1 );
if ( ( text = this.history_fetch_recording() ) !== false )
{
this.editor_document.value = text;
}
},
update_for_form_submit: function(subjecttext, minchars)
{
return true;
}
});
//==============================================================================================================//
// MAIN EDITOR CODE
if( USE_RTE ){//&& !Prototype.Browser.WebKit ){ // Dont support safari
Debug.write("Extending with RTE");
_type = _editor_rte;
} else {
Debug.write("Extending with STD");
_type = _editor_std;
}
_editor.prototype.editor = Class.create(_type, {
initialize: function( editor_id, mode, initial_content, options )
{
this.id = editor_id;
this.is_rte = mode;
this.use_bbcode = !mode;
this.events = null;
this.options = [];
this.items = [];
this.settings = {};
this.open_brace = '';
this.close_brace = '';
this.allow_advanced = 0;
this.initialized = 0;
this.ips_frame_html = '';
this.forum_fix_ie_newlines = 1;
this.has_focus = null;
this.history_recordings = [];
this.history_pointer = -1;
this._ie_cache = null;
this._showing_html = false;
this._loading = false;
this.original = $H();
this.hidden_objects = [];
this.fontoptions = $A();
this.sizeoptions = $A();
this.font_state = null;
this.size_state = null;
this.palettes = {};
this.defaults = {};
this.key_handlers = [];
this.showing_sidebar = false;
this.emoticons_loaded = false;
this.emoClick = false;
this.options = Object.extend({
file_path: '',
forum_fix_ie_newlines: 1,
char_set: 'UTF-8',
ignore_controls: [],
button_update: []
}, arguments[3] || {});
this.button_update = $A( [ "bold", "italic", "underline", "justifyleft", "justifycenter",
"justifyright", "insertorderedlist", "insertunorderedlist", "superscript", "subscript", "strikethrough" ].concat( this.options.button_update ) );
this.values = ipb.editor_values; // The values for things like font list, colors etc.
this.items['text_obj'] = $( this.id + "_textarea" );
this.items['buttons'] = $A();
this.items['controls'] = $( this.id + '_controls' );
//Other configuration
this.open_brace = this.use_bbcode ? '[' : '<';
this.close_brace = this.use_bbcode ? ']' : '>';
this.allow_advanced = this.use_bbcode ? 0 : 1;
this.doc_body = $$('body')[0];
//Object.extend( this._history, _editor_history );
this.events = new _editor_events();
this._identifyType();
// Any custom BBCodes to build?
if( this.values.get('bbcodes') && $( this.id + '_cmd_otherstyles' ) ) // check for existence of other styles menu
{
this.buildCustomStyles();
}
// Lets try and find the form this belongs to, and add a submit
// event to convert the text properly
if( this.items['text_obj'].up('form') ){
this.items['text_obj'].up('form').observe( 'submit', function(e){
this.update_for_form_submit();
}.bindAsEventListener(this) );
}
this.init( initial_content );
Debug.write("All editor initialization complete");
},
/* ------------------------------ */
/**
* Initialization
*/
init: function( initial_text )
{
try {
if ( this.initialized ){
return;
}
// Set WYSIWYG flag
if( $( this.id + '_wysiwyg_used' ) ){
$( this.id + '_wysiwyg_used' ).value = parseInt( this.is_rte );
}
if( ipb.Cookie.get('emoticon_sidebar') == '1' && $( this.id + '_sidebar' ) )
{
this.buildEmoticons();
$( this.id + '_sidebar' ).show();
$( 'editor_' + this.id ).addClassName('with_sidebar');
ipb.Cookie.set( 'emoticon_sidebar', 1, 1 );
this.showing_sidebar = true;
}
// Get default frame HTML
this.ips_frame_html = this.get_frame_html();
// Set editor up
this.editor_set_content( initial_text );
// Set mouse events
this.editor_set_functions();
// Set controls up
this.editor_set_controls();
// Having this here forces the page to jump down to the editor when it loads
// which is highly undesirable. Tested STD and RTE in FF and IE8, and Safari with STd
// with this commented out and seems fine... Bug 15476
//this.editor_check_focus();
this.initialized = true;
}
catch(err){ Debug.error( "#4 " + err ); }
},
/* ------------------------------ */
/**
* Builds custom styles menu & toolbars
*/
buildCustomStyles: function()
{
var buttons = false;
var other_styles = false;
// Create the toolbar to start with
var toolbar = ipb.editor_values.get('templates')['toolbar'].evaluate( { 'id': this.id, 'toolbarid': '3' } );
$( this.id + '_toolbar_2' ).insert( { after: toolbar } );
// And init the other styles menu
this.init_editor_menu( $( this.id + '_cmd_otherstyles' ) );
this.values.get('bbcodes').each( function( bbcode ){
if( !bbcode.value['image'].blank() )
{
$( this.id + '_toolbar_3' ).insert( ipb.editor_values.get('templates')['button'].evaluate( { 'id': this.id, 'cmd': bbcode.key, 'title': bbcode.value['title'], 'img': bbcode.value['image'] } ) );
buttons = true;
}
else
{
$( this.id + '_popup_otherstyles_menu' ).insert( ipb.editor_values.get('templates')['menu_item'].evaluate( { 'id': this.id, 'cmd': bbcode.key, 'title': bbcode.value['title'] } ) );
other_styles = true;
}
if( !( bbcode.value['useoption'] == '0' && bbcode.value['single_tag'] == '1' ) )
{
var item_wrap = new Element('div', { id: this.id + '_palette_otherstyles_' + bbcode.key } );
item_wrap.addClassName('ipb_palette').addClassName('extended');
item_wrap.writeAttribute("styleid", bbcode.key);
var _content = this.values.get('templates')['generic'].evaluate( {
id: this.id + '_' + bbcode.key,
title: bbcode.value['title'],
example: bbcode.value['example'],
option_text: bbcode.value['menu_option_text'] || '',
value_text: bbcode.value['menu_content_text'] || ''
} );
item_wrap.update( _content );
this.doc_body.insert( { top: item_wrap } );
// Figure out what needs to be shown
if( bbcode.value['useoption'] == '0' ){
item_wrap.select('.optional').invoke('remove');
}
if( bbcode.value['single_tag'] == '1' ){
item_wrap.select('.tagcontent').invoke('remove');
}
this.palettes[ 'otherstyles_' + bbcode.key ] = new ipb.Menu( $( this.id + '_cmd_custom_' + bbcode.key ), item_wrap, { stopClose: true, offsetX: 0, offsetY: 42, positionSource: $( this.id + '_cmd_otherstyles' ) } );
item_wrap.down('input[type="submit"]').observe('click', this.events.handle_custom_onclick.bindAsEventListener( this ) );
}
// Set up events
$( this.id + '_cmd_custom_' + bbcode.key ).observe('click', this.events.handle_custom_command.bindAsEventListener( this, bbcode.key ));
}.bind(this));
if( buttons ){
$( this.id + '_toolbar_3' ).show();
}
if( other_styles ){
$( this.id + '_cmd_otherstyles' ).show();
}
},
/* ------------------------------ */
/**
* Resizes the content area
*/
resize_to: function( size )
{
var afterFinish = function(){};
// Bug #17799
// Opera 10 wouldn't resize the emoticon pane when the editor resize buttons were used
// Have to manually recalculate height, resize editor, then remove height
if( Prototype.Browser.Opera && $( this.id + '_emoticon_holder' ) )
{
var height = $( this.id + '_emoticon_holder' ).getHeight();
var currentSize = ( this.is_rte ) ? $( this.editor_box ).getHeight() : $( this.items['text_obj'] ).getHeight();
var diff = currentSize - size;
var newSize = height - diff;
$( this.id + '_emoticon_holder' ).setStyle('height: ' + newSize + 'px');
var afterFinish = function(e){
$( this.id + '_emoticon_holder' ).setStyle('height: auto;');
}.bind( this );
//window.opera.postError("Height: " + height + "; diff: " + diff + "; newSize: " + newSize);
}
try {
if( this.is_rte )
{
new Effect.Morph( $( this.editor_box ), { style: 'height: ' + size + 'px', duration: 0.3, afterFinish: afterFinish } );
$( this.items['text_obj'] ).setStyle( 'height: ' + size + 'px' );
}
else
{
new Effect.Morph( $( this.items['text_obj'] ), { style: 'height: ' + size + 'px', duration: 0.3, afterFinish: afterFinish } );
if( $( this.editor_box ) ){ $( this.editor_box ).setStyle( 'height: ' + size + 'px' ); }
}
} catch(err) { Debug.write( "#5 " + err ); }
},
/* ------------------------------ */
/**
* Returns HTML for the RTE frame
*/
get_frame_html: function()
{
var ips_frame_html = "";
ips_frame_html += "\n";
ips_frame_html += "\n";
ips_frame_html += "";
ips_frame_html += "\n";
if( isRTL && rtlFull )
{
ips_frame_html += "\n";
if( rtlIe && Prototype.Browser.IE )
{
ips_frame_html += "\n";
}
}
ips_frame_html += "\n";
ips_frame_html += "\n";
ips_frame_html += "{:content:}\n";
ips_frame_html += "\n";
ips_frame_html += "";
return ips_frame_html;
},
editor_check_focus: function()
{
if( this.is_rte )
{
Debug.write( "Focussing RTE" );
try {
this.editor_window.focus();
} catch(err) { Debug.write( "Could not focus editor window" ); }
}
else
{
Debug.write( "Focussing STD Textarea" );
if( !this._ie_cache )
{
this.items['text_obj'].focus();
}
}
/*if ( ! this.editor_window.has_focus ){
this.editor_window.focus();
}*/
},
editor_set_controls: function()
{
//Debug.write( $( this.id + '_controls' ).select('span') );
controls = $( this.id + '_controls' ).select('.rte_control').each( function(elem)
{
if( !elem.id ){ return; }
if( this.options.ignore_controls.include( elem.id.toLowerCase() ) ){ return; }
if( elem.hasClassName('rte_button') ){
this.init_editor_button( elem );
} else if ( elem.hasClassName( 'rte_menu' ) && !elem.hasClassName( 'rte_special') ){
this.init_editor_menu( elem ); // SKINNOTE: IE error on this line
} else if ( elem.hasClassName( 'rte_palette' ) ){
this.init_editor_palette( elem );
} else {
return;
}
this.set_control_unselectable( elem );
}.bind(this));
if( $( this.id + '_resizer' ) ){
this.init_editor_button( $( this.id + '_cmd_r_small' ) );
this.set_control_unselectable( $( this.id + '_cmd_r_small' ) );
this.init_editor_button( $( this.id + '_cmd_r_big' ) );
this.set_control_unselectable( $( this.id + '_cmd_r_big' ) );
}
},
set_button_context: function(obj, state, type)
{
//-----------------------------------------
// Showing HTML?
//-----------------------------------------
if ( this._showing_html ){
return false;
}
if ( Object.isUndefined( type ) ){
type = 'button';
}
if ( state == 'mousedown' && ( obj.readAttribute('cmd') == 'undo' || obj.readAttribute('cmd') == 'redo' ) ){
return false;
}
switch ( obj.readAttribute('state') )
{
case 'true':
{
switch (state)
{
case 'mouseout':
this.editor_set_ctl_style(obj, 'button', 'selected');
break;
case 'mouseover':
case 'mousedown':
case 'mouseup':
this.editor_set_ctl_style(obj, type, 'down');
break;
}
break;
}
default:
{
switch (state)
{
case 'mouseout':
this.editor_set_ctl_style(obj, type, 'normal');
break;
case 'mousedown':
this.editor_set_ctl_style(obj, type, 'down');
break;
case 'mouseover':
case 'mouseup':
this.editor_set_ctl_style(obj, type, 'hover');
break;
}
break;
}
}
},
editor_set_ctl_style: function( obj, type, mode )
{
if ( obj.readAttribute('mode') == mode ){ return; }
// Add in -menu class
var extra = '';
if ( type == 'menu' ){
extra = '_menu';
} else if ( type == 'menubutton' ) {
extra = '_menubutton';
}
// Add in -color if it's a color box
extra += obj.readAttribute('colorname') ? '_color' : '';
// Add in -emo if it's an emo
extra += obj.readAttribute('emo_id') ? '_emo' : '';
// Set mode...
obj.writeAttribute('mode', mode);
try
{
switch ( mode )
{
case "normal":
obj.addClassName('rte_normal' + extra).removeClassName('rte_hover').removeClassName('rte_selected');
break;
case "hover":
obj.addClassName('rte_hover' + extra ).removeClassName('rte_normal').removeClassName('rte_selected');
break;
case "selected":
case "down":
obj.addClassName('rte_selected' + extra ).removeClassName('rte_normal').removeClassName('rte_hover');
break;
}
}
catch (err)
{
Debug.write( "#6 " + err );
}
},
set_control_unselectable: function(elem)
{
if( !$(elem) ){ return; }
$( elem ).descendants().each( function(dec){
dec.writeAttribute( 'unselectable', 'on' );
});
$(elem).writeAttribute( 'unselectable', 'on' );
},
init_editor_button: function( elem )
{
// What command are we running?
elem.writeAttribute( 'cmd', elem.id.replace( this.id + '_cmd_', '' ) );
elem.writeAttribute( 'editor_id', this.id );
// Add to buttons array
this.items['buttons'][ elem.readAttribute('cmd') ] = elem;
// Set up defaults
elem.writeAttribute('state', false);
elem.writeAttribute('mode', 'normal');
elem.writeAttribute('real_type', 'button');
elem.observe( 'click', this.events.button_onmouse_event.bindAsEventListener( this ) );
elem.observe( 'mousedown', this.events.button_onmouse_event.bindAsEventListener( this ) );
elem.observe( 'mouseover', this.events.button_onmouse_event.bindAsEventListener( this ) );
elem.observe( 'mouseout', this.events.button_onmouse_event.bindAsEventListener( this ) );
},
/* ------------------------------ */
/**
* Builds a simple menu
*
* @var {element} elem The relevant element
*/
init_editor_menu: function( elem )
{
// Build the details
elem.writeAttribute( 'cmd', elem.id.replace( this.id + '_cmd_', '' ) );
elem.writeAttribute( 'editor_id', this.id );
this.items['buttons'][ elem.readAttribute('cmd') ] = elem;
// Build wrapper
var wrap = new Element('ul', { id: this.id + '_popup_' + elem.readAttribute('cmd') + '_menu' } );
wrap.writeAttribute( 'cmd', elem.readAttribute('cmd' ) ).addClassName('ipbmenu_content');
wrap.hide();
if( elem.hasClassName('rte_font') )
{
this.fontoptions[ '_default' ] = elem.innerHTML;
ipb.editor_values.get('primary_fonts').each( function(font){
var item = new Element( 'li', { 'id': this.id + '_fontoption_' + font.key } );
item.setStyle( 'font-family: "' + font.value + '"; cursor: pointer' ).addClassName('fontitem');
item.update( font.value );
$( item ).observe( 'click', this.events.font_format_option_onclick.bindAsEventListener( this ) );
wrap.insert( item );
this.fontoptions[ font.key ] = item;
}.bind(this));
elem.insert( { after: wrap } );
}
else if( elem.hasClassName('rte_fontsize') )
{
this.sizeoptions[ '_default' ] = elem.innerHTML;
ipb.editor_values.get('font_sizes').each( function( size ){
var item = new Element( 'li', { id: this.id + '_sizeoption_' + size } );
item.setStyle( 'font-size: ' + this.convert_size( size, 1 ) + 'px; cursor: pointer' ).addClassName('fontitem');
item.update( size );
$( item ).observe( 'click', this.events.font_format_option_onclick.bindAsEventListener( this ) );
wrap.insert( item );
wrap.addClassName("fontsizes");
this.sizeoptions.push( size );
}.bind(this));
elem.insert( { after: wrap } );
}
else if( elem.hasClassName('rte_special') )
{
/*ipb.editor_values.get('other_styles').each( function(style){
var item = new Element( 'li', { id: this.id + '_otherstyle_' + style.key } ).setStyle('cursor: pointer;').addClassName('specialitem');
item.update( style.value[0] );
//$( item ).observe( 'click', this.events.other_styles_onclick.bindAsEventListener( this ) );
wrap.insert( item );
// Set up palette
var item_wrap = new Element('div', {id: this.id + '_palette_other_' + style.key } );
item_wrap.hide().addClassName('ipb_palette').addClassName('extended');
item_wrap.writeAttribute("styleid", style.key);
var _content = ipb.editor_values.get('templates')['generic'].evaluate( {
id: this.id + '_' + style.key,
title: style.value[0],
example: style.value[3],
option_text: style.value[5] || '',
value_text: style.value[4] || ''
} );
item_wrap.update( _content );
item_wrap.down('input[type="submit"]').observe('click', this.events.other_styles_onclick.bindAsEventListener( this ) );
$( this.id + '_controls').insert( { bottom: item_wrap } );
if( !style.value[2] )
{
item_wrap.select('.optional').invoke('remove');
}
this.palettes[ 'otherstyles_' + style.key ] = new ipb.Menu( $( item ), item_wrap, { stopClose: true, offsetX: 50, offsetY: 50 } );
$( item ).observe('click', this.events.other_styles_preshow_onclick.bindAsEventListener( this, style.key ) );
}.bind(this));
*/
elem.insert( { after: wrap } );
}
// Init function for IE
var beforeOpen = function( menu ){
this.editor_check_focus();
this.preserve_ie_range();
Debug.write("Preserved IE Range");
}.bind(this);
// Create new menu
new ipb.Menu( $( elem ), wrap, {}, { beforeOpen: beforeOpen } );
},
/* ------------------------------ */
/**
* Builds a palette
*
* @var {element} elem The relevant element
*/
init_editor_palette: function( elem )
{
elem.writeAttribute( 'cmd', elem.id.replace( this.id + '_cmd_', '' ) );
elem.writeAttribute( 'editor_id', this.id );
this.items['buttons'][ elem.readAttribute('cmd') ] = elem;
wrap = new Element('div', { id: this.id + '_palette_' + elem.readAttribute('cmd') } );
wrap.writeAttribute( 'cmd', elem.readAttribute('cmd') ).addClassName('ipb_palette');
wrap.hide();
opt = {};
var handleReturn = false;
switch( elem.readAttribute('cmd') )
{
case 'forecolor':
case 'backcolor':
var table = new Element('table', { id: this.id + '_' + elem.readAttribute('cmd') + '_palette' }).addClassName('rte_colors');
// At this point IE would quite like you to have a tbody too
var tbody = new Element('tbody');
table.insert( tbody );
var tr = null;
var td = null;
var color = '';
for( i=0; i < ipb.editor_values.get('colors').length; i++ )
{
color = ipb.editor_values.get('colors')[i];
if( i % ipb.editor_values.get('colors_perrow') == 0 ){
tr = new Element('tr');
tbody.insert( tr );
}
td = new Element('td', { id: this.id + '_' + elem.readAttribute('cmd') + '_color_' + color } );
td.setStyle('background-color: #' + color).setStyle('background-image: none').writeAttribute('colorname', color);
tr.insert( td );
// Events
$( td ).observe('click', this.events.color_cell_onclick.bindAsEventListener( this ) );
}
wrap.insert( table ).addClassName('color_palette');
elem.insert( { after: wrap } );
break;
/*case 'emoticons':
if( Object.isUndefined( ipb.editor_values.get('emoticons') ) )
{
elem.hide();
return;
}
/*var table = new Element( 'ul', { id: this.id + '_emoticons_palette' } ).addClassName('rte_emoticons');
var perrow = 10;
var row = null;
var i = 0;
ipb.editor_values.get('emoticons').each( function(emote){
var _tmp = emote.value.split(',');
var img = new Element('img', { id: 'smid_' + _tmp[0], src: ipb.vars['emoticon_url'] + '/' + _tmp[1] } );
var li = new Element('li', { id: this.id + '_emoticons_emote_' + _tmp[0] } ).setStyle('').addClassName('emote');
li.writeAttribute('emo_id', _tmp[0] );
li.writeAttribute('emo_img', _tmp[1] );
li.writeAttribute('emo_code', emote.key);
table.insert( li.insert( img ) );
$( li ).observe('click', this.events.emoticon_onclick.bindAsEventListener( this ) );
}.bind(this));
//-------------
var table = new Element( 'table', { id: this.id + '_emoticons_palette' } ).addClassName('rte_emoticons');
// Same as before, tbody please, says IE
var tbody = new Element('tbody');
table.insert( tbody );
var tr = null;
var td = null;
var perrow = 10;
var i = 0;
//Debug.write( ipb.editor_values.get('emoticons') );
ipb.editor_values.get('emoticons').each( function(emote){
if( i % perrow == 0 )
{
tr = new Element( 'tr' );
tbody.insert( tr );
}
i++;
var _tmp = emote.value.split(',');
var img = new Element('img', { id: 'smid_' + _tmp[0], src: ipb.vars['emoticon_url'] + '/' + _tmp[1] } );
td = new Element('td', { id: this.id + '_emoticons_emote_' + _tmp[0] } ).setStyle('cursor: pointer; text-align: center').addClassName('emote');
td.writeAttribute('emo_id', _tmp[0] );
td.writeAttribute('emo_img', _tmp[1] );
td.writeAttribute('emo_code', emote.key);
td.insert( img );
tr.insert( td );
$( td ).observe('click', this.events.emoticon_onclick.bindAsEventListener( this ) );
}.bind(this));
// IE sucks
if( Prototype.Browser.IE )
{
var tmpdiv = new Element( 'div' ).setStyle('overflow-x: scroll');
wrap.insert( tmpdiv.insert( table ) ).addClassName('emoticons_palette');
elem.insert( { after: wrap } );
}
else
{
wrap.insert( table ).addClassName('emoticons_palette');
elem.insert( { after: wrap } );
}
if( this.values.get('show_emoticon_link') )
{
var emote_link = this.values.get('templates')['emoticons_showall'].evaluate( { id: this.id } );
wrap.insert( { bottom: emote_link } );
$( this.id + '_all_emoticons' ).observe( 'click', this.events.show_emoticon_sidebar.bindAsEventListener( this ) );
}
break;*/
case 'link':
case 'image':
case 'email':
case 'media':
if( Object.isUndefined( ipb.editor_values.get('templates')[ elem.readAttribute('cmd') ] ) )
{
elem.hide();
return;
}
try {
wrap.update( ipb.editor_values.get('templates')[ elem.readAttribute('cmd') ].evaluate( { id: this.id } ) );
wrap.down('input[type="submit"]').observe('click', this.events.palette_submit.bindAsEventListener( this ) );
} catch( err ) { Debug.write("#7 " + err); }
this.doc_body.insert( { top: wrap } );
if( elem.readAttribute('cmd') == 'link' )
{
try {
this.defaults['link_text'] = $F( this.id + '_urltext' );
this.defaults['link_url'] = $F( this.id + '_url' );
} catch( err ){ Debug.write( "#8 " + err ); }
$( elem ).observe('click', this.events.link_onclick.bindAsEventListener( this ) );
}
if( elem.readAttribute('cmd') == 'image' )
{
try {
this.defaults['img'] = $F( this.id + '_img' );
} catch( err ){ Debug.write( "#15 " + err ); }
$( elem ).observe('click', this.events.image_onclick.bindAsEventListener( this ) );
}
if( elem.readAttribute('cmd') == 'email' )
{
try {
this.defaults['email_text'] = $F( this.id + '_emailtext' );
this.defaults['email'] = $F( this.id + '_email' );
} catch( err ){ Debug.write( "#8 " + err ); }
$( elem ).observe('click', this.events.email_onclick.bindAsEventListener( this ) );
}
if( elem.readAttribute('cmd') == 'media' )
{
try {
this.defaults['media'] = $F( this.id + '_media' );
} catch( err ){ Debug.write( "#17 " + err ); }
$( elem ).observe('click', this.events.media_onclick.bindAsEventListener( this ) );
}
this.key_handlers[ elem.readAttribute('cmd') ] = false;
break;
default:
this.items['buttons'][ elem.readAttribute( 'cmd' ) ] = null;
elem.hide(); // Hide since we dont know what to do with it
wrap.remove();
break;
}
// Insert title
if( elem.readAttribute('title' ) )
{
title = new Element( 'div' );
title.update( elem.readAttribute('title') ).addClassName('rte_title');
wrap.insert( { top: title } );
}
if( !elem.readAttribute('cmd').endsWith('color') ){
opt = { stopClose: true };
}
$( elem ).observe('mouseover', this.events.palette_button_onmouseover.bindAsEventListener( this ) );
$( elem ).observe('mouseover', this.events.palette_onmouse_event.bindAsEventListener( this ) );
$( elem ).observe('mouseout', this.events.palette_onmouse_event.bindAsEventListener( this ) );
// Init function for IE
var beforeOpen = function( menu ){
this.editor_check_focus();
this.preserve_ie_range();
Debug.write("Preserved IE Range");
}.bind(this);
//this.doc_body.insert( wrap.setStyle('position: absolute; top:0px; left:0px;') );
this.palettes[ elem.readAttribute('cmd') ] = new ipb.Menu( $( elem ), wrap, opt, { beforeOpen: beforeOpen } );
},
convert_size: function( size, type )
{
if( type == 1 )
{
switch( size )
{
case 1:
return 9;
break;
case 2:
return 13;
break;
case 3:
return 15;
break;
case 4:
return 17;
break;
case 5:
return 21;
break;
case 6:
return 26;
break;
case 7:
return 36;
break;
default:
return 13;
}
} else {
switch( size )
{
case '7.5pt':
case '9px': return 1;
case '13px': return 2;
case '15px': return 3;
case '17px': return 4;
case '21px': return 5;
case '26px': return 6;
case '36px': return 7;
default: return '';
}
}
},
format_text: function( e, command, arg )
{
// Check for special commands
if( command.startsWith( 'resize_' ) ){
//
}
if( command == 'switcheditor' ){
try {
ipb.switchEditor( this.id );
} catch(err) {
Debug.error( "#9 " + err );
}
}
// Recording state?
if ( ! this.is_rte && command != 'redo' ){
this.history_record_state( this.editor_get_contents() );
}
this.editor_check_focus();
// Execute command
if ( this[ command ] )
{
var return_val = this[ command ](e);
}
else
{
try
{
/*Debug.write( "In format text, selection is: " + this.get_selection() );*/
var return_val = this.apply_formatting( command, false, (typeof arg == 'undefined' ? true : arg) );
}
catch(e)
{
Debug.warn( "#10 " + e );
var return_val = false;
}
}
// Recording state
if ( ! this.is_rte && command != 'undo' ){
this.history_record_state( this.editor_get_contents() );
}
// Set context
this.set_context(command);
// Check focus
this.editor_check_focus();
return return_val;
},
spellcheck: function()
{
// Only IE can use this
if( !Prototype.Browser.IE ){ return; }
try {
if ( this.rte_mode ){
var tmpis = new ActiveXObject("ieSpell.ieSpellExtension").CheckDocumentNode( this.editor_document );
} else {
var tmpis = new ActiveXObject("ieSpell.ieSpellExtension").CheckAllLinkedDocuments( this.editor_document );
}
} catch( exception ) {
if ( exception.number == -2146827859 ) {
if ( confirm( ipb.lang['js_rte_erroriespell'] ? ipb.lang['js_rte_erroriespell'] : "ieSpell не обнаружен. Нажмите Ок для сохранения страницы." ) )
{
window.open("http://www.iespell.com/download.php", "Download");
}
}
else
{
alert( ipb.lang['js_rte_errorloadingiespell'] ? ipb.lang['js_rte_errorloadingiespell'] : "Ошибка при загрузке ieSpell: Exception " + exception.number);
}
}
},
wrap_tags: function(tag_name, has_option, selected_text)
{
//-----------------------------------------
// Fix up for HTML use
//-----------------------------------------
var tag_close = tag_name;
if ( ! this.use_bbcode )
{
switch( tag_name )
{
case 'url':
tag_name = 'a href';
tag_close = 'a';
break;
case'email':
tag_name = 'a href';
tag_close = 'a';
has_option = 'mailto:' + has_option;
break;
case 'img':
tag_name = 'img src';
tag_close = '';
break;
case 'font':
tag_name = 'font face';
tag_close = 'font';
break;
case 'size':
tag_name = 'font size';
tag_close = 'font';
break;
case 'color':
tag_name = 'font color';
tag_close = 'font';
break;
case 'background':
tag_name = 'font bgcolor';
tag_close = 'font';
break;
case 'indent':
tag_name = tag_close = 'blockquote';
break;
case 'left':
case 'right':
case 'center':
has_option = tag_name;
tag_name = 'div align';
tag_close = 'div';
break;
}
}
//-----------------------------------------
// Got selected text?
//-----------------------------------------
if ( Object.isUndefined( selected_text ) )
{
selected_text = this.get_selection();
selected_text = (selected_text === false) ? '' : new String(selected_text);
}
//-----------------------------------------
// Using option?
//-----------------------------------------
if ( has_option === true )
{
var option = prompt( ips_language_arrayp['js_rte_optionals'] ? ips_language_arrayp['js_rte_optionals'] : "Введите аттрибуты для данного тега", '');
if ( option )
{
var opentag = this.open_brace + tag_name + '="' + option + '"' + this.close_brace;
}
else
{
return false;
}
}
else if ( has_option !== false )
{
var opentag = this.open_brace + tag_name + '="' + has_option + '"' + this.close_brace;
}
else
{
var opentag = this.open_brace + tag_name + this.close_brace;
}
var closetag = ( tag_close != '' ) ? this.open_brace + '/' + tag_close + this.close_brace : '';
var text = opentag + selected_text + closetag;
//Debug.write( text );
/*Debug.write("Wrap tags selection is: " + this.get_selection() );*/
this.insert_text( text );
return false;
},
/* ! wrap_tags_lite */
wrap_tags_lite: function( start_text, close_text, replace_selection )
{
selected_text = '';
if( Object.isUndefined( replace_selection ) || replace_selection == 0 )
{
// Got selected text?
selected_text = this.get_selection();
selected_text = (selected_text === false) ? '' : new String(selected_text);
}
this.insert_text( start_text + selected_text + close_text );
return false;
},
/* ! preserve_ie_range */
preserve_ie_range: function()
{
if ( Prototype.Browser.IE && document.selection && ! this.emoClick )
{
/* Don't preserve range for emoticon click. It buggers things up epically */
this._ie_cache = this.is_rte ? ( this.editor_document.selection.createRange ) ? this.editor_document.selection.createRange() : null : document.selection.createRange();
Debug.write( "Preserved IE Range: ");
this.emoClick = false;
}
},
clean_html: function( t )
{
if ( t.blank() || Object.isUndefined(t) )
{
return t;
}
// Sort out BR tags
t = t.replace( /
/ig, "
");
// Remove empty tags
t = t.replace( /
(\s+?)?<\/p>/ig, "");
// HR issues
t = t.replace( /
<\/p>/ig , "
");
t = t.replace( / <\/p>
<\/p>/ig, "
");
// Attempt to fix some formatting issues...
t = t.replace( /<(p|div)([^&]*)>/ig , "\n<$1$2>\n" );
t = t.replace( /<\/(p|div)([^&]*)>/ig , "\n$1$2>\n");
t = t.replace( /
(?!<\/td)/ig , "
\n" );
// And some table issues...
t = t.replace( /<\/(td|tr|tbody|table)>/ig , "$1>\n");
t = t.replace( /<(tr|tbody|table(.+?)?)>/ig , "<$1>\n" );
t = t.replace( /<(td(.+?)?)>/ig , "\t<$1>" );
// Newlines
t = t.replace( / <\/p>/ig , "
");
t = t.replace( /
/ig , "
\n");
t = t.replace( /
/ig , "
\n");
t = t.replace( /
\n<\/td>/ig , " |
| " );
// Script tags
t = t.replace( /