* @private
*/
var $mOldid, $mNewid;
- var $mOldtext, $mNewtext;
+ var $mOldContent, $mNewContent;
protected $mDiffLang;
/**
}
}
+ private function showMissingRevision() {
+ $out = $this->getOutput();
+
+ $missing = array();
+ if ( $this->mOldRev === null ) {
+ $missing[] = $this->deletedIdMarker( $this->mOldid );
+ }
+ if ( $this->mNewRev === null ) {
+ $missing[] = $this->deletedIdMarker( $this->mNewid );
+ }
+
+ $out->setPageTitle( $this->msg( 'errorpagetitle' ) );
+ $out->addWikiMsg( 'difference-missing-revision',
+ $this->getLanguage()->listToText( $missing ), count( $missing ) );
+ }
+
function showDiffPage( $diffOnly = false ) {
wfProfileIn( __METHOD__ );
$out->setRobotPolicy( 'noindex,nofollow' );
if ( !$this->loadRevisionData() ) {
- // Sounds like a deleted revision... Let's see what we can do.
- $t = $this->getTitle()->getPrefixedText();
- $d = $this->msg( 'missingarticle-diff',
- $this->deletedIdMarker( $this->mOldid ),
- $this->deletedIdMarker( $this->mNewid ) )->escaped();
- $out->setPageTitle( $this->msg( 'errorpagetitle' ) );
- $out->addWikiMsg( 'missing-article', "<nowiki>$t</nowiki>", "<span class='plainlinks'>$d</span>" );
+ $this->showMissingRevision();
wfProfileOut( __METHOD__ );
return;
}
# 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' ) ) {
+ //TODO: come up with a good solution for non-text content here.
+ // at least, the content format needs to be passed to the client somehow.
+ // Currently, action=raw will just fail for non-text content.
+
$urls = array(
'File' => array( 'Extension' => 'wiki', 'URL' =>
# This should be mOldPage, but it may not be set, see below.
$out->setRevisionTimestamp( $this->mNewRev->getTimestamp() );
$out->setArticleFlag( true );
+ // NOTE: only needed for B/C: custom rendering of JS/CSS via hook
if ( $this->mNewPage->isCssJsSubpage() || $this->mNewPage->isCssOrJsPage() ) {
// 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 ( ContentHandler::runLegacyHooks( 'ShowRawCssJs', array( $this->mNewContent, $this->mNewPage, $out ) ) ) {
+ // NOTE: deprecated hook, B/C only
+ // use the content object's own rendering
+ $po = $this->mNewRev->getContent()->getParserOutput( $this->mNewRev->getTitle(), $this->mNewRev->getId() );
+ $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( !ContentHandler::runLegacyHooks( 'ArticleViewCustom', array( $this->mNewContent, $this->mNewPage, $out ) ) ) {
+ // NOTE: deprecated hook, B/C only
// Handled by extension
} else {
// Normal page
$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 ) {
wfProfileOut( __METHOD__ );
}
+ protected function getParserOutput( WikiPage $page, Revision $rev ) {
+ $parserOptions = $page->makeParserOptions( $this->getContext() );
+
+ 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
function showDiff( $otitle, $ntitle, $notice = '' ) {
$diff = $this->getDiff( $otitle, $ntitle, $notice );
if ( $diff === false ) {
- $this->getOutput()->addWikiMsg( 'missing-article', "<nowiki>(fixme, bug)</nowiki>", '' );
+ $this->showMissingRevision();
return false;
} else {
$this->showDiffStyle();
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 ) ) ) {
}
}
+ /**
+ * Generate a diff, no caching.
+ *
+ * Subclasses may override this to provide a
+ *
+ * @param $old Content: old content
+ * @param $new Content: new content
+ *
+ * @since 1.21
+ */
+ function generateContentDiffBody( Content $old, Content $new ) {
+ if ( !( $old instanceof TextContent ) ) {
+ throw new MWException( "Diff not implemented for " . get_class( $old ) . "; "
+ . "override generateContentDiffBody to fix this." );
+ }
+
+ if ( !( $new instanceof TextContent ) ) {
+ throw new MWException( "Diff not implemented for " . get_class( $new ) . "; "
+ . "override generateContentDiffBody to fix this." );
+ }
+
+ $otext = $old->serialize();
+ $ntext = $new->serialize();
+
+ 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.21, use generateContentDiffBody() instead!
*/
function generateDiffBody( $otext, $ntext ) {
+ wfDeprecated( __METHOD__, "1.21" );
+
+ 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__ );
* 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();
if ( !$diff && !$otitle ) {
$header .= "
- <tr valign='top'>
+ <tr style='vertical-align: top;'>
<td class='diff-ntitle'>{$ntitle}</td>
</tr>";
$multiColspan = 1;
$multiColspan = 2;
}
$header .= "
- <tr valign='top'>
+ <tr style='vertical-align: top;'>
<td colspan='$colspan' class='diff-otitle'>{$otitle}</td>
<td colspan='$colspan' class='diff-ntitle'>{$ntitle}</td>
</tr>";
}
if ( $multi != '' ) {
- $header .= "<tr><td colspan='{$multiColspan}' align='center' class='diff-multi'>{$multi}</td></tr>";
+ $header .= "<tr><td colspan='{$multiColspan}' style='text-align: center;' class='diff-multi'>{$multi}</td></tr>";
}
if ( $notice != '' ) {
- $header .= "<tr><td colspan='{$multiColspan}' align='center'>{$notice}</td></tr>";
+ $header .= "<tr><td colspan='{$multiColspan}' style='text-align: center;'>{$notice}</td></tr>";
}
return $header . $diff . "</table>";
/**
* Use specified text instead of loading from the database
+ * @deprecated since 1.21, use setContent() instead.
*/
function setText( $oldText, $newText ) {
- $this->mOldtext = $oldText;
- $this->mNewtext = $newText;
+ wfDeprecated( __METHOD__, "1.21" );
+
+ $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.21
+ */
+ function setContent( Content $oldContent, Content $newContent ) {
+ $this->mOldContent = $oldContent;
+ $this->mNewContent = $newContent;
+
$this->mTextLoaded = 2;
$this->mRevisionsLoaded = true;
}
// Load the new revision object
$this->mNewRev = $this->mNewid
? Revision::newFromId( $this->mNewid )
- : Revision::newFromTitle( $this->getTitle(), false, Revision::AVOID_MASTER );
+ : Revision::newFromTitle( $this->getTitle(), false, Revision::READ_NORMAL );
if ( !$this->mNewRev instanceof Revision ) {
return false;
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, $this->getUser() );
+ 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, $this->getUser() );
+ if ( $this->mNewContent === false ) {
return false;
}
}
if ( !$this->loadRevisionData() ) {
return false;
}
- $this->mNewtext = $this->mNewRev->getText( Revision::FOR_THIS_USER );
+ $this->mNewContent = $this->mNewRev->getContent( Revision::FOR_THIS_USER, $this->getUser() );
return true;
}
}