On Tim's request, this change moved getParserOutput() and getSecondaryDataUpdates()
from the ContentHandler to the Content interface.
Change-Id: Ia654aa8710a242ba5fe7a4eb528e6a6449035f59
*/
public function isCountable( $hasLinks = null ) ;
+
/**
- * Convenience method, shorthand for
- * $this->getContentHandler()->getParserOutput( $this, $title, $revId, $options, $generateHtml )
- *
- * @note: subclasses should NOT override this to provide custom rendering.
- * Override ContentHandler::getParserOutput() instead!
+ * Parse the Content object and generate a ParserOutput from the result.
+ * $result->getText() can be used to obtain the generated HTML. If no HTML
+ * is needed, $generateHtml can be set to false; in that case,
+ * $result->getText() may return null.
*
- * @param $title Title
- * @param $revId null
- * @param $options null|ParserOptions
- * @param $generateHtml Boolean Whether to generate HTML (default: true).
- * If false, the result of calling getText() on the ParserOutput object
- * returned by this method is undefined.
+ * @param $title Title The page title to use as a context for rendering
+ * @param $revId null|int The revision being rendered (optional)
+ * @param $options null|ParserOptions Any parser options
+ * @param $generateHtml Boolean Whether to generate HTML (default: true). If false,
+ * the result of calling getText() on the ParserOutput object returned by
+ * this method is undefined.
*
* @since WD.1
*
* @return ParserOutput
*/
- public function getParserOutput( Title $title, $revId = null, ParserOptions $options = null,
- $generateHtml = true );
+ public function getParserOutput( Title $title,
+ $revId = null,
+ ParserOptions $options = null, $generateHtml = true );
+ # TODO: make RenderOutput and RenderOptions base classes
+
+ /**
+ * Returns a list of DataUpdate objects for recording information about this
+ * Content in some secondary data store. If the optional second argument,
+ * $old, is given, the updates may model only the changes that need to be
+ * made to replace information about the old content with information about
+ * the new content.
+ *
+ * This default implementation calls
+ * $this->getParserOutput( $content, $title, null, null, false ),
+ * and then calls getSecondaryDataUpdates( $title, $recursive ) on the
+ * resulting ParserOutput object.
+ *
+ * Subclasses may implement this to determine the necessary updates more
+ * efficiently, or make use of information about the old content.
+ *
+ * @param $title Title The context for determining the necessary updates
+ * @param $old Content|null An optional Content object representing the
+ * previous content, i.e. the content being replaced by this Content
+ * object.
+ * @param $recursive boolean Whether to include recursive updates (default:
+ * false).
+ * @param $parserOutput ParserOutput|null Optional ParserOutput object.
+ * Provide if you have one handy, to avoid re-parsing of the content.
+ *
+ * @return Array. A list of DataUpdate objects for putting information
+ * about this content object somewhere.
+ *
+ * @since WD.1
+ */
+ public function getSecondaryDataUpdates( Title $title,
+ Content $old = null,
+ $recursive = true, ParserOutput $parserOutput = null
+ );
/**
* Construct the redirect destination from this content and return an
return $this->getNativeData() === $that->getNativeData();
}
+
/**
- * @see Content::getParserOutput()
+ * Returns a list of DataUpdate objects for recording information about this
+ * Content in some secondary data store.
+ *
+ * This default implementation calls
+ * $this->getParserOutput( $content, $title, null, null, false ),
+ * and then calls getSecondaryDataUpdates( $title, $recursive ) on the
+ * resulting ParserOutput object.
+ *
+ * Subclasses may override this to determine the secondary data updates more
+ * efficiently, preferrably without the need to generate a parser output object.
+ *
+ * @see Content::getSecondaryDataUpdates()
+ *
+ * @param $title Title The context for determining the necessary updates
+ * @param $old Content|null An optional Content object representing the
+ * previous content, i.e. the content being replaced by this Content
+ * object.
+ * @param $recursive boolean Whether to include recursive updates (default:
+ * false).
+ * @param $parserOutput ParserOutput|null Optional ParserOutput object.
+ * Provide if you have one handy, to avoid re-parsing of the content.
+ *
+ * @return Array. A list of DataUpdate objects for putting information
+ * about this content object somewhere.
+ *
+ * @since WD.1
*/
- public function getParserOutput( Title $title, $revId = null, ParserOptions $options = null,
- $generateHtml = true )
- {
- return $this->getContentHandler()->getParserOutput(
- $this, $title, $revId, $options, $generateHtml );
+ public function getSecondaryDataUpdates( Title $title,
+ Content $old = null,
+ $recursive = true, ParserOutput $parserOutput = null
+ ) {
+ if ( !$parserOutput ) {
+ $parserOutput = $this->getParserOutput( $title, null, null, false );
+ }
+
+ return $parserOutput->getSecondaryDataUpdates( $title, $recursive );
}
+
/**
* @see Content::getRedirectChain()
*/
return $diff;
}
+
+ /**
+ * Returns a generic ParserOutput object, wrapping the HTML returned by
+ * getHtml().
+ *
+ * @param $title Title Context title for parsing
+ * @param $revId int|null Revision ID (for {{REVISIONID}})
+ * @param $options ParserOptions|null Parser options
+ * @param $generateHtml bool Whether or not to generate HTML
+ *
+ * @return ParserOutput representing the HTML form of the text
+ */
+ public function getParserOutput( Title $title,
+ $revId = null,
+ ParserOptions $options = null, $generateHtml = true
+ ) {
+ # Generic implementation, relying on $this->getHtml()
+
+ if ( $generateHtml ) {
+ $html = $this->getHtml();
+ } else {
+ $html = '';
+ }
+
+ $po = new ParserOutput( $html );
+ return $po;
+ }
+
+ /**
+ * Generates an HTML version of the content, for display. Used by
+ * getParserOutput() to construct a ParserOutput object.
+ *
+ * This default implementation just calls getHighlightHtml(). Content
+ * models that have another mapping to HTML (as is the case for markup
+ * languages like wikitext) should override this method to generate the
+ * appropriate HTML.
+ *
+ * @return string An HTML representation of the content
+ */
+ protected function getHtml() {
+ return $this->getHighlightHtml();
+ }
+
+ /**
+ * Generates a syntax-highlighted version of the content, as HTML.
+ * Used by the default implementation of getHtml().
+ *
+ * @return string an HTML representation of the content's markup
+ */
+ protected function getHighlightHtml( ) {
+ # TODO: make Highlighter interface, use highlighter here, if available
+ return htmlspecialchars( $this->getNativeData() );
+ }
+
}
/**
return $truncatedtext;
}
+
+ /**
+ * Returns a ParserOutput object resulting from parsing the content's text
+ * using $wgParser.
+ *
+ * @since WD.1
+ *
+ * @param $content Content the content to render
+ * @param $title \Title
+ * @param $revId null
+ * @param $options null|ParserOptions
+ * @param $generateHtml bool
+ *
+ * @internal param \IContextSource|null $context
+ * @return ParserOutput representing the HTML form of the text
+ */
+ public function getParserOutput( Title $title,
+ $revId = null,
+ ParserOptions $options = null, $generateHtml = true
+ ) {
+ global $wgParser;
+
+ if ( !$options ) {
+ $options = new ParserOptions();
+ }
+
+ $po = $wgParser->parse( $this->getNativeData(), $title, $options, true, true, $revId );
+ return $po;
+ }
+
+ protected function getHtml() {
+ throw new MWException(
+ "getHtml() not implemented for wikitext. "
+ . "Use getParserOutput()->getText()."
+ );
+ }
+
+
}
/**
return new JavaScriptContent( $pst );
}
+
+ protected function getHtml( ) {
+ $html = "";
+ $html .= "<pre class=\"mw-code mw-js\" dir=\"ltr\">\n";
+ $html .= $this->getHighlightHtml( );
+ $html .= "\n</pre>\n";
+
+ return $html;
+ }
}
/**
return new CssContent( $pst );
}
+
+ protected function getHtml( ) {
+ $html = "";
+ $html .= "<pre class=\"mw-code mw-css\" dir=\"ltr\">\n";
+ $html .= $this->getHighlightHtml( );
+ $html .= "\n</pre>\n";
+
+ return $html;
+ }
}
return $reason;
}
- /**
- * Parse the Content object and generate a ParserOutput from the result.
- * $result->getText() can be used to obtain the generated HTML. If no HTML
- * is needed, $generateHtml can be set to false; in that case,
- * $result->getText() may return null.
- *
- * @param $content Content the content to render
- * @param $title Title The page title to use as a context for rendering
- * @param $revId null|int The revision being rendered (optional)
- * @param $options null|ParserOptions Any parser options
- * @param $generateHtml Boolean Whether to generate HTML (default: true). If false,
- * the result of calling getText() on the ParserOutput object returned by
- * this method is undefined.
- *
- * @since WD.1
- *
- * @return ParserOutput
- */
- public abstract function getParserOutput( Content $content, Title $title,
- $revId = null,
- ParserOptions $options = null, $generateHtml = true );
- # TODO: make RenderOutput and RenderOptions base classes
-
- /**
- * Returns a list of DataUpdate objects for recording information about this
- * Content in some secondary data store. If the optional second argument,
- * $old, is given, the updates may model only the changes that need to be
- * made to replace information about the old content with information about
- * the new content.
- *
- * This default implementation calls
- * $this->getParserOutput( $content, $title, null, null, false ),
- * and then calls getSecondaryDataUpdates( $title, $recursive ) on the
- * resulting ParserOutput object.
- *
- * Subclasses may implement this to determine the necessary updates more
- * efficiently, or make use of information about the old content.
- *
- * @param $content Content The content for determining the necessary updates
- * @param $title Title The context for determining the necessary updates
- * @param $old Content|null An optional Content object representing the
- * previous content, i.e. the content being replaced by this Content
- * object.
- * @param $recursive boolean Whether to include recursive updates (default:
- * false).
- * @param $parserOutput ParserOutput|null Optional ParserOutput object.
- * Provide if you have one handy, to avoid re-parsing of the content.
- *
- * @return Array. A list of DataUpdate objects for putting information
- * about this content object somewhere.
- *
- * @since WD.1
- */
- public function getSecondaryDataUpdates( Content $content, Title $title,
- Content $old = null,
- $recursive = true, ParserOutput $parserOutput = null
- ) {
- if ( !$parserOutput ) {
- $parserOutput = $this->getParserOutput( $content, $title, null, null, false );
- }
-
- return $parserOutput->getSecondaryDataUpdates( $title, $recursive );
- }
-
-
/**
* Get the Content object that needs to be saved in order to undo all revisions
* between $undo and $undoafter. Revisions must belong to the same page,
return $mergedContent;
}
- /**
- * Returns a generic ParserOutput object, wrapping the HTML returned by
- * getHtml().
- *
- * @param $content Content The content to render
- * @param $title Title Context title for parsing
- * @param $revId int|null Revision ID (for {{REVISIONID}})
- * @param $options ParserOptions|null Parser options
- * @param $generateHtml bool Whether or not to generate HTML
- *
- * @return ParserOutput representing the HTML form of the text
- */
- public function getParserOutput( Content $content, Title $title,
- $revId = null,
- ParserOptions $options = null, $generateHtml = true
- ) {
- $this->checkModelID( $content->getModel() );
-
- # Generic implementation, relying on $this->getHtml()
-
- if ( $generateHtml ) {
- $html = $this->getHtml( $content );
- } else {
- $html = '';
- }
-
- $po = new ParserOutput( $html );
- return $po;
- }
-
- /**
- * Generates an HTML version of the content, for display. Used by
- * getParserOutput() to construct a ParserOutput object.
- *
- * This default implementation just calls getHighlightHtml(). Content
- * models that have another mapping to HTML (as is the case for markup
- * languages like wikitext) should override this method to generate the
- * appropriate HTML.
- *
- * @param $content Content The content to render
- *
- * @return string An HTML representation of the content
- */
- protected function getHtml( Content $content ) {
- $this->checkModelID( $content->getModel() );
-
- return $this->getHighlightHtml( $content );
- }
-
- /**
- * Generates a syntax-highlighted version the content, as HTML.
- * Used by the default implementation of getHtml().
- *
- * @param $content Content the content to render
- *
- * @return string an HTML representation of the content's markup
- */
- protected function getHighlightHtml( Content $content ) {
- $this->checkModelID( $content->getModel() );
-
- # TODO: make Highlighter interface, use highlighter here, if available
- return htmlspecialchars( $content->getNativeData() );
- }
-
-
}
/**
return new WikitextContent( '' );
}
- /**
- * Returns a ParserOutput object resulting from parsing the content's text
- * using $wgParser.
- *
- * @since WD.1
- *
- * @param $content Content the content to render
- * @param $title \Title
- * @param $revId null
- * @param $options null|ParserOptions
- * @param $generateHtml bool
- *
- * @internal param \IContextSource|null $context
- * @return ParserOutput representing the HTML form of the text
- */
- public function getParserOutput( Content $content, Title $title,
- $revId = null,
- ParserOptions $options = null, $generateHtml = true
- ) {
- global $wgParser;
-
- $this->checkModelID( $content->getModel() );
-
- if ( !$options ) {
- $options = new ParserOptions();
- }
-
- $po = $wgParser->parse( $content->getNativeData(), $title, $options, true, true, $revId );
- return $po;
- }
-
- protected function getHtml( Content $content ) {
- throw new MWException(
- "getHtml() not implemented for wikitext. "
- . "Use getParserOutput()->getText()."
- );
- }
-
/**
* Returns true because wikitext supports sections.
*
public function getPageLanguage( Title $title, Content $content = null ) {
return wfGetLangObj( 'en' );
}
-
- protected function getHtml( Content $content ) {
- $html = "";
- $html .= "<pre class=\"mw-code mw-js\" dir=\"ltr\">\n";
- $html .= $this->getHighlightHtml( $content );
- $html .= "\n</pre>\n";
-
- return $html;
- }
}
/**
public function getPageLanguage( Title $title, Content $content = null ) {
return wfGetLangObj( 'en' );
}
-
- protected function getHtml( Content $content ) {
- $html = "";
- $html .= "<pre class=\"mw-code mw-css\" dir=\"ltr\">\n";
- $html .= $this->getHighlightHtml( $content );
- $html .= "\n</pre>\n";
-
- return $html;
- }
}
}
# Update the links tables and other secondary data
- $contentHandler = $revision->getContentHandler();
- $updates = $contentHandler->getSecondaryDataUpdates( $content, $this->getTitle(), null, true, $editInfo->output );
+ $updates = $content->getSecondaryDataUpdates( $this->getTitle(), null, true, $editInfo->output );
DataUpdate::runUpdates( $updates );
wfRunHooks( 'ArticleEditUpdates', array( &$this, &$editInfo, $options['changed'] ) );
$p_result = $content->getParserOutput( $title, $page->getLatest(), $popts, $wgEnableParserCache );
# Update the links tables
- $updates = $content->getContentHandler()->getSecondaryDataUpdates( $content, $title, null, true, $p_result );
+ $updates = $content->getSecondaryDataUpdates( $title, null, true, $p_result );
DataUpdate::runUpdates( $updates );
$r['linkupdate'] = '';
wfProfileOut( __METHOD__.'-parse' );
wfProfileIn( __METHOD__.'-update' );
- $updates = $content->getContentHandler()->getSecondaryDataUpdates( $content, $this->title, null, false, $parserOutput );
+ $updates = $content->getSecondaryDataUpdates( $this->title, null, false, $parserOutput );
DataUpdate::runUpdates( $updates );
wfProfileOut( __METHOD__.'-update' );
wfProfileOut( __METHOD__.'-parse' );
wfProfileIn( __METHOD__.'-update' );
- $updates = $content->getContentHandler()->getSecondaryDataUpdates( $content, $title, null, false, $parserOutput );
+ $updates = $content->getSecondaryDataUpdates( $title, null, false, $parserOutput );
DataUpdate::runUpdates( $updates );
wfProfileOut( __METHOD__.'-update' );
$dbw = wfGetDB( DB_MASTER );
$dbw->begin( __METHOD__ );
- $contentHandler = $content->getContentHandler();
- $updates = $contentHandler->getSecondaryDataUpdates( $content, $page->getTitle() );
+ $updates = $content->getSecondaryDataUpdates( $page->getTitle() );
DataUpdate::runUpdates( $updates );
$dbw->commit( __METHOD__ );
}
- public function dataGetParserOutput() {
- return array(
- array("ContentHandlerTest_testGetParserOutput", "hello ''world''\n", "<p>hello <i>world</i>\n</p>"),
- // @todo: more...?
- );
- }
-
- /**
- * @dataProvider dataGetParserOutput
- */
- public function testGetParserOutput( $title, $text, $expectedHtml ) {
- $title = Title::newFromText( $title );
- $handler = ContentHandler::getForModelID( $title->getContentModel() );
- $content = ContentHandler::makeContent( $text, $title );
-
- $po = $handler->getParserOutput( $content, $title );
-
- $this->assertEquals( $expectedHtml, $po->getText() );
- // @todo: assert more properties
- }
-
- public function dataGetSecondaryDataUpdates() {
- return array(
- array("ContentHandlerTest_testGetSecondaryDataUpdates_1", "hello ''world''\n",
- array( 'LinksUpdate' => array( 'mRecursive' => true,
- 'mLinks' => array() ) )
- ),
- array("ContentHandlerTest_testGetSecondaryDataUpdates_2", "hello [[world test 21344]]\n",
- array( 'LinksUpdate' => array( 'mRecursive' => true,
- 'mLinks' => array( array( 'World_test_21344' => 0 ) ) ) )
- ),
- // @todo: more...?
- );
- }
-
- /**
- * @dataProvider dataGetSecondaryDataUpdates
- */
- public function testGetSecondaryDataUpdates( $title, $text, $expectedStuff ) {
- $title = Title::newFromText( $title );
- $title->resetArticleID( 2342 ); //dummy id. fine as long as we don't try to execute the updates!
-
- $handler = ContentHandler::getForModelID( $title->getContentModel() );
- $content = ContentHandler::makeContent( $text, $title );
-
- $updates = $handler->getSecondaryDataUpdates( $content, $title );
-
- // make updates accessible by class name
- foreach ( $updates as $update ) {
- $class = get_class( $update );
- $updates[ $class ] = $update;
- }
-
- foreach ( $expectedStuff as $class => $fieldValues ) {
- $this->assertArrayHasKey( $class, $updates, "missing an update of type $class" );
-
- $update = $updates[ $class ];
-
- foreach ( $fieldValues as $field => $value ) {
- $v = $update->$field; #if the field doesn't exist, just crash and burn
- $this->assertEquals( $value, $v, "unexpected value for field $field in instance of $class" );
- }
- }
- }
-
public function testSupportsSections() {
$this->markTestIncomplete( "not yet implemented" );
}
{
return new DummyContentForTesting( '' );
}
-
- /**
- * @param Content $content
- * @param Title $title
- * @param null $revId
- * @param null|ParserOptions $options
- * @param Boolean $generateHtml whether to generate Html (default: true). If false,
- * the result of calling getText() on the ParserOutput object returned by
- * this method is undefined.
- *
- * @return ParserOutput
- */
- public function getParserOutput( Content $content, Title $title, $revId = null, ParserOptions $options = NULL, $generateHtml = true )
- {
- return new ParserOutput( $content->getNativeData() );
- }
}
class DummyContentForTesting extends AbstractContent {
{
return false;
}
+
+ /**
+ * @param Title $title
+ * @param null $revId
+ * @param null|ParserOptions $options
+ * @param Boolean $generateHtml whether to generate Html (default: true). If false,
+ * the result of calling getText() on the ParserOutput object returned by
+ * this method is undefined.
+ *
+ * @return ParserOutput
+ */
+ public function getParserOutput( Title $title, $revId = null, ParserOptions $options = NULL, $generateHtml = true )
+ {
+ return new ParserOutput( $this->getNativeData() );
+ }
}
public function dataGetParserOutput() {
return array(
- array("hello <world>\n", "<pre class=\"mw-code mw-css\" dir=\"ltr\">\nhello <world>\n\n</pre>\n"),
+ array("MediaWiki:Test.css", "hello <world>\n", "<pre class=\"mw-code mw-css\" dir=\"ltr\">\nhello <world>\n\n</pre>\n"),
// @todo: more...?
);
}
public function dataGetParserOutput() {
return array(
- array("hello <world>\n", "<pre class=\"mw-code mw-js\" dir=\"ltr\">\nhello <world>\n\n</pre>\n"),
+ array("MediaWiki:Test.js", "hello <world>\n", "<pre class=\"mw-code mw-js\" dir=\"ltr\">\nhello <world>\n\n</pre>\n"),
// @todo: more...?
);
}
return new WikitextContent( $text );
}
+
public function dataGetParserOutput() {
return array(
- array("hello ''world''\n", "<p>hello <i>world</i>\n</p>"),
+ array("WikitextContentTest_testGetParserOutput", "hello ''world''\n", "<p>hello <i>world</i>\n</p>"),
// @todo: more...?
);
}
/**
* @dataProvider dataGetParserOutput
*/
- public function testGetParserOutput( $text, $expectedHtml ) {
- $content = $this->newContent( $text );
+ public function testGetParserOutput( $title, $text, $expectedHtml ) {
+ $title = Title::newFromText( $title );
+ $content = ContentHandler::makeContent( $text, $title );
- $po = $content->getParserOutput( $this->context->getTitle() );
+ $po = $content->getParserOutput( $title );
$this->assertEquals( $expectedHtml, $po->getText() );
- return $po;
+ // @todo: assert more properties
}
+ public function dataGetSecondaryDataUpdates() {
+ return array(
+ array("WikitextContentTest_testGetSecondaryDataUpdates_1", "hello ''world''\n",
+ array( 'LinksUpdate' => array( 'mRecursive' => true,
+ 'mLinks' => array() ) )
+ ),
+ array("WikitextContentTest_testGetSecondaryDataUpdates_2", "hello [[world test 21344]]\n",
+ array( 'LinksUpdate' => array( 'mRecursive' => true,
+ 'mLinks' => array( array( 'World_test_21344' => 0 ) ) ) )
+ ),
+ // @todo: more...?
+ );
+ }
+
+ /**
+ * @dataProvider dataGetSecondaryDataUpdates
+ */
+ public function testGetSecondaryDataUpdates( $title, $text, $expectedStuff ) {
+ $title = Title::newFromText( $title );
+ $title->resetArticleID( 2342 ); //dummy id. fine as long as we don't try to execute the updates!
+
+ $handler = ContentHandler::getForModelID( $title->getContentModel() );
+ $content = ContentHandler::makeContent( $text, $title );
+
+ $updates = $content->getSecondaryDataUpdates( $title );
+
+ // make updates accessible by class name
+ foreach ( $updates as $update ) {
+ $class = get_class( $update );
+ $updates[ $class ] = $update;
+ }
+
+ foreach ( $expectedStuff as $class => $fieldValues ) {
+ $this->assertArrayHasKey( $class, $updates, "missing an update of type $class" );
+
+ $update = $updates[ $class ];
+
+ foreach ( $fieldValues as $field => $value ) {
+ $v = $update->$field; #if the field doesn't exist, just crash and burn
+ $this->assertEquals( $value, $v, "unexpected value for field $field in instance of $class" );
+ }
+ }
+ }
+
+
static $sections =
"Intro