-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
Copy pathJSDispatcher.kt
70 lines (52 loc) · 2.16 KB
/
JSDispatcher.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package kotlinx.coroutines
import org.w3c.dom.*
import kotlin.js.Promise
internal actual typealias W3CWindow = Window
internal actual fun w3cSetTimeout(window: W3CWindow, handler: () -> Unit, timeout: Int): Int =
setTimeout(window, handler, timeout)
internal actual fun w3cSetTimeout(handler: () -> Unit, timeout: Int): Int =
setTimeout(handler, timeout)
internal actual fun w3cClearTimeout(window: W3CWindow, handle: Int) =
window.clearTimeout(handle)
internal actual fun w3cClearTimeout(handle: Int) =
clearTimeout(handle)
internal actual class ScheduledMessageQueue actual constructor(private val dispatcher: SetTimeoutBasedDispatcher) : MessageQueue() {
internal val processQueue: dynamic = { process() }
actual override fun schedule() {
dispatcher.scheduleQueueProcessing()
}
actual override fun reschedule() {
setTimeout(processQueue, 0)
}
internal actual fun setTimeout(timeout: Int) {
setTimeout(processQueue, timeout)
}
}
internal object NodeDispatcher : SetTimeoutBasedDispatcher() {
override fun scheduleQueueProcessing() {
process.nextTick(messageQueue.processQueue)
}
}
internal actual class WindowMessageQueue actual constructor(private val window: W3CWindow) : MessageQueue() {
private val messageName = "dispatchCoroutine"
init {
window.addEventListener("message", { event: dynamic ->
if (event.source == window && event.data == messageName) {
event.stopPropagation()
process()
}
}, true)
}
actual override fun schedule() {
Promise.resolve(Unit).then({ process() })
}
actual override fun reschedule() {
window.postMessage(messageName, "*")
}
}
// We need to reference global setTimeout and clearTimeout so that it works on Node.JS as opposed to
// using them via "window" (which only works in browser)
private external fun setTimeout(handler: dynamic, timeout: Int = definedExternally): Int
private external fun clearTimeout(handle: Int = definedExternally)
private fun setTimeout(window: Window, handler: () -> Unit, timeout: Int): Int =
window.setTimeout(handler, timeout)