Skip to content

Commit 080ca6a

Browse files
committed
Fixed web history rewriting incorrectly when started via a link
1 parent 67adb50 commit 080ca6a

File tree

4 files changed

+32
-14
lines changed

4 files changed

+32
-14
lines changed

decompose/src/webMain/kotlin/com/arkivanov/decompose/router/webhistory/WebHistoryNavigation.kt

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,15 @@ internal fun <T : Any> enableWebHistory(navigation: WebNavigation<T>, browserHis
6060
browserHistory.replaceState(nodes)
6161
}
6262
},
63-
onRewrite = { oldSize, newHistory ->
64-
if (oldSize > 1) {
63+
onRewrite = { newHistory ->
64+
val currentIndex = browserHistory.currentIndex()
65+
if (currentIndex > 0) {
6566
browserHistory.setOnPopStateListener {
6667
browserHistory.setOnPopStateListener(::onPopState)
6768
browserHistory.replaceState(newHistory.first())
6869
newHistory.drop(1).forEach(browserHistory::pushState)
6970
}
70-
71-
browserHistory.go(-oldSize + 1)
71+
browserHistory.go(-currentIndex)
7272
} else {
7373
browserHistory.replaceState(newHistory.first())
7474
newHistory.drop(1).forEach(browserHistory::pushState)
@@ -135,7 +135,7 @@ private fun <T : Any> WebNavigation<T>.subscribe(
135135
isEnabled: () -> Boolean,
136136
onPush: (List<NodeHistory<T>>) -> Unit,
137137
onPop: (count: Int, NodeHistory<T>) -> Unit,
138-
onRewrite: (oldSize: Int, newHistory: List<NodeHistory<T>>) -> Unit,
138+
onRewrite: (newHistory: List<NodeHistory<T>>) -> Unit,
139139
onUpdateUrl: (NodeHistory<T>) -> Unit,
140140
): Cancellation {
141141
var activeChildCancellation: Cancellation? = null
@@ -164,11 +164,8 @@ private fun <T : Any> WebNavigation<T>.subscribe(
164164
onPop = { count, childNodes ->
165165
onPop(count, inactiveNodes + nodeOf(item = activeItem, children = childNodes))
166166
},
167-
onRewrite = { oldSize, childHistory ->
168-
onRewrite(
169-
oldSize,
170-
childHistory.map { childNodes -> inactiveNodes + nodeOf(item = activeItem, children = childNodes) },
171-
)
167+
onRewrite = { childHistory ->
168+
onRewrite(childHistory.map { childNodes -> inactiveNodes + nodeOf(item = activeItem, children = childNodes) })
172169
},
173170
onUpdateUrl = { childNodes ->
174171
onUpdateUrl(inactiveNodes + nodeOf(item = activeItem, children = childNodes))
@@ -182,7 +179,7 @@ private fun <T : Any> WebNavigation<T>.onHistoryChanged(
182179
oldHistory: List<HistoryItem<T>>,
183180
onPush: (List<NodeHistory<T>>) -> Unit,
184181
onPop: (count: Int, NodeHistory<T>) -> Unit,
185-
onRewrite: (oldSize: Int, newHistory: List<NodeHistory<T>>) -> Unit,
182+
onRewrite: (newHistory: List<NodeHistory<T>>) -> Unit,
186183
onUpdateUrl: (NodeHistory<T>) -> Unit,
187184
) {
188185
val newKeys = newHistory.map { it.key }
@@ -226,9 +223,7 @@ private fun <T : Any> WebNavigation<T>.onHistoryChanged(
226223
previousNodes += itemHistory.last()
227224
}
228225

229-
val oldPaths = oldHistory.flatMap(::historyOf)
230-
231-
onRewrite(oldPaths.size, historyChange)
226+
onRewrite(historyChange)
232227
}
233228
}
234229
}

decompose/src/webTest/kotlin/com/arkivanov/decompose/router/webhistory/TestBrowserHistory.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.arkivanov.decompose.router.webhistory
22

33
import kotlin.test.assertEquals
4+
import kotlin.test.assertTrue
45

56
class TestBrowserHistory : BrowserHistory {
67

@@ -13,7 +14,9 @@ class TestBrowserHistory : BrowserHistory {
1314

1415
override fun go(delta: Int) {
1516
scheduleOperation {
17+
val oldIndex = index
1618
index += delta
19+
assertTrue(index in stack.indices, "Invalid go operation: delta=$delta, index=$oldIndex, range=${stack.indices}")
1720
onPopStateListener?.invoke(stack[index].data)
1821
}
1922
}

decompose/src/webTest/kotlin/com/arkivanov/decompose/router/webhistory/TestWebNavigation.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import com.arkivanov.decompose.value.Value
66
import kotlinx.serialization.KSerializer
77
import kotlinx.serialization.builtins.serializer
88
import kotlin.test.assertContentEquals
9+
import kotlin.test.assertEquals
910
import kotlin.test.assertNotNull
1011
import kotlin.test.assertNull
1112

decompose/src/webTest/kotlin/com/arkivanov/decompose/router/webhistory/WebHistoryNavigationTest.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,25 @@ class WebHistoryNavigationTest {
779779
assertHistory(nav = nav, urls = listOf("/1/1/1", "/1/1/2"))
780780
}
781781

782+
@Test
783+
fun GIVEN_created_one_root_and_two_children_WHEN_root_replaced_with_with_one_child_THEN_one_item_in_history() {
784+
val nav =
785+
TestWebNavigation(initialHistory = listOf(1)) { cfg ->
786+
when (cfg) {
787+
1 -> TestWebNavigation(initialHistory = listOf(12, 13))
788+
2 -> TestWebNavigation(initialHistory = listOf(22))
789+
else -> null
790+
}
791+
}
792+
793+
enableWebHistory(nav, history)
794+
795+
nav.navigate(listOf(2))
796+
history.runPendingOperations()
797+
798+
assertHistory(nav = nav, urls = listOf("/2/22"))
799+
}
800+
782801
private fun assertHistory(nav: TestWebNavigation, urls: List<String>, index: Int = urls.lastIndex) {
783802
history.assertStack(urls = urls, index = index)
784803
nav.assertHistory(urls = urls.slice(0..index))

0 commit comments

Comments
 (0)