Skip to content

Commit 8948b7c

Browse files
author
Sven Hagemann
committed
WIP
1 parent 4c79c32 commit 8948b7c

File tree

5 files changed

+36
-49
lines changed

5 files changed

+36
-49
lines changed

lib/Caxy/HtmlDiff/AbstractDiff.php

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace Caxy\HtmlDiff;
44

55
use Caxy\HtmlDiff\Util\MbStringUtil;
6+
use HTMLPurifier;
7+
use HTMLPurifier_Config;
68

79
/**
810
* Class AbstractDiff.
@@ -66,12 +68,12 @@ abstract class AbstractDiff
6668
protected $diffCaches = array();
6769

6870
/**
69-
* @var \HTMLPurifier
71+
* @var HTMLPurifier
7072
*/
7173
protected $purifier;
7274

7375
/**
74-
* @var \HTMLPurifier_Config|null
76+
* @var HTMLPurifier_Config|null
7577
*/
7678
protected $purifierConfig = null;
7779

@@ -129,7 +131,7 @@ public function initPurifier($defaultPurifierSerializerCache = null)
129131
if (null !== $this->purifierConfig) {
130132
$HTMLPurifierConfig = $this->purifierConfig;
131133
} else {
132-
$HTMLPurifierConfig = \HTMLPurifier_Config::createDefault();
134+
$HTMLPurifierConfig = HTMLPurifier_Config::createDefault();
133135
}
134136

135137
// Cache.SerializerPath defaults to Null and sets
@@ -144,7 +146,7 @@ public function initPurifier($defaultPurifierSerializerCache = null)
144146
// created by the web/php user (www-user, php-fpm, etc.)
145147
$HTMLPurifierConfig->set('Cache.SerializerPermissions', 0777);
146148

147-
$this->purifier = new \HTMLPurifier($HTMLPurifierConfig);
149+
$this->purifier = new HTMLPurifier($HTMLPurifierConfig);
148150
}
149151

150152
/**
@@ -369,33 +371,13 @@ public function isGroupDiffs()
369371
}
370372

371373
/**
372-
* @param \HTMLPurifier_Config $config
374+
* @param HTMLPurifier_Config $config
373375
*/
374-
public function setHTMLPurifierConfig(\HTMLPurifier_Config $config)
376+
public function setHTMLPurifierConfig(HTMLPurifier_Config $config)
375377
{
376378
$this->purifierConfig = $config;
377379
}
378380

379-
/**
380-
* @param string $tag
381-
*
382-
* @return string
383-
*/
384-
protected function getOpeningTag($tag)
385-
{
386-
return '/<'.$tag.'[^>]*/i';
387-
}
388-
389-
/**
390-
* @param string $tag
391-
*
392-
* @return string
393-
*/
394-
protected function getClosingTag($tag)
395-
{
396-
return '</'.$tag.'>';
397-
}
398-
399381
/**
400382
* @param string $html
401383
*

lib/Caxy/HtmlDiff/HtmlDiff.php

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -574,13 +574,22 @@ protected function insertTag($tag, $cssClass, &$words)
574574
$this->content .= $specialCaseTagInjection.implode('', $this->extractConsecutiveWords($words, 'tag'));
575575
} else {
576576
$workTag = $this->extractConsecutiveWords($words, 'tag');
577-
if (isset($workTag[ 0 ]) && $this->isOpeningTag($workTag[ 0 ]) && !$this->isClosingTag($workTag[ 0 ])) {
578-
if ($this->stringUtil->strpos($workTag[ 0 ], 'class=')) {
579-
$workTag[ 0 ] = str_replace('class="', 'class="diffmod ', $workTag[ 0 ]);
580-
$workTag[ 0 ] = str_replace("class='", 'class="diffmod ', $workTag[ 0 ]);
577+
578+
if (
579+
isset($workTag[0]) &&
580+
$this->isOpeningTag($workTag[0]) === true &&
581+
$this->isClosingTag($workTag[0]) === false
582+
) {
583+
if ($this->stringUtil->strpos($workTag[0], 'class=') !== false) {
584+
$workTag[0] = str_replace('class="', 'class="diffmod ', $workTag[0]);
585+
$workTag[0] = str_replace("class='", 'class="diffmod ', $workTag[0]);
586+
} elseif ($this->stringUtil->strpos($workTag[0], '/>') !== false) {
587+
$workTag[0] = str_replace('/>', ' class="diffmod" />', $workTag[0]);
581588
} else {
582-
$workTag[ 0 ] = str_replace('>', ' class="diffmod">', $workTag[ 0 ]);
589+
$workTag[0] = str_replace('>', ' class="diffmod">', $workTag[0]);
583590
}
591+
592+
var_dump($workTag[ 0 ]);
584593
}
585594

586595
$appendContent = implode('', $workTag).$specialCaseTagInjection;

lib/Caxy/HtmlDiff/ListDiffLines.php

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -389,35 +389,31 @@ private function getInnerText(DOMNode $node) : string
389389
$bufferDom->appendChild($bufferDom->importNode($child, true));
390390
}
391391

392-
return $bufferDom->saveHTML();
392+
return trim($bufferDom->saveHTML());
393393
}
394394

395395
private function setInnerText(DOMNode $node, string $html) : void
396396
{
397-
$html = trim($html);/*
398-
echo "\r\n" . '------------------------' . "\r\n";
399-
echo $html . "\r\n";
400-
echo '------------------------' . "\r\n";
401-
*/
397+
$html = sprintf('<%s>%s</%s>', 'body', $html, 'body');
402398

