Skip to content

Commit

Permalink
Pass editor view to updateDOM widget method.
Browse files Browse the repository at this point in the history
FEATURE: `WidgetType.updateDOM` is now passed the editor view object.

See https://discuss.codemirror.net/t/is-view-requestmeasure-required-when-a-block-widget-changes-height/5604
  • Loading branch information
marijnh committed Jan 26, 2023
1 parent 84f483a commit 91e0a7d
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 25 deletions.
11 changes: 6 additions & 5 deletions src/blockview.ts
Expand Up @@ -5,6 +5,7 @@ import {clientRectsFor, Rect, clearAttributes} from "./dom"
import {LineDecoration, WidgetType, BlockType} from "./decoration"
import {Attrs, combineAttrs, attrsEq, updateAttrs} from "./attributes"
import browser from "./browser"
import {EditorView} from "./editorview"
import {Text} from "@codemirror/state"

export interface BlockView extends ContentView {
Expand Down Expand Up @@ -90,7 +91,7 @@ export class LineView extends ContentView implements BlockView {
}
}

sync(track?: {node: Node, written: boolean}) {
sync(view: EditorView, track?: {node: Node, written: boolean}) {
if (!this.dom) {
this.setDOM(document.createElement("div"))
this.dom!.className = "cm-line"
Expand All @@ -105,7 +106,7 @@ export class LineView extends ContentView implements BlockView {
this.dom!.classList.add("cm-line")
this.prevAttrs = undefined
}
super.sync(track)
super.sync(view, track)
let last = this.dom!.lastChild
while (last && ContentView.get(last) instanceof MarkView)
last = last.lastChild
Expand Down Expand Up @@ -186,11 +187,11 @@ export class BlockWidgetView extends ContentView implements BlockView {

get children() { return noChildren }

sync() {
if (!this.dom || !this.widget.updateDOM(this.dom)) {
sync(view: EditorView) {
if (!this.dom || !this.widget.updateDOM(this.dom, view)) {
if (this.dom && this.prevWidget) this.prevWidget.destroy(this.dom)
this.prevWidget = null
this.setDOM(this.widget.toDOM(this.editorView))
this.setDOM(this.widget.toDOM(view))
this.dom!.contentEditable = "false"
}
}
Expand Down
11 changes: 3 additions & 8 deletions src/contentview.ts
Expand Up @@ -31,11 +31,6 @@ export abstract class ContentView {
abstract children: ContentView[]
breakAfter!: number

get editorView(): EditorView {
if (!this.parent) throw new Error("Accessing view in orphan content view")
return this.parent.editorView
}

get overrideDOMText(): Text | null { return null }

get posAtStart(): number {
Expand Down Expand Up @@ -64,7 +59,7 @@ export abstract class ContentView {
// given position.
coordsAt(_pos: number, _side: number): Rect | null { return null }

sync(track?: {node: Node, written: boolean}) {
sync(view: EditorView, track?: {node: Node, written: boolean}) {
if (this.dirty & Dirty.Node) {
let parent = this.dom as HTMLElement
let prev: Node | null = null, next
Expand All @@ -75,7 +70,7 @@ export abstract class ContentView {
if (!contentView || !contentView.parent && contentView.canReuseDOM(child))
child.reuseDOM(next)
}
child.sync(track)
child.sync(view, track)
child.dirty = Dirty.Not
}
next = prev ? prev.nextSibling : parent.firstChild
Expand All @@ -92,7 +87,7 @@ export abstract class ContentView {
while (next) next = rm(next)
} else if (this.dirty & Dirty.Child) {
for (let child of this.children) if (child.dirty) {
child.sync(track)
child.sync(view, track)
child.dirty = Dirty.Not
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/decoration.ts
Expand Up @@ -105,7 +105,7 @@ export abstract class WidgetType {
/// true to indicate that it could update, false to indicate it
/// couldn't (in which case the widget will be redrawn). The default
/// implementation just returns false.
updateDOM(dom: HTMLElement): boolean { return false }
updateDOM(dom: HTMLElement, view: EditorView): boolean { return false }

/// @internal
compare(other: WidgetType): boolean {
Expand Down
4 changes: 1 addition & 3 deletions src/docview.ts
Expand Up @@ -43,8 +43,6 @@ export class DocView extends ContentView {
// ourselves
lastUpdate = Date.now()

get editorView() { return this.view }

get length() { return this.view.state.doc.length }

constructor(readonly view: EditorView) {
Expand Down Expand Up @@ -117,7 +115,7 @@ export class DocView extends ContentView {
// selection from the one it displays (issue #218). This tries
// to detect that situation.
let track = browser.chrome || browser.ios ? {node: observer.selectionRange.focusNode!, written: false} : undefined
this.sync(track)
this.sync(this.view, track)
this.dirty = Dirty.Not
if (track && (track.written || observer.selectionRange.focusNode != track.node)) this.forceSelection = true
this.dom.style.height = ""
Expand Down
17 changes: 9 additions & 8 deletions src/inlineview.ts
Expand Up @@ -2,8 +2,9 @@ import {Text as DocText} from "@codemirror/state"
import {ContentView, DOMPos, Dirty, mergeChildrenInto, noChildren} from "./contentview"
import {WidgetType, MarkDecoration} from "./decoration"
import {Rect, Rect0, flattenRect, textRange, clientRectsFor, clearAttributes, contains} from "./dom"
import {CompositionWidget} from "./docview"
import {CompositionWidget, DocView} from "./docview"
import browser from "./browser"
import {EditorView} from "./editorview"

const MaxJoinLen = 256

Expand All @@ -21,7 +22,7 @@ export class TextView extends ContentView {
this.setDOM(textDOM || document.createTextNode(this.text))
}

sync(track?: {node: Node, written: boolean}) {
sync(view: EditorView, track?: {node: Node, written: boolean}) {
if (!this.dom) this.createDOM()
if (this.dom!.nodeValue != this.text) {
if (track && track.node == this.dom) track.written = true
Expand Down Expand Up @@ -87,10 +88,10 @@ export class MarkView extends ContentView {
}
}

sync(track?: {node: Node, written: boolean}) {
sync(view: EditorView, track?: {node: Node, written: boolean}) {
if (!this.dom) this.setDOM(this.setAttrs(document.createElement(this.mark.tagName)))
else if (this.dirty & Dirty.Attrs) this.setAttrs(this.dom)
super.sync(track)
super.sync(view, track)
}

merge(from: number, to: number, source: ContentView | null, _hasStart: boolean, openStart: number, openEnd: number): boolean {
Expand Down Expand Up @@ -168,11 +169,11 @@ export class WidgetView extends ContentView {
return result
}

sync() {
if (!this.dom || !this.widget.updateDOM(this.dom)) {
sync(view: EditorView) {
if (!this.dom || !this.widget.updateDOM(this.dom, view)) {
if (this.dom && this.prevWidget) this.prevWidget.destroy(this.dom)
this.prevWidget = null
this.setDOM(this.widget.toDOM(this.editorView))
this.setDOM(this.widget.toDOM(view))
this.dom!.contentEditable = "false"
}
}
Expand Down Expand Up @@ -206,7 +207,7 @@ export class WidgetView extends ContentView {
if (this.length == 0) return DocText.empty
let top: ContentView = this
while (top.parent) top = top.parent
let view = (top as any).editorView, text: DocText | undefined = view && view.state.doc, start = this.posAtStart
let {view} = top as DocView, text: DocText | undefined = view && view.state.doc, start = this.posAtStart
return text ? text.slice(start, start + this.length) : DocText.empty
}

Expand Down

0 comments on commit 91e0a7d

Please sign in to comment.