@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,114 @@
|
|
|
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\Bridges\Tracy;
|
|
11
|
+
|
|
12
|
+
use Latte;
|
|
13
|
+
use Tracy;
|
|
14
|
+
use Tracy\BlueScreen;
|
|
15
|
+
use Tracy\Helpers;
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* BlueScreen panels for Tracy 2.x
|
|
20
|
+
*/
|
|
21
|
+
class BlueScreenPanel
|
|
22
|
+
{
|
|
23
|
+
public static function initialize(?BlueScreen $blueScreen = null): void
|
|
24
|
+
{
|
|
25
|
+
$blueScreen ??= Tracy\Debugger::getBlueScreen();
|
|
26
|
+
$blueScreen->addPanel([self::class, 'renderError']);
|
|
27
|
+
$blueScreen->addAction([self::class, 'renderUnknownMacro']);
|
|
28
|
+
if (
|
|
29
|
+
version_compare(Tracy\Debugger::VERSION, '2.9.0', '>=')
|
|
30
|
+
&& version_compare(Tracy\Debugger::VERSION, '3.0', '<')
|
|
31
|
+
) {
|
|
32
|
+
Tracy\Debugger::addSourceMapper([self::class, 'mapLatteSourceCode']);
|
|
33
|
+
$blueScreen->addFileGenerator(fn(string $file) => substr($file, -6) === '.latte'
|
|
34
|
+
? "{block content}\n\$END\$"
|
|
35
|
+
: null);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
public static function renderError(?\Throwable $e): ?array
|
|
41
|
+
{
|
|
42
|
+
if ($e instanceof Latte\CompileException && $e->sourceName) {
|
|
43
|
+
return [
|
|
44
|
+
'tab' => 'Template',
|
|
45
|
+
'panel' => (preg_match('#\n|\?#', $e->sourceName)
|
|
46
|
+
? ''
|
|
47
|
+
: '<p>'
|
|
48
|
+
. (@is_file($e->sourceName) // @ - may trigger error
|
|
49
|
+
? '<b>File:</b> ' . Helpers::editorLink($e->sourceName, $e->position?->line)
|
|
50
|
+
: '<b>' . htmlspecialchars($e->sourceName . ($e->position?->line ? ':' . $e->position->line : '')) . '</b>')
|
|
51
|
+
. '</p>')
|
|
52
|
+
. '<pre class="code tracy-code"><div>'
|
|
53
|
+
. BlueScreen::highlightLine(htmlspecialchars($e->sourceCode, ENT_IGNORE, 'UTF-8'), $e->position->line ?? 0, 15, $e->position->column ?? 0)
|
|
54
|
+
. '</div></pre>',
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
} elseif (
|
|
58
|
+
$e
|
|
59
|
+
&& ($file = $e->getFile())
|
|
60
|
+
&& (version_compare(Tracy\Debugger::VERSION, '2.9.0', '<'))
|
|
61
|
+
&& ($mapped = self::mapLatteSourceCode($file, $e->getLine()))
|
|
62
|
+
) {
|
|
63
|
+
return [
|
|
64
|
+
'tab' => 'Template',
|
|
65
|
+
'panel' => '<p><b>File:</b> ' . Helpers::editorLink($mapped['file'], $mapped['line']) . '</p>'
|
|
66
|
+
. ($mapped['line']
|
|
67
|
+
? BlueScreen::highlightFile($mapped['file'], $mapped['line'])
|
|
68
|
+
: ''),
|
|
69
|
+
];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
public static function renderUnknownMacro(?\Throwable $e): ?array
|
|
77
|
+
{
|
|
78
|
+
if (
|
|
79
|
+
$e instanceof Latte\CompileException
|
|
80
|
+
&& $e->sourceName
|
|
81
|
+
&& @is_file($e->sourceName) // @ - may trigger error
|
|
82
|
+
&& (preg_match('#Unknown tag (\{\w+)\}, did you mean (\{\w+)\}\?#A', $e->getMessage(), $m)
|
|
83
|
+
|| preg_match('#Unknown attribute (n:\w+), did you mean (n:\w+)\?#A', $e->getMessage(), $m))
|
|
84
|
+
) {
|
|
85
|
+
return [
|
|
86
|
+
'link' => Helpers::editorUri($e->sourceName, $e->position?->line, 'fix', $m[1], $m[2]),
|
|
87
|
+
'label' => 'fix it',
|
|
88
|
+
];
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
/** @return array{file: string, line: int, label: string, active: bool} */
|
|
96
|
+
public static function mapLatteSourceCode(string $file, int $line): ?array
|
|
97
|
+
{
|
|
98
|
+
if (!strpos($file, '.latte--')) {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
$lines = file($file);
|
|
103
|
+
if (
|
|
104
|
+
!preg_match('#^/\*\* source: (\S+\.latte)#m', implode('', array_slice($lines, 0, 10)), $m)
|
|
105
|
+
|| !@is_file($m[1]) // @ - may trigger error
|
|
106
|
+
) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
$file = $m[1];
|
|
111
|
+
$line = $line && preg_match('#/\* line (\d+) \*/#', $lines[$line - 1], $m) ? (int) $m[1] : 0;
|
|
112
|
+
return ['file' => $file, 'line' => $line, 'label' => 'Latte', 'active' => true];
|
|
113
|
+
}
|
|
114
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
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\Bridges\Tracy;
|
|
11
|
+
|
|
12
|
+
use Latte\Engine;
|
|
13
|
+
use Latte\Runtime\Template;
|
|
14
|
+
use Tracy;
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Bar panel for Tracy 2.x
|
|
19
|
+
*/
|
|
20
|
+
class LattePanel implements Tracy\IBarPanel
|
|
21
|
+
{
|
|
22
|
+
public bool $dumpParameters = true;
|
|
23
|
+
|
|
24
|
+
/** @var Template[] */
|
|
25
|
+
private array $templates = [];
|
|
26
|
+
private array $list;
|
|
27
|
+
private ?string $name = null;
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
public static function initialize(Engine $latte, ?string $name = null, ?Tracy\Bar $bar = null): void
|
|
31
|
+
{
|
|
32
|
+
$bar ??= Tracy\Debugger::getBar();
|
|
33
|
+
$bar->addPanel(new self($latte, $name));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
public function __construct(Engine $latte, ?string $name = null)
|
|
38
|
+
{
|
|
39
|
+
$this->name = $name;
|
|
40
|
+
$latte->probe = function (Template $template): void {
|
|
41
|
+
$this->templates[] = $template;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Renders tab.
|
|
48
|
+
*/
|
|
49
|
+
public function getTab(): ?string
|
|
50
|
+
{
|
|
51
|
+
if (!$this->templates) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return Tracy\Helpers::capture(function () {
|
|
56
|
+
$name = $this->name ?? basename(reset($this->templates)->getName());
|
|
57
|
+
require __DIR__ . '/templates/LattePanel.tab.phtml';
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Renders panel.
|
|
64
|
+
*/
|
|
65
|
+
public function getPanel(): string
|
|
66
|
+
{
|
|
67
|
+
$this->list = [];
|
|
68
|
+
$this->buildList($this->templates[0]);
|
|
69
|
+
|
|
70
|
+
return Tracy\Helpers::capture(function () {
|
|
71
|
+
$list = $this->list;
|
|
72
|
+
$dumpParameters = $this->dumpParameters;
|
|
73
|
+
require __DIR__ . '/templates/LattePanel.panel.phtml';
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
private function buildList(Template $template, int $depth = 0, int $count = 1): void
|
|
79
|
+
{
|
|
80
|
+
$this->list[] = (object) [
|
|
81
|
+
'template' => $template,
|
|
82
|
+
'depth' => $depth,
|
|
83
|
+
'count' => $count,
|
|
84
|
+
'phpFile' => (new \ReflectionObject($template))->getFileName(),
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
$children = $counter = [];
|
|
88
|
+
foreach ($this->templates as $t) {
|
|
89
|
+
if ($t->getReferringTemplate() === $template) {
|
|
90
|
+
$children[$t->getName()] = $t;
|
|
91
|
+
@$counter[$t->getName()]++;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
foreach ($children as $name => $t) {
|
|
96
|
+
$this->buildList($t, $depth + 1, $counter[$name]);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
declare(strict_types=1);
|
|
3
|
+
|
|
4
|
+
namespace Latte\Bridges\Tracy;
|
|
5
|
+
|
|
6
|
+
use Latte\Runtime\Template;
|
|
7
|
+
use Tracy\Dumper;
|
|
8
|
+
use Tracy\Helpers;
|
|
9
|
+
|
|
10
|
+
$colors = [
|
|
11
|
+
'include' => '#00000052',
|
|
12
|
+
'extends' => '#cd1c1c7d',
|
|
13
|
+
'import' => '#17c35b8f',
|
|
14
|
+
'includeblock' => '#17c35b8f',
|
|
15
|
+
'embed' => '#4f1ccd7d',
|
|
16
|
+
'sandbox' => 'black',
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
?>
|
|
20
|
+
|
|
21
|
+
<style class="tracy-debug">
|
|
22
|
+
#tracy-debug .LattePanel td {
|
|
23
|
+
white-space: nowrap;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
#tracy-debug .LattePanel-php {
|
|
27
|
+
background: #8993be;
|
|
28
|
+
color: white;
|
|
29
|
+
border-radius: 79px;
|
|
30
|
+
padding: 1px 4px 3px 4px;
|
|
31
|
+
font-size: 75%;
|
|
32
|
+
font-style: italic;
|
|
33
|
+
font-weight: bold;
|
|
34
|
+
vertical-align: text-top;
|
|
35
|
+
opacity: .5;
|
|
36
|
+
margin-left: 2ex;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
#tracy-debug .LattePanel-type {
|
|
40
|
+
border-radius: 2px;
|
|
41
|
+
padding: 2px 4px;
|
|
42
|
+
font-size: 80%;
|
|
43
|
+
color: white;
|
|
44
|
+
font-weight: bold;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
#tracy-debug .LattePanel-include {
|
|
48
|
+
background: #00000052;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
#tracy-debug .LattePanel-extends {
|
|
52
|
+
background: #cd1c1c7d;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
#tracy-debug .LattePanel-import,
|
|
56
|
+
#tracy-debug .LattePanel-includeblock {
|
|
57
|
+
background: #17c35b8f;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
#tracy-debug .LattePanel-embed {
|
|
61
|
+
background: #4f1ccd7d;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
#tracy-debug .LattePanel-sandbox {
|
|
65
|
+
background: black;
|
|
66
|
+
}
|
|
67
|
+
</style>
|
|
68
|
+
|
|
69
|
+
<h1>Rendered Templates</h1>
|
|
70
|
+
|
|
71
|
+
<div class="tracy-inner LattePanel">
|
|
72
|
+
<table>
|
|
73
|
+
<?php foreach ($list as $item): ?>
|
|
74
|
+
<tr>
|
|
75
|
+
<td>
|
|
76
|
+
<?php if ($item->template->getReferenceType()): ?>
|
|
77
|
+
<span style="margin-left: <?= $item->depth * 4 ?>ex"></span>└
|
|
78
|
+
<span class="LattePanel-type" style="background: <?= $colors[$item->template->getReferenceType()] ?>"><?= Helpers::escapeHtml($item->template->getReferenceType()) ?></span>
|
|
79
|
+
<?php endif ?>
|
|
80
|
+
|
|
81
|
+
<?= Helpers::editorLink($item->template->getName()) ?>
|
|
82
|
+
|
|
83
|
+
<a href="<?= Helpers::escapeHtml(Helpers::editorUri($item->phpFile)) ?>" class="LattePanel-php">php</a>
|
|
84
|
+
</td>
|
|
85
|
+
|
|
86
|
+
<td><?= $item->count > 1 ? $item->count . '×' : '' ?></td>
|
|
87
|
+
</tr>
|
|
88
|
+
<?php endforeach ?>
|
|
89
|
+
</table>
|
|
90
|
+
|
|
91
|
+
<?php if ($dumpParameters): ?>
|
|
92
|
+
<h2>Parameters</h2>
|
|
93
|
+
|
|
94
|
+
<div class="tracy-inner">
|
|
95
|
+
<?= Dumper::toHtml(reset($list)->template->getParameters(), [Dumper::LIVE => true]); ?>
|
|
96
|
+
</div>
|
|
97
|
+
<?php endif ?>
|
|
98
|
+
</div>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
declare(strict_types=1);
|
|
3
|
+
|
|
4
|
+
namespace Latte\Bridges\Tracy;
|
|
5
|
+
|
|
6
|
+
use Tracy\Helpers;
|
|
7
|
+
|
|
8
|
+
?>
|
|
9
|
+
<span title="Latte Templates">
|
|
10
|
+
<svg viewBox="0 0 1793.77 1538.57">
|
|
11
|
+
<path fill="#F1A443" d="M934.87 1166.46c41.84,-2.2 75.14,-17.07 99.91,-44.59 24.77,-27.53 37.16,-58.9 37.16,-94.13 0,-38.53 -12.38,-71.01 -37.16,-97.43 -24.77,-26.42 -58.08,-45.14 -99.91,-56.15l0 292.31zm-67.71 -786.08c-40.74,2.2 -72.66,15.41 -95.79,39.63 -23.12,24.22 -34.68,52.29 -34.68,84.22 0,33.03 11.29,63.03 33.86,90 22.57,26.98 54.77,43.21 96.61,48.72l0 -262.58zm0 1013.98l0 -64.41c-61.66,-5.5 -114.22,-15.97 -157.71,-31.38 -43.49,-15.41 -79.27,-37.43 -107.34,-66.06 -28.07,-28.63 -48.72,-64.13 -61.93,-106.52 -13.21,-42.39 -19.82,-92.76 -19.82,-151.11l198.18 0c4.4,35.23 10.18,64.41 17.34,87.53 7.16,23.12 16.51,41.84 28.07,56.15 11.56,14.31 25.6,25.05 42.11,32.2 16.51,7.16 36.88,12.39 61.1,15.69l0 -318.73c-55.05,-14.31 -102.94,-30.55 -143.67,-48.72 -40.74,-18.16 -74.59,-39.63 -101.57,-64.41 -26.97,-24.77 -47.34,-53.4 -61.1,-85.88 -13.76,-32.48 -20.64,-71.29 -20.64,-116.43 0,-42.93 8.26,-83.39 24.77,-121.38 16.51,-37.98 39.36,-71.29 68.53,-99.91 29.18,-28.63 63.58,-51.19 103.22,-67.71 39.63,-16.51 83.12,-25.32 130.46,-26.42l0 -72.67 67.71 0 0 72.67c203.68,6.6 310.47,113.4 320.38,320.38l-194.87 0c-5.5,-59.45 -18.44,-99.91 -38.81,-121.38 -20.37,-21.47 -49.27,-33.31 -86.7,-35.51l0 284.05c73.76,24.22 132.94,47.89 177.53,71.01 44.59,23.12 78.72,47.61 102.39,73.49 23.67,25.87 39.36,54.22 47.07,85.05 7.71,30.83 11.56,66.61 11.56,107.34 0,48.44 -7.98,92.2 -23.94,131.29 -15.97,39.08 -38.81,72.94 -68.54,101.56 -29.72,28.63 -65.5,51.2 -107.34,67.71 -41.84,16.51 -88.08,25.87 -138.72,28.07l0 64.41 -67.71 0z"/>
|
|
12
|
+
<path fill="#5F4D36" d="M462.33 1411.31c-54.32,0 -98.33,-4.78 -132.03,-14.33 -33.7,-9.56 -59.85,-24.14 -78.46,-43.76 -18.61,-19.62 -30.93,-44.51 -36.97,-74.69 -6.04,-30.18 -9.05,-65.38 -9.05,-105.62 0,-9.05 0.5,-22.13 1.51,-39.23 1.01,-17.1 1.76,-35.21 2.27,-54.32 0.5,-19.11 1.26,-36.97 2.26,-53.56 1.01,-16.6 1.51,-28.42 1.51,-35.46 0,-58.34 -8.8,-99.08 -26.41,-122.22 -17.6,-23.13 -50.05,-34.7 -97.33,-34.7l0 -129.76c47.28,0 79.72,-11.82 97.33,-35.46 17.6,-23.64 26.41,-64.63 26.41,-122.97 0,-7.04 -0.5,-18.86 -1.51,-35.46 -1.01,-16.6 -1.76,-33.95 -2.26,-52.06 -0.5,-18.11 -1.26,-35.71 -2.27,-52.81 -1.01,-17.1 -1.51,-30.18 -1.51,-39.23 0,-40.24 3.02,-75.45 9.05,-105.62 6.03,-30.18 18.36,-55.08 36.97,-74.69 18.61,-19.62 44.76,-34.2 78.46,-43.76 33.7,-9.56 77.71,-14.34 132.03,-14.34l55.83 0 0 123.73 -33.2 0c-44.26,0 -74.18,7.04 -89.78,21.12 -15.59,14.08 -23.39,38.73 -23.39,73.94 0,45.27 1.51,90.03 4.53,134.29 3.02,44.26 4.53,89.02 4.53,134.29 0,21.12 -4.53,40.49 -13.58,58.09 -9.05,17.6 -20.87,33.19 -35.46,46.77 -14.59,13.58 -31.69,24.4 -51.3,32.44 -19.62,8.05 -39.98,13.58 -61.11,16.6 21.12,3.02 41.49,8.55 61.11,16.59 19.61,8.05 36.72,18.86 51.3,32.44 14.59,13.58 26.41,29.17 35.46,46.77 9.05,17.6 13.58,36.97 13.58,58.09 0,45.27 -1.51,90.28 -4.53,135.04 -3.02,44.76 -4.53,89.78 -4.53,135.05 0,35.21 7.79,59.85 23.39,73.94 15.59,14.08 45.52,21.12 89.78,21.12l33.2 0 0 123.73 -55.83 0z"/>
|
|
13
|
+
<path fill="#5F4D36" d="M1275.61 1411.31l0 -123.73 33.2 0c44.26,0 74.19,-7.04 89.78,-21.12 15.59,-14.08 23.39,-38.73 23.39,-73.94 0,-45.27 -1.51,-90.28 -4.53,-135.05 -3.02,-44.76 -4.53,-89.78 -4.53,-135.04 0,-21.12 4.53,-40.49 13.58,-58.09 9.05,-17.6 20.87,-33.19 35.46,-46.77 14.59,-13.58 31.69,-24.4 51.3,-32.44 19.61,-8.05 39.98,-13.58 61.11,-16.59 -21.12,-3.02 -41.5,-8.55 -61.11,-16.6 -19.62,-8.05 -36.72,-18.86 -51.3,-32.44 -14.59,-13.58 -26.41,-29.17 -35.46,-46.77 -9.05,-17.6 -13.58,-36.97 -13.58,-58.09 0,-45.27 1.51,-90.03 4.53,-134.29 3.02,-44.26 4.53,-89.02 4.53,-134.29 0,-35.21 -7.8,-59.85 -23.39,-73.94 -15.59,-14.08 -45.52,-21.12 -89.78,-21.12l-33.2 0 0 -123.73 55.83 0c54.32,0 98.33,4.78 132.03,14.34 33.7,9.55 59.85,24.14 78.46,43.76 18.61,19.61 30.93,44.51 36.97,74.69 6.03,30.17 9.05,65.38 9.05,105.62 0,9.05 -0.5,22.13 -1.51,39.23 -1.01,17.1 -1.76,34.7 -2.26,52.81 -0.5,18.11 -1.26,35.46 -2.27,52.06 -1.01,16.59 -1.51,28.41 -1.51,35.46 0,58.34 8.8,99.33 26.41,122.97 17.6,23.64 50.04,35.46 97.32,35.46l0 129.76c-47.28,0 -79.72,11.57 -97.32,34.7 -17.6,23.14 -26.41,63.88 -26.41,122.22 0,7.04 0.5,18.86 1.51,35.46 1.01,16.6 1.76,34.45 2.27,53.56 0.5,19.11 1.26,37.22 2.26,54.32 1.01,17.1 1.51,30.18 1.51,39.23 0,40.24 -3.02,75.44 -9.05,105.62 -6.04,30.18 -18.36,55.07 -36.97,74.69 -18.61,19.61 -44.76,34.2 -78.46,43.76 -33.7,9.55 -77.7,14.33 -132.03,14.33l-55.83 0z"/>
|
|
14
|
+
</svg><span class="tracy-label"><?= Helpers::escapeHtml($name) ?></span>
|
|
15
|
+
</span>
|
|
@@ -0,0 +1,44 @@
|
|
|
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\Compiler;
|
|
11
|
+
|
|
12
|
+
use Latte;
|
|
13
|
+
use Latte\Compiler\Nodes\Php\ExpressionNode;
|
|
14
|
+
use Latte\Compiler\Nodes\Php\ParameterNode;
|
|
15
|
+
use Latte\Compiler\Nodes\Php\Scalar;
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
/** @internal */
|
|
19
|
+
final class Block
|
|
20
|
+
{
|
|
21
|
+
use Latte\Strict;
|
|
22
|
+
|
|
23
|
+
public string $method;
|
|
24
|
+
public string $content;
|
|
25
|
+
public string $escaping;
|
|
26
|
+
|
|
27
|
+
/** @var ParameterNode[] */
|
|
28
|
+
public array $parameters = [];
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
public function __construct(
|
|
32
|
+
public /*readonly*/ ExpressionNode $name,
|
|
33
|
+
public /*readonly*/ int|string $layer,
|
|
34
|
+
public /*readonly*/ Tag $tag,
|
|
35
|
+
) {
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
public function isDynamic(): bool
|
|
40
|
+
{
|
|
41
|
+
return !$this->name instanceof Scalar\StringNode
|
|
42
|
+
&& !$this->name instanceof Scalar\IntegerNode;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,244 @@
|
|
|
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\Compiler;
|
|
11
|
+
|
|
12
|
+
use Latte;
|
|
13
|
+
use Latte\Compiler\Nodes\Html\ElementNode;
|
|
14
|
+
use Latte\ContentType;
|
|
15
|
+
use Latte\Runtime\Filters;
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Context-aware escaping.
|
|
20
|
+
*/
|
|
21
|
+
final class Escaper
|
|
22
|
+
{
|
|
23
|
+
use Latte\Strict;
|
|
24
|
+
|
|
25
|
+
public const
|
|
26
|
+
Text = 'text',
|
|
27
|
+
JavaScript = 'js',
|
|
28
|
+
Css = 'css',
|
|
29
|
+
ICal = 'ical',
|
|
30
|
+
Url = 'url';
|
|
31
|
+
|
|
32
|
+
public const
|
|
33
|
+
HtmlText = 'html',
|
|
34
|
+
HtmlComment = 'html/comment',
|
|
35
|
+
HtmlBogusTag = 'html/bogus',
|
|
36
|
+
HtmlCss = 'html/css',
|
|
37
|
+
HtmlJavaScript = 'html/js',
|
|
38
|
+
HtmlTag = 'html/tag',
|
|
39
|
+
HtmlAttribute = 'html/attr';
|
|
40
|
+
|
|
41
|
+
private string $state = '';
|
|
42
|
+
private string $tag = '';
|
|
43
|
+
private string $quote = '';
|
|
44
|
+
private string $subType = '';
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
public function __construct(
|
|
48
|
+
private string $contentType,
|
|
49
|
+
) {
|
|
50
|
+
$this->state = $this->contentType;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
public function getContentType(): string
|
|
55
|
+
{
|
|
56
|
+
return $this->contentType;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
public function getState(): string
|
|
61
|
+
{
|
|
62
|
+
return $this->state;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
public function export(): string
|
|
67
|
+
{
|
|
68
|
+
return ($this->state === self::HtmlAttribute && $this->quote === '' ? 'html/unquoted-attr' : $this->state)
|
|
69
|
+
. ($this->subType ? '/' . $this->subType : '');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
public function enterContentType(string $type): void
|
|
74
|
+
{
|
|
75
|
+
$this->contentType = $this->state = $type;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
public function enterHtmlText(?ElementNode $node): void
|
|
80
|
+
{
|
|
81
|
+
$this->state = self::HtmlText;
|
|
82
|
+
if ($this->contentType === ContentType::Html && $node) {
|
|
83
|
+
$name = strtolower($node->name);
|
|
84
|
+
if (
|
|
85
|
+
($name === 'script' || $name === 'style')
|
|
86
|
+
&& is_string($attr = $node->getAttribute('type') ?? 'css')
|
|
87
|
+
&& preg_match('#(java|j|ecma|live)script|module|json|css|plain#i', $attr)
|
|
88
|
+
) {
|
|
89
|
+
$this->state = $name === 'script'
|
|
90
|
+
? self::HtmlJavaScript
|
|
91
|
+
: self::HtmlCss;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
public function enterHtmlTag(string $name): void
|
|
98
|
+
{
|
|
99
|
+
$this->state = self::HtmlTag;
|
|
100
|
+
$this->tag = strtolower($name);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
public function enterHtmlAttribute(?string $name = null, string $quote = ''): void
|
|
105
|
+
{
|
|
106
|
+
$this->state = self::HtmlAttribute;
|
|
107
|
+
$this->quote = $quote;
|
|
108
|
+
$this->subType = '';
|
|
109
|
+
|
|
110
|
+
if ($this->contentType === ContentType::Html && is_string($name)) {
|
|
111
|
+
$name = strtolower($name);
|
|
112
|
+
if (str_starts_with($name, 'on')) {
|
|
113
|
+
$this->subType = self::JavaScript;
|
|
114
|
+
} elseif ($name === 'style') {
|
|
115
|
+
$this->subType = self::Css;
|
|
116
|
+
} elseif ((in_array($name, ['href', 'src', 'action', 'formaction'], true)
|
|
117
|
+
|| ($name === 'data' && $this->tag === 'object'))
|
|
118
|
+
) {
|
|
119
|
+
$this->subType = self::Url;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
public function enterHtmlAttributeQuote(string $quote = '"'): void
|
|
126
|
+
{
|
|
127
|
+
$this->quote = $quote;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
public function enterHtmlBogusTag(): void
|
|
132
|
+
{
|
|
133
|
+
$this->state = self::HtmlBogusTag;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
public function enterHtmlComment(): void
|
|
138
|
+
{
|
|
139
|
+
$this->state = self::HtmlComment;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
public function escape(string $str): string
|
|
144
|
+
{
|
|
145
|
+
[$lq, $rq] = $this->state === self::HtmlAttribute && !$this->quote ? ["'\"' . ", " . '\"'"] : ['', ''];
|
|
146
|
+
return match ($this->contentType) {
|
|
147
|
+
ContentType::Html => match ($this->state) {
|
|
148
|
+
self::HtmlText => 'LR\Filters::escapeHtmlText(' . $str . ')',
|
|
149
|
+
self::HtmlTag => 'LR\Filters::escapeHtmlTag(' . $str . ')',
|
|
150
|
+
self::HtmlAttribute => match ($this->subType) {
|
|
151
|
+
'',
|
|
152
|
+
self::Url => $lq . 'LR\Filters::escapeHtmlAttr(' . $str . ')' . $rq,
|
|
153
|
+
self::JavaScript => $lq . 'LR\Filters::escapeHtmlAttr(LR\Filters::escapeJs(' . $str . '))' . $rq,
|
|
154
|
+
self::Css => $lq . 'LR\Filters::escapeHtmlAttr(LR\Filters::escapeCss(' . $str . '))' . $rq,
|
|
155
|
+
},
|
|
156
|
+
self::HtmlComment => 'LR\Filters::escapeHtmlComment(' . $str . ')',
|
|
157
|
+
self::HtmlBogusTag => 'LR\Filters::escapeHtml(' . $str . ')',
|
|
158
|
+
self::HtmlJavaScript => 'LR\Filters::escapeJs(' . $str . ')',
|
|
159
|
+
self::HtmlCss => 'LR\Filters::escapeCss(' . $str . ')',
|
|
160
|
+
default => throw new \LogicException("Unknown context $this->contentType, $this->state."),
|
|
161
|
+
},
|
|
162
|
+
ContentType::Xml => match ($this->state) {
|
|
163
|
+
self::HtmlText,
|
|
164
|
+
self::HtmlBogusTag => 'LR\Filters::escapeXml(' . $str . ')',
|
|
165
|
+
self::HtmlAttribute => $lq . 'LR\Filters::escapeXml(' . $str . ')' . $rq,
|
|
166
|
+
self::HtmlComment => 'LR\Filters::escapeHtmlComment(' . $str . ')',
|
|
167
|
+
self::HtmlTag => 'LR\Filters::escapeXmlAttrUnquoted(' . $str . ')',
|
|
168
|
+
default => throw new \LogicException("Unknown context $this->contentType, $this->state."),
|
|
169
|
+
},
|
|
170
|
+
ContentType::JavaScript => 'LR\Filters::escapeJs(' . $str . ')',
|
|
171
|
+
ContentType::Css => 'LR\Filters::escapeCss(' . $str . ')',
|
|
172
|
+
ContentType::ICal => 'LR\Filters::escapeIcal(' . $str . ')',
|
|
173
|
+
ContentType::Text => $str,
|
|
174
|
+
default => throw new \LogicException("Unknown content-type $this->contentType."),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
public function check(string $str): string
|
|
180
|
+
{
|
|
181
|
+
if ($this->state === self::HtmlAttribute && $this->subType === self::Url) {
|
|
182
|
+
$str = 'LR\Filters::safeUrl(' . $str . ')';
|
|
183
|
+
}
|
|
184
|
+
return $str;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
public static function getConvertor(string $source, string $dest): ?callable
|
|
189
|
+
{
|
|
190
|
+
$table = [
|
|
191
|
+
self::Text => [
|
|
192
|
+
'html' => 'escapeHtmlText',
|
|
193
|
+
'html/attr' => 'escapeHtmlAttr',
|
|
194
|
+
'html/attr/js' => 'escapeHtmlAttr',
|
|
195
|
+
'html/attr/css' => 'escapeHtmlAttr',
|
|
196
|
+
'html/attr/url' => 'escapeHtmlAttr',
|
|
197
|
+
'html/comment' => 'escapeHtmlComment',
|
|
198
|
+
'xml' => 'escapeXml',
|
|
199
|
+
'xml/attr' => 'escapeXml',
|
|
200
|
+
],
|
|
201
|
+
self::JavaScript => [
|
|
202
|
+
'html' => 'escapeHtmlText',
|
|
203
|
+
'html/attr' => 'escapeHtmlAttr',
|
|
204
|
+
'html/attr/js' => 'escapeHtmlAttr',
|
|
205
|
+
'html/js' => 'escapeHtmlRawText',
|
|
206
|
+
'html/comment' => 'escapeHtmlComment',
|
|
207
|
+
],
|
|
208
|
+
self::Css => [
|
|
209
|
+
'html' => 'escapeHtmlText',
|
|
210
|
+
'html/attr' => 'escapeHtmlAttr',
|
|
211
|
+
'html/attr/css' => 'escapeHtmlAttr',
|
|
212
|
+
'html/css' => 'escapeHtmlRawText',
|
|
213
|
+
'html/comment' => 'escapeHtmlComment',
|
|
214
|
+
],
|
|
215
|
+
'html' => [
|
|
216
|
+
'html/attr' => 'convertHtmlToHtmlAttr',
|
|
217
|
+
'html/attr/js' => 'convertHtmlToHtmlAttr',
|
|
218
|
+
'html/attr/css' => 'convertHtmlToHtmlAttr',
|
|
219
|
+
'html/attr/url' => 'convertHtmlToHtmlAttr',
|
|
220
|
+
'html/comment' => 'escapeHtmlComment',
|
|
221
|
+
'html/unquoted-attr' => 'convertHtmlToUnquotedAttr',
|
|
222
|
+
],
|
|
223
|
+
'html/attr' => [
|
|
224
|
+
'html' => 'convertHtmlToHtmlAttr',
|
|
225
|
+
'html/unquoted-attr' => 'convertHtmlAttrToUnquotedAttr',
|
|
226
|
+
],
|
|
227
|
+
'html/attr/url' => [
|
|
228
|
+
'html' => 'convertHtmlToHtmlAttr',
|
|
229
|
+
'html/attr' => 'nop',
|
|
230
|
+
],
|
|
231
|
+
'html/unquoted-attr' => [
|
|
232
|
+
'html' => 'convertHtmlToHtmlAttr',
|
|
233
|
+
],
|
|
234
|
+
];
|
|
235
|
+
|
|
236
|
+
if ($source === $dest) {
|
|
237
|
+
return [Filters::class, 'nop'];
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return isset($table[$source][$dest])
|
|
241
|
+
? [Filters::class, $table[$source][$dest]]
|
|
242
|
+
: null;
|
|
243
|
+
}
|
|
244
|
+
}
|