40 private const SIDE_DELETED =
'deleted';
41 private const SIDE_ADDED =
'added';
42 private const SIDE_CLASSES = [
43 self::SIDE_DELETED =>
'diff-side-deleted',
44 self::SIDE_ADDED =>
'diff-side-added'
48 $this->leadingContextLines = 2;
49 $this->trailingContextLines = 2;
58 $msg = preg_replace(
'/^ /m',
"\u{00A0} ", $msg );
59 $msg = preg_replace(
'/ $/m',
" \u{00A0}", $msg );
60 $msg = preg_replace(
'/ /',
"\u{00A0} ", $msg );
73 protected function blockHeader( $xbeg, $xlen, $ybeg, $ylen ) {
76 return Html::rawElement(
81 [
'colspan' =>
'2',
'class' =>
'diff-lineno',
'id' =>
'mw-diff-left-l' . $xbeg ],
82 '<!--LINE ' . $xbeg .
'-->'
87 [
'colspan' =>
'2',
'class' =>
'diff-lineno' ],
88 '<!--LINE ' . $ybeg .
'-->'
107 protected function lines(
$lines, $prefix =
' ', $color =
'white' ) {
118 return $this->
wrapLine(
'+', [
'diff-addedline', $this->getClassForSide( self::SIDE_ADDED ) ], $line );
129 return $this->
wrapLine(
'−', [
'diff-deletedline', $this->getClassForSide( self::SIDE_DELETED ) ], $line );
141 return $this->
wrapLine(
'', [
'diff-context', $this->getClassForSide( $side ) ], $line );
151 protected function wrapLine( $marker, $class, $line ) {
152 if ( $line !==
'' ) {
156 $line = Html::element(
'br' );
159 $markerAttrs = [
'class' =>
'diff-marker' ];
161 $markerAttrs[
'data-marker'] = $marker;
164 return Html::element(
'td', $markerAttrs ) .
165 Html::rawElement(
'td', [
'class' => $class ], $line );
173 return Html::element(
'td', [
'colspan' =>
'2',
'class' => $this->getClassForSide( $side ) ] );
182 foreach (
$lines as $line ) {
191 [
'class' =>
'diffchange' ],
207 foreach (
$lines as $line ) {
215 [
'class' =>
'diffchange' ],
232 foreach (
$lines as $line ) {
237 $this->
contextLine( htmlspecialchars( $line ), self::SIDE_DELETED ) .
238 $this->
contextLine( htmlspecialchars( $line ), self::SIDE_ADDED )
251 protected function changed( $orig, $closing ) {
253 $del = $diff->orig();
254 $add = $diff->closing();
256 # Notice that WordLevelDiff returns HTML-escaped output.
257 # Hence, we will be calling addedLine/deletedLine without HTML-escaping.
259 $ndel = count( $del );
260 $nadd = count( $add );
261 $n = max( $ndel, $nadd );
262 for ( $i = 0; $i < $n; $i++ ) {
263 $delLine = $i < $ndel ? $this->
deletedLine( $del[$i] ) : $this->
emptyLine( self::SIDE_DELETED );
264 $addLine = $i < $nadd ? $this->
addedLine( $add[$i] ) : $this->
emptyLine( self::SIDE_ADDED );
283 private function getClassForSide(
string $side ): string {
284 if ( !isset( self::SIDE_CLASSES[$side] ) ) {
285 throw new InvalidArgumentException(
"Invalid diff side: $side" );
287 return self::SIDE_CLASSES[$side];
if(!defined('MW_SETUP_CALLBACK'))
Performs a word-level diff on several lines.
if(!file_exists( $CREDITS)) $lines