From ca09384745e846e5058076714492786a910268d7 Mon Sep 17 00:00:00 2001 From: Mattes Mohr Date: Sat, 25 Dec 2021 13:21:32 +0100 Subject: [PATCH] Quick fix (#59) * Fix issues * Clean up code * Clean up comments * Add a custom attribute --- .../HTMLKit/Compatibility/Deprecations.swift | 3 + .../External/Attributes/BasicAttributes.swift | 537 ++++++++------ .../External/Attributes/EventAttributes.swift | 290 ++++---- Sources/HTMLKit/External/Components.swift | 30 +- .../External/Elements/BasicElements.swift | 22 +- .../External/Elements/BodyElements.swift | 664 +++++++++++++----- .../Elements/DefinitionElements.swift | 26 +- .../External/Elements/FigureElements.swift | 16 +- .../External/Elements/FormElements.swift | 54 +- .../External/Elements/HeadElements.swift | 56 +- .../External/Elements/HtmlElements.swift | 22 +- .../External/Elements/InputElements.swift | 42 +- .../External/Elements/ListElements.swift | 16 +- .../External/Elements/MapElements.swift | 14 +- .../External/Elements/MediaElements.swift | 22 +- .../External/Elements/ObjectElements.swift | 14 +- .../External/Elements/RubyElements.swift | 26 +- .../External/Elements/TableElements.swift | 94 ++- Sources/HTMLKit/External/Functions.swift | 50 -- Sources/HTMLKit/External/Layouts.swift | 18 +- Sources/HTMLKit/External/Statements.swift | 229 ++++-- Sources/HTMLKit/External/Types.swift | 117 ++- .../Internal/Core/Anys/AnyAttribute.swift | 10 +- .../Internal/Core/Anys/AnyContent.swift | 14 +- .../Internal/Core/Anys/AnyElement.swift | 10 +- .../HTMLKit/Internal/Core/Anys/AnyNode.swift | 10 +- .../Core/Builders/ContentBuilder.swift | 132 +--- .../Core/Builders/StringBuilder.swift | 11 +- Sources/HTMLKit/Internal/Core/Elements.swift | 62 +- .../Core/Extensions/Datatypes+Content.swift | 10 + Sources/HTMLKit/Internal/Core/Nodes.swift | 22 +- .../Core/Rendering/Context/Conditions.swift | 254 ++++--- .../Rendering/Context/ContextVariable.swift | 39 +- .../Core/Rendering/Context/DateVariable.swift | 80 +++ .../Rendering/Context/EscapingOption.swift | 9 +- .../Core/Rendering/Context/HTMLContext.swift | 43 +- .../Rendering/Context/TemplateValue.swift | 122 +++- .../Context/TemplateValueMapping.swift | 21 +- .../Core/Rendering/ContextManager.swift | 30 +- .../Core/Rendering/EnvironmentModifier.swift | 17 +- .../Internal/Core/Rendering/Formula.swift | 65 +- .../Internal/Core/Rendering/Renderer.swift | 83 ++- .../Core/Variables/DateVariable.swift | 111 --- .../Internal/Core/Variables/StringValue.swift | 9 - .../Features/Conversion/Converter.swift | 220 +++--- .../Features/Conversion/Stencils.swift | 12 +- .../Features/Localization/Localized.swift | 10 +- 47 files changed, 2194 insertions(+), 1574 deletions(-) delete mode 100644 Sources/HTMLKit/External/Functions.swift create mode 100644 Sources/HTMLKit/Internal/Core/Rendering/Context/DateVariable.swift delete mode 100644 Sources/HTMLKit/Internal/Core/Variables/DateVariable.swift delete mode 100644 Sources/HTMLKit/Internal/Core/Variables/StringValue.swift diff --git a/Sources/HTMLKit/Compatibility/Deprecations.swift b/Sources/HTMLKit/Compatibility/Deprecations.swift index c4c7975e..71022e00 100644 --- a/Sources/HTMLKit/Compatibility/Deprecations.swift +++ b/Sources/HTMLKit/Compatibility/Deprecations.swift @@ -30,3 +30,6 @@ public protocol HTMLNode {} @available(*, deprecated, message: "Is no longer in the scope.") public enum HTMLIdentifier {} + +@available(*, deprecated, message: "Is no longer in the scope.") +public struct StringValue {} diff --git a/Sources/HTMLKit/External/Attributes/BasicAttributes.swift b/Sources/HTMLKit/External/Attributes/BasicAttributes.swift index 3868521a..1e8946c3 100644 --- a/Sources/HTMLKit/External/Attributes/BasicAttributes.swift +++ b/Sources/HTMLKit/External/Attributes/BasicAttributes.swift @@ -1,27 +1,27 @@ -/// # Description: +/// ## Description /// The file contains the basic attribute handlers. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr import OrderedCollections -/// # Description: +/// ## Description /// The alias combines the global attributes. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#global-attributes /// -public typealias GlobalAttributes = AccessKeyAttribute & AutocapitalizeAttribute & AutofocusAttribute & ClassAttribute & EditAttribute & DirectionAttribute & DragAttribute & EnterKeyHintAttribute & HiddenAttribute & InputModeAttribute & IsAttribute & ItemIdAttribute & ItemPropertyAttribute & ItemReferenceAttribute & ItemScopeAttribute & ItemTypeAttribute & IdentifierAttribute & LanguageAttribute & NonceAttribute & RoleAttribute & SpellCheckAttribute & StyleAttribute & TabulatorAttribute & TitleAttribute & TranslateAttribute +public typealias GlobalAttributes = AccessKeyAttribute & AutocapitalizeAttribute & AutofocusAttribute & ClassAttribute & EditAttribute & DirectionAttribute & DragAttribute & EnterKeyHintAttribute & HiddenAttribute & InputModeAttribute & IsAttribute & ItemIdAttribute & ItemPropertyAttribute & ItemReferenceAttribute & ItemScopeAttribute & ItemTypeAttribute & IdentifierAttribute & LanguageAttribute & NonceAttribute & RoleAttribute & SpellCheckAttribute & StyleAttribute & TabulatorAttribute & TitleAttribute & TranslateAttribute & CustomAttribute -/// # Description: +/// ## Description /// The protocol provides the element with the accesskey handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-accesskey-attribute /// public protocol AccessKeyAttribute: AnyAttribute { @@ -61,10 +61,10 @@ extension AccessKeyAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the accept handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-input-accept /// public protocol AcceptAttribute: AnyAttribute { @@ -104,10 +104,10 @@ extension AcceptAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the action handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-input-alt /// public protocol ActionAttribute: AnyAttribute { @@ -147,10 +147,10 @@ extension ActionAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the alternate handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-input-alt /// public protocol AlternateAttribute: AnyAttribute { @@ -190,10 +190,10 @@ extension AlternateAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the asynchronously handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-autocapitalize /// public protocol AsynchronouslyAttribute: AnyAttribute { @@ -233,10 +233,10 @@ extension AsynchronouslyAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the autocapitalize handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-autocapitalize /// public protocol AutocapitalizeAttribute: AnyAttribute { @@ -276,10 +276,10 @@ extension AutocapitalizeAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the autocomplete handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-fe-autocomplete /// public protocol AutocompleteAttribute: AnyAttribute { @@ -319,10 +319,10 @@ extension AutocompleteAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the autofocus handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-fe-autofocus /// public protocol AutofocusAttribute: AnyAttribute { @@ -362,10 +362,10 @@ extension AutofocusAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the autoplay handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-input-checked /// public protocol AutoplayAttribute: AnyAttribute { @@ -405,10 +405,53 @@ extension AutoplayAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description +/// The protocol provides the element with the charset handler. +/// +/// ## References +/// https://html.spec.whatwg.org/#attr-meta-charset +/// +public protocol CharsetAttribute: AnyAttribute { + + /// The func adds + /// + /// + func charset(_ value: Charset) -> Self +} + +extension CharsetAttribute { + + internal var key: String { "charset" } +} + +extension CharsetAttribute where Self: ContentNode { + + internal func mutate(charset value: String) -> Self { + + guard var attributes = self.attributes else { + return .init(attributes: set(key: key, value: value), content: content) + } + + return .init(attributes: update(key: key, value: value, on: &attributes), content: content) + } +} + +extension CharsetAttribute where Self: EmptyNode { + + internal func mutate(charset value: String) -> Self { + + guard var attributes = self.attributes else { + return .init(attributes: set(key: key, value: value)) + } + + return .init(attributes: update(key: key, value: value, on: &attributes)) + } +} + +/// ## Description /// The protocol provides the element with the checked handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-input-checked /// public protocol CheckedAttribute: AnyAttribute { @@ -448,10 +491,10 @@ extension CheckedAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the cite handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-tdth-colspan /// public protocol CiteAttribute: AnyAttribute { @@ -491,10 +534,10 @@ extension CiteAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the class handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-tdth-colspan /// public protocol ClassAttribute: AnyAttribute{ @@ -534,10 +577,10 @@ extension ClassAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the columns handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-tdth-colspan /// public protocol ColumnsAttribute: AnyAttribute { @@ -577,10 +620,10 @@ extension ColumnsAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the columnspan handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-tdth-colspan /// public protocol ColumnSpanAttribute: AnyAttribute { @@ -620,10 +663,10 @@ extension ColumnSpanAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the content handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-contenteditable /// public protocol ContentAttribute: AnyAttribute { @@ -668,10 +711,10 @@ extension ContentAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the iseditable handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-contenteditable /// public protocol EditAttribute: AnyAttribute { @@ -711,10 +754,10 @@ extension EditAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the controls handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-accesskey-attribute /// public protocol ControlsAttribute: AnyAttribute { @@ -754,10 +797,10 @@ extension ControlsAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the coordinates handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-accesskey-attribute /// public protocol CoordinatesAttribute: AnyAttribute { @@ -797,10 +840,10 @@ extension CoordinatesAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the date handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-accesskey-attribute /// public protocol DataAttribute: AnyAttribute{ @@ -840,10 +883,10 @@ extension DataAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the datetime handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-accesskey-attribute /// public protocol DateTimeAttribute: AnyAttribute { @@ -883,10 +926,10 @@ extension DateTimeAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the default handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-track-default /// public protocol DefaultAttribute: AnyAttribute { @@ -926,10 +969,10 @@ extension DefaultAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the defer handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-script-defer /// public protocol DeferAttribute: AnyAttribute { @@ -969,10 +1012,10 @@ extension DeferAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the direction handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-dir /// public protocol DirectionAttribute: AnyAttribute { @@ -1012,10 +1055,10 @@ extension DirectionAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the disabled handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-fe-disabled /// public protocol DisabledAttribute: AnyAttribute { @@ -1055,10 +1098,10 @@ extension DisabledAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the download handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-hyperlink-download /// public protocol DownloadAttribute: AnyAttribute { @@ -1098,10 +1141,10 @@ extension DownloadAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the isdraggable handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-draggable /// public protocol DragAttribute: AnyAttribute { @@ -1141,10 +1184,10 @@ extension DragAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the encoding handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-fs-enctype /// public protocol EncodingAttribute: AnyAttribute { @@ -1184,10 +1227,10 @@ extension EncodingAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the enterkeyhint handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-enterkeyhint /// public protocol EnterKeyHintAttribute: AnyAttribute { @@ -1227,10 +1270,10 @@ extension EnterKeyHintAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the for handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-label-for /// public protocol ForAttribute: AnyAttribute { @@ -1270,10 +1313,10 @@ extension ForAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the form handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-fae-form /// public protocol FormAttribute: AnyAttribute { @@ -1313,10 +1356,10 @@ extension FormAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the formaction handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-fs-formaction /// public protocol FormActionAttribute: AnyAttribute { @@ -1356,10 +1399,53 @@ extension FormActionAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description +/// The protocol provides the element with the http-equiv handler. +/// +/// ## References +/// https://html.spec.whatwg.org/#attr-meta-http-equiv +/// +public protocol EquivalentAttribute: AnyAttribute { + + /// The handler specifiies the header cells for the element. + /// + /// + func equivalent(_ value: Equivalent) -> Self +} + +extension EquivalentAttribute { + + internal var key: String { "http-equiv" } +} + +extension HeaderAttribute where Self: ContentNode { + + internal func mutate(httpequiv value: String) -> Self { + + guard var attributes = self.attributes else { + return .init(attributes: set(key: key, value: value), content: content) + } + + return .init(attributes: update(key: key, value: value, on: &attributes), content: content) + } +} + +extension EquivalentAttribute where Self: EmptyNode { + + internal func mutate(httpequiv value: String) -> Self { + + guard var attributes = self.attributes else { + return .init(attributes: set(key: key, value: value)) + } + + return .init(attributes: update(key: key, value: value, on: &attributes)) + } +} + +/// ## Description /// The protocol provides the element with the headers handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-tdth-headers /// public protocol HeaderAttribute: AnyAttribute { @@ -1399,10 +1485,10 @@ extension HeaderAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the height handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-dim-height /// public protocol HeightAttribute: AnyAttribute { @@ -1442,10 +1528,10 @@ extension HeightAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with hidden handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-hidden) /// public protocol HiddenAttribute: AnyAttribute { @@ -1485,10 +1571,10 @@ extension HiddenAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with high handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-meter-high) /// public protocol HighAttribute: AnyAttribute { @@ -1528,10 +1614,10 @@ extension HighAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with reference handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-hyperlink-href) /// public protocol ReferenceAttribute: AnyAttribute { @@ -1576,10 +1662,10 @@ extension ReferenceAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the language reference handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-hyperlink-hreflang /// public protocol ReferenceLanguageAttribute: AnyAttribute { @@ -1619,10 +1705,10 @@ extension ReferenceLanguageAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the id handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-id-attribute /// public protocol IdentifierAttribute: AnyAttribute { @@ -1667,10 +1753,10 @@ extension IdentifierAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the ismap handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-img-ismap /// public protocol IsMapAttribute: AnyAttribute { @@ -1710,10 +1796,10 @@ extension IsMapAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the inputmode handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-inputmode /// public protocol InputModeAttribute: AnyAttribute { @@ -1753,10 +1839,10 @@ extension InputModeAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the inputmode handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-is /// public protocol IsAttribute: AnyAttribute { @@ -1796,10 +1882,10 @@ extension IsAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the itemid handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-itemid /// public protocol ItemIdAttribute: AnyAttribute { @@ -1839,10 +1925,10 @@ extension ItemIdAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the itemproperty handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#names:-the-itemprop-attribute /// public protocol ItemPropertyAttribute: AnyAttribute { @@ -1882,10 +1968,10 @@ extension ItemPropertyAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the itemreference handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-itemref /// public protocol ItemReferenceAttribute: AnyAttribute { @@ -1925,10 +2011,10 @@ extension ItemReferenceAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the itemscope handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-itemscope /// public protocol ItemScopeAttribute: AnyAttribute { @@ -1968,10 +2054,10 @@ extension ItemScopeAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the itemtype handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-itemtype /// public protocol ItemTypeAttribute: AnyAttribute { @@ -2011,10 +2097,10 @@ extension ItemTypeAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the kind handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-track-kind /// public protocol KindAttribute: AnyAttribute { @@ -2054,10 +2140,10 @@ extension KindAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the label handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-track-label /// public protocol LabelAttribute: AnyAttribute { @@ -2097,10 +2183,10 @@ extension LabelAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the language handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-lang /// public protocol LanguageAttribute: AnyAttribute { @@ -2140,10 +2226,10 @@ extension LanguageAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the list handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-input-list /// public protocol ListAttribute: AnyAttribute { @@ -2183,10 +2269,10 @@ extension ListAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the loop handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-media-loop /// public protocol LoopAttribute: AnyAttribute { @@ -2226,10 +2312,10 @@ extension LoopAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the low handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-meter-low /// public protocol LowAttribute: AnyAttribute { @@ -2269,10 +2355,10 @@ extension LowAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the maximumvalue handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-input-max /// https://html.spec.whatwg.org/#attr-meter-max /// @@ -2313,10 +2399,10 @@ extension MaximumValueAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the maximumlength handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-input-maxlength /// public protocol MaximumLengthAttribute: AnyAttribute { @@ -2356,10 +2442,10 @@ extension MaximumLengthAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the media handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-link-media /// public protocol MediaAttribute: AnyAttribute { @@ -2399,10 +2485,10 @@ extension MediaAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the method handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-fs-method /// public protocol MethodAttribute: AnyAttribute { @@ -2442,10 +2528,10 @@ extension MethodAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the minimumvalue handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-input-min /// public protocol MinimumValueAttribute: AnyAttribute { @@ -2485,10 +2571,10 @@ extension MinimumValueAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the minimumlength handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-input-minlength /// public protocol MinimumLengthAttribute: AnyAttribute { @@ -2528,10 +2614,10 @@ extension MinimumLengthAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the multiple handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-input-multiple /// public protocol MultipleAttribute: AnyAttribute { @@ -2571,10 +2657,10 @@ extension MultipleAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the muted handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-media-muted /// public protocol MutedAttribute: AnyAttribute { @@ -2614,10 +2700,10 @@ extension MutedAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the name handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-form-name /// public protocol NameAttribute: AnyAttribute { @@ -2664,10 +2750,10 @@ extension NameAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the nonce handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-nonce /// public protocol NonceAttribute: AnyAttribute { @@ -2707,10 +2793,10 @@ extension NonceAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the novalidate handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-fs-novalidate /// public protocol NoValidateAttribute: AnyAttribute { @@ -2750,10 +2836,10 @@ extension NoValidateAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the open handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-details-open /// public protocol OpenAttribute: AnyAttribute { @@ -2793,10 +2879,10 @@ extension OpenAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the optimum handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-meter-optimum /// public protocol OptimumAttribute: AnyAttribute { @@ -2836,10 +2922,10 @@ extension OptimumAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the pattern handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-input-pattern /// public protocol PatternAttribute: AnyAttribute { @@ -2879,10 +2965,10 @@ extension PatternAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the part handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-input-pattern /// public protocol PartAttribute: AnyAttribute { @@ -2922,10 +3008,10 @@ extension PartAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the ping handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-input-pattern /// public protocol PingAttribute: AnyAttribute { @@ -2965,10 +3051,10 @@ extension PingAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the placeholder handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-input-placeholder /// public protocol PlaceholderAttribute: AnyAttribute { @@ -3013,10 +3099,10 @@ extension PlaceholderAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the poster handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-video-poster /// public protocol PosterAttribute: AnyAttribute { @@ -3056,10 +3142,10 @@ extension PosterAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the preload handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-media-preload /// public protocol PreloadAttribute: AnyAttribute { @@ -3099,10 +3185,10 @@ extension PreloadAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the readonly handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-readonly-attribute /// public protocol ReadyOnlyAttribute: AnyAttribute { @@ -3142,10 +3228,10 @@ extension ReadyOnlyAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the referrerpolicy handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-hyperlink-referrerpolicy /// public protocol ReferrerPolicyAttribute: AnyAttribute { @@ -3185,10 +3271,10 @@ extension ReferrerPolicyAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the relationship handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-link-rel /// public protocol RelationshipAttribute: AnyAttribute { @@ -3228,10 +3314,10 @@ extension RelationshipAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the required handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-input-required /// public protocol RequiredAttribute: AnyAttribute { @@ -3271,10 +3357,10 @@ extension RequiredAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the reversed handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol ReversedAttribute: AnyAttribute { @@ -3314,10 +3400,10 @@ extension ReversedAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the role handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol RoleAttribute: AnyAttribute { @@ -3357,10 +3443,10 @@ extension RoleAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the rows handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol RowsAttribute: AnyAttribute { @@ -3400,10 +3486,10 @@ extension RowsAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the rowspan handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-tdth-rowspan /// public protocol RowSpanAttribute: AnyAttribute { @@ -3443,10 +3529,10 @@ extension RowSpanAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the sandbox handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-iframe-sandbox /// public protocol SandboxAttribute: AnyAttribute { @@ -3486,10 +3572,10 @@ extension SandboxAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the scope handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-th-scope /// public protocol ScopeAttribute: AnyAttribute { @@ -3529,10 +3615,10 @@ extension ScopeAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the shape handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-area-shape /// public protocol ShapeAttribute: AnyAttribute { @@ -3572,10 +3658,10 @@ extension ShapeAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the size handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-size-attribute /// public protocol SizeAttribute: AnyAttribute { @@ -3615,10 +3701,10 @@ extension SizeAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the sizes handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol SizesAttribute: AnyAttribute { @@ -3658,10 +3744,10 @@ extension SizesAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the slot handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-slot /// public protocol SlotAttribute: AnyAttribute { @@ -3701,10 +3787,10 @@ extension SlotAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the span handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-colgroup-span /// https://html.spec.whatwg.org/#attr-col-span /// @@ -3745,10 +3831,10 @@ extension SpanAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the hasspellcheck handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-spellcheck /// public protocol SpellCheckAttribute: AnyAttribute { @@ -3788,10 +3874,10 @@ extension SpellCheckAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the source handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-input-src /// public protocol SourceAttribute: AnyAttribute { @@ -3831,10 +3917,10 @@ extension SourceAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the start handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-start /// public protocol StartAttribute: AnyAttribute { @@ -3874,10 +3960,10 @@ extension StartAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the step handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-step-attribute /// public protocol StepAttribute: AnyAttribute { @@ -3917,10 +4003,10 @@ extension StepAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the style handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-style /// public protocol StyleAttribute: AnyAttribute { @@ -3960,10 +4046,10 @@ extension StyleAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the tabindex handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-tabindex /// public protocol TabulatorAttribute: AnyAttribute { @@ -4003,10 +4089,10 @@ extension TabulatorAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the target handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-base-target /// public protocol TargetAttribute: AnyAttribute { @@ -4046,10 +4132,10 @@ extension TargetAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the title handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-title /// public protocol TitleAttribute: AnyAttribute { @@ -4089,10 +4175,10 @@ extension TitleAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the translate handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-translate /// public protocol TranslateAttribute: AnyAttribute { @@ -4132,10 +4218,10 @@ extension TranslateAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the type handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-link-type /// public protocol TypeAttribute: AnyAttribute { @@ -4177,10 +4263,10 @@ extension TypeAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the value handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-input-value /// public protocol ValueAttribute: AnyAttribute { @@ -4225,10 +4311,10 @@ extension ValueAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the width handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-dim-width /// public protocol WidthAttribute: AnyAttribute { @@ -4268,10 +4354,10 @@ extension WidthAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the wrap handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-textarea-wrap /// public protocol WrapAttribute: AnyAttribute { @@ -4311,10 +4397,10 @@ extension WrapAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the property handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol PropertyAttribute: AnyAttribute { @@ -4353,3 +4439,42 @@ extension PropertyAttribute where Self: EmptyNode { return .init(attributes: update(key: key, value: value, on: &attributes)) } } + + +/// ## Description +/// The protocol provides the element with the property handler. +/// +/// ## References +/// https://html.spec.whatwg.org/#attr-ol-reversed +/// +public protocol CustomAttribute: AnyAttribute { + + /// The func adds + /// + /// + func custom(key: String, value: Any) -> Self +} + +extension CustomAttribute where Self: ContentNode { + + internal func mutate(key: String, value: Any) -> Self { + + guard var attributes = self.attributes else { + return .init(attributes: set(key: key, value: value), content: content) + } + + return .init(attributes: update(key: key, value: value, on: &attributes), content: content) + } +} + +extension CustomAttribute where Self: EmptyNode { + + internal func mutate(key: String, value: Any) -> Self { + + guard var attributes = self.attributes else { + return .init(attributes: set(key: key, value: value)) + } + + return .init(attributes: update(key: key, value: value, on: &attributes)) + } +} diff --git a/Sources/HTMLKit/External/Attributes/EventAttributes.swift b/Sources/HTMLKit/External/Attributes/EventAttributes.swift index 1f0f2981..1d09e2d3 100644 --- a/Sources/HTMLKit/External/Attributes/EventAttributes.swift +++ b/Sources/HTMLKit/External/Attributes/EventAttributes.swift @@ -1,27 +1,27 @@ -/// # Description: +/// ## Description /// The file contains the event attribute handlers. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr import OrderedCollections -/// # Description: +/// ## Description /// The alias combines the global attributes. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public typealias GlobalEventAttributes = ContextMenuEventAttribute & WheelEventAttribute & DragEventAttribute & DragEndEventAttribute & DragEnterEventAttribute & DragLeaveEventAttribute & DragOverEventAttribute & DragStartEventAttribute & DropEventAttribute -/// # Description: +/// ## Description /// The protocol provides the element with the onafterprint handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol AfterPrintEventAttribute: AnyAttribute { @@ -61,10 +61,10 @@ extension AfterPrintEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onbeforeprint handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol BeforePrintEventAttribute: AnyAttribute { @@ -104,10 +104,10 @@ extension BeforePrintEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onbeforeunload handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol BeforeUnloadEventAttribute: AnyAttribute { @@ -147,10 +147,10 @@ extension BeforeUnloadEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onerror handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol ErrorEventAttribute: AnyAttribute { @@ -190,10 +190,10 @@ extension ErrorEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onhashchange handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol HashChangeEventAttribute: AnyAttribute { @@ -233,10 +233,10 @@ extension HashChangeEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onload handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol LoadEventAttribute: AnyAttribute { @@ -276,10 +276,10 @@ extension LoadEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onmessage handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol MessageEventAttribute: AnyAttribute { @@ -319,10 +319,10 @@ extension MessageEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onoffline handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol OfflineEventAttribute: AnyAttribute { @@ -362,10 +362,10 @@ extension OfflineEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the ononline handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol OnlineEventAttribute: AnyAttribute { @@ -405,10 +405,10 @@ extension OnlineEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onpagehide handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol PageHideEventAttribute: AnyAttribute { @@ -448,10 +448,10 @@ extension PageHideEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onpageshow handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol PageShowEventAttribute: AnyAttribute { @@ -491,10 +491,10 @@ extension PageShowEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onpopstate handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol PopstateEventAttribute: AnyAttribute { @@ -534,10 +534,10 @@ extension PopstateEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onresize handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol ResizeEventAttribute: AnyAttribute { @@ -577,10 +577,10 @@ extension ResizeEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onstorage handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol StorageEventAttribute: AnyAttribute { @@ -620,10 +620,10 @@ extension StorageEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onunload handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol UnloadEventAttribute: AnyAttribute { @@ -663,10 +663,10 @@ extension UnloadEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onblur handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol BlurEventAttribute: AnyAttribute { @@ -706,10 +706,10 @@ extension BlurEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onchange handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol ChangeEventAttribute: AnyAttribute { @@ -749,10 +749,10 @@ extension ChangeEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the oncontextmenu handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol ContextMenuEventAttribute: AnyAttribute { @@ -792,10 +792,10 @@ extension ContextMenuEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onfocus handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol FocusEventAttribute: AnyAttribute { @@ -835,10 +835,10 @@ extension FocusEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the oninput handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol InputEventAttribute: AnyAttribute { @@ -878,10 +878,10 @@ extension InputEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the oninvalid handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol InvalidEventAttribute: AnyAttribute { @@ -921,10 +921,10 @@ extension InvalidEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onreset handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol ResetEventAttribute: AnyAttribute { @@ -964,10 +964,10 @@ extension ResetEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onsearch handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol SearchEventAttribute: AnyAttribute { @@ -1007,10 +1007,10 @@ extension SearchEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onselect handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol SelectEventAttribute: AnyAttribute { @@ -1050,10 +1050,10 @@ extension SelectEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onsubmit handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol SubmitEventAttribute: AnyAttribute { @@ -1093,10 +1093,10 @@ extension SubmitEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onkeydown handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol KeyDownEventAttribute: AnyAttribute { @@ -1136,10 +1136,10 @@ extension KeyDownEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onkeypress handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol KeyPressEventAttribute: AnyAttribute { @@ -1179,10 +1179,10 @@ extension KeyPressEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onkeyup handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol KeyUpEventAttribute: AnyAttribute { @@ -1222,10 +1222,10 @@ extension KeyUpEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onclick handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol ClickEventAttribute: AnyAttribute { @@ -1265,10 +1265,10 @@ extension ClickEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the ondbclick handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol DoubleClickEventAttribute: AnyAttribute { @@ -1308,10 +1308,10 @@ extension DoubleClickEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onmousedown handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol MouseDownEventAttribute: AnyAttribute { @@ -1351,10 +1351,10 @@ extension MouseDownEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onmousemove handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol MouseMoveEventAttribute: AnyAttribute { @@ -1394,10 +1394,10 @@ extension MouseMoveEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onmouseout handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol MouseOutEventAttribute: AnyAttribute { @@ -1437,10 +1437,10 @@ extension MouseOutEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onmouseover handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol MouseOverEventAttribute: AnyAttribute { @@ -1480,10 +1480,10 @@ extension MouseOverEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onmouseup handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol MouseUpEventAttribute: AnyAttribute { @@ -1523,10 +1523,10 @@ extension MouseUpEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onwheel handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol WheelEventAttribute: AnyAttribute { @@ -1566,10 +1566,10 @@ extension WheelEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the ondrag handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol DragEventAttribute: AnyAttribute { @@ -1609,10 +1609,10 @@ extension DragEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the ondragenter handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol DragEnterEventAttribute: AnyAttribute { @@ -1652,10 +1652,10 @@ extension DragEnterEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the ondragend handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol DragEndEventAttribute: AnyAttribute { @@ -1695,10 +1695,10 @@ extension DragEndEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the ondragleave handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol DragLeaveEventAttribute: AnyAttribute { @@ -1738,10 +1738,10 @@ extension DragLeaveEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the ondragover handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol DragOverEventAttribute: AnyAttribute { @@ -1781,10 +1781,10 @@ extension DragOverEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the ondragstart handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol DragStartEventAttribute: AnyAttribute { @@ -1824,10 +1824,10 @@ extension DragStartEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the ondrop handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol DropEventAttribute: AnyAttribute { @@ -1867,10 +1867,10 @@ extension DropEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onscroll handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol ScrollEventAttribute: AnyAttribute { @@ -1910,10 +1910,10 @@ extension ScrollEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the oncopy handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol CopyEventAttribute: AnyAttribute { @@ -1953,10 +1953,10 @@ extension CopyEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the oncut handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol CutEventAttribute: AnyAttribute { @@ -1996,10 +1996,10 @@ extension CutEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onpaste handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol PasteEventAttribute: AnyAttribute { @@ -2039,10 +2039,10 @@ extension PasteEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onabort handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol AbortEventAttribute: AnyAttribute { @@ -2082,10 +2082,10 @@ extension AbortEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the oncanplay handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol CanPlayEventAttribute: AnyAttribute { @@ -2125,10 +2125,10 @@ extension CanPlayEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the oncanplaythrough handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol CanPlayThroughEventAttribute: AnyAttribute { @@ -2168,10 +2168,10 @@ extension CanPlayThroughEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the oncuechange handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol CueChangeEventAttribute: AnyAttribute { @@ -2211,10 +2211,10 @@ extension CueChangeEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the ondurationchange handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol DurationChangeEventAttribute: AnyAttribute { @@ -2254,10 +2254,10 @@ extension DurationChangeEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onemptied handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol EmptiedEventAttribute: AnyAttribute { @@ -2297,10 +2297,10 @@ extension EmptiedEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onended handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol EndedEventAttribute: AnyAttribute { @@ -2340,10 +2340,10 @@ extension EndedEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onloadeddata handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol LoadedDataEventAttribute: AnyAttribute { @@ -2383,10 +2383,10 @@ extension LoadedDataEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onloadedmetadata handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol LoadedMetaDataEventAttribute: AnyAttribute { @@ -2426,10 +2426,10 @@ extension LoadedMetaDataEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onloadstart handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol LoadStartEventAttribute: AnyAttribute { @@ -2469,10 +2469,10 @@ extension LoadStartEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onpause handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol PauseEventAttribute: AnyAttribute { @@ -2512,10 +2512,10 @@ extension PauseEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onplay handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol PlayEventAttribute: AnyAttribute { @@ -2555,10 +2555,10 @@ extension PlayEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onplaying handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol PlayingEventAttribute: AnyAttribute { @@ -2598,10 +2598,10 @@ extension PlayingEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onprogress handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol ProgressEventAttribute: AnyAttribute { @@ -2641,10 +2641,10 @@ extension ProgressEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onratechange handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol RateChangeEventAttribute: AnyAttribute { @@ -2684,10 +2684,10 @@ extension RateChangeEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onseeked handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol SeekedEventAttribute: AnyAttribute { @@ -2727,10 +2727,10 @@ extension SeekedEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onseeking handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol SeekingEventAttribute: AnyAttribute { @@ -2770,10 +2770,10 @@ extension SeekingEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onstalled handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol StalledEventAttribute: AnyAttribute { @@ -2813,10 +2813,10 @@ extension StalledEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onsuspend handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol SuspendEventAttribute: AnyAttribute { @@ -2856,10 +2856,10 @@ extension SuspendEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the ontimeupdate handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol TimeUpdateEventAttribute: AnyAttribute { @@ -2899,10 +2899,10 @@ extension TimeUpdateEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onvolumechange handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol VolumeChangeEventAttribute: AnyAttribute { @@ -2942,10 +2942,10 @@ extension VolumeChangeEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the onwaiting handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol WaitingEventAttribute: AnyAttribute { @@ -2985,10 +2985,10 @@ extension WaitingEventAttribute where Self: EmptyNode { } } -/// # Description: +/// ## Description /// The protocol provides the element with the ontoggle handler. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#attr-ol-reversed /// public protocol ToggleEventAttribute: AnyAttribute { diff --git a/Sources/HTMLKit/External/Components.swift b/Sources/HTMLKit/External/Components.swift index a706e3f4..f68ce2c6 100644 --- a/Sources/HTMLKit/External/Components.swift +++ b/Sources/HTMLKit/External/Components.swift @@ -1,17 +1,17 @@ -/// # Description: +/// ## Description /// The file contains the view components. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr -/// # Description: +/// ## Description /// The component returns a meta element with twitter and opengraph. /// -/// # References: +/// ## References /// public struct MetaTitle: Component { @@ -44,10 +44,10 @@ public struct MetaTitle: Component { } } -/// # Description: +/// ## Description /// The component returns a meta element with twitter and opengraph. /// -/// # References: +/// ## References /// public struct MetaDescription: Component { @@ -80,10 +80,10 @@ public struct MetaDescription: Component { } } -/// # Description: +/// ## Description /// The component returns a link element. /// -/// # References: +/// ## References /// public struct Favicon: Component { @@ -100,10 +100,10 @@ public struct Favicon: Component { } } -/// # Description: +/// ## Description /// The component returns a link element. /// -/// # References: +/// ## References /// public struct Stylesheet: Component { @@ -121,10 +121,10 @@ public struct Stylesheet: Component { } } -/// # Description: +/// ## Description /// The component returns a meta element. /// -/// # References: +/// ## References /// public struct Viewport: Component { @@ -155,10 +155,10 @@ public struct Viewport: Component { } } -/// # Description: +/// ## Description /// The component returns a meta element. /// -/// # References: +/// ## References /// public struct Author: Component { diff --git a/Sources/HTMLKit/External/Elements/BasicElements.swift b/Sources/HTMLKit/External/Elements/BasicElements.swift index 1d071741..e7d7a9c2 100644 --- a/Sources/HTMLKit/External/Elements/BasicElements.swift +++ b/Sources/HTMLKit/External/Elements/BasicElements.swift @@ -1,19 +1,19 @@ -/// # Description: +/// ## Description /// The file contains the basics elements. These elements should be used at first. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr import OrderedCollections -/// # Description: +/// ## Description /// The element represents a comment output. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#comments /// public struct Comment: CommentNode, GlobalElement { @@ -36,10 +36,10 @@ extension Comment: AnyContent { } } -/// # Description: +/// ## Description /// The element represents the the document. /// -/// # References: +/// ## References /// https://dom.spec.whatwg.org/#document-element /// public struct Document: DocumentNode, BasicElement { @@ -62,10 +62,10 @@ extension Document: AnyContent { } } -/// # Description: +/// ## Description /// The element represents the document's root element. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-html-element /// public struct Html: ContentNode, BasicElement { @@ -191,6 +191,10 @@ extension Html: GlobalAttributes { public func translate(_ value: String) -> Html { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Html { + return mutate(key: key, value: value) + } } extension Html: AnyContent { diff --git a/Sources/HTMLKit/External/Elements/BodyElements.swift b/Sources/HTMLKit/External/Elements/BodyElements.swift index 5c4e77dd..53c90ed5 100644 --- a/Sources/HTMLKit/External/Elements/BodyElements.swift +++ b/Sources/HTMLKit/External/Elements/BodyElements.swift @@ -1,200 +1,200 @@ -/// # Description: +/// ## Description /// The file contains the body elements. The html element Body only allows these elements /// to be its descendants. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr import OrderedCollections -/// # Description: +/// ## Description /// The alias points to Navigation. /// public typealias Nav = Navigation -/// # Description: +/// ## Description /// The alias points to Heading1. /// public typealias H1 = Heading1 -/// # Description: +/// ## Description /// The alias points to Heading2. /// public typealias H2 = Heading2 -/// # Description: +/// ## Description /// The alias points to Heading3. /// public typealias H3 = Heading3 -/// # Description: +/// ## Description /// The alias points to Heading4. /// public typealias H4 = Heading4 -/// # Description: +/// ## Description /// The alias points to Heading5. /// public typealias H5 = Heading5 -/// # Description: +/// ## Description /// The alias points to Heading6. /// public typealias H6 = Heading6 -/// # Description: +/// ## Description /// The alias points to HeadingGroup. /// public typealias Hgroup = HeadingGroup -/// # Description: +/// ## Description /// The alias points to Paragraph. /// public typealias P = Paragraph -/// # Description: +/// ## Description /// The alias points to HorizontalRule. /// public typealias Hr = HorizontalRule -/// # Description: +/// ## Description /// The alias points to PreformattedText. /// public typealias Pre = PreformattedText -/// # Description: +/// ## Description /// The alias points to OrderedList. /// public typealias Ol = OrderedList -/// # Description: +/// ## Description /// The alias points to UnorderedList. /// public typealias Ul = UnorderedList -/// # Description: +/// ## Description /// The alias points to DescriptionList. /// public typealias Dl = DescriptionList -/// # Description: +/// ## Description /// The alias points to Division. /// public typealias Div = Division -/// # Description: +/// ## Description /// The alias points to Anchor. /// public typealias A = Anchor -/// # Description: +/// ## Description /// The alias points to Emphasize. /// public typealias Em = Emphasize -/// # Description: +/// ## Description /// The alias points to StrikeThrough. /// public typealias S = StrikeThrough -/// # Description: +/// ## Description /// The alias points to ShortQuote. /// public typealias Q = ShortQuote -/// # Description: +/// ## Description /// The alias points to Definition. /// public typealias Dfn = Definition -/// # Description: +/// ## Description /// The alias points to Abbreviation. /// public typealias Abbr = Abbreviation -/// # Description: +/// ## Description /// The alias points to Variable. /// public typealias V = Variable -/// # Description: +/// ## Description /// The alias points to SampleOutput. /// public typealias Samp = SampleOutput -/// # Description: +/// ## Description /// The alias points to KeyboardInput. /// public typealias Kbd = KeyboardInput -/// # Description: +/// ## Description /// The alias points to Subscript. /// public typealias Sub = Subscript -/// # Description: +/// ## Description /// The alias points to Superscript. /// public typealias Sup = Superscript -/// # Description: +/// ## Description /// The alias points to Italic. /// public typealias I = Italic -/// # Description: +/// ## Description /// The alias points to Bold. /// public typealias B = Bold -/// # Description: +/// ## Description /// The alias points to Underline. /// public typealias U = Underline -/// # Description: +/// ## Description /// The alias points to LineBreak. /// public typealias Br = LineBreak -/// # Description: +/// ## Description /// The alias points to WordBreak. /// public typealias Wbr = WordBreak -/// # Description: +/// ## Description /// The alias points to InsertedText. /// public typealias Ins = InsertedText -/// # Description: +/// ## Description /// The alias points to DeletedText. /// public typealias Del = DeletedText -/// # Description: +/// ## Description /// The alias points to Image. /// public typealias Img = Image -/// # Description: +/// ## Description /// The alias points to InlineFrame. /// public typealias Iframe = InlineFrame -/// # Description: +/// ## Description /// The alias points to Parameter. /// public typealias Param = Parameter -/// # Description: +/// ## Description /// The element represents a self-contained content. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-article-element /// public struct Article: ContentNode, BodyElement { @@ -320,6 +320,10 @@ extension Article: GlobalAttributes { public func translate(_ value: String) -> Article { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Article { + return mutate(key: key, value: value) + } } extension Article: AnyContent { @@ -369,10 +373,10 @@ extension Article: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a generic section of the document. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-section-element /// public struct Section: ContentNode, BodyElement { @@ -498,6 +502,10 @@ extension Section: GlobalAttributes { public func translate(_ value: String) -> Section { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Section { + return mutate(key: key, value: value) + } } extension Section: AnyContent { @@ -547,10 +555,10 @@ extension Section: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a section of a page that links to other pages or parts within the page. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-nav-element) /// public struct Navigation: ContentNode, BodyElement { @@ -676,6 +684,10 @@ extension Navigation: GlobalAttributes { public func translate(_ value: String) -> Navigation { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Navigation { + return mutate(key: key, value: value) + } } extension Navigation: AnyContent { @@ -725,10 +737,10 @@ extension Navigation: Modifiable { } } -/// # Description: +/// ## Description /// The element defines some content aside from the content it is placed in. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-aside-element /// public struct Aside: ContentNode, BodyElement { @@ -854,6 +866,10 @@ extension Aside: GlobalAttributes { public func translate(_ value: String) -> Aside { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Aside { + return mutate(key: key, value: value) + } } extension Aside: AnyContent { @@ -903,10 +919,10 @@ extension Aside: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a heading. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-h1,-h2,-h3,-h4,-h5,-and-h6-elements /// public struct Heading1: ContentNode, BodyElement { @@ -1032,6 +1048,10 @@ extension Heading1: GlobalAttributes { public func translate(_ value: String) -> Heading1 { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Heading1 { + return mutate(key: key, value: value) + } } extension Heading1: AnyContent { @@ -1092,10 +1112,10 @@ extension Heading1: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a heading. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-h1,-h2,-h3,-h4,-h5,-and-h6-elements /// public struct Heading2: ContentNode, BodyElement { @@ -1221,6 +1241,10 @@ extension Heading2: GlobalAttributes { public func translate(_ value: String) -> Heading2 { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Heading2 { + return mutate(key: key, value: value) + } } extension Heading2: AnyContent { @@ -1281,10 +1305,10 @@ extension Heading2: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a heading. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-h1,-h2,-h3,-h4,-h5,-and-h6-elements /// public struct Heading3: ContentNode, BodyElement { @@ -1410,6 +1434,10 @@ extension Heading3: GlobalAttributes { public func translate(_ value: String) -> Heading3 { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Heading3 { + return mutate(key: key, value: value) + } } extension Heading3: AnyContent { @@ -1470,10 +1498,10 @@ extension Heading3: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a heading. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-h1,-h2,-h3,-h4,-h5,-and-h6-elements /// public struct Heading4: ContentNode, BodyElement { @@ -1599,6 +1627,10 @@ extension Heading4: GlobalAttributes { public func translate(_ value: String) -> Heading4 { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Heading4 { + return mutate(key: key, value: value) + } } extension Heading4: AnyContent { @@ -1659,10 +1691,10 @@ extension Heading4: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a heading. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-h1,-h2,-h3,-h4,-h5,-and-h6-elements /// public struct Heading5: ContentNode, BodyElement { @@ -1788,6 +1820,10 @@ extension Heading5: GlobalAttributes { public func translate(_ value: String) -> Heading5 { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Heading5 { + return mutate(key: key, value: value) + } } extension Heading5: AnyContent { @@ -1848,10 +1884,10 @@ extension Heading5: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a heading. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-h1,-h2,-h3,-h4,-h5,-and-h6-elements /// public struct Heading6: ContentNode, BodyElement { @@ -1977,6 +2013,10 @@ extension Heading6: GlobalAttributes { public func translate(_ value: String) -> Heading6 { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Heading6 { + return mutate(key: key, value: value) + } } extension Heading6: AnyContent { @@ -2037,10 +2077,10 @@ extension Heading6: Modifiable { } } -/// # Description: +/// ## Description /// The element is used to group a set of heading elements. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-hgroup-element /// public struct HeadingGroup: ContentNode, BodyElement { @@ -2166,6 +2206,10 @@ extension HeadingGroup: GlobalAttributes { public func translate(_ value: String) -> HeadingGroup { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> HeadingGroup { + return mutate(key: key, value: value) + } } extension HeadingGroup: AnyContent { @@ -2215,10 +2259,10 @@ extension HeadingGroup: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a header. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-header-element /// public struct Header: ContentNode, BodyElement { @@ -2344,6 +2388,10 @@ extension Header: GlobalAttributes { public func translate(_ value: String) -> Header { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Header { + return mutate(key: key, value: value) + } } extension Header: AnyContent { @@ -2393,10 +2441,10 @@ extension Header: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a footer. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-footer-element /// public struct Footer: ContentNode, BodyElement { @@ -2522,6 +2570,10 @@ extension Footer: GlobalAttributes { public func translate(_ value: String) -> Footer { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Footer { + return mutate(key: key, value: value) + } } extension Footer: AnyContent { @@ -2571,10 +2623,10 @@ extension Footer: Modifiable { } } -/// # Description: +/// ## Description /// The element represents the contact information. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-address-element /// public struct Address: ContentNode, BodyElement { @@ -2700,6 +2752,10 @@ extension Address: GlobalAttributes { public func translate(_ value: String) -> Address { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Address { + return mutate(key: key, value: value) + } } extension Address: AnyContent { @@ -2749,10 +2805,10 @@ extension Address: Modifiable { } } -/// # Description: +/// ## Description /// The element is used to define a paragraph. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-p-element /// public struct Paragraph: ContentNode, BodyElement { @@ -2878,6 +2934,10 @@ extension Paragraph: GlobalAttributes { public func translate(_ value: String) -> Paragraph { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Paragraph { + return mutate(key: key, value: value) + } } extension Paragraph: AnyContent { @@ -2938,10 +2998,10 @@ extension Paragraph: Modifiable { } } -/// # Description: +/// ## Description /// The element is used for horizontal rules that act as dividers between sections. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-hr-element /// public struct HorizontalRule: EmptyNode, BodyElement { @@ -3062,6 +3122,10 @@ extension HorizontalRule: GlobalAttributes { public func translate(_ value: String) -> HorizontalRule { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> HorizontalRule { + return mutate(key: key, value: value) + } } extension HorizontalRule: AnyContent { @@ -3111,10 +3175,10 @@ extension HorizontalRule: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a block of preformatted text. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-pre-element /// public struct PreformattedText: ContentNode, BodyElement { @@ -3240,6 +3304,10 @@ extension PreformattedText: GlobalAttributes { public func translate(_ value: String) -> PreformattedText { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> PreformattedText { + return mutate(key: key, value: value) + } } extension PreformattedText: AnyContent { @@ -3289,10 +3357,10 @@ extension PreformattedText: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a section that is quoted from another source. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-blockquote-element /// public struct Blockquote: ContentNode, BodyElement { @@ -3422,6 +3490,10 @@ extension Blockquote: GlobalAttributes, CiteAttribute { public func cite(_ value: String) -> Blockquote { return mutate(cite: value) } + + public func custom(key: String, value: Any) -> Blockquote { + return mutate(key: key, value: value) + } } extension Blockquote: AnyContent { @@ -3482,10 +3554,10 @@ extension Blockquote: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a list of items, where the items have been intentionally ordered. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-ol-element /// public struct OrderedList: ContentNode, BodyElement { @@ -3623,6 +3695,10 @@ extension OrderedList: GlobalAttributes, ReversedAttribute, StartAttribute, Type public func type(_ value: String) -> OrderedList { return mutate(type: value) } + + public func custom(key: String, value: Any) -> OrderedList { + return mutate(key: key, value: value) + } } extension OrderedList: AnyContent { @@ -3672,10 +3748,10 @@ extension OrderedList: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a list of items, where the order of the items is not important. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-ul-element /// public struct UnorderedList: ContentNode, BodyElement { @@ -3801,6 +3877,10 @@ extension UnorderedList: GlobalAttributes { public func translate(_ value: String) -> UnorderedList { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> UnorderedList { + return mutate(key: key, value: value) + } } extension UnorderedList: AnyContent { @@ -3850,10 +3930,10 @@ extension UnorderedList: Modifiable { } } -/// # Description: +/// ## Description /// The element defines a list of terms and corresponding definitions. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-dl-element /// public struct DescriptionList: ContentNode, BodyElement { @@ -3979,6 +4059,10 @@ extension DescriptionList: GlobalAttributes { public func translate(_ value: String) -> DescriptionList { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> DescriptionList { + return mutate(key: key, value: value) + } } extension DescriptionList: AnyContent { @@ -4028,10 +4112,10 @@ extension DescriptionList: Modifiable { } } -/// # Description: +/// # Figure /// The element can thus be used to annotate illustrations, diagrams, photos, code listings. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-figure-element /// public struct Figure: ContentNode, BodyElement { @@ -4157,6 +4241,10 @@ extension Figure: GlobalAttributes { public func translate(_ value: String) -> Figure { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Figure { + return mutate(key: key, value: value) + } } extension Figure: AnyContent { @@ -4206,10 +4294,10 @@ extension Figure: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a comment output. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-a-element /// public struct Anchor: ContentNode, BodyElement { @@ -4375,6 +4463,10 @@ extension Anchor: GlobalAttributes, DownloadAttribute, ReferenceAttribute, Refer public func type(_ value: String) -> Anchor { return mutate(type: value) } + + public func custom(key: String, value: Any) -> Anchor { + return mutate(key: key, value: value) + } } extension Anchor: AnyContent { @@ -4435,10 +4527,10 @@ extension Anchor: Modifiable { } } -/// # Description: +/// ## Description /// The element provides typographic emphasis. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-em-element /// public struct Emphasize: ContentNode, BodyElement { @@ -4564,6 +4656,10 @@ extension Emphasize: GlobalAttributes { public func translate(_ value: String) -> Emphasize { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Emphasize { + return mutate(key: key, value: value) + } } extension Emphasize: AnyContent { @@ -4613,10 +4709,10 @@ extension Emphasize: Modifiable { } } -/// # Description: +/// ## Description /// The element provides strong typographic emphasis. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-strong-element /// public struct Strong: ContentNode, BodyElement { @@ -4742,6 +4838,10 @@ extension Strong: GlobalAttributes { public func translate(_ value: String) -> Strong { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Strong { + return mutate(key: key, value: value) + } } extension Strong: AnyContent { @@ -4791,10 +4891,10 @@ extension Strong: Modifiable { } } -/// # Description: +/// ## Description /// The element represents side comments such as small print. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-small-element /// public struct Small: ContentNode, BodyElement { @@ -4920,6 +5020,10 @@ extension Small: GlobalAttributes { public func translate(_ value: String) -> Small { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Small { + return mutate(key: key, value: value) + } } extension Small: AnyContent { @@ -4980,10 +5084,10 @@ extension Small: Modifiable { } } -/// # Description: +/// ## Description /// The element represents contents that are no longer accurate or no longer relevant. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-s-element /// public struct StrikeThrough: ContentNode, BodyElement { @@ -5109,6 +5213,10 @@ extension StrikeThrough: GlobalAttributes { public func translate(_ value: String) -> StrikeThrough { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> StrikeThrough { + return mutate(key: key, value: value) + } } extension StrikeThrough: AnyContent { @@ -5169,10 +5277,10 @@ extension StrikeThrough: Modifiable { } } -/// # Description: +/// ## Description /// The element represents the dominant contents of the document. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-main-element /// public struct Main: ContentNode, BodyElement { @@ -5298,6 +5406,10 @@ extension Main: GlobalAttributes { public func translate(_ value: String) -> Main { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Main { + return mutate(key: key, value: value) + } } extension Main: AnyContent { @@ -5347,10 +5459,10 @@ extension Main: Modifiable { } } -/// # Description: +/// ## Description /// The element is used to represent different kinds of containers. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-div-element /// public struct Division: ContentNode, BodyElement { @@ -5476,6 +5588,10 @@ extension Division: GlobalAttributes { public func translate(_ value: String) -> Division { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Division { + return mutate(key: key, value: value) + } } extension Division: AnyContent { @@ -5525,10 +5641,10 @@ extension Division: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a comment output. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-dfn-element /// public struct Definition: ContentNode, BodyElement { @@ -5654,6 +5770,10 @@ extension Definition: GlobalAttributes { public func translate(_ value: String) -> Definition { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Definition { + return mutate(key: key, value: value) + } } extension Definition: AnyContent { @@ -5703,10 +5823,10 @@ extension Definition: Modifiable { } } -/// # Description: +/// ## Description /// The element specifies a citation. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-cite-element /// public struct Cite: ContentNode, BodyElement { @@ -5832,6 +5952,10 @@ extension Cite: GlobalAttributes { public func translate(_ value: String) -> Cite { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Cite { + return mutate(key: key, value: value) + } } extension Cite: AnyContent { @@ -5881,10 +6005,10 @@ extension Cite: Modifiable { } } -/// # Description: +/// ## Description /// The element is used for a short quotation. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-q-element /// public struct ShortQuote: ContentNode, BodyElement { @@ -6014,6 +6138,10 @@ extension ShortQuote: GlobalAttributes, CiteAttribute { public func cite(_ value: String) -> ShortQuote { return mutate(cite: value) } + + public func custom(key: String, value: Any) -> ShortQuote { + return mutate(key: key, value: value) + } } extension ShortQuote: AnyContent { @@ -6063,10 +6191,10 @@ extension ShortQuote: Modifiable { } } -/// # Description: +/// ## Description /// The element represents an abbreviation or acronym. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-abbr-element /// public struct Abbreviation: ContentNode, BodyElement { @@ -6192,6 +6320,10 @@ extension Abbreviation: GlobalAttributes { public func translate(_ value: String) -> Abbreviation { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Abbreviation { + return mutate(key: key, value: value) + } } extension Abbreviation: AnyContent { @@ -6241,10 +6373,10 @@ extension Abbreviation: Modifiable { } } -/// # Description: +/// ## Description /// The element allows one or more spans of phrasing content to be marked with ruby annotations. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-ruby-element /// public struct Ruby: ContentNode, BodyElement { @@ -6370,6 +6502,10 @@ extension Ruby: GlobalAttributes { public func translate(_ value: String) -> Ruby { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Ruby { + return mutate(key: key, value: value) + } } extension Ruby: AnyContent { @@ -6419,10 +6555,10 @@ extension Ruby: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a comment output. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-data-element /// public struct Data: ContentNode, BodyElement { @@ -6556,6 +6692,10 @@ extension Data: GlobalAttributes, ValueAttribute { public func value(_ value: TemplateValue) -> Data { return mutate(value: value.rawValue) } + + public func custom(key: String, value: Any) -> Data { + return mutate(key: key, value: value) + } } extension Data: AnyContent { @@ -6605,10 +6745,10 @@ extension Data: Modifiable { } } -/// # Description: +/// ## Description /// The element represents its contents, along with a machine-readable form of those contents in the datetime attribute. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-time-element /// public struct Time: ContentNode, BodyElement { @@ -6738,6 +6878,10 @@ extension Time: GlobalAttributes, DateTimeAttribute { public func dateTime(_ value: String) -> Time { return mutate(datetime: value) } + + public func custom(key: String, value: Any) -> Time { + return mutate(key: key, value: value) + } } extension Time: AnyContent { @@ -6787,10 +6931,10 @@ extension Time: Modifiable { } } -/// # Description: +/// ## Description /// The element represents an example of code. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-code-element /// public struct Code: ContentNode, BodyElement { @@ -6916,6 +7060,10 @@ extension Code: GlobalAttributes { public func translate(_ value: String) -> Code { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Code { + return mutate(key: key, value: value) + } } extension Code: AnyContent { @@ -6965,10 +7113,10 @@ extension Code: Modifiable { } } -/// # Description: +/// ## Description /// The element indicates a variable name. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-link-element /// public struct Variable: ContentNode, BodyElement { @@ -7094,6 +7242,10 @@ extension Variable: GlobalAttributes { public func translate(_ value: String) -> Variable { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Variable { + return mutate(key: key, value: value) + } } extension Variable: AnyContent { @@ -7143,10 +7295,10 @@ extension Variable: Modifiable { } } -/// # Description: +/// ## Description /// The element represents sample or quoted output from another program or computing system. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-samp-element /// public struct SampleOutput: ContentNode, BodyElement { @@ -7272,6 +7424,10 @@ extension SampleOutput: GlobalAttributes { public func translate(_ value: String) -> SampleOutput { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> SampleOutput { + return mutate(key: key, value: value) + } } extension SampleOutput: AnyContent { @@ -7321,10 +7477,10 @@ extension SampleOutput: Modifiable { } } -/// # Description: +/// ## Description /// The element represents user input. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-kbd-element /// public struct KeyboardInput: ContentNode, BodyElement { @@ -7450,6 +7606,10 @@ extension KeyboardInput: GlobalAttributes { public func translate(_ value: String) -> KeyboardInput { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> KeyboardInput { + return mutate(key: key, value: value) + } } extension KeyboardInput: AnyContent { @@ -7499,10 +7659,10 @@ extension KeyboardInput: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a subscript. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-sub-and-sup-elements /// public struct Subscript: ContentNode, BodyElement { @@ -7628,6 +7788,10 @@ extension Subscript: GlobalAttributes { public func translate(_ value: String) -> Subscript { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Subscript { + return mutate(key: key, value: value) + } } extension Subscript: AnyContent { @@ -7677,10 +7841,10 @@ extension Subscript: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a superscript. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-sub-and-sup-elements /// public struct Superscript: ContentNode, BodyElement { @@ -7806,6 +7970,10 @@ extension Superscript: GlobalAttributes { public func translate(_ value: String) -> Superscript { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Superscript { + return mutate(key: key, value: value) + } } extension Superscript: AnyContent { @@ -7855,10 +8023,10 @@ extension Superscript: Modifiable { } } -/// # Description: +/// ## Description /// The element represents an italic font text. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-i-element /// public struct Italic: ContentNode, BodyElement { @@ -7984,6 +8152,10 @@ extension Italic: GlobalAttributes { public func translate(_ value: String) -> Italic { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Italic { + return mutate(key: key, value: value) + } } extension Italic: Localizable { @@ -8044,10 +8216,10 @@ extension Italic: Modifiable { } } -/// # Description: +/// ## Description /// The element represents an bold font text. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-b-element /// public struct Bold: ContentNode, BodyElement { @@ -8173,6 +8345,10 @@ extension Bold: GlobalAttributes { public func translate(_ value: String) -> Bold { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Bold { + return mutate(key: key, value: value) + } } extension Bold: Localizable { @@ -8233,10 +8409,10 @@ extension Bold: Modifiable { } } -/// # Description: +/// ## Description /// The element specifies that the enclosed text should be displayed as underlined. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-u-element /// public struct Underline: ContentNode, BodyElement { @@ -8362,6 +8538,10 @@ extension Underline: GlobalAttributes { public func translate(_ value: String) -> Underline { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Underline { + return mutate(key: key, value: value) + } } extension Underline: Localizable { @@ -8422,10 +8602,10 @@ extension Underline: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a run of text in the document marked or highlighted for reference purposes. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-mark-element /// public struct Mark: ContentNode, BodyElement { @@ -8551,6 +8731,10 @@ extension Mark: GlobalAttributes { public func translate(_ value: String) -> Mark { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Mark { + return mutate(key: key, value: value) + } } extension Mark: AnyContent { @@ -8600,10 +8784,10 @@ extension Mark: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a span of text that is to be isolated from its surroundings for the purposes of bidirectional text formatting. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-bdi-element /// public struct Bdi: ContentNode, BodyElement { @@ -8729,6 +8913,10 @@ extension Bdi: GlobalAttributes { public func translate(_ value: String) -> Bdi { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Bdi { + return mutate(key: key, value: value) + } } extension Bdi: AnyContent { @@ -8778,10 +8966,10 @@ extension Bdi: Modifiable { } } -/// # Description: +/// ## Description /// The element represents explicit text directionality formatting control. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-bdo-element /// public struct Bdo: EmptyNode, BodyElement { @@ -8902,6 +9090,10 @@ extension Bdo: GlobalAttributes { public func translate(_ value: String) -> Bdo { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Bdo { + return mutate(key: key, value: value) + } } extension Bdo: AnyContent { @@ -8951,10 +9143,10 @@ extension Bdo: Modifiable { } } -/// # Description: +/// ## Description /// The element doesn't mean anything on its own. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-span-element /// public struct Span: ContentNode, BodyElement { @@ -9080,6 +9272,10 @@ extension Span: GlobalAttributes { public func translate(_ value: String) -> Span { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Span { + return mutate(key: key, value: value) + } } extension Span: AnyContent { @@ -9129,10 +9325,10 @@ extension Span: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a line break. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-br-element /// public struct LineBreak: EmptyNode, BodyElement { @@ -9253,6 +9449,10 @@ extension LineBreak: GlobalAttributes { public func translate(_ value: String) -> LineBreak { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> LineBreak { + return mutate(key: key, value: value) + } } extension LineBreak: AnyContent { @@ -9302,10 +9502,10 @@ extension LineBreak: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a line break opportunity. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-wbr-element /// public struct WordBreak: EmptyNode, BodyElement { @@ -9426,6 +9626,10 @@ extension WordBreak: GlobalAttributes { public func translate(_ value: String) -> WordBreak { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> WordBreak { + return mutate(key: key, value: value) + } } extension WordBreak: AnyContent { @@ -9475,10 +9679,10 @@ extension WordBreak: Modifiable { } } -/// # Description: +/// ## Description /// The element represents an addition to the document. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-ins-element /// public struct InsertedText: ContentNode, BodyElement { @@ -9612,6 +9816,10 @@ extension InsertedText: GlobalAttributes, CiteAttribute, DateTimeAttribute { public func dateTime(_ value: String) -> InsertedText { return mutate(datetime: value) } + + public func custom(key: String, value: Any) -> InsertedText { + return mutate(key: key, value: value) + } } extension InsertedText: AnyContent { @@ -9661,10 +9869,10 @@ extension InsertedText: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a removal from the document. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-del-element /// public struct DeletedText: ContentNode, BodyElement { @@ -9798,6 +10006,10 @@ extension DeletedText: GlobalAttributes, CiteAttribute, DateTimeAttribute { public func dateTime(_ value: String) -> DeletedText { return mutate(datetime: value) } + + public func custom(key: String, value: Any) -> DeletedText { + return mutate(key: key, value: value) + } } extension DeletedText: AnyContent { @@ -9847,10 +10059,10 @@ extension DeletedText: Modifiable { } } -/// # Description: +/// ## Description /// The element is a container which provides multiple sources to its contained image element. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-picture-element /// public struct Picture: ContentNode, BodyElement { @@ -9976,6 +10188,10 @@ extension Picture: GlobalAttributes { public func translate(_ value: String) -> Picture { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Picture { + return mutate(key: key, value: value) + } } extension Picture: AnyContent { @@ -10025,10 +10241,10 @@ extension Picture: Modifiable { } } -/// # Description: +/// ## Description /// The element represents an image. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-img-element /// public struct Image: EmptyNode, BodyElement { @@ -10181,6 +10397,10 @@ extension Image: GlobalAttributes, AlternateAttribute, SourceAttribute, SizesAtt public func referrerPolicy(_ type: Policy) -> Image { return mutate(referrerpolicy: type.rawValue) } + + public func custom(key: String, value: Any) -> Image { + return mutate(key: key, value: value) + } } extension Image: AnyContent { @@ -10230,10 +10450,10 @@ extension Image: Modifiable { } } -/// # Description: +/// ## Description /// The element represents its nested browsing context. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-iframe-element /// public struct InlineFrame: ContentNode, BodyElement { @@ -10383,6 +10603,10 @@ extension InlineFrame: GlobalAttributes, SourceAttribute, NameAttribute, WidthAt public func referrerPolicy(_ type: Policy) -> InlineFrame { return mutate(referrerpolicy: type.rawValue) } + + public func custom(key: String, value: Any) -> InlineFrame { + return mutate(key: key, value: value) + } } extension InlineFrame: AnyContent { @@ -10432,10 +10656,10 @@ extension InlineFrame: Modifiable { } } -/// # Description: +/// ## Description /// The element provides an integration point for an external application or interactive content. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-embed-element /// public struct Embed: EmptyNode, BodyElement { @@ -10572,6 +10796,10 @@ extension Embed: GlobalAttributes, SourceAttribute, TypeAttribute, WidthAttribut public func height(_ size: Int) -> Embed { return mutate(height: size) } + + public func custom(key: String, value: Any) -> Embed { + return mutate(key: key, value: value) + } } extension Embed: AnyContent { @@ -10621,10 +10849,10 @@ extension Embed: Modifiable { } } -/// # Description: +/// ## Description /// The element represents an external resource. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-object-element /// public struct Object: ContentNode, BodyElement { @@ -10782,6 +11010,10 @@ extension Object: GlobalAttributes, DataAttribute, TypeAttribute, NameAttribute, public func height(_ size: Int) -> Object { return mutate(height: size) } + + public func custom(key: String, value: Any) -> Object { + return mutate(key: key, value: value) + } } extension Object: AnyContent { @@ -10831,10 +11063,10 @@ extension Object: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a comment output. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-video-element /// public struct Video: ContentNode, BodyElement { @@ -10988,6 +11220,10 @@ extension Video: GlobalAttributes, SourceAttribute, AutoplayAttribute, LoopAttri public func height(_ size: Int) -> Video { return mutate(height: size) } + + public func custom(key: String, value: Any) -> Video { + return mutate(key: key, value: value) + } } extension Video: AnyContent { @@ -11037,10 +11273,10 @@ extension Video: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a comment output. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-audio-element /// public struct Audio: ContentNode, BodyElement { @@ -11186,6 +11422,10 @@ extension Audio: GlobalAttributes, SourceAttribute, AutoplayAttribute, LoopAttri public func controls() -> Audio { return mutate(controls: "controls") } + + public func custom(key: String, value: Any) -> Audio { + return mutate(key: key, value: value) + } } extension Audio: AnyContent { @@ -11235,10 +11475,10 @@ extension Audio: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a comment output. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-map-elements /// public struct Map: ContentNode, BodyElement { @@ -11372,6 +11612,10 @@ extension Map: GlobalAttributes, NameAttribute { public func name(_ value: TemplateValue) -> Map { return mutate(name: value.rawValue) } + + public func custom(key: String, value: Any) -> Map { + return mutate(key: key, value: value) + } } extension Map: AnyContent { @@ -11421,10 +11665,10 @@ extension Map: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a comment output. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-form-element /// public struct Form: ContentNode, BodyElement { @@ -11590,6 +11834,10 @@ extension Form: GlobalAttributes, ActionAttribute, AutocompleteAttribute, Encodi public func relationship(_ type: Relation) -> Form { return mutate(rel: type.rawValue) } + + public func custom(key: String, value: Any) -> Form { + return mutate(key: key, value: value) + } } extension Form: AnyContent { @@ -11639,10 +11887,10 @@ extension Form: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a set of options. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-datalist-element /// public struct DataList: ContentNode, BodyElement { @@ -11768,6 +12016,10 @@ extension DataList: GlobalAttributes { public func translate(_ value: String) -> DataList { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> DataList { + return mutate(key: key, value: value) + } } extension DataList: AnyContent { @@ -11817,10 +12069,10 @@ extension DataList: Modifiable { } } -/// # Description: +/// ## Description /// The element represents the result of a calculation. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-output-element /// public struct Output: ContentNode, BodyElement { @@ -11962,6 +12214,10 @@ extension Output: GlobalAttributes, ForAttribute, FormAttribute, NameAttribute { public func name(_ value: TemplateValue) -> Output { return mutate(name: value.rawValue) } + + public func custom(key: String, value: Any) -> Output { + return mutate(key: key, value: value) + } } extension Output: AnyContent { @@ -12011,10 +12267,10 @@ extension Output: Modifiable { } } -/// # Description: +/// ## Description /// The element represents the completion progress of a task. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-progress-element /// public struct Progress: ContentNode, BodyElement { @@ -12152,6 +12408,10 @@ extension Progress: GlobalAttributes, ValueAttribute, MaximumValueAttribute { public func value(_ value: TemplateValue) -> Progress { return mutate(value: value.rawValue) } + + public func custom(key: String, value: Any) -> Progress { + return mutate(key: key, value: value) + } } extension Progress: AnyContent { @@ -12201,10 +12461,10 @@ extension Progress: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a scalar measurement within a known range, or a fractional value. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-meter-element /// public struct Meter: ContentNode, BodyElement { @@ -12354,6 +12614,10 @@ extension Meter: GlobalAttributes, ValueAttribute, MinimumValueAttribute, Maximu public func value(_ value: TemplateValue) -> Meter { return mutate(value: value.rawValue) } + + public func custom(key: String, value: Any) -> Meter { + return mutate(key: key, value: value) + } } extension Meter: AnyContent { @@ -12403,10 +12667,10 @@ extension Meter: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a disclosure widget from which the user can obtain additional information or controls. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-details-element /// public struct Details: ContentNode, BodyElement { @@ -12540,6 +12804,10 @@ extension Details: GlobalAttributes, OpenAttribute, ToggleEventAttribute { public func isOpen(_ condition: Bool) -> Details { return mutate(open: condition) } + + public func custom(key: String, value: Any) -> Details { + return mutate(key: key, value: value) + } } extension Details: AnyContent { @@ -12589,10 +12857,10 @@ extension Details: Modifiable { } } -/// # Description: +/// ## Description /// The element defines a dialog box or window. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-dialog-element /// public struct Dialog: ContentNode, BodyElement { @@ -12722,6 +12990,10 @@ extension Dialog: GlobalAttributes, OpenAttribute { public func isOpen(_ condition: Bool) -> Dialog { return mutate(open: condition) } + + public func custom(key: String, value: Any) -> Dialog { + return mutate(key: key, value: value) + } } extension Dialog: AnyContent { @@ -12771,13 +13043,13 @@ extension Dialog: Modifiable { } } -/// # Description: +/// ## Description /// The element allows to include dynamic script and data blocks in a document. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-script-element /// -public struct Script: ContentNode, BodyElement { +public struct Script: ContentNode, BodyElement, HeadElement { internal var name: String { "script" } @@ -12924,6 +13196,10 @@ extension Script: GlobalAttributes, AsynchronouslyAttribute, ReferrerPolicyAttri public func type(_ value: MediaType) -> Script { return mutate(type: value.rawValue) } + + public func custom(key: String, value: Any) -> Script { + return mutate(key: key, value: value) + } } extension Script: AnyContent { @@ -12973,10 +13249,10 @@ extension Script: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a caption for the rest of the contents of a fieldset. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-template-element /// public struct NoScript: ContentNode, BodyElement { @@ -13102,6 +13378,10 @@ extension NoScript: GlobalAttributes { public func translate(_ value: String) -> NoScript { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> NoScript { + return mutate(key: key, value: value) + } } extension NoScript: AnyContent { @@ -13151,10 +13431,10 @@ extension NoScript: Modifiable { } } -/// # Description: +/// ## Description /// The element is used to declare fragments of HTML that can be cloned and inserted in the document by script. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-template-element /// public struct Template: ContentNode, BodyElement { @@ -13280,6 +13560,10 @@ extension Template: GlobalAttributes { public func translate(_ value: String) -> Template { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Template { + return mutate(key: key, value: value) + } } extension Template: AnyContent { @@ -13329,10 +13613,10 @@ extension Template: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a comment output. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-canvas-element /// public struct Canvas: ContentNode, BodyElement { @@ -13466,6 +13750,10 @@ extension Canvas: GlobalAttributes, WidthAttribute, HeightAttribute { public func height(_ size: Int) -> Canvas { return mutate(height: size) } + + public func custom(key: String, value: Any) -> Canvas { + return mutate(key: key, value: value) + } } extension Canvas: AnyContent { @@ -13515,10 +13803,10 @@ extension Canvas: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a comment output. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-table-element /// public struct Table: ContentNode, BodyElement { @@ -13652,6 +13940,10 @@ extension Table: GlobalAttributes, WidthAttribute, HeightAttribute { public func height(_ size: Int) -> Table { return mutate(height: size) } + + public func custom(key: String, value: Any) -> Table { + return mutate(key: key, value: value) + } } extension Table: AnyContent { diff --git a/Sources/HTMLKit/External/Elements/DefinitionElements.swift b/Sources/HTMLKit/External/Elements/DefinitionElements.swift index 61278ec9..262c612c 100644 --- a/Sources/HTMLKit/External/Elements/DefinitionElements.swift +++ b/Sources/HTMLKit/External/Elements/DefinitionElements.swift @@ -1,30 +1,30 @@ -/// # Description: +/// ## Description /// The file contains the definition elements. The html element DescriptionList only allows these /// elements to be its descendants. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr import OrderedCollections -/// # Description: +/// ## Description /// The alias points to TermName. /// public typealias Dt = TermName -/// # Description: +/// ## Description /// The alias points to TermDefinition. /// public typealias Dd = TermDefinition -/// # Description: +/// ## Description /// The element specifies a term name. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-dt-element /// public struct TermName: ContentNode, DescriptionElement { @@ -150,6 +150,10 @@ extension TermName: GlobalAttributes { public func translate(_ value: String) -> TermName { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> TermName { + return mutate(key: key, value: value) + } } extension TermName: AnyContent { @@ -199,10 +203,10 @@ extension TermName: Modifiable { } } -/// # Description: +/// ## Description /// The element specifies a term definition. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-dd-element /// public struct TermDefinition: ContentNode, DescriptionElement { @@ -328,6 +332,10 @@ extension TermDefinition: GlobalAttributes { public func translate(_ value: String) -> TermDefinition { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> TermDefinition { + return mutate(key: key, value: value) + } } extension TermDefinition: AnyContent { diff --git a/Sources/HTMLKit/External/Elements/FigureElements.swift b/Sources/HTMLKit/External/Elements/FigureElements.swift index 9b9bc327..cb8e08e0 100644 --- a/Sources/HTMLKit/External/Elements/FigureElements.swift +++ b/Sources/HTMLKit/External/Elements/FigureElements.swift @@ -1,25 +1,25 @@ -/// # Description: +/// ## Description /// The file contains the figure elements. The html element Figure only allows these elements to be its /// descendants. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr import OrderedCollections -/// # Description: +/// ## Description /// The alias points to FigureCaption. /// public typealias Figcaption = FigureCaption -/// # Description: +/// ## Description /// The element is used to label a figure. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-figcaption-element /// public struct FigureCaption: ContentNode, FigureElement { @@ -145,6 +145,10 @@ extension FigureCaption: GlobalAttributes { public func translate(_ value: String) -> FigureCaption { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> FigureCaption { + return mutate(key: key, value: value) + } } extension FigureCaption: AnyContent { diff --git a/Sources/HTMLKit/External/Elements/FormElements.swift b/Sources/HTMLKit/External/Elements/FormElements.swift index e3b55163..30441a19 100644 --- a/Sources/HTMLKit/External/Elements/FormElements.swift +++ b/Sources/HTMLKit/External/Elements/FormElements.swift @@ -1,20 +1,20 @@ -/// # Description: +/// ## Description /// The file contains the form elements. The html element Form only allows these elements to be its /// descendants. There are some exceptions too. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr import OrderedCollections -/// # Description: +/// ## Description /// The element represents a typed data field to allow the user to edit the data. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-input-element /// public struct Input: EmptyNode, FormElement { @@ -251,6 +251,10 @@ extension Input: GlobalAttributes, AcceptAttribute, AlternateAttribute, Autocomp public func width(_ size: Int) -> Input { return mutate(width: size) } + + public func custom(key: String, value: Any) -> Input { + return mutate(key: key, value: value) + } } extension Input: AnyContent { @@ -300,10 +304,10 @@ extension Input: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a caption for a form control. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-label-element /// public struct Label: ContentNode, FormElement { @@ -433,6 +437,10 @@ extension Label: GlobalAttributes, ForAttribute { public func `for`(_ value: String) -> Label { return mutate(for: value) } + + public func custom(key: String, value: Any) -> Label { + return mutate(key: key, value: value) + } } extension Label: AnyContent { @@ -493,10 +501,10 @@ extension Label: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a control for selecting amongst a set of options. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-select-element /// public struct Select: ContentNode, FormElement { @@ -654,6 +662,10 @@ extension Select: GlobalAttributes, AutocompleteAttribute, DisabledAttribute, Fo public func size(_ size: Int) -> Select { return mutate(size: size) } + + public func custom(key: String, value: Any) -> Select { + return mutate(key: key, value: value) + } } extension Select: AnyContent { @@ -703,10 +715,10 @@ extension Select: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a multiline plain text edit control. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-textarea-element /// public struct TextArea: ContentNode, FormElement { @@ -888,6 +900,10 @@ extension TextArea: GlobalAttributes, AutocompleteAttribute, ColumnsAttribute, D public func wrap(_ type: Wrapping) -> TextArea { return mutate(wrap: type.rawValue) } + + public func custom(key: String, value: Any) -> TextArea { + return mutate(key: key, value: value) + } } extension TextArea: AnyContent { @@ -937,10 +953,10 @@ extension TextArea: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a comment output. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-button-element /// public struct Button: ContentNode, FormElement { @@ -1098,6 +1114,10 @@ extension Button: GlobalAttributes, DisabledAttribute, FormAttribute, FormAction public func value(_ value: TemplateValue) -> Button { return mutate(value: value.rawValue) } + + public func custom(key: String, value: Any) -> Button { + return mutate(key: key, value: value) + } } extension Button: AnyContent { @@ -1158,10 +1178,10 @@ extension Button: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a set of form controls grouped together. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-fieldset-element /// public struct Fieldset: ContentNode, FormElement { @@ -1303,6 +1323,10 @@ extension Fieldset: GlobalAttributes, DisabledAttribute, FormAttribute, NameAttr public func name(_ value: TemplateValue) -> Fieldset { return mutate(name: value.rawValue) } + + public func custom(key: String, value: Any) -> Fieldset { + return mutate(key: key, value: value) + } } extension Fieldset: AnyContent { diff --git a/Sources/HTMLKit/External/Elements/HeadElements.swift b/Sources/HTMLKit/External/Elements/HeadElements.swift index 6fafc8b4..7104d714 100644 --- a/Sources/HTMLKit/External/Elements/HeadElements.swift +++ b/Sources/HTMLKit/External/Elements/HeadElements.swift @@ -1,22 +1,22 @@ -/// # Description: +/// ## Description /// The file contains the figure elements. The html element Head only allows these elements to be its /// descendants. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr import OrderedCollections -/// # Description: +/// ## Description /// The element represents the document's title. /// /// There must be no more than one title element per document. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-title-element /// public struct Title: ContentNode, HeadElement { @@ -142,6 +142,10 @@ extension Title: GlobalAttributes { public func translate(_ value: String) -> Title { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Title { + return mutate(key: key, value: value) + } } extension Title: AnyContent { @@ -192,12 +196,12 @@ extension Title: Modifiable { } -/// # Description: +/// ## Description /// The element specifies the document base url. /// /// There must be no more than one base element per document. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-base-element /// public struct Base: EmptyNode, HeadElement { @@ -330,6 +334,10 @@ extension Base: GlobalAttributes, ReferenceAttribute, TargetAttribute { public func target(_ type: Target) -> Base { return mutate(target: type.rawValue) } + + public func custom(key: String, value: Any) -> Base { + return mutate(key: key, value: value) + } } extension Base: AnyContent { @@ -379,11 +387,11 @@ extension Base: Modifiable { } } -/// # Description: +/// ## Description /// The element provides meta information about the document. /// /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-meta-element /// public struct Meta: EmptyNode, HeadElement { @@ -399,7 +407,7 @@ public struct Meta: EmptyNode, HeadElement { } } -extension Meta: GlobalAttributes, ContentAttribute, NameAttribute, PropertyAttribute { +extension Meta: GlobalAttributes, ContentAttribute, NameAttribute, PropertyAttribute, CharsetAttribute, EquivalentAttribute { public func accessKey(_ value: String) -> Meta { return mutate(accesskey: value) @@ -524,6 +532,18 @@ extension Meta: GlobalAttributes, ContentAttribute, NameAttribute, PropertyAttri public func property(_ type: Graphs) -> Meta { return mutate(property: type.rawValue) } + + public func charset(_ value: Charset) -> Meta { + return mutate(charset: value.rawValue) + } + + public func equivalent(_ value: Equivalent) -> Meta { + return mutate(httpequiv: value.rawValue) + } + + public func custom(key: String, value: Any) -> Meta { + return mutate(key: key, value: value) + } } extension Meta: AnyContent { @@ -573,11 +593,11 @@ extension Meta: Modifiable { } } -/// # Description: +/// ## Description /// The element contains style information for the document. /// /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-style-element /// public struct Style: ContentNode, HeadElement { @@ -715,6 +735,10 @@ extension Style: GlobalAttributes, TypeAttribute, MediaAttribute, LoadEventAttri public func media(_ value: String) -> Style { return mutate(media: value) } + + public func custom(key: String, value: Any) -> Style { + return mutate(key: key, value: value) + } } extension Style: AnyContent { @@ -764,10 +788,10 @@ extension Style: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a comment output. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-link-element /// public struct Link: EmptyNode, HeadElement { @@ -928,6 +952,10 @@ extension Link: GlobalAttributes, ReferenceAttribute, ReferenceLanguageAttribute public func type(_ value: MediaType) -> Link { return mutate(type: value.rawValue) } + + public func custom(key: String, value: Any) -> Link { + return mutate(key: key, value: value) + } } extension Link: AnyContent { diff --git a/Sources/HTMLKit/External/Elements/HtmlElements.swift b/Sources/HTMLKit/External/Elements/HtmlElements.swift index 928c9a85..48060280 100644 --- a/Sources/HTMLKit/External/Elements/HtmlElements.swift +++ b/Sources/HTMLKit/External/Elements/HtmlElements.swift @@ -1,20 +1,20 @@ -/// # Description: +/// ## Description /// The file contains the html elements. The html element Html only allows these elements to be its /// descendants. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr import OrderedCollections -/// # Description: +/// ## Description /// The element contains the information about the document's content. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-head-element /// public struct Head: ContentNode, HtmlElement { @@ -140,6 +140,10 @@ extension Head: GlobalAttributes { public func translate(_ value: String) -> Head { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Head { + return mutate(key: key, value: value) + } } extension Head: AnyContent { @@ -189,10 +193,10 @@ extension Head: Modifiable { } } -/// # Description: +/// ## Description /// The element contains the document's content. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-body-element /// public struct Body: ContentNode, HtmlElement { @@ -354,6 +358,10 @@ extension Body: GlobalAttributes, AfterPrintEventAttribute, BeforePrintEventAttr public func translate(_ value: String) -> Body { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Body { + return mutate(key: key, value: value) + } } extension Body: AnyContent { diff --git a/Sources/HTMLKit/External/Elements/InputElements.swift b/Sources/HTMLKit/External/Elements/InputElements.swift index fe25210a..5a15f0a3 100644 --- a/Sources/HTMLKit/External/Elements/InputElements.swift +++ b/Sources/HTMLKit/External/Elements/InputElements.swift @@ -1,25 +1,25 @@ -/// # Description: +/// ## Description /// The file contains the input elements. The html element Input only allows these elements to be its /// descendants. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr import OrderedCollections -/// # Description: +/// ## Description /// The alias points to OptionGroup. /// public typealias Optgroup = OptionGroup -/// # Description: +/// ## Description /// The element represents a group of options. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-optgroup-element /// public struct OptionGroup: ContentNode, InputElement { @@ -153,6 +153,10 @@ extension OptionGroup: GlobalAttributes, DisabledAttribute, LabelAttribute { public func label(_ value: String) -> OptionGroup { return mutate(label: value) } + + public func custom(key: String, value: Any) -> OptionGroup { + return mutate(key: key, value: value) + } } extension OptionGroup: AnyContent { @@ -202,10 +206,10 @@ extension OptionGroup: Modifiable { } } -/// # Description: +/// ## Description /// The element represents an option. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-option-element /// public struct Option: ContentNode, InputElement { @@ -347,6 +351,10 @@ extension Option: GlobalAttributes, DisabledAttribute, LabelAttribute, ValueAttr public func value(_ value: TemplateValue) -> Option { return mutate(value: value.rawValue) } + + public func custom(key: String, value: Any) -> Option { + return mutate(key: key, value: value) + } } extension Option: AnyContent { @@ -396,10 +404,10 @@ extension Option: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a caption for the rest of the contents of a fieldset. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-legend-element /// public struct Legend: ContentNode, InputElement { @@ -411,10 +419,12 @@ public struct Legend: ContentNode, InputElement { internal var content: [AnyContent] public init(@ContentBuilder content: () -> [AnyContent]) { + self.content = content() } internal init(attributes: OrderedDictionary?, content: [AnyContent]) { + self.attributes = attributes self.content = content } @@ -525,6 +535,10 @@ extension Legend: GlobalAttributes { public func translate(_ value: String) -> Legend { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Legend { + return mutate(key: key, value: value) + } } extension Legend: AnyContent { @@ -574,10 +588,10 @@ extension Legend: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a summary, caption, or legend for the rest of the content. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-summary-element /// public struct Summary: ContentNode, InputElement { @@ -703,6 +717,10 @@ extension Summary: GlobalAttributes { public func translate(_ value: String) -> Summary { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Summary { + return mutate(key: key, value: value) + } } extension Summary: AnyContent { diff --git a/Sources/HTMLKit/External/Elements/ListElements.swift b/Sources/HTMLKit/External/Elements/ListElements.swift index b99a1e8e..88525616 100644 --- a/Sources/HTMLKit/External/Elements/ListElements.swift +++ b/Sources/HTMLKit/External/Elements/ListElements.swift @@ -1,25 +1,25 @@ -/// # Description: +/// ## Description /// The file contains the list elements. The html elements OrderedList or UnorderedList only /// allows these elements to be its descendants. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr import OrderedCollections -/// # Description: +/// ## Description /// The alias points to ListItem. /// public typealias Li = ListItem -/// # Description: +/// ## Description /// The element represents a item of a list. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-li-element /// public struct ListItem: ContentNode, ListElement { @@ -153,6 +153,10 @@ extension ListItem: GlobalAttributes, ValueAttribute { public func value(_ value: TemplateValue) -> ListItem { return mutate(value: value.rawValue) } + + public func custom(key: String, value: Any) -> ListItem { + return mutate(key: key, value: value) + } } extension ListItem: AnyContent { diff --git a/Sources/HTMLKit/External/Elements/MapElements.swift b/Sources/HTMLKit/External/Elements/MapElements.swift index dcebfe6c..0bb31871 100644 --- a/Sources/HTMLKit/External/Elements/MapElements.swift +++ b/Sources/HTMLKit/External/Elements/MapElements.swift @@ -1,20 +1,20 @@ -/// # Description: +/// ## Description /// The file contains the map elements. The html element Map only allows these elements to be its /// descendants. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr import OrderedCollections -/// # Description: +/// ## Description /// The element defines an image map. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-area-element /// public struct Area: ContentNode, MapElement { @@ -180,6 +180,10 @@ extension Area: GlobalAttributes, AlternateAttribute, CoordinatesAttribute, Shap public func referrerPolicy(_ type: Policy) -> Area { return mutate(referrerpolicy: type.rawValue) } + + public func custom(key: String, value: Any) -> Area { + return mutate(key: key, value: value) + } } extension Area: AnyContent { diff --git a/Sources/HTMLKit/External/Elements/MediaElements.swift b/Sources/HTMLKit/External/Elements/MediaElements.swift index e429a527..91a675f4 100644 --- a/Sources/HTMLKit/External/Elements/MediaElements.swift +++ b/Sources/HTMLKit/External/Elements/MediaElements.swift @@ -1,20 +1,20 @@ -/// # Description: +/// ## Description /// The file contains the media elements. The html elements Audio or Video only allows these elements /// to be its descendants. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr import OrderedCollections -/// # Description: +/// ## Description /// The element allows authors to specify multiple alternative source for other elements. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-source-element /// public struct Source: EmptyNode, MediaElement { @@ -159,6 +159,10 @@ extension Source: GlobalAttributes, TypeAttribute, SourceAttribute, SizesAttribu public func height(_ size: Int) -> Source { return mutate(height: size) } + + public func custom(key: String, value: Any) -> Source { + return mutate(key: key, value: value) + } } extension Source: AnyContent { @@ -208,10 +212,10 @@ extension Source: Modifiable { } } -/// # Description: +/// ## Description /// The element allows to specify explicit external timed text tracks for media elements. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-track-element /// public struct Track: EmptyNode, MediaElement { @@ -348,6 +352,10 @@ extension Track: GlobalAttributes, KindAttribute, SourceAttribute, LabelAttribut public func `default`() -> Track { return mutate(default: "default") } + + public func custom(key: String, value: Any) -> Track { + return mutate(key: key, value: value) + } } extension Track: AnyContent { diff --git a/Sources/HTMLKit/External/Elements/ObjectElements.swift b/Sources/HTMLKit/External/Elements/ObjectElements.swift index 2e3b6dd2..a85d98c0 100644 --- a/Sources/HTMLKit/External/Elements/ObjectElements.swift +++ b/Sources/HTMLKit/External/Elements/ObjectElements.swift @@ -1,20 +1,20 @@ -/// # Description: +/// ## Description /// The file contains the object elements. The html element Object only allows these elements to be its /// descendants. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr import OrderedCollections -/// # Description: +/// ## Description /// The element defines parameters for plugins invoked by an object element. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-param-element /// public struct Parameter: EmptyNode, ObjectElement { @@ -151,6 +151,10 @@ extension Parameter: GlobalAttributes, NameAttribute, ValueAttribute { public func value(_ value: TemplateValue) -> Parameter { return mutate(value: value.rawValue) } + + public func custom(key: String, value: Any) -> Parameter { + return mutate(key: key, value: value) + } } extension Parameter: AnyContent { diff --git a/Sources/HTMLKit/External/Elements/RubyElements.swift b/Sources/HTMLKit/External/Elements/RubyElements.swift index 24cf0214..a27d2609 100644 --- a/Sources/HTMLKit/External/Elements/RubyElements.swift +++ b/Sources/HTMLKit/External/Elements/RubyElements.swift @@ -1,30 +1,30 @@ -/// # Description: +/// ## Description /// The file contains the ruby elements. The html element Ruby only allows these elements to be its /// descendants. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr import OrderedCollections -/// # Description: +/// ## Description /// The alias points to RubyText. /// public typealias Rt = RubyText -/// # Description: +/// ## Description /// The alias points to RubyPronunciation. /// public typealias Rp = RubyPronunciation -/// # Description: +/// ## Description /// The element marks the ruby text component of a ruby annotation. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-rt-element /// public struct RubyText: ContentNode, RubyElement { @@ -150,6 +150,10 @@ extension RubyText: GlobalAttributes { public func translate(_ value: String) -> RubyText { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> RubyText { + return mutate(key: key, value: value) + } } extension RubyText: AnyContent { @@ -199,10 +203,10 @@ extension RubyText: Modifiable { } } -/// # Description: +/// ## Description /// The element represents nothing. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-rp-element /// public struct RubyPronunciation: ContentNode, RubyElement { @@ -328,6 +332,10 @@ extension RubyPronunciation: GlobalAttributes { public func translate(_ value: String) -> RubyPronunciation { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> RubyPronunciation { + return mutate(key: key, value: value) + } } extension RubyPronunciation: AnyContent { diff --git a/Sources/HTMLKit/External/Elements/TableElements.swift b/Sources/HTMLKit/External/Elements/TableElements.swift index b61ed73e..b150febd 100644 --- a/Sources/HTMLKit/External/Elements/TableElements.swift +++ b/Sources/HTMLKit/External/Elements/TableElements.swift @@ -1,60 +1,60 @@ -/// # Description: +/// ## Description /// The file contains the table elements. The html element Table only allows these elements to be its /// descendants. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr import OrderedCollections -/// # Description: +/// ## Description /// The alias points to ColumnGroup. /// public typealias Colgroup = ColumnGroup -/// # Description: +/// ## Description /// The alias points to Column. /// public typealias Col = Column -/// # Description: +/// ## Description /// The alias points to TableBody. /// public typealias Tbody = TableBody -/// # Description: +/// ## Description /// The alias points to TableHead. /// public typealias Thead = TableHead -/// # Description: +/// ## Description /// The alias points to TableFoot. /// public typealias Tfoot = TableFoot -/// # Description: +/// ## Description /// The alias points to TableRow. /// public typealias Tr = TableRow -/// # Description: +/// ## Description /// The alias points to DataCell. /// public typealias Td = DataCell -/// # Description: +/// ## Description /// The alias points to HeaderCell. /// public typealias Th = HeaderCell -/// # Description: +/// ## Description /// The element represents the title of the table. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-caption-element /// public struct Caption: ContentNode, TableElement { @@ -180,6 +180,10 @@ extension Caption: GlobalAttributes { public func translate(_ value: String) -> Caption { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> Caption { + return mutate(key: key, value: value) + } } extension Caption: AnyContent { @@ -229,10 +233,10 @@ extension Caption: Modifiable { } } -/// # Description: +/// ## Description /// The element specifies a group of one or more columns. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-colgroup-element /// public struct ColumnGroup: ContentNode, TableElement { @@ -362,6 +366,10 @@ extension ColumnGroup: GlobalAttributes, SpanAttribute { public func span(_ size: Int) -> ColumnGroup { return mutate(span: size) } + + public func custom(key: String, value: Any) -> ColumnGroup { + return mutate(key: key, value: value) + } } extension ColumnGroup: AnyContent { @@ -411,10 +419,10 @@ extension ColumnGroup: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a column in a table. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-col-element /// public struct Column: ContentNode, TableElement { @@ -544,6 +552,10 @@ extension Column: GlobalAttributes, SpanAttribute { public func span(_ size: Int) -> Column { return mutate(span: size) } + + public func custom(key: String, value: Any) -> Column { + return mutate(key: key, value: value) + } } extension Column: AnyContent { @@ -593,10 +605,10 @@ extension Column: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a block of rows in a table. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-tbody-element /// public struct TableBody: ContentNode, TableElement { @@ -730,6 +742,10 @@ extension TableBody: GlobalAttributes, WidthAttribute, HeightAttribute { public func height(_ size: Int) -> TableBody { return mutate(height: size) } + + public func custom(key: String, value: Any) -> TableBody { + return mutate(key: key, value: value) + } } extension TableBody: AnyContent { @@ -779,10 +795,10 @@ extension TableBody: Modifiable { } } -/// # Description: +/// ## Description /// The element represents the block of rows that consist of the column labels. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-thead-element /// public struct TableHead: ContentNode, TableElement { @@ -916,6 +932,10 @@ extension TableHead: GlobalAttributes, WidthAttribute, HeightAttribute { public func height(_ size: Int) -> TableHead { return mutate(height: size) } + + public func custom(key: String, value: Any) -> TableHead { + return mutate(key: key, value: value) + } } extension TableHead: AnyContent { @@ -965,10 +985,10 @@ extension TableHead: Modifiable { } } -/// # Description: +/// ## Description /// The element represents the block of rows that consist of the column summaries. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-tfoot-element /// public struct TableFoot: ContentNode, TableElement { @@ -1094,6 +1114,10 @@ extension TableFoot: GlobalAttributes { public func translate(_ value: String) -> TableFoot { return mutate(translate: value) } + + public func custom(key: String, value: Any) -> TableFoot { + return mutate(key: key, value: value) + } } extension TableFoot: AnyContent { @@ -1143,10 +1167,10 @@ extension TableFoot: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a row of cells in a table. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-tr-element /// public struct TableRow: ContentNode, TableElement { @@ -1280,6 +1304,10 @@ extension TableRow: GlobalAttributes, WidthAttribute, HeightAttribute { public func height(_ size: Int) -> TableRow { return mutate(height: size) } + + public func custom(key: String, value: Any) -> TableRow { + return mutate(key: key, value: value) + } } extension TableRow: AnyContent { @@ -1329,10 +1357,10 @@ extension TableRow: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a data cell in a table. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-td-element /// public struct DataCell: ContentNode, TableElement { @@ -1470,6 +1498,10 @@ extension DataCell: GlobalAttributes, ColumnSpanAttribute, RowSpanAttribute, Hea public func headers(_ value: String) -> DataCell { return mutate(headers: value) } + + public func custom(key: String, value: Any) -> DataCell { + return mutate(key: key, value: value) + } } extension DataCell: AnyContent { @@ -1519,10 +1551,10 @@ extension DataCell: Modifiable { } } -/// # Description: +/// ## Description /// The element represents a header cell in a table. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#the-th-element /// public struct HeaderCell: ContentNode, TableElement { @@ -1664,6 +1696,10 @@ extension HeaderCell: GlobalAttributes, ColumnSpanAttribute, RowSpanAttribute, H public func scope(_ value: String) -> HeaderCell { return mutate(scope: value) } + + public func custom(key: String, value: Any) -> HeaderCell { + return mutate(key: key, value: value) + } } extension HeaderCell: AnyContent { diff --git a/Sources/HTMLKit/External/Functions.swift b/Sources/HTMLKit/External/Functions.swift deleted file mode 100644 index fb85344f..00000000 --- a/Sources/HTMLKit/External/Functions.swift +++ /dev/null @@ -1,50 +0,0 @@ -/// # Description: -/// The file contains basic functions. -/// -/// # Note: -/// If you about to add something to the file, stick to the official documentation to keep the code consistent. -/// -/// # Authors: -/// Mats Moll: https://github.com/matsmoll -/// Mattes Mohr: https://github.com/mattesmohr - -/// # Description: -/// The function is for -/// -/// # References: -/// -public struct Unwrap: Component { - - let content: IF - - public init(_ value: TemplateValue, @ContentBuilder content: (TemplateValue) -> AnyContent) { - var ifContent: AnyContent = "" - if value.isMasqueradingOptional { - ifContent = content(value.unsafeCast(to: A.self)) - } else { - switch value { - case .constant(let value): - if value != nil { - ifContent = content(.constant(value!)) - } - case .dynamic(let variable): - ifContent = content(.dynamic(variable.unsafelyUnwrapped)) - } - } - self.content = IF(value.isDefined) { - ifContent - } - } - - init(content: IF) { - self.content = content - } - - public var body: AnyContent { - content - } - - public func `else`(@ContentBuilder content: () -> AnyContent) -> AnyContent { - self.content.else(render: content) - } -} diff --git a/Sources/HTMLKit/External/Layouts.swift b/Sources/HTMLKit/External/Layouts.swift index ef85aaa4..833c18b7 100644 --- a/Sources/HTMLKit/External/Layouts.swift +++ b/Sources/HTMLKit/External/Layouts.swift @@ -1,17 +1,17 @@ -/// # Description: +/// ## Description /// The file contains layout components. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr -/// # Description: +/// ## Description /// The protocol is for /// -/// # References: +/// ## References /// public protocol Page: GlobalElement { @@ -31,10 +31,10 @@ extension Page { public var scripts: AnyContent { body.scripts } } -/// # Description: +/// ## Description /// The protocol is for /// -/// # References: +/// ## References /// public protocol View: GlobalElement { @@ -60,10 +60,10 @@ extension View { public var scripts: AnyContent { body.scripts } } -/// # Description: +/// ## Description /// The protocol is for /// -/// # References: +/// ## References /// public protocol Component: GlobalElement { diff --git a/Sources/HTMLKit/External/Statements.swift b/Sources/HTMLKit/External/Statements.swift index 0a8d55e3..fcf6e73f 100644 --- a/Sources/HTMLKit/External/Statements.swift +++ b/Sources/HTMLKit/External/Statements.swift @@ -1,41 +1,52 @@ -/// # Description: +/// ## Description /// The file contains basic statements. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr -/// # Description: +/// ## Description /// The statement is for /// -/// # References: +/// ## References /// public struct IF: GlobalElement { + public enum IFPrerenderErrors: Error { + + case dynamiclyEvaluatedCondition + } + public class Condition { - let condition: Conditionable - var localFormula: Renderer.Formula - var view: AnyContent = "" + public let condition: Conditionable + + public var localFormula: Renderer.Formula - init(condition: Conditionable) { + public var view: AnyContent = "" + + public init(condition: Conditionable) { + self.condition = condition localFormula = Renderer.Formula() } } - let conditions: [Condition] + public let conditions: [Condition] public init(_ condition: Conditionable, @ContentBuilder content: () -> AnyContent) { + let ifCondition = Condition(condition: condition) ifCondition.view = content() + self.conditions = [ifCondition] } - init(conditions: [Condition]) { + public init(conditions: [Condition]) { + self.conditions = conditions } } @@ -55,162 +66,184 @@ extension IF.Condition: Conditionable { } } -/// This is a struct that should never exist in a template, and therefore will be used to evaluate if a `Condition`is dynamic or static -struct ConditionPrerenderTest {} - -enum IFPrerenderErrors: Error { - case dynamiclyEvaluatedCondition -} - extension IF: AnyContent { public var scripts: AnyContent { + IF(conditions: conditions.map { htmlCondition in + let scriptCondition = IF.Condition(condition: htmlCondition.condition) scriptCondition.view = htmlCondition.view.scripts + return scriptCondition }) } public func render(with manager: Renderer.ContextManager) throws -> String { + for condition in conditions { + if try condition.evaluate(with: manager) { return try condition.render(with: manager) } } + return "" } public func prerender(_ formula: Renderer.Formula) throws { + var isStaticallyEvaluated = true + for condition in conditions { + condition.localFormula.calendar = formula.calendar + condition.localFormula.timeZone = formula.timeZone do { + guard isStaticallyEvaluated else { throw IFPrerenderErrors.dynamiclyEvaluatedCondition } + let testContext = Renderer.ContextManager(contexts: [:]) + if try condition.condition.evaluate(with: testContext) { + try condition.view.prerender(formula) + return // Returning as the first true condition should be the only one that is rendered } + } catch { - // If an error was thrown, then there is some missing context and therefore the whole condition should be evaluated at runtime + isStaticallyEvaluated = false + try condition.prerender(formula) } } + if isStaticallyEvaluated == false { formula.add(mappable: self) } } - /// Add an else if condition - /// - /// - Parameters: - /// - condition: The condition to be evaluated - /// - render: The view to render if true - /// - Returns: returns a modified if statment - public func elseIf(_ condition: Conditionable, @ContentBuilder render: () -> AnyContent) -> IF { + public func elseIf(_ condition: Conditionable, @ContentBuilder content: () -> AnyContent) -> IF { + let ifCondition = Condition(condition: condition) - ifCondition.view = render() + ifCondition.view = content() + return .init(conditions: conditions + [ifCondition]) } - /// Add an else if condition - /// - /// - Parameters: - /// - path: The path to evaluate - /// - render: The view to render if true - /// - Returns: returns a modified if statment - public func elseIf(isNil path: TemplateValue, @ContentBuilder render: () -> AnyContent) -> IF { + public func elseIf(isNil path: TemplateValue, @ContentBuilder content: () -> AnyContent) -> IF { + let condition = Condition(condition: IsNullCondition(path: path)) - condition.view = render() + condition.view = content() + return .init(conditions: conditions + [condition]) } - /// Add an else if condition - /// - /// - Parameters: - /// - path: The path to evaluate - /// - render: The view to render if true - /// - Returns: returns a modified if statment - public func elseIf(isNotNil path: TemplateValue, @ContentBuilder render: () -> AnyContent) -> IF { + public func elseIf(isNotNil path: TemplateValue, @ContentBuilder content: () -> AnyContent) -> IF { + let condition = Condition(condition: NotNullCondition(path: path)) - condition.view = render() + condition.view = content() + return .init(conditions: conditions + [condition]) } - /// Add an else condition - /// - /// - Parameter render: The view to be rendered - /// - Returns: A mappable object - public func `else`(@ContentBuilder render: () -> AnyContent) -> AnyContent { + public func `else`(@ContentBuilder content: () -> AnyContent) -> AnyContent { + let trueCondition = Condition(condition: AlwaysTrueCondition()) - trueCondition.view = render() + trueCondition.view = content() + return IF(conditions: conditions + [trueCondition]) } } -/// # Description: +/// ## Description /// The statement is for /// -/// # References: +/// ## References /// public struct ForEach: GlobalElement where Values: Sequence { public let context: TemplateValue - let content: AnyContent + public let content: AnyContent - let localFormula: Renderer.Formula + public let localFormula: Renderer.Formula - let condition: Conditionable - var isEnumerated: Bool = false + public let condition: Conditionable + + public var isEnumerated: Bool = false public init(in context: TemplateValue, @ContentBuilder content: (TemplateValue) -> AnyContent) { self.condition = true self.context = context + switch context { - case .constant(let values): self.content = values.reduce(into: "") { $0 += content(.constant($1)) } - case .dynamic(let variable): self.content = content(.dynamic(.root(Values.Element.self, rootId: "\(variable.pathId)-loop"))) + case .constant(let values): + + self.content = values.reduce(into: "") { + $0 += content(.constant($1)) + } + + case .dynamic(let variable): + self.content = content(.dynamic(.root(Values.Element.self, rootId: "\(variable.pathId)-loop"))) } - localFormula = .init() + + self.localFormula = .init() } public init(in context: TemplateValue, @ContentBuilder content: (TemplateValue) -> AnyContent) { self.context = context.unsafelyUnwrapped + switch context { case .constant(let values): + if let values = values { + self.content = values.reduce(into: "") { $0 += content(.constant($1)) } + } else { + self.content = "" } + case .dynamic(let variable): self.content = content(.dynamic(.root(Values.Element.self, rootId: variable.unsafelyUnwrapped.pathId + "-loop"))) } + self.condition = context.isDefined - localFormula = .init() + + self.localFormula = .init() } public init(enumerated context: TemplateValue, @ContentBuilder content: ((element: TemplateValue, index: TemplateValue)) -> AnyContent) { self.condition = true self.context = context + switch context { - case .constant(let values): self.content = values.enumerated().reduce(into: "") { $0 += content((.constant($1.element), .constant($1.offset))) } + case .constant(let values): + + self.content = values.enumerated().reduce(into: "") { + $0 += content((.constant($1.element), .constant($1.offset))) + } + case .dynamic(let variable): self.content = content( ( .dynamic(.root(Values.Element.self, rootId: "\(variable.pathId)-loop")), .dynamic(.root(Int.self, rootId: "\(variable.pathId)-loop-index")) )) } - localFormula = .init() + + self.localFormula = .init() + self.isEnumerated = true } } @@ -218,10 +251,12 @@ public struct ForEach: GlobalElement where Values: Sequence { extension ForEach { public init(enumerated context: Values, @ContentBuilder content: ((element: TemplateValue, index: TemplateValue)) -> AnyContent) { + self.init(enumerated: .constant(context), content: content) } public init(in values: Values, @ContentBuilder content: (TemplateValue) -> AnyContent) { + self.init(in: .constant(values), content: content) } } @@ -229,26 +264,44 @@ extension ForEach { extension ForEach: AnyContent { public func prerender(_ formula: Renderer.Formula) throws { + formula.add(mappable: self) + try content.prerender(localFormula) } public func render(with manager: Renderer.ContextManager) throws -> String { + switch context { case .constant(_): + return try localFormula.render(with: manager) + case .dynamic(let variable): - guard try condition.evaluate(with: manager) else { return "" } + + guard try condition.evaluate(with: manager) else { + return "" + } + var rendering = "" + let elements = try manager.value(for: variable) + if isEnumerated { + for (index, element) in elements.enumerated() { + manager.set(index, for: .root(Int.self, rootId: variable.pathId + "-loop-index")) + manager.set(element, for: .root(Values.Element.self, rootId: variable.pathId + "-loop")) + rendering += try localFormula.render(with: manager) } + } else { + for element in elements { + manager.set(element, for: .root(Values.Element.self, rootId: variable.pathId + "-loop")) rendering += try localFormula.render(with: manager) } @@ -259,16 +312,52 @@ extension ForEach: AnyContent { } } -extension TemplateValue where Value: Sequence { +/// ## Description +/// The function is for +/// +/// ## References +/// +public struct Unwrap: Component { + + public let content: IF - func forEach(@ContentBuilder content: (TemplateValue) -> AnyContent) -> AnyContent { - ForEach(in: self, content: content) + public init(_ value: TemplateValue, @ContentBuilder content: (TemplateValue) -> AnyContent) { + + var ifContent: AnyContent = "" + + if value.isMasqueradingOptional { + + ifContent = content(value.unsafeCast(to: A.self)) + + } else { + + switch value { + case .constant(let value): + + if value != nil { + ifContent = content(.constant(value!)) + } + + case .dynamic(let variable): + + ifContent = content(.dynamic(variable.unsafelyUnwrapped)) + } + } + + self.content = IF(value.isDefined) { + ifContent + } } -} -extension Sequence { - - public func htmlForEach(@ContentBuilder content: (TemplateValue) -> AnyContent) -> AnyContent { - ForEach(in: .constant(self), content: content) + public init(content: IF) { + self.content = content + } + + public var body: AnyContent { + content + } + + public func `else`(@ContentBuilder content: () -> AnyContent) -> AnyContent { + self.content.else(content: content) } } diff --git a/Sources/HTMLKit/External/Types.swift b/Sources/HTMLKit/External/Types.swift index 49d06fd3..dfb22e44 100644 --- a/Sources/HTMLKit/External/Types.swift +++ b/Sources/HTMLKit/External/Types.swift @@ -1,17 +1,17 @@ -/// # Description: +/// ## Description /// The file contains html types. /// -/// # Note: +/// # Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// # Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr -/// # Description: +/// ## Description /// The type is for /// -/// # References: +/// ## References /// public struct NameType: RawRepresentable { @@ -32,10 +32,10 @@ extension NameType { static let applicationName = NameType(rawValue: "application-name")! } -/// # Description: +/// ## Description /// The type is for /// -/// # References: +/// ## References /// public enum Buttons: String { @@ -44,10 +44,10 @@ public enum Buttons: String { case reset } -/// # Description: +/// ## Description /// The type is for /// -/// # References: +/// ## References /// public enum Encoding: String { @@ -56,10 +56,10 @@ public enum Encoding: String { case plainText = "text/plain" } -/// # Description: +/// ## Description /// The type is for /// -/// # References: +/// ## References /// public enum Method: String { @@ -67,10 +67,10 @@ public enum Method: String { case get } -/// # Description: +/// ## Description /// The type is for /// -/// # References: +/// ## References /// public enum Inputs: String { @@ -98,10 +98,10 @@ public enum Inputs: String { case phone = "tel" } -/// # Description: +/// ## Description /// The type is for /// -/// # References: +/// ## References /// public enum Language: String { @@ -291,10 +291,10 @@ public enum Language: String { case zulu = "zu" } -/// # Description: +/// ## Description /// The type is for /// -/// # References: +/// ## References /// public enum Policy: String { @@ -308,10 +308,10 @@ public enum Policy: String { case unsafeUrl = "unsafe-url" } -/// # Description: +/// ## Description /// The type is for /// -/// # References: +/// ## References /// public enum Relation: String { @@ -338,10 +338,10 @@ public enum Relation: String { case shortcutIcon = "shortcut icon" } -/// # Description: +/// ## Description /// The type is for /// -/// # References: +/// ## References /// public enum Target: String { @@ -362,10 +362,10 @@ public enum Shape: String { case rectangle = "rect" } -/// # Description: +/// ## Description /// The type is for /// -/// # References: +/// ## References /// public enum Wrapping: String { @@ -373,10 +373,10 @@ public enum Wrapping: String { case hard } -/// # Description: +/// ## Description /// The type is for /// -/// # References: +/// ## References /// public enum Direction: String { @@ -385,10 +385,10 @@ public enum Direction: String { case auto } -/// # Description: +/// ## Description /// The type is for /// -/// # References: +/// ## References /// public struct MediaType: RawRepresentable { @@ -410,10 +410,10 @@ extension MediaType { static let javascript = MediaType(rawValue: "application/javascript")! } -/// # Description: +/// ## Description /// The type is for /// -/// # References: +/// ## References /// public enum Marker: String { @@ -424,10 +424,10 @@ public enum Marker: String { case lowercaseRoman = "i" } -/// # Description: +/// ## Description /// The type is for /// -/// # References: +/// ## References /// public enum DocumentType: String { @@ -441,10 +441,10 @@ public enum DocumentType: String { case xhtml = #"html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd""# } -/// # Description: +/// ## Description /// The type is for /// -/// # References: +/// ## References /// public enum Graphs: String { @@ -457,10 +457,10 @@ public enum Graphs: String { case siteName = "og:site_name" } -/// # Description: +/// ## Description /// The type is for /// -/// # References: +/// ## References /// public enum Hint: String { @@ -473,10 +473,10 @@ public enum Hint: String { case send } -/// # Description: +/// ## Description /// The type is for /// -/// # References: +/// ## References /// public enum Capitalization: String { @@ -485,3 +485,46 @@ public enum Capitalization: String { case words = "words" case sentences = "sentences" } + +/// ## Description +/// The type is for +/// +/// ## References +/// +public struct Charset: RawRepresentable { + + public var rawValue: String + + public init?(rawValue: String) { + self.rawValue = rawValue + } +} + +extension Charset { + + static let utf8 = Charset(rawValue: "UTF-8")! + static let utf16 = Charset(rawValue: "UTF-16")! + static let ansi = Charset(rawValue: "Windows-1252")! + static let iso = Charset(rawValue: "ISO-8859-1")! +} + +/// ## Description +/// The type is for +/// +/// ## References +/// +public struct Equivalent: RawRepresentable { + + public var rawValue: String + + public init?(rawValue: String) { + self.rawValue = rawValue + } +} + +extension Equivalent { + + static let content = Equivalent(rawValue: "content-type")! + static let `default` = Equivalent(rawValue: "default-style")! + static let refresh = Equivalent(rawValue: "refresh")! +} diff --git a/Sources/HTMLKit/Internal/Core/Anys/AnyAttribute.swift b/Sources/HTMLKit/Internal/Core/Anys/AnyAttribute.swift index 7dbf23c9..acfb155a 100644 --- a/Sources/HTMLKit/Internal/Core/Anys/AnyAttribute.swift +++ b/Sources/HTMLKit/Internal/Core/Anys/AnyAttribute.swift @@ -1,19 +1,19 @@ -/// # Description: +/// ## Description /// The file contains the attribute definition. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors: /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr import OrderedCollections -/// # Description: +/// ## Description /// The protocol defines a html attribute. /// -/// # References: +/// ## References /// public protocol AnyAttribute { } diff --git a/Sources/HTMLKit/Internal/Core/Anys/AnyContent.swift b/Sources/HTMLKit/Internal/Core/Anys/AnyContent.swift index 990c3a65..5c986225 100644 --- a/Sources/HTMLKit/Internal/Core/Anys/AnyContent.swift +++ b/Sources/HTMLKit/Internal/Core/Anys/AnyContent.swift @@ -1,29 +1,29 @@ -/// # Description: +/// ## Description /// The file contains the content definition. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr import Foundation -/// # Description: +/// ## Description /// The protocol defines a html content. /// -/// # References: +/// ## References /// public protocol AnyContent { var renderWhenLocalizing: Bool { get } + + var scripts: AnyContent { get } func render(with manager: Renderer.ContextManager) throws -> String func prerender(_ formula: Renderer.Formula) throws - - var scripts: AnyContent { get } } extension AnyContent { diff --git a/Sources/HTMLKit/Internal/Core/Anys/AnyElement.swift b/Sources/HTMLKit/Internal/Core/Anys/AnyElement.swift index da31bc23..76c673f2 100644 --- a/Sources/HTMLKit/Internal/Core/Anys/AnyElement.swift +++ b/Sources/HTMLKit/Internal/Core/Anys/AnyElement.swift @@ -1,17 +1,17 @@ -/// # Description: +/// ## Description /// The file contains the element definition. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr -/// # Description: +/// ## Description /// The protocol defines a html element. /// -/// # References: +/// ## References /// public protocol AnyElement: AnyContent { } diff --git a/Sources/HTMLKit/Internal/Core/Anys/AnyNode.swift b/Sources/HTMLKit/Internal/Core/Anys/AnyNode.swift index 570308d1..e02b29ba 100644 --- a/Sources/HTMLKit/Internal/Core/Anys/AnyNode.swift +++ b/Sources/HTMLKit/Internal/Core/Anys/AnyNode.swift @@ -1,17 +1,17 @@ -/// # Description: +/// ## Description /// The file contains the node definition. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr -/// # Description: +/// ## Description /// The protocol defines a html node. /// -/// # References: +/// ## References /// public protocol AnyNode { } diff --git a/Sources/HTMLKit/Internal/Core/Builders/ContentBuilder.swift b/Sources/HTMLKit/Internal/Core/Builders/ContentBuilder.swift index e9061731..2110d88c 100644 --- a/Sources/HTMLKit/Internal/Core/Builders/ContentBuilder.swift +++ b/Sources/HTMLKit/Internal/Core/Builders/ContentBuilder.swift @@ -1,17 +1,17 @@ -/// # Description: +/// ## Description /// The file contains the basic attribute handlers. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr -/// # Description: -/// The builder builds up a result value from a sequence of the content. +/// ## Description +/// The builder builds up a result value from a sequence of any content. /// -/// # References: +/// ## References /// @resultBuilder public class ContentBuilder { @@ -19,123 +19,11 @@ return [] } - public static func buildBlock(_ elements: T...) -> [T] { - return elements + public static func buildBlock(_ component: T...) -> [T] { + return component } - public static func buildBlock(_ elements: [T]...) -> [T] { - return elements.flatMap( { $0 } ) - } -} - -extension ContentBuilder where T: AnyContent { - - public static func buildBlock(_ content: T...) -> [T] { - return content - } -} - -extension ContentBuilder where T == String { - - public static func buildBlock(_ content: T...) -> [T] { - return content - } -} - -extension ContentBuilder where T: HtmlElement { - - public static func buildBlock(_ content: T...) -> [T] { - return content - } -} - -extension ContentBuilder where T: BodyElement { - - public static func buildBlock(_ content: T...) -> [T] { - return content - } -} - -extension ContentBuilder where T: DescriptionElement { - - public static func buildBlock(_ content: T...) -> [T] { - return content - } -} - -extension ContentBuilder where T: FigureElement { - - public static func buildBlock(_ content: T...) -> [T] { - return content - } -} - -extension ContentBuilder where T: FormElement { - - public static func buildBlock(_ content: T...) -> [T] { - return content - } -} - -extension ContentBuilder where T: BasicElement { - - public static func buildBlock(_ content: T...) -> [T] { - return content - } -} - -extension ContentBuilder where T: HeadElement { - - public static func buildBlock(_ content: T...) -> [T] { - return content - } -} - -extension ContentBuilder where T: InputElement { - - public static func buildBlock(_ content: T...) -> [T] { - return content - } -} - -extension ContentBuilder where T: ListElement { - - public static func buildBlock(_ content: T...) -> [T] { - return content - } -} - -extension ContentBuilder where T: MapElement { - - public static func buildBlock(_ content: T...) -> [T] { - return content - } -} - -extension ContentBuilder where T: MediaElement { - - public static func buildBlock(_ content: T...) -> [T] { - return content - } -} - -extension ContentBuilder where T: ObjectElement { - - public static func buildBlock(_ content: T...) -> [T] { - return content - } -} - -extension ContentBuilder where T: RubyElement { - - public static func buildBlock(_ content: T...) -> [T] { - return content - } -} - -extension ContentBuilder where T: TableElement { - - public static func buildBlock(_ content: T...) -> [T] { - return content + public static func buildBlock(_ component: [T]...) -> [T] { + return component.flatMap( { $0 } ) } } diff --git a/Sources/HTMLKit/Internal/Core/Builders/StringBuilder.swift b/Sources/HTMLKit/Internal/Core/Builders/StringBuilder.swift index 0f82d9d3..73fd6cdc 100644 --- a/Sources/HTMLKit/Internal/Core/Builders/StringBuilder.swift +++ b/Sources/HTMLKit/Internal/Core/Builders/StringBuilder.swift @@ -1,13 +1,18 @@ -/// # Description: +/// ## Description /// The file contains the result builder for string. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr +/// ## Description +/// The builder builds up a result value from a sequence of string. +/// +/// ## References +/// @resultBuilder public class StringBuilder { public static func buildBlock(_ component: String...) -> String { diff --git a/Sources/HTMLKit/Internal/Core/Elements.swift b/Sources/HTMLKit/Internal/Core/Elements.swift index d9d208da..647eeaa6 100644 --- a/Sources/HTMLKit/Internal/Core/Elements.swift +++ b/Sources/HTMLKit/Internal/Core/Elements.swift @@ -1,123 +1,123 @@ -/// # Description: +/// ## Description /// The file contains the element definitions. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr public typealias GlobalElement = BodyElement & DescriptionElement & FigureElement & FormElement & BasicElement & HeadElement & ListElement & MapElement & MediaElement & ObjectElement & RubyElement & TableElement & HtmlElement -/// # Description: +/// ## Description /// The protocol defines a body element. /// -/// # References: +/// ## References /// public protocol BodyElement: AnyElement { } -/// # Description: +/// ## Description /// The protocol defines a description element. /// -/// # References: +/// ## References /// public protocol DescriptionElement: AnyElement { } -/// # Description: +/// ## Description /// The protocol defines a figure element. /// -/// # References: +/// ## References /// public protocol FigureElement: AnyElement { } -/// # Description: +/// ## Description /// The protocol defines a form element. /// -/// # References: +/// ## References /// public protocol FormElement: AnyElement { } -/// # Description: +/// ## Description /// The protocol defines a basic element. /// -/// # References: +/// ## References /// public protocol BasicElement: AnyElement { } -/// # Description: +/// ## Description /// The protocol defines a head element. /// -/// # References: +/// ## References /// public protocol HeadElement: AnyElement { } -/// # Description: +/// ## Description /// The protocol defines a input element. /// -/// # References: +/// ## References /// public protocol InputElement: AnyElement { } -/// # Description: +/// ## Description /// The protocol defines a list element. /// -/// # References: +/// ## References /// public protocol ListElement: AnyElement { } -/// # Description: +/// ## Description /// The protocol defines a map element. /// -/// # References: +/// ## References /// public protocol MapElement: AnyElement { } -/// # Description: +/// ## Description /// The protocol defines a media element. /// -/// # References: +/// ## References /// public protocol MediaElement: AnyElement { } -/// # Description: +/// ## Description /// The protocol defines a object element. /// -/// # References: +/// ## References /// public protocol ObjectElement: AnyElement { } -/// # Description: +/// ## Description /// The protocol defines a ruby element. /// -/// # References: +/// ## References /// public protocol RubyElement: AnyElement { } -/// # Description: +/// ## Description /// The protocol defines a table element. /// -/// # References: +/// ## References /// public protocol TableElement: AnyElement { } -/// # Description: +/// ## Description /// The protocol defines a html element. /// -/// # References: +/// ## References /// public protocol HtmlElement: AnyElement { } diff --git a/Sources/HTMLKit/Internal/Core/Extensions/Datatypes+Content.swift b/Sources/HTMLKit/Internal/Core/Extensions/Datatypes+Content.swift index 80b1239d..1c9770b4 100644 --- a/Sources/HTMLKit/Internal/Core/Extensions/Datatypes+Content.swift +++ b/Sources/HTMLKit/Internal/Core/Extensions/Datatypes+Content.swift @@ -383,3 +383,13 @@ extension UUID: AnyContent { formula.add(string: self.uuidString) } } + +/// The extension is +/// +/// +extension Sequence { + + public func htmlForEach(@ContentBuilder content: (TemplateValue) -> AnyContent) -> AnyContent { + ForEach(in: .constant(self), content: content) + } +} diff --git a/Sources/HTMLKit/Internal/Core/Nodes.swift b/Sources/HTMLKit/Internal/Core/Nodes.swift index 9d9688ba..4a89e8be 100644 --- a/Sources/HTMLKit/Internal/Core/Nodes.swift +++ b/Sources/HTMLKit/Internal/Core/Nodes.swift @@ -1,19 +1,19 @@ -/// # Description: +/// ## Description /// The file contains the node definitions. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr import OrderedCollections -/// # Description: +/// ## Description /// The protocol defines a node with content. /// -/// # References: +/// ## References /// internal protocol ContentNode: AnyNode { @@ -531,10 +531,10 @@ extension ContentNode where Content == String { } } -/// # Description: +/// ## Description /// The protocol defines a node without content. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#void-elements /// internal protocol EmptyNode: AnyNode { @@ -592,10 +592,10 @@ extension EmptyNode where Self: Modifiable { } } -/// # Description: +/// ## Description /// The protocol defines a node for comments. /// -/// # References: +/// ## References /// https://html.spec.whatwg.org/#comments /// internal protocol CommentNode: AnyNode { @@ -618,10 +618,10 @@ extension CommentNode { } } -/// # Description: +/// ## Description /// The protocol defines the document node. /// -/// # References: +/// ## References /// internal protocol DocumentNode: AnyNode { diff --git a/Sources/HTMLKit/Internal/Core/Rendering/Context/Conditions.swift b/Sources/HTMLKit/Internal/Core/Rendering/Context/Conditions.swift index 0821f1cc..ab8624d3 100644 --- a/Sources/HTMLKit/Internal/Core/Rendering/Context/Conditions.swift +++ b/Sources/HTMLKit/Internal/Core/Rendering/Context/Conditions.swift @@ -3,12 +3,13 @@ /// public struct Equal: Conditionable where Value: Equatable { - let path: TemplateValue - - let value: TemplateValue + public let path: TemplateValue + + public let value: TemplateValue public func evaluate(with manager: Renderer.ContextManager) throws -> Bool { - try path.value(from: manager) == value.value(from: manager) + + return try path.value(from: manager) == value.value(from: manager) } } @@ -17,12 +18,13 @@ public struct Equal: Conditionable where Value: Equatable { /// public struct NotEqual: Conditionable where Value: Equatable { - let path: TemplateValue - - let value: Value + public let path: TemplateValue + + public let value: Value public func evaluate(with manager: Renderer.ContextManager) throws -> Bool { - try path.value(from: manager) != value + + return try path.value(from: manager) != value } } @@ -31,12 +33,13 @@ public struct NotEqual: Conditionable where Value: Equatable { /// public struct LessThen: Conditionable where Value: Comparable { - let path: TemplateValue - - let value: Value + public let path: TemplateValue + + public let value: Value public func evaluate(with manager: Renderer.ContextManager) throws -> Bool { - try path.value(from: manager) < value + + return try path.value(from: manager) < value } } @@ -45,12 +48,13 @@ public struct LessThen: Conditionable where Value: Comparable { /// public struct GreaterThen: Conditionable where Value: Comparable { - let path: TemplateValue - - let value: Value + public let path: TemplateValue + + public let value: Value public func evaluate(with manager: Renderer.ContextManager) throws -> Bool { - try path.value(from: manager) > value + + return try path.value(from: manager) > value } } @@ -59,36 +63,38 @@ public struct GreaterThen: Conditionable where Value: Comparable { /// public struct Between: Conditionable where Value: Comparable { - /// The path to the variable - let path: TemplateValue - - /// The value to be compared with - let upperBound: Value - - let lowerBound: Value + public let path: TemplateValue + + public let upperBound: Value + + public let lowerBound: Value public func evaluate(with manager: Renderer.ContextManager) throws -> Bool { - try lowerBound...upperBound ~= path.value(from: manager) + + return try lowerBound...upperBound ~= path.value(from: manager) } } /// A condition that is allways true -/// Used as the `else` condition /// -struct AlwaysTrueCondition: Conditionable { - func evaluate(with manager: Renderer.ContextManager) throws -> Bool { +/// +public struct AlwaysTrueCondition: Conditionable { + + public func evaluate(with manager: Renderer.ContextManager) throws -> Bool { + return true } } /// A condition that is allways true -/// Used as the `else` condition /// -struct InvertCondition: Conditionable { +/// +public struct InvertCondition: Conditionable { - let condition: Conditionable + public let condition: Conditionable - func evaluate(with manager: Renderer.ContextManager) throws -> Bool { + public func evaluate(with manager: Renderer.ContextManager) throws -> Bool { + return try !condition.evaluate(with: manager) } } @@ -96,12 +102,13 @@ struct InvertCondition: Conditionable { /// The struct is for /// /// -struct BoolCondition: Conditionable { +public struct BoolCondition: Conditionable { - let path: TemplateValue + public let path: TemplateValue - func evaluate(with manager: Renderer.ContextManager) throws -> Bool { - try path.value(from: manager) + public func evaluate(with manager: Renderer.ContextManager) throws -> Bool { + + return try path.value(from: manager) } } @@ -110,12 +117,13 @@ struct BoolCondition: Conditionable { /// public struct NullableEqual: Conditionable where Value: Equatable { - let path: TemplateValue - - let value: Value + public let path: TemplateValue + + public let value: Value public func evaluate(with manager: Renderer.ContextManager) throws -> Bool { - try path.value(from: manager) == value + + return try path.value(from: manager) == value } } @@ -124,12 +132,13 @@ public struct NullableEqual: Conditionable where Value: Equatable { /// public struct NullableNotEqual: Conditionable where Value: Equatable { - let path: TemplateValue - - let value: Value + public let path: TemplateValue + + public let value: Value public func evaluate(with manager: Renderer.ContextManager) throws -> Bool { - try path.value(from: manager) != value + + return try path.value(from: manager) != value } } @@ -138,14 +147,18 @@ public struct NullableNotEqual: Conditionable where Value: Equatable { /// public struct NullableLessThen: Conditionable where Value: Comparable { - let path: TemplateValue - - let value: Value + public let path: TemplateValue + + public let value: Value public func evaluate(with manager: Renderer.ContextManager) throws -> Bool { + if let pathValue = try path.value(from: manager) { + return pathValue < value + } else { + return false } } @@ -156,14 +169,18 @@ public struct NullableLessThen: Conditionable where Value: Comparable { /// public struct NullableGreaterThen: Conditionable where Value: Comparable { - let path: TemplateValue - - let value: Value + public let path: TemplateValue + + public let value: Value public func evaluate(with manager: Renderer.ContextManager) throws -> Bool { + if let pathValue = try path.value(from: manager) { + return pathValue > value + } else { + return false } } @@ -174,11 +191,12 @@ public struct NullableGreaterThen: Conditionable where Value: Comparable /// public struct AndCondition: Conditionable { - let first: Conditionable - - let second: Conditionable + public let first: Conditionable + + public let second: Conditionable public func evaluate(with manager: Renderer.ContextManager) throws -> Bool { + return try first.evaluate(with: manager) && second.evaluate(with: manager) } } @@ -188,9 +206,9 @@ public struct AndCondition: Conditionable { /// public struct OrCondition: Conditionable { - let first: Conditionable - - let second: Conditionable + public let first: Conditionable + + public let second: Conditionable public func evaluate(with manager: Renderer.ContextManager) throws -> Bool { return try first.evaluate(with: manager) || second.evaluate(with: manager) @@ -202,7 +220,7 @@ public struct OrCondition: Conditionable { /// public struct NotNullCondition: Conditionable { - let path: TemplateValue + public let path: TemplateValue public func evaluate(with manager: Renderer.ContextManager) throws -> Bool { try path.value(from: manager) != nil @@ -214,7 +232,7 @@ public struct NotNullCondition: Conditionable { /// public struct NotNullConditionGeneral: Conditionable { - let path: TemplateValue + public let path: TemplateValue public func evaluate(with manager: Renderer.ContextManager) throws -> Bool { if let value = try path.value(from: manager) as? Defineable { @@ -230,7 +248,7 @@ public struct NotNullConditionGeneral: Conditionable { /// public struct IsNullConditionGeneral: Conditionable { - let path: TemplateValue + public let path: TemplateValue public func evaluate(with manager: Renderer.ContextManager) throws -> Bool { if let value = try path.value(from: manager) as? Defineable { @@ -246,17 +264,21 @@ public struct IsNullConditionGeneral: Conditionable { /// public struct InCollectionCondition: Conditionable where Value: Equatable { - let valuePath: TemplateValue - let arrayPath: TemplateValue<[Value]> + public let valuePath: TemplateValue + + public let arrayPath: TemplateValue<[Value]> public init(value: TemplateValue, array: TemplateValue<[Value]>) { + self.valuePath = value self.arrayPath = array } public func evaluate(with manager: Renderer.ContextManager) throws -> Bool { + let value = try valuePath.value(from: manager) let array = try arrayPath.value(from: manager) + return array.contains(where: { $0 == value }) } } @@ -266,19 +288,24 @@ public struct InCollectionCondition: Conditionable where Value: Equatable /// public struct InCollectionConditionOptional: Conditionable where Value: Equatable { - let valuePath: TemplateValue - let arrayPath: TemplateValue<[Value]> + public let valuePath: TemplateValue + + public let arrayPath: TemplateValue<[Value]> public init(value: TemplateValue, array: TemplateValue<[Value]>) { + self.valuePath = value self.arrayPath = array } public func evaluate(with manager: Renderer.ContextManager) throws -> Bool { + guard let value = try valuePath.value(from: manager) else { return false } + let array = try arrayPath.value(from: manager) + return array.contains(where: { $0 == value }) } } @@ -288,194 +315,149 @@ public struct InCollectionConditionOptional: Conditionable where Value: E /// public struct IsNullCondition: Conditionable { - let path: TemplateValue + public let path: TemplateValue public func evaluate(with manager: Renderer.ContextManager) throws -> Bool { try path.value(from: manager) == nil } } -extension TemplateValue: Conditionable where Value == Bool { - public func evaluate(with manager: Renderer.ContextManager) throws -> Bool { - switch self { - case .constant(let value): return value - case .dynamic(let variable): return try manager.value(for: variable) - } - } -} - /// Creates a `Equal` condition /// -/// - Parameters: -/// - lhs: The key path -/// - rhs: The constant value -/// - Returns: A `TemplateConditionable` object +/// public func == (lhs: TemplateValue, rhs: Value) -> Conditionable where Value: Equatable { return Equal(path: lhs, value: TemplateValue.constant(rhs)) } /// Creates a `Equal` condition /// -/// - Parameters: -/// - lhs: The key path -/// - rhs: The constant value -/// - Returns: A `TemplateConditionable` object +/// public func == (lhs: TemplateValue, rhs: TemplateValue) -> Conditionable where Value: Equatable { return Equal(path: lhs, value: rhs) } /// Creates a `Equal` condition /// -/// - Parameters: -/// - lhs: The key path -/// - rhs: The constant value -/// - Returns: A `TemplateConditionable` object +/// public func != (lhs: TemplateValue, rhs: Value) -> Conditionable where Value: Equatable { return NotEqual(path: lhs, value: rhs) } /// Creates a `LessThen` condition /// -/// - Parameters: -/// - lhs: The key path -/// - rhs: The constant value -/// - Returns: A `TemplateConditionable` object +/// public func < (lhs: TemplateValue, rhs: Value) -> Conditionable where Value: Comparable { return LessThen(path: lhs, value: rhs) } /// Creates a `GreaterThen` condition /// -/// - Parameters: -/// - lhs: The key path -/// - rhs: The constant value -/// - Returns: A `TemplateConditionable` object +/// public func > (lhs: TemplateValue, rhs: Value) -> Conditionable where Value: Comparable { return GreaterThen(path: lhs, value: rhs) } +/// Creates a `GreaterThen` condition +/// +/// public func ~= (lhs: Range, rhs: TemplateValue) -> Conditionable where Value: Comparable { return Between(path: rhs, upperBound: lhs.upperBound, lowerBound: lhs.lowerBound) } +/// Creates a `GreaterThen` condition +/// +/// public func ~= (lhs: ClosedRange, rhs: TemplateValue) -> Conditionable where Value: Comparable { return Between(path: rhs, upperBound: lhs.upperBound, lowerBound: lhs.lowerBound) } +/// Creates a `GreaterThen` condition +/// +/// public func ~= (lhs: TemplateValue, rhs: Range) -> Conditionable where Value: Comparable { return Between(path: lhs, upperBound: rhs.upperBound, lowerBound: rhs.lowerBound) } +/// Creates a `GreaterThen` condition +/// +/// public func ~= (lhs: TemplateValue, rhs: ClosedRange) -> Conditionable where Value: Comparable { return Between(path: lhs, upperBound: rhs.upperBound, lowerBound: rhs.lowerBound) } /// Creates a `Equal` condition /// -/// - Parameters: -/// - lhs: The key path -/// - rhs: The constant value -/// - Returns: A `TemplateConditionable` object +/// public func == (lhs: TemplateValue, rhs: Value) -> Conditionable where Value: Equatable { return NullableEqual(path: lhs, value: rhs) } /// Creates a `Equal` condition /// -/// - Parameters: -/// - lhs: The key path -/// - rhs: The constant value -/// - Returns: A `TemplateConditionable` object +/// public func != (lhs: TemplateValue, rhs: Value) -> Conditionable where Value: Equatable { return NullableNotEqual(path: lhs, value: rhs) } /// Creates a `LessThen` condition /// -/// - Parameters: -/// - lhs: The key path -/// - rhs: The constant value -/// - Returns: A `TemplateConditionable` object +/// public func < (lhs: TemplateValue, rhs: Value) -> Conditionable where Value: Comparable { return NullableLessThen(path: lhs, value: rhs) } /// Creates a `GreaterThen` condition /// -/// - Parameters: -/// - lhs: The key path -/// - rhs: The constant value -/// - Returns: A `TemplateConditionable` object +/// public func > (lhs: TemplateValue, rhs: Value) -> Conditionable where Value: Comparable { return NullableGreaterThen(path: lhs, value: rhs) } /// Creates a `GreaterThen` condition /// -/// - Parameters: -/// - lhs: The key path -/// - rhs: The constant value -/// - Returns: A `TemplateConditionable` object +/// public func >= (lhs: TemplateValue, rhs: Value) -> Conditionable where Value: Comparable { return InvertCondition(condition: LessThen(path: lhs, value: rhs)) } /// Creates a `GreaterThen` condition /// -/// - Parameters: -/// - lhs: The key path -/// - rhs: The constant value -/// - Returns: A `TemplateConditionable` object +/// public func <= (lhs: TemplateValue, rhs: Value) -> Conditionable where Value: Comparable { return InvertCondition(condition: GreaterThen(path: lhs, value: rhs)) } /// Creates a `GreaterThen` condition /// -/// - Parameters: -/// - lhs: The key path -/// - rhs: The constant value -/// - Returns: A `TemplateConditionable` object +/// public func >= (lhs: TemplateValue, rhs: Value) -> Conditionable where Value: Comparable { return InvertCondition(condition: NullableLessThen(path: lhs, value: rhs)) } /// Creates a `GreaterThen` condition /// -/// - Parameters: -/// - lhs: The key path -/// - rhs: The constant value -/// - Returns: A `TemplateConditionable` object +/// public func <= (lhs: TemplateValue, rhs: Value) -> Conditionable where Value: Comparable { return InvertCondition(condition: NullableGreaterThen(path: lhs, value: rhs)) } /// Creates a `AndCondition` condition /// -/// - Parameters: -/// - lhs: The key path -/// - rhs: The constant value -/// - Returns: A `TemplateConditionable` object +/// public func && (lhs: Conditionable, rhs: Conditionable) -> Conditionable { return AndCondition(first: lhs, second: rhs) } /// Creates a `OrCondition` condition /// -/// - Parameters: -/// - lhs: The key path -/// - rhs: The constant value -/// - Returns: A `TemplateConditionable` object +/// public func || (lhs: Conditionable, rhs: Conditionable) -> Conditionable { return OrCondition(first: lhs, second: rhs) } /// Creates a `InvertCondition` condition /// -/// - Parameters: -/// - lhs: The key path -/// - rhs: The constant value -/// - Returns: A `TemplateConditionable` object +/// public prefix func ! (condition: Conditionable) -> Conditionable { return InvertCondition(condition: condition) } diff --git a/Sources/HTMLKit/Internal/Core/Rendering/Context/ContextVariable.swift b/Sources/HTMLKit/Internal/Core/Rendering/Context/ContextVariable.swift index 4d2783e0..1d963c5f 100644 --- a/Sources/HTMLKit/Internal/Core/Rendering/Context/ContextVariable.swift +++ b/Sources/HTMLKit/Internal/Core/Rendering/Context/ContextVariable.swift @@ -3,14 +3,16 @@ /// @dynamicMemberLookup public class ContextVariable { - let pathId: String - let rootId: String + public let pathId: String + + public let rootId: String + + public let root: KeyPath + + public let escaping: EscapingOption - let root: KeyPath - - let escaping: EscapingOption - - init(value: KeyPath, id: String, rootId: String = "", escaping: EscapingOption = .safeHTML) { + public init(value: KeyPath, id: String, rootId: String = "", escaping: EscapingOption = .safeHTML) { + self.root = value self.pathId = id self.rootId = rootId @@ -18,37 +20,44 @@ } public subscript(dynamicMember keyPath: KeyPath) -> ContextVariable { + let newPath = root.appending(path: keyPath) + return ContextVariable(value: newPath, id: pathId + "-" + String(reflecting: Subject.self), rootId: rootId) } public func escaping(_ option: EscapingOption) -> ContextVariable { - .init(value: root, id: pathId, rootId: rootId, escaping: option) + + return .init(value: root, id: pathId, rootId: rootId, escaping: option) } - func append(_ context: ContextVariable) throws -> ContextVariable { + public func append(_ context: ContextVariable) throws -> ContextVariable { + let path = root.appending(path: context.root) + return .init(value: path, id: pathId + "-" + context.pathId, rootId: rootId, escaping: escaping) } } extension ContextVariable { + public static func root(_ value: T.Type = T.self, rootId: String = "") -> ContextVariable { - ContextVariable(value: \T.self, id: rootId + String(reflecting: T.self), rootId: rootId) + + return ContextVariable(value: \T.self, id: rootId + String(reflecting: T.self), rootId: rootId) } -} - -extension ContextVariable { - - func applyEscaping(_ render: String) -> String { + + public func applyEscaping(_ render: String) -> String { + switch escaping { case .safeHTML: + return render .replacingOccurrences(of: "&", with: "&") .replacingOccurrences(of: "<", with: "<") .replacingOccurrences(of: ">", with: ">") .replacingOccurrences(of: "\"", with: """) .replacingOccurrences(of: "'", with: "'") + case .unsafeNone: return render } diff --git a/Sources/HTMLKit/Internal/Core/Rendering/Context/DateVariable.swift b/Sources/HTMLKit/Internal/Core/Rendering/Context/DateVariable.swift new file mode 100644 index 00000000..c3bbbbe6 --- /dev/null +++ b/Sources/HTMLKit/Internal/Core/Rendering/Context/DateVariable.swift @@ -0,0 +1,80 @@ +import Foundation + +/// A struct that renders a data in a specified format +/// +/// +public struct DateVariable: AnyContent { + + public enum Errors: LocalizedError { + + case unableToCopyFormatter + + public var errorDescription: String? { + return "Unable to copy the DateFormatter when rendering a date with a locale" + } + } + + public enum Reference { + + case solid(TemplateValue) + case optional(TemplateValue) + } + + public enum Format { + + case style(Style) + case literal(String) + + public struct Style { + + let dateStyle: DateFormatter.Style + let timeStyle: DateFormatter.Style + } + } + + public let dateReference: Reference + + public var format: Format + + public func render(with manager: Renderer.ContextManager) throws -> String { + + var optionalDate: Date? + + switch dateReference { + case .solid(let path): + + optionalDate = try path.value(from: manager) + + case .optional(let path): + + optionalDate = try path.value(from: manager) + } + + guard let date = optionalDate else { return "" } + + let formatter = DateFormatter() + + if let locale = manager.locale { + + formatter.locale = .init(identifier: locale) + } + + switch format { + case .literal(let format): + + formatter.dateFormat = format + + case .style(let style): + + formatter.dateStyle = style.dateStyle + formatter.timeStyle = style.timeStyle + } + + return formatter.string(from: date) + } + + public func prerender(_ formula: Renderer.Formula) throws { + + formula.add(mappable: self) + } +} diff --git a/Sources/HTMLKit/Internal/Core/Rendering/Context/EscapingOption.swift b/Sources/HTMLKit/Internal/Core/Rendering/Context/EscapingOption.swift index 5a919bce..3b01b992 100644 --- a/Sources/HTMLKit/Internal/Core/Rendering/Context/EscapingOption.swift +++ b/Sources/HTMLKit/Internal/Core/Rendering/Context/EscapingOption.swift @@ -2,13 +2,18 @@ /// /// public enum EscapingOption: CustomDebugStringConvertible { + case unsafeNone case safeHTML public var debugDescription: String { + switch self { - case .unsafeNone: return "Unsafe" - case .safeHTML: return "Safe" + case .unsafeNone: + return "Unsafe" + + case .safeHTML: + return "Safe" } } } diff --git a/Sources/HTMLKit/Internal/Core/Rendering/Context/HTMLContext.swift b/Sources/HTMLKit/Internal/Core/Rendering/Context/HTMLContext.swift index ac28f06f..7db8008b 100644 --- a/Sources/HTMLKit/Internal/Core/Rendering/Context/HTMLContext.swift +++ b/Sources/HTMLKit/Internal/Core/Rendering/Context/HTMLContext.swift @@ -3,20 +3,24 @@ /// @propertyWrapper @dynamicMemberLookup public class HTMLContext { - enum Errors: Error { + public enum Errors: Error { + case unknownKeyPath } - let pathId: String - let rootId: String - let escaping: EscapingOption - let isMascadingOptional: Bool - - let keyPath: AnyKeyPath + public let pathId: String + + public let rootId: String + + public let escaping: EscapingOption + + public let isMascadingOptional: Bool + + public let keyPath: AnyKeyPath public var wrappedValue: HTMLContext { self } - init(keyPath: KeyPath, id: String, rootId: String = "", escaping: EscapingOption = .safeHTML, isMascadingOptional: Bool = false) { + public init(keyPath: KeyPath, id: String, rootId: String = "", escaping: EscapingOption = .safeHTML, isMascadingOptional: Bool = false) { self.keyPath = keyPath self.pathId = id self.rootId = rootId @@ -24,7 +28,7 @@ self.isMascadingOptional = isMascadingOptional } - init(keyPath: AnyKeyPath, id: String, rootId: String = "", escaping: EscapingOption = .safeHTML, isMascadingOptional: Bool = false) { + public init(keyPath: AnyKeyPath, id: String, rootId: String = "", escaping: EscapingOption = .safeHTML, isMascadingOptional: Bool = false) { self.keyPath = keyPath self.pathId = id self.rootId = rootId @@ -41,43 +45,48 @@ } public func escaping(_ option: EscapingOption) -> HTMLContext { - .init(keyPath: keyPath, id: pathId, rootId: rootId, escaping: option, isMascadingOptional: isMascadingOptional) + + return .init(keyPath: keyPath, id: pathId, rootId: rootId, escaping: option, isMascadingOptional: isMascadingOptional) } public subscript(dynamicMember keyPath: KeyPath) -> HTMLContext { + guard let newPath = self.keyPath.appending(path: keyPath) else { fatalError() } + return HTMLContext(keyPath: newPath, id: pathId + "-" + String(reflecting: Subject.self), rootId: rootId, isMascadingOptional: isMascadingOptional) } public static func root(_ type: Value.Type, rootId: String) -> HTMLContext { - .init(keyPath: \Value.self, id: "", rootId: rootId) + return .init(keyPath: \Value.self, id: "", rootId: rootId) } public func makeOptional() -> HTMLContext { - .init(keyPath: keyPath, id: pathId, rootId: rootId, escaping: escaping, isMascadingOptional: true) + return .init(keyPath: keyPath, id: pathId, rootId: rootId, escaping: escaping, isMascadingOptional: true) } public func unsafeCast(to type: T.Type) -> HTMLContext { - .init(keyPath: keyPath, id: pathId, rootId: rootId, escaping: escaping) + return .init(keyPath: keyPath, id: pathId, rootId: rootId, escaping: escaping) } } extension HTMLContext: AnyContent where Value: AnyContent { public func render(with manager: Renderer.ContextManager) throws -> String { - applyEscaping( - try manager.value(for: self) - .render(with: manager) + + return applyEscaping( + try manager.value(for: self).render(with: manager) ) } public func prerender(_ formula: Renderer.Formula) throws { + formula.add(mappable: self) } func applyEscaping(_ render: String) -> String { + switch escaping { case .safeHTML: return render @@ -91,6 +100,7 @@ extension HTMLContext: AnyContent where Value: AnyContent { default: string += String(char) } } + case .unsafeNone: return render } @@ -100,6 +110,7 @@ extension HTMLContext: AnyContent where Value: AnyContent { extension HTMLContext: Conditionable where Value == Bool { public func evaluate(with manager: Renderer.ContextManager) throws -> Bool { + try manager.value(for: self) } } diff --git a/Sources/HTMLKit/Internal/Core/Rendering/Context/TemplateValue.swift b/Sources/HTMLKit/Internal/Core/Rendering/Context/TemplateValue.swift index e94d8857..59471cd5 100644 --- a/Sources/HTMLKit/Internal/Core/Rendering/Context/TemplateValue.swift +++ b/Sources/HTMLKit/Internal/Core/Rendering/Context/TemplateValue.swift @@ -19,8 +19,11 @@ import Foundation get { switch self { case .constant(let value): + return "\(value)" + default: + return "" } } @@ -29,8 +32,11 @@ import Foundation public var isDefined: Conditionable { if isMasqueradingOptional { + return true + } else { + return NotNullConditionGeneral(path: self) } } @@ -38,8 +44,11 @@ import Foundation public var isNotDefined: Conditionable { if isMasqueradingOptional { + return false + } else { + return IsNullConditionGeneral(path: self) } } @@ -47,16 +56,26 @@ import Foundation var isMasqueradingOptional: Bool { switch self { - case .constant: return false - case .dynamic(let variable): return variable.isMascadingOptional + case .constant: + + return false + + case .dynamic(let variable): + + return variable.isMascadingOptional } } public subscript(dynamicMember keyPath: KeyPath) -> TemplateValue { switch self { - case .constant(let value): return .constant(value[keyPath: keyPath]) - case .dynamic(let variable): return .dynamic(variable[dynamicMember: keyPath]) + case .constant(let value): + + return .constant(value[keyPath: keyPath]) + + case .dynamic(let variable): + + return .dynamic(variable[dynamicMember: keyPath]) } } @@ -68,8 +87,12 @@ import Foundation public func escaping(_ option: EscapingOption) -> TemplateValue { switch self { - case .dynamic(let variable): return .dynamic(variable.escaping(option)) - default: return self + case .dynamic(let variable): + + return .dynamic(variable.escaping(option)) + + default: + return self } } @@ -81,24 +104,39 @@ import Foundation public func value(from manager: Renderer.ContextManager) throws -> Value { switch self { - case .constant(let value): return value - case .dynamic(let variable): return try manager.value(for: variable) + case .constant(let value): + + return value + + case .dynamic(let variable): + + return try manager.value(for: variable) } } public func makeOptional() -> TemplateValue { switch self { - case .constant(let value): return .constant(value) - case .dynamic(let variable): return .dynamic(variable.makeOptional()) + case .constant(let value): + + return .constant(value) + + case .dynamic(let variable): + + return .dynamic(variable.makeOptional()) } } public func unsafeCast(to type: T.Type) -> TemplateValue { switch self { - case .constant(let value): return .constant(value as! T) - case .dynamic(let variable): return .dynamic(variable.unsafeCast(to: T.self)) + case .constant(let value): + + return .constant(value as! T) + + case .dynamic(let variable): + + return .dynamic(variable.unsafeCast(to: T.self)) } } @@ -113,16 +151,25 @@ extension TemplateValue: AnyContent where Value: AnyContent { public func prerender(_ formula: Renderer.Formula) throws { switch self { - case .constant(let value): try value.prerender(formula) - case .dynamic(let variable): try variable.prerender(formula) + case .constant(let value): + + try value.prerender(formula) + + case .dynamic(let variable): + try variable.prerender(formula) } } public func render(with manager: Renderer.ContextManager) throws -> String { switch self { - case .constant(let value): return try value.render(with: manager) - case .dynamic(let variable): return try variable.render(with: manager) + case .constant(let value): + + return try value.render(with: manager) + + case .dynamic(let variable): + + return try variable.render(with: manager) } } } @@ -148,3 +195,46 @@ extension TemplateValue: ExpressibleByIntegerLiteral where Value == Int { self = .constant(value) } } + +extension TemplateValue where Value: Sequence { + + func forEach(@ContentBuilder content: (TemplateValue) -> AnyContent) -> AnyContent { + ForEach(in: self, content: content) + } +} + +extension TemplateValue: Conditionable where Value == Bool { + + public func evaluate(with manager: Renderer.ContextManager) throws -> Bool { + + switch self { + case .constant(let value): + return value + + case .dynamic(let variable): + return try manager.value(for: variable) + } + } +} + +extension TemplateValue where Value == Date { + + public func style(date: DateFormatter.Style = .short, time: DateFormatter.Style = .short) -> AnyContent { + return DateVariable(dateReference: .solid(self), format: .style(.init(dateStyle: date, timeStyle: time))) + } + + public func formatted(string format: String) -> AnyContent { + return DateVariable(dateReference: .solid(self), format: .literal(format)) + } +} + +extension TemplateValue where Value == Date? { + + public func style(date: DateFormatter.Style = .short, time: DateFormatter.Style = .short) -> AnyContent { + return DateVariable(dateReference: .optional(self), format: .style(.init(dateStyle: date, timeStyle: time))) + } + + public func formatted(string format: String) -> AnyContent { + return DateVariable(dateReference: .optional(self), format: .literal(format)) + } +} diff --git a/Sources/HTMLKit/Internal/Core/Rendering/Context/TemplateValueMapping.swift b/Sources/HTMLKit/Internal/Core/Rendering/Context/TemplateValueMapping.swift index 7b0defd4..df649c3f 100644 --- a/Sources/HTMLKit/Internal/Core/Rendering/Context/TemplateValueMapping.swift +++ b/Sources/HTMLKit/Internal/Core/Rendering/Context/TemplateValueMapping.swift @@ -2,10 +2,13 @@ /// /// public class TemplateValueMapping { - let variable: TemplateValue - let transform: (B) throws -> C + + public let variable: TemplateValue + + public let transform: (B) throws -> C - init(variable: TemplateValue, transform: @escaping (B) throws -> C) { + public init(variable: TemplateValue, transform: @escaping (B) throws -> C) { + self.variable = variable self.transform = transform } @@ -14,14 +17,22 @@ public class TemplateValueMapping { extension TemplateValueMapping: AnyContent where C: AnyContent { public func prerender(_ formula: Renderer.Formula) throws { + switch variable { - case .constant(let value): try transform(value).prerender(formula) - case .dynamic(_): formula.add(mappable: self) + case .constant(let value): + + try transform(value).prerender(formula) + + case .dynamic(_): + + formula.add(mappable: self) } } public func render(with manager: Renderer.ContextManager) throws -> String { + let value = try variable.value(from: manager) + return try transform(value).render(with: manager) } } diff --git a/Sources/HTMLKit/Internal/Core/Rendering/ContextManager.swift b/Sources/HTMLKit/Internal/Core/Rendering/ContextManager.swift index 0859679d..9505f85b 100644 --- a/Sources/HTMLKit/Internal/Core/Rendering/ContextManager.swift +++ b/Sources/HTMLKit/Internal/Core/Rendering/ContextManager.swift @@ -2,48 +2,44 @@ import Lingo extension Renderer { - /// Manage the different contexts - /// This will remove the generic type in the render call public class ContextManager { - /// The different context variables used when rendering - var contexts: [String: Any] - - /// The lingo object that is needed to use localization - let lingo: Lingo? - - /// The path to the selected locale to use in localization + public let lingo: Lingo? public var locale: String? + public var contexts: [String: Any] - init(rootContext: Context, lingo: Lingo? = nil) { + public init(rootContext: Context, lingo: Lingo? = nil) { + self.contexts = ["" : rootContext] self.lingo = lingo self.locale = nil } - init(contexts: [String: Any], lingo: Lingo? = nil) { + public init(contexts: [String: Any], lingo: Lingo? = nil) { + self.contexts = contexts self.lingo = lingo self.locale = nil } - /// The value for a `ContextVariable` - /// - /// - Returns: The value at the `ContextVariable` - func value(for variable: HTMLContext) throws -> Value { + public func value(for variable: HTMLContext) throws -> Value { + if let variableContext = contexts[variable.rootId] { + if let value = variableContext[keyPath: variable.keyPath] as? Value { return value + } else { throw Errors.unableToCastVariable } + } else { throw Errors.unableToRetriveValue } } - func set(_ context: Value, for variable: ContextVariable) { - contexts[variable.rootId] = context + public func set(_ context: Value, for variable: ContextVariable) { + self.contexts[variable.rootId] = context } } } diff --git a/Sources/HTMLKit/Internal/Core/Rendering/EnvironmentModifier.swift b/Sources/HTMLKit/Internal/Core/Rendering/EnvironmentModifier.swift index 9875ab8f..04f21b75 100644 --- a/Sources/HTMLKit/Internal/Core/Rendering/EnvironmentModifier.swift +++ b/Sources/HTMLKit/Internal/Core/Rendering/EnvironmentModifier.swift @@ -3,21 +3,30 @@ /// public struct EnvironmentModifier: AnyContent { - let view: AnyContent - let locale: AnyContent - - let localFormula = Renderer.Formula() + public let view: AnyContent + + public let locale: AnyContent + + public let localFormula = Renderer.Formula() public func prerender(_ formula: Renderer.Formula) throws { + try view.prerender(localFormula) + formula.add(mappable: self) } public func render(with manager: Renderer.ContextManager) throws -> String { + let prevLocale = manager.locale + manager.locale = try locale.render(with: manager) + let rendering = try localFormula.render(with: manager) + manager.locale = prevLocale + return rendering + } } diff --git a/Sources/HTMLKit/Internal/Core/Rendering/Formula.swift b/Sources/HTMLKit/Internal/Core/Rendering/Formula.swift index 77d1c650..68285114 100644 --- a/Sources/HTMLKit/Internal/Core/Rendering/Formula.swift +++ b/Sources/HTMLKit/Internal/Core/Rendering/Formula.swift @@ -3,73 +3,58 @@ import Lingo extension Renderer { - /// A formula for a view - /// This contains the different parts to pice to gether, in order to increase the performance public class Formula { - /// The different pices or ingredients needed to render the view - var ingredient: [AnyContent] + public var ingredient: [AnyContent] - /// The calendar to use when rendering dates - var calendar: Calendar + public var calendar: Calendar - /// The time zone to use when rendering dates - var timeZone: TimeZone + public var timeZone: TimeZone - /// Init's a view - /// - /// - Parameters: - /// - view: The view type - /// - contextPaths: The contextPaths. *Is empty by default* - init(calendar: Calendar = .current, timeZone: TimeZone = .current) { - ingredient = [] + public init(calendar: Calendar = .current, timeZone: TimeZone = .current) { + + self.ingredient = [] self.calendar = calendar self.timeZone = timeZone } - /// Adds a static string to the formula - /// - /// - Parameter string: The string to add public func add(string: String) { + if let last = ingredient.last as? String { + _ = ingredient.removeLast() - ingredient.append(last + string) + + self.ingredient.append(last + string) + } else { - ingredient.append(string) + self.ingredient.append(string) } } - /// Adds a generic `Mappable` object - /// - /// - Parameter mappable: The `Mappable` to add public func add(mappable: AnyContent) { + if let stringRepresentation = mappable as? String { + add(string: stringRepresentation) + } else { - ingredient.append(mappable) + + self.ingredient.append(mappable) } } - /// Renders a formula - /// - /// - Parameters: - /// - context: The context needed to render the formula - /// - lingo: The lingo to use when rendering - /// - Returns: A rendered formula - /// - Throws: If some of the formula fails, for some reason - func render(with context: T, lingo: Lingo?) throws -> String { + public func render(with context: T, lingo: Lingo?) throws -> String { + let contextManager = ContextManager(rootContext: context, lingo: lingo) + return try render(with: contextManager) } - /// Render a formula with a existing `ContextManager` - /// This may be needed when using a local formula - /// - /// - Parameter manager: The manager to use when rendering - /// - Returns: A rendered formula - /// - Throws: If some of the formula fails, for some reason - func render(with manager: ContextManager) throws -> String { - return try ingredient.reduce(into: "") { $0 += try $1.render(with: manager) } + public func render(with manager: ContextManager) throws -> String { + + return try ingredient.reduce(into: "") { + $0 += try $1.render(with: manager) + } } } } diff --git a/Sources/HTMLKit/Internal/Core/Rendering/Renderer.swift b/Sources/HTMLKit/Internal/Core/Rendering/Renderer.swift index 0a74c536..f6539557 100644 --- a/Sources/HTMLKit/Internal/Core/Rendering/Renderer.swift +++ b/Sources/HTMLKit/Internal/Core/Rendering/Renderer.swift @@ -3,14 +3,13 @@ import Lingo /// A struct containing the different formulas for the different views. /// -/// try renderer.add(template: WelcomeView()) // Builds the formula -/// try renderer.render(WelcomeView.self) // Renders the formula +/// public class Renderer { - static let empty = ContextManager(rootContext: ()) + public static let empty = ContextManager(rootContext: ()) - /// The different Errors that can happen when rendering or pre-rendering a template public enum Errors: LocalizedError { + case unableToFindFormula case unableToRetriveValue case unableToRegisterKeyPath @@ -18,88 +17,86 @@ public class Renderer { case unableToCastVariable public var errorDescription: String? { + switch self { - case .unableToFindFormula: return "Unable to find a formula for the given view type" - case .unableToRetriveValue: return "Unable to retrive the wanted value in the context" - case .unableToRegisterKeyPath: return "Unable to register a KeyPath when creating the template formula" - case .unableToAddVariable: return "Unable to add variable to formula" - case .unableToCastVariable: return "Unable to cast value when retriving variable" + case .unableToFindFormula: + return "Unable to find a formula for the given view type" + + case .unableToRetriveValue: + return "Unable to retrive the wanted value in the context" + + case .unableToRegisterKeyPath: + return "Unable to register a KeyPath when creating the template formula" + + case .unableToAddVariable: + return "Unable to add variable to formula" + + case .unableToCastVariable: + return "Unable to cast value when retriving variable" } } public var recoverySuggestion: String? { + switch self { case .unableToFindFormula: return "Remember to add the template to the renderer with .add(template: ) or .add(view: )" - default: return nil + + default: + return nil } } } - /// A cache that contains all the brewed `Template`'s - var formulaCache: [ObjectIdentifier: Formula] - - /// The localization to use when rendering - var lingo: Lingo? + public var formulaCache: [ObjectIdentifier: Formula] - /// The calendar to use when rendering dates + public var lingo: Lingo? + public var calendar: Calendar = Calendar(identifier: .gregorian) - - /// The time zone to use when rendering dates + public var timeZone: TimeZone = TimeZone(secondsFromGMT: 0) ?? TimeZone.current public init() { - formulaCache = [:] + self.formulaCache = [:] } public func render(raw type: T.Type) throws -> String { + guard let formula = formulaCache[ObjectIdentifier(type)] else { throw Errors.unableToFindFormula } + return try formula.render(with: (), lingo: lingo) } public func render(raw type: T.Type, with context: T.Context) throws -> String { + guard let formula = formulaCache[ObjectIdentifier(type)] else { throw Errors.unableToFindFormula } + return try formula.render(with: context, lingo: lingo) } - /// Adds a forumla to the renderer - /// - /// try renderer.add(view: WelcomeView()) - /// - /// - Parameter view: The view type to add - /// - Throws: If the pre-rendering process fails for some reason public func add(view: T) throws { + let formula = Formula() + try view.prerender(formula) - formulaCache[ObjectIdentifier(T.self)] = formula + + self.formulaCache[ObjectIdentifier(T.self)] = formula } - /// Adds a forumla to the renderer - /// - /// try renderer.add(view: WelcomeView()) - /// - /// - Parameter view: The view type to add - /// - Throws: If the pre-rendering process fails for some reason public func add(view: T) throws { + let formula = Formula() + try view.prerender(formula) - formulaCache[ObjectIdentifier(T.self)] = formula + + self.formulaCache[ObjectIdentifier(T.self)] = formula } - /// Registers a localization directory to the renderer - /// - /// try renderer.registerLocalization() // Using default values - /// try renderer.registerLocalization(atPath: "Localization", defaultLocale: "nb") - /// - /// - Parameters: - /// - path: A relative path to the localization folder. This is by *default* set to "Resource/Localization" - /// - defaultLocale: The default locale to use. This is by *default* set to "en" - /// - Throws: If there is an error registrating the lingo public func registerLocalization(atPath path: String = "Resources/Localization", defaultLocale: String = "en") throws { - lingo = try Lingo(rootPath: path, defaultLocale: defaultLocale) + self.lingo = try Lingo(rootPath: path, defaultLocale: defaultLocale) } } diff --git a/Sources/HTMLKit/Internal/Core/Variables/DateVariable.swift b/Sources/HTMLKit/Internal/Core/Variables/DateVariable.swift deleted file mode 100644 index 992b1e03..00000000 --- a/Sources/HTMLKit/Internal/Core/Variables/DateVariable.swift +++ /dev/null @@ -1,111 +0,0 @@ -import Foundation - -/// A struct that renders a data in a specified format -/// -/// -struct DateVariable: AnyContent { - - enum Errors: LocalizedError { - case unableToCopyFormatter - - var errorDescription: String? { - return "Unable to copy the DateFormatter when rendering a date with a locale" - } - } - - enum Reference { - case solid(TemplateValue) - case optional(TemplateValue) - } - - enum Format { - case style(Style) - case literal(String) - - struct Style { - let dateStyle: DateFormatter.Style - let timeStyle: DateFormatter.Style - } - } - - let dateReference: Reference - - var format: Format - - func render(with manager: Renderer.ContextManager) throws -> String { - - var optionalDate: Date? - switch dateReference { - case .solid(let path): optionalDate = try path.value(from: manager) - case .optional(let path): optionalDate = try path.value(from: manager) - } - - guard let date = optionalDate else { return "" } - - let formatter = DateFormatter() - - if let locale = manager.locale { - formatter.locale = .init(identifier: locale) - } - switch format { - case .literal(let format): - formatter.dateFormat = format - case .style(let style): - formatter.dateStyle = style.dateStyle - formatter.timeStyle = style.timeStyle - } - return formatter.string(from: date) - } - - func prerender(_ formula: Renderer.Formula) throws { - formula.add(mappable: self) - } -} - -extension TemplateValue where Value == Date { - - /// Render a date in a formate - /// - /// - Parameters: - /// - datePath: The path to the date - /// - dateStyle: The style to use to render the date - /// - timeStyle: The style to use to render the time - /// - Returns: A `CompiledTemplate` - public func style(date: DateFormatter.Style = .short, time: DateFormatter.Style = .short) -> AnyContent { - return DateVariable(dateReference: .solid(self), format: .style(.init(dateStyle: date, timeStyle: time))) - } - - /// Render a date in a formate - /// - /// - Parameters: - /// - datePath: The path to the date - /// - format: The formate to render the date with - /// - Returns: A `CompiledTemplate` - public func formatted(string format: String) -> AnyContent { - return DateVariable(dateReference: .solid(self), format: .literal(format)) - } -} - -extension TemplateValue where Value == Date? { - - /// Render a date in a formate - /// - /// - Parameters: - /// - datePath: The path to the date - /// - dateStyle: The style to use to render the date - /// - timeStyle: The style to use to render the time - /// - Returns: A `CompiledTemplate` - public func style(date: DateFormatter.Style = .short, time: DateFormatter.Style = .short) -> AnyContent { - return DateVariable(dateReference: .optional(self), format: .style(.init(dateStyle: date, timeStyle: time))) - } - - /// Render a date in a formate - /// - /// - Parameters: - /// - datePath: The path to the date - /// - format: The formate to render the date with - /// - Returns: A `CompiledTemplate` - public func formatted(string format: String) -> AnyContent { - return DateVariable(dateReference: .optional(self), format: .literal(format)) - } -} diff --git a/Sources/HTMLKit/Internal/Core/Variables/StringValue.swift b/Sources/HTMLKit/Internal/Core/Variables/StringValue.swift deleted file mode 100644 index fa030394..00000000 --- a/Sources/HTMLKit/Internal/Core/Variables/StringValue.swift +++ /dev/null @@ -1,9 +0,0 @@ -/// The struct is for -/// -/// -@dynamicMemberLookup struct StringValue { - - public subscript(dynamicMember string: Type) -> StringValue { - return .init() - } -} diff --git a/Sources/HTMLKit/Internal/Features/Conversion/Converter.swift b/Sources/HTMLKit/Internal/Features/Conversion/Converter.swift index a724eb7d..1b171735 100644 --- a/Sources/HTMLKit/Internal/Features/Conversion/Converter.swift +++ b/Sources/HTMLKit/Internal/Features/Conversion/Converter.swift @@ -1,10 +1,10 @@ -/// # Description: +/// ## Description /// The file contains the converter. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr @@ -304,16 +304,16 @@ public class Converter { } } - @StringBuilder internal func decode(element: XMLNode, preindent: Int? = nil) -> String { + @StringBuilder internal func decode(element: XMLNode, indent: Int? = nil) -> String { switch element.kind { case .text: - TextElement(node: element).build(preindent: preindent) + TextElement(node: element).build(preindent: indent) case .comment: - CommentElement(node: element).build(preindent: preindent) + CommentElement(node: element).build(preindent: indent) default: @@ -321,213 +321,213 @@ public class Converter { switch element.localName { case "html": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "head": - ContentElement(element: element).build(verbatim: "Head", preindent: preindent) + ContentElement(element: element).build(verbatim: "Head", preindent: indent) case "body": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "nav": - ContentElement(element: element).build(verbatim: "Navigation", preindent: preindent) + ContentElement(element: element).build(verbatim: "Navigation", preindent: indent) case "link": - EmptyElement(element: element).build(preindent: preindent) + EmptyElement(element: element).build(preindent: indent) case "aside": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "section": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "h1": - ContentElement(element: element).build(verbatim: "Heading1", preindent: preindent) + ContentElement(element: element).build(verbatim: "Heading1", preindent: indent) case "h2": - ContentElement(element: element).build(verbatim: "Heading2", preindent: preindent) + ContentElement(element: element).build(verbatim: "Heading2", preindent: indent) case "h3": - ContentElement(element: element).build(verbatim: "Heading3", preindent: preindent) + ContentElement(element: element).build(verbatim: "Heading3", preindent: indent) case "h4": - ContentElement(element: element).build(verbatim: "Heading4", preindent: preindent) + ContentElement(element: element).build(verbatim: "Heading4", preindent: indent) case "h5": - ContentElement(element: element).build(verbatim: "Heading5", preindent: preindent) + ContentElement(element: element).build(verbatim: "Heading5", preindent: indent) case "h6": - ContentElement(element: element).build(verbatim: "Heading6", preindent: preindent) + ContentElement(element: element).build(verbatim: "Heading6", preindent: indent) case "hgroup": - ContentElement(element: element).build(verbatim: "HeadingGroup", preindent: preindent) + ContentElement(element: element).build(verbatim: "HeadingGroup", preindent: indent) case "header": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "footer": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "address": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "p": - ContentElement(element: element).build(verbatim: "Paragraph", preindent: preindent) + ContentElement(element: element).build(verbatim: "Paragraph", preindent: indent) case "hr": - EmptyElement(element: element).build(verbatim: "HorizontalRule", preindent: preindent) + EmptyElement(element: element).build(verbatim: "HorizontalRule", preindent: indent) case "pre": - ContentElement(element: element).build(verbatim: "PreformattedText", preindent: preindent) + ContentElement(element: element).build(verbatim: "PreformattedText", preindent: indent) case "blockquote": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "ol": - ContentElement(element: element).build(verbatim: "OrderedList", preindent: preindent) + ContentElement(element: element).build(verbatim: "OrderedList", preindent: indent) case "ul": - ContentElement(element: element).build(verbatim: "UnorderedList", preindent: preindent) + ContentElement(element: element).build(verbatim: "UnorderedList", preindent: indent) case "dl": - ContentElement(element: element).build(verbatim: "DescriptionList", preindent: preindent) + ContentElement(element: element).build(verbatim: "DescriptionList", preindent: indent) case "figure": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "a": - ContentElement(element: element).build(verbatim: "Anchor", preindent: preindent) + ContentElement(element: element).build(verbatim: "Anchor", preindent: indent) case "em": - ContentElement(element: element).build(verbatim: "Emphasize", preindent: preindent) + ContentElement(element: element).build(verbatim: "Emphasize", preindent: indent) case "small": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "s": - ContentElement(element: element).build(verbatim: "StrikeThrough", preindent: preindent) + ContentElement(element: element).build(verbatim: "StrikeThrough", preindent: indent) case "main": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "div": - ContentElement(element: element).build(verbatim: "Division", preindent: preindent) + ContentElement(element: element).build(verbatim: "Division", preindent: indent) case "dfn": - ContentElement(element: element).build(verbatim: "Definition", preindent: preindent) + ContentElement(element: element).build(verbatim: "Definition", preindent: indent) case "cite": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "q": - ContentElement(element: element).build(verbatim: "ShortQuote", preindent: preindent) + ContentElement(element: element).build(verbatim: "ShortQuote", preindent: indent) case "rt": - ContentElement(element: element).build(verbatim: "RubyText", preindent: preindent) + ContentElement(element: element).build(verbatim: "RubyText", preindent: indent) case "rp": - ContentElement(element: element).build(verbatim: "RubyPronunciation", preindent: preindent) + ContentElement(element: element).build(verbatim: "RubyPronunciation", preindent: indent) case "abbr": - ContentElement(element: element).build(verbatim: "Abbreviation", preindent: preindent) + ContentElement(element: element).build(verbatim: "Abbreviation", preindent: indent) case "data": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "time": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "code": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "v": - ContentElement(element: element).build(verbatim: "Variable", preindent: preindent) + ContentElement(element: element).build(verbatim: "Variable", preindent: indent) case "samp": - ContentElement(element: element).build(verbatim: "SampleOutput", preindent: preindent) + ContentElement(element: element).build(verbatim: "SampleOutput", preindent: indent) case "kbd": - ContentElement(element: element).build(verbatim: "KeyboardOutput", preindent: preindent) + ContentElement(element: element).build(verbatim: "KeyboardOutput", preindent: indent) case "sub": - ContentElement(element: element).build(verbatim: "Subscript", preindent: preindent) + ContentElement(element: element).build(verbatim: "Subscript", preindent: indent) case "sup": - ContentElement(element: element).build(verbatim: "Superscript", preindent: preindent) + ContentElement(element: element).build(verbatim: "Superscript", preindent: indent) case "i": - ContentElement(element: element).build(verbatim: "Italic", preindent: preindent) + ContentElement(element: element).build(verbatim: "Italic", preindent: indent) case "b": - ContentElement(element: element).build(verbatim: "Bold", preindent: preindent) + ContentElement(element: element).build(verbatim: "Bold", preindent: indent) case "u": - ContentElement(element: element).build(verbatim: "SampleOutput", preindent: preindent) + ContentElement(element: element).build(verbatim: "SampleOutput", preindent: indent) case "mark": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "bdi": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "bdo": - EmptyElement(element: element).build(preindent: preindent) + EmptyElement(element: element).build(preindent: indent) case "span": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "br": - EmptyElement(element: element).build(verbatim: "LineBreak", preindent: preindent) + EmptyElement(element: element).build(verbatim: "LineBreak", preindent: indent) case "wbr": - EmptyElement(element: element).build(verbatim: "WordBreak", preindent: preindent) + EmptyElement(element: element).build(verbatim: "WordBreak", preindent: indent) case "ins": - ContentElement(element: element).build(verbatim: "InsertedText", preindent: preindent) + ContentElement(element: element).build(verbatim: "InsertedText", preindent: indent) case "del": - ContentElement(element: element).build(verbatim: "DeletedText", preindent: preindent) + ContentElement(element: element).build(verbatim: "DeletedText", preindent: indent) case "img": - ContentElement(element: element).build(verbatim: "Image", preindent: preindent) + ContentElement(element: element).build(verbatim: "Image", preindent: indent) case "embed": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "iframe": - ContentElement(element: element).build(verbatim: "InlineFrame", preindent: preindent) + ContentElement(element: element).build(verbatim: "InlineFrame", preindent: indent) case "param": - EmptyElement(element: element).build(verbatim: "Parameter", preindent: preindent) + EmptyElement(element: element).build(verbatim: "Parameter", preindent: indent) case "dt": - ContentElement(element: element).build(verbatim: "TermName", preindent: preindent) + ContentElement(element: element).build(verbatim: "TermName", preindent: indent) case "dd": - ContentElement(element: element).build(verbatim: "TermDefinition", preindent: preindent) + ContentElement(element: element).build(verbatim: "TermDefinition", preindent: indent) case "figcaption": - ContentElement(element: element).build(verbatim: "FigureCaption", preindent: preindent) + ContentElement(element: element).build(verbatim: "FigureCaption", preindent: indent) case "optgroup": - ContentElement(element: element).build(verbatim: "OptionGroup", preindent: preindent) + ContentElement(element: element).build(verbatim: "OptionGroup", preindent: indent) case "option": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "legend": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "summary": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "li": - ContentElement(element: element).build(verbatim: "ListItem", preindent: preindent) + ContentElement(element: element).build(verbatim: "ListItem", preindent: indent) case "colgroup": - ContentElement(element: element).build(verbatim: "ColumnGroup", preindent: preindent) + ContentElement(element: element).build(verbatim: "ColumnGroup", preindent: indent) case "col": - ContentElement(element: element).build(verbatim: "Column", preindent: preindent) + ContentElement(element: element).build(verbatim: "Column", preindent: indent) case "tbody": - ContentElement(element: element).build(verbatim: "TableBody", preindent: preindent) + ContentElement(element: element).build(verbatim: "TableBody", preindent: indent) case "thead": - ContentElement(element: element).build(verbatim: "TableHead", preindent: preindent) + ContentElement(element: element).build(verbatim: "TableHead", preindent: indent) case "tfoot": - ContentElement(element: element).build(verbatim: "TableFoot", preindent: preindent) + ContentElement(element: element).build(verbatim: "TableFoot", preindent: indent) case "tr": - ContentElement(element: element).build(verbatim: "TableRow", preindent: preindent) + ContentElement(element: element).build(verbatim: "TableRow", preindent: indent) case "td": - ContentElement(element: element).build(verbatim: "DataCell", preindent: preindent) + ContentElement(element: element).build(verbatim: "DataCell", preindent: indent) case "th": - ContentElement(element: element).build(verbatim: "HeaderCell", preindent: preindent) + ContentElement(element: element).build(verbatim: "HeaderCell", preindent: indent) case "textarea": - ContentElement(element: element).build(verbatim: "TextArea", preindent: preindent) + ContentElement(element: element).build(verbatim: "TextArea", preindent: indent) case "input": - EmptyElement(element: element).build(preindent: preindent) + EmptyElement(element: element).build(preindent: indent) case "video": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "audio": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "map": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "area": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "form": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "datalist": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "output": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "meter": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "details": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "dialog": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "script": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "noscript": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "template": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "canvas": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "table": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "fieldset": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "button": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "select": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "label": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "title": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "base": - EmptyElement(element: element).build(preindent: preindent) + EmptyElement(element: element).build(preindent: indent) case "meta": - EmptyElement(element: element).build(preindent: preindent) + EmptyElement(element: element).build(preindent: indent) case "style": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) case "source": - EmptyElement(element: element).build(preindent: preindent) + EmptyElement(element: element).build(preindent: indent) case "track": - EmptyElement(element: element).build(preindent: preindent) + EmptyElement(element: element).build(preindent: indent) case "article": - ContentElement(element: element).build(preindent: preindent) + ContentElement(element: element).build(preindent: indent) default: "element is not listed. contact the author" } diff --git a/Sources/HTMLKit/Internal/Features/Conversion/Stencils.swift b/Sources/HTMLKit/Internal/Features/Conversion/Stencils.swift index 3ade8192..dbbfc98e 100644 --- a/Sources/HTMLKit/Internal/Features/Conversion/Stencils.swift +++ b/Sources/HTMLKit/Internal/Features/Conversion/Stencils.swift @@ -1,10 +1,10 @@ -/// # Description: +/// ## Description /// The file contains the stencils for the converter. /// -/// # Note: +/// ## Note /// If you about to add something to the file, stick to the official documentation to keep the code consistent. /// -/// # Authors: +/// ## Authors /// Mats Moll: https://github.com/matsmoll /// Mattes Mohr: https://github.com/mattesmohr @@ -100,7 +100,7 @@ internal struct ContentElement { } return children.map { child in - return Converter.default.decode(element: child, preindent: 2) + return Converter.default.decode(element: child, indent: 2) } } @@ -224,7 +224,7 @@ internal struct PageLayout { private var name: String private var content: String { - return Converter.default.decode(element: root, preindent: 2) + return Converter.default.decode(element: root, indent: 2) } private var type: String { @@ -271,7 +271,7 @@ internal struct ViewLayout { private var name: String private var content: String { - return Converter.default.decode(element: root, preindent: 2) + return Converter.default.decode(element: root, indent: 2) } private var root: XMLElement diff --git a/Sources/HTMLKit/Internal/Features/Localization/Localized.swift b/Sources/HTMLKit/Internal/Features/Localization/Localized.swift index 86e27c3b..eef0c17c 100644 --- a/Sources/HTMLKit/Internal/Features/Localization/Localized.swift +++ b/Sources/HTMLKit/Internal/Features/Localization/Localized.swift @@ -10,13 +10,13 @@ public struct NoData: Encodable {} /// public struct Localized: AnyContent where B: Encodable { - enum Errors: Error { + public enum Errors: Error { case missingLingoConfig } - let key: String + public let key: String - let context: TemplateValue? + public let context: TemplateValue? public init(key: String, context: TemplateValue) { self.key = key @@ -38,7 +38,9 @@ public struct Localized: AnyContent where B: Encodable { if let value = try context?.value(from: manager) { guard let data = try? JSONEncoder().encode(value) else { - print("-- ERROR: Not able to encode content when localizing \(key), in \(locale), with content: \(String(describing: context)).") + + print("-- ERROR: Not able to encode content when localizing \(key), in \(locale), with content: \(String(describing: context)).") + return "" }