Topic on Extension talk:WYSIWYG

Andreas Jonsson (talkcontribs)

Disclaimer: This is a patch against a slightly customized variant of version 1.6.0, so it might not apply cleanly. It is not tested very much and it might not be backwards compliant with older MediaWiki releases.

Also, please note that to support self links correctly, it will be necessary to either modify core or to copy and paste the method 'replaceInternalLinks2' from the core parser.

=== modified file 'extensions/WYSIWYG/CKeditor.body.php'
--- extensions/WYSIWYG/CKeditor.body.php	2012-02-27 13:33:51 +0000
+++ extensions/WYSIWYG/CKeditor.body.php	2012-03-05 07:37:32 +0000
@@ -130,7 +130,9 @@
 	}
 
 	public static function onParserBeforeStrip( &$parser, &$text, &$stripState ) {
-		$text = $parser->strip( $text, $stripState );
+		if (get_class($parser) == 'CKeditorParser') {
+			$text = $parser->strip( $text, $stripState );
+		}
 		return true;
 	}
 
@@ -219,25 +221,22 @@
  
 
 	public function onCustomEditor( $article, $user ) {
-		global $wgRequest, $mediaWiki;
+		global $wgRequest, $wgUseExternalEditor;
 
-		$action = $mediaWiki->getVal( 'Action' );
+		$action = $wgRequest->getVal( 'action', 'view' );
 
 		$internal = $wgRequest->getVal( 'internaledit' );
 		$external = $wgRequest->getVal( 'externaledit' );
 		$section = $wgRequest->getVal( 'section' );
 		$oldid = $wgRequest->getVal( 'oldid' );
-		if( !$mediaWiki->getVal( 'UseExternalEditor' ) || $action == 'submit' || $internal ||
+		if( !$wgUseExternalEditor || $action == 'submit' || $internal ||
 		$section || $oldid || ( !$user->getOption( 'externaleditor' ) && !$external ) ) {
 			$editor = new CKeditorEditPage( $article );
-			$editor->submit();
-		} elseif( $mediaWiki->getVal( 'UseExternalEditor' ) && ( $external || $user->getOption( 'externaleditor' ) ) ) {
-			$mode = $wgRequest->getVal( 'mode' );
-			$extedit = new ExternalEdit( $article, $mode );
-			$extedit->edit();
+			$editor->edit();
+			return false;
+		} else {
+			return true;
 		}
-
-		return false;
 	}
 
     public static function onDoEditSectionLink ($skin, $title, $section, $tooltip, $result, $lang = false ) {
@@ -491,7 +490,7 @@
 		$skin->mTitle =& $wgTitle;
 		$skin->initPage( $wgOut );
 		$skin->userpage = $wgUser->getUserPage()->getPrefixedText();
-		$skin->setupUserCss( $wgOut );
+		$skin->setupSkinUserCss( $wgOut );
 
 		if( !empty( $skin->usercss ) && preg_match_all( '/@import "([^"]+)";/', $skin->usercss, $matches ) ) {
 			$userStyles = $matches[1];
@@ -692,13 +691,6 @@
     */
 	if( showFCKEditor & RTE_VISIBLE ){
 		if ( toolbar ){	// insert wiki buttons
-			// 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 ; };
-
 			for( var i = 0; i < mwEditButtons.length; i++ ) {
 				mwInsertEditButton(toolbar, mwEditButtons[i]);
 			}

=== added file 'extensions/WYSIWYG/CKeditorLinker.php'
--- extensions/WYSIWYG/CKeditorLinker.php	1970-01-01 00:00:00 +0000
+++ extensions/WYSIWYG/CKeditorLinker.php	2012-03-05 07:52:14 +0000
@@ -0,0 +1,448 @@
+<?php
+
+/**
+ * Since the core parser have moved to use a static method pattern for
+ * rendering links, the functionality from CKeditorSkin has been moved
+ * here and now relies on hooks.
+ *
+ * The methods in the skin that as of 1.19 are no longer called from
+ * core has been ignored, which means that some extensions might break.
+ *
+ * The method 'makeSelfLinkObj' is called directly from the core
+ * parser, but no hook is available for it, so a patch to core is
+ * required to support it.
+ *
+ * The public methods of CKeditorSkin are:
+ * 
+ * makeImageLink2 - used in core, hook available: ImageBeforeProduceHTML
+ * makeLinkObj - deprecated, unused in core
+ * makeKnownLinkObj - deprecated, unused in core
+ * makeColouredLinkObj - deprecated, unused in core
+ * makeBrokenLinkObj - only used in makeImageLink2
+ * makeSelfLinkObj - used by core parser, impossible to hook
+ * makeMediaLinkObj - only used by formatComment in core
+ * makeExternalLink - used in core, hook available: LinkerMakeExternalLink
+ */
+class CKeditorLinker {
+
+	public static function addHooks() {
+		global $wgHooks;
+
+		$wgHooks['ImageBeforeProduceHTML'][] = 'CKeditorLinker::makeImageLink2';
+		$wgHooks['LinkerMakeExternalLink'][] = 'CKeditorLinker::makeExternalLink';
+		$wgHooks['LinkEnd'][]                = 'CKeditorLinker::linkEnd';
+		$wgHooks['LinkBegin'][]              = 'CKeditorLinker::linkBegin';
+	}
+
+	public static function removeHooks() {
+		self::removeHook('ImageBeforeProduceHTML', 'CKeditorLinker::makeImageLink2');
+		self::removeHook('LinkerMakeExternalLink', 'CKeditorLinker::makeExternalLink');
+		self::removeHook('LinkEnd', 'CKeditorLinker::linkEnd');
+		self::removeHook('LinkBegin', 'CKeditorLinker::linkBegin');
+	}
+
+	private static function removeHook($hookName, $function) {
+		global $wgHooks;
+		$hook = $wgHooks[$hookName];
+		$i = array_search($function, $hook);
+		if ($i) {
+			$wgHooks[$hookName] = array_splice($hook, $i, 1);
+		}
+	}
+
+	/**
+	 * 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".
+	 */
+	static function makeImageLink2( $skin, Title $nt, $file, $frameParams = array(), $handlerParams = array(), $time, &$ret ) {
+		$orginal = $nt->getText();
+		$file = RepoGroup::singleton()->getLocalRepo()->newFile( $nt );
+		$found = $file->exists();
+
+		if( !empty( $frameParams['alt'] ) && $frameParams['alt'] == 'RTENOTITLE' ){ // 2223
+			$frameParams['alt'] = '';
+		}
+		if( $found ) {
+			$type = 'image';
+			if ($file->getMediaType() == MEDIATYPE_VIDEO) {
+				$type = 'video';
+			} else if ($file->getMediaType() == MEDIATYPE_AUDIO) {
+				$type = 'audio';
+			}
+			if ($type == 'image') {
+				$url = $file->getUrl();
+			} else {
+				$url = $file->createThumb( 230 );
+			}
+		}
+
+		// 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['border'] ) ) {
+			$ret .= "_fck_mw_type=\"border" . "\" ";
+			$class .= 'fck_mw_border';
+		} 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'] ) && $fp['alt'] != 'Image:' . $orginal ) {
+			$ret .= "alt=\"" . htmlspecialchars( $fp['alt'] ) . "\" ";
+		} else {
+			$ret .= "alt=\"\" ";
+		}
+
+		if( $class ) {
+			$ret .= "class=\"$class\" ";
+		}
+        if (isset($fp['no-link']))
+            $ret .= 'no-link="1" ';
+        if (isset($fp['link-title']) && is_object($fp['link-title']))
+            $ret .= 'link="'.htmlentities ($fp['link-title']->getFullText()).'" ';
+        if (isset($fp['link-url']))
+            $ret .= 'link="'.$fp['link-url'].'" ';
+
+		$ret .= '/>';
+
+		return false;
+	}
+
+	static function makeExternalLink( $url, $text, &$link, &$attribs, $linktype ) {
+		$url = htmlspecialchars( $url );
+		$text = htmlspecialchars( $text );
+		$url = preg_replace( "/^RTECOLON/", ":", $url ); // change 'RTECOLON' => ':'
+		$args = '';
+		if( $text == 'RTENOTITLE' ){ // 2223
+			$args .= '_fcknotitle="true" ';
+			$text = $url;
+		}
+		$link= '<a ' . $args . 'href="' . $url . '">' . $text . '</a>';
+
+		return false;
+	}
+
+	function makeColouredLinkObj( $nt, $colour, $text = '', $query = '', $trail = '', $prefix = '' ) {
+		return self::makeKnownLinkObj( $nt, $text, $query, $trail, $prefix, '', $style );
+	}
+
+	function makeKnownLinkObj( $nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '', $style = '' ) {
+		wfProfileIn( __METHOD__ );
+
+		$args = '';
+		if ( !is_object( $nt ) ) {
+			wfProfileOut( __METHOD__ );
+			return $text;
+		}
+
+		$u = $nt->getFullText();
+		$u = rawurlencode($u);  // Fix for links containing "
+		//#Updating links tables -> #Updating_links_tables
+		$u = str_replace( "#" . $nt->getFragment(), $nt->getFragmentForURL(), $u );
+
+		if ( $nt->getFragment() != '' ) {
+			if( $nt->getPrefixedDBkey() == '' ) {
+				$u = '';
+				if ( '' == $text ) {
+					$text = htmlspecialchars( $nt->getFragment() );
+				}
+			}
+
+			/**
+			 * See tickets 1386 and 1690 before changing anything
+			 */
+			if( $nt->getPartialUrl() == '' ) {
+				$u .= $nt->getFragmentForURL();
+			}
+		}
+		if ( $text == '' ) {
+			$text = htmlspecialchars( $nt->getPrefixedText() );
+		}
+
+		if( $nt->getNamespace() == NS_CATEGORY ) {
+			$u = ':' . $u;
+		}
+
+		list( $inside, $trail ) = Linker::splitTrail( $trail );
+		$title = "{$prefix}{$text}{$inside}";
+
+		$u = preg_replace( "/^RTECOLON/", ":", $u ); // change 'RTECOLON' => ':'
+		if( substr( $text, 0, 10 ) == 'RTENOTITLE' ){ // starts with RTENOTITLE
+			$args .= '_fcknotitle="true" ';
+			$title = rawurldecode($u);
+			$trail = substr( $text, 10 ) . $trail;
+		}
+
+		$r = "<a {$args}href=\"{$u}\">{$title}</a>{$trail}";
+		wfProfileOut( __METHOD__ );
+		return $r;
+	}
+
+	function makeBrokenLinkObj( $nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
+		# Fail gracefully
+		if ( !isset( $nt ) ) {
+			# throw new MWException();
+			return "<!-- ERROR -->{$prefix}{$text}{$trail}";
+		}
+		$args = '';
+
+		wfProfileIn( __METHOD__ );
+
+		$u = $nt->getFullText();
+		$u = rawurlencode($u);  // Fix for links containing "
+		
+		//#Updating links tables -> #Updating_links_tables
+		$u = str_replace( "#" . $nt->getFragment(), $nt->getFragmentForURL(), $u );
+
+		if ( '' == $text ) {
+			$text = htmlspecialchars( $nt->getPrefixedText() );
+		}
+		if( $nt->getNamespace() == NS_CATEGORY ) {
+			$u = ':' . $u;
+		}
+
+		list( $inside, $trail ) = Linker::splitTrail( $trail );
+		$title = "{$prefix}{$text}{$inside}";
+
+		$u = preg_replace( "/^RTECOLON/", ":", $u ); // change 'RTECOLON' => ':'
+		if( substr( $text, 0, 10 ) == 'RTENOTITLE' ){	// starts with RTENOTITLE
+			$args .= '_fcknotitle="true" ';
+			$title = rawurldecode($u);
+			$trail = substr( $text, 10 ) . $trail;
+		}
+		$s = "<a {$args}href=\"{$u}\">{$title}</a>{$trail}";
+
+		wfProfileOut( __METHOD__ );
+		return $s;
+	}
+
+	static function makeSelfLinkObj( $nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
+		$args = '';
+		if ( '' == $text ) {
+			$text = $nt->mDbkeyform;
+		}
+		list( $inside, $trail ) = Linker::splitTrail( $trail );
+		$title = "{$prefix}{$text}";
+		if( $text == 'RTENOTITLE' ){ // 2223
+			$args .= '_fcknotitle="true" ';
+			$title = $nt->mDbkeyform;
+		}
+		return "<a {$args}href=\"".$nt->mDbkeyform."\" class=\"selflink\">{$title}</a>{$inside}{$trail}";
+	}
+
+	/**
+	 * Create a direct link to a given uploaded file.
+	 *
+	 * @param $title Title object.
+	 * @param $text  String: pre-sanitized HTML
+	 * @return string HTML
+	 *
+	 * @todo Handle invalid or missing images better.
+	 */
+	static function makeMediaLinkObj( $title, $text = '' ) {
+		if( is_null( $title ) ) {
+			### HOTFIX. Instead of breaking, return empty string.
+			return $text;
+		} else {
+			$args = '';
+			$orginal = $title->getPartialURL();
+			$img = wfFindFile( $title );
+			if( $img ) {
+				$url  = $img->getURL();
+				$class = 'internal';
+			} else {
+				$upload = SpecialPage::getTitleFor( 'Upload' );
+				$url = $upload->getLocalUrl( 'wpDestFile=' . urlencode( $title->getDBkey() ) );
+				$class = 'new';
+			}
+			$alt = htmlspecialchars( $title->getText() );
+			if( $text == '' ) {
+				$text = $alt;
+			}
+			$orginal = preg_replace( "/^RTECOLON/", ":", $orginal ); // change 'RTECOLON' => ':'
+			if( $text == 'RTENOTITLE' ){ // 2223
+				$args .= '_fcknotitle="true" ';
+				$text = $orginal;
+				$alt = $orginal;
+			}
+			return "<a href=\"{$orginal}\" class=\"$class\" {$args} _fck_mw_filename=\"{$orginal}\" _fck_mw_type=\"media\" title=\"{$alt}\">{$text}</a>";
+		}
+	}
+
+	static function linkBegin( $skin, Title $target, &$text, array &$attribs, &$query, &$options, &$ret) {
+		if ( $target->isExternal() ) {
+			$args = '';
+			$u = $target->getFullURL();
+			$link = $target->getPrefixedURL();
+			if ( '' == $text ) {
+				$text = $target->getPrefixedText();
+			}
+			$style = Linker::getInterwikiLinkAttributes( $link, $text, 'extiw' );
+
+			if( $text == 'RTENOTITLE' ) { // 2223
+				$text = $u = $link;
+				$args .= '_fcknotitle="true" ';
+			}
+			$t = "<a {$args}href=\"{$u}\"{$style}>{$text}</a>";
+
+			wfProfileOut( __METHOD__ );
+			$ret = $t;
+			return false;
+		}
+
+		return true;
+	}
+
+	static function linkEnd(  $skin, Title $target, array $options, &$text, array &$attribs, &$ret ) {
+
+		if ( in_array('known', $options) ) {
+			$args = '';
+			if ( !is_object( $target ) ) {
+				wfProfileOut( __METHOD__ );
+				return $text;
+			}
+
+			$u = $target->getFullText();
+			$u = rawurlencode($u);  // Fix for links containing "
+			//#Updating links tables -> #Updating_links_tables
+			$u = str_replace( "#" . $target->getFragment(), $target->getFragmentForURL(), $u );
+
+			if ( $target->getFragment() != '' ) {
+				if( $target->getPrefixedDBkey() == '' ) {
+					$u = '';
+					if ( '' == $text ) {
+						$text = htmlspecialchars( $target->getFragment() );
+					}
+				}
+
+				/**
+				 * See tickets 1386 and 1690 before changing anything
+				 */
+				if( $target->getPartialUrl() == '' ) {
+					$u .= $target->getFragmentForURL();
+				}
+			}
+			if ( $text == '' ) {
+				$text = htmlspecialchars( $target->getPrefixedText() );
+			}
+
+			if( $target->getNamespace() == NS_CATEGORY ) {
+				$u = ':' . $u;
+			}
+
+			$u = preg_replace( "/^RTECOLON/", ":", $u ); // change 'RTECOLON' => ':'
+			if( substr( $text, 0, 10 ) == 'RTENOTITLE' ){ // starts with RTENOTITLE
+				$args .= '_fcknotitle="true" ';
+				$text = rawurldecode($u);
+			}
+
+			$r = "<a {$args}href=\"{$u}\">{$text}</a>";
+			wfProfileOut( __METHOD__ );
+
+			$ret = $r;
+
+			return false;
+		}
+
+
+		if (in_array('broken', $options)) {
+			if ( !isset( $target ) ) {
+				# throw new MWException();
+				return "<!-- ERROR -->{$prefix}{$text}";
+			}
+			$args = '';
+
+			wfProfileIn( __METHOD__ );
+
+			$u = $target->getFullText();
+			$u = rawurlencode($u);  // Fix for links containing "
+		
+			//#Updating links tables -> #Updating_links_tables
+			$u = str_replace( "#" . $target->getFragment(), $target->getFragmentForURL(), $u );
+
+			if ( '' == $text ) {
+				$text = htmlspecialchars( $target->getPrefixedText() );
+			}
+			if( $target->getNamespace() == NS_CATEGORY ) {
+				$u = ':' . $u;
+			}
+
+			$u = preg_replace( "/^RTECOLON/", ":", $u ); // change 'RTECOLON' => ':'
+			if( substr( $text, 0, 10 ) == 'RTENOTITLE' ){	// starts with RTENOTITLE
+				$args .= '_fcknotitle="true" ';
+				$text = rawurldecode($u);
+			}
+			$s = "<a {$args}href=\"{$u}\">{$text}</a>";
+
+			wfProfileOut( __METHOD__ );
+			$ret = $s;
+			return false;
+		}
+		
+		return true;
+	}
+
+}
\ No newline at end of file

=== modified file 'extensions/WYSIWYG/CKeditorParser.body.php'
--- extensions/WYSIWYG/CKeditorParser.body.php	2012-02-27 13:33:51 +0000
+++ extensions/WYSIWYG/CKeditorParser.body.php	2012-03-02 11:17:39 +0000
@@ -391,17 +390,11 @@
       if (!$stripcomments && $element == '!--') {
         $commentState->setPair($marker, $output);
       } elseif ($element == 'html' || $element == 'nowiki') {
-        $nowikiItems[$marker] = $output;
+		$state->addNoWiki($marker, $output);
       } else {
-        $generalItems[$marker] = $output;
+		$state->addGeneral($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
@@ -728,66 +721,73 @@
   }
 
   function parse($text, Title $title, ParserOptions $options, $linestart = true, $clearState = true, $revid = null) {
-    $text = preg_replace("/^#REDIRECT/", '<!--FCK_REDIRECT-->', $text);
-    $text = preg_replace("/\<(noinclude|includeonly|onlyinclude)\>/i", '%%%start-$1%%%', $text);
-    $text = preg_replace("/\<\/(noinclude|includeonly|onlyinclude)\>/i", '%%%end-$1%%%', $text);
-    $parserOutput = parent::parse($text, $title, $options, $linestart, $clearState, $revid);
-
-
-    $parserOutput->setText(strtr($parserOutput->getText(), array('FCKLR_fcklr_FCKLR' => '<br fcklr="true"/>')));
-    $parserOutput->setText(strtr($parserOutput->getText(), array('--~~~~' => '<span class="fck_mw_signature">_</span>')));
-
-    if (!empty($this->fck_mw_strtr_span)) {
-      global $leaveRawTemplates;
-      if (!empty($leaveRawTemplates)) {
-        foreach ($leaveRawTemplates as $l) {
-          $this->fck_mw_strtr_span[$l] = substr($this->fck_mw_strtr_span[$l], 30, -7);
-        }
-      }
-      $text = strtr($parserOutput->getText(), $this->fck_mw_strtr_span);
-      $parserOutput->setText(strtr($text, $this->fck_mw_strtr_span));
-
-      //replace fckLR strings with empty strings
-//                        $parserOutput->setText( strtr( $parserOutput->getText(), array('fckLR' => '') ) );
-    }
-
-    // there were properties, look for the placeholder FCK_PROPERTY_X_FOUND and replace
-    // it with <span class="fck_mw_property">property string without brakets</span>
-    if (count($this->fck_mw_propertyAtPage) > 0) {
-      $tmpText = $parserOutput->getText();
-      foreach ($this->fck_mw_propertyAtPage as $p => $val)
-        $tmpText = str_replace('FCK_PROPERTY_' . $p . '_FOUND', $val, $tmpText);
-      $parserOutput->setText($tmpText);
-    }
-    // there were Richmedia links, look for the placeholder FCK_RICHMEDIA_X_FOUND and replace
-    // it with <a title="My Document.doc" _fck_mw_type="Document" _fck_mw_filename="My Document.doc"
-    // _fcksavedurl="Document:MyDocument.doc" href="My_Document.doc">Document:My Document.doc</a>
-    if (count($this->fck_mw_richmediaLinkAtPage) > 0) {
-      $tmpText = $parserOutput->getText();
-      foreach ($this->fck_mw_richmediaLinkAtPage as $p => $val)
-        $tmpText = str_replace('FCK_RICHMEDIA_' . $p . '_FOUND', $val, $tmpText);
-      $parserOutput->setText($tmpText);
-    }
-
-    if (!empty($this->fck_matches)) {
-      $text = $parserOutput->getText();
-      foreach ($this->fck_matches as $key => $m) {
-        $text = str_replace($key, $m[3], $text);
-      }
-      $parserOutput->setText($text);
-    }
-
-    if (!empty($parserOutput->mLanguageLinks)) {
-      foreach ($parserOutput->mLanguageLinks as $l) {
-        $parserOutput->setText($parserOutput->getText() . "\n" . '<a href="' . $l . '">' . $l . '</a>');
-      }
-    }
-
-    $parserOutput->setText(str_replace('<!--FCK_REDIRECT-->', '#REDIRECT', $parserOutput->getText()));
-    $parserOutput->setText(preg_replace('/%%%start\-(noinclude|includeonly|onlyinclude)%%%/i', '<span class="fck_mw_$1" _fck_mw_tagname="$1" startTag="true"></span>', $parserOutput->getText()));
-    $parserOutput->setText(preg_replace('/%%%end\-(noinclude|includeonly|onlyinclude)%%%/i', 'fckLR<span class="fck_mw_$1" _fck_mw_tagname="$1" endTag="true"></span>', $parserOutput->getText()));
-    return $parserOutput;
+    CKeditorLinker::addHooks();
+	try {
+		$text = preg_replace("/^#REDIRECT/", '<!--FCK_REDIRECT-->', $text);
+		$text = preg_replace("/\<(noinclude|includeonly|onlyinclude)\>/i", '%%%start-$1%%%', $text);
+		$text = preg_replace("/\<\/(noinclude|includeonly|onlyinclude)\>/i", '%%%end-$1%%%', $text);
+		$parserOutput = parent::parse($text, $title, $options, $linestart, $clearState, $revid);
+
+
+		$parserOutput->setText(strtr($parserOutput->getText(), array('FCKLR_fcklr_FCKLR' => '<br fcklr="true"/>')));
+		$parserOutput->setText(strtr($parserOutput->getText(), array('--~~~~' => '<span class="fck_mw_signature">_</span>')));
+
+		if (!empty($this->fck_mw_strtr_span)) {
+			global $leaveRawTemplates;
+			if (!empty($leaveRawTemplates)) {
+				foreach ($leaveRawTemplates as $l) {
+					$this->fck_mw_strtr_span[$l] = substr($this->fck_mw_strtr_span[$l], 30, -7);
+				}
+			}
+			$text = strtr($parserOutput->getText(), $this->fck_mw_strtr_span);
+			$parserOutput->setText(strtr($text, $this->fck_mw_strtr_span));
+
+			//replace fckLR strings with empty strings
+			//                        $parserOutput->setText( strtr( $parserOutput->getText(), array('fckLR' => '') ) );
+		}
+
+		// there were properties, look for the placeholder FCK_PROPERTY_X_FOUND and replace
+		// it with <span class="fck_mw_property">property string without brakets</span>
+		if (count($this->fck_mw_propertyAtPage) > 0) {
+			$tmpText = $parserOutput->getText();
+			foreach ($this->fck_mw_propertyAtPage as $p => $val)
+				$tmpText = str_replace('FCK_PROPERTY_' . $p . '_FOUND', $val, $tmpText);
+			$parserOutput->setText($tmpText);
+		}
+		// there were Richmedia links, look for the placeholder FCK_RICHMEDIA_X_FOUND and replace
+		// it with <a title="My Document.doc" _fck_mw_type="Document" _fck_mw_filename="My Document.doc"
+		// _fcksavedurl="Document:MyDocument.doc" href="My_Document.doc">Document:My Document.doc</a>
+		if (count($this->fck_mw_richmediaLinkAtPage) > 0) {
+			$tmpText = $parserOutput->getText();
+			foreach ($this->fck_mw_richmediaLinkAtPage as $p => $val)
+				$tmpText = str_replace('FCK_RICHMEDIA_' . $p . '_FOUND', $val, $tmpText);
+			$parserOutput->setText($tmpText);
+		}
+
+		if (!empty($this->fck_matches)) {
+			$text = $parserOutput->getText();
+			foreach ($this->fck_matches as $key => $m) {
+				$text = str_replace($key, $m[3], $text);
+			}
+			$parserOutput->setText($text);
+		}
+
+		if (!empty($parserOutput->mLanguageLinks)) {
+			foreach ($parserOutput->mLanguageLinks as $l) {
+				$parserOutput->setText($parserOutput->getText() . "\n" . '<a href="' . $l . '">' . $l . '</a>');
+			}
+		}
+
+		$parserOutput->setText(str_replace('<!--FCK_REDIRECT-->', '#REDIRECT', $parserOutput->getText()));
+		$parserOutput->setText(preg_replace('/%%%start\-(noinclude|includeonly|onlyinclude)%%%/i', '<span class="fck_mw_$1" _fck_mw_tagname="$1" startTag="true"></span>', $parserOutput->getText()));
+		$parserOutput->setText(preg_replace('/%%%end\-(noinclude|includeonly|onlyinclude)%%%/i', 'fckLR<span class="fck_mw_$1" _fck_mw_tagname="$1" endTag="true"></span>', $parserOutput->getText()));
+		CKeditorLinker::removeHooks();
+		return $parserOutput;
+	} catch (Exception $e) {
+		CKeditorLinker::removeHooks();
+		throw $e;
+	}
   }
 
   /**

=== modified file 'extensions/WYSIWYG/CKeditorSajax.body.php'
--- extensions/WYSIWYG/CKeditorSajax.body.php	2012-02-27 13:33:51 +0000
+++ extensions/WYSIWYG/CKeditorSajax.body.php	2012-03-02 10:15:19 +0000
@@ -3,6 +3,53 @@
  * AJAX functions used by CKeditor extension
  */
 
+/**
+ * Function converts an Javascript escaped string back into a string with
+ * specified charset (default is UTF-8).
+ * Modified function from http://pure-essence.net/stuff/code/utf8RawUrlDecode.phps
+ *
+ * @param $source String escaped with Javascript's escape() function
+ * @param $iconv_to String destination character set will be used as second parameter
+ * in the iconv function. Default is UTF-8.
+ * @return string
+ */
+function js_unescape( $source, $iconv_to = 'UTF-8' ) {
+        $decodedStr = '';
+        $pos = 0;
+        $len = strlen ( $source );
+
+        while ( $pos < $len ) {
+                $charAt = substr ( $source, $pos, 1 );
+                if ( $charAt == '%' ) {
+                        $pos++;
+                        $charAt = substr ( $source, $pos, 1 );
+
+                        if ( $charAt == 'u' ) {
+                                // we got a unicode character
+                                $pos++;
+                                $unicodeHexVal = substr ( $source, $pos, 4 );
+                                $unicode = hexdec ( $unicodeHexVal );
+                                $decodedStr .= code2utf( $unicode );
+                                $pos += 4;
+                        } else {
+                                // we have an escaped ascii character
+                                $hexVal = substr ( $source, $pos, 2 );
+                                $decodedStr .= chr ( hexdec ( $hexVal ) );
+                                $pos += 2;
+                        }
+                } else {
+                        $decodedStr .= $charAt;
+                        $pos++;
+                }
+        }
+
+        if ( $iconv_to != "UTF-8" ) {
+                $decodedStr = iconv( "utf-8", $iconv_to, $decodedStr );
+        }
+
+        return $decodedStr;
+}
+
 function wfSajaxGetMathUrl( $term ) {
 	$originalLink = MathRenderer::renderMath( $term );
 
@@ -124,8 +171,8 @@
 	global $wgContLang, $wgExtraNamespaces;
 	$limit = 30;
 	$ns = array(NS_MAIN, NS_CATEGORY, NS_IMAGE, NS_TEMPLATE, NS_USER, NS_HELP);
-    if (defined(SF_NS_FORM)) $ns[]= SF_NS_FORM;
-    if (defined(SMW_NS_PROPERTY)) $ns[]= SMW_NS_PROPERTY;
+    if (defined('SF_NS_FORM')) $ns[]= SF_NS_FORM;
+    if (defined('SMW_NS_PROPERTY')) $ns[]= SMW_NS_PROPERTY;
 
 	$term = $wgContLang->checkTitleEncoding( $wgContLang->recodeInput( js_unescape( $term ) ) );
     $prefix = "";

=== modified file 'extensions/WYSIWYG/WYSIWYG.php'
--- extensions/WYSIWYG/WYSIWYG.php	2012-02-27 13:33:51 +0000
+++ extensions/WYSIWYG/WYSIWYG.php	2012-03-02 10:09:52 +0000
@@ -99,6 +99,7 @@
 $wgAutoloadClasses['CKeditorParser'] = $dir . 'CKeditorParser.body.php';
 $wgAutoloadClasses['CKeditorParserOptions'] = $dir . 'CKeditorParserOptions.body.php';
 $wgAutoloadClasses['CKeditorParserWrapper'] = $dir . 'CKeditorParserWrapper.body.php';
+$wgAutoloadClasses['CKeditorLinker'] = $dir . 'CKeditorLinker.php';
 $wgAutoloadClasses['CKeditorSkin'] = $dir . 'CKeditorSkin.body.php';
 $wgAutoloadClasses['CKeditorEditPage'] = $dir . 'CKeditorEditPage.body.php';
 $wgAutoloadClasses['CKeditor_MediaWiki'] = $dir . 'CKeditor.body.php';

50.0.205.100 (talkcontribs)

It'd be great if you could regenerate your patch separately from your customizations!

93.159.249.66 (talkcontribs)

Works fine for MW1.18 too.

80.15.165.8 (talkcontribs)

very good...works also on my 1.18 however, I have got some few problems using Syntaxhighlight_geshi extension with it. after editing, all source code goes from multiline to singleline. After hacking code, I noticed that geshi was syntaxhighlight and source hooks. I modified this extension to also take into account syntaxhighlight hook . works only a little bit better, but the problem is not solved for the following reason: If you want to use geshi within ckeditor, a syntaxhighlighter plugin in ckeditor must be setted up.

So, I think it would only be useful displaying a special tag, at the moment.

Special tag does not display as it should for unknown tags to fckeditor. this is mainly because $wgParser is used. used $this in classes that overloads the parser will solve this issue.

however, once you managed to display the special block, when you switch to source . all the code is displayed, but linefeeds are removed !!!!

sancelot@free.fr

89.238.206.230 (talkcontribs)

Hi.

So, anyone has a final solution to fix this problem? Thank you.

Compumatter (talkcontribs)

Thanks for taking the time to detail those many changes.

I have gone through each of your 'diffs' and new file additions and following your very detailed instructions created a new WYSIWYG extension adding only those changes. It works perfectly with my recent 1.18 addition and can be downloaded from our wiki at : http://wiki.linuxmatter.com/index.php/Ckeditor:central

67.164.20.7 (talkcontribs)

Compumatter - your patch works great.

However, if you try to insert an image via an external link, the following attributes are missing at the bottom:

Alignment Height Width

Hence, one does not have the ability to alight the image

67.164.20.7 (talkcontribs)

I copied and pasted the code exactly, creating a new CKeditor.body.php but mediawiki is telling me there is a parser/synthax error on line 101 of the patch....anyone have the same problem?

I dont see what the error is

212.227.35.75 (talkcontribs)

Hi,

I use 1.18 and receive the following error:

Notice: Undefined index: riched_load_semantic_toolbar in [..]\xampp-win32-1.7.7-usb-lite\xampp\htdocs\smwp3\extensions\WYSIWYG\CKeditor.body.php on line 436

And Ideas?

Thanks, peter

77.93.128.126 (talkcontribs)

I have the same error message using 1.19. Did you have any luck getting past it?

Congminh1709~mediawikiwiki (talkcontribs)

I found the solution to fix the error" Undefined index: riched_load_semantic_toolbar in... " Find this line in file CKeditor.body.php (line 436)

if ( $wgUser->getOption( 'riched_load_semantic_toolbar', $wgDefaultUserOptions['riched_load_semantic_toolbar'] ) ) {

Put this line before

if (defined('SMW_HALO_VERSION'))

Hope this helps.

This post was posted by Congminh1709~mediawikiwiki, but signed as Congminh1709.

142.213.185.51 (talkcontribs)

Yes ! We use MW 1.18 and your solution fix the error. Thank you very much !!!

91.192.15.78 (talkcontribs)

I followed this instruction and afterwards mediawiki 1.18.2 starts to work with the WYSIWYG extensions. But.... the problem was with saving categories, I did not noticed it at the beggining but categories were erased during save of an article. Maybe I've made smth wrong ? :> But at the general I am waiting for a stable release without patches that I need to run - it is just crazy ;)

35.9.18.187 (talkcontribs)

How do you apply this patch?

Just delete the + or - signs before each line?

DheerajKumarBit (talkcontribs)

Worked great!!!

I applied the patch to WYSIWYG version 1.7 and used it with MW-1.19.0

The Custom parser in CKedtorParser.body.php which extends Parser class needs to modified a little bit because it doesn't work well for thumb images, math tag and many more extension tags like imagemap, ncl, dpl,etc.

The mediawiki plugin of CKeditor needs to be modified because at some places it adds extra linefeeds or removes linefeeds.To make WYSIWYG compatible with IE7 you may use JQuery while modifying mediawiki plugin of CKeditor ( it is there in path WYSIWYG/CKeditor/_source/plugins/mediawiki/plugin.js ).

12.139.67.10 (talkcontribs)

@DheerajKumarBit Can you please share the extra fixes you mentioned?

DheerajKumarBit (talkcontribs)

I've made many fixes which can be broadly categorized in two groups

  1. Fixes to make WYSIWYG compatible with IE7 (changes in Mediawiki plugin of ckeditor)
  2. Fixes to correct custom parser of WYSIWYG (changes in CKeditorParser.body.php & CKeditorLinker.php)

I don't remember all the changes because there were so many. So, here is the complete files. After applying above patch just replace these two files.

CKeditorLinker.php

<?php

class CKeditorLinker {

       public static function addHooks() {
               global $wgHooks;

               $wgHooks['ImageBeforeProduceHTML'][] = 'CKeditorLinker::makeImageLink2';
               $wgHooks['LinkerMakeExternalLink'][] = 'CKeditorLinker::makeExternalLink';
               $wgHooks['LinkEnd'][]                = 'CKeditorLinker::linkEnd';
               $wgHooks['LinkBegin'][]              = 'CKeditorLinker::linkBegin';
       }

       public static function removeHooks() {
               self::removeHook('ImageBeforeProduceHTML', 'CKeditorLinker::makeImageLink2');
               self::removeHook('LinkerMakeExternalLink', 'CKeditorLinker::makeExternalLink');
               self::removeHook('LinkEnd', 'CKeditorLinker::linkEnd');
               self::removeHook('LinkBegin', 'CKeditorLinker::linkBegin');
       }

       private static function removeHook($hookName, $function) {
               global $wgHooks;
               $hook = $wgHooks[$hookName];
               $i = array_search($function, $hook);
               if ($i) {
                       $wgHooks[$hookName] = array_splice($hook, $i, 1);
               }
       }

       static function makeImageLink2( $skin, Title $nt, $file, $frameParams = array(), $handlerParams = array(), $time, &$ret ) {
               $orginal = $nt->getText();
               $file = RepoGroup::singleton()->getLocalRepo()->newFile( $nt );
               $found = $file->exists();

               if( !empty( $frameParams['alt'] ) && $frameParams['alt'] == 'RTENOTITLE' ){ // 2223
                       $frameParams['alt'] = '';
               }
               if( $found ) {
                       $type = 'image';
                       if ($file->getMediaType() == MEDIATYPE_VIDEO) {
                               $type = 'video';
                       } else if ($file->getMediaType() == MEDIATYPE_AUDIO) {
                               $type = 'audio';
                       }
                       if ($type == 'image') {
                               $url = $file->getUrl();
                       } else {
                               $url = $file->createThumb( 230 );
                       }
               }
               // Shortcuts
               $fp =& $frameParams;
               $hp =& $handlerParams;
		// Clean up parameters
		$page = isset( $hp['page'] ) ? $hp['page'] : false;

		if ( $file && !isset( $hp['width'] ) ) {
			if ( isset( $hp['height'] ) && $file->isVectorized() ) {
				// If its a vector image, and user only specifies height
				// we don't want it to be limited by its "normal" width.
				global $wgSVGMaxSize;
				$hp['width'] = $wgSVGMaxSize;
			} else {
				$hp['width'] = $file->getWidth( $page );
			}

			if ( isset( $fp['thumbnail'] ) || isset( $fp['framed'] ) || isset( $fp['frameless'] ) || !$hp['width'] ) {
				global $wgThumbLimits, $wgThumbUpright;
				if ( !isset( $widthOption ) || !isset( $wgThumbLimits[$widthOption] ) ) {
					$widthOption = User::getDefaultOption( 'thumbsize' );
				}

				// Reduce width for upright images when parameter 'upright' is used
				if ( isset( $fp['upright'] ) && $fp['upright'] == 0 ) {
					$fp['upright'] = $wgThumbUpright;
				}
				// For caching health: If width scaled down due to upright parameter, round to full __0 pixel to avoid the creation of a lot of odd thumbs
				$prefWidth = isset( $fp['upright'] ) ?
					round( $wgThumbLimits[$widthOption] * $fp['upright'], -1 ) :
					$wgThumbLimits[$widthOption];

				// Use width which is smaller: real image width or user preference width
				// Unless image is scalable vector.
				if ( !isset( $hp['height'] ) && ( $hp['width'] <= 0 ||
						$prefWidth < $hp['width'] || $file->isVectorized() ) ) {
					$hp['width'] = $prefWidth;
				}
			}
		}
               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'] . "\" ";
			       $ret .= "style=\"width: ".$hp['width']."px\" ";
                       }
                       if( isset( $hp['height'] ) ) {
                               $ret .= "_fck_mw_height=\"" . $hp['height'] . "\" ";
				$ret .= "style=\"height: ".$hp['height']."px\" ";
                       }
               }
               $class = '';
               if( isset( $fp['thumbnail'] ) ) {
                       $ret .= "_fck_mw_type=\"thumb" . "\" ";
                       $class .= 'fck_mw_frame';
               } else if( isset( $fp['border'] ) ) {
                       $ret .= "_fck_mw_type=\"border" . "\" ";
                       $class .= 'fck_mw_border';
               } 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'] ) && $fp['alt'] != 'Image:' . $orginal ) {
                       $ret .= "alt=\"" . htmlspecialchars( $fp['alt'] ) . "\" ";
               } else {
                       $ret .= "alt=\"\" ";
               }

               if( $class ) {
                       $ret .= "class=\"$class\" ";
               }
        if (isset($fp['no-link']))
            $ret .= 'no-link="1" ';
        if (isset($fp['link-title']) && is_object($fp['link-title']))
            $ret .= 'link="'.htmlentities ($fp['link-title']->getFullText()).'" ';
        if (isset($fp['link-url']))
            $ret .= 'link="'.$fp['link-url'].'" ';

               $ret .= '/>';

               return false;
       }



       static function makeExternalLink( $url, $text, &$link, &$attribs, $linktype ) {
               $url = htmlspecialchars( $url );
               //$text = htmlspecialchars( $text );//don't remove html tags
               $url = preg_replace( "/^RTECOLON/", ":", $url ); // change 'RTECOLON' => ':'
               $args = '';
               if( $text == 'RTENOTITLE' ){ // 2223
                       $args .= '_fcknotitle="true" ';
                       $text = $url;
               }
               $link= '<a ' . $args . 'href="' . $url . '">' . $text . '</a>';

               return false;
       }

       function makeColouredLinkObj( $nt, $colour, $text = '', $query = '', $trail = '', $prefix = '' ) {
               return self::makeKnownLinkObj( $nt, $text, $query, $trail, $prefix, '', $style );
       }

       function makeKnownLinkObj( $nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '', $style = '' ) {
               wfProfileIn( __METHOD__ );

               $args = '';
               if ( !is_object( $nt ) ) {
                       wfProfileOut( __METHOD__ );
                       return $text;
               }

               $u = $nt->getFullText();
               $u = rawurlencode($u);  // Fix for links containing "
               //#Updating links tables -> #Updating_links_tables
               $u = str_replace( "#" . $nt->getFragment(), $nt->getFragmentForURL(), $u );

               if ( $nt->getFragment() != '' ) {
                       if( $nt->getPrefixedDBkey() == '' ) {
                               $u = '';
                               if ( '' == $text ) {
                                       $text = htmlspecialchars( $nt->getFragment() );
                               }
                       }

                       /**
                        * See tickets 1386 and 1690 before changing anything
                        */
                       if( $nt->getPartialUrl() == '' ) {
                               $u .= $nt->getFragmentForURL();
                       }
               }
               if ( $text == '' ) {
                       $text = htmlspecialchars( $nt->getPrefixedText() );
               }

               if( $nt->getNamespace() == NS_CATEGORY ) {
                       $u = ':' . $u;
               }

               list( $inside, $trail ) = Linker::splitTrail( $trail );
               $title = "{$prefix}{$text}{$inside}";

               $u = preg_replace( "/^RTECOLON/", ":", $u ); // change 'RTECOLON' => ':'
               if( substr( $text, 0, 10 ) == 'RTENOTITLE' ){ // starts with RTENOTITLE
                       $args .= '_fcknotitle="true" ';
                       $title = rawurldecode($u);
                       $trail = substr( $text, 10 ) . $trail;
               }

               $r = "<a {$args}href=\"{$u}\">{$title}</a>{$trail}";
               wfProfileOut( __METHOD__ );
               return $r;
       }

       function makeBrokenLinkObj( $nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
               # Fail gracefully
               if ( !isset( $nt ) ) {
                       # throw new MWException();
                       return "<!-- ERROR -->{$prefix}{$text}{$trail}";
               }
               $args = '';

               wfProfileIn( __METHOD__ );

               $u = $nt->getFullText();
               $u = rawurlencode($u);  // Fix for links containing "
               
               //#Updating links tables -> #Updating_links_tables
               $u = str_replace( "#" . $nt->getFragment(), $nt->getFragmentForURL(), $u );

               if ( '' == $text ) {
                       $text = htmlspecialchars( $nt->getPrefixedText() );
               }
               if( $nt->getNamespace() == NS_CATEGORY ) {
                       $u = ':' . $u;
               }

               list( $inside, $trail ) = Linker::splitTrail( $trail );
               $title = "{$prefix}{$text}{$inside}";

               $u = preg_replace( "/^RTECOLON/", ":", $u ); // change 'RTECOLON' => ':'
               if( substr( $text, 0, 10 ) == 'RTENOTITLE' ){   // starts with RTENOTITLE
                       $args .= '_fcknotitle="true" ';
                       $title = rawurldecode($u);
                       $trail = substr( $text, 10 ) . $trail;
               }
               $s = "<a {$args}href=\"{$u}\">{$title}</a>{$trail}";

               wfProfileOut( __METHOD__ );
               return $s;
       }

       static function makeSelfLinkObj( $nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
               $args = '';
               if ( '' == $text ) {
                       $text = $nt->mDbkeyform;
               }
               list( $inside, $trail ) = Linker::splitTrail( $trail );
               $title = "{$prefix}{$text}";
               if( $text == 'RTENOTITLE' ){ // 2223
                       $args .= '_fcknotitle="true" ';
                       $title = $nt->mDbkeyform;
               }
               return "<a {$args}href=\"".$nt->mDbkeyform."\" class=\"selflink\">{$title}</a>{$inside}{$trail}";
       }

       /**
        * Create a direct link to a given uploaded file.
        *
        * @param $title Title object.
        * @param $text  String: pre-sanitized HTML
        * @return string HTML
        *
        * @todo Handle invalid or missing images better.
        */
       static function makeMediaLinkObj( $title, $text = '' ) {
               if( is_null( $title ) ) {
                       ### HOTFIX. Instead of breaking, return empty string.
                       return $text;
               } else {
                       $args = '';
                       $orginal = $title->getPartialURL();
                       $img = wfFindFile( $title );
                       if( $img ) {
                               $url  = $img->getURL();
                               $class = 'internal';
                       } else {
                               $upload = SpecialPage::getTitleFor( 'Upload' );
                               $url = $upload->getLocalUrl( 'wpDestFile=' . urlencode( $title->getDBkey() ) );
                               $class = 'new';
                       }
                       $alt = htmlspecialchars( $title->getText() );
                       if( $text == '' ) {
                               $text = $alt;
                       }
                       $orginal = preg_replace( "/^RTECOLON/", ":", $orginal ); // change 'RTECOLON' => ':'
                       if( $text == 'RTENOTITLE' ){ // 2223
                               $args .= '_fcknotitle="true" ';
                               $text = $orginal;
                               $alt = $orginal;
                       }
                       return "<a href=\"{$orginal}\" class=\"$class\" {$args} _fck_mw_filename=\"{$orginal}\" _fck_mw_type=\"media\" title=\"{$alt}\">{$text}</a>";
               }
       }

       static function linkBegin( $skin, Title $target, &$text, array &$attribs, &$query, &$options, &$ret) {
               if ( $target->isExternal() ) {
                       $args = '';
                       $u = $target->getFullURL();
                       $link = $target->getPrefixedURL();
                       if ( '' == $text ) {
                               $text = $target->getPrefixedText();
                       }
                       $style = Linker::getInterwikiLinkAttributes( $link, $text, 'extiw' );

                       if( $text == 'RTENOTITLE' ) { // 2223
                               $text = $u = $link;
                               $args .= '_fcknotitle="true" ';
                       }
                       $t = "<a {$args}href=\"{$u}\"{$style}>{$text}</a>";

                       wfProfileOut( __METHOD__ );
                       $ret = $t;
                       return false;
               }

               return true;
       }

       static function linkEnd(  $skin, Title $target, array $options, &$text, array &$attribs, &$ret ) {

               if ( in_array('known', $options) ) {
                       $args = '';
                       if ( !is_object( $target ) ) {
                               wfProfileOut( __METHOD__ );
                               return $text;
                       }

                       $u = $target->getFullText();
                       $u = rawurlencode($u);  // Fix for links containing "
                       //#Updating links tables -> #Updating_links_tables
                       $u = str_replace( "#" . $target->getFragment(), $target->getFragmentForURL(), $u );

                       if ( $target->getFragment() != '' ) {
                               if( $target->getPrefixedDBkey() == '' ) {
                                       $u = '';
                                       if ( '' == $text ) {
                                               $text = htmlspecialchars( $target->getFragment() );
                                       }
                               }

                               /**
                                * See tickets 1386 and 1690 before changing anything
                                */
                               if( $target->getPartialUrl() == '' ) {
                                       $u .= $target->getFragmentForURL();
                               }
                       }
                       if ( $text == '' ) {
                               $text = htmlspecialchars( $target->getPrefixedText() );
                       }

                       if( $target->getNamespace() == NS_CATEGORY ) {
                               $u = ':' . $u;
                       }

                       $u = preg_replace( "/^RTECOLON/", ":", $u ); // change 'RTECOLON' => ':'
                       if( substr( $text, 0, 10 ) == 'RTENOTITLE' ){ // starts with RTENOTITLE
                               $args .= '_fcknotitle="true" ';
                               $text = rawurldecode($u);
                       }

                       $r = "<a {$args}href=\"{$u}\">{$text}</a>";
                       wfProfileOut( __METHOD__ );

                       $ret = $r;

                       return false;
               }


               if (in_array('broken', $options)) {
                       if ( !isset( $target ) ) {
                               # throw new MWException();
                               return "<!-- ERROR -->{$prefix}{$text}";
                       }
                       $args = '';

                       wfProfileIn( __METHOD__ );

                       $u = $target->getFullText();
                       $u = rawurlencode($u);  // Fix for links containing "
               
                       //#Updating links tables -> #Updating_links_tables
                       $u = str_replace( "#" . $target->getFragment(), $target->getFragmentForURL(), $u );

                       if ( '' == $text ) {
                               $text = htmlspecialchars( $target->getPrefixedText() );
                       }
                       if( $target->getNamespace() == NS_CATEGORY ) {
                               $u = ':' . $u;
                       }

                       $u = preg_replace( "/^RTECOLON/", ":", $u ); // change 'RTECOLON' => ':'
                       if( substr( $text, 0, 10 ) == 'RTENOTITLE' ){   // starts with RTENOTITLE
                               $args .= '_fcknotitle="true" ';
                               $text = rawurldecode($u);
                       }
                       $s = "<a {$args}href=\"{$u}\">{$text}</a>";

                       wfProfileOut( __METHOD__ );
                       $ret = $s;
                       return false;
               }
               
               return true;
       }

}

CKeditorParser.body.php

<?php

class CKeditorParser extends CKeditorParserWrapper {

  public static $fck_mw_makeImage_options;
  protected $fck_mw_strtr_span;
  protected $fck_mw_strtr_span_counter = 1;
  protected $fck_mw_taghook;
  protected $fck_internal_parse_text;
  protected $fck_matches = array();
  protected $fck_mw_propertyAtPage = array();
  protected $fck_mw_richmediaLinkAtPage = array();
  private $fck_allTagsCurrentTagReplaced = '';
  // list here all standard wiki tags that are supported by Mediawiki
  private $FCKeditorWikiTags = array(
      "nowiki",
      "includeonly",
      "onlyinclude",
      "noinclude"
  );
  private $FCKeditorMagicWords = array(
      "NOTOC",
      "FORCETOC",
      "TOC",
      "NOEDITSECTION",
      "NEWSECTIONLINK",
      "NONEWSECTIONLINK", // MW 1.15+
      "NOCONTENTCONVERT",
      "NOCC",
      "NOTITLECONVERT",
      "NOTC",
      "NOGALLERY",
      "INDEX", // MW 1.14+
      "NOINDEX", // MW 1.14+
      "STATICREDIRECT", // MW 1.14+
      "NOGALLERY",
      "HIDDENCAT",
      "START",
      "END"
  );
  private $FCKeditorDateTimeVariables = array(
      'CURRENTYEAR',
      'CURRENTMONTH',
      'CURRENTMONTHNAME',
      'CURRENTMONTHNAMEGEN',
      'CURRENTMONTHABBREV',
      'CURRENTDAY',
      'CURRENTDAY2',
      'CURRENTDOW',
      'CURRENTDAYNAME',
      'CURRENTTIME',
      'CURRENTHOUR',
      'CURRENTWEEK',
      'CURRENTTIMESTAMP'
  );
  private $FCKeditorWikiVariables = array(
      'SITENAME',
      'SERVER',
      'SERVERNAME',
      'DIRMARK',
      'SCRIPTPATH',
      'CURRENTVERSION',
      'CONTENTLANG',
      'REVISIONID',
      'REVISIONDAY',
      'REVISIONDAY2',
      'REVISIONMONTH',
      'REVISIONYEAR',
      'REVISIONTIMESTAMP',
      'REVISIONUSER', // MW 1.15+
      'FULLPAGENAME',
      'PAGENAME',
      'BASEPAGENAME',
      'SUBPAGENAME',
      'SUBJECTPAGENAME',
      'TALKPAGENAME',
      'NAMESPACE',
      'ARTICLESPACE',
      'TALKSPACE'
  );
  private $FCKeditorFunctionHooks = array(
      'lc',
      'lcfirst',
      'uc',
      'ucfirst',
      'formatnum',
      '#dateformat', // MW 1.15+
      'padleft',
      'padright',
      'plural',
      'grammar',
      '#language',
      'int',
      '#tag',
  );
  // these tags are for Semantic Forms extension (in a forms page)
  private $FCKeditorSFspecialTags = array(
      'info',
      'for template',
      'field',
      'end template',
      'standard input'
  );

  public function __construct() {
    global $wgParser;
    parent::__construct();
    // add custom tags from extensions to list
    foreach ($wgParser->getTags() as $h) {
      if (!in_array($h, $this->FCKeditorWikiTags) &&
              !(defined('SMW_DI_VERSION') && $h == "webservice")
      )
        $this->FCKeditorWikiTags[] = $h;
    }
    // add custom parser funtions from extensions to list
    foreach ($wgParser->getFunctionHooks() as $h) {
      // ask and sparql + ws are no special tags and have there own <span> elements in FCK
      // when SMWHalo or the DataImport extension is installed
      if (defined('SMW_HALO_VERSION') && in_array($h, array("ask", "sparql")))
        continue;
      if (defined('SMW_DI_VERSION') && $h == "ws")
        continue;
      if (!in_array('#' . $h, $this->FCKeditorFunctionHooks))
        $this->FCKeditorFunctionHooks[] = '#' . $h;
    }

  }

  public function getSpecialTags() {
    return $this->FCKeditorWikiTags;
  }

  public function getMagicWords() {
    return $this->FCKeditorMagicWords;
  }

  public function getDateTimeVariables() {
    return $this->FCKeditorDateTimeVariables;
  }

  public function getWikiVariables() {
    return $this->FCKeditorWikiVariables;
  }

  public function getFunctionHooks() {
    return $this->FCKeditorFunctionHooks;
  }

  public function getSfSpecialTags() {
    return $this->FCKeditorSFspecialTags;
  }

  /**
   * 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, $replaceLineBreaks = true) {
    $key = 'Fckmw' . $this->fck_mw_strtr_span_counter . 'fckmw';
    $this->fck_mw_strtr_span_counter++;
    if ($replaceLineBreaks) {
      $this->fck_mw_strtr_span[$key] = str_replace(array("\r\n", "\n", "\r"), 'fckLR', $text);
    } else {
      $this->fck_mw_strtr_span[$key] = $text;
    }
    return $key;
  }

  /**
   * Handle link to subpage if necessary
   * @param string $target the source of the link
   * @param string &$text the link text, modified as necessary
   * @return string the full name of the link
   * @private
   */
  function maybeDoSubpageLink($target, &$text) {
    return $target;
  }

  /**
   * DO NOT replace special strings like "ISBN xxx" and "RFC xxx" with
   * magic external links.
   *
   * DML
   * @private
   */
  function magicLinkCallback($m) {
    if (isset($m[1]) && $m[1] !== '') {
      # Skip anchor
      return $m[0];
    } elseif (isset($m[2]) && $m[2] !== '') {
      # Skip HTML element
      return $m[0];
    } elseif (isset($m[3]) && $m[3] !== '') {
      # Free external link
      return $this->makeFreeExternalLink($m[0]);
    } else { # skip the rest
      return $m[0];
    }
  }

  /**
   * 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 (in_array($this->fck_mw_taghook, array('ref', 'math', 'references', 'source'))) {
      $class = $this->fck_mw_taghook;
    } else {
      $class = 'special';
    }
    $ret = '<span class="fck_mw_' . $class . '" _fck_mw_customtag="true" ' .
            '_fck_mw_tagname="' . $this->fck_mw_taghook . '" _fck_mw_tagtype="t"';
    if (empty($argv)) {
      $ret .= '>';
    } else {
      foreach ($argv as $key => $value) {
        $ret .= " " . $key . "=\"" . $value . "\"";
      }
      $ret .= '>';
    }
    if (is_null($str)) {
      //$ret = substr( $ret, 0, -1 ) . ' />';
      $ret .= '>_</span>';
    } 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 . '" _fck_mw_customtag="true" _fck_mw_tagname="' . $tagName . '">';
    } else {
      $ret = '<span class="fck_mw_' . $tagName . '" _fck_mw_customtag="true" _fck_mw_tagname="' . $tagName . '"';
      foreach ($argv as $key => $value) {
        $ret .= " " . $key . "=\"" . $value . "\"";
      }
      $ret .= '>';
    }
    if (!is_null($str))
      $ret .= htmlspecialchars($str);
    else
      $ret .= '_';
    $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, $wgUseTeX, $wgScriptPath, $wgVersion, $wgHooks, $wgExtensionFunctions;
    
    wfProfileIn(__METHOD__);
    $render = ( $this->mOutputType == OT_HTML );

    $uniq_prefix = $this->mUniqPrefix;
    $commentState = new ReplacementArray;
    $nowikiItems = array();
    $generalItems = array();

    $elements = array_merge(array('nowiki', 'gallery', 'math'), array_keys($this->mTagHooks));
    if (( isset($wgHooks['ParserFirstCallInit']) && in_array('efSyntaxHighlight_GeSHiSetup', $wgHooks['ParserFirstCallInit']) )
            || ( isset($wgExtensionFunctions) && in_array('efSyntaxHighlight_GeSHiSetup', $wgExtensionFunctions) )) {
      $elements = array_merge($elements, array('source'));
    }
    if (( isset($wgHooks['ParserFirstCallInit']) && in_array('wfCite', $wgHooks['ParserFirstCallInit']) )
            || ( isset($wgExtensionFunctions) && in_array('wfCite', $wgExtensionFunctions) )) {
      $elements = array_merge($elements, array('ref', 'references'));
    }
    global $wgRawHtml;
    if ($wgRawHtml) {
      $elements[] = 'html';
    }

    # 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]);
    }

    $elements = array_unique($elements);
    $matches = array();
    if (version_compare("1.12", $wgVersion, ">")) {
      $text = Parser::extractTagsAndParams($elements, $text, $matches, $uniq_prefix);
    } else {
      $text = self::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 'references':
            $output = $this->fck_wikiTag('references', $content, $params);
            break;
          case 'ref':
            $output = $this->fck_wikiTag('ref', $content, $params);
            break;
          case 'source':
            $output = $this->fck_wikiTag('source', $content, $params);
            break;
          case 'html':
            if ($wgRawHtml) {
              $output = $this->fck_wikiTag('html', $content, $params);
            }
            break;
          case 'nowiki':
            $output = $this->fck_wikiTag('nowiki', $content, $params); // required by FCKeditor
            break;
          case 'math':
            if ($wgUseTeX) { //normal render
              $output = $wgContLang->armourMath(MathRenderer::renderMath($content));
		$position = stripos($output, 'src="');
		$tmpstr = substr($output, $position + 5);
		$position = stripos($tmpstr, '"');
		$imgSrc = substr($tmpstr, 0,$position);
		$output = '<img _fckfakelement="true" _fck_mw_math="' . $content . '" _fcksavedurl="'. $imgSrc .'" src="' . $imgSrc .'" />';
            } else // show fakeimage
              $output = '<img _fckfakelement="true" class="FCK__MWMath" _fck_mw_math="' . $content . '" src="' . $wgScriptPath . '/skins/common/images/button_math.png" />';
            break;
          case 'gallery':
            $output = $this->fck_wikiTag('gallery', $content, $params); // required by FCKeditor
            break;
	case 'imagemap':
            $imagelink = substr($content,strpos($content,"Image:")+6,strpos($content,".")-strpos($content,"Image:")-6+4);
            $url = wfSajaxGetImageUrl($imagelink);
	    $style = "";
	    $param = explode('|', $content, 2);
	    $options = explode('|', $param[1]);
	    foreach ( $options as $option ) {
			if( strpos($option, 'px') > 0 ) {
				$style = "width:".$option ;
				break;
			}
		}
            $output = '<img _fck_mw_filename="'.$imagelink.'" _sik_img_map="'.substr($content,strpos($content,".")+5).'" src="'.$url.'"  style="'.$style.'" />';
            break;
          default:
            if (isset($this->mTagHooks[$tagName])) {
              $this->fck_mw_taghook = $tagName; // required by FCKeditor
		$this->setHook( $tagName, array( $this, 'fck_genericTagHook' ) );
              $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') {
		$state->addNoWiki($marker, $output);
      } else {
		$state->addGeneral($marker, $output);
      }
    }
    # 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);
    }

    $this->fck_matches = $matches;
    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), false);
        $text = substr_replace($text, $replacement . "\n", $spaceStart, $spaceLen + 1);
      } else {
        # Remove just the comment.
        $replacement = $this->fck_addToStrtr(substr($text, $start, $end - $start), false);
        $text = substr_replace($text, "\n".$replacement, $start, $end - $start);
      }
    }
    wfProfileOut(__METHOD__);

    return $text;
  }

  function replaceInternalLinks($text) {
    $text = preg_replace("/\[\[([^\|\[\]]*?)\|?\]\]/", "[[$1|RTENOTITLE]]", $text); // #2223: [[()]]	=>	[[%1|RTENOTITLE]]
    $text = preg_replace("/\[\[:(.*?)\]\]/", "[[RTECOLON$1]]", $text); // change ':' => 'RTECOLON' in links
    $text = parent::replaceInternalLinks($text);
    $text = preg_replace("/\|RTENOTITLE\]\]/", "]]", $text); // remove unused RTENOTITLE

    return $text;
  }

  function makeImage($nt, $options, $holders = false) {
    CKeditorParser::$fck_mw_makeImage_options = $options;
    return parent::makeImage($nt, $options, $holders);
  }

  /**
   * 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($this, 'fck_leaveTemplatesAlone'),
                3 => array($this, '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 (!$pos) {
          $opened = 0;
          $closed = 0;
        } else {
          $opened = substr_count($text, '[', 0, $pos); // count [
          $closed = substr_count($text, ']', 0, $pos); // count ]
        }
        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));
          if (defined('SMW_HALO_VERSION') && substr($inner, 0, 7) == '{{#ask:' || substr($inner, 0, 10) == '{{#sparql:')
            $fck_mw_template = 'fck_smw_query';
          else if (defined('SMW_DI_VERSION') && substr($inner, 0, 6) == '{{#ws:')
            $fck_mw_template = 'fck_smw_webservice';
          else {
            $funcName = (($fp = strpos($inner, ':', 2)) !== false) ? substr($inner, 2, $fp - 2) : substr($inner, 2, strlen($inner) - 4);
            if (in_array($funcName, $this->FCKeditorDateTimeVariables))
              $fck_mw_template = 'v';
            else if (in_array($funcName, $this->FCKeditorWikiVariables))
              $fck_mw_template = 'w';
            else if (in_array($funcName, $this->FCKeditorFunctionHooks))
              $fck_mw_template = 'p';
            else
              $fck_mw_template = 'fck_mw_template';
          }
          // check if the recogized "template" is one of these special form tags of Semantic Forms
          global $wgTitle;
          if (defined('SF_VERSION') &&
                  $wgTitle && $wgTitle->getNamespace() == SF_NS_FORM &&
                  $fck_mw_template == 'fck_mw_template') {
            foreach ($this->FCKeditorSFspecialTags as $sfTag) {
              if (preg_match('/^\{' . $sfTag . '(\s|\}|\|)/', str_replace(array("\r\n", "\n", "\r"), ' ', $funcName))) {
                $fck_mw_template = 'sf';
                $funcName = $sfTag;
                break;
              }
            }
          }

          if (strlen($fck_mw_template) > 2) {
            if ($opened <= $closed) { // {{template}} is NOT in [] or [[]]
              $this->fck_mw_strtr_span['Fckmw' . $this->fck_mw_strtr_span_counter . 'fckmw'] = '<span class="' . $fck_mw_template . '">' . str_replace(array("\r\n", "\n", "\r"), 'fckLR', $inner) . '</span>';
            } else {
              $this->fck_mw_strtr_span['Fckmw' . $this->fck_mw_strtr_span_counter . 'fckmw'] = str_replace(array("\r\n", "\n", "\r"), 'fckLR', $inner);
            }
          } else if (strlen($fck_mw_template) > 1) { // SF tag
            $this->fck_mw_strtr_span['Fckmw' . $this->fck_mw_strtr_span_counter . 'fckmw'] = '<span class="fck_mw_special" _fck_mw_customtag="true" _fck_mw_tagname="' . $funcName . '" _fck_mw_tagtype="' . $fck_mw_template . '">'
                    . str_replace(array("\r\n", "\n", "\r"), 'fckLR', $inner) . '</span>';
          } else {
            $this->fck_mw_strtr_span['Fckmw' . $this->fck_mw_strtr_span_counter . 'fckmw'] = '<span class="fck_mw_special" _fck_mw_customtag="true" _fck_mw_tagname="' . $funcName . '" _fck_mw_tagtype="' . $fck_mw_template . '">';
            if (strlen($inner) > strlen($funcName) + 5) {
              $content = substr($inner, strlen($funcName) + 3, -2);
              $this->fck_mw_strtr_span['Fckmw' . $this->fck_mw_strtr_span_counter . 'fckmw'].= $content;
            }
            $this->fck_mw_strtr_span['Fckmw' . $this->fck_mw_strtr_span_counter . 'fckmw'].= '_</span>';
          }
          $this->fck_mw_strtr_span['href="Fckmw' . $this->fck_mw_strtr_span_counter . 'fckmw"'] = 'href="' . $inner . '"';
          $startingPos = $pos + 19;
          $this->fck_mw_strtr_span_counter++;
        }
        $lastSum = $sum;
      }
      $stringToParse .= substr($text, $startingPos);
      $text = &$stringToParse;
    }

    return $text;
  }

  function internalParse($text, $isMain = true, $frame = false) {
    $this->fck_internal_parse_text = & $text;
    
    // also replace all custom tags
    foreach ($this->FCKeditorWikiTags as $tag) {
      $tag = $this->guessCaseSensitiveTag($tag, $text);
      $this->fck_allTagsCurrentTagReplaced = $tag;
      $text = StringUtils::delimiterReplaceCallback("<$tag", "</$tag>", array($this, 'fck_allTags'), $text);
    }
    // Rule tags (the tag is not registered as a official wiki tag, therefore
    // not treated by the parser before
    if (defined('SEMANTIC_RULES_VERSION')) {
      $text = $this->replaceRules($text);
    }
    // __TOC__ etc. must be replaced
    $text = $this->stripToc($text);
    // HTML comments shouldn't be stripped
    $text = $this->fck_replaceHTMLcomments($text);
    // as well as templates
    $text = $this->fck_replaceTemplates($text);
    // as well as properties
    $text = $this->fck_replaceSpecialLinks($text);

    

    $text = $this->parseExternalLinksWithTmpl($text);

    $finalString = parent::internalParse($text, $isMain);
    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, $origText, $isMain = true) {
    return $text;
  }

  function parseExternalLinksWithTmpl($text) {
    $callback = array(
        '[' => array(
            'end' => ']',
            'cb' => array(
                1 => array($this, 'fck_replaceCkmarkupInLink')
            ),
            'min' => 1,
            'max' => 1,
        )
    );

    $text = $this->replace_callback($text, $callback);
    return $text;
  }

  /**
   * Check external links if they use some templates or parser functions e.g.
   * [http://google.de/?search=quertz {{PAGENAME}}]
   * [{{fullurl:{{FULLPAGENAME}}|printable=yes}} Printable version]
   * Then these will not get replaced by the normal parsing process. At this
   * point these links look like:
   * [http://google.de/?search=quertz FckmwXXfckmw]
   * [FckmwXYfckmw Printable version]
   * and are not recognized by the mediawiki parser. Therefore we revert the
   * replaced elements, built the anchor element but replace is with FckmwXZfckmw
   * so that the parser wont touch it.
   */
  function fck_replaceCkmarkupInLink($matches) {
    $p = strpos($matches['title'], ' ');
    if ($p === false)
      return $matches['text'];
    $target = substr($matches['title'], 0, $p);
    $title = substr($matches['title'], $p + 1);
    if (!preg_match('/Fckmw\d+fckmw/', $title) &&
            !preg_match('/Fckmw\d+fckmw/', $target))
      return $matches['text'];

    $title = $this->revertEncapsulatedString($title);
    $target = $this->revertEncapsulatedString($target);
    return $this->fck_addToStrtr('<a href="' . $target . '" _cke_saved_href="' . $target . '" _cke_mw_type="http">' . $title . '</a>');
  }

  function stripNoGallery(&$text) {
    
  }

  function stripToc($text) {
    $prefix = '<span class="fck_mw_magic" _fck_mw_customtag="true" _fck_mw_tagname="%s" _fck_mw_tagtype="c">';
    $suffix = '_</span>';

    $strtr = array();
    foreach ($this->FCKeditorMagicWords as $word) {
      $strtr['__' . $word . '__'] = sprintf($prefix, $word) . $suffix;
    }
    foreach ($strtr as $key => $val) {
      $strtr[$key] = $this->fck_addToStrtr($val, $key);
    }
    return strtr($text, $strtr);
  }

  function doDoubleUnderscore($text) {
    return $text;
  }

  function parse($text, Title $title, ParserOptions $options, $linestart = true, $clearState = true, $revid = null) {

CKeditorLinker::addHooks();
       try {
               $text = preg_replace("/^#REDIRECT/", '<!--FCK_REDIRECT-->', $text);
               $text = preg_replace("/\<(noinclude|includeonly|onlyinclude)\>/i", '%%%start-$1%%%', $text);
               $text = preg_replace("/\<\/(noinclude|includeonly|onlyinclude)\>/i", '%%%end-$1%%%', $text);
               $parserOutput = parent::parse($text, $title, $options, $linestart, $clearState, $revid);

               $parserOutput->setText(strtr($parserOutput->getText(), array('FCKLR_fcklr_FCKLR' => '<br fcklr="true"/>')));
               $parserOutput->setText(strtr($parserOutput->getText(), array('--~~~~' => '<span class="fck_mw_signature">_</span>')));

               if (!empty($this->fck_mw_strtr_span)) {
                       global $leaveRawTemplates;
                       if (!empty($leaveRawTemplates)) {
                               foreach ($leaveRawTemplates as $l) {
                                       $this->fck_mw_strtr_span[$l] = substr($this->fck_mw_strtr_span[$l], 30, -7);
                               }
                       }
                       $text = strtr($parserOutput->getText(), $this->fck_mw_strtr_span);
                       $parserOutput->setText(strtr($text, $this->fck_mw_strtr_span));

                       
               }

               
               if (count($this->fck_mw_propertyAtPage) > 0) {
                       $tmpText = $parserOutput->getText();
                       foreach ($this->fck_mw_propertyAtPage as $p => $val)
                               $tmpText = str_replace('FCK_PROPERTY_' . $p . '_FOUND', $val, $tmpText);
                       $parserOutput->setText($tmpText);
               }
               
               if (count($this->fck_mw_richmediaLinkAtPage) > 0) {
                       $tmpText = $parserOutput->getText();
                       foreach ($this->fck_mw_richmediaLinkAtPage as $p => $val)
                               $tmpText = str_replace('FCK_RICHMEDIA_' . $p . '_FOUND', $val, $tmpText);
                       $parserOutput->setText($tmpText);
               }

               if (!empty($this->fck_matches)) {
                       $text = $parserOutput->getText();
                       foreach ($this->fck_matches as $key => $m) {
                               $text = str_replace($key, $m[3], $text);
                       }
                       $parserOutput->setText($text);
               }

               if (!empty($parserOutput->mLanguageLinks)) {
                       foreach ($parserOutput->mLanguageLinks as $l) {
                               $parserOutput->setText($parserOutput->getText() . "\n" . '<a href="' . $l . '">' . $l . '</a>');
                       }
               }

               $parserOutput->setText(str_replace('<!--FCK_REDIRECT-->', '#REDIRECT', $parserOutput->getText()));
               $parserOutput->setText(preg_replace('/%%%start\-(noinclude|includeonly|onlyinclude)%%%/i', '<span class="fck_mw_$1" _fck_mw_tagname="$1" startTag="true"></span>', $parserOutput->getText()));
               $parserOutput->setText(preg_replace('/%%%end\-(noinclude|includeonly|onlyinclude)%%%/i', 'fckLR<span class="fck_mw_$1" _fck_mw_tagname="$1" endTag="true"></span>', $parserOutput->getText()));
               CKeditorLinker::removeHooks();
               return $parserOutput;
       } catch (Exception $e) {
               CKeditorLinker::removeHooks();
               throw $e;
       }
  }

  /**
   * Make lists from lines starting with ':', '*', '#', etc.
   *
   * @private
   * @return string the lists rendered as HTML
   */
  function doBlockLevels($text, $linestart) {
    wfProfileIn(__METHOD__);

    # 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(__METHOD__ . '-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(__METHOD__ . '-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(__METHOD__);
    return $output;
  }

  /**
   * replace property links like [[someProperty::value]] with FCK_PROPERTY_X_FOUND where X is
   * the number of the replaced property. The actual property string is stored in
   * $this->fck_mw_propertyAtPage[X] with X being the same number as in the replaced text.
   * This affects also links that are created with the RichMedia extension like:
   * [[Document:My_Document.doc|Document:My Document.doc]]. These are replaced with
   * FCK_RICHMEDIA_X_FOUND where X is the number of the replaced link. The actual link
   * value is stored in $this->fck_mw_richmediaLinkAtPage[X].
   *
   * @access private
   * @param string $wikitext
   * @return string $wikitext
   */
  private function fck_replaceSpecialLinks($text) {
    // use the call back function to let the parser do the work to find each link
    // that looks like [[something whatever is inside these brakets]]
    $callback = array('[' =>
        array(
            'end' => ']',
            'cb' => array(
                2 => array($this, 'fck_leaveTemplatesAlone'),
                3 => array('', ''),
            ),
            'min' => 2,
            'max' => 2,
        )
    );
    $text = $this->replace_callback($text, $callback);

    // now each property string is prefixed with <!--FCK_SKIP_START--> and
    // tailed with <!--FCK_SKIP_END-->
    // use this knowledge to find properties within these comments
    // and replace them with FCK_PROPERTY_X_FOUND that will be used later to be replaced
    // by the current property string
    while (preg_match('/\<\!--FCK_SKIP_START--\>\[\[(.*?)\]\]\<\!--FCK_SKIP_END--\>/', $text, $matches)) {
      $replacedVal = $this->revertEncapsulatedString($matches[1]);
      $replacement = $this->replaceSpecialLinkValue($replacedVal);
      $pos = strpos($text, $matches[0]);
      $before = substr($text, 0, $pos);
      $after = substr($text, $pos + strlen($matches[0]));
      $text = $before . $replacement . $after;
    }
    return $text;
  }

  /**
   * Replace a former encoded FckmwXXfckmw with it's actual value. Things
   * are replaced sequencially and if the same part has a replacement
   * already and the outer part will replaced by itself, then the inner
   * content must be the original string, without any replacements.
   *
   * This can happen, if a property contains a param/template call like:
   * [[Property::{{{1}}}]] or if a parser function/template contains a
   * comment. Things are replaces sequencially and if the same part has
   * a replacement already but is replaced as well then we are in trouble.
   *
   * Replacements are saved in the member variable $fck_mw_strtr_span which
   * is an array with the key containing the replacement string FckmwXXfckmw
   * and the value the original text. For each replacement there are two keys:
   *   1) FckmwXXfckmw
   *   2) href="FckmwXXfckmw"
   * Presumabely these are historical reasons. We must replace the content of
   * the href key, except for html comments.
   * In the future this replacement strategy should be checked whether not to
   * use one variable for each replacement only.
   *
   * @access private
   * @param string text
   * @return string text
   */
  private function revertEncapsulatedString($text) {
    if (preg_match_all('/Fckmw\d+fckmw/', $text, $matches)) {
      for ($i = 0, $is = count($matches[0]); $i < $is; $i++) {
        // comments are directly in the main key FckmwXfckmw
        if (isset($this->fck_mw_strtr_span[$matches[0][$i]]) &&
                substr($this->fck_mw_strtr_span[$matches[0][$i]], 0, 4) == '<!--') {
          $text = str_replace(
                  $matches[0][$i], $this->fck_mw_strtr_span[$matches[0][$i]], $text);
        } else if (isset($this->fck_mw_strtr_span['href="' . $matches[0][$i] . '"'])) {
          $text = str_replace(
                  $matches[0][$i], substr($this->fck_mw_strtr_span['href="' . $matches[0][$i] . '"'], 6, -1), $text);
        }
      }
    }
    return $text;
  }

  /**
   * Checks for replacments by replacePropertyValue() and replaceRichmediaLinkValue()
   * If a property was replaced, don't try to find and replace a richmedia link
   *
   * @access private
   * @param  string match
   * @param  string orig (maybe FckmwXfckmw)
   * @return string replaced placeholder or [[match]]
   */
  private function replaceSpecialLinkValue($match) {
    if (defined('SMW_VERSION')) {
      $res = $this->replacePropertyValue($match);
      if (preg_match('/FCK_PROPERTY_\d+_FOUND/', $res)) // property was replaced, we can quit here.
        return $res;
    }
    if (defined('SMW_RM_VERSION')) {
      $res = $this->replaceRichmediaLinkValue($match);
      if (preg_match('/FCK_RICHMEDIA_\d+_FOUND/', $res)) // richmedia link was replaced, we can quit here.
        return $res;
    }
    // an ordinary link. If this is something like [[{{{1}}}]] then this would be an
    // empty link, because during parsing, the parameter will not exist. Therefore
    // do not use the original value but the template replacement
    if (preg_match_all('/\{{2,3}.*?\}{2,3}+/', $match, $matches)) {
      for ($i = 0, $is = count($matches[0]); $i < $is; $i++) {
        $key = 'Fckmw' . $this->fck_mw_strtr_span_counter . 'fckmw';
        $this->fck_mw_strtr_span_counter++;
        $this->fck_mw_strtr_span[$key] = $matches[0][$i];
        $match = str_replace($matches[0][$i], $key, $match);
      }
    }
    return '[[' . $match . ']]';
  }

  /**
   * check the parser match from inside the [[ ]] and see if it's a property.
   * If thats the case, safe the property string in the array
   * $this->fck_mw_propertyAtPage and return a placeholder FCK_PROPERTY_X_FOUND
   * for the Xth occurence. Otherwise return the link content unmodified.
   * The missing [[ ]] have to be added again, so that the original remains untouched
   *
   * @access private
   * @param  string $match
   * @return string replacement or "[[$match]]"
   */
  private function replacePropertyValue($match) {
    $prop = explode('::', $match);
    if (count($prop) < 2)
      $prop = explode(':=', $match); // support old syntax [[prop:=val]]
    if ((count($prop) == 2) && (strlen($prop[0]) > 0) && (strlen($prop[1]) > 0)) {
      if (($p = strpos($prop[1], '|')) !== false) {
        // Hack to prevent that something like this is misplaced: [[prop::{{{param|}}}]]
        // still this must work: [[prop::foo|{{{param|}}}]]
        $view = substr($prop[1], $p + 1);
        $val = substr($prop[1], 0, $p);
        if (!(preg_match('/\{\{[^\}].*$/', $val) && preg_match('/^[^\{].*\}\}/', $view) )) {
          $prop[0] .= '::' . substr($prop[1], 0, $p);
          $prop[1] = substr($prop[1], $p + 1);
        }
      }
      // encode html entities in the value
      $prop[1] = htmlentities($prop[1], ENT_COMPAT, "UTF-8");
      // replace an empty value with &nbsp; for IE8
      if (preg_match('/^\s+$/', $prop[1])) {
		$prop[1] = '&nbsp;';
      }
      $p = count($this->fck_mw_propertyAtPage);
      $this->fck_mw_propertyAtPage[$p] = '<span class="fck_mw_property" property="' . $prop[0] . '">' . $prop[1] . '</span>';
      return 'FCK_PROPERTY_' . $p . '_FOUND';
    }
    return "[[" . $match . "]]";
  }

  /**
   * check the parser match from inside the [[ ]] and see if it's a link from
   * the RichMedia extension.
   * If thats the case, safe the richmedia string in the array
   * $this->fck_mw_richmediaLinkAtPage and return a placeholder FCK_RICHMEDIA_X_FOUND
   * for the Xth occurence. Otherwise return the link content unmodified.
   * The missing [[ ]] have to be added again, so that the original remains untouched
   *
   * @access private
   * @param  string $match
   * @return string replacement or "[[$match]]"
   */
  private function replaceRichmediaLinkValue($match) {
    $orig = "[[" . $match . "]]";
    if ($match && $match{0} == ":")
      $match = substr($match, 1);
    if (strpos($match, ":") === false)
      return $orig;
    $ns = substr($match, 0, strpos($match, ':'));
    if (in_array(strtolower($ns), array('pdf', 'document', 'audio', 'video'))) { //$wgExtraNamespaces doesn't help really
      $link = explode('|', $match);
      $basename = substr($link[0], strlen($ns) + 1);
      $p = count($this->fck_mw_richmediaLinkAtPage);
      $this->fck_mw_richmediaLinkAtPage[$p] = '<a title="' . str_replace('_', ' ', $basename) . '" _fck_mw_type="' . $ns . '" ' .
              '_fck_mw_filename="' . $basename . '" _fcksavedurl="' . $link[0] . '" href="' . $basename . '">' .
              ((count($link) > 1) ? $link[1] : str_replace('_', ' ', $link[0])) . '</a>';
      return 'FCK_RICHMEDIA_' . $p . '_FOUND';
    }
    return $orig;
  }

  /**
   * Replace wikitext for rules with place holder FckmwXfckmw
   *
   * @global Title $wgTitle
   * @global Request $wgRequest
   * @param  String $text
   * @return String
   */
  private function replaceRules($text) {
    if (preg_match_all('/<rule[^>]*>.*?<\/rule>/is', $text, $matches)) {
      for ($i = 0; $i < count($matches[0]); $i++) {
        preg_match_all('/<rule\s*(?:name=\"([\w\-\#;]+)\"\s*)?(?:type=\"([\w\-\#;]+)\"\s*)?(?:formula=\"([\w\-\#;]+)\"\s*)?(?:variableSpec=\"([\w\-\#;]+)\"\s*)?[^(?<!\-)>]*>(.*?)<\/rule>/is', $matches[0][$i], $ruleContent);
        if (count($ruleContent) > 1) {
          $name = count($ruleContent[1]) ? htmlentities($ruleContent[1][0], ENT_COMPAT, "UTF-8") : null;
          $type = count($ruleContent[2]) ? htmlentities($ruleContent[2][0], ENT_COMPAT, "UTF-8") : null;
          $formula = count($ruleContent[3]) ? htmlentities($ruleContent[3][0], ENT_COMPAT, "UTF-8") : null;
          $variableSpec = count($ruleContent[4]) ? htmlentities($ruleContent[4][0], ENT_COMPAT, "UTF-8") : null;
          $rule = count($ruleContent[5]) ? htmlentities($ruleContent[5][0], ENT_COMPAT, "UTF-8") : null;
          $this->fck_mw_strtr_span['Fckmw' . $this->fck_mw_strtr_span_counter . 'fckmw'] =
                  '<span class="fck_smw_rule"' .
                  ' name="' . $name . '"' .
                  ' type="' . $type . '"' .
                  ' formula="' . $formula . '"' .
                  ' variablespec="' . $variableSpec . '">' .
                  $rule . '</span>';
          $this->fck_mw_strtr_span['href="Fckmw' . $this->fck_mw_strtr_span_counter . 'fckmw"'] =
                  'href="' . $rule . '"';
          $key = 'Fckmw' . $this->fck_mw_strtr_span_counter . 'fckmw';
          $this->fck_mw_strtr_span_counter++;
          $cnt = 1;
          $text = str_replace($matches[0][$i], $key, $text, $cnt);
        }
      }
    }
    /*
      }
     */
    return $text;
  }

  /**
   * Replace wikitext for webservice definition, called as a parser hook
   *
   * @param string $str Input
   * @param array $argv Arguments
   * @return string
   */
  private function replaceWebserviceDefinition($str, $argv, $parser) {

    $ret = '<' . $this->fck_mw_taghook;
    if (empty($argv)) {
      $ret .= '>';
    } else {
      foreach ($argv as $key => $value) {
        $ret .= " " . $key . "=\"" . $value . "\"";
      }
      $ret .= '>';
    }
    if (!is_null($str))
      $ret .= $str;
    $ret .= '</' . $this->fck_mw_taghook . '>';
    $ret = '<span class="fck_smw_webservice">' .
            htmlspecialchars($ret) .
            '</span>';
    $replacement = $this->fck_addToStrtr($ret);
    return $replacement;
  }

  /**
   * When getting the available tags from the wiki, these are returned in
   * lower case although some might be in camel case. Also tags are case
   * sensitive. Therefore guess here the correct tag.
   *
   * @param string $tag small case
   * @param string $text wiki text
   * @return string $tag case sensitive tag
   */
  private function guessCaseSensitiveTag($tag, $text) {
    preg_match('/<(' . $tag . ')>/i', $text, $matchOpen);
    preg_match('/<\/(' . $tag . ')>/i', $text, $matchClose);
    if (count($matchOpen) > 0 &&
            count($matchClose) > 0 &&
            $matchOpen[1] == $matchClose[1])
      return $matchOpen[1];
    return $tag;
  }

  /*
   * Use the generic string matching function from the wiki parser and try
   * to find any tags in the wikitext e.g. <tag foo="bar">some text</tag>
   *
   * @param Array(string)
   * @return string placeholder
   */

  public function fck_allTags($matches) {
    // check for tag attributes
    $attr = array();
    if ($matches[1]{0} != ">") {
      $f = strpos($matches[1], '>');
      $t = explode(' ', substr($matches[1], 0, $f));
      foreach ($t as $x) {
        if (strlen($x) > 0 && ($g = strpos($x, '=')) !== false) {
          $attr[substr($x, 0, $g)] = str_replace("'", "", str_replace('"', '', substr($x, $g + 1)));
        }
      }
      $matches[1] = substr($matches[1], $f);
    }
    // check for uniqe makers that should be reverted
    if (strpos($matches[1], $this->mUniqPrefix) !== false) {
      foreach ($this->fck_matches as $key => $m) {
        $replacement = str_replace($key, $m[3], $matches[1]);
        if ($replacement != $matches[1]) { // we did replace something
          $matches[1] = $replacement;
          unset($this->fck_matches[$key]);
        }
      }
    }
    return $this->fck_wikiTag($this->fck_allTagsCurrentTagReplaced, substr($matches[1], 1), $attr);
  }

}


If it doesn't work for you, let me know.
Cheers

70.114.150.135 (talkcontribs)

DheerajKumarBit,

I tried the changes that you suggested and my mediawiki page does not load. I am running mediawiki 1.19 and WYSIWYG 1.7 with the patched files for:
CKeditorParser.body.php
CKeditorLinker.php
WYSIWYG.php (from http://wiki.linuxmatter.com/index.php/File:WYSIWYG.zip)
CKeditorSajax.body.php (from http://wiki.linuxmatter.com/index.php/File:WYSIWYG.zip)
CKeditor.body.php (from http://wiki.linuxmatter.com/index.php/File:WYSIWYG.zip)


Can you tell me if there is something else that I need to do here? I have also added the following two lines in the LocalSettings.php
require_once("{$wgScriptPath}/extensions/WYSIWYG/WYSIWYG.php");
$wgGroupPermissions['registered_users']['wysiwyg']=true;

Thanks

DheerajKumarBit (talkcontribs)

Even i tried ZIP file from http://wiki.linuxmatter.com/index.php/File:WYSIWYG.zip but it didn't work for me with MW-1.19.x . So, Here is the code of remaining 3 files.

WYSIWYG.php

<?php
/**
 * CKeditor extension - a WYSIWYG editor for MediaWiki
 *
 * @file
 * @ingroup Extensions
 * @version 1.0
 * @author Frederico Caldeira Knabben
 * @author Wiktor Walc <w.walc(at)fckeditor(dot)net>
 * @copyright Copyright © Frederico Caldeira Knabben, Wiktor Walc, other CKeditor team members and other contributors
 * @license GNU Lesser General Public License 2.1 or later
 */
/*
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
*/

# Not a valid entry point, skip unless MEDIAWIKI is defined
if( !defined( 'MEDIAWIKI' ) ) {
	echo <<<HEREDOC
To install WYSIWYG extension, put the following line in LocalSettings.php:
require_once( "\$IP/extensions/WYSIWYG/WYSIWYG.php" );
HEREDOC;
	exit( 1 );
}

# quit when comming from the command line,
# special case, to make Halo webtests run (here we don't have a browser)
if ((!array_key_exists('SERVER_NAME', $_SERVER) || $_SERVER['SERVER_NAME'] == NULL) &&
    (strpos($_SERVER['PHP_SELF'], 'run-test.php') === false) )
	return;

define('WYSIWYG_EDITOR_VERSION', '1.7.0_1 [B5]');

// define to check with {{#isExtensionInstalled:wysiwyg}} if extension is installed
// the parser function comes in the SMWHalo extension
define('wysiwyg', 'true}]');

# Configuration variables
// Path to this extension
$wgFCKEditorExtDir = 'extensions/WYSIWYG';

// Path to the actual editor
$wgFCKEditorDir = 'extensions/WYSIWYG/ckeditor/';

$wgFCKEditorToolbarSet = 'Wiki';

// '0' for automatic ('300' minimum).
$wgFCKEditorHeight = '0';

// Array of namespaces that FCKeditor is disabled for. Use constants like NS_MEDIAWIKI here.
$wgFCKEditorExcludedNamespaces = array();

// set this to true if you want the Richeditor show up only when the
// URL param mode=wysiwyg is set
$wgCKEditorUrlparamMode = false;

// hide toolbar buttons when some extensions are not installed (default show buttons)
$wgCKEditorHideDisabledTbutton = false;

$wysiwygIP = $IP . '/' . $wgFCKEditorExtDir;

$wysiwygScriptPath = $wgScriptPath . '/' . $wgFCKEditorExtDir;

/**
 * Enable use of AJAX features.
 */
require_once('CKeditorSajax.body.php');
$wgAjaxExportList[] = 'wfSajaxSearchImageCKeditor';
$wgAjaxExportList[] = 'wfSajaxSearchArticleCKeditor';
$wgAjaxExportList[] = 'wfSajaxSearchCategoryCKeditor';
$wgAjaxExportList[] = 'wfSajaxWikiToHTML';
$wgAjaxExportList[] = 'wfSajaxGetImageUrl';
$wgAjaxExportList[] = 'wfSajaxGetMathUrl';
$wgAjaxExportList[] = 'wfSajaxSearchTemplateCKeditor';
$wgAjaxExportList[] = 'wfSajaxSearchSpecialTagCKeditor';
//$wgAjaxExportList[] = 'wfSajaxToggleCKeditor';

// Extension credits that will show up on Special:Version
$wgExtensionCredits['other'][] = array(
	'path' => __FILE__,
	'name' => 'WYSIWYG extension',
	'author' => array( 'Frederico Caldeira Knabben', 'Wiktor Walc', 'others', 'Jack Phoenix', 'ontoprise GmbH' ),
	'version' => WYSIWYG_EDITOR_VERSION.', CKEditor 3.6 (revision 6902)',
	'url' => 'http://smwforum.ontoprise.com/smwforum/index.php/Help:WYSIWYG_Extension',
	'descriptionmsg' => 'fckeditor-desc',
);

// Autoloadable classes
$dir = dirname( __FILE__ ) . '/';
//$wgAutoloadClasses['CKEditor'] = $dir . 'ckeditor/ckeditor_php5.php';
$wgAutoloadClasses['CKeditorParser'] = $dir . 'CKeditorParser.body.php';
$wgAutoloadClasses['CKeditorParserOptions'] = $dir . 'CKeditorParserOptions.body.php';
$wgAutoloadClasses['CKeditorParserWrapper'] = $dir . 'CKeditorParserWrapper.body.php';
$wgAutoloadClasses['CKeditorLinker'] = $dir . 'CKeditorLinker.php';
$wgAutoloadClasses['CKeditorSkin'] = $dir . 'CKeditorSkin.body.php';
$wgAutoloadClasses['CKeditorEditPage'] = $dir . 'CKeditorEditPage.body.php';
$wgAutoloadClasses['CKeditor_MediaWiki'] = $dir . 'CKeditor.body.php';

// Path to internationalization file
$wgExtensionMessagesFiles['CKeditor'] = $dir . 'CKeditor.i18n.php';

$oCKeditorExtension = new CKeditor_MediaWiki();
// Hooked functions
$wgHooks['ParserAfterTidy'][]                   = array( $oCKeditorExtension, 'onParserAfterTidy' );
$wgHooks['EditPageBeforePreviewText'][]         = array( $oCKeditorExtension, 'onEditPageBeforePreviewText' );
$wgHooks['EditPagePreviewTextEnd'][]            = array( $oCKeditorExtension, 'onEditPagePreviewTextEnd' );
$wgHooks['CustomEditor'][]                      = array( $oCKeditorExtension, 'onCustomEditor' );

$wgHooks['LanguageGetMagic'][]					= 'CKeditor_MediaWiki::onLanguageGetMagic';
$wgHooks['ParserBeforeStrip'][]					= 'CKeditor_MediaWiki::onParserBeforeStrip';
$wgHooks['ParserBeforeInternalParse'][]			= 'CKeditor_MediaWiki::onParserBeforeInternalParse';
$wgHooks['EditPageBeforeConflictDiff'][]		= 'CKeditor_MediaWiki::onEditPageBeforeConflictDiff';
$wgHooks['SanitizerAfterFixTagAttributes'][]	= 'CKeditor_MediaWiki::onSanitizerAfterFixTagAttributes';
$wgHooks['MakeGlobalVariablesScript'][]			= 'CKeditor_MediaWiki::onMakeGlobalVariablesScript';
$wgHooks['GetPreferences'][]					= 'CKeditor_MediaWiki::onGetPreferences';
// bugfix for http://smwforum.ontoprise.com/smwbugs/show_bug.cgi?id=13511
$wgHooks['OutputPageParserOutput'][]            = 'CKeditor_MediaWiki::onOutputPageParserOutput';
$wgHooks['BeforePageDisplay'][]                 = 'CKeditor_MediaWiki::onBeforePageDisplay';
$wgHooks['GetLocalURL'][]                 = 'CKeditor_MediaWiki::onGetLocalURL';


// Defaults for new preferences options
$wgDefaultUserOptions['riched_use_toggle'] = 1;
$wgDefaultUserOptions['cke_show'] = 'wikitexteditor';

if (defined('SMW_HALO_VERSION')) {
  // when SMWHalo is used then the QueryInterface opens in an Iframe
    $wgEditPageFrameOptions = 'SAMEORIGIN';
    // Semantic toobar is NOT loaded by default
    $wgDefaultUserOptions['riched_load_semantic_toolbar'] = 0;
}

CKeditorSajax.body.php

<?php
/**
 * AJAX functions used by CKeditor extension
 */
/**
 * Function converts an Javascript escaped string back into a string with
 * specified charset (default is UTF-8).
 * Modified function from http://pure-essence.net/stuff/code/utf8RawUrlDecode.phps
 *
 * @param $source String escaped with Javascript's escape() function
 * @param $iconv_to String destination character set will be used as second parameter
 * in the iconv function. Default is UTF-8.
 * @return string
 */
function js_unescape( $source, $iconv_to = 'UTF-8' ) {
        $decodedStr = '';
        $pos = 0;
        $len = strlen ( $source );

        while ( $pos < $len ) {
                $charAt = substr ( $source, $pos, 1 );
                if ( $charAt == '%' ) {
                        $pos++;
                        $charAt = substr ( $source, $pos, 1 );

                        if ( $charAt == 'u' ) {
                                // we got a unicode character
                                $pos++;
                                $unicodeHexVal = substr ( $source, $pos, 4 );
                                $unicode = hexdec ( $unicodeHexVal );
                                $decodedStr .= code2utf( $unicode );
                                $pos += 4;
                        } else {
                                // we have an escaped ascii character
                                $hexVal = substr ( $source, $pos, 2 );
                                $decodedStr .= chr ( hexdec ( $hexVal ) );
                                $pos += 2;
                        }
                } else {
                        $decodedStr .= $charAt;
                        $pos++;
                }
        }

        if ( $iconv_to != "UTF-8" ) {
                $decodedStr = iconv( "utf-8", $iconv_to, $decodedStr );
        }

        return $decodedStr;
}

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 CKeditorParserOptions();    
	$options->setTidy( true );
	$parser = new CKeditorParser();

	if( in_array( 'wfCite', $wgExtensionFunctions ) ) {
		$parser->setHook( 'ref', array( $parser, 'ref' ) );
		$parser->setHook( 'references', array( $parser, 'references' ) );
	}
	$parser->setOutputType( OT_HTML );
	$originalLink = $parser->parse( '[[File:' . $term . ']]', $wgTitle, $options )->getText();
     	if( false == strpos( $originalLink, 'src="' ) ) {
		return '';
	}

	$srcPart = substr( $originalLink, strpos( $originalLink, "src=" )+ 5 );
	$url = strtok( $srcPart, '"' );
        if (substr($url, -(strlen($term))) == $term)
            return $url;
        return "";
}

function wfSajaxSearchSpecialTagCKeditor( $empty ) {
	global $wgParser, $wgRawHtml;

	$ret = "nowiki\nincludeonly\nonlyinclude\nnoinclude\ngallery\n";
	if( $wgRawHtml ){
		$ret.= "html\n";
	}
	$wgParser->firstCallInit();
	foreach( $wgParser->getTags() as $h ) {
		if( !in_array( $h, array( 'pre', 'math', 'ref', 'references' ) ) ) {
			$ret .= $h . "\n";
		}
	}
	$arr = explode( "\n", $ret );
	sort( $arr );
	$ret = implode( "\n", $arr );

	return $ret;
}

function wfSajaxSearchImageCKeditor( $term ) {
	global $wgContLang;
	$limit = 40;

	$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 ) );
	$term4 = str_replace( ' ', '_', $wgContLang->ucfirst( $term2 ) );
	$term = $term1;

	$dbr = wfGetDB( DB_SLAVE );
    // nothing yet typed in, get all images (actually up to $limit only)
   	if ( strlen( str_replace( '_', '', $term ) ) < 1 )
        $res = $dbr->select( 'page',
            'page_title',
    		array(
        		'page_namespace IN (' . NS_IMAGE . ',' . NS_FILE . ')'
            ),
            __METHOD__,
            array( 'LIMIT' => $limit + 1 )
        );
    // get list depending on the input
    else
        $res = $dbr->select( 'page',
            'page_title',
    		array(
        		'page_namespace IN (' . NS_IMAGE . ',' . NS_FILE . ')',
            	"page_title LIKE '%". $dbr->strencode( $term1 ) ."%'".
                "OR (LOWER(CONVERT(page_title, CHAR)) LIKE '%". $dbr->strencode( $term2 ) ."%') ".
    			"OR (UPPER(CONVERT(page_title, CHAR)) LIKE '%". $dbr->strencode( $term3 ) ."%') ".
        		"OR (page_title LIKE '%". $dbr->strencode( $term4 ) ."%') "
            ),
            __METHOD__,
            array( 'LIMIT' => $limit + 1 )
        );

	$ret = array();
	$i = 0;
	while ( ( $row = $dbr->fetchObject( $res ) ) && ( ++$i <= $limit ) ) {
        $pos = strrpos($row->page_title, '.');
        if ($pos === false) continue;
        $suffix = strtolower(substr($row->page_title, $pos + 1));
        if (! in_array($suffix,
                array('gif', 'jpg', 'jpeg', 'tif', 'tiff', 'svg', 'png')))
            continue;
		$ret[] = $row->page_title;
	}
    if (count($ret) == $limit )
        $ret[]= '___TOO__MANY__RESULTS___';

	return join("\n", $ret);
}

function wfSajaxSearchArticleCKeditor( $term ) {
	global $wgContLang, $wgExtraNamespaces;
	$limit = 30;
	$ns = array(NS_MAIN, NS_CATEGORY, NS_IMAGE, NS_TEMPLATE, NS_USER, NS_HELP);
    //if (defined(SF_NS_FORM)) $ns[]= SF_NS_FORM;
    //if (defined(SMW_NS_PROPERTY)) $ns[]= SMW_NS_PROPERTY;
	if (defined('SF_NS_FORM')) $ns[]= SF_NS_FORM;
    if (defined('SMW_NS_PROPERTY')) $ns[]= SMW_NS_PROPERTY;

	$term = $wgContLang->checkTitleEncoding( $wgContLang->recodeInput( js_unescape( $term ) ) );
    $prefix = "";
    
    // Check if title is valid
    if (preg_match(Title::getTitleInvalidRegex(), $term) === 1) {
    	return "***Title has an invalid format***";
    }
    
    if ( ( strlen( str_replace( '_', '', $term ) ) < 1 ) && ( count($ns) > 1 ) ) {
		return '';
    }

    if ( $term[0] == ':' ) {
        $prefix= ':';
        $term= substr($term, 1);
    }
    $pos= strpos($term, ':');
    if ( $pos !== false ) {
        $nsName = strtolower(substr($term, 0, $pos));
        foreach ($ns as $idx) {
            if (strtolower(MWNamespace::getCanonicalName($idx)) == $nsName) {
                $prefix.= MWNamespace::getCanonicalName($idx) . ':';
                $term= substr($term, $pos + 1);
                $ns = array($idx);
                break;
            }
        }
    }
	if( strpos( strtolower( $term ), 'image:' ) === 0 ) {
		$ns = array(NS_IMAGE);
		$term = substr( strtolower( $term ), 6 );
		$prefix .= 'Image:';
	} else if( strpos( $term, ':' ) && is_array( $wgExtraNamespaces ) ) {
		$pos = strpos( $term, ':' );
		$find_ns = array_search( substr( $term, 0, $pos ), $wgExtraNamespaces );
		if( $find_ns ) {
			$ns = array($find_ns);
			$prefix .= substr( $term, 0, $pos + 1 );
			$term = substr( $term, $pos + 1 );
		}
	}

	$term1 = str_replace( ' ', '_', $wgContLang->ucfirst( $term ) );
	$term2 = str_replace( ' ', '_', $wgContLang->lc( $term ) );
	$term3 = str_replace( ' ', '_', $wgContLang->uc( $term ) );
	$term4 = str_replace( ' ', '_', $wgContLang->ucfirst( $term2 ) );
	$term = $term1;

	

    $dbr = wfGetDB( DB_SLAVE );
	$res = $dbr->select(
        'page',
        'page_title, page_namespace',
        array(
			'page_namespace in ('.implode(',', $ns).') and '.
			"( page_title LIKE '%". $dbr->strencode( $term1 ) ."%' ".
			"OR (LOWER(CONVERT(page_title, CHAR)) LIKE '%". $dbr->strencode( $term2 ) ."%') ".
			"OR (UPPER(CONVERT(page_title, CHAR)) LIKE '%". $dbr->strencode( $term3 ) ."%') ".
			"OR (page_title LIKE '%". $dbr->strencode( $term4 ) ."%') )"
		),
		__METHOD__,
		array( 'LIMIT' => $limit + 1 )
	);
	$ret = array();
	$i = 0;
	while ( ( $row = $dbr->fetchObject( $res ) ) && ( ++$i <= $limit ) ) {
        $title = '';
        if( isset( $prefix ) && !empty( $prefix ) ) {
			$title .= $prefix;
	}
        else if ($row->page_namespace != NS_MAIN) {
            $title .= MWNamespace::getCanonicalName($row->page_namespace).':';
        }
        $title .= $row->page_title;
		$ret[]= $title;
	}
    // if we have not yet enough results, check the special pages
    if (count($ret) < $limit && $term2 != "") {
        global $wgSpecialPages;
        $specialPages = array_keys($wgSpecialPages);
        foreach ($specialPages as $page) {
            if (strpos(strtolower($page), $term2) !== FALSE ||
                strpos(strtoupper($page), $term3) !== FALSE )
                $ret[] = MWNamespace::getCanonicalName(NS_SPECIAL).':'.$page;
        }
    }
	return join("\n", $ret);
}

function wfSajaxSearchCategoryCKeditor(){
	$ns = NS_CATEGORY;
	$dbr = wfGetDB( DB_SLAVE );
	/** @todo FIXME: should use Database class */
	$m_sql = "SELECT tmpSelectCat1.cl_to AS title FROM ".$dbr->tableName('categorylinks')." AS tmpSelectCat1 ".
		"LEFT JOIN ".$dbr->tableName('page')." AS tmpSelectCatPage ON ( tmpSelectCat1.cl_to = tmpSelectCatPage.page_title ".
		"AND tmpSelectCatPage.page_namespace =$ns ) ".
		"LEFT JOIN ".$dbr->tableName('categorylinks')." AS tmpSelectCat2 ON tmpSelectCatPage.page_id = tmpSelectCat2.cl_from ".
		"WHERE tmpSelectCat2.cl_from IS NULL GROUP BY tmpSelectCat1.cl_to";

	$res = $dbr->query( $m_sql, __METHOD__ );

	$ret = '';
	$i = 0;
	while ( ( $row = $dbr->fetchObject( $res ) ) ) {
		$ret .= $row->title . "\n";
		$sub = explode( "\n", wfSajaxSearchCategoryChildrenCKeditor( $row->title ) );
		foreach( $sub as $subrow )
			if( strlen( $subrow ) > 0 )
				$ret.= ' ' . $subrow . "\n";
	}

	return $ret;
}

function wfSajaxSearchCategoryChildrenCKeditor( $m_root ){
	$limit = 50;
	$ns = NS_CATEGORY;
	$dbr = wfGetDB( DB_SLAVE );
	/// @todo FIXME: should use Database class
	$sql = "SELECT tmpSelectCatPage.page_title AS title FROM ".$dbr->tableName('categorylinks')." AS tmpSelectCat ".
			"LEFT JOIN ".$dbr->tableName('page')." AS tmpSelectCatPage ON tmpSelectCat.cl_from = tmpSelectCatPage.page_id ".
			"WHERE tmpSelectCat.cl_to LIKE ".$dbr->addQuotes($m_root)." AND tmpSelectCatPage.page_namespace = $ns"; 

	$res = $dbr->query( $sql, __METHOD__ );
	$ret = '';
	$i = 0;
	while ( ( $row = $dbr->fetchObject( $res ) ) ) {
		$ret .= $row->title . "\n";
		$sub = explode( "\n", wfSajaxSearchCategoryChildrenCKeditor( $row->title ) );
		foreach( $sub as $subrow )
			if( strlen( $subrow ) > 0 )
				$ret.= ' ' . $subrow . "\n";
	}

	return $ret;
}

function wfSajaxSearchTemplateCKeditor( $empty ) {
	$dbr = wfGetDB( DB_SLAVE );
	$res = $dbr->select( 'page',
		'page_title',
		array( 'page_namespace' => NS_TEMPLATE ),
		__METHOD__,
		array( 'ORDER BY' => 'page_title' )
	);

	$ret = '';
	while ( $row = $dbr->fetchObject( $res ) ) {
		$ret .= $row->page_title . "\n";
	}

	return $ret;
}

function wfSajaxWikiToHTML( $wiki, $title = '' ) {
	global $wgTitle;

    if ($title)
        $wgTitle = Title::newFromText($title);

	$options = new CKeditorParserOptions();
	$options->setTidy( true );
	$parser = new CKeditorParser();
	$parser->setOutputType( OT_HTML );

        $resultText = $parser->parse( $wiki, $wgTitle, $options )->getText();
	return str_replace( '<!-- Tidy found serious XHTML errors -->', '',  $resultText);
}

CKeditor.body.php

<?php

//////////////NOT IN USE. Left for backwards compatibility with SemanticForms//////////////////
/**
 * Options for FCKeditor
 * [start with FCKeditor]
 */
define('RTE_VISIBLE', 1);
/**
 * Options for FCKeditor
 * [show toggle link]
 */
define('RTE_TOGGLE_LINK', 2);
/**
 * Options for FCKeditor
 * [show popup link]
 */
define('RTE_POPUP', 4);

/////////////////////////////////////////////////////////////////////////////////////////////////

class CKeditor_MediaWiki {

  private $excludedNamespaces;

  public function __construct() {
    $this->registerResourceLoaderModules();
  }

  /**
   * Gets the namespaces where FCKeditor should be disabled
   * First check is done against user preferences, second is done against the global variable $wgFCKEditorExcludedNamespaces
   */
  private function getExcludedNamespaces() {
    global $wgUser, $wgDefaultUserOptions, $wgFCKEditorExcludedNamespaces;

    if (is_null($this->excludedNamespaces)) {
      $this->excludedNamespaces = array();
      $namespaces = self::buildNamespaceOptions(MWNamespace::getCanonicalNamespaces());
      foreach ($namespaces as $key => $value) {
        $optionValue = 'cke_ns_' . $value;
        $default = array_key_exists($optionValue, $wgDefaultUserOptions) ? $wgDefaultUserOptions[$optionValue] : '';
        if ($wgUser->getOption($optionValue, $default)) {
          $this->excludedNamespaces[] = constant($value);
        }
      }
      /*
        If this site's LocalSettings.php defines Namespaces that shouldn't use the FCKEditor (in the #wgFCKexcludedNamespaces array), those excluded
        namespaces should be combined with those excluded in the user's preferences.
       */
      if (!empty($wgFCKEditorExcludedNamespaces) && is_array($wgFCKEditorExcludedNamespaces)) {
        $this->excludedNamespaces = array_merge($wgFCKEditorExcludedNamespaces, $this->excludedNamespaces);
      }
    }

    return $this->excludedNamespaces;
  }

  public static function onLanguageGetMagic(&$magicWords, $langCode) {
    $magicWords['NORICHEDITOR'] = array(0, '__NORICHEDITOR__');

    return true;
  }

  public static function onParserBeforeInternalParse(&$parser, &$text, &$strip_state) {
    MagicWord::get('NORICHEDITOR')->matchAndRemove($text);

    return true;
  }

  /**
   * @param $pageEditor EditPage instance
   * @param $out OutputPage instance
   * @return true
   */
  public static function onEditPageBeforeConflictDiff($pageEditor, $out) {
    global $wgRequest;

    /*
      Show WikiText instead of HTML when there is a conflict
      http://dev.fckeditor.net/ticket/1385
     */
    $pageEditor->textbox2 = $wgRequest->getVal('wpTextbox1');
    $pageEditor->textbox1 = $pageEditor->getWikiContent();

    return true;
  }

  public static function onParserBeforeStrip(&$parser, &$text, &$stripState) {
    //$text = $parser->strip($text, $stripState);
	if (get_class($parser) == 'CKeditorParser') {
                       $text = $parser->strip( $text, $stripState );
               }
    return true;
  }

  public static function onSanitizerAfterFixTagAttributes($text, $element, &$attribs) {
    $text = preg_match_all("/Fckmw\d+fckmw/", $text, $matches);

    if (!empty($matches[0][0])) {
      global $leaveRawTemplates;
      if (!isset($leaveRawTemplates)) {
        $leaveRawTemplates = array();
      }
      $leaveRawTemplates = array_merge($leaveRawTemplates, $matches[0]);
      $attribs = array_merge($attribs, $matches[0]);
    }

    return true;
  }

  // we need to move our hook onBeforePageDisplay at the end of the list so that
  // style sheets are already inserted into the out object.
  public static function onOutputPageParserOutput(&$out, $parseroutput) {
    global $wgHooks;
    $noHooks = count($wgHooks['BeforePageDisplay']);
    if ($wgHooks['BeforePageDisplay'][$noHooks - 1] != 'CKeditor_MediaWiki::onBeforePageDisplay') {
      $BeforePageDisplay = array();
      for ($i = 0; $i < $noHooks; $i++) {
        if ($wgHooks['BeforePageDisplay'][$i] == 'CKeditor_MediaWiki::onBeforePageDisplay')
          continue;
        $BeforePageDisplay[] = $wgHooks['BeforePageDisplay'][$i];
      }
      $wgHooks['BeforePageDisplay'] = $BeforePageDisplay;
      $wgHooks['BeforePageDisplay'][] = 'CKeditor_MediaWiki::onBeforePageDisplay';
      return true;
    }
    return true;
  }

  // take content of css files and put this as inline text into the page, instead
  // of using the link elements to fetch css files separate from the server.
  // The latter causes IE to hang when more than 31 style sheets are processed this way.
  public static function onBeforePageDisplay(&$out, &$text) {
    global $wgRequest, $wgScriptPath;

	$wgRequest->response()->header("X-UA-Compatible: IE=Edge");//forces IE to render in standard mode
    //var_dump($out->styles);
    $action = $wgRequest->getText('action');
    if (!in_array($action, array('edit', 'submit'))) {
      return $out;
    }

    $inlineStyles = array();
    foreach ($out->styles as $key => $val) {
      if (count($out->styles[$key]) > 0) {
        if (isset($out->styles[$key]['condition']) ||
                isset($out->styles[$key]['dir']) ||
                strpos($key, '?') !== false ||
                strpos($key, 'jquery.fancybox') !== false)
          continue;
        $count = 1;
        $cssFile = dirname(__FILE__) . '/../../' . str_replace($wgScriptPath, '', $key, $count);
        $cssFile = str_replace('//', '/', $cssFile);
        if (isset($out->styles[$key]['media']) &&
                file_exists($cssFile)) {
          $cssCont = file_get_contents($cssFile);
          if ($cssCont !== false) {
            if (!isset($inlineStyles[$out->styles[$key]['media']]))
              $inlineStyles[$out->styles[$key]['media']] = '';
            $inlineStyles[$out->styles[$key]['media']] .= $cssCont . "\n";
            unset($out->styles[$key]);
          }
        }
      }
    }
    foreach ($inlineStyles as $media => $css) {
      $out->addInlineStyle($css);
    }

    $out->addModules('ext.wysiwyg.core');
    return $out;
  }

  public function onCustomEditor($article, $user) {
	global $wgRequest, $wgUseExternalEditor;

	$action = $wgRequest->getVal( 'action', 'view' );

    $internal = $wgRequest->getVal('internaledit');
    $external = $wgRequest->getVal('externaledit');
    $section = $wgRequest->getVal('section');
    $oldid = $wgRequest->getVal('oldid');
	if( !$wgUseExternalEditor
            || $action == 'submit'
            || $internal
            || $section
            || $oldid
            || (!$user->getOption('externaleditor') && !$external )) {
      $editor = new CKeditorEditPage($article);
   
	$editor->edit();
                       return false;
               } else {
                       return true;
    }
  }

  public function onEditPageBeforePreviewText(&$editPage, $previewOnOpen) {
    global $wgUser, $wgRequest;

    if ($wgUser->getOption('showtoolbar') && !$previewOnOpen) {
      $this->oldTextBox1 = $editPage->textbox1;
      $editPage->importFormData($wgRequest);
      //bugfix #16730: load WYSIWYG on preview
      if ($wgUser->getOption('cke_show') != 'wikitexteditor') {
        $wgRequest->setVal('mode', 'wysiwyg');
      }
    }

    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;

    MagicWord::get('NORICHEDITOR')->matchAndRemove($text);

    # Don't initialize for users that have chosen to disable the toolbar, rich editor or that do not have a FCKeditor-compatible browser
    if (!$wgUser->getOption('showtoolbar') || $wgUser->getOption('riched_disable') || !$wgFCKEditorIsCompatible) {
      return true;
    }

    # Are we editing a page that's in an excluded namespace? If so, bail out.
    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;
  }

  /**
   * Adds some new JS global variables
   * @param $vars Array: array of JS global variables
   * @return true
   */
  public static function onMakeGlobalVariablesScript($vars) {
    global $wgFCKEditorDir, $wgFCKEditorExtDir, $wgFCKEditorToolbarSet, $wgFCKEditorHeight,
    $wgGroupPermissions;

    $vars['WYSIWYG_EDITOR_VERSION'] = WYSIWYG_EDITOR_VERSION;
    $vars['wgFCKEditorDir'] = $wgFCKEditorDir;
    $vars['wgFCKEditorExtDir'] = $wgFCKEditorExtDir;
    $vars['wgFCKEditorToolbarSet'] = $wgFCKEditorToolbarSet;
    $vars['wgFCKEditorHeight'] = $wgFCKEditorHeight;
    $ckParser = new CKeditorParser();
    $vars['wgCKeditorMagicWords'] = array(
        'wikitags' => $ckParser->getSpecialTags(),
        'magicwords' => $ckParser->getMagicWords(),
        'datevars' => $ckParser->getDateTimeVariables(),
        'wikivars' => $ckParser->getWikiVariables(),
        'parserhooks' => $ckParser->getFunctionHooks()
    );

    if (defined('SF_VERSION'))
      $vars['wgCKeditorMagicWords']['sftags'] = $ckParser->getSfSpecialTags();
    $instExt = array();
    if (defined('SMW_DI_VERSION'))
      $instExt[] = 'SMW_DI_VERSION';
    if (defined('SMW_HALO_VERSION'))
      $instExt[] = 'SMW_HALO_VERSION';
    if (defined('SMW_RM_VERSION'))
      $instExt[] = 'SMW_RM_VERSION';
    if (defined('SEMANTIC_RULES_VERSION'))
      $instExt[] = 'SEMANTIC_RULES_VERSION';
    $vars['wgCKeditorUseBuildin4Extensions'] = $instExt;

    $vars['wgGroupPermissions'] = $wgGroupPermissions;

    return true;
  }

  /**
   * Adds new toggles into Special:Preferences
   * @param $user User object
   * @param $preferences Preferences object
   * @return true
   */
  public static function onGetPreferences($user, &$preferences) {
    global $wgDefaultUserOptions;
    wfLoadExtensionMessages('CKeditor');

    $preferences['cke_show'] = array(
        'type' => 'radio',
        'section' => 'editing/fckeditor',
        'options' => array(
            wfMsgHtml('edit-in-richeditor') => 'richeditor',
            wfMsgHtml('edit-in-wikitexteditor') => 'wikitexteditor',
            wfMsgHtml('tog-riched_toggle_remember_state') => 'rememberlast'
        )
    );

    $preferences['riched_use_toggle'] = array(
        'type' => 'toggle',
        'section' => 'editing/fckeditor',
        'label-message' => 'tog-riched_use_toggle',
    );

    if (defined('SMW_HALO_VERSION')) {
      $preferences['riched_load_semantic_toolbar'] = array(
          'type' => 'toggle',
          'section' => 'editing/fckeditor',
          'label-message' => 'load-stb-on-startup',
      );
    }

    // Show default options in Special:Preferences
    if (!array_key_exists('cke_show', $user->mOptions) && !empty($wgDefaultUserOptions['cke_show']))
      $user->setOption('cke_show', $wgDefaultUserOptions['cke_show']);
    if (!array_key_exists('riched_use_toggle', $user->mOptions) && !empty($wgDefaultUserOptions['riched_use_toggle']))
      $user->setOption('riched_use_toggle', $wgDefaultUserOptions['riched_use_toggle']);


    //the name of multiselect also goes into the selected value and it looks like there is a length limit so keep it short
    $preferences['cke_ns_'] = array(
        'type' => 'multiselect',
        'section' => 'editing/fckeditor-disable-namespaces',
        'options' => self::buildNamespaceOptions(MWNamespace::getCanonicalNamespaces())
    );

    return true;
  }

  /**
   * Build option array for multiselect control
   * @param array $canonicalNamespaces array of MW namespaces
   * @return array array of namespace options e.g. "MediaWiki_talk" => "NS_MEDIAWIKI_TALK"
   */
  private static function buildNamespaceOptions($canonicalNamespaces) {
    $result = array();
    foreach ($canonicalNamespaces as $key => $namespace) {
      if (empty($namespace)) {
        $namespace = 'Main';
      }
      $constName = strtoupper('ns_' . $namespace);
      if (!defined($constName)) {
        define($constName, $key);
      }
      $result[$namespace] = $constName;
    }

    return $result;
  }

  /**
   * Register all SMW modules with the MediaWiki Resource Loader.
   */
  private function registerResourceLoaderModules() {
    global $wgResourceModules, $wysiwygIP, $wysiwygScriptPath;

    $moduleTemplate = array(
        'localBasePath' => $wysiwygIP,
        'remoteBasePath' => $wysiwygScriptPath,
        'group' => 'ext.wysiwyg'
    );

    $wgResourceModules['ext.wysiwyg.core'] = $moduleTemplate + array(
        'messages' => array(
            'wysiwyg-qi-edit-query',
            'wysiwyg-qi-insert-query',
            'wysiwyg-qi-insert-new-query',
            'wysiwyg-rename',
            'wysiwyg-title-empty',
            'wysiwyg-title-invalid',
            'wysiwyg-title-exists',
            'wysiwyg-show-richtexteditor',
            'wysiwyg-show-wikitexteditor',
            'wysiwyg-save-and-continue',
            'wysiwyg-save-failed',
            'wysiwyg-save-failed-unknown-error',
            'wysiwyg-save-error',
            'wysiwyg-save-successful',
            'wysiwyg-move-failed',
            'wysiwyg-move-failed-unknown-error',
            'wysiwyg-move-error',
            'wysiwyg-move-successful',
            'wysiwyg-last-save',
            'wysiwyg-never',
            'wysiwyg-no-changes',
            'wysiwyg-save-before-rename',
            'wysiwyg-save-before-exit'
        ),
        'styles' => array(
            'ckeditor/_source/skins/kama/editor.css',
            'ckeditor/_source/skins/kama/dialog.css',
            'ckeditor/_source/skins/kama/templates.css'
        ),
        'scripts' => array(
            'scripts/setBasePath.js',
            'ckeditor/_source/core/ckeditor_base.js',
            'ckeditor/_source/core/event.js',
            'ckeditor/_source/core/editor_basic.js',
            'ckeditor/_source/core/env.js',
            'ckeditor/_source/core/ckeditor_basic.js',
            'ckeditor/_source/core/dom.js',
            'ckeditor/_source/core/tools.js',
            'ckeditor/_source/core/dtd.js',
            'ckeditor/_source/core/dom/event.js',
            'ckeditor/_source/core/dom/domobject.js',
            'ckeditor/_source/core/dom/window.js',
            'ckeditor/_source/core/dom/document.js',
            'ckeditor/_source/core/dom/node.js',
            'ckeditor/_source/core/dom/nodelist.js',
            'ckeditor/_source/core/dom/element.js',
            'ckeditor/_source/core/command.js',
            'ckeditor/_source/core/config.js',
            'ckeditor/_source/core/focusmanager.js',
            'ckeditor/_source/core/lang.js',
            'ckeditor/_source/core/scriptloader.js',
            'ckeditor/_source/core/resourcemanager.js',
            'ckeditor/_source/core/plugins.js',
            'ckeditor/_source/core/skins.js',
            'ckeditor/_source/core/themes.js',
            'ckeditor/_source/core/ui.js',
            'ckeditor/_source/core/editor.js',
            'ckeditor/_source/core/htmlparser.js',
            'ckeditor/_source/core/htmlparser/comment.js',
            'ckeditor/_source/core/htmlparser/text.js',
            'ckeditor/_source/core/htmlparser/cdata.js',
            'ckeditor/_source/core/htmlparser/fragment.js',
            'ckeditor/_source/core/htmlparser/element.js',
            'ckeditor/_source/core/htmlparser/filter.js',
            'ckeditor/_source/core/htmlparser/basicwriter.js',
            'ckeditor/_source/core/loader.js',
            'ckeditor/_source/core/ckeditor.js',
            'ckeditor/_source/core/dom/comment.js',
            'ckeditor/_source/core/dom/elementpath.js',
            'ckeditor/_source/core/dom/text.js',
            'ckeditor/_source/core/dom/documentfragment.js',
            'ckeditor/_source/core/dom/walker.js',
            'ckeditor/_source/core/dom/range.js',
            'ckeditor/_source/core/dom/rangelist.js',
            'ckeditor/_source/core/_bootstrap.js',
            'ckeditor/_source/skins/kama/skin.js',
            'ckeditor/_source/lang/en.js',
            'ckeditor/_source/adapters/jquery.js',
            'ckeditor/_source/plugins/about/plugin.js',
            'ckeditor/_source/plugins/ajax/plugin.js',
            'ckeditor/_source/plugins/autogrow/plugin.js',
            'ckeditor/_source/plugins/a11yhelp/plugin.js',
            'ckeditor/_source/plugins/basicstyles/plugin.js',
            'ckeditor/_source/plugins/bidi/plugin.js',
            'ckeditor/_source/plugins/blockquote/plugin.js',
            'ckeditor/_source/plugins/button/plugin.js',
            'ckeditor/_source/plugins/clipboard/plugin.js',
            'ckeditor/_source/plugins/colorbutton/plugin.js',
            'ckeditor/_source/plugins/colordialog/plugin.js',
            'ckeditor/_source/plugins/contextmenu/plugin.js',
            'ckeditor/_source/plugins/dialogadvtab/plugin.js',
            'ckeditor/_source/plugins/div/plugin.js',
            'ckeditor/_source/plugins/enterkey/plugin.js',
            'ckeditor/_source/plugins/entities/plugin.js',
            'ckeditor/_source/plugins/filebrowser/plugin.js',
            'ckeditor/_source/plugins/find/plugin.js',
            'ckeditor/_source/plugins/flash/plugin.js',
            'ckeditor/_source/plugins/font/plugin.js',
            'ckeditor/_source/plugins/format/plugin.js',
            'ckeditor/_source/plugins/horizontalrule/plugin.js',
            'ckeditor/_source/plugins/htmldataprocessor/plugin.js',
            'ckeditor/_source/plugins/iframe/plugin.js',
            'ckeditor/_source/plugins/iframedialog/plugin.js',
            'ckeditor/_source/plugins/indent/plugin.js',
            'ckeditor/_source/plugins/justify/plugin.js',
            'ckeditor/_source/plugins/keystrokes/plugin.js',
            'ckeditor/_source/plugins/link/plugin.js',
            'ckeditor/_source/plugins/list/plugin.js',
            'ckeditor/_source/plugins/liststyle/plugin.js',
            'ckeditor/_source/plugins/maximize/plugin.js',
            'ckeditor/_source/plugins/newpage/plugin.js',
            'ckeditor/_source/plugins/pagebreak/plugin.js',
            'ckeditor/_source/plugins/pastefromword/plugin.js',
            'ckeditor/_source/plugins/pastetext/plugin.js',
            'ckeditor/_source/plugins/popup/plugin.js',
            'ckeditor/_source/plugins/preview/plugin.js',
            'ckeditor/_source/plugins/print/plugin.js',
            'ckeditor/_source/plugins/removeformat/plugin.js',
            'ckeditor/_source/plugins/save/plugin.js',
            'ckeditor/_source/plugins/scayt/plugin.js',
            'ckeditor/_source/plugins/smiley/plugin.js',
            'ckeditor/_source/plugins/showblocks/plugin.js',
            'ckeditor/_source/plugins/showborders/plugin.js',
            'ckeditor/_source/plugins/sourcearea/plugin.js',
            'ckeditor/_source/plugins/stylescombo/plugin.js',
            'ckeditor/_source/plugins/table/plugin.js',
            'ckeditor/_source/plugins/tabletools/plugin.js',
            'ckeditor/_source/plugins/specialchar/plugin.js',
            'ckeditor/_source/plugins/tab/plugin.js',
            'ckeditor/_source/plugins/templates/plugin.js',
            'ckeditor/_source/plugins/toolbar/plugin.js',
            'ckeditor/_source/plugins/undo/plugin.js',
            'ckeditor/_source/plugins/wysiwygarea/plugin.js',
            'ckeditor/_source/plugins/wsc/plugin.js',
            'ckeditor/_source/plugins/xml/plugin.js',
            'ckeditor/_source/plugins/styles/plugin.js',
            'ckeditor/_source/plugins/styles/styles/default.js',
            'ckeditor/_source/plugins/dialog/plugin.js',
            'ckeditor/_source/plugins/domiterator/plugin.js',
            'ckeditor/_source/plugins/panelbutton/plugin.js',
            'ckeditor/_source/plugins/floatpanel/plugin.js',
            'ckeditor/_source/plugins/menu/plugin.js',
            'ckeditor/_source/plugins/editingblock/plugin.js',
            'ckeditor/_source/plugins/selection/plugin.js',
            'ckeditor/_source/plugins/fakeobjects/plugin.js',
            'ckeditor/_source/plugins/richcombo/plugin.js',
            'ckeditor/_source/plugins/htmlwriter/plugin.js',
            'ckeditor/_source/plugins/menubutton/plugin.js',
            'ckeditor/_source/plugins/dialogui/plugin.js',
            'ckeditor/_source/plugins/panel/plugin.js',
            'ckeditor/_source/plugins/listblock/plugin.js',
            'ckeditor/_source/themes/default/theme.js',
            'ckeditor/_source/plugins/mediawiki/plugin.js',
            'ckeditor/_source/plugins/mwtemplate/plugin.js',
            'ckeditor/_source/plugins/smwtoolbar/plugin.js',
            'ckeditor/_source/plugins/smwqueryinterface/plugin.js',
            'ckeditor/_source/plugins/smwrichmedia/plugin.js',
            'ckeditor/_source/plugins/smwrule/plugin.js',
            'ckeditor/_source/plugins/smwwebservice/plugin.js',
            'ckeditor/_source/plugins/saveAndExit/plugin.js',
            'ckeditor/_source/plugins/mediawiki.api/plugin.js',
            'ckeditor/config.js',
            'scripts/jquery.jscroll.js',
            'scripts/init.js'
        )
    );
  }

  public static function onGetLocalURL($title, $url, $query) {
    if (!strpos($query, 'mode=')) {
      $url = str_replace('action=edit', 'action=edit&mode=wysiwyg', $url);
    }
    return true;
  }

}


If you get any error after using these files, please post it here.

70.114.150.135 (talkcontribs)

Thanks DheerajKumarBit

The versions of the three files that you posted worked perfect with the stock install of WYSIWYG 1.7 on Mediawiki 1.19.1

213.44.50.129 (talkcontribs)

Hi DheerajKumarBit,

I run MW 1.19 and i get WYSIWYG 1.7 as advice above. Problem : 1/ There is no file like CKeditorLinker.php in my directory WYSIWYG 1.7, so i added it. 2/ After modify the 4 others files, the extension works but when i click on [Show Rich Text Editor], all the content of the page disappear in the new box. Any idea to fix it? Thanks in advance!

This post was posted by 213.44.50.129, but signed as Spi.

DheerajKumarBit (talkcontribs)

Hi,

You followed the right steps and that's why you were able to get the anchor/link Show RichTextEditor in edit mode of the article. Your problem seems to be related with JavaScript( client side ) and not PHP ( server side). Can you please let me know if you are getting any JavaScript error, which stops the further execution of scripts and you are left with a blank page in the new box.

213.44.50.129 (talkcontribs)
DheerajKumarBit (talkcontribs)

Hi Spi,
Then i was wrong 500 Internal Server Error means something went wrong on server side. So, can you please check your web server error logs, what does go wrong?

213.44.50.129 (talkcontribs)

I seems to have some conflicts with my others functions on home page, so i tried to edit a page with only text and i get a notice and an error

PHP Notice: Undefined property: StripState::$nowiki in /home/spi/public_html/premium/mediawiki-1.19.0/extensions/WYSIWYG/CKeditorParser.body.php on line 397, referer: http://localhost/wiki/index.php?title=Categorie:Film_americain&action=edit&mode=wysiwyg

PHP Fatal error: Call to a member function mergeArray() on a non-object in /home/spi/public_html/premium/mediawiki-1.19.0/extensions/WYSIWYG/CKeditorParser.body.php on line 397, referer: http://localhost/wiki/index.php?title=Categorie:Film_americain&action=edit&mode=wysiwyg

To remember, i run the original version of WYSIWYG1.7 and use your 5 modified files

This post was posted by 213.44.50.129, but signed as Spi.

DheerajKumarBit (talkcontribs)

Hi Spi,
Thanks for posting this error from logs. It points that you haven't replaced the CKeditorParser.body.php which i have posted in this thread because nowhere mergeArray function has been called and this function has been called in the original version of WYSIWYG1.7 . So, I'll request you to once again replace 5 files and along with that also apply the patch from Editor removes assigned category thread.

213.44.50.129 (talkcontribs)

Exact, its weird, i thought i had modify the 5 files, my bad, sorry for that. Now WYSIWYG works great, ive no problem with category. Thanks you for help. I was just wondering if it is still possible to make work the Upload function of WYSIWYG cause i had RichMedia and all the extension needed for that, but i dont work and ive an error with my richmedia extension, maybe MW1.19 cant run it?

This post was posted by 213.44.50.129, but signed as Spi.

DheerajKumarBit (talkcontribs)

Sorry but we are not using RichMedia, so i haven't ever looked into this. As many core MW components have changed in MW-1.19.x from MW-1.17.x, so RichMedia needs to be modified to work with MW-1.19.x

213.44.50.129 (talkcontribs)

Ok, thanks for making work my Wysiwyg DheerajKumarBit :)

PS: Any way to display the Rich editor at the load of edit page instead of the basic editor?

This post was posted by 213.44.50.129, but signed as Spi.

DheerajKumarBit (talkcontribs)

You can change the value of $wgDefaultUserOptions['cke_show'] in WYSIWYG.php from 'wikitexteditor' to 'richtexteditor'.

Brad Chase~mediawikiwiki (talkcontribs)

This is working for me with MediaWiki 1.19.1, with one minor issue. When I first go to edit, it says "[Show RichTextEditor]" at the top of the edit window instead of "[Show WikiTextEditor]". If you click the link, does switch to the WikiText editor.

I also discovered that if you use the WYSIWYG extension at the same time as the WikiEditor extension, You end up with the WYSIWYG appearing inside the WikiEditor edit area with the WikiEditor controls still shown at the top.

This post was posted by Brad Chase~mediawikiwiki, but signed as Brad Chase.

DheerajKumarBit (talkcontribs)

Hi Brad,
The issue([Show RichTextEditor]) can be fixed easily. But this issue is related to JavaScript(client side) and not related to PHP (server side) and in the same way there are many issues while you toggle wikitext button. To solve [Show RichTextEditor] issue you can replace WYSIWYG/scripts/init.js

init.js

(function($){

  CKEDITOR.mw = {};
  
  function init(){
    removeMediawikiClutter();
    
    var wikieditor = $('#wpTextbox1');
    if(!wikieditor.length){
      wikieditor = $('#free_text');
    }
    var toolbar = $('#toolbar');
    
    //if not mode=wysiwyg then return
    if(mw.util.getParamValue('mode') !== 'wysiwyg'){
      return;
    }
    //if not ckeditor compatible browser then return
    if(CKEDITOR.env && !CKEDITOR.env.isCompatible){
      return;
    }
    //if this namespace is excluded then return
    var namespace = mw.config.get('wgCanonicalNamespace');
    if(mw.user.options.get('cke_ns_' + ('ns_' + namespace).toUpperCase())){
      return;
    }
    //if the content contains __NORICHEDITOR__ then return
    if(mw.util.$content.text().indexOf( '__NORICHEDITOR__' ) > -1){
      return;
    }
	//show ckeditor, hide the wikieditor and the wikitoolbar if configured
    if((mw.user.options.get('cke_show') !== 'wikitexteditor')
      && !(mw.user.options.get('cke_show') === 'rememberlast'
        && mw.user.options.get('riched_use_toggle')
        && $.cookie('wgCKeditorToggleState') === 'hidden'))
    {
      if(toolbar.length){
        toolbar.hide();
      }
      var editor = CKEDITOR.replace(wikieditor.attr('id'));
      mw.config.set('wgCKeditorInstance', editor);
      mw.config.set('wgCKeditorVisible', true);

      //open semantic toolbar if configured
      if ( mw.user.options.get('riched_load_semantic_toolbar')){
        editor.on('instanceReady', function(event){
          event.editor.execCommand('SMWtoolbarClose');
          event.editor.execCommand('SMWtoolbarOpen');
        });
      }
    }

    //show the toggle if configured
    if(mw.user.options.get('riched_use_toggle')){
      var toggleDiv = $('<div/>').attr('id', 'ckTools').css('float', 'right');
      var toggleAnchor = $('<a/>').attr('class', 'fckToogle').attr('id', 'toggleAnchor').attr('href', '');
      
      toggleDiv.append(toggleAnchor);        
      
      if(toolbar.length){
        toolbar.before(toggleDiv);
      }
      else{
        wikieditor.before(toggleDiv);
      }

      toggleAnchor.html(mw.config.get('wgCKeditorVisible') ? mw.msg('wysiwyg-show-wikitexteditor') : mw.msg('wysiwyg-show-richtexteditor'));

      $('#toggleAnchor').live('click', function(event){
        event.preventDefault();
        toggleEditor($(this), wikieditor, toolbar);
      });

      toggleDiv.append('[');
      toggleDiv.append(toggleAnchor);
      toggleDiv.append(']');
    }
    else{
      //if toggle is not visible don't remember last state
      $.cookie('wgCKeditorToggleState', 'visible', {expires: -1});
    }
  }

  function removeMediawikiClutter(){
    $('#editpage-copywarn').hide();
    $('#wpSummaryLabel').hide();
    $('#wpSummary').hide();
  }
  
  function toggleEditor(toggle, wikieditor, toolbar){
    if(mw.config.get('wgCKeditorVisible')){
      mw.config.set('wgCKeditorVisible', false);
      var editor = CKEDITOR.instances[wikieditor.attr('id')];
      editor.execCommand('SMWtoolbarClose');
      editor.execCommand('SMWtoolbarOpen');
      editor.destroy();
      mw.config.set('wgCKeditorInstance', null);
      if(mw.user.options.get('showtoolbar') && toolbar.length){
        toolbar.show();
      }
      if(toggle.length){
        toggle.text(mw.msg('wysiwyg-show-richtexteditor'));
      }
      
      if(mw.user.options.get('cke_show') === 'rememberlast' && mw.user.options.get('riched_use_toggle')){
        $.cookie('wgCKeditorToggleState', 'hidden', {
          expires: 1000
        });
      }
    }
    else{
      if(toggle.length){
        toggle.parent().hide();
      }
      if(toolbar.length){
        toolbar.hide();
      }
      wikieditor.ckeditor(function(){
        if(toggle.length){
          setTimeout(function(){
            toggle.parent().show();
            toggle.text(mw.msg('wysiwyg-show-wikitexteditor'));
          }, 1000);
        }
      });
      editor = wikieditor.ckeditorGet();
      mw.config.set('wgCKeditorVisible', true);
      mw.config.set('wgCKeditorInstance', editor);
      if(mw.user.options.get('cke_show') === 'rememberlast' && mw.user.options.get('riched_use_toggle')){
        $.cookie('wgCKeditorToggleState', 'visible', {
          expires: 1000
        });
      }

      editor.on('instanceReady', function(event){
        event.editor.execCommand('SMWtoolbarClose');
        event.editor.execCommand('SMWtoolbarOpen');
      });
    }
  }

  function createfloatingToolbar(ckeToolbar, editor){
    var textArea = $('#cke_contents_' + editor.name);
    var width = textArea.width() || ckeToolbar.css('width');
    width += 'px';
    
    var height = parseInt(ckeToolbar.height(), 10) + 'px';
    var placeholder = $('#cke-toolbar-placeholder');
    if(!placeholder.length){
      placeholder = $('<div/>').attr('id', 'cke-toolbar-placeholder');
      ckeToolbar.after(placeholder);
    }
    placeholder.css({
      'height' : height,
      'width' : width,
      'background-color' : 'white'
    });

    placeholder.click(function(){
      textArea.children('iframe').eq(0).focus();
    });

    ckeToolbar.addClass('cke_wrapper').css({
      'position' : 'absolute',
      'border-radius' : '1px',
      'padding' : '1px'
    });
    var ckeToolbarTd = ckeToolbar.children('td').eq(0);
    ckeToolbarTd.css({
      'width' : width
    });
    
    ckeToolbar.jScroll({
      top: 5,
      speed: 0
    });
  }

  function resizeFloatingToolbar(ckeToolbar, editor, size){
    size = size || {};
    var width = size.width || ckeToolbar.width();
    var height = ckeToolbar.height();

    if(size.maximize){
      ckeToolbar.css('paddingTop', 1);
    }
    else{
   //   width -= 10;
	width = ckeToolbar.width() - 9;
    }
    width += 'px';
    var placeholder = $('#cke-toolbar-placeholder');
    placeholder.css({
      'height': height,
      'width' : width
    });
    var ckeToolbarTd = ckeToolbar.children('td').eq(0);
    ckeToolbarTd.css({
      'width' : width
    });

    
  }

  CKEDITOR.mw.isEditAllowed = function(){
    var userGroups = mw.config.get('wgUserGroups');
    var wgGroupPermissions = mw.config.get('wgGroupPermissions');

    var result = false;
    //if edit=true in one of the user groups then edit is allowed
    $.each(wgGroupPermissions, function(group, permissions){
      if($.inArray(group, userGroups) > -1 && permissions.edit){
        result = true;
        return false;
      }
    });

    return result;
  };

  CKEDITOR.mw.isMoveAllowed = function(){
    var userGroups = mw.config.get('wgUserGroups');
    var wgGroupPermissions = mw.config.get('wgGroupPermissions');

    var result = false;
    //if edit=true in one of the user groups then edit is allowed
    $.each(wgGroupPermissions, function(group, permissions){
      if($.inArray(group, userGroups) > -1 && permissions.move){
        result = true;
        return false;
      }
    });

    return result;
  };



  $(document).ready( function(){
    if(!CKEDITOR.mw.isEditAllowed()){
      return;
    }
    
    init();

    //create a floating toolbar when ckeditor instance is ready
    CKEDITOR.on('instanceReady', function(event){
      var ckeditorInstance = event.editor;
      var instanceName = ckeditorInstance.name;
      var ckeToolbar = $('#cke_top_' + instanceName).parent();
      createfloatingToolbar(ckeToolbar, ckeditorInstance);
      //resize the floating toolbar when ckeditor is resized
      ckeditorInstance.on('resize', function(event){
        if(event.data && event.data.width){
          resizeFloatingToolbar(ckeToolbar, ckeditorInstance, event.data);
        }
      });
      //ckeditor is maximize/minimized by "maximize" command. Fire "resize" event after "maximize" command is executed
      ckeditorInstance.on('afterCommandExec', function(event){
        if(event.data.name === 'maximize'){
          var width = ckeditorInstance.getResizable(true).getSize('width', true) || $('#cke_contents_' + instanceName).width();
          var height = ckeditorInstance.getResizable(true).getSize('height', true) || $('#cke_contents_' + instanceName).height();
          ckeditorInstance.fire('resize', {
            width: width,
            height: height,
            maximize: event.data.command.state === CKEDITOR.TRISTATE_ON
          });
        }
      });
      //fire "resize" event when skin is resized
      var smwMenu = $( '#smwh_menu' );
      if(smwMenu.length && smwMenu.getOntoskin){
        smwMenu.getOntoskin().addResizeListener(function(){
          var width = ckeditorInstance.getResizable(true).getSize('width', true) || $('#cke_contents_' + instanceName).width();
          var height = ckeditorInstance.getResizable(true).getSize('height', true) || $('#cke_contents_' + instanceName).height();
          ckeditorInstance.fire('resize', {
            width: width,
            height: height
          });
        });
      }

      //if "save" button is clicked then reset dirty indicator so the save dilog won't popup
      $('#wpSave').click(function(){
        ckeditorInstance.resetDirty();
      });

      //clean up when leaving the page
      $(window).unload(function(){
        ckeditorInstance.destroy();
        mw.config.set('wgCKeditorInstance', null);
        mw.config.set('wgCKeditorVisible', false);
      });

      //show confirmation dialog when there are unsaved changes
      $(window).bind('beforeunload', function(event){
        if(ckeditorInstance.checkDirty()){
          return mw.msg('wysiwyg-save-before-exit');
        }
      });
    });
  });


})(jQuery);
64.198.30.83 (talkcontribs)

Hey there,

I thought I had correctly set up all the necessary patches (using MediaWiki 1.19 and WYSIWYG 1.7 with these files), however, every page of my wiki is displaying the text of CKeditorSajax.body.php. Literally just the text of that file.

If you have any idea as to why please let me know!

Thanks!

65.95.81.89 (talkcontribs)

I have it working well in 1.19.3 and on another server running 1.19.0! Thanks so much,

However I'm noticing the the insert image doesn't select the thumbnail image (even when you select it from the drop down menu), but only posts the full size image. Any suggestions?

Also, if the rich text editor is enabled by default, the 'preferences' user page gives an error.

If I can fix those, we'll be in great shape.

207.173.231.130 (talkcontribs)

Greetings DheerajKumarBit...

I am running MW 1.19.1 on Ubuntu Server 12.04, and I have the WYSIWYG 1.7 extension installed. I replaced all five of the files you provided above, and my MW works just fine...

But I do not get the [Show RichTextEditor] line at all when editing/creating. I see the standard MW editor. I have the correct includes statement in my localsettings, and my Wiki is working very well... I just can't do any rich-text. I get no errors on page. It's as if it isn't even bothering to load. Can you help?

137.201.242.130 (talkcontribs)

I am having the exact same problem except I am running MW 1.19.1 on Server 2008R2 and have WYSIWYG 1.7 installed. Everything works fine except being able to [Show RichTextEditor]. Please Help.

131.234.225.208 (talkcontribs)

I Have the same problem, there is no [Show RichTextEditor] Button

DheerajKumarBit (talkcontribs)

Hi,

I'm sorry that i was not able to reply to your query in time. Can you try with changing $wgDefaultUserOptions['cke_show'] = 'wikitexteditor'; to $wgDefaultUserOptions['cke_show'] = 'richeditor'; in WYSIWYG.php.

Let me know the changes what you see and try to test in Firefox.

207.173.231.130 (talkcontribs)

DheerajKumarBit,

I apologize for the delayed response in getting back with you. I did attempt to change that line, but it does not exist as you have typed it.

Instead, this is what is in my WYSIWYG.php file.

$wgDefaultUserOptions['cke_show'] = 'richtexteditor';

I changed it to 'richeditor' as you suggested and this made no difference.

DheerajKumarBit (talkcontribs)

I'll suggest you to try few tests by changing options in my preferences like toggle editor and also check if WYSIWYG is enabled for all users in LocalSettings.php. I'll strongly recommend you to install Firebug in firefox and follow below instructions

  • use Console tab of firebug to check if you are getting any javascript errors.
  • use debug mode of Mediawiki with url like http://localhost/index.php?title=Main_Page&debug=true, this won't minify JavaScript using Mediawiki Resource Loader and you can check if JavaScript files of WIYIWYG/CKeditor are getting loaded or not using Script tab.
  • you can use breakpoint in firebug to track the execution of JavaScript.

Let me know if you need my help.

207.173.231.130 (talkcontribs)

Console Error on "Edit". mw.loader::execute> Exception thrown by ext.wysiwyg.core: arr is undefined

Please note, I have disabled the MediaWiki editor in the LocalSettings.php.

Firebug installed, Debug enabled. Scripts page gives me: (I am not a programmer, I am a hardware guy/sysadmin..)

<!DOCTYPE html>
<html lang="en" dir="ltr" class="client-nojs">
<head>
<title>Editing Main Page - Snap Fitness Wiki</title>
<meta charset="UTF-8" />
<meta name="generator" content="MediaWiki 1.19.1" />
<meta name="robots" content="noindex,nofollow" />
<link rel="alternate" type="application/x-wiki" title="Edit" href="/index.php?title=Main_Page&amp;action=edit" />
<link rel="edit" title="Edit" href="/index.php?title=Main_Page&amp;action=edit" />
<link rel="shortcut icon" href="/favicon.ico" />
<link rel="search" type="application/opensearchdescription+xml" href="/opensearch_desc.php" title="Snap Fitness Wiki (en)" />
<link rel="EditURI" type="application/rsd+xml" href="http://192.168.30.44/api.php?action=rsd" />
<link rel="alternate" type="application/atom+xml" title="Snap Fitness Wiki Atom feed" href="/index.php?title=Special:RecentChanges&amp;feed=atom" />
<link rel="stylesheet" href="http://192.168.30.44/load.php?debug=false&amp;lang=en&amp;modules=mediawiki.legacy.commonPrint%2Cshared%7Cskins.modern&amp;only=styles&amp;skin=modern&amp;*" />
<!--[if IE 8]><link rel="stylesheet" href="/skins/common/IE80Fixes.css?303" media="screen" /><![endif]-->
<link rel="stylesheet" href="/extensions/PrettyPhoto/modules/prettyPhoto.css" /><meta name="ResourceLoaderDynamicStyles" content="" />
<style>a:lang(ar),a:lang(ckb),a:lang(fa),a:lang(kk-arab),a:lang(mzn),a:lang(ps),a:lang(ur){text-decoration:none}a.new,#quickbar a.new{color:#ba0000}
/* cache key: my_wiki:resourceloader:filter:minify-css:7:c88e2bcd56513749bec09a7e29cb3ffa */
</style>
<script src="http://192.168.30.44/load.php?debug=false&amp;lang=en&amp;modules=startup&amp;only=scripts&amp;skin=modern&amp;*"></script>
<script>if(window.mw){
mw.config.set({"wgCanonicalNamespace":"","wgCanonicalSpecialPageName":false,"wgNamespaceNumber":0,"wgPageName":"Main_Page","wgTitle":"Main Page","wgCurRevisionId":238,"wgArticleId":1,"wgIsArticle":false,"wgAction":"edit","wgUserName":"Ckliewer","wgUserGroups":["Wiki-Admin","Wiki-Users","bureaucrat","sysop","*","user","autoconfirmed"],"wgCategories":[],"wgBreakFrames":true,"wgPageContentLanguage":"en","wgSeparatorTransformTable":["",""],"wgDigitTransformTable":["",""],"wgRelevantPageName":"Main_Page","wgRestrictionEdit":[],"wgRestrictionMove":[],"wgIsMainPage":true,"wgVectorEnabledModules":{"collapsiblenav":true,"collapsibletabs":true,"editwarning":false,"expandablesearch":false,"footercleanup":false,"sectioneditlinks":false,"simplesearch":true,"experiments":true},"wgWikiEditorEnabledModules":{"toolbar":false,"dialogs":false,"hidesig":true,"templateEditor":false,"templates":false,"preview":false,"previewDialog":false,"publish":false,"toc":false}});
}</script><script>if(window.mw){
mw.loader.implement("user.options",function($){mw.user.options.set({"ccmeonemails":0,"cols":80,"date":"default","diffonly":0,"disablemail":0,"disablesuggest":0,"editfont":"default","editondblclick":0,"editsection":1,"editsectiononrightclick":0,"enotifminoredits":0,"enotifrevealaddr":0,"enotifusertalkpages":1,"enotifwatchlistpages":0,"extendwatchlist":0,"externaldiff":0,"externaleditor":0,"fancysig":0,"forceeditsummary":0,"gender":"unknown","hideminor":0,"hidepatrolled":0,"highlightbroken":1,"imagesize":2,"justify":0,"math":1,"minordefault":0,"newpageshidepatrolled":0,"nocache":0,"noconvertlink":0,"norollbackdiff":0,"numberheadings":0,"previewonfirst":0,"previewontop":1,"quickbar":5,"rcdays":7,"rclimit":50,"rememberpassword":0,"rows":25,"searchlimit":20,"showhiddencats":0,"showjumplinks":1,"shownumberswatching":1,"showtoc":1,"showtoolbar":1,"skin":"modern","stubthreshold":0,"thumbsize":2,"underline":2,"uselivepreview":0,"usenewrc":0,"watchcreations":0,"watchdefault":0,"watchdeletion":0,
"watchlistdays":3,"watchlisthideanons":0,"watchlisthidebots":0,"watchlisthideliu":0,"watchlisthideminor":0,"watchlisthideown":0,"watchlisthidepatrolled":0,"watchmoves":0,"wllimit":250,"vector-simplesearch":1,"breadcrumbs-filter-duplicates":true,"breadcrumbs-ignore-refreshes":true,"riched_use_toggle":1,"cke_show":"richtexteditor","variant":"en","language":"en","searchNs0":true,"searchNs1":false,"searchNs2":false,"searchNs3":false,"searchNs4":false,"searchNs5":false,"searchNs6":false,"searchNs7":false,"searchNs8":false,"searchNs9":false,"searchNs10":false,"searchNs11":false,"searchNs12":false,"searchNs13":false,"searchNs14":false,"searchNs15":false,"nickname":"","timecorrection":"Offset|0","watchlisttoken":"00269b064af0df83f1dbf7c5848f6b44625688e3"});;},{},{});mw.loader.implement("user.tokens",function($){mw.user.tokens.set({"editToken":"3cb5a8fac9ea9c6d7772c221b1e46a24+\\","watchToken":"ca21f25eeeb31df2da4fb5fddb2bb5a8+\\"});;},{},{});
/* cache key: my_wiki:resourceloader:filter:minify-js:7:aee664222e9cf83b7532a5e5d0895bc9 */
}</script>
<script>if(window.mw){
mw.loader.load(["mediawiki.page.startup","mediawiki.legacy.wikibits","mediawiki.legacy.ajax"]);
}</script>
</head>
<body class="mediawiki ltr sitedir-ltr ns-0 ns-subject page-Main_Page skin-modern action-edit">
<!-- heading -->
<div id="mw_header"><h1 id="firstHeading"><span dir="auto">Editing Main Page</span></h1></div>
<div id="mw_main">
<div id="mw_contentwrapper">
<!-- navigation portlet -->
<div id="p-cactions" class="portlet">
<h5>Views</h5>
<div class="pBody">
<ul>
<li id="ca-nstab-main" class="selected"><a href="/index.php/Main_Page" primary="1" context="subject" title="View the content page [c]" accesskey="c">Page</a></li>
<li id="ca-talk" class="new"><a href="/index.php?title=Talk:Main_Page&amp;action=edit&amp;redlink=1" primary="1" context="talk" title="Discussion about the content page [t]" accesskey="t">Discussion</a></li>
<li id="ca-edit" class="selected"><a href="/index.php?title=Main_Page&amp;action=edit" primary="1" title="You can edit this page. Please use the preview button before saving">Edit</a></li>
<li id="ca-history"><a href="/index.php?title=Main_Page&amp;action=history" rel="archives" title="Past revisions of this page [h]" accesskey="h">History</a></li>
<li id="ca-delete"><a href="/index.php?title=Main_Page&amp;action=delete" title="Delete this page [d]" accesskey="d">Delete</a></li>
<li id="ca-move"><a href="/index.php/Special:MovePage/Main_Page" title="Move this page [m]" accesskey="m">Move</a></li>
<li id="ca-protect"><a href="/index.php?title=Main_Page&amp;action=protect" title="Protect this page [=]" accesskey="=">Protect</a></li>
<li id="ca-watch"><a href="/index.php?title=Main_Page&amp;action=watch&amp;token=cb98908f1677b61c095af38053fdf1ec%2B%5C" title="Add this page to your watchlist">Watch</a></li>
</ul>
</div>
</div>
<!-- content -->
<div id="mw_content">
<!-- contentholder does nothing by default, but it allows users to style the text inside
the content area without affecting the meaning of 'em' in #mw_content, which is used
for the margins -->
<div id="mw_contentholder">
<div class='mw-topboxes'>
<div id="mw-js-message" style="display:none;"></div>
<div class="mw-topbox" id="siteSub">From Snap Fitness Wiki</div>
</div>
<div id="contentSub"></div>
<div id="jump-to-nav">Jump to: <a href="#mw_portlets">navigation</a>, <a href="#searchInput">search</a></div>
<div id="mw-content-text"><div id="wikiPreview" class="ontop" style="display: none;"></div><form id="editform" name="editform" method="post" action="/index.php?title=Main_Page&amp;action=submit" enctype="multipart/form-data"><input type='hidden' value="" name="wpSection" />
<input type='hidden' value="20120827132214" name="wpStarttime" />
<input type='hidden' value="20120810165138" name="wpEdittime" />
<input type='hidden' value="" name="wpScrolltop" id="wpScrolltop" />
<input type="hidden" value="d41d8cd98f00b204e9800998ecf8427e" name="wpAutoSummary" /><input type="hidden" value="0" name="oldid" /><div id="toolbar"></div><textarea tabindex="1" accesskey="," id="wpTextbox1" cols="80" rows="25" style="" lang="en" dir="ltr" name="wpTextbox1">== Welcome to the Snap Fitness Wiki. ==
Select a category below.
* [[Systems]]
* [[Development]]
* [[Design]]
* [[Database]]
* [[Quality Assurance]]
* [[Release]]
* [[Software]]
* [[Contacts]]
* [[HR]]
</textarea><div id="editpage-copywarn">
<p>Please note that all contributions to Snap Fitness Wiki may be edited, altered, or removed by other contributors.
If you do not want your writing to be edited mercilessly, then do not submit it here.<br />
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see <a href="/index.php?title=Snap_Fitness_Wiki:Copyrights&amp;action=edit&amp;redlink=1" class="new" title="Snap Fitness Wiki:Copyrights (page does not exist)">Snap Fitness Wiki:Copyrights</a> for details).
<b>Do not submit copyrighted work without permission!</b>
</p>
</div>
<div class='editOptions'>
<span class="mw-summary" id="wpSummaryLabel"><label for="wpSummary">Summary:</label></span> <input class="mw-summary" id="wpSummary" maxlength="200" tabindex="1" size="60" spellcheck="true" title="Enter a short summary [b]" accesskey="b" name="wpSummary" /><div class='editCheckboxes'><input name="wpMinoredit" type="checkbox" value="1" tabindex="3" accesskey="i" id="wpMinoredit" />&#160;<label for='wpMinoredit' id='mw-editpage-minoredit' title="Mark this as a minor edit [i]">This is a minor edit</label>
<input name="wpWatchthis" type="checkbox" value="1" tabindex="4" accesskey="w" id="wpWatchthis" />&#160;<label for='wpWatchthis' id='mw-editpage-watch' title="Add this page to your watchlist [w]">Watch this page</label></div>
<div class='editButtons'>
<input id="wpSave" name="wpSave" type="submit" tabindex="5" value="Save page" accesskey="s" title="Save your changes [s]" />
<input id="wpPreview" name="wpPreview" type="submit" tabindex="6" value="Show preview" accesskey="p" title="Preview your changes, please use this before saving! [p]" />
<input id="wpDiff" name="wpDiff" type="submit" tabindex="7" value="Show changes" accesskey="v" title="Show which changes you made to the text [v]" />
<span class='editHelp'><a href="/index.php/Main_Page" title="Main Page" id="mw-editform-cancel">Cancel</a> | <a target="helpwindow" href="/index.php/Help:Editing">Editing help</a> (opens in new window)</span>
</div><!-- editButtons -->
</div><!-- editOptions -->
<input type="hidden" value="3cb5a8fac9ea9c6d7772c221b1e46a24+\" name="wpEditToken" />
<div class="mw-editTools"></div>
<div class="templatesUsed"></div><div class="hiddencats"></div>
</form>
</div><div class="printfooter">
Retrieved from "<a href="http://192.168.30.44/index.php/Main_Page">http://192.168.30.44/index.php/Main_Page</a>"</div>
<div class='mw_clear'></div>
<div id='catlinks' class='catlinks catlinks-allhidden'></div> </div><!-- mw_contentholder -->
</div><!-- mw_content -->
</div><!-- mw_contentwrapper -->
<div id="mw_portlets">
<!-- portlets -->
<div class="generated-sidebar portlet" id="p-navigation">
<h5>Navigation</h5>
<div class='pBody'>
<ul>
<li id="n-mainpage-description"><a href="/index.php/Main_Page" title="Visit the main page [z]" accesskey="z">Main page</a></li>
<li id="n-Development"><a href="/index.php/Development">Development</a></li>
<li id="n-HR"><a href="/index.php/HR">HR</a></li>
<li id="n-Systems"><a href="/index.php/Systems">Systems</a></li>
<li id="n-Software"><a href="/index.php/Software">Software</a></li>
<li id="n-currentevents"><a href="/index.php/Snap_Fitness_Wiki:Current_events" title="Find background information on current events">Current events</a></li>
<li id="n-randompage"><a href="/index.php/Special:Random" title="Load a random page [x]" accesskey="x">Random page</a></li>
<li id="n-help"><a href="/index.php/Help:Contents" title="The place to find out">Help</a></li>
</ul>
</div>
</div>
<div id="p-search" class="portlet">
<h5><label for="searchInput">Search</label></h5>
<div id="searchBody" class="pBody">
<form action="/index.php" id="searchform">
<input type='hidden' name="title" value="Special:Search"/>
<input type="search" name="search" title="Search Snap Fitness Wiki [f]" accesskey="f" id="searchInput" />
<input type="submit" name="go" value="Go" title="Go to a page with this exact name if exists" id="searchGoButton" class="searchButton" />&#160;
<input type="submit" name="fulltext" value="Search" title="Search the pages for this text" id="mw-searchButton" class="searchButton" />
</form>
</div>
</div>
<div class="portlet" id="p-tb">
<h5>Toolbox</h5>
<div class="pBody">
<ul>
<li id="t-whatlinkshere"><a href="/index.php/Special:WhatLinksHere/Main_Page" title="A list of all wiki pages that link here [j]" accesskey="j">What links here</a></li>
<li id="t-recentchangeslinked"><a href="/index.php/Special:RecentChangesLinked/Main_Page" title="Recent changes in pages linked from this page [k]" accesskey="k">Related changes</a></li>
<li id="t-upload"><a href="/index.php/Special:Upload" title="Upload files [u]" accesskey="u">Upload file</a></li>
<li id="t-specialpages"><a href="/index.php/Special:SpecialPages" title="A list of all special pages [q]" accesskey="q">Special pages</a></li>
</ul>
</div>
</div>
</div><!-- mw_portlets -->
</div><!-- main -->
<div class="mw_clear"></div>
<!-- personal portlet -->
<div class="portlet" id="p-personal">
<h5>Personal tools</h5>
<div class="pBody">
<ul>
<li id="pt-userpage"><a href="/index.php/User:Ckliewer" class="new" title="Your user page [.]" accesskey=".">Ckliewer</a></li>
<li id="pt-mytalk"><a href="/index.php/User_talk:Ckliewer" class="new" title="Your talk page [n]" accesskey="n">My talk</a></li>
<li id="pt-adminlinks"><a href="/index.php/Special:AdminLinks">Admin links</a></li>
<li id="pt-preferences"><a href="/index.php/Special:Preferences" title="Your preferences">My preferences</a></li>
<li id="pt-watchlist"><a href="/index.php/Special:Watchlist" title="A list of pages you are monitoring for changes [l]" accesskey="l">My watchlist</a></li>
<li id="pt-mycontris"><a href="/index.php/Special:Contributions/Ckliewer" title="A list of your contributions [y]" accesskey="y">My contributions</a></li>
<li id="pt-logout"><a href="/index.php?title=Special:UserLogout&amp;returnto=Main+Page&amp;returntoquery=action%3Dedit" title="Log out">Log out</a></li>
</ul>
</div>
</div>
<!-- footer -->
<div id="footer">
<ul id="f-list">
<li id="privacy"><a href="/index.php/Snap_Fitness_Wiki:Privacy_policy" title="Snap Fitness Wiki:Privacy policy">Privacy policy</a></li>
<li id="about"><a href="/index.php/Snap_Fitness_Wiki:About" title="Snap Fitness Wiki:About">About Snap Fitness Wiki</a></li>
<li id="disclaimer"><a href="/index.php/Snap_Fitness_Wiki:General_disclaimer" title="Snap Fitness Wiki:General disclaimer">Disclaimers</a></li>
</ul>
<div id="mw_poweredby">
<a href="//www.mediawiki.org/">Powered by MediaWiki</a>
</div>
</div>
<script>if(window.mw){
mw.loader.load(["ext.wikiEditor.toolbar.hideSig","ext.MsUpload","mediawiki.action.edit","ext.breadCrumbs","mediawiki.user","mediawiki.page.ready","mediawiki.action.watch.ajax","ext.GoogleCodePrettify","ext.wysiwyg.core"], null, true);
}</script>
<script type="text/javascript">var msu_vars = {"path":"\/extensions\/MsUpload","use_mslinks":"false","autoKat":"false","autoIndex":"false","autoChecked":"false","debugMode":"false"};</script>
<script>if(window.mw){
mw.loader.using("mediawiki.action.edit", function() {mw.toolbar.addButton("/skins/common/images/button_bold.png", "Bold text", "\'\'\'", "\'\'\'", "Bold text", "mw-editbutton-bold");
mw.toolbar.addButton("/skins/common/images/button_italic.png", "Italic text", "\'\'", "\'\'", "Italic text", "mw-editbutton-italic");
mw.toolbar.addButton("/skins/common/images/button_link.png", "Internal link", "[[", "]]", "Link title", "mw-editbutton-link");
mw.toolbar.addButton("/skins/common/images/button_extlink.png", "External link (remember http:// prefix)", "[", "]", "http://www.example.com link title", "mw-editbutton-extlink");
mw.toolbar.addButton("/skins/common/images/button_headline.png", "Level 2 headline", "\n== ", " ==\n", "Headline text", "mw-editbutton-headline");
mw.toolbar.addButton("/skins/common/images/button_image.png", "Embedded file", "[[File:", "]]", "Example.jpg", "mw-editbutton-image");
mw.toolbar.addButton("/skins/common/images/button_media.png", "File link", "[[Media:", "]]", "Example.ogg", "mw-editbutton-media");
mw.toolbar.addButton("/skins/common/images/button_nowiki.png", "Ignore wiki formatting", "\x3cnowiki\x3e", "\x3c/nowiki\x3e", "Insert non-formatted text here", "mw-editbutton-nowiki");
mw.toolbar.addButton("/skins/common/images/button_sig.png", "Your signature with timestamp", "--[[Special:Contributions/207.173.231.130|207.173.231.130]] 13:31, 27 August 2012 (UTC)", "", "", "mw-editbutton-signature");
mw.toolbar.addButton("/skins/common/images/button_hr.png", "Horizontal line (use sparingly)", "\n----\n", "", "", "mw-editbutton-hr");
// Create button bar
$(function() { mw.toolbar.init(); } );
});
}</script>
<script src="/extensions/PrettyPhoto/modules/jquery.prettyPhoto.js?303"></script>
<script src="/extensions/PrettyPhoto/modules/init.js?303"></script>
<!-- Served in 0.167 secs. --></body></html>
DheerajKumarBit (talkcontribs)

I understand your problems being a system admin guy as I'm also working in the same. Your error says that your trying to load ext.wysiwyg.core module but haven't registered it properly before trying to load. I'll suggest you to check $wgResourceModules['ext.wysiwyg.core'] in CKeditor.body.php. It should have all scripts registered with Mediawiki Resource Loader. But if it didn't solve your problem attach a small screen shot of firebug console with errors. It'll help me and I'll try to reproduce the same on my machine.

207.173.231.130 (talkcontribs)

I appreciate all of your help. :) Here is the snippet from the CKeditor.body.php file with the segment you suggested I check.

