From c877fcbce37cc6a4f1049a5a8ed7a2762445d739 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 2 Dec 2023 23:07:00 +0300 Subject: [PATCH] Add plain html input renderer --- .../kscience/visionforge/JsVisionClient.kt | 1 + .../kscience/visionforge/inputRenderers.kt | 71 +++++++++++-------- 2 files changed, 42 insertions(+), 30 deletions(-) diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt index 388ed2af..6ae70280 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt @@ -264,6 +264,7 @@ public class JsVisionClient : AbstractPlugin(), VisionClient { override fun content(target: String): Map = if (target == ElementVisionRenderer.TYPE) { listOf( + htmlVisionRenderer, inputVisionRenderer, checkboxVisionRenderer, numberVisionRenderer, diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt index 4e984cb0..af54bd75 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt @@ -2,6 +2,7 @@ package space.kscience.visionforge import kotlinx.browser.document import kotlinx.html.InputType +import kotlinx.html.div import kotlinx.html.js.input import org.w3c.dom.HTMLElement import org.w3c.dom.HTMLFormElement @@ -38,26 +39,36 @@ private fun HTMLInputElement.subscribeToInput(inputVision: VisionOfHtmlInput) { } } +internal val htmlVisionRenderer: ElementVisionRenderer = + ElementVisionRenderer { _, vision, _ -> + div {}.also { div -> + div.subscribeToVision(vision) + vision.useProperty(VisionOfPlainHtml::content) { + div.textContent = it + } + } + } + internal val inputVisionRenderer: ElementVisionRenderer = ElementVisionRenderer(acceptRating = ElementVisionRenderer.DEFAULT_RATING - 1) { _, vision, _ -> input { type = InputType.text - }.apply { + }.also { htmlInputElement -> val onEvent: (Event) -> Unit = { - vision.value = value.asValue() + vision.value = htmlInputElement.value.asValue() } when (vision.feedbackMode) { - InputFeedbackMode.ONCHANGE -> onchange = onEvent + InputFeedbackMode.ONCHANGE -> htmlInputElement.onchange = onEvent - InputFeedbackMode.ONINPUT -> oninput = onEvent + InputFeedbackMode.ONINPUT -> htmlInputElement.oninput = onEvent InputFeedbackMode.NONE -> {} } - subscribeToInput(vision) + htmlInputElement.subscribeToInput(vision) vision.useProperty(VisionOfHtmlInput::value) { - this@apply.value = it?.string ?: "" + htmlInputElement.value = it?.string ?: "" } } } @@ -66,22 +77,22 @@ internal val checkboxVisionRenderer: ElementVisionRenderer = ElementVisionRenderer { _, vision, _ -> input { type = InputType.checkBox - }.apply { + }.also { htmlInputElement -> val onEvent: (Event) -> Unit = { - vision.checked = checked + vision.checked = htmlInputElement.checked } when (vision.feedbackMode) { - InputFeedbackMode.ONCHANGE -> onchange = onEvent + InputFeedbackMode.ONCHANGE -> htmlInputElement.onchange = onEvent - InputFeedbackMode.ONINPUT -> oninput = onEvent + InputFeedbackMode.ONINPUT -> htmlInputElement.oninput = onEvent InputFeedbackMode.NONE -> {} } - subscribeToInput(vision) + htmlInputElement.subscribeToInput(vision) vision.useProperty(VisionOfCheckbox::checked) { - this@apply.checked = it ?: false + htmlInputElement.checked = it ?: false } } } @@ -90,22 +101,22 @@ internal val textVisionRenderer: ElementVisionRenderer = ElementVisionRenderer { _, vision, _ -> input { type = InputType.text - }.apply { + }.also { htmlInputElement -> val onEvent: (Event) -> Unit = { - vision.text = value + vision.text = htmlInputElement.value } when (vision.feedbackMode) { - InputFeedbackMode.ONCHANGE -> onchange = onEvent + InputFeedbackMode.ONCHANGE -> htmlInputElement.onchange = onEvent - InputFeedbackMode.ONINPUT -> oninput = onEvent + InputFeedbackMode.ONINPUT -> htmlInputElement.oninput = onEvent InputFeedbackMode.NONE -> {} } - subscribeToInput(vision) + htmlInputElement.subscribeToInput(vision) vision.useProperty(VisionOfTextField::text) { - this@apply.value = it ?: "" + htmlInputElement.value = it ?: "" } } } @@ -114,21 +125,21 @@ internal val numberVisionRenderer: ElementVisionRenderer = ElementVisionRenderer { _, vision, _ -> input { type = InputType.text - }.apply { + }.also { htmlInputElement -> val onEvent: (Event) -> Unit = { - value.toDoubleOrNull()?.let { vision.number = it } + htmlInputElement.value.toDoubleOrNull()?.let { vision.number = it } } when (vision.feedbackMode) { - InputFeedbackMode.ONCHANGE -> onchange = onEvent + InputFeedbackMode.ONCHANGE -> htmlInputElement.onchange = onEvent - InputFeedbackMode.ONINPUT -> oninput = onEvent + InputFeedbackMode.ONINPUT -> htmlInputElement.oninput = onEvent InputFeedbackMode.NONE -> {} } - subscribeToInput(vision) + htmlInputElement.subscribeToInput(vision) vision.useProperty(VisionOfNumberField::value) { - this@apply.valueAsNumber = it?.double ?: 0.0 + htmlInputElement.valueAsNumber = it?.double ?: 0.0 } } } @@ -140,21 +151,21 @@ internal val rangeVisionRenderer: ElementVisionRenderer = min = vision.min.toString() max = vision.max.toString() step = vision.step.toString() - }.apply { + }.also { htmlInputElement -> val onEvent: (Event) -> Unit = { - value.toDoubleOrNull()?.let { vision.number = it } + htmlInputElement.value.toDoubleOrNull()?.let { vision.number = it } } when (vision.feedbackMode) { - InputFeedbackMode.ONCHANGE -> onchange = onEvent + InputFeedbackMode.ONCHANGE -> htmlInputElement.onchange = onEvent - InputFeedbackMode.ONINPUT -> oninput = onEvent + InputFeedbackMode.ONINPUT -> htmlInputElement.oninput = onEvent InputFeedbackMode.NONE -> {} } - subscribeToInput(vision) + htmlInputElement.subscribeToInput(vision) vision.useProperty(VisionOfRangeField::value) { - this@apply.valueAsNumber = it?.double ?: 0.0 + htmlInputElement.valueAsNumber = it?.double ?: 0.0 } } }