Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 38 additions & 12 deletions Sources/HTMLKit/Abstraction/Attributes/BasicAttributes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -307,18 +307,18 @@ extension AutocapitalizeAttribute where Self: EmptyNode {
/// A type that provides the `autocomplete` modifier.
@_documentation(visibility: internal)
public protocol AutocompleteAttribute: Attribute {

/// Specify an auto completion.
///
/// ```swift
/// Input()
/// .autocomplete(.off)
/// .autocomplete(true)
/// ```
///
/// - Parameter value: The value to be expected.
/// - Parameter values: The values to be expected.
///
/// - Returns: The element
func autocomplete(_ value: Values.Completion) -> Self
func autocomplete(_ value: Bool) -> Self

/// Specify an auto completion.
///
Expand All @@ -330,7 +330,19 @@ public protocol AutocompleteAttribute: Attribute {
/// - Parameter values: The values to be expected.
///
/// - Returns: The element
func autocomplete(_ values: OrderedSet<Values.Completion>) -> Self
func autocomplete(_ values: [Values.Completion]) -> Self

/// Specify an auto completion.
///
/// ```swift
/// Input()
/// .autocomplete(.organization, .organizationTitle)
/// ```
///
/// - Parameter values: The values to be expected.
///
/// - Returns: The element
func autocomplete(_ values: Values.Completion...) -> Self
}

extension AutocompleteAttribute where Self: ContentNode {
Expand Down Expand Up @@ -515,13 +527,27 @@ public protocol ClassAttribute: Attribute{
/// Paragraph {
/// "Lorem ipsum..."
/// }
/// .class("text")
/// .class(["text", "white"])
/// ```
///
/// - Parameter value: The class to apply to.
/// - Parameter names: The class to apply to.
///
/// - Returns: The element
func `class`(_ value: String) -> Self
func `class`(_ names: [String]) -> Self

/// Use a style class on an element.
///
/// ```swift
/// Paragraph {
/// "Lorem ipsum..."
/// }
/// .class("text", "white")
/// ```
///
/// - Parameter names: The class to apply to.
///
/// - Returns: The element
func `class`(_ names: String...) -> Self
}

extension ClassAttribute where Self: ContentNode {
Expand Down Expand Up @@ -2937,19 +2963,19 @@ public protocol SandboxAttribute: Attribute {
/// InlineFrame {
/// }
/// .source("https://...")
/// .sandbox(.allowDownloads)
/// .sandbox([.allowDownloads, .allowPopups])
/// ```
func sandbox(_ value: Values.Permission) -> Self
func sandbox(_ values: [Values.Permission]) -> Self

/// Define the permissions for the element.
///
/// ```swift
/// InlineFrame {
/// }
/// .source("https://...")
/// .sandbox([.allowDownloads, .allowPopups])
/// .sandbox(.allowDownloads, .allowPopups)
/// ```
func sandbox(_ values: OrderedSet<Values.Permission>) -> Self
func sandbox(_ values: Values.Permission...) -> Self
}

extension SandboxAttribute where Self: ContentNode {
Expand Down
54 changes: 42 additions & 12 deletions Sources/HTMLKit/Abstraction/Elements/BasicElements.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,22 +101,35 @@ public struct Html: ContentNode, BasicElement {
self.content = content
}

public func modify(if condition: Bool, element: (Html) -> Html) -> Html {
public func modify(if condition: Bool, use strategy: MergeStrategy = .replacing, element: (Html) -> Html) -> Html {

if condition {
return self.modify(element(self))

switch strategy {
case .combining:
return self.combine(element(self))

case .replacing:
return self.replace(element(self))
}
}

return self
}

public func modify<T>(unwrap value: T?, element: (Html, T) -> Html) -> Html {
public func modify<T>(unwrap value: T?, use strategy: MergeStrategy = .replacing, element: (Html, T) -> Html) -> Html {

guard let value = value else {
return self
}

return self.modify(element(self, value as T))
switch strategy {
case .combining:
return self.combine(element(self, value as T))

case .replacing:
return self.replace(element(self, value as T))
}
}
}

Expand All @@ -134,8 +147,12 @@ extension Html: GlobalAttributes, GlobalEventAttributes {
return mutate(autofocus: .init("autofocus", context: .trusted))
}

public func `class`(_ value: String) -> Html {
return mutate(class: .init(value, context: .tainted(.html)))
public func `class`(_ names: [String]) -> Html {
return mutate(class: .init(EnumeratedList(values: names, separator: " "), context: .tainted(.html)))
}

public func `class`(_ names: String...) -> Html {
return mutate(class: .init(EnumeratedList(values: names, separator: " "), context: .tainted(.html)))
}

@available(*, deprecated, message: "Use the editable(_:) modifier instead.")
Expand Down Expand Up @@ -201,7 +218,7 @@ extension Html: GlobalAttributes, GlobalEventAttributes {
}

if let elements = elements {
copy = copy.mutate(itemref: .init(elements.joined(separator: " "), context: .tainted(.html)))
copy = copy.mutate(itemref: .init(EnumeratedList(values: elements, separator: " "), context: .tainted(.html)))
}

return copy
Expand All @@ -221,7 +238,7 @@ extension Html: GlobalAttributes, GlobalEventAttributes {
copy = copy.mutate(itemtype: .init(schema.absoluteString, context: .tainted(.html)))
}

copy = copy.mutate(itemref: .init(elements.joined(separator: " "), context: .tainted(.html)))
copy = copy.mutate(itemref: .init(EnumeratedList(values: elements, separator: " "), context: .tainted(.html)))

return copy
}
Expand Down Expand Up @@ -406,22 +423,35 @@ public struct Custom: CustomNode, GlobalElement {
self.content = content
}

public func modify(if condition: Bool, element: (Custom) -> Custom) -> Custom {
public func modify(if condition: Bool, use strategy: MergeStrategy = .replacing, element: (Custom) -> Custom) -> Custom {

if condition {
return self.modify(element(self))

switch strategy {
case .combining:
return self.combine(element(self))

case .replacing:
return self.replace(element(self))
}
}

return self
}

public func modify<T>(unwrap value: T?, element: (Custom, T) -> Custom) -> Custom {
public func modify<T>(unwrap value: T?, use strategy: MergeStrategy = .replacing, element: (Custom, T) -> Custom) -> Custom {

guard let value = value else {
return self
}

return self.modify(element(self, value as T))
switch strategy {
case .combining:
return self.combine(element(self, value as T))

case .replacing:
return self.replace(element(self, value as T))
}
}
}

Expand Down
Loading