Skip to content

Commit

Permalink
Merge pull request #105 from hpehl/bind-boolean-attributes
Browse files Browse the repository at this point in the history
Add single mount point for boolean attributes
  • Loading branch information
jwstegemann authored Jul 13, 2020
2 parents 5b3935a + d1176a9 commit 494781a
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 5 deletions.
1 change: 0 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,3 @@ jobs:
path: core/build/reports/tests/allTests
- name: Build with Gradle
run: ./gradlew build

13 changes: 12 additions & 1 deletion core/src/jsMain/kotlin/dev/fritz2/dom/attributes.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ internal object ValueAttributeDelegate {
*/
internal object CheckedAttributeDelegate {
operator fun <X : Element> getValue(thisRef: Tag<X>, property: KProperty<*>): Flow<Boolean> =
throw NotImplementedError()
throw NotImplementedError()

operator fun <X : Element> setValue(thisRef: Tag<X>, property: KProperty<*>, values: Flow<Boolean>) {
CheckedAttributeMountPoint(values, thisRef.domNode)
Expand Down Expand Up @@ -71,6 +71,17 @@ interface WithAttributes<out T : Element> : WithDomNode<T> {
*/
fun Flow<String>.bindAttr(name: String) = AttributeMountPoint(name, this, domNode)

/**
* bind a boolean [Flow] to a boolean attribute / flag. When the flow emits `true` the attribute will be added.
* When the flow emits `false` the attribute will be removed.
*
* @param name of the attribute
* @param value value for the attribute (defaults to "")
* @receiver the [Flow] to bind
*/
fun Flow<Boolean>.bindAttr(name: String, value: String = ""): BooleanAttributeMountPoint =
BooleanAttributeMountPoint(name, this, domNode, value)

/**
* bind a [Flow] of [List]s to an attribute. The attribute will be updated in the DOM whenever a new value appears on this [Flow].
* The elements of the list will be concatenated by empty space.
Expand Down
22 changes: 19 additions & 3 deletions core/src/jsMain/kotlin/dev/fritz2/dom/mount.kt
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,25 @@ class AttributeMountPoint(val name: String, upstream: Flow<String>, val target:
* @param value last value (to be replaced)
*/
override fun set(value: String, last: String?) {
//FIXME: Should only be true for Boolean-Attributes...
if (value == "false") target?.removeAttribute(name)
else target?.setAttribute(name, value)
target?.setAttribute(name, value)
}
}

/**
* [BooleanAttributeMountPoint] is a special [SingleMountPoint] for the boolean attributes.
*/
class BooleanAttributeMountPoint(
private val name: String,
upstream: Flow<Boolean>,
private val target: Element?,
private val trueValue: String
) : SingleMountPoint<Boolean>(upstream) {
override fun set(value: Boolean, last: Boolean?) {
if (value) {
target?.setAttribute(name, trueValue)
} else {
target?.removeAttribute(name)
}
}
}

Expand Down
16 changes: 16 additions & 0 deletions core/src/jsTest/kotlin/dev/fritz2/dom/attributes.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import org.w3c.dom.HTMLDivElement
import kotlin.browser.document
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue


class AttributeTests {
Expand All @@ -35,6 +37,10 @@ class AttributeTests {
const(value1).bindAttr("data-$name1")
attr(name2, values2)
const(values3).bindAttr(name3)

const(true).bindAttr("test4")
const(false).bindAttr("test5")
const(true).bindAttr("test6", "foo")
}
}.mount(targetId)

Expand All @@ -54,5 +60,15 @@ class AttributeTests {
assertEquals(values2.joinToString(separator = " "), element.getAttribute(name2))
assertEquals(values3.joinToString(separator = " "), element.getAttribute(name3))

assertEquals(value0, element.getAttribute(name0))
assertEquals(value1, element.getAttribute(name1))

assertTrue(element.hasAttribute("test4"))
assertEquals("", element.getAttribute("test4"))

assertFalse(element.hasAttribute("test5"))

assertTrue(element.hasAttribute("test6"))
assertEquals("foo", element.getAttribute("test6"))
}
}

0 comments on commit 494781a

Please sign in to comment.