Version 3.3.4

This commit is contained in:
Neo committed 2025-12-19 00:35:52 -08:00
1 parent 78706903a2
commit fb6b5baabc
2206 files changed
+409828 -382984

No files matched your search

+367 -78
View File
@@ -4,6 +4,84 @@
* (c) 2011 IPS, Inc.
*/
ipsTextArea = {
/**
* Insert text at the cursor position
* Some code from
* @link http://bytes.com/topic/javascript/answers/149268-moving-cursor-end-textboxes-text
* @param editorId
* @param text
*/
insertAtCursor: function( editorId, text )
{
var te = $('cke_' + editorId).down('textarea');
var scrollPos = te.scrollTop;
if ( CKEDITOR.env.ie )
{
te.focus();
sel = document.selection.createRange();
sel.text = text;
sel.select();
}
else if ( te.selectionStart || te.selectionStart == '0' )
{
var startPos = te.selectionStart;
var endPos = te.selectionEnd;
te.value = te.value.substring(0, startPos) + text + te.value.substring(endPos, te.value.length);
if ( startPos == endPos )
{
this.setSelectionRange( te, startPos + text.length, endPos + text.length );
}
else
{
this.setCaretToPos( te, startPos + text.length );
}
}
else
{
te.value += text;
}
te.scrollTop = scrollPos;
},
/**
* Set selection range
* Some code from
* @link http://bytes.com/topic/javascript/answers/149268-moving-cursor-end-textboxes-text
*/
setSelectionRange: function(input, selectionStart, selectionEnd)
{
if ( input.setSelectionRange )
{
input.focus();
input.setSelectionRange(selectionStart, selectionEnd);
}
else if ( input.createTextRange )
{
var range = input.createTextRange();
range.collapse(true);
range.moveEnd('character', selectionEnd);
range.moveStart('character', selectionStart);
range.select();
}
},
/**
* Set caret position
* Some code from
* @link http://bytes.com/topic/javascript/answers/149268-moving-cursor-end-textboxes-text
*/
setCaretToPos: function( input, pos )
{
this.setSelectionRange( input, pos, pos );
}
}
IPSCKTools = {
/**
* Get the selected HTML from the editor
@@ -16,7 +94,10 @@ IPSCKTools = {
if ( CKEDITOR.env.ie )
{
try {
selection.unlock(true);
if ( ! Prototype.Browser.IE8 )
{
selection.unlock(true);
}
} catch(e){}
var text = selection.getNative().createRange().htmlText;
@@ -51,13 +132,32 @@ IPSCKTools = {
* Clean HTML for inserting between tags
* @param object
*/
cleanHtmlForTagWrap: function( html )
cleanHtmlForTagWrap: function( html, convert )
{
var text = html.replace( /<br( \/)?>$/, '' );
var text = ( typeof( html ) != 'undefined' ) ? html.replace( /<br( \/)?>$/, '' ) : '';
/* The text may have become double encoded */
if ( convert )
{
text = text.replace( /&lt;/g , '<' );
text = text.replace( /&gt;/g , '>' );
text = text.replace( /&amp;/g , '&' );
text = text.replace( /&#39;/g , "'" );
text = text.replace( /&quot;/g, '"' );
}
return text;
},
/**
* Remove HTML formatting
* @param string
*/
stripHtmlTags: function( html )
{
return html.stripTags();
}
}
};
/*
* This is just a wrapper class around the objects to give it a global interface
@@ -66,6 +166,7 @@ IPBoard.prototype.textEditor = {
mainStore: $H(),
lastSetUp: null,
htmlCheckbox: $H(),
_tmpContent: '',
IPS_TEXTEDITOR_POLLING: 10000, /* 10 seconds */
IPS_NEW_POST_POLLING: (2 * 60000), /* 2 mins */
@@ -99,26 +200,98 @@ IPBoard.prototype.textEditor = {
ipb.textEditor.lastSetUp = editorId;
},
/**
* Bind a HTML checkbox to the toggle stuffs
*/
bindHtmlCheckbox: function( elem, editorId )
{
editorId = ( editorId ) ? editorId : ipb.textEditor.getEditor().editorId;
if ( $( elem ) )
{
ipb.textEditor.htmlCheckbox[ editorId ] = $( elem );
$( elem ).writeAttribute( 'data-editorId', editorId );
$( elem ).observe('change', ipb.textEditor.htmlModeToggled.bindAsEventListener( this, $( elem ) ) );
}
},
/**
* HTML mode has been toggled so we force STD mode
*/
htmlModeToggled: function( e, elem )
{
textObj = ipb.textEditor.getEditor( $( elem ).readAttribute( 'data-editorId' ) );
isRte = textObj.isRte();
button = $( 'cke_' + textObj.editorId ).down('.cke_button_ipsswitch');
if ( elem.checked )
{
$('editor_html_message_' + textObj.editorId).show();
if ( isRte )
{
button.hide();
ipb.textEditor.switchEditor(true, textObj.editorId);
}
else
{
button.hide();
}
}
else
{
$('editor_html_message_' + textObj.editorId).hide();
if ( ! button.visible() )
{
button.show();
}
}
},
/**
* Switches an editor from rte to std or vice-versa
*/
switchEditor: function()
switchEditor: function( noSaveChange, editorId )
{
textObj = ipb.textEditor.getEditor();
isRte = textObj.isRte();
ourcontent = textObj.getText();
editorId = ( editorId ) ? editorId : ipb.textEditor.getEditor().editorId;
textObj = ipb.textEditor.getEditor( editorId );
isRte = textObj.isRte();
ourcontent = textObj.getText();
saveCookie = ( noSaveChange ) ? false : true;
htmlOps = null;
noSmilies = 0;
if ( $( 'noSmilies_' + editorId ) )
{
noSmilies = parseInt( $F( 'noSmilies_' + editorId ) );
}
if ( $( ipb.textEditor.htmlCheckbox[ editorId ] ) )
{
htmlOps = ( ipb.textEditor.htmlCheckbox[ editorId ].checked ) ? 1 : 0;
}
var _url = ipb.textEditor.ajaxUrl + '&app=core&module=ajax&section=editor&do=switch&secure_key=' + ipb.vars['secure_hash'];
if ( htmlOps !== null )
{
_url += '&htmlStatus=' + htmlOps;
}
Debug.write( _url );
Debug.write( 'Fetched editor content: ' + ourcontent );
new Ajax.Request( _url,
{
method: 'post',
parameters: { 'content' : ourcontent.encodeParam(),
'isRte' : isRte },
parameters: { 'content' : ourcontent.encodeParam(),
'isRte' : isRte,
'noSmilies' : noSmilies },
onSuccess: function(t)
{
{
/* No Permission */
if ( t.responseText != 'nopermission' )
{
@@ -128,23 +301,27 @@ IPBoard.prototype.textEditor = {
if ( textObj.isRte() )
{
/* Reset flag */
textObj.setIsRte( false );
textObj.setIsRte( false, noSaveChange );
/* Hackery! Passing t.responseText through to .setData doesn't allow html entities to parse in the text area
* literally, if you pass &#123; it will show &#123; - not good.
*/
$$('body').first().insert( new Element( 'code', { 'class': 'hide', 'id': 'xx-new-contents-xx' } ).update( t.responseText ) );
/* Can it sister */
textObj.CKEditor.setMode( 'source' );
textObj.insert( $('xx-new-contents-xx').innerHTML, false, true );
$('xx-new-contents-xx').remove();
/* Update */
$( textObj.editorId ).value = ipb.textEditor.stdPre( t.responseText );
ipb.Cookie.set( 'rteStatus', 'std' );
try
{
Debug.write( $F( textObj.editorId ) );
textObj.CKEditor.setData( $F( textObj.editorId ) );
}
catch( err )
{
Debug.write( "CKEditor error: " + err );
}
/* Update all other editors */
ipb.textEditor.toggleEditors( 'std' );
if ( saveCookie )
{
ipb.Cookie.set( 'rteStatus', 'std' );
}
/* Update text-direction, since CKE forces LTR in 'source' mode */
if( isRTL )
@@ -153,11 +330,21 @@ IPBoard.prototype.textEditor = {
$(elem).setStyle( { textAlign: 'right' } );
});
}
if ( $('cke_' + textObj.editorId + '_stray') )
{
$('cke_' + textObj.editorId + '_stray').remove();
if ( $('ips_x_smile_show_all') )
{
$('ips_x_smile_show_all').remove();
}
}
}
else
{
/* Reset flag */
textObj.setIsRte( true );
textObj.setIsRte( true, noSaveChange );
try
{
@@ -171,10 +358,10 @@ IPBoard.prototype.textEditor = {
/* Init editor */
textObj.CKEditor.setMode( 'wysiwyg' );
ipb.Cookie.set( 'rteStatus', 'rte' );
/* Update all other editors */
ipb.textEditor.toggleEditors( 'rte' );
if ( saveCookie )
{
ipb.Cookie.set( 'rteStatus', 'rte' );
}
}
}
}.bind(this),
@@ -192,18 +379,36 @@ IPBoard.prototype.textEditor = {
*/
toggleEditors: function( mode )
{
return false;
/* We no longer use this as it doesn't ping ajax to convert! */
ipb.textEditor.mainStore.each( function( instance ){
if( instance.key != ipb.textEditor.lastSetUp )
{
if( mode == 'std' )
_editor = ipb.textEditor.getEditor( instance.key );
if ( ! _editor.options.isHtml )
{
instance.value.setIsRte( false );
instance.value.CKEditor.setMode( 'source' );
}
else
{
instance.value.setIsRte( true );
instance.value.CKEditor.setMode( 'wysiwyg' );
if( mode == 'std' )
{
instance.value.setIsRte( false );
instance.value.CKEditor.setMode( 'source' );
if ( $('cke_' + _editor.editorId + '_stray') )
{
$('cke_' + _editor.editorId + '_stray').remove();
if ( $('ips_x_smile_show_all') )
{
$('ips_x_smile_show_all').remove();
}
}
}
else
{
instance.value.setIsRte( true );
instance.value.CKEditor.setMode( 'wysiwyg' );
}
}
}
});
@@ -225,9 +430,12 @@ IPBoard.prototype.textEditor = {
*/
getCurrentEditorId: function()
{
if( Object.isUndefined( CKEDITOR ) ){
if ( typeof(CKEDITOR) == 'undefined' || Object.isUndefined( CKEDITOR ) )
{
return ipb.textEditor.lastSetUp;
} else {
}
else
{
if ( CKEDITOR.currentInstance && ipb.textEditor.mainStore.get( CKEDITOR.currentInstance.name ).CKEditor )
{
return CKEDITOR.currentInstance.name;
@@ -272,9 +480,12 @@ IPBoard.prototype.textEditor = {
/* Properly encoded HTML &amp;#39; isn't parsed in the text area */
text = text.replace( /&amp;/g, '&' );
text = text.replace( /<br([^>]+?)?>(\n)?/g, '\n' );
if ( ! $(ipb.textEditor.htmlCheckbox) || ! $(ipb.textEditor.htmlCheckbox).checked )
{
//text = text.replace( /<br([^>]+?)?>(\n)?/g, '\n' );
}
return text;
},
@@ -315,14 +526,32 @@ IPBoard.prototype.textEditorObjects = Class.create( {
minimize: 0,
minimizeNowOpen: 0,
isRte: 1,
isHtml: 0,
bypassCKEditor: 0,
isTypingCallBack: false,
delayInit: false,
noSmilies: false,
ips_AutoSaveData: {},
ips_AutoSaveTemplate: new Template( ipb.textEditor.IPS_AUTOSAVETEMPLATE ) }, arguments[1] );
/* Do we have an override? */
this.setIsRte( this.cookie == 'rte' ? 1 : ( this.cookie == 'std' ? 0 : 1 ) );
/* Force */
if ( this.options.type == 'ipsacp' )
{
this.setIsRte( true );
}
else if ( this.options.isRte == 0 )
{
this.setIsRte( false );
}
else if ( this.options.isRte == 1 )
{
this.setIsRte( true );
}
else
{
/* Do we have an override? */
this.setIsRte( this.cookie == 'rte' ? 1 : ( this.cookie == 'std' ? 0 : 1 ) );
}
/* Force STD if iDevice */
if ( ipb.vars['is_touch'] !== false )
@@ -341,16 +570,22 @@ IPBoard.prototype.textEditorObjects = Class.create( {
/**
* Set RTe status of current editor
*/
setIsRte: function( value )
setIsRte: function( value, noSaveChange )
{
this.options.isRte = ( value ) ? 1 : 0;
value = ( value ) ? 1 : 0;
saveCookie = ( noSaveChange ) ? false : true;
/* Set cookie */
ipb.Cookie.set( 'rteStatus', ( value ) ? 'rte' : 'std' );
this.options.isRte = value;
if ( $( 'isRte_' + this.editorId ) )
{
$F( 'isRte_' + this.editorId ) = this.options.isRte;
$( 'isRte_' + this.editorId ).value = value;
}
/* Set cookie */
if ( saveCookie )
{
ipb.Cookie.set( 'rteStatus', ( value ) ? 'rte' : 'std', 1 );
}
},
@@ -366,21 +601,23 @@ IPBoard.prototype.textEditorObjects = Class.create( {
* Fetch editor contents
*/
getText: function()
{
{
var val = '';
if ( ! this.options.bypassCKEditor && this.CKEditor )
{
return this.CKEditor.getData();
val = this.CKEditor.getData();
}
else
{
/* If CKEditor isn't beingn used (iOS, etc) */
if( $( this.editorId ) )
{
return $( this.editorId ).value;
val = $( this.editorId ).value;
}
return '';
}
return val;
},
/**
@@ -409,14 +646,18 @@ IPBoard.prototype.textEditorObjects = Class.create( {
{
$( this.editorId ).value = ipb.textEditor.ckPre( $( this.editorId ).value );
}
else
{
$( this.editorId ).value = ipb.textEditor.stdPre( $( this.editorId ).value );
}
/* RTE init */
try
{
var config = {
toolbar: ( this.options.type == 'mini' ? 'ipsmini' : 'ipsfull' ),
toolbar: ( this.options.type == 'ipsacp' ) ? 'ipsacp' : ( this.options.type == 'mini' ? 'ipsmini' : 'ipsfull' ),
height: ( Object.isNumber( this.options.height ) && this.options.height > 0 ) ? this.options.height : ( this.options.type == 'mini' ? 150 : 300 ),
ips_AutoSaveKey: this.options.ips_AutoSaveKey
ips_AutoSaveKey: this.options.ips_AutoSaveKey
};
/* STD editor? */
@@ -454,23 +695,26 @@ IPBoard.prototype.textEditorObjects = Class.create( {
/* Quickly make some changes if minimized */
if ( this.options.minimize )
{
$('cke_top_' + this.editorId ).down('.cke_toolbox_collapser').hide();
$('cke_bottom_' + this.editorId ).hide();
$('cke_' + this.editorId ).down('.cke_wrapper').addClassName('minimized');
if ( ! this.isRte() )
try
{
$('cke_' + this.editorId ).down('.cke_wrapper').addClassName('std');
}
else
{
/* IE bug when clicking the text editor to expand and it also registers a toolbar click*/
if ( Prototype.Browser.IE9 )
$('cke_top_' + this.editorId ).down('.cke_toolbox_collapser').hide();
$('cke_bottom_' + this.editorId ).hide();
$('cke_' + this.editorId ).down('.cke_wrapper').addClassName('minimized');
if ( ! this.isRte() )
{
$('cke_top_' + this.editorId ).down('.cke_toolbox').setStyle( { 'position': 'absolute', 'left': '-2000px' } );
$('cke_' + this.editorId ).down('.cke_wrapper').addClassName('std');
}
}
else
{
/* IE bug when clicking the text editor to expand and it also registers a toolbar click*/
if ( Prototype.Browser.IE9 )
{
$('cke_top_' + this.editorId ).down('.cke_toolbox').setStyle( { 'position': 'absolute', 'left': '-2000px' } );
}
}
}catch(e){}
ev.editor.on('focus', function()
{
@@ -543,6 +787,32 @@ IPBoard.prototype.textEditorObjects = Class.create( {
$(elem).setStyle( { textAlign: 'right' } );
});
}
/* Is HTML? */
if ( this.options.isHtml == 1 )
{
if ( Object.isUndefined( ipb.textEditor.htmlCheckbox[ this.editorId ] ) || ipb.textEditor.htmlCheckbox[ this.editorId ] == null )
{
$('cke_' + this.editorId ).insert( new Element( 'input', { type: 'checkbox', id: 'cbx_' + this.editorId, checked: true } ).hide() );
ipb.textEditor.bindHtmlCheckbox( $('cbx_' + this.editorId ), this.editorId );
}
$( ipb.textEditor.htmlCheckbox[ this.editorId ] ).checked = true;
}
/* HTML checkbox checked? */
if ( $( ipb.textEditor.htmlCheckbox[ this.editorId ] ) )
{
/* Check status of HTML checkbox on load */
ipb.textEditor.htmlModeToggled( this, ipb.textEditor.htmlCheckbox[ this.editorId ] );
}
if ( this.options.noSmilies )
{
$('cke_top_' + this.editorId ).down('.cke_button_ipsemoticon').up('.cke_button').hide();
}
}
}.bind(this) );
},
@@ -752,15 +1022,30 @@ IPBoard.prototype.textEditorObjects = Class.create( {
if ( this.options.minimize == 1 && this.options.minimizeNowOpen != 1 )
{
/* Scroll to editor when it loads? */
if( scrollOnInit )
if ( scrollOnInit )
{
$( this.editorId ).scrollTo();
}
this.showEditor();
}
else
{
/* Scroll always? */
if ( scrollOnInit === 'always' )
{
if ( this.options.bypassCKEditor != 1 )
{
$( 'cke_' + this.editorId ).scrollTo();
}
else
{
$( this.editorId ).scrollTo();
}
}
}
if ( ! this.options.bypassCKEditor )
if ( this.options.bypassCKEditor != 1 )
{
if ( this.isRte() )
{
@@ -778,7 +1063,8 @@ IPBoard.prototype.textEditorObjects = Class.create( {
}
else
{
this.CKEditor.setData( this.CKEditor.getData() + ipb.textEditor.stdPre( content ) );
ipsTextArea.insertAtCursor( this.editorId, ipb.textEditor.stdPre( content ) );
//this.CKEditor.setData( this.CKEditor.getData() + ipb.textEditor.stdPre( content ) );
}
}
else
@@ -789,10 +1075,10 @@ IPBoard.prototype.textEditorObjects = Class.create( {
}
else
{
$( this.editorId ).value = content;
$( this.editorId ).value += content;
}
},
/**
* Show any display data we might have
@@ -819,7 +1105,7 @@ IPBoard.prototype.textEditorObjects = Class.create( {
var sd = this.options.ips_AutoSaveData;
if ( sd.key )
{
{
html = this.options.ips_AutoSaveTemplate.evaluate( sd );
if ( $('cke_' + this.editorId ).down('.cke_bottom').select('.cke_path').length < 1 )
@@ -892,7 +1178,7 @@ IPBoard.prototype.textEditorObjects = Class.create( {
if ( this.isRte() )
{
setTimeout( function() { this.CKEditor.setData( ipb.textEditor.ckPre( this.options.ips_AutoSaveData.restore_rte ) ); }.bind(this), 500 );
setTimeout( function() { this.CKEditor.setData( ipb.textEditor.ckPre( this.options.ips_AutoSaveData.restore_rte.replace( /&amp;/g, '&' ) ) ); }.bind(this), 500 );
}
else
{
@@ -929,7 +1215,7 @@ IPBoard.prototype.textEditorObjects = Class.create( {
onSuccess: function(t)
{
/* No Permission */
if ( t.responseJSON && t.responseJSON['status'] == 'ok' )
if ( t.responseJSON && ( t.responseJSON['status'] == 'ok' || t.responseJSON['status'] == 'nothingToSave' ) )
{
/* Reset 'dirty' */
editor.resetDirty();
@@ -937,7 +1223,10 @@ IPBoard.prototype.textEditorObjects = Class.create( {
/* No longer busy */
command.setState( CKEDITOR.TRISTATE_OFF );
this.updateSaveMessage();
if ( t.responseJSON['status'] == 'ok' )
{
this.updateSaveMessage();
}
}
}.bind(this)
} );