Skip to content

Commit

Permalink
Make coordinate queries in block widgets work
Browse files Browse the repository at this point in the history
FIX: Fix an issue where `coordsAtPos` would return null when querying a position
in a block widget.
  • Loading branch information
marijnh committed Aug 11, 2024
1 parent 228bab7 commit f40079c
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 28 deletions.
31 changes: 29 additions & 2 deletions src/blockview.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {ContentView, DOMPos, ViewFlag, noChildren, mergeChildrenInto} from "./contentview"
import {DocView} from "./docview"
import {TextView, MarkView, inlineDOMAtPos, joinInlineInto, coordsInChildren} from "./inlineview"
import {clientRectsFor, Rect, clearAttributes} from "./dom"
import {clientRectsFor, Rect, flattenRect, clearAttributes} from "./dom"
import {LineDecoration, WidgetType, PointDecoration} from "./decoration"
import {Attrs, combineAttrs, attrsEq, updateAttrs} from "./attributes"
import browser from "./browser"
Expand Down Expand Up @@ -240,7 +240,10 @@ export class BlockWidgetView extends ContentView implements BlockView {
get isWidget() { return true }

coordsAt(pos: number, side: number) {
return this.widget.coordsAt(this.dom!, pos, side)
let custom = this.widget.coordsAt(this.dom!, pos, side)
if (custom) return custom
if (this.widget instanceof BlockGapWidget) return null
return flattenRect(this.dom!.getBoundingClientRect(), this.length ? pos == 0 : side <= 0)
}

destroy() {
Expand All @@ -253,3 +256,27 @@ export class BlockWidgetView extends ContentView implements BlockView {
return startSide == endSide ? false : side < 0 ? startSide < 0 : endSide > 0
}
}

export class BlockGapWidget extends WidgetType {
constructor(readonly height: number) { super() }

toDOM() {
let elt = document.createElement("div")
elt.className = "cm-gap"
this.updateDOM(elt)
return elt
}

eq(other: BlockGapWidget) { return other.height == this.height }

updateDOM(elt: HTMLElement) {
elt.style.height = this.height + "px"
return true
}

get editable() { return true }

get estimatedHeight() { return this.height }

ignoreEvent() { return false }
}
28 changes: 2 additions & 26 deletions src/docview.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {ChangeSet, RangeSet, findClusterBreak, SelectionRange} from "@codemirror/state"
import {ContentView, ChildCursor, ViewFlag, DOMPos, replaceRange} from "./contentview"
import {BlockView, LineView, BlockWidgetView} from "./blockview"
import {BlockView, LineView, BlockWidgetView, BlockGapWidget} from "./blockview"
import {TextView, MarkView} from "./inlineview"
import {ContentBuilder} from "./buildview"
import browser from "./browser"
import {Decoration, DecorationSet, WidgetType, addRange, MarkDecoration} from "./decoration"
import {Decoration, DecorationSet, addRange, MarkDecoration} from "./decoration"
import {getAttrs} from "./attributes"
import {clientRectsFor, isEquivalentPosition, Rect, scrollRectIntoView,
getSelection, hasSelection, textRange, DOMSelectionState,
Expand Down Expand Up @@ -581,30 +581,6 @@ function betweenUneditable(pos: DOMPos) {
(pos.offset == pos.node.childNodes.length || (pos.node.childNodes[pos.offset] as HTMLElement).contentEditable == "false")
}

class BlockGapWidget extends WidgetType {
constructor(readonly height: number) { super() }

toDOM() {
let elt = document.createElement("div")
elt.className = "cm-gap"
this.updateDOM(elt)
return elt
}

eq(other: BlockGapWidget) { return other.height == this.height }

updateDOM(elt: HTMLElement) {
elt.style.height = this.height + "px"
return true
}

get editable() { return true }

get estimatedHeight() { return this.height }

ignoreEvent() { return false }
}

export function findCompositionNode(view: EditorView, headPos: number): {from: number, to: number, node: Text} | null {
let sel = view.observer.selectionRange
if (!sel.focusNode) return null
Expand Down

0 comments on commit f40079c

Please sign in to comment.