From c27f6857deeb4c4623db294172a8ec572790a9be Mon Sep 17 00:00:00 2001
From: Dave Verwer
Date: Tue, 1 Jun 2021 16:56:34 +0100
Subject: [PATCH] Boolean attributes (#68)
* Change `required` and `autofocus` to be boolean attributes.
* Added `readonly`, `disabled`, and `multiple` boolean attributes to `input` elements.
* Added `readonly ` and `disabled ` attributes to the `textarea` element.
* Added a `placeholder` attribute to the `textarea` element.
* Changed the `allowfullscreen` attribute on the `iframe` element to be a boolean attribute.
* Added an `open` boolean attribute to the `details` element.
* Added the `hidden` boolean attribute as a global attribute.
* Added `checked` boolean attribute to the `input` element.
* Added a `name` to the `file` input element in the form test.
---
Sources/Plot/API/HTMLAttributes.swift | 70 ++++++++++++++++++++++--
Tests/PlotTests/HTMLComponentTests.swift | 4 +-
Tests/PlotTests/HTMLTests.swift | 44 +++++++++++----
3 files changed, 100 insertions(+), 18 deletions(-)
diff --git a/Sources/Plot/API/HTMLAttributes.swift b/Sources/Plot/API/HTMLAttributes.swift
index db87b87..9fa1c3d 100644
--- a/Sources/Plot/API/HTMLAttributes.swift
+++ b/Sources/Plot/API/HTMLAttributes.swift
@@ -74,6 +74,12 @@ public extension Node where Context: HTMLContext {
static func title(_ title: String) -> Node {
.attribute(named: "title", value: title)
}
+
+ /// Assign whether the element should be hidden.
+ /// - parameter isHidden: Whether the element should be hidden or not.
+ static func hidden(_ isHidden: Bool) -> Node {
+ isHidden ? .attribute(named: "hidden") : .empty
+ }
}
public extension Attribute where Context: HTMLNamableContext {
@@ -185,6 +191,16 @@ public extension Node where Context == HTML.AnchorContext {
}
}
+// MARK: - Interactive elements
+
+public extension Node where Context == HTML.DetailsContext {
+ /// Assign whether the details element is opened/expanded.
+ /// - parameter isOpen: Whether the element should be displayed as open.
+ static func open(_ isOpen: Bool) -> Node {
+ isOpen ? .attribute(named: "open") : .empty
+ }
+}
+
// MARK: - Sources and media
public extension Attribute where Context: HTMLSourceContext {
@@ -286,7 +302,7 @@ public extension Attribute where Context == HTML.InputContext {
Attribute(name: "type", value: type.rawValue)
}
- /// Assigns a placeholder to the input field.
+ /// Assign a placeholder to the input field.
/// - parameter placeholder: The placeholder to assign.
static func placeholder(_ placeholder: String) -> Attribute {
Attribute(name: "placeholder", value: placeholder)
@@ -301,13 +317,37 @@ public extension Attribute where Context == HTML.InputContext {
/// Assign whether the element is required before submitting the form.
/// - parameter isRequired: Whether the element is required.
static func required(_ isRequired: Bool) -> Attribute {
- isRequired ? Attribute(name: "required", value: "true") : .empty
+ isRequired ? Attribute(name: "required", value: nil, ignoreIfValueIsEmpty: false) : .empty
}
/// Assign whether the element should be autofocused when the page loads.
/// - parameter isOn: Whether autofocus should be turned on.
static func autofocus(_ isOn: Bool) -> Attribute {
- isOn ? Attribute(name: "autofocus", value: "true") : .empty
+ isOn ? Attribute(name: "autofocus", value: nil, ignoreIfValueIsEmpty: false) : .empty
+ }
+
+ /// Assign whether the element should be read-only.
+ /// - parameter isReadonly: Whether the input is read-only.
+ static func readonly(_ isReadonly: Bool) -> Attribute {
+ isReadonly ? Attribute(name: "readonly", value: nil, ignoreIfValueIsEmpty: false) : .empty
+ }
+
+ /// Assign whether the element should be disabled.
+ /// - parameter isDisabled: Whether the input is disabled.
+ static func disabled(_ isDisabled: Bool) -> Attribute {
+ isDisabled ? Attribute(name: "disabled", value: nil, ignoreIfValueIsEmpty: false) : .empty
+ }
+
+ /// Assign whether the element should allow the selection of multiple values.
+ /// - parameter isMultiple: Whether multiple values are allowed.
+ static func multiple(_ isEnabled: Bool) -> Attribute {
+ isEnabled ? Attribute(name: "multiple", value: nil, ignoreIfValueIsEmpty: false) : .empty
+ }
+
+ /// Assign whether a checkbox or radio input element has an active state.
+ /// - parameter isChecked: Whether the element has an active state.
+ static func checked(_ isChecked: Bool) -> Attribute {
+ isChecked ? Attribute(name: "checked", value: nil, ignoreIfValueIsEmpty: false) : .empty
}
}
@@ -332,16 +372,34 @@ public extension Node where Context == HTML.TextAreaContext {
.attribute(named: "rows", value: String(rows))
}
+ /// Assign a placeholder to the text area.
+ /// - parameter placeholder: The placeholder to assign.
+ static func placeholder(_ placeholder: String) -> Node {
+ .attribute(named: "placeholder", value: placeholder)
+ }
+
/// Assign whether the element is required before submitting the form.
/// - parameter isRequired: Whether the element is required.
static func required(_ isRequired: Bool) -> Node {
- isRequired ? .attribute(named: "required", value: "true") : .empty
+ isRequired ? .attribute(named: "required") : .empty
}
/// Assign whether the element should be autofocused when the page loads.
/// - parameter isOn: Whether autofocus should be turned on.
static func autofocus(_ isOn: Bool) -> Node {
- isOn ? .attribute(named: "autofocus", value: "true") : .empty
+ isOn ? .attribute(named: "autofocus") : .empty
+ }
+
+ /// Assign whether the element should be read-only.
+ /// - parameter isReadonly: Whether the input is read-only.
+ static func readonly(_ isReadonly: Bool) -> Node {
+ isReadonly ? .attribute(named: "readonly") : .empty
+ }
+
+ /// Assign whether the element should be disabled.
+ /// - parameter isDisabled: Whether the input is disabled.
+ static func disabled(_ isDisabled: Bool) -> Node {
+ isDisabled ? .attribute(named: "disabled") : .empty
}
}
@@ -423,7 +481,7 @@ public extension Attribute where Context == HTML.IFrameContext {
/// Assign whether to grant the iframe full screen capabilities.
/// - parameter allow: Whether the iframe should be allowed to go full screen.
static func allowfullscreen(_ allow: Bool) -> Attribute {
- Attribute(name: "allowfullscreen", value: String(allow))
+ allow ? Attribute(name: "allowfullscreen", value: nil, ignoreIfValueIsEmpty: false) : .empty
}
}
diff --git a/Tests/PlotTests/HTMLComponentTests.swift b/Tests/PlotTests/HTMLComponentTests.swift
index 1c6d3d2..42dd660 100644
--- a/Tests/PlotTests/HTMLComponentTests.swift
+++ b/Tests/PlotTests/HTMLComponentTests.swift
@@ -364,7 +364,7 @@ final class HTMLComponentTests: XCTestCase {
\
- \
+ \
+ \
Summary
Text
\
+ Open Summary
Text
\
+ Closed Summary
Text
\
+