Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attempt padding modifier fusion to avoid nested divs #253

Merged
merged 10 commits into from
Jun 21, 2021
21 changes: 11 additions & 10 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
exclude: __Snapshots__
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.5.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- id: detect-private-key
- id: check-merge-conflict
- repo: https://github.com/hodovani/pre-commit-swift
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- id: detect-private-key
- id: check-merge-conflict
- repo: https://github.com/hodovani/pre-commit-swift
rev: master
hooks:
- id: swift-lint
- id: swift-format
- id: swift-lint
- id: swift-format
17 changes: 13 additions & 4 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
"repositoryURL": "https://github.com/swiftwasm/JavaScriptKit.git",
"state": {
"branch": null,
"revision": "ebd9ca04215397f0e3cb72d6e96406a980a424e5",
"version": "0.10.0"
"revision": "b19e7c8b10a2750ed47753e31ed13613171f3294",
"version": "0.10.1"
}
},
{
Expand All @@ -33,8 +33,8 @@
"repositoryURL": "https://github.com/apple/swift-argument-parser",
"state": {
"branch": null,
"revision": "9564d61b08a5335ae0a36f789a7d71493eacadfc",
"version": "0.3.2"
"revision": "986d191f94cec88f6350056da59c2e59e83d1229",
"version": "0.4.3"
}
},
{
Expand All @@ -45,6 +45,15 @@
"revision": "8e0ef8bb7482ab97dcd2cd1d6855bd38921c345d",
"version": "0.1.0"
}
},
{
"package": "SnapshotTesting",
"repositoryURL": "https://github.com/pointfreeco/swift-snapshot-testing.git",
"state": {
"branch": null,
"revision": "f8a9c997c3c1dab4e216a8ec9014e23144cbab37",
"version": "1.9.0"
}
}
]
},
Expand Down
15 changes: 14 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ let package = Package(
.package(url: "https://github.com/OpenCombine/OpenCombine.git", from: "0.12.0"),
.package(url: "https://github.com/swiftwasm/OpenCombineJS.git", .upToNextMinor(from: "0.1.1")),
.package(name: "Benchmark", url: "https://github.com/google/swift-benchmark", from: "0.1.0"),
.package(
name: "SnapshotTesting",
url: "https://github.com/pointfreeco/swift-snapshot-testing.git",
from: "1.9.0"
),
],
targets: [
// Targets are the basic building blocks of a package. A target can define
Expand Down Expand Up @@ -180,7 +185,15 @@ let package = Package(
),
.testTarget(
name: "TokamakStaticHTMLTests",
dependencies: ["TokamakStaticHTML"]
dependencies: [
"TokamakStaticHTML",
.product(
name: "SnapshotTesting",
package: "SnapshotTesting",
condition: .when(platforms: [.macOS, .linux])
),
],
exclude: ["__Snapshots__"]
),
]
)
20 changes: 17 additions & 3 deletions Sources/TokamakCore/Modifiers/PaddingLayout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,30 @@ public struct _PaddingLayout: ViewModifier {
}

