Function builder test

This commit is contained in:
2020-03-01 13:19:27 +01:00
parent 6e5c10c089
commit 1f819c925f
6 changed files with 117 additions and 101 deletions

View File

@@ -1,5 +1,14 @@
package nl.astraeus.css.properties package nl.astraeus.css.properties
enum class AlignContentValue(
val value: String
) {
STRETCH("stretch"),
;
fun css() = value
}
class AlignContent( class AlignContent(
value: String value: String
) : CssProperty(value) { ) : CssProperty(value) {

View File

@@ -1,5 +1,7 @@
package nl.astraeus.css.properties package nl.astraeus.css.properties
import kotlin.time.AbstractDoubleTimeSource
open class Measurement( open class Measurement(
value: String value: String
) : CssProperty(value) { ) : CssProperty(value) {
@@ -10,6 +12,7 @@ open class Measurement(
fun inherit() = Measurement("inherit") fun inherit() = Measurement("inherit")
fun normal() = Measurement("normal") fun normal() = Measurement("normal")
fun px(nr: Int) = Measurement("${nr}px") fun px(nr: Int) = Measurement("${nr}px")
fun px(nr: Double) = Measurement("${nr}px")
fun em(nr: Int) = Measurement("${nr}em") fun em(nr: Int) = Measurement("${nr}em")
fun em(nr: Double) = Measurement("${nr}em") fun em(nr: Double) = Measurement("${nr}em")
fun perc(nr: Int) = Measurement("${nr}%") fun perc(nr: Int) = Measurement("${nr}%")
@@ -20,3 +23,10 @@ open class Measurement(
fun cm(nr: Double) = Measurement("${nr}cm") fun cm(nr: Double) = Measurement("${nr}cm")
} }
} }
fun Int.px(): Measurement = Measurement.px(this)
fun Double.px(): Measurement = Measurement.px(this)
fun Int.em(): Measurement = Measurement.em(this)
fun Double.em(): Measurement = Measurement.em(this)
fun Int.perc(): Measurement = Measurement.perc(this)
fun Double.perc(): Measurement = Measurement.perc(this)

View File

@@ -15,6 +15,7 @@ open class FontFace(
override fun getValidator(name: String) = null override fun getValidator(name: String) = null
/*
override fun getMapping(): Map<String, Any?> = mapOf( override fun getMapping(): Map<String, Any?> = mapOf(
"font-family" to fontFamily, "font-family" to fontFamily,
"font-size" to fontSize, "font-size" to fontSize,
@@ -24,4 +25,5 @@ open class FontFace(
"font-weight" to fontWeight, "font-weight" to fontWeight,
"unicode-range" to unicodeRange "unicode-range" to unicodeRange
) )
*/
} }

View File

@@ -10,57 +10,27 @@ annotation class CssTagMarker
abstract class CssGenerator { abstract class CssGenerator {
val definitions: MutableMap<String, Css> = mutableMapOf() val definitions: MutableMap<String, Css> = mutableMapOf()
val extentions: MutableList<Css> = mutableListOf() val properties: MutableMap<String, List<CssProperty>> = mutableMapOf()
abstract fun getMapping(): Map<String, Any?>
abstract fun getValidator(name: String): List<Validator>? abstract fun getValidator(name: String): List<Validator>?
private fun propertyCss(indent: String, name: String, prop: CssProperty, minified: Boolean): String { private fun propertyCss(indent: String, name: String, props: List<CssProperty>, minified: Boolean): String {
val builder = StringBuilder()
getValidator(name)?.forEach { getValidator(name)?.forEach {
if (!it.validate(prop)) { if (!it.validate(props)) {
log.warn { "Validate error '$name' - ${it.getMessage(name)}" } log.warn { "Validate error '$name' - ${it.getMessage(name)}" }
} }
} }
return if (!minified) { for (prop in props) {
val paddedName = StringBuilder() if (builder.isNotEmpty()) {
paddedName.append(indent) builder.append(",")
paddedName.append(name) if (!minified) {
paddedName.append(":") builder.append(" ")
while (paddedName.length < 32) {
paddedName.append(' ')
}
"$paddedName${prop.css()};\n"
} else {
"$name:${prop.css()};"
}
}
private fun propertyCss(indent: String, name: String, props: List<*>, minified: Boolean): String {
val builder = StringBuilder()
getValidator(name)?.forEach {
if (!it.validate(props as List<CssProperty>)) {
log.warn { "Validate error '$name' - ${it.getListMessage(name)}" }
}
}
for ((index, prop) in props.withIndex()) {
if (prop is CssProperty) {
getValidator(name)?.forEach {
if (!it.validate(prop)) {
log.warn { "Validate error '$name' - ${it.getMessage(name)}" }
}
} }
if (builder.isNotEmpty()) {
builder.append(",")
if (!minified) {
builder.append(" ")
}
}
builder.append(prop.css())
} }
builder.append(prop.css())
} }
return if (!minified) { return if (!minified) {
@@ -80,12 +50,8 @@ abstract class CssGenerator {
fun generatePropertyCss(indent: String, minified: Boolean): String { fun generatePropertyCss(indent: String, minified: Boolean): String {
val builder = StringBuilder() val builder = StringBuilder()
for ((name, prop) in getMapping()) { for ((name, prop) in properties) {
if (prop is List<*> && prop.isNotEmpty()) { builder.append(propertyCss(indent, name, prop, minified))
builder.append(propertyCss(indent, name, prop, minified))
} else if (prop is CssProperty) {
builder.append(propertyCss(indent, name, prop, minified))
}
} }
return builder.toString() return builder.toString()
@@ -145,6 +111,7 @@ abstract class CssGenerator {
@CssTagMarker @CssTagMarker
open class Style( open class Style(
/*
var alignContent: AlignContent? = null, var alignContent: AlignContent? = null,
var alignItems: AlignItems? = null, var alignItems: AlignItems? = null,
var alignSelf: AlignSelf? = null, var alignSelf: AlignSelf? = null,
@@ -248,10 +215,12 @@ open class Style(
var fontSize: FontSize? = null, var fontSize: FontSize? = null,
var height: Measurement? = null, var height: Measurement? = null,
var left: Measurement? = null, var left: Measurement? = null,
var margin: List<Measurement>? = null,
var top: Measurement? = null, var top: Measurement? = null,
var transitionDelay: DelayDuration? = null, var transitionDelay: DelayDuration? = null,
var transitionDuration: DelayDuration? = null, var transitionDuration: DelayDuration? = null,
var width: Measurement? = null var width: Measurement? = null
*/
) : CssGenerator() { ) : CssGenerator() {
var fontFace: FontFace? = null var fontFace: FontFace? = null
private val validators = mapOf<String, List<Validator>>( private val validators = mapOf<String, List<Validator>>(
@@ -270,6 +239,7 @@ open class Style(
override fun getValidator(name: String) = validators[name] override fun getValidator(name: String) = validators[name]
/*
override fun getMapping(): Map<String, Any?> = mapOf( override fun getMapping(): Map<String, Any?> = mapOf(
"align-content" to alignContent, "align-content" to alignContent,
"align-items" to alignItems, "align-items" to alignItems,
@@ -369,11 +339,13 @@ open class Style(
"font-size" to fontSize, "font-size" to fontSize,
"height" to height, "height" to height,
"left" to left, "left" to left,
"margin" to margin,
"top" to top, "top" to top,
"transition-delay" to transitionDelay, "transition-delay" to transitionDelay,
"transition-duration" to transitionDuration, "transition-duration" to transitionDuration,
"width" to width "width" to width
) )
*/
fun select(selector: String, style: Css) { fun select(selector: String, style: Css) {
definitions[selector] = style definitions[selector] = style
@@ -388,4 +360,20 @@ open class Style(
face.invoke(fontFace!!) face.invoke(fontFace!!)
} }
fun alignContent(value: AlignContentValue) {
properties["align-content"] = listOf(CssProperty(value.css()))
}
fun margin(all: Measurement) {
properties["margin"] = listOf(all)
}
fun margin(topBottom: Measurement, leftRight: Measurement) {
properties["margin"] = listOf(topBottom, leftRight)
}
fun margin(top: Measurement, right: Measurement, bottom: Measurement, left: Measurement) {
properties["margin"] = listOf(top, right, bottom, left)
}
} }

View File

@@ -4,14 +4,10 @@ import nl.astraeus.css.properties.CssProperty
abstract class Validator { abstract class Validator {
open fun validate(property: CssProperty): Boolean = true
open fun validate(properties: List<CssProperty>): Boolean = true open fun validate(properties: List<CssProperty>): Boolean = true
open fun getMessage(name: String): String = "'$name' validation message not defined for $this" open fun getMessage(name: String): String = "'$name' validation message not defined for $this"
open fun getListMessage(name: String): String = "'$name' validation message not defined for $this"
} }
class MaxCountValidator( class MaxCountValidator(
@@ -20,7 +16,7 @@ class MaxCountValidator(
override fun validate(property: List<CssProperty>): Boolean = property.size <= number override fun validate(property: List<CssProperty>): Boolean = property.size <= number
override fun getListMessage(name: String): String = "'$name' should not have more than 4 entries" override fun getMessage(name: String): String = "'$name' should not have more than 4 entries"
} }
@@ -36,6 +32,6 @@ class InitialInheritSingleValue: Validator() {
return true return true
} }
override fun getListMessage(name: String): String = "'$name' can only have single value when 'initial' or 'inherit'" override fun getMessage(name: String): String = "'$name' can only have single value when 'initial' or 'inherit'"
} }

View File

@@ -2,6 +2,7 @@ package nl.astraeus.css
import nl.astraeus.css.properties.* import nl.astraeus.css.properties.*
import nl.astraeus.css.properties.AlignContent.Companion.flexStart import nl.astraeus.css.properties.AlignContent.Companion.flexStart
import nl.astraeus.css.properties.AlignContentValue.*
import nl.astraeus.css.style.Css import nl.astraeus.css.style.Css
import nl.astraeus.css.style.Style import nl.astraeus.css.style.Style
@@ -17,10 +18,10 @@ private fun Style.sizePX(
width: Int, width: Int,
height: Int height: Int
) { ) {
this@sizePX.top = Measurement.px(top) // this@sizePX.top = Measurement.px(top)
this@sizePX.left = Measurement.px(left) // this@sizePX.left = Measurement.px(left)
this@sizePX.width = Measurement.px(width) // this@sizePX.width = Measurement.px(width)
this@sizePX.height = Measurement.px(height) // this@sizePX.height = Measurement.px(height)
} }
private fun generateCss( private fun generateCss(
@@ -30,34 +31,34 @@ private fun generateCss(
css.style { css.style {
select("body") { select("body") {
fontFamily = base.mainFont // fontFamily = base.mainFont
color = base.mainColor // color = base.mainColor
backgroundColor = base.mainBackgroundColor // backgroundColor = base.mainBackgroundColor
} }
select(".test") { select(".test") {
top = Measurement.px(10) // top = Measurement.px(10)
left = Measurement.em(5) // left = Measurement.em(5)
backgroundColor = Color.rgba(255, 255, 255, 0.75) // backgroundColor = Color.rgba(255, 255, 255, 0.75)
select("> a") { select("> a") {
color = Color.hsl(200, 50, 50) // color = Color.hsl(200, 50, 50)
} }
} }
select("nav") { select("nav") {
select("ul") { select("ul") {
color = Color.hsl(0, 100, 25) // color = Color.hsl(0, 100, 25)
backgroundColor = base.mainBackgroundColor // backgroundColor = base.mainBackgroundColor
} }
select("li") { select("li") {
sizePX(25, 25, 200, 200) sizePX(25, 25, 200, 200)
select("a") { select("a") {
width = Measurement.px(725) // width = Measurement.px(725)
background = text("red initial") // background = text("red initial")
backgroundColor = base.mainBackgroundColor // backgroundColor = base.mainBackgroundColor
all = All.initial() // all = All.initial()
} }
} }
} }
@@ -78,29 +79,29 @@ fun main() {
println(css2) println(css2)
val border = css { val border = css {
borderRadius = BorderRadius(1, 2, 3, 4) // borderRadius = BorderRadius(1, 2, 3, 4)
borderColor = listOf(Color.hsl(22,66,55)) // borderColor = listOf(Color.hsl(22,66,55))
select("a") { select("a") {
width = Measurement.px(10) // width = Measurement.px(10)
} }
} }
val border2: Css = { val border2: Css = {
borderRadius = BorderRadius(1, 2, 3, 4) // borderRadius = BorderRadius(1, 2, 3, 4)
borderColor = listOf(Color.hsl(20,60,50)) // borderColor = listOf(Color.hsl(20,60,50))
} }
val font: Css = { val font: Css = {
fontFamily = text("Arial, Courier") // fontFamily = text("Arial, Courier")
fontSize = FontSize.larger() // fontSize = FontSize.larger()
} }
val sd = style { val sd = style {
select("#pipo") { select("#pipo") {
backgroundColor = Color.hex("eeeeee") // backgroundColor = Color.hex("eeeeee")
fontFamily = text("Arial, Courier") // fontFamily = text("Arial, Courier")
animationDelay = listOf(DelayDuration.initial()) // animationDelay = listOf(DelayDuration.initial())
select("div") { select("div") {
fontFace { fontFace {
@@ -112,56 +113,66 @@ fun main() {
fontWeight = FontWeight._600() fontWeight = FontWeight._600()
} }
fontFamily = text("SanSation") // fontFamily = text("SanSation")
color = Color.hex("1b1b1b1") // color = Color.hex("1b1b1b1")
alignContent = flexStart() // alignContent = flexStart()
animationName = listOf( // animationName = listOf(
text("foo"), // text("foo"),
text("bar") // text("bar")
) // )
select("span") { select("span") {
animationIterationCount = listOf( // animationIterationCount = listOf(
Count.count(3), // Count.count(3),
Count.infinite() // Count.infinite()
) // )
animationTimingFunction = listOf( // animationTimingFunction = listOf(
AnimationTimingFunction.cubicBezier(0.1, 0.2, 0.3, 0.4), // AnimationTimingFunction.cubicBezier(0.1, 0.2, 0.3, 0.4),
AnimationTimingFunction.easeInOut() // AnimationTimingFunction.easeInOut()
) // )
} }
select("border-0") { select("border-0") {
apply(border) apply(border)
borderRadius = BorderRadius(4, 5, 6, 7) // borderRadius = BorderRadius(4, 5, 6, 7)
} }
select("border-1") { select("border-1") {
apply(border2) apply(border2)
borderRadius = BorderRadius(4, 5, 6, 7) // borderRadius = BorderRadius(4, 5, 6, 7)
} }
select("border-2") { select("border-2") {
borderRadius = BorderRadius(4, 5, 6, 7) // borderRadius = BorderRadius(4, 5, 6, 7)
apply(border2) apply(border2)
display = Display.none() // display = Display.none()
borderBottomWidth = BorderWidth.perc(13) // borderBottomWidth = BorderWidth.perc(13)
} }
} }
} }
} }
val borderStyle = style { val borderStyle = style {
select(".border") { select(".border") {
apply(border) apply(border)
apply(font) apply(font)
select("> p") { select("> p") {
fontSize = FontSize.smaller() // fontSize = FontSize.smaller()
} }
} }
} }
val test = style {
select("nav") {
alignContent(STRETCH)
margin(0.px(), 2.em(), 0.5.px(), Measurement.auto())
}
}
println("======") println("======")
println(sd.generateCss()) println(sd.generateCss())
println("======") println("======")
println(sd.generateCss(minified = true)) println(sd.generateCss(minified = true))
println("======") println("======")
println(borderStyle.generateCss()) println(borderStyle.generateCss())
println("======")
println(test.generateCss())
} }