diff --git a/Sources/HTMLKit/Abstraction/Attributes/ContentAttributes.swift b/Sources/HTMLKit/Abstraction/Attributes/ContentAttributes.swift index b7bb6c79..d624262f 100644 --- a/Sources/HTMLKit/Abstraction/Attributes/ContentAttributes.swift +++ b/Sources/HTMLKit/Abstraction/Attributes/ContentAttributes.swift @@ -982,16 +982,62 @@ extension DisabledAttribute where Self: EmptyNode { public protocol DownloadAttribute: Attribute { /// Mark the target as downloadable. - /// + /// /// ```swift /// Anchor { /// "Lorem ipsum..." /// } - /// .download() + /// .download(true) /// ``` - /// + /// + /// - Parameter condition: Whether the target is downloadable. + /// + /// - Returns: The element + func download(_ condition: Bool) -> Self + + /// Mark the target as downloadable. + /// + /// ```swift + /// Anchor { + /// "Lorem ipsum..." + /// } + /// .download("filename") + /// ``` + /// + /// - Parameter value: The name to label the download. + /// + /// - Returns: The element + func download(_ name: String) -> Self + + /// Mark the target as downloadable. + /// + /// ```swift + /// Anchor { + /// "Lorem ipsum..." + /// } + /// .download("filename") + /// ``` + /// + /// - Parameters: + /// - localizedKey: The string key to be translated. + /// - tableName: The translation table to look in. + /// /// - Returns: The element - func download() -> Self + func download(_ localizedKey: LocalizedStringKey, tableName: String?) -> Self + + /// Mark the target as downloadable. + /// + /// ```swift + /// Anchor { + /// "Lorem ipsum..." + /// } + /// .download("filename") + /// ``` + /// + /// - Parameter value: The name to label the download. + /// + /// - Returns: The element + func download(verbatim name: String) -> Self } extension DownloadAttribute where Self: ContentNode { @@ -1334,6 +1380,20 @@ public protocol HiddenAttribute: Attribute { /// /// - Returns: The element func hidden(_ condition: Bool) -> Self + + /// Hide an element. + /// + /// ```swift + /// Paragraph { + /// "Lorem ipsum..." + /// } + /// .hidden(.untilFound) + /// ``` + /// + /// - Parameter value: The condition under which to hide the element. + /// + /// - Returns: The element + func hidden(_ value: Values.Condition) -> Self } extension HiddenAttribute where Self: ContentNode { @@ -2726,13 +2786,28 @@ public protocol RelationshipAttribute: Attribute { /// "Lorem ipsum..." /// } /// .reference("https://...") - /// .relationship(.author) + /// .relationship(.author, .external) + /// ``` + /// + /// - Parameter values: The relationship types to associate with. + /// + /// - Returns: The element + func relationship(_ values: Values.Relation...) -> Self + + /// Indicate the relationship between documents. + /// + /// ```swift + /// Anchor { + /// "Lorem ipsum..." + /// } + /// .reference("https://...") + /// .relationship([.author, .external]) /// ``` /// - /// - Parameter value: The relationship type to associate with. + /// - Parameter values: The relationship types to associate with. /// /// - Returns: The element - func relationship(_ value: Values.Relation) -> Self + func relationship(_ values: [Values.Relation]) -> Self } extension RelationshipAttribute where Self: ContentNode { @@ -4245,3 +4320,97 @@ extension AbbreviatedAttribute where Self: EmptyNode { return self.mutate(key: "abbr", value: value) } } + +/// A type that provides the `imageSources` modifier. +@_documentation(visibility: internal) +public protocol ImageSourcesAttribute: Attribute { + + /// Preload a set of sources. + /// + /// ```swift + /// Link() + /// .relationship(.preload) + /// .as(.image) + /// .imageSources([SourceCandidate("...webp", width: 1024), SourceCandidate("...webp", width: 1680)]) + /// ``` + /// + /// - Parameter candidates: The candidates to load in advance. + /// + /// - Returns: The element. + func imageSources(_ candidates: [SourceCandidate]) -> Self + + /// Preload a set of sources. + /// + /// ```swift + /// Link() + /// .relationship(.preload) + /// .as(.image) + /// .imageSources(SourceCandidate("...webp", width: 1024), SourceCandidate("...webp", width: 1680)) + /// ``` + /// + /// - Parameter candidates: The candidates to load in advance. + /// + /// - Returns: The element. + func imageSources(_ candidates: SourceCandidate...) -> Self +} + +extension ImageSourcesAttribute where Self: ContentNode { + + internal func mutate(imagesrcset value: AttributeData) -> Self { + return self.mutate(key: "imagesrcset", value: value) + } +} + +extension ImageSourcesAttribute where Self: EmptyNode { + + internal func mutate(imagesrcset value: AttributeData) -> Self { + return self.mutate(key: "imagesrcset", value: value) + } +} + +/// A type that provides the `imageSizes` modifier. +@_documentation(visibility: internal) +public protocol ImageSizesAttribute: Attribute { + + /// Preload the right source size. + /// + /// ```swift + /// Link() + /// .relationship(.preload) + /// .as(.image) + /// .imageSizes(SizeCandidate("100vw", conditions: .maxWidth("1680px")), SizeCandidate("80vw")) + /// ``` + /// + /// - Parameter candidates: The candidates to choose from. + /// + /// - Returns: The element. + func imageSizes(_ candidates: [SizeCandidate]) -> Self + + /// Preload the right source size. + /// + /// ```swift + /// Link() + /// .relationship(.preload) + /// .as(.image) + /// .imageSizes(SizeCandidate("100vw", conditions: .maxWidth("1680px")), SizeCandidate("80vw")) + /// ``` + /// + /// - Parameter candidates: The candidates to choose from. + /// + /// - Returns: The element. + func imageSizes(_ candidates: SizeCandidate...) -> Self +} + +extension ImageSizesAttribute where Self: ContentNode { + + internal func mutate(imagesizes value: AttributeData) -> Self { + return self.mutate(key: "imagesizes", value: value) + } +} + +extension ImageSizesAttribute where Self: EmptyNode { + + internal func mutate(imagesizes value: AttributeData) -> Self { + return self.mutate(key: "imagesizes", value: value) + } +} diff --git a/Sources/HTMLKit/Abstraction/Elements/BasicElements.swift b/Sources/HTMLKit/Abstraction/Elements/BasicElements.swift index d3470bf9..08d5ebf7 100644 --- a/Sources/HTMLKit/Abstraction/Elements/BasicElements.swift +++ b/Sources/HTMLKit/Abstraction/Elements/BasicElements.swift @@ -195,6 +195,10 @@ extension Html: GlobalContentAttributes, GlobalEventAttributes { return self } + public func hidden(_ value: Values.Condition) -> Html { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Html { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } diff --git a/Sources/HTMLKit/Abstraction/Elements/BodyElements.swift b/Sources/HTMLKit/Abstraction/Elements/BodyElements.swift index 10104f52..3428e23a 100644 --- a/Sources/HTMLKit/Abstraction/Elements/BodyElements.swift +++ b/Sources/HTMLKit/Abstraction/Elements/BodyElements.swift @@ -281,6 +281,10 @@ extension Article: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessi return self } + public func hidden(_ value: Values.Condition) -> Article { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Article { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -819,6 +823,10 @@ extension Section: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessi return self } + public func hidden(_ value: Values.Condition) -> Section { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Section { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -1359,6 +1367,10 @@ extension Navigation: GlobalContentAttributes, GlobalEventAttributes, GlobalAcce return self } + public func hidden(_ value: Values.Condition) -> Navigation { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Navigation { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -1894,6 +1906,10 @@ extension Aside: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessibi return self } + + public func hidden(_ value: Values.Condition) -> Aside { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } public func inputMode(_ value: Values.Mode) -> Aside { return mutate(inputmode: .init(value.rawValue, context: .trusted)) @@ -2428,6 +2444,10 @@ extension Heading1: GlobalContentAttributes, GlobalEventAttributes, GlobalAccess return self } + public func hidden(_ value: Values.Condition) -> Heading1 { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Heading1 { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -2969,6 +2989,10 @@ extension Heading2: GlobalContentAttributes, GlobalEventAttributes, GlobalAccess return self } + public func hidden(_ value: Values.Condition) -> Heading2 { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Heading2 { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -3511,6 +3535,10 @@ extension Heading3: GlobalContentAttributes, GlobalEventAttributes, GlobalAccess return self } + public func hidden(_ value: Values.Condition) -> Heading3 { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Heading3 { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -4053,6 +4081,10 @@ extension Heading4: GlobalContentAttributes, GlobalEventAttributes, GlobalAccess return self } + public func hidden(_ value: Values.Condition) -> Heading4 { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Heading4 { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -4595,6 +4627,10 @@ extension Heading5: GlobalContentAttributes, GlobalEventAttributes, GlobalAccess return self } + public func hidden(_ value: Values.Condition) -> Heading5 { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Heading5 { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -5137,6 +5173,10 @@ extension Heading6: GlobalContentAttributes, GlobalEventAttributes, GlobalAccess return self } + public func hidden(_ value: Values.Condition) -> Heading6 { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Heading6 { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -5683,6 +5723,10 @@ extension HeadingGroup: GlobalContentAttributes, GlobalEventAttributes, GlobalAc return self } + + public func hidden(_ value: Values.Condition) -> HeadingGroup { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } public func inputMode(_ value: Values.Mode) -> HeadingGroup { return mutate(inputmode: .init(value.rawValue, context: .trusted)) @@ -6218,6 +6262,10 @@ extension Header: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessib return self } + public func hidden(_ value: Values.Condition) -> Header { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Header { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -6750,6 +6798,10 @@ extension Footer: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessib return self } + public func hidden(_ value: Values.Condition) -> Footer { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Footer { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -7289,6 +7341,10 @@ extension Address: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessi return self } + public func hidden(_ value: Values.Condition) -> Address { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Address { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -7822,6 +7878,10 @@ extension Paragraph: GlobalContentAttributes, GlobalEventAttributes, GlobalAcces return self } + public func hidden(_ value: Values.Condition) -> Paragraph { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Paragraph { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -8359,6 +8419,10 @@ extension HorizontalRule: GlobalContentAttributes, GlobalEventAttributes, Global return self } + public func hidden(_ value: Values.Condition) -> HorizontalRule { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> HorizontalRule { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -8898,6 +8962,10 @@ extension PreformattedText: GlobalContentAttributes, GlobalEventAttributes, Glob return self } + public func hidden(_ value: Values.Condition) -> PreformattedText { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> PreformattedText { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -9430,6 +9498,10 @@ extension Blockquote: GlobalContentAttributes, GlobalEventAttributes, GlobalAcce return self } + + public func hidden(_ value: Values.Condition) -> Blockquote { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } public func inputMode(_ value: Values.Mode) -> Blockquote { return mutate(inputmode: .init(value.rawValue, context: .trusted)) @@ -9982,6 +10054,10 @@ extension OrderedList: GlobalContentAttributes, GlobalEventAttributes, GlobalAcc return self } + public func hidden(_ value: Values.Condition) -> OrderedList { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> OrderedList { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -10535,6 +10611,10 @@ extension UnorderedList: GlobalContentAttributes, GlobalEventAttributes, GlobalA return self } + public func hidden(_ value: Values.Condition) -> UnorderedList { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> UnorderedList { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -11086,6 +11166,10 @@ extension Menu: GlobalContentAttributes { return self } + public func hidden(_ value: Values.Condition) -> Menu { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Menu { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -11376,6 +11460,10 @@ extension DescriptionList: GlobalContentAttributes, GlobalEventAttributes, Globa return self } + public func hidden(_ value: Values.Condition) -> DescriptionList { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> DescriptionList { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -11914,6 +12002,10 @@ extension Figure: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessib return self } + public func hidden(_ value: Values.Condition) -> Figure { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Figure { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -12449,6 +12541,10 @@ extension Anchor: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessib return self } + public func hidden(_ value: Values.Condition) -> Anchor { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Anchor { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -12574,8 +12670,26 @@ extension Anchor: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessib return self } - public func download() -> Anchor { - return mutate(download: .init("download", context: .trusted)) + public func download(_ condition: Bool = true) -> Anchor { + + if condition { + return mutate(download: .init("download", context: .trusted)) + } + + return self + } + + @_disfavoredOverload + public func download(_ name: String) -> Anchor { + return mutate(download: .init(name, context: .tainted(.html))) + } + + public func download(_ localizedKey: LocalizedStringKey, tableName: String?) -> Anchor { + return mutate(download: .init(LocalizedString(key: localizedKey, table: tableName), context: .tainted(.html))) + } + + public func download(verbatim name: String) -> Anchor { + return mutate(download: .init(name, context: .tainted(.html))) } public func reference(_ value: String) -> Anchor { @@ -12606,8 +12720,12 @@ extension Anchor: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessib return mutate(referrerpolicy: .init(value.rawValue, context: .trusted)) } - public func relationship(_ value: Values.Relation) -> Anchor { - return mutate(rel: .init(value.rawValue, context: .trusted)) + public func relationship(_ values: Values.Relation...) -> Anchor { + return mutate(rel: .init(EnumeratedList(values: values, separator: " "), context: .trusted)) + } + + public func relationship(_ values: [Values.Relation]) -> Anchor { + return mutate(rel: .init(EnumeratedList(values: values, separator: " "), context: .trusted)) } public func target(_ value: Values.Target) -> Anchor { @@ -13036,6 +13154,10 @@ extension Emphasize: GlobalContentAttributes, GlobalEventAttributes, GlobalAcces return self } + + public func hidden(_ value: Values.Condition) -> Emphasize { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } public func inputMode(_ value: Values.Mode) -> Emphasize { return mutate(inputmode: .init(value.rawValue, context: .trusted)) @@ -13571,6 +13693,10 @@ extension Strong: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessib return self } + + public func hidden(_ value: Values.Condition) -> Strong { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } public func inputMode(_ value: Values.Mode) -> Strong { return mutate(inputmode: .init(value.rawValue, context: .trusted)) @@ -14107,6 +14233,10 @@ extension Small: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessibi return self } + public func hidden(_ value: Values.Condition) -> Small { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Small { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -14651,6 +14781,10 @@ extension StrikeThrough: GlobalContentAttributes, GlobalEventAttributes { return self } + public func hidden(_ value: Values.Condition) -> StrikeThrough { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> StrikeThrough { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -14972,6 +15106,10 @@ extension Main: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessibil return self } + + public func hidden(_ value: Values.Condition) -> Main { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } public func inputMode(_ value: Values.Mode) -> Main { return mutate(inputmode: .init(value.rawValue, context: .trusted)) @@ -15513,6 +15651,10 @@ extension Search: GlobalContentAttributes { return self } + public func hidden(_ value: Values.Condition) -> Search { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Search { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -15796,6 +15938,10 @@ extension Division: GlobalContentAttributes, GlobalEventAttributes, GlobalAccess return self } + public func hidden(_ value: Values.Condition) -> Division { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Division { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -16459,6 +16605,10 @@ extension Definition: GlobalContentAttributes, GlobalEventAttributes, GlobalAcce return self } + public func hidden(_ value: Values.Condition) -> Definition { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Definition { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -16995,6 +17145,10 @@ extension Cite: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessibil return self } + public func hidden(_ value: Values.Condition) -> Cite { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Cite { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -17530,6 +17684,10 @@ extension ShortQuote: GlobalContentAttributes, GlobalEventAttributes, GlobalAcce return self } + public func hidden(_ value: Values.Condition) -> ShortQuote { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> ShortQuote { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -18070,6 +18228,10 @@ extension Abbreviation: GlobalContentAttributes, GlobalEventAttributes, GlobalAc return self } + public func hidden(_ value: Values.Condition) -> Abbreviation { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Abbreviation { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -18606,6 +18768,10 @@ extension Ruby: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessibil return self } + public func hidden(_ value: Values.Condition) -> Ruby { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Ruby { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -19144,6 +19310,10 @@ extension Data: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessibil return self } + public func hidden(_ value: Values.Condition) -> Data { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Data { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -19694,6 +19864,10 @@ extension Time: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessibil return self } + public func hidden(_ value: Values.Condition) -> Time { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Time { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -20234,6 +20408,10 @@ extension Code: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessibil return self } + + public func hidden(_ value: Values.Condition) -> Code { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } public func inputMode(_ value: Values.Mode) -> Code { return mutate(inputmode: .init(value.rawValue, context: .trusted)) @@ -20772,6 +20950,10 @@ extension Variable: GlobalContentAttributes, GlobalEventAttributes, GlobalAccess return self } + public func hidden(_ value: Values.Condition) -> Variable { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Variable { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -21304,6 +21486,10 @@ extension SampleOutput: GlobalContentAttributes, GlobalEventAttributes, GlobalAc return self } + + public func hidden(_ value: Values.Condition) -> SampleOutput { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } public func inputMode(_ value: Values.Mode) -> SampleOutput { return mutate(inputmode: .init(value.rawValue, context: .trusted)) @@ -21842,6 +22028,10 @@ extension KeyboardInput: GlobalContentAttributes, GlobalEventAttributes, GlobalA return self } + public func hidden(_ value: Values.Condition) -> KeyboardInput { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> KeyboardInput { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -22379,6 +22569,10 @@ extension Subscript: GlobalContentAttributes, GlobalEventAttributes, GlobalAcces return self } + public func hidden(_ value: Values.Condition) -> Subscript { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Subscript { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -22915,6 +23109,10 @@ extension Superscript: GlobalContentAttributes, GlobalEventAttributes, GlobalAcc return self } + public func hidden(_ value: Values.Condition) -> Superscript { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Superscript { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -23451,6 +23649,10 @@ extension Italic: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessib return self } + + public func hidden(_ value: Values.Condition) -> Italic { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } public func inputMode(_ value: Values.Mode) -> Italic { return mutate(inputmode: .init(value.rawValue, context: .trusted)) @@ -23998,6 +24200,10 @@ extension Bold: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessibil return self } + public func hidden(_ value: Values.Condition) -> Bold { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Bold { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -24544,6 +24750,10 @@ extension Underline: GlobalContentAttributes, GlobalEventAttributes, GlobalAcces return self } + public func hidden(_ value: Values.Condition) -> Underline { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Underline { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -25090,6 +25300,10 @@ extension Mark: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessibil return self } + public func hidden(_ value: Values.Condition) -> Mark { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Mark { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -25627,6 +25841,10 @@ extension Bdi: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessibili return self } + public func hidden(_ value: Values.Condition) -> Bdi { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Bdi { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -26152,6 +26370,10 @@ extension Bdo: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessibili return self } + public func hidden(_ value: Values.Condition) -> Bdo { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Bdo { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -26685,6 +26907,10 @@ extension Span: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessibil return self } + public func hidden(_ value: Values.Condition) -> Span { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Span { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -27215,6 +27441,10 @@ extension LineBreak: GlobalContentAttributes, GlobalEventAttributes, GlobalAcces return self } + public func hidden(_ value: Values.Condition) -> LineBreak { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> LineBreak { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -27736,6 +27966,10 @@ extension WordBreak: GlobalContentAttributes, GlobalEventAttributes, GlobalAcces return self } + + public func hidden(_ value: Values.Condition) -> WordBreak { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } public func inputMode(_ value: Values.Mode) -> WordBreak { return mutate(inputmode: .init(value.rawValue, context: .trusted)) @@ -28269,6 +28503,10 @@ extension InsertedText: GlobalContentAttributes, GlobalEventAttributes, GlobalAc return self } + + public func hidden(_ value: Values.Condition) -> InsertedText { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } public func inputMode(_ value: Values.Mode) -> InsertedText { return mutate(inputmode: .init(value.rawValue, context: .trusted)) @@ -28811,6 +29049,10 @@ extension DeletedText: GlobalContentAttributes, GlobalEventAttributes, GlobalAcc return self } + public func hidden(_ value: Values.Condition) -> DeletedText { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> DeletedText { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -29357,6 +29599,10 @@ extension Picture: GlobalContentAttributes, GlobalEventAttributes { return self } + public func hidden(_ value: Values.Condition) -> Picture { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Picture { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -29651,6 +29897,10 @@ extension Image: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessibi return self } + + public func hidden(_ value: Values.Condition) -> Image { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } public func inputMode(_ value: Values.Mode) -> Image { return mutate(inputmode: .init(value.rawValue, context: .trusted)) @@ -30260,6 +30510,10 @@ extension InlineFrame: GlobalContentAttributes, GlobalEventAttributes, GlobalAcc return self } + public func hidden(_ value: Values.Condition) -> InlineFrame { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> InlineFrame { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -30824,6 +31078,10 @@ extension Embed: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessibi return self } + public func hidden(_ value: Values.Condition) -> Embed { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Embed { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -31378,6 +31636,10 @@ extension Object: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessib return self } + public func hidden(_ value: Values.Condition) -> Object { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Object { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -31937,6 +32199,10 @@ extension Video: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessibi return self } + public func hidden(_ value: Values.Condition) -> Video { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Video { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -32539,6 +32805,10 @@ extension Audio: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessibi return self } + public func hidden(_ value: Values.Condition) -> Audio { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Audio { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -33121,6 +33391,10 @@ extension Map: GlobalContentAttributes, GlobalEventAttributes, NameAttribute { return self } + public func hidden(_ value: Values.Condition) -> Map { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Map { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -33434,6 +33708,10 @@ extension Form: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessibil return self } + public func hidden(_ value: Values.Condition) -> Form { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Form { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -33596,8 +33874,12 @@ extension Form: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessibil return mutate(target: .init(value.rawValue, context: .trusted)) } - public func relationship(_ value: Values.Relation) -> Form { - return mutate(rel: .init(value.rawValue, context: .trusted)) + public func relationship(_ values: Values.Relation...) -> Form { + return mutate(rel: .init(EnumeratedList(values: values, separator: " "), context: .trusted)) + } + + public func relationship(_ values: [Values.Relation]) -> Form { + return mutate(rel: .init(EnumeratedList(values: values, separator: " "), context: .trusted)) } public func popover(_ value: Values.Popover.State) -> Form { @@ -34014,6 +34296,10 @@ extension DataList: GlobalContentAttributes, GlobalEventAttributes, GlobalAccess return self } + + public func hidden(_ value: Values.Condition) -> DataList { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } public func inputMode(_ value: Values.Mode) -> DataList { return mutate(inputmode: .init(value.rawValue, context: .trusted)) @@ -34550,6 +34836,10 @@ extension Output: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessib return self } + public func hidden(_ value: Values.Condition) -> Output { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Output { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -35096,6 +35386,10 @@ extension Progress: GlobalContentAttributes, GlobalEventAttributes, GlobalAccess return self } + + public func hidden(_ value: Values.Condition) -> Progress { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } public func inputMode(_ value: Values.Mode) -> Progress { return mutate(inputmode: .init(value.rawValue, context: .trusted)) @@ -35650,6 +35944,10 @@ extension Meter: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessibi return self } + + public func hidden(_ value: Values.Condition) -> Meter { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } public func inputMode(_ value: Values.Mode) -> Meter { return mutate(inputmode: .init(value.rawValue, context: .trusted)) @@ -36221,7 +36519,11 @@ extension Details: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessi return self } - + + public func hidden(_ value: Values.Condition) -> Details { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Details { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -36783,6 +37085,10 @@ extension Dialog: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessib return self } + public func hidden(_ value: Values.Condition) -> Dialog { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Dialog { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -37343,6 +37649,10 @@ extension Script: GlobalContentAttributes, GlobalEventAttributes, Asynchronously return self } + public func hidden(_ value: Values.Condition) -> Script { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Script { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -37683,6 +37993,10 @@ extension NoScript: GlobalContentAttributes, GlobalEventAttributes { return self } + + public func hidden(_ value: Values.Condition) -> NoScript { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } public func inputMode(_ value: Values.Mode) -> NoScript { return mutate(inputmode: .init(value.rawValue, context: .trusted)) @@ -37994,6 +38308,10 @@ extension Template: GlobalContentAttributes, GlobalEventAttributes, ShadowRootMo return self } + public func hidden(_ value: Values.Condition) -> Template { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Template { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -38296,6 +38614,10 @@ extension Canvas: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessib return self } + + public func hidden(_ value: Values.Condition) -> Canvas { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } public func inputMode(_ value: Values.Mode) -> Canvas { return mutate(inputmode: .init(value.rawValue, context: .trusted)) @@ -38844,6 +39166,10 @@ extension Table: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessibi return self } + + public func hidden(_ value: Values.Condition) -> Table { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } public func inputMode(_ value: Values.Mode) -> Table { return mutate(inputmode: .init(value.rawValue, context: .trusted)) @@ -39756,6 +40082,10 @@ extension Slot: GlobalContentAttributes, NameAttribute { return self } + public func hidden(_ value: Values.Condition) -> Slot { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Slot { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } diff --git a/Sources/HTMLKit/Abstraction/Elements/DefinitionElements.swift b/Sources/HTMLKit/Abstraction/Elements/DefinitionElements.swift index 71b4b362..9ec8f71b 100644 --- a/Sources/HTMLKit/Abstraction/Elements/DefinitionElements.swift +++ b/Sources/HTMLKit/Abstraction/Elements/DefinitionElements.swift @@ -143,6 +143,10 @@ extension TermName: GlobalContentAttributes, GlobalEventAttributes, GlobalAccess return self } + public func hidden(_ value: Values.Condition) -> TermName { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> TermName { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -681,6 +685,10 @@ extension TermDefinition: GlobalContentAttributes, GlobalEventAttributes, Global return self } + public func hidden(_ value: Values.Condition) -> TermDefinition { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> TermDefinition { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } diff --git a/Sources/HTMLKit/Abstraction/Elements/FigureElements.swift b/Sources/HTMLKit/Abstraction/Elements/FigureElements.swift index d249b31e..fff3e1d7 100644 --- a/Sources/HTMLKit/Abstraction/Elements/FigureElements.swift +++ b/Sources/HTMLKit/Abstraction/Elements/FigureElements.swift @@ -139,6 +139,10 @@ extension FigureCaption: GlobalContentAttributes, GlobalEventAttributes, GlobalA return self } + public func hidden(_ value: Values.Condition) -> FigureCaption { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> FigureCaption { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } diff --git a/Sources/HTMLKit/Abstraction/Elements/FormElements.swift b/Sources/HTMLKit/Abstraction/Elements/FormElements.swift index 7ef9ed73..78eb11c3 100644 --- a/Sources/HTMLKit/Abstraction/Elements/FormElements.swift +++ b/Sources/HTMLKit/Abstraction/Elements/FormElements.swift @@ -121,6 +121,10 @@ extension Input: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessibi return self } + public func hidden(_ value: Values.Condition) -> Input { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Input { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -780,6 +784,10 @@ extension Label: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessibi return self } + public func hidden(_ value: Values.Condition) -> Label { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Label { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -1335,6 +1343,10 @@ extension Select: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessib return self } + public func hidden(_ value: Values.Condition) -> Select { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Select { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -1823,6 +1835,10 @@ extension TextArea: GlobalContentAttributes, GlobalEventAttributes, GlobalAccess return self } + public func hidden(_ value: Values.Condition) -> TextArea { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> TextArea { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -2444,6 +2460,10 @@ extension Button: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessib return self } + public func hidden(_ value: Values.Condition) -> Button { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Button { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -3063,6 +3083,10 @@ extension Fieldset: GlobalContentAttributes, GlobalEventAttributes, GlobalAccess return self } + public func hidden(_ value: Values.Condition) -> Fieldset { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Fieldset { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } diff --git a/Sources/HTMLKit/Abstraction/Elements/HeadElements.swift b/Sources/HTMLKit/Abstraction/Elements/HeadElements.swift index f87bb8cf..51cdb886 100644 --- a/Sources/HTMLKit/Abstraction/Elements/HeadElements.swift +++ b/Sources/HTMLKit/Abstraction/Elements/HeadElements.swift @@ -132,6 +132,10 @@ extension Title: GlobalContentAttributes, GlobalEventAttributes { return self } + public func hidden(_ value: Values.Condition) -> Title { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Title { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -433,6 +437,10 @@ extension Base: GlobalContentAttributes, GlobalEventAttributes, ReferenceAttribu return self } + public func hidden(_ value: Values.Condition) -> Base { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Base { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -732,6 +740,10 @@ extension Meta: GlobalContentAttributes, GlobalEventAttributes, ContentAttribute return self } + public func hidden(_ value: Values.Condition) -> Meta { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Meta { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -1074,6 +1086,10 @@ extension Style: GlobalContentAttributes, GlobalEventAttributes, TypeAttribute, return self } + public func hidden(_ value: Values.Condition) -> Style { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Style { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -1322,7 +1338,7 @@ public struct Link: EmptyNode, HeadElement, BodyElement { } } -extension Link: GlobalContentAttributes, GlobalEventAttributes, ReferenceAttribute, ReferenceLanguageAttribute, MediaAttribute, ReferrerPolicyAttribute, RelationshipAttribute, SizesAttribute, TypeAttribute, FetchPriorityAttribute, BlockingAttribute, FormEventAttribute, IntegrityAttribute, AsAttribute, CrossOriginAttribute { +extension Link: GlobalContentAttributes, GlobalEventAttributes, ReferenceAttribute, ReferenceLanguageAttribute, MediaAttribute, ReferrerPolicyAttribute, RelationshipAttribute, SizesAttribute, TypeAttribute, FetchPriorityAttribute, BlockingAttribute, FormEventAttribute, IntegrityAttribute, AsAttribute, CrossOriginAttribute, ImageSourcesAttribute, ImageSizesAttribute { public func accessKey(_ value: Character) -> Link { return mutate(accesskey: .init("\(value)", context: .trusted)) @@ -1392,6 +1408,10 @@ extension Link: GlobalContentAttributes, GlobalEventAttributes, ReferenceAttribu return self } + public func hidden(_ value: Values.Condition) -> Link { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Link { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -1549,8 +1569,12 @@ extension Link: GlobalContentAttributes, GlobalEventAttributes, ReferenceAttribu return mutate(referrerpolicy: .init(value.rawValue, context: .trusted)) } - public func relationship(_ value: Values.Relation) -> Link { - return mutate(rel: .init(value.rawValue, context: .trusted)) + public func relationship(_ values: Values.Relation...) -> Link { + return mutate(rel: .init(EnumeratedList(values: values, separator: " "), context: .trusted)) + } + + public func relationship(_ values: [Values.Relation]) -> Link { + return mutate(rel: .init(EnumeratedList(values: values, separator: " "), context: .trusted)) } public func sizes(_ candidates: [String]) -> Link { @@ -1577,6 +1601,22 @@ extension Link: GlobalContentAttributes, GlobalEventAttributes, ReferenceAttribu return mutate(popover: .init(value.rawValue, context: .trusted)) } + public func imageSources(_ candidates: [SourceCandidate]) -> Link { + return mutate(imagesrcset: .init(EnumeratedList(values: candidates, separator: ", "), context: .tainted(.html))) + } + + public func imageSources(_ candidates: SourceCandidate...) -> Link { + return mutate(imagesrcset: .init(EnumeratedList(values: candidates, separator: ", "), context: .tainted(.html))) + } + + public func imageSizes(_ candidates: [SizeCandidate]) -> Link { + return mutate(imagesizes: .init(EnumeratedList(values: candidates, separator: ", "), context: .tainted(.html))) + } + + public func imageSizes(_ candidates: SizeCandidate...) -> Link { + return mutate(imagesizes: .init(EnumeratedList(values: candidates, separator: ", "), context: .tainted(.html))) + } + public func custom(key: String, value: String, context: EscapeContext = .tainted(.html)) -> Link { return mutate(key: key, value: .init(value, context: context)) } diff --git a/Sources/HTMLKit/Abstraction/Elements/HtmlElements.swift b/Sources/HTMLKit/Abstraction/Elements/HtmlElements.swift index 3b658737..02fb8d55 100644 --- a/Sources/HTMLKit/Abstraction/Elements/HtmlElements.swift +++ b/Sources/HTMLKit/Abstraction/Elements/HtmlElements.swift @@ -130,6 +130,10 @@ extension Head: GlobalContentAttributes, GlobalEventAttributes { return self } + public func hidden(_ value: Values.Condition) -> Head { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Head { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -438,6 +442,10 @@ extension Body: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessibil return self } + public func hidden(_ value: Values.Condition) -> Body { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Body { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } diff --git a/Sources/HTMLKit/Abstraction/Elements/InputElements.swift b/Sources/HTMLKit/Abstraction/Elements/InputElements.swift index 05a78b87..85f750fb 100644 --- a/Sources/HTMLKit/Abstraction/Elements/InputElements.swift +++ b/Sources/HTMLKit/Abstraction/Elements/InputElements.swift @@ -145,6 +145,10 @@ extension OptionGroup: GlobalContentAttributes, GlobalEventAttributes, GlobalAcc return self } + public func hidden(_ value: Values.Condition) -> OptionGroup { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> OptionGroup { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -703,6 +707,10 @@ extension Option: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessib return self } + public func hidden(_ value: Values.Condition) -> Option { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Option { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -1293,6 +1301,10 @@ extension Legend: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessib return self } + public func hidden(_ value: Values.Condition) -> Legend { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Legend { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -1831,6 +1843,10 @@ extension Summary: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessi return self } + public func hidden(_ value: Values.Condition) -> Summary { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Summary { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } diff --git a/Sources/HTMLKit/Abstraction/Elements/ListElements.swift b/Sources/HTMLKit/Abstraction/Elements/ListElements.swift index c6e7d7b3..151fa58a 100644 --- a/Sources/HTMLKit/Abstraction/Elements/ListElements.swift +++ b/Sources/HTMLKit/Abstraction/Elements/ListElements.swift @@ -139,6 +139,10 @@ extension ListItem: GlobalContentAttributes, GlobalEventAttributes, GlobalAccess return self } + public func hidden(_ value: Values.Condition) -> ListItem { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> ListItem { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } diff --git a/Sources/HTMLKit/Abstraction/Elements/MapElements.swift b/Sources/HTMLKit/Abstraction/Elements/MapElements.swift index 35056de5..4ef40a66 100644 --- a/Sources/HTMLKit/Abstraction/Elements/MapElements.swift +++ b/Sources/HTMLKit/Abstraction/Elements/MapElements.swift @@ -126,6 +126,10 @@ extension Area: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessibil return self } + + public func hidden(_ value: Values.Condition) -> Area { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } public func inputMode(_ value: Values.Mode) -> Area { return mutate(inputmode: .init(value.rawValue, context: .trusted)) @@ -291,16 +295,38 @@ extension Area: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessibil return mutate(target: .init(value.rawValue, context: .trusted)) } - public func download() -> Area { - return mutate(download: .init("download", context: .trusted)) + public func download(_ condition: Bool = true) -> Area { + + if condition { + return mutate(download: .init("download", context: .trusted)) + } + + return self + } + + @_disfavoredOverload + public func download(_ name: String) -> Area { + return mutate(download: .init(name, context: .tainted(.html))) + } + + public func download(_ localizedKey: LocalizedStringKey, tableName: String?) -> Area { + return mutate(download: .init(LocalizedString(key: localizedKey, table: tableName), context: .tainted(.html))) + } + + public func download(verbatim name: String) -> Area { + return mutate(download: .init(name, context: .tainted(.html))) } public func ping(_ value: String) -> Area { return mutate(ping: .init(value, context: .tainted(.html))) } - public func relationship(_ value: Values.Relation) -> Area { - return mutate(rel: .init(value.rawValue, context: .trusted)) + public func relationship(_ values: Values.Relation...) -> Area { + return mutate(rel: .init(EnumeratedList(values: values, separator: " "), context: .trusted)) + } + + public func relationship(_ values: [Values.Relation]) -> Area { + return mutate(rel: .init(EnumeratedList(values: values, separator: " "), context: .trusted)) } public func referrerPolicy(_ value: Values.Policy) -> Area { diff --git a/Sources/HTMLKit/Abstraction/Elements/MediaElements.swift b/Sources/HTMLKit/Abstraction/Elements/MediaElements.swift index e5b6e464..65cec284 100644 --- a/Sources/HTMLKit/Abstraction/Elements/MediaElements.swift +++ b/Sources/HTMLKit/Abstraction/Elements/MediaElements.swift @@ -120,6 +120,10 @@ extension Source: GlobalContentAttributes, GlobalEventAttributes, TypeAttribute, return self } + public func hidden(_ value: Values.Condition) -> Source { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Source { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -469,6 +473,10 @@ extension Track: GlobalContentAttributes, GlobalEventAttributes, KindAttribute, return self } + public func hidden(_ value: Values.Condition) -> Track { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Track { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } diff --git a/Sources/HTMLKit/Abstraction/Elements/RubyElements.swift b/Sources/HTMLKit/Abstraction/Elements/RubyElements.swift index 2efa389b..4c2d4b9a 100644 --- a/Sources/HTMLKit/Abstraction/Elements/RubyElements.swift +++ b/Sources/HTMLKit/Abstraction/Elements/RubyElements.swift @@ -141,6 +141,10 @@ extension RubyText: GlobalContentAttributes, GlobalEventAttributes, GlobalAccess return self } + public func hidden(_ value: Values.Condition) -> RubyText { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> RubyText { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -682,6 +686,10 @@ extension RubyPronunciation: GlobalContentAttributes, GlobalEventAttributes, Glo return self } + + public func hidden(_ value: Values.Condition) -> RubyPronunciation { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } public func inputMode(_ value: Values.Mode) -> RubyPronunciation { return mutate(inputmode: .init(value.rawValue, context: .trusted)) diff --git a/Sources/HTMLKit/Abstraction/Elements/TableElements.swift b/Sources/HTMLKit/Abstraction/Elements/TableElements.swift index 896dee2e..0ed92911 100644 --- a/Sources/HTMLKit/Abstraction/Elements/TableElements.swift +++ b/Sources/HTMLKit/Abstraction/Elements/TableElements.swift @@ -164,6 +164,10 @@ extension Caption: GlobalContentAttributes, GlobalEventAttributes, GlobalAccessi return self } + public func hidden(_ value: Values.Condition) -> Caption { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> Caption { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -701,6 +705,10 @@ extension ColumnGroup: GlobalContentAttributes, GlobalEventAttributes, SpanAttri return self } + public func hidden(_ value: Values.Condition) -> ColumnGroup { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> ColumnGroup { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -1002,6 +1010,10 @@ extension Column: GlobalContentAttributes, GlobalEventAttributes, SpanAttribute return self } + + public func hidden(_ value: Values.Condition) -> Column { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } public func inputMode(_ value: Values.Mode) -> Column { return mutate(inputmode: .init(value.rawValue, context: .trusted)) @@ -1315,6 +1327,10 @@ extension TableBody: GlobalContentAttributes, GlobalEventAttributes, GlobalAcces return self } + public func hidden(_ value: Values.Condition) -> TableBody { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> TableBody { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -1869,6 +1885,10 @@ extension TableHead: GlobalContentAttributes, GlobalEventAttributes, GlobalAcces return self } + public func hidden(_ value: Values.Condition) -> TableHead { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> TableHead { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -2423,6 +2443,10 @@ extension TableFoot: GlobalContentAttributes, GlobalEventAttributes, GlobalAcces return self } + public func hidden(_ value: Values.Condition) -> TableFoot { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> TableFoot { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -2963,6 +2987,10 @@ extension TableRow: GlobalContentAttributes, GlobalEventAttributes, GlobalAccess return self } + public func hidden(_ value: Values.Condition) -> TableRow { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> TableRow { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -3516,6 +3544,10 @@ extension DataCell: GlobalContentAttributes, GlobalEventAttributes, GlobalAccess return self } + public func hidden(_ value: Values.Condition) -> DataCell { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> DataCell { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } @@ -4078,6 +4110,10 @@ extension HeaderCell: GlobalContentAttributes, GlobalEventAttributes, GlobalAcce return self } + public func hidden(_ value: Values.Condition) -> HeaderCell { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } + public func inputMode(_ value: Values.Mode) -> HeaderCell { return mutate(inputmode: .init(value.rawValue, context: .trusted)) } diff --git a/Sources/HTMLKit/Abstraction/Tokens/ValueTokens.swift b/Sources/HTMLKit/Abstraction/Tokens/ValueTokens.swift index d25131ce..a3fd0536 100644 --- a/Sources/HTMLKit/Abstraction/Tokens/ValueTokens.swift +++ b/Sources/HTMLKit/Abstraction/Tokens/ValueTokens.swift @@ -803,18 +803,21 @@ public enum Values { /// Indicates an alternate presentation. case alternate - /// Indicates the preferred url. - case canonical - /// Indicates an author page. case author /// Indicates a perma link. case bookmark + /// Indicates the preferred url. + case canonical + /// Indicates a dns prefetch. case dnsPrefetch = "dns-prefetch" + /// Hints to block rendering until fully parsed. + case expect + /// Indicates a external resource. case external @@ -824,15 +827,15 @@ public enum Values { /// Indicates a document icon. case icon + /// Indicates a licence information. + case licence + /// Indicates a app manifest. case manifest /// Indicates a module preload. case modulePreload = "modulepreload" - /// Indicates a licence information. - case licence - /// Indicates a page pagination. case next @@ -863,6 +866,9 @@ public enum Values { /// Indicates a page pagination. case prev + /// Indicates about data collection and usage practices. + case privacyPolicy = "privacy-policy" + /// Indicates a search content. case search @@ -872,6 +878,9 @@ public enum Values { /// Indicates a content tag. case tag + /// Indicates about agreements. + case terms = "terms-of-service" + /// Indicates a touch icon. case appleTouchIcon = "apple-touch-icon" @@ -2166,4 +2175,17 @@ public enum Values { /// Indicates the script contains json data. case data = "application/json" } + + /// An enumeration of hide condition. + /// + /// ```swift + /// Paragraph { + /// "Lorem ipsum..." + /// } + /// .hidden(.untilFound) + /// ``` + public enum Condition: String { + + case untilFound = "until-found" + } } diff --git a/Sources/HTMLKit/Framework/Rendering/EnumeratedList.swift b/Sources/HTMLKit/Framework/Rendering/EnumeratedList.swift index 88e61a85..a3207892 100644 --- a/Sources/HTMLKit/Framework/Rendering/EnumeratedList.swift +++ b/Sources/HTMLKit/Framework/Rendering/EnumeratedList.swift @@ -90,6 +90,12 @@ extension EnumeratedList { self.values = values.map(\.rawValue) self.separator = separator } + + internal init(values: [Values.Relation], separator: String) { + + self.values = values.map(\.rawValue) + self.separator = separator + } } extension EnumeratedList: Equatable { diff --git a/Tests/HTMLKitTests/AttributesTests.swift b/Tests/HTMLKitTests/AttributesTests.swift index aafc46bf..1f24e1a0 100644 --- a/Tests/HTMLKitTests/AttributesTests.swift +++ b/Tests/HTMLKitTests/AttributesTests.swift @@ -10,7 +10,7 @@ final class AttributesTests: XCTestCase { @ContentBuilder var body: Content } - typealias AllAttributes = AccessKeyAttribute & AcceptAttribute & ActionAttribute & AlternateAttribute & AsynchronouslyAttribute & AutocapitalizeAttribute & AutocompleteAttribute & AutofocusAttribute & AutoplayAttribute & CharsetAttribute & CheckedAttribute & CiteAttribute & ClassAttribute & ColumnsAttribute & ColumnSpanAttribute & ContentAttribute & EditAttribute & ControlsAttribute & DataAttribute & DateTimeAttribute & DefaultAttribute & DeferAttribute & DirectionAttribute & DisabledAttribute & DownloadAttribute & DragAttribute & EncodingAttribute & EnterKeyAttribute & ForAttribute & FormAttribute & FormActionAttribute & EquivalentAttribute & HeadersAttribute & HeightAttribute & HiddenAttribute & HighAttribute & ReferenceAttribute & ReferenceLanguageAttribute & IdentifierAttribute & IsMapAttribute & InputModeAttribute & IsAttribute & ItemAttribute & ItemPropertyAttribute & KindAttribute & LabelAttribute & LanguageAttribute & ListAttribute & LoopAttribute & LowAttribute & MaximumValueAttribute & MaximumLengthAttribute & MediaAttribute & MethodAttribute & MinimumValueAttribute & MinimumLengthAttribute & MultipleAttribute & MutedAttribute & NameAttribute & NonceAttribute & NoValidateAttribute & OpenAttribute & OptimumAttribute & PatternAttribute & PartAttribute & PingAttribute & PlaceholderAttribute & PosterAttribute & PreloadAttribute & ReadOnlyAttribute & ReferrerPolicyAttribute & RelationshipAttribute & RequiredAttribute & ReversedAttribute & RoleAttribute & RowsAttribute & RowSpanAttribute & SandboxAttribute & ScopeAttribute & ShapeAttribute & SizeAttribute & SizesAttribute & SlotAttribute & SpanAttribute & SpellCheckAttribute & SourceAttribute & StartAttribute & StepAttribute & StyleAttribute & TabulatorAttribute & TargetAttribute & TitleAttribute & TranslateAttribute & TypeAttribute & ValueAttribute & WidthAttribute & WrapAttribute & PropertyAttribute & SelectedAttribute & WindowEventAttribute & FocusEventAttribute & PointerEventAttribute & MouseEventAttribute & WheelEventAttribute & InputEventAttribute & KeyboardEventAttribute & DragEventAttribute & ClipboardEventAttribute & SelectionEventAttribute & MediaEventAttribute & FormEventAttribute & DetailEventAttribute & AtomicAccessibilityAttribute & BusyAccessibilityAttribute & ControlsAccessibilityAttribute & CurrentAccessibilityAttribute & DescriptionsAccessibilityAttribute & DetailAccessibilityAttribute & DisabledAccessibilityAttribute & FlowAccessibilityAttribute & PopupAccessibilityAttribute & HiddenAccessibilityAttribute & InvalidAccessibilityAttribute & ShortcutsAccessibilityAttribute & LabelAccessibilityAttribute & LabelsAccessibilityAttribute & LiveAccessibilityAttribute & OwnsAccessibilityAttribute & MultilineAccessibilityAttribute & RowIndexAccessibilityAttribute & RelevantAccessibilityAttribute & RoleDescriptionAccessibilityAttribute & SortAccessibilityAttribute & OrientationAccessibilityAttribute & RequiredAccessibilityAttribute & ReadOnlyAccessibilityAttribute & ModalAccessibilityAttribute & LevelAccessibilityAttribute & HintAccessibilityAttribute & PositionAccessibilityAttribute & MultiselectAccessibilityAttribute & RowCountAccessibilityAttribute & ColumnIndexAccessibilityAttribute & ColumnCountAccessibilityAttribute & RowSpanAccessibilityAttribute & ColumnSpanAccessibilityAttribute & MaximumValueAccessibilityAttribute & MinimumValueAccessibilityAttribute & ValueAccessibilityAttribute & PressedAccessibilityAttribute & SelectedAccessibilityAttribute & CheckedAccessibilityAttribute & ExpandedAccessibilityAttribute & FocusedAccessibilityAttribute & CompletionAccessibilityAttribute & DrawAttribute & FillAttribute & StrokeAttribute & RadiusAttribute & PositionPointAttribute & RadiusPointAttribute & CenterPointAttribute & ViewBoxAttribute & NamespaceAttribute & PointsAttribute & ShadowRootModeAttribute & InertAttribute & FetchPriorityAttribute & LoadingAttribute & SourceSetAttribute & DecodingAttribute & BlockingAttribute & PopoverAttribute & PopoverTargetAttribute & UseMapAttribute & PlaysInlineAttribute & IntegrityAttribute & AsAttribute & CrossOriginAttribute & SourceLanguageAttribute & SourceDocumentAttribute & AbbreviatedAttribute + typealias AllAttributes = AccessKeyAttribute & AcceptAttribute & ActionAttribute & AlternateAttribute & AsynchronouslyAttribute & AutocapitalizeAttribute & AutocompleteAttribute & AutofocusAttribute & AutoplayAttribute & CharsetAttribute & CheckedAttribute & CiteAttribute & ClassAttribute & ColumnsAttribute & ColumnSpanAttribute & ContentAttribute & EditAttribute & ControlsAttribute & DataAttribute & DateTimeAttribute & DefaultAttribute & DeferAttribute & DirectionAttribute & DisabledAttribute & DownloadAttribute & DragAttribute & EncodingAttribute & EnterKeyAttribute & ForAttribute & FormAttribute & FormActionAttribute & EquivalentAttribute & HeadersAttribute & HeightAttribute & HiddenAttribute & HighAttribute & ReferenceAttribute & ReferenceLanguageAttribute & IdentifierAttribute & IsMapAttribute & InputModeAttribute & IsAttribute & ItemAttribute & ItemPropertyAttribute & KindAttribute & LabelAttribute & LanguageAttribute & ListAttribute & LoopAttribute & LowAttribute & MaximumValueAttribute & MaximumLengthAttribute & MediaAttribute & MethodAttribute & MinimumValueAttribute & MinimumLengthAttribute & MultipleAttribute & MutedAttribute & NameAttribute & NonceAttribute & NoValidateAttribute & OpenAttribute & OptimumAttribute & PatternAttribute & PartAttribute & PingAttribute & PlaceholderAttribute & PosterAttribute & PreloadAttribute & ReadOnlyAttribute & ReferrerPolicyAttribute & RelationshipAttribute & RequiredAttribute & ReversedAttribute & RoleAttribute & RowsAttribute & RowSpanAttribute & SandboxAttribute & ScopeAttribute & ShapeAttribute & SizeAttribute & SizesAttribute & SlotAttribute & SpanAttribute & SpellCheckAttribute & SourceAttribute & StartAttribute & StepAttribute & StyleAttribute & TabulatorAttribute & TargetAttribute & TitleAttribute & TranslateAttribute & TypeAttribute & ValueAttribute & WidthAttribute & WrapAttribute & PropertyAttribute & SelectedAttribute & WindowEventAttribute & FocusEventAttribute & PointerEventAttribute & MouseEventAttribute & WheelEventAttribute & InputEventAttribute & KeyboardEventAttribute & DragEventAttribute & ClipboardEventAttribute & SelectionEventAttribute & MediaEventAttribute & FormEventAttribute & DetailEventAttribute & AtomicAccessibilityAttribute & BusyAccessibilityAttribute & ControlsAccessibilityAttribute & CurrentAccessibilityAttribute & DescriptionsAccessibilityAttribute & DetailAccessibilityAttribute & DisabledAccessibilityAttribute & FlowAccessibilityAttribute & PopupAccessibilityAttribute & HiddenAccessibilityAttribute & InvalidAccessibilityAttribute & ShortcutsAccessibilityAttribute & LabelAccessibilityAttribute & LabelsAccessibilityAttribute & LiveAccessibilityAttribute & OwnsAccessibilityAttribute & MultilineAccessibilityAttribute & RowIndexAccessibilityAttribute & RelevantAccessibilityAttribute & RoleDescriptionAccessibilityAttribute & SortAccessibilityAttribute & OrientationAccessibilityAttribute & RequiredAccessibilityAttribute & ReadOnlyAccessibilityAttribute & ModalAccessibilityAttribute & LevelAccessibilityAttribute & HintAccessibilityAttribute & PositionAccessibilityAttribute & MultiselectAccessibilityAttribute & RowCountAccessibilityAttribute & ColumnIndexAccessibilityAttribute & ColumnCountAccessibilityAttribute & RowSpanAccessibilityAttribute & ColumnSpanAccessibilityAttribute & MaximumValueAccessibilityAttribute & MinimumValueAccessibilityAttribute & ValueAccessibilityAttribute & PressedAccessibilityAttribute & SelectedAccessibilityAttribute & CheckedAccessibilityAttribute & ExpandedAccessibilityAttribute & FocusedAccessibilityAttribute & CompletionAccessibilityAttribute & DrawAttribute & FillAttribute & StrokeAttribute & RadiusAttribute & PositionPointAttribute & RadiusPointAttribute & CenterPointAttribute & ViewBoxAttribute & NamespaceAttribute & PointsAttribute & ShadowRootModeAttribute & InertAttribute & FetchPriorityAttribute & LoadingAttribute & SourceSetAttribute & DecodingAttribute & BlockingAttribute & PopoverAttribute & PopoverTargetAttribute & UseMapAttribute & PlaysInlineAttribute & IntegrityAttribute & AsAttribute & CrossOriginAttribute & SourceLanguageAttribute & SourceDocumentAttribute & AbbreviatedAttribute & ImageSourcesAttribute & ImageSizesAttribute struct Tag: ContentNode, GlobalElement, AllAttributes { @@ -83,6 +83,10 @@ final class AttributesTests: XCTestCase { return self } + + func hidden(_ value: Values.Condition) -> Tag { + return mutate(hidden: .init(value.rawValue, context: .trusted)) + } func id(_ value: String) -> Tag { return self.mutate(id: .init(value, context: .tainted(.html))) @@ -319,8 +323,26 @@ final class AttributesTests: XCTestCase { return self } - func download() -> Tag { - return self.mutate(download: .init("download", context: .trusted)) + func download(_ condition: Bool = true) -> Tag { + + if condition { + return self.mutate(download: .init("download", context: .trusted)) + } + + return self + } + + @_disfavoredOverload + func download(_ name: String) -> Tag { + return self.mutate(download: .init(name, context: .tainted(.html))) + } + + func download(_ localizedKey: LocalizedStringKey, tableName: String?) -> Tag { + return self.mutate(download: .init(LocalizedString(key: localizedKey, table: tableName), context: .tainted(.html))) + } + + func download(verbatim name: String) -> Tag { + return self.mutate(download: .init(name, context: .tainted(.html))) } func encoding(_ value: Values.Encoding) -> Tag { @@ -521,8 +543,12 @@ final class AttributesTests: XCTestCase { return self.mutate(referrerpolicy: .init(value.rawValue, context: .trusted)) } - func relationship(_ value: Values.Relation) -> Tag { - return self.mutate(rel: .init(value.rawValue, context: .trusted)) + public func relationship(_ values: Values.Relation...) -> Tag { + return mutate(rel: .init(EnumeratedList(values: values, separator: " "), context: .trusted)) + } + + public func relationship(_ values: [Values.Relation]) -> Tag { + return mutate(rel: .init(EnumeratedList(values: values, separator: " "), context: .trusted)) } func required(_ condition: Bool = true) -> Tag { @@ -1184,6 +1210,22 @@ final class AttributesTests: XCTestCase { func abbreviated(verbatim value: String) -> Tag { return self.mutate(abbr: .init(value, context: .tainted(.html))) } + + func imageSources(_ candidates: [HTMLKit.SourceCandidate]) -> Tag { + return mutate(imagesrcset: .init(EnumeratedList(values: candidates, separator: ", "), context: .tainted(.html))) + } + + func imageSources(_ candidates: HTMLKit.SourceCandidate...) -> Tag { + return mutate(imagesrcset: .init(EnumeratedList(values: candidates, separator: ", "), context: .tainted(.html))) + } + + func imageSizes(_ candidates: [HTMLKit.SizeCandidate]) -> Tag { + return mutate(imagesizes: .init(EnumeratedList(values: candidates, separator: ", "), context: .tainted(.html))) + } + + func imageSizes(_ candidates: HTMLKit.SizeCandidate...) -> Tag { + return mutate(imagesizes: .init(EnumeratedList(values: candidates, separator: ", "), context: .tainted(.html))) + } } var renderer = Renderer() @@ -1303,19 +1345,18 @@ final class AttributesTests: XCTestCase { func testHiddenAttribute() throws { let view = TestView { - // unconditionally Tag {}.hidden() - // with a false condition Tag {}.hidden(false) - // with a true condition Tag {}.hidden(true) + Tag {}.hidden(.untilFound) } XCTAssertEqual(try renderer.render(view: view), """ \ \ - + \ + """ ) } @@ -1722,11 +1763,17 @@ final class AttributesTests: XCTestCase { let view = TestView { Tag {}.download() + Tag {}.download(false) + Tag {}.download(true) + Tag {}.download("filename") } XCTAssertEqual(try renderer.render(view: view), """ - + \ + \ + \ + """ ) } @@ -2274,11 +2321,15 @@ final class AttributesTests: XCTestCase { let view = TestView { Tag {}.relationship(.author) + Tag {}.relationship(.author, .external) + Tag {}.relationship([.author, .external]) } XCTAssertEqual(try renderer.render(view: view), """ - + \ + \ + """ ) } @@ -3840,4 +3891,52 @@ final class AttributesTests: XCTestCase { """ ) } + + func testImageSourcesAttribute() throws { + + let view = TestView { + Tag {}.imageSources(SourceCandidate("img.webp")) + Tag {}.imageSources(SourceCandidate("img.png", density: 4)) + Tag {}.imageSources(SourceCandidate("img.png", density: .ultra)) + Tag {}.imageSources(SourceCandidate("img.png", width: 1024)) + Tag {}.imageSources(SourceCandidate("img.png", width: 1024), SourceCandidate("img.png", density: .ultra)) + } + + XCTAssertEqual(try renderer.render(view: view), + """ + \ + \ + \ + \ + + """ + ) + } + + func testImageSizesAttribute() throws { + + let view = TestView { + Tag {}.imageSizes(SizeCandidate("auto")) + Tag {}.imageSizes(SizeCandidate("100vw", conditions: .orientation(.landscape))) + Tag {}.imageSizes(SizeCandidate("100vw", conditions: .orientation(.portrait))) + Tag {}.imageSizes(SizeCandidate("100vw", conditions: .orientation(.landscape), .width("50em"))) + Tag {}.imageSizes(SizeCandidate("calc(100vw - 100px)", conditions: .minWidth("50em"))) + Tag {}.imageSizes(SizeCandidate("100vw", conditions: .maxWidth("50em"))) + Tag {}.imageSizes([SizeCandidate("100vw"), SizeCandidate("100vw", conditions: .maxWidth("50em"))]) + Tag {}.imageSizes(SizeCandidate("100vw"), SizeCandidate("100vw", conditions: .maxWidth("50em"))) + } + + XCTAssertEqual(try renderer.render(view: view), + """ + \ + \ + \ + \ + \ + \ + \ + + """ + ) + } }