public extension View {
func padding(_ insets: EdgeInsets) -> some View {
func padding(_ insets: EdgeInsets) -> ModifiedContent<Self, _PaddingLayout> {
modifier(_PaddingLayout(insets: insets))
}

func padding(_ edges: Edge.Set = .all, _ length: CGFloat? = nil) -> some View {
func padding(_ edges: Edge.Set = .all,
_ length: CGFloat? = nil) -> ModifiedContent<Self, _PaddingLayout>
{
let insets = length.map { EdgeInsets(_all: $0) }
return modifier(_PaddingLayout(edges: edges, insets: insets))
}

func padding(_ length: CGFloat) -> some View {
func padding(_ length: CGFloat) -> ModifiedContent<Self, _PaddingLayout> {
padding(.all, length)
}
}

public extension ModifiedContent where Modifier == _PaddingLayout, Content: View {
func padding(_ length: CGFloat) -> ModifiedContent<Content, _PaddingLayout> {
var layout = modifier
layout.insets?.top += length
layout.insets?.leading += length
layout.insets?.bottom += length
layout.insets?.trailing += length

return ModifiedContent(content: content, modifier: layout)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct MetadataOffset<Pointee> {

func apply(to ptr: UnsafeRawPointer) -> UnsafePointer<Pointee> {
#if arch(wasm32)
return unsafeBitCast(offset, to: UnsafePointer<Pointee>.self)
return UnsafePointer<Pointee>(bitPattern: Int(offset))!
Copy link
Collaborator Author

@MaxDesiatov MaxDesiatov Jun 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes a compiler warning that was previously produced on every build.

#else
return ptr.advanced(by: numericCast(offset)).assumingMemoryBound(to: Pointee.self)
#endif
Expand Down
5 changes: 4 additions & 1 deletion Sources/TokamakStaticHTML/Views/HTML.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@ public extension AnyHTML {
if attributes.isEmpty {
renderedAttributes = ""
} else {
let mappedAttributes = attributes.map { #"\#($0)="\#($1)""# }
let mappedAttributes = attributes
// Exclude empty values to avoid waste of space with `class=""`
.filter { !$1.isEmpty }
.map { #"\#($0)="\#($1)""# }
if shouldSortAttributes {
renderedAttributes = mappedAttributes.sorted().joined(separator: " ")
} else {
Expand Down
166 changes: 21 additions & 145 deletions Tests/TokamakStaticHTMLTests/HTMLTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,153 +15,13 @@
// Created by Max Desiatov on 07/12/2018.
//

#if canImport(SnapshotTesting)

import SnapshotTesting
import TokamakStaticHTML
import XCTest

private let expectedHTML =
#"""
<html>
<head>
<title></title>
<style>
._tokamak-stack > * {
flex-shrink: 0;
}
._tokamak-scrollview-hideindicators {
scrollbar-color: transparent;
scrollbar-width: 0;
}
._tokamak-scrollview-hideindicators::-webkit-scrollbar {
width: 0;
height: 0;
}
._tokamak-list {
list-style: none;
overflow-y: auto;
width: 100%;
height: 100%;
padding: 0;
}
._tokamak-disclosuregroup-label {
cursor: pointer;
}
._tokamak-disclosuregroup-chevron-container {
width: .25em;
height: .25em;
padding: 10px;
display: inline-block;
}
._tokamak-disclosuregroup-chevron {
width: 100%;
height: 100%;
transform: rotate(45deg);
border-right: solid 2px rgba(0, 0, 0, 0.25);
border-top: solid 2px rgba(0, 0, 0, 0.25);
}
._tokamak-disclosuregroup-content {
display: flex;
flex-direction: column;
margin-left: 1em;
}
._tokamak-buttonstyle-reset {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background: transparent;
border: none;
margin: 0;
padding: 0;
font-size: inherit;
}

._tokamak-text-redacted {
position: relative;
}
._tokamak-text-redacted::after {
content: " ";
background-color: rgb(200, 200, 200);
position: absolute;
left: 0;
width: calc(100% + .1em);
height: 1.2em;
border-radius: .1em;
}
._tokamak-geometryreader {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
._tokamak-navigationview {
display: flex;
flex-direction: row;
align-items: stretch;
width: 100%;
height: 100%;
}
._tokamak-navigationview-content {
display: flex; flex-direction: column;
align-items: center; justify-content: center;
flex-grow: 1;
height: 100%;
}

._tokamak-formcontrol {
color-scheme: light dark;
}

._tokamak-link {
text-decoration: none;
}

._tokamak-texteditor {
width: 100%;
height: 100%;
}

@media (prefers-color-scheme:dark) {
._tokamak-text-redacted::after {
background-color: rgb(100, 100, 100);
}

._tokamak-disclosuregroup-chevron {
border-right-color: rgba(255, 255, 255, 0.25);
border-top-color: rgba(255, 255, 255, 0.25);
}
}
</style>
</head>
<body style="margin: 0;display: flex;
width: 100%;
height: 100%;
justify-content: center;
align-items: center;
overflow: hidden;"><div class="_tokamak-stack" style="display: flex; flex-direction: column; align-items: center;
height: 100%;
"><span class="" style="
font-family: system,
-apple-system,
'.SFNSText-Regular',
'San Francisco',
'Roboto',
'Segoe UI',
'Helvetica Neue',
'Lucida Grande',
sans-serif;
color: rgba(0.0, 0.0, 0.0, 1.0);
font-style: normal;
font-weight: 400;
letter-spacing: normal;
vertical-align: baseline;
text-decoration: none;
text-decoration-color: inherit;
text-align: left;">text</span>
<div style="flex-grow: 1; "></div></div></body>
</html>
"""#

final class ReconcilerTests: XCTestCase {
final class HTMLTests: XCTestCase {
struct Model {
let text: Text
}
Expand All @@ -184,6 +44,22 @@ final class ReconcilerTests: XCTestCase {
let resultingHTML = StaticHTMLRenderer(OptionalBody(model: Model(text: Text("text"))))
.render(shouldSortAttributes: true)

XCTAssertEqual(resultingHTML, expectedHTML)
assertSnapshot(matching: resultingHTML, as: .lines)
}

func testPaddingFusion() {
let nestedTwice = StaticHTMLRenderer(
Text("text").padding(10).padding(20)
).render(shouldSortAttributes: true)

assertSnapshot(matching: nestedTwice, as: .lines)

let nestedThrice = StaticHTMLRenderer(
Text("text").padding(20).padding(20).padding(20)
).render(shouldSortAttributes: true)

assertSnapshot(matching: nestedThrice, as: .lines)
}
}

#endif
Loading