merged master
[lhc/web/wiklou.git] / includes / diff / DifferenceEngine.php
index db3c37c..30b2f28 100644 (file)
@@ -38,7 +38,7 @@ class DifferenceEngine extends ContextSource {
         * @private
         */
        var $mOldid, $mNewid;
-       var $mOldtext, $mNewtext;
+       var $mOldContent, $mNewContent;
        protected $mDiffLang;
 
        /**
@@ -213,7 +213,7 @@ class DifferenceEngine extends ContextSource {
                # If external diffs are enabled both globally and for the user,
                # we'll use the application/x-external-editor interface to call
                # an external diff tool like kompare, kdiff3, etc.
-               if ( ExternalEdit::useExternalEngine( $this->getContext(), 'diff' ) ) {
+               if ( ExternalEdit::useExternalEngine( $this->getContext(), 'diff' ) ) { #FIXME: how to handle this for non-text content?
                        $urls = array(
                                'File' => array( 'Extension' => 'wiki', 'URL' =>
                                        # This should be mOldPage, but it may not be set, see below.
@@ -500,19 +500,20 @@ class DifferenceEngine extends ContextSource {
                        $out->setRevisionTimestamp( $this->mNewRev->getTimestamp() );
                        $out->setArticleFlag( true );
 
-                       if ( $this->mNewPage->isCssJsSubpage() || $this->mNewPage->isCssOrJsPage() ) {
+                       if ( $this->mNewPage->isCssJsSubpage() || $this->mNewPage->isCssOrJsPage() ) { #NOTE: only needed for B/C: custom rendering of JS/CSS via hook
                                // Stolen from Article::view --AG 2007-10-11
                                // Give hooks a chance to customise the output
                                // @TODO: standardize this crap into one function
-                               if ( wfRunHooks( 'ShowRawCssJs', array( $this->mNewtext, $this->mNewPage, $out ) ) ) {
-                                       // Wrap the whole lot in a <pre> and don't parse
-                                       $m = array();
-                                       preg_match( '!\.(css|js)$!u', $this->mNewPage->getText(), $m );
-                                       $out->addHTML( "<pre class=\"mw-code mw-{$m[1]}\" dir=\"ltr\">\n" );
-                                       $out->addHTML( htmlspecialchars( $this->mNewtext ) );
-                                       $out->addHTML( "\n</pre>\n" );
+                               if ( !Hook::isRegistered( 'ShowRawCssJs' )
+                                       || wfRunHooks( 'ShowRawCssJs', array( ContentHandler::getContentText( $this->mNewContent ), $this->mNewPage, $out ) ) ) { #NOTE: deperecated hook, B/C only
+                                       // use the content object's own rendering
+                                       $po = $this->mContentObject->getParserOutput();
+                                       $out->addHTML( $po->getText() );
                                }
-                       } elseif ( !wfRunHooks( 'ArticleViewCustom', array( $this->mNewtext, $this->mNewPage, $out ) ) ) {
+                       } elseif( !wfRunHooks( 'ArticleContentViewCustom', array( $this->mNewContent, $this->mNewPage, $out ) ) ) {
+                               // Handled by extension
+                       } elseif( Hooks::isRegistered( 'ArticleViewCustom' )
+                                       && !wfRunHooks( 'ArticleViewCustom', array( ContentHandler::getContentText( $this->mNewContent ), $this->mNewPage, $out ) ) ) { #NOTE: deperecated hook, B/C only
                                // Handled by extension
                        } else {
                                // Normal page
@@ -526,15 +527,7 @@ class DifferenceEngine extends ContextSource {
                                        $wikiPage = WikiPage::factory( $this->mNewPage );
                                }
 
-                               $parserOptions = ParserOptions::newFromContext( $this->getContext() );
-                               $parserOptions->enableLimitReport();
-                               $parserOptions->setTidy( true );
-
-                               if ( !$this->mNewRev->isCurrent() ) {
-                                       $parserOptions->setEditSection( false );
-                               }
-
-                               $parserOutput = $wikiPage->getParserOutput( $parserOptions, $this->mNewid );
+                               $parserOutput = $this->getParserOutput( $wikiPage, $this->mNewRev );
 
                                # WikiPage::getParserOutput() should not return false, but just in case
                                if( $parserOutput ) {
@@ -548,6 +541,19 @@ class DifferenceEngine extends ContextSource {
                wfProfileOut( __METHOD__ );
        }
 
+       protected function getParserOutput( WikiPage $page, Revision $rev ) {
+               $parserOptions = ParserOptions::newFromContext( $this->getContext() );
+               $parserOptions->enableLimitReport();
+               $parserOptions->setTidy( true );
+
+               if ( !$rev->isCurrent() || !$rev->getTitle()->quickUserCan( "edit" ) ) {
+                       $parserOptions->setEditSection( false );
+               }
+
+               $parserOutput = $page->getParserOutput( $parserOptions, $rev->getId() );
+               return $parserOutput;
+       }
+
        /**
         * Get the diff text, send it to the OutputPage object
         * Returns false if the diff could not be generated, otherwise returns true
@@ -644,7 +650,7 @@ class DifferenceEngine extends ContextSource {
                        return false;
                }
 
-               $difftext = $this->generateDiffBody( $this->mOldtext, $this->mNewtext );
+               $difftext = $this->generateContentDiffBody( $this->mOldContent, $this->mNewContent );
 
                // Save to cache for 7 days
                if ( !wfRunHooks( 'AbortDiffCache', array( &$this ) ) ) {
@@ -681,14 +687,50 @@ class DifferenceEngine extends ContextSource {
                }
        }
 
+       /**
+        * Generate a diff, no caching.
+        *
+        * Subclasses may override this to provide a
+        *
+        * @param $old Content: old content
+        * @param $new Content: new content
+        *
+        * @since 1.WD
+        */
+       function generateContentDiffBody( Content $old, Content $new ) {
+               #XXX: generate a warning if $old or $new are not instances of TextContent?
+               #XXX: fail if $old and $new don't have the same content model? or what?
+
+               $otext = $old->serialize();
+               $ntext = $new->serialize();
+
+               #XXX: text should be "already segmented". what does that mean?
+               return $this->generateTextDiffBody( $otext, $ntext );
+       }
+
        /**
         * Generate a diff, no caching
         *
         * @param $otext String: old text, must be already segmented
         * @param $ntext String: new text, must be already segmented
-        * @return bool|string
+        * @deprecated since 1.WD, use generateContentDiffBody() instead!
         */
        function generateDiffBody( $otext, $ntext ) {
+               wfDeprecated( __METHOD__, "1.WD" );
+
+               return $this->generateTextDiffBody( $otext, $ntext );
+       }
+
+       /**
+        * Generate a diff, no caching
+        *
+        * @todo move this to TextDifferenceEngine, make DifferenceEngine abstract. At some point.
+        *
+        * @param $otext String: old text, must be already segmented
+        * @param $ntext String: new text, must be already segmented
+        * @return bool|string
+        */
+       function generateTextDiffBody( $otext, $ntext ) {
                global $wgExternalDiffEngine, $wgContLang;
 
                wfProfileIn( __METHOD__ );
@@ -851,7 +893,7 @@ class DifferenceEngine extends ContextSource {
         *        the visibility of the revision and a link to edit the page.
         * @return String HTML fragment
         */
-       private function getRevisionHeader( Revision $rev, $complete = '' ) {
+       protected function getRevisionHeader( Revision $rev, $complete = '' ) {
                $lang = $this->getLanguage();
                $user = $this->getUser();
                $revtimestamp = $rev->getTimestamp();
@@ -943,10 +985,25 @@ class DifferenceEngine extends ContextSource {
 
        /**
         * Use specified text instead of loading from the database
+        * @deprecated since 1.WD
         */
-       function setText( $oldText, $newText ) {
-               $this->mOldtext = $oldText;
-               $this->mNewtext = $newText;
+       function setText( $oldText, $newText ) { #FIXME: no longer use this, use setContent()!
+               wfDeprecated( __METHOD__, "1.WD" );
+
+               $oldContent = ContentHandler::makeContent( $oldText, $this->getTitle() );
+               $newContent = ContentHandler::makeContent( $newText, $this->getTitle() );
+
+               $this->setContent( $oldContent, $newContent );
+       }
+
+       /**
+        * Use specified text instead of loading from the database
+        * @since 1.WD
+        */
+       function setContent( Content $oldContent, Content $newContent ) {
+               $this->mOldContent = $oldContent;
+               $this->mNewContent = $newContent;
+
                $this->mTextLoaded = 2;
                $this->mRevisionsLoaded = true;
        }
@@ -1074,14 +1131,14 @@ class DifferenceEngine extends ContextSource {
                        return false;
                }
                if ( $this->mOldRev ) {
-                       $this->mOldtext = $this->mOldRev->getText( Revision::FOR_THIS_USER );
-                       if ( $this->mOldtext === false ) {
+                       $this->mOldContent = $this->mOldRev->getContent( Revision::FOR_THIS_USER );
+                       if ( $this->mOldContent === false ) {
                                return false;
                        }
                }
                if ( $this->mNewRev ) {
-                       $this->mNewtext = $this->mNewRev->getText( Revision::FOR_THIS_USER );
-                       if ( $this->mNewtext === false ) {
+                       $this->mNewContent = $this->mNewRev->getContent( Revision::FOR_THIS_USER );
+                       if ( $this->mNewContent === false ) {
                                return false;
                        }
                }
@@ -1102,7 +1159,7 @@ class DifferenceEngine extends ContextSource {
                if ( !$this->loadRevisionData() ) {
                        return false;
                }
-               $this->mNewtext = $this->mNewRev->getText( Revision::FOR_THIS_USER );
+               $this->mNewContent = $this->mNewRev->getContent( Revision::FOR_THIS_USER );
                return true;
        }
 }