Skip to content

Commit bbf9093

Browse files
authored
Introduce the usemap attribute (#160)
* Introduce the usemap attribute * Let htmlkit handle the required hash character
1 parent 275404a commit bbf9093

File tree

3 files changed

+58
-2
lines changed

3 files changed

+58
-2
lines changed

Sources/HTMLKit/Abstraction/Attributes/BasicAttributes.swift

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2638,6 +2638,41 @@ extension TypeAttribute where Self: EmptyNode {
26382638
}
26392639
}
26402640

2641+
/// A type that provides the `useMap` modifier
2642+
@_documentation(visibility: internal)
2643+
public protocol UseMapAttribute: Attribute {
2644+
2645+
/// Link the element with an associated map.
2646+
///
2647+
/// ```swift
2648+
/// Image()
2649+
/// .source("....png")
2650+
/// .useMap("...")
2651+
/// Map {
2652+
/// Area()
2653+
/// .shape(.circle)
2654+
/// .coordinates(...)
2655+
/// }
2656+
/// .name("...")
2657+
/// ```
2658+
/// - Parameter name: The name of the map to link to
2659+
func useMap(_ name: String) -> Self
2660+
}
2661+
2662+
extension UseMapAttribute where Self: ContentNode {
2663+
2664+
internal func mutate(usemap value: String) -> Self {
2665+
return self.mutate(key: "usemap", value: "#\(value)")
2666+
}
2667+
}
2668+
2669+
extension UseMapAttribute where Self: EmptyNode {
2670+
2671+
internal func mutate(usemap value: String) -> Self {
2672+
return self.mutate(key: "usemap", value: "#\(value)")
2673+
}
2674+
}
2675+
26412676
/// The protocol provides the element with the value handler.
26422677
@_documentation(visibility: internal)
26432678
public protocol ValueAttribute: Attribute {

Sources/HTMLKit/Abstraction/Elements/BodyElements.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15617,7 +15617,7 @@ public struct Image: EmptyNode, HtmlElement, BodyElement, FormElement, FigureEle
1561715617
}
1561815618
}
1561915619

