/************************************************/ /* 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, "&sect"); } } //----------------------------------------- // 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.unhtmlspecialchars( emo_code ) + ''; 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. ([^>]*)<\/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 not detected. Click Ok to go to download page." ) ) { window.open("http://www.iespell.com/download.php", "Download"); } } else { alert( ipb.lang['js_rte_errorloadingiespell'] ? ipb.lang['js_rte_errorloadingiespell'] : "Error Loading 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'] : "Enter the optional arguments for this tag", ''); 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\n"); t = t.replace( /
    (?!<\/td)/ig , "
    \n" ); // And some table issues... t = t.replace( /<\/(td|tr|tbody|table)>/ig , "\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( /