From 3aae661f6d3540ef2645015a89db07303f324a9e Mon Sep 17 00:00:00 2001 From: Bret McMillan Date: Fri, 14 Nov 2008 16:28:30 -0500 Subject: working on getting tinymce to work w/ mediawiki --- extensions/TinyMCE_MW2.php | 99 ++++++++++++++++ .../tiny_mce/plugins/mediawiki/editor_plugin.js | 125 +++++++++++++++++++++ .../tiny_mce/plugins/mediawiki/wiki2html.js | 103 +++++++++++++++++ 3 files changed, 327 insertions(+) create mode 100644 extensions/TinyMCE_MW2.php create mode 100644 extensions/tinymce/jscripts/tiny_mce/plugins/mediawiki/editor_plugin.js create mode 100644 extensions/tinymce/jscripts/tiny_mce/plugins/mediawiki/wiki2html.js diff --git a/extensions/TinyMCE_MW2.php b/extensions/TinyMCE_MW2.php new file mode 100644 index 0000000..370eb50 --- /dev/null +++ b/extensions/TinyMCE_MW2.php @@ -0,0 +1,99 @@ + +Copyright 2008, Red Hat, Inc., All rights reserved. + +Rewritten from Joseph Socoloski's original tinymce extension; +moves logic to the tinymce plugin framework + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +*/ + + +if( !defined( 'MEDIAWIKI' ) ) { + die(); +} + +$wgExtensionCredits['other'][] = array( + + "name" => "Next-gen TinyMCE MediaWiki extension", + "author" => "Bret McMillan ", + "version" => "0.1", + "url" => "http://www.redhat.com/", + "description" => "Easily implement Moxiecode's TinyMCE into MediaWiki using the plugin framework, extends Joseph Socoloski's original work" + ); + +# REGISTER HOOKS +$wgHooks['ArticleAfterFetchContent'][] = 'wfCheckBeforeEdit'; +$wgHooks['EditPage::showEditForm:initial'][] = 'wfTinymceAddScript'; + +function wfTinymceAddScript ($q) { + + global $wgOut, $wgTitle, $wgScriptPath, $wgMyWikiURL; + global $wgTempText, $wgTinymceDir, $wgTinymceTheme, $wgExt_valid_elements, $wgUseTinymce; + + $wgTinymceDir = "tinymce"; + $ns_allowed = true; + $ns = $wgTitle->getNamespace(); + + if ($ns_allowed && $wgUseTinymce) { + # use the more modern example straight from moxiecode + $wgOut->addScript(""); + + $wgOut->addScript( "" ); + + #Since editing add the button + $wgOut->addHTML("

Toggle Visual Editor

"); + } else { + $wgOut->addScript("" ); + $wgUseTinymce = true; + } + return true; +} + +# Check existing article for any tags we don't want TinyMCE parsing... +function wfCheckBeforeEdit ($q, $text) { + global $wgUseTinymce; + + if (preg_match("|<(data.*?)>(.*?)</data>|is", $text, $a)) { + $wgUseTinymce = false; + } + elseif(preg_match("|<(data.*?)>(.*?)|is", $text, $a)) { + $wgUseTinymce = false;} + else{$wgUseTinymce = true;} + return true; +} + +?> + diff --git a/extensions/tinymce/jscripts/tiny_mce/plugins/mediawiki/editor_plugin.js b/extensions/tinymce/jscripts/tiny_mce/plugins/mediawiki/editor_plugin.js new file mode 100644 index 0000000..8767200 --- /dev/null +++ b/extensions/tinymce/jscripts/tiny_mce/plugins/mediawiki/editor_plugin.js @@ -0,0 +1,125 @@ +/** + * $Id$ + * + * @author Bret McMillan + * @copyright Copyright © 2004-2008, Red Hat, Inc., All rights reserved. + * + * Adapted from: + * - the "example" and "bbcode" plugins provided by Moxicode + * - Remy Sharp's wiki2html code: http://remysharp.com/2008/04/01/wiki-to-html-using-javascript/ + * + * See also: http://en.wikipedia.org/wiki/Wikipedia:Cheatsheet + */ + +(function() { + tinymce.create('tinymce.plugins.MediaWikiPlugin', { + /** + * Initializes the plugin, this will be executed after the plugin has been created. + * This call is done before the editor instance has finished it's initialization so use the onInit event + * of the editor instance to intercept that event. + * + * @param {tinymce.Editor} ed Editor instance that the plugin is initialized in. + * @param {string} url Absolute URL to where the plugin is located. + */ + init : function(ed, url) { + var t = this; + // load wiki2html syncronous calls... + // might want to explore async later + tinymce.ScriptLoader.load(tinymce.PluginManager.urls.mediawiki + '/wiki2html.js'); + + ed.onBeforeSetContent.add(function(ed, o) { + o.content = t['_mw2html'](o.content); + }); + + ed.onPostProcess.add(function(ed, o) { + if (o.set) + o.content = t['_mw2html'](o.content); + + if (o.get) + o.content = t['_html2mw'](o.content); + + }); + }, + + /** + * Returns information about the plugin as a name/value array. + * The current keys are longname, author, authorurl, infourl and version. + * + * @return {Object} Name/value array containing information about the plugin. + */ + getInfo : function() { + return { + longname : 'MediaWiki plugin', + author : 'Bret McMillan ', + authorurl : 'http://www.redhat.com/', + infourl : 'http://www.redhat.com/', + version : "0.1" + }; + }, + + // Private methods + + // HTML -> MediaWiki, it'd be nice to get this upstream into remy's code + _html2mw : function(s) { + // s = tinymce.trim(s); + + function rep(re, str) { + s = s.replace(re, str); + }; + + // WikiWord urls + rep(/\1<\/a>/gim, "[[$1]]"); + + // handle where url's text is the same as the url + rep(/\1<\/a>/gim, "$1"); + + + // handle external urls with body text + rep(/(.+?)<\/a>/gim,"[$1 $2]"); + + // to '' + rep(/(.*?)<\/em>/gim, "''$1''"); + + // to ''' + rep(/(.*?)<\/strong>/gim, "'''$1'''"); + + // headers + rep(/

