@vituum/vite-plugin-latte 2.0.0-next.4 → 2.0.0
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 +1 -1
- package/index.js +4 -2
- package/package.json +11 -9
- package/types/index.d.ts +1 -1
- package/vendor/autoload.php +1 -4
- package/vendor/composer/InstalledVersions.php +36 -2
- package/vendor/composer/autoload_classmap.php +14 -15
- package/vendor/composer/autoload_psr4.php +2 -0
- package/vendor/composer/autoload_static.php +38 -15
- package/vendor/composer/installed.json +32 -22
- package/vendor/composer/installed.php +12 -12
- package/vendor/composer/platform_check.php +4 -5
- package/vendor/latte/latte/bin/latte-lint +10 -3
- package/vendor/latte/latte/composer.json +16 -6
- package/vendor/latte/latte/src/Bridges/Tracy/BlueScreenPanel.php +13 -38
- package/vendor/latte/latte/src/Bridges/Tracy/LattePanel.php +9 -7
- package/vendor/latte/latte/src/Bridges/Tracy/TracyExtension.php +2 -4
- package/vendor/latte/latte/src/Bridges/Tracy/dist/panel.phtml +94 -0
- package/vendor/latte/latte/src/Bridges/Tracy/dist/tab.phtml +10 -0
- package/vendor/latte/latte/src/Latte/Compiler/Block.php +4 -6
- package/vendor/latte/latte/src/Latte/Compiler/Escaper.php +67 -86
- package/vendor/latte/latte/src/Latte/Compiler/Node.php +6 -3
- package/vendor/latte/latte/src/Latte/Compiler/NodeHelpers.php +16 -6
- package/vendor/latte/latte/src/Latte/Compiler/NodeTraverser.php +25 -12
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/AreaNode.php +7 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/AuxiliaryNode.php +5 -4
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/FragmentNode.php +8 -4
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/AttributeNode.php +7 -15
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/BogusTagNode.php +4 -6
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/CommentNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ElementNode.php +37 -67
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ExpressionAttributeNode.php +60 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/TagNode.php +70 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/NopNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ArgumentNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ArrayItemNode.php +4 -15
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ClosureUseNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ComplexTypeNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayAccessNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayNode.php +6 -22
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignNode.php +18 -5
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignOpNode.php +18 -7
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AuxiliaryNode.php +5 -4
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/BinaryOpNode.php +38 -9
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CastNode.php +14 -6
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClassConstantFetchNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CloneNode.php +12 -4
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClosureNode.php +10 -6
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ConstantFetchNode.php +7 -6
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/EmptyNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FilterCallNode.php +10 -4
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallNode.php +14 -5
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InstanceofNode.php +14 -5
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/IssetNode.php +6 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MatchNode.php +6 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallNode.php +18 -5
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/NewNode.php +14 -4
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PostOpNode.php +14 -6
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PreOpNode.php +14 -6
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PropertyFetchNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticMethodCallNode.php +14 -15
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticPropertyFetchNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TemporaryNode.php +7 -6
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TernaryNode.php +16 -11
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/UnaryOpNode.php +19 -9
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/VariableNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ExpressionNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/FilterNode.php +33 -8
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/IdentifierNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/InterpolatedStringPartNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/IntersectionTypeNode.php +6 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ListItemNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ListNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/MatchArmNode.php +6 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ModifierNode.php +29 -41
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NameNode.php +9 -4
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NullableTypeNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/OperatorNode.php +27 -0
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ParameterNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/BooleanNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/FloatNode.php +9 -6
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/IntegerNode.php +8 -6
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/InterpolatedStringNode.php +9 -5
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/NullNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/StringNode.php +6 -4
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ScalarNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/SuperiorTypeNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/UnionTypeNode.php +6 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/VarLikeIdentifierNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/{Expression/NotNode.php → VariadicPlaceholderNode.php} +9 -9
- package/vendor/latte/latte/src/Latte/{Essential → Compiler}/Nodes/PrintNode.php +9 -15
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/StatementNode.php +7 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/TemplateNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/TextNode.php +6 -4
- package/vendor/latte/latte/src/Latte/Compiler/PhpHelpers.php +32 -18
- package/vendor/latte/latte/src/Latte/Compiler/Position.php +7 -7
- package/vendor/latte/latte/src/Latte/Compiler/PrintContext.php +72 -104
- package/vendor/latte/latte/src/Latte/Compiler/Tag.php +17 -16
- package/vendor/latte/latte/src/Latte/Compiler/TagLexer.php +11 -8
- package/vendor/latte/latte/src/Latte/Compiler/TagParser.php +28 -23
- package/vendor/latte/latte/src/Latte/Compiler/TagParserData.php +360 -336
- package/vendor/latte/latte/src/Latte/Compiler/TemplateGenerator.php +49 -38
- package/vendor/latte/latte/src/Latte/Compiler/TemplateLexer.php +37 -12
- package/vendor/latte/latte/src/Latte/Compiler/TemplateParser.php +35 -21
- package/vendor/latte/latte/src/Latte/Compiler/TemplateParserHtml.php +121 -71
- package/vendor/latte/latte/src/Latte/Compiler/Token.php +79 -70
- package/vendor/latte/latte/src/Latte/Compiler/TokenStream.php +21 -14
- package/vendor/latte/latte/src/Latte/ContentType.php +4 -3
- package/vendor/latte/latte/src/Latte/Engine.php +147 -188
- package/vendor/latte/latte/src/Latte/Essential/AuxiliaryIterator.php +5 -7
- package/vendor/latte/latte/src/Latte/Essential/Blueprint.php +5 -5
- package/vendor/latte/latte/src/Latte/Essential/CachingIterator.php +5 -4
- package/vendor/latte/latte/src/Latte/Essential/CoreExtension.php +155 -127
- package/vendor/latte/latte/src/Latte/Essential/Filters.php +99 -44
- package/vendor/latte/latte/src/Latte/Essential/Nodes/BlockNode.php +14 -13
- package/vendor/latte/latte/src/Latte/Essential/Nodes/CaptureNode.php +5 -6
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ContentTypeNode.php +3 -4
- package/vendor/latte/latte/src/Latte/Essential/Nodes/CustomFunctionCallNode.php +46 -0
- package/vendor/latte/latte/src/Latte/Essential/Nodes/DebugbreakNode.php +2 -3
- package/vendor/latte/latte/src/Latte/Essential/Nodes/DefineNode.php +10 -7
- package/vendor/latte/latte/src/Latte/Essential/Nodes/DoNode.php +3 -4
- package/vendor/latte/latte/src/Latte/Essential/Nodes/DumpNode.php +2 -3
- package/vendor/latte/latte/src/Latte/Essential/Nodes/EmbedNode.php +8 -9
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ExtendsNode.php +3 -5
- package/vendor/latte/latte/src/Latte/Essential/Nodes/FirstLastSepNode.php +4 -7
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ForNode.php +6 -5
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ForeachNode.php +7 -7
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IfChangedNode.php +4 -5
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IfContentNode.php +7 -6
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IfNode.php +11 -11
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ImportNode.php +5 -6
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeBlockNode.php +26 -27
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeFileNode.php +7 -10
- package/vendor/latte/latte/src/Latte/Essential/Nodes/IterateWhileNode.php +6 -6
- package/vendor/latte/latte/src/Latte/Essential/Nodes/JumpNode.php +4 -8
- package/vendor/latte/latte/src/Latte/Essential/Nodes/NAttrNode.php +35 -47
- package/vendor/latte/latte/src/Latte/Essential/Nodes/NClassNode.php +4 -5
- package/vendor/latte/latte/src/Latte/Essential/Nodes/NElseNode.php +69 -34
- package/vendor/latte/latte/src/Latte/Essential/Nodes/NTagNode.php +9 -33
- package/vendor/latte/latte/src/Latte/Essential/Nodes/ParametersNode.php +7 -4
- package/vendor/latte/latte/src/Latte/Essential/Nodes/RawPhpNode.php +3 -4
- package/vendor/latte/latte/src/Latte/Essential/Nodes/RollbackNode.php +2 -3
- package/vendor/latte/latte/src/Latte/Essential/Nodes/SpacelessNode.php +4 -5
- package/vendor/latte/latte/src/Latte/Essential/Nodes/SwitchNode.php +9 -7
- package/vendor/latte/latte/src/Latte/Essential/Nodes/TemplatePrintNode.php +4 -4
- package/vendor/latte/latte/src/Latte/Essential/Nodes/TemplateTypeNode.php +3 -4
- package/vendor/latte/latte/src/Latte/Essential/Nodes/TraceNode.php +2 -3
- package/vendor/latte/latte/src/Latte/Essential/Nodes/TranslateNode.php +5 -5
- package/vendor/latte/latte/src/Latte/Essential/Nodes/TryNode.php +4 -5
- package/vendor/latte/latte/src/Latte/Essential/Nodes/VarNode.php +10 -6
- package/vendor/latte/latte/src/Latte/Essential/Nodes/VarPrintNode.php +2 -3
- package/vendor/latte/latte/src/Latte/Essential/Nodes/VarTypeNode.php +3 -4
- package/vendor/latte/latte/src/Latte/Essential/Nodes/WhileNode.php +5 -5
- package/vendor/latte/latte/src/Latte/Essential/Passes.php +82 -21
- package/vendor/latte/latte/src/Latte/Essential/RawPhpExtension.php +2 -4
- package/vendor/latte/latte/src/Latte/Essential/RollbackException.php +1 -3
- package/vendor/latte/latte/src/Latte/Essential/Tracer.php +24 -28
- package/vendor/latte/latte/src/Latte/Essential/TranslatorExtension.php +14 -14
- package/vendor/latte/latte/src/Latte/Extension.php +12 -6
- package/vendor/latte/latte/src/Latte/Feature.php +24 -0
- package/vendor/latte/latte/src/Latte/Helpers.php +65 -15
- package/vendor/latte/latte/src/Latte/Loader.php +1 -9
- package/vendor/latte/latte/src/Latte/Loaders/FileLoader.php +11 -17
- package/vendor/latte/latte/src/Latte/Loaders/StringLoader.php +7 -21
- package/vendor/latte/latte/src/Latte/Policy.php +4 -3
- package/vendor/latte/latte/src/Latte/Runtime/Block.php +2 -4
- package/vendor/latte/latte/src/Latte/Runtime/Cache.php +143 -0
- package/vendor/latte/latte/src/Latte/Runtime/FilterExecutor.php +5 -6
- package/vendor/latte/latte/src/Latte/Runtime/FilterInfo.php +11 -11
- package/vendor/latte/latte/src/Latte/Runtime/FunctionExecutor.php +5 -6
- package/vendor/latte/latte/src/Latte/Runtime/Helpers.php +91 -0
- package/vendor/latte/latte/src/Latte/Runtime/Html.php +3 -5
- package/vendor/latte/latte/src/Latte/Runtime/HtmlHelpers.php +374 -0
- package/vendor/latte/latte/src/Latte/Runtime/HtmlStringable.php +1 -3
- package/vendor/latte/latte/src/Latte/Runtime/Template.php +162 -182
- package/vendor/latte/latte/src/Latte/Runtime/XmlHelpers.php +108 -0
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/FunctionCallNode.php +12 -4
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/MethodCallNode.php +15 -5
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/PropertyFetchNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/SandboxNode.php +5 -6
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticMethodCallNode.php +14 -4
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticPropertyFetchNode.php +4 -3
- package/vendor/latte/latte/src/Latte/Sandbox/RuntimeChecker.php +8 -6
- package/vendor/latte/latte/src/Latte/Sandbox/SandboxExtension.php +16 -12
- package/vendor/latte/latte/src/Latte/Sandbox/SecurityPolicy.php +18 -16
- package/vendor/latte/latte/src/Latte/attributes.php +7 -3
- package/vendor/latte/latte/src/Latte/exceptions.php +52 -6
- package/vendor/latte/latte/src/Tools/Linter.php +74 -28
- package/vendor/latte/latte/src/Tools/LinterExtension.php +176 -0
- package/vendor/nette/utils/composer.json +15 -5
- package/vendor/nette/utils/readme.md +1 -1
- package/vendor/nette/utils/src/HtmlStringable.php +4 -1
- package/vendor/nette/utils/src/Iterators/CachingIterator.php +10 -25
- package/vendor/nette/utils/src/Iterators/Mapper.php +2 -3
- package/vendor/nette/utils/src/SmartObject.php +3 -0
- package/vendor/nette/utils/src/StaticClass.php +1 -11
- package/vendor/nette/utils/src/Translator.php +1 -1
- package/vendor/nette/utils/src/Utils/ArrayHash.php +6 -10
- package/vendor/nette/utils/src/Utils/ArrayList.php +8 -12
- package/vendor/nette/utils/src/Utils/Arrays.php +38 -18
- package/vendor/nette/utils/src/Utils/Callback.php +13 -8
- package/vendor/nette/utils/src/Utils/DateTime.php +95 -26
- package/vendor/nette/utils/src/Utils/FileInfo.php +6 -7
- package/vendor/nette/utils/src/Utils/FileSystem.php +10 -5
- package/vendor/nette/utils/src/Utils/Finder.php +31 -12
- package/vendor/nette/utils/src/Utils/Floats.php +1 -0
- package/vendor/nette/utils/src/Utils/Helpers.php +22 -2
- package/vendor/nette/utils/src/Utils/Html.php +130 -127
- package/vendor/nette/utils/src/Utils/Image.php +80 -60
- package/vendor/nette/utils/src/Utils/ImageColor.php +5 -0
- package/vendor/nette/utils/src/Utils/ImageType.php +2 -0
- package/vendor/nette/utils/src/Utils/Iterables.php +41 -7
- package/vendor/nette/utils/src/Utils/Json.php +2 -0
- package/vendor/nette/utils/src/Utils/ObjectHelpers.php +2 -0
- package/vendor/nette/utils/src/Utils/Paginator.php +10 -43
- package/vendor/nette/utils/src/Utils/Random.php +2 -0
- package/vendor/nette/utils/src/Utils/Reflection.php +22 -15
- package/vendor/nette/utils/src/Utils/ReflectionMethod.php +6 -1
- package/vendor/nette/utils/src/Utils/Strings.php +62 -57
- package/vendor/nette/utils/src/Utils/Type.php +91 -42
- package/vendor/nette/utils/src/Utils/Validators.php +9 -7
- package/vendor/latte/latte/src/Bridges/Tracy/templates/LattePanel.panel.phtml +0 -101
- package/vendor/latte/latte/src/Bridges/Tracy/templates/LattePanel.tab.phtml +0 -15
- package/vendor/latte/latte/src/Latte/Compiler/ExpressionBuilder.php +0 -129
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ErrorSuppressNode.php +0 -36
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallableNode.php +0 -39
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallableNode.php +0 -42
- package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticMethodCallableNode.php +0 -57
- package/vendor/latte/latte/src/Latte/PositionAwareException.php +0 -47
- package/vendor/latte/latte/src/Latte/Runtime/Filters.php +0 -283
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/FunctionCallableNode.php +0 -29
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/MethodCallableNode.php +0 -30
- package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticMethodCallableNode.php +0 -30
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
<?php
|
|
1
|
+
<?php declare(strict_types=1);
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* This file is part of the Latte (https://latte.nette.org)
|
|
5
5
|
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
declare(strict_types=1);
|
|
9
|
-
|
|
10
8
|
namespace Latte\Runtime;
|
|
11
9
|
|
|
12
10
|
use Latte;
|
|
11
|
+
use function in_array, strtoupper;
|
|
13
12
|
|
|
14
13
|
|
|
15
14
|
/**
|
|
16
|
-
*
|
|
15
|
+
* Content type context for contextual filters.
|
|
17
16
|
*/
|
|
18
17
|
class FilterInfo
|
|
19
18
|
{
|
|
20
|
-
public
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
public function __construct(?string $contentType = null)
|
|
24
|
-
{
|
|
25
|
-
$this->contentType = $contentType;
|
|
19
|
+
public function __construct(
|
|
20
|
+
public ?string $contentType = null,
|
|
21
|
+
) {
|
|
26
22
|
}
|
|
27
23
|
|
|
28
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Validates content type is allowed for this filter.
|
|
27
|
+
* @param list<string|null> $contentTypes
|
|
28
|
+
*/
|
|
29
29
|
public function validate(array $contentTypes, ?string $name = null): void
|
|
30
30
|
{
|
|
31
|
-
if (!in_array($this->contentType, $contentTypes, true)) {
|
|
31
|
+
if (!in_array($this->contentType, $contentTypes, strict: true)) {
|
|
32
32
|
$name = $name ? " |$name" : $name;
|
|
33
33
|
$type = $this->contentType ? ' ' . strtoupper($this->contentType) : '';
|
|
34
34
|
throw new Latte\RuntimeException("Filter{$name} used with incompatible type{$type}.");
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
<?php
|
|
1
|
+
<?php declare(strict_types=1);
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* This file is part of the Latte (https://latte.nette.org)
|
|
5
5
|
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
declare(strict_types=1);
|
|
9
|
-
|
|
10
8
|
namespace Latte\Runtime;
|
|
11
9
|
|
|
12
10
|
use Latte\Helpers;
|
|
11
|
+
use function array_keys;
|
|
13
12
|
|
|
14
13
|
|
|
15
14
|
/**
|
|
@@ -19,10 +18,10 @@ use Latte\Helpers;
|
|
|
19
18
|
#[\AllowDynamicProperties]
|
|
20
19
|
class FunctionExecutor
|
|
21
20
|
{
|
|
22
|
-
/** @var callable
|
|
21
|
+
/** @var array<string, callable> */
|
|
23
22
|
private array $_list = [];
|
|
24
23
|
|
|
25
|
-
/** @var bool
|
|
24
|
+
/** @var array<string, bool> */
|
|
26
25
|
private array $_aware = [];
|
|
27
26
|
|
|
28
27
|
|
|
@@ -39,7 +38,7 @@ class FunctionExecutor
|
|
|
39
38
|
|
|
40
39
|
/**
|
|
41
40
|
* Returns all run-time functions.
|
|
42
|
-
* @return callable
|
|
41
|
+
* @return array<string, callable>
|
|
43
42
|
*/
|
|
44
43
|
public function getAll(): array
|
|
45
44
|
{
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
<?php declare(strict_types=1);
|
|
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
|
+
namespace Latte\Runtime;
|
|
9
|
+
|
|
10
|
+
use Latte;
|
|
11
|
+
use Latte\ContentType;
|
|
12
|
+
use Latte\RuntimeException;
|
|
13
|
+
use Nette;
|
|
14
|
+
use function addcslashes, is_string, json_encode, preg_replace, str_replace, strtoupper;
|
|
15
|
+
use const JSON_INVALID_UTF8_SUBSTITUTE, JSON_THROW_ON_ERROR, JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE;
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Template runtime helpers.
|
|
20
|
+
* @internal
|
|
21
|
+
*/
|
|
22
|
+
class Helpers
|
|
23
|
+
{
|
|
24
|
+
/**
|
|
25
|
+
* Ensures the value is a string or returns null.
|
|
26
|
+
* @return ($value is string ? string : null)
|
|
27
|
+
*/
|
|
28
|
+
public static function stringOrNull(mixed $value): ?string
|
|
29
|
+
{
|
|
30
|
+
return is_string($value) ? $value : null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Escapes string for use inside CSS template.
|
|
36
|
+
*/
|
|
37
|
+
public static function escapeCss(mixed $s): string
|
|
38
|
+
{
|
|
39
|
+
// http://www.w3.org/TR/2006/WD-CSS21-20060411/syndata.html#q6
|
|
40
|
+
return addcslashes((string) $s, "\x00..\x1F!\"#$%&'()*+,./:;<=>?@[\\]^`{|}~");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Escapes variables for use inside <script>.
|
|
46
|
+
*/
|
|
47
|
+
public static function escapeJs(mixed $s): string
|
|
48
|
+
{
|
|
49
|
+
if ($s instanceof HtmlStringable || $s instanceof Nette\HtmlStringable) {
|
|
50
|
+
$s = $s->__toString();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
$json = json_encode($s, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_INVALID_UTF8_SUBSTITUTE | JSON_THROW_ON_ERROR);
|
|
54
|
+
return str_replace([']]>', '<!', '</'], [']]\u003E', '\u003C!', '<\/'], $json);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Escapes string for use inside iCal template.
|
|
60
|
+
*/
|
|
61
|
+
public static function escapeICal(mixed $s): string
|
|
62
|
+
{
|
|
63
|
+
// https://www.ietf.org/rfc/rfc5545.txt
|
|
64
|
+
$s = str_replace("\r", '', (string) $s);
|
|
65
|
+
$s = preg_replace('#[\x00-\x08\x0B-\x1F]#', "\u{FFFD}", (string) $s);
|
|
66
|
+
return addcslashes($s, "\";\\,:\n");
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Converts content between content types.
|
|
72
|
+
*/
|
|
73
|
+
public static function convertTo(FilterInfo $info, string $dest, string $s): string
|
|
74
|
+
{
|
|
75
|
+
$source = $info->contentType ?: ContentType::Text;
|
|
76
|
+
if ($source === $dest) {
|
|
77
|
+
return $s;
|
|
78
|
+
} elseif ($conv = Latte\Compiler\Escaper::getConvertor($source, $dest)) {
|
|
79
|
+
$info->contentType = $dest;
|
|
80
|
+
return $conv($s);
|
|
81
|
+
} else {
|
|
82
|
+
throw new RuntimeException('Filters: unable to convert content type ' . strtoupper($source) . ' to ' . strtoupper($dest));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
public static function nop(mixed $s): string
|
|
88
|
+
{
|
|
89
|
+
return (string) $s;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
<?php
|
|
1
|
+
<?php declare(strict_types=1);
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* This file is part of the Latte (https://latte.nette.org)
|
|
5
5
|
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
declare(strict_types=1);
|
|
9
|
-
|
|
10
8
|
namespace Latte\Runtime;
|
|
11
9
|
|
|
12
10
|
|
|
@@ -15,10 +13,10 @@ namespace Latte\Runtime;
|
|
|
15
13
|
*/
|
|
16
14
|
class Html implements HtmlStringable
|
|
17
15
|
{
|
|
18
|
-
private string $value;
|
|
16
|
+
private readonly string $value;
|
|
19
17
|
|
|
20
18
|
|
|
21
|
-
public function __construct($value)
|
|
19
|
+
public function __construct(string|\Stringable|null $value)
|
|
22
20
|
{
|
|
23
21
|
$this->value = (string) $value;
|
|
24
22
|
}
|
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
<?php declare(strict_types=1);
|
|
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
|
+
namespace Latte\Runtime;
|
|
9
|
+
|
|
10
|
+
use Latte;
|
|
11
|
+
use Latte\ContentType;
|
|
12
|
+
use Nette;
|
|
13
|
+
use function get_debug_type, html_entity_decode, htmlspecialchars, in_array, is_array, is_bool, is_float, is_int, is_string, ord, preg_match, preg_replace, preg_replace_callback, str_replace, strip_tags, strtolower, strtr;
|
|
14
|
+
use const ENT_HTML5, ENT_NOQUOTES, ENT_QUOTES, ENT_SUBSTITUTE, JSON_INVALID_UTF8_SUBSTITUTE, JSON_THROW_ON_ERROR, JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE;
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Runtime utilities for handling HTML.
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
21
|
+
final class HtmlHelpers
|
|
22
|
+
{
|
|
23
|
+
private const BooleanAttributes = [
|
|
24
|
+
'allowfullscreen' => 1, 'async' => 1, 'autofocus' => 1, 'autoplay' => 1, 'checked' => 1, 'controls' => 1,
|
|
25
|
+
'contenteditable' => 1, 'default' => 1, 'defer' => 1, 'disabled' => 1, 'draggable' => 1, 'formnovalidate' => 1,
|
|
26
|
+
'hidden' => 1, 'inert' => 1, 'ismap' => 1, 'itemscope' => 1, 'loop' => 1, 'multiple' => 1, 'muted' => 1,
|
|
27
|
+
'nomodule' => 1, 'novalidate' => 1, 'open' => 1, 'playsinline' => 1, 'readonly' => 1, 'required' => 1,
|
|
28
|
+
'reversed' => 1, 'selected' => 1, 'spellcheck' => 1,
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
private const SpaceSeparatedAttributes = [
|
|
32
|
+
'accesskey' => 1, 'class' => 1, 'headers' => 1, 'itemprop' => 1, 'ping' => 1, 'rel' => 1, 'role' => 1, 'sandbox' => 1,
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Escapes string for use inside HTML text.
|
|
38
|
+
*/
|
|
39
|
+
public static function escapeText(mixed $s): string
|
|
40
|
+
{
|
|
41
|
+
if ($s instanceof HtmlStringable || $s instanceof Nette\HtmlStringable) {
|
|
42
|
+
return $s->__toString();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
$s = htmlspecialchars((string) $s, ENT_NOQUOTES | ENT_SUBSTITUTE, 'UTF-8');
|
|
46
|
+
$s = strtr($s, ['{{' => '{<!-- -->{', '{' => '{']);
|
|
47
|
+
return $s;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Escapes string for use inside HTML attribute value.
|
|
53
|
+
*/
|
|
54
|
+
public static function escapeAttr(mixed $s): string
|
|
55
|
+
{
|
|
56
|
+
if ($s instanceof HtmlStringable) {
|
|
57
|
+
$s = self::convertHtmlToText($s->__toString());
|
|
58
|
+
}
|
|
59
|
+
$s = (string) $s;
|
|
60
|
+
$s = htmlspecialchars($s, ENT_QUOTES | ENT_HTML5 | ENT_SUBSTITUTE, 'UTF-8');
|
|
61
|
+
$s = str_replace('{', '{', $s);
|
|
62
|
+
return $s;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Escapes string for use inside HTML tag.
|
|
68
|
+
*/
|
|
69
|
+
public static function escapeTag(mixed $s): string
|
|
70
|
+
{
|
|
71
|
+
$s = (string) $s;
|
|
72
|
+
$s = htmlspecialchars($s, ENT_QUOTES | ENT_HTML5 | ENT_SUBSTITUTE, 'UTF-8');
|
|
73
|
+
return preg_replace_callback(
|
|
74
|
+
'#[=/\s]#',
|
|
75
|
+
fn($m) => '&#' . ord($m[0]) . ';',
|
|
76
|
+
$s,
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Escapes string for use inside HTML/XML comments.
|
|
83
|
+
*/
|
|
84
|
+
public static function escapeComment(mixed $s): string
|
|
85
|
+
{
|
|
86
|
+
$s = (string) $s;
|
|
87
|
+
if ($s && ($s[0] === '-' || $s[0] === '>' || $s[0] === '!')) {
|
|
88
|
+
$s = ' ' . $s;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
$s = str_replace('--', '- - ', $s);
|
|
92
|
+
if (str_ends_with($s, '-')) {
|
|
93
|
+
$s .= ' ';
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return $s;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Escapes HTML for usage in <script type=text/html>
|
|
102
|
+
*/
|
|
103
|
+
public static function escapeRawHtml(mixed $s): string
|
|
104
|
+
{
|
|
105
|
+
if ($s instanceof HtmlStringable || $s instanceof Nette\HtmlStringable) {
|
|
106
|
+
return self::convertHtmlToRawText($s->__toString());
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return htmlspecialchars((string) $s, ENT_QUOTES | ENT_HTML5 | ENT_SUBSTITUTE, 'UTF-8');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Escapes only quotes.
|
|
115
|
+
*/
|
|
116
|
+
public static function escapeQuotes(mixed $s): string
|
|
117
|
+
{
|
|
118
|
+
return strtr((string) $s, ['"' => '"', "'" => ''']);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Converts JS and CSS for usage in <script> or <style>
|
|
124
|
+
*/
|
|
125
|
+
public static function convertJSToRawText(mixed $s): string
|
|
126
|
+
{
|
|
127
|
+
return preg_replace('#</(script|style)#i', '<\/$1', (string) $s);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Sanitizes <script> in <script type=text/html>
|
|
133
|
+
*/
|
|
134
|
+
public static function convertHtmlToRawText(string $s): string
|
|
135
|
+
{
|
|
136
|
+
return preg_replace('#(</?)(script)#i', '$1x-$2', $s);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Converts HTML text to quoted attribute.
|
|
142
|
+
*/
|
|
143
|
+
public static function convertHtmlToAttr(string $s): string
|
|
144
|
+
{
|
|
145
|
+
return self::escapeAttr(self::convertHtmlToText($s));
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Converts HTML attribute to HTML text. The < > chars need to be escaped.
|
|
151
|
+
*/
|
|
152
|
+
public static function convertAttrToHtml(string $s): string
|
|
153
|
+
{
|
|
154
|
+
return self::escapeAttr(html_entity_decode($s, ENT_QUOTES | ENT_HTML5, 'UTF-8'));
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Converts HTML to plain text.
|
|
160
|
+
*/
|
|
161
|
+
public static function convertHtmlToText(string $s): string
|
|
162
|
+
{
|
|
163
|
+
$s = strip_tags($s);
|
|
164
|
+
return html_entity_decode($s, ENT_QUOTES | ENT_HTML5, 'UTF-8');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
public static function classifyAttributeType(string $name): string
|
|
169
|
+
{
|
|
170
|
+
$name = strtolower($name);
|
|
171
|
+
return match (true) {
|
|
172
|
+
isset(self::BooleanAttributes[$name]) => 'bool',
|
|
173
|
+
isset(self::SpaceSeparatedAttributes[$name]) => 'list',
|
|
174
|
+
str_starts_with($name, 'data-') => 'data',
|
|
175
|
+
str_starts_with($name, 'aria-') => 'aria',
|
|
176
|
+
$name === 'style' => 'style',
|
|
177
|
+
default => '',
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Formats common HTML attribute.
|
|
184
|
+
*/
|
|
185
|
+
public static function formatAttribute(string $namePart, mixed $value, bool $migrationWarnings = false): string
|
|
186
|
+
{
|
|
187
|
+
if ($migrationWarnings) {
|
|
188
|
+
if ($value === null) {
|
|
189
|
+
self::triggerMigrationWarning(trim($namePart), $value);
|
|
190
|
+
} elseif (is_string($value) && str_starts_with($name = ltrim($namePart), 'on')) {
|
|
191
|
+
self::triggerMigrationWarning($name, 'string value: previously it was JSON-encoded, now it is rendered as a string');
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return match (true) {
|
|
195
|
+
is_string($value), is_int($value), is_float($value), $value instanceof \Stringable => $namePart . '="' . self::escapeAttr($value) . '"',
|
|
196
|
+
$value === null => '',
|
|
197
|
+
default => self::triggerInvalidValue(trim($namePart), $value),
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Formats boolean HTML attribute.
|
|
204
|
+
*/
|
|
205
|
+
public static function formatBoolAttribute(string $namePart, mixed $value): string
|
|
206
|
+
{
|
|
207
|
+
return $value ? $namePart : '';
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Formats space separated HTML attribute.
|
|
213
|
+
*/
|
|
214
|
+
public static function formatListAttribute(string $namePart, mixed $value): string
|
|
215
|
+
{
|
|
216
|
+
return match (true) {
|
|
217
|
+
is_array($value) => self::formatArrayAttribute($namePart, $value, fn($v, $k) => $v === true ? $k : $v, ' '),
|
|
218
|
+
default => self::formatAttribute($namePart, $value),
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Formats HTML attribute 'style'.
|
|
225
|
+
*/
|
|
226
|
+
public static function formatStyleAttribute(string $namePart, mixed $value): string
|
|
227
|
+
{
|
|
228
|
+
return match (true) {
|
|
229
|
+
is_array($value) => self::formatArrayAttribute($namePart, $value, fn($v, $k) => is_string($k) ? $k . ': ' . $v : $v, '; '),
|
|
230
|
+
default => self::formatAttribute($namePart, $value),
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Formats data-* HTML attribute.
|
|
237
|
+
*/
|
|
238
|
+
public static function formatDataAttribute(string $namePart, mixed $value, bool $migrationWarnings = false): string
|
|
239
|
+
{
|
|
240
|
+
if ($migrationWarnings && (is_bool($value) || $value === null)) {
|
|
241
|
+
self::triggerMigrationWarning(trim($namePart), $value);
|
|
242
|
+
}
|
|
243
|
+
$escape = fn($value) => str_contains($value, '"')
|
|
244
|
+
? "'" . str_replace(['&', "'"], ['&', '''], $value) . "'"
|
|
245
|
+
: '"' . str_replace(['&', '"'], ['&', '"'], $value) . '"';
|
|
246
|
+
return match (true) {
|
|
247
|
+
is_bool($value) => $namePart . '="' . ($value ? 'true' : 'false') . '"',
|
|
248
|
+
is_array($value) || $value instanceof \stdClass => $namePart . '=' . $escape(json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_INVALID_UTF8_SUBSTITUTE | JSON_THROW_ON_ERROR)),
|
|
249
|
+
default => self::formatAttribute($namePart, $value),
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Formats aria-* HTML attribute.
|
|
256
|
+
*/
|
|
257
|
+
public static function formatAriaAttribute(string $namePart, mixed $value, bool $migrationWarnings = false): string
|
|
258
|
+
{
|
|
259
|
+
if ($migrationWarnings && is_bool($value)) {
|
|
260
|
+
self::triggerMigrationWarning(trim($namePart), $value);
|
|
261
|
+
}
|
|
262
|
+
return match (true) {
|
|
263
|
+
is_bool($value) => $namePart . '="' . ($value ? 'true' : 'false') . '"',
|
|
264
|
+
is_array($value) => self::formatArrayAttribute($namePart, $value, fn($v, $k) => $v === true ? $k : $v, ' '),
|
|
265
|
+
default => self::formatAttribute($namePart, $value),
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
/** @param array<mixed> $items */
|
|
271
|
+
private static function formatArrayAttribute(string $namePart, array $items, \Closure $cb, string $separator): string
|
|
272
|
+
{
|
|
273
|
+
$res = [];
|
|
274
|
+
foreach ($items as $k => $v) {
|
|
275
|
+
if ($v != null) { // intentionally ==, skip nulls & empty string
|
|
276
|
+
$res[] = $cb($v, $k);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return $res ? $namePart . '="' . self::escapeAttr(implode($separator, $res)) . '"' : '';
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
public static function triggerInvalidValue(string $name, mixed $value): string
|
|
284
|
+
{
|
|
285
|
+
$source = Latte\Helpers::guessTemplatePosition();
|
|
286
|
+
$type = get_debug_type($value);
|
|
287
|
+
trigger_error("Invalid value for attribute '$name': $type is not allowed" . ($source ? " ($source)" : '.'), E_USER_WARNING);
|
|
288
|
+
return '';
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
public static function triggerMigrationWarning(string $name, mixed $value): void
|
|
293
|
+
{
|
|
294
|
+
$source = Latte\Helpers::guessTemplatePosition();
|
|
295
|
+
$message = match ($value) {
|
|
296
|
+
null => "value null: previously it rendered as $name=\"\", now the attribute is omitted",
|
|
297
|
+
true => "value true: previously it rendered as $name=\"1\", now it renders as $name=\"true\"",
|
|
298
|
+
false => "value false: previously it rendered as $name=\"\", now it renders as $name=\"false\"",
|
|
299
|
+
default => $value,
|
|
300
|
+
};
|
|
301
|
+
trigger_error("Behavior change for attribute '$name' with $message" . ($source ? " ($source)" : '.'), E_USER_WARNING);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Checks if the given tag name represents a void (empty) HTML element.
|
|
307
|
+
*/
|
|
308
|
+
public static function isVoidElement(string $name): bool
|
|
309
|
+
{
|
|
310
|
+
static $names = [
|
|
311
|
+
'img' => 1, 'hr' => 1, 'br' => 1, 'input' => 1, 'meta' => 1, 'area' => 1, 'embed' => 1, 'keygen' => 1, 'source' => 1, 'base' => 1,
|
|
312
|
+
'col' => 1, 'link' => 1, 'param' => 1, 'basefont' => 1, 'frame' => 1, 'isindex' => 1, 'wbr' => 1, 'command' => 1, 'track' => 1,
|
|
313
|
+
];
|
|
314
|
+
return isset($names[strtolower($name)]);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Determines if the given HTML attribute is a URL attribute that requires special handling.
|
|
320
|
+
*/
|
|
321
|
+
public static function isUrlAttribute(string $tag, string $attr): bool
|
|
322
|
+
{
|
|
323
|
+
$attr = strtolower($attr);
|
|
324
|
+
return in_array($attr, ['href', 'src', 'action', 'formaction'], strict: true)
|
|
325
|
+
|| ($attr === 'data' && strtolower($tag) === 'object');
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Classifies script content type based on the MIME type.
|
|
331
|
+
*/
|
|
332
|
+
public static function classifyScriptType(string $type): string
|
|
333
|
+
{
|
|
334
|
+
if (preg_match('#((application|text)/(((x-)?java|ecma|j|live)script|json)|application/.+\+json|text/plain|module|importmap|)$#Ai', $type)) {
|
|
335
|
+
return ContentType::JavaScript;
|
|
336
|
+
|
|
337
|
+
} elseif (preg_match('#text/((x-)?template|html)$#Ai', $type)) {
|
|
338
|
+
return ContentType::Html;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
return ContentType::Text;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Checks that the HTML tag name can be changed.
|
|
347
|
+
*/
|
|
348
|
+
public static function validateTagChange(mixed $name, ?string $origName = null): string
|
|
349
|
+
{
|
|
350
|
+
$name ??= $origName;
|
|
351
|
+
if (!is_string($name)) {
|
|
352
|
+
throw new Latte\RuntimeException('Tag name must be string, ' . get_debug_type($name) . ' given');
|
|
353
|
+
|
|
354
|
+
} elseif (!preg_match('~' . Latte\Compiler\TemplateLexer::ReTagName . '$~DAu', $name)) {
|
|
355
|
+
throw new Latte\RuntimeException("Invalid tag name '$name'");
|
|
356
|
+
|
|
357
|
+
} elseif (self::isVoidElement($name) !== self::isVoidElement($origName ?? 'div') // non-void is default
|
|
358
|
+
|| in_array(strtolower($name), ['style', 'script'], strict: true)) {
|
|
359
|
+
throw new Latte\RuntimeException("Forbidden: Cannot change element to <$name>");
|
|
360
|
+
}
|
|
361
|
+
return $name;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
public static function validateAttributeName(mixed $name): void
|
|
366
|
+
{
|
|
367
|
+
if (!is_string($name)) {
|
|
368
|
+
throw new Latte\RuntimeException('Attribute name must be string, ' . get_debug_type($name) . ' given');
|
|
369
|
+
|
|
370
|
+
} elseif (!preg_match('~' . Latte\Compiler\TemplateLexer::ReAttrName . '+$~DAu', $name)) {
|
|
371
|
+
throw new Latte\RuntimeException("Invalid attribute name '$name'");
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|