Index: /MediaWiki/trunk/FCKeditor.body.php
===================================================================
--- /MediaWiki/trunk/FCKeditor.body.php	(revision 1660)
+++ /MediaWiki/trunk/FCKeditor.body.php	(revision 1660)
@@ -0,0 +1,315 @@
+<?php
+
+class FCKeditor_MediaWiki
+{
+	private $count = array();
+	private $wgFCKBypassText = "";
+	private $debug = 0;
+	private $excludedNamespaces;
+	private $oldTextBox1;
+	static $nsToggles = array(
+	'riched_disable_ns_main',
+	'riched_disable_ns_talk',
+	'riched_disable_ns_user',
+	'riched_disable_ns_user_talk',
+	'riched_disable_ns_project',
+	'riched_disable_ns_project_talk',
+	'riched_disable_ns_image',
+	'riched_disable_ns_image_talk',
+	'riched_disable_ns_mediawiki',
+	'riched_disable_ns_mediawiki_talk',
+	'riched_disable_ns_template',
+	'riched_disable_ns_template_talk',
+	'riched_disable_ns_help',
+	'riched_disable_ns_help_talk',
+	'riched_disable_ns_category',
+	'riched_disable_ns_category_talk',
+	);
+
+	static $messagesLoaded = false;
+
+	function __call($m,$a)
+	{
+		print "\n#### " . $m . "\n";
+		if (!isset($this->count[$m])) {
+			$this->count[$m] = 0;
+		}
+		$this->count[$m]++;
+		return true;
+	}
+
+	function onMonoBookTemplateToolboxEnd()
+	{
+		if ($this->debug) {
+			print_r($this->count);
+		}
+	}
+
+	private function getExcludedNamespaces()
+	{
+		global $wgUser;
+
+		if ( is_null( $this->excludedNamespaces ) ) {
+			$this->excludedNamespaces = array();
+			foreach ( self::$nsToggles as $toggle ) {
+				if ( $wgUser->getOption( $toggle ) ) {
+					$this->excludedNamespaces[] = constant(strtoupper(str_replace("riched_disable_", "", $toggle)));
+				}
+			}
+		}
+
+		return $this->excludedNamespaces;
+	}
+
+	public function registerHooks() {
+		global $wgHooks;
+
+		$wgHooks['UserToggles'][]                       = array($this, 'onUserToggles');
+		$wgHooks['MessagesPreLoad'][]                   = array($this, 'onMessagesPreLoad');
+		$wgHooks['ParserAfterTidy'][]                   = array($this, 'onParserAfterTidy');
+		$wgHooks['EditPage::showEditForm:initial'][]    = array($this, 'onEditPageShowEditFormInitial');
+		$wgHooks['EditPageBeforePreviewText'][]         = array($this, 'onEditPageBeforePreviewText');
+		$wgHooks['EditPagePreviewTextEnd'][]            = array($this, 'onEditPagePreviewTextEnd');
+
+		if ($this->debug) {
+			$opcje =  array('ArticleSave',
+			'ArticleInsertComplete', 'ArticleSaveComplete', 'TitleMoveComplete', 'ArticleProtect', 'ArticleProtectComplete', 'ArticleDelete', 'ArticleDeleteComplete', 'AlternateEdit', 'ArticleFromTitle', 'ArticleAfterFetchContent',
+			'ArticlePageDataBefore', 'ArticlePageDataAfter', 'ParserBeforeStrip', 'ParserAfterStrip', 'ParserBeforeInternalParse', 'InternalParseBeforeLinks', 'ParserBeforeTidy', 'ParserAfterTidy', 'ParserClearState', 'ParserGetVariableValueSwitch',
+			'ParserGetVariableValueTs', 'ParserGetVariableValueVarCache', 'OutputPageBeforeHTML', 'OutputPageParserOutput', 'CategoryPageView', 'PageRenderingHash', 'ArticleViewHeader', 'ArticleViewRedirect', 'editSectionLinkForOther', 'editSectionLink',
+			'AutoAuthenticate', 'UserLoginComplete', 'UserLogout', 'UserLogoutComplete', 'userCan', 'WatchArticle', 'WatchArticleComplete', 'UnwatchArticle', 'UnwatchArticleComplete', 'MarkPatrolled',
+			'MarkPatrolledComplete', 'EmailUser', 'EmailUserComplete', 'UploadVerification', 'UploadComplete', 'SpecialMovepageAfterMove', 'SpecialSearchNogomatch', 'ArticleEditUpdateNewTalk', 'UserRetrieveNewTalks', 'UserClearNewTalkNotification',
+			'ArticlePurge', 'SpecialPageGetRedirect', 'SpecialPageExecuteBeforeHeader', 'SpecialPageExecuteBeforePage', 'SpecialPageExecuteAfterPage', 'SpecialVersionExtensionTypes', 'SpecialPage_initList', 'UploadForm:initial', 'UploadForm:BeforeProcessing', 'AddNewAccount',
+			'AbortNewAccount', 'BlockIp', 'BlockIpComplete', 'UserRights', 'GetBlockedStatus', 'LogPageActionText', 'LogPageLogHeader', 'LogPageLogName', 'LogPageValidTypes', 'BeforePageDisplay',
+			'MonoBookTemplateToolboxEnd', 'PersonalUrls', 'SkinTemplateContentActions', 'SkinTemplateTabs', 'SkinTemplatePreventOtherActiveTabs', 'SkinTemplateSetupPageCss', 'SkinTemplateBuildContentActionUrlsAfterSpecialPage', 'SkinTemplateBuildNavUrlsNav_urlsAfterPermalink', 'UserCreateForm', 'UserLoginForm',
+			'ArticleEditUpdatesDeleteFromRecentchanges', 'EditFilter', 'EditPage::showEditForm:initial', 'GetInternalURL', 'GetLocalURL', 'GetFullURL', 'LanguageGetMagic', 'MagicWordMagicWords', 'MagicWordwgVariableIDs', 'MessagesPreLoad',
+			'ParserTestParser', 'SpecialContributionsBeforeMainOutput', 'UnknownAction', 'wgQueryPages', 'DisplayOldSubtitle', 'LoadAllMessages', 'RecentChange_save', 'UserToggles', 'BadImage', 'DiffViewHeader',
+			'EditFormPreloadText', 'EmailConfirmed', 'FetchChangesList', 'MathAfterTexvc', 'SiteNoticeAfter', 'SiteNoticeBefore');
+
+			foreach ($opcje as $o) {
+				$wgHooks[$o][] = $this;
+			}
+		}
+	}
+
+	public function onEditPageBeforePreviewText(&$editPage, $previewOnOpen)
+	{
+		global $wgUser, $wgRequest;
+
+		if ($wgUser->getOption( 'showtoolbar' ) && !$wgUser->getOption( 'riched_disable' ) && !$previewOnOpen ) {
+			$this->oldTextBox1 = $editPage->textbox1;
+			$editPage->importFormData( $wgRequest );
+		}
+
+		return true;
+	}
+
+	public function onEditPagePreviewTextEnd(&$editPage, $previewOnOpen)
+	{
+		global $wgUser;
+
+		if ($wgUser->getOption( 'showtoolbar' ) && !$wgUser->getOption( 'riched_disable' ) && !$previewOnOpen ) {
+			$editPage->textbox1 = $this->oldTextBox1;
+		}
+
+		return true;
+	}
+
+	public function onParserAfterTidy(&$parser, &$text)
+	{
+		global $wgUseTeX, $wgUser, $wgTitle, $wgFCKEditorIsCompatible;
+
+		if (!$wgUser->getOption( 'showtoolbar' ) || $wgUser->getOption( 'riched_disable' ) || !$wgFCKEditorIsCompatible) {
+			return true;
+		}
+
+		if (is_object($wgTitle) && in_array($wgTitle->getNamespace(), $this->getExcludedNamespaces())) {
+			return true;
+		}
+
+		if ($wgUseTeX) {
+			//it may add much overload on page with huge amount of math content...
+			$text = preg_replace('/<img class="tex" alt="([^"]*)"/m', '<img _fckfakelement="true" _fck_mw_math="$1"', $text);
+			$text = preg_replace("/<img class='tex' src=\"([^\"]*)\" alt=\"([^\"]*)\"/m", '<img src="$1" _fckfakelement="true" _fck_mw_math="$2"', $text);
+		}
+
+		return true;
+	}
+
+	public function onMessagesPreLoad()
+	{
+		global $wgMessageCache, $wgUser, $wgContLanguageCode;
+
+		if ( !self::$messagesLoaded ) {
+			$lang = $wgUser->getOption( 'language', $wgContLanguageCode );
+			$i18nfile = dirname( __FILE__ ) . DIRECTORY_SEPARATOR .'FCKeditor.i18n.' . $lang . '.php';
+
+			if ( file_exists( $i18nfile ) ) {
+				require( $i18nfile );
+			} else {
+				$lang = 'en';
+				require( dirname( __FILE__ ) . DIRECTORY_SEPARATOR .'FCKeditor.i18n.en.php' );
+			}
+
+			$wgMessageCache->addMessages( $allMessages, $lang );
+			self::$messagesLoaded = true;
+		}
+
+		return true;
+	}
+
+	/**
+	 * Add FCK script
+	 * 
+	 * @param unknown_type $q
+	 * @return unknown
+	 */
+	public function onEditPageShowEditFormInitial( $form ) {
+		global $wgOut, $wgTitle, $wgScriptPath;
+		global $wgFCKEditorToolbarSet, $wgFCKEditorIsCompatible;
+		global $wgFCKEditorExtDir, $wgFCKEditorDir, $wgFCKEditorHeight, $wgUser;
+		global $wgStylePath, $wgStyleVersion, $wgDefaultSkin, $wgExtensionFunctions;
+
+		if (!$wgUser->getOption( 'showtoolbar' ) || $wgUser->getOption( 'riched_disable' ) || !$wgFCKEditorIsCompatible) {
+			return true;
+		}
+
+		if (in_array($wgTitle->getNamespace(), $this->getExcludedNamespaces())) {
+			return true;
+		}
+
+		$options = new FCKeditorParserOptions();
+		$options->setTidy(true);
+		$parser = new FCKeditorParser();
+		$parser->setOutputType(OT_HTML);
+		$form->textbox1 = $parser->parse($form->textbox1, $wgTitle, $options)->getText();
+
+		$printsheet = htmlspecialchars( "$wgStylePath/common/wikiprintable.css?$wgStyleVersion" );
+
+		//CSS trick,  we need to get user CSS stylesheets somehow... it must be done in a different way!
+		$skin = $wgUser->getSkin();
+		$skin->loggedin = $wgUser->isLoggedIn();
+		$skin->mTitle =& $wgTitle;
+		$skin->skinname = 'monobook';
+		$skin->userpage = $wgUser->getUserPage()->getPrefixedText();
+		$skin->setupUserCss();
+
+		preg_match_all('/@import "([^"]+)";/', $skin->usercss, $matches);
+		$userStyles = $matches[1];
+		//End of CSS trick
+
+		$script = <<<HEREDOC
+<script type="text/javascript" src="$wgScriptPath/$wgFCKEditorDir/fckeditor.js"></script>
+<script type="text/javascript"> 
+var sEditorAreaCSS = '$printsheet,/mediawiki/skins/monobook/main.css?{$wgStyleVersion}';
+</script>
+<!--[if lt IE 5.5000]><script type="text/javascript">sEditorAreaCSS += ',/mediawiki/skins/monobook/IE50Fixes.css?{$wgStyleVersion}'; </script><![endif]-->
+<!--[if IE 5.5000]><script type="text/javascript">sEditorAreaCSS += ',/mediawiki/skins/monobook/IE55Fixes.css?{$wgStyleVersion}'; </script><![endif]-->
+<!--[if IE 6]><script type="text/javascript">sEditorAreaCSS += ',/mediawiki/skins/monobook/IE60Fixes.css?{$wgStyleVersion}'; </script><![endif]-->
+<!--[if IE 7]><script type="text/javascript">sEditorAreaCSS += ',/mediawiki/skins/monobook/IE70Fixes.css?{$wgStyleVersion}'; </script><![endif]-->
+<!--[if lt IE 7]><script type="text/javascript">sEditorAreaCSS += ',/mediawiki/skins/monobook/IEFixes.css?{$wgStyleVersion}'; </script><![endif]-->
+HEREDOC;
+
+		if (!is_null($userStyles) && !empty($userStyles)) {
+			$script .= '
+<script type="text/javascript"> 
+sEditorAreaCSS += ",'.implode(',', $userStyles).'";
+</script>';
+		}
+
+		$script .= <<<HEREDOC
+<script type="text/javascript"> 
+
+// Remove the mwSetupToolbar onload hook to avoid a JavaScript error with FF.
+if ( window.removeEventListener )
+	window.removeEventListener( 'load', mwSetupToolbar, false ) ;
+else if ( window.detachEvent )
+	window.detachEvent( 'onload', mwSetupToolbar ) ;
+	
+mwSetupToolbar = function() { return false ; } ;
+
+function onLoadFCKeditor()
+{
+	if ( document.getElementById('wpTextbox1') )
+	{
+		var height = $wgFCKEditorHeight ;
+		
+		if ( height == 0 )
+		{
+			// Get the window (inner) size.
+			var height = window.innerHeight || ( document.documentElement && document.documentElement.clientHeight ) || 550 ;
+			
+			// Reduce the height to the offset of the toolbar.
+			var offset = document.getElementById('wikiPreview') || document.getElementById('toolbar') ;
+			while ( offset )
+			{
+				height -= offset.offsetTop ;
+				offset = offset.offsetParent ;
+			}
+			
+			// Add a small space to be left in the bottom.
+			height -= 20 ;
+		}
+
+		// Enforce a minimum height.
+		height = ( !height || height < 300 ) ? 300 : height ;
+		
+		// Create the editor instance and replace the textarea.
+		var oFCKeditor = new FCKeditor('wpTextbox1') ;
+		oFCKeditor.BasePath = '$wgScriptPath/$wgFCKEditorDir/' ;
+		oFCKeditor.Config['CustomConfigurationsPath'] = '$wgScriptPath/$wgFCKEditorExtDir/fckeditor_config.js' ;
+		oFCKeditor.Config['EditorAreaCSS'] = "$wgScriptPath/$wgFCKEditorExtDir/css/fckeditor.css" ;
+		oFCKeditor.Height = height ;
+		oFCKeditor.ToolbarSet = '$wgFCKEditorToolbarSet' ;
+		oFCKeditor.ReplaceTextarea() ;
+		
+		// Hide the default toolbar.
+		document.getElementById('toolbar').style.cssText = 'display:none;' ;
+	}
+}
+addOnloadHook( onLoadFCKeditor ) ;
+
+/*
+function showSource() {
+	var wp = document.getElementById("wpDiff");
+	var s = document.createElement("input");
+	s.type="submit";
+	s.value="Wiki2HTML";
+	s.name="Wiki2HTML";
+	s.onclick = function wiki2html() {
+		var oEditor = FCKeditorAPI.GetInstance('wpTextbox1');
+		WikiToHTML_Call();
+		return false;
+	}
+	wp.parentNode.insertBefore(s, wp.nextSibling);
+}
+
+var sajax_debug_mode = false;
+var sajax_request_type = "GET";
+
+function WikiToHTML_Result(result)
+{
+	var oEditor = FCKeditorAPI.GetInstance('wpTextbox1');
+	oEditor.SetHTML(result.responseText);
+}
+function WikiToHTML_Call()
+{
+	var oEditor = FCKeditorAPI.GetInstance('wpTextbox1');
+	sajax_do_call('wfSajaxWikiToHTML', [oEditor.GetHTML()], WikiToHTML_Result);
+}
+
+addOnloadHook(showSource);
+*/
+</script>
+HEREDOC;
+
+		$wgOut->addScript($script);
+
+		return true;
+	}
+
+	public function onUserToggles( &$extraToggles ) {
+		$extraToggles[] = 'riched_disable';
+		$extraToggles = array_merge($extraToggles, self::$nsToggles);
+		return true;
+	}
+}
Index: /MediaWiki/trunk/FCKeditor.i18n.en.php
===================================================================
--- /MediaWiki/trunk/FCKeditor.i18n.en.php	(revision 1660)
+++ /MediaWiki/trunk/FCKeditor.i18n.en.php	(revision 1660)
@@ -0,0 +1,22 @@
+<?php
+
+$allMessages = array(
+'textrichditor' => 'Rich Editor',
+'tog-riched_disable' => 'Rich Editor: disable globally',
+'tog-riched_disable_ns_main' => 'Rich Editor: disable within the main namespace',
+'tog-riched_disable_ns_talk' => 'Rich Editor: disable within the "{{ns:Talk}}" namespace',
+'tog-riched_disable_ns_user' => 'Rich Editor: disable within the "{{ns:User}}" namespace',
+'tog-riched_disable_ns_user_talk' => 'Rich Editor: disable within the "{{ns:User_talk}}" namespace',
+'tog-riched_disable_ns_project' => 'Rich Editor: disable within the "{{ns:Project}}" namespace',
+'tog-riched_disable_ns_project_talk' => 'Rich Editor: disable within the "{{ns:Project_talk}}" namespace',
+'tog-riched_disable_ns_image' => 'Rich Editor: disable within the "{{ns:Image}}" namespace',
+'tog-riched_disable_ns_image_talk' => 'Rich Editor: disable within the "{{ns:Image_talk}}" namespace',
+'tog-riched_disable_ns_mediawiki' => 'Rich Editor: disable within the "{{ns:MediaWiki}}" namespace',
+'tog-riched_disable_ns_mediawiki_talk' => 'Rich Editor: disable within the "{{ns:MediaWiki_talk}}" namespace',
+'tog-riched_disable_ns_template' => 'Rich Editor: disable within the "{{ns:Template}}" namespace',
+'tog-riched_disable_ns_template_talk' => 'Rich Editor: disable within the "{{ns:Template_talk}}" namespace',
+'tog-riched_disable_ns_help' => 'Rich Editor: disable within the "{{ns:Help}}" namespace',
+'tog-riched_disable_ns_help_talk' => 'Rich Editor: disable within the "{{ns:Help_talk}}" namespace',
+'tog-riched_disable_ns_category' => 'Rich Editor: disable within the "{{ns:Category}}" namespace',
+'tog-riched_disable_ns_category_talk' => 'Rich Editor: disable within the "{{ns:Category_talk}}" namespace',
+);
Index: /MediaWiki/trunk/FCKeditor.i18n.pl.php
===================================================================
--- /MediaWiki/trunk/FCKeditor.i18n.pl.php	(revision 1660)
+++ /MediaWiki/trunk/FCKeditor.i18n.pl.php	(revision 1660)
@@ -0,0 +1,22 @@
+<?php
+
+$allMessages = array(
+'textrichditor' => 'Rich Editor',
+'tog-riched_disable' => 'Wyłącz Rich Editora',
+'tog-riched_disable_ns_main' => 'Wyłącz Rich Editora wewątrz głównej przestrzeni nazw',
+'tog-riched_disable_ns_talk' => 'Wyłącz Rich Editora wewątrz przestrzeni nazw "{{ns:Talk}}"',
+'tog-riched_disable_ns_user' => 'Wyłącz Rich Editora wewątrz przestrzeni nazw "{{ns:User}}"',
+'tog-riched_disable_ns_user_talk' => 'Wyłącz Rich Editora wewątrz przestrzeni nazw "{{ns:User_talk}}"',
+'tog-riched_disable_ns_project' => 'Wyłącz Rich Editora wewątrz przestrzeni nazw "{{ns:Project}}"',
+'tog-riched_disable_ns_project_talk' => 'Wyłącz Rich Editora wewątrz przestrzeni nazw "{{ns:Project_talk}}"',
+'tog-riched_disable_ns_image' => 'Wyłącz Rich Editora wewątrz przestrzeni nazw "{{ns:Image}}"',
+'tog-riched_disable_ns_image_talk' => 'Wyłącz Rich Editora wewątrz przestrzeni nazw "{{ns:Image_talk}}"',
+'tog-riched_disable_ns_mediawiki' => 'Wyłącz Rich Editora wewątrz przestrzeni nazw "{{ns:MediaWiki}}"',
+'tog-riched_disable_ns_mediawiki_talk' => 'Wyłącz Rich Editora wewątrz przestrzeni nazw "{{ns:MediaWiki_talk}}"',
+'tog-riched_disable_ns_template' => 'Wyłącz Rich Editora wewątrz przestrzeni nazw "{{ns:Template}}"',
+'tog-riched_disable_ns_template_talk' => 'Wyłącz Rich Editora wewątrz przestrzeni nazw "{{ns:Template_talk}}"',
+'tog-riched_disable_ns_help' => 'Wyłącz Rich Editora wewątrz przestrzeni nazw "{{ns:Help}}"',
+'tog-riched_disable_ns_help_talk' => 'Wyłącz Rich Editora wewątrz przestrzeni nazw "{{ns:Help_talk}}"',
+'tog-riched_disable_ns_category' => 'Wyłącz Rich Editora wewątrz przestrzeni nazw "{{ns:Category}}"',
+'tog-riched_disable_ns_category_talk' => 'Wyłącz Rich Editora wewątrz przestrzeni nazw "{{ns:Category_talk}}"',
+);
Index: /MediaWiki/trunk/FCKeditor.php
===================================================================
--- /MediaWiki/trunk/FCKeditor.php	(revision 1660)
+++ /MediaWiki/trunk/FCKeditor.php	(revision 1660)
@@ -0,0 +1,73 @@
+<?php
+
+# Not a valid entry point, skip unless MEDIAWIKI is defined
+if (!defined('MEDIAWIKI')) {
+	echo <<<HEREDOC
+To install my extension, put the following line in LocalSettings.php:
+require_once( "\$IP/extensions/FCKeditor/FCKeditor.php" );
+HEREDOC;
+	exit( 1 );
+}
+
+/*
+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
+*/
+
+require_once $IP . "/includes/GlobalFunctions.php";
+require_once $IP . "/includes/ParserOptions.php";
+require_once $IP . "/includes/Parser.php";
+require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . "FCKeditorSajax.body.php";
+require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . "FCKeditorParser.body.php";
+require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . "FCKeditorParserOptions.body.php";
+require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . "FCKeditorSkin.body.php";
+require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . "FCKeditor.body.php";
+require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . "fckeditor" . DIRECTORY_SEPARATOR . "fckeditor.php";
+
+$wgFCKEditorExtDir       = "extensions/FCKeditor";
+$wgFCKEditorDir          = "extensions/FCKeditor/fckeditor";
+$wgFCKEditorToolbarSet   = "Wiki";
+$wgFCKEditorHeight       = "0";		// "0" for automatic ("300" minimum).
+
+/**
+ * Enable use of AJAX features.
+ */
+$wgUseAjax = true;
+$wgAjaxExportList[] = 'wfSajaxSearchImageFCKeditor';
+$wgAjaxExportList[] = 'wfSajaxSearchArticleFCKeditor';
+$wgAjaxExportList[] = 'wfSajaxWikiToHTML';
+$wgAjaxExportList[] = 'wfSajaxGetImageUrl';
+$wgAjaxExportList[] = 'wfSajaxGetMathUrl';
+
+$wgExtensionCredits['other'][] = array(
+"name" => "FCKeditor extension",
+"author" => "FCKeditor.net (inspired by the code written by Mafs [Meta])",
+"version" => 'fckeditor/mw-extension $Rev$ 2007',
+"url" => "http://meta.wikimedia.org/wiki/FCKeditor",
+"description" => "FCKeditor extension"
+);
+
+$fckeditor = new FCKeditor("fake");
+$wgFCKEditorIsCompatible = $fckeditor->IsCompatible();
+
+$oFCKeditorExtension = new FCKeditor_MediaWiki();
+$oFCKeditorExtension->registerHooks();
+
+
+
+
+
+
+
+
Index: /MediaWiki/trunk/FCKeditorParser.body.php
===================================================================
--- /MediaWiki/trunk/FCKeditorParser.body.php	(revision 1660)
+++ /MediaWiki/trunk/FCKeditorParser.body.php	(revision 1660)
@@ -0,0 +1,607 @@
+<?php
+
+class FCKeditorParser extends Parser
+{
+	public static $fkc_mw_makeImage_options;
+	protected $fck_mw_strtr_span;
+	protected $fck_mw_strtr_span_counter=1;
+	protected $fck_mw_taghook;
+	protected $fck_internal_parse_text;
+
+	private $FCKeditorMagicWords = array(
+	'__NOTOC__',
+	'__FORCETOC__',
+	'__NOEDITSECTION__',
+	'__START__',
+	'__NOTITLECONVERT__',
+	'__NOCONTENTCONVERT__',
+	'__END__',
+	'__TOC__',
+	'__NOTC__',
+	'__NOCC__',
+	"__FORCETOC__",
+	"__NEWSECTIONLINK__",
+	"__NOGALLERY__",
+	);
+
+	function __construct() {
+		global $wgParser;
+		parent::Parser();
+
+		foreach ($wgParser->getTags() as $h) {
+			if (!in_array($h, array("pre"))) {
+				$this->setHook($h, array($this, "fck_genericTagHook"));
+			}
+		}
+	}
+
+	/**
+	 * Add special string (that would be changed by Parser) to array and return simple unique string 
+	 * that will remain unchanged during whole parsing operation.
+	 * At the end we'll replace all this unique strings with original content
+	 *
+	 * @param string $text
+	 * @return string
+	 */
+	private function fck_addToStrtr($text) {
+		$key = 'Fckmw'.$this->fck_mw_strtr_span_counter.'fckmw';
+		$this->fck_mw_strtr_span_counter++;
+		$this->fck_mw_strtr_span[$key] = $text;
+		return $key;
+	}
+
+	/**
+	* Callback function for custom tags: feed, ref, references etc.
+	*
+	* @param string $str Input
+	* @param array $argv Arguments
+	* @return string
+	*/
+	function fck_genericTagHook( $str, $argv, $parser ) {
+		if (empty($argv)) {
+			$ret = "<span class=\"fck_mw_".$this->fck_mw_taghook."\" _fck_mw_customtag=\"true\" _fck_mw_tagname=\"".$this->fck_mw_taghook."\">";
+		}
+		else {
+			$ret = "<span class=\"fck_mw_".$this->fck_mw_taghook."\" _fck_mw_customtag=\"true\" _fck_mw_tagname=\"".$this->fck_mw_taghook."\"";
+			foreach ($argv as $key=>$value) {
+				$ret .= " ".$key."=\"".$value."\"";
+			}
+			$ret .=">";
+		}
+		if (is_null($str)) {
+			$ret = substr($ret, 0, -1) . " />";
+		}
+		else {
+			$ret .= htmlspecialchars($str);
+			$ret .= "</span>";
+		}
+
+		$replacement = $this->fck_addToStrtr($ret);
+		return $replacement;
+	}
+
+	/**
+	* Callback function for wiki tags: nowiki, includeonly, noinclude
+	*
+	* @param string $tagName tag name, eg. nowiki, math
+	* @param string $str Input
+	* @param array $argv Arguments
+	* @return string
+	*/
+	function fck_wikiTag( $tagName, $str, $argv = array()) {
+		if (empty($argv)) {
+			$ret = "<span class=\"fck_mw_".$tagName."\">";
+		}
+		else {
+			$ret = "<span class=\"fck_mw_".$tagName."\"";
+			foreach ($argv as $key=>$value) {
+				$ret .= " ".$key."=\"".$value."\"";
+			}
+			$ret .=">";
+		}
+		if (is_null($str)) {
+			$ret = substr($ret, 0, -1) . " />";
+		}
+		else {
+			$ret .= htmlspecialchars($str);
+			$ret .= "</span>";
+		}
+
+		$replacement = $this->fck_addToStrtr($ret);
+
+		return $replacement;
+	}
+
+	/**
+	 * Strips and renders nowiki, pre, math, hiero
+	 * If $render is set, performs necessary rendering operations on plugins
+	 * Returns the text, and fills an array with data needed in unstrip()
+	 *
+	 * @param StripState $state
+	 *
+	 * @param bool $stripcomments when set, HTML comments <!-- like this -->
+	 *  will be stripped in addition to other tags. This is important
+	 *  for section editing, where these comments cause confusion when
+	 *  counting the sections in the wikisource
+	 *
+	 * @param array dontstrip contains tags which should not be stripped;
+	 *  used to prevent stipping of <gallery> when saving (fixes bug 2700)
+	 *
+	 * @private
+	 */
+	function strip( $text, $state, $stripcomments = false , $dontstrip = array () ) {
+		global $wgContLang;
+
+		wfProfileIn( __METHOD__ );
+		$render = ($this->mOutputType == OT_HTML);
+
+		$uniq_prefix = $this->mUniqPrefix;
+		$commentState = new ReplacementArray;
+		$nowikiItems = array();
+		$generalItems = array();
+
+		$elements = array_merge(
+		array( 'nowiki', 'gallery' ),
+		array_keys( $this->mTagHooks ) );
+		global $wgRawHtml;
+		if( $wgRawHtml ) {
+			$elements[] = 'html';
+		}
+		if( $this->mOptions->getUseTeX() ) {
+			$elements[] = 'math';
+		}
+
+		# Removing $dontstrip tags from $elements list (currently only 'gallery', fixing bug 2700)
+		foreach ( $elements AS $k => $v ) {
+			if ( !in_array ( $v , $dontstrip ) ) continue;
+			unset ( $elements[$k] );
+		}
+
+		$matches = array();
+		$text = Parser::extractTagsAndParams( $elements, $text, $matches, $uniq_prefix );
+
+		foreach( $matches as $marker => $data ) {
+			list( $element, $content, $params, $tag ) = $data;
+			if( $render ) {
+				$tagName = strtolower( $element );
+				wfProfileIn( __METHOD__."-render-$tagName" );
+				switch( $tagName ) {
+					case '!--':
+						// Comment
+						if( substr( $tag, -3 ) == '-->' ) {
+							$output = $tag;
+						} else {
+							// Unclosed comment in input.
+							// Close it so later stripping can remove it
+							$output = "$tag-->";
+						}
+						break;
+					case 'html':
+						if( $wgRawHtml ) {
+							$output = $content;
+							break;
+						}
+						// Shouldn't happen otherwise. :)
+					case 'nowiki':
+						$output = $this->fck_wikiTag('nowiki', $content, $params); //required by FCKeditor
+						break;
+					case 'math':
+						$output = $wgContLang->armourMath( MathRenderer::renderMath( $content ) );
+						break;
+					case 'gallery':
+						$output = $this->renderImageGallery( $content, $params );
+						break;
+					default:
+						if( isset( $this->mTagHooks[$tagName] ) ) {
+							$this->fck_mw_taghook = $tagName; //required by FCKeditor
+							$output = call_user_func_array( $this->mTagHooks[$tagName],
+							array( $content, $params, $this ) );
+						} else {
+							throw new MWException( "Invalid call hook $element" );
+						}
+				}
+				wfProfileOut( __METHOD__."-render-$tagName" );
+			} else {
+				// Just stripping tags; keep the source
+				$output = $tag;
+			}
+
+			// Unstrip the output, to support recursive strip() calls
+			$output = $state->unstripBoth( $output );
+
+			if( !$stripcomments && $element == '!--' ) {
+				$commentState->setPair( $marker, $output );
+			} elseif ( $element == 'html' || $element == 'nowiki' ) {
+				$nowikiItems[$marker] = $output;
+			} else {
+				$generalItems[$marker] = $output;
+			}
+		}
+		# Add the new items to the state
+		# We do this after the loop instead of during it to avoid slowing
+		# down the recursive unstrip
+		$state->nowiki->mergeArray( $nowikiItems );
+		$state->general->mergeArray( $generalItems );
+
+		# Unstrip comments unless explicitly told otherwise.
+		# (The comments are always stripped prior to this point, so as to
+		# not invoke any extension tags / parser hooks contained within
+		# a comment.)
+		if ( !$stripcomments ) {
+			// Put them all back and forget them
+			$text = $commentState->replace( $text );
+		}
+
+		wfProfileOut( __METHOD__ );
+		return $text;
+	}
+
+	/** Replace HTML comments with unique text using fck_addToStrtr function
+	 *
+	 * @private
+	 * @param string $text
+	 * @return string
+	 */
+	private function fck_replaceHTMLcomments( $text ) {
+		wfProfileIn( __METHOD__ );
+		while (($start = strpos($text, '<!--')) !== false) {
+			$end = strpos($text, '-->', $start + 4);
+			if ($end === false) {
+				# Unterminated comment; bail out
+				break;
+			}
+
+			$end += 3;
+
+			# Trim space and newline if the comment is both
+			# preceded and followed by a newline
+			$spaceStart = max($start - 1, 0);
+			$spaceLen = $end - $spaceStart;
+			while (substr($text, $spaceStart, 1) === ' ' && $spaceStart > 0) {
+				$spaceStart--;
+				$spaceLen++;
+			}
+			while (substr($text, $spaceStart + $spaceLen, 1) === ' ')
+			$spaceLen++;
+			if (substr($text, $spaceStart, 1) === "\n" and substr($text, $spaceStart + $spaceLen, 1) === "\n") {
+				# Remove the comment, leading and trailing
+				# spaces, and leave only one newline.
+				$replacement = $this->fck_addToStrtr(substr($text, $spaceStart, $spaceLen+1));
+				$text = substr_replace($text, $replacement."\n", $spaceStart, $spaceLen + 1);
+			}
+			else {
+				# Remove just the comment.
+				$replacement = $this->fck_addToStrtr(substr($text, $start, $end - $start));
+				$text = substr_replace($text, $replacement, $start, $end - $start);
+			}
+		}
+		wfProfileOut( __METHOD__ );
+
+		return $text;
+	}
+
+	function replaceInternalLinks( $text ) {
+		return parent::replaceInternalLinks($text);
+	}
+
+	function makeImage( $nt, $options ) {
+		FCKeditorParser::$fkc_mw_makeImage_options = $options;
+		return parent::makeImage( $nt, $options );
+	}
+
+	/**
+	 * Replace templates with unique text to preserve them from parsing
+	 *
+	 * @todo if {{template}} is inside string that also must be returned unparsed, 
+	 * e.g. <noinclude>{{template}}</noinclude>
+	 * {{template}} replaced with Fckmw[n]fckmw which is wrong...
+	 * 
+	 * @param string $text
+	 * @return string
+	 */
+	private function fck_replaceTemplates( $text ) {
+
+		$callback = array('{' =>
+		array(
+		'end'=>'}',
+		'cb' => array(
+		2=>array('FCKeditorParser', 'fck_leaveTemplatesAlone'),
+		3=>array('FCKeditorParser', 'fck_leaveTemplatesAlone'),
+		),
+		'min' =>2,
+		'max' =>3,
+		)
+		);
+
+		$text = $this->replace_callback($text, $callback);
+
+		$tags = array();
+		$offset=0;
+		$textTmp = $text;
+		while (false !== ($pos = strpos($textTmp, "<!--FCK_SKIP_START-->")))
+		{
+			$tags[abs($pos + $offset)] = 1;
+			$textTmp = substr($textTmp, $pos+21);
+			$offset += $pos + 21;
+		}
+
+		$offset=0;
+		$textTmp = $text;
+		while (false !== ($pos = strpos($textTmp, "<!--FCK_SKIP_END-->")))
+		{
+			$tags[abs($pos + $offset)] = -1;
+			$textTmp = substr($textTmp, $pos+19);
+			$offset += $pos + 19;
+		}
+
+		if (!empty($tags)) {
+			ksort($tags);
+
+			$strtr = array("<!--FCK_SKIP_START-->" => "", "<!--FCK_SKIP_END-->" => "");
+
+			$sum=0;
+			$lastSum=0;
+			$finalString = "";
+			$stringToParse = "";
+			$startingPos = 0;
+			$inner = "";
+			$strtr_span = array();
+			foreach ($tags as $pos=>$type) {
+				$sum += $type;
+				if ($sum == 1 && $lastSum == 0) {
+					$stringToParse .= strtr(substr($text, $startingPos, $pos - $startingPos), $strtr);
+					$startingPos = $pos;
+				}
+				else if ($sum == 0) {
+					$stringToParse .= 'Fckmw'.$this->fck_mw_strtr_span_counter.'fckmw';
+					$inner = htmlspecialchars(strtr(substr($text, $startingPos, $pos - $startingPos + 19), $strtr));
+					$this->fck_mw_strtr_span['href="Fckmw'.$this->fck_mw_strtr_span_counter.'fckmw"'] = 'href="'.$inner.'"';
+					$this->fck_mw_strtr_span['Fckmw'.$this->fck_mw_strtr_span_counter.'fckmw'] = '<span class="fck_mw_template">'.$inner.'</span>';
+					$startingPos = $pos + 19;
+					$this->fck_mw_strtr_span_counter++;
+				}
+				$lastSum = $sum;
+			}
+			$stringToParse .= substr($text, $startingPos);
+			$text = &$stringToParse;
+		}
+
+		return $text;
+	}
+
+	function internalParse ( $text ) {
+
+		$this->fck_internal_parse_text =& $text;
+
+		//these three tags should remain unchanged
+		$text = StringUtils::delimiterReplaceCallback( '<includeonly>', '</includeonly>', array($this, 'fck_includeonly'), $text );
+		$text = StringUtils::delimiterReplaceCallback( '<noinclude>', '</noinclude>', array($this, 'fck_noinclude'), $text );
+		$text = StringUtils::delimiterReplaceCallback( '<onlyinclude>', '</onlyinclude>', array($this, 'fck_onlyinclude'), $text );
+
+		//html comments shouldn't be stripped
+		$text = $this->fck_replaceHTMLcomments( $text );
+		//as well as templates
+		$text = $this->fck_replaceTemplates( $text );
+
+		$finalString = parent::internalParse($text);
+
+		return $finalString;
+	}
+	function fck_includeonly( $matches ) {
+		return $this->fck_wikiTag('includeonly', $matches[1]);
+	}
+	function fck_noinclude( $matches ) {
+		return $this->fck_wikiTag('noinclude', $matches[1]);
+	}
+	function fck_onlyinclude( $matches ) {
+		return $this->fck_wikiTag('onlyinclude', $matches[1]);
+	}
+	function fck_leaveTemplatesAlone( $matches ) {
+		return "<!--FCK_SKIP_START-->".$matches['text']."<!--FCK_SKIP_END-->";
+	}
+	function formatHeadings( $text, $isMain=true ) {
+		return $text;
+	}
+	function replaceFreeExternalLinks( $text ) { return $text; }
+	function stripNoGallery($text) {}
+	function stripToc( $text ) {
+		//$prefix = '<span class="fck_mw_magic">';
+		//$suffix = '</span>';
+		$prefix = '';
+		$suffix = '';
+
+		$strtr = array();
+		foreach ($this->FCKeditorMagicWords as $word) {
+			$strtr[$word] = $prefix . $word . $suffix;
+		}
+
+		return strtr( $text, $strtr );
+	}
+
+	function parse( $text, &$title, $options, $linestart = true, $clearState = true, $revid = null ) {
+		$parserOutput = parent::parse($text, $title, $options, $linestart , $clearState , $revid );
+
+		$categories = $parserOutput->getCategories();
+		if ($categories) {
+			$appendString = "";
+			foreach ($categories as $cat=>$val) {
+				$appendString .= "<a href=\"Category:" . $cat ."\">Category:" . $cat ."</a> ";
+			}
+			$parserOutput->setText($parserOutput->getText() . $appendString);
+		}
+
+		if (!empty($this->fck_mw_strtr_span)) {
+			$parserOutput->setText(strtr($parserOutput->getText(), $this->fck_mw_strtr_span));
+		}
+
+		return $parserOutput;
+	}
+
+	/**
+	 * Make lists from lines starting with ':', '*', '#', etc.
+	 *
+	 * @private
+	 * @return string the lists rendered as HTML
+	 */
+	function doBlockLevels( $text, $linestart ) {
+		$fname = 'Parser::doBlockLevels';
+		wfProfileIn( $fname );
+
+		# Parsing through the text line by line.  The main thing
+		# happening here is handling of block-level elements p, pre,
+		# and making lists from lines starting with * # : etc.
+		#
+		$textLines = explode( "\n", $text );
+
+		$lastPrefix = $output = '';
+		$this->mDTopen = $inBlockElem = false;
+		$prefixLength = 0;
+		$paragraphStack = false;
+
+		if ( !$linestart ) {
+			$output .= array_shift( $textLines );
+		}
+		foreach ( $textLines as $oLine ) {
+			$lastPrefixLength = strlen( $lastPrefix );
+			$preCloseMatch = preg_match('/<\\/pre/i', $oLine );
+			$preOpenMatch = preg_match('/<pre/i', $oLine );
+			if ( !$this->mInPre ) {
+				# Multiple prefixes may abut each other for nested lists.
+				$prefixLength = strspn( $oLine, '*#:;' );
+				$pref = substr( $oLine, 0, $prefixLength );
+
+				# eh?
+				$pref2 = str_replace( ';', ':', $pref );
+				$t = substr( $oLine, $prefixLength );
+				$this->mInPre = !empty($preOpenMatch);
+			} else {
+				# Don't interpret any other prefixes in preformatted text
+				$prefixLength = 0;
+				$pref = $pref2 = '';
+				$t = $oLine;
+			}
+
+			# List generation
+			if( $prefixLength && 0 == strcmp( $lastPrefix, $pref2 ) ) {
+				# Same as the last item, so no need to deal with nesting or opening stuff
+				$output .= $this->nextItem( substr( $pref, -1 ) );
+				$paragraphStack = false;
+
+				if ( substr( $pref, -1 ) == ';') {
+					# The one nasty exception: definition lists work like this:
+					# ; title : definition text
+					# So we check for : in the remainder text to split up the
+					# title and definition, without b0rking links.
+					$term = $t2 = '';
+					if ($this->findColonNoLinks($t, $term, $t2) !== false) {
+						$t = $t2;
+						$output .= $term . $this->nextItem( ':' );
+					}
+				}
+			} elseif( $prefixLength || $lastPrefixLength ) {
+				# Either open or close a level...
+				$commonPrefixLength = $this->getCommon( $pref, $lastPrefix );
+				$paragraphStack = false;
+
+				while( $commonPrefixLength < $lastPrefixLength ) {
+					$output .= $this->closeList( $lastPrefix{$lastPrefixLength-1} );
+					--$lastPrefixLength;
+				}
+				if ( $prefixLength <= $commonPrefixLength && $commonPrefixLength > 0 ) {
+					$output .= $this->nextItem( $pref{$commonPrefixLength-1} );
+				}
+				while ( $prefixLength > $commonPrefixLength ) {
+					$char = substr( $pref, $commonPrefixLength, 1 );
+					$output .= $this->openList( $char );
+
+					if ( ';' == $char ) {
+						# FIXME: This is dupe of code above
+						if ($this->findColonNoLinks($t, $term, $t2) !== false) {
+							$t = $t2;
+							$output .= $term . $this->nextItem( ':' );
+						}
+					}
+					++$commonPrefixLength;
+				}
+				$lastPrefix = $pref2;
+			}
+			if( 0 == $prefixLength ) {
+				wfProfileIn( "$fname-paragraph" );
+				# No prefix (not in list)--go to paragraph mode
+				// XXX: use a stack for nestable elements like span, table and div
+				$openmatch = preg_match('/(?:<table|<blockquote|<h1|<h2|<h3|<h4|<h5|<h6|<pre|<tr|<p|<ul|<ol|<li|<\\/tr|<\\/td|<\\/th)/iS', $t );
+				$closematch = preg_match(
+				'/(?:<\\/table|<\\/blockquote|<\\/h1|<\\/h2|<\\/h3|<\\/h4|<\\/h5|<\\/h6|'.
+				'<td|<th|<\\/?div|<hr|<\\/pre|<\\/p|'.$this->mUniqPrefix.'-pre|<\\/li|<\\/ul|<\\/ol|<\\/?center)/iS', $t );
+				if ( $openmatch or $closematch ) {
+					$paragraphStack = false;
+					# TODO bug 5718: paragraph closed
+					$output .= $this->closeParagraph();
+					if ( $preOpenMatch and !$preCloseMatch ) {
+						$this->mInPre = true;
+					}
+					if ( $closematch ) {
+						$inBlockElem = false;
+					} else {
+						$inBlockElem = true;
+					}
+				} else if ( !$inBlockElem && !$this->mInPre ) {
+					if ( ' ' == $t{0} and ( $this->mLastSection == 'pre' or trim($t) != '' ) ) {
+						// pre
+						if ($this->mLastSection != 'pre') {
+							$paragraphStack = false;
+							$output .= $this->closeParagraph().'<pre class="_fck_mw_lspace">';
+							$this->mLastSection = 'pre';
+						}
+						$t = substr( $t, 1 );
+					} else {
+						// paragraph
+						if ( '' == trim($t) ) {
+							if ( $paragraphStack ) {
+								$output .= $paragraphStack.'<br />';
+								$paragraphStack = false;
+								$this->mLastSection = 'p';
+							} else {
+								if ($this->mLastSection != 'p' ) {
+									$output .= $this->closeParagraph();
+									$this->mLastSection = '';
+									$paragraphStack = '<p>';
+								} else {
+									$paragraphStack = '</p><p>';
+								}
+							}
+						} else {
+							if ( $paragraphStack ) {
+								$output .= $paragraphStack;
+								$paragraphStack = false;
+								$this->mLastSection = 'p';
+							} else if ($this->mLastSection != 'p') {
+								$output .= $this->closeParagraph().'<p>';
+								$this->mLastSection = 'p';
+							}
+						}
+					}
+				}
+				wfProfileOut( "$fname-paragraph" );
+			}
+			// somewhere above we forget to get out of pre block (bug 785)
+			if($preCloseMatch && $this->mInPre) {
+				$this->mInPre = false;
+			}
+			if ($paragraphStack === false) {
+				$output .= $t."\n";
+			}
+		}
+		while ( $prefixLength ) {
+			$output .= $this->closeList( $pref2{$prefixLength-1} );
+			--$prefixLength;
+		}
+		if ( '' != $this->mLastSection ) {
+			$output .= '</' . $this->mLastSection . '>';
+			$this->mLastSection = '';
+		}
+
+		wfProfileOut( $fname );
+		return $output;
+	}
+}
Index: /MediaWiki/trunk/FCKeditorParserOptions.body.php
===================================================================
--- /MediaWiki/trunk/FCKeditorParserOptions.body.php	(revision 1660)
+++ /MediaWiki/trunk/FCKeditorParserOptions.body.php	(revision 1660)
@@ -0,0 +1,14 @@
+<?php
+
+class FCKeditorParserOptions extends ParserOptions
+{
+	function getNumberHeadings() {return false;}
+	function getEditSection() {return false;}
+
+	function getSkin() {
+		if ( !isset( $this->mSkin ) ) {
+			$this->mSkin = new FCKeditorSkin( $this->mUser->getSkin() );
+		}
+		return $this->mSkin;
+	}
+}
Index: /MediaWiki/trunk/FCKeditorSajax.body.php
===================================================================
--- /MediaWiki/trunk/FCKeditorSajax.body.php	(revision 1660)
+++ /MediaWiki/trunk/FCKeditorSajax.body.php	(revision 1660)
@@ -0,0 +1,134 @@
+<?php
+
+function wfSajaxGetMathUrl( $term )
+{
+	$originalLink = MathRenderer::renderMath( $term );
+
+	if (false == strpos($originalLink, "src=\"")) {
+		return "";
+	}
+
+	$srcPart = substr($originalLink, strpos($originalLink, "src=")+ 5);
+	$url = strtok($srcPart, '"');
+
+	return $url;
+}
+
+function wfSajaxGetImageUrl( $term )
+{
+	global $wgExtensionFunctions, $wgTitle;
+
+	$options = new FCKeditorParserOptions();
+	$options->setTidy(true);
+	$parser = new FCKeditorParser();
+
+	if (in_array("wfCite", $wgExtensionFunctions)) {
+		$parser->setHook('ref', array($parser, 'ref'));
+		$parser->setHook('references', array($parser, 'references'));
+	}
+	$parser->setOutputType(OT_HTML);
+	$originalLink = $parser->parse("[[Image:".$term."]]", $wgTitle, $options)->getText();
+	if (false == strpos($originalLink, "src=\"")) {
+		return "";
+	}
+
+	$srcPart = substr($originalLink, strpos($originalLink, "src=")+ 5);
+	$url = strtok($srcPart, '"');
+
+	return $url;
+}
+
+function wfSajaxSearchImageFCKeditor( $term )
+{
+	global $wgContLang, $wgOut;
+	$limit = 10;
+
+	$term = $wgContLang->checkTitleEncoding( $wgContLang->recodeInput( js_unescape( $term ) ) );
+	$term1 = str_replace( ' ', '_', $wgContLang->ucfirst( $term ) );
+	$term2 = str_replace( ' ', '_', $wgContLang->lc( $term ) );
+	$term3 = str_replace( ' ', '_', $wgContLang->uc( $term ) );
+	$term = $term1;
+
+	if ( strlen( str_replace( '_', '', $term ) )<3 )
+	return "";
+
+	$db =& wfGetDB( DB_SLAVE );
+	$res = $db->select( 'page', 'page_title',
+	array(  'page_namespace' => NS_IMAGE,
+	"LOWER(page_title) LIKE '%". $db->strencode( $term2 ) ."%'" ),
+	"wfSajaxSearch",
+	array( 'LIMIT' => $limit+1 )
+	);
+
+	$ret = "";
+	$i=0;
+	while ( ( $row = $db->fetchObject( $res ) ) && ( ++$i <= $limit ) ) {
+		$ret .= $row->page_title ."\n";
+	}
+
+	$term = htmlspecialchars( $term );
+
+	return $ret;
+}
+
+function wfSajaxSearchArticleFCKeditor( $term )
+{
+	global $wgContLang, $wgOut;
+	$limit = 10;
+	$ns = NS_MAIN;
+
+	$term = $wgContLang->checkTitleEncoding( $wgContLang->recodeInput( js_unescape( $term ) ) );
+
+	if (strpos($term, "Category:") === 0) {
+		$ns = NS_CATEGORY;
+		$term = substr($term, 9);
+		$prefix = "Category:";
+	}
+	else if (strpos($term, ":Category:") === 0) {
+		$ns = NS_CATEGORY;
+		$term = substr($term, 10);
+		$prefix = ":Category:";
+	}
+
+	$term1 = str_replace( ' ', '_', $wgContLang->ucfirst( $term ) );
+	$term2 = str_replace( ' ', '_', $wgContLang->lc( $term ) );
+	$term3 = str_replace( ' ', '_', $wgContLang->uc( $term ) );
+	$term = $term1;
+
+	if ( strlen( str_replace( '_', '', $term ) )<3 ) {
+		return "";
+	}
+
+	$db =& wfGetDB( DB_SLAVE );
+	$res = $db->select( 'page', 'page_title',
+	array(  'page_namespace' => $ns,
+	"LOWER(page_title) LIKE '%". $db->strencode( $term2 ) ."%'" ),
+	"wfSajaxSearch",
+	array( 'LIMIT' => $limit+1 )
+	);
+
+	$ret = "";
+	$i=0;
+	while ( ( $row = $db->fetchObject( $res ) ) && ( ++$i <= $limit ) ) {
+		if (isset($prefix) && !is_null($prefix)) {
+			$ret .= $prefix;
+		}
+		$ret .= $row->page_title ."\n";
+	}
+
+	$term = htmlspecialchars( $term );
+
+	return $ret;
+}
+
+function wfSajaxWikiToHTML( $wiki )
+{
+	global $wgTitle;
+
+	$options = new FCKeditorParserOptions();
+	$options->setTidy(true);
+	$parser = new FCKeditorParser();
+	$parser->setOutputType(OT_HTML);
+
+	return $parser->parse($wiki, $wgTitle, $options)->getText();
+}
Index: /MediaWiki/trunk/FCKeditorSkin.body.php
===================================================================
--- /MediaWiki/trunk/FCKeditorSkin.body.php	(revision 1660)
+++ /MediaWiki/trunk/FCKeditorSkin.body.php	(revision 1660)
@@ -0,0 +1,346 @@
+<?php
+
+class FCKeditorSkin
+{
+	private $skin;
+
+	/**
+	 * Create image link in MediaWiki 1.10
+	 *
+	 * @param Title $nt
+	 * @param string $label label text
+	 * @param string $alt alt text
+	 * @param string $align horizontal alignment: none, left, center, right)
+	 * @param array $params Parameters to be passed to the media handler
+	 * @param boolean $framed shows image in original size in a frame
+	 * @param boolean $thumb shows image as thumbnail in a frame
+	 * @param string $manual_thumb image name for the manual thumbnail
+	 * @param string $valign vertical alignment: baseline, sub, super, top, text-top, middle, bottom, text-bottom
+	 * @return string     * 
+	 */
+	function makeImageLinkObj( $nt, $label, $alt, $align = '', $params = array(), $framed = false,
+	$thumb = false, $manual_thumb = '', $valign = '' )
+	{
+		$orginal = $nt->getText();
+		$img   = new Image( $nt );
+		$imgName = $img->getName();
+		$found = $img->getURL();
+
+		if ($found) {
+			//trick to get real Url for image:
+			$originalLink = strip_tags(Linker::makeImageLinkObj($nt, $label, $alt, $align , $params , $framed , $thumb , $manual_thumb , $valign ), "<img>");
+			$srcPart = substr($originalLink, strpos($originalLink, "src=")+ 5);
+			$url = strtok($srcPart, '"');
+		}
+
+		$ret = "<img ";
+
+		if ($found) {
+			$ret .= "src=\"{$url}\" ";
+		}
+		else {
+			$ret .= "_fck_mw_valid=\"false"."\" ";
+		}
+		$ret .= "_fck_mw_filename=\"{$orginal}\" ";
+
+		if ($align) {
+			$ret .= "_fck_mw_location=\"".strtolower($align)."\" ";
+		}
+		if (!empty($params)) {
+			if (isset($params['width'])) {
+				$ret .= "_fck_mw_width=\"".$params['width']."\" ";
+			}
+			if (isset($params['height'])) {
+				$ret .= "_fck_mw_height=\"".$params['height']."\" ";
+			}
+		}
+		$class = "";
+		if ($thumb) {
+			$ret .= "_fck_mw_type=\"thumb"."\" ";
+			$class .= "fck_mw_frame";
+		}
+		else if ($framed) {
+			$ret .= "_fck_mw_type=\"frame"."\" ";
+			$class .= "fck_mw_frame";
+		}
+
+		if ($align == "right") {
+			$class .= ($class?" ":"") . "fck_mw_right";
+		}
+		else if($align == "center") {
+			$class .= ($class?" ":"") . "fck_mw_center";
+		}
+		else if($align == "left") {
+			$class .= ($class?" ":"") . "fck_mw_left";
+		}
+		else if($framed || $thumb) {
+			$class .= ($class?" ":"") . "fck_mw_right";
+		}
+
+		if (!$found) {
+			$class .= ($class?" ":"") . "fck_mw_notfound";
+		}
+
+		if (!is_null($alt) && !empty($alt) && false !== strpos(FCKeditorParser::$fkc_mw_makeImage_options, $alt) && $alt != "Image:" . $orginal) {
+			$ret .= "alt=\"".htmlspecialchars($alt)."\" ";
+		}
+		else {
+			$ret .= "alt=\"\" ";
+		}
+
+		if ($class) {
+			$ret .= "class=\"$class\" ";
+		}
+
+		$ret .= "/>";
+
+		return $ret;
+	}
+
+	/**
+	 * Make an image link in Mediawiki 1.11
+	 * @param Title $title Title object
+	 * @param File $file File object, or false if it doesn't exist
+	 *
+	 * @param array $frameParams Associative array of parameters external to the media handler.
+	 *     Boolean parameters are indicated by presence or absence, the value is arbitrary and 
+	 *     will often be false.
+	 *          thumbnail       If present, downscale and frame
+	 *          manualthumb     Image name to use as a thumbnail, instead of automatic scaling
+	 *          framed          Shows image in original size in a frame
+	 *          frameless       Downscale but don't frame
+	 *          upright         If present, tweak default sizes for portrait orientation
+	 *          upright_factor  Fudge factor for "upright" tweak (default 0.75)
+	 *          border          If present, show a border around the image
+	 *          align           Horizontal alignment (left, right, center, none)
+	 *          valign          Vertical alignment (baseline, sub, super, top, text-top, middle, 
+	 *                          bottom, text-bottom)
+	 *          alt             Alternate text for image (i.e. alt attribute). Plain text.
+	 *          caption         HTML for image caption.
+	 *
+	 * @param array $handlerParams Associative array of media handler parameters, to be passed 
+	 *       to transform(). Typical keys are "width" and "page". 
+	 */
+	function makeImageLink2( Title $nt, $file, $frameParams = array(), $handlerParams = array() ) {
+		$orginal = $nt->getText();
+		$img   = new Image( $nt );
+		$imgName = $img->getName();
+		$found = $img->getURL();
+
+		if ($found) {
+			$originalLink = Linker::makeImageLink2( $nt, $file, $frameParams, $handlerParams);
+
+			if (false !== strpos($originalLink, "src=\"")) {
+				$srcPart = substr($originalLink, strpos($originalLink, "src=")+ 5);
+				$url = strtok($srcPart, '"');
+			}
+			$srcPart = substr($originalLink, strpos($originalLink, "src=")+ 5);
+			$url = strtok($srcPart, '"');
+		}
+
+		// Shortcuts
+		$fp =& $frameParams;
+		$hp =& $handlerParams;
+
+		if (!isset($fp['align'])) {
+			$fp['align'] = '';
+		}
+
+		$ret = "<img ";
+
+		if ($found) {
+			$ret .= "src=\"{$url}\" ";
+		}
+		else {
+			$ret .= "_fck_mw_valid=\"false"."\" ";
+		}
+		$ret .= "_fck_mw_filename=\"{$orginal}\" ";
+
+		if ($fp['align']) {
+			$ret .= "_fck_mw_location=\"".strtolower($fp['align'])."\" ";
+		}
+		if (!empty($hp)) {
+			if (isset($hp['width'])) {
+				$ret .= "_fck_mw_width=\"".$hp['width']."\" ";
+			}
+			if (isset($hp['height'])) {
+				$ret .= "_fck_mw_height=\"".$hp['height']."\" ";
+			}
+		}
+		$class = "";
+		if (isset($fp['thumbnail'])) {
+			$ret .= "_fck_mw_type=\"thumb"."\" ";
+			$class .= "fck_mw_frame";
+		}
+		else if (isset($fp['framed'])) {
+			$ret .= "_fck_mw_type=\"frame"."\" ";
+			$class .= "fck_mw_frame";
+		}
+
+		if ($fp['align'] == "right") {
+			$class .= ($class?" ":"") . "fck_mw_right";
+		}
+		else if($fp['align'] == "center") {
+			$class .= ($class?" ":"") . "fck_mw_center";
+		}
+		else if($fp['align'] == "left") {
+			$class .= ($class?" ":"") . "fck_mw_left";
+		}
+		else if(isset($fp['framed']) || isset($fp['thumbnail'])) {
+			$class .= ($class?" ":"") . "fck_mw_right";
+		}
+
+		if (!$found) {
+			$class .= ($class?" ":"") . "fck_mw_notfound";
+		}
+
+		if (isset($fp['alt']) && !empty($fp['alt']) && false !== strpos(FCKeditorParser::$fkc_mw_makeImage_options, $fp['alt']) && $fp['alt'] != "Image:" . $orginal) {
+			$ret .= "alt=\"".htmlspecialchars($fp['alt'])."\" ";
+		}
+		else {
+			$ret .= "alt=\"\" ";
+		}
+
+		if ($class) {
+			$ret .= "class=\"$class\" ";
+		}
+
+		$ret .= "/>";
+
+		return $ret;
+	}
+
+	function makeKnownLinkObj( $nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '', $style = '' )
+	{
+		$fname = 'FCKeditorSkin::makeKnownLinkObj';
+		wfProfileIn( $fname );
+
+		if ( !is_object( $nt ) ) {
+			wfProfileOut( $fname );
+			return $text;
+		}
+
+		//$u = $nt->escapeLocalURL( $query );
+		$u = $nt->getFullText();
+
+		if ( $nt->getFragment() != '' ) {
+			if( $nt->getPrefixedDbkey() == '' ) {
+				$u = '';
+				if ( '' == $text ) {
+					$text = htmlspecialchars( $nt->getFragment() );
+				}
+			}
+			//see ticket 1386 why it is commented
+			//$u .= $nt->getFragmentForURL();
+		}
+		if ( $text == '' ) {
+			$text = htmlspecialchars( $nt->getPrefixedText() );
+		}
+
+		if ($nt->getNamespace() == NS_CATEGORY) {
+			$u = ':' . $u;
+		}
+
+		list( $inside, $trail ) = Linker::splitTrail( $trail );
+		$r = "<a href=\"{$u}\">{$prefix}{$text}{$inside}</a>{$trail}";
+		wfProfileOut( $fname );
+		return $r;
+	}
+
+	function makeBrokenLinkObj( $nt, $text = '', $query = '', $trail = '', $prefix = '' )
+	{
+		# Fail gracefully
+		if ( ! isset($nt) ) {
+			# throw new MWException();
+			return "<!-- ERROR -->{$prefix}{$text}{$trail}";
+		}
+
+		$fname = 'FCKeditorSkin::makeBrokenLinkObj';
+		wfProfileIn( $fname );
+
+		$u = $nt->getFullText();
+
+		if ( '' == $text ) {
+			$text = htmlspecialchars( $nt->getPrefixedText() );
+		}
+		if ($nt->getNamespace() == NS_CATEGORY) {
+			$u = ':' . $u;
+		}
+
+		list( $inside, $trail ) = Linker::splitTrail( $trail );
+		$s = "<a href=\"{$u}\">{$prefix}{$text}{$inside}</a>{$trail}";
+
+		wfProfileOut( $fname );
+		return $s;
+	}
+
+	/**
+	 * Create a direct link to a given uploaded file.
+	 *
+	 * @param $title Title object.
+	 * @param $text  String: pre-sanitized HTML
+	 * @return string HTML
+	 *
+	 * @public
+	 * @todo Handle invalid or missing images better.
+	 */
+	function makeMediaLinkObj( $title, $text = '' ) {
+		if( is_null( $title ) ) {
+			### HOTFIX. Instead of breaking, return empty string.
+			return $text;
+		} else {
+			$orginal = $title->getPartialURL();
+			// Mediawiki 1.11
+			if ( function_exists('wfFindFile') ) {
+				$img  = wfFindFile( $title );
+				if( $img ) {
+					$url  = $img->getURL();
+					$class = 'internal';
+				} else {
+					$upload = SpecialPage::getTitleFor( 'Upload' );
+					$url = $upload->getLocalUrl( 'wpDestFile=' . urlencode( $title->getDbKey() ) );
+					$class = 'new';
+				}
+			}
+			// Mediawiki 1.10
+			else {
+				$img  = new Image( $title );
+				if( $img->exists() ) {
+					$url  = $img->getURL();
+					$class = 'internal';
+				} else {
+					$upload = SpecialPage::getTitleFor( 'Upload' );
+					$url = $upload->getLocalUrl( 'wpDestFile=' . urlencode( $img->getName() ) );
+					$class = 'new';
+				}
+			}
+			$alt = htmlspecialchars( $title->getText() );
+			if( $text == '' ) {
+				$text = $alt;
+			}
+			$u = htmlspecialchars( $url );
+			return "<a href=\"{$orginal}\" class=\"$class\" _fck_mw_filename=\"{$orginal}\" _fck_mw_type=\"media\" title=\"{$alt}\">{$text}</a>";
+		}
+	}
+
+	function makeExternalLink( $url, $text, $escape = true, $linktype = '', $ns = null ) {
+		$url = htmlspecialchars( $url );
+		if( $escape ) {
+			$text = htmlspecialchars( $text );
+		}
+		if ($linktype == 'autonumber') {
+			return '<a href="'.$url.'">[n]</a>';
+		}
+		return '<a href="'.$url.'">'.$text.'</a>';
+	}
+
+	function __call( $m, $a)
+	{
+		return call_user_func_array( array( $this->skin, $m ), $a );
+	}
+
+	function __construct( &$skin )
+	{
+		$this->skin = $skin;
+	}
+}
Index: /MediaWiki/trunk/css/fckeditor.css
===================================================================
--- /MediaWiki/trunk/css/fckeditor.css	(revision 1660)
+++ /MediaWiki/trunk/css/fckeditor.css	(revision 1660)
@@ -0,0 +1,1651 @@
+/*
+** MediaWiki 'monobook' style sheet for CSS2-capable browsers.
+** Copyright Gabriel Wicke - http://wikidev.net/
+** License: GPL (http://www.gnu.org/copyleft/gpl.html)
+**
+** Loosely based on http://www.positioniseverything.net/ordered-floats.html by Big John
+** and the Plone 2.0 styles, see http://plone.org/ (Alexander Limi,Joe Geldart & Tom Croucher,
+** Michael Zeltner and Geir Bækholt)
+** All you guys rock :)
+*/
+
+/**
+ * Stylesheet for screen/projection.  All rules not marked media-specific are
+ * shared with handheld.css and should be updated in tandem.  The rules can't
+ * be in the same file because old browsers like IE5 won't obey @media rules.
+ *
+ * Rules that are screen/projection-specific are marked with commented-out
+ * @media rules and indentation.
+ */
+
+/* @media screen, projection { */
+	#column-one {
+		padding-top: 160px;
+	}
+/* } */
+/* the left column width is specified in class .portlet */
+
+/* Font size:
+** We take advantage of keyword scaling- browsers won't go below 9px
+** More at http://www.w3.org/2003/07/30-font-size
+** http://style.cleverchimp.com/font_size_intervals/altintervals.html
+*/
+
+body {
+	color: black;
+	margin: 0;
+	padding: 0;
+	font: 83% sans-serif;
+	width: 100%;
+	background: white;
+	line-height: 1.5em;
+}
+
+/* scale back up to a sane default */
+.visualClear {
+	clear: both;
+}
+
+/* general styles */
+
+table {
+	font-size: 100%;
+	color: black;
+	/* we don't want the bottom borders of <h2>s to be visible through
+	   floated tables */
+	background-color: white;
+	margin: 0 0 0 5px;
+}
+a {
+	text-decoration: underline !important;
+	color: #002bb8 !important;
+	background: none;
+}
+a:visited {
+	color: #002bb8 !important;
+}
+a:active {
+	color: #002bb8 !important;
+}
+a:hover {
+	text-decoration: underline;
+}
+a.stub {
+	color: #772233;
+}
+a.new, #p-personal a.new {
+	color: #ba0000;
+}
+a.new:visited, #p-personal a.new:visited {
+	color: #a55858;
+}
+
+img {
+	border: none;
+	vertical-align: middle;
+}
+/* @media screen, projection { */
+	p {
+		margin: .4em 0 .5em 5px;
+		line-height: 1.5em;
+	}
+/* } */
+p img {
+	margin: 0;
+}
+
+hr {
+	height: 1px;
+	color: #aaa;
+	background-color: #aaa;
+	border: 0;
+	margin: .2em 0 .2em 0;
+}
+
+h1, h2, h3, h4, h5, h6 {
+	color: black;
+	background: none;
+	font-weight: normal;
+	margin: 0 0 0 5px;
+	padding-top: .5em;
+	padding-bottom: .17em;
+	border-bottom: 1px solid #aaa;
+}
+h1 { font-size: 188%; }
+h1 .editsection { font-size: 53%; }
+h2 { font-size: 150%; }
+h2 .editsection { font-size: 67%; }
+h3, h4, h5, h6 {
+	border-bottom: none;
+	font-weight: bold;
+}
+h3 { font-size: 132%; }
+h3 .editsection { font-size: 76%; font-weight: normal; }
+h4 { font-size: 116%; }
+h4 .editsection { font-size: 86%; font-weight: normal; }
+h5 { font-size: 100%; }
+h5 .editsection { font-weight: normal; }
+h6 { font-size: 80%;  }
+h6 .editsection { font-size: 125%; font-weight: normal; }
+
+.editsection {
+	float: right;
+	margin-left: 5px;
+}
+
+ul {
+	line-height: 1.5em;
+	list-style-type: square;
+	margin: .3em 0 0 1.5em;
+	padding: 0;
+	list-style-image: url(bullet.gif);
+}
+ol {
+	line-height: 1.5em;
+	margin: .3em 0 0 3.2em;
+	padding: 0;
+	list-style-image: none;
+}
+li {
+	margin-bottom: .1em;
+}
+dt {
+	font-weight: bold;
+	margin-bottom: .1em;
+}
+dl {
+	margin-top: .2em;
+	margin-bottom: .5em;
+}
+dd {
+	line-height: 1.5em;
+	margin-left: 2em;
+	margin-bottom: .1em;
+}
+
+fieldset {
+	border: 1px solid #2f6fab;
+	margin: 1em 0 1em 0;
+	padding: 0 1em 1em;
+	line-height: 1.5em;
+}
+legend {
+	padding: .5em;
+	font-size: 95%;
+}
+form {
+	border: none;
+	margin: 0;
+}
+
+textarea {
+	width: 100%;
+	padding: .1em;
+}
+
+input.historysubmit {
+	padding: 0 .3em .3em .3em !important;
+	font-size: 94%;
+	cursor: pointer;
+	height: 1.7em !important;
+	margin-left: 1.6em;
+}
+select {
+	vertical-align: top;
+}
+abbr, acronym, .explain {
+	border-bottom: 1px dotted black;
+	color: black;
+	background: none;
+	cursor: help;
+}
+q {
+	font-family: Times, "Times New Roman", serif;
+	font-style: italic;
+}
+/* disabled for now
+blockquote {
+	font-family: Times, "Times New Roman", serif;
+	font-style: italic;
+}*/
+code {
+	background-color: #f9f9f9;
+}
+pre {
+	padding: 1em;
+	border: 1px dashed #2f6fab;
+	color: black;
+	background-color: #f9f9f9;
+	line-height: 1.1em;
+}
+
+/*
+** the main content area
+*/
+
+/* @media screen, projection { */
+	#siteSub {
+		display: none;
+	}
+	#jump-to-nav {
+		display: none;
+	}
+/* } */
+
+#contentSub, #contentSub2 {
+	font-size: 84%;
+	line-height: 1.2em;
+	margin: 0 0 1.4em 1em;
+	color: #7d7d7d;
+	width: auto;
+}
+span.subpages {
+	display: block;
+}
+
+/* Some space under the headers in the content area */
+h1, h2 {
+	margin-bottom: .6em;
+}
+h3, h4, h5 {
+	margin-bottom: .3em;
+}
+.firstHeading {
+	margin-bottom: .1em;
+}
+
+/* user notification thing */
+.usermessage {
+	background-color: #ffce7b;
+	border: 1px solid #ffa500;
+	color: black;
+	font-weight: bold;
+	margin: 2em 0 1em;
+	padding: .5em 1em;
+	vertical-align: middle;
+}
+#siteNotice {
+	text-align: center;
+	font-size: 95%;
+	padding: 0 .9em;
+}
+#siteNotice p {
+	margin: 0;
+	padding: 0;
+}
+.error {
+	color: red;
+	font-size: larger;
+}
+.errorbox, .successbox {
+	font-size: larger;
+	border: 2px solid;
+	padding: .5em 1em;
+	float: left;
+	margin-bottom: 2em;
+	color: #000;
+}
+.errorbox {
+	border-color: red;
+	background-color: #fff2f2;
+}
+.successbox {
+	border-color: green;
+	background-color: #dfd;
+}
+.errorbox h2, .successbox h2 {
+	font-size: 1em;
+	font-weight: bold;
+	display: inline;
+	margin: 0 .5em 0 0;
+	border: none;
+}
+
+#catlinks {
+	border: 1px solid #aaa;
+	background-color: #f9f9f9;
+	padding: 5px;
+	margin-top: 1em;
+	clear: both;
+}
+/* currently unused, intended to be used by a metadata box
+in the bottom-right corner of the content area */
+.documentDescription {
+	/* The summary text describing the document */
+	font-weight: bold;
+	display: block;
+	margin: 1em 0;
+	line-height: 1.5em;
+}
+.documentByLine {
+	text-align: right;
+	font-size: 90%;
+	clear: both;
+	font-weight: normal;
+	color: #76797c;
+}
+
+/* emulate center */
+.center {
+	width: 100%;
+	text-align: center;
+}
+*.center * {
+	margin-left: auto;
+	margin-right: auto;
+}
+/* small for tables and similar */
+.small, .small * {
+	font-size: 94%;
+}
+table.small {
+	font-size: 100%;
+}
+
+/*
+** content styles
+*/
+
+#toc,
+.toc,
+.mw-warning {
+	border: 1px solid #aaa;
+	background-color: #f9f9f9;
+	padding: 5px;
+	font-size: 95%;
+}
+#toc h2,
+.toc h2 {
+	display: inline;
+	border: none;
+	padding: 0;
+	font-size: 100%;
+	font-weight: bold;
+}
+#toc #toctitle,
+.toc #toctitle,
+#toc .toctitle,
+.toc .toctitle {
+	text-align: center;
+}
+#toc ul,
+.toc ul {
+	list-style-type: none;
+	list-style-image: none;
+	margin-left: 0;
+	padding-left: 0;
+	text-align: left;
+}
+#toc ul ul,
+.toc ul ul {
+	margin: 0 0 0 2em;
+}
+#toc .toctoggle,
+.toc .toctoggle {
+	font-size: 94%;
+}
+
+.mw-warning {
+	margin-left: 50px;
+	margin-right: 50px;
+	text-align: center;
+}
+
+/* images */
+div.floatright, table.floatright {
+	clear: right;
+	float: right;
+	position: relative;
+	margin: 0 0 .5em .5em;
+	border: 0;
+/*
+	border: .5em solid white;
+	border-width: .5em 0 .8em 1.4em;
+*/
+}
+div.floatright p { font-style: italic; }
+div.floatleft, table.floatleft {
+	float: left;
+	clear: left;
+	position: relative;
+	margin: 0 .5em .5em 0;
+	border: 0;
+/*
+	margin: .3em .5em .5em 0;
+	border: .5em solid white;
+	border-width: .5em 1.4em .8em 0;
+*/
+}
+div.floatleft p { font-style: italic; }
+/* thumbnails */
+div.thumb {
+	margin-bottom: .5em;
+	border-style: solid;
+	border-color: white;
+	width: auto;
+}
+div.thumbinner {
+	border: 1px solid #ccc;
+	padding: 3px !important;
+	background-color: #f9f9f9;
+	font-size: 94%;
+	text-align: center;
+	overflow: hidden;
+}
+html .thumbimage {
+	border: 1px solid #ccc;
+}
+html .thumbcaption {
+	border: none;
+	text-align: left;
+	line-height: 1.4em;
+	padding: 3px !important;
+	font-size: 94%;
+}
+div.magnify {
+	float: right;
+	border: none !important;
+	background: none !important;
+}
+div.magnify a, div.magnify img {
+	display: block;
+	border: none !important;
+	background: none !important;
+}
+div.tright {
+	clear: right;
+	float: right;
+	border-width: .5em 0 .8em 1.4em;
+}
+div.tleft {
+	float: left;
+	clear: left;
+	margin-right: .5em;
+	border-width: .5em 1.4em .8em 0;
+}
+
+.hiddenStructure {
+	display: none;
+	speak: none;
+}
+img.tex {
+	vertical-align: middle;
+}
+span.texhtml {
+	font-family: serif;
+}
+
+/* Have a checkered background on images on the description pages and in galleries
+   to make transparency visible
+
+#file img, .gallerybox .thumb img {
+	background: url(Checker-16x16.png) repeat;
+}
+*/
+
+/*
+** classes for special content elements like town boxes
+** intended to be referenced directly from the wiki src
+*/
+
+/*
+** User styles
+*/
+/* table standards */
+table.rimage {
+	float: right;
+	position: relative;
+	margin-left: 1em;
+	margin-bottom: 1em;
+	text-align: center;
+}
+.toccolours {
+	border: 1px solid #aaa;
+	background-color: #f9f9f9;
+	padding: 5px;
+	font-size: 95%;
+}
+div.townBox {
+	position: relative;
+	float: right;
+	background: white;
+	margin-left: 1em;
+	border: 1px solid gray;
+	padding: .3em;
+	width: 200px;
+	overflow: hidden;
+	clear: right;
+}
+div.townBox dl {
+	padding: 0;
+	margin: 0 0 .3em;
+	font-size: 96%;
+}
+div.townBox dl dt {
+	background: none;
+	margin: .4em 0 0;
+}
+div.townBox dl dd {
+	margin: .1em 0 0 1.1em;
+	background-color: #f3f3f3;
+}
+
+/*
+** edit views etc
+*/
+.special li {
+	line-height: 1.4em;
+	margin: 0;
+	padding: 0;
+}
+
+/* Page history styling */
+/* the auto-generated edit comments */
+.autocomment {
+	color: gray;
+}
+#pagehistory span.user {
+	margin-left: 1.4em;
+	margin-right: .4em;
+}
+#pagehistory span.minor {
+	font-weight: bold;
+}
+#pagehistory li {
+	border: 1px solid white;
+}
+#pagehistory li.selected {
+	background-color: #f9f9f9;
+	border: 1px dashed #aaa;
+}
+
+/*
+** Diff rendering
+*/
+table.diff, td.diff-otitle, td.diff-ntitle {
+	background-color: white;
+}
+td.diff-addedline {
+	background: #cfc;
+	font-size: smaller;
+}
+td.diff-deletedline {
+	background: #ffa;
+	font-size: smaller;
+}
+td.diff-context {
+	background: #eee;
+	font-size: smaller;
+}
+.diffchange {
+	color: red;
+	font-weight: bold;
+	text-decoration: none;
+}
+
+/*
+** keep the whitespace in front of the ^=, hides rule from konqueror
+** this is css3, the validator doesn't like it when validating as css2
+*/
+ a.external,
+ a[href ^="gopher://"] {
+	background: url(external.png) center right no-repeat;
+	padding-right: 13px;
+}
+ a[href ^="https://"],
+.link-https {
+	background: url(lock_icon.gif) center right no-repeat;
+	padding-right: 16px;
+}
+ a[href ^="mailto:"],
+.link-mailto {
+	background: url(mail_icon.gif) center right no-repeat;
+	padding-right: 18px;
+}
+ a[href ^="news://"] {
+	background: url(news_icon.png) center right no-repeat;
+	padding-right: 18px;
+}
+ a[href ^="ftp://"],
+.link-ftp {
+	background: url(file_icon.gif) center right no-repeat;
+	padding-right: 18px;
+}
+ a[href ^="irc://"],
+.link-irc {
+	background: url(discussionitem_icon.gif) center right no-repeat;
+	padding-right: 18px;
+}
+a.external[href $=".ogg"], a.external[href $=".OGG"],
+a.external[href $=".mid"], a.external[href $=".MID"],
+a.external[href $=".midi"], a.external[href $=".MIDI"],
+a.external[href $=".mp3"], a.external[href $=".MP3"],
+a.external[href $=".wav"], a.external[href $=".WAV"],
+a.external[href $=".wma"], a.external[href $=".WMA"],
+.link-audio {
+	background: url("audio.png") center right no-repeat;
+	padding-right: 13px;
+}
+a.external[href $=".ogm"], a.external[href $=".OGM"],
+a.external[href $=".avi"], a.external[href $=".AVI"],
+a.external[href $=".mpeg"], a.external[href $=".MPEG"],
+a.external[href $=".mpg"], a.external[href $=".MPG"],
+.link-video {
+	background: url("video.png") center right no-repeat;
+	padding-right: 13px;
+}
+a.external[href $=".pdf"], a.external[href $=".PDF"],
+a.external[href *=".pdf#"], a.external[href *=".PDF#"],
+a.external[href *=".pdf?"], a.external[href *=".PDF?"],
+.link-document {
+	background: url("document.png") center right no-repeat;
+	padding-right: 12px;
+}
+
+/* disable interwiki styling */
+a.extiw,
+a.extiw:active {
+	color: #36b;
+	background: none;
+	padding: 0;
+}
+a.external {
+	color: #36b;
+}
+/* this can be used in the content area to switch off
+special external link styling */
+.plainlinks a {
+	background: none !important;
+	padding: 0 !important;
+}
+/*
+** Structural Elements
+*/
+
+/*
+** general portlet styles (elements in the quickbar)
+*/
+.portlet {
+	border: none;
+	margin: 0 0 .5em;
+	padding: 0;
+	float: none;
+	width: 11.6em;
+	overflow: hidden;
+}
+.portlet h4 {
+	font-size: 95%;
+	font-weight: normal;
+	white-space: nowrap;
+}
+.portlet h5 {
+	background: transparent;
+	padding: 0 1em 0 .5em;
+	display: inline;
+	height: 1em;
+	text-transform: lowercase;
+	font-size: 91%;
+	font-weight: normal;
+	white-space: nowrap;
+}
+.portlet h6 {
+	background: #ffae2e;
+	border: 1px solid #2f6fab;
+	border-style: solid solid none solid;
+	padding: 0 1em 0 1em;
+	text-transform: lowercase;
+	display: block;
+	font-size: 1em;
+	height: 1.2em;
+	font-weight: normal;
+	white-space: nowrap;
+}
+.pBody {
+	font-size: 95%;
+	background-color: white;
+	color: black;
+	border-collapse: collapse;
+	border: 1px solid #aaa;
+	padding: 0 .8em .3em .5em;
+}
+.portlet h1,
+.portlet h2,
+.portlet h3,
+.portlet h4 {
+	margin: 0;
+	padding: 0;
+}
+.portlet ul {
+	line-height: 1.5em;
+	list-style-type: square;
+	list-style-image: url(bullet.gif);
+	font-size: 95%;
+}
+.portlet li {
+	padding: 0;
+	margin: 0;
+}
+
+/*
+** Logo properties
+*/
+
+/* @media screen, projection { */
+	#p-logo {
+		top: 0;
+		left: 0;
+		position: absolute; /*needed to use z-index */
+		z-index: 3;
+		height: 155px;
+		width: 12em;
+		overflow: visible;
+	}
+	#p-logo h5 {
+		display: none;
+	}
+	#p-logo a,
+	#p-logo a:hover {
+		display: block;
+		height: 155px;
+		width: 12.2em;
+		background-repeat: no-repeat;
+		background-position: 35% 50% !important;
+		text-decoration: none;
+	}
+/* } */
+/*
+** the navigation portlet
+*/
+
+/* @media screen, projection { */
+	#p-navigation {
+		position: relative;
+		z-index: 3;
+	}
+	#p-navigation a {
+		display: block;
+	}
+	#p-navigation li.active a, #p-navigation li.active a:hover {
+		display: inline;
+	}
+/* } */
+
+#p-navigation .pBody {
+	padding-right: 0;
+}
+
+#p-navigation li.active a, #p-navigation li.active a:hover {
+	text-decoration: none;
+	font-weight: bold;
+}
+
+
+/*
+** Search portlet
+*/
+/* @media screen, projection { */
+	#p-search {
+		position: relative;
+		z-index: 3;
+	}
+/* } */
+input.searchButton {
+	margin-top: 1px;
+	font-size: 95%;
+}
+#searchGoButton {
+	padding-left: .5em;
+	padding-right: .5em;
+	font-weight: bold;
+}
+#searchInput {
+	width: 10.9em;
+	margin: 0;
+	font-size: 95%;
+}
+#p-search .pBody {
+	padding: .5em .4em .4em .4em;
+	text-align: center;
+}
+
+/*
+** the personal toolbar
+*/
+/* @media screen, projection { */
+	#p-personal {
+		position: absolute;
+		left: 0;
+		top: 0;
+		z-index: 0;
+	}
+	#p-personal {
+		width: 100%;
+		white-space: nowrap;
+		padding: 0;
+		margin: 0;
+		border: none;
+		background: none;
+		overflow: visible;
+		line-height: 1.2em;
+	}
+	#p-personal h5 {
+		display: none;
+	}
+	#p-personal .portlet,
+	#p-personal .pBody {
+		z-index: 0;
+		padding: 0;
+		margin: 0;
+		border: none;
+		overflow: visible;
+		background: none;
+	}
+/* this is the ul contained in the portlet */
+	#p-personal ul {
+		border: none;
+		line-height: 1.4em;
+		color: #2f6fab;
+		padding: 0 2em 0 3em;
+		margin: 0;
+		text-align: right;
+		list-style: none;
+		z-index: 0;
+		background: none;
+		cursor: default;
+	}
+	#p-personal li {
+		z-index: 0;
+		border: none;
+		padding: 0;
+		display: inline;
+		color: #2f6fab;
+		margin-left: 1em;
+		line-height: 1.2em;
+		background: none;
+	}
+	#p-personal li a {
+		text-decoration: none;
+		color: #005896;
+		padding-bottom: .2em;
+		background: none;
+	}
+	#p-personal li a:hover {
+		background-color: white;
+		padding-bottom: .2em;
+		text-decoration: none;
+	}
+	#p-personal li.active a:hover {
+		background-color: transparent;
+	}
+	/* the icon in front of the user name, single quotes
+	in bg url to hide it from iemac */
+	li#pt-userpage,
+	li#pt-anonuserpage,
+	li#pt-login {
+		background: url(user.gif) top left no-repeat;
+		padding-left: 20px;
+		text-transform: none;
+	}
+/* } */
+#p-personal ul {
+	text-transform: lowercase;
+}
+#p-personal li.active {
+	font-weight: bold;
+}
+/*
+** the page-related actions- page/talk, edit etc
+*/
+/* @media screen, projection { */
+	#p-cactions {
+		position: absolute;
+		top: 1.3em;
+		left: 11.5em;
+		margin: 0;
+		white-space: nowrap;
+		width: 76%;
+		line-height: 1.1em;
+		overflow: visible;
+		background: none;
+		border-collapse: collapse;
+		padding-left: 1em;
+		list-style: none;
+		font-size: 95%;
+	}
+	#p-cactions ul {
+		list-style: none;
+	}
+	#p-cactions li {
+		display: inline;
+		border: 1px solid #aaa;
+		border-bottom: none;
+		padding: 0 0 .1em 0;
+		margin: 0 .3em 0 0;
+		overflow: visible;
+		background: white;
+	}
+	#p-cactions li.selected {
+		border-color: #fabd23;
+		padding: 0 0 .2em 0;
+		font-weight: bold;
+	}
+	#p-cactions li a {
+		background-color: #fbfbfb;
+		color: #002bb8;
+		border: none;
+		padding: 0 .8em .3em;
+		position: relative;
+		z-index: 0;
+		margin: 0;
+		text-decoration: none;
+	}
+	#p-cactions li.selected a {
+		z-index: 3;
+		padding: 0 1em .2em!important;
+		background-color: white;
+	}
+	#p-cactions .new a {
+		color: #ba0000;
+	}
+	#p-cactions li a:hover {
+		z-index: 3;
+		text-decoration: none;
+		background-color: white;
+	}
+	#p-cactions h5 {
+		display: none;
+	}
+	#p-cactions li.istalk {
+		margin-right: 0;
+	}
+	#p-cactions li.istalk a {
+		padding-right: .5em;
+	}
+	#p-cactions #ca-addsection a {
+		padding-left: .4em;
+		padding-right: .4em;
+	}
+	/* offsets to distinguish the tab groups */
+	li#ca-talk {
+		margin-right: 1.6em;
+	}
+	li#ca-watch, li#ca-unwatch, li#ca-varlang-0, li#ca-print {
+		margin-left: 1.6em;
+	}
+	#p-cactions .pBody {
+		font-size: 1em;
+		background-color: transparent;
+		color: inherit;
+		border-collapse: inherit;
+		border: 0;
+		padding: 0;
+	}
+/* } */
+#p-cactions .hiddenStructure {
+	display: none;
+}
+#p-cactions li a {
+	text-transform: lowercase;
+}
+
+/*
+** the remaining portlets
+*/
+/* @media screen, projection { */
+	#p-tbx,
+	#p-lang {
+		position: relative;
+		z-index: 3;
+	}
+/* } */
+
+/* TODO: #t-iscite is only used by the Cite extension, come up with some
+ * system which allows extensions to add to this file on the fly
+ */
+#t-ispermalink, #t-iscite {
+	color: #999;
+}
+/*
+** footer
+*/
+#footer {
+	background-color: white;
+	border-top: 1px solid #fabd23;
+	border-bottom: 1px solid #fabd23;
+	margin: .6em 0 1em 0;
+	padding: .4em 0 1.2em 0;
+	text-align: center;
+	font-size: 90%;
+}
+#footer li {
+	display: inline;
+	margin: 0 1.3em;
+}
+#f-poweredbyico, #f-copyrightico {
+	margin: 0 8px;
+	position: relative;
+	top: -2px; /* Bump it up just a tad */
+}
+#f-poweredbyico {
+	float: right;
+	height: 1%;
+}
+#f-copyrightico {
+	float: left;
+	height: 1%;
+}
+
+/* js pref toc */
+#preftoc {
+	margin: 0;
+	padding: 0;
+	width: 100%;
+	clear: both;
+}
+#preftoc li {
+	background-color: #f0f0f0;
+	color: #000;
+}
+/* @media screen, projection { */
+	#preftoc li {
+		margin: 1px -2px 1px 2px;
+		float: left;
+		padding: 2px 0 3px 0;
+		border: 1px solid #fff;
+		border-right-color: #716f64;
+		border-bottom: 0;
+		position: relative;
+		white-space: nowrap;
+		list-style-type: none;
+		list-style-image: none;
+		z-index: 3;
+	}
+/* } */
+#preftoc li.selected {
+	font-weight: bold;
+	background-color: #f9f9f9;
+	border: 1px solid #aaa;
+	border-bottom: none;
+	cursor: default;
+	top: 1px;
+	padding-top: 2px;
+	margin-right: -3px;
+}
+#preftoc > li.selected {
+	top: 2px;
+}
+#preftoc a,
+#preftoc a:active {
+	display: block;
+	color: #000;
+	padding: 0 .7em;
+	position: relative;
+	text-decoration: none;
+}
+#preftoc li.selected a {
+	cursor: default;
+	text-decoration: none;
+}
+#prefcontrol {
+	padding-top: 2em;
+	clear: both;
+}
+#preferences {
+	margin: 0;
+	border: 1px solid #aaa;
+	clear: both;
+	padding: 1.5em;
+	background-color: #F9F9F9;
+}
+.prefsection {
+	border: none;
+	padding: 0;
+	margin: 0;
+}
+.prefsection fieldset {
+	border: 1px solid #aaa;
+	float: left;
+	margin-right: 2em;
+}
+.prefsection legend {
+	font-weight: bold;   
+}
+.prefsection table, .prefsection legend {
+	background-color: #F9F9F9;
+}
+/* @media screen, projection { */
+	.mainLegend {
+		display: none;
+	}
+/* } */
+div.prefsectiontip {
+	font-size: 95%;
+	margin-top: 0;
+	background-color: #FFC1C1;
+	padding: .2em .7em;
+	clear: both;
+}
+.btnSavePrefs {
+	font-weight: bold;
+	padding-left: .3em;
+	padding-right: .3em;
+}
+
+.preferences-login {
+	clear: both;
+	margin-bottom: 1.5em;
+}
+
+.prefcache {
+	font-size: 90%;
+	margin-top: 2em;
+}
+
+div#userloginForm form,
+div#userlogin form#userlogin2 {
+	margin: 0 3em 1em 0;
+	border: 1px solid #aaa;
+	clear: both;
+	padding: 1.5em 2em;
+	background-color: #f9f9f9;
+	float: left;
+}
+
+div#userloginForm table,
+div#userlogin form#userlogin2 table {
+	background-color: #f9f9f9;
+}
+
+div#userloginForm h2,
+div#userlogin form#userlogin2 h2 {
+	padding-top: 0;
+}
+
+div#userlogin .captcha {
+	border: 1px solid #bbb;
+	padding: 1.5em 2em;
+	width: 400px;
+	background-color: white;
+}
+
+
+#userloginprompt, #languagelinks {
+	font-size: 85%;
+}
+
+#login-sectiontip {
+	font-size: 85%;
+	line-height: 1.2;
+	padding-top: 2em;
+}
+
+#userlogin .loginText, #userlogin .loginPassword {
+	width: 12em;
+}
+
+#userloginlink a, #wpLoginattempt, #wpCreateaccount {
+	font-weight: bold;
+}
+
+/* @media screen, projection { */
+	/*
+	** IE/Mac fixes, hope to find a validating way to move this
+	** to a separate stylesheet. This would work but doesn't validate:
+	** @import("IEMacFixes.css");
+	*/
+	/* tabs: border on the a, not the div */
+	* > html #p-cactions li { border: none; }
+	* > html #p-cactions li a {
+		border: 1px solid #aaa;
+		border-bottom: none;
+	}
+	* > html #p-cactions li.selected a { border-color: #fabd23; }
+	/* footer icons need a fixed width */
+	* > html #f-poweredbyico,
+	* > html #f-copyrightico { width: 88px; }
+	* > html ,
+	* > html pre {
+		overflow-x: auto;
+		width: 100%;
+		padding-bottom: 25px;
+	}
+/* } */
+
+/* more IE fixes */
+/* float/negative margin brokenness */
+* html #footer {margin-top: 0;}
+* html div.editsection { font-size: smaller; }
+#pagehistory li.selected { position: relative; }
+
+/* Mac IE 5.0 fix; floated content turns invisible */
+* > html #column-one {
+	position: absolute;
+	left: 0;
+	top: 0;
+}
+* > html #footer {
+	margin-left: 13.2em;
+}
+.redirectText {
+	font-size: 150%;
+	margin: 5px;
+}
+
+.printfooter {
+	display: none;
+}
+
+.not-patrolled {
+	background-color: #ffa;
+}
+div.patrollink {
+	font-size: 75%;
+	text-align: right;
+}
+span.newpage, span.minor, span.searchmatch, span.bot {
+	font-weight: bold;
+}
+span.unpatrolled {
+	font-weight: bold;
+	color: red;
+}
+
+span.searchmatch {
+	color: red;
+}
+.sharedUploadNotice {
+	font-style: italic;
+}
+
+span.updatedmarker {
+	color: black;
+	background-color: #0f0;
+}
+
+table.gallery {
+	border: 1px solid #ccc;
+	margin: 2px;
+	padding: 2px;
+	background-color: white;
+}
+
+table.gallery tr {
+	vertical-align: top;
+}
+
+table.gallery td {
+	vertical-align: top;
+	background-color: #f9f9f9;
+	border: solid 2px white;
+}
+/* Keep this temporarily so that cached pages will display right */
+table.gallery td.galleryheader {
+    text-align: center;
+	font-weight: bold;
+}
+table.gallery caption {
+	font-weight: bold;
+}
+
+div.gallerybox {
+	margin: 2px;
+}
+
+div.gallerybox div.thumb {
+	text-align: center;
+	border: 1px solid #ccc;
+	margin: 2px;
+}
+
+div.gallerytext {
+	font-size: 94%;
+	padding: 2px 4px;
+}
+
+span.comment {
+	font-style: italic;
+}
+
+span.changedby {
+	font-size: 95%;
+}
+
+.previewnote {
+	text-indent: 3em;
+	color: #c00;
+	border-bottom: 1px solid #aaa;
+	padding-bottom: 1em;
+	margin-bottom: 1em;
+}
+
+.previewnote p {
+	margin: 0;
+	padding: 0;
+}
+
+.editExternally {
+	border: 1px solid gray;
+	background-color: #ffffff;
+	padding: 3px;
+	margin-top: 0.5em;
+	float: left;
+	font-size: small;
+	text-align: center;
+}
+.editExternallyHelp {
+	font-style: italic;
+	color: gray;
+}
+
+li span.deleted, span.history-deleted {
+	text-decoration: line-through;
+	color: #888;
+	font-style: italic;
+}
+
+.toggle {
+	margin-left: 2em;
+	text-indent: -2em;
+}
+
+/* Classes for EXIF data display */
+table.mw_metadata {
+	font-size: 0.8em;
+	margin-left: 0.5em;
+	margin-bottom: 0.5em;
+	width: 300px;
+}
+
+table.mw_metadata caption {
+	font-weight: bold;
+}
+
+table.mw_metadata th {
+	font-weight: normal;
+}
+
+table.mw_metadata td {
+	padding: 0.1em;
+}
+
+table.mw_metadata {
+	border: none;
+	border-collapse: collapse;
+}
+
+table.mw_metadata td, table.mw_metadata th {
+	text-align: center;
+	border: 1px solid #aaaaaa;
+	padding-left: 0.1em;
+	padding-right: 0.1em;
+}
+
+table.mw_metadata th {
+	background-color: #f9f9f9;
+}
+
+table.mw_metadata td {
+	background-color: #fcfcfc;
+}
+
+table.collapsed tr.collapsable {
+	display: none;
+}
+
+
+/* filetoc */
+ul#filetoc {
+	text-align: center;
+	border: 1px solid #aaaaaa;
+	background-color: #f9f9f9;
+	padding: 5px;
+	font-size: 95%;
+	margin-bottom: 0.5em;
+	margin-left: 0;
+	margin-right: 0;
+}
+
+#filetoc li {
+	display: inline;
+	list-style-type: none;
+	padding-right: 2em;
+}
+
+input#wpSummary {
+	width: 80%;
+}
+
+/* @bug 1714 */
+input#wpSave, input#wpDiff {
+	margin-right: 0.33em;
+}
+
+#editform .editOptions {
+	display: inline;
+}
+
+#wpSave {
+	font-weight: bold;
+}
+
+/* Classes for article validation */
+
+table.revisionform_default {
+	border: 1px solid #000000;
+}
+
+table.revisionform_focus {
+	border: 1px solid #000000;
+	background-color:#00BBFF;
+}
+
+tr.revision_tr_default {
+	background-color:#EEEEEE;
+}
+
+tr.revision_tr_first {
+	background-color:#DDDDDD;
+}
+
+p.revision_saved {
+	color: green;
+	font-weight:bold;
+}
+
+#mw_trackbacks {
+	border: solid 1px #bbbbff;
+	background-color: #eeeeff;
+	padding: 0.2em;
+}
+
+
+/* Allmessages table */
+
+#allmessagestable th {
+	background-color: #b2b2ff;
+}
+
+#allmessagestable tr.orig {
+	background-color: #ffe2e2;
+}
+
+#allmessagestable tr.new {
+	background-color: #e2ffe2;
+}
+
+#allmessagestable tr.def {
+	background-color: #f0f0ff;
+}
+
+
+/* noarticletext */
+div.noarticletext {
+	border: 1px solid #ccc;
+	background: #fff;
+	padding: .2em 1em;
+	color: #000;
+}
+
+div#searchTargetContainer {
+	left:       10px;
+	top:        10px;
+	width:      90%;
+	background: white;
+}
+
+div#searchTarget {
+	padding:    3px;
+	margin:     5px;
+	background: #F0F0F0;
+	border:     solid 1px blue;
+}
+
+div#searchTarget ul li {
+	list-style: none;
+}
+
+div#searchTarget ul li:before {
+	color: orange;
+	content: "\00BB \0020";
+}
+
+div.multipageimagenavbox {
+   border: solid 1px silver;
+   padding: 4px;
+   margin: 1em;
+   -moz-border-radius: 6px;
+   background: #f0f0f0;
+}
+
+div.multipageimagenavbox div.thumb {
+   border: none;
+   margin-left: 2em;
+   margin-right: 2em;
+}
+
+div.multipageimagenavbox hr {
+   margin: 6px;
+}
+
+table.multipageimage td {
+   text-align: center;
+}
+
+/** Special:Version */
+
+table#sv-ext, table#sv-hooks {
+	margin: 1em;
+	padding:0em;
+}
+
+#sv-ext td, #sv-hooks td,
+#sv-ext th, #sv-hooks th {
+	border: 1px solid #A0A0A0;
+	padding: 0 0.15em 0 0.15em;
+}
+#sv-ext th, #sv-hooks th {
+	background-color: #F0F0F0;
+	color: black;
+	padding: 0 0.15em 0 0.15em;
+}
+tr.sv-space{
+	height: 0.8em;
+	border:none;
+}
+tr.sv-space td { display: none; }
+
+/*
+  Table pager (e.g. Special:Imagelist)
+  - remove underlines from the navigation link
+  - collapse borders
+  - set the borders to outsets (similar to Special:Allmessages)
+  - remove line wrapping for all td and th, set background color
+  - restore line wrapping for the last two table cells (description and size)
+*/
+.TablePager_nav a { text-decoration: none; }
+.TablePager { border-collapse: collapse; }
+.TablePager, .TablePager td, .TablePager th { 
+	border: 1px solid #aaaaaa;
+	padding: 0 0.15em 0 0.15em;
+}
+.TablePager th { background-color: #eeeeff }
+.TablePager td { background-color: #ffffff }
+.TablePager tr:hover td { background-color: #eeeeff }
+
+.imagelist td, .imagelist th { white-space: nowrap }
+.imagelist .TablePager_col_links { background-color: #eeeeff }
+.imagelist .TablePager_col_img_description { white-space: normal }
+.imagelist th.TablePager_sort { background-color: #ccccff }
+
+.templatesUsed { margin-top: 1.5em; }
+
+.mw-summary-preview {
+	margin: 0.1em 0;
+}
+
+/* Convenience links on Special:Ipblocklist */
+p.mw-ipb-conveniencelinks {
+	font-size: 90%;
+	float: right;
+}
+
+/**
+ * Here is some stuff that's ACTUALLY COMMON TO ALL SKINS.
+ * When the day comes, it can be moved to a *real* common.css.
+ */
+.mw-plusminus-null { color: #aaa; }
+.texvc { direction: ltr; unicode-bidi: embed; }
+/* Stop floats from intruding into edit area in previews */
+#toolbar, #wpTextbox1 { clear: both; }
+
+.MediaTransformError {
+	background-color: #ccc;
+	padding: 0.1em;
+}
+.MediaTransformError td {
+	text-align: center;
+	vertical-align: middle;
+	font-size: 90%;
+}
+
+
+/**
+ * FCKeditor specific styles
+ */
+
+img.fck_mw_frame
+{
+	background-color: #F9F9F9;
+	border: 1px solid #CCCCCC;
+	padding: 3px !important;
+}
+
+img.fck_mw_right
+{
+	margin: 0.5em 5px 0.8em 1.4em ;
+	clear: right;
+	float: right;
+}
+
+img.fck_mw_left
+{
+	margin: 0.5em 1.4em 0.8em 0em;
+	clear: left;
+	float: left;
+}
+
+img.fck_mw_center
+{
+	margin-left: auto;
+	margin-right: auto;
+	margin-bottom: 0.5em;
+	display: block;
+}
+
+img.fck_mw_notfound 
+{
+	font-size: 1px;
+	height: 25px;
+	width: 25px;
+	overflow: hidden ;
+}
Index: /MediaWiki/trunk/fckeditor/COPY_HERE.txt
===================================================================
--- /MediaWiki/trunk/fckeditor/COPY_HERE.txt	(revision 1660)
+++ /MediaWiki/trunk/fckeditor/COPY_HERE.txt	(revision 1660)
@@ -0,0 +1,3 @@
+Go to http://www.fckeditor.net/download and download the latest version. Then
+ uncompress the contents of the "fckeditor" directory of the download file to
+ this folder (extensions/FCKeditor/fckeditor).
Index: /MediaWiki/trunk/fckeditor_config.js
===================================================================
--- /MediaWiki/trunk/fckeditor_config.js	(revision 1660)
+++ /MediaWiki/trunk/fckeditor_config.js	(revision 1660)
@@ -0,0 +1,69 @@
+﻿/*
+ * FCKeditor Extension for MediaWiki specific settings.
+ */
+
+// When using the modified image dialog you must set this variable. It must
+// correspond to $wgScriptPath in LocalSettings.php.
+FCKConfig.mwScriptPath = '' ;     
+
+// Setup the editor toolbar.
+FCKConfig.ToolbarSets['Wiki'] = [
+	['Source'],
+	['Cut','Copy','Paste',/*'PasteText','PasteWord',*/'-','Print'],
+	['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],
+	['SpecialChar','Table','Image','Rule'],
+	['MW_Template','MW_Ref','MW_Math'],
+	'/',
+	['FontFormat'],
+	['Bold','Italic','Underline','StrikeThrough','-','Subscript','Superscript'],
+	['OrderedList','UnorderedList','-','Blockquote'],
+//	['JustifyLeft','JustifyCenter','JustifyRight','JustifyFull'],
+	['Link','Unlink','Anchor'],
+//	['TextColor','BGColor'],
+	['FitWindow','-','About']
+] ;
+
+// Load the extension plugins.
+FCKConfig.PluginsPath = FCKConfig.EditorPath + '../plugins/' ;
+FCKConfig.Plugins.Add( 'mediawiki' ) ;
+
+FCKConfig.ForcePasteAsPlainText = true ;
+FCKConfig.FontFormats	= 'p;h1;h2;h3;h4;h5;h6;pre' ;
+
+FCKConfig.AutoDetectLanguage	= false ;
+FCKConfig.DefaultLanguage		= 'en' ;
+
+// FCKConfig.DisableObjectResizing = true ;
+
+FCKConfig.EditorAreaStyles = '\
+.FCK__MWTemplate \
+{ \
+	border: 1px dotted #00F; \
+	background-position: center center; \
+	background-image: url(' + FCKConfig.PluginsPath + 'mediawiki/images/icon_template.gif); \
+	background-repeat: no-repeat; \
+	width: 20px; \
+	height: 15px; \
+	vertical-align: middle; \
+} \
+.FCK__MWRef \
+{ \
+	border: 1px dotted #00F; \
+	background-position: center center; \
+	background-image: url(' + FCKConfig.PluginsPath + 'mediawiki/images/icon_ref.gif); \
+	background-repeat: no-repeat; \
+	width: 18px; \
+	height: 15px; \
+	vertical-align: middle; \
+} \
+.FCK__MWReferences \
+{ \
+	border: 1px dotted #00F; \
+	background-position: center center; \
+	background-image: url(' + FCKConfig.PluginsPath + 'mediawiki/images/icon_references.gif); \
+	background-repeat: no-repeat; \
+	width: 66px; \
+	height: 15px; \
+	vertical-align: middle; \
+} \
+' ;
Index: /MediaWiki/trunk/plugins/mediawiki/dialogs/image.html
===================================================================
--- /MediaWiki/trunk/plugins/mediawiki/dialogs/image.html	(revision 1660)
+++ /MediaWiki/trunk/plugins/mediawiki/dialogs/image.html	(revision 1660)
@@ -0,0 +1,337 @@
+﻿<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Image dialog window.
+-->
+<html>
+<head>
+	<title>Image Properties</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<meta name="robots" content="noindex, nofollow" />
+	<script type="text/javascript">
+
+var oEditor		= window.parent.InnerDialogLoaded() ;
+var FCK			= oEditor.FCK ;
+var FCKLang		= oEditor.FCKLang ;
+var FCKConfig	= oEditor.FCKConfig ;
+var FCKRegexLib	= oEditor.FCKRegexLib ;
+var FCKTools	= oEditor.FCKTools ;
+
+document.write( '<script src="' + FCKConfig.BasePath + 'dialog/common/fck_dialog_common.js" type="text/javascript"><\/script>' ) ;
+
+	</script>
+	<script type="text/javascript">
+
+// Get the selected image (if available).
+var oImage = FCK.Selection.GetSelectedElement() ;
+
+if ( oImage && oImage.tagName != 'IMG' )
+	oImage = null ;
+
+window.onload = function()
+{
+	// Translate the dialog box texts.
+	oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+	// Load the selected element information (if any).
+	LoadSelection() ;
+
+	//	UpdateOriginal() ;
+
+	window.parent.SetAutoSize( true ) ;
+	window.parent.SetOkButton( true ) ;
+}
+
+function LoadSelection()
+{
+	if ( ! oImage ) return ;
+
+	var sUrl = GetAttribute( oImage, '_fcksavedurl', '' ) ;
+	if ( sUrl.length == 0 )
+		sUrl = GetAttribute( oImage, 'src', '' ) ;
+
+	GetE('txtUrl').value    = GetAttribute( oImage, '_fck_mw_filename', '' ) ;
+	GetE('txtAlt').value    = GetAttribute( oImage, 'alt', '' ) ;
+	GetE('xType').value		= GetAttribute( oImage, '_fck_mw_type', '' ) ;
+	GetE('cmbAlign').value  = GetAttribute( oImage, '_fck_mw_location', '' ) ;
+
+	GetE('txtWidth').value  = GetAttribute( oImage, '_fck_mw_width', '' ) ;
+	GetE('txtHeight').value = GetAttribute( oImage, '_fck_mw_height', '' ) ;
+
+	UpdatePreview();
+}
+
+//#### The OK button was hit.
+function Ok()
+{
+	if ( GetE('txtUrl').value.length == 0 )
+	{
+		GetE('txtUrl').focus() ;
+		return false ;
+	}
+
+	window.parent.document.getElementById( 'btnOk' ).disabled = true ;
+	window.parent.document.getElementById( 'btnCancel' ).disabled = true ;
+
+	var imgName		= GetE('txtUrl').value ;
+	var imgCaption	= GetE('txtAlt').value ;
+	var imgType		= GetE('xType').value ;
+	var imgLocation	= GetE('cmbAlign').value ;
+	var imgWidth	= GetE('txtWidth').value ;
+	var imgHeight	= GetE('txtHeight').value ;
+
+	var ajaxArg = imgName ;
+
+	if ( imgType.length > 0 )
+		ajaxArg += '|' + imgType ;
+
+	if ( imgLocation.length > 0 )
+		ajaxArg += '|' + imgLocation ;
+
+	if ( imgWidth.length > 0 )
+	{
+		ajaxArg += '|' + imgWidth ;
+
+		if ( imgHeight.length > 0 )
+			ajaxArg += 'x' + imgHeight ;
+
+		ajaxArg += 'px' ;
+	}
+
+	if ( imgCaption.length > 0 )
+		ajaxArg += '|' + imgCaption ;
+
+	oEditor.window.parent.sajax_request_type = 'GET' ;
+	oEditor.window.parent.sajax_do_call( 'wfSajaxGetImageUrl', [ajaxArg], UpdateImageFromAjax ) ;
+
+	return false ;
+}
+
+function UpdateImageFromAjax( response )
+{
+	var bHasImage = ( oImage != null ) ;
+
+	if ( !bHasImage )
+		oImage = FCK.CreateElement( 'IMG' ) ;
+	else
+		oEditor.FCKUndo.SaveUndoStep() ;
+
+	UpdateImage( oImage, response.responseText ) ;
+
+	// Call it using setTimeout to avoid a strange behavior in Firefox.
+	window.setTimeout( window.parent.Cancel, 0 ) ;
+}
+
+function UpdateImage( e, realUrl )
+{
+	var imgType = GetE('xType').value ;
+	var imgLocation = GetE('cmbAlign').value ;
+
+	SetAttribute( e, "_fck_mw_filename", GetE('txtUrl').value ) ;
+	SetAttribute( e, "alt", GetE('txtAlt').value ) ;
+	SetAttribute( e, "_fck_mw_type", imgType ) ;
+	SetAttribute( e, "_fck_mw_location", imgLocation ) ;
+	SetAttribute( e, "_fck_mw_width", GetE('txtWidth').value ) ;
+	SetAttribute( e, "_fck_mw_height", GetE('txtHeight').value ) ;
+
+	SetAttribute( e, "width" , GetE('txtWidth').value ) ;
+	SetAttribute( e, "height", GetE('txtHeight').value ) ;
+
+	if ( imgType == 'thumb' || imgType == 'frame' )
+	{
+		e.className = 'fck_mw_frame' ;
+
+		if ( imgLocation.length == 0 )
+			imgLocation = 'right' ;
+	}
+
+	if ( imgLocation.length > 0 )
+		e.className += ' fck_mw_' + imgLocation ;
+
+	if ( realUrl.length == 0 )
+	{
+		e.className += ' fck_mw_notfound' ;
+		realUrl = 'about:blank' ;
+	}
+
+	e.src = realUrl ;
+	SetAttribute( e, "_fcksavedurl", realUrl ) ;
+}
+
+var searchTimer ;
+
+//#### Called while the user types the URL.
+function OnUrlChange()
+{
+	var link = GetE('txtUrl').value.Trim() ;
+
+	if ( searchTimer )
+		window.clearTimeout( searchTimer ) ;
+
+	if ( link.length < 3  )
+	{
+		ClearSearch() ;
+
+		if ( link.length == 0 )
+			SetSearchMessage( 'start typing in the above field' ) ;
+		else
+			SetSearchMessage( 'too short... type more' ) ;
+		return ;
+	}
+
+	SetSearchMessage( 'stop typing to search' ) ;
+	searchTimer = window.setTimeout( StartSearch, 500 ) ;
+}
+
+function StartSearch()
+{
+	var link = GetE('txtUrl').value.Trim() ;
+
+	if ( link.length < 3  )
+		return ;
+
+	SetSearchMessage( 'searching...' ) ;
+
+	// Make an Ajax search for the pages.
+	oEditor.window.parent.sajax_request_type = 'GET' ;
+	oEditor.window.parent.sajax_do_call( 'wfSajaxSearchImageFCKeditor', [link], LoadSearchResults ) ;
+}
+
+function LoadSearchResults( result )
+{
+	var results = result.responseText.Trim().split( '\n' ) ;
+	var select = GetE( 'xWikiResults' ) ;
+
+	ClearSearch() ;
+
+	if ( results.length == 0 || ( results.length == 1 && results[0].length == 0 ) )
+	{
+		SetSearchMessage( 'no images found' ) ;
+	}
+	else
+	{
+		if ( results.length == 1 )
+			SetSearchMessage( 'one image found' ) ;
+		else
+			SetSearchMessage( results.length + ' images found' ) ;
+
+		for ( var i = 0 ; i < results.length ; i++ )
+			FCKTools.AddSelectOption( select, results[i], results[i] ) ;
+	}
+}
+
+function ClearSearch()
+{
+	var select = GetE( 'xWikiResults' ) ;
+
+	while ( select.options.length > 0 )
+		select.remove( 0 )
+}
+
+function SetSearchMessage( message )
+{
+	GetE('xWikiSearchStatus').innerHTML = message ;
+}
+
+function SetUrl( url )
+{
+	if ( url.length > 0 )
+		GetE('txtUrl').value = url ;
+}
+
+function UpdatePreviewFromAjax( response )
+{
+	var eImgPreview = window.document.getElementById('prevImg');
+	eImgPreview.src = response.responseText ;
+	SetAttribute(eImgPreview, "width" , '180px' ) ;
+	SetAttribute(eImgPreview, "height", '130px' ) ;
+	//UpdateImage( eImgPreview, response.responseText ) ;
+}
+
+function UpdatePreview()
+{
+	var ajaxArg = GetE('txtUrl').value + '|180x130px';
+	oEditor.window.parent.sajax_request_type = 'GET' ;
+	oEditor.window.parent.sajax_do_call( 'wfSajaxGetImageUrl', [ajaxArg], UpdatePreviewFromAjax ) ;
+}
+
+	</script>
+</head>
+<body scroll="no" style="overflow: hidden">
+	<div id="divInfo">
+		<table cellspacing="1" cellpadding="1" border="0" width="100%">
+			<tr valign="center">
+				<td>
+					<span>Image file name</span><br />
+					<input id="txtUrl" style="width: 100%" type="text" onkeyup="OnUrlChange();" />
+					<br />
+					Automatic search results (<span id="xWikiSearchStatus">start typing in the above field</span>)<br />
+					<select id="xWikiResults" size="5" style="width: 100%; height: 70px" onclick="SetUrl( this.value );UpdatePreview();">
+					</select>
+				</td>
+				<td width="180px" height="130px"><div style="width:180; height:130; border:solid 1px black;" valign="center" align="center">
+					<img id="prevImg" width="180px" height="130px" alt="Preview"></div>
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2">
+					<span>Caption</span><br />
+					<input id="txtAlt" style="width: 100%" type="text"><br />
+				</td>
+			</tr>
+			<tr>
+				<td valign="top" colspan="2">
+					<table cellspacing="0" cellpadding="0" border="0">
+						<tr>
+							<td nowrap="nowrap">
+								Special Type<br />
+								<select id="xType">
+									<option value="" selected="selected"></option>
+									<option value="thumb">Thumbnail</option>
+									<option value="frame">Frame</option>
+									<option value="border">Border</option>
+								</select>
+							</td>
+							<td style="padding-left:7px;">
+								<span fcklang="DlgImgAlign">Align</span><br />
+								<select id="cmbAlign" onchange="UpdatePreview();">
+									<option value="" selected></option>
+									<option fcklang="DlgImgAlignRight" value="right">Right</option>
+									<option fcklang="DlgImgAlignLeft" value="left">Left</option>
+									<option value="center">Center</option>
+								</select>
+							</td>
+							<td style="padding-left:7px;">
+								<span fcklang="DlgImgWidth">Width</span><br />
+								<input type="text" size="3" id="txtWidth">
+							</td>
+							<td style="padding-left:7px;">
+								<span fcklang="DlgImgHeight">Height</span><br />
+								<input type="text" size="3" id="txtHeight">
+							</td>
+						</tr>
+					</table>
+				</td>
+			</tr>
+		</table>
+	</div>
+</body>
+</html>
Index: /MediaWiki/trunk/plugins/mediawiki/dialogs/link.html
===================================================================
--- /MediaWiki/trunk/plugins/mediawiki/dialogs/link.html	(revision 1660)
+++ /MediaWiki/trunk/plugins/mediawiki/dialogs/link.html	(revision 1660)
@@ -0,0 +1,231 @@
+﻿<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Link dialog window.
+-->
+<html>
+<head>
+	<title>Link Properties</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<meta name="robots" content="noindex, nofollow" />
+	<script type="text/javascript">
+
+var oEditor		= window.parent.InnerDialogLoaded() ;
+var FCK			= oEditor.FCK ;
+var FCKLang		= oEditor.FCKLang ;
+var FCKConfig	= oEditor.FCKConfig ;
+var FCKRegexLib	= oEditor.FCKRegexLib ;
+var FCKTools	= oEditor.FCKTools ;
+
+document.write( '<script src="' + FCKConfig.BasePath + 'dialog/common/fck_dialog_common.js" type="text/javascript"><\/script>' ) ;
+
+	</script>
+	<script type="text/javascript">
+
+// oLink: The actual selected link in the editor.
+var oLink = FCK.Selection.MoveToAncestorNode( 'A' ) ;
+if ( oLink )
+	FCK.Selection.SelectNode( oLink ) ;
+
+window.onload = function()
+{
+	// Translate the dialog box texts.
+	oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+	// Load the selected link information (if any).
+	LoadSelection() ;
+
+	// Activate the "OK" button.
+	window.parent.SetOkButton( true ) ;
+	window.parent.SetAutoSize( true ) ;
+}
+
+function LoadSelection()
+{
+	if ( !oLink ) return ;
+
+	// Get the actual Link href.
+	var sHRef = oLink.getAttribute( '_fcksavedurl' ) ;
+	if ( sHRef == null )
+		sHRef = oLink.getAttribute( 'href' , 2 ) || '' ;
+
+	GetE('txtUrl').value = sHRef ;
+}
+
+var searchTimer ;
+
+//#### Called while the user types the URL.
+function OnUrlChange()
+{
+	var link = GetE('txtUrl').value.Trim() ;
+
+	if ( searchTimer )
+		window.clearTimeout( searchTimer ) ;
+		
+	if ( link.StartsWith( '#' ) )
+	{
+		SetSearchMessage( 'anchor link... no search for it' ) ;
+		return ;
+	} 
+	
+	if ( link.StartsWith( 'mailto:' ) )
+	{
+		SetSearchMessage( 'e-mail link... no search for it' ) ;
+		return ;
+	} 
+	
+	if( /^\w+:\/\//.test( link ) )
+	{
+		SetSearchMessage( 'external link... no search for it' ) ;
+		return ;
+	}
+
+	if ( link.length < 3  )
+	{
+		ClearSearch() ;
+
+		if ( link.length == 0 )
+			SetSearchMessage( 'start typing in the above field' ) ;
+		else
+			SetSearchMessage( 'too short... type more' ) ;
+		return ;
+	}
+	
+	SetSearchMessage( 'stop typing to search' ) ;
+	searchTimer = window.setTimeout( StartSearch, 500 ) ;
+}
+
+function StartSearch()
+{
+	var link = GetE('txtUrl').value.Trim() ;
+
+	if ( link.length < 3  )
+		return ;
+
+	SetSearchMessage( 'searching...' ) ;
+
+	// Make an Ajax search for the pages.
+	oEditor.window.parent.sajax_request_type = 'GET' ;
+	oEditor.window.parent.sajax_do_call( 'wfSajaxSearchArticleFCKeditor', [link], LoadSearchResults ) ;
+}
+
+function LoadSearchResults( result )
+{
+	var results = result.responseText.Trim().split( '\n' ) ;
+	var select = GetE( 'xWikiResults' ) ;
+	
+	ClearSearch() ;
+
+	if ( results.length == 0 || ( results.length == 1 && results[0].length == 0 ) )
+	{
+		SetSearchMessage( 'no articles found' ) ;
+	}
+	else
+	{
+		if ( results.length == 1 )
+			SetSearchMessage( 'one article found' ) ;
+		else
+			SetSearchMessage( results.length + ' articles found' ) ;
+
+		for ( var i = 0 ; i < results.length ; i++ )
+			FCKTools.AddSelectOption( select, results[i], results[i] ) ;
+	}
+}
+
+function ClearSearch()
+{
+	var select = GetE( 'xWikiResults' ) ;
+
+	while ( select.options.length > 0 )
+		select.remove( 0 ) 
+}
+
+function SetSearchMessage( message )
+{
+	GetE('xWikiSearchStatus').innerHTML = message ;
+}
+
+function SetUrl( url )
+{
+	GetE('txtUrl').value = url ;
+}
+
+//#### The OK button was hit.
+function Ok()
+{
+	var sUri = GetE('txtUrl').value ;
+	var sInnerHtml ;
+
+	// If no link is selected, create a new one (it may result in more than one link creation - #220).
+	var aLinks = oLink ? [ oLink ] : oEditor.FCK.CreateLink( sUri ) ;
+
+	// If no selection, no links are created, so use the uri as the link text (by dom, 2006-05-26)
+	var aHasSelection = ( aLinks.length > 0 ) ;
+	if ( !aHasSelection )
+	{
+		sInnerHtml = sUri;
+
+		var oLinkPathRegEx = new RegExp("//?([^?\"']+)([?].*)?$") ;
+		var asLinkPath = oLinkPathRegEx.exec( sUri ) ;
+		if (asLinkPath != null)
+			sInnerHtml = asLinkPath[1];  // use matched path
+		
+		// Create a new (empty) anchor.
+		aLinks = [ oEditor.FCK.InsertElement( 'a' ) ] ;
+	}
+
+	oEditor.FCKUndo.SaveUndoStep() ;
+
+	for ( var i = 0 ; i < aLinks.length ; i++ )
+	{
+		oLink = aLinks[i] ;
+
+		if ( aHasSelection )
+			sInnerHtml = oLink.innerHTML ;		// Save the innerHTML (IE changes it if it is like an URL).
+
+		oLink.href = sUri ;
+		SetAttribute( oLink, '_fcksavedurl', sUri ) ;
+
+		oLink.innerHTML = sInnerHtml ;		// Set (or restore) the innerHTML
+
+	}
+
+	// Select the (first) link.
+	oEditor.FCKSelection.SelectNode( aLinks[0] );
+
+	return true ;
+}
+
+	</script>
+</head>
+<body scroll="no" style="overflow: hidden">
+	<div id="divInfo">
+		<div id="divLinkTypeUrl">
+			<span>Link</span><br />
+			<input id="txtUrl" style="width: 100%" type="text" onkeyup="OnUrlChange();" />
+			<br />
+			Automatic search results (<span id="xWikiSearchStatus">start typing in the above field</span>)<br />
+			<select id="xWikiResults" size="10" style="width: 100%; height:150px" onclick="SetUrl( this.value );">
+			</select>
+		</div>
+	</div>
+</body>
+</html>
Index: /MediaWiki/trunk/plugins/mediawiki/dialogs/math.html
===================================================================
--- /MediaWiki/trunk/plugins/mediawiki/dialogs/math.html	(revision 1660)
+++ /MediaWiki/trunk/plugins/mediawiki/dialogs/math.html	(revision 1660)
@@ -0,0 +1,128 @@
+﻿<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Link dialog window.
+-->
+<html>
+<head>
+	<title>Formula Editor</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<meta name="robots" content="noindex, nofollow" />
+	<script type="text/javascript">
+
+var oEditor		= window.parent.InnerDialogLoaded() ;
+var FCK			= oEditor.FCK ;
+var FCKLang		= oEditor.FCKLang ;
+var FCKConfig	= oEditor.FCKConfig ;
+var FCKRegexLib	= oEditor.FCKRegexLib ;
+var FCKTools	= oEditor.FCKTools ;
+
+document.write( '<script src="' + FCKConfig.BasePath + 'dialog/common/fck_dialog_common.js" type="text/javascript"><\/script>' ) ;
+
+	</script>
+	<script type="text/javascript">
+
+// Get the selected flash embed (if available).
+var oMathImage = FCK.Selection.GetSelectedElement() ;
+
+if ( oMathImage )
+{
+	if ( oMathImage.tagName != 'IMG' || !oMathImage.getAttribute('_fck_mw_math') )
+		oMathImage = null ;
+}
+
+window.onload = function()
+{
+	// Translate the dialog box texts.
+	oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+	// Load the selected link information (if any).
+	LoadSelection() ;
+
+	// Activate the "OK" button.
+	window.parent.SetOkButton( true ) ;
+	window.parent.SetAutoSize( true ) ;
+}
+
+function LoadSelection()
+{
+	if ( !oMathImage ) return ;
+
+	GetE('xTemplateRaw').value = oMathImage.getAttribute( '_fck_mw_math' ) ;
+}
+
+//#### The OK button was hit.
+function Ok()
+{
+	var formula = GetE('xTemplateRaw').value.Trim() ;
+	
+	if ( formula.length == 0 )
+	{
+		alert( 'Please type the formula' ) ;
+		return false ;
+	}
+
+	window.parent.document.getElementById( 'btnOk' ).disabled = true ;
+	window.parent.document.getElementById( 'btnCancel' ).disabled = true ;
+
+	oEditor.window.parent.sajax_request_type = 'GET' ;
+	oEditor.window.parent.sajax_do_call( 'wfSajaxGetMathUrl', [formula], UpdateImageFromAjax ) ;
+	
+	return false ;
+}
+
+function UpdateImageFromAjax( response )
+{
+	if ( !oMathImage )
+		oMathImage = FCK.CreateElement( 'IMG' ) ;
+	else
+		oEditor.FCKUndo.SaveUndoStep() ;
+	
+	SetAttribute( oMathImage, "_fck_mw_math", GetE('xTemplateRaw').value.Trim() ) ;
+	SetAttribute( oMathImage, "_fckfakelement", 'true' ) ;
+
+	oMathImage.src = response.responseText ;
+	SetAttribute( oMathImage, "_fcksavedurl", response.responseText ) ;
+
+	// Call it using setTimeout to avoid a strange behavior in Firefox.
+	window.setTimeout( window.parent.Cancel, 0 ) ;
+}
+
+	</script>
+</head>
+<body style="overflow: hidden">
+	<div id="divInfo">
+		<table cellpadding="0" cellspacing="0" border="0" width="100%" height="100%">
+			<tr>
+				<td>
+					<span>Formula (TeX markup)</span>
+				</td>
+			</tr>
+			<tr>
+				<td height="100%">
+					<textarea id="xTemplateRaw" style="width: 100%; height: 100%; font-family: Monospace"
+						cols="50" rows="10" wrap="off"></textarea>
+				</td>
+			</tr>
+		</table>
+	</div>
+</body>
+</html>
Index: /MediaWiki/trunk/plugins/mediawiki/dialogs/ref.html
===================================================================
--- /MediaWiki/trunk/plugins/mediawiki/dialogs/ref.html	(revision 1660)
+++ /MediaWiki/trunk/plugins/mediawiki/dialogs/ref.html	(revision 1660)
@@ -0,0 +1,124 @@
+﻿<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Link dialog window.
+-->
+<html>
+<head>
+	<title>Reference Properties</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<meta name="robots" content="noindex, nofollow" />
+	<script type="text/javascript">
+
+var oEditor		= window.parent.InnerDialogLoaded() ;
+var FCK			= oEditor.FCK ;
+var FCKLang		= oEditor.FCKLang ;
+var FCKConfig	= oEditor.FCKConfig ;
+var FCKRegexLib	= oEditor.FCKRegexLib ;
+var FCKTools	= oEditor.FCKTools ;
+
+document.write( '<script src="' + FCKConfig.BasePath + 'dialog/common/fck_dialog_common.js" type="text/javascript"><\/script>' ) ;
+
+	</script>
+	<script type="text/javascript">
+
+// Get the selected flash embed (if available).
+var oFakeImage = FCK.Selection.GetSelectedElement() ;
+var oRef ;
+
+if ( oFakeImage )
+{
+	if ( oFakeImage.tagName == 'IMG' && oFakeImage.getAttribute('_fck_mw_ref') )
+		oRef = FCK.GetRealElement( oFakeImage ) ;
+	else
+		oFakeImage = null ;
+}
+
+window.onload = function()
+{
+	// Translate the dialog box texts.
+	oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+	// Load the selected link information (if any).
+	LoadSelection() ;
+
+	// Activate the "OK" button.
+	window.parent.SetOkButton( true ) ;
+	window.parent.SetAutoSize( true ) ;
+}
+
+function LoadSelection()
+{
+	if ( !oRef ) return ;
+
+	GetE('xRefText').value = FCKTools.HTMLDecode( oRef.innerHTML ).replace( /&quot;/g, '"' ) ;
+	GetE('xRefName').value = oRef.getAttribute( 'name' ) ;
+}
+
+//#### The OK button was hit.
+function Ok()
+{
+	if ( !oRef )
+	{
+		oRef = FCK.EditorDocument.createElement( 'SPAN' ) ;
+		oRef.className = 'fck_mw_ref' ;
+	}
+	
+	var refData = FCKTools.HTMLEncode( GetE('xRefText').value ).Trim().replace( /"/g, '&quot;' ) ;
+	oRef.innerHTML = refData ;
+	SetAttribute( oRef, "name", GetE('xRefName').value ) ;
+
+	if ( !oFakeImage )
+	{
+		oFakeImage	= oEditor.FCKDocumentProcessor_CreateFakeImage( 'FCK__MWRef', oRef ) ;
+		oFakeImage.setAttribute( '_fck_mw_ref', 'true', 0 ) ;
+		oFakeImage	= FCK.InsertElement( oFakeImage ) ;
+	}
+
+	return true ;
+}
+
+	</script>
+</head>
+<body style="overflow: hidden">
+	<div id="divInfo">
+		<table cellpadding="0" cellspacing="0" border="0" width="100%" height="100%">
+			<tr>
+				<td>
+					<span>Reference text (Wikitext)</span>
+				</td>
+			</tr>
+			<tr>
+				<td height="100%">
+					<textarea id="xRefText" style="width: 100%; height: 100%; font-family: Monospace"
+						cols="50" rows="5"></textarea>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					Reference name (optional)<br />
+					<input id="xRefName" type="text" size="15" />
+				</td>
+			</tr>
+		</table>
+	</div>
+</body>
+</html>
Index: /MediaWiki/trunk/plugins/mediawiki/dialogs/template.html
===================================================================
--- /MediaWiki/trunk/plugins/mediawiki/dialogs/template.html	(revision 1660)
+++ /MediaWiki/trunk/plugins/mediawiki/dialogs/template.html	(revision 1660)
@@ -0,0 +1,123 @@
+﻿<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Link dialog window.
+-->
+<html>
+<head>
+	<title>Template Properties</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<meta name="robots" content="noindex, nofollow" />
+	<script type="text/javascript">
+
+var oEditor		= window.parent.InnerDialogLoaded() ;
+var FCK			= oEditor.FCK ;
+var FCKLang		= oEditor.FCKLang ;
+var FCKConfig	= oEditor.FCKConfig ;
+var FCKRegexLib	= oEditor.FCKRegexLib ;
+var FCKTools	= oEditor.FCKTools ;
+
+document.write( '<script src="' + FCKConfig.BasePath + 'dialog/common/fck_dialog_common.js" type="text/javascript"><\/script>' ) ;
+
+	</script>
+	<script type="text/javascript">
+
+// Get the selected flash embed (if available).
+var oFakeImage = FCK.Selection.GetSelectedElement() ;
+var oTemplateSpan ;
+
+if ( oFakeImage )
+{
+	if ( oFakeImage.tagName == 'IMG' && oFakeImage.getAttribute('_fck_mw_template') )
+		oTemplateSpan = FCK.GetRealElement( oFakeImage ) ;
+	else
+		oFakeImage = null ;
+}
+
+window.onload = function()
+{
+	// Translate the dialog box texts.
+	oEditor.FCKLanguageManager.TranslatePage(document) ;
+
+	// Load the selected link information (if any).
+	LoadSelection() ;
+
+	// Activate the "OK" button.
+	window.parent.SetOkButton( true ) ;
+	window.parent.SetAutoSize( true ) ;
+}
+
+function LoadSelection()
+{
+	if ( !oTemplateSpan ) return ;
+
+	GetE('xTemplateRaw').value = FCKTools.HTMLDecode( oTemplateSpan.innerHTML ).replace( /&quot;/g, '"' ) ;
+}
+
+//#### The OK button was hit.
+function Ok()
+{
+	if ( !oTemplateSpan )
+	{
+		oTemplateSpan = FCK.EditorDocument.createElement( 'SPAN' ) ;
+		oTemplateSpan.className = 'fck_mw_template' ;
+	}
+	
+	var templateData = FCKTools.HTMLEncode( GetE('xTemplateRaw').value ).Trim().replace( /"/g, '&quot;' ) ;
+	
+	if ( !( /^{{[\s\S]+}}$/.test( templateData ) ) )
+	{
+		alert( 'Templates must start with {{ and end with }}. Please check it.' ) ;
+		return false ;
+	}
+	
+	oTemplateSpan.innerHTML = templateData ;
+
+	if ( !oFakeImage )
+	{
+		oFakeImage	= oEditor.FCKDocumentProcessor_CreateFakeImage( 'FCK__MWTemplate', oTemplateSpan ) ;
+		oFakeImage.setAttribute( '_fck_mw_template', 'true', 0 ) ;
+		oFakeImage	= FCK.InsertElement( oFakeImage ) ;
+	}
+
+	return true ;
+}
+
+	</script>
+</head>
+<body style="overflow: hidden">
+	<div id="divInfo">
+		<table cellpadding="0" cellspacing="0" border="0" width="100%" height="100%">
+			<tr>
+				<td>
+					<span>Template raw definition (from {{ to }})</span><br />
+				</td>
+			</tr>
+			<tr>
+				<td height="100%">
+					<textarea id="xTemplateRaw" style="width: 100%; height: 100%; font-family: Monospace"
+						cols="50" rows="10" wrap="off"></textarea>
+				</td>
+			</tr>
+		</table>
+	</div>
+</body>
+</html>
Index: /MediaWiki/trunk/plugins/mediawiki/fckplugin.js
===================================================================
--- /MediaWiki/trunk/plugins/mediawiki/fckplugin.js	(revision 1660)
+++ /MediaWiki/trunk/plugins/mediawiki/fckplugin.js	(revision 1660)
@@ -0,0 +1,694 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Main MediaWiki integration plugin.
+ *
+ * Wikitext syntax reference:
+ *	http://meta.wikimedia.org/wiki/Help:Wikitext_examples
+ *	http://meta.wikimedia.org/wiki/Help:Advanced_editing
+ *
+ * MediaWiki Sandbox:
+ *	http://meta.wikimedia.org/wiki/Meta:Sandbox
+ */
+
+// Rename the "Source" buttom to "Wikitext".
+FCKToolbarItems.RegisterItem( 'Source', new FCKToolbarButton( 'Source', 'Wikitext', null, FCK_TOOLBARITEM_ICONTEXT, true, true, 1 ) ) ;
+
+// Register our toolbar buttons.
+var tbButton = new FCKToolbarButton( 'MW_Template', 'Template', 'Insert/Edit Template' ) ;
+tbButton.IconPath = FCKConfig.PluginsPath + 'mediawiki/images/tb_icon_template.gif' ;
+FCKToolbarItems.RegisterItem( 'MW_Template', tbButton ) ;
+
+tbButton = new FCKToolbarButton( 'MW_Ref', 'Reference', 'Insert/Edit Reference' ) ;
+tbButton.IconPath = FCKConfig.PluginsPath + 'mediawiki/images/tb_icon_ref.gif' ;
+FCKToolbarItems.RegisterItem( 'MW_Ref', tbButton ) ;
+
+tbButton = new FCKToolbarButton( 'MW_Math', 'Formula', 'Insert/Edit Formula' ) ;
+tbButton.IconPath = FCKConfig.PluginsPath + 'mediawiki/images/tb_icon_math.gif' ;
+FCKToolbarItems.RegisterItem( 'MW_Math', tbButton ) ;
+
+// Override some dialogs.
+FCKCommands.RegisterCommand( 'MW_Template', new FCKDialogCommand( 'MW_Template', 'Template Properties', FCKConfig.PluginsPath + 'mediawiki/dialogs/template.html', 400, 330 ) ) ;
+FCKCommands.RegisterCommand( 'MW_Ref', new FCKDialogCommand( 'MW_Ref', 'Reference Properties', FCKConfig.PluginsPath + 'mediawiki/dialogs/ref.html', 400, 250 ) ) ;
+FCKCommands.RegisterCommand( 'MW_Math', new FCKDialogCommand( 'MW_Math', 'Formula', FCKConfig.PluginsPath + 'mediawiki/dialogs/math.html', 400, 300 ) ) ;
+FCKCommands.RegisterCommand( 'Link', new FCKDialogCommand( 'Link', FCKLang.DlgLnkWindowTitle, FCKConfig.PluginsPath + 'mediawiki/dialogs/link.html', 400, 250 ) ) ;
+FCKCommands.RegisterCommand( 'Image', new FCKDialogCommand( 'Image', FCKLang.DlgImgTitle, FCKConfig.PluginsPath + 'mediawiki/dialogs/image.html', 450, 300 ) ) ;
+
+// MediaWiki Wikitext Data Processor implementation.
+FCK.DataProcessor =
+{
+	_inPre : false,
+	_inLSpace : false,	
+
+	/*
+	 * Returns a string representing the HTML format of "data". The returned
+	 * value will be loaded in the editor.
+	 * The HTML must be from <html> to </html>, eventually including
+	 * the DOCTYPE.
+	 *     @param {String} data The data to be converted in the
+	 *            DataProcessor specific format.
+	 */
+	ConvertToHtml : function( data )
+	{
+		// Call the original code.
+		return FCKDataProcessor.prototype.ConvertToHtml.call( this, data ) ;
+	},
+
+	/*
+	 * Converts a DOM (sub-)tree to a string in the data format.
+	 *     @param {Object} rootNode The node that contains the DOM tree to be
+	 *            converted to the data format.
+	 *     @param {Boolean} excludeRoot Indicates that the root node must not
+	 *            be included in the conversion, only its children.
+	 *     @param {Boolean} format Indicates that the data must be formatted
+	 *            for human reading. Not all Data Processors may provide it.
+	 */
+	ConvertToDataFormat : function( rootNode, excludeRoot, ignoreIfEmptyParagraph, format )
+	{
+		// rootNode is <body>.
+
+		// Normalize the document for text node processing.
+		rootNode.normalize() ;
+
+		var stringBuilder = new Array() ;
+		this._AppendNode( rootNode, stringBuilder ) ;
+		return stringBuilder.join( '' ).Trim() ;
+	},
+
+	/*
+	 * Makes any necessary changes to a piece of HTML for insertion in the
+	 * editor selection position.
+	 *     @param {String} html The HTML to be fixed.
+	 */
+	FixHtml : function( html )
+	{
+		return html ;
+	},
+
+	// Collection of element definitions:
+	//		0 : Prefix
+	//		1 : Suffix
+	//		2 : Ignore children
+	_BasicElements : {
+		body	: [ ],
+		b		: [ "'''", "'''" ],
+		strong	: [ "'''", "'''" ],
+		i		: [ "''", "''" ],
+		em		: [ "''", "''" ],
+		p		: [ '\n', '\n' ],
+		h1		: [ '\n= ', ' =\n' ],
+		h2		: [ '\n== ', ' ==\n' ],
+		h3		: [ '\n=== ', ' ===\n' ],
+		h4		: [ '\n==== ', ' ====\n' ],
+		h5		: [ '\n===== ', ' =====\n' ],
+		h6		: [ '\n====== ', ' ======\n' ],
+		br		: [ '<br>', null, true ],
+		hr		: [ '\n----\n', null, true ]
+	} ,
+
+	// This function is based on FCKXHtml._AppendNode.
+	_AppendNode : function( htmlNode, stringBuilder )
+	{
+		if ( !htmlNode )
+			return ;
+
+		switch ( htmlNode.nodeType )
+		{
+			// Element Node.
+			case 1 :
+
+				// Here we found an element that is not the real element, but a
+				// fake one (like the Flash placeholder image), so we must get the real one.
+				if ( htmlNode.getAttribute('_fckfakelement') && !htmlNode.getAttribute( '_fck_mw_math' ) )
+					return this._AppendNode( FCK.GetRealElement( htmlNode ), stringBuilder ) ;
+
+				// Mozilla insert custom nodes in the DOM.
+				if ( FCKBrowserInfo.IsGecko && htmlNode.hasAttribute('_moz_editor_bogus_node') )
+					return ;
+
+				// This is for elements that are instrumental to FCKeditor and
+				// must be removed from the final HTML.
+				if ( htmlNode.getAttribute('_fcktemp') )
+					return ;
+
+				// Get the element name.
+				var sNodeName = htmlNode.tagName.toLowerCase()  ;
+
+				if ( FCKBrowserInfo.IsIE )
+				{
+					// IE doens't include the scope name in the nodeName. So, add the namespace.
+					if ( htmlNode.scopeName && htmlNode.scopeName != 'HTML' && htmlNode.scopeName != 'FCK' )
+						sNodeName = htmlNode.scopeName.toLowerCase() + ':' + sNodeName ;
+				}
+				else
+				{
+					if ( sNodeName.StartsWith( 'fck:' ) )
+						sNodeName = sNodeName.Remove( 0,4 ) ;
+				}
+
+				// Check if the node name is valid, otherwise ignore this tag.
+				// If the nodeName starts with a slash, it is a orphan closing tag.
+				// On some strange cases, the nodeName is empty, even if the node exists.
+				if ( !FCKRegexLib.ElementName.test( sNodeName ) )
+					return ;
+
+				if ( sNodeName == 'br' && ( this._inPre || this._inLSpace ) ) 
+				{
+					stringBuilder.push( "\n" ) ;
+					if ( this._inLSpace )
+						stringBuilder.push( " " ) ;
+					return ;
+				}
+					
+				// Remove the <br> if it is a bogus node.
+				if ( sNodeName == 'br' && htmlNode.getAttribute( 'type', 2 ) == '_moz' )
+					return ;
+
+				// The already processed nodes must be marked to avoid then to be duplicated (bad formatted HTML).
+				// So here, the "mark" is checked... if the element is Ok, then mark it.
+				if ( htmlNode._fckxhtmljob && htmlNode._fckxhtmljob == FCKXHtml.CurrentJobNum )
+					return ;
+
+				var basicElement = this._BasicElements[ sNodeName ] ;
+				if ( basicElement )
+				{
+					if ( basicElement[0] )
+						stringBuilder.push( basicElement[0] ) ;
+
+					if ( !basicElement[2] )
+						this._AppendChildNodes( htmlNode, stringBuilder ) ;
+
+					if ( basicElement[1] )
+						stringBuilder.push( basicElement[1] ) ;
+				}
+				else
+				{
+					switch ( sNodeName )
+					{
+						case 'ol' :
+						case 'ul' :
+							var isFirstLevel = !htmlNode.parentNode.nodeName.IEquals( 'ul', 'ol', 'li' ) ;
+
+							this._AppendChildNodes( htmlNode, stringBuilder ) ;
+
+							if ( isFirstLevel )
+								stringBuilder.push( '\n' ) ;
+
+							break ;
+
+						case 'li' :
+
+							stringBuilder.push( '\n' ) ;
+
+							var listPrefix = '' ;
+							var parent = htmlNode.parentNode ;
+
+							while ( parent )
+							{
+								if ( parent.nodeName.toLowerCase() == 'ul' )
+									listPrefix = '*' + listPrefix ;
+								else if ( parent.nodeName.toLowerCase() == 'ol' )
+									listPrefix = '#' + listPrefix ;
+								else if ( parent.nodeName.toLowerCase() != 'li' )
+									break ;
+
+								parent = parent.parentNode ;
+							}
+
+							stringBuilder.push( listPrefix ) ;
+							stringBuilder.push( ' ' ) ;
+							this._AppendChildNodes( htmlNode, stringBuilder ) ;
+
+							break ;
+
+						case 'a' :
+
+							// Get the actual Link href.
+							var href = htmlNode.getAttribute( '_fcksavedurl' ) ;
+							var hrefType		= htmlNode.getAttribute( '_fck_mw_type' ) || '' ;
+							
+							if ( href == null )
+								href = htmlNode.getAttribute( 'href' , 2 ) || '' ;
+
+							if ( hrefType == "media" )
+							{
+								var isWikiUrl = true ;
+								stringBuilder.push( '[[Media:' ) ;
+							}
+							else
+							{
+								var isWikiUrl = !( href.StartsWith( 'mailto:' ) || /^\w+:\/\//.test( href ) ) ;
+								stringBuilder.push( isWikiUrl ? '[[' : '[' ) ;
+							}
+							stringBuilder.push( href ) ;
+							if ( href != htmlNode.innerHTML && htmlNode.innerHTML != '[n]' )
+							{
+								stringBuilder.push( isWikiUrl? '|' : ' ' ) ;
+								this._AppendChildNodes( htmlNode, stringBuilder ) ;
+							}
+							stringBuilder.push( isWikiUrl ? ']]' : ']' ) ;
+
+							break ;
+							
+						case 'dl' :
+							stringBuilder.push( '\n' ) ;
+							this._AppendChildNodes( htmlNode, stringBuilder ) ;
+							if (stringBuilder.length > 0 && !stringBuilder[ stringBuilder.length - 1 ].EndsWith( '\n' ))
+								stringBuilder.push( '\n' ) ;
+							break ;
+
+						case 'dt' :
+							stringBuilder.push( ';' ) ;
+							this._AppendChildNodes( htmlNode, stringBuilder ) ;
+							break ;
+
+						case 'dd' :
+							stringBuilder.push( ':' ) ;
+							this._AppendChildNodes( htmlNode, stringBuilder ) ;
+							stringBuilder.push( '\n' ) ;
+							break ;
+							
+						case 'table' :
+
+							var attribs = this._GetAttributesStr( htmlNode ) ;
+
+							stringBuilder.push( '\n{|' ) ;
+							if ( attribs.length > 0 )
+								stringBuilder.push( attribs ) ;
+							stringBuilder.push( '\n' ) ;
+
+							if ( htmlNode.caption && htmlNode.caption.innerHTML.length > 0 )
+							{
+								stringBuilder.push( '|+ ' ) ;
+								this._AppendChildNodes( htmlNode.caption, stringBuilder ) ;
+								stringBuilder.push( '\n' ) ;
+							}
+
+							for ( var r = 0 ; r < htmlNode.rows.length ; r++ )
+							{
+								attribs = this._GetAttributesStr( htmlNode.rows[r] ) ;
+
+								stringBuilder.push( '|-' ) ;
+								if ( attribs.length > 0 )
+									stringBuilder.push( attribs ) ;
+								stringBuilder.push( '\n' ) ;
+
+								for ( var c = 0 ; c < htmlNode.rows[r].cells.length ; c++ )
+								{
+									attribs = this._GetAttributesStr( htmlNode.rows[r].cells[c] ) ;
+
+									stringBuilder.push( '|' ) ;
+
+									if ( attribs.length > 0 )
+										stringBuilder.push( attribs + ' |' ) ;
+
+									stringBuilder.push( ' ' ) ;
+
+									this._IsInsideCell = true ;
+									this._AppendChildNodes( htmlNode.rows[r].cells[c], stringBuilder ) ;
+									this._IsInsideCell = false ;
+
+									stringBuilder.push( '\n' ) ;
+								}
+							}
+
+							stringBuilder.push( '|}\n' ) ;
+
+							break ;
+
+						case 'img' :
+
+							var formula = htmlNode.getAttribute( '_fck_mw_math' ) ;
+
+							if ( formula && formula.length > 0 )
+							{
+								stringBuilder.push( '<math>' ) ;
+								stringBuilder.push( formula ) ;
+								stringBuilder.push( '</math>' ) ;
+								return ;
+							}
+
+							var imgName		= htmlNode.getAttribute( '_fck_mw_filename' ) ;
+							var imgCaption	= htmlNode.getAttribute( 'alt' ) || '' ;
+							var imgType		= htmlNode.getAttribute( '_fck_mw_type' ) || '' ;
+							var imgLocation	= htmlNode.getAttribute( '_fck_mw_location' ) || '' ;
+							var imgWidth	= htmlNode.getAttribute( '_fck_mw_width' ) || '' ;
+							var imgHeight	= htmlNode.getAttribute( '_fck_mw_height' ) || '' ;
+
+							stringBuilder.push( '[[Image:' )
+							stringBuilder.push( imgName )
+
+							if ( imgType.length > 0 )
+								stringBuilder.push( '|' + imgType ) ;
+
+							if ( imgLocation.length > 0 )
+								stringBuilder.push( '|' + imgLocation ) ;
+
+							if ( imgWidth.length > 0 )
+							{
+								stringBuilder.push( '|' + imgWidth ) ;
+
+								if ( imgHeight.length > 0 )
+									stringBuilder.push( 'x' + imgHeight ) ;
+
+								stringBuilder.push( 'px' ) ;
+							}
+
+							if ( imgCaption.length > 0 )
+								stringBuilder.push( '|' + imgCaption ) ;
+
+							stringBuilder.push( ']]' )
+
+							break ;
+
+						case 'span' :
+							switch ( htmlNode.className )
+							{
+								case 'fck_mw_ref' :
+									var refName = htmlNode.getAttribute( 'name' ) ;
+
+									stringBuilder.push( '<ref' ) ;
+
+									if ( refName && refName.length > 0 )
+										stringBuilder.push( ' name="' + refName + '"' ) ;
+
+									if ( htmlNode.innerHTML.length == 0 )
+										stringBuilder.push( ' />' ) ;
+									else
+									{
+										stringBuilder.push( '>' ) ;
+										stringBuilder.push( htmlNode.innerHTML ) ;
+										stringBuilder.push( '</ref>' ) ;
+									}
+									return ;
+
+								case 'fck_mw_references' :
+									stringBuilder.push( '<references />' ) ;
+									return ;
+
+								case 'fck_mw_template' :
+									stringBuilder.push( FCKTools.HTMLDecode(htmlNode.innerHTML) ) ;
+									return ;
+								
+								case 'fck_mw_magic' :
+									stringBuilder.push( htmlNode.innerHTML ) ;
+									return ;
+
+								case 'fck_mw_nowiki' :
+									sNodeName = 'nowiki' ;
+									break ;
+
+								case 'fck_mw_includeonly' :
+									sNodeName = 'includeonly' ;
+									break ;
+
+								case 'fck_mw_noinclude' :
+									sNodeName = 'noinclude' ;
+									break ;
+
+								case 'fck_mw_onlyinclude' :
+									sNodeName = 'onlyinclude' ;
+									break ;
+							}
+
+							// Change the node name and fell in the "default" case.
+							if ( htmlNode.getAttribute( '_fck_mw_customtag' ) )
+								sNodeName = htmlNode.getAttribute( '_fck_mw_tagname' ) ;
+
+						case 'pre' :
+							var attribs = this._GetAttributesStr( htmlNode ) ;
+							
+							if ( htmlNode.className == "_fck_mw_lspace")
+							{
+								stringBuilder.push( "\n " ) ;
+								this._inLSpace = true ;
+								this._AppendChildNodes( htmlNode, stringBuilder ) ;
+								this._inLSpace = false ;
+								if ( stringBuilder[stringBuilder.length-2] == "\n" && stringBuilder[stringBuilder.length-1] == " " )
+									stringBuilder.pop() ;
+								else
+									stringBuilder.push( "\n" ) ;
+							}
+							else
+							{
+								stringBuilder.push( '<' ) ;
+								stringBuilder.push( sNodeName ) ;
+
+								if ( attribs.length > 0 )
+									stringBuilder.push( attribs ) ;
+
+								stringBuilder.push( '>' ) ;
+								this._inPre = true ;
+								this._AppendChildNodes( htmlNode, stringBuilder ) ;
+								this._inPre = false ;
+								stringBuilder.push( '<\/' ) ;
+								stringBuilder.push( sNodeName ) ;
+								stringBuilder.push( '>' ) ;								
+							}
+						
+							break ;
+						default :
+							var attribs = this._GetAttributesStr( htmlNode ) ;
+
+							stringBuilder.push( '<' ) ;
+							stringBuilder.push( sNodeName ) ;
+
+							if ( attribs.length > 0 )
+								stringBuilder.push( attribs ) ;
+
+							stringBuilder.push( '>' ) ;
+							this._AppendChildNodes( htmlNode, stringBuilder ) ;
+							stringBuilder.push( '<\/' ) ;
+							stringBuilder.push( sNodeName ) ;
+							stringBuilder.push( '>' ) ;
+							break ;
+					}
+				}
+
+				htmlNode._fckxhtmljob = FCKXHtml.CurrentJobNum ;
+				return ;
+
+			// Text Node.
+			case 3 :
+
+				var parentIsSpecialTag = htmlNode.parentNode.getAttribute( '_fck_mw_customtag' ) ; 
+				var textValue = htmlNode.nodeValue;
+
+				if ( !parentIsSpecialTag ) 
+				{
+					textValue = textValue.replace( /[\n\t]/g, ' ' ) ; 
+					textValue = FCKTools.HTMLEncode( textValue ) ;
+					textValue = textValue.replace( /\u00A0/g, '&nbsp;' ) ;
+
+					if ( !htmlNode.previousSibling ||
+					( stringBuilder.length > 0 && stringBuilder[ stringBuilder.length - 1 ].EndsWith( '\n' ) ) && !this._inLSpace )
+					{
+						textValue = textValue.LTrim() ;
+					}
+
+					if ( !htmlNode.nextSibling && !this._inLSpace )
+						textValue = textValue.RTrim() ;
+
+					textValue = textValue.replace( / {2,}/g, ' ' ) ;
+
+					if ( this._inLSpace && textValue.length == 1 && textValue.charCodeAt(0) == 13 )
+						textValue = textValue + " " ;
+					
+					if ( this._IsInsideCell )
+						textValue = textValue.replace( /\|/g, '&#124;' ) ;
+	
+				}
+				else 
+				{
+					textValue = FCKTools.HTMLDecode( textValue ) ;
+				}
+
+				stringBuilder.push( textValue ) ;
+				return ;
+
+			// Comment
+			case 8 :
+				// IE catches the <!DOTYPE ... > as a comment, but it has no
+				// innerHTML, so we can catch it, and ignore it.
+				if ( FCKBrowserInfo.IsIE && !htmlNode.innerHTML )
+					return ;
+
+				stringBuilder.push( "<!--"  ) ;
+
+				try	{ stringBuilder.push( htmlNode.nodeValue ) ; }
+				catch (e) { /* Do nothing... probably this is a wrong format comment. */ }
+
+				stringBuilder.push( " -->" ) ;
+				return ;
+		}
+	},
+
+	_AppendChildNodes : function( htmlNode, stringBuilder, isBlockElement )
+	{
+		var child = htmlNode.firstChild ;
+
+		while ( child )
+		{
+			this._AppendNode( child, stringBuilder ) ;
+			child = child.nextSibling ;
+		}
+	},
+
+	_GetAttributesStr : function( htmlNode )
+	{
+		var attStr = '' ;
+		var aAttributes = htmlNode.attributes ;
+
+		for ( var n = 0 ; n < aAttributes.length ; n++ )
+		{
+			var oAttribute = aAttributes[n] ;
+
+			if ( oAttribute.specified )
+			{
+				var sAttName = oAttribute.nodeName.toLowerCase() ;
+				var sAttValue ;
+
+				// Ignore any attribute starting with "_fck".
+				if ( sAttName.StartsWith( '_fck' ) )
+					continue ;
+				// There is a bug in Mozilla that returns '_moz_xxx' attributes as specified.
+				else if ( sAttName.indexOf( '_moz' ) == 0 )
+					continue ;
+				// For "class", nodeValue must be used.
+				else if ( sAttName == 'class' )
+				{
+					// Get the class, removing any fckXXX we can have there.
+					sAttValue = oAttribute.nodeValue.replace( /(^|\s*)fck\S+/, '' ).Trim() ;
+
+					if ( sAttValue.length == 0 )
+						continue ;
+				}
+				// XHTML doens't support attribute minimization like "CHECKED". It must be trasformed to cheched="checked".
+				else if ( oAttribute.nodeValue === true )
+					sAttValue = sAttName ;
+				else
+					sAttValue = htmlNode.getAttribute( sAttName, 2 ) ;	// We must use getAttribute to get it exactly as it is defined.
+
+				attStr += ' ' + sAttName + '="' + sAttValue.replace( '"', '&quot;' ) + '"' ;
+			}
+		}
+		return attStr ;
+	}
+} ;
+
+// Here we change the SwitchEditMode function to make the Ajax call when
+// switching from Wikitext.
+(function()
+{
+	var original = FCK.SwitchEditMode ;
+
+	FCK.SwitchEditMode = function()
+	{
+		var args = arguments ;
+
+		var loadHTMLFromAjax = function( result )
+		{
+			FCK.EditingArea.Textarea.value = result.responseText ;
+			original.apply( FCK, args ) ;
+		}
+
+		if ( FCK.EditMode == FCK_EDITMODE_SOURCE )
+		{
+			// Hide the textarea to avoid seeing the code change.
+			FCK.EditingArea.Textarea.style.visibility = 'hidden' ;
+
+			var loading = document.createElement( 'span' ) ;
+			loading.innerHTML = '&nbsp;Loading Wikitext. Please wait...&nbsp;' ;
+			loading.style.position = 'absolute' ;
+			loading.style.left = '5px' ;
+//			loading.style.backgroundColor = '#ff0000' ;
+			FCK.EditingArea.Textarea.parentNode.appendChild( loading, FCK.EditingArea.Textarea ) ;
+
+			// Use Ajax to transform the Wikitext to HTML.
+			window.parent.sajax_request_type = 'POST' ;
+			window.parent.sajax_do_call( 'wfSajaxWikiToHTML', [FCK.EditingArea.Textarea.value], loadHTMLFromAjax ) ;
+		}
+		else
+			original.apply( FCK, args ) ;
+	}
+})() ;
+
+// MediaWiki document processor.
+FCKDocumentProcessor.AppendNew().ProcessDocument = function( document )
+{
+	// Templates and magic words.
+	var aSpans = document.getElementsByTagName( 'SPAN' ) ;
+
+	var eSpan ;
+	var i = aSpans.length - 1 ;
+	while ( i >= 0 && ( eSpan = aSpans[i--] ) )
+	{
+		var className = null ;
+		switch ( eSpan.className )
+		{
+			case 'fck_mw_ref' :
+				className = 'FCK__MWRef' ;
+			case 'fck_mw_references' :
+				if ( className == null )
+					className = 'FCK__MWReferences' ;
+			case 'fck_mw_template' :
+			case 'fck_mw_magic' :
+				if ( className == null )
+					className = 'FCK__MWTemplate' ;
+
+				var oImg = FCKDocumentProcessor_CreateFakeImage( className, eSpan.cloneNode(true) ) ;
+				oImg.setAttribute( '_' + eSpan.className, 'true', 0 ) ;
+
+				eSpan.parentNode.insertBefore( oImg, eSpan ) ;
+				eSpan.parentNode.removeChild( eSpan ) ;
+			break ;
+		}
+	}
+}
+
+// Context menu for templates.
+FCK.ContextMenu.RegisterListener({
+	AddItems : function( contextMenu, tag, tagName )
+	{
+		if ( tagName == 'IMG' )
+		{
+			if ( tag.getAttribute( '_fck_mw_template' ) )
+			{
+				contextMenu.AddSeparator() ;
+				contextMenu.AddItem( 'MW_Template', 'Template Properties' ) ;
+			}
+			if ( tag.getAttribute( '_fck_mw_magic' ) )
+			{
+				contextMenu.AddSeparator() ;
+				contextMenu.AddItem( 'MW_MagicWord', 'Modify Magic Word' ) ;
+			}
+			if ( tag.getAttribute( '_fck_mw_ref' ) )
+			{
+				contextMenu.AddSeparator() ;
+				contextMenu.AddItem( 'MW_Ref', 'Reference Properties' ) ;
+			}
+			if ( tag.getAttribute( '_fck_mw_math' ) )
+			{
+				contextMenu.AddSeparator() ;
+				contextMenu.AddItem( 'MW_Math', 'Edit Formula' ) ;
+			}
+		}
+	}
+}) ;
