1<?php 2/** 3 * Copyright © 2000, 2001 Geoffrey T. Dairiki <dairiki@dairiki.org> 4 * You may copy this code freely under the conditions of the GPL. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License along 17 * with this program; if not, write to the Free Software Foundation, Inc., 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 * http://www.gnu.org/copyleft/gpl.html 20 * 21 * @file 22 * @ingroup DifferenceEngine 23 * @defgroup DifferenceEngine DifferenceEngine 24 */ 25 26namespace MediaWiki\Diff; 27 28/** 29 * Stores, escapes and formats the results of word-level diff 30 * 31 * @internal 32 * @ingroup DifferenceEngine 33 */ 34class WordAccumulator { 35 public $insClass = ' class="diffchange diffchange-inline"'; 36 public $delClass = ' class="diffchange diffchange-inline"'; 37 38 private $lines = []; 39 private $line = ''; 40 private $group = ''; 41 private $tag = ''; 42 43 /** 44 * @param string $new_tag 45 */ 46 private function flushGroup( $new_tag ) { 47 if ( $this->group !== '' ) { 48 if ( $this->tag == 'ins' ) { 49 $this->line .= "<ins{$this->insClass}>" . htmlspecialchars( $this->group ) . '</ins>'; 50 } elseif ( $this->tag == 'del' ) { 51 $this->line .= "<del{$this->delClass}>" . htmlspecialchars( $this->group ) . '</del>'; 52 } else { 53 $this->line .= htmlspecialchars( $this->group ); 54 } 55 } 56 $this->group = ''; 57 $this->tag = $new_tag; 58 } 59 60 /** 61 * @param string $new_tag 62 */ 63 private function flushLine( $new_tag ) { 64 $this->flushGroup( $new_tag ); 65 if ( $this->line != '' ) { 66 array_push( $this->lines, $this->line ); 67 } else { 68 # make empty lines visible by inserting an NBSP 69 array_push( $this->lines, "\u{00A0}" ); 70 } 71 $this->line = ''; 72 } 73 74 /** 75 * @param string[] $words 76 * @param string $tag 77 */ 78 public function addWords( $words, $tag = '' ) { 79 if ( $tag != $this->tag ) { 80 $this->flushGroup( $tag ); 81 } 82 83 foreach ( $words as $word ) { 84 // new-line should only come as first char of word. 85 if ( $word == '' ) { 86 continue; 87 } 88 if ( $word[0] == "\n" ) { 89 $this->flushLine( $tag ); 90 $word = substr( $word, 1 ); 91 } 92 // FIXME: Don't use assert() 93 // phpcs:ignore MediaWiki.Usage.ForbiddenFunctions.assert 94 assert( !strstr( $word, "\n" ) ); 95 $this->group .= $word; 96 } 97 } 98 99 /** 100 * @return string[] 101 */ 102 public function getLines() { 103 $this->flushLine( '~done' ); 104 105 return $this->lines; 106 } 107} 108