(.*?)<\/h1>/gim, "\n=$1="); + rep(/

(.*?)<\/h2>/gim, "\n==$1=="); + rep(/

(.*?)<\/h3>/gim, "\n===$1==="); + rep(/

(.*?)<\/h4>/gim, "\n====$1===="); + rep(/

(.*?)<\/h5>/gim, "\n=====$1====="); + rep(/
(.*?)<\/h6>/gim, "\n======$1======"); + + //

+ rep(/

([\s\S]*?)<\/p>/gim, '\n\n$1'); + + //
+ rep(/]*>/gim, '\n\n'); + + // + //rep(/ /gi, ' '); + + // ul,ol lists + // XXXXXXXXXXXXXXXXXXXXXX + + + // images + // XXXXXXXXXXXXXXXXXXXXXX + + // tables + // XXXXXXXXXXXXXXXXXXXXXX + + return s; + }, + + // MediaWiki -> HTML, delegate to remy's code + _mw2html : function(s) { + //s = tinymce.trim(s); + return s.wiki2html(); + } + }); + + // Register plugin + tinymce.PluginManager.add('mediawiki', tinymce.plugins.MediaWikiPlugin); +})(); \ No newline at end of file diff --git a/extensions/tinymce/jscripts/tiny_mce/plugins/mediawiki/wiki2html.js b/extensions/tinymce/jscripts/tiny_mce/plugins/mediawiki/wiki2html.js new file mode 100644 index 0000000..63ccf52 --- /dev/null +++ b/extensions/tinymce/jscripts/tiny_mce/plugins/mediawiki/wiki2html.js @@ -0,0 +1,103 @@ +/* + @author: remy sharp / http://remysharp.com + @url: http://remysharp.com/2008/04/01/wiki-to-html-using-javascript/ + @license: Creative Commons License - ShareAlike http://creativecommons.org/licenses/by-sa/3.0/ + @version: 1.0 + + Can extend String or be used stand alone - just change the flag at the top of the script. +*/ + +(function () { + +var extendString = true; + +if (extendString) { + String.prototype.wiki2html = wiki2html; + String.prototype.iswiki = iswiki; +} else { + window.wiki2html = wiki2html; + window.iswiki = iswiki; +} + +// utility function to check whether it's worth running through the wiki2html +function iswiki(s) { + if (extendString) { + s = this; + } + + return !!(s.match(/^[\s{2} `#\*='{2}]/m)); +} + +// the regex beast... +function wiki2html(s) { + if (extendString) { + s = this; + } + + // lists need to be done using a function to allow for recusive calls + function list(str) { + return str.replace(/(?:(?:(?:^|\n)[\*#].*)+)/g, function (m) { // (?=[\*#]) + var type = m.match(/(^|\n)#/) ? 'OL' : 'UL'; + // strip first layer of list + m = m.replace(/(^|\n)[\*#][ ]{0,1}/g, "$1"); + m = list(m); + return '<' + type + '>

  • ' + m.replace(/^\n/, '').split(/\n/).join('
  • ') + '
  • '; + }); + } + + return list(s + + /* BLOCK ELEMENTS */ + .replace(/(?:^|\n+)([^# =\*<].+)(?:\n+|$)/gm, function (m, l) { + if (l.match(/^\^+$/)) return l; + return "\n

    " + l + "

    \n"; + }) + + .replace(/(?:^|\n)[ ]{2}(.*)+/g, function (m, l) { // blockquotes + if (l.match(/^\s+$/)) return m; + return '
    ' + l + ''; + }) + + .replace(/((?:^|\n)[ ]+.*)+/g, function (m) { // code + if (m.match(/^\s+$/)) return m; + return '
    ' + m.replace(/(^|\n)[ ]+/g, "$1") + '
    '; + }) + + .replace(/(?:^|\n)([=]+)(.*)\1/g, function (m, l, t) { // headings + return '' + t + ''; + }) + + /* INLINE ELEMENTS */ + .replace(/'''(.*?)'''/g, function (m, l) { // bold + return '' + l + ''; + }) + + .replace(/''(.*?)''/g, function (m, l) { // italic + return '' + l + ''; + }) + + .replace(/[^\[](http[^\[\s]*)/g, function (m, l) { // normal link + return '' + l + ''; + }) + + .replace(/[\[](http.*)[!\]]/g, function (m, l) { // external link + var p = l.replace(/[\[\]]/g, '').split(/ /); + var link = p.shift(); + return '' + (p.length ? p.join(' ') : link) + ''; + }) + + .replace(/\[\[(.*?)\]\]/g, function (m, l) { // internal link or image + var p = l.split(/\|/); + var link = p.shift(); + + if (link.match(/^Image:(.*)/)) { + // no support for images - since it looks up the source from the wiki db :-( + return m; + } else { + return '' + (p.length ? p.join('|') : link) + ''; + } + }) + ); +} + +})(); \ No newline at end of file -- cgit