feat: CSR WIP

This commit is contained in:
DavidOnTop 2024-09-21 16:56:25 +02:00
parent 0c0ed26408
commit 959241c16b
No known key found for this signature in database
GPG key ID: 5D05538A45D5149F
19 changed files with 172 additions and 65 deletions

View file

@ -1,5 +1,6 @@
package top.davidon.sfs.dom
import top.davidon.sfs.dom.codecs.StringCodec
import top.davidon.sfs.dom.tags.Tag
/** tag + modifiers + value */

View file

@ -1,6 +1,9 @@
package top.davidon.sfs.dom
import top.davidon.sfs.dom.Value
import top.davidon.sfs.dom.codecs.Codec
import top.davidon.sfs.dom.keys.Key
class Modifier[F, T](val key: Key, val value: Value[F, T]) {}
class Modifier[F, T](
val key: Key,
val value: Value[F, T]
) {}

View file

@ -1,3 +0,0 @@
package top.davidon.sfs.dom
object SFS extends ScalaFullStack {}

View file

@ -7,7 +7,7 @@ import top.davidon.sfs.dom.defs.eventProps.GlobalEventProps
import top.davidon.sfs.dom.defs.props.HtmlProps
import top.davidon.sfs.dom.defs.tags.{HtmlTags, SvgTags}
trait ScalaFullStack
trait ScalaFullStackDOM
extends HtmlTags
with HtmlAttrs
with HtmlProps

View file