399+
$bufferDom = new DOMDocument();
403400

404-
$htmlFragment = $node->ownerDocument->createDocumentFragment();
405-
$htmlFragment->ownerDocument->preserveWhiteSpace = false;
406-
$htmlFragment->appendXML($html);
401+
try {
402+
$bufferDom->loadHTML($html);
403+
} catch (\Exception $exception) {
404+
var_dump($html);
405+
exit;
406+
}
407407

408-
$node->nodeValue = '';
409-
$node->appendChild($htmlFragment);
408+
$bufferDom->saveHTML($bufferDom->childNodes[0]);
410409
}
411410

412411
private function wrapNode(DOMNode $node, string $tagName) : void
413412
{
414-
$htmlFragment = $node->ownerDocument->createDocumentFragment();
415-
$htmlFragment->appendXML(
413+
$this->setInnerText(
414+
$node,
416415
sprintf('<%s>%s</%s>', $tagName, $this->getInnerText($node), $tagName)
417416
);
418-
419-
$node->nodeValue = '';
420-
$node->appendChild($htmlFragment);
421417
}
422418

423419
private function childCountWithoutTextNode(DOMNode $node) : int

tests/fixtures/HtmlDiff/first-and-last.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,5 @@
3535
</newText>
3636

3737
<expected>
38-
<ol class="diff-list"><li class="removed"><del> Etiam feugiat lorem non metus. Nullam accumsan lorem in dui. </del></li><li class="removed"><del> Praesent ac sem eget est egestas volutpat. Nulla neque dolor, sagittis eget, iaculis quis, molestie non, velit. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Aenean massa. </del></li><li class="removed"><del> Vestibulum suscipit nulla quis orci. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. </del></li><li class="replacement">Suspendisse non nisl sit amet velit hendrerit rutrum. Aenean massa. Curabitur ullamcorper ultricies nisi. Praesent vestibulum dapibus nibh. In dui magna, posuere eget, vestibulum et, tempor auctor, justo.</li><li class="normal new"><ins> Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. </ins></li><li class="normal new"><ins> Duis lobortis massa imperdiet quam. Donec sodales sagittis magna. Nam ipsum risus, rutrum vitae, vestibulum eu, molestie vel, lacus. Suspendisse eu ligula. Morbi nec metus. </ins></li></ol>
38+
<ol class="diff-list"><li class="removed"><del>Etiam feugiat lorem non metus. Nullam accumsan lorem in dui.</del></li><li class="removed"><del>Praesent ac sem eget est egestas volutpat. Nulla neque dolor, sagittis eget, iaculis quis, molestie non, velit. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Aenean massa.</del></li><li class="removed"><del>Vestibulum suscipit nulla quis orci. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos.</del></li><li class="replacement">Suspendisse non nisl sit amet velit hendrerit rutrum. Aenean massa. Curabitur ullamcorper ultricies nisi. Praesent vestibulum dapibus nibh. In dui magna, posuere eget, vestibulum et, tempor auctor, justo.</li><li class="normal new"><ins>Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu.</ins></li><li class="normal new"><ins>Duis lobortis massa imperdiet quam. Donec sodales sagittis magna. Nam ipsum risus, rutrum vitae, vestibulum eu, molestie vel, lacus. Suspendisse eu ligula. Morbi nec metus.</ins></li></ol>
3939
</expected>

tests/fixtures/HtmlDiff/override-5.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,5 @@
2727
</newText>
2828

2929
<expected>
30-
<p>In addition to the <em>means of egress</em> required by this chapter, <del class="diffmod">provisions </del><em class="diffmod"><ins class="diffmod">emergency escape and rescue openings </ins></em>shall be <del class="diffmod">made for </del><em class="diffmod"><del class="diffmod">emergency escape and rescue openings</del></em><ins class="diffmod">provided</ins> in<ins class="diffins"> the following occupancies:</ins></p><ins class="diffins"> </ins><div style="padding-left:30px;" class="diffmod"><ins class="diffins">1.</ins> Group R<ins class="diffins">-1 and R-2</ins> occupancies.<del class="diffmod"> </del></div><ins class="diffmod"> </ins><div style="padding-left:30px;" class="diffmod"><ins class="diffmod">2. Group R-1 and R-2 occupancies located on stories with one exit or access to one exit where permitted by Tables 1006.3.2(1) and 1006.3.2(2). </ins></div><ins class="diffmod"> </ins><div style="padding-left:30px;" class="diffmod"><ins class="diffmod">3. Group R-3 occupancies.</ins></div><ins class="diffmod"> </ins><p class="diffmod"><br /><em>Basements</em> and sleeping rooms below the fourth story above <em>grade plane</em> shall have at least one exterior <em>emergency escape and rescue opening</em> in accordance with this section. Where <em>basements</em> contain one or more sleeping rooms, <em>emergency escape and rescue openings</em> shall be required in each sleeping room, but shall not be required in adjoining areas of the <em>basement</em>. Such openings shall open directly into a <em>public way</em> or to a <em>yard </em>or<em> court</em> that opens to a <em>public way</em>.</p> <ul class="exception diff-list"><li class="normal"><strong>Exceptions:</strong><br / class="diffmod"><ol class="diff-list"><li class="removed"><del><em>Groups R-1 and R-2 occupancies are not required to provide emergency and escape openings where they comply with all of the following:</em><ol><li><em>Each story has access to two or more means of egress.<br /></em></li> <li><em>The building is constructed of Type I, Type II, Type IIIA or Type IV construction.</em></li> <li><em>The building is equipped throughout with an approved automatic sprinkler system in accordance with Sections 903.3.1.1 or 903.3.3.2.</em></li> </ol></del></li><li class="removed"><del><em>The emergency escape and rescue opening is permitted to open onto a balcony within an atrium in accordance with the requirements of Section 404, provided the balcony provides access to an exit and the dwelling unit or sleeping unit has a means of egress that is not open to the atrium.</em></del></li><li class="replacement"><ins><em>Emergency escape and rescue opening</em> are not required from Group R-1 and R-2 occupancies where each story has access to at least two exits or access to exits and the building is equipped throughout with an automatic sprinkler system in accordance with Section 903.3.1.1.</ins></li><li class="normal"><em>Basements</em> with a ceiling height of less than 80 inches (2032 mm) shall not be required to have <em>emergency escape and rescue openings</em>.</li><li class="normal"><em>Emergency escape and rescue openings</em> are not required from <em>basements</em> or sleeping rooms that have an <em>exit</em> door or <em>exit access</em> door that opens directly into a <em>public way</em> or to a <em>yard</em>, <em>court</em> or exterior exit balcony that opens to a <em>public way</em>.</li><li class="normal"><em>Basements</em> without <em>habitable spaces</em> and having not more than 200 square feet (18.6 m<sup>2</sup>) in floor area shall not be required to have <em>emergency escape and rescue openings</em>.</li></ol></li></ul>
30+
<p>In addition to the <em>means of egress</em> required by this chapter, <del class="diffmod">provisions </del><em class="diffmod"><ins class="diffmod">emergency escape and rescue openings </ins></em>shall be <del class="diffmod">made for </del><em class="diffmod"><del class="diffmod">emergency escape and rescue openings</del></em><ins class="diffmod">provided</ins> in<ins class="diffins"> the following occupancies:</ins></p><ins class="diffins"> </ins><div style="padding-left:30px;" class="diffmod"><ins class="diffins">1.</ins> Group R<ins class="diffins">-1 and R-2</ins> occupancies.<del class="diffmod"> </del></div><ins class="diffmod"> </ins><div style="padding-left:30px;" class="diffmod"><ins class="diffmod">2. Group R-1 and R-2 occupancies located on stories with one exit or access to one exit where permitted by Tables 1006.3.2(1) and 1006.3.2(2). </ins></div><ins class="diffmod"> </ins><div style="padding-left:30px;" class="diffmod"><ins class="diffmod">3. Group R-3 occupancies.</ins></div><ins class="diffmod"> </ins><p class="diffmod"><br /><em>Basements</em> and sleeping rooms below the fourth story above <em>grade plane</em> shall have at least one exterior <em>emergency escape and rescue opening</em> in accordance with this section. Where <em>basements</em> contain one or more sleeping rooms, <em>emergency escape and rescue openings</em> shall be required in each sleeping room, but shall not be required in adjoining areas of the <em>basement</em>. Such openings shall open directly into a <em>public way</em> or to a <em>yard </em>or<em> court</em> that opens to a <em>public way</em>.</p> <ul class="exception diff-list"><li class="normal"><strong>Exceptions:</strong><br class="diffmod"><ol class="diff-list"><li class="removed"><del><em>Groups R-1 and R-2 occupancies are not required to provide emergency and escape openings where they comply with all of the following:</em><ol><li><em>Each story has access to two or more means of egress.<br /></em></li> <li><em>The building is constructed of Type I, Type II, Type IIIA or Type IV construction.</em></li> <li><em>The building is equipped throughout with an approved automatic sprinkler system in accordance with Sections 903.3.1.1 or 903.3.3.2.</em></li> </ol></del></li><li class="removed"><del><em>The emergency escape and rescue opening is permitted to open onto a balcony within an atrium in accordance with the requirements of Section 404, provided the balcony provides access to an exit and the dwelling unit or sleeping unit has a means of egress that is not open to the atrium.</em></del></li><li class="replacement"><ins><em>Emergency escape and rescue opening</em> are not required from Group R-1 and R-2 occupancies where each story has access to at least two exits or access to exits and the building is equipped throughout with an automatic sprinkler system in accordance with Section 903.3.1.1.</ins></li><li class="normal"><em>Basements</em> with a ceiling height of less than 80 inches (2032 mm) shall not be required to have <em>emergency escape and rescue openings</em>.</li><li class="normal"><em>Emergency escape and rescue openings</em> are not required from <em>basements</em> or sleeping rooms that have an <em>exit</em> door or <em>exit access</em> door that opens directly into a <em>public way</em> or to a <em>yard</em>, <em>court</em> or exterior exit balcony that opens to a <em>public way</em>.</li><li class="normal"><em>Basements</em> without <em>habitable spaces</em> and having not more than 200 square feet (18.6 m<sup>2</sup>) in floor area shall not be required to have <em>emergency escape and rescue openings</em>.</li></ol></li></ul>
3131
</expected>

0 commit comments

Comments
 (0)