Skip to content

Commit e7a11bd

Browse files
committed
click event wasn't forwarded to cells behind a selection
1 parent 57c9255 commit e7a11bd

File tree

2 files changed

+29
-25
lines changed

2 files changed

+29
-25
lines changed

editor-runtime/src/jsMain/kotlin/org/modelix/editor/DomUtils.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.modelix.editor
22

33
import kotlinx.browser.document
4+
import kotlinx.browser.window
45
import org.w3c.dom.DOMRect
56
import org.w3c.dom.HTMLElement
67
import org.w3c.dom.Node
@@ -17,7 +18,7 @@ data class Bounds(val x: Double, val y: Double, val width: Double, val height: D
1718
}
1819

1920
fun HTMLElement.getAbsoluteBounds(): Bounds {
20-
return getBoundingClientRect().toBounds()
21+
return getBoundingClientRect().toBounds().translated(window.scrollX, window.scrollY)
2122
}
2223

2324
fun HTMLElement.setBounds(bounds: Bounds) {
@@ -30,7 +31,7 @@ fun HTMLElement.setBounds(bounds: Bounds) {
3031
}
3132

3233
fun HTMLElement.getAbsoluteInnerBounds(): Bounds {
33-
return (getClientRects().asSequence().firstOrNull()?.toBounds() ?: ZERO_BOUNDS)
34+
return (getClientRects().asSequence().firstOrNull()?.toBounds()?.translated(window.scrollX, window.scrollY) ?: ZERO_BOUNDS)
3435
}
3536

3637
fun DOMRect.toBounds() = Bounds(x, y, width, height)

editor-runtime/src/jsMain/kotlin/org/modelix/editor/JsEditorComponent.kt

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -98,33 +98,36 @@ class JsEditorComponent(engine: EditorEngine, rootCellCreator: (EditorState) ->
9898
}
9999

100100
fun processClick(event: MouseEvent): Boolean {
101-
val target = event.target ?: return false
102-
val htmlElement = target as? HTMLElement
103-
val producer: IProducesHtml = htmlElement?.let { GeneratedHtmlMap.getProducer(it) } ?: return false
104-
val absoluteClickX = event.clientX
105-
when (producer) {
106-
is LayoutableCell -> {
107-
val layoutable = producer as? LayoutableCell ?: return false
108-
val text = htmlElement.innerText
109-
val cellAbsoluteBounds = htmlElement.getAbsoluteInnerBounds()
110-
val relativeClickX = absoluteClickX - cellAbsoluteBounds.x
111-
val characterWidth = cellAbsoluteBounds.width / text.length
112-
val caretPos = (relativeClickX / characterWidth).roundToInt()
113-
.coerceAtMost(layoutable.cell.getMaxCaretPos())
114-
changeSelection(CaretSelection(layoutable, caretPos))
115-
return true
101+
val absoluteClickX = event.pageX
102+
val targets = document.elementsFromPoint(event.clientX.toDouble(), event.clientY.toDouble())
103+
for (target in targets) {
104+
val htmlElement = target as? HTMLElement
105+
val producer: IProducesHtml = htmlElement?.let { GeneratedHtmlMap.getProducer(it) } ?: continue
106+
when (producer) {
107+
is LayoutableCell -> {
108+
val layoutable = producer as? LayoutableCell ?: continue
109+
val text = htmlElement.innerText
110+
val cellAbsoluteBounds = htmlElement.getAbsoluteInnerBounds()
111+
val relativeClickX = absoluteClickX - cellAbsoluteBounds.x
112+
val characterWidth = cellAbsoluteBounds.width / text.length
113+
val caretPos = (relativeClickX / characterWidth).roundToInt()
114+
.coerceAtMost(layoutable.cell.getMaxCaretPos())
115+
changeSelection(CaretSelection(layoutable, caretPos))
116+
return true
117+
}
118+
is Layoutable -> {
119+
if (selectClosestInLine(producer.getLine() ?: continue, absoluteClickX)) return true
120+
}
121+
is TextLine -> {
122+
if (selectClosestInLine(producer, absoluteClickX)) return true
123+
}
124+
else -> continue
116125
}
117-
is Layoutable -> {
118-
return selectClosestInLine(producer.getLine() ?: return false, absoluteClickX)
119-
}
120-
is TextLine -> {
121-
return selectClosestInLine(producer, absoluteClickX)
122-
}
123-
else -> return false
124126
}
127+
return false
125128
}
126129

127-
private fun selectClosestInLine(line: TextLine, absoluteClickX: Int): Boolean {
130+
private fun selectClosestInLine(line: TextLine, absoluteClickX: Double): Boolean {
128131
val words = line.words.filterIsInstance<LayoutableCell>()
129132
val closest = words.map { it to GeneratedHtmlMap.getOutput(it)!! }.minByOrNull {
130133
min(

0 commit comments

Comments
 (0)