From 41772231e4794827a8128661010d8391721c75a7 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Sun, 1 Nov 2026 13:34:16 +0600 Subject: [PATCH 1/6] start 0.33.0 --- CHANGELOG.md | 2 ++ gradle.properties | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc3bad4281f..454d6a3a8af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog +## 0.33.0 + ## 0.32.1 * `Coroutines`: diff --git a/gradle.properties b/gradle.properties index 88c615f5985..1162f4dbb80 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,5 +16,5 @@ crypto_js_version=4.2.0 # Project data group=dev.inmo -version=0.32.1 -android_code_version=320 +version=0.33.0 +android_code_version=321 From 19ca5e14876cad8d87246b9a6ebe36c6ea7fa9ee Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Sun, 1 Nov 2026 13:54:10 +0600 Subject: [PATCH 2/6] fix MutationObserver options in JS --- CHANGELOG.md | 4 + common/build.gradle | 16 ++ .../common/HTMLElementDomChanged.kt | 4 +- .../micro_utils/common/MutationObserver.kt | 31 ++++ .../common/MutationObserverBrowserTests.kt | 158 ++++++++++++++++++ .../common/MutationObserverInitTests.kt | 80 +++++++++ 6 files changed, 292 insertions(+), 1 deletion(-) create mode 100644 common/src/jsMain/kotlin/dev/inmo/micro_utils/common/MutationObserver.kt create mode 100644 common/src/jsTest/kotlin/dev/inmo/micro_utils/common/MutationObserverBrowserTests.kt create mode 100644 common/src/jsTest/kotlin/dev/inmo/micro_utils/common/MutationObserverInitTests.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 454d6a3a8af..0a51631e9f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## 0.33.0 +* `Common`: + * Add JS `MutationObserverInit` factory that omits unspecified options and preserves browser defaults. + * Use safe `MutationObserver` options in `onRemoved` and cover DOM observation and outside-click cleanup with browser tests. + ## 0.32.1 * `Coroutines`: diff --git a/common/build.gradle b/common/build.gradle index 058da15463d..c8b2193b674 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -7,6 +7,22 @@ plugins { apply from: "$mppJvmJsWasmJsAndroidLinuxMingwLinuxArm64Project" kotlin { + js { + browser { + testTask { + useKarma { + useChromeHeadlessNoSandbox() + useConfigDirectory(rootProject.relativeProjectPath("gradle/karma.config.d")) + } + } + } + nodejs { + testTask { + filter.excludeTestsMatching("dev.inmo.micro_utils.common.MutationObserverBrowserTests*") + } + } + } + sourceSets { commonMain { dependencies { diff --git a/common/src/jsMain/kotlin/dev/inmo/micro_utils/common/HTMLElementDomChanged.kt b/common/src/jsMain/kotlin/dev/inmo/micro_utils/common/HTMLElementDomChanged.kt index 825414a3587..eb33eb79b21 100644 --- a/common/src/jsMain/kotlin/dev/inmo/micro_utils/common/HTMLElementDomChanged.kt +++ b/common/src/jsMain/kotlin/dev/inmo/micro_utils/common/HTMLElementDomChanged.kt @@ -1,7 +1,9 @@ package dev.inmo.micro_utils.common import kotlinx.browser.document -import org.w3c.dom.* +import org.w3c.dom.Element +import org.w3c.dom.MutationObserver +import org.w3c.dom.Node fun Node.onRemoved(block: () -> Unit): MutationObserver { lateinit var observer: MutationObserver diff --git a/common/src/jsMain/kotlin/dev/inmo/micro_utils/common/MutationObserver.kt b/common/src/jsMain/kotlin/dev/inmo/micro_utils/common/MutationObserver.kt new file mode 100644 index 00000000000..f2493a9217a --- /dev/null +++ b/common/src/jsMain/kotlin/dev/inmo/micro_utils/common/MutationObserver.kt @@ -0,0 +1,31 @@ +package dev.inmo.micro_utils.common + +import org.w3c.dom.MutationObserverInit as NativeMutationObserverInit + +/** + * Creates options for [org.w3c.dom.MutationObserver] without adding unspecified properties. + * + * Unlike the Kotlin DOM factory, this factory leaves absent options out of the JavaScript object. In particular, + * an absent [attributeFilter] must not become a null sequence, and absent [attributes] and [characterData] must not + * override the browser defaults implied by their filters or old-value options. + * + * Null arguments are omitted. Explicit false values and empty arrays are preserved. The browser remains responsible + * for validating the options passed to [org.w3c.dom.MutationObserver.observe]. + */ +fun MutationObserverInit( + childList: Boolean? = null, + attributes: Boolean? = null, + characterData: Boolean? = null, + subtree: Boolean? = null, + attributeOldValue: Boolean? = null, + characterDataOldValue: Boolean? = null, + attributeFilter: Array? = null +): NativeMutationObserverInit = js("{}").unsafeCast().apply { + if (childList != null) this.childList = childList + if (attributes != null) this.attributes = attributes + if (characterData != null) this.characterData = characterData + if (subtree != null) this.subtree = subtree + if (attributeOldValue != null) this.attributeOldValue = attributeOldValue + if (characterDataOldValue != null) this.characterDataOldValue = characterDataOldValue + if (attributeFilter != null) this.attributeFilter = attributeFilter +} diff --git a/common/src/jsTest/kotlin/dev/inmo/micro_utils/common/MutationObserverBrowserTests.kt b/common/src/jsTest/kotlin/dev/inmo/micro_utils/common/MutationObserverBrowserTests.kt new file mode 100644 index 00000000000..a29c8f17e4b --- /dev/null +++ b/common/src/jsTest/kotlin/dev/inmo/micro_utils/common/MutationObserverBrowserTests.kt @@ -0,0 +1,158 @@ +package dev.inmo.micro_utils.common + +import kotlinx.browser.document +import org.w3c.dom.MutationObserver +import org.w3c.dom.events.Event +import kotlin.js.Promise +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFails +import kotlin.test.assertNull +import kotlin.test.assertSame +import kotlin.test.assertTrue + +/** Runs only in the browser: jsNodeTest excludes this class rather than reporting DOM checks as passing. */ +class MutationObserverBrowserTests { + @Test + fun childListSubtreeRecordsCanBeDrainedAndDisconnected() { + val root = document.createElement("div") + val nested = document.createElement("div") + val child = document.createElement("span") + root.appendChild(nested) + val observer = MutationObserver { _, _ -> } + try { + observer.observe(root, MutationObserverInit(childList = true, subtree = true)) + nested.appendChild(child) + val record = observer.takeRecords().single() + assertEquals("childList", record.type) + assertSame(nested, record.target) + assertSame(child, record.addedNodes.item(0)) + assertEquals(0, record.removedNodes.length) + assertNull(record.attributeName) + assertTrue(observer.takeRecords().isEmpty()) + observer.disconnect() + nested.removeChild(child) + assertTrue(observer.takeRecords().isEmpty()) + } finally { + observer.disconnect() + } + } + + @Test + fun attributeFilterEnablesObservationAndPreservesOldValues() { + val target = document.createElement("div") + target.setAttribute("data-state", "old") + val observer = MutationObserver { _, _ -> } + try { + observer.observe(target, MutationObserverInit(attributeFilter = arrayOf("data-state"), attributeOldValue = true)) + target.setAttribute("ignored", "value") + target.setAttribute("data-state", "new") + val record = observer.takeRecords().single() + assertEquals("attributes", record.type) + assertSame(target, record.target) + assertEquals("data-state", record.attributeName) + assertEquals("old", record.oldValue) + assertNull(record.attributeNamespace) + } finally { + observer.disconnect() + } + } + + @Test + fun characterDataOldValueEnablesObservation() { + val target = document.createTextNode("old") + val observer = MutationObserver { _, _ -> } + try { + observer.observe(target, MutationObserverInit(characterDataOldValue = true)) + target.data = "new" + val record = observer.takeRecords().single() + assertEquals("characterData", record.type) + assertSame(target, record.target) + assertEquals("old", record.oldValue) + } finally { + observer.disconnect() + } + } + + @Test + fun nullAttributeFilterIsOmittedInsteadOfConvertedToASequence() { + val target = document.createElement("div") + val observer = MutationObserver { _, _ -> } + try { + observer.observe(target, MutationObserverInit(childList = true, attributeFilter = null)) + target.appendChild(document.createElement("span")) + assertEquals("childList", observer.takeRecords().single().type) + } finally { + observer.disconnect() + } + } + + @Test + fun emptyAttributeFilterDoesNotObserveAllAttributes() { + val target = document.createElement("div") + val observer = MutationObserver { _, _ -> } + try { + observer.observe(target, MutationObserverInit(attributeFilter = emptyArray())) + target.setAttribute("data-state", "new") + assertTrue(observer.takeRecords().isEmpty()) + } finally { + observer.disconnect() + } + } + + @Test + fun nativeValidationRejectsContradictoryOptions() { + val target = document.createElement("div") + val observer = MutationObserver { _, _ -> } + try { + assertFails { observer.observe(target, MutationObserverInit()) } + assertFails { + observer.observe(target, MutationObserverInit(attributes = false, attributeFilter = arrayOf("class"))) + } + assertFails { + observer.observe(target, MutationObserverInit(characterData = false, characterDataOldValue = true)) + } + } finally { + observer.disconnect() + } + } + + @Test + fun onRemovedCallsBackOnceAndDisconnects(): Promise { + val parent = document.createElement("div") + val child = document.createElement("span") + parent.appendChild(child) + document.body!!.appendChild(parent) + var calls = 0 + val observer = child.onRemoved { calls++ } + parent.removeChild(child) + return Promise.resolve(Unit).then { + assertEquals(1, calls) + parent.appendChild(child) + parent.removeChild(child) + }.then { + assertEquals(1, calls) + }.finally { + observer.disconnect() + parent.parentNode?.removeChild(parent) + } + } + + @Test + fun onClickOutsideStopsListeningAfterRemoval(): Promise { + val target = document.createElement("div") + document.body!!.appendChild(target) + var calls = 0 + val listener = target.onClickOutside { calls++ } + document.dispatchEvent(Event("click")) + assertEquals(1, calls) + target.parentNode!!.removeChild(target) + return Promise.resolve(Unit).then { + document.dispatchEvent(Event("click")) + assertEquals(1, calls) + }.finally { + document.removeEventListener("click", listener) + target.parentNode?.removeChild(target) + } + } +} diff --git a/common/src/jsTest/kotlin/dev/inmo/micro_utils/common/MutationObserverInitTests.kt b/common/src/jsTest/kotlin/dev/inmo/micro_utils/common/MutationObserverInitTests.kt new file mode 100644 index 00000000000..9f5fc20ed71 --- /dev/null +++ b/common/src/jsTest/kotlin/dev/inmo/micro_utils/common/MutationObserverInitTests.kt @@ -0,0 +1,80 @@ +package dev.inmo.micro_utils.common + +import org.w3c.dom.MutationObserverInit as NativeMutationObserverInit +import kotlin.test.Test +import kotlin.test.assertContentEquals +import kotlin.test.assertEquals +import kotlin.test.assertSame + +class MutationObserverInitTests { + private fun keys(options: NativeMutationObserverInit): List = + js("Object.keys(options)").unsafeCast>().sorted() + + @Test + fun emptyOptionsHaveNoProperties() { + assertEquals(emptyList(), keys(MutationObserverInit())) + } + + @Test + fun childListOptionsOmitUnspecifiedProperties() { + val options = MutationObserverInit(childList = true, subtree = true) + assertEquals(listOf("childList", "subtree"), keys(options)) + assertEquals(true, options.childList) + assertEquals(true, options.subtree) + } + + @Test + fun explicitNullOptionsAreOmitted() { + val options = MutationObserverInit( + childList = null, + attributes = null, + characterData = null, + subtree = null, + attributeOldValue = null, + characterDataOldValue = null, + attributeFilter = null + ) + assertEquals(emptyList(), keys(options)) + } + + @Test + fun explicitFalseAndEmptyFilterArePreserved() { + val filter = emptyArray() + val options = MutationObserverInit(false, false, false, false, false, false, filter) + assertEquals( + listOf("attributeFilter", "attributeOldValue", "attributes", "characterData", "characterDataOldValue", "childList", "subtree"), + keys(options) + ) + assertEquals(false, options.childList) + assertEquals(false, options.attributes) + assertEquals(false, options.characterData) + assertEquals(false, options.subtree) + assertEquals(false, options.attributeOldValue) + assertEquals(false, options.characterDataOldValue) + assertSame(filter, options.attributeFilter) + assertContentEquals(emptyArray(), options.attributeFilter) + } + + @Test + fun filtersAndOldValueOptionsDoNotForceObservationFlags() { + val filter = arrayOf("class", "data-state") + val options = MutationObserverInit( + attributeFilter = filter, + attributeOldValue = true, + characterDataOldValue = true + ) + assertEquals(listOf("attributeFilter", "attributeOldValue", "characterDataOldValue"), keys(options)) + assertSame(filter, options.attributeFilter) + assertEquals(true, options.attributeOldValue) + assertEquals(true, options.characterDataOldValue) + } + + @Test + fun eachCallCreatesIndependentOptions() { + val first = MutationObserverInit(childList = true) + val second = MutationObserverInit(attributes = true) + first.subtree = true + assertEquals(listOf("childList", "subtree"), keys(first)) + assertEquals(listOf("attributes"), keys(second)) + } +} From 3bd1b5da5c9d3c4daa98f1a9a0d5c5fb1ad49524 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Sun, 1 Nov 2026 14:33:16 +0600 Subject: [PATCH 3/6] test: clean up DOM after observer test failures --- .../common/MutationObserverBrowserTests.kt | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/common/src/jsTest/kotlin/dev/inmo/micro_utils/common/MutationObserverBrowserTests.kt b/common/src/jsTest/kotlin/dev/inmo/micro_utils/common/MutationObserverBrowserTests.kt index a29c8f17e4b..99b2345d1ec 100644 --- a/common/src/jsTest/kotlin/dev/inmo/micro_utils/common/MutationObserverBrowserTests.kt +++ b/common/src/jsTest/kotlin/dev/inmo/micro_utils/common/MutationObserverBrowserTests.kt @@ -3,6 +3,7 @@ package dev.inmo.micro_utils.common import kotlinx.browser.document import org.w3c.dom.MutationObserver import org.w3c.dom.events.Event +import org.w3c.dom.events.EventListener import kotlin.js.Promise import kotlin.test.Test import kotlin.test.assertEquals @@ -121,19 +122,21 @@ class MutationObserverBrowserTests { fun onRemovedCallsBackOnceAndDisconnects(): Promise { val parent = document.createElement("div") val child = document.createElement("span") - parent.appendChild(child) - document.body!!.appendChild(parent) var calls = 0 - val observer = child.onRemoved { calls++ } - parent.removeChild(child) + var observer: MutationObserver? = null return Promise.resolve(Unit).then { + parent.appendChild(child) + document.body!!.appendChild(parent) + observer = child.onRemoved { calls++ } + parent.removeChild(child) + }.then { assertEquals(1, calls) parent.appendChild(child) parent.removeChild(child) }.then { assertEquals(1, calls) }.finally { - observer.disconnect() + observer?.disconnect() parent.parentNode?.removeChild(parent) } } @@ -141,17 +144,19 @@ class MutationObserverBrowserTests { @Test fun onClickOutsideStopsListeningAfterRemoval(): Promise { val target = document.createElement("div") - document.body!!.appendChild(target) var calls = 0 - val listener = target.onClickOutside { calls++ } - document.dispatchEvent(Event("click")) - assertEquals(1, calls) - target.parentNode!!.removeChild(target) + var listener: EventListener? = null return Promise.resolve(Unit).then { + document.body!!.appendChild(target) + listener = target.onClickOutside { calls++ } + document.dispatchEvent(Event("click")) + assertEquals(1, calls) + target.parentNode!!.removeChild(target) + }.then { document.dispatchEvent(Event("click")) assertEquals(1, calls) }.finally { - document.removeEventListener("click", listener) + listener?.let { document.removeEventListener("click", it) } target.parentNode?.removeChild(target) } } From a81d28426bb55874923963d193a335027e807520 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Sun, 1 Nov 2026 16:08:03 +0600 Subject: [PATCH 4/6] update dependencies --- CHANGELOG.md | 6 ++++++ gradle/libs.versions.toml | 10 +++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a51631e9f0..77187084e45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## 0.33.0 +* `Versions`: + * `Exposed`: `1.5.1` -> `1.6.0` + * `Serialization`: `1.11.0` -> `1.12.0` + * `Compose`: `1.12.1` -> `1.12.2` + * `SQLite`: `3.53.4.0` -> `3.54.1.0` + * `Ktor`: `3.6.0` -> `3.6.1` * `Common`: * Add JS `MutationObserverInit` factory that omits unspecified options and preserves browser defaults. * Use safe `MutationObserver` options in `onRemoved` and cover DOM observation and outside-click cleanup with browser tests. diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e06b3767319..d43b635a3ed 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,25 +1,25 @@ [versions] kt = "2.4.21" -kt-serialization = "1.11.0" +kt-serialization = "1.12.0" kt-coroutines = "1.11.0" kotlinx-browser = "0.5.0" kslog = "2.1.0" -jb-compose = "1.12.1" +jb-compose = "1.12.2" jb-compose-material3 = "1.9.0" jb-compose-icons = "1.7.8" -jb-exposed = "1.5.1" +jb-exposed = "1.6.0" jb-dokka = "2.2.0" -sqlite = "3.53.4.0" +sqlite = "3.54.1.0" korlibs = "5.4.0" uuid = "0.8.4" -ktor = "3.6.0" +ktor = "3.6.1" gh-release = "2.5.2" From a84a89fb5b9e503c41529a3b4d4bedd0c3869720 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Tue, 3 Nov 2026 17:44:45 +0600 Subject: [PATCH 5/6] rename MutationObserverInit -> MutationObserverOptions to avoid naming collisions --- CHANGELOG.md | 2 +- .../dev/inmo/micro_utils/common/HTMLElementDomChanged.kt | 2 +- .../kotlin/dev/inmo/micro_utils/common/MutationObserver.kt | 4 +--- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77187084e45..3676579410d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ * `SQLite`: `3.53.4.0` -> `3.54.1.0` * `Ktor`: `3.6.0` -> `3.6.1` * `Common`: - * Add JS `MutationObserverInit` factory that omits unspecified options and preserves browser defaults. + * Add JS `MutationObserverOptions` factory that omits unspecified options and preserves browser defaults. * Use safe `MutationObserver` options in `onRemoved` and cover DOM observation and outside-click cleanup with browser tests. ## 0.32.1 diff --git a/common/src/jsMain/kotlin/dev/inmo/micro_utils/common/HTMLElementDomChanged.kt b/common/src/jsMain/kotlin/dev/inmo/micro_utils/common/HTMLElementDomChanged.kt index eb33eb79b21..00e68211c70 100644 --- a/common/src/jsMain/kotlin/dev/inmo/micro_utils/common/HTMLElementDomChanged.kt +++ b/common/src/jsMain/kotlin/dev/inmo/micro_utils/common/HTMLElementDomChanged.kt @@ -19,7 +19,7 @@ fun Node.onRemoved(block: () -> Unit): MutationObserver { } } - observer.observe(document, MutationObserverInit(childList = true, subtree = true)) + observer.observe(document, MutationObserverOptions(childList = true, subtree = true)) return observer } diff --git a/common/src/jsMain/kotlin/dev/inmo/micro_utils/common/MutationObserver.kt b/common/src/jsMain/kotlin/dev/inmo/micro_utils/common/MutationObserver.kt index f2493a9217a..3acd8e6c0ed 100644 --- a/common/src/jsMain/kotlin/dev/inmo/micro_utils/common/MutationObserver.kt +++ b/common/src/jsMain/kotlin/dev/inmo/micro_utils/common/MutationObserver.kt @@ -1,7 +1,5 @@ package dev.inmo.micro_utils.common -import org.w3c.dom.MutationObserverInit as NativeMutationObserverInit - /** * Creates options for [org.w3c.dom.MutationObserver] without adding unspecified properties. * @@ -12,7 +10,7 @@ import org.w3c.dom.MutationObserverInit as NativeMutationObserverInit * Null arguments are omitted. Explicit false values and empty arrays are preserved. The browser remains responsible * for validating the options passed to [org.w3c.dom.MutationObserver.observe]. */ -fun MutationObserverInit( +fun MutationObserverOptions( childList: Boolean? = null, attributes: Boolean? = null, characterData: Boolean? = null, From 997e03e2329d25d8547765d5b93e6a5155982919 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Tue, 3 Nov 2026 18:36:40 +0600 Subject: [PATCH 6/6] fix of build --- .../micro_utils/common/MutationObserver.kt | 4 +++- .../common/MutationObserverBrowserTests.kt | 16 ++++++++-------- .../common/MutationObserverInitTests.kt | 18 +++++++++--------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/common/src/jsMain/kotlin/dev/inmo/micro_utils/common/MutationObserver.kt b/common/src/jsMain/kotlin/dev/inmo/micro_utils/common/MutationObserver.kt index 3acd8e6c0ed..77f6be2d775 100644 --- a/common/src/jsMain/kotlin/dev/inmo/micro_utils/common/MutationObserver.kt +++ b/common/src/jsMain/kotlin/dev/inmo/micro_utils/common/MutationObserver.kt @@ -1,5 +1,7 @@ package dev.inmo.micro_utils.common +import org.w3c.dom.MutationObserverInit + /** * Creates options for [org.w3c.dom.MutationObserver] without adding unspecified properties. * @@ -18,7 +20,7 @@ fun MutationObserverOptions( attributeOldValue: Boolean? = null, characterDataOldValue: Boolean? = null, attributeFilter: Array? = null -): NativeMutationObserverInit = js("{}").unsafeCast().apply { +): MutationObserverInit = js("{}").unsafeCast().apply { if (childList != null) this.childList = childList if (attributes != null) this.attributes = attributes if (characterData != null) this.characterData = characterData diff --git a/common/src/jsTest/kotlin/dev/inmo/micro_utils/common/MutationObserverBrowserTests.kt b/common/src/jsTest/kotlin/dev/inmo/micro_utils/common/MutationObserverBrowserTests.kt index 99b2345d1ec..0e111be8a58 100644 --- a/common/src/jsTest/kotlin/dev/inmo/micro_utils/common/MutationObserverBrowserTests.kt +++ b/common/src/jsTest/kotlin/dev/inmo/micro_utils/common/MutationObserverBrowserTests.kt @@ -22,7 +22,7 @@ class MutationObserverBrowserTests { root.appendChild(nested) val observer = MutationObserver { _, _ -> } try { - observer.observe(root, MutationObserverInit(childList = true, subtree = true)) + observer.observe(root, MutationObserverOptions(childList = true, subtree = true)) nested.appendChild(child) val record = observer.takeRecords().single() assertEquals("childList", record.type) @@ -45,7 +45,7 @@ class MutationObserverBrowserTests { target.setAttribute("data-state", "old") val observer = MutationObserver { _, _ -> } try { - observer.observe(target, MutationObserverInit(attributeFilter = arrayOf("data-state"), attributeOldValue = true)) + observer.observe(target, MutationObserverOptions(attributeFilter = arrayOf("data-state"), attributeOldValue = true)) target.setAttribute("ignored", "value") target.setAttribute("data-state", "new") val record = observer.takeRecords().single() @@ -64,7 +64,7 @@ class MutationObserverBrowserTests { val target = document.createTextNode("old") val observer = MutationObserver { _, _ -> } try { - observer.observe(target, MutationObserverInit(characterDataOldValue = true)) + observer.observe(target, MutationObserverOptions(characterDataOldValue = true)) target.data = "new" val record = observer.takeRecords().single() assertEquals("characterData", record.type) @@ -80,7 +80,7 @@ class MutationObserverBrowserTests { val target = document.createElement("div") val observer = MutationObserver { _, _ -> } try { - observer.observe(target, MutationObserverInit(childList = true, attributeFilter = null)) + observer.observe(target, MutationObserverOptions(childList = true, attributeFilter = null)) target.appendChild(document.createElement("span")) assertEquals("childList", observer.takeRecords().single().type) } finally { @@ -93,7 +93,7 @@ class MutationObserverBrowserTests { val target = document.createElement("div") val observer = MutationObserver { _, _ -> } try { - observer.observe(target, MutationObserverInit(attributeFilter = emptyArray())) + observer.observe(target, MutationObserverOptions(attributeFilter = emptyArray())) target.setAttribute("data-state", "new") assertTrue(observer.takeRecords().isEmpty()) } finally { @@ -106,12 +106,12 @@ class MutationObserverBrowserTests { val target = document.createElement("div") val observer = MutationObserver { _, _ -> } try { - assertFails { observer.observe(target, MutationObserverInit()) } + assertFails { observer.observe(target, MutationObserverOptions()) } assertFails { - observer.observe(target, MutationObserverInit(attributes = false, attributeFilter = arrayOf("class"))) + observer.observe(target, MutationObserverOptions(attributes = false, attributeFilter = arrayOf("class"))) } assertFails { - observer.observe(target, MutationObserverInit(characterData = false, characterDataOldValue = true)) + observer.observe(target, MutationObserverOptions(characterData = false, characterDataOldValue = true)) } } finally { observer.disconnect() diff --git a/common/src/jsTest/kotlin/dev/inmo/micro_utils/common/MutationObserverInitTests.kt b/common/src/jsTest/kotlin/dev/inmo/micro_utils/common/MutationObserverInitTests.kt index 9f5fc20ed71..783ea1f75f0 100644 --- a/common/src/jsTest/kotlin/dev/inmo/micro_utils/common/MutationObserverInitTests.kt +++ b/common/src/jsTest/kotlin/dev/inmo/micro_utils/common/MutationObserverInitTests.kt @@ -1,23 +1,23 @@ package dev.inmo.micro_utils.common -import org.w3c.dom.MutationObserverInit as NativeMutationObserverInit +import org.w3c.dom.MutationObserverInit import kotlin.test.Test import kotlin.test.assertContentEquals import kotlin.test.assertEquals import kotlin.test.assertSame class MutationObserverInitTests { - private fun keys(options: NativeMutationObserverInit): List = + private fun keys(@Suppress("unused") options: MutationObserverInit): List = js("Object.keys(options)").unsafeCast>().sorted() @Test fun emptyOptionsHaveNoProperties() { - assertEquals(emptyList(), keys(MutationObserverInit())) + assertEquals(emptyList(), keys(MutationObserverOptions())) } @Test fun childListOptionsOmitUnspecifiedProperties() { - val options = MutationObserverInit(childList = true, subtree = true) + val options = MutationObserverOptions(childList = true, subtree = true) assertEquals(listOf("childList", "subtree"), keys(options)) assertEquals(true, options.childList) assertEquals(true, options.subtree) @@ -25,7 +25,7 @@ class MutationObserverInitTests { @Test fun explicitNullOptionsAreOmitted() { - val options = MutationObserverInit( + val options = MutationObserverOptions( childList = null, attributes = null, characterData = null, @@ -40,7 +40,7 @@ class MutationObserverInitTests { @Test fun explicitFalseAndEmptyFilterArePreserved() { val filter = emptyArray() - val options = MutationObserverInit(false, false, false, false, false, false, filter) + val options = MutationObserverOptions(false, false, false, false, false, false, filter) assertEquals( listOf("attributeFilter", "attributeOldValue", "attributes", "characterData", "characterDataOldValue", "childList", "subtree"), keys(options) @@ -58,7 +58,7 @@ class MutationObserverInitTests { @Test fun filtersAndOldValueOptionsDoNotForceObservationFlags() { val filter = arrayOf("class", "data-state") - val options = MutationObserverInit( + val options = MutationObserverOptions( attributeFilter = filter, attributeOldValue = true, characterDataOldValue = true @@ -71,8 +71,8 @@ class MutationObserverInitTests { @Test fun eachCallCreatesIndependentOptions() { - val first = MutationObserverInit(childList = true) - val second = MutationObserverInit(attributes = true) + val first = MutationObserverOptions(childList = true) + val second = MutationObserverOptions(attributes = true) first.subtree = true assertEquals(listOf("childList", "subtree"), keys(first)) assertEquals(listOf("attributes"), keys(second))