More properties and cleanup

This commit is contained in:
2020-02-24 09:47:14 +01:00
parent 1c3ac8f0d0
commit 083f234d82
31 changed files with 827 additions and 413 deletions

View File

@@ -8,4 +8,3 @@ pluginManagement {
}
}
rootProject.name = "kotlin-css-generator"

View File

@@ -1,17 +0,0 @@
package nl.astraeus.css
enum class AlignContent(
val value: String
) : CssProperty {
STRETCH("stretch"),
CENTER("center"),
FLEX_START("flex-start"),
FLEX_END("flex-end"),
SPACE_BETWEEN("space-between"),
SPACE_AROUND("space-around"),
INITIAL("initial"),
INHERIT("inherit"),
;
override fun css(): String = value
}

View File

@@ -1,16 +0,0 @@
package nl.astraeus.css
enum class AlignItems(
val value: String
) : CssProperty {
STRETCH("stretch"),
CENTER("center"),
FLEX_START("flex-start"),
FLEX_END("flex-end"),
BASELINE("baseline"),
INITIAL("initial"),
INHERIT("inherit"),
;
override fun css(): String = value
}

View File

@@ -1,17 +0,0 @@
package nl.astraeus.css
enum class AlignSelf(
val value: String
) : CssProperty {
AUTO("auto"),
STRETCH("stretch"),
CENTER("center"),
FLEX_START("flex-start"),
FLEX_END("flex-end"),
BASELINE("baseline"),
INITIAL("initial"),
INHERIT("inherit"),
;
override fun css(): String = value
}

View File

@@ -1,12 +0,0 @@
package nl.astraeus.css
enum class All(
val value: String
) : CssProperty {
INITIAL("initial"),
INHERIT("inherit"),
UNSET("unset"),
;
override fun css(): String = value
}

View File

@@ -1,29 +0,0 @@
package nl.astraeus.css
enum class AnimationDirection(
val value: String
) : CssProperty {
NORMAL("normal"),
REVERSE("reverse"),
ALTERNATE("alternate"),
ALTERNATE_REVERSE("alternate-reverse"),
INITIAL("initial"),
INHERIT("inherit"),
;
override fun css(): String = value
}
enum class AnimationFillMode(
val value: String
) : CssProperty {
NONE("none"),
FORWARDS("forwards"),
BACKWARDS("backwards"),
BOTH("both"),
INITIAL("initial"),
INHERIT("inherit"),
;
override fun css(): String = value
}

View File

@@ -1,63 +0,0 @@
package nl.astraeus.css
fun hex(hex: String): Color = HexColor(hex)
fun rgb(red: Int, green: Int, blue: Int): Color = RGBColor(red, green, blue)
fun rgba(red: Int, green: Int, blue: Int, alpha: Double): Color = RGBAColor(red, green, blue, alpha)
fun hsl(hue: Int, saturation: Int, lightness: Int): Color = HSLColor(hue, saturation, lightness)
fun hsla(hue: Int, saturation: Int, lightness: Int, alpha: Double): Color = HSLAColor(hue, saturation, lightness, alpha)
open class Color : CssProperty {
override fun css(): String = "#xxxxxx"
}
class HexColor(
val hex: String
) : Color() {
override fun css(): String = "#$hex"
}
class RGBColor(
val red: Int,
val green: Int,
val blue: Int
) : Color() {
override fun css(): String = "rgb($red, $green, $blue)"
}
class RGBAColor(
val red: Int,
val green: Int,
val blue: Int,
val alpha: Double
) : Color() {
override fun css(): String = "rgba($red, $green, $blue, $alpha)"
}
class HSLColor(
val hue: Int,
val saturation: Int,
val lightness: Int
) : Color() {
override fun css(): String = "hsl($hue, $saturation, $lightness)"
}
class HSLAColor(
val hue: Int,
val saturation: Int,
val lightness: Int,
val alpha: Double
) : Color() {
override fun css(): String = "hsla($hue, $saturation, $lightness, $alpha)"
}

View File

@@ -1,30 +0,0 @@
package nl.astraeus.css
enum class CountType {
NUMBER,
INFINITE,
INITIAL,
INHERIT
}
class Count(
val type: CountType,
val number: Int
) : CssProperty {
override fun css(): String = when(type) {
CountType.NUMBER -> "$number"
CountType.INFINITE -> "infinite"
CountType.INITIAL -> "initial"
CountType.INHERIT -> "inherit"
}
companion object {
fun count(number: Int): Count = Count(CountType.NUMBER, number)
fun infinite(): Count = Count(CountType.INFINITE, 0)
fun initial(): Count = Count(CountType.INITIAL, 0)
fun inherit(): Count = Count(CountType.INHERIT, 0)
}
}