$wgResourceModules['ext.wysiwyg.core'] = $moduleTemplate + array(

       'messages' => array(
           'wysiwyg-qi-edit-query',
           'wysiwyg-qi-insert-query',
           'wysiwyg-qi-insert-new-query',
           'wysiwyg-rename',
           'wysiwyg-title-empty',
           'wysiwyg-title-invalid',
           'wysiwyg-title-exists',
           'wysiwyg-show-richtexteditor',
           'wysiwyg-show-wikitexteditor',
           'wysiwyg-save-and-continue',
           'wysiwyg-save-failed',
           'wysiwyg-save-failed-unknown-error',
           'wysiwyg-save-error',
           'wysiwyg-save-successful',
           'wysiwyg-move-failed',
           'wysiwyg-move-failed-unknown-error',
           'wysiwyg-move-error',
           'wysiwyg-move-successful',
           'wysiwyg-last-save',
           'wysiwyg-never',
           'wysiwyg-no-changes',
           'wysiwyg-save-before-rename',
           'wysiwyg-save-before-exit'

As for the screenshot, what I posted was quite specific. This is the ONLY error that is thrown on the page when I click Edit in an article. mw.loader::execute> Exception thrown by ext.wysiwyg.core: arr is undefined The line to the right points to http://192.168.30.44/load.php?debug=false&lang=en&modules=jquery%2Cmediawiki&only=scripts&skin=modern&version=20120613T182239Z and references line 148. Line 148 reads: registry[module].messages)){mw.messages.set(registry[module].messages);}try{script=registry[module].script;markModuleReady=function(){registry[module].state='ready';handlePending(module);if($.isFunction(callback)){callback();}};nestedAddScript=function(arr,callback,async,i){if(i>=arr.length){callback();return;}addScript(arr[i],function(){nestedAddScript(arr,callback,async,i+1);},async);};if($.isArray(script)){registry[module].state='loading';nestedAddScript(script,markModuleReady,registry[module].async,0);}else if($.isFunction(script)){script($);markModuleReady();}}catch(e){if(window.console&&typeof window.console.log==='function'){console.log('mw.loader::execute> Exception thrown by '+module+': '+e.message);}registry[module].state='error';}}function request(dependencies,ready,error,async){var regItemDeps,regItemDepLen,n;if(typeof dependencies==='string'){dependencies=[dependencies];if(registry[dependencies[0]]!==undefined){regItemDeps=registry[dependencies[0]].dependencies;

125.89.61.69 (talkcontribs)
DomDoucet (talkcontribs)

The patch is erasing my links to categories with MediaWiki 1.20. Any solution posted? Thank you

MarkJurgens (talkcontribs)

Thanks for your help, this works great in 1.19, It also works in 20.2 but seems to be deleting/altering existing links. Any fix for this?

Sephirothindra (talkcontribs)

Woowww!!! The patch works at my wiki 1.19.7!!! Thank you so much!!

194.156.246.226 (talkcontribs)

hey


thank u for ur time and help

but it doesn't work for me - I don't see a button to change to richeditor when I click "edit"

here my settings:

MediaWiki 1.19.8 PHP 5.4.19 (apache2handler) MySQL 5.5.32


WYSIWYG extension (Version 1.7.0_1 [B5], CKEditor 3.6 (revision 6902))

I edited the 5 files, but it doesn't work

I also opened a new thread - would be very great if someone can help me :D Link to new thread: http://www.mediawiki.org/wiki/Extension_talk:WYSIWYG#MW_1.19.8_-_Editor_doenst_open.2C_no_button_is_shown_34212

greets

DylanKao (talkcontribs)

Hi DheerajKumarBit,

I tried to modify that 5 files you provided and the rich text editor button is not show on the wiki page. Do you have any idea for this? I running the mediawiki from 1.17 upgrade to 1.19. and use the source from (http://wiki.linuxmatter.com/index.php/File:WYSIWYG.zip)

Quirax (talkcontribs)

First, check your user settings. In user settings, there is a check box which enable rich editor button.

Second, check is there require routine in localsettings.php.

If the check box has checked and there is require routinein localsettings.php, please redownload that.

DheerajKumarBit (talkcontribs)

Rather than downloading source from above link you can manually copy & paste 5 files that should work if not try to find out if any JavaScript error is there on the page.

DylanKao (talkcontribs)

Hi DheerajKumarBit,

Even I changed that files, the "Rich Text Button" won't show in the page. :'( I never seem any JavaScript error on IE browser, so I have no idea for it. Sorry, May I ask if there is new version release for MW 1.19.1? It will help us to quickly to use that. big thanks. :DDD

65.95.81.89 (talkcontribs)

Seems to work 'okay' in 1.19.3 but not the very first time, I usually have to refresh. Any idea why that is?

Sephirothindra (talkcontribs)

Hi.. I have success use your patch DheerajKumarBit, that was good. But when I 'show preview', the rich text editor button javascript was missing. What happen that? I use mediawiki 1.19.

Skew (talkcontribs)

I see the code for Semantic Forms is included in your patched files. Have you (or anyone) seen this updated WYSIWYG extension work with the free text field in forms?

116.50.61.180 (talkcontribs)

This thread is a mess! I am runningi 1.19.5 and none of the above comments and modified files seem to work. Has anyone gotten this working on 1.19.5 or 1.19.x? If you have, can you please just zip the complete wysiwyg folder from your extension folder and provde it here for us to download.

I'm assuming these two lines need to be added to the LocalSettings file:

require_once "$IP/extensions/WYSIWYG/WYSIWYG.php"; $wgGroupPermissions['*']['wysiwyg']=true; // for all users

  1. $wgGroupPermissions['registered_users']['wysiwyg']=true; // or only for registered users

And then it should work right???

Riparap (talkcontribs)

What version of wysiwyg from table #Download you are using?

I have not tested #6 bundle with MW 1.19, but perhaps you could try if #6 bundle happens to work there any better.

Reply to "Patch for MW 1.19"