* Follow the TODO comment in TextSlotDiffRenderer ::getTextDiffInternal() by moving the code out to three parallel implementations, namely ExternalTextDiffer, PhpTextDiffer and Wikidiff2TextDiffer. * Add a container/factory class ManifoldTextDiffer to glue them together and collate available formats. * Move the inline legend to Wikidiff2TextDiffer. Not the toggle since the ability to toggle depends on the available format, not the current format. * Update the diff cache keys so that ManifoldTextDiffer can store the engine=>format map it used to generate the diff. * Drop support for the second parameter to TextSlotDiffRenderer ::setEngine(), since nothing used it anymore. * Provide a format batch API, since some engines are able to efficiently generate multiple formats. This might be used by DifferenceEngine in future. Needs risky change notification for the cache key change. Bug: T339184 Depends-On: I8a35b9b8ec1622c9a36d2496bdd24f51bc52c85f Change-Id: I5c506e39162855aff53dd420dd8145156739059c
127 lines
3.2 KiB
PHP
127 lines
3.2 KiB
PHP
<?php
|
|
|
|
namespace MediaWiki\Diff\TextDiffer;
|
|
|
|
use MessageLocalizer;
|
|
use OutputPage;
|
|
|
|
/**
|
|
* The base class for specific implementations of TextDiffer, apart from
|
|
* ManifoldTextDiffer.
|
|
*
|
|
* A place for protected utility functions.
|
|
*
|
|
* @since 1.41
|
|
*/
|
|
abstract class BaseTextDiffer implements TextDiffer {
|
|
/** @var MessageLocalizer */
|
|
private $localizer;
|
|
|
|
/**
|
|
* @param MessageLocalizer $localizer
|
|
*/
|
|
public function setLocalizer(
|
|
MessageLocalizer $localizer
|
|
) {
|
|
$this->localizer = $localizer;
|
|
}
|
|
|
|
/**
|
|
* Provide a MessageLocalizer, or throw if setLocalizer() has not been called.
|
|
*
|
|
* @return MessageLocalizer
|
|
*/
|
|
protected function getLocalizer(): MessageLocalizer {
|
|
return $this->localizer;
|
|
}
|
|
|
|
public function hasFormat( string $format ): bool {
|
|
return in_array( $format, $this->getFormats(), true );
|
|
}
|
|
|
|
public function addRowWrapper( string $format, string $diffText ): string {
|
|
if ( $this->getFormatContext( $format ) === self::CONTEXT_PLAIN ) {
|
|
return "<tr><td colspan=\"4\">$diffText</td></tr>";
|
|
} else {
|
|
return $diffText;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Throw an exception if any of the formats in the array is not supported.
|
|
*
|
|
* @param string[] $formats
|
|
*/
|
|
protected function validateFormats( $formats ) {
|
|
$badFormats = array_diff( $formats, $this->getFormats() );
|
|
if ( $badFormats ) {
|
|
throw new \InvalidArgumentException( 'The requested format is not supported by this engine' );
|
|
}
|
|
}
|
|
|
|
public function render( string $oldText, string $newText, string $format ): string {
|
|
$result = $this->renderBatch( $oldText, $newText, [ $format ] );
|
|
return reset( $result );
|
|
}
|
|
|
|
public function renderBatch( string $oldText, string $newText, array $formats ): array {
|
|
$this->validateFormats( $formats );
|
|
if ( !count( $formats ) ) {
|
|
return [];
|
|
}
|
|
return $this->doRenderBatch( $oldText, $newText, $formats );
|
|
}
|
|
|
|
/**
|
|
* Subclasses should override this to render diffs in the specified formats.
|
|
* The $formats array is guaranteed to not be empty and to contain only
|
|
* formats supported by the subclass.
|
|
*
|
|
* @param string $oldText
|
|
* @param string $newText
|
|
* @param array $formats
|
|
* @return array
|
|
*/
|
|
abstract protected function doRenderBatch( string $oldText, string $newText, array $formats ): array;
|
|
|
|
public function addModules( OutputPage $out, string $format ): void {
|
|
}
|
|
|
|
public function getCacheKeys( array $formats ): array {
|
|
return [];
|
|
}
|
|
|
|
public function localize( string $format, string $diff, array $options = [] ): string {
|
|
return $diff;
|
|
}
|
|
|
|
public function getTablePrefixes( string $format ): array {
|
|
return [];
|
|
}
|
|
|
|
public function getPreferredFormatBatch( string $format ): array {
|
|
return [ $format ];
|
|
}
|
|
|
|
/**
|
|
* Replace a common convention for language-independent line numbers with
|
|
* the text in the language of the current localizer.
|
|
*
|
|
* @param string $text
|
|
* @param bool $reducedLineNumbers
|
|
*
|
|
* @return string
|
|
*/
|
|
protected function localizeLineNumbers(
|
|
$text, $reducedLineNumbers
|
|
) {
|
|
return preg_replace_callback( '/<!--LINE (\d+)-->/',
|
|
function ( array $matches ) use ( $reducedLineNumbers ) {
|
|
if ( $matches[1] === '1' && $reducedLineNumbers ) {
|
|
return '';
|
|
}
|
|
return $this->getLocalizer()->msg( 'lineno' )->numParams( $matches[1] )->escaped();
|
|
}, $text );
|
|
}
|
|
|
|
}
|