feat: CSR WIP
This commit is contained in:
parent
0c0ed26408
commit
959241c16b
19 changed files with 172 additions and 65 deletions
|
@ -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 */
|
||||
|
|
|
@ -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]
|
||||
) {}
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
package top.davidon.sfs.dom
|
||||
|
||||
object SFS extends ScalaFullStack {}
|
|
@ -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
|
|
@ -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
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package top.davidon.sfs.dom.codecs
|
||||
|
||||
//trait StringCodec[T] extends Codec[T, String] {}
|
||||
type StringCodec[T] = Codec[T, String]
|
|
@ -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
|
||||
)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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] {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue