Add word diff to EditHistory
authorTim Düsterhus <duesterhus@woltlab.com>
Thu, 12 Feb 2015 21:22:00 +0000 (22:22 +0100)
committerTim Düsterhus <duesterhus@woltlab.com>
Sun, 18 Dec 2016 15:46:43 +0000 (16:46 +0100)
com.woltlab.wcf/templates/editHistory.tpl
wcfsetup/install/files/lib/page/EditHistoryPage.class.php
wcfsetup/install/files/lib/util/Diff.class.php

index bbd1b9aa45f73161211855222b84779bc6e40868..f5feb3ce8213ce71cb83f71e63a24cf91ed2c95b 100644 (file)
@@ -19,7 +19,7 @@
 
 <div><div>
 {assign var='prevType' value=''}
-{foreach from=$diff->getRawDiff() item='line'}
+{foreach from=$diff item='line'}
 {if $line[0] !== $prevType}
        </div>
        
@@ -44,9 +44,9 @@
        {/if}
        <div{if $line[0] === '+'} style="color: green;"{elseif $line[0] === '-'} style="color: red;"{/if}>
 {/if}
-{if $line[0] === ' '}{$line[1]}<br>{/if}
-{if $line[0] === '-'}{$line[1]}<br>{/if}
-{if $line[0] === '+'}{$line[1]}<br>{/if}
+{if $line[0] === ' '}{@$line[1]}<br>{/if}
+{if $line[0] === '-'}{@$line[1]}<br>{/if}
+{if $line[0] === '+'}{@$line[1]}<br>{/if}
 {assign var='prevType' value=$line[0]}
 {/foreach}
 </div></div>
index 393b0593775c7d14c81fae10d49024fa2fcc2de9..3c856aaccf36d6249bfc94f1d6f096eb51e04516 100644 (file)
@@ -161,7 +161,44 @@ class EditHistoryPage extends AbstractPage {
                if ($this->old && $this->new) {
                        $a = explode("\n", StringUtil::unifyNewlines($this->old->getMessage()));
                        $b = explode("\n", StringUtil::unifyNewlines($this->new->getMessage()));
-                       $this->diff = new Diff($a, $b);
+                       $diff = new Diff($a, $b);
+                       $this->diff = $diff->getRawDiff();
+                       
+                       // create word diff for small changes (only one consecutive paragraph modified)
+                       for ($i = 0, $max = count($this->diff); $i < $max;) {
+                               $previousIsNotRemoved = !isset($this->diff[$i - 1][0]) || $this->diff[$i - 1][0] !== Diff::REMOVED;
+                               $currentIsRemoved = $this->diff[$i][0] === Diff::REMOVED;
+                               $nextIsAdded = isset($this->diff[$i + 1][0]) && $this->diff[$i + 1][0] === Diff::ADDED;
+                               $afterNextIsNotAdded = !isset($this->diff[$i + 2][0]) || $this->diff[$i + 2][0] !== Diff::ADDED;
+                               
+                               if ($previousIsNotRemoved && $currentIsRemoved && $nextIsAdded && $afterNextIsNotAdded) {
+                                       $a = preg_split('/(\\W)/u', $this->diff[$i][1], -1, PREG_SPLIT_DELIM_CAPTURE);
+                                       $b = preg_split('/(\\W)/u', $this->diff[$i + 1][1], -1, PREG_SPLIT_DELIM_CAPTURE);
+                                       
+                                       $diff = new Diff($a, $b);
+                                       $this->diff[$i][1] = '';
+                                       $this->diff[$i + 1][1] = '';
+                                       foreach ($diff->getRawDiff() as $entry) {
+                                               $entry[1] = StringUtil::encodeHTML($entry[1]);
+                                               
+                                               if ($entry[0] === Diff::SAME) {
+                                                       $this->diff[$i][1] .= $entry[1];
+                                                       $this->diff[$i + 1][1] .= $entry[1];
+                                               }
+                                               else if ($entry[0] === Diff::REMOVED) {
+                                                       $this->diff[$i][1] .= '<strong>'.$entry[1].'</strong>';
+                                               }
+                                               else if ($entry[0] === Diff::ADDED) {
+                                                       $this->diff[$i + 1][1] .= '<strong>'.$entry[1].'</strong>';
+                                               }
+                                       }
+                                       $i += 2;
+                               }
+                               else {
+                                       $this->diff[$i][1] = StringUtil::encodeHTML($this->diff[$i][1]);
+                                       $i++;
+                               }
+                       }
                }
                
                // set default values
index e5ae6aa48ff8c1de080756b218e390db7561d305..e7691c59cca6484d6023de8974ed4d920c15ecee 100644 (file)
@@ -199,7 +199,7 @@ class Diff {
                                $this->d[] = [self::REMOVED, $this->a[$positionA++]];
                        }
                        
-                       // find next matching item in b, every item in between must be removed
+                       // find next matching item in b, every item in between must be added
                        while ($positionB < $this->sizeB && $this->b[$positionB] !== $item) {
                                $this->d[] = [self::ADDED, $this->b[$positionB++]];
                        }