TinyMCE integration with phpBB3

Modification Name: TinyMCE integration
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 garakkio@gmail.com
* @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(/&nbsp;/gi," ");
      rep(/&quot;/gi,"\"");
      rep(/&lt;/gi,"<");
      rep(/&gt;/gi,">");
      rep(/&amp;/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>&nbsp;");
      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
原文地址:https://www.cnblogs.com/huqingyu/p/1778420.html