Skip to content

Commit

Permalink
HTML: Constrain <form>-specific elements to BodyContext (#44)
Browse files Browse the repository at this point in the history
This change moves the APIs for creating what can be seen as “form-specific”
HTML elements (such as `<input>` and `<fieldset>`) from an extension
constrained to `HTML.FormContext` to the main `HTML.BodyContext` instead.
This enables such elements to be mixed and matched with other body elements,
such as `<div>`.

While such elements might most often appear within forms, there’s nothing
within the HTML spec that enforces that, so neither should Plot.
  • Loading branch information
JohnSundell authored May 9, 2020
1 parent 9e53175 commit 61e8289
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 22 deletions.
40 changes: 18 additions & 22 deletions Sources/Plot/API/HTMLElements.swift
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,12 @@ public extension Node where Context: HTML.BodyContext {
.selfClosedElement(named: "embed", attributes: attributes)
}

/// Add a `<fieldset>` HTML element within the current context.
/// - parameter nodes: The element's attributes and child elements.
static func fieldset(_ nodes: Node<HTML.FormContext>...) -> Node {
.element(named: "fieldset", nodes: nodes)
}

/// Add a `<form>` HTML element within the current context.
/// - parameter nodes: The element's attributes and child elements.
static func form(_ nodes: Node<HTML.FormContext>...) -> Node {
Expand Down Expand Up @@ -259,6 +265,12 @@ public extension Node where Context: HTML.BodyContext {
.element(named: "iframe", attributes: attributes)
}

/// Add an `<input/>` HTML element within the current context.
/// - parameter nodes: The element's attributes.
static func input(_ attributes: Attribute<HTML.InputContext>...) -> Node {
.selfClosedElement(named: "input", attributes: attributes)
}

/// Add an `<ins>` HTML element within the current context.
/// - parameter nodes: The element's attributes and child elements.
static func ins(_ nodes: Node<HTML.BodyContext>...) -> Node {
Expand Down Expand Up @@ -349,6 +361,12 @@ public extension Node where Context: HTML.BodyContext {
.element(named: "table", nodes: nodes)
}

/// Add a `<textarea>` HTML element within the current context.
/// - parameter nodes: The element's attributes and nodes.
static func textarea(_ nodes: Node<HTML.TextAreaContext>...) -> Node {
.element(named: "textarea", nodes: nodes)
}

/// Add a `<u>` HTML element within the current context.
/// - parameter nodes: The element's attributes and child elements.
static func u(_ nodes: Node<HTML.BodyContext>...) -> Node {
Expand Down Expand Up @@ -448,28 +466,6 @@ public extension Node where Context: HTMLSourceListContext {
}
}

// MARK: - Forms

public extension Node where Context == HTML.FormContext {
/// Add a `<fieldset>` HTML element within the current context.
/// - parameter nodes: The element's attributes and child elements.
static func fieldset(_ nodes: Node<HTML.FormContext>...) -> Node {
.element(named: "fieldset", nodes: nodes)
}

/// Add an `<input/>` HTML element within the current context.
/// - parameter nodes: The element's attributes.
static func input(_ attributes: Attribute<HTML.InputContext>...) -> Node {
.selfClosedElement(named: "input", attributes: attributes)
}

/// Add a `<textarea>` HTML element within the current context.
/// - parameter nodes: The element's attributes and nodes.
static func textarea(_ nodes: Node<HTML.TextAreaContext>...) -> Node {
.element(named: "textarea", nodes: nodes)
}
}

// MARK: - Other

public extension Node where Context == HTML.DetailsContext {
Expand Down
23 changes: 23 additions & 0 deletions Tests/PlotTests/HTMLTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,28 @@ final class HTMLTests: XCTestCase {
</body>
""")
}

func testFormWithBodyNodes() {
let html = HTML(.body(
.form(
.method(.post),
.div(
.class("wrapper"),
.p("Text"),
.input(
.type(.submit),
.value("Action")
)
)
)
))

assertEqualHTMLContent(html, """
<body><form method="post"><div class="wrapper">\
<p>Text</p><input type="submit" value="Action"/>\
</div></form></body>
""")
}

func testHeadings() {
let html = HTML(.body(
Expand Down Expand Up @@ -722,6 +744,7 @@ extension HTMLTests {
("testFormContentType", testFormContentType),
("testFormMethod", testFormMethod),
("testFormNoValidate", testFormNoValidate),
("testFormWithBodyNodes", testFormWithBodyNodes),
("testHeadings", testHeadings),
("testParagraph", testParagraph),
("testImage", testImage),
Expand Down

0 comments on commit 61e8289

Please sign in to comment.