Skip to content

Commit fe40c3b

Browse files
fixes
1 parent 96c4b79 commit fe40c3b

File tree

4 files changed

+212
-167
lines changed

4 files changed

+212
-167
lines changed

Sources/HTMLKitUtilities/HTMLElementAttribute.swift

Lines changed: 133 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public enum HTMLElementAttribute : Hashable {
1414
case role(Extra.ariarole? = nil)
1515

1616
case autocapitalize(Extra.autocapitalize? = nil)
17-
case autofocus(Bool = false)
17+
case autofocus(Bool? = false)
1818
case `class`([String] = [])
1919
case contenteditable(Extra.contenteditable? = nil)
2020
case data(_ id: String, _ value: String? = nil)
@@ -24,13 +24,13 @@ public enum HTMLElementAttribute : Hashable {
2424
case exportparts([String] = [])
2525
case hidden(Extra.hidden? = nil)
2626
case id(String? = nil)
27-
case inert(Bool = false)
27+
case inert(Bool? = false)
2828
case inputmode(Extra.inputmode? = nil)
2929
case `is`(String? = nil)
3030
case itemid(String? = nil)
3131
case itemprop(String? = nil)
3232
case itemref(String? = nil)
33-
case itemscope(Bool = false)
33+
case itemscope(Bool? = false)
3434
case itemtype(String? = nil)
3535
case lang(String? = nil)
3636
case nonce(String? = nil)
@@ -50,7 +50,7 @@ public enum HTMLElementAttribute : Hashable {
5050
/// Usually only used if certain browsers need it for compatibility.
5151
case trailingSlash
5252

53-
case htmx(_ attribute: HTMLElementAttribute.HTMX)
53+
case htmx(_ attribute: HTMLElementAttribute.HTMX? = nil)
5454

5555
case custom(_ id: String, _ value: String?)
5656

@@ -60,15 +60,26 @@ public enum HTMLElementAttribute : Hashable {
6060
// MARK: init rawValue
6161
public init?(key: String, _ function: FunctionCallExprSyntax) {
6262
let expression:ExprSyntax = function.arguments.first!.expression
63-
func string() -> String { expression.stringLiteral!.string }
64-
func boolean() -> Bool { expression.booleanLiteral!.literal.text == "true" }
65-
func enumeration<T : HTMLInitializable>() -> T {
66-
let function:FunctionCallExprSyntax = expression.functionCall!
67-
return T(key: function.calledExpression.memberAccess!.declName.baseName.text, arguments: function.arguments)!
63+
func string() -> String? { expression.stringLiteral?.string }
64+
func boolean() -> Bool? { expression.booleanLiteral?.literal.text == "true" }
65+
func enumeration<T : HTMLInitializable>() -> T? {
66+
guard let function:FunctionCallExprSyntax = expression.functionCall, let member:MemberAccessExprSyntax = function.calledExpression.memberAccess else {
67+
if let member:MemberAccessExprSyntax = expression.memberAccess {
68+
return T(key: member.declName.baseName.text, arguments: function.arguments)
69+
}
70+
return nil
71+
}
72+
return T(key: member.declName.baseName.text, arguments: function.arguments)
73+
}
74+
func int() -> Int? {
75+
guard let s:String = expression.integerLiteral?.literal.text else { return nil }
76+
return Int(s)
6877
}
69-
func int() -> Int { Int(expression.integerLiteral!.literal.text) ?? -1 }
7078
func array_string() -> [String] { expression.array!.elements.map({ $0.expression.stringLiteral!.string }) }
71-
func float() -> Float { Float(expression.floatLiteral!.literal.text) ?? -1 }
79+
func float() -> Float? {
80+
guard let s:String = expression.floatLiteral?.literal.text else { return nil }
81+
return Float(s)
82+
}
7283
switch key {
7384
case "accesskey": self = .accesskey(string())
7485
case "ariaattribute": self = .ariaattribute(enumeration())
@@ -157,11 +168,11 @@ public enum HTMLElementAttribute : Hashable {
157168
case .htmx(let htmx):
158169
switch htmx {
159170
case .ws(let value):
160-
return "ws-" + value.key
171+
return (value != nil ? "ws-" + value!.key : "")
161172
case .sse(let value):
162-
return "sse-" + value.key
173+
return (value != nil ? "sse-" + value!.key : "")
163174
default:
164-
return "hx-" + htmx.key
175+
return (htmx != nil ? "hx-" + htmx!.key : "")
165176
}
166177
case .custom(let id, _): return id
167178
case .event(let event, _): return "on" + event.rawValue
@@ -175,7 +186,7 @@ public enum HTMLElementAttribute : Hashable {
175186
case .ariaattribute(let value): return value?.htmlValue
176187
case .role(let value): return value?.rawValue
177188
case .autocapitalize(let value): return value?.rawValue
178-
case .autofocus(let value): return value ? "" : nil
189+
case .autofocus(let value): return value == true ? "" : nil
179190
case .class(let value): return value.joined(separator: " ")
180191
case .contenteditable(let value): return value?.htmlValue
181192
case .data(_, let value): return value
@@ -185,13 +196,13 @@ public enum HTMLElementAttribute : Hashable {
185196
case .exportparts(let value): return value.joined(separator: ",")
186197
case .hidden(let value): return value?.htmlValue
187198
case .id(let value): return value
188-
case .inert(let value): return value ? "" : nil
199+
case .inert(let value): return value == true ? "" : nil
189200
case .inputmode(let value): return value?.rawValue
190201
case .is(let value): return value
191202
case .itemid(let value): return value
192203
case .itemprop(let value): return value
193204
case .itemref(let value): return value
194-
case .itemscope(let value): return value ? "" : nil
205+
case .itemscope(let value): return value == true ? "" : nil
195206
case .itemtype(let value): return value
196207
case .lang(let value): return value
197208
case .nonce(let value): return value
@@ -208,7 +219,7 @@ public enum HTMLElementAttribute : Hashable {
208219

209220
case .trailingSlash: return nil
210221

211-
case .htmx(let htmx): return htmx.htmlValue
222+
case .htmx(let htmx): return htmx?.htmlValue
212223
case .custom(_, let value): return value
213224
case .event(_, let value): return value
214225
}
@@ -241,88 +252,99 @@ public extension HTMLElementAttribute.Extra {
241252
// MARK: aria attributes
242253
// https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes
243254
enum ariaattribute : HTMLInitializable {
244-
case activedescendant(String)
245-
case atomic(Bool)
246-
case autocomplete(Autocomplete)
255+
case activedescendant(String?)
256+
case atomic(Bool?)
257+
case autocomplete(Autocomplete?)
247258

248-
case braillelabel(String)
249-
case brailleroledescription(String)
250-
case busy(Bool)
259+
case braillelabel(String?)
260+
case brailleroledescription(String?)
261+
case busy(Bool?)
251262

252-
case checked(Checked)
253-
case colcount(Int)
254-
case colindex(Int)
255-
case colindextext(String)
256-
case colspan(Int)
263+
case checked(Checked?)
264+
case colcount(Int?)
265+
case colindex(Int?)
266+
case colindextext(String?)
267+
case colspan(Int?)
257268
case controls([String])
258-
case current(Current)
269+
case current(Current?)
259270

260271
case describedby([String])
261-
case description(String)
272+
case description(String?)
262273
case details([String])
263-
case disabled(Bool)
264-
case dropeffect(DropEffect)
274+
case disabled(Bool?)
275+
case dropeffect(DropEffect?)
265276

266-
case errormessage(String)
267-
case expanded(Expanded)
277+
case errormessage(String?)
278+
case expanded(Expanded?)
268279

269280
case flowto([String])
270281

271-
case grabbed(Grabbed)
282+
case grabbed(Grabbed?)
272283

273-
case haspopup(HasPopup)
274-
case hidden(Hidden)
284+
case haspopup(HasPopup?)
285+
case hidden(Hidden?)
275286

276-
case invalid(Invalid)
287+
case invalid(Invalid?)
277288

278-
case keyshortcuts(String)
289+
case keyshortcuts(String?)
279290

280-
case label(String)
291+
case label(String?)
281292
case labelledby([String])
282-
case level(Int)
283-
case live(Live)
293+
case level(Int?)
294+
case live(Live?)
284295

285-
case modal(Bool)
286-
case multiline(Bool)
287-
case multiselectable(Bool)
296+
case modal(Bool?)
297+
case multiline(Bool?)
298+
case multiselectable(Bool?)
288299

289-
case orientation(Orientation)
300+
case orientation(Orientation?)
290301
case owns([String])
291302

292-
case placeholder(String)
293-
case posinset(Int)
294-
case pressed(Pressed)
303+
case placeholder(String?)
304+
case posinset(Int?)
305+
case pressed(Pressed?)
295306

296-
case readonly(Bool)
307+
case readonly(Bool?)
297308

298-
case relevant(Relevant)
299-
case required(Bool)
300-
case roledescription(String)
301-
case rowcount(Int)
302-
case rowindex(Int)
303-
case rowindextext(String)
304-
case rowspan(Int)
309+
case relevant(Relevant?)
310+
case required(Bool?)
311+
case roledescription(String?)
312+
case rowcount(Int?)
313+
case rowindex(Int?)
314+
case rowindextext(String?)
315+
case rowspan(Int?)
305316

306-
case selected(Selected)
307-
case setsize(Int)
308-
case sort(Sort)
317+
case selected(Selected?)
318+
case setsize(Int?)
319+
case sort(Sort?)
309320

310-
case valuemax(Float)
311-
case valuemin(Float)
312-
case valuenow(Float)
313-
case valuetext(String)
321+
case valuemax(Float?)
322+
case valuemin(Float?)
323+
case valuenow(Float?)
324+
case valuetext(String?)
314325

315326
public init?(key: String, arguments: LabeledExprListSyntax) {
316327
let expression:ExprSyntax = arguments.first!.expression
317-
func string() -> String { expression.stringLiteral!.string }
318-
func boolean() -> Bool { expression.booleanLiteral!.literal.text == "true" }
319-
func enumeration<T : HTMLInitializable>() -> T {
320-
let function:FunctionCallExprSyntax = expression.functionCall!
321-
return T(key: function.calledExpression.memberAccess!.declName.baseName.text, arguments: function.arguments)!
328+
func string() -> String? { expression.stringLiteral?.string }
329+
func boolean() -> Bool? { expression.booleanLiteral?.literal.text == "true" }
330+
func enumeration<T : HTMLInitializable>() -> T? {
331+
guard let function:FunctionCallExprSyntax = expression.functionCall, let member:MemberAccessExprSyntax = function.calledExpression.memberAccess else {
332+
if let member:MemberAccessExprSyntax = expression.memberAccess {
333+
return T(key: member.declName.baseName.text, arguments: arguments)
334+
}
335+
return nil
336+
}
337+
return T(key: member.declName.baseName.text, arguments: function.arguments)
338+
}
339+
func int() -> Int? {
340+
guard let s:String = expression.integerLiteral?.literal.text else { return nil }
341+
return Int(s)
322342
}
323-
func int() -> Int { Int(expression.integerLiteral!.literal.text) ?? -1 }
324343
func array_string() -> [String] { expression.array!.elements.map({ $0.expression.stringLiteral!.string }) }
325-
func float() -> Float { Float(expression.floatLiteral!.literal.text) ?? -1 }
344+
func float() -> Float? {
345+
guard let s:String = expression.floatLiteral?.literal.text else { return nil }
346+
return Float(s)
347+
}
326348
switch key {
327349
case "activedescendant": self = .activedescendant(string())
328350
case "atomic": self = .atomic(boolean())
@@ -440,59 +462,63 @@ public extension HTMLElementAttribute.Extra {
440462
}
441463

442464
public var htmlValue : String? {
465+
func unwrap<T>(_ value: T?) -> String? {
466+
guard let value:T = value else { return nil }
467+
return "\(value)"
468+
}
443469
switch self {
444470
case .activedescendant(let value): return value
445-
case .atomic(let value): return "\(value)"
446-
case .autocomplete(let value): return value.rawValue
471+
case .atomic(let value): return unwrap(value)
472+
case .autocomplete(let value): return value?.rawValue
447473
case .braillelabel(let value): return value
448474
case .brailleroledescription(let value): return value
449-
case .busy(let value): return "\(value)"
450-
case .checked(let value): return value.rawValue
451-
case .colcount(let value): return "\(value)"
452-
case .colindex(let value): return "\(value)"
475+
case .busy(let value): return unwrap(value)
476+
case .checked(let value): return value?.rawValue
477+
case .colcount(let value): return unwrap(value)
478+
case .colindex(let value): return unwrap(value)
453479
case .colindextext(let value): return value
454-
case .colspan(let value): return "\(value)"
480+
case .colspan(let value): return unwrap(value)
455481
case .controls(let value): return value.joined(separator: " ")
456-
case .current(let value): return value.rawValue
482+
case .current(let value): return value?.rawValue
457483
case .describedby(let value): return value.joined(separator: " ")
458484
case .description(let value): return value
459485
case .details(let value): return value.joined(separator: " ")
460-
case .disabled(let value): return "\(value)"
461-
case .dropeffect(let value): return value.rawValue
486+
case .disabled(let value): return unwrap(value)
487+
case .dropeffect(let value): return value?.rawValue
462488
case .errormessage(let value): return value
463-
case .expanded(let value): return value.rawValue
489+
case .expanded(let value): return value?.rawValue
464490
case .flowto(let value): return value.joined(separator: " ")
465-
case .grabbed(let value): return value.rawValue
466-
case .haspopup(let value): return value.rawValue
467-
case .hidden(let value): return value.rawValue
468-
case .invalid(let value): return value.rawValue
491+
case .grabbed(let value): return value?.rawValue
492+
case .haspopup(let value): return value?.rawValue
493+
case .hidden(let value): return value?.rawValue
494+
case .invalid(let value): return value?.rawValue
469495
case .keyshortcuts(let value): return value
470496
case .label(let value): return value
471497
case .labelledby(let value): return value.joined(separator: " ")
472-
case .level(let value): return "\(value)"
473-
case .live(let value): return value.rawValue
474-
case .modal(let value): return "\(value)"
475-
case .multiline(let value): return "\(value)"
476-
case .multiselectable(let value): return "\(value)"
477-
case .orientation(let value): return value.rawValue
498+
case .level(let value): return unwrap(value)
499+
case .live(let value): return value?.rawValue
500+
case .modal(let value): return unwrap(value)
501+
case .multiline(let value): return unwrap(value)
502+
case .multiselectable(let value): return unwrap(value)
503+
case .orientation(let value): return value?.rawValue
478504
case .owns(let value): return value.joined(separator: " ")
479505
case .placeholder(let value): return value
480-
case .posinset(let value): return "\(value)"
481-
case .pressed(let value): return value.rawValue
482-
case .readonly(let value): return "\(value)"
483-
case .relevant(let value): return value.rawValue
484-
case .required(let value): return "\(value)"
506+
case .posinset(let value): return unwrap(value)
507+
case .pressed(let value): return value?.rawValue
508+
case .readonly(let value): return unwrap(value)
509+
case .relevant(let value): return value?.rawValue
510+
case .required(let value): return unwrap(value)
485511
case .roledescription(let value): return value
486-
case .rowcount(let value): return "\(value)"
487-
case .rowindex(let value): return "\(value)"
512+
case .rowcount(let value): return unwrap(value)
513+
case .rowindex(let value): return unwrap(value)
488514
case .rowindextext(let value): return value
489-
case .rowspan(let value): return "\(value)"
490-
case .selected(let value): return value.rawValue
491-
case .setsize(let value): return "\(value)"
492-
case .sort(let value): return value.rawValue
493-
case .valuemax(let value): return "\(value)"
494-
case .valuemin(let value): return "\(value)"
495-
case .valuenow(let value): return "\(value)"
515+
case .rowspan(let value): return unwrap(value)
516+
case .selected(let value): return value?.rawValue
517+
case .setsize(let value): return unwrap(value)
518+
case .sort(let value): return value?.rawValue
519+
case .valuemax(let value): return unwrap(value)
520+
case .valuemin(let value): return unwrap(value)
521+
case .valuenow(let value): return unwrap(value)
496522
case .valuetext(let value): return value
497523
}
498524
}

0 commit comments

Comments
 (0)