Skip to content

Commit e4e5085

Browse files
stop reinventing the wheel...; some organization
1 parent 6622b1a commit e4e5085

File tree

10 files changed

+1959
-2210
lines changed

10 files changed

+1959
-2210
lines changed

Package.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ let package = Package(
3333
name: "HTMLKitUtilities",
3434
dependencies: [
3535
"HTMLKitUtilityMacros",
36+
.product(name: "SwiftDiagnostics", package: "swift-syntax"),
37+
.product(name: "SwiftSyntax", package: "swift-syntax"),
38+
.product(name: "SwiftSyntaxMacros", package: "swift-syntax"),
3639
.product(name: "NIOCore", package: "swift-nio")
3740
]
3841
),

Sources/HTMLKitMacros/HTMLElement.swift

Lines changed: 7 additions & 426 deletions
Large diffs are not rendered by default.

Sources/HTMLKitMacros/HTMLKitMacros.swift

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,6 @@
77

88
import SwiftCompilerPlugin
99
import SwiftSyntaxMacros
10-
import SwiftDiagnostics
11-
12-
// MARK: DiagnosticMsg
13-
struct DiagnosticMsg : DiagnosticMessage {
14-
let message:String
15-
let diagnosticID:MessageID
16-
let severity:DiagnosticSeverity
17-
18-
init(id: String, message: String, severity: DiagnosticSeverity = .error) {
19-
self.message = message
20-
self.diagnosticID = MessageID(domain: "HTMLKitMacros", id: id)
21-
self.severity = severity
22-
}
23-
}
24-
extension DiagnosticMsg : FixItMessage {
25-
var fixItID : MessageID { diagnosticID }
26-
}
27-
2810

