Mercurial
comparison .cms/lib/codemirror/src/edit/options.js @ 0:78edf6b517a0 draft
24.10
author | Coffee CMS <info@coffee-cms.ru> |
---|---|
date | Fri, 11 Oct 2024 22:40:23 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:78edf6b517a0 |
---|---|
1 import { onBlur } from "../display/focus.js" | |
2 import { getGutters, updateGutters } from "../display/gutters.js" | |
3 import { loadMode, resetModeState } from "../display/mode_state.js" | |
4 import { initScrollbars, updateScrollbars } from "../display/scrollbars.js" | |
5 import { updateSelection } from "../display/selection.js" | |
6 import { regChange } from "../display/view_tracking.js" | |
7 import { getKeyMap } from "../input/keymap.js" | |
8 import { defaultSpecialCharPlaceholder } from "../line/line_data.js" | |
9 import { Pos } from "../line/pos.js" | |
10 import { findMaxLine } from "../line/spans.js" | |
11 import { clearCaches, compensateForHScroll, estimateLineHeights } from "../measurement/position_measurement.js" | |
12 import { replaceRange } from "../model/changes.js" | |
13 import { mobile, windows } from "../util/browser.js" | |
14 import { addClass, rmClass } from "../util/dom.js" | |
15 import { off, on } from "../util/event.js" | |
16 | |
17 import { themeChanged } from "./utils.js" | |
18 | |
19 export let Init = {toString: function(){return "CodeMirror.Init"}} | |
20 | |
21 export let defaults = {} | |
22 export let optionHandlers = {} | |
23 | |
24 export function defineOptions(CodeMirror) { | |
25 let optionHandlers = CodeMirror.optionHandlers | |
26 | |
27 function option(name, deflt, handle, notOnInit) { | |
28 CodeMirror.defaults[name] = deflt | |
29 if (handle) optionHandlers[name] = | |
30 notOnInit ? (cm, val, old) => {if (old != Init) handle(cm, val, old)} : handle | |
31 } | |
32 | |
33 CodeMirror.defineOption = option | |
34 | |
35 // Passed to option handlers when there is no old value. | |
36 CodeMirror.Init = Init | |
37 | |
38 // These two are, on init, called from the constructor because they | |
39 // have to be initialized before the editor can start at all. | |
40 option("value", "", (cm, val) => cm.setValue(val), true) | |
41 option("mode", null, (cm, val) => { | |
42 cm.doc.modeOption = val | |
43 loadMode(cm) | |
44 }, true) | |
45 | |
46 option("indentUnit", 2, loadMode, true) | |
47 option("indentWithTabs", false) | |
48 option("smartIndent", true) | |
49 option("tabSize", 4, cm => { | |
50 resetModeState(cm) | |
51 clearCaches(cm) | |
52 regChange(cm) | |
53 }, true) | |
54 | |
55 option("lineSeparator", null, (cm, val) => { | |
56 cm.doc.lineSep = val | |
57 if (!val) return | |
58 let newBreaks = [], lineNo = cm.doc.first | |
59 cm.doc.iter(line => { | |
60 for (let pos = 0;;) { | |
61 let found = line.text.indexOf(val, pos) | |
62 if (found == -1) break | |
63 pos = found + val.length | |
64 newBreaks.push(Pos(lineNo, found)) | |
65 } | |
66 lineNo++ | |
67 }) | |
68 for (let i = newBreaks.length - 1; i >= 0; i--) | |
69 replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length)) | |
70 }) | |
71 option("specialChars", /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b\u200e\u200f\u2028\u2029\u202d\u202e\u2066\u2067\u2069\ufeff\ufff9-\ufffc]/g, (cm, val, old) => { | |
72 cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g") | |
73 if (old != Init) cm.refresh() | |
74 }) | |
75 option("specialCharPlaceholder", defaultSpecialCharPlaceholder, cm => cm.refresh(), true) | |
76 option("electricChars", true) | |
77 option("inputStyle", mobile ? "contenteditable" : "textarea", () => { | |
78 throw new Error("inputStyle can not (yet) be changed in a running editor") // FIXME | |
79 }, true) | |
80 option("spellcheck", false, (cm, val) => cm.getInputField().spellcheck = val, true) | |
81 option("autocorrect", false, (cm, val) => cm.getInputField().autocorrect = val, true) | |
82 option("autocapitalize", false, (cm, val) => cm.getInputField().autocapitalize = val, true) | |
83 option("rtlMoveVisually", !windows) | |
84 option("wholeLineUpdateBefore", true) | |
85 | |
86 option("theme", "default", cm => { | |
87 themeChanged(cm) | |
88 updateGutters(cm) | |
89 }, true) | |
90 option("keyMap", "default", (cm, val, old) => { | |
91 let next = getKeyMap(val) | |
92 let prev = old != Init && getKeyMap(old) | |
93 if (prev && prev.detach) prev.detach(cm, next) | |
94 if (next.attach) next.attach(cm, prev || null) | |
95 }) | |
96 option("extraKeys", null) | |
97 option("configureMouse", null) | |
98 | |
99 option("lineWrapping", false, wrappingChanged, true) | |
100 option("gutters", [], (cm, val) => { | |
101 cm.display.gutterSpecs = getGutters(val, cm.options.lineNumbers) | |
102 updateGutters(cm) | |
103 }, true) | |
104 option("fixedGutter", true, (cm, val) => { | |
105 cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0" | |
106 cm.refresh() | |
107 }, true) | |
108 option("coverGutterNextToScrollbar", false, cm => updateScrollbars(cm), true) | |
109 option("scrollbarStyle", "native", cm => { | |
110 initScrollbars(cm) | |
111 updateScrollbars(cm) | |
112 cm.display.scrollbars.setScrollTop(cm.doc.scrollTop) | |
113 cm.display.scrollbars.setScrollLeft(cm.doc.scrollLeft) | |
114 }, true) | |
115 option("lineNumbers", false, (cm, val) => { | |
116 cm.display.gutterSpecs = getGutters(cm.options.gutters, val) | |
117 updateGutters(cm) | |
118 }, true) | |
119 option("firstLineNumber", 1, updateGutters, true) | |
120 option("lineNumberFormatter", integer => integer, updateGutters, true) | |
121 option("showCursorWhenSelecting", false, updateSelection, true) | |
122 | |
123 option("resetSelectionOnContextMenu", true) | |
124 option("lineWiseCopyCut", true) | |
125 option("pasteLinesPerSelection", true) | |
126 option("selectionsMayTouch", false) | |
127 | |
128 option("readOnly", false, (cm, val) => { | |
129 if (val == "nocursor") { | |
130 onBlur(cm) | |
131 cm.display.input.blur() | |
132 } | |
133 cm.display.input.readOnlyChanged(val) | |
134 }) | |
135 | |
136 option("screenReaderLabel", null, (cm, val) => { | |
137 val = (val === '') ? null : val | |
138 cm.display.input.screenReaderLabelChanged(val) | |
139 }) | |
140 | |
141 option("disableInput", false, (cm, val) => {if (!val) cm.display.input.reset()}, true) | |
142 option("dragDrop", true, dragDropChanged) | |
143 option("allowDropFileTypes", null) | |
144 | |
145 option("cursorBlinkRate", 530) | |
146 option("cursorScrollMargin", 0) | |
147 option("cursorHeight", 1, updateSelection, true) | |
148 option("singleCursorHeightPerLine", true, updateSelection, true) | |
149 option("workTime", 100) | |
150 option("workDelay", 100) | |
151 option("flattenSpans", true, resetModeState, true) | |
152 option("addModeClass", false, resetModeState, true) | |
153 option("pollInterval", 100) | |
154 option("undoDepth", 200, (cm, val) => cm.doc.history.undoDepth = val) | |
155 option("historyEventDelay", 1250) | |
156 option("viewportMargin", 10, cm => cm.refresh(), true) | |
157 option("maxHighlightLength", 10000, resetModeState, true) | |
158 option("moveInputWithCursor", true, (cm, val) => { | |
159 if (!val) cm.display.input.resetPosition() | |
160 }) | |
161 | |
162 option("tabindex", null, (cm, val) => cm.display.input.getField().tabIndex = val || "") | |
163 option("autofocus", null) | |
164 option("direction", "ltr", (cm, val) => cm.doc.setDirection(val), true) | |
165 option("phrases", null) | |
166 } | |
167 | |
168 function dragDropChanged(cm, value, old) { | |
169 let wasOn = old && old != Init | |
170 if (!value != !wasOn) { | |
171 let funcs = cm.display.dragFunctions | |
172 let toggle = value ? on : off | |
173 toggle(cm.display.scroller, "dragstart", funcs.start) | |
174 toggle(cm.display.scroller, "dragenter", funcs.enter) | |
175 toggle(cm.display.scroller, "dragover", funcs.over) | |
176 toggle(cm.display.scroller, "dragleave", funcs.leave) | |
177 toggle(cm.display.scroller, "drop", funcs.drop) | |
178 } | |
179 } | |
180 | |
181 function wrappingChanged(cm) { | |
182 if (cm.options.lineWrapping) { | |
183 addClass(cm.display.wrapper, "CodeMirror-wrap") | |
184 cm.display.sizer.style.minWidth = "" | |
185 cm.display.sizerWidth = null | |
186 } else { | |
187 rmClass(cm.display.wrapper, "CodeMirror-wrap") | |
188 findMaxLine(cm) | |
189 } | |
190 estimateLineHeights(cm) | |
191 regChange(cm) | |
192 clearCaches(cm) | |
193 setTimeout(() => updateScrollbars(cm), 100) | |
194 } |