15620-
extension Image: GlobalAttributes, GlobalEventAttributes, GlobalAriaAttributes, AlternateAttribute, SourceAttribute, SizesAttribute, WidthAttribute, HeightAttribute, ReferrerPolicyAttribute, FetchPriorityAttribute & LoadingAttribute & SourceSetAttribute & DecodingAttribute & IsMapAttribute {
15620+
extension Image: GlobalAttributes, GlobalEventAttributes, GlobalAriaAttributes, AlternateAttribute, SourceAttribute, SizesAttribute, WidthAttribute, HeightAttribute, ReferrerPolicyAttribute, FetchPriorityAttribute & LoadingAttribute & SourceSetAttribute & DecodingAttribute & IsMapAttribute & UseMapAttribute {
1562115621

1562215622
public func accessKey(_ value: Character) -> Image {
1562315623
return mutate(accesskey: value)
@@ -15798,6 +15798,10 @@ extension Image: GlobalAttributes, GlobalEventAttributes, GlobalAriaAttributes,
1579815798
return mutate(popover: value.rawValue)
1579915799
}
1580015800

15801+
public func useMap(_ value: String) -> Image {
15802+
return mutate(usemap: value)
15803+
}
15804+
1580115805
public func custom(key: String, value: Any) -> Image {
1580215806
return mutate(key: key, value: value)
1580315807
}

Tests/HTMLKitTests/AttributesTests.swift

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ final class AttributesTests: XCTestCase {
1414
@ContentBuilder<Content> var body: Content
1515
}
1616

17-
typealias AllAttributes = AccessKeyAttribute & AcceptAttribute & ActionAttribute & AlternateAttribute & AsynchronouslyAttribute & AutocapitalizeAttribute & AutocompleteAttribute & AutofocusAttribute & AutoplayAttribute & CharsetAttribute & CheckedAttribute & CiteAttribute & ClassAttribute & ColumnsAttribute & ColumnSpanAttribute & ContentAttribute & EditAttribute & ControlsAttribute & CoordinatesAttribute & DataAttribute & DateTimeAttribute & DefaultAttribute & DeferAttribute & DirectionAttribute & DisabledAttribute & DownloadAttribute & DragAttribute & EncodingAttribute & EnterKeyHintAttribute & ForAttribute & FormAttribute & FormActionAttribute & EquivalentAttribute & HeaderAttribute & HeightAttribute & HiddenAttribute & HighAttribute & ReferenceAttribute & ReferenceLanguageAttribute & IdentifierAttribute & IsMapAttribute & InputModeAttribute & IsAttribute & ItemIdAttribute & ItemPropertyAttribute & ItemReferenceAttribute & ItemScopeAttribute & ItemTypeAttribute & 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 & ReadyOnlyAttribute & 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 & AriaAtomicAttribute & AriaBusyAttribute & AriaControlsAttribute & AriaCurrentAttribute & AriaDescribedAttribute & AriaDetailsAttribute & AriaDisabledAttribute & AriaErrorMessageAttribute & AriaFlowToAttribute & AriaPopupAttribute & AriaHiddenAttribute & AriaInvalidAttribute & AriaShortcutsAttribute & AriaLabelAttribute & AriaLabeledAttribute & AriaLiveAttribute & AriaOwnsAttribute & AriaRelevantAttribute & AriaRoleDescriptionAttribute & DrawAttribute & FillAttribute & FillOpacityAttribute & StrokeAttribute & StrokeWidthAttribute & StrokeOpacityAttribute & StrokeLineCapAttribute & StrokeLineJoinAttribute & RadiusAttribute & PositionPointAttribute & RadiusPointAttribute & CenterPointAttribute & ViewBoxAttribute & NamespaceAttribute & PointsAttribute & ShadowRootModeAttribute & InertAttribute & FetchPriorityAttribute & LoadingAttribute & SourceSetAttribute & DecodingAttribute & BlockingAttribute & PopoverAttribute & PopoverTargetAttribute & PopoverActionAttribute
17+
typealias AllAttributes = AccessKeyAttribute & AcceptAttribute & ActionAttribute & AlternateAttribute & AsynchronouslyAttribute & AutocapitalizeAttribute & AutocompleteAttribute & AutofocusAttribute & AutoplayAttribute & CharsetAttribute & CheckedAttribute & CiteAttribute & ClassAttribute & ColumnsAttribute & ColumnSpanAttribute & ContentAttribute & EditAttribute & ControlsAttribute & CoordinatesAttribute & DataAttribute & DateTimeAttribute & DefaultAttribute & DeferAttribute & DirectionAttribute & DisabledAttribute & DownloadAttribute & DragAttribute & EncodingAttribute & EnterKeyHintAttribute & ForAttribute & FormAttribute & FormActionAttribute & EquivalentAttribute & HeaderAttribute & HeightAttribute & HiddenAttribute & HighAttribute & ReferenceAttribute & ReferenceLanguageAttribute & IdentifierAttribute & IsMapAttribute & InputModeAttribute & IsAttribute & ItemIdAttribute & ItemPropertyAttribute & ItemReferenceAttribute & ItemScopeAttribute & ItemTypeAttribute & 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 & ReadyOnlyAttribute & 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 & AriaAtomicAttribute & AriaBusyAttribute & AriaControlsAttribute & AriaCurrentAttribute & AriaDescribedAttribute & AriaDetailsAttribute & AriaDisabledAttribute & AriaErrorMessageAttribute & AriaFlowToAttribute & AriaPopupAttribute & AriaHiddenAttribute & AriaInvalidAttribute & AriaShortcutsAttribute & AriaLabelAttribute & AriaLabeledAttribute & AriaLiveAttribute & AriaOwnsAttribute & AriaRelevantAttribute & AriaRoleDescriptionAttribute & DrawAttribute & FillAttribute & FillOpacityAttribute & StrokeAttribute & StrokeWidthAttribute & StrokeOpacityAttribute & StrokeLineCapAttribute & StrokeLineJoinAttribute & RadiusAttribute & PositionPointAttribute & RadiusPointAttribute & CenterPointAttribute & ViewBoxAttribute & NamespaceAttribute & PointsAttribute & ShadowRootModeAttribute & InertAttribute & FetchPriorityAttribute & LoadingAttribute & SourceSetAttribute & DecodingAttribute & BlockingAttribute & PopoverAttribute & PopoverTargetAttribute & PopoverActionAttribute & UseMapAttribute
1818

1919
struct Tag: ContentNode, GlobalElement, AllAttributes {
2020

@@ -591,6 +591,10 @@ final class AttributesTests: XCTestCase {
591591
return self.mutate(popoveraction: value.rawValue)
592592
}
593593

594+
func useMap(_ id: String) -> Tag {
595+
return mutate(usemap: id)
596+
}
597+
594598
func custom(key: String, value: Any) -> Tag {
595599
return self.mutate(key: key, value: value)
596600
}
@@ -1991,6 +1995,19 @@ final class AttributesTests: XCTestCase {
19911995
)
19921996
}
19931997

1998+
func testUseMapAttribute() throws {
1999+
2000+
let view = TestView {
2001+
Tag {}.useMap("image_map")
2002+
}
2003+
2004+
XCTAssertEqual(try renderer.render(view: view),
2005+
"""
2006+
<tag usemap="#image_map"></tag>
2007+
"""
2008+
)
2009+
}
2010+
19942011
func testSelectedAttribute() throws {
19952012

19962013
let view = TestView {

0 commit comments

Comments
 (0)