mirror of
https://github.com/phfroidmont/scalive.git
synced 2025-12-25 13:36:59 +01:00
Add more JS commands
This commit is contained in:
parent
b0caefd0f4
commit
66c2ac5d71
1 changed files with 224 additions and 15 deletions
|
|
@ -14,13 +14,182 @@ object JSCommands:
|
||||||
given JsonEncoder[JSCommand] =
|
given JsonEncoder[JSCommand] =
|
||||||
JsonEncoder[Json].contramap(ops => Json.Arr(ops.reverse*))
|
JsonEncoder[Json].contramap(ops => Json.Arr(ops.reverse*))
|
||||||
|
|
||||||
private def classNames(names: String) = names.split("\\s+")
|
private def classNames(names: String): Seq[String] = names.split("\\s+")
|
||||||
|
private def transitionClasses(names: String | (String, String, String))
|
||||||
|
: Option[Seq[Seq[String]]] =
|
||||||
|
names match
|
||||||
|
case "" => None
|
||||||
|
case names: String => Some(Seq(classNames(names), Seq.empty, Seq.empty))
|
||||||
|
case t: (String, String, String) => Some(t.toList.map(classNames))
|
||||||
|
|
||||||
extension (ops: JSCommand)
|
extension (ops: JSCommand)
|
||||||
private def addOp[A: JsonEncoder](kind: String, args: A) =
|
private def addOp[A: JsonEncoder](kind: String, args: A): JSCommand =
|
||||||
(kind, args).toJsonAST.getOrElse(throw new IllegalArgumentException()) :: ops
|
(kind, args).toJsonAST.fold(e => throw new IllegalArgumentException(e), identity) :: ops
|
||||||
|
|
||||||
def toggleClass(
|
def addClass = ClassOp("add_class", ops)
|
||||||
|
def toggleClass = ClassOp("toggle_class", ops)
|
||||||
|
def removeClass = ClassOp("remove_class", ops)
|
||||||
|
|
||||||
|
def dispatch(
|
||||||
|
event: String,
|
||||||
|
to: String = "",
|
||||||
|
detail: Map[String, String] = Map.empty,
|
||||||
|
bubbles: Boolean = true,
|
||||||
|
blocking: Boolean = false
|
||||||
|
) =
|
||||||
|
ops.addOp(
|
||||||
|
"dispatch",
|
||||||
|
Args.Dispatch(
|
||||||
|
event,
|
||||||
|
Option.when(to.nonEmpty)(to),
|
||||||
|
Option.when(detail.nonEmpty)(detail),
|
||||||
|
Option.when(!bubbles)(bubbles),
|
||||||
|
Option.when(blocking)(blocking)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def exec(attr: String, to: String = "") =
|
||||||
|
ops.addOp(
|
||||||
|
"exec",
|
||||||
|
Args.Attr(
|
||||||
|
attr,
|
||||||
|
Option.when(to.nonEmpty)(to)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def focus(to: String = "") =
|
||||||
|
ops.addOp(
|
||||||
|
"focus",
|
||||||
|
Args.To(Option.when(to.nonEmpty)(to))
|
||||||
|
)
|
||||||
|
|
||||||
|
def focusFirst(to: String = "") =
|
||||||
|
ops.addOp(
|
||||||
|
"focus_first",
|
||||||
|
Args.To(Option.when(to.nonEmpty)(to))
|
||||||
|
)
|
||||||
|
|
||||||
|
def hide(
|
||||||
|
to: String = "",
|
||||||
|
transition: String | (String, String, String) = "",
|
||||||
|
time: Int = 200,
|
||||||
|
blocking: Boolean = true
|
||||||
|
) =
|
||||||
|
ops.addOp(
|
||||||
|
"hide",
|
||||||
|
Args.Hide(
|
||||||
|
Option.when(to.nonEmpty)(to),
|
||||||
|
transitionClasses(transition),
|
||||||
|
Option.when(time != 200)(time),
|
||||||
|
Option.when(!blocking)(blocking)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def ignoreAttributes(to: String = "") =
|
||||||
|
ops.addOp("ignore_attributes", Args.To(Option.when(to.nonEmpty)(to)))
|
||||||
|
|
||||||
|
def navigate(href: String, replace: Boolean = false) =
|
||||||
|
ops.addOp("navigate", Args.Href(href, Option.when(replace)(replace)))
|
||||||
|
|
||||||
|
def patch(href: String, replace: Boolean = false) =
|
||||||
|
ops.addOp(
|
||||||
|
"patch",
|
||||||
|
Args.Href(href, Option.when(replace)(replace))
|
||||||
|
)
|
||||||
|
|
||||||
|
def popFocus() =
|
||||||
|
ops.addOp("pop_focus", Json.Obj.empty)
|
||||||
|
|
||||||
|
def push() = ???
|
||||||
|
|
||||||
|
def pushFocus(to: String = "") =
|
||||||
|
ops.addOp("push_focus", Args.To(Option.when(to.nonEmpty)(to)))
|
||||||
|
|
||||||
|
def removeAttribute(attr: String, to: String = "") =
|
||||||
|
ops.addOp(
|
||||||
|
"remove_attribute",
|
||||||
|
Args.Attr(
|
||||||
|
attr,
|
||||||
|
Option.when(to.nonEmpty)(to)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def setAttribute(arg: (String, String), to: String = "") =
|
||||||
|
ops.addOp("set_attribute", Args.SetAttribute(arg, Option.when(to.nonEmpty)(to)))
|
||||||
|
|
||||||
|
def show(
|
||||||
|
to: String = "",
|
||||||
|
transition: String | (String, String, String) = "",
|
||||||
|
time: Int = 200,
|
||||||
|
blocking: Boolean = true,
|
||||||
|
display: String = "block"
|
||||||
|
) =
|
||||||
|
ops.addOp(
|
||||||
|
"show",
|
||||||
|
Args.Show(
|
||||||
|
Option.when(to.nonEmpty)(to),
|
||||||
|
transitionClasses(transition),
|
||||||
|
Option.when(time != 200)(time),
|
||||||
|
Option.when(!blocking)(blocking),
|
||||||
|
Option.when(display != "block")(display)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def toggle(
|
||||||
|
to: String = "",
|
||||||
|
in: String | (String, String, String) = "",
|
||||||
|
out: String | (String, String, String) = "",
|
||||||
|
time: Int = 200,
|
||||||
|
blocking: Boolean = true,
|
||||||
|
display: String = "block"
|
||||||
|
) =
|
||||||
|
ops.addOp(
|
||||||
|
"toggle",
|
||||||
|
Args.Toggle(
|
||||||
|
Option.when(to.nonEmpty)(to),
|
||||||
|
transitionClasses(in),
|
||||||
|
transitionClasses(out),
|
||||||
|
Option.when(time != 200)(time),
|
||||||
|
Option.when(!blocking)(blocking),
|
||||||
|
Option.when(display != "block")(display)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def toggleAttribute(
|
||||||
|
name: String,
|
||||||
|
value: String,
|
||||||
|
altValue: String = "",
|
||||||
|
to: String = ""
|
||||||
|
) =
|
||||||
|
ops.addOp(
|
||||||
|
"toggle_attribute",
|
||||||
|
Args.ToggleAttribute(
|
||||||
|
Seq(name, value).appendedAll(Option.when(altValue.nonEmpty)(altValue)),
|
||||||
|
Option.when(to.nonEmpty)(to)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def transition(
|
||||||
|
transition: String | (String, String, String) = "",
|
||||||
|
to: String = "",
|
||||||
|
time: Int = 200,
|
||||||
|
blocking: Boolean = true
|
||||||
|
) =
|
||||||
|
ops.addOp(
|
||||||
|
"transition",
|
||||||
|
Args.Transition(
|
||||||
|
transition match
|
||||||
|
case names: String => Seq(classNames(names), Seq.empty, Seq.empty)
|
||||||
|
case t: (String, String, String) => t.toList.map(classNames),
|
||||||
|
Option.when(to.nonEmpty)(to),
|
||||||
|
Option.when(time != 200)(time),
|
||||||
|
Option.when(!blocking)(blocking)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end extension
|
||||||
|
|
||||||
|
final private[scalive] class ClassOp(kind: String, ops: JSCommand):
|
||||||
|
def apply(
|
||||||
names: String,
|
names: String,
|
||||||
to: String = "",
|
to: String = "",
|
||||||
transition: String | (String, String, String) = "",
|
transition: String | (String, String, String) = "",
|
||||||
|
|
@ -28,26 +197,66 @@ object JSCommands:
|
||||||
blocking: Boolean = true
|
blocking: Boolean = true
|
||||||
) =
|
) =
|
||||||
ops.addOp(
|
ops.addOp(
|
||||||
"toggle_class",
|
kind,
|
||||||
Args.ToggleClass(
|
Args.ClassChange(
|
||||||
classNames(names),
|
classNames(names),
|
||||||
Some(to).filterNot(_.isBlank),
|
Option.when(to.nonEmpty)(to),
|
||||||
transition match
|
transitionClasses(transition),
|
||||||
case "" => None
|
Option.when(time != 200)(time),
|
||||||
case names: String => Some(classNames(names))
|
Option.when(!blocking)(blocking)
|
||||||
case t: (String, String, String) => Some(t.toList),
|
|
||||||
Some(time).filterNot(_ == 200),
|
|
||||||
Some(blocking).filterNot(_ == true)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
private object Args:
|
private object Args:
|
||||||
final case class ToggleClass(
|
final case class ClassChange(
|
||||||
names: Seq[String],
|
names: Seq[String],
|
||||||
to: Option[String],
|
to: Option[String],
|
||||||
transition: Option[Seq[String]],
|
transition: Option[Seq[Seq[String]]],
|
||||||
time: Option[Int],
|
time: Option[Int],
|
||||||
blocking: Option[Boolean])
|
blocking: Option[Boolean])
|
||||||
derives JsonEncoder
|
derives JsonEncoder
|
||||||
|
final case class Dispatch(
|
||||||
|
event: String,
|
||||||
|
to: Option[String],
|
||||||
|
detail: Option[Map[String, String]],
|
||||||
|
bubbles: Option[Boolean],
|
||||||
|
blocking: Option[Boolean])
|
||||||
|
derives JsonEncoder
|
||||||
|
final case class Attr(attr: String, to: Option[String]) derives JsonEncoder
|
||||||
|
final case class To(to: Option[String]) derives JsonEncoder
|
||||||
|
final case class Hide(
|
||||||
|
to: Option[String],
|
||||||
|
transition: Option[Seq[Seq[String]]],
|
||||||
|
time: Option[Int],
|
||||||
|
blocking: Option[Boolean])
|
||||||
|
derives JsonEncoder
|
||||||
|
final case class SetAttribute(
|
||||||
|
arg: (String, String),
|
||||||
|
to: Option[String])
|
||||||
|
derives JsonEncoder
|
||||||
|
final case class Href(href: String, replace: Option[Boolean]) derives JsonEncoder
|
||||||
|
final case class Show(
|
||||||
|
to: Option[String],
|
||||||
|
transition: Option[Seq[Seq[String]]],
|
||||||
|
time: Option[Int],
|
||||||
|
blocking: Option[Boolean],
|
||||||
|
display: Option[String])
|
||||||
|
derives JsonEncoder
|
||||||
|
final case class Toggle(
|
||||||
|
to: Option[String],
|
||||||
|
in: Option[Seq[Seq[String]]],
|
||||||
|
out: Option[Seq[Seq[String]]],
|
||||||
|
time: Option[Int],
|
||||||
|
blocking: Option[Boolean],
|
||||||
|
display: Option[String])
|
||||||
|
derives JsonEncoder
|
||||||
|
final case class ToggleAttribute(arg: Seq[String], to: Option[String]) derives JsonEncoder
|
||||||
|
final case class Transition(
|
||||||
|
transition: Seq[Seq[String]],
|
||||||
|
to: Option[String],
|
||||||
|
time: Option[Int],
|
||||||
|
blocking: Option[Boolean])
|
||||||
|
derives JsonEncoder
|
||||||
|
end Args
|
||||||
|
|
||||||
end JSCommands
|
end JSCommands
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue