Skip to content

Commit d360dbf

Browse files
authored
[web] Commonize entities in ui and simplify InputEventExt casting (JetBrains#2895)
Goal of this PR is to reduce amount of dubpicated wasm/js sourcesets in the ui module ## Testing `./gradlew testWeb` ## Release Notes N/A
1 parent 04e8ce5 commit d360dbf

13 files changed

Lines changed: 123 additions & 289 deletions

File tree

compose/ui/ui/src/jsMain/kotlin/androidx/compose/ui/internal/jsinterop/JsInteropUtils.js.kt

Lines changed: 0 additions & 22 deletions
This file was deleted.

compose/ui/ui/src/jsMain/kotlin/androidx/compose/ui/platform/DomInputStrategy.js.kt

Lines changed: 0 additions & 23 deletions
This file was deleted.

compose/ui/ui/src/jsMain/kotlin/androidx/compose/ui/platform/PlatformClipboard.js.kt

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ import kotlin.js.Promise
2323
import kotlinx.coroutines.await
2424
import org.w3c.files.Blob
2525

26-
actual typealias NativeClipboard = W3CTemporaryClipboard
27-
2826
private val browserClipboard by lazy {
2927
getW3CClipboard()
3028
}
@@ -152,33 +150,4 @@ private fun createClipboardItemWithPlainText(text: String): Array<ClipboardItem>
152150

153151
// Can't truly clear the clipboard, so setting the empty text
154152
private fun emptyClipboardItems(): Array<ClipboardItem> =
155-
js("[new ClipboardItem({'text/plain': new Blob([''], { type: 'text/plain' })})]")
156-
157-
/**
158-
* https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API
159-
*
160-
* We declare this external interface temporary because
161-
* the IDL in kotlinx-browser is incorrect:
162-
* https://github.com/Kotlin/kotlinx-browser/issues/14
163-
*/
164-
@ExperimentalComposeUiApi
165-
@JsName("Clipboard")
166-
external class W3CTemporaryClipboard {
167-
fun read(): Promise<Array<ClipboardItem>>
168-
fun write(data: Array<ClipboardItem>): Promise<Nothing>
169-
fun writeText(text: String): Promise<Nothing>
170-
}
171-
172-
/**
173-
* https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API
174-
*
175-
* We declare this external interface temporary because
176-
* the IDL in kotlinx-browser is incorrect:
177-
* https://github.com/Kotlin/kotlinx-browser/issues/14
178-
*/
179-
@ExperimentalComposeUiApi
180-
@JsName("ClipboardItem")
181-
external interface ClipboardItem {
182-
val types: Array<String>
183-
fun getType(type: String): Promise<Blob>
184-
}
153+
js("[new ClipboardItem({'text/plain': new Blob([''], { type: 'text/plain' })})]")

compose/ui/ui/src/wasmJsMain/kotlin/androidx/compose/ui/internal/jsinterop/JsInteropUtils.wasmJs.kt

Lines changed: 0 additions & 22 deletions
This file was deleted.

compose/ui/ui/src/wasmJsMain/kotlin/androidx/compose/ui/platform/DomInputStrategy.wasmJs.kt

Lines changed: 0 additions & 23 deletions
This file was deleted.

compose/ui/ui/src/wasmJsMain/kotlin/androidx/compose/ui/platform/PlatformClipboard.wasm.kt

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ import kotlin.js.Promise
2626
import kotlinx.coroutines.await
2727
import org.w3c.files.Blob
2828

29-
actual typealias NativeClipboard = W3CTemporaryClipboard
30-
3129
private val browserClipboard by lazy {
3230
getW3CClipboard()
3331
}
@@ -164,33 +162,4 @@ private fun invalidClipboardItems(): JsArray<ClipboardItem> =
164162

165163
private fun warn(text: String) {
166164
js("console.warn(text)")
167-
}
168-
169-
/**
170-
* https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API
171-
*
172-
* We declare this external interface temporary because
173-
* the IDL in kotlinx-browser is incorrect:
174-
* https://github.com/Kotlin/kotlinx-browser/issues/14
175-
*/
176-
@ExperimentalComposeUiApi
177-
@JsName("Clipboard")
178-
external class W3CTemporaryClipboard {
179-
fun read(): Promise<JsArray<ClipboardItem>>
180-
fun write(data: JsArray<ClipboardItem>): Promise<Nothing>
181-
fun writeText(text: String): Promise<Nothing>
182-
}
183-
184-
/**
185-
* https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API
186-
*
187-
* We declare this external interface temporary because
188-
* the IDL in kotlinx-browser is incorrect:
189-
* https://github.com/Kotlin/kotlinx-browser/issues/14
190-
*/
191-
@ExperimentalComposeUiApi
192-
@JsName("ClipboardItem")
193-
external interface ClipboardItem : JsAny {
194-
val types: JsArray<JsString>
195-
fun getType(type: JsString): Promise<Blob>
196165
}

compose/ui/ui/src/webMain/kotlin/androidx/compose/ui/internal/jsinterop/JsInteropUtils.kt

Lines changed: 0 additions & 23 deletions
This file was deleted.

compose/ui/ui/src/webMain/kotlin/androidx/compose/ui/platform/DomInputStrategy.kt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,10 @@ import kotlin.js.unsafeCast
3131
import kotlinx.browser.document
3232
import kotlinx.browser.window
3333
import org.w3c.dom.HTMLElement
34+
import org.w3c.dom.EventInit
3435
import org.w3c.dom.events.CompositionEvent
3536
import org.w3c.dom.events.Event
37+
import org.w3c.dom.events.UIEvent
3638
import org.w3c.dom.events.InputEvent
3739
import org.w3c.dom.events.KeyboardEvent
3840

@@ -159,16 +161,20 @@ private external interface DocumentOrShadowRootLike : JsAny {
159161
}
160162

161163
@JsName("InputEvent")
162-
internal external class InputEventExt : JsAny {
164+
internal external class InputEventExt : UIEvent {
165+
val data: String?
163166
val inputType: String
164167
var textRangeStart: Int
165168
var textRangeEnd: Int
169+
170+
constructor(type: String, eventInitDict: EventInit = definedExternally)
166171
}
167172

168-
internal val InputEvent.textRangeSize: Int
173+
internal inline fun UIEvent.asInputEventExt(): InputEventExt = unsafeCast<InputEventExt>()
174+
175+
internal val InputEventExt.textRangeSize: Int
169176
get() = this.asInputEventExt().let { it.textRangeEnd - it.textRangeStart }
170177

171-
internal expect inline fun InputEvent.asInputEventExt(): InputEventExt
172178

173179
private fun ImeOptions.createDomElement(): HTMLElement {
174180
val htmlElement = document.createElement(

compose/ui/ui/src/webMain/kotlin/androidx/compose/ui/platform/NativeInputEventsProcessor.kt

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ package androidx.compose.ui.platform
1818

1919
import androidx.compose.runtime.TestOnly
2020
import androidx.compose.ui.input.key.toComposeEvent
21-
import androidx.compose.ui.internal.jsinterop.timestampAsDouble
22-
import androidx.compose.ui.internal.jsinterop.timestampAsInt
2321
import androidx.compose.ui.text.input.BackspaceCommand
2422
import androidx.compose.ui.text.input.CommitTextCommand
2523
import androidx.compose.ui.text.input.SetComposingTextCommand
2624
import androidx.compose.ui.text.input.SetSelectionCommand
2725
import androidx.compose.ui.text.input.TextFieldValue
2826
import androidx.compose.ui.util.fastAny
2927
import androidx.compose.ui.util.fastForEach
28+
import kotlin.js.toDouble
29+
import kotlin.js.toInt
3030
import org.w3c.dom.events.CompositionEvent
3131
import org.w3c.dom.events.InputEvent
3232
import org.w3c.dom.events.KeyboardEvent
@@ -74,7 +74,7 @@ internal abstract class NativeInputEventsProcessor(
7474
fun runCheckpoint(currentTextFieldValue: TextFieldValue) {
7575
isCheckpointScheduled = false
7676

77-
collectedEvents.sortBy { it.timestampAsInt() }
77+
collectedEvents.sortBy { it.timeStamp.toInt() }
7878

7979
val isInIMEComposition = collectedEvents.fastAny {
8080
it.type == "compositionstart"
@@ -85,7 +85,7 @@ internal abstract class NativeInputEventsProcessor(
8585
}
8686

8787
collectedEvents.fastForEach { evt ->
88-
val timestamp = evt.timestampAsDouble()
88+
val timestamp = evt.timeStamp.toDouble()
8989

9090
when (evt.type) {
9191
"keydown" -> {
@@ -123,7 +123,7 @@ internal abstract class NativeInputEventsProcessor(
123123
}
124124

125125
"beforeinput" -> {
126-
(evt as InputEvent).process(
126+
evt.asInputEventExt().process(
127127
currentTextFieldValue = currentTextFieldValue
128128
)
129129
}
@@ -133,9 +133,8 @@ internal abstract class NativeInputEventsProcessor(
133133
collectedEvents.clear()
134134
}
135135

136-
private fun InputEvent.process(currentTextFieldValue: TextFieldValue) {
137-
val inputExt = this.asInputEventExt()
138-
val editCommands = when (inputExt.inputType) {
136+
private fun InputEventExt.process(currentTextFieldValue: TextFieldValue) {
137+
val editCommands = when (inputType) {
139138
"deleteContentBackward" -> buildList {
140139
// this means "deleteContentBackward" happened because of an earlier "keydown" event, so skipping it here
141140
if (lastProcessedKeydown?.isBackspace() == true) return@buildList
@@ -153,7 +152,7 @@ internal abstract class NativeInputEventsProcessor(
153152
// deleteContentBackward can happen under very non-trivial circumstances,
154153
// for instance; when an input suggestion on Android Chrome is accepted,
155154
// the browser then deletes space after the word just to add space again
156-
add(SetSelectionCommand(inputExt.textRangeStart, inputExt.textRangeEnd))
155+
add(SetSelectionCommand(textRangeStart, textRangeEnd))
157156
add(BackspaceCommand())
158157
} else if (textRangeSize == 0) {
159158
// under specific circumstance previous symbol can be deleted while inputing new one
@@ -170,7 +169,7 @@ internal abstract class NativeInputEventsProcessor(
170169
if (lastProcessedKeydown?.altKey == false) {
171170
val layoutResult = composeSender.currentTextLayoutResult() ?: return@buildList
172171
val text = layoutResult.layoutInput.text
173-
val wordBoundary = layoutResult.getWordBoundary(inputExt.textRangeStart.coerceIn(0, text.length - 1))
172+
val wordBoundary = layoutResult.getWordBoundary(textRangeStart.coerceIn(0, text.length - 1))
174173

175174
add(SetSelectionCommand(wordBoundary.start, wordBoundary.end))
176175
add(BackspaceCommand())
@@ -181,7 +180,7 @@ internal abstract class NativeInputEventsProcessor(
181180
"insertReplacementText" -> buildList {
182181
if (data == null) return@buildList
183182
if (textRangeSize > 0) {
184-
add(SetSelectionCommand(inputExt.textRangeStart, inputExt.textRangeEnd))
183+
add(SetSelectionCommand(textRangeStart, textRangeEnd))
185184
}
186185

187186
add(CommitTextCommand(data, 1))
@@ -190,7 +189,7 @@ internal abstract class NativeInputEventsProcessor(
190189
"insertText" -> buildList {
191190
if (data == null) return@buildList
192191
if (textRangeSize > 0 && currentTextFieldValue.selection.collapsed) {
193-
add(SetSelectionCommand(inputExt.textRangeStart, inputExt.textRangeEnd))
192+
add(SetSelectionCommand(textRangeStart, textRangeEnd))
194193
}
195194

196195
add(CommitTextCommand(data, 1))
@@ -199,7 +198,7 @@ internal abstract class NativeInputEventsProcessor(
199198
"insertCompositionText" -> buildList {
200199
if (data == null) return@buildList
201200
if (textRangeSize > 0) {
202-
add(SetSelectionCommand(inputExt.textRangeStart, inputExt.textRangeEnd))
201+
add(SetSelectionCommand(textRangeStart, textRangeEnd))
203202
}
204203
add(SetComposingTextCommand(data, 1))
205204
}

0 commit comments

Comments
 (0)