diff --git a/Sources/HTMLKit/Abstraction/Attributes/BasicAttributes.swift b/Sources/HTMLKit/Abstraction/Attributes/BasicAttributes.swift
index d28141b6..28410196 100644
--- a/Sources/HTMLKit/Abstraction/Attributes/BasicAttributes.swift
+++ b/Sources/HTMLKit/Abstraction/Attributes/BasicAttributes.swift
@@ -4159,3 +4159,66 @@ extension PopoverTargetAttribute where Self: EmptyNode {
return self.mutate(key: "popovertargetaction", value: value)
}
}
+
+/// A type that provides the `abbreviated` modifier.
+@_documentation(visibility: internal)
+public protocol AbbreviatedAttribute: Attribute {
+
+ /// Announce a brief alternate label.
+ ///
+ /// ```
+ /// HeaderCell {
+ /// "Lorem ipsum..."
+ /// }
+ /// .abbreviated("Lorem Ipsum")
+ /// ```
+ ///
+ /// - Parameter value: The alternate label to describe the content.
+ ///
+ /// - Returns: The element
+ func abbreviated(_ value: String) -> Self
+
+ /// Announce a brief localized alternate label.
+ ///
+ /// ```
+ /// HeaderCell {
+ /// "Lorem ipsum..."
+ /// }
+ /// .abbreviated("Lorem Ipsum")
+ /// ```
+ ///
+ /// - Parameters:
+ /// - localizedKey: The string key to be translated.
+ /// - tableName: The translation table to look in.
+ ///
+ /// - Returns: The element
+ func abbreviated(_ localizedKey: LocalizedStringKey, tableName: String?) -> Self
+
+ /// Announce a brief alternate label without localization.
+ ///
+ /// ```
+ /// HeaderCell {
+ /// "Lorem ipsum..."
+ /// }
+ /// .abbreviated(verbatim: "Lorem Ipsum")
+ /// ```
+ ///
+ /// - Parameter value: The alternate label to describe the content.
+ ///
+ /// - Returns: The element
+ func abbreviated(verbatim value: String) -> Self
+}
+
+extension AbbreviatedAttribute where Self: ContentNode {
+
+ internal func mutate(abbr value: AttributeData) -> Self {
+ return self.mutate(key: "abbr", value: value)
+ }
+}
+
+extension AbbreviatedAttribute where Self: EmptyNode {
+
+ internal func mutate(abbr value: AttributeData) -> Self {
+ return self.mutate(key: "abbr", value: value)
+ }
+}
diff --git a/Sources/HTMLKit/Abstraction/Elements/TableElements.swift b/Sources/HTMLKit/Abstraction/Elements/TableElements.swift
index 139c799d..bff14b86 100644
--- a/Sources/HTMLKit/Abstraction/Elements/TableElements.swift
+++ b/Sources/HTMLKit/Abstraction/Elements/TableElements.swift
@@ -3984,7 +3984,7 @@ public struct HeaderCell: ContentNode, TableElement {
}
}
-extension HeaderCell: GlobalAttributes, GlobalEventAttributes, GlobalAccessibilityAttributes, ColumnSpanAttribute, RowSpanAttribute, HeadersAttribute, ScopeAttribute, ColumnIndexAccessibilityAttribute {
+extension HeaderCell: GlobalAttributes, GlobalEventAttributes, GlobalAccessibilityAttributes, ColumnSpanAttribute, RowSpanAttribute, HeadersAttribute, ScopeAttribute, ColumnIndexAccessibilityAttribute, AbbreviatedAttribute {
public func accessKey(_ value: Character) -> HeaderCell {
return mutate(accesskey: .init("\(value)", context: .trusted))
@@ -4191,6 +4191,19 @@ extension HeaderCell: GlobalAttributes, GlobalEventAttributes, GlobalAccessibili
return mutate(popover: .init(value.rawValue, context: .trusted))
}
+ @_disfavoredOverload
+ public func abbreviated(_ value: String) -> HeaderCell {
+ return mutate(abbr: .init(value, context: .tainted(.html)))
+ }
+
+ public func abbreviated(_ localizedKey: LocalizedStringKey, tableName: String? = nil) -> HeaderCell {
+ return mutate(abbr: .init(LocalizedString(key: localizedKey, table: tableName), context: .tainted(.html)))
+ }
+
+ public func abbreviated(verbatim value: String) -> HeaderCell {
+ return mutate(abbr: .init(value, context: .tainted(.html)))
+ }
+
public func custom(key: String, value: String, context: EscapeContext = .tainted(.html)) -> HeaderCell {
return mutate(key: key, value: .init(value, context: context))
}
diff --git a/Tests/HTMLKitTests/AttributesTests.swift b/Tests/HTMLKitTests/AttributesTests.swift
index 6e2d0ec5..09389a03 100644
--- a/Tests/HTMLKitTests/AttributesTests.swift
+++ b/Tests/HTMLKitTests/AttributesTests.swift
@@ -15,7 +15,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
+ 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
struct Tag: ContentNode, GlobalElement, AllAttributes {
@@ -1172,6 +1172,19 @@ final class AttributesTests: XCTestCase {
return self
}
+
+ @_disfavoredOverload
+ func abbreviated(_ value: String) -> Tag {
+ return self.mutate(abbr: .init(value, context: .tainted(.html)))
+ }
+
+ func abbreviated(_ localizedKey: HTMLKit.LocalizedStringKey, tableName: String? = nil) -> Tag {
+ return self.mutate(abbr: .init(LocalizedString(key: localizedKey, table: tableName), context: .tainted(.html)))
+ }
+
+ func abbreviated(verbatim value: String) -> Tag {
+ return self.mutate(abbr: .init(value, context: .tainted(.html)))
+ }
}
var renderer = Renderer()
@@ -3811,4 +3824,17 @@ final class AttributesTests: XCTestCase {
"""
)
}
+
+ func testAbbreviatedAttribute() throws {
+
+ let view = TestView {
+ Tag {}.abbreviated("HTML")
+ }
+
+ XCTAssertEqual(try renderer.render(view: view),
+ """
+
+ """
+ )
+ }
}