Function builder test
This commit is contained in:
@@ -1,5 +1,14 @@
|
||||
package nl.astraeus.css.properties
|
||||
|
||||
enum class AlignContentValue(
|
||||
val value: String
|
||||
) {
|
||||
STRETCH("stretch"),
|
||||
;
|
||||
|
||||
fun css() = value
|
||||
}
|
||||
|
||||
class AlignContent(
|
||||
value: String
|
||||
) : CssProperty(value) {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package nl.astraeus.css.properties
|
||||
|
||||
import kotlin.time.AbstractDoubleTimeSource
|
||||
|
||||
open class Measurement(
|
||||
value: String
|
||||
) : CssProperty(value) {
|
||||
@@ -10,6 +12,7 @@ open class Measurement(
|
||||
fun inherit() = Measurement("inherit")
|
||||
fun normal() = Measurement("normal")
|
||||
fun px(nr: Int) = Measurement("${nr}px")
|
||||
fun px(nr: Double) = Measurement("${nr}px")
|
||||
fun em(nr: Int) = Measurement("${nr}em")
|
||||
fun em(nr: Double) = Measurement("${nr}em")
|
||||
fun perc(nr: Int) = Measurement("${nr}%")
|
||||
@@ -20,3 +23,10 @@ open class Measurement(
|
||||
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)
|
||||
|
||||
@@ -15,6 +15,7 @@ open class FontFace(
|
||||
|
||||
override fun getValidator(name: String) = null
|
||||
|
||||
/*
|
||||
override fun getMapping(): Map<String, Any?> = mapOf(
|
||||
"font-family" to fontFamily,
|
||||
"font-size" to fontSize,
|
||||
@@ -24,4 +25,5 @@ open class FontFace(
|
||||
"font-weight" to fontWeight,
|
||||
"unicode-range" to unicodeRange
|
||||
)
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -10,57 +10,27 @@ annotation class CssTagMarker
|
||||
|
||||
abstract class CssGenerator {
|
||||
val definitions: MutableMap<String, Css> = mutableMapOf()
|
||||
val extentions: MutableList<Css> = mutableListOf()
|
||||
|
||||
abstract fun getMapping(): Map<String, Any?>
|
||||
val properties: MutableMap<String, List<CssProperty>> = mutableMapOf()
|
||||
|
||||
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 {
|
||||
if (!it.validate(prop)) {
|
||||
if (!it.validate(props)) {
|
||||
log.warn { "Validate error '$name' - ${it.getMessage(name)}" }
|
||||
}
|
||||
}
|
||||
|
||||
return if (!minified) {
|
||||
val paddedName = StringBuilder()
|
||||
paddedName.append(indent)
|
||||
paddedName.append(name)
|
||||
paddedName.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)}" }
|
||||
}
|
||||
for (prop in props) {
|
||||
if (builder.isNotEmpty()) {
|
||||
builder.append(",")
|
||||
if (!minified) {
|
||||
builder.append(" ")
|
||||
}
|
||||
if (builder.isNotEmpty()) {
|
||||
builder.append(",")
|
||||
if (!minified) {
|
||||
builder.append(" ")
|
||||
}
|
||||
}
|
||||
builder.append(prop.css())
|
||||
}
|
||||
builder.append(prop.css())
|
||||
}
|
||||
|
||||
return if (!minified) {
|
||||
@@ -80,12 +50,8 @@ abstract class CssGenerator {
|
||||
fun generatePropertyCss(indent: String, minified: Boolean): String {
|
||||
val builder = StringBuilder()
|
||||
|
||||
for ((name, prop) in getMapping()) {
|
||||
if (prop is List<*> && prop.isNotEmpty()) {
|
||||
builder.append(propertyCss(indent, name, prop, minified))
|
||||
} else if (prop is CssProperty) {
|
||||
builder.append(propertyCss(indent, name, prop, minified))
|
||||
}
|
||||
for ((name, prop) in properties) {
|
||||
builder.append(propertyCss(indent, name, prop, minified))
|
||||
}
|
||||
|
||||
return builder.toString()
|
||||
@@ -145,6 +111,7 @@ abstract class CssGenerator {
|
||||
|
||||
@CssTagMarker
|
||||
open class Style(
|
||||
/*
|
||||
var alignContent: AlignContent? = null,
|
||||
var alignItems: AlignItems? = null,
|
||||
var alignSelf: AlignSelf? = null,
|
||||
@@ -248,10 +215,12 @@ open class Style(
|
||||
var fontSize: FontSize? = null,
|
||||
var height: Measurement? = null,
|
||||
var left: Measurement? = null,
|
||||
var margin: List<Measurement>? = null,
|
||||
var top: Measurement? = null,
|
||||
var transitionDelay: DelayDuration? = null,
|
||||
var transitionDuration: DelayDuration? = null,
|
||||
var width: Measurement? = null
|
||||
*/
|
||||
) : CssGenerator() {
|
||||
var fontFace: FontFace? = null
|
||||
private val validators = mapOf<String, List<Validator>>(
|
||||
@@ -270,6 +239,7 @@ open class Style(
|
||||
|
||||
override fun getValidator(name: String) = validators[name]
|
||||
|
||||
/*
|
||||
override fun getMapping(): Map<String, Any?> = mapOf(
|
||||
"align-content" to alignContent,
|
||||
"align-items" to alignItems,
|
||||
@@ -369,11 +339,13 @@ open class Style(
|
||||
"font-size" to fontSize,
|
||||
"height" to height,
|
||||
"left" to left,
|
||||
"margin" to margin,
|
||||
"top" to top,
|
||||
"transition-delay" to transitionDelay,
|
||||
"transition-duration" to transitionDuration,
|
||||
"width" to width
|
||||
)
|
||||
*/
|
||||
|
||||
fun select(selector: String, style: Css) {
|
||||
definitions[selector] = style
|
||||
@@ -388,4 +360,20 @@ open class Style(
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,14 +4,10 @@ import nl.astraeus.css.properties.CssProperty
|
||||
|
||||
abstract class Validator {
|
||||
|
||||
open fun validate(property: 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 getListMessage(name: String): String = "'$name' validation message not defined for $this"
|
||||
|
||||
}
|
||||
|
||||
class MaxCountValidator(
|
||||
@@ -20,7 +16,7 @@ class MaxCountValidator(
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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'"
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package nl.astraeus.css
|
||||
|
||||
import nl.astraeus.css.properties.*
|
||||
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.Style
|
||||
|
||||
@@ -17,10 +18,10 @@ private fun Style.sizePX(
|
||||
width: Int,
|
||||
height: Int
|
||||
) {
|
||||
this@sizePX.top = Measurement.px(top)
|
||||
this@sizePX.left = Measurement.px(left)
|
||||
this@sizePX.width = Measurement.px(width)
|
||||
this@sizePX.height = Measurement.px(height)
|
||||
// this@sizePX.top = Measurement.px(top)
|
||||
// this@sizePX.left = Measurement.px(left)
|
||||
// this@sizePX.width = Measurement.px(width)
|
||||
// this@sizePX.height = Measurement.px(height)
|
||||
}
|
||||
|
||||
private fun generateCss(
|
||||
@@ -30,34 +31,34 @@ private fun generateCss(
|
||||
|
||||
css.style {
|
||||
select("body") {
|
||||
fontFamily = base.mainFont
|
||||
color = base.mainColor
|
||||
backgroundColor = base.mainBackgroundColor
|
||||
// fontFamily = base.mainFont
|
||||
// color = base.mainColor
|
||||
// backgroundColor = base.mainBackgroundColor
|
||||
}
|
||||
|
||||
select(".test") {
|
||||
top = Measurement.px(10)
|
||||
left = Measurement.em(5)
|
||||
backgroundColor = Color.rgba(255, 255, 255, 0.75)
|
||||
// top = Measurement.px(10)
|
||||
// left = Measurement.em(5)
|
||||
// backgroundColor = Color.rgba(255, 255, 255, 0.75)
|
||||
|
||||
select("> a") {
|
||||
color = Color.hsl(200, 50, 50)
|
||||
// color = Color.hsl(200, 50, 50)
|
||||
}
|
||||
}
|
||||
|
||||
select("nav") {
|
||||
select("ul") {
|
||||
color = Color.hsl(0, 100, 25)
|
||||
backgroundColor = base.mainBackgroundColor
|
||||
// color = Color.hsl(0, 100, 25)
|
||||
// backgroundColor = base.mainBackgroundColor
|
||||
}
|
||||
select("li") {
|
||||
sizePX(25, 25, 200, 200)
|
||||
|
||||
select("a") {
|
||||
width = Measurement.px(725)
|
||||
background = text("red initial")
|
||||
backgroundColor = base.mainBackgroundColor
|
||||
all = All.initial()
|
||||
// width = Measurement.px(725)
|
||||
// background = text("red initial")
|
||||
// backgroundColor = base.mainBackgroundColor
|
||||
// all = All.initial()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -78,29 +79,29 @@ fun main() {
|
||||
println(css2)
|
||||
|
||||
val border = css {
|
||||
borderRadius = BorderRadius(1, 2, 3, 4)
|
||||
borderColor = listOf(Color.hsl(22,66,55))
|
||||
// borderRadius = BorderRadius(1, 2, 3, 4)
|
||||
// borderColor = listOf(Color.hsl(22,66,55))
|
||||
|
||||
select("a") {
|
||||
width = Measurement.px(10)
|
||||
// width = Measurement.px(10)
|
||||
}
|
||||
}
|
||||
|
||||
val border2: Css = {
|
||||
borderRadius = BorderRadius(1, 2, 3, 4)
|
||||
borderColor = listOf(Color.hsl(20,60,50))
|
||||
// borderRadius = BorderRadius(1, 2, 3, 4)
|
||||
// borderColor = listOf(Color.hsl(20,60,50))
|
||||
}
|
||||
|
||||
val font: Css = {
|
||||
fontFamily = text("Arial, Courier")
|
||||
fontSize = FontSize.larger()
|
||||
// fontFamily = text("Arial, Courier")
|
||||
// fontSize = FontSize.larger()
|
||||
}
|
||||
|
||||
val sd = style {
|
||||
select("#pipo") {
|
||||
backgroundColor = Color.hex("eeeeee")
|
||||
fontFamily = text("Arial, Courier")
|
||||
animationDelay = listOf(DelayDuration.initial())
|
||||
// backgroundColor = Color.hex("eeeeee")
|
||||
// fontFamily = text("Arial, Courier")
|
||||
// animationDelay = listOf(DelayDuration.initial())
|
||||
|
||||
select("div") {
|
||||
fontFace {
|
||||
@@ -112,56 +113,66 @@ fun main() {
|
||||
fontWeight = FontWeight._600()
|
||||
}
|
||||
|
||||
fontFamily = text("SanSation")
|
||||
color = Color.hex("1b1b1b1")
|
||||
alignContent = flexStart()
|
||||
animationName = listOf(
|
||||
text("foo"),
|
||||
text("bar")
|
||||
)
|
||||
// fontFamily = text("SanSation")
|
||||
// color = Color.hex("1b1b1b1")
|
||||
// alignContent = flexStart()
|
||||
// animationName = listOf(
|
||||
// text("foo"),
|
||||
// text("bar")
|
||||
// )
|
||||
select("span") {
|
||||
animationIterationCount = listOf(
|
||||
Count.count(3),
|
||||
Count.infinite()
|
||||
)
|
||||
animationTimingFunction = listOf(
|
||||
AnimationTimingFunction.cubicBezier(0.1, 0.2, 0.3, 0.4),
|
||||
AnimationTimingFunction.easeInOut()
|
||||
)
|
||||
// animationIterationCount = listOf(
|
||||
// Count.count(3),
|
||||
// Count.infinite()
|
||||
// )
|
||||
// animationTimingFunction = listOf(
|
||||
// AnimationTimingFunction.cubicBezier(0.1, 0.2, 0.3, 0.4),
|
||||
// AnimationTimingFunction.easeInOut()
|
||||
// )
|
||||
}
|
||||
select("border-0") {
|
||||
apply(border)
|
||||
borderRadius = BorderRadius(4, 5, 6, 7)
|
||||
// borderRadius = BorderRadius(4, 5, 6, 7)
|
||||
}
|
||||
select("border-1") {
|
||||
apply(border2)
|
||||
borderRadius = BorderRadius(4, 5, 6, 7)
|
||||
// borderRadius = BorderRadius(4, 5, 6, 7)
|
||||
}
|
||||
select("border-2") {
|
||||
borderRadius = BorderRadius(4, 5, 6, 7)
|
||||
// borderRadius = BorderRadius(4, 5, 6, 7)
|
||||
apply(border2)
|
||||
|
||||
display = Display.none()
|
||||
borderBottomWidth = BorderWidth.perc(13)
|
||||
// display = Display.none()
|
||||
// borderBottomWidth = BorderWidth.perc(13)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val borderStyle = style {
|
||||
select(".border") {
|
||||
apply(border)
|
||||
apply(font)
|
||||
|
||||
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(sd.generateCss())
|
||||
println("======")
|
||||
println(sd.generateCss(minified = true))
|
||||
println("======")
|
||||
println(borderStyle.generateCss())
|
||||
println("======")
|
||||
println(test.generateCss())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user