@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.
Files changed (234) hide show
  1. package/README.md +1 -1
  2. package/index.js +4 -2
  3. package/package.json +11 -9
  4. package/types/index.d.ts +1 -1
  5. package/vendor/autoload.php +1 -4
  6. package/vendor/composer/InstalledVersions.php +36 -2
  7. package/vendor/composer/autoload_classmap.php +14 -15
  8. package/vendor/composer/autoload_psr4.php +2 -0
  9. package/vendor/composer/autoload_static.php +38 -15
  10. package/vendor/composer/installed.json +32 -22
  11. package/vendor/composer/installed.php +12 -12
  12. package/vendor/composer/platform_check.php +4 -5
  13. package/vendor/latte/latte/bin/latte-lint +10 -3
  14. package/vendor/latte/latte/composer.json +16 -6
  15. package/vendor/latte/latte/src/Bridges/Tracy/BlueScreenPanel.php +13 -38
  16. package/vendor/latte/latte/src/Bridges/Tracy/LattePanel.php +9 -7
  17. package/vendor/latte/latte/src/Bridges/Tracy/TracyExtension.php +2 -4
  18. package/vendor/latte/latte/src/Bridges/Tracy/dist/panel.phtml +94 -0
  19. package/vendor/latte/latte/src/Bridges/Tracy/dist/tab.phtml +10 -0
  20. package/vendor/latte/latte/src/Latte/Compiler/Block.php +4 -6
  21. package/vendor/latte/latte/src/Latte/Compiler/Escaper.php +67 -86
  22. package/vendor/latte/latte/src/Latte/Compiler/Node.php +6 -3
  23. package/vendor/latte/latte/src/Latte/Compiler/NodeHelpers.php +16 -6
  24. package/vendor/latte/latte/src/Latte/Compiler/NodeTraverser.php +25 -12
  25. package/vendor/latte/latte/src/Latte/Compiler/Nodes/AreaNode.php +7 -3
  26. package/vendor/latte/latte/src/Latte/Compiler/Nodes/AuxiliaryNode.php +5 -4
  27. package/vendor/latte/latte/src/Latte/Compiler/Nodes/FragmentNode.php +8 -4
  28. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/AttributeNode.php +7 -15
  29. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/BogusTagNode.php +4 -6
  30. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/CommentNode.php +4 -3
  31. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ElementNode.php +37 -67
  32. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ExpressionAttributeNode.php +60 -0
  33. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/TagNode.php +70 -0
  34. package/vendor/latte/latte/src/Latte/Compiler/Nodes/NopNode.php +4 -3
  35. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ArgumentNode.php +4 -3
  36. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ArrayItemNode.php +4 -15
  37. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ClosureUseNode.php +4 -3
  38. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ComplexTypeNode.php +4 -3
  39. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayAccessNode.php +4 -3
  40. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayNode.php +6 -22
  41. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignNode.php +18 -5
  42. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignOpNode.php +18 -7
  43. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AuxiliaryNode.php +5 -4
  44. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/BinaryOpNode.php +38 -9
  45. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CastNode.php +14 -6
  46. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClassConstantFetchNode.php +4 -3
  47. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CloneNode.php +12 -4
  48. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClosureNode.php +10 -6
  49. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ConstantFetchNode.php +7 -6
  50. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/EmptyNode.php +4 -3
  51. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FilterCallNode.php +10 -4
  52. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallNode.php +14 -5
  53. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InNode.php +4 -3
  54. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InstanceofNode.php +14 -5
  55. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/IssetNode.php +6 -3
  56. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MatchNode.php +6 -3
  57. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallNode.php +18 -5
  58. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/NewNode.php +14 -4
  59. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PostOpNode.php +14 -6
  60. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PreOpNode.php +14 -6
  61. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PropertyFetchNode.php +4 -3
  62. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticMethodCallNode.php +14 -15
  63. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticPropertyFetchNode.php +4 -3
  64. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TemporaryNode.php +7 -6
  65. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TernaryNode.php +16 -11
  66. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/UnaryOpNode.php +19 -9
  67. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/VariableNode.php +4 -3
  68. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ExpressionNode.php +4 -3
  69. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/FilterNode.php +33 -8
  70. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/IdentifierNode.php +4 -3
  71. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/InterpolatedStringPartNode.php +4 -3
  72. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/IntersectionTypeNode.php +6 -3
  73. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ListItemNode.php +4 -3
  74. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ListNode.php +4 -3
  75. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/MatchArmNode.php +6 -3
  76. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ModifierNode.php +29 -41
  77. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NameNode.php +9 -4
  78. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NullableTypeNode.php +4 -3
  79. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/OperatorNode.php +27 -0
  80. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ParameterNode.php +4 -3
  81. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/BooleanNode.php +4 -3
  82. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/FloatNode.php +9 -6
  83. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/IntegerNode.php +8 -6
  84. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/InterpolatedStringNode.php +9 -5
  85. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/NullNode.php +4 -3
  86. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/StringNode.php +6 -4
  87. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ScalarNode.php +4 -3
  88. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/SuperiorTypeNode.php +4 -3
  89. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/UnionTypeNode.php +6 -3
  90. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/VarLikeIdentifierNode.php +4 -3
  91. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/{Expression/NotNode.php → VariadicPlaceholderNode.php} +9 -9
  92. package/vendor/latte/latte/src/Latte/{Essential → Compiler}/Nodes/PrintNode.php +9 -15
  93. package/vendor/latte/latte/src/Latte/Compiler/Nodes/StatementNode.php +7 -3
  94. package/vendor/latte/latte/src/Latte/Compiler/Nodes/TemplateNode.php +4 -3
  95. package/vendor/latte/latte/src/Latte/Compiler/Nodes/TextNode.php +6 -4
  96. package/vendor/latte/latte/src/Latte/Compiler/PhpHelpers.php +32 -18
  97. package/vendor/latte/latte/src/Latte/Compiler/Position.php +7 -7
  98. package/vendor/latte/latte/src/Latte/Compiler/PrintContext.php +72 -104
  99. package/vendor/latte/latte/src/Latte/Compiler/Tag.php +17 -16
  100. package/vendor/latte/latte/src/Latte/Compiler/TagLexer.php +11 -8
  101. package/vendor/latte/latte/src/Latte/Compiler/TagParser.php +28 -23
  102. package/vendor/latte/latte/src/Latte/Compiler/TagParserData.php +360 -336
  103. package/vendor/latte/latte/src/Latte/Compiler/TemplateGenerator.php +49 -38
  104. package/vendor/latte/latte/src/Latte/Compiler/TemplateLexer.php +37 -12
  105. package/vendor/latte/latte/src/Latte/Compiler/TemplateParser.php +35 -21
  106. package/vendor/latte/latte/src/Latte/Compiler/TemplateParserHtml.php +121 -71
  107. package/vendor/latte/latte/src/Latte/Compiler/Token.php +79 -70
  108. package/vendor/latte/latte/src/Latte/Compiler/TokenStream.php +21 -14
  109. package/vendor/latte/latte/src/Latte/ContentType.php +4 -3
  110. package/vendor/latte/latte/src/Latte/Engine.php +147 -188
  111. package/vendor/latte/latte/src/Latte/Essential/AuxiliaryIterator.php +5 -7
  112. package/vendor/latte/latte/src/Latte/Essential/Blueprint.php +5 -5
  113. package/vendor/latte/latte/src/Latte/Essential/CachingIterator.php +5 -4
  114. package/vendor/latte/latte/src/Latte/Essential/CoreExtension.php +155 -127
  115. package/vendor/latte/latte/src/Latte/Essential/Filters.php +99 -44
  116. package/vendor/latte/latte/src/Latte/Essential/Nodes/BlockNode.php +14 -13
  117. package/vendor/latte/latte/src/Latte/Essential/Nodes/CaptureNode.php +5 -6
  118. package/vendor/latte/latte/src/Latte/Essential/Nodes/ContentTypeNode.php +3 -4
  119. package/vendor/latte/latte/src/Latte/Essential/Nodes/CustomFunctionCallNode.php +46 -0
  120. package/vendor/latte/latte/src/Latte/Essential/Nodes/DebugbreakNode.php +2 -3
  121. package/vendor/latte/latte/src/Latte/Essential/Nodes/DefineNode.php +10 -7
  122. package/vendor/latte/latte/src/Latte/Essential/Nodes/DoNode.php +3 -4
  123. package/vendor/latte/latte/src/Latte/Essential/Nodes/DumpNode.php +2 -3
  124. package/vendor/latte/latte/src/Latte/Essential/Nodes/EmbedNode.php +8 -9
  125. package/vendor/latte/latte/src/Latte/Essential/Nodes/ExtendsNode.php +3 -5
  126. package/vendor/latte/latte/src/Latte/Essential/Nodes/FirstLastSepNode.php +4 -7
  127. package/vendor/latte/latte/src/Latte/Essential/Nodes/ForNode.php +6 -5
  128. package/vendor/latte/latte/src/Latte/Essential/Nodes/ForeachNode.php +7 -7
  129. package/vendor/latte/latte/src/Latte/Essential/Nodes/IfChangedNode.php +4 -5
  130. package/vendor/latte/latte/src/Latte/Essential/Nodes/IfContentNode.php +7 -6
  131. package/vendor/latte/latte/src/Latte/Essential/Nodes/IfNode.php +11 -11
  132. package/vendor/latte/latte/src/Latte/Essential/Nodes/ImportNode.php +5 -6
  133. package/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeBlockNode.php +26 -27
  134. package/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeFileNode.php +7 -10
  135. package/vendor/latte/latte/src/Latte/Essential/Nodes/IterateWhileNode.php +6 -6
  136. package/vendor/latte/latte/src/Latte/Essential/Nodes/JumpNode.php +4 -8
  137. package/vendor/latte/latte/src/Latte/Essential/Nodes/NAttrNode.php +35 -47
  138. package/vendor/latte/latte/src/Latte/Essential/Nodes/NClassNode.php +4 -5
  139. package/vendor/latte/latte/src/Latte/Essential/Nodes/NElseNode.php +69 -34
  140. package/vendor/latte/latte/src/Latte/Essential/Nodes/NTagNode.php +9 -33
  141. package/vendor/latte/latte/src/Latte/Essential/Nodes/ParametersNode.php +7 -4
  142. package/vendor/latte/latte/src/Latte/Essential/Nodes/RawPhpNode.php +3 -4
  143. package/vendor/latte/latte/src/Latte/Essential/Nodes/RollbackNode.php +2 -3
  144. package/vendor/latte/latte/src/Latte/Essential/Nodes/SpacelessNode.php +4 -5
  145. package/vendor/latte/latte/src/Latte/Essential/Nodes/SwitchNode.php +9 -7
  146. package/vendor/latte/latte/src/Latte/Essential/Nodes/TemplatePrintNode.php +4 -4
  147. package/vendor/latte/latte/src/Latte/Essential/Nodes/TemplateTypeNode.php +3 -4
  148. package/vendor/latte/latte/src/Latte/Essential/Nodes/TraceNode.php +2 -3
  149. package/vendor/latte/latte/src/Latte/Essential/Nodes/TranslateNode.php +5 -5
  150. package/vendor/latte/latte/src/Latte/Essential/Nodes/TryNode.php +4 -5
  151. package/vendor/latte/latte/src/Latte/Essential/Nodes/VarNode.php +10 -6
  152. package/vendor/latte/latte/src/Latte/Essential/Nodes/VarPrintNode.php +2 -3
  153. package/vendor/latte/latte/src/Latte/Essential/Nodes/VarTypeNode.php +3 -4
  154. package/vendor/latte/latte/src/Latte/Essential/Nodes/WhileNode.php +5 -5
  155. package/vendor/latte/latte/src/Latte/Essential/Passes.php +82 -21
  156. package/vendor/latte/latte/src/Latte/Essential/RawPhpExtension.php +2 -4
  157. package/vendor/latte/latte/src/Latte/Essential/RollbackException.php +1 -3
  158. package/vendor/latte/latte/src/Latte/Essential/Tracer.php +24 -28
  159. package/vendor/latte/latte/src/Latte/Essential/TranslatorExtension.php +14 -14
  160. package/vendor/latte/latte/src/Latte/Extension.php +12 -6
  161. package/vendor/latte/latte/src/Latte/Feature.php +24 -0
  162. package/vendor/latte/latte/src/Latte/Helpers.php +65 -15
  163. package/vendor/latte/latte/src/Latte/Loader.php +1 -9
  164. package/vendor/latte/latte/src/Latte/Loaders/FileLoader.php +11 -17
  165. package/vendor/latte/latte/src/Latte/Loaders/StringLoader.php +7 -21
  166. package/vendor/latte/latte/src/Latte/Policy.php +4 -3
  167. package/vendor/latte/latte/src/Latte/Runtime/Block.php +2 -4
  168. package/vendor/latte/latte/src/Latte/Runtime/Cache.php +143 -0
  169. package/vendor/latte/latte/src/Latte/Runtime/FilterExecutor.php +5 -6
  170. package/vendor/latte/latte/src/Latte/Runtime/FilterInfo.php +11 -11
  171. package/vendor/latte/latte/src/Latte/Runtime/FunctionExecutor.php +5 -6
  172. package/vendor/latte/latte/src/Latte/Runtime/Helpers.php +91 -0
  173. package/vendor/latte/latte/src/Latte/Runtime/Html.php +3 -5
  174. package/vendor/latte/latte/src/Latte/Runtime/HtmlHelpers.php +374 -0
  175. package/vendor/latte/latte/src/Latte/Runtime/HtmlStringable.php +1 -3
  176. package/vendor/latte/latte/src/Latte/Runtime/Template.php +162 -182
  177. package/vendor/latte/latte/src/Latte/Runtime/XmlHelpers.php +108 -0
  178. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/FunctionCallNode.php +12 -4
  179. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/MethodCallNode.php +15 -5
  180. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/PropertyFetchNode.php +4 -3
  181. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/SandboxNode.php +5 -6
  182. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticMethodCallNode.php +14 -4
  183. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticPropertyFetchNode.php +4 -3
  184. package/vendor/latte/latte/src/Latte/Sandbox/RuntimeChecker.php +8 -6
  185. package/vendor/latte/latte/src/Latte/Sandbox/SandboxExtension.php +16 -12
  186. package/vendor/latte/latte/src/Latte/Sandbox/SecurityPolicy.php +18 -16
  187. package/vendor/latte/latte/src/Latte/attributes.php +7 -3
  188. package/vendor/latte/latte/src/Latte/exceptions.php +52 -6
  189. package/vendor/latte/latte/src/Tools/Linter.php +74 -28
  190. package/vendor/latte/latte/src/Tools/LinterExtension.php +176 -0
  191. package/vendor/nette/utils/composer.json +15 -5
  192. package/vendor/nette/utils/readme.md +1 -1
  193. package/vendor/nette/utils/src/HtmlStringable.php +4 -1
  194. package/vendor/nette/utils/src/Iterators/CachingIterator.php +10 -25
  195. package/vendor/nette/utils/src/Iterators/Mapper.php +2 -3
  196. package/vendor/nette/utils/src/SmartObject.php +3 -0
  197. package/vendor/nette/utils/src/StaticClass.php +1 -11
  198. package/vendor/nette/utils/src/Translator.php +1 -1
  199. package/vendor/nette/utils/src/Utils/ArrayHash.php +6 -10
  200. package/vendor/nette/utils/src/Utils/ArrayList.php +8 -12
  201. package/vendor/nette/utils/src/Utils/Arrays.php +38 -18
  202. package/vendor/nette/utils/src/Utils/Callback.php +13 -8
  203. package/vendor/nette/utils/src/Utils/DateTime.php +95 -26
  204. package/vendor/nette/utils/src/Utils/FileInfo.php +6 -7
  205. package/vendor/nette/utils/src/Utils/FileSystem.php +10 -5
  206. package/vendor/nette/utils/src/Utils/Finder.php +31 -12
  207. package/vendor/nette/utils/src/Utils/Floats.php +1 -0
  208. package/vendor/nette/utils/src/Utils/Helpers.php +22 -2
  209. package/vendor/nette/utils/src/Utils/Html.php +130 -127
  210. package/vendor/nette/utils/src/Utils/Image.php +80 -60
  211. package/vendor/nette/utils/src/Utils/ImageColor.php +5 -0
  212. package/vendor/nette/utils/src/Utils/ImageType.php +2 -0
  213. package/vendor/nette/utils/src/Utils/Iterables.php +41 -7
  214. package/vendor/nette/utils/src/Utils/Json.php +2 -0
  215. package/vendor/nette/utils/src/Utils/ObjectHelpers.php +2 -0
  216. package/vendor/nette/utils/src/Utils/Paginator.php +10 -43
  217. package/vendor/nette/utils/src/Utils/Random.php +2 -0
  218. package/vendor/nette/utils/src/Utils/Reflection.php +22 -15
  219. package/vendor/nette/utils/src/Utils/ReflectionMethod.php +6 -1
  220. package/vendor/nette/utils/src/Utils/Strings.php +62 -57
  221. package/vendor/nette/utils/src/Utils/Type.php +91 -42
  222. package/vendor/nette/utils/src/Utils/Validators.php +9 -7
  223. package/vendor/latte/latte/src/Bridges/Tracy/templates/LattePanel.panel.phtml +0 -101
  224. package/vendor/latte/latte/src/Bridges/Tracy/templates/LattePanel.tab.phtml +0 -15
  225. package/vendor/latte/latte/src/Latte/Compiler/ExpressionBuilder.php +0 -129
  226. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ErrorSuppressNode.php +0 -36
  227. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallableNode.php +0 -39
  228. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallableNode.php +0 -42
  229. package/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticMethodCallableNode.php +0 -57
  230. package/vendor/latte/latte/src/Latte/PositionAwareException.php +0 -47
  231. package/vendor/latte/latte/src/Latte/Runtime/Filters.php +0 -283
  232. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/FunctionCallableNode.php +0 -29
  233. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/MethodCallableNode.php +0 -30
  234. 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
- * Filter runtime info
15
+ * Content type context for contextual filters.
17
16
  */
18
17
  class FilterInfo
19
18
  {
20
- public ?string $contentType = null;
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, ['{{' => '{<!-- -->{', '{' => '&#123;']);
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('{', '&#123;', $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, ['"' => '&quot;', "'" => '&apos;']);
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(['&', "'"], ['&amp;', '&apos;'], $value) . "'"
245
+ : '"' . str_replace(['&', '"'], ['&amp;', '&quot;'], $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
+ }
@@ -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