Author: Garak
Modification Description:: Integrate TinyMCE WYSIWYG editor in the posting textarea.
Modification Version:: 0.4.3
Requirements: TinyMCE 3.2.0.2 or above
Screenshots: example screenshot (sorry it's in italian)
New!: since 0.2 version, font size is working properly
Instructions
1 - download TinyMCE (Note: this MOD was tested with version 3.2.0.2, any later 3.2.X version should work). Optional: download language pack for a localized version (in this case, please notice comments inside config file at step 5)
2 - unzip tiny_mce directory (Note: it's NOT the main directory) under styles/prosilver/template/
So, you should have a directory named styles/prosilver/template/tiny_mce (Note: this mod could work with other themes also, but it's untested)
3 - open file styles/prosilver/template/tiny_mce/plugins/bbcode/editor_plugin.js and replace its content with the following
- Code: Select all
-
/**
* $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $
*
* @author Moxiecode
* @author Garak [email protected]
* @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
*/
(function() {
tinymce.create('tinymce.plugins.BBCodePlugin', {
init : function(ed, url) {
var t = this, dialect = ed.getParam('bbcode_dialect', 'punbb').toLowerCase();
ed.onBeforeSetContent.add(function(ed, o) {
o.content = t['_' + dialect + '_bbcode2html'](o.content);
});
ed.onPostProcess.add(function(ed, o) {
if (o.set)
o.content = t['_' + dialect + '_bbcode2html'](o.content);
if (o.get)
o.content = t['_' + dialect + '_html2bbcode'](o.content);
});
},
getInfo : function() {
return {
longname : 'BBCode Plugin',
author : 'Moxiecode Systems AB',
authorurl : 'http://tinymce.moxiecode.com',
infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/bbcode',
version : tinymce.majorVersion + "." + tinymce.minorVersion
};
},
// Private methods
// HTML -> BBCode in PunBB dialect
_punbb_html2bbcode : function(s) {
s = tinymce.trim(s);
function rep(re, str) {
s = s.replace(re, str);
};
// example: <strong> to [b]
rep(/<a.*?href=\"(.*?)\".*?>(.*?)<\/a>/gi,"[url=$1]$2[/url]");
rep(/<blockquote><div><cite><\/cite>(.*?)<\/div><\/blockquote>/gi,"[quote]$1[/quote]");
rep(/<blockquote><div><cite>(.*?) wrote:<\/cite>(.*?)<\/div><\/blockquote>/gi,"[quote=\"$1\"]$2[/quote]");
rep(/<span style=\"color: ?(.*?);\">(.*?)<\/span>/gi,"[color=$1]$2[/color]");
rep(/<font.*?color=\"(.*?)\".*?>(.*?)<\/font>/gi,"[color=$1]$2[/color]");
// font size
rep(/<span.*?style=\"font-size: (\d{2,3})%;\">(.*?)<\/span>/gi,"[size=$1]$2[/size]");
rep(/<span style=\"font-size: (\d{2,3})%; color: ?(.*?);\">(.*?)<\/span>/gi,"[size=$1][color=$2]$3[/color][/size]");
rep(/<font>(.*?)<\/font>/gi,"$1");
// emoticons
rep(/<img.*?src=\"images\/smilies\/icon_e_biggrin\.gif\".*?\/>/gi,":-D");
rep(/<img.*?src=\"images\/smilies\/icon_e_smile\.gif\".*?\/>/gi,":-)");
rep(/<img.*?src=\"images\/smilies\/icon_e_wink\.gif\".*?\/>/gi,";-)");
rep(/<img.*?src=\"images\/smilies\/icon_e_sad\.gif\".*?\/>/gi,":-(");
rep(/<img.*?src=\"images\/smilies\/icon_e_surprised\.gif\".*?\/>/gi,":-o");
rep(/<img.*?src=\"images\/smilies\/icon_e_eek\.gif\".*?\/>/gi,":shock:");
rep(/<img.*?src=\"images\/smilies\/icon_e_confused\.gif\".*?\/>/gi,":-?");
rep(/<img.*?src=\"images\/smilies\/icon_cool\.gif\".*?\/>/gi,"8-)");
rep(/<img.*?src=\"images\/smilies\/icon_lol\.gif\".*?\/>/gi,":lol:");
rep(/<img.*?src=\"images\/smilies\/icon_mad\.gif\".*?\/>/gi,":-x");
rep(/<img.*?src=\"images\/smilies\/icon_razz\.gif\".*?\/>/gi,":-p");
rep(/<img.*?src=\"images\/smilies\/icon_redface\.gif\".*?\/>/gi,":oops:");
rep(/<img.*?src=\"images\/smilies\/icon_cry\.gif\".*?\/>/gi,":cry:");
rep(/<img.*?src=\"images\/smilies\/icon_evil\.gif\".*?\/>/gi,":evil:");
rep(/<img.*?src=\"images\/smilies\/icon_twisted\.gif\".*?\/>/gi,":twisted:");
rep(/<img.*?src=\"images\/smilies\/icon_rolleyes\.gif\".*?\/>/gi,":roll:");
rep(/<img.*?src=\"images\/smilies\/icon_exclaim\.gif\".*?\/>/gi,":!:");
rep(/<img.*?src=\"images\/smilies\/icon_question\.gif\".*?\/>/gi,":?:");
rep(/<img.*?src=\"images\/smilies\/icon_arrow\.gif\".*?\/>/gi,":arrow:");
rep(/<img.*?src=\"images\/smilies\/icon_neutral\.gif\".*?\/>/gi,":-|");
rep(/<img.*?src=\"images\/smilies\/icon_mrgreen\.gif\".*?\/>/gi,":mrgreen:");
rep(/<img.*?src=\"images\/smilies\/icon_e_geek\.gif\".*?\/>/gi,":geek:");
rep(/<img.*?src=\"images\/smilies\/icon_e_ugeek\.gif\".*?\/>/gi,":ugeek:");
// lists
rep(/<ul[^>]*>(.*?)<\/ul>/gi,"[list]\n$1[/list]");
rep(/<ol style="list-style-type: lower-alpha;">(.*?)<\/ol>/gi,"[list=a]\n$1[/list]");
rep(/<ol[^>]*>(.*?)<\/ol>/gi,"[list=1]\n$1[/list]");
rep(/<li>(.*?)<\/li>/gi,"[*]$1\n");
rep(/<img.*?src=\"(.*?)\".*?\/>/gi,"");
rep(/<dl class=\"codebox\"><dt>Code: <a href=\"#\" onclick=\"selectCode(this); return false;\">Select all<\/a><\/dt><dd><code>(.*?)<br \/><\/code><\/dd><\/dl>/gi,"[code]$1[/code]");
rep(/<\/(strong|b)>/gi,"[/b]");
rep(/<(strong|b)>/gi,"[b]");
rep(/<\/(em|i)>/gi,"[/i]");
rep(/<(em|i)>/gi,"[i]");
rep(/<\/u>/gi,"[/u]");
rep(/<span style=\"text-decoration: ?underline;\">(.*?)<\/span>/gi,"[u]$1[/u]");
rep(/<u>/gi,"[u]");
rep(/<blockquote[^>]*>/gi,"[quote]");
rep(/<\/blockquote>/gi,"[/quote]");
rep(/<br \/>/gi,"\n");
rep(/<br\/>/gi,"\n");
rep(/<br>/gi,"\n");
rep(/<p>/gi,"");
rep(/<\/p>/gi,"\n");
rep(/ /gi," ");
rep(/"/gi,"\"");
rep(/</gi,"<");
rep(/>/gi,">");
rep(/&/gi,"&");
return s;
},
// BBCode -> HTML from PunBB dialect
_punbb_bbcode2html : function(s) {
s = tinymce.trim(s);
function rep(re, str) {
s = s.replace(re, str);
};
// example: [b] to <strong>
rep(/\n/gi,"<br />");
rep(/\[b\]/gi,"<strong>");
rep(/\[\/b\]/gi,"</strong>");
rep(/\[i\]/gi,"<em>");
rep(/\[\/i\]/gi,"</em>");
rep(/\[u\]/gi,"<u>");
rep(/\[\/u\]/gi,"</u>");
rep(/\[url=([^\]]+)\](.*?)\[\/url\]/gi,"<a href=\"$1\">$2</a>");
rep(/\[url\](.*?)\[\/url\]/gi,"<a href=\"$1\">$1</a>");
rep(/\[img\](.*?)\[\/img\]/gi,"<img src=\"$1\" />");
rep(/\[color=(.*?)\](.*?)\[\/color\]/gi,"<font color=\"$1\">$2</font>");
rep(/\[code\](.*?)\[\/code\]/gi,"<dl class=\"codebox\"><dt>Code: <a href=\"#\" onclick=\"return false;\">Select all<\/a><\/dt><dd><code>$1<br \/><\/code><\/dd><\/dl> ");
rep(/\[quote=\"(.*?)\"\](.*?)\[\/quote\]/gi,"<blockquote><div><cite>$1 wrote:<\/cite>$2<\/div><\/blockquote><br />");
rep(/\[quote.*?\](.*?)\[\/quote\]/gi,"<blockquote><div><cite><\/cite>$1<\/div><\/blockquote><br />");
// font size
rep(/\[size=50\](.*?)\[\/size\]/gi,"<span style=\"font-size: 50%;\">$1</span>");
rep(/\[size=85\](.*?)\[\/size\]/gi,"<span style=\"font-size: 85%;\">$1</span>");
rep(/\[size=150\](.*?)\[\/size\]/gi,"<span style=\"font-size: 150%;\">$1</span>");
rep(/\[size=200\](.*?)\[\/size\]/gi,"<span style=\"font-size: 200%;\">$1</span>");
// emoticons
rep(/:D/gi, "<img src=\"./images/smilies/icon_e_biggrin.gif\" />");
rep(/:-D/gi, "<img src=\"./images/smilies/icon_e_biggrin.gif\" />");
rep(/:grin:/gi, "<img src=\"./images/smilies/icon_e_biggrin.gif\" />");
rep(/:\)/gi, "<img src=\"./images/smilies/icon_e_smile.gif\" />");
rep(/:-\)/gi, "<img src=\"./images/smilies/icon_e_smile.gif\" />");
rep(/:smile:/gi, "<img src=\"./images/smilies/icon_e_smile.gif\" />");
rep(/;\)/gi, "<img src=\"./images/smilies/icon_e_wink.gif\" />");
rep(/;-\)/gi, "<img src=\"./images/smilies/icon_e_wink.gif\" />");
rep(/:wink:/gi, "<img src=\"./images/smilies/icon_e_wink.gif\" />");
rep(/:\(/gi, "<img src=\"./images/smilies/icon_e_sad.gif\" />");
rep(/:-\(/gi, "<img src=\"./images/smilies/icon_e_sad.gif\" />");
rep(/:sad:/gi, "<img src=\"./images/smilies/icon_e_sad.gif\" />");
rep(/:o/gi, "<img src=\"./images/smilies/icon_e_surprised.gif\" />");
rep(/:-o/gi, "<img src=\"./images/smilies/icon_e_surprised.gif\" />");
rep(/:eek:/gi, "<img src=\"./images/smilies/icon_e_surprised.gif\" />");
rep(/:shock:/gi, "<img src=\"./images/smilies/icon_e_eek.gif\" />");
rep(/:\?/gi, "<img src=\"./images/smilies/icon_e_confused.gif\" />");
rep(/:-\?/gi, "<img src=\"./images/smilies/icon_e_confused.gif\" />");
rep(/:\?\?\?:/gi, "<img src=\"./images/smilies/icon_e_confused.gif\" />");
rep(/8-\)/gi, "<img src=\"./images/smilies/icon_cool.gif\" />");
rep(/:cool:/gi, "<img src=\"./images/smilies/icon_cool.gif\" />");
rep(/:lol:/gi, "<img src=\"./images/smilies/icon_lol.gif\" />");
rep(/:x/gi, "<img src=\"./images/smilies/icon_mad.gif\" />");
rep(/:-x/gi, "<img src=\"./images/smilies/icon_mad.gif\" />");
rep(/:mad:/gi, "<img src=\"./images/smilies/icon_mad.gif\" />");
rep(/:p/gi, "<img src=\"./images/smilies/icon_razz.gif\" />");
rep(/:-p/gi, "<img src=\"./images/smilies/icon_razz.gif\" />");
rep(/:razz:/gi, "<img src=\"./images/smilies/icon_razz.gif\" />");
rep(/:oops:/gi, "<img src=\"./images/smilies/icon_redface.gif\" />");
rep(/:cry:/gi, "<img src=\"./images/smilies/icon_cry.gif\" />");
rep(/:evil:/gi, "<img src=\"./images/smilies/icon_evil.gif\" />");
rep(/:twisted:/gi, "<img src=\"./images/smilies/icon_twisted.gif\" />");
rep(/:roll:/gi, "<img src=\"./images/smilies/icon_rolleyes.gif\" />");
rep(/:\!:/gi, "<img src=\"./images/smilies/icon_exclaim.gif\" />");
rep(/:\?:/gi, "<img src=\"./images/smilies/icon_question.gif\" />");
rep(/:idea:/gi, "<img src=\"./images/smilies/icon_idea.gif\" />");
rep(/:arrow:/gi, "<img src=\"./images/smilies/icon_arrow.gif\" />");
rep(/:\|/gi, "<img src=\"./images/smilies/icon_neutral.gif\" />");
rep(/:-\|/gi, "<img src=\"./images/smilies/icon_neutral.gif\" />");
rep(/:mrgreen:/gi, "<img src=\"./images/smilies/icon_mrgreen.gif\" />");
rep(/:geek:/gi, "<img src=\"./images/smilies/icon_e_geek.gif\" />");
rep(/:ugeek:/gi, "<img src=\"./images/smilies/icon_e_ugeek.gif\" />");
// lists
rep(/\[list\](.*?)\[\/list\]/gi, "<ul><li>$1</li></ul>");
rep(/\[list=1\](.*?)\[\/list\]/gi, "<ol><li>$1</li></ol>");
rep(/\[list=a\](.*?)\[\/list\]/gi, "<ol style=\"list-style-type: lower-alpha;\"><li>$1</li></ol>");
rep(/\[\*\]/g, "</li><li>");
// fix empty li's
rep(/<li><br \/><\/li>/g, "");
rep(/<li\/>/g, "");
return s;
}
});
// Register plugin
tinymce.PluginManager.add('bbcode', tinymce.plugins.BBCodePlugin);
})();
4 - create a file styles/prosilver/theme/bbcode.css and insert the following content
- Code: Select all
-
blockquote {
font-size: 0.95em;
background: none no-repeat scroll 6px 8px #EBEBEB;
background-color: #EBEADD;
background-image: url("./images/quote.gif");
border: 1px solid #DBDBDB;
margin: 0.5em 1px 0 25px;
overflow: hidden;
padding: 5px;
}
blockquote cite {
display: block;
font-size: 0.9em;
font-style: normal;
font-weight: bold;
margin-left: 20px;
}
dl.codebox {
background-color: #FFFFFF;
border: 1px solid #D8D8D8;
font-size: 1em;
padding: 3px;
}
dl.codebox dt {
border-bottom: 1px solid #CCCCCC;
display: block;
font-size: 0.8em;
font-weight: bold;
margin-bottom: 3px;
text-transform: uppercase;
}
dl.codebox code {
color:#2E8B57;
display: block;
font: 0.9em/1.3em Monaco,"Andale Mono","Courier New",Courier,mono;
height: auto;
margin: 2px 0;
max-height: 200px;
overflow: auto;
padding-top: 5px;
white-space: normal;
}
5 - create a file styles/prosilver/template/tiny_mce_config.js and insert the following content (adapting the language option)
- Code: Select all
-
tinyMCE.init({
theme : "advanced",
mode: "textareas",
editor_selector : "rich",
plugins : "bbcode",
/* for a localized version: install your language file, uncomment next line and adapt it */
/* language : "it", */
theme_advanced_buttons1 : "bold,italic,underline,bullist,numlist,image,link,unlink,fontsizeselect,forecolor,justifyleft,justifycenter,justifyright,justifyfull,undo,redo,removeformat",
theme_advanced_buttons2 : "",
theme_advanced_buttons3 : "",
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "center",
/* for a localized version: you should adapt next line by translating texts */
theme_advanced_font_sizes : "tiny=50%,small=85%,normal=100%,big=150%,huge=200%",
content_css : "styles/prosilver/theme/bbcode.css",
convert_fonts_to_spans: true,
font_size_style_values : "8,10,12,14,18,24,36",
entity_encoding : "raw",
add_unload_trigger : false,
remove_linebreaks : false,
setupcontent_callback : "inizia",
force_p_newlines : false,
forced_root_block : false,
//convert_fonts_to_spans : false,
media_types : "flash=swf"
});
function toggla(bb)
{
var bottone = document.getElementById('bottonecambia');
if (tinyMCE.getInstanceById('message') != null) {
tinyMCE.execCommand('mceRemoveControl', false, 'message');
bb.style.display = '';
bottone.removeChild(bottone.firstChild);
bottone.appendChild(document.createTextNode('visual editor'));
} else {
tinyMCE.execCommand('mceAddControl', false, 'message');
bb.style.display = 'none';
bottone.removeChild(bottone.firstChild);
bottone.appendChild(document.createTextNode('bb source'));
}
}
function inizia(editor_id, body, doc)
{
rte = tinyMCE.getInstanceById(editor_id);
var bb = document.getElementById('format-buttons');
if (bb && bb.style.display != 'none') {
bb.style.display = 'none';
var sottobb = document.createElement('div');
bb.parentNode.insertBefore(sottobb, bb.nextSibling);
var a1 = document.createElement('a');
a1.setAttribute('id', 'bottonecambia');
a1.appendChild(document.createTextNode('bb source'));
tinymce.dom.Event.add(a1, 'click', function(e) {toggla(bb);});
sottobb.appendChild(a1);
}
var boxfaccine = document.getElementById('smiley-box');
if (!boxfaccine) {
return;
}
var imgs = boxfaccine.getElementsByTagName('img');
var ia;
for (var i = 0; i < imgs.length; i ++) {
ia = imgs[i].parentNode;
ia.onclick = null;
if (ia.getAttribute('onclick') == 'javascript:return false;') {
continue;
}
ia.setAttribute('onclick', 'javascript:return false;');
tinymce.dom.Event.add(ia, 'click', function(e) {
var bb = document.getElementById('format-buttons');
if (bb && bb.style.display != 'none') {
insert_text(e.target.alt, true);
} else {
rte.execCommand('mceInsertContent', false, rte.dom.createHTML('img', {src: e.target.src}));
}
tinymce.dom.Event.stop(e);
});
}
rte.focus();
}
6 - edit styles/prosilver/template/overall_header.html
-Find:
- Code: Select all
-
<script type="text/javascript">
-Add before:
- Code: Select all
-
<script type="text/javascript" src="{T_TEMPLATE_PATH}/tiny_mce/tiny_mce.js"></script>
<script type="text/javascript" src="{T_TEMPLATE_PATH}/tiny_mce_config.js"></script>
7 - edit styles/prosilver/template/posting_editor.html
- Find
- Code: Select all
-
<textarea <!-- IF S_UCP_ACTION and not S_PRIVMSGS and not S_EDIT_DRAFT -->name="signature" id="signature" style="height: 9em;"<!-- ELSE -->name="message" id="message"<!-- ENDIF --> rows="15" cols="76" tabindex="3" o nselect="storeCaret(this);" onclick="storeCaret(this);" onkeyup="storeCaret(this);" class="inputbox">{MESSAGE}{DRAF _MESSAGE}{SIGNATURE}</textarea>
- Replace with
- Code: Select all
-
<textarea class="rich" <!-- IF S_UCP_ACTION and not S_PRIVMSGS and not S_EDIT_DRAFT -->name="signature" id="signature" style="height: 9em;"<!-- ELSE -->name="message" id="message"<!-- ENDIF --> rows="15" cols="76" tabindex="3" o nselect="storeCaret(this);" onclick="storeCaret(this);" onkeyup="storeCaret(this);" class="inputbox">{MESSAGE}{DRAFT_MESSAGE}{SIGNATURE}</textarea>
(simply add a class named "rich")
8 - purge the cache.
Notes
- flash is currently not working
- The list of emoticons is standard for prosilver theme: if you change icons theme, or modify that one, you must adapt js code in plugin
- The support for bbcode is limited to standard. If you use custom bbcodes, you must adapt js code in plugin