@ -4,16 +4,22 @@ import top.davidon.sfs.dom.codecs.{Codec, StringAsIsCodec}
class Value[F, T](
val value: F,
val codec: Codec[F, T],
var isReactive: Boolean = false
val codec: Codec[F, T]
) {
def apply(): T = {
codec.encode(value)
}
def reactive(value: Boolean = true): Value[F, T] = {
isReactive = value
this
override def toString: String = {
value match
case v: Int => codecs.IntAsStringCodec.encode(v)
case v: Long => codecs.LongAsStringCodec.encode(v)
case v: Double => codecs.DoubleAsStringCodec.encode(v)
case v: Boolean => codecs.BooleanAsTrueFalseStringCodec.encode(v)
case v: Iterable[String] =>
codecs.IterableAsSpaceSeparatedStringCodec.encode(v)
case _ =>
throw Exception("Couldn't find codec to convert a value to a string")
}
}
@ -22,9 +28,8 @@ object Value {
iterator: Iterable[Value[?, String]]
): Value[String, String] = {
Value(
iterator.map(v => v.codec.encode(v.value)).mkString(""),
StringAsIsCodec,
iterator.exists(_.isReactive)
iterator.map(v => v.toString).mkString(""),
StringAsIsCodec
)
}

View file

@ -0,0 +1,7 @@
package top.davidon.sfs.dom.codecs
class AsIsCodec[T](val strCodec: StringCodec[T]) extends Codec[T, T] {
override def encode(scalaValue: T): T = scalaValue
override def decode(domValue: T): T = domValue
}

View file

@ -0,0 +1,4 @@
package top.davidon.sfs.dom.codecs
//trait StringCodec[T] extends Codec[T, String] {}
type StringCodec[T] = Codec[T, String]

View file

@ -2,28 +2,26 @@ package top.davidon.sfs.dom
package object codecs {
lazy val IntAsStringCodec: Codec[Int, String] = new Codec[Int, String] {
lazy val IntAsStringCodec: StringCodec[Int] =
new StringCodec[Int] {
override def decode(domValue: String): Int =
domValue.toInt // @TODO this can throw exception. How do we handle this?
override def decode(domValue: String): Int =
domValue.toInt // @TODO this can throw exception. How do we handle this?
override def encode(scalaValue: Int): String = scalaValue.toString
}
override def encode(scalaValue: Int): String = scalaValue.toString
}
lazy val DoubleAsIsCodec: Codec[Double, Double] = AsIsCodec()
lazy val DoubleAsStringCodec: Codec[Double, String] =
new Codec[Double, String] {
lazy val DoubleAsStringCodec: StringCodec[Double] =
new StringCodec[Double] {
override def decode(domValue: String): Double =
domValue.toDouble // @TODO this can throw exception. How do we handle this?
override def encode(scalaValue: Double): String = scalaValue.toString
}
lazy val LongAsIsCodec: Codec[Long, Long] = AsIsCodec()
lazy val LongAsStringCodec: Codec[Long, String] =
new Codec[Long, String] {
lazy val LongAsStringCodec: StringCodec[Long] =
new StringCodec[Long] {
override def decode(domValue: String): Long =
domValue.toLong // @TODO this can throw exception. How do we handle this?
@ -31,8 +29,8 @@ package object codecs {
override def encode(scalaValue: Long): String = scalaValue.toString
}
lazy val BooleanAsTrueFalseStringCodec: Codec[Boolean, String] =
new Codec[Boolean, String] {
lazy val BooleanAsTrueFalseStringCodec: StringCodec[Boolean] =
new StringCodec[Boolean] {
override def decode(domValue: String): Boolean = domValue == "true"
@ -40,16 +38,16 @@ package object codecs {
if scalaValue then "true" else "false"
}
lazy val BooleanAsYesNoStringCodec: Codec[Boolean, String] =
new Codec[Boolean, String] {
lazy val BooleanAsYesNoStringCodec: StringCodec[Boolean] =
new StringCodec[Boolean] {
override def decode(domValue: String): Boolean = domValue == "yes"
override def encode(scalaValue: Boolean): String =
if scalaValue then "yes" else "no"
}
lazy val BooleanAsOnOffStringCodec: Codec[Boolean, String] =
new Codec[Boolean, String] {
lazy val BooleanAsOnOffStringCodec: StringCodec[Boolean] =
new StringCodec[Boolean] {
override def decode(domValue: String): Boolean = domValue == "on"
@ -57,9 +55,8 @@ package object codecs {
if scalaValue then "on" else "off"
}
lazy val IterableAsSpaceSeparatedStringCodec
: Codec[Iterable[String], String] =
new Codec[Iterable[String], String] { // could use for e.g. className
lazy val IterableAsSpaceSeparatedStringCodec: StringCodec[Iterable[String]] =
new StringCodec[Iterable[String]] { // could use for e.g. className
override def decode(domValue: String): Iterable[String] =
if domValue == "" then Nil else domValue.split(' ')
@ -67,9 +64,8 @@ package object codecs {
override def encode(scalaValue: Iterable[String]): String =
scalaValue.mkString(" ")
}
lazy val IterableAsCommaSeparatedStringCodec
: Codec[Iterable[String], String] =
new Codec[Iterable[String], String] { // could use for lists of IDs
lazy val IterableAsCommaSeparatedStringCodec: StringCodec[Iterable[String]] =
new StringCodec[Iterable[String]] { // could use for lists of IDs
override def decode(domValue: String): Iterable[String] =
if domValue == "" then Nil else domValue.split(',')
@ -77,12 +73,8 @@ package object codecs {
override def encode(scalaValue: Iterable[String]): String =
scalaValue.mkString(",")
}
val StringAsIsCodec: Codec[String, String] = AsIsCodec()
val IntAsIsCodec: Codec[Int, Int] = AsIsCodec()
val BooleanAsIsCodec: Codec[Boolean, Boolean] = AsIsCodec()
val BooleanAsAttrPresenceCodec: Codec[Boolean, String] =
new Codec[Boolean, String] {
lazy val BooleanAsAttrPresenceCodec: StringCodec[Boolean] =
new StringCodec[Boolean] {
override def decode(domValue: String): Boolean = domValue != null
@ -90,9 +82,12 @@ package object codecs {
if scalaValue then "" else null
}
def AsIsCodec[V](): Codec[V, V] = new Codec[V, V] {
override def encode(scalaValue: V): V = scalaValue
override def decode(domValue: V): V = domValue
}
lazy val LongAsIsCodec: AsIsCodec[Long] = AsIsCodec(LongAsStringCodec)
lazy val DoubleAsIsCodec: AsIsCodec[Double] = AsIsCodec(DoubleAsStringCodec)
lazy val StringAsIsCodec: AsIsCodec[String] & StringCodec[String] =
new AsIsCodec[String](StringAsIsCodec) with StringCodec[String] {}
lazy val IntAsIsCodec: AsIsCodec[Int] = AsIsCodec(IntAsStringCodec)
lazy val BooleanAsIsCodec: AsIsCodec[Boolean] = AsIsCodec(
BooleanAsTrueFalseStringCodec
)
}

View file

@ -1,10 +1,10 @@
package top.davidon.sfs.dom.keys
import top.davidon.sfs.dom.codecs.Codec
import top.davidon.sfs.dom.codecs.{Codec, StringCodec}
import top.davidon.sfs.dom.{Modifier, Value}
class AriaAttr[V](
suffix: String,
val codec: Codec[V, String]
val codec: StringCodec[V]
) extends Key {
override val name: String = "aria-" + suffix

View file

@ -1,11 +1,11 @@
package top.davidon.sfs.dom.keys
import top.davidon.sfs.dom.codecs.Codec
import top.davidon.sfs.dom.codecs.{Codec, StringCodec}
import top.davidon.sfs.dom.{Modifier, Value}
class HtmlAttr[V](
override val name: String,
val codec: Codec[V, String]
val codec: StringCodec[V]
) extends Key {
@inline def apply(value: V): Modifier[V, String] = {
this := value

View file

@ -1,10 +1,10 @@
package top.davidon.sfs.dom.keys
import top.davidon.sfs.dom.codecs.Codec
import top.davidon.sfs.dom.codecs.{Codec, StringCodec}
import top.davidon.sfs.dom.{Modifier, Value}
class SvgAttr[V](
val localName: String,
val codec: Codec[V, String],
val codec: StringCodec[V],
val namespacePrefix: Option[String]
) extends Key {
override val name: String =

View file

@ -1,6 +1,7 @@
package top.davidon.sfs.dom.tags
import org.scalajs.dom
import top.davidon.sfs.dom.codecs.StringCodec
import top.davidon.sfs.dom.{Element, Modifier, Value}
trait Tag[+Ref <: dom.Element] {