View File

@@ -1,113 +1,6 @@
package nl.astraeus.css
@DslMarker
annotation class CssTagMarker
@CssTagMarker
open class Style(
var alignContent: AlignContent? = null,
var alignItems: AlignItems? = null,
var alignSelf: AlignSelf? = null,
var all: All? = null,
var animation: TextProperty? = null,
var animationDelay: DelayDuration? = null,
var animationDirection: AnimationDirection? = null,
var animationDuration: DelayDuration? = null,
var animationFillMode: AnimationFillMode? = null,
var animationIterationCount: Count? = null,
var backgroundColor: Color? = null,
var color: Color? = null,
var fontFamily: TextProperty? = null,
var fontSize: FontSize? = null,
var height: Measurement? = null,
var left: Measurement? = null,
var top: Measurement? = null,
var transitionDelay: DelayDuration? = null,
var transitionDuration: DelayDuration? = null,
var width: Measurement? = null
) {
fun getMapping() = mapOf(
"align-content" to alignContent,
"align-items" to alignItems,
"align-self" to alignSelf,
"all" to all,
"animation" to animation,
"animation-delay" to animationDelay,
"animation-direction" to animationDirection,
"animation-duration" to animationDuration,
"animation-fill-mode" to animationFillMode,
"animation-iteration-count" to animationIterationCount,
"background-color" to backgroundColor,
"color" to color,
"font-family" to fontFamily,
"font-size" to fontSize,
"height" to height,
"left" to left,
"top" to top,
"transition-delay" to transitionDelay,
"transition-duration" to transitionDuration,
"width" to width
)
fun propertyCss(indent: String, name: String, prop: CssProperty?): String = if (prop != null) {
"$indent$name: ${prop.css()};\n"
} else {
""
}
fun generatePropertyCss(indent: String): String {
val builder = StringBuilder()
for ((name, prop) in getMapping()) {
builder.append(propertyCss(indent, name, prop))
}
return builder.toString()
}
}
@CssTagMarker
open class StyleDefinition : Style() {
val definitions: MutableMap<String, StyleDefinition> = mutableMapOf()
val includes: MutableList<Style> = mutableListOf()
fun css(selector: String, style: StyleDefinition.() -> Unit) {
val styleValue = StyleDefinition()
style(styleValue)
definitions[selector] = styleValue
}
fun include(style: Style) {
includes.add(style)
}
open fun generateCss(namespace: String = "", indent: String = " "): String {
val builder = StringBuilder()
for ((name, prop) in definitions) {
val css = StringBuilder()
css.append(prop.generatePropertyCss(indent))
for (style in prop.includes) {
css.append(style.generatePropertyCss(indent))
}
if (css.isNotBlank()) {
builder.append("$namespace $name".trim())
builder.append(" {\n")
builder.append(css)
builder.append("}\n\n")
}
builder.append(prop.generateCss( "${namespace} $name".trim(), indent))
}
return builder.toString()
}
}
import nl.astraeus.css.style.StyleDefinition
fun css(definition: StyleDefinition.() -> Unit): StyleDefinition {
val css = StyleDefinition()
@@ -118,7 +11,8 @@ fun css(definition: StyleDefinition.() -> Unit): StyleDefinition {
}
class CssBuilder {
var definition: StyleDefinition = StyleDefinition()
var definition: StyleDefinition =
StyleDefinition()
fun style(definition: StyleDefinition.() -> Unit) {
definition(this.definition)

View File

@@ -1,17 +0,0 @@
package nl.astraeus.css
interface CssProperty {
fun css(): String
}
fun text(value: String) = TextProperty(value)
class TextProperty(
val value: String
): CssProperty {
override fun css(): String = value
}

View File

@@ -1,25 +0,0 @@
package nl.astraeus.css
enum class DelayDurationType {
TIME,
INITIAL,
INHERIT
}
class DelayDuration(
val type: DelayDurationType,
val seconds: Int
) : CssProperty {
override fun css(): String = when(type) {
DelayDurationType.TIME -> "${seconds}s"
DelayDurationType.INITIAL -> "initial"
DelayDurationType.INHERIT -> "inherit"
}
}
fun seconds(seconds: Int): DelayDuration = DelayDuration(DelayDurationType.TIME, seconds)
fun initial(): DelayDuration = DelayDuration(DelayDurationType.INITIAL, 0)
fun inherit(): DelayDuration = DelayDuration(DelayDurationType.INHERIT, 0)

View File

@@ -1,58 +0,0 @@
package nl.astraeus.css
fun px(nr: Int): Measurement = Measurement(MeasurementType.PX, nr)
fun em(nr: Int): Measurement = Measurement(MeasurementType.EM, nr)
fun perc(nr: Int): Measurement = Measurement(MeasurementType.PERCENTAGE, nr)
fun pc(nr: Int): Measurement = Measurement(MeasurementType.PICAS, nr)
enum class MeasurementType {
PX,
EM,
PERCENTAGE,
PICAS,
OTHER
}
open class Measurement(
val type: MeasurementType,
val intValue: Int = 0,
val stringValue: String = ""
) : CssProperty {
override fun css(): String = when(type) {
MeasurementType.PX -> {
"${intValue}px"
}
MeasurementType.EM -> {
"${intValue}em"
}
MeasurementType.PERCENTAGE -> {
"${stringValue}%"
}
MeasurementType.PICAS -> {
"${stringValue}pc"
}
else -> {
error("Unhandled type $type")
}
}
}
enum class FontSizeType {
PX,
EM,
PERCENTAGE,
}
class FontSize(
val fontType: FontSizeType,
intValue: Int = 0,
stringValue: String = ""
) : Measurement(
MeasurementType.PX,
intValue,
stringValue
) {
override fun css(): String = "12px"
}

View File

@@ -0,0 +1,17 @@
package nl.astraeus.css.properties
class AlignContent(
value: String
) : CssProperty(value) {
companion object {
fun stretch() = AlignContent("stretch")
fun center() = AlignContent("center")
fun flexStart() = AlignContent("flex-start")
fun flexEnd() = AlignContent("flex-end")
fun spaceBetween() = AlignContent("space-between")
fun spaceAround() = AlignContent("space-around")
fun initial() = AlignContent("initial")
fun inherit() = AlignContent("inherit")
}
}

View File

@@ -0,0 +1,17 @@
package nl.astraeus.css.properties
class AlignItems(
value: String
) : CssProperty(value) {
companion object {
fun stretch() = AlignItems("stretch")
fun center() = AlignItems("center")
fun flexStart() = AlignItems("flex-start")
fun flexEnd() = AlignItems("flex-end")
fun baseline() = AlignItems("baseline")
fun initial() = AlignItems("initial")
fun inherit() = AlignItems("inherit")
}
}

View File

@@ -0,0 +1,17 @@
package nl.astraeus.css.properties
class AlignSelf(
value: String
) : CssProperty(value) {
companion object {
fun auto() = AlignSelf("auto")
fun stretch() = AlignSelf("stretch")
fun center() = AlignSelf("center")
fun flexStart() = AlignSelf("flex-start")
fun flexEnd() = AlignSelf("flex-end")
fun baseline() = AlignSelf("baseline")
fun initial() = AlignSelf("initial")
fun inherit() = AlignSelf("inherit")
}
}

View File

@@ -0,0 +1,14 @@
package nl.astraeus.css.properties
class All(
value: String
) : CssProperty(value) {
companion object {
fun initial() = All("initial")
fun inherit() = All("inherit")
fun unset() = All("unset")
fun revert() = All("revert")
}
}

View File

@@ -0,0 +1,77 @@
package nl.astraeus.css.properties
class AnimationDirection(
value: String
) : CssProperty(value) {
companion object {
fun normal() = AnimationDirection("normal")
fun reverse() = AnimationDirection("reverse")
fun alternate() = AnimationDirection("alternate")
fun alternateReverse() = AnimationDirection("alternate-reverse")
fun initial() = AnimationDirection("initial")
fun inherit() = AnimationDirection("inherit")
}
}
class AnimationFillMode(
value: String
) : CssProperty(value) {
companion object {
fun none() = AnimationFillMode("none")
fun forwards() = AnimationFillMode("forwards")
fun backwards() = AnimationFillMode("backwards")
fun both() = AnimationFillMode("both")
fun initial() = AnimationFillMode("initial")
fun inherit() = AnimationFillMode("inherit")
}
}
class AnimationFrame(
value: String = ""
): CssProperty(value) {
companion object {
fun name(name: String): AnimationFrame = AnimationFrame(name)
fun none(): AnimationFrame = AnimationFrame("none")
fun initial(): AnimationFrame = AnimationFrame("initial")
fun inherit(): AnimationFrame = AnimationFrame("inherit")
}
}
class AnimationPlayState(
value: String
) : CssProperty(value) {
companion object {
fun name(name: String) = AnimationPlayState(name)
fun paused() = AnimationPlayState("paused")
fun running() = AnimationPlayState("running")
fun initial() = AnimationPlayState("initial")
fun inherit() = AnimationPlayState("inherit")
}
}
class AnimationTimingFunction(
value: String = ""
) : CssProperty(value) {
companion object {
fun linear() = AnimationTimingFunction("linear")
fun ease() = AnimationTimingFunction("ease")
fun easeIn() = AnimationTimingFunction("ease-in")
fun easeOut() = AnimationTimingFunction("ease-out")
fun easeInOut() = AnimationTimingFunction("ease-in-out")
fun cubicBezier(
n1: Double,
n2: Double,
n3: Double,
n4: Double
) = AnimationTimingFunction("cubic-bezier($n1, $n2, $n3, $n4)")
fun initial() = AnimationTimingFunction("initial")
fun inherit() = AnimationTimingFunction("inherit")
}
}

View File

@@ -0,0 +1,13 @@
package nl.astraeus.css.properties
class BackfaceVisibility(
value: String
) : CssProperty(value) {
companion object {
fun visible() = BackfaceVisibility("visible")
fun hidden() = BackfaceVisibility("hidden")
fun initial() = BackfaceVisibility("initial")
fun inherit() = BackfaceVisibility("inherit")
}
}

View File

@@ -0,0 +1,125 @@
package nl.astraeus.css.properties
class BackgroundAttachment(
value: String
) : CssProperty(value) {
companion object {
fun scroll() = BackgroundAttachment("scroll")
fun fixed() = BackgroundAttachment("fixed")
fun local() = BackgroundAttachment("local")
fun initial() = BackgroundAttachment("initial")
fun inherit() = BackgroundAttachment("inherit")
}
}
class BackgroundBlendMode(
value: String
) : CssProperty(value) {
companion object {
fun normal() = BackgroundBlendMode("normal")
fun multiply() = BackgroundBlendMode("multiply")
fun screen() = BackgroundBlendMode("screen")
fun overlay() = BackgroundBlendMode("overlay")
fun darken() = BackgroundBlendMode("darken")
fun lighten() = BackgroundBlendMode("lighten")
fun colorDodge() = BackgroundBlendMode("color-dodge")
fun saturation() = BackgroundBlendMode("saturation")
fun color() = BackgroundBlendMode("color")
fun luminosity() = BackgroundBlendMode("luminosity")
}
}
class BackgroundClip(
value: String
) : CssProperty(value) {
companion object {
fun borderBox() = BackgroundClip("border-box")
fun paddingBox() = BackgroundClip("padding-box")
fun contentBox() = BackgroundClip("content-box")
fun initial() = BackgroundClip("initial")
fun inherit() = BackgroundClip("inherit")
}
}
class BackgroundOrigin(
value: String
) : CssProperty(value) {
companion object {
fun borderBox() = BackgroundOrigin("border-box")
fun paddingBox() = BackgroundOrigin("padding-box")
fun contentBox() = BackgroundOrigin("content-box")
fun initial() = BackgroundOrigin("initial")
fun inherit() = BackgroundOrigin("inherit")
}
}
class BackgroundPosition(
value: String
) : CssProperty(value) {
override fun validateMultiple(props: List<*>) {
for (prop in props) {
if (prop is CssProperty) {
if (prop.css() == "initial" || prop.css() == "inherit") {
check(props.size == 1) {
"'background-position' can only have single value when 'initial' or 'inherit'"
}
}
}
}
}
companion object {
fun left() = BackgroundPosition("left")
fun center() = BackgroundPosition("center")
fun right() = BackgroundPosition("right")
fun initial() = BackgroundPosition("initial")
fun inherit() = BackgroundPosition("inherit")
}
}
class BackgroundRepeat(
value: String
) : CssProperty(value) {
companion object {
fun repeat() = BackgroundRepeat("repeat")
fun repeatX() = BackgroundRepeat("repeat-x")
fun repeatY() = BackgroundRepeat("repeat-y")
fun noRepeat() = BackgroundRepeat("no-repeat")
fun space() = BackgroundRepeat("space")
fun round() = BackgroundRepeat("round")
fun initial() = BackgroundRepeat("initial")
fun inherit() = BackgroundRepeat("inherit")
fun unset() = BackgroundRepeat("unset")
}
}
class BackgroundSize(
value: String
) : CssProperty(value) {
override fun validateMultiple(props: List<*>) {
check(props.size <= 2) {
"'background-size' can not have more than 2 values"
}
}
companion object {
fun px(px: Int) = BackgroundSize("${px}px")
fun perc(pc: Double) = BackgroundSize("${pc}%")
fun auto() = BackgroundSize("auto")
fun cover() = BackgroundSize("cover")
fun contain() = BackgroundSize("contain")
fun initial() = BackgroundSize("initial")
fun inherit() = BackgroundSize("inherit")
}
}

View File

@@ -0,0 +1,79 @@
package nl.astraeus.css.properties
class BorderRadius(
value: String
): CssProperty(value) {
override fun validateMultiple(props: List<*>) {
check(props.size <= 2) {
"'background-size' can not have more than 2 values"
}
for (prop in props) {
if (prop is CssProperty) {
if (prop.css() == "initial" || prop.css() == "inherit") {
check(props.size == 1) {
"'border-radius' can only have single value when 'initial' or 'inherit'"
}
}
}
}
}
companion object {
fun px(nr: Int) = BorderRadius("${nr}px")
fun em(nr: Int) = BorderRadius("${nr}em")
fun em(nr: Double) = BorderRadius("${nr}em")
fun perc(nr: Int) = BorderRadius("${nr}%")
fun perc(nr: Double) = BorderRadius("${nr}%")
fun pc(nr: Int) = BorderRadius("${nr}pc")
fun pc(nr: Double) = BorderRadius("${nr}pc")
fun cm(nr: Int) = BorderRadius("${nr}cm")
fun cm(nr: Double) = BorderRadius("${nr}cm")
fun initial() = BorderRadius("initial")
fun inherit() = BorderRadius("inherit")
}
}
class BorderStyle(
value: String
): CssProperty(value) {
companion object {
fun none() = BorderStyle("none")
fun hidden() = BorderStyle("hidden")
fun dotted() = BorderStyle("dotted")
fun dashed() = BorderStyle("dashed")
fun solid() = BorderStyle("solid")
fun double() = BorderStyle("double")
fun groove() = BorderStyle("groove")
fun ridge() = BorderStyle("ridge")
fun inset() = BorderStyle("inset")
fun outset() = BorderStyle("outset")
fun initial() = BorderStyle("initial")
fun inherit() = BorderStyle("inherit")
}
}
class BorderWidth(
value: String
): CssProperty(value) {
companion object {
fun thin() = BorderWidth("thin")
fun medium() = BorderWidth("medium")
fun thick() = BorderWidth("thick")
fun px(nr: Int) = BorderRadius("${nr}px")
fun em(nr: Int) = BorderRadius("${nr}em")
fun em(nr: Double) = BorderRadius("${nr}em")
fun perc(nr: Int) = BorderRadius("${nr}%")
fun perc(nr: Double) = BorderRadius("${nr}%")
fun pc(nr: Int) = BorderRadius("${nr}pc")
fun pc(nr: Double) = BorderRadius("${nr}pc")
fun cm(nr: Int) = BorderRadius("${nr}cm")
fun cm(nr: Double) = BorderRadius("${nr}cm")
fun initial() = BorderWidth("initial")
fun inherit() = BorderWidth("inherit")
}
}

View File

@@ -0,0 +1,35 @@
package nl.astraeus.css.properties
class Color(
value: String
) : CssProperty(value) {
companion object {
fun transparant() = Color("transparant")
fun initial() = Color("initial")
fun inherit() = Color("inherit")
fun hex(hex: String) = Color("#$hex")
fun rgb(
red: Int,
green: Int,
blue: Int
) = Color("rgb($red, $green, $blue)")
fun rgba(
red: Int,
green: Int,
blue: Int,
alpha: Double
) = Color("rgba($red, $green, $blue, $alpha)")
fun hsl(
hue: Int,
saturation: Int,
lightness: Int
) = Color("hsl($hue, $saturation, $lightness)")
fun hsla(
hue: Int,
saturation: Int,
lightness: Int,
alpha: Double
) = Color("hsla($hue, $saturation, $lightness, $alpha)")
}
}

View File

@@ -0,0 +1,17 @@
package nl.astraeus.css.properties
class Count(
value: String
) : CssProperty(value) {
companion object {
fun count(number: Int): Count =
Count("$number")
fun infinite(): Count =
Count("infinite")
fun initial(): Count =
Count("initial")
fun inherit(): Count =
Count("inherit")
}
}

View File

@@ -0,0 +1,17 @@
package nl.astraeus.css.properties
open class CssProperty(
val value: String
) {
fun css(): String = value
open fun validate() {}
open fun validateMultiple(props: List<*>) {}
}
fun text(value: String) = TextProperty(value)
class TextProperty(
value: String
): CssProperty(value)

View File

@@ -0,0 +1,12 @@
package nl.astraeus.css.properties
class DelayDuration(
value: String
) : CssProperty(value) {
companion object {
fun seconds(seconds: Int) = DelayDuration("${seconds}s")
fun initial() = DelayDuration("initial")
fun inherit() = DelayDuration("inherit")
}
}

View File

@@ -0,0 +1,13 @@
package nl.astraeus.css.properties
class Image(
value: String
) : CssProperty(value) {
companion object {
fun url(url: String) = Image("url($url)")
fun none() = Image("none")
fun initial() = Image("initial")
fun inherit() = Image("inherit")
}
}

View File

@@ -0,0 +1,49 @@
package nl.astraeus.css.properties
open class Measurement(
value: String
) : CssProperty(value) {
companion object {
fun auto() = Measurement("auto")
fun initial() = Measurement("initial")
fun inherit() = Measurement("inherit")
fun px(nr: Int) = Measurement("${nr}px")
fun em(nr: Int) = Measurement("${nr}em")
fun em(nr: Double) = Measurement("${nr}em")
fun perc(nr: Int) = Measurement("${nr}%")
fun perc(nr: Double) = Measurement("${nr}%")
fun pc(nr: Int) = Measurement("${nr}pc")
fun pc(nr: Double) = Measurement("${nr}pc")
fun cm(nr: Int) = Measurement("${nr}cm")
fun cm(nr: Double) = Measurement("${nr}cm")
}
}
class FontSize(
value: String
) : CssProperty(value) {
companion object {
fun xxSmall() = FontSize("xx-small")
fun xSmall() = FontSize("x-small")
fun small() = FontSize("small")
fun medium() = FontSize("medium")
fun large() = FontSize("large")
fun xLarge() = FontSize("x-large")
fun xxLarge() = FontSize("xx-large")
fun smaller() = FontSize("smaller")
fun larger() = FontSize("larger")
fun initial() = FontSize("initial")
fun inherit() = FontSize("inherit")
fun px(nr: Int) = FontSize("${nr}px")
fun em(nr: Int) = FontSize("${nr}em")
fun em(nr: Double) = FontSize("${nr}em")
fun perc(nr: Int) = FontSize("${nr}%")
fun perc(nr: Double) = FontSize("${nr}%")
fun pc(nr: Int) = FontSize("${nr}pc")
fun pc(nr: Double) = FontSize("${nr}pc")
fun cm(nr: Int) = FontSize("${nr}cm")
fun cm(nr: Double) = FontSize("${nr}cm")
}
}

View File

@@ -0,0 +1,148 @@
package nl.astraeus.css.style
import nl.astraeus.css.properties.*
@DslMarker
annotation class CssTagMarker
@CssTagMarker
open class Style(
var alignContent: AlignContent? = null,
var alignItems: AlignItems? = null,
var alignSelf: AlignSelf? = null,
var all: All? = null,
var animation: TextProperty? = null,
var animationDelay: List<DelayDuration>? = null,
var animationDirection: List<AnimationDirection>? = null,
var animationDuration: List<DelayDuration>? = null,
var animationFillMode: List<AnimationFillMode>? = null,
var animationIterationCount: List<Count>? = null,
var animationFrame: AnimationFrame? = null,
var animationName: List<TextProperty>? = null,
var animationPlayState: List<AnimationPlayState>? = null,
var animationTimingFunction: List<AnimationTimingFunction>? = null,
var backfaceVisibility: BackfaceVisibility? = null,
var background: TextProperty? = null,
var backgroundAttachment: BackgroundAttachment? = null,
var backgroundBlendMode: BackgroundBlendMode? = null,
var backgroundClip: BackgroundClip? = null,
var backgroundColor: Color? = null,
var backgroundImage: Image? = null,
var backgroundOrigin: BackgroundOrigin? = null,
var backgroundPosition: List<BackgroundPosition>? = null,
var backgroundRepeat: List<BackgroundRepeat>? = null,
var backgroundSize: List<BackgroundSize>? = null,
var border: TextProperty? = null,
var borderBottom: TextProperty? = null,
var borderColor: Color? = null,
var borderBottomColor: Color? = null,
var borderBottomLeftRadius: List<BorderRadius>? = null,
var borderBottomRightRadius: List<BorderRadius>? = null,
var borderBottomStyle: BorderStyle? = null,
var borderBottomWidth: BorderWidth? = null,
var borderLeft: TextProperty? = null,
var borderLeftColor: Color? = null,
var borderRadius: List<BorderRadius>? = null,
var borderRight: TextProperty? = null,
var borderRightColor: Color? = null,
var borderTop: TextProperty? = null,
var borderTopColor: Color? = null,
var color: Color? = null,
var fontFamily: TextProperty? = null,
var fontSize: FontSize? = null,
var height: Measurement? = null,
var left: Measurement? = null,
var top: Measurement? = null,
var transitionDelay: DelayDuration? = null,
var transitionDuration: DelayDuration? = null,
var width: Measurement? = null
) {
fun getMapping() = mapOf(
"align-content" to alignContent,
"align-items" to alignItems,
"align-self" to alignSelf,
"all" to all,
"animation" to animation,
"animation-delay" to animationDelay,
"animation-direction" to animationDirection,
"animation-duration" to animationDuration,
"animation-fill-mode" to animationFillMode,
"animation-iteration-count" to animationIterationCount,
"animation-frame" to animationFrame,
"animation-name" to animationName,
"animation-play-state" to animationPlayState,
"animation-timing-function" to animationTimingFunction,
"backface-visibility" to backfaceVisibility,
"background" to background,
"background-attachment" to backgroundAttachment,
"background-blend-mode" to backgroundBlendMode,
"background-clip" to backgroundClip,
"background-color" to backgroundColor,
"background-image" to backgroundImage,
"background-origin" to backgroundOrigin,
"background-position" to backgroundPosition,
"background-repeat" to backgroundRepeat,
"background-size" to backgroundSize,
"border" to border,
"border-bottom" to borderBottom,
"border-bottom-color" to borderBottomColor,
"border-bottom-left-radius" to borderBottomLeftRadius,
"border-bottom-right-radius" to borderBottomRightRadius,
"border-color" to borderColor,
"border-left" to borderLeft,
"border-left-color" to borderLeftColor,
"border-right" to borderRight,
"border-right-color" to borderRightColor,
"border-top" to borderTop,
"border-top-color" to borderTopColor,
"color" to color,
"font-family" to fontFamily,
"font-size" to fontSize,
"height" to height,
"left" to left,
"top" to top,
"transition-delay" to transitionDelay,
"transition-duration" to transitionDuration,
"width" to width
)
fun propertyCss(indent: String, name: String, prop: CssProperty): String {
prop.validate()
return "$indent$name: ${prop.css()};\n"
}
fun propertyCss(indent: String, name: String, props: List<*>): String {
val builder = StringBuilder()
for ((index, prop) in props.withIndex()) {
if (prop is CssProperty) {
if (index == 0) {
prop.validateMultiple(props)
}
if (builder.isNotEmpty()) {
builder.append(", ")
}
builder.append(prop.css())
}
}
return "$indent$name: $builder;\n"
}
fun generatePropertyCss(indent: String): String {
val builder = StringBuilder()
for ((name, prop) in getMapping()) {
if (prop is List<*> && prop.isNotEmpty()) {
builder.append(propertyCss(indent, name, prop))
} else if (prop is CssProperty) {
builder.append(propertyCss(indent, name, prop))
}
}
return builder.toString()
}
}

View File

@@ -0,0 +1,42 @@
package nl.astraeus.css.style
@CssTagMarker
open class StyleDefinition : Style() {
val definitions: MutableMap<String, StyleDefinition> = mutableMapOf()
val includes: MutableList<Style> = mutableListOf()
fun css(selector: String, style: StyleDefinition.() -> Unit) {
val styleValue = StyleDefinition()
style(styleValue)
definitions[selector] = styleValue
}
fun include(style: Style) {
includes.add(style)
}
open fun generateCss(namespace: String = "", indent: String = " "): String {
val builder = StringBuilder()
for ((name, prop) in definitions) {
val css = StringBuilder()
css.append(prop.generatePropertyCss(indent))
for (style in prop.includes) {
css.append(style.generatePropertyCss(indent))
}
if (css.isNotBlank()) {
builder.append("$namespace $name".trim())
builder.append(" {\n")
builder.append(css)
builder.append("}\n\n")
}
builder.append(prop.generateCss( "${namespace} $name".trim(), indent))
}
return builder.toString()
}
}

View File

@@ -1,5 +1,10 @@
package nl.astraeus.css
import nl.astraeus.css.properties.Color.Companion.hsl
import nl.astraeus.css.properties.Color.Companion.rgba
import nl.astraeus.css.properties.Measurement.Companion.em
import nl.astraeus.css.properties.Measurement.Companion.px
//import kotlin.test.Test
object TestCssBuilder {

View File

@@ -0,0 +1,99 @@
package nl.astraeus.css
import nl.astraeus.css.properties.*
import nl.astraeus.css.properties.Measurement.Companion.em
import nl.astraeus.css.properties.Measurement.Companion.px
import nl.astraeus.css.style.StyleDefinition
class StyleBase(
val mainColor: Color = Color.hsl(128, 50, 50),
val mainBackgroundColor: Color = Color.hsl(64, 50, 50),
val mainFont: TextProperty = text("Arial")
)
private fun StyleDefinition.sizePX(
left: Int,
top: Int,
width: Int,
height: Int
) {
this@sizePX.top = px(top)
this@sizePX.left = px(left)
this@sizePX.width = px(width)
this@sizePX.height = px(height)
}
private fun generateCss(
base: StyleBase
): String {
val css = CssBuilder()
css.style {
css("body") {
fontFamily = base.mainFont
color = base.mainColor
backgroundColor = base.mainBackgroundColor
alignContent = AlignContent.initial()
}
css(".test") {
top = px(10)
left = em(5)
backgroundColor = Color.rgba(255, 255, 255, 0.75)
css("> a") {
color = Color.hsl(200, 50, 50)
}
}
css("nav") {
css("ul") {
color = Color.hsl(0, 100, 25)
backgroundColor = base.mainBackgroundColor
}
css("li") {
sizePX(25, 25, 200, 200)
css("a") {
width = px(725)
background = text("")
backgroundColor = base.mainBackgroundColor
}
}
}
}
return css.getCss()
}
fun main() {
val css1 = generateCss(StyleBase())
val css2 = generateCss(StyleBase(
Color.hsl(32, 40, 50),
Color.hsl(64, 60, 35),
text("Courier")
))
println(css1)
println(css2)
val sd = css {
css("#pipo") {
backgroundColor = Color.hex("eeeeee")
fontFamily = text("Arial, Courier")
animationDelay = listOf(DelayDuration.initial())
css("div") {
color = Color.hex("1b1b1b1")
alignContent = AlignContent.flexStart()
animationName = listOf(text("foo"), text("bar"))
animationIterationCount = listOf(
Count.count(3), Count.infinite())
animationTimingFunction = listOf(AnimationTimingFunction.cubicBezier(0.1, 0.2, 0.3, 0.4), AnimationTimingFunction.easeInOut())
}
}
}
println("======")
println(sd.generateCss())
}

View File

@@ -1,8 +1,12 @@
package nl.astraeus.css
import nl.astraeus.css.properties.*
import nl.astraeus.css.properties.AlignContent.Companion.flexStart
import nl.astraeus.css.style.StyleDefinition
class StyleBase(
val mainColor: Color = hsl(128, 50, 50),
val mainBackgroundColor: Color = hsl(64, 50, 50),
val mainColor: Color = Color.hsl(128, 50, 50),
val mainBackgroundColor: Color = Color.hsl(64, 50, 50),
val mainFont: TextProperty = text("Arial")
)
@@ -12,10 +16,10 @@ private fun StyleDefinition.sizePX(
width: Int,
height: Int
) {
this@sizePX.top = px(top)
this@sizePX.left = px(left)
this@sizePX.width = px(width)
this@sizePX.height = 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(
@@ -31,26 +35,28 @@ private fun generateCss(
}
css(".test") {
top = px(10)
left = em(5)
backgroundColor = rgba(255, 255, 255, 0.75)
top = Measurement.px(10)
left = Measurement.em(5)
backgroundColor = Color.rgba(255, 255, 255, 0.75)
css("> a") {
color = hsl(200, 50, 50)
color = Color.hsl(200, 50, 50)
}
}
css("nav") {
css("ul") {
color = hsl(0, 100, 25)
color = Color.hsl(0, 100, 25)
backgroundColor = base.mainBackgroundColor
}
css("li") {
sizePX(25, 25, 200, 200)
css("a") {
width = px(725)
width = Measurement.px(725)
background = text("")
backgroundColor = base.mainBackgroundColor
all = All.initial()
}
}
}
@@ -62,8 +68,8 @@ private fun generateCss(
fun main() {
val css1 = generateCss(StyleBase())
val css2 = generateCss(StyleBase(
hsl(32, 40, 50),
hsl(64, 60, 35),
Color.hsl(32, 40, 50),
Color.hsl(64, 60, 35),
text("Courier")
))
@@ -72,14 +78,17 @@ fun main() {
val sd = css {
css("#pipo") {
backgroundColor = hex("eeeeee")
backgroundColor = Color.hex("eeeeee")
fontFamily = text("Arial, Courier")
animationDelay = initial()
animationDelay = listOf(DelayDuration.initial())
css("div") {
color = hex("1b1b1b1")
alignContent = AlignContent.FLEX_START
animationIterationCount = Count.count(3)
color = Color.hex("1b1b1b1")
alignContent = flexStart()
animationName = listOf(text("foo"), text("bar"))
animationIterationCount = listOf(
Count.count(3), Count.infinite())
animationTimingFunction = listOf(AnimationTimingFunction.cubicBezier(0.1, 0.2, 0.3, 0.4), AnimationTimingFunction.easeInOut())
}
}
}