Skip to content

Commit 44607b7

Browse files
committed
Save point.
Created ListDiff and ListNode classes. Started on custom list diffing functionality.
1 parent 4888c71 commit 44607b7

File tree

5 files changed

+233
-5
lines changed

5 files changed

+233
-5
lines changed

demo/demo.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ demo.controller('diffCtrl', ['$scope', '$http', '$sce', '$timeout', function ($s
3838
$scope.loading = true;
3939
$http.post('index.php', { oldText: $scope.oldText, newText: $scope.newText })
4040
.success(function (data) {
41+
//alert(JSON.stringify(data));
4142
$scope.diff = data.diff;
4243
$scope.loading = false;
4344
});

demo/index.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
'Caxy/HtmlDiff/HtmlDiff',
1111
'Caxy/HtmlDiff/Match',
1212
'Caxy/HtmlDiff/Operation',
13+
'Caxy/HtmlDiff/ListDiff',
1314
);
1415

1516
foreach ($classes as $class) {
@@ -20,7 +21,7 @@
2021

2122
if ($input) {
2223
$data = json_decode($input, true);
23-
$diff = new HtmlDiff($data['oldText'], $data['newText'], 'UTF-8', array());
24+
$diff = new HtmlDiff($_POST['oldText'], $_POST['newText'], 'UTF-8', array());
2425
$diff->build();
2526

2627
header('Content-Type: application/json');

lib/Caxy/HtmlDiff/HtmlDiff.php

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,15 @@ class HtmlDiff extends AbstractDiff
88
protected $insertSpaceInReplace = false;
99
protected $newIsolatedDiffTags;
1010
protected $oldIsolatedDiffTags;
11-
protected $isolatedDiffTags = array ('ol' => '[[REPLACE_ORDERED_LIST]]', 'ul' => '[[REPLACE_UNORDERED_LIST]]', 'sub' => '[[REPLACE_SUB_SCRIPT]]' , 'sup' => '[[REPLACE_SUPER_SCRIPT]]', 'dl' => '[[REPLACE_DEFINITION_LIST]]', 'table' => '[[REPLACE_TABLE]]');
12-
11+
protected $isolatedDiffTags = array (
12+
'ol' => '[[REPLACE_ORDERED_LIST]]',
13+
'ul' => '[[REPLACE_UNORDERED_LIST]]',
14+
'sub' => '[[REPLACE_SUB_SCRIPT]]',
15+
'sup' => '[[REPLACE_SUPER_SCRIPT]]',
16+
'dl' => '[[REPLACE_DEFINITION_LIST]]',
17+
'table' => '[[REPLACE_TABLE]]'
18+
);
19+
1320
/**
1421
* @param boolean $boolean
1522
* @return HtmlDiff
@@ -39,7 +46,7 @@ public function build()
3946
foreach ($operations as $item) {
4047
$this->performOperation( $item );
4148
}
42-
49+
4350
return $this->content;
4451
}
4552

@@ -200,6 +207,12 @@ protected function diffElements($oldText, $newText)
200207

201208
return $wrapStart . $diff->build() . $wrapEnd;
202209
}
210+
211+
protected function diffList($oldText, $newText)
212+
{
213+
$diff = new ListDiff($oldText, $newText, $this->encoding, $this->isolatedDiffTags, $this->groupDiffs);
214+
return $diff->build();
215+
}
203216

204217
protected function processEqualOperation($operation)
205218
{
@@ -209,7 +222,10 @@ protected function processEqualOperation($operation)
209222
if (in_array($s, $this->isolatedDiffTags) && isset($this->newIsolatedDiffTags[$pos])) {
210223
$oldText = implode("", $this->findIsolatedDiffTagsInOld($operation, $pos));
211224
$newText = implode("", $this->newIsolatedDiffTags[$pos]);
212-
$result[] = $this->diffElements($oldText, $newText);
225+
$type = in_array($s, array($this->isolatedDiffTags['ol'], $this->isolatedDiffTags['dl'], $this->isolatedDiffTags['ul']))
226+
? "List"
227+
: "Elements";
228+
$result[] = $this->{'diff' . $type}($oldText, $newText);
213229
} else {
214230
$result[] = $s;
215231
}

lib/Caxy/HtmlDiff/ListDiff.php

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
<?php
2+
3+
namespace Caxy\HtmlDiff;
4+
5+
6+
class ListDiff extends HtmlDiff
7+
{
8+
protected $listWords = array();
9+
protected $listTags = array();
10+
protected $listIsolatedDiffTags = array();
11+
protected $isolatedDiffTags = array (
12+
'ol' => '[[REPLACE_ORDERED_LIST]]',
13+
'ul' => '[[REPLACE_UNORDERED_LIST]]',
14+
'dl' => '[[REPLACE_DEFINITION_LIST]]',
15+
);
16+
17+
protected $listType; // holds the type of list this is ol, ul, dl
18+
protected $list; // hold the old/new content of the content of the list
19+
protected $childLists; // contains the old/new child lists content within this list
20+
protected $textMatches; // contains the old/new text strings that match
21+
protected $childListObjects;
22+
23+
public function build()
24+
{
25+
ini_set('xdebug.var_display_max_depth', 5);
26+
ini_set('xdebug.var_display_max_children', 256);
27+
ini_set('xdebug.var_display_max_data', 1024);
28+
// get content from li's
29+
$this->splitInputsToWords();
30+
$this->replaceIsolatedDiffTags();
31+
$this->indexNewWords();
32+
$this->diffListContent();
33+
die;
34+
}
35+
36+
protected function diffListContent()
37+
{
38+
/* Format the list we're focusing on.
39+
* There will always be one list, though passed as an array with one item.
40+
* Format this to only have the list contents, outside of the array.
41+
*/
42+
$this->formatThisListContent();
43+
/* In cases where we're dealing with nested lists,
44+
* make sure we use placeholders to replace the nested lists
45+
*/
46+
$this->replaceListIsolatedDiffTags();
47+
// Set matches of lists.
48+
$this->matchAndCompareLists();
49+
// Create child lists objects
50+
$this->createChildListObjects();
51+
// Diff the child lists
52+
$this->diff();
53+
}
54+
55+
protected function formatThisListContent()
56+
{
57+
foreach ($this->oldIsolatedDiffTags as $key => $diffTagArray) {
58+
$openingTag = preg_replace("/[^A-Za-z0-9 ]/", '', $diffTagArray[0]);
59+
$closingTag = preg_replace("/[^A-Za-z0-9 ]/", '', $diffTagArray[count($diffTagArray) - 1]);
60+
61+
if (array_key_exists($openingTag, $this->isolatedDiffTags) &&
62+
array_key_exists($closingTag, $this->isolatedDiffTags)
63+
) {
64+
$this->listType = $openingTag;
65+
array_shift($this->oldIsolatedDiffTags[$key]);
66+
array_pop($this->oldIsolatedDiffTags[$key]);
67+
array_shift($this->newIsolatedDiffTags[$key]);
68+
array_pop($this->newIsolatedDiffTags[$key]);
69+
$this->list['old'] = $this->oldIsolatedDiffTags[$key];
70+
$this->list['new'] = $this->newIsolatedDiffTags[$key];
71+
}
72+
}
73+
}
74+
75+
protected function matchAndCompareLists()
76+
{
77+
// Build childLists array of old/new content of lists.
78+
$this->buildChildLists();
79+
// Compare the lists, saving total matches to textMatches array.
80+
$this->compareChildLists();
81+
// Create the child list objects from textMatches array
82+
$this->createChildListObjects();
83+
}
84+
85+
protected function compareChildLists()
86+
{
87+
// Always compare the new against the old.
88+
// Compare each new string against each old string.
89+
$matchPercentages = array();
90+
foreach ($this->childLists['new'] as $thisKey => $thisList) {
91+
$matchPercentages[$thisKey] = array();
92+
foreach ($this->childLists['old'] as $thatKey => $thatList) {
93+
similar_text($thisList, $thatList, $percentage);
94+
$matchPercentages[$thisKey][] = $percentage;
95+
}
96+
}
97+
//var_dump($matchPercentages);
98+
99+
$bestMatchPercentages = $matchPercentages;
100+
foreach ($bestMatchPercentages as &$thisMatch) {
101+
arsort($thisMatch);
102+
}
103+
var_dump($bestMatchPercentages);
104+
105+
// Build matches.
106+
$matches = array();
107+
$taken = array();
108+
$takenItems = array(2,3);
109+
$absolute = 100;
110+
foreach ($bestMatchPercentages as $item => $percentages) {
111+
$highestMatch = -1;
112+
$highestMatchKey = -1;
113+
114+
foreach ($percentages as $key => $percent) {
115+
$str = "key: ".$key." / percent: ".$percent;
116+
//var_dump($str);
117+
if (!in_array($key, $taken) && $percent > $highestMatch) {
118+
// If matches 100%, set and move on.
119+
/*
120+
* if ($percent == $absolute) {
121+
$highestMatch = $percent;
122+
$highestMatchKey = $key;
123+
break;
124+
} else {
125+
// If not an absolute match, loop through the other high results, checking if any are higher
126+
foreach ($bestMatchPercentages as $otherItem => $otherPercentages) {
127+
if ($otherPercentages[$key] > $percent) {
128+
array_column($taken, $otherPercentages)
129+
}
130+
}
131+
}
132+
*/
133+
$str = "Key: ".$key." / percent: ".$percent; var_dump($str);
134+
$columns = array_column($bestMatchPercentages, $key);
135+
var_dump(
136+
// Start to filter: GOAL is to get values higher than $percent and keys not included in $takenItems
137+
array_filter(
138+
// Build array we want the filter to use
139+
$columns,
140+
// return if value is higher than percent
141+
function ($v) use ($percent, $columns) {
142+
return $v > $percent && ();
143+
}
144+
)
145+
);
146+
/*var_dump(
147+
(array_column($bestMatchPercentages, $key))
148+
);*/
149+
}
150+
die;
151+
}
152+
153+
$matches[] = array('new' => $item, 'old' => $highestMatchKey > -1 ? $highestMatchKey : null);
154+
if ($highestMatchKey > -1) {
155+
$taken[] = $highestMatchKey;
156+
}
157+
}
158+
159+
// Save the matches.
160+
$this->textMatches = $matches;
161+
//var_dump($matches);
162+
}
163+
164+
protected function buildChildLists()
165+
{
166+
$this->childLists['old'] = $this->getListsContent($this->list['old']);
167+
$this->childLists['new'] = $this->getListsContent($this->list['new']);
168+
}
169+
170+
protected function createChildListObjects()
171+
{
172+
/*$this->childListObjects = array();
173+
foreach ($this->textMatches as $match) {
174+
$object = new ListNode($match['old'], $match['new']);
175+
$this->childListObjects[] = $object;
176+
}*/
177+
}
178+
179+
protected function diff()
180+
{
181+
182+
}
183+
184+
public function replaceListIsolatedDiffTags()
185+
{
186+
$this->listIsolatedDiffTags['old'] = $this->createIsolatedDiffTagPlaceholders($this->list['old']);
187+
$this->listIsolatedDiffTags['new'] = $this->createIsolatedDiffTagPlaceholders($this->list['new']);
188+
}
189+
190+
protected function getListsContent(array $contentArray, $stripTags = true)
191+
{
192+
preg_match_all('/<li>(.*?)<\/li>/s', implode('', $contentArray), $matches);
193+
return $matches[intval($stripTags)];
194+
}
195+
}

lib/Caxy/HtmlDiff/ListNode.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace Caxy\HtmlDiff;
4+
5+
class ListNode extends HtmlDiff
6+
{
7+
protected $oldText;
8+
protected $newText;
9+
10+
public function __construct($oldText, $newText)
11+
{
12+
$this->oldText = $oldText;
13+
$this->newText = $newText;
14+
}
15+
}

0 commit comments

Comments
 (0)