diff --git a/src/commonMain/kotlin/nl/astraeus/css/CssBuilder.kt b/src/commonMain/kotlin/nl/astraeus/css/CssBuilder.kt index 9e5d75b..f4c3461 100644 --- a/src/commonMain/kotlin/nl/astraeus/css/CssBuilder.kt +++ b/src/commonMain/kotlin/nl/astraeus/css/CssBuilder.kt @@ -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) } diff --git a/src/commonMain/kotlin/nl/astraeus/css/properties/Border.kt b/src/commonMain/kotlin/nl/astraeus/css/properties/Border.kt index 1b7a295..20e53e1 100644 --- a/src/commonMain/kotlin/nl/astraeus/css/properties/Border.kt +++ b/src/commonMain/kotlin/nl/astraeus/css/properties/Border.kt @@ -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") diff --git a/src/commonMain/kotlin/nl/astraeus/css/properties/Clear.kt b/src/commonMain/kotlin/nl/astraeus/css/properties/Clear.kt new file mode 100644 index 0000000..4ad89b6 --- /dev/null +++ b/src/commonMain/kotlin/nl/astraeus/css/properties/Clear.kt @@ -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") + } + +} diff --git a/src/commonMain/kotlin/nl/astraeus/css/properties/Clip.kt b/src/commonMain/kotlin/nl/astraeus/css/properties/Clip.kt new file mode 100644 index 0000000..cb5a22a --- /dev/null +++ b/src/commonMain/kotlin/nl/astraeus/css/properties/Clip.kt @@ -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") + + } +} diff --git a/src/commonMain/kotlin/nl/astraeus/css/properties/Common.kt b/src/commonMain/kotlin/nl/astraeus/css/properties/Common.kt index 6062ba3..a67eb20 100644 --- a/src/commonMain/kotlin/nl/astraeus/css/properties/Common.kt +++ b/src/commonMain/kotlin/nl/astraeus/css/properties/Common.kt @@ -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") } } - diff --git a/src/commonMain/kotlin/nl/astraeus/css/properties/Content.kt b/src/commonMain/kotlin/nl/astraeus/css/properties/Content.kt new file mode 100644 index 0000000..3a392b4 --- /dev/null +++ b/src/commonMain/kotlin/nl/astraeus/css/properties/Content.kt @@ -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") + } + +} diff --git a/src/commonMain/kotlin/nl/astraeus/css/properties/Count.kt b/src/commonMain/kotlin/nl/astraeus/css/properties/Count.kt index fbaa7b3..f895917 100644 --- a/src/commonMain/kotlin/nl/astraeus/css/properties/Count.kt +++ b/src/commonMain/kotlin/nl/astraeus/css/properties/Count.kt @@ -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 = diff --git a/src/commonMain/kotlin/nl/astraeus/css/properties/Direction.kt b/src/commonMain/kotlin/nl/astraeus/css/properties/Direction.kt new file mode 100644 index 0000000..9000760 --- /dev/null +++ b/src/commonMain/kotlin/nl/astraeus/css/properties/Direction.kt @@ -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") + } + +} diff --git a/src/commonMain/kotlin/nl/astraeus/css/properties/Display.kt b/src/commonMain/kotlin/nl/astraeus/css/properties/Display.kt new file mode 100644 index 0000000..b0f6ce0 --- /dev/null +++ b/src/commonMain/kotlin/nl/astraeus/css/properties/Display.kt @@ -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") + } + +} diff --git a/src/commonMain/kotlin/nl/astraeus/css/properties/EmptyCells.kt b/src/commonMain/kotlin/nl/astraeus/css/properties/EmptyCells.kt new file mode 100644 index 0000000..57bd14f --- /dev/null +++ b/src/commonMain/kotlin/nl/astraeus/css/properties/EmptyCells.kt @@ -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") + } + +} diff --git a/src/commonMain/kotlin/nl/astraeus/css/properties/Float.kt b/src/commonMain/kotlin/nl/astraeus/css/properties/Float.kt new file mode 100644 index 0000000..08b1d69 --- /dev/null +++ b/src/commonMain/kotlin/nl/astraeus/css/properties/Float.kt @@ -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") + } + +} diff --git a/src/commonMain/kotlin/nl/astraeus/css/properties/Font.kt b/src/commonMain/kotlin/nl/astraeus/css/properties/Font.kt new file mode 100644 index 0000000..5ab5da3 --- /dev/null +++ b/src/commonMain/kotlin/nl/astraeus/css/properties/Font.kt @@ -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") + } + +} + diff --git a/src/commonMain/kotlin/nl/astraeus/css/properties/Measurement.kt b/src/commonMain/kotlin/nl/astraeus/css/properties/Measurement.kt index d7335e2..016cd3d 100644 --- a/src/commonMain/kotlin/nl/astraeus/css/properties/Measurement.kt +++ b/src/commonMain/kotlin/nl/astraeus/css/properties/Measurement.kt @@ -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") - } -} diff --git a/src/commonMain/kotlin/nl/astraeus/css/properties/Span.kt b/src/commonMain/kotlin/nl/astraeus/css/properties/Span.kt new file mode 100644 index 0000000..1b851dd --- /dev/null +++ b/src/commonMain/kotlin/nl/astraeus/css/properties/Span.kt @@ -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") + } + +} diff --git a/src/commonMain/kotlin/nl/astraeus/css/style/FontFace.kt b/src/commonMain/kotlin/nl/astraeus/css/style/FontFace.kt new file mode 100644 index 0000000..a823b16 --- /dev/null +++ b/src/commonMain/kotlin/nl/astraeus/css/style/FontFace.kt @@ -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 = 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 + ) +} diff --git a/src/commonMain/kotlin/nl/astraeus/css/style/Style.kt b/src/commonMain/kotlin/nl/astraeus/css/style/Style.kt index da17f92..e8457f0 100644 --- a/src/commonMain/kotlin/nl/astraeus/css/style/Style.kt +++ b/src/commonMain/kotlin/nl/astraeus/css/style/Style.kt @@ -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 = mutableMapOf() + val extentions: MutableList = mutableListOf() + + abstract fun getMapping(): Map + + abstract fun getValidator(name: String): List? + + 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)) { + 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? = null, var borderBottomRightRadius: List? = null, - var borderBottomStyle: BorderStyle? = null, + var borderBottomStyle: RuleBorderStyle? = null, var borderBottomWidth: BorderWidth? = null, var borderCollapse: BorderCollapse? = null, var borderColor: List? = null, @@ -50,20 +187,20 @@ open class Style( var borderImageWidth: List? = null, var borderLeft: TextProperty? = null, var borderLeftColor: Color? = null, - var borderLeftStyle: BorderStyle? = null, + var borderLeftStyle: RuleBorderStyle? = null, var borderLeftWidth: BorderWidth? = null, - var borderRadius: List? = 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? = null, - var borderStyle: List? = null, + var borderStyle: List? = 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>( "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 = mapOf( + override fun getValidator(name: String) = validators[name] + + override fun getMapping(): Map = 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)) { - 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!!) } - } diff --git a/src/commonMain/kotlin/nl/astraeus/css/style/StyleDefinition.kt b/src/commonMain/kotlin/nl/astraeus/css/style/StyleDefinition.kt deleted file mode 100644 index b2c621f..0000000 --- a/src/commonMain/kotlin/nl/astraeus/css/style/StyleDefinition.kt +++ /dev/null @@ -1,51 +0,0 @@ -package nl.astraeus.css.style - -@CssTagMarker -open class StyleDefinition : Style() { - val definitions: MutableMap = mutableMapOf() - val includes: MutableList