diff --git a/src/jsMain/kotlin/dom-js.kt b/src/jsMain/kotlin/dom-js.kt index 62e18cb1..00d4b9a8 100644 --- a/src/jsMain/kotlin/dom-js.kt +++ b/src/jsMain/kotlin/dom-js.kt @@ -153,3 +153,41 @@ private val Node.ownerDocumentExt: Document this is Document -> this else -> ownerDocument ?: throw IllegalStateException("Node has no ownerDocument") } + + +/** + * Provides a short access to document elements by ID via delegated + * property syntax. Received element is not cached and received + * directly from the [Document] by calling [Document.getElementById] + * function on every property access. Throws an exception if element + * is not found or has different type + * + * To access an element with `theId` ID use the following property declaration + * ``` + * val theId by document.gettingElementById + * ``` + * + * To access an element of specific type, just add it to the property declaration + * ``` + * val theId: HTMLImageElement by document.gettingElementById + * ``` + */ +inline val Document.gettingElementById get() = DocumentGettingElementById(this) + +/** + * Implementation details of [Document.gettingElementById] + * @see Document.gettingElementById + */ +inline class DocumentGettingElementById(val document: Document) { + /** + * Implementation details of [Document.gettingElementById]. Delegated property + * @see Document.gettingElementById + */ + inline operator fun getValue(x: Any?, kProperty: KProperty<*>): T { + val id = kProperty.name + val element = document.getElementById(id) ?: throw NullPointerException("Element $id is not found") + return element as? T ?: throw ClassCastException( + "Element $id has type ${element::class.simpleName} which does not implement ${T::class.simpleName}" + ) + } +}