2911
@main
3012
struct HTMLKitMacros : CompilerPlugin {

Sources/HTMLKitUtilities/HTMLElementAttribute.swift

Lines changed: 1132 additions & 0 deletions
Large diffs are not rendered by default.

Sources/HTMLKitUtilities/HTMLKitUtilities.swift

Lines changed: 447 additions & 1415 deletions
Large diffs are not rendered by default.

Sources/HTMLKitUtilities/HTMX.swift

Lines changed: 5 additions & 302 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@ public extension HTMLElementAttribute {
4949

5050
public init?(rawValue: String) {
5151
guard rawValue.last == ")" else { return nil }
52-
let key:Substring = rawValue.split(separator: "(")[0]
52+
var key:Substring = rawValue.split(separator: "(")[0]
53+
if key.hasPrefix("hx-") {
54+
key.removeFirst(3)
55+
}
5356
func literal() -> String { HTMLElementAttribute.literal(key: key, rawValue: rawValue) }
5457
func string() -> String { HTMLElementAttribute.string(key: key, rawValue: rawValue) }
5558
func boolean() -> Bool { HTMLElementAttribute.boolean(key: key, rawValue: rawValue) }
@@ -261,7 +264,7 @@ public extension HTMLElementAttribute {
261264
return ""
262265
}
263266
case .sync(let selector, let strategy):
264-
return selector + (strategy == nil ? "" : ":" + strategy!.htmlValue)
267+
return selector + (strategy == nil ? "" : ":" + strategy!.htmlValue!)
265268
case .validate(let value): return value.rawValue
266269

267270
case .get(let value): return value
@@ -282,304 +285,4 @@ public extension HTMLElementAttribute {
282285
}
283286
}
284287
}
285-
}
286-
287-
// MARK: Attributes
288-
289-
290-
291-
292-
public extension HTMLElementAttribute.HTMX {
293-
// MARK: Boost
294-
enum TrueOrFalse : String, HTMLInitializable {
295-
case `true`, `false`
296-
}
297-
298-
// MARK: Event
299-
enum Event : String {
300-
case abort
301-
case afterOnLoad
302-
case afterProcessNode
303-
case afterRequest
304-
case afterSettle
305-
case afterSwap
306-
case beforeCleanupElement
307-
case beforeOnLoad
308-
case beforeProcessNode
309-
case beforeRequest
310-
case beforeSend
311-
case beforeSwap
312-
case beforeTransition
313-
case configRequest
314-
case confirm
315-
case historyCacheError
316-
case historyCacheMiss
317-
case historyCacheMissError
318-
case historyCacheMissLoad
319-
case historyRestore
320-
case beforeHistorySave
321-
case load
322-
case noSSESourceError
323-
case onLoadError
324-
case oobAfterSwap
325-
case oobBeforeSwap
326-
case oobErrorNoTarget
327-
case prompt
328-
case beforeHistoryUpdate
329-
case pushedIntoHistory
330-
case replacedInHistory
331-
case responseError
332-
case sendError
333-
case sseError
334-
case sseOpen
335-
case swapError
336-
case targetError
337-
case timeout
338-
case trigger
339-
case validateURL
340-
case validationValidate
341-
case validationFailed
342-
case validationHalted
343-
case xhrAbort
344-
case xhrLoadEnd
345-
case xhrLoadStart
346-
case xhrProgress
347-
348-
public var key : String {
349-
func slug() -> String {
350-
switch self {
351-
case .afterOnLoad: return "after-on-load"
352-
case .afterProcessNode: return "after-process-node"
353-
case .afterRequest: return "after-request"
354-
case .afterSettle: return "after-settle"
355-
case .afterSwap: return "after-swap"
356-
case .beforeCleanupElement: return "before-cleanup-element"
357-
case .beforeOnLoad: return "before-on-load"
358-
case .beforeProcessNode: return "before-process-node"
359-
case .beforeRequest: return "before-request"
360-
case .beforeSend: return "before-send"
361-
case .beforeSwap: return "before-swap"
362-
case .beforeTransition: return "before-transition"
363-
case .configRequest: return "config-request"
364-
case .historyCacheError: return "history-cache-error"
365-
case .historyCacheMiss: return "history-cache-miss"
366-
case .historyCacheMissError: return "history-cache-miss-error"
367-
case .historyCacheMissLoad: return "history-cache-miss-load"
368-
case .historyRestore: return "history-restore"
369-
case .beforeHistorySave: return "before-history-save"
370-
case .noSSESourceError: return "no-sse-source-error"
371-
case .onLoadError: return "on-load-error"
372-
case .oobAfterSwap: return "oob-after-swap"
373-
case .oobBeforeSwap: return "oob-before-swap"
374-
case .oobErrorNoTarget: return "oob-error-no-target"
375-
case .beforeHistoryUpdate: return "before-history-update"
376-
case .pushedIntoHistory: return "pushed-into-history"
377-
case .replacedInHistory: return "replaced-in-history"
378-
case .responseError: return "response-error"
379-
case .sendError: return "send-error"
380-
case .sseError: return "sse-error"
381-
case .sseOpen: return "sse-open"
382-
case .swapError: return "swap-error"
383-
case .targetError: return "target-error"
384-
case .validateURL: return "validate-url"
385-
case .validationValidate: return "validation:validate"
386-
case .validationFailed: return "validation:failed"
387-
case .validationHalted: return "validation:halted"
388-
case .xhrAbort: return "xhr:abort"
389-
case .xhrLoadEnd: return "xhr:loadend"
390-
case .xhrLoadStart: return "xhr:loadstart"
391-
case .xhrProgress: return "xhr:progress"
392-
default: return rawValue
393-
}
394-
}
395-
return ":" + slug()
396-
}
397-
}
398-
399-
// MARK: Params
400-
enum Params {
401-
case all
402-
case none
403-
case not([String])
404-
case list([String])
405-
406-
public init?(rawValue: String) {
407-
let key:Substring = rawValue.split(separator: "(")[0]
408-
func array_string() -> [String] {
409-
let string:String = String(rawValue[rawValue.index(rawValue.startIndex, offsetBy: key.count + 2)..<rawValue.index(before: rawValue.endIndex)])
410-
let ranges:[Range<String.Index>] = try! string.ranges(of: Regex("\"([^\"]+)\"")) // TODO: fix? (doesn't parse correctly if the string contains escaped quotation marks)
411-
return ranges.map({
412-
let item:String = String(string[$0])
413-
return String(item[item.index(after: item.startIndex)..<item.index(before: item.endIndex)])
414-
})
415-
}
416-
switch key {
417-
case "all": self = .all
418-
case "none": self = .none
419-
case "not": self = .not(array_string())
420-
case "list": self = .list(array_string())
421-
default: return nil
422-
}
423-
}
424-
425-
public var htmlValue : String {
426-
switch self {
427-
case .all: return "*"
428-
case .none: return "none"
429-
case .not(let list): return "not " + list.joined(separator: ",")
430-
case .list(let list): return list.joined(separator: ",")
431-
}
432-
}
433-
}
434-
435-
// MARK: Swap
436-
enum Swap : String, HTMLInitializable {
437-
case innerHTML, outerHTML
438-
case textContent
439-
case beforebegin, afterbegin
440-
case beforeend, afterend
441-
case delete, none
442-
}
443-
444-
// MARK: Sync
445-
enum SyncStrategy {
446-
case drop, abort, replace
447-
case queue(Queue)
448-
449-
public init?(rawValue: String) {
450-
let values:[Substring] = rawValue.split(separator: "(")
451-
switch values[0] {
452-
case "drop": self = .drop
453-
case "abort": self = .abort
454-
case "replace": self = .replace
455-
case "queue":
456-
guard let value_index:Substring.Index = values[1].firstIndex(where: { $0.isLetter }) else { return nil }
457-
let value:Substring = rawValue[value_index..<values[1].index(before: values[1].endIndex)]
458-
self = .queue(Queue(rawValue: String(value))!)
459-
break
460-
default: return nil
461-
}
462-
}
463-
464-
public enum Queue : String {
465-
case first, last, all
466-
}
467-
468-
public var htmlValue : String {
469-
switch self {
470-
case .drop: return "drop"
471-
case .abort: return "abort"
472-
case .replace: return "replace"
473-
case .queue(let queue): return "queue " + queue.rawValue
474-
}
475-
}
476-
}
477-
478-
// MARK: URL
479-
enum URL {
480-
case `true`, `false`
481-
case url(String)
482-
483-
public init?(rawValue: String) {
484-
let key:Substring = rawValue.split(separator: "(")[0]
485-
switch key {
486-
case "true": self = .true
487-
case "false": self = .false
488-
case "url": self = .url(HTMLElementAttribute.string(key: key, rawValue: rawValue))
489-
default: return nil
490-
}
491-
}
492-
493-
public var htmlValue : String {
494-
switch self {
495-
case .true: return "true"
496-
case .false: return "false"
497-
case .url(let url): return url.hasPrefix("http://") || url.hasPrefix("https://") ? url : (url.first == "/" ? "" : "/") + url
498-
}
499-
}
500-
}
501-
}
502-
503-
// MARK: Server Sent Events
504-
public extension HTMLElementAttribute.HTMX {
505-
enum ServerSentEvents {
506-
case connect(String)
507-
case swap(String)
508-
case close(String)
509-
510-
public init?(rawValue: String) {
511-
guard rawValue.last == ")" else { return nil }
512-
let key:Substring = rawValue.split(separator: "(")[0]
513-
func string() -> String { HTMLElementAttribute.string(key: key, rawValue: rawValue) }
514-
switch key {
515-
case "connect": self = .connect(string())
516-
case "swap": self = .swap(string())
517-
case "close": self = .close(string())
518-
default: return nil
519-
}
520-
}
521-
522-
public var key : String {
523-
switch self {
524-
case .connect(_): return "connect"
525-
case .swap(_): return "swap"
526-
case .close(_): return "close"
527-
}
528-
}
529-
530-
public var htmlValue : String {
531-
switch self {
532-
case .connect(let value),
533-
.swap(let value),
534-
.close(let value):
535-
return value
536-
}
537-
}
538-
}
539-
}
540-
541-
// MARK: WebSocket
542-
public extension HTMLElementAttribute.HTMX {
543-
enum WebSocket {
544-
case connect(String)
545-
case send(Bool)
546-
547-
public init?(rawValue: String) {
548-
guard rawValue.last == ")" else { return nil }
549-
let key:Substring = rawValue.split(separator: "(")[0]
550-
func string() -> String { HTMLElementAttribute.string(key: key, rawValue: rawValue) }
551-
func boolean() -> Bool { HTMLElementAttribute.boolean(key: key, rawValue: rawValue) }
552-
switch key {
553-
case "connect": self = .connect(string())
554-
case "send": self = .send(boolean())
555-
default: return nil
556-
}
557-
}
558-
559-
public var key : String {
560-
switch self {
561-
case .connect(_): return "connect"
562-
case .send(_): return "send"
563-
}
564-
}
565-
566-
public var htmlValue : String {
567-
switch self {
568-
case .connect(let value): return value
569-
case .send(_): return ""
570-
}
571-
}
572-
573-
public enum Event : String {
574-
case wsConnecting
575-
case wsOpen
576-
case wsClose
577-
case wsError
578-
case wsBeforeMessage
579-
case wsAfterMessage
580-
case wsConfigSend
581-
case wsBeforeSend
582-
case wsAfterSend
583-
}
584-
}
585288
}

0 commit comments

Comments
 (0)