mirror of
https://github.com/phfroidmont/scalive.git
synced 2025-12-25 13:36:59 +01:00
Fix splitByIndex diff
This commit is contained in:
parent
681feced9f
commit
eab5eb3316
4 changed files with 65 additions and 21 deletions
|
|
@ -41,19 +41,18 @@ object DiffBuilder:
|
|||
case Content.DynElementColl(dyn) => ???
|
||||
case Content.DynSplit(splitVar) =>
|
||||
splitVar.render(trackUpdates) match
|
||||
case Some((entries, keysCount)) =>
|
||||
case Some((entries, keysCount, includeStatics)) =>
|
||||
val static =
|
||||
entries.collectFirst { case (_, Some(el)) => el.static }.getOrElse(List.empty)
|
||||
val includeStatic = !trackUpdates || keysCount == entries.count(_._2.isDefined)
|
||||
if !trackUpdates || includeStatics then
|
||||
entries.collectFirst { case (_, el) => el.static }.getOrElse(List.empty)
|
||||
else List.empty
|
||||
List(
|
||||
Some(
|
||||
Diff.Comprehension(
|
||||
static = if includeStatic then static else Seq.empty,
|
||||
entries = entries.map {
|
||||
case (key, Some(el)) =>
|
||||
Diff.Dynamic(key.toString, build(Seq.empty, el.dynamicMods, trackUpdates))
|
||||
case (key, None) => Diff.Dynamic(key.toString, Diff.Deleted)
|
||||
},
|
||||
static = static,
|
||||
entries = entries.map((key, el) =>
|
||||
Diff.Dynamic(key.toString, build(Seq.empty, el.dynamicMods, trackUpdates))
|
||||
),
|
||||
count = keysCount
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -99,10 +99,12 @@ private class SplitVar[I, O, Key](
|
|||
private val memoized: mutable.Map[Key, (Var[I], O)] =
|
||||
mutable.Map.empty
|
||||
|
||||
private var nonEmptySyncCount = 0
|
||||
|
||||
private[scalive] def sync(): Unit =
|
||||
parent.sync()
|
||||
if parent.changed then
|
||||
// We keep track of the key to set deleted ones to None
|
||||
// We keep track of the keys to remove deleted ones afterwards
|
||||
val nextKeys = mutable.HashSet.empty[Key]
|
||||
parent.currentValue.foreach(input =>
|
||||
val entryKey = key(input)
|
||||
|
|
@ -122,16 +124,19 @@ private class SplitVar[I, O, Key](
|
|||
if !nextKeys.contains(k) then
|
||||
val _ = memoized.remove(k)
|
||||
)
|
||||
if memoized.nonEmpty then nonEmptySyncCount += 1
|
||||
|
||||
private[scalive] def render(trackUpdates: Boolean)
|
||||
: Option[(changeList: List[(Key, Option[O])], keysCount: Int)] =
|
||||
: Option[(changeList: List[(Int, O)], keysCount: Int, includeStatics: Boolean)] =
|
||||
if parent.changed || !trackUpdates then
|
||||
Some(
|
||||
(
|
||||
memoized.collect {
|
||||
case (k, (entryVar, output)) if !trackUpdates || entryVar.changed => (k, Some(output))
|
||||
changeList = memoized.values.zipWithIndex.collect {
|
||||
case ((entryVar, output), index) if !trackUpdates || entryVar.changed =>
|
||||
(index, output)
|
||||
}.toList,
|
||||
memoized.size
|
||||
keysCount = memoized.size,
|
||||
includeStatics = nonEmptySyncCount == 1
|
||||
)
|
||||
)
|
||||
else None
|
||||
|
|
|
|||
|
|
@ -33,13 +33,11 @@ object HtmlBuilder:
|
|||
dyn.render(false).foreach(_.foreach(el => build(el.static, el.dynamicMods, strw)))
|
||||
case Content.DynElementColl(dyn) => ???
|
||||
case Content.DynSplit(splitVar) =>
|
||||
val (entries, _) = splitVar.render(false).getOrElse(List.empty -> 0)
|
||||
val staticOpt = entries.collectFirst { case (_, Some(el)) => el.static }
|
||||
entries.foreach {
|
||||
case (_, Some(entryEl)) =>
|
||||
build(staticOpt.getOrElse(Nil), entryEl.dynamicMods, strw)
|
||||
case _ => ()
|
||||
}
|
||||
val (entries, _, _) = splitVar.render(false).getOrElse((List.empty, 0, true))
|
||||
val staticOpt = entries.collectFirst { case (_, el) => el.static }
|
||||
entries.foreach((_, entryEl) =>
|
||||
build(staticOpt.getOrElse(Nil), entryEl.dynamicMods, strw)
|
||||
)
|
||||
strw.write(static.last)
|
||||
|
||||
end HtmlBuilder
|
||||
|
|
|
|||
|
|
@ -290,6 +290,48 @@ object LiveViewSpec extends TestSuite:
|
|||
)
|
||||
)
|
||||
}
|
||||
test("diff add one to empty list") {
|
||||
val model = Var(TestModel(items = List.empty))
|
||||
val el =
|
||||
div(
|
||||
ul(
|
||||
model(_.items).splitByIndex((_, elem) =>
|
||||
li(
|
||||
"Nom: ",
|
||||
elem(_.name),
|
||||
" Age: ",
|
||||
elem(_.age.toString)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
el.syncAll()
|
||||
el.setAllUnchanged()
|
||||
|
||||
model.update(_.copy(items = List(NestedModel("a", 20))))
|
||||
|
||||
assertEqualsDiff(
|
||||
el,
|
||||
Json.Obj(
|
||||
"0" ->
|
||||
Json
|
||||
.Obj(
|
||||
"s" -> Json.Arr(
|
||||
Json.Str("<li>Nom: "),
|
||||
Json.Str(" Age: "),
|
||||
Json.Str("</li>")
|
||||
),
|
||||
"k" -> Json.Obj(
|
||||
"0" -> Json.Obj(
|
||||
"0" -> Json.Str("a"),
|
||||
"1" -> Json.Str("20")
|
||||
),
|
||||
"kc" -> Json.Num(1)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
test("diff with first item removed") {
|
||||
model.update(_.copy(items = initModel.items.tail))
|
||||
assertEqualsDiff(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue