More properties, cleanup

This commit is contained in:
2020-03-01 12:47:23 +01:00
parent ba58deeaf5
commit b80873a85a
20 changed files with 636 additions and 231 deletions

View File

@@ -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!!)
}
}