Skip to content

Commit e764b2a

Browse files
committed
Create stdHTML.cls
1 parent ef01418 commit e764b2a

File tree

1 file changed

+244
-0
lines changed

1 file changed

+244
-0
lines changed

src/WIP/stdHTML.cls

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
VERSION 1.0 CLASS
2+
BEGIN
3+
MultiUse = -1 'True
4+
END
5+
Attribute VB_Name = "stdHTML"
6+
Attribute VB_GlobalNameSpace = False
7+
Attribute VB_Creatable = False
8+
Attribute VB_PredeclaredId = True
9+
Attribute VB_Exposed = False
10+
11+
12+
Private Enum EElementType
13+
ENone
14+
EElement
15+
ELiteral
16+
End Enum
17+
Private Type TElement
18+
TagName As String
19+
Attributes As Variant()
20+
Children As stdHTML()
21+
isSelfClosing As Boolean
22+
End Type
23+
Private Type TLiteral
24+
content as string
25+
End Type
26+
27+
Private Type TThis
28+
ElementType As EElementType
29+
Element as TElement
30+
Literal as TLiteral
31+
End Type
32+
Private This As TThis
33+
34+
'Creates a new stdHTML object. This is the main entry point for creating HTML document objects.
35+
Public Function Create() as stdHTML
36+
set Create = New stdHTML
37+
Call Create.protInit("html", Array())
38+
End Function
39+
40+
' Creates a new stdHTML object with the specified tag name and attributes, and adds it to the current element.
41+
'@param tagName - Name of the tag to create
42+
'@param attributes - Attributes to add to the tag
43+
'@param isSelfClosing - Whether the tag is self-closing
44+
Public Function CreateChild(ByVal tagName as string, ByVal attributes as variant, optional byval isSelfClosing as Boolean = false) as stdHTML
45+
set CreateChild = new stdHTML
46+
Call CreateChild.protInit(tagName, attributes, isSelfClosing)
47+
48+
'Theoretically someone could call this function on a literal element, or the predeclared stdHTML object.
49+
If this.ElementType = EElementType.EElement Then
50+
Dim iUB as long: iUB = UBound(This.Element.Children)
51+
ReDim Preserve This.Element.Children(iUB + 1)
52+
Set This.Element.Children(iUB + 1) = CreateChild
53+
else
54+
Err.Raise vbObjectError + 1, "Cannot add child to a non-element context."
55+
End if
56+
End Function
57+
58+
'Creates a literal element and adds it to the current element.
59+
'@param text - Text to add
60+
Public Sub CreateLiteral(ByVal text as string)
61+
Dim newLit as stdHTML: set newLit = new stdHTML
62+
Call newLit.protInitLiteral(text)
63+
64+
'Theoretically someone could call this function on a literal element, or the predeclared stdHTML object.
65+
If this.ElementType = EElementType.EElement Then
66+
Dim iUB as long: iUB = UBound(This.Element.Children)
67+
ReDim Preserve This.Element.Children(iUB + 1)
68+
Set This.Element.Children(iUB + 1) = newLit
69+
else
70+
Err.Raise vbObjectError + 1, "Cannot add literal to a non-element context."
71+
End If
72+
End Sub
73+
74+
75+
'Initialise an element object.
76+
'@param tagName - Name of the tag to create
77+
'@param attributes - Attributes to add to the tag
78+
'@param isSelfClosing - Whether the tag is self-closing
79+
Public Sub protInitElement(tagName as string, attributes as variant, isSelfClosing as Boolean)
80+
This.ElementType = EElementType.EElement
81+
This.Element.TagName = tagName
82+
This.Element.Attributes = attributes
83+
This.Element.isSelfClosing = isSelfClosing
84+
End Sub
85+
86+
'Initialise a literal object.
87+
'@param content - Content of the literal element
88+
Public Sub protInitLiteral(content as string)
89+
This.ElementType = EElementType.ELiteral
90+
This.Literal.content = content
91+
End Sub
92+
93+
94+
95+
Public Property Get TagName() as string
96+
Select Case this.ElementType
97+
Case EElementType.EElement
98+
TagName = This.Element.TagName
99+
Case EElementType.ELiteral
100+
TagName = ""
101+
case else
102+
Err.Raise vbObjectError + 1, "Invalid element type."
103+
End Select
104+
End Property
105+
106+
Public Property Get Attr(name as string) as variant
107+
Dim i as Long
108+
For i = 0 to UBound(This.Element.Attributes) step 2
109+
if This.Element.Attributes(i) = name then
110+
Attr = This.Element.Attributes(i + 1)
111+
exit for
112+
end if
113+
next i
114+
Attr = Empty 'If the attribute doesn't exist, return empty
115+
End Property
116+
Public Property Let Attr(name as string, value as variant)
117+
Dim i as Long
118+
For i = 0 to UBound(This.Element.Attributes) step 2
119+
if This.Element.Attributes(i) = name then
120+
This.Element.Attributes(i + 1) = value
121+
Exit Property
122+
end if
123+
next i
124+
125+
'If the attribute doesn't exist, add it
126+
Dim iUB as Long: iUB = UBound(This.Element.Attributes)
127+
ReDim Preserve This.Element.Attributes(iUB + 2)
128+
This.Element.Attributes(iUB + 1) = name
129+
This.Element.Attributes(iUB + 2) = value
130+
End Property
131+
132+
133+
Public Property Get Id() as string
134+
ID = Attr("id")
135+
End Property
136+
Public Property Let ID(value As String)
137+
Attr("id") = value
138+
End Property
139+
140+
Public Property Get Title() as string
141+
Title = Attr("title")
142+
End Property
143+
Public Property Let Title(value As String)
144+
Attr("title") = value
145+
End Property
146+
147+
Public Property Get Children() As stdHTML()
148+
If this.ElementType <> EElementType.EElement then Err.Raise vbObjectError + 1, "Cannot get children of a non-element context."
149+
Children = This.Element.Children
150+
End Property
151+
152+
'Adds the specified classes to the element
153+
'@param classes - Classes to add
154+
Public Sub AddClasses(ParamArray classes() as string)
155+
If this.ElementType <> EElementType.EElement then Err.Raise vbObjectError + 1, "Cannot add classes to a non-element context."
156+
157+
Dim classes as string: classes = Attr("class")
158+
If isEmpty(classes) then
159+
Attr("class") = Join(classes, " ")
160+
Else
161+
Dim newClass as variant
162+
For each newClass in classes
163+
If InStr(1, classes, newClass, vbTextCompare) = 0 then
164+
classes = classes & " " & newClass
165+
end if
166+
next
167+
Attr("class") = classes
168+
end if
169+
End Sub
170+
171+
'Removes the specified classes from the element
172+
'@param classes - Classes to remove
173+
Public Sub RemoveClasses(ParamArray classes() as string)
174+
If this.ElementType <> EElementType.EElement then Err.Raise vbObjectError + 1, "Cannot remove classes from a non-element context."
175+
176+
Dim classes as string: classes = Attr("class")
177+
If not isEmpty(classes) then
178+
Dim remClass as variant
179+
For each remClass in classes
180+
If InStr(1, classes, remClass, vbTextCompare) <> 0 then
181+
classes = Replace(classes, newClass, "")
182+
end if
183+
next
184+
185+
Attr("class") = Replace(classes, " ", " ")
186+
end if
187+
End Sub
188+
189+
'Obtain the HTML string representation of the element.
190+
'@param indent - Indentation string to use for nested elements
191+
Public Function ToString(Optional indent As String = "") As String
192+
select case this.ElementType
193+
case EElementType.EElement
194+
Dim output As String: output = indent & "<" & this.Element.TagName
195+
196+
Dim i As Long
197+
For i = 0 To UBound(this.Element.Attributes) Step 2
198+
output = output & " " & this.Element.Attributes(i) & serializeAttribute(this.Element.Attributes(i + 1))
199+
Next i
200+
201+
If this.Element.isSelfClosing Then
202+
output = output & " />"
203+
Else
204+
output = output & ">"
205+
206+
Dim child As stdHTML
207+
For Each child In this.Element.Children
208+
output = output & vbCrLf & child.ToString(indent & " ")
209+
Next child
210+
211+
output = output & vbCrLf & indent & "</" & this.Element.TagName & ">"
212+
End If
213+
214+
ToString = output
215+
case EElementType.ELiteral
216+
ToString = this.Literal.content
217+
end Select
218+
End Function
219+
220+
'Serializes an attribute to a string
221+
'@param attr - Attribute to serialize
222+
'@returns Serialized attribute
223+
Private Function serializeAttribute(ByRef attr as Variant) as string
224+
select case varType(attr)
225+
case vbNull
226+
serializeAttribute = ""
227+
case vbString
228+
serializeAttribute = "='" & attr & "'"
229+
case vbBoolean
230+
serializeAttribute = "=" & IIf(attr, "true", "false")
231+
case vbLong, vbInteger
232+
serializeAttribute = "=" & CStr(attr)
233+
case vbDouble, vbSingle
234+
serializeAttribute = "=" & CStr(attr)
235+
case vbDate
236+
serializeAttribute = "='" & format(attr, "yyyy-mm-dd") & "'"
237+
case vbCurrency
238+
serializeAttribute = "=" & CStr(attr)
239+
case vbByte
240+
serializeAttribute = "=" & CStr(attr)
241+
case else
242+
Err.Raise vbObjectError + 2, "Unsupported attribute type: " & VarType(attr) & ". For: " & attr
243+
end select
244+
End Function

0 commit comments

Comments
 (0)