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(BadHtmlContext context,
32 HtmlNode node,
33 out IEnumerable<HtmlNode>? elseBranch)
34 {
35 List<(HtmlAttribute, IEnumerable<HtmlNode>)> branches = new List<(HtmlAttribute, IEnumerable<HtmlNode>)>();
36 List<HtmlNode> currentBranch = new List<HtmlNode>();
37 HtmlAttribute? conditionAttribute = node.Attributes["test"];
38
39 if (conditionAttribute == null)
40 {
42 "Missing 'test' attribute in 'bs:if' node",
43 context.CreateOuterPosition()
44 );
45 }
46
47 if (string.IsNullOrEmpty(conditionAttribute.Value))
48 {
50 "Empty 'test' attribute in 'bs:if' node",
51 context.CreateAttributePosition(conditionAttribute)
52 );
53 }
54
55 foreach (HtmlNode child in node.ChildNodes)
56 {
57 if (child.Name == "bs:else")
58 {
59 branches.Add((conditionAttribute!, currentBranch));
60
61 currentBranch = new List<HtmlNode>();
62 HtmlAttribute? nextCondition = child.Attributes["test"];
63
64 if (conditionAttribute == null)
65 {
66 if (nextCondition != null)
67 {
68 throw BadRuntimeException.Create(context.ExecutionContext.Scope,
69 "Found bs:else node with attribute 'test' after bs:else node without 'test' attribute",
70 context.CreateAttributePosition(nextCondition)
71 );
72 }
73
74 throw BadRuntimeException.Create(context.ExecutionContext.Scope,
75 "Found bs:else node after bs:else node without 'test' attribute",
76 context.CreateInnerPosition()
77 );
78 }
79
80 conditionAttribute = child.Attributes["test"];
81
82 if (conditionAttribute == null)
83 {
84 continue;
85 }
86
87 if (string.IsNullOrEmpty(conditionAttribute.Value))
88 {
89 throw BadRuntimeException.Create(context.ExecutionContext.Scope,
90 "Empty 'test' attribute in 'bs:else' node",
91 context.CreateAttributePosition(conditionAttribute)
92 );
93 }
94 }
95 else
96 {
97 currentBranch.Add(child);
98 }
99 }
100
101 if (conditionAttribute == null)
102 {
103 elseBranch = currentBranch;
104 }
105 else
106 {
107 elseBranch = null;
108 branches.Add((conditionAttribute, currentBranch));
109 }
110
111 return branches;
112 }
113
121 private static bool EvaluateCondition(BadHtmlContext context, HtmlAttribute conditionAttribute)
122 {
123 BadObject resultObj = context.ParseAndExecuteSingle(conditionAttribute.Value,
124 context.CreateAttributePosition(conditionAttribute)
125 );
126
127 if (resultObj is not IBadBoolean result)
128 {
130 "Result of 'test' attribute in 'bs:if' node is not a boolean",
131 context.CreateAttributePosition(conditionAttribute)
132 );
133 }
134
135 return result.Value;
136 }
137
139 protected override void TransformNode(BadHtmlContext context)
140 {
141 List<(HtmlAttribute, IEnumerable<HtmlNode>)> branches =
142 DissectContent(context, context.InputNode, out IEnumerable<HtmlNode>? elseBranch);
143
144 bool executedAny = false;
145
146 foreach ((HtmlAttribute condition, IEnumerable<HtmlNode> block) branch in branches)
147 {
148 if (!EvaluateCondition(context, branch.condition))
149 {
150 continue;
151 }
152
153 executedAny = true;
154
155 using BadExecutionContext branchContext =
157 context.ExecutionContext.Scope,
158 null
159 )
160 );
161
162 foreach (HtmlNode? child in branch.block)
163 {
164 BadHtmlContext childContext = context.CreateChild(child, context.OutputNode, branchContext);
165
166 Transform(childContext);
167 }
168 }
169
170 if (executedAny || elseBranch == null)
171 {
172 return;
173 }
174
175 using BadExecutionContext elseContext =
177 context.ExecutionContext.Scope,
178 null
179 )
180 );
181
182 foreach (HtmlNode? child in elseBranch)
183 {
184 BadHtmlContext childContext = context.CreateChild(child, context.OutputNode, elseContext);
185
186 Transform(childContext);
187 }
188 }
189}
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:597
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.