annotate .cms/lib/codemirror/src/model/line_widget.js @ 0:78edf6b517a0 draft

24.10
author Coffee CMS <info@coffee-cms.ru>
date Fri, 11 Oct 2024 22:40:23 +0000
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
1 import { runInOp } from "../display/operations.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
2 import { addToScrollTop } from "../display/scrolling.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
3 import { regLineChange } from "../display/view_tracking.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
4 import { heightAtLine, lineIsHidden } from "../line/spans.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
5 import { lineNo, updateLineHeight } from "../line/utils_line.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
6 import { widgetHeight } from "../measurement/widgets.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
7 import { changeLine } from "./changes.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
8 import { eventMixin } from "../util/event.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
9 import { signalLater } from "../util/operation_group.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
10
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
11 // Line widgets are block elements displayed above or below a line.
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
12
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
13 export class LineWidget {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
14 constructor(doc, node, options) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
15 if (options) for (let opt in options) if (options.hasOwnProperty(opt))
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
16 this[opt] = options[opt]
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
17 this.doc = doc
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
18 this.node = node
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
19 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
20
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
21 clear() {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
22 let cm = this.doc.cm, ws = this.line.widgets, line = this.line, no = lineNo(line)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
23 if (no == null || !ws) return
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
24 for (let i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
25 if (!ws.length) line.widgets = null
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
26 let height = widgetHeight(this)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
27 updateLineHeight(line, Math.max(0, line.height - height))
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
28 if (cm) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
29 runInOp(cm, () => {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
30 adjustScrollWhenAboveVisible(cm, line, -height)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
31 regLineChange(cm, no, "widget")
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
32 })
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
33 signalLater(cm, "lineWidgetCleared", cm, this, no)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
34 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
35 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
36
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
37 changed() {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
38 let oldH = this.height, cm = this.doc.cm, line = this.line
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
39 this.height = null
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
40 let diff = widgetHeight(this) - oldH
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
41 if (!diff) return
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
42 if (!lineIsHidden(this.doc, line)) updateLineHeight(line, line.height + diff)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
43 if (cm) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
44 runInOp(cm, () => {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
45 cm.curOp.forceUpdate = true
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
46 adjustScrollWhenAboveVisible(cm, line, diff)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
47 signalLater(cm, "lineWidgetChanged", cm, this, lineNo(line))
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
48 })
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
49 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
50 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
51 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
52 eventMixin(LineWidget)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
53
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
54 function adjustScrollWhenAboveVisible(cm, line, diff) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
55 if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop))
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
56 addToScrollTop(cm, diff)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
57 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
58
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
59 export function addLineWidget(doc, handle, node, options) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
60 let widget = new LineWidget(doc, node, options)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
61 let cm = doc.cm
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
62 if (cm && widget.noHScroll) cm.display.alignWidgets = true
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
63 changeLine(doc, handle, "widget", line => {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
64 let widgets = line.widgets || (line.widgets = [])
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
65 if (widget.insertAt == null) widgets.push(widget)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
66 else widgets.splice(Math.min(widgets.length, Math.max(0, widget.insertAt)), 0, widget)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
67 widget.line = line
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
68 if (cm && !lineIsHidden(doc, line)) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
69 let aboveVisible = heightAtLine(line) < doc.scrollTop
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
70 updateLineHeight(line, line.height + widgetHeight(widget))
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
71 if (aboveVisible) addToScrollTop(cm, widget.height)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
72 cm.curOp.forceUpdate = true
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
73 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
74 return true
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
75 })
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
76 if (cm) signalLater(cm, "lineWidgetAdded", cm, widget, typeof handle == "number" ? handle : lineNo(handle))
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
77 return widget
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
78 }