@difizen/libro-codemirror 0.0.2-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +0 -0
- package/es/auto-complete/closebrackets.d.ts +12 -0
- package/es/auto-complete/closebrackets.d.ts.map +1 -0
- package/es/auto-complete/closebrackets.js +408 -0
- package/es/auto-complete/completion.d.ts +57 -0
- package/es/auto-complete/completion.d.ts.map +1 -0
- package/es/auto-complete/completion.js +265 -0
- package/es/auto-complete/config.d.ts +22 -0
- package/es/auto-complete/config.d.ts.map +1 -0
- package/es/auto-complete/config.js +44 -0
- package/es/auto-complete/filter.d.ts +13 -0
- package/es/auto-complete/filter.d.ts.map +1 -0
- package/es/auto-complete/filter.js +191 -0
- package/es/auto-complete/index.d.ts +17 -0
- package/es/auto-complete/index.d.ts.map +1 -0
- package/es/auto-complete/index.js +107 -0
- package/es/auto-complete/snippet.d.ts +14 -0
- package/es/auto-complete/snippet.d.ts.map +1 -0
- package/es/auto-complete/snippet.js +447 -0
- package/es/auto-complete/state.d.ts +63 -0
- package/es/auto-complete/state.d.ts.map +1 -0
- package/es/auto-complete/state.js +452 -0
- package/es/auto-complete/theme.d.ts +6 -0
- package/es/auto-complete/theme.d.ts.map +1 -0
- package/es/auto-complete/theme.js +151 -0
- package/es/auto-complete/tooltip.d.ts +5 -0
- package/es/auto-complete/tooltip.d.ts.map +1 -0
- package/es/auto-complete/tooltip.js +365 -0
- package/es/auto-complete/view.d.ts +43 -0
- package/es/auto-complete/view.d.ts.map +1 -0
- package/es/auto-complete/view.js +372 -0
- package/es/auto-complete/word.d.ts +3 -0
- package/es/auto-complete/word.d.ts.map +1 -0
- package/es/auto-complete/word.js +119 -0
- package/es/completion.d.ts +6 -0
- package/es/completion.d.ts.map +1 -0
- package/es/completion.js +84 -0
- package/es/config.d.ts +184 -0
- package/es/config.d.ts.map +1 -0
- package/es/config.js +473 -0
- package/es/editor.d.ts +361 -0
- package/es/editor.d.ts.map +1 -0
- package/es/editor.js +1126 -0
- package/es/factory.d.ts +3 -0
- package/es/factory.d.ts.map +1 -0
- package/es/factory.js +12 -0
- package/es/hyperlink.d.ts +15 -0
- package/es/hyperlink.d.ts.map +1 -0
- package/es/hyperlink.js +120 -0
- package/es/indent.d.ts +8 -0
- package/es/indent.d.ts.map +1 -0
- package/es/indent.js +58 -0
- package/es/indentation-markers/config.d.ts +17 -0
- package/es/indentation-markers/config.d.ts.map +1 -0
- package/es/indentation-markers/config.js +10 -0
- package/es/indentation-markers/index.d.ts +3 -0
- package/es/indentation-markers/index.d.ts.map +1 -0
- package/es/indentation-markers/index.js +160 -0
- package/es/indentation-markers/map.d.ts +77 -0
- package/es/indentation-markers/map.d.ts.map +1 -0
- package/es/indentation-markers/map.js +265 -0
- package/es/indentation-markers/utils.d.ts +27 -0
- package/es/indentation-markers/utils.d.ts.map +1 -0
- package/es/indentation-markers/utils.js +91 -0
- package/es/index.d.ts +11 -0
- package/es/index.d.ts.map +1 -0
- package/es/index.js +10 -0
- package/es/libro-icon.d.ts +3 -0
- package/es/libro-icon.d.ts.map +1 -0
- package/es/libro-icon.js +2 -0
- package/es/mimetype.d.ts +22 -0
- package/es/mimetype.d.ts.map +1 -0
- package/es/mimetype.js +59 -0
- package/es/mode.d.ts +86 -0
- package/es/mode.d.ts.map +1 -0
- package/es/mode.js +284 -0
- package/es/monitor.d.ts +32 -0
- package/es/monitor.d.ts.map +1 -0
- package/es/monitor.js +129 -0
- package/es/python-lang.d.ts +3 -0
- package/es/python-lang.d.ts.map +1 -0
- package/es/python-lang.js +7 -0
- package/es/style/base.css +131 -0
- package/es/style/theme.css +12 -0
- package/es/style/variables.css +403 -0
- package/es/theme.d.ts +35 -0
- package/es/theme.d.ts.map +1 -0
- package/es/theme.js +225 -0
- package/es/tooltip.d.ts +10 -0
- package/es/tooltip.d.ts.map +1 -0
- package/es/tooltip.js +170 -0
- package/package.json +74 -0
- package/src/auto-complete/README.md +71 -0
- package/src/auto-complete/closebrackets.ts +423 -0
- package/src/auto-complete/completion.ts +345 -0
- package/src/auto-complete/config.ts +101 -0
- package/src/auto-complete/filter.ts +215 -0
- package/src/auto-complete/index.ts +112 -0
- package/src/auto-complete/snippet.ts +394 -0
- package/src/auto-complete/state.ts +472 -0
- package/src/auto-complete/theme.ts +126 -0
- package/src/auto-complete/tooltip.ts +386 -0
- package/src/auto-complete/view.ts +343 -0
- package/src/auto-complete/word.ts +118 -0
- package/src/completion.ts +61 -0
- package/src/config.ts +689 -0
- package/src/editor.ts +1078 -0
- package/src/factory.ts +10 -0
- package/src/hyperlink.ts +95 -0
- package/src/indent.ts +69 -0
- package/src/indentation-markers/config.ts +31 -0
- package/src/indentation-markers/index.ts +192 -0
- package/src/indentation-markers/map.ts +273 -0
- package/src/indentation-markers/utils.ts +84 -0
- package/src/index.ts +11 -0
- package/src/libro-icon.ts +4 -0
- package/src/mimetype.ts +49 -0
- package/src/mode.ts +269 -0
- package/src/monitor.ts +105 -0
- package/src/python-lang.ts +7 -0
- package/src/style/base.css +129 -0
- package/src/style/theme.css +12 -0
- package/src/style/variables.css +405 -0
- package/src/theme.ts +231 -0
- package/src/tooltip.ts +145 -0
package/es/editor.js
ADDED
|
@@ -0,0 +1,1126 @@
|
|
|
1
|
+
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
|
|
2
|
+
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
3
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
4
|
+
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
5
|
+
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
6
|
+
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
7
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
8
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
9
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
10
|
+
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
|
|
11
|
+
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
12
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
13
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
14
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
15
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
|
|
16
|
+
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
17
|
+
import { insertNewlineAndIndent, redo as _redo, undo as _undo } from '@codemirror/commands';
|
|
18
|
+
import { ensureSyntaxTree } from '@codemirror/language';
|
|
19
|
+
import { Prec, EditorState, EditorSelection, StateEffect, StateField } from '@codemirror/state';
|
|
20
|
+
import { Decoration, EditorView } from '@codemirror/view';
|
|
21
|
+
import { defaultSelectionStyle, defaultConfig } from '@difizen/libro-code-editor';
|
|
22
|
+
import { findFirstArrayIndex, removeAllWhereFromArray } from '@difizen/libro-common';
|
|
23
|
+
import { Disposable, Emitter } from '@difizen/mana-app';
|
|
24
|
+
import { getOrigin, watch } from '@difizen/mana-app';
|
|
25
|
+
import { v4 } from 'uuid';
|
|
26
|
+
import { EditorConfiguration } from "./config.js";
|
|
27
|
+
import { ensure } from "./mode.js";
|
|
28
|
+
import { monitorPlugin } from "./monitor.js";
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The class name added to CodeMirrorWidget instances.
|
|
32
|
+
*/
|
|
33
|
+
var EDITOR_CLASS = 'jp-CodeMirrorEditor';
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The class name added to read only cell editor widgets.
|
|
37
|
+
*/
|
|
38
|
+
var READ_ONLY_CLASS = 'jp-mod-readOnly';
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* The class name for the hover box for collaborator cursors.
|
|
42
|
+
*/
|
|
43
|
+
// const COLLABORATOR_CURSOR_CLASS = 'jp-CollaboratorCursor';
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* The class name for the hover box for collaborator cursors.
|
|
47
|
+
*/
|
|
48
|
+
// const COLLABORATOR_HOVER_CLASS = 'jp-CollaboratorCursor-hover';
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The key code for the up arrow key.
|
|
52
|
+
*/
|
|
53
|
+
var UP_ARROW = 38;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The key code for the down arrow key.
|
|
57
|
+
*/
|
|
58
|
+
var DOWN_ARROW = 40;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The time that a collaborator name hover persists.
|
|
62
|
+
*/
|
|
63
|
+
// const HOVER_TIMEOUT = 1000;
|
|
64
|
+
/**
|
|
65
|
+
* The default configuration options for an editor.
|
|
66
|
+
*/
|
|
67
|
+
|
|
68
|
+
// interface IYCodeMirrorBinding {
|
|
69
|
+
// text: Y.Text;
|
|
70
|
+
// awareness: Awareness | null;
|
|
71
|
+
// undoManager: Y.UndoManager | null;
|
|
72
|
+
// }
|
|
73
|
+
|
|
74
|
+
export var codeMirrorDefaultConfig = _objectSpread(_objectSpread({}, defaultConfig), {}, {
|
|
75
|
+
mode: 'null',
|
|
76
|
+
mimetype: 'text/x-python',
|
|
77
|
+
theme: 'jupyter',
|
|
78
|
+
smartIndent: true,
|
|
79
|
+
electricChars: true,
|
|
80
|
+
keyMap: 'default',
|
|
81
|
+
extraKeys: null,
|
|
82
|
+
gutters: [],
|
|
83
|
+
fixedGutter: true,
|
|
84
|
+
showCursorWhenSelecting: false,
|
|
85
|
+
coverGutterNextToScrollbar: false,
|
|
86
|
+
dragDrop: true,
|
|
87
|
+
lineSeparator: null,
|
|
88
|
+
scrollbarStyle: 'native',
|
|
89
|
+
lineWiseCopyCut: true,
|
|
90
|
+
scrollPastEnd: false,
|
|
91
|
+
styleActiveLine: false,
|
|
92
|
+
styleSelectedText: true,
|
|
93
|
+
selectionPointer: false,
|
|
94
|
+
handlePaste: true,
|
|
95
|
+
lineWrap: 'off',
|
|
96
|
+
//
|
|
97
|
+
highlightActiveLineGutter: false,
|
|
98
|
+
highlightSpecialChars: true,
|
|
99
|
+
history: true,
|
|
100
|
+
drawSelection: true,
|
|
101
|
+
dropCursor: true,
|
|
102
|
+
allowMultipleSelections: true,
|
|
103
|
+
autocompletion: true,
|
|
104
|
+
rectangularSelection: true,
|
|
105
|
+
crosshairCursor: true,
|
|
106
|
+
highlightSelectionMatches: true,
|
|
107
|
+
foldGutter: true,
|
|
108
|
+
syntaxHighlighting: true,
|
|
109
|
+
jupyterKernelCompletion: true,
|
|
110
|
+
indentationMarkers: true,
|
|
111
|
+
hyperLink: true,
|
|
112
|
+
jupyterKernelTooltip: true,
|
|
113
|
+
tabEditorFunction: true,
|
|
114
|
+
lspCompletion: true,
|
|
115
|
+
lspTooltip: true,
|
|
116
|
+
lspLint: true,
|
|
117
|
+
placeholder: ''
|
|
118
|
+
});
|
|
119
|
+
export var CodeMirrorEditor = /*#__PURE__*/function () {
|
|
120
|
+
/**
|
|
121
|
+
* Construct a CodeMirror editor.
|
|
122
|
+
*/
|
|
123
|
+
function CodeMirrorEditor(options) {
|
|
124
|
+
var _this = this;
|
|
125
|
+
_classCallCheck(this, CodeMirrorEditor);
|
|
126
|
+
this.handleTooltipChange = function (val) {
|
|
127
|
+
_this.modalChangeEmitter.fire(val);
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* Initialize the editor binding.
|
|
131
|
+
*/
|
|
132
|
+
// protected _initializeEditorBinding(): void {
|
|
133
|
+
// const sharedModel = this.model.sharedModel as models.IYText;
|
|
134
|
+
// this._yeditorBinding = {
|
|
135
|
+
// text: sharedModel.ysource,
|
|
136
|
+
// awareness: sharedModel.awareness,
|
|
137
|
+
// undoManager: sharedModel.undoManager,
|
|
138
|
+
// };
|
|
139
|
+
// }
|
|
140
|
+
this.save = function () {
|
|
141
|
+
//
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* A signal emitted when either the top or bottom edge is requested.
|
|
145
|
+
*/
|
|
146
|
+
this.edgeRequestedEmitter = new Emitter();
|
|
147
|
+
this.edgeRequested = this.edgeRequestedEmitter.event;
|
|
148
|
+
this.modalChangeEmitter = new Emitter();
|
|
149
|
+
this._selectionMarkers = {};
|
|
150
|
+
this._caretHover = null;
|
|
151
|
+
this._hoverTimeout = undefined;
|
|
152
|
+
this._hoverId = undefined;
|
|
153
|
+
this._keydownHandlers = new Array();
|
|
154
|
+
this._uuid = '';
|
|
155
|
+
this._isDisposed = false;
|
|
156
|
+
this._lastChange = null;
|
|
157
|
+
this._editorConfig = new EditorConfiguration(options);
|
|
158
|
+
var host = this.host = options.host;
|
|
159
|
+
host.classList.add(EDITOR_CLASS);
|
|
160
|
+
host.classList.add('jp-Editor');
|
|
161
|
+
host.addEventListener('focus', this, true);
|
|
162
|
+
host.addEventListener('blur', this, true);
|
|
163
|
+
host.addEventListener('scroll', this, true);
|
|
164
|
+
this._uuid = options.uuid || v4();
|
|
165
|
+
|
|
166
|
+
// State and effects for handling the selection marks
|
|
167
|
+
this._addMark = StateEffect.define();
|
|
168
|
+
this._removeMark = StateEffect.define();
|
|
169
|
+
this._markField = StateField.define({
|
|
170
|
+
create: function create() {
|
|
171
|
+
return Decoration.none;
|
|
172
|
+
},
|
|
173
|
+
update: function update(marks, transaction) {
|
|
174
|
+
var _marks = marks.map(transaction.changes);
|
|
175
|
+
var _iterator = _createForOfIteratorHelper(transaction.effects),
|
|
176
|
+
_step;
|
|
177
|
+
try {
|
|
178
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
179
|
+
var ef = _step.value;
|
|
180
|
+
if (ef.is(_this._addMark)) {
|
|
181
|
+
var e = ef;
|
|
182
|
+
var decorations = _this._buildMarkDecoration(e.value.uuid, e.value.selections);
|
|
183
|
+
_marks = _marks.update({
|
|
184
|
+
add: decorations
|
|
185
|
+
});
|
|
186
|
+
_this._selectionMarkers[e.value.uuid] = decorations;
|
|
187
|
+
} else if (ef.is(_this._removeMark)) {
|
|
188
|
+
var _e = ef;
|
|
189
|
+
var _iterator2 = _createForOfIteratorHelper(ef.value.decorations),
|
|
190
|
+
_step2;
|
|
191
|
+
try {
|
|
192
|
+
var _loop = function _loop() {
|
|
193
|
+
var rd = _step2.value;
|
|
194
|
+
_marks = _marks.update({
|
|
195
|
+
filter: function filter(from, to, value) {
|
|
196
|
+
return !(from === rd.from && to === rd.to && value === rd.value);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
};
|
|
200
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
201
|
+
_loop();
|
|
202
|
+
}
|
|
203
|
+
} catch (err) {
|
|
204
|
+
_iterator2.e(err);
|
|
205
|
+
} finally {
|
|
206
|
+
_iterator2.f();
|
|
207
|
+
}
|
|
208
|
+
delete _this._selectionMarkers[_e.value.uuid];
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
} catch (err) {
|
|
212
|
+
_iterator.e(err);
|
|
213
|
+
} finally {
|
|
214
|
+
_iterator.f();
|
|
215
|
+
}
|
|
216
|
+
return _marks;
|
|
217
|
+
},
|
|
218
|
+
provide: function provide(f) {
|
|
219
|
+
return EditorView.decorations.from(f);
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// Handle selection style.
|
|
224
|
+
var style = options.selectionStyle || {};
|
|
225
|
+
this._selectionStyle = _objectSpread(_objectSpread({}, defaultSelectionStyle), style);
|
|
226
|
+
var model = this._model = options.model;
|
|
227
|
+
var config = options.config || {};
|
|
228
|
+
var fullConfig = this._config = _objectSpread(_objectSpread(_objectSpread({}, codeMirrorDefaultConfig), config), {}, {
|
|
229
|
+
mimetype: options.model.mimeType
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
// this._initializeEditorBinding();
|
|
233
|
+
|
|
234
|
+
// Extension for handling DOM events
|
|
235
|
+
var domEventHandlers = EditorView.domEventHandlers({
|
|
236
|
+
keydown: function keydown(event) {
|
|
237
|
+
var index = findFirstArrayIndex(_this._keydownHandlers, function (handler) {
|
|
238
|
+
if (handler(_this, event) === true) {
|
|
239
|
+
event.preventDefault();
|
|
240
|
+
return true;
|
|
241
|
+
}
|
|
242
|
+
return false;
|
|
243
|
+
});
|
|
244
|
+
if (index === -1) {
|
|
245
|
+
return _this.onKeydown(event);
|
|
246
|
+
}
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
var updateListener = EditorView.updateListener.of(function (update) {
|
|
251
|
+
_this._onDocChanged(update);
|
|
252
|
+
});
|
|
253
|
+
this._editor = createEditor(host, fullConfig, this.model.value, this._editorConfig, [this._markField, Prec.high(domEventHandlers), updateListener, monitorPlugin({
|
|
254
|
+
onTooltipChange: this.handleTooltipChange
|
|
255
|
+
})]);
|
|
256
|
+
|
|
257
|
+
// every time the model is switched, we need to re-initialize the editor binding
|
|
258
|
+
// this.model.sharedModelSwitched.connect(this._initializeEditorBinding, this);
|
|
259
|
+
|
|
260
|
+
this._onMimeTypeChanged();
|
|
261
|
+
this._onCursorActivity();
|
|
262
|
+
// this._poll = new Poll({
|
|
263
|
+
// factory: async () => {
|
|
264
|
+
// this._checkSync();
|
|
265
|
+
// },
|
|
266
|
+
// frequency: { interval: 3000, backoff: false },
|
|
267
|
+
// standby: () => {
|
|
268
|
+
// // If changed, only stand by when hidden, otherwise always stand by.
|
|
269
|
+
// return this._lastChange ? 'when-hidden' : true;
|
|
270
|
+
// },
|
|
271
|
+
// });
|
|
272
|
+
|
|
273
|
+
watch(model, 'mimeType', this._onMimeTypeChanged);
|
|
274
|
+
}
|
|
275
|
+
_createClass(CodeMirrorEditor, [{
|
|
276
|
+
key: "uuid",
|
|
277
|
+
get:
|
|
278
|
+
/**
|
|
279
|
+
* The DOM node that hosts the editor.
|
|
280
|
+
*/
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* The uuid of this editor;
|
|
284
|
+
*/
|
|
285
|
+
function get() {
|
|
286
|
+
return this._uuid;
|
|
287
|
+
},
|
|
288
|
+
set: function set(value) {
|
|
289
|
+
this._uuid = value;
|
|
290
|
+
}
|
|
291
|
+
}, {
|
|
292
|
+
key: "onModalChange",
|
|
293
|
+
get: function get() {
|
|
294
|
+
return this.modalChangeEmitter.event;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* The selection style of this editor.
|
|
299
|
+
*/
|
|
300
|
+
}, {
|
|
301
|
+
key: "selectionStyle",
|
|
302
|
+
get: function get() {
|
|
303
|
+
return this._selectionStyle;
|
|
304
|
+
},
|
|
305
|
+
set: function set(value) {
|
|
306
|
+
this._selectionStyle = value;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Get the codemirror editor wrapped by the editor.
|
|
311
|
+
*/
|
|
312
|
+
}, {
|
|
313
|
+
key: "editor",
|
|
314
|
+
get: function get() {
|
|
315
|
+
return this._editor;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Get the codemirror doc wrapped by the widget.
|
|
320
|
+
*/
|
|
321
|
+
}, {
|
|
322
|
+
key: "doc",
|
|
323
|
+
get: function get() {
|
|
324
|
+
return this._editor.state.doc;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Get the number of lines in the editor.
|
|
329
|
+
*/
|
|
330
|
+
}, {
|
|
331
|
+
key: "lineCount",
|
|
332
|
+
get: function get() {
|
|
333
|
+
return this.doc.lines;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Returns a model for this editor.
|
|
338
|
+
*/
|
|
339
|
+
}, {
|
|
340
|
+
key: "model",
|
|
341
|
+
get: function get() {
|
|
342
|
+
return this._model;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* The height of a line in the editor in pixels.
|
|
347
|
+
*/
|
|
348
|
+
}, {
|
|
349
|
+
key: "lineHeight",
|
|
350
|
+
get: function get() {
|
|
351
|
+
return this._editor.defaultLineHeight;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* The widget of a character in the editor in pixels.
|
|
356
|
+
*/
|
|
357
|
+
}, {
|
|
358
|
+
key: "charWidth",
|
|
359
|
+
get: function get() {
|
|
360
|
+
return this._editor.defaultCharacterWidth;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Tests whether the editor is disposed.
|
|
365
|
+
*/
|
|
366
|
+
}, {
|
|
367
|
+
key: "isDisposed",
|
|
368
|
+
get: function get() {
|
|
369
|
+
return this._isDisposed;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Dispose of the resources held by the widget.
|
|
374
|
+
*/
|
|
375
|
+
}, {
|
|
376
|
+
key: "dispose",
|
|
377
|
+
value: function dispose() {
|
|
378
|
+
if (this.isDisposed) {
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
this._isDisposed = true;
|
|
382
|
+
this.host.removeEventListener('focus', this, true);
|
|
383
|
+
this.host.removeEventListener('blur', this, true);
|
|
384
|
+
this.host.removeEventListener('scroll', this, true);
|
|
385
|
+
this._keydownHandlers.length = 0;
|
|
386
|
+
// this._poll.dispose();
|
|
387
|
+
this.editor.destroy();
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Get a config option for the editor.
|
|
392
|
+
*/
|
|
393
|
+
}, {
|
|
394
|
+
key: "getOption",
|
|
395
|
+
value: function getOption(option) {
|
|
396
|
+
return this._config[option];
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Set a config option for the editor.
|
|
401
|
+
*/
|
|
402
|
+
}, {
|
|
403
|
+
key: "setOption",
|
|
404
|
+
value: function setOption(option, value) {
|
|
405
|
+
// Don't bother setting the option if it is already the same.
|
|
406
|
+
if (this._config[option] !== value) {
|
|
407
|
+
this._config[option] = value;
|
|
408
|
+
this._editorConfig.reconfigureExtension(this._editor, option, value);
|
|
409
|
+
}
|
|
410
|
+
if (option === 'readOnly') {
|
|
411
|
+
if (value === true) {
|
|
412
|
+
getOrigin(this._editor).dom.classList.add(READ_ONLY_CLASS);
|
|
413
|
+
} else {
|
|
414
|
+
getOrigin(this._editor).dom.classList.remove(READ_ONLY_CLASS);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Set config options for the editor.
|
|
420
|
+
*
|
|
421
|
+
* This method is preferred when setting several options. The
|
|
422
|
+
* options are set within an operation, which only performs
|
|
423
|
+
* the costly update at the end, and not after every option
|
|
424
|
+
* is set.
|
|
425
|
+
*/
|
|
426
|
+
}, {
|
|
427
|
+
key: "setOptions",
|
|
428
|
+
value: function setOptions(options) {
|
|
429
|
+
this._config = _objectSpread(_objectSpread({}, this._config), options);
|
|
430
|
+
this._editorConfig.reconfigureExtensions(this._editor, options);
|
|
431
|
+
}
|
|
432
|
+
}, {
|
|
433
|
+
key: "injectExtension",
|
|
434
|
+
value: function injectExtension(ext) {
|
|
435
|
+
this._editorConfig.injectExtension(this._editor, ext);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* Returns the content for the given line number.
|
|
440
|
+
*/
|
|
441
|
+
}, {
|
|
442
|
+
key: "getLine",
|
|
443
|
+
value: function getLine(line) {
|
|
444
|
+
// TODO: CM6 remove +1 when CM6 first line number has propagated
|
|
445
|
+
var _line = line + 1;
|
|
446
|
+
return _line <= this.doc.lines ? this.doc.line(_line).text : undefined;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Find an offset for the given position.
|
|
451
|
+
*/
|
|
452
|
+
}, {
|
|
453
|
+
key: "getOffsetAt",
|
|
454
|
+
value: function getOffsetAt(position) {
|
|
455
|
+
// TODO: CM6 remove +1 when CM6 first line number has propagated
|
|
456
|
+
return this.doc.line(position.line + 1).from + position.column;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Find a position for the given offset.
|
|
461
|
+
*/
|
|
462
|
+
}, {
|
|
463
|
+
key: "getPositionAt",
|
|
464
|
+
value: function getPositionAt(offset) {
|
|
465
|
+
// TODO: CM6 remove -1 when CM6 first line number has propagated
|
|
466
|
+
var line = this.doc.lineAt(offset);
|
|
467
|
+
return {
|
|
468
|
+
line: line.number - 1,
|
|
469
|
+
column: offset - line.from
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Undo one edit (if any undo events are stored).
|
|
475
|
+
*/
|
|
476
|
+
}, {
|
|
477
|
+
key: "undo",
|
|
478
|
+
value: function undo() {
|
|
479
|
+
_undo({
|
|
480
|
+
state: getOrigin(this.state),
|
|
481
|
+
dispatch: this.editor.dispatch
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Redo one undone edit.
|
|
487
|
+
*/
|
|
488
|
+
}, {
|
|
489
|
+
key: "redo",
|
|
490
|
+
value: function redo() {
|
|
491
|
+
_redo({
|
|
492
|
+
state: getOrigin(this.state),
|
|
493
|
+
dispatch: this.editor.dispatch
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* Clear the undo history.
|
|
499
|
+
*/
|
|
500
|
+
}, {
|
|
501
|
+
key: "clearHistory",
|
|
502
|
+
value: function clearHistory() {
|
|
503
|
+
// this._yeditorBinding?.undoManager?.clear();
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
/**
|
|
507
|
+
* Brings browser focus to this editor text.
|
|
508
|
+
*/
|
|
509
|
+
}, {
|
|
510
|
+
key: "focus",
|
|
511
|
+
value: function focus() {
|
|
512
|
+
this._editor.focus();
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* Test whether the editor has keyboard focus.
|
|
517
|
+
*/
|
|
518
|
+
}, {
|
|
519
|
+
key: "hasFocus",
|
|
520
|
+
value: function hasFocus() {
|
|
521
|
+
return this._editor.hasFocus;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* Explicitly blur the editor.
|
|
526
|
+
*/
|
|
527
|
+
}, {
|
|
528
|
+
key: "blur",
|
|
529
|
+
value: function blur() {
|
|
530
|
+
this._editor.contentDOM.blur();
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* Refresh the editor if it is focused;
|
|
535
|
+
* otherwise postpone refreshing till focusing.
|
|
536
|
+
*/
|
|
537
|
+
}, {
|
|
538
|
+
key: "resizeToFit",
|
|
539
|
+
value: function resizeToFit() {
|
|
540
|
+
this._clearHover();
|
|
541
|
+
}
|
|
542
|
+
}, {
|
|
543
|
+
key: "state",
|
|
544
|
+
get: function get() {
|
|
545
|
+
return this._editor.state;
|
|
546
|
+
}
|
|
547
|
+
}, {
|
|
548
|
+
key: "firstLine",
|
|
549
|
+
value: function firstLine() {
|
|
550
|
+
// TODO: return 1 when CM6 first line number has propagated
|
|
551
|
+
return 0;
|
|
552
|
+
}
|
|
553
|
+
}, {
|
|
554
|
+
key: "lastLine",
|
|
555
|
+
value: function lastLine() {
|
|
556
|
+
return this.doc.lines - 1;
|
|
557
|
+
}
|
|
558
|
+
}, {
|
|
559
|
+
key: "cursorCoords",
|
|
560
|
+
value: function cursorCoords(where
|
|
561
|
+
// mode?: 'window' | 'page' | 'local',
|
|
562
|
+
) {
|
|
563
|
+
var selection = this.state.selection.main;
|
|
564
|
+
var pos = where ? selection.from : selection.to;
|
|
565
|
+
var rect = this.editor.coordsAtPos(pos);
|
|
566
|
+
return rect;
|
|
567
|
+
}
|
|
568
|
+
}, {
|
|
569
|
+
key: "getRange",
|
|
570
|
+
value: function getRange(from, to
|
|
571
|
+
// separator?: string,
|
|
572
|
+
) {
|
|
573
|
+
var fromOffset = this.getOffsetAt(this._toPosition(from));
|
|
574
|
+
var toOffset = this.getOffsetAt(this._toPosition(to));
|
|
575
|
+
return this.state.sliceDoc(fromOffset, toOffset);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Add a keydown handler to the editor.
|
|
580
|
+
*
|
|
581
|
+
* @param handler - A keydown handler.
|
|
582
|
+
*
|
|
583
|
+
* @returns A disposable that can be used to remove the handler.
|
|
584
|
+
*/
|
|
585
|
+
}, {
|
|
586
|
+
key: "addKeydownHandler",
|
|
587
|
+
value: function addKeydownHandler(handler) {
|
|
588
|
+
var _this2 = this;
|
|
589
|
+
this._keydownHandlers.push(handler);
|
|
590
|
+
return Disposable.create(function () {
|
|
591
|
+
removeAllWhereFromArray(_this2._keydownHandlers, function (val) {
|
|
592
|
+
return val === handler;
|
|
593
|
+
});
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* Reveal the given position in the editor.
|
|
599
|
+
*/
|
|
600
|
+
}, {
|
|
601
|
+
key: "revealPosition",
|
|
602
|
+
value: function revealPosition(position) {
|
|
603
|
+
var offset = this.getOffsetAt(position);
|
|
604
|
+
this._editor.dispatch({
|
|
605
|
+
effects: EditorView.scrollIntoView(offset)
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
/**
|
|
610
|
+
* Reveal the given selection in the editor.
|
|
611
|
+
*/
|
|
612
|
+
}, {
|
|
613
|
+
key: "revealSelection",
|
|
614
|
+
value: function revealSelection(selection) {
|
|
615
|
+
var start = this.getOffsetAt(selection.start);
|
|
616
|
+
var end = this.getOffsetAt(selection.end);
|
|
617
|
+
this._editor.dispatch({
|
|
618
|
+
effects: EditorView.scrollIntoView(EditorSelection.range(start, end))
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
/**
|
|
623
|
+
* Get the window coordinates given a cursor position.
|
|
624
|
+
*/
|
|
625
|
+
}, {
|
|
626
|
+
key: "getCoordinateForPosition",
|
|
627
|
+
value: function getCoordinateForPosition(position) {
|
|
628
|
+
var offset = this.getOffsetAt(position);
|
|
629
|
+
var rect = this.editor.coordsAtPos(offset);
|
|
630
|
+
return rect;
|
|
631
|
+
}
|
|
632
|
+
/**
|
|
633
|
+
* Get the cursor position given window coordinates.
|
|
634
|
+
*
|
|
635
|
+
* @param coordinate - The desired coordinate.
|
|
636
|
+
*
|
|
637
|
+
* @returns The position of the coordinates, or null if not
|
|
638
|
+
* contained in the editor.
|
|
639
|
+
*/
|
|
640
|
+
}, {
|
|
641
|
+
key: "getPositionForCoordinate",
|
|
642
|
+
value: function getPositionForCoordinate(coordinate) {
|
|
643
|
+
var offset = this.editor.posAtCoords({
|
|
644
|
+
x: coordinate.left,
|
|
645
|
+
y: coordinate.top
|
|
646
|
+
});
|
|
647
|
+
return this.getPositionAt(offset) || null;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* Returns the primary position of the cursor, never `null`.
|
|
652
|
+
*/
|
|
653
|
+
}, {
|
|
654
|
+
key: "getCursorPosition",
|
|
655
|
+
value: function getCursorPosition() {
|
|
656
|
+
var offset = this.state.selection.main.head;
|
|
657
|
+
return this.getPositionAt(offset);
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
/**
|
|
661
|
+
* Set the primary position of the cursor.
|
|
662
|
+
*
|
|
663
|
+
* #### Notes
|
|
664
|
+
* This will remove any secondary cursors.
|
|
665
|
+
*/
|
|
666
|
+
}, {
|
|
667
|
+
key: "setCursorPosition",
|
|
668
|
+
value: function setCursorPosition(position
|
|
669
|
+
// options?: { bias?: number; origin?: string; scroll?: boolean },
|
|
670
|
+
) {
|
|
671
|
+
var offset = this.getOffsetAt(position);
|
|
672
|
+
this.editor.dispatch({
|
|
673
|
+
selection: {
|
|
674
|
+
anchor: offset
|
|
675
|
+
},
|
|
676
|
+
scrollIntoView: true
|
|
677
|
+
});
|
|
678
|
+
// If the editor does not have focus, this cursor change
|
|
679
|
+
// will get screened out in _onCursorsChanged(). Make an
|
|
680
|
+
// exception for this method.
|
|
681
|
+
if (!this.editor.hasFocus) {
|
|
682
|
+
this.model.selections = this.getSelections();
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
/**
|
|
687
|
+
* Returns the primary selection, never `null`.
|
|
688
|
+
*/
|
|
689
|
+
}, {
|
|
690
|
+
key: "getSelection",
|
|
691
|
+
value: function getSelection() {
|
|
692
|
+
return this.getSelections()[0];
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* Set the primary selection. This will remove any secondary cursors.
|
|
697
|
+
*/
|
|
698
|
+
}, {
|
|
699
|
+
key: "setSelection",
|
|
700
|
+
value: function setSelection(selection) {
|
|
701
|
+
this.setSelections([selection]);
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
/**
|
|
705
|
+
* Gets the selections for all the cursors, never `null` or empty.
|
|
706
|
+
*/
|
|
707
|
+
}, {
|
|
708
|
+
key: "getSelections",
|
|
709
|
+
value: function getSelections() {
|
|
710
|
+
var _this3 = this;
|
|
711
|
+
var selections = this.state.selection.ranges; //= [{anchor: number, head: number}]
|
|
712
|
+
if (selections.length > 0) {
|
|
713
|
+
var sel = selections.map(function (r) {
|
|
714
|
+
return {
|
|
715
|
+
anchor: _this3._toCodeMirrorPosition(_this3.getPositionAt(r.from)),
|
|
716
|
+
head: _this3._toCodeMirrorPosition(_this3.getPositionAt(r.to))
|
|
717
|
+
};
|
|
718
|
+
});
|
|
719
|
+
return sel.map(function (selection) {
|
|
720
|
+
return _this3._toSelection(selection);
|
|
721
|
+
});
|
|
722
|
+
}
|
|
723
|
+
var cursor = this._toCodeMirrorPosition(this.getPositionAt(this.state.selection.main.head));
|
|
724
|
+
var selection = this._toSelection({
|
|
725
|
+
anchor: cursor,
|
|
726
|
+
head: cursor
|
|
727
|
+
});
|
|
728
|
+
return [selection];
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
/**
|
|
732
|
+
* Sets the selections for all the cursors, should not be empty.
|
|
733
|
+
* Cursors will be removed or added, as necessary.
|
|
734
|
+
* Passing an empty array resets a cursor position to the start of a document.
|
|
735
|
+
*/
|
|
736
|
+
}, {
|
|
737
|
+
key: "setSelections",
|
|
738
|
+
value: function setSelections(selections) {
|
|
739
|
+
var _this4 = this;
|
|
740
|
+
var sel = selections.length ? selections.map(function (r) {
|
|
741
|
+
return EditorSelection.range(_this4.getOffsetAt(r.start), _this4.getOffsetAt(r.end));
|
|
742
|
+
}) : [EditorSelection.range(0, 0)];
|
|
743
|
+
this.editor.dispatch({
|
|
744
|
+
selection: EditorSelection.create(sel)
|
|
745
|
+
});
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
/**
|
|
749
|
+
* Replaces the current selection with the given text.
|
|
750
|
+
*
|
|
751
|
+
* @param text The text to be inserted.
|
|
752
|
+
*/
|
|
753
|
+
}, {
|
|
754
|
+
key: "replaceSelection",
|
|
755
|
+
value: function replaceSelection(text) {
|
|
756
|
+
this.editor.dispatch(this.state.replaceSelection(text));
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
/**
|
|
760
|
+
* Get a list of tokens for the current editor text content.
|
|
761
|
+
*/
|
|
762
|
+
}, {
|
|
763
|
+
key: "getTokens",
|
|
764
|
+
value: function getTokens() {
|
|
765
|
+
var _this5 = this;
|
|
766
|
+
var tokens = [];
|
|
767
|
+
var tree = ensureSyntaxTree(this.state, this.doc.length);
|
|
768
|
+
if (tree) {
|
|
769
|
+
tree.iterate({
|
|
770
|
+
enter: function enter(node) {
|
|
771
|
+
tokens.push({
|
|
772
|
+
value: _this5.state.sliceDoc(node.from, node.to),
|
|
773
|
+
offset: node.from,
|
|
774
|
+
type: node.name
|
|
775
|
+
});
|
|
776
|
+
return true;
|
|
777
|
+
}
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
return tokens;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
/**
|
|
784
|
+
* Get the token at a given editor position.
|
|
785
|
+
*/
|
|
786
|
+
}, {
|
|
787
|
+
key: "getTokenAt",
|
|
788
|
+
value: function getTokenAt(offset) {
|
|
789
|
+
var tree = ensureSyntaxTree(this.state, offset);
|
|
790
|
+
if (tree) {
|
|
791
|
+
var node = tree.resolveInner(offset);
|
|
792
|
+
return {
|
|
793
|
+
value: this.state.sliceDoc(node.from, node.to),
|
|
794
|
+
offset: node.from,
|
|
795
|
+
type: node.name
|
|
796
|
+
};
|
|
797
|
+
} else {
|
|
798
|
+
return {
|
|
799
|
+
value: '',
|
|
800
|
+
offset: offset
|
|
801
|
+
};
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
/**
|
|
806
|
+
* Get the token a the cursor position.
|
|
807
|
+
*/
|
|
808
|
+
}, {
|
|
809
|
+
key: "getTokenAtCursor",
|
|
810
|
+
value: function getTokenAtCursor() {
|
|
811
|
+
return this.getTokenAt(this.state.selection.main.head);
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
/**
|
|
815
|
+
* Insert a new indented line at the current cursor position.
|
|
816
|
+
*/
|
|
817
|
+
}, {
|
|
818
|
+
key: "newIndentedLine",
|
|
819
|
+
value: function newIndentedLine() {
|
|
820
|
+
insertNewlineAndIndent({
|
|
821
|
+
state: this.state,
|
|
822
|
+
dispatch: this.editor.dispatch
|
|
823
|
+
});
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
/**
|
|
827
|
+
* Execute a codemirror command on the editor.
|
|
828
|
+
*
|
|
829
|
+
* @param command - The name of the command to execute.
|
|
830
|
+
*/
|
|
831
|
+
}, {
|
|
832
|
+
key: "execCommand",
|
|
833
|
+
value: function execCommand(command) {
|
|
834
|
+
command(this.editor);
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
/**
|
|
838
|
+
* Handle keydown events from the editor.
|
|
839
|
+
*/
|
|
840
|
+
}, {
|
|
841
|
+
key: "onKeydown",
|
|
842
|
+
value: function onKeydown(event) {
|
|
843
|
+
var position = this.state.selection.main.head;
|
|
844
|
+
if (position === 0 && event.keyCode === UP_ARROW) {
|
|
845
|
+
if (!event.shiftKey) {
|
|
846
|
+
// this.edgeRequested.emit('top');
|
|
847
|
+
this.edgeRequestedEmitter.fire('top');
|
|
848
|
+
}
|
|
849
|
+
return false;
|
|
850
|
+
}
|
|
851
|
+
var line = this.doc.lineAt(position).number;
|
|
852
|
+
if (line === 1 && event.keyCode === UP_ARROW) {
|
|
853
|
+
if (!event.shiftKey) {
|
|
854
|
+
// this.edgeRequested.emit('topLine');
|
|
855
|
+
this.edgeRequestedEmitter.fire('topLine');
|
|
856
|
+
}
|
|
857
|
+
return false;
|
|
858
|
+
}
|
|
859
|
+
var length = this.doc.length;
|
|
860
|
+
if (position === length && event.keyCode === DOWN_ARROW) {
|
|
861
|
+
if (!event.shiftKey) {
|
|
862
|
+
// this.edgeRequested.emit('bottom');
|
|
863
|
+
this.edgeRequestedEmitter.fire('bottom');
|
|
864
|
+
}
|
|
865
|
+
return false;
|
|
866
|
+
}
|
|
867
|
+
return false;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
/**
|
|
871
|
+
* Handles a mime type change.
|
|
872
|
+
*/
|
|
873
|
+
}, {
|
|
874
|
+
key: "_onMimeTypeChanged",
|
|
875
|
+
value: function _onMimeTypeChanged() {
|
|
876
|
+
var _this6 = this;
|
|
877
|
+
var mime = this._model.mimeType;
|
|
878
|
+
// TODO: should we provide a hook for when the mode is done being set?
|
|
879
|
+
void ensure(mime).then(function (spec) {
|
|
880
|
+
if (spec) {
|
|
881
|
+
_this6._editorConfig.reconfigureExtension(_this6._editor, 'language', spec.support);
|
|
882
|
+
}
|
|
883
|
+
return;
|
|
884
|
+
});
|
|
885
|
+
}
|
|
886
|
+
}, {
|
|
887
|
+
key: "_buildMarkDecoration",
|
|
888
|
+
value: function _buildMarkDecoration(uuid,
|
|
889
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
890
|
+
_selections) {
|
|
891
|
+
var decorations = [];
|
|
892
|
+
|
|
893
|
+
// If we are marking selections corresponding to an active hover,
|
|
894
|
+
// remove it.
|
|
895
|
+
if (uuid === this._hoverId) {
|
|
896
|
+
this._clearHover();
|
|
897
|
+
}
|
|
898
|
+
// If we can id the selection to a specific collaborator,
|
|
899
|
+
// use that information.
|
|
900
|
+
// let collaborator: ICollaborator | undefined;
|
|
901
|
+
// if (this._model.modelDB.collaborators) {
|
|
902
|
+
// collaborator = this._model.modelDB.collaborators.get(uuid);
|
|
903
|
+
// }
|
|
904
|
+
|
|
905
|
+
// Style each selection for the uuid.
|
|
906
|
+
// selections.forEach(selection => {
|
|
907
|
+
// const from = selection.from;
|
|
908
|
+
// const to = selection.to;
|
|
909
|
+
// // Only render selections if the start is not equal to the end.
|
|
910
|
+
// // In that case, we don't need to render the cursor.
|
|
911
|
+
// if (from !== to) {
|
|
912
|
+
// const style = collaborator
|
|
913
|
+
// ? { ...selection.style, color: collaborator.color }
|
|
914
|
+
// : selection.style;
|
|
915
|
+
// const decoration = Decoration.mark({
|
|
916
|
+
// attributes: this._toMarkSpec(style),
|
|
917
|
+
// });
|
|
918
|
+
// decorations.push(from > to ? decoration.range(to, from) : decoration.range(to, from));
|
|
919
|
+
// } else if (collaborator) {
|
|
920
|
+
// const caret = Decoration.widget({
|
|
921
|
+
// widget: this._getCaret(collaborator),
|
|
922
|
+
// });
|
|
923
|
+
// decorations.push(caret.range(from));
|
|
924
|
+
// }
|
|
925
|
+
// });
|
|
926
|
+
|
|
927
|
+
return decorations;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
/**
|
|
931
|
+
* Converts the selection style to a text marker options.
|
|
932
|
+
*/
|
|
933
|
+
// protected _toMarkSpec(style: IEditorSelectionStyle) {
|
|
934
|
+
// const r = parseInt(style.color.slice(1, 3), 16);
|
|
935
|
+
// const g = parseInt(style.color.slice(3, 5), 16);
|
|
936
|
+
// const b = parseInt(style.color.slice(5, 7), 16);
|
|
937
|
+
// const css = `background-color: rgba( ${r}, ${g}, ${b}, 0.15)`;
|
|
938
|
+
// return {
|
|
939
|
+
// className: style.className,
|
|
940
|
+
// title: style.displayName,
|
|
941
|
+
// css,
|
|
942
|
+
// };
|
|
943
|
+
// }
|
|
944
|
+
|
|
945
|
+
/**
|
|
946
|
+
* Construct a caret element representing the position
|
|
947
|
+
* of a collaborator's cursor.
|
|
948
|
+
*/
|
|
949
|
+
// protected _getCaret(collaborator: ICollaborator): CaretWidget {
|
|
950
|
+
// return new CaretWidget(collaborator, {
|
|
951
|
+
// setHoverId: (sessionId: string) => {
|
|
952
|
+
// this._clearHover();
|
|
953
|
+
// this._hoverId = sessionId;
|
|
954
|
+
// },
|
|
955
|
+
// setHoverTimeout: () => {
|
|
956
|
+
// this._hoverTimeout = window.setTimeout(() => {
|
|
957
|
+
// this._clearHover();
|
|
958
|
+
// }, HOVER_TIMEOUT);
|
|
959
|
+
// },
|
|
960
|
+
// clearHoverTimeout: () => {
|
|
961
|
+
// window.clearTimeout(this._hoverTimeout);
|
|
962
|
+
// },
|
|
963
|
+
// });
|
|
964
|
+
// }
|
|
965
|
+
|
|
966
|
+
/**
|
|
967
|
+
* Handles a cursor activity event.
|
|
968
|
+
*/
|
|
969
|
+
}, {
|
|
970
|
+
key: "_onCursorActivity",
|
|
971
|
+
value: function _onCursorActivity() {
|
|
972
|
+
// Only add selections if the editor has focus. This avoids unwanted
|
|
973
|
+
// triggering of cursor activity due to collaborator actions.
|
|
974
|
+
if (this._editor.hasFocus) {
|
|
975
|
+
var selections = this.getSelections();
|
|
976
|
+
this.model.selections = selections;
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
/**
|
|
981
|
+
* Converts a code mirror selection to an editor selection.
|
|
982
|
+
*/
|
|
983
|
+
}, {
|
|
984
|
+
key: "_toSelection",
|
|
985
|
+
value: function _toSelection(selection) {
|
|
986
|
+
return {
|
|
987
|
+
uuid: this.uuid,
|
|
988
|
+
start: this._toPosition(selection.anchor),
|
|
989
|
+
end: this._toPosition(selection.head),
|
|
990
|
+
style: this.selectionStyle
|
|
991
|
+
};
|
|
992
|
+
}
|
|
993
|
+
/**
|
|
994
|
+
* Convert a code mirror position to an editor position.
|
|
995
|
+
*/
|
|
996
|
+
}, {
|
|
997
|
+
key: "_toPosition",
|
|
998
|
+
value: function _toPosition(position) {
|
|
999
|
+
return {
|
|
1000
|
+
line: position.line,
|
|
1001
|
+
column: position.ch
|
|
1002
|
+
};
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
/**
|
|
1006
|
+
* Convert an editor position to a code mirror position.
|
|
1007
|
+
*/
|
|
1008
|
+
}, {
|
|
1009
|
+
key: "_toCodeMirrorPosition",
|
|
1010
|
+
value: function _toCodeMirrorPosition(position) {
|
|
1011
|
+
return {
|
|
1012
|
+
line: position.line,
|
|
1013
|
+
ch: position.column
|
|
1014
|
+
};
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
/**
|
|
1018
|
+
* Handles document changes.
|
|
1019
|
+
*/
|
|
1020
|
+
}, {
|
|
1021
|
+
key: "_onDocChanged",
|
|
1022
|
+
value: function _onDocChanged(update) {
|
|
1023
|
+
if (update.transactions.length && update.transactions[0].selection) {
|
|
1024
|
+
this._onCursorActivity();
|
|
1025
|
+
}
|
|
1026
|
+
if (update.docChanged) {
|
|
1027
|
+
this._lastChange = update.changes;
|
|
1028
|
+
}
|
|
1029
|
+
this.model.value = update.state.doc.toJSON().join('\n');
|
|
1030
|
+
}
|
|
1031
|
+
/**
|
|
1032
|
+
* Handle the DOM events for the editor.
|
|
1033
|
+
*
|
|
1034
|
+
* @param event - The DOM event sent to the editor.
|
|
1035
|
+
*
|
|
1036
|
+
* #### Notes
|
|
1037
|
+
* This method implements the DOM `EventListener` interface and is
|
|
1038
|
+
* called in response to events on the editor's DOM node. It should
|
|
1039
|
+
* not be called directly by user code.
|
|
1040
|
+
*/
|
|
1041
|
+
}, {
|
|
1042
|
+
key: "handleEvent",
|
|
1043
|
+
value: function handleEvent(event) {
|
|
1044
|
+
switch (event.type) {
|
|
1045
|
+
case 'focus':
|
|
1046
|
+
this._evtFocus();
|
|
1047
|
+
break;
|
|
1048
|
+
case 'blur':
|
|
1049
|
+
this._evtBlur();
|
|
1050
|
+
break;
|
|
1051
|
+
case 'scroll':
|
|
1052
|
+
this._evtScroll();
|
|
1053
|
+
break;
|
|
1054
|
+
default:
|
|
1055
|
+
break;
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
/**
|
|
1060
|
+
* Handle `focus` events for the editor.
|
|
1061
|
+
*/
|
|
1062
|
+
}, {
|
|
1063
|
+
key: "_evtFocus",
|
|
1064
|
+
value: function _evtFocus() {
|
|
1065
|
+
this.host.classList.add('jp-mod-focused');
|
|
1066
|
+
|
|
1067
|
+
// Update the selections on editor gaining focus because
|
|
1068
|
+
// the onCursorActivity function filters usual cursor events
|
|
1069
|
+
// based on the editor's focus.
|
|
1070
|
+
this._onCursorActivity();
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
/**
|
|
1074
|
+
* Handle `blur` events for the editor.
|
|
1075
|
+
*/
|
|
1076
|
+
}, {
|
|
1077
|
+
key: "_evtBlur",
|
|
1078
|
+
value: function _evtBlur() {
|
|
1079
|
+
this.host.classList.remove('jp-mod-focused');
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
/**
|
|
1083
|
+
* Handle `scroll` events for the editor.
|
|
1084
|
+
*/
|
|
1085
|
+
}, {
|
|
1086
|
+
key: "_evtScroll",
|
|
1087
|
+
value: function _evtScroll() {
|
|
1088
|
+
// Remove any active hover.
|
|
1089
|
+
this._clearHover();
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
/**
|
|
1093
|
+
* Clear the hover for a caret, due to things like
|
|
1094
|
+
* scrolling, resizing, deactivation, etc, where
|
|
1095
|
+
* the position is no longer valid.
|
|
1096
|
+
*/
|
|
1097
|
+
}, {
|
|
1098
|
+
key: "_clearHover",
|
|
1099
|
+
value: function _clearHover() {
|
|
1100
|
+
if (this._caretHover) {
|
|
1101
|
+
window.clearTimeout(this._hoverTimeout);
|
|
1102
|
+
document.body.removeChild(this._caretHover);
|
|
1103
|
+
this._caretHover = null;
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
// protected _poll: Poll;
|
|
1108
|
+
// protected _yeditorBinding: IYCodeMirrorBinding | null;
|
|
1109
|
+
}]);
|
|
1110
|
+
return CodeMirrorEditor;
|
|
1111
|
+
}();
|
|
1112
|
+
export function createEditor(host, config, value, editorConfig, additionalExtensions) {
|
|
1113
|
+
var extensions = editorConfig.getInitialExtensions(config);
|
|
1114
|
+
extensions.push.apply(extensions, _toConsumableArray(additionalExtensions));
|
|
1115
|
+
var view = new EditorView({
|
|
1116
|
+
state: EditorState.create({
|
|
1117
|
+
doc: value,
|
|
1118
|
+
extensions: extensions
|
|
1119
|
+
}),
|
|
1120
|
+
parent: host
|
|
1121
|
+
});
|
|
1122
|
+
if (config.readOnly) {
|
|
1123
|
+
view.dom.classList.add(READ_ONLY_CLASS);
|
|
1124
|
+
}
|
|
1125
|
+
return view;
|
|
1126
|
+
}
|