More properties, cleanup
This commit is contained in:
@@ -1,20 +1,23 @@
|
||||
package nl.astraeus.css
|
||||
|
||||
import nl.astraeus.css.style.StyleDefinition
|
||||
import nl.astraeus.css.style.Css
|
||||
import nl.astraeus.css.style.Style
|
||||
|
||||
fun css(definition: StyleDefinition.() -> Unit): StyleDefinition {
|
||||
val css = StyleDefinition()
|
||||
fun css(definition: Css) = definition
|
||||
|
||||
fun style(definition: Css): Style {
|
||||
val css = Style()
|
||||
|
||||
definition(css)
|
||||
|
||||
return css
|
||||
}
|
||||
|
||||
class CssBuilder {
|
||||
var definition: StyleDefinition =
|
||||
StyleDefinition()
|
||||
|
||||
fun style(definition: StyleDefinition.() -> Unit) {
|
||||
class CssBuilder {
|
||||
var definition: Style = Style()
|
||||
|
||||
fun style(definition: Style.() -> Unit) {
|
||||
definition(this.definition)
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,16 @@ package nl.astraeus.css.properties
|
||||
class BorderRadius(
|
||||
value: String
|
||||
): CssProperty(value) {
|
||||
constructor(topLeft: Int, topRight: Int, bottomRight: Int, bottomLeft: Int): this(
|
||||
"${topLeft}px ${topRight}px ${bottomRight}px ${bottomLeft}px"
|
||||
)
|
||||
constructor(topLeft: Int, topRightBottomLeft: Int, bottomRight: Int): this(
|
||||
"${topLeft}px ${topRightBottomLeft}px ${bottomRight}px"
|
||||
)
|
||||
constructor(topLeftBottomRight: Int, topRightBottomLeft: Int): this(
|
||||
"${topLeftBottomRight}px ${topRightBottomLeft}px"
|
||||
)
|
||||
constructor(radius: Int): this("${radius}px")
|
||||
|
||||
companion object {
|
||||
fun px(nr: Int) = BorderRadius("${nr}px")
|
||||
@@ -19,23 +29,23 @@ class BorderRadius(
|
||||
}
|
||||
}
|
||||
|
||||
class BorderStyle(
|
||||
class RuleBorderStyle(
|
||||
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")
|
||||
fun none() = RuleBorderStyle("none")
|
||||
fun hidden() = RuleBorderStyle("hidden")
|
||||
fun dotted() = RuleBorderStyle("dotted")
|
||||
fun dashed() = RuleBorderStyle("dashed")
|
||||
fun solid() = RuleBorderStyle("solid")
|
||||
fun double() = RuleBorderStyle("double")
|
||||
fun groove() = RuleBorderStyle("groove")
|
||||
fun ridge() = RuleBorderStyle("ridge")
|
||||
fun inset() = RuleBorderStyle("inset")
|
||||
fun outset() = RuleBorderStyle("outset")
|
||||
fun initial() = RuleBorderStyle("initial")
|
||||
fun inherit() = RuleBorderStyle("inherit")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,15 +58,15 @@ class BorderWidth(
|
||||
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 px(nr: Int) = BorderWidth("${nr}px")
|
||||
fun em(nr: Int) = BorderWidth("${nr}em")
|
||||
fun em(nr: Double) = BorderWidth("${nr}em")
|
||||
fun perc(nr: Int) = BorderWidth("${nr}%")
|
||||
fun perc(nr: Double) = BorderWidth("${nr}%")
|
||||
fun pc(nr: Int) = BorderWidth("${nr}pc")
|
||||
fun pc(nr: Double) = BorderWidth("${nr}pc")
|
||||
fun cm(nr: Int) = BorderWidth("${nr}cm")
|
||||
fun cm(nr: Double) = BorderWidth("${nr}cm")
|
||||
|
||||
fun initial() = BorderWidth("initial")
|
||||
fun inherit() = BorderWidth("inherit")
|
||||
|
||||
17
src/commonMain/kotlin/nl/astraeus/css/properties/Clear.kt
Normal file
17
src/commonMain/kotlin/nl/astraeus/css/properties/Clear.kt
Normal file
@@ -0,0 +1,17 @@
|
||||
package nl.astraeus.css.properties
|
||||
|
||||
|
||||
class Clear(
|
||||
value: String
|
||||
): CssProperty(value) {
|
||||
|
||||
companion object {
|
||||
fun none() = Clear("none")
|
||||
fun left() = Clear("left")
|
||||
fun right() = Clear("right")
|
||||
fun both() = Clear("both")
|
||||
fun initial() = Clear("initial")
|
||||
fun inherit() = Clear("inherit")
|
||||
}
|
||||
|
||||
}
|
||||
54
src/commonMain/kotlin/nl/astraeus/css/properties/Clip.kt
Normal file
54
src/commonMain/kotlin/nl/astraeus/css/properties/Clip.kt
Normal file
@@ -0,0 +1,54 @@
|
||||
package nl.astraeus.css.properties
|
||||
|
||||
class Clip(
|
||||
value: String
|
||||
) : CssProperty(value) {
|
||||
|
||||
companion object {
|
||||
fun auto() = Clip("auto")
|
||||
fun rect(top: Int, right: Int, bottom: Int, left: Int) = Clip("rect(${top}px,${right}px,${bottom}px,${left}px)")
|
||||
fun initial() = Clip("initial")
|
||||
fun inherit() = Clip("inherit")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class ClipPath(
|
||||
value: String
|
||||
) : CssProperty(value) {
|
||||
|
||||
companion object {
|
||||
fun auto() = ClipPath("auto")
|
||||
fun circle(perc: Double) = ClipPath("circle(${perc}%)")
|
||||
fun ellipse(radiusX: Double, radiusY: Double) = ClipPath("ellipse(${radiusX}%,${radiusY}%)")
|
||||
fun ellipse(
|
||||
radiusX: Double,
|
||||
radiusY: Double,
|
||||
positionX: Double,
|
||||
positionY: Double
|
||||
) = ClipPath("ellipse(${radiusX}%,${radiusY}% at ${positionX}%,${positionY}%)")
|
||||
// todo: other options
|
||||
fun marginBox() = ClipPath("margin-box")
|
||||
fun borderBox() = ClipPath("border-box")
|
||||
fun paddingBox() = ClipPath("padding-box")
|
||||
fun contentBox() = ClipPath("content-box")
|
||||
fun fillBox() = ClipPath("fill-box")
|
||||
fun strokeBox() = ClipPath("stroke-box")
|
||||
fun viewBox() = ClipPath("view-box")
|
||||
fun none() = ClipPath("none")
|
||||
}
|
||||
}
|
||||
|
||||
class ClipOrigin(
|
||||
value: String
|
||||
) : CssProperty(value) {
|
||||
|
||||
companion object {
|
||||
fun borderBox() = ClipOrigin("border-box")
|
||||
fun paddingBox() = ClipOrigin("padding-box")
|
||||
fun contentBox() = ClipOrigin("content-box")
|
||||
fun initial() = ClipOrigin("initial")
|
||||
fun inherit() = ClipOrigin("inherit")
|
||||
|
||||
}
|
||||
}
|
||||
@@ -20,17 +20,14 @@ class Length(
|
||||
|
||||
}
|
||||
|
||||
class ClipOrigin(
|
||||
class Fill(
|
||||
value: String
|
||||
) : CssProperty(value) {
|
||||
|
||||
companion object {
|
||||
fun borderBox() = ClipOrigin("border-box")
|
||||
fun paddingBox() = ClipOrigin("padding-box")
|
||||
fun contentBox() = ClipOrigin("content-box")
|
||||
fun initial() = ClipOrigin("initial")
|
||||
fun inherit() = ClipOrigin("inherit")
|
||||
|
||||
fun balance() = Fill("balance")
|
||||
fun auto() = Fill("auto")
|
||||
fun initial() = Fill("initial")
|
||||
fun inherit() = Fill("inherit")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
22
src/commonMain/kotlin/nl/astraeus/css/properties/Content.kt
Normal file
22
src/commonMain/kotlin/nl/astraeus/css/properties/Content.kt
Normal file
@@ -0,0 +1,22 @@
|
||||
package nl.astraeus.css.properties
|
||||
|
||||
class Content(
|
||||
value: String
|
||||
) : CssProperty(value) {
|
||||
|
||||
companion object {
|
||||
fun normal() = Content("normal")
|
||||
fun none() = Content("none")
|
||||
fun counter() = Content("counter")
|
||||
fun attr(attribute: String) = Content("attr($attribute)")
|
||||
fun string(txt: String) = Content("\"$txt\"")
|
||||
fun openQuote() = Content("open-quote")
|
||||
fun closeQuote() = Content("close-quote")
|
||||
fun noOpenQuote() = Content("no-open-quote")
|
||||
fun noCloseQuote() = Content("no-close-quote")
|
||||
fun url(url: String) = Content("url($url)")
|
||||
fun initial() = Content("initial")
|
||||
fun inherit() = Content("inherit")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,6 +7,8 @@ class Count(
|
||||
companion object {
|
||||
fun count(number: Int): Count =
|
||||
Count("$number")
|
||||
fun auto(): Count =
|
||||
Count("auto")
|
||||
fun infinite(): Count =
|
||||
Count("infinite")
|
||||
fun initial(): Count =
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package nl.astraeus.css.properties
|
||||
|
||||
class Direction(
|
||||
value: String
|
||||
) : CssProperty(value) {
|
||||
|
||||
companion object {
|
||||
fun ltr() = Direction("ltr")
|
||||
fun rtl() = Direction("rtl")
|
||||
fun initial() = Direction("initial")
|
||||
fun inherit() = Direction("inherit")
|
||||
}
|
||||
|
||||
}
|
||||
33
src/commonMain/kotlin/nl/astraeus/css/properties/Display.kt
Normal file
33
src/commonMain/kotlin/nl/astraeus/css/properties/Display.kt
Normal file
@@ -0,0 +1,33 @@
|
||||
package nl.astraeus.css.properties
|
||||
|
||||
class Display(
|
||||
value: String
|
||||
) : CssProperty(value) {
|
||||
|
||||
companion object {
|
||||
fun inline() = Display("inline")
|
||||
fun block() = Display("block")
|
||||
fun contents() = Display("contents")
|
||||
fun flex() = Display("flex")
|
||||
fun grid() = Display("grid")
|
||||
fun inlineBlock() = Display("inline-block")
|
||||
fun inlineFlex() = Display("inline-flex")
|
||||
fun inlineGrid() = Display("inline-grid")
|
||||
fun inlineTable() = Display("inline-table")
|
||||
fun listItem() = Display("list-item")
|
||||
fun runIn() = Display("run-in")
|
||||
fun table() = Display("table")
|
||||
fun tableCaption() = Display("table-caption")
|
||||
fun tableColumnGroup() = Display("table-column-group")
|
||||
fun tableHeaderGroup() = Display("table-header-group")
|
||||
fun tableFooterGroup() = Display("table-footer-group")
|
||||
fun tableRowGroup() = Display("table-row-group")
|
||||
fun tableCell() = Display("table-cell")
|
||||
fun tableColumn() = Display("table-column")
|
||||
fun tableRow() = Display("table-row")
|
||||
fun none() = Display("none")
|
||||
fun initial() = Display("initial")
|
||||
fun inherit() = Display("inherit")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package nl.astraeus.css.properties
|
||||
|
||||
class EmptyCells(
|
||||
value: String
|
||||
) : CssProperty(value) {
|
||||
|
||||
companion object {
|
||||
fun show() = EmptyCells("show")
|
||||
fun hide() = EmptyCells("hide")
|
||||
fun initial() = EmptyCells("initial")
|
||||
fun inherit() = EmptyCells("inherit")
|
||||
}
|
||||
|
||||
}
|
||||
15
src/commonMain/kotlin/nl/astraeus/css/properties/Float.kt
Normal file
15
src/commonMain/kotlin/nl/astraeus/css/properties/Float.kt
Normal file
@@ -0,0 +1,15 @@
|
||||
package nl.astraeus.css.properties
|
||||
|
||||
class Float(
|
||||
value: String
|
||||
) : CssProperty(value) {
|
||||
|
||||
companion object {
|
||||
fun none() = Float("none")
|
||||
fun left() = Float("left")
|
||||
fun right() = Float("right")
|
||||
fun initial() = Float("initial")
|
||||
fun inherit() = Float("inherit")
|
||||
}
|
||||
|
||||
}
|
||||
80
src/commonMain/kotlin/nl/astraeus/css/properties/Font.kt
Normal file
80
src/commonMain/kotlin/nl/astraeus/css/properties/Font.kt
Normal file
@@ -0,0 +1,80 @@
|
||||
package nl.astraeus.css.properties
|
||||
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
||||
class FontStretch(
|
||||
value: String
|
||||
) : CssProperty(value) {
|
||||
|
||||
companion object {
|
||||
fun normal() = FontStretch("normal")
|
||||
fun condensed() = FontStretch("condensed")
|
||||
fun ultraCondensed() = FontStretch("ultra-condensed")
|
||||
fun extraCondensed() = FontStretch("extra-condensed")
|
||||
fun semiCondensed() = FontStretch("semi-condensed")
|
||||
fun expanded() = FontStretch("expanded")
|
||||
fun semiExpanded() = FontStretch("semi-expanded")
|
||||
fun extraExpanded() = FontStretch("extra-expanded")
|
||||
fun ultraExpanded() = FontStretch("ultra-expanded")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class FontStyle(
|
||||
value: String
|
||||
) : CssProperty(value) {
|
||||
|
||||
companion object {
|
||||
fun normal() = FontStyle("normal")
|
||||
fun italic() = FontStyle("italic")
|
||||
fun oblique() = FontStyle("oblique")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class FontWeight(
|
||||
value: String
|
||||
) : CssProperty(value) {
|
||||
|
||||
companion object {
|
||||
fun normal() = FontWeight("normal")
|
||||
fun bold() = FontWeight("bold")
|
||||
fun _100() = FontWeight("100")
|
||||
fun _200() = FontWeight("200")
|
||||
fun _300() = FontWeight("300")
|
||||
fun _400() = FontWeight("400")
|
||||
fun _500() = FontWeight("500")
|
||||
fun _600() = FontWeight("600")
|
||||
fun _700() = FontWeight("700")
|
||||
fun _800() = FontWeight("800")
|
||||
fun _900() = FontWeight("900")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ open class Measurement(
|
||||
fun auto() = Measurement("auto")
|
||||
fun initial() = Measurement("initial")
|
||||
fun inherit() = Measurement("inherit")
|
||||
fun normal() = Measurement("normal")
|
||||
fun px(nr: Int) = Measurement("${nr}px")
|
||||
fun em(nr: Int) = Measurement("${nr}em")
|
||||
fun em(nr: Double) = Measurement("${nr}em")
|
||||
@@ -19,31 +20,3 @@ open class Measurement(
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
||||
14
src/commonMain/kotlin/nl/astraeus/css/properties/Span.kt
Normal file
14
src/commonMain/kotlin/nl/astraeus/css/properties/Span.kt
Normal file
@@ -0,0 +1,14 @@
|
||||
package nl.astraeus.css.properties
|
||||
|
||||
class Span(
|
||||
value: String
|
||||
) : CssProperty(value) {
|
||||
|
||||
companion object {
|
||||
fun none() = Clip("none")
|
||||
fun all() = Clip("all")
|
||||
fun initial() = Clip("initial")
|
||||
fun inherit() = Clip("inherit")
|
||||
}
|
||||
|
||||
}
|
||||
27
src/commonMain/kotlin/nl/astraeus/css/style/FontFace.kt
Normal file
27
src/commonMain/kotlin/nl/astraeus/css/style/FontFace.kt
Normal file
@@ -0,0 +1,27 @@
|
||||
package nl.astraeus.css.style
|
||||
|
||||
import nl.astraeus.css.properties.*
|
||||
|
||||
@CssTagMarker
|
||||
open class FontFace(
|
||||
var fontFamily: TextProperty? = null,
|
||||
var fontSize: FontSize? = null,
|
||||
var src: TextProperty? = null,
|
||||
var fontStretch: FontStretch? = null,
|
||||
var fontStyle: FontStyle? = null,
|
||||
var fontWeight: FontWeight? = null,
|
||||
var unicodeRange: TextProperty? = null
|
||||
) : CssGenerator() {
|
||||
|
||||
override fun getValidator(name: String) = null
|
||||
|
||||
override fun getMapping(): Map<String, Any?> = mapOf(
|
||||
"font-family" to fontFamily,
|
||||
"font-size" to fontSize,
|
||||
"src" to src,
|
||||
"font-stretch" to fontStretch,
|
||||
"font-style" to fontStyle,
|
||||
"font-weight" to fontWeight,
|
||||
"unicode-range" to unicodeRange
|
||||
)
|
||||
}
|
||||
@@ -3,9 +3,146 @@ package nl.astraeus.css.style
|
||||
import nl.astraeus.css.properties.*
|
||||
import nl.astraeus.logging.log
|
||||
|
||||
typealias Css = Style.() -> Unit
|
||||
|
||||
@DslMarker
|
||||
annotation class CssTagMarker
|
||||
|
||||
abstract class CssGenerator {
|
||||
val definitions: MutableMap<String, Css> = mutableMapOf()
|
||||
val extentions: MutableList<Css> = mutableListOf()
|
||||
|
||||
abstract fun getMapping(): Map<String, Any?>
|
||||
|
||||
abstract fun getValidator(name: String): List<Validator>?
|
||||
|
||||
private fun propertyCss(indent: String, name: String, prop: CssProperty, minified: Boolean): String {
|
||||
getValidator(name)?.forEach {
|
||||
if (!it.validate(prop)) {
|
||||
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)}" }
|
||||
}
|
||||
}
|
||||
if (builder.isNotEmpty()) {
|
||||
builder.append(",")
|
||||
if (!minified) {
|
||||
builder.append(" ")
|
||||
}
|
||||
}
|
||||
builder.append(prop.css())
|
||||
}
|
||||
}
|
||||
|
||||
return if (!minified) {
|
||||
val paddedName = StringBuilder()
|
||||
paddedName.append(indent)
|
||||
paddedName.append(name)
|
||||
paddedName.append(":")
|
||||
while (paddedName.length < 32) {
|
||||
paddedName.append(' ')
|
||||
}
|
||||
"$paddedName$builder;\n"
|
||||
} else {
|
||||
"$name:$builder;"
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
return builder.toString()
|
||||
}
|
||||
|
||||
open fun generateCss(namespace: String = "", indent: String = " ", minified: Boolean = false): String {
|
||||
val builder = StringBuilder()
|
||||
|
||||
for ((name, prop) in definitions) {
|
||||
val css = StringBuilder()
|
||||
|
||||
val finalStyle = Style()
|
||||
|
||||
prop(finalStyle)
|
||||
|
||||
css.append(finalStyle.generatePropertyCss(indent, minified))
|
||||
|
||||
if (css.isNotBlank()) {
|
||||
builder.append("\n$namespace $name".trim())
|
||||
if (!minified) {
|
||||
builder.append(" ")
|
||||
}
|
||||
builder.append("{")
|
||||
if (!minified) {
|
||||
builder.append("\n")
|
||||
}
|
||||
|
||||
finalStyle.fontFace?.let { ff ->
|
||||
if (!minified) {
|
||||
builder.append(indent)
|
||||
}
|
||||
builder.append("@font-face {")
|
||||
if (!minified) {
|
||||
builder.append("\n")
|
||||
}
|
||||
builder.append(ff.generatePropertyCss(" $indent", minified))
|
||||
builder.append(indent)
|
||||
builder.append("}")
|
||||
if (!minified) {
|
||||
builder.append("\n")
|
||||
}
|
||||
}
|
||||
|
||||
builder.append(css)
|
||||
builder.append("}")
|
||||
if (!minified) {
|
||||
builder.append("\n\n")
|
||||
}
|
||||
}
|
||||
|
||||
builder.append(finalStyle.generateCss( "$namespace $name".trim(), indent, minified))
|
||||
}
|
||||
|
||||
return builder.toString()
|
||||
}
|
||||
}
|
||||
|
||||
@CssTagMarker
|
||||
open class Style(
|
||||
var alignContent: AlignContent? = null,
|
||||
@@ -38,7 +175,7 @@ open class Style(
|
||||
var borderBottomColor: Color? = null,
|
||||
var borderBottomLeftRadius: List<BorderRadius>? = null,
|
||||
var borderBottomRightRadius: List<BorderRadius>? = null,
|
||||
var borderBottomStyle: BorderStyle? = null,
|
||||
var borderBottomStyle: RuleBorderStyle? = null,
|
||||
var borderBottomWidth: BorderWidth? = null,
|
||||
var borderCollapse: BorderCollapse? = null,
|
||||
var borderColor: List<Color>? = null,
|
||||
@@ -50,20 +187,20 @@ open class Style(
|
||||
var borderImageWidth: List<BorderImageWidth>? = null,
|
||||
var borderLeft: TextProperty? = null,
|
||||
var borderLeftColor: Color? = null,
|
||||
var borderLeftStyle: BorderStyle? = null,
|
||||
var borderLeftStyle: RuleBorderStyle? = null,
|
||||
var borderLeftWidth: BorderWidth? = null,
|
||||
var borderRadius: List<BorderRadius>? = null,
|
||||
var borderRadius: BorderRadius? = null,
|
||||
var borderRight: TextProperty? = null,
|
||||
var borderRightColor: Color? = null,
|
||||
var borderRightStyle: BorderStyle? = null,
|
||||
var borderRightStyle: RuleBorderStyle? = null,
|
||||
var borderRightWidth: BorderWidth? = null,
|
||||
var borderSpacing: List<BorderSpacing>? = null,
|
||||
var borderStyle: List<BorderStyle>? = null,
|
||||
var borderStyle: List<RuleBorderStyle>? = null,
|
||||
var borderTop: TextProperty? = null,
|
||||
var borderTopColor: Color? = null,
|
||||
var borderTopLeftRadius: BorderRadius? = null,
|
||||
var borderTopRightRadius: BorderRadius? = null,
|
||||
var borderTopStyle: BorderStyle? = null,
|
||||
var borderTopStyle: RuleBorderStyle? = null,
|
||||
var borderTopWidth: BorderWidth? = null,
|
||||
var bottom: Measurement? = null,
|
||||
var boxDecorationBreak: BoxDecorationBreak? = null,
|
||||
@@ -75,6 +212,31 @@ open class Style(
|
||||
var captionSide: CaptionSide? = null,
|
||||
var caretColor: Color? = null,
|
||||
//var charset: TextProperty? = null,
|
||||
var clear: Clear? = null,
|
||||
var clip: Clip? = null,
|
||||
var clipPath: ClipPath? = null,
|
||||
var columnCount: Count? = null,
|
||||
var columnFill: Fill? = null,
|
||||
var columnGap: Measurement? = null,
|
||||
var columnRule: TextProperty? = null,
|
||||
var columnRuleColor: Color? = null,
|
||||
var columnRuleStyle: RuleBorderStyle? = null,
|
||||
var columnRuleWidth: Measurement? = null,
|
||||
var columnSpan: Span? = null,
|
||||
var columnWidth: Measurement? = null,
|
||||
var columns: TextProperty? = null,
|
||||
var content: Content? = null,
|
||||
var counterIncrement: TextProperty? = null,
|
||||
var counterReset: TextProperty? = null,
|
||||
var cursor: TextProperty? = null,
|
||||
var direction: Direction? = null,
|
||||
var display: Display? = null,
|
||||
var emptyCells: EmptyCells? = null,
|
||||
var filter: TextProperty? = null,
|
||||
var flex: TextProperty? = null,
|
||||
var float: Float? = null,
|
||||
var font: TextProperty? = null,
|
||||
|
||||
var color: Color? = null,
|
||||
var fontFamily: TextProperty? = null,
|
||||
var fontSize: FontSize? = null,
|
||||
@@ -84,7 +246,8 @@ open class Style(
|
||||
var transitionDelay: DelayDuration? = null,
|
||||
var transitionDuration: DelayDuration? = null,
|
||||
var width: Measurement? = null
|
||||
) {
|
||||
) : CssGenerator() {
|
||||
var fontFace: FontFace? = null
|
||||
private val validators = mapOf<String, List<Validator>>(
|
||||
"background-position" to listOf(InitialInheritSingleValue()),
|
||||
"background-size" to listOf(MaxCountValidator(2)),
|
||||
@@ -99,7 +262,9 @@ open class Style(
|
||||
"border-style" to listOf(MaxCountValidator(4))
|
||||
)
|
||||
|
||||
fun getMapping(): Map<String, Any?> = mapOf(
|
||||
override fun getValidator(name: String) = validators[name]
|
||||
|
||||
override fun getMapping(): Map<String, Any?> = mapOf(
|
||||
"align-content" to alignContent,
|
||||
"align-items" to alignItems,
|
||||
"align-self" to alignSelf,
|
||||
@@ -167,7 +332,33 @@ open class Style(
|
||||
"caption-side" to captionSide,
|
||||
"caret-color" to caretColor,
|
||||
//"@charset" to charset,
|
||||
"clear" to clear,
|
||||
"clip" to clip,
|
||||
"clip-path" to clipPath,
|
||||
"color" to color,
|
||||
"column-count" to columnCount,
|
||||
"column-fill" to columnFill,
|
||||
"column-gap" to columnGap,
|
||||
"column-rule" to columnRule,
|
||||
"column-rule-color" to columnRuleColor,
|
||||
"column-rule-style" to columnRuleStyle,
|
||||
"column-rule-width" to columnRuleWidth,
|
||||
"column-span" to columnSpan,
|
||||
"column-width" to columnWidth,
|
||||
"columns" to columns,
|
||||
"content" to content,
|
||||
"counter-increment" to counterIncrement,
|
||||
"counter-reset" to counterReset,
|
||||
"cursor" to cursor,
|
||||
"direction" to direction,
|
||||
"display" to display,
|
||||
"empty-cells" to emptyCells,
|
||||
"filter" to filter,
|
||||
"flex" to flex,
|
||||
"float" to float,
|
||||
"font" to font,
|
||||
|
||||
|
||||
"font-family" to fontFamily,
|
||||
"font-size" to fontSize,
|
||||
"height" to height,
|
||||
@@ -178,79 +369,17 @@ open class Style(
|
||||
"width" to width
|
||||
)
|
||||
|
||||
fun propertyCss(indent: String, name: String, prop: CssProperty, minified: Boolean): String {
|
||||
validators[name]?.forEach {
|
||||
if (!it.validate(prop)) {
|
||||
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()};"
|
||||
}
|
||||
fun select(selector: String, style: Css) {
|
||||
definitions[selector] = style
|
||||
}
|
||||
|
||||
fun propertyCss(indent: String, name: String, props: List<*>, minified: Boolean): String {
|
||||
val builder = StringBuilder()
|
||||
|
||||
validators[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) {
|
||||
validators[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())
|
||||
}
|
||||
}
|
||||
|
||||
return if (!minified) {
|
||||
val paddedName = StringBuilder()
|
||||
paddedName.append(indent)
|
||||
paddedName.append(name)
|
||||
paddedName.append(":")
|
||||
while(paddedName.length < 32) {
|
||||
paddedName.append(' ')
|
||||
}
|
||||
"$paddedName$builder;\n"
|
||||
} else {
|
||||
"$name:$builder;"
|
||||
}
|
||||
fun apply(style: Css) {
|
||||
style(this)
|
||||
}
|
||||
|
||||
fun generatePropertyCss(indent: String, minified: Boolean): String {
|
||||
val builder = StringBuilder()
|
||||
fun fontFace(face: FontFace.() -> Unit) {
|
||||
fontFace = FontFace()
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
return builder.toString()
|
||||
face.invoke(fontFace!!)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
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 = " ", minified: Boolean = false): String {
|
||||
val builder = StringBuilder()
|
||||
|
||||
for ((name, prop) in definitions) {
|
||||
val css = StringBuilder()
|
||||
css.append(prop.generatePropertyCss(indent, minified))
|
||||
for (style in prop.includes) {
|
||||
css.append(style.generatePropertyCss(indent, minified))
|
||||
}
|
||||
if (css.isNotBlank()) {
|
||||
builder.append("\n$namespace $name".trim())
|
||||
if (!minified) {
|
||||
builder.append(" ")
|
||||
}
|
||||
builder.append("{")
|
||||
if (!minified) {
|
||||
builder.append("\n")
|
||||
}
|
||||
builder.append(css)
|
||||
builder.append("}")
|
||||
if (!minified) {
|
||||
builder.append("\n\n")
|
||||
}
|
||||
}
|
||||
|
||||
builder.append(prop.generateCss( "$namespace $name".trim(), indent, minified))
|
||||
}
|
||||
|
||||
return builder.toString()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,12 +15,12 @@ object TestCssBuilder {
|
||||
|
||||
css.style {
|
||||
|
||||
css(".test") {
|
||||
select(".test") {
|
||||
top = px(10)
|
||||
left = em(5)
|
||||
backgroundColor = rgba(255, 255, 255, 0.75)
|
||||
|
||||
css("> a") {
|
||||
select("> a") {
|
||||
color = hsl(200, 50, 50)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,32 +29,32 @@ private fun generateCss(
|
||||
val css = CssBuilder()
|
||||
|
||||
css.style {
|
||||
css("body") {
|
||||
select("body") {
|
||||
fontFamily = base.mainFont
|
||||
color = base.mainColor
|
||||
backgroundColor = base.mainBackgroundColor
|
||||
alignContent = AlignContent.initial()
|
||||
}
|
||||
|
||||
css(".test") {
|
||||
select(".test") {
|
||||
top = px(10)
|
||||
left = em(5)
|
||||
backgroundColor = Color.rgba(255, 255, 255, 0.75)
|
||||
|
||||
css("> a") {
|
||||
select("> a") {
|
||||
color = Color.hsl(200, 50, 50)
|
||||
}
|
||||
}
|
||||
|
||||
css("nav") {
|
||||
css("ul") {
|
||||
select("nav") {
|
||||
select("ul") {
|
||||
color = Color.hsl(0, 100, 25)
|
||||
backgroundColor = base.mainBackgroundColor
|
||||
}
|
||||
css("li") {
|
||||
select("li") {
|
||||
sizePX(25, 25, 200, 200)
|
||||
|
||||
css("a") {
|
||||
select("a") {
|
||||
width = px(725)
|
||||
background = text("")
|
||||
backgroundColor = base.mainBackgroundColor
|
||||
@@ -78,12 +78,12 @@ fun main() {
|
||||
println(css2)
|
||||
|
||||
val sd = css {
|
||||
css("#pipo") {
|
||||
select("#pipo") {
|
||||
backgroundColor = Color.hex("eeeeee")
|
||||
fontFamily = text("Arial, Courier")
|
||||
animationDelay = listOf(DelayDuration.initial())
|
||||
|
||||
css("div") {
|
||||
select("div") {
|
||||
color = Color.hex("1b1b1b1")
|
||||
alignContent = AlignContent.flexStart()
|
||||
animationName = listOf(text("foo"), text("bar"))
|
||||
|
||||
@@ -2,7 +2,8 @@ package nl.astraeus.css
|
||||
|
||||
import nl.astraeus.css.properties.*
|
||||
import nl.astraeus.css.properties.AlignContent.Companion.flexStart
|
||||
import nl.astraeus.css.style.StyleDefinition
|
||||
import nl.astraeus.css.style.Css
|
||||
import nl.astraeus.css.style.Style
|
||||
|
||||
class StyleBase(
|
||||
val mainColor: Color = Color.hsl(128, 50, 50),
|
||||
@@ -10,7 +11,7 @@ class StyleBase(
|
||||
val mainFont: TextProperty = text("Arial")
|
||||
)
|
||||
|
||||
private fun StyleDefinition.sizePX(
|
||||
private fun Style.sizePX(
|
||||
left: Int,
|
||||
top: Int,
|
||||
width: Int,
|
||||
@@ -28,31 +29,31 @@ private fun generateCss(
|
||||
val css = CssBuilder()
|
||||
|
||||
css.style {
|
||||
css("body") {
|
||||
select("body") {
|
||||
fontFamily = base.mainFont
|
||||
color = base.mainColor
|
||||
backgroundColor = base.mainBackgroundColor
|
||||
}
|
||||
|
||||
css(".test") {
|
||||
select(".test") {
|
||||
top = Measurement.px(10)
|
||||
left = Measurement.em(5)
|
||||
backgroundColor = Color.rgba(255, 255, 255, 0.75)
|
||||
|
||||
css("> a") {
|
||||
select("> a") {
|
||||
color = Color.hsl(200, 50, 50)
|
||||
}
|
||||
}
|
||||
|
||||
css("nav") {
|
||||
css("ul") {
|
||||
select("nav") {
|
||||
select("ul") {
|
||||
color = Color.hsl(0, 100, 25)
|
||||
backgroundColor = base.mainBackgroundColor
|
||||
}
|
||||
css("li") {
|
||||
select("li") {
|
||||
sizePX(25, 25, 200, 200)
|
||||
|
||||
css("a") {
|
||||
select("a") {
|
||||
width = Measurement.px(725)
|
||||
background = text("red initial")
|
||||
backgroundColor = base.mainBackgroundColor
|
||||
@@ -76,34 +77,83 @@ fun main() {
|
||||
println(css1)
|
||||
println(css2)
|
||||
|
||||
val sd = css {
|
||||
css("#pipo") {
|
||||
val border = css {
|
||||
borderRadius = BorderRadius(1, 2, 3, 4)
|
||||
borderColor = listOf(Color.hsl(22,66,55))
|
||||
|
||||
select("a") {
|
||||
width = Measurement.px(10)
|
||||
}
|
||||
}
|
||||
|
||||
val border2: Css = {
|
||||
borderRadius = BorderRadius(1, 2, 3, 4)
|
||||
borderColor = listOf(Color.hsl(20,60,50))
|
||||
}
|
||||
|
||||
val font: Css = {
|
||||
fontFamily = text("Arial, Courier")
|
||||
fontSize = FontSize.larger()
|
||||
}
|
||||
|
||||
val sd = style {
|
||||
select("#pipo") {
|
||||
backgroundColor = Color.hex("eeeeee")
|
||||
fontFamily = text("Arial, Courier")
|
||||
animationDelay = listOf(DelayDuration.initial())
|
||||
|
||||
css("div") {
|
||||
select("div") {
|
||||
fontFace {
|
||||
fontFamily = text("SanSation")
|
||||
fontSize = FontSize.larger()
|
||||
src = text("font/sansation_bold.woff")
|
||||
fontStretch = FontStretch.condensed()
|
||||
fontStyle = FontStyle.italic()
|
||||
fontWeight = FontWeight._600()
|
||||
}
|
||||
|
||||
fontFamily = text("SanSation")
|
||||
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()
|
||||
)
|
||||
borderRadius = listOf(
|
||||
BorderRadius.px(4),
|
||||
BorderRadius.px(5),
|
||||
BorderRadius.px(6),
|
||||
BorderRadius.px(7),
|
||||
BorderRadius.px(8)
|
||||
)
|
||||
select("span") {
|
||||
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)
|
||||
}
|
||||
select("border-1") {
|
||||
apply(border2)
|
||||
borderRadius = BorderRadius(4, 5, 6, 7)
|
||||
}
|
||||
select("border-2") {
|
||||
borderRadius = BorderRadius(4, 5, 6, 7)
|
||||
apply(border2)
|
||||
|
||||
display = Display.none()
|
||||
borderBottomWidth = BorderWidth.perc(13)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
val borderStyle = style {
|
||||
select(".border") {
|
||||
apply(border)
|
||||
apply(font)
|
||||
|
||||
select("> p") {
|
||||
fontSize = FontSize.smaller()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,4 +162,6 @@ fun main() {
|
||||
println(sd.generateCss())
|
||||
println("======")
|
||||
println(sd.generateCss(minified = true))
|
||||
println("======")
|
||||
println(borderStyle.generateCss())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user