@vituum/vite-plugin-latte 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -0
- package/handler.js +9 -0
- package/index.js +138 -0
- package/index.php +173 -0
- package/latte/AssetFilter.php +11 -0
- package/latte/FetchFunction.php +28 -0
- package/latte/IconFilter.php +14 -0
- package/latte/JsonTag.php +64 -0
- package/latte/PlaceholderFunction.php +11 -0
- package/latte/RandomColorFunction.php +14 -0
- package/latte/TelFilter.php +22 -0
- package/package.json +35 -0
- package/vendor/autoload.php +7 -0
- package/vendor/bin/latte-lint +107 -0
- package/vendor/composer/ClassLoader.php +572 -0
- package/vendor/composer/InstalledVersions.php +350 -0
- package/vendor/composer/LICENSE +21 -0
- package/vendor/composer/autoload_classmap.php +183 -0
- package/vendor/composer/autoload_namespaces.php +9 -0
- package/vendor/composer/autoload_psr4.php +9 -0
- package/vendor/composer/autoload_real.php +57 -0
- package/vendor/composer/autoload_static.php +193 -0
- package/vendor/composer/installed.json +93 -0
- package/vendor/composer/installed.php +32 -0
- package/vendor/composer/platform_check.php +26 -0
- package/vendor/latte/latte/bin/latte-lint +29 -0
- package/vendor/latte/latte/composer.json +53 -0
- package/vendor/latte/latte/license.md +60 -0
- package/vendor/latte/latte/ncs.php +14 -0
- package/vendor/latte/latte/ncs.xml +9 -0
- package/vendor/latte/latte/readme.md +21 -0
- package/vendor/latte/latte/src/Bridges/Tracy/BlueScreenPanel.php +114 -0
- package/vendor/latte/latte/src/Bridges/Tracy/LattePanel.php +99 -0
- package/vendor/latte/latte/src/Bridges/Tracy/templates/LattePanel.panel.phtml +98 -0
- package/vendor/latte/latte/src/Bridges/Tracy/templates/LattePanel.tab.phtml +15 -0
- package/vendor/latte/latte/src/Latte/Compiler/Block.php +44 -0
- package/vendor/latte/latte/src/Latte/Compiler/Escaper.php +244 -0
- package/vendor/latte/latte/src/Latte/Compiler/ExpressionBuilder.php +128 -0
- package/vendor/latte/latte/src/Latte/Compiler/Node.php +28 -0
- package/vendor/latte/latte/src/Latte/Compiler/NodeHelpers.php +132 -0
- package/vendor/latte/latte/src/Latte/Compiler/NodeTraverser.php +77 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/AreaNode.php +17 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/AuxiliaryNode.php +27 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/FragmentNode.php +59 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/AttributeNode.php +48 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/BogusTagNode.php +46 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/CommentNode.php +39 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ElementNode.php +129 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/QuotedValue.php +53 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/NopNode.php +21 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ArgumentNode.php +45 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ComplexTypeNode.php +17 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayAccessNode.php +41 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayItemNode.php +52 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayNode.php +94 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignNode.php +39 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignOpNode.php +45 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/BinaryOpNode.php +65 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CastNode.php +43 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClassConstantFetchNode.php +42 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CloneNode.php +36 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClosureNode.php +73 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClosureUseNode.php +37 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ConstantFetchNode.php +37 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/EmptyNode.php +36 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ErrorSuppressNode.php +36 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FilterCallNode.php +39 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallNode.php +45 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallableNode.php +39 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InRangeNode.php +42 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InstanceofNode.php +40 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/IssetNode.php +40 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MatchNode.php +49 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallNode.php +50 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallableNode.php +42 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/NewNode.php +45 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/NotNode.php +36 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PostOpNode.php +43 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PreOpNode.php +43 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PropertyFetchNode.php +42 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticCallNode.php +55 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticCallableNode.php +47 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticPropertyFetchNode.php +42 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TernaryNode.php +50 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/UnaryOpNode.php +45 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/VariableNode.php +40 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ExpressionNode.php +17 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/FilterNode.php +67 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/IdentifierNode.php +36 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/IntersectionTypeNode.php +39 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/MatchArmNode.php +45 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ModifierNode.php +107 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NameNode.php +89 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NullableTypeNode.php +35 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ParameterNode.php +54 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/BooleanNode.php +30 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/EncapsedStringNode.php +80 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/EncapsedStringPartNode.php +30 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/FloatNode.php +63 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/IntegerNode.php +70 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/NullNode.php +29 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/StringNode.php +40 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ScalarNode.php +15 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/SuperiorTypeNode.php +29 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/UnionTypeNode.php +39 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/VarLikeIdentifierNode.php +21 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/StatementNode.php +15 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/TemplateNode.php +34 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/TextNode.php +37 -0
- package/vendor/latte/latte/src/Latte/Compiler/PhpHelpers.php +227 -0
- package/vendor/latte/latte/src/Latte/Compiler/Position.php +43 -0
- package/vendor/latte/latte/src/Latte/Compiler/PrintContext.php +334 -0
- package/vendor/latte/latte/src/Latte/Compiler/Tag.php +117 -0
- package/vendor/latte/latte/src/Latte/Compiler/TagLexer.php +399 -0
- package/vendor/latte/latte/src/Latte/Compiler/TagParser.php +388 -0
- package/vendor/latte/latte/src/Latte/Compiler/TagParserData.php +580 -0
- package/vendor/latte/latte/src/Latte/Compiler/TemplateGenerator.php +206 -0
- package/vendor/latte/latte/src/Latte/Compiler/TemplateLexer.php +391 -0
- package/vendor/latte/latte/src/Latte/Compiler/TemplateParser.php +448 -0
- package/vendor/latte/latte/src/Latte/Compiler/TemplateParserHtml.php +506 -0
- package/vendor/latte/latte/src/Latte/Compiler/Token.php +259 -0
- package/vendor/latte/latte/src/Latte/Compiler/TokenStream.php +151 -0
- package/vendor/latte/latte/src/Latte/ContentType.php +22 -0
- package/vendor/latte/latte/src/Latte/Engine.php +591 -0
- package/vendor/latte/latte/src/Latte/Essential/Blueprint.php +160 -0
- package/vendor/latte/latte/src/Latte/Essential/CachingIterator.php +232 -0
- package/vendor/latte/latte/src/Latte/Essential/CoreExtension.php +232 -0
- package/vendor/latte/latte/src/Latte/Essential/Filters.php +591 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/BlockNode.php +161 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/CaptureNode.php +98 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ContentTypeNode.php +74 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/DebugbreakNode.php +53 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/DefineNode.php +134 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/DoNode.php +49 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/DumpNode.php +58 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/EmbedNode.php +125 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ExtendsNode.php +60 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/FirstLastSepNode.php +81 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ForNode.php +91 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ForeachNode.php +155 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IfChangedNode.php +141 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IfContentNode.php +82 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IfNode.php +180 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ImportNode.php +49 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeBlockNode.php +140 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeFileNode.php +81 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IterateWhileNode.php +94 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/NAttrNode.php +105 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/NClassNode.php +54 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/NTagNode.php +79 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ParametersNode.php +84 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/PrintNode.php +70 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/RawPhpNode.php +46 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/RollbackNode.php +37 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/SkipNode.php +71 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/SpacelessNode.php +62 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/SwitchNode.php +118 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/TemplatePrintNode.php +39 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/TemplateTypeNode.php +38 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/TraceNode.php +35 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/TranslateNode.php +104 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/TryNode.php +75 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/VarNode.php +106 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/VarPrintNode.php +40 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/VarTypeNode.php +36 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/WhileNode.php +81 -0
- package/vendor/latte/latte/src/Latte/Essential/Passes.php +115 -0
- package/vendor/latte/latte/src/Latte/Essential/RawPhpExtension.php +28 -0
- package/vendor/latte/latte/src/Latte/Essential/RollbackException.php +16 -0
- package/vendor/latte/latte/src/Latte/Essential/Tracer.php +117 -0
- package/vendor/latte/latte/src/Latte/Essential/TranslatorExtension.php +101 -0
- package/vendor/latte/latte/src/Latte/Extension.php +97 -0
- package/vendor/latte/latte/src/Latte/Helpers.php +96 -0
- package/vendor/latte/latte/src/Latte/Loader.php +37 -0
- package/vendor/latte/latte/src/Latte/Loaders/FileLoader.php +95 -0
- package/vendor/latte/latte/src/Latte/Loaders/StringLoader.php +76 -0
- package/vendor/latte/latte/src/Latte/Policy.php +24 -0
- package/vendor/latte/latte/src/Latte/PositionAwareException.php +50 -0
- package/vendor/latte/latte/src/Latte/Runtime/Block.php +24 -0
- package/vendor/latte/latte/src/Latte/Runtime/FilterExecutor.php +151 -0
- package/vendor/latte/latte/src/Latte/Runtime/FilterInfo.php +39 -0
- package/vendor/latte/latte/src/Latte/Runtime/Filters.php +234 -0
- package/vendor/latte/latte/src/Latte/Runtime/Html.php +35 -0
- package/vendor/latte/latte/src/Latte/Runtime/HtmlStringable.php +17 -0
- package/vendor/latte/latte/src/Latte/Runtime/Template.php +381 -0
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/FunctionCallNode.php +30 -0
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/FunctionCallableNode.php +29 -0
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/MethodCallNode.php +32 -0
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/MethodCallableNode.php +30 -0
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/PropertyFetchNode.php +32 -0
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/SandboxNode.php +73 -0
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticCallNode.php +31 -0
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticCallableNode.php +30 -0
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticPropertyFetchNode.php +32 -0
- package/vendor/latte/latte/src/Latte/Sandbox/RuntimeChecker.php +116 -0
- package/vendor/latte/latte/src/Latte/Sandbox/SandboxExtension.php +132 -0
- package/vendor/latte/latte/src/Latte/Sandbox/SecurityPolicy.php +185 -0
- package/vendor/latte/latte/src/Latte/Strict.php +101 -0
- package/vendor/latte/latte/src/Latte/attributes.php +24 -0
- package/vendor/latte/latte/src/Latte/exceptions.php +69 -0
- package/vendor/latte/latte/src/Tools/Linter.php +175 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This file is part of the Latte (https://latte.nette.org)
|
|
5
|
+
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
declare(strict_types=1);
|
|
9
|
+
|
|
10
|
+
namespace Latte\Loaders;
|
|
11
|
+
|
|
12
|
+
use Latte;
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Template loader.
|
|
17
|
+
*/
|
|
18
|
+
class StringLoader implements Latte\Loader
|
|
19
|
+
{
|
|
20
|
+
use Latte\Strict;
|
|
21
|
+
|
|
22
|
+
/** @var string[]|null [name => content] */
|
|
23
|
+
private ?array $templates = null;
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param string[] $templates
|
|
28
|
+
*/
|
|
29
|
+
public function __construct(?array $templates = null)
|
|
30
|
+
{
|
|
31
|
+
$this->templates = $templates;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Returns template source code.
|
|
37
|
+
*/
|
|
38
|
+
public function getContent(string $name): string
|
|
39
|
+
{
|
|
40
|
+
if ($this->templates === null) {
|
|
41
|
+
return $name;
|
|
42
|
+
} elseif (isset($this->templates[$name])) {
|
|
43
|
+
return $this->templates[$name];
|
|
44
|
+
} else {
|
|
45
|
+
throw new Latte\RuntimeException("Missing template '$name'.");
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
public function isExpired(string $name, int $time): bool
|
|
51
|
+
{
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Returns referred template name.
|
|
58
|
+
*/
|
|
59
|
+
public function getReferredName(string $name, string $referringName): string
|
|
60
|
+
{
|
|
61
|
+
if ($this->templates === null) {
|
|
62
|
+
throw new \LogicException("Missing template '$name'.");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return $name;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Returns unique identifier for caching.
|
|
71
|
+
*/
|
|
72
|
+
public function getUniqueId(string $name): string
|
|
73
|
+
{
|
|
74
|
+
return $this->getContent($name);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This file is part of the Latte (https://latte.nette.org)
|
|
5
|
+
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
declare(strict_types=1);
|
|
9
|
+
|
|
10
|
+
namespace Latte;
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
interface Policy
|
|
14
|
+
{
|
|
15
|
+
function isTagAllowed(string $tag): bool;
|
|
16
|
+
|
|
17
|
+
function isFilterAllowed(string $filter): bool;
|
|
18
|
+
|
|
19
|
+
function isFunctionAllowed(string $function): bool;
|
|
20
|
+
|
|
21
|
+
function isMethodAllowed(string $class, string $method): bool;
|
|
22
|
+
|
|
23
|
+
function isPropertyAllowed(string $class, string $property): bool;
|
|
24
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This file is part of the Latte (https://latte.nette.org)
|
|
5
|
+
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
declare(strict_types=1);
|
|
9
|
+
|
|
10
|
+
namespace Latte;
|
|
11
|
+
|
|
12
|
+
use Latte\Compiler\Position;
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
/** @internal */
|
|
16
|
+
trait PositionAwareException
|
|
17
|
+
{
|
|
18
|
+
public ?string $sourceCode = null;
|
|
19
|
+
public ?string $sourceName = null;
|
|
20
|
+
public ?Position $position = null;
|
|
21
|
+
private string $origMessage;
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
public function setSource(string $code, ?string $name = null): self
|
|
25
|
+
{
|
|
26
|
+
$this->sourceCode = $code;
|
|
27
|
+
$this->sourceName = $name;
|
|
28
|
+
$this->generateMessage();
|
|
29
|
+
return $this;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
private function generateMessage(): void
|
|
34
|
+
{
|
|
35
|
+
$this->origMessage ??= $this->message;
|
|
36
|
+
$info = [];
|
|
37
|
+
if ($this->sourceName && @is_file($this->sourceName)) { // @ - may trigger error
|
|
38
|
+
$info[] = "in '" . str_replace(dirname($this->sourceName, 2), '...', $this->sourceName) . "'";
|
|
39
|
+
}
|
|
40
|
+
if ($this->position?->line > 1) {
|
|
41
|
+
$info[] = 'on line ' . $this->position->line;
|
|
42
|
+
}
|
|
43
|
+
if ($this->position?->column) {
|
|
44
|
+
$info[] = 'at column ' . $this->position->column;
|
|
45
|
+
}
|
|
46
|
+
$this->message = $info
|
|
47
|
+
? rtrim($this->origMessage, '.') . ' (' . implode(' ', $info) . ')'
|
|
48
|
+
: $this->origMessage;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This file is part of the Latte (https://latte.nette.org)
|
|
5
|
+
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
declare(strict_types=1);
|
|
9
|
+
|
|
10
|
+
namespace Latte\Runtime;
|
|
11
|
+
|
|
12
|
+
use Latte;
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
/** @internal */
|
|
16
|
+
final class Block
|
|
17
|
+
{
|
|
18
|
+
use Latte\Strict;
|
|
19
|
+
|
|
20
|
+
public ?string $contentType = null;
|
|
21
|
+
|
|
22
|
+
/** @var callable[] */
|
|
23
|
+
public array $functions = [];
|
|
24
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This file is part of the Latte (https://latte.nette.org)
|
|
5
|
+
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
declare(strict_types=1);
|
|
9
|
+
|
|
10
|
+
namespace Latte\Runtime;
|
|
11
|
+
|
|
12
|
+
use Latte;
|
|
13
|
+
use Latte\ContentType;
|
|
14
|
+
use Latte\Helpers;
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Filter executor.
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
21
|
+
class FilterExecutor
|
|
22
|
+
{
|
|
23
|
+
/** @var callable[] */
|
|
24
|
+
private array $_dynamic = [];
|
|
25
|
+
|
|
26
|
+
/** @var array<string, array{callable, ?bool}> */
|
|
27
|
+
private array $_static = [];
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Registers run-time filter.
|
|
32
|
+
*/
|
|
33
|
+
public function add(?string $name, callable $callback): static
|
|
34
|
+
{
|
|
35
|
+
if ($name === null) {
|
|
36
|
+
array_unshift($this->_dynamic, $callback);
|
|
37
|
+
} else {
|
|
38
|
+
$this->_static[$name] = [$callback, null];
|
|
39
|
+
unset($this->$name);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return $this;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Returns all run-time filters.
|
|
48
|
+
* @return callable[]
|
|
49
|
+
*/
|
|
50
|
+
public function getAll(): array
|
|
51
|
+
{
|
|
52
|
+
return array_combine(array_keys($this->_static), array_column($this->_static, 0));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Returns filter for classic calling.
|
|
58
|
+
*/
|
|
59
|
+
public function __get(string $name): callable
|
|
60
|
+
{
|
|
61
|
+
if (isset($this->_static[$name])) {
|
|
62
|
+
[$callback, $aware] = $this->prepareFilter($name);
|
|
63
|
+
if ($aware) { // FilterInfo aware filter
|
|
64
|
+
return $this->$name = function (...$args) use ($callback) {
|
|
65
|
+
array_unshift($args, $info = new FilterInfo);
|
|
66
|
+
if ($args[1] instanceof HtmlStringable) {
|
|
67
|
+
$args[1] = $args[1]->__toString();
|
|
68
|
+
$info->contentType = ContentType::Html;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
$res = $callback(...$args);
|
|
72
|
+
return $info->contentType === ContentType::Html
|
|
73
|
+
? new Html($res)
|
|
74
|
+
: $res;
|
|
75
|
+
};
|
|
76
|
+
} else { // classic filter
|
|
77
|
+
return $this->$name = $callback;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// dynamic filter
|
|
82
|
+
foreach ($this->_dynamic as $loader) {
|
|
83
|
+
$callback = $loader($name);
|
|
84
|
+
if ($callback !== null) {
|
|
85
|
+
$this->_static[$name] = [$callback, null];
|
|
86
|
+
return $this->__get($name);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
$hint = ($t = Helpers::getSuggestion(array_keys($this->_static), $name))
|
|
91
|
+
? ", did you mean '$t'?"
|
|
92
|
+
: '.';
|
|
93
|
+
throw new \LogicException("Filter '$name' is not defined$hint");
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Calls filter with FilterInfo.
|
|
99
|
+
*/
|
|
100
|
+
public function filterContent(string $name, FilterInfo $info, mixed ...$args): mixed
|
|
101
|
+
{
|
|
102
|
+
if (!isset($this->_static[$name])) {
|
|
103
|
+
$hint = ($t = Helpers::getSuggestion(array_keys($this->_static), $name))
|
|
104
|
+
? ", did you mean '$t'?"
|
|
105
|
+
: '.';
|
|
106
|
+
throw new \LogicException("Filter |$name is not defined$hint");
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
[$callback, $aware] = $this->prepareFilter($name);
|
|
110
|
+
|
|
111
|
+
if ($info->contentType === ContentType::Html && $args[0] instanceof HtmlStringable) {
|
|
112
|
+
$args[0] = $args[0]->__toString();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if ($aware) { // FilterInfo aware filter
|
|
116
|
+
array_unshift($args, $info);
|
|
117
|
+
return $callback(...$args);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// classic filter
|
|
121
|
+
if ($info->contentType !== ContentType::Text) {
|
|
122
|
+
throw new Latte\RuntimeException("Filter |$name is called with incompatible content type " . strtoupper($info->contentType)
|
|
123
|
+
. ($info->contentType === ContentType::Html ? ', try to prepend |stripHtml.' : '.'));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
$res = ($this->$name)(...$args);
|
|
127
|
+
if ($res instanceof HtmlStringable) {
|
|
128
|
+
trigger_error("Filter |$name should be changed to content-aware filter.");
|
|
129
|
+
$info->contentType = ContentType::Html;
|
|
130
|
+
$res = $res->__toString();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return $res;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* @return array{callable, bool}
|
|
139
|
+
*/
|
|
140
|
+
private function prepareFilter(string $name): array
|
|
141
|
+
{
|
|
142
|
+
if (!isset($this->_static[$name][1])) {
|
|
143
|
+
$params = Helpers::toReflection($this->_static[$name][0])->getParameters();
|
|
144
|
+
$this->_static[$name][1] = $params
|
|
145
|
+
&& $params[0]->getType() instanceof \ReflectionNamedType
|
|
146
|
+
&& $params[0]->getType()->getName() === FilterInfo::class;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return $this->_static[$name];
|
|
150
|
+
}
|
|
151
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This file is part of the Latte (https://latte.nette.org)
|
|
5
|
+
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
declare(strict_types=1);
|
|
9
|
+
|
|
10
|
+
namespace Latte\Runtime;
|
|
11
|
+
|
|
12
|
+
use Latte;
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Filter runtime info
|
|
17
|
+
*/
|
|
18
|
+
class FilterInfo
|
|
19
|
+
{
|
|
20
|
+
use Latte\Strict;
|
|
21
|
+
|
|
22
|
+
public ?string $contentType = null;
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
public function __construct(?string $contentType = null)
|
|
26
|
+
{
|
|
27
|
+
$this->contentType = $contentType;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
public function validate(array $contentTypes, ?string $name = null): void
|
|
32
|
+
{
|
|
33
|
+
if (!in_array($this->contentType, $contentTypes, true)) {
|
|
34
|
+
$name = $name ? " |$name" : $name;
|
|
35
|
+
$type = $this->contentType ? ' ' . strtoupper($this->contentType) : '';
|
|
36
|
+
throw new Latte\RuntimeException("Filter{$name} used with incompatible type{$type}.");
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This file is part of the Latte (https://latte.nette.org)
|
|
5
|
+
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
declare(strict_types=1);
|
|
9
|
+
|
|
10
|
+
namespace Latte\Runtime;
|
|
11
|
+
|
|
12
|
+
use Latte;
|
|
13
|
+
use Latte\ContentType;
|
|
14
|
+
use Latte\RuntimeException;
|
|
15
|
+
use Nette;
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Escaping & sanitization filters.
|
|
20
|
+
* @internal
|
|
21
|
+
*/
|
|
22
|
+
class Filters
|
|
23
|
+
{
|
|
24
|
+
/** @deprecated */
|
|
25
|
+
public static string $dateFormat = "j.\u{a0}n.\u{a0}Y";
|
|
26
|
+
|
|
27
|
+
/** @internal use XML syntax? */
|
|
28
|
+
public static bool $xml = false;
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Escapes string for use everywhere inside HTML (except for comments).
|
|
33
|
+
*/
|
|
34
|
+
public static function escapeHtml($s): string
|
|
35
|
+
{
|
|
36
|
+
return htmlspecialchars((string) $s, ENT_QUOTES | ENT_HTML5 | ENT_SUBSTITUTE, 'UTF-8');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Escapes string for use inside HTML text.
|
|
42
|
+
*/
|
|
43
|
+
public static function escapeHtmlText($s): string
|
|
44
|
+
{
|
|
45
|
+
if ($s instanceof HtmlStringable || $s instanceof Nette\HtmlStringable) {
|
|
46
|
+
return $s->__toString();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
$s = htmlspecialchars((string) $s, ENT_NOQUOTES | ENT_SUBSTITUTE, 'UTF-8');
|
|
50
|
+
$s = strtr($s, ['{{' => '{<!-- -->{', '{' => '{']);
|
|
51
|
+
return $s;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Escapes string for use inside HTML attribute value.
|
|
57
|
+
*/
|
|
58
|
+
public static function escapeHtmlAttr($s, bool $double = true): string
|
|
59
|
+
{
|
|
60
|
+
$double = $double && $s instanceof HtmlStringable ? false : $double;
|
|
61
|
+
$s = (string) $s;
|
|
62
|
+
if (str_contains($s, '`') && strpbrk($s, ' <>"\'') === false) {
|
|
63
|
+
$s .= ' '; // protection against innerHTML mXSS vulnerability nette/nette#1496
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
$s = htmlspecialchars($s, ENT_QUOTES | ENT_HTML5 | ENT_SUBSTITUTE, 'UTF-8', $double);
|
|
67
|
+
$s = str_replace('{', '{', $s);
|
|
68
|
+
return $s;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Escapes string for use inside HTML tag.
|
|
74
|
+
*/
|
|
75
|
+
public static function escapeHtmlTag($s): string
|
|
76
|
+
{
|
|
77
|
+
$s = (string) $s;
|
|
78
|
+
return preg_match('#^[a-z0-9:-]+$#i', $s)
|
|
79
|
+
? $s
|
|
80
|
+
: '"' . self::escapeHtmlAttr($s) . '"';
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Escapes string for use inside HTML/XML comments.
|
|
86
|
+
*/
|
|
87
|
+
public static function escapeHtmlComment($s): string
|
|
88
|
+
{
|
|
89
|
+
$s = (string) $s;
|
|
90
|
+
if ($s && ($s[0] === '-' || $s[0] === '>' || $s[0] === '!')) {
|
|
91
|
+
$s = ' ' . $s;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
$s = str_replace('--', '- - ', $s);
|
|
95
|
+
if (substr($s, -1) === '-') {
|
|
96
|
+
$s .= ' ';
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return $s;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Escapes string for use everywhere inside XML (except for comments).
|
|
105
|
+
*/
|
|
106
|
+
public static function escapeXml($s): string
|
|
107
|
+
{
|
|
108
|
+
// XML 1.0: \x09 \x0A \x0D and C1 allowed directly, C0 forbidden
|
|
109
|
+
// XML 1.1: \x00 forbidden directly and as a character reference,
|
|
110
|
+
// \x09 \x0A \x0D \x85 allowed directly, C0, C1 and \x7F allowed as character references
|
|
111
|
+
$s = preg_replace('#[\x00-\x08\x0B\x0C\x0E-\x1F]#', "\u{FFFD}", (string) $s);
|
|
112
|
+
return htmlspecialchars($s, ENT_QUOTES | ENT_XML1 | ENT_SUBSTITUTE, 'UTF-8');
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Escapes string for use inside XML attribute name.
|
|
118
|
+
*/
|
|
119
|
+
public static function escapeXmlAttrUnquoted($s): string
|
|
120
|
+
{
|
|
121
|
+
$s = (string) $s;
|
|
122
|
+
return preg_match('#^[a-z0-9:-]+$#i', $s)
|
|
123
|
+
? $s
|
|
124
|
+
: '"' . self::escapeXml($s) . '"';
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Escapes string for use inside CSS template.
|
|
130
|
+
*/
|
|
131
|
+
public static function escapeCss($s): string
|
|
132
|
+
{
|
|
133
|
+
// http://www.w3.org/TR/2006/WD-CSS21-20060411/syndata.html#q6
|
|
134
|
+
return addcslashes((string) $s, "\x00..\x1F!\"#$%&'()*+,./:;<=>?@[\\]^`{|}~");
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Escapes variables for use inside <script>.
|
|
140
|
+
*/
|
|
141
|
+
public static function escapeJs(mixed $s): string
|
|
142
|
+
{
|
|
143
|
+
if ($s instanceof HtmlStringable || $s instanceof Nette\HtmlStringable) {
|
|
144
|
+
$s = $s->__toString();
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
$json = json_encode($s, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_INVALID_UTF8_SUBSTITUTE);
|
|
148
|
+
if ($error = json_last_error()) {
|
|
149
|
+
throw new Latte\RuntimeException(json_last_error_msg(), $error);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return str_replace([']]>', '<!', '</'], [']]\u003E', '\u003C!', '<\/'], $json);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Escapes string for use inside iCal template.
|
|
158
|
+
*/
|
|
159
|
+
public static function escapeICal($s): string
|
|
160
|
+
{
|
|
161
|
+
// https://www.ietf.org/rfc/rfc5545.txt
|
|
162
|
+
$s = str_replace("\r", '', (string) $s);
|
|
163
|
+
$s = preg_replace('#[\x00-\x08\x0B-\x1F]#', "\u{FFFD}", (string) $s);
|
|
164
|
+
return addcslashes($s, "\";\\,:\n");
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Escapes CSS/JS for usage in <script> and <style>..
|
|
170
|
+
*/
|
|
171
|
+
public static function escapeHtmlRawText($s): string
|
|
172
|
+
{
|
|
173
|
+
return preg_replace('#</(script|style)#i', '<\/$1', (string) $s);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Converts ... to ...
|
|
179
|
+
*/
|
|
180
|
+
public static function convertTo(FilterInfo $info, string $dest, string $s): string
|
|
181
|
+
{
|
|
182
|
+
$source = $info->contentType ?: ContentType::Text;
|
|
183
|
+
if ($source === $dest) {
|
|
184
|
+
return $s;
|
|
185
|
+
} elseif ($conv = Latte\Compiler\Escaper::getConvertor($source, $dest)) {
|
|
186
|
+
$info->contentType = $dest;
|
|
187
|
+
return $conv($s);
|
|
188
|
+
} else {
|
|
189
|
+
throw new RuntimeException('Filters: unable to convert content type ' . strtoupper($source) . ' to ' . strtoupper($dest));
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
public static function nop(string $s): string
|
|
195
|
+
{
|
|
196
|
+
return $s;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Converts HTML text to quoted attribute. The quotation marks need to be escaped.
|
|
202
|
+
*/
|
|
203
|
+
public static function convertHtmlToHtmlAttr(string $s): string
|
|
204
|
+
{
|
|
205
|
+
return self::escapeHtmlAttr($s, false);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Converts HTML text to unquoted attribute. The quotation marks need to be escaped.
|
|
211
|
+
*/
|
|
212
|
+
public static function convertHtmlToUnquotedAttr(string $s): string
|
|
213
|
+
{
|
|
214
|
+
return '"' . self::escapeHtmlAttr($s, false) . '"';
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Converts HTML quoted attribute to unquoted.
|
|
220
|
+
*/
|
|
221
|
+
public static function convertHtmlAttrToUnquotedAttr(string $s): string
|
|
222
|
+
{
|
|
223
|
+
return '"' . $s . '"';
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Sanitizes string for use inside href attribute.
|
|
229
|
+
*/
|
|
230
|
+
public static function safeUrl(string $s): string
|
|
231
|
+
{
|
|
232
|
+
return preg_match('~^(?:(?:https?|ftp)://[^@]+(?:/.*)?|(?:mailto|tel|sms):.+|[/?#].*|[^:]+)$~Di', $s) ? $s : '';
|
|
233
|
+
}
|
|
234
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This file is part of the Latte (https://latte.nette.org)
|
|
5
|
+
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
declare(strict_types=1);
|
|
9
|
+
|
|
10
|
+
namespace Latte\Runtime;
|
|
11
|
+
|
|
12
|
+
use Latte;
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* HTML literal.
|
|
17
|
+
*/
|
|
18
|
+
class Html implements HtmlStringable
|
|
19
|
+
{
|
|
20
|
+
use Latte\Strict;
|
|
21
|
+
|
|
22
|
+
private string $value;
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
public function __construct($value)
|
|
26
|
+
{
|
|
27
|
+
$this->value = (string) $value;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
public function __toString(): string
|
|
32
|
+
{
|
|
33
|
+
return $this->value;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This file is part of the Latte (https://latte.nette.org)
|
|
5
|
+
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
declare(strict_types=1);
|
|
9
|
+
|
|
10
|
+
namespace Latte\Runtime;
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
interface HtmlStringable
|
|
14
|
+
{
|
|
15
|
+
/** in HTML format */
|
|
16
|
+
function __toString(): string;
|
|
17
|
+
}
|