BadScript 2
Loading...
Searching...
No Matches
BadIfNodeTransformer.cs
Go to the documentation of this file.
1using System.Collections.Generic;
2
7
8using HtmlAgilityPack;
9
10namespace BadHtml.Transformer;
11
16{
18 protected override bool CanTransform(BadHtmlContext context)
19 {
20 return context.InputNode.Name == "bs:if";
21 }
22
31 private static List<(HtmlAttribute, IEnumerable<HtmlNode>)> DissectContent(
32 BadHtmlContext context,
33 HtmlNode node,
34 out IEnumerable<HtmlNode>? elseBranch)
35 {
36 List<(HtmlAttribute, IEnumerable<HtmlNode>)> branches = new List<(HtmlAttribute, IEnumerable<HtmlNode>)>();
37 List<HtmlNode> currentBranch = new List<HtmlNode>();
38 HtmlAttribute? conditionAttribute = node.Attributes["test"];
39
40 if (conditionAttribute == null)
41 {
43 context.ExecutionContext.Scope,
44 "Missing 'test' attribute in 'bs:if' node",
45 context.CreateOuterPosition()
46 );
47 }
48
49 if (string.IsNullOrEmpty(conditionAttribute.Value))
50 {
52 context.ExecutionContext.Scope,
53 "Empty 'test' attribute in 'bs:if' node",
54 context.CreateAttributePosition(conditionAttribute)
55 );
56 }
57
58 foreach (HtmlNode child in node.ChildNodes)
59 {
60 if (child.Name == "bs:else")
61 {
62 branches.Add((conditionAttribute!, currentBranch));
63
64 currentBranch = new List<HtmlNode>();
65 HtmlAttribute? nextCondition = child.Attributes["test"];
66
67 if (conditionAttribute == null)
68 {
69 if (nextCondition != null)
70 {
72 context.ExecutionContext.Scope,
73 "Found bs:else node with attribute 'test' after bs:else node without 'test' attribute",
74 context.CreateAttributePosition(nextCondition)
75 );
76 }
77
79 context.ExecutionContext.Scope,
80 "Found bs:else node after bs:else node without 'test' attribute",
81 context.CreateInnerPosition()
82 );
83 }
84
85 conditionAttribute = child.Attributes["test"];
86
87 if (conditionAttribute == null)
88 {
89 continue;
90 }
91
92 if (string.IsNullOrEmpty(conditionAttribute.Value))
93 {
95 context.ExecutionContext.Scope,
96 "Empty 'test' attribute in 'bs:else' node",
97 context.CreateAttributePosition(conditionAttribute)
98 );
99 }
100 }
101 else
102 {
103 currentBranch.Add(child);
104 }
105 }
106
107 if (conditionAttribute == null)
108 {
109 elseBranch = currentBranch;
110 }
111 else
112 {
113 elseBranch = null;
114 branches.Add((conditionAttribute, currentBranch));
115 }
116
117 return branches;
118 }
119
127 private static bool EvaluateCondition(BadHtmlContext context, HtmlAttribute conditionAttribute)
128 {
129 BadObject resultObj = context.ParseAndExecuteSingle(
130 conditionAttribute.Value,
131 context.CreateAttributePosition(conditionAttribute)
132 );
133
134 if (resultObj is not IBadBoolean result)
135 {
137 context.ExecutionContext.Scope,
138 "Result of 'test' attribute in 'bs:if' node is not a boolean",
139 context.CreateAttributePosition(conditionAttribute)
140 );
141 }
142
143 return result.Value;
144 }
145
147 protected override void TransformNode(BadHtmlContext context)
148 {
149 List<(HtmlAttribute, IEnumerable<HtmlNode>)> branches =
150 DissectContent(context, context.InputNode, out IEnumerable<HtmlNode>? elseBranch);
151
152 bool executedAny = false;
153
154 foreach ((HtmlAttribute condition, IEnumerable<HtmlNode> block) branch in branches)
155 {
156 if (!EvaluateCondition(context, branch.condition))
157 {
158 continue;
159 }
160
161 executedAny = true;
162 using BadExecutionContext branchContext = new BadExecutionContext(
164 "bs:if",
165 context.ExecutionContext.Scope,
166 null
167 )
168 );
169
170 foreach (HtmlNode? child in branch.block)
171 {
172 BadHtmlContext childContext = context.CreateChild(child, context.OutputNode, branchContext);
173
174 Transform(childContext);
175 }
176 }
177
178 if (executedAny || elseBranch == null)
179 {
180 return;
181 }
182
183 using BadExecutionContext elseContext = new BadExecutionContext(
185 "bs:if",
186 context.ExecutionContext.Scope,
187 null
188 )
189 );
190
191 foreach (HtmlNode? child in elseBranch)
192 {
193 BadHtmlContext childContext = context.CreateChild(child, context.OutputNode, elseContext);
194
195 Transform(childContext);
196 }
197 }
198}
Implements the Html Context for the Transformation Process.
BadSourcePosition CreateAttributePosition(HtmlAttribute attribute)
Creates the Source Position of the specified Attribute.
BadSourcePosition CreateOuterPosition()
Creates the Source Position of the current Input Nodes Outer Content.
BadHtmlContext CreateChild(HtmlNode inputNode, HtmlNode outputNode, BadExecutionContext? executionContext=null)
Creates a child context with the specified input, output node and optional execution context.
readonly HtmlNode InputNode
The Current Input Node.
readonly BadExecutionContext ExecutionContext
The Execution Context that is used to evaluate badscript code.
readonly HtmlNode OutputNode
The Current Output Node.
BadObject ParseAndExecuteSingle(string code, BadSourcePosition pos)
Parses and executes the specified code and returns the result of the last expression.
Base class of all Node transformers.
static void Transform(BadHtmlContext context)
Transforms the input node with one of the registered transformers.
Implements the 'bs:if' node transformer.
override void TransformNode(BadHtmlContext context)
override bool CanTransform(BadHtmlContext context)
static List<(HtmlAttribute, IEnumerable< HtmlNode >)> DissectContent(BadHtmlContext context, HtmlNode node, out IEnumerable< HtmlNode >? elseBranch)
Dissects the HTML content of the 'bs:if' node into a list of branches.
static bool EvaluateCondition(BadHtmlContext context, HtmlAttribute conditionAttribute)
Evaluates a condition attribute.
The Execution Context. Every execution of a script needs a context the script is running in....
BadScope Scope
The Root Scope of the Context.
BadScope CreateChild(string name, BadScope? caller, bool? useVisibility, BadScopeFlags flags=BadScopeFlags.RootScope)
Creates a subscope of the current scope.
Definition BadScope.cs:792
static BadRuntimeException Create(BadScope? scope, string message)
Creates a new BadScriptException.
The Base Class for all BadScript Objects.
Definition BadObject.cs:14
Implements the Interface for Native Boolean.
Definition IBadBoolean.cs:7
Implementations of Html Node Transformers that are used in the Transformation Process.
Contains the Error Objects for the BadScript2 Language.
Contains the Native Runtime Objects.
Definition BadBoolean.cs:6
Contains the Runtime Objects.
Definition BadArray.cs:10
Contains the Runtime Implementation.