Skip to content

Commit

Permalink
added UrlNode [WIP]
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Aug 9, 2023
1 parent 46df9d8 commit bb3073e
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 17 deletions.
10 changes: 6 additions & 4 deletions src/Latte/Compiler/Escaper.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ public function enterContentType(string $type): void
}


public function enterSubType(string $type): void
{
$this->subType = $type;
}


public function enterHtmlText(?ElementNode $node): void
{
$this->state = self::HtmlText;
Expand Down Expand Up @@ -110,10 +116,6 @@ public function enterHtmlAttribute(?string $name = null): void
$this->subType = self::JavaScript;
} elseif ($name === 'style') {
$this->subType = self::Css;
} elseif ((in_array($name, ['href', 'src', 'action', 'formaction'], true)
|| ($name === 'data' && $this->tag === 'object'))
) {
$this->subType = self::Url;
}
}
}
Expand Down
15 changes: 2 additions & 13 deletions src/Latte/Compiler/Nodes/Html/AttributeNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

use Latte\Compiler\NodeHelpers;
use Latte\Compiler\Nodes\AreaNode;
use Latte\Compiler\Nodes\FragmentNode;
use Latte\Compiler\Nodes\TextNode;
use Latte\Compiler\Position;
use Latte\Compiler\PrintContext;
Expand All @@ -38,18 +37,8 @@ public function print(PrintContext $context): string
$res .= "echo '=';";
$quote = $this->quote ?? ($this->value instanceof TextNode ? null : '"');
$res .= $quote ? 'echo ' . var_export($quote, true) . ';' : '';

$escaper = $context->beginEscape();
$escaper->enterHtmlAttribute(NodeHelpers::toText($this->name));
if ($this->value instanceof FragmentNode && $escaper->export() === 'html/attr/url') {
foreach ($this->value->children as $child) {
$res .= $child->print($context);
$escaper->enterHtmlAttribute(null);
}
} else {
$res .= $this->value->print($context);
}

$context->beginEscape()->enterHtmlAttribute(NodeHelpers::toText($this->name));
$res .= $this->value->print($context);
$context->restoreEscape();
$res .= $quote ? 'echo ' . var_export($quote, true) . ';' : '';
return $res;
Expand Down
46 changes: 46 additions & 0 deletions src/Latte/Compiler/Nodes/UrlNode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

/**
* This file is part of the Latte (https://latte.nette.org)
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
*/

declare(strict_types=1);

namespace Latte\Compiler\Nodes;

use Latte\Compiler\PrintContext;


class UrlNode extends AreaNode
{
public function __construct(
public AreaNode $value,
) {
$this->position = $value->position;
}


public function print(PrintContext $context): string
{
$escaper = $context->beginEscape();
$escaper->enterSubType($escaper::Url);
$res = '';
if ($this->value instanceof FragmentNode) {
foreach ($this->value->children as $child) {
$res .= $child->print($context);
$escaper->enterSubType('');
}
} else {
$res .= $this->value->print($context);
}
$context->restoreEscape();
return $res;
}


public function &getIterator(): \Generator
{
yield $this->value;
}
}
15 changes: 15 additions & 0 deletions src/Latte/Compiler/TemplateParserHtml.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Latte\Compiler\Nodes\AreaNode;
use Latte\Compiler\Nodes\FragmentNode;
use Latte\Compiler\Nodes\Html;
use Latte\Compiler\Nodes\UrlNode;
use Latte\ContentType;
use Latte\Helpers;
use Latte\SecurityViolationException;
Expand Down Expand Up @@ -262,6 +263,10 @@ private function parseAttribute(): ?Node
}

[$value, $quote] = $this->parseAttributeValue();
if ($value && $this->isUrlAttribute(NodeHelpers::toText($name), $this->element)) {
$value = new UrlNode($value);
}

return new Html\AttributeNode(
name: $name,
value: $value,
Expand Down Expand Up @@ -501,4 +506,14 @@ private function getPrefix(string $name): string
default => Tag::PrefixNone,
};
}


private function isUrlAttribute(?string $name, ?Html\ElementNode $elem): bool
{
$name = strtolower($name ?? '');
return $this->parser->getContentType() === ContentType::Html
&& ((in_array($name, ['href', 'src', 'action', 'formaction'], true)
|| ($name === 'data' && strtolower($elem->name) === 'object'))
);
}
}

0 comments on commit bb3073e

Please sign in to comment.