return $this->options;
}
+ /**
+ * Sets a ParserOutput to be returned by getRevisionParserOutput().
+ *
+ * @note For internal use by RevisionRenderer only! This method may be modified
+ * or removed without notice per the deprecation policy.
+ *
+ * @internal
+ *
+ * @param ParserOutput $output
+ */
+ public function setRevisionParserOutput( ParserOutput $output ) {
+ $this->revisionOutput = $output;
+
+ // If there is only one slot, we assume that the combined output is identical
+ // with the main slot's output. This is intended to prevent a redundant re-parse of
+ // the content in case getSlotParserOutput( SlotRecord::MAIN ) is called, for instance
+ // from ContentHandler::getSecondaryDataUpdates.
+ if ( $this->revision->getSlotRoles() === [ SlotRecord::MAIN ] ) {
+ $this->slotsOutput[ SlotRecord::MAIN ] = $output;
+ }
+ }
+
/**
* @param array $hints Hints given as an associative array. Known keys:
* - 'generate-html' => bool: Whether the caller is interested in output HTML (as opposed
* - 'audience' the audience to use for content access. Default is
* RevisionRecord::FOR_PUBLIC if $forUser is not set, RevisionRecord::FOR_THIS_USER
* if $forUser is set. Can be set to RevisionRecord::RAW to disable audience checks.
+ * - 'known-revision-output' a combined ParserOutput for the revision, perhaps from
+ * some cache. the caller is responsible for ensuring that the ParserOutput indeed
+ * matched the $rev and $options. This mechanism is intended as a temporary stop-gap,
+ * for the time until caches have been changed to store RenderedRevision states instead
+ * of ParserOutput objects.
*
* @return RenderedRevision|null The rendered revision, or null if the audience checks fails.
*/
$renderedRevision->setSaveParseLogger( $this->saveParseLogger );
+ if ( isset( $hints['known-revision-output'] ) ) {
+ $renderedRevision->setRevisionParserOutput( $hints['known-revision-output'] );
+ }
+
return $renderedRevision;
}
$stashedEdit = ApiStashEdit::checkCache( $title, $mainContent, $legacyUser );
}
- if ( $stashedEdit ) {
- /** @var ParserOutput $output */
- $output = $stashedEdit->output;
-
- // TODO: this should happen when stashing the ParserOutput, not now!
- $output->setCacheTime( $stashedEdit->timestamp );
-
- // TODO: MCR: allow output for all slots to be stashed.
- $this->canonicalParserOutput = $output;
- }
-
$userPopts = ParserOptions::newFromUserAndLang( $user, $this->contLang );
Hooks::run( 'ArticlePrepareTextForEdit', [ $wikiPage, $userPopts ] );
} else {
$this->parentRevision = $parentRevision;
}
+
+ $renderHints = [ 'use-master' => $this->useMaster(), 'audience' => RevisionRecord::RAW ];
+
+ if ( $stashedEdit ) {
+ /** @var ParserOutput $output */
+ $output = $stashedEdit->output;
+
+ // TODO: this should happen when stashing the ParserOutput, not now!
+ $output->setCacheTime( $stashedEdit->timestamp );
+
+ $renderHints['known-revision-output'] = $output;
+ }
+
+ // NOTE: we want a canonical rendering, so don't pass $this->user or ParserOptions
+ // NOTE: the revision is either new or current, so we can bypass audience checks.
+ $this->renderedRevision = $this->revisionRenderer->getRenderedRevision(
+ $this->revision,
+ null,
+ null,
+ $renderHints
+ );
}
/**
* @return RenderedRevision
*/
public function getRenderedRevision() {
- if ( !$this->renderedRevision ) {
- $this->assertPrepared( __METHOD__ );
-
- // NOTE: we want a canonical rendering, so don't pass $this->user or ParserOptions
- // NOTE: the revision is either new or current, so we can bypass audience checks.
- $this->renderedRevision = $this->revisionRenderer->getRenderedRevision(
- $this->revision,
- null,
- null,
- [ 'use-master' => $this->useMaster(), 'audience' => RevisionRecord::RAW ]
- );
- }
+ $this->assertPrepared( __METHOD__ );
return $this->renderedRevision;
}
// Prune any output that depends on the revision ID.
if ( $this->renderedRevision ) {
$this->renderedRevision->updateRevision( $revision );
+ } else {
+
+ // NOTE: we want a canonical rendering, so don't pass $this->user or ParserOptions
+ // NOTE: the revision is either new or current, so we can bypass audience checks.
+ $this->renderedRevision = $this->revisionRenderer->getRenderedRevision(
+ $this->revision,
+ null,
+ null,
+ [ 'use-master' => $this->useMaster(), 'audience' => RevisionRecord::RAW ]
+ );
+
+ // XXX: Since we presumably are dealing with the current revision,
+ // we could try to get the ParserOutput from the parser cache.
}
// TODO: optionally get ParserOutput from the ParserCache here.
$this->assertContains( 'time:20180101000003!', $html );
}
+ public function testSetRevisionParserOutput() {
+ $title = $this->getMockTitle( 3, 21 );
+ $rev = $this->getMockRevision( RevisionStoreRecord::class, $title );
+
+ $options = ParserOptions::newCanonical( 'canonical' );
+ $rr = new RenderedRevision( $title, $rev, $options, $this->combinerCallback );
+
+ $output = new ParserOutput( 'Kittens' );
+ $rr->setRevisionParserOutput( $output );
+
+ $this->assertSame( $output, $rr->getRevisionParserOutput() );
+ $this->assertSame( 'Kittens', $rr->getRevisionParserOutput()->getText() );
+
+ $this->assertSame( $output, $rr->getSlotParserOutput( SlotRecord::MAIN ) );
+ $this->assertSame( 'Kittens', $rr->getSlotParserOutput( SlotRecord::MAIN )->getText() );
+ }
+
public function testNoHtml() {
/** @var MockObject|Content $mockContent */
$mockContent = $this->getMockBuilder( WikitextContent::class )
$this->assertSame( $html, $rr->getSlotParserOutput( SlotRecord::MAIN )->getText() );
}
+ public function testGetRenderedRevision_known() {
+ $renderer = $this->newRevisionRenderer( 100, true ); // use master
+ $title = $this->getMockTitle( 7, 21 );
+
+ $rev = new MutableRevisionRecord( $title );
+ $rev->setId( 21 ); // current!
+ $rev->setUser( new UserIdentityValue( 9, 'Frank', 0 ) );
+ $rev->setTimestamp( '20180101000003' );
+ $rev->setComment( CommentStoreComment::newUnsavedComment( '' ) );
+
+ $text = "uncached text";
+ $rev->setContent( SlotRecord::MAIN, new WikitextContent( $text ) );
+
+ $output = new ParserOutput( 'cached text' );
+
+ $options = ParserOptions::newCanonical( 'canonical' );
+ $rr = $renderer->getRenderedRevision(
+ $rev,
+ $options,
+ null,
+ [ 'known-revision-output' => $output ]
+ );
+
+ $this->assertSame( $output, $rr->getRevisionParserOutput() );
+ $this->assertSame( 'cached text', $rr->getRevisionParserOutput()->getText() );
+ $this->assertSame( 'cached text', $rr->getSlotParserOutput( SlotRecord::MAIN )->getText() );
+ }
+
public function testGetRenderedRevision_old() {
$renderer = $this->newRevisionRenderer( 100 );
$title = $this->getMockTitle( 7, 21 );