Skip to content

Commit c3438d3

Browse files
committed
Re-wrap HTML attributes
1 parent 5e0c294 commit c3438d3

4 files changed

Lines changed: 67 additions & 17 deletions

File tree

tests/Phug/Component/ComponentExtensionTest.php

Lines changed: 59 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace Phug\Test\Component;
44

5+
use DOMAttr;
6+
use DOMDocument;
57
use Exception;
68
use PHPUnit\Framework\TestCase;
79
use Phug\Compiler\Event\NodeEvent;
@@ -21,6 +23,7 @@
2123
use Phug\Util\Partial\ValueTrait;
2224
use Pug\Pug;
2325
use ReflectionException;
26+
use SimpleXMLElement;
2427
use XhtmlFormatter\Formatter;
2528

2629
/**
@@ -403,6 +406,8 @@ public function testNamespace()
403406
public function getPugPhpTestsTemplates(): array
404407
{
405408
return array_map(function ($file) {
409+
$file = basename($file);
410+
406411
return [$file, substr($file, 0, -5).'.pug'];
407412
}, glob(__DIR__.'/../../templates/*.html'));
408413
}
@@ -411,7 +416,6 @@ public function getPugPhpTestsTemplates(): array
411416
* @dataProvider getPugPhpTestsTemplates
412417
*
413418
* @covers ::attachEvents
414-
* @covers ::parseOutput
415419
*
416420
* @param string $htmlFile Expected output template file
417421
* @param string $pugFile Input template file
@@ -420,35 +424,81 @@ public function getPugPhpTestsTemplates(): array
420424
*/
421425
public function testPugPhpTestsTemplates(string $htmlFile, string $pugFile)
422426
{
427+
$templateFolder = __DIR__.'/../../templates/';
423428
$pug = new Pug([
424429
'debug' => false,
425430
'pretty' => true,
426431
]);
427432
ComponentExtension::enable($pug);
428433

429434
$this->assertSame(
430-
$this->rawHtml(file_get_contents($htmlFile)),
431-
$this->rawHtml($pug->renderFile($pugFile, [])),
435+
$this->rawHtml(file_get_contents($templateFolder . $htmlFile)),
436+
$this->rawHtml($pug->renderFile($templateFolder . $pugFile, [])),
432437
basename($pugFile)
433438
);
434439
}
435440

436441
private function rawHtml($html)
437442
{
438443
$html = strtr($html, [
439-
"'" => '"',
440444
"\r" => '',
441445
]);
442446
$html = preg_replace('`\n{2,}`', "\n", $html);
443447
$html = preg_replace('`(?<!\n) {2,}`', ' ', $html);
444448
$html = preg_replace('` *$`m', '', $html);
445449
$html = $this->format($html);
446-
$html = preg_replace_callback('`(<(?:style|script)(?:[^>]*)>)([\s\S]+)(</(?:style|script)>)`', function ($matches) {
447-
[, $start, $content, $end] = $matches;
448-
$content = trim(preg_replace('`^ *`m', '', $content));
450+
$html = preg_replace_callback(
451+
'`(<(?:style|script)[^>]*>)([\s\S]+)(</(?:style|script)>)`',
452+
function ($matches) {
453+
[, $start, $content, $end] = $matches;
454+
$content = trim(preg_replace('`^ *`m', '', $content));
455+
456+
return "$start\n$content\n$end";
457+
},
458+
$html
459+
);
460+
$html = preg_replace_callback(
461+
'`class="([^"]+)"`',
462+
function ($matches) {
463+
$classes = preg_split('/\s+/', $matches[1]);
464+
sort($classes);
449465

450-
return "$start\n$content\n$end";
451-
}, $html);
466+
return 'class="' . implode(' ', $classes) . '"';
467+
},
468+
$html
469+
);
470+
$document = new DOMDocument();
471+
$html = preg_replace_callback(
472+
'/(?<start><(?<tag>\w+)\s(?<parameters>[^>]+))>/',
473+
function ($matches) use ($document) {
474+
try {
475+
$tag = rtrim($matches['start'], '/') . '/>';
476+
$document->loadHTML("<html><body>$tag</body></html>");
477+
$node = $document->getElementsByTagName('body')[0]->firstChild;
478+
} catch (Exception $error) {
479+
return $matches[0];
480+
}
481+
482+
$attributes = iterator_to_array($node->attributes);
483+
ksort($attributes);
484+
485+
return '<' . $matches['tag'] .
486+
implode('', array_map(
487+
static function (DOMAttr $value): string {
488+
$name = $value->name;
489+
490+
if ($value->textContent === '') {
491+
return " $name";
492+
}
493+
494+
return " $name=\"" . htmlentities($value->textContent) . '"';
495+
},
496+
$attributes
497+
)) .
498+
'>';
499+
},
500+
$html
501+
);
452502

453503
return $html;
454504
}

tests/templates/inline-tags.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
</small>
55
tag
66
<h1>
7-
J"aime
7+
J'aime
88
<strong>
99
Pug
1010
</strong>
1111
</h1>
1212
<h1>
13-
J"aime
13+
J'aime
1414
<strong>
1515
beaucoup
1616
</strong>
@@ -19,7 +19,7 @@ <h1>
1919
</strong>
2020
</h1>
2121
<h1>
22-
J"aime #[strong beaucoup]
22+
J'aime #[strong beaucoup]
2323
<strong>
2424
beaucoup
2525
</strong>
@@ -28,7 +28,7 @@ <h1>
2828
<div>
2929
<div>
3030
<h1>
31-
J"aime
31+
J'aime
3232
<strong>
3333
beaucoup
3434
</strong>
@@ -78,4 +78,4 @@ <h1>
7878
!
7979
This line has no tag.
8080
</article>
81-
</div>
81+
</div>

tests/templates/mixin.attrs.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ <h1 class="foo bar">
2222
<div class="stretch">
2323
<div class="centered">
2424
<h1 class="highlight">
25-
Section 3" and quote&quot;&quot;
25+
Section 3' and quote&quot;&quot;
2626
</h1>
2727
<p>Last content.</p>
2828
<div class="footer">

tests/templates/mixin.block-tag-behaviour.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ <h1>
55
Foo
66
</h1>
77
<article>
8-
<p>I"m article foo</p>
8+
<p>I'm article foo</p>
99
</article>
1010
</section>
1111
</body>
@@ -17,7 +17,7 @@ <h1>
1717
Something
1818
</h1>
1919
<article>
20-
I"m a much longer
20+
I'm a much longer
2121
text-only article,
2222
but you can still
2323
inline html tags

0 commit comments

Comments
 (0)