wiki.techinc.nl/includes/diff/SlotDiffRenderer.php
Sam Wilson 1eb586013c diff: Add legend and tooltips to inline diff display
Add a legend at the top of the inline diff display, showing the
meanings of the colours of the inserted and deleted highlighting.
Also add the same text as tooltips on the highlighted elements.

The legend is added as part of a new area above the diff table
that can be modified via a new TextSlotDiffRendererTablePrefix
hook, so that extensions can add other buttons etc. there as
required.

This is a follow-up to the previous attempt, which added the
legend in DifferenceEngine::showDiff() and was called from
too many places. This patch moves it to be called in
DifferenceEngine::showDiffPage().

Bug: T324759
Change-Id: I2a3c67bcfa47313dee597e602a62073e4e298cd2
Follow-up: I6de30bf79eb5ac262285951792782b870d075e00
2023-05-31 15:43:28 +10:00

111 lines
3.8 KiB
PHP

<?php
/**
* Renders a diff for a single slot.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* @file
* @ingroup DifferenceEngine
*/
use Wikimedia\Assert\Assert;
/**
* Renders a diff for a single slot (that is, a diff between two content objects).
*
* Callers should obtain instances of this class by invoking ContentHandler::getSlotDiffRenderer
* on the content handler of the new content object (ie. the one shown on the right side
* of the diff), or of the old one if the new one does not exist.
*
* The default implementation just does a text diff on the native text representation.
* Content handler extensions can subclass this to provide a more appropriate diff method by
* overriding ContentHandler::getSlotDiffRendererInternal. Other extensions that want to interfere
* with diff generation in some way can use the GetSlotDiffRenderer hook.
*
* @stable to extend
* @ingroup DifferenceEngine
*/
abstract class SlotDiffRenderer {
/**
* Get a diff between two content objects. One of them might be null (meaning a slot was
* created or removed), but both cannot be. $newContent (or if it's null then $oldContent)
* must have the same content model that was used to obtain this diff renderer.
* @param Content|null $oldContent
* @param Content|null $newContent
* @return string HTML, one or more <tr> tags.
*/
abstract public function getDiff( Content $oldContent = null, Content $newContent = null );
/**
* Get the content to add above the main diff table.
*
* @param IContextSource $context
* @return string The full HTML for the prefix area, with its contents.
*/
public function getTablePrefix( IContextSource $context ): string {
return '';
}
/**
* Add modules needed for correct styling/behavior of the diff.
* @stable to override
* @param OutputPage $output
*/
public function addModules( OutputPage $output ) {
}
/**
* Return any extra keys to split the diff cache by.
* @stable to override
* @return string[]
*/
public function getExtraCacheKeys() {
return [];
}
/**
* Helper method to normalize the input of getDiff().
* Verifies that at least one of $oldContent and $newContent is not null, verifies that
* they are instances of one of the allowed classes (if provided), and replaces null with
* empty content.
* @param Content|null &$oldContent
* @param Content|null &$newContent
* @param string|array|null $allowedClasses
*/
protected function normalizeContents(
Content &$oldContent = null, Content &$newContent = null, $allowedClasses = null
) {
if ( !$oldContent && !$newContent ) {
throw new InvalidArgumentException( '$oldContent and $newContent cannot both be null' );
}
if ( $allowedClasses ) {
if ( !is_array( $allowedClasses ) ) {
$allowedClasses = explode( '|', $allowedClasses );
}
$allowedClasses[] = 'null';
Assert::parameterType( $allowedClasses, $oldContent, '$oldContent' );
Assert::parameterType( $allowedClasses, $newContent, '$newContent' );
}
if ( !$oldContent ) {
$oldContent = $newContent->getContentHandler()->makeEmptyContent();
} elseif ( !$newContent ) {
$newContent = $oldContent->getContentHandler()->makeEmptyContent();
}
}
}