@instructure/ui-source-code-editor 8.33.1 → 8.33.2-snapshot-5
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/CHANGELOG.md +8 -0
- package/es/SourceCodeEditor/SourceCodeEditorLocator.js +5 -10
- package/es/SourceCodeEditor/customKeybinding.js +7 -3
- package/es/SourceCodeEditor/index.js +42 -122
- package/es/SourceCodeEditor/props.js +3 -1
- package/es/SourceCodeEditor/styles.js +11 -7
- package/es/SourceCodeEditor/theme.js +5 -5
- package/lib/SourceCodeEditor/SourceCodeEditorLocator.js +3 -13
- package/lib/SourceCodeEditor/customKeybinding.js +7 -5
- package/lib/SourceCodeEditor/index.js +37 -153
- package/lib/SourceCodeEditor/props.js +3 -5
- package/lib/SourceCodeEditor/styles.js +10 -8
- package/lib/SourceCodeEditor/theme.js +5 -6
- package/lib/index.js +0 -1
- package/package.json +15 -15
- package/tsconfig.build.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [8.33.2-snapshot-5](https://github.com/instructure/instructure-ui/compare/v8.33.1...v8.33.2-snapshot-5) (2023-01-23)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @instructure/ui-source-code-editor
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
6
14
|
## [8.33.1](https://github.com/instructure/instructure-ui/compare/v8.33.0...v8.33.1) (2023-01-06)
|
|
7
15
|
|
|
8
16
|
**Note:** Version bump only for package @instructure/ui-source-code-editor
|
|
@@ -21,60 +21,55 @@
|
|
|
21
21
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
|
+
|
|
24
25
|
import { locator } from '@instructure/ui-test-locator';
|
|
25
26
|
import { find, findAll } from '@instructure/ui-test-queries';
|
|
26
|
-
import { SourceCodeEditor } from './index';
|
|
27
|
+
import { SourceCodeEditor } from './index';
|
|
27
28
|
|
|
29
|
+
// @ts-expect-error ts-migrate(2339) FIXME: Property 'selector' does not exist on type 'typeof... Remove this comment to see the full error message
|
|
28
30
|
export const SourceCodeEditorLocator = locator(SourceCodeEditor.selector, {
|
|
29
31
|
findContainer: async function () {
|
|
30
32
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
31
33
|
args[_key] = arguments[_key];
|
|
32
34
|
}
|
|
33
|
-
|
|
34
35
|
return await find('[class$=-codeEditorContainer]', ...args);
|
|
35
36
|
},
|
|
36
37
|
findLabel: async function () {
|
|
37
38
|
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
38
39
|
args[_key2] = arguments[_key2];
|
|
39
40
|
}
|
|
40
|
-
|
|
41
41
|
return await find('[class$=-screenReaderContent]', ...args);
|
|
42
42
|
},
|
|
43
43
|
findInput: async function () {
|
|
44
44
|
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
|
|
45
45
|
args[_key3] = arguments[_key3];
|
|
46
46
|
}
|
|
47
|
-
|
|
48
47
|
return await find('[role="textbox"]', ...args);
|
|
49
48
|
},
|
|
50
49
|
findGutter: async function () {
|
|
51
50
|
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
|
|
52
51
|
args[_key4] = arguments[_key4];
|
|
53
52
|
}
|
|
54
|
-
|
|
55
53
|
return await find('.cm-gutter', ...args);
|
|
56
54
|
},
|
|
57
55
|
findScroller: async function () {
|
|
58
56
|
for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
|
|
59
57
|
args[_key5] = arguments[_key5];
|
|
60
58
|
}
|
|
61
|
-
|
|
62
59
|
return await find('.cm-scroller', ...args);
|
|
63
60
|
},
|
|
64
61
|
findAllLines: async function () {
|
|
65
62
|
for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
|
|
66
63
|
args[_key6] = arguments[_key6];
|
|
67
64
|
}
|
|
68
|
-
|
|
69
65
|
return await findAll('.cm-line', ...args);
|
|
70
66
|
},
|
|
71
67
|
findAllGutterElements: async function () {
|
|
72
68
|
for (var _len7 = arguments.length, args = new Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {
|
|
73
69
|
args[_key7] = arguments[_key7];
|
|
74
70
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
71
|
+
const allGutterElements = await findAll('.cm-gutterElement', ...args);
|
|
72
|
+
// first gutter element is always a placeholder
|
|
78
73
|
allGutterElements.shift();
|
|
79
74
|
return allGutterElements;
|
|
80
75
|
}
|
|
@@ -21,8 +21,10 @@
|
|
|
21
21
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
|
+
|
|
24
25
|
import { cursorCharLeft, cursorCharRight, cursorGroupLeft, cursorGroupRight, cursorLineBoundaryLeft, cursorLineBoundaryRight, cursorLineBoundaryBackward, cursorLineBoundaryForward, cursorSyntaxLeft, cursorSyntaxRight, deleteCharBackward, deleteCharForward, deleteGroupBackward, deleteGroupForward, deleteToLineEnd, deleteToLineStart, selectCharLeft, selectCharRight, selectGroupLeft, selectGroupRight, selectLineBoundaryLeft, selectLineBoundaryRight, selectLineBoundaryBackward, selectLineBoundaryForward, selectSyntaxLeft, selectSyntaxRight } from '@codemirror/commands';
|
|
25
|
-
const rtlHorizontalArrowKeymap = [
|
|
26
|
+
const rtlHorizontalArrowKeymap = [
|
|
27
|
+
// Left/Start/Forward
|
|
26
28
|
{
|
|
27
29
|
key: 'ArrowLeft',
|
|
28
30
|
run: cursorCharRight,
|
|
@@ -46,7 +48,8 @@ const rtlHorizontalArrowKeymap = [// Left/Start/Forward
|
|
|
46
48
|
key: 'Home',
|
|
47
49
|
run: cursorLineBoundaryForward,
|
|
48
50
|
shift: selectLineBoundaryForward
|
|
49
|
-
},
|
|
51
|
+
},
|
|
52
|
+
// Right/End/Backward
|
|
50
53
|
{
|
|
51
54
|
key: 'ArrowRight',
|
|
52
55
|
run: cursorCharLeft,
|
|
@@ -70,7 +73,8 @@ const rtlHorizontalArrowKeymap = [// Left/Start/Forward
|
|
|
70
73
|
key: 'End',
|
|
71
74
|
run: cursorLineBoundaryBackward,
|
|
72
75
|
shift: selectLineBoundaryBackward
|
|
73
|
-
},
|
|
76
|
+
},
|
|
77
|
+
// Delete/Backspace
|
|
74
78
|
{
|
|
75
79
|
key: 'Delete',
|
|
76
80
|
run: deleteCharBackward
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
|
|
2
2
|
const _excluded = ["label", "styles"];
|
|
3
|
-
|
|
4
3
|
var _dec, _dec2, _dec3, _dec4, _class, _class2;
|
|
5
|
-
|
|
6
4
|
/*
|
|
7
5
|
* The MIT License (MIT)
|
|
8
6
|
*
|
|
@@ -33,7 +31,8 @@ import { deepEqual as isEqual } from '@instructure/ui-utils';
|
|
|
33
31
|
import { EditorState, StateEffect } from '@codemirror/state';
|
|
34
32
|
import { EditorView, highlightSpecialChars, highlightActiveLine, drawSelection, dropCursor, rectangularSelection, crosshairCursor, lineNumbers, highlightActiveLineGutter, keymap } from '@codemirror/view';
|
|
35
33
|
import { autocompletion, completionKeymap, closeBrackets, closeBracketsKeymap } from '@codemirror/autocomplete';
|
|
36
|
-
import { highlightSelectionMatches
|
|
34
|
+
import { highlightSelectionMatches
|
|
35
|
+
// Search feature is turned off for now, see note at keymaps
|
|
37
36
|
// searchKeymap
|
|
38
37
|
} from '@codemirror/search';
|
|
39
38
|
import { indentSelection, defaultKeymap, indentWithTab, history, historyKeymap } from '@codemirror/commands';
|
|
@@ -45,7 +44,8 @@ import { css } from '@codemirror/lang-css';
|
|
|
45
44
|
import { markdown } from '@codemirror/lang-markdown';
|
|
46
45
|
import { json } from '@codemirror/lang-json';
|
|
47
46
|
import { shell } from '@codemirror/legacy-modes/mode/shell';
|
|
48
|
-
import { yaml } from '@codemirror/legacy-modes/mode/yaml';
|
|
47
|
+
import { yaml } from '@codemirror/legacy-modes/mode/yaml';
|
|
48
|
+
// import { oneDarkTheme, oneDarkHighlightStyle } from '@codemirror/theme-one-dark'
|
|
49
49
|
|
|
50
50
|
import { testable } from '@instructure/ui-testable';
|
|
51
51
|
import { omitProps, passthroughProps, withDeterministicId } from '@instructure/ui-react-utils';
|
|
@@ -57,7 +57,6 @@ import generateStyle from './styles';
|
|
|
57
57
|
import generateComponentTheme from './theme';
|
|
58
58
|
import { rtlHorizontalArrowKeymap } from './customKeybinding';
|
|
59
59
|
import { propTypes, allowedProps } from './props';
|
|
60
|
-
|
|
61
60
|
/**
|
|
62
61
|
---
|
|
63
62
|
category: components
|
|
@@ -70,32 +69,24 @@ let SourceCodeEditor = (_dec = withDeterministicId(), _dec2 = withStyle(generate
|
|
|
70
69
|
this._raf.push(requestAnimationFrame(callback));
|
|
71
70
|
}
|
|
72
71
|
}
|
|
73
|
-
|
|
74
72
|
cancelAnimationFrames() {
|
|
75
73
|
this._raf.forEach(request => request.cancel());
|
|
76
|
-
|
|
77
74
|
this._raf = [];
|
|
78
75
|
}
|
|
79
|
-
|
|
80
76
|
focus() {
|
|
81
77
|
this.addAnimationFrame(() => {
|
|
82
78
|
var _this$_editorView;
|
|
83
|
-
|
|
84
79
|
(_this$_editorView = this._editorView) === null || _this$_editorView === void 0 ? void 0 : _this$_editorView.focus();
|
|
85
80
|
});
|
|
86
81
|
}
|
|
87
|
-
|
|
88
82
|
get hasFocus() {
|
|
89
83
|
var _this$_editorView2;
|
|
90
|
-
|
|
91
84
|
return (_this$_editorView2 = this._editorView) === null || _this$_editorView2 === void 0 ? void 0 : _this$_editorView2.hasFocus;
|
|
92
85
|
}
|
|
93
|
-
|
|
94
86
|
selectAll() {
|
|
95
87
|
if (this._editorView) {
|
|
96
88
|
this.addAnimationFrame(() => {
|
|
97
89
|
var _this$currentDocValue;
|
|
98
|
-
|
|
99
90
|
this.dispatchViewSelection({
|
|
100
91
|
anchor: 0,
|
|
101
92
|
head: (_this$currentDocValue = this.currentDocValue) === null || _this$currentDocValue === void 0 ? void 0 : _this$currentDocValue.length
|
|
@@ -103,7 +94,6 @@ let SourceCodeEditor = (_dec = withDeterministicId(), _dec2 = withStyle(generate
|
|
|
103
94
|
});
|
|
104
95
|
}
|
|
105
96
|
}
|
|
106
|
-
|
|
107
97
|
deselectAll() {
|
|
108
98
|
if (this._editorView) {
|
|
109
99
|
this.addAnimationFrame(() => {
|
|
@@ -114,7 +104,6 @@ let SourceCodeEditor = (_dec = withDeterministicId(), _dec2 = withStyle(generate
|
|
|
114
104
|
});
|
|
115
105
|
}
|
|
116
106
|
}
|
|
117
|
-
|
|
118
107
|
indentCurrentSelection() {
|
|
119
108
|
this.addAnimationFrame(() => {
|
|
120
109
|
if (this._editorView) {
|
|
@@ -122,14 +111,12 @@ let SourceCodeEditor = (_dec = withDeterministicId(), _dec2 = withStyle(generate
|
|
|
122
111
|
state: this._editorView.state,
|
|
123
112
|
dispatch: transaction => {
|
|
124
113
|
var _this$_editorView3;
|
|
125
|
-
|
|
126
114
|
(_this$_editorView3 = this._editorView) === null || _this$_editorView3 === void 0 ? void 0 : _this$_editorView3.update([transaction]);
|
|
127
115
|
}
|
|
128
116
|
});
|
|
129
117
|
}
|
|
130
118
|
});
|
|
131
119
|
}
|
|
132
|
-
|
|
133
120
|
indentAll() {
|
|
134
121
|
this.addAnimationFrame(() => {
|
|
135
122
|
if (this._editorView && this.currentDocValue) {
|
|
@@ -137,7 +124,6 @@ let SourceCodeEditor = (_dec = withDeterministicId(), _dec2 = withStyle(generate
|
|
|
137
124
|
}
|
|
138
125
|
});
|
|
139
126
|
}
|
|
140
|
-
|
|
141
127
|
indentCodeRange(from, to) {
|
|
142
128
|
this.addAnimationFrame(() => {
|
|
143
129
|
if (this._editorView && this.currentDocValue) {
|
|
@@ -146,24 +132,22 @@ let SourceCodeEditor = (_dec = withDeterministicId(), _dec2 = withStyle(generate
|
|
|
146
132
|
});
|
|
147
133
|
}
|
|
148
134
|
});
|
|
149
|
-
}
|
|
150
|
-
|
|
135
|
+
}
|
|
151
136
|
|
|
137
|
+
// Attach state effects
|
|
152
138
|
dispatchViewEffects(effects) {
|
|
153
139
|
if (!this._editorView || !effects) return;
|
|
154
|
-
|
|
155
140
|
this._editorView.dispatch({
|
|
156
141
|
effects
|
|
157
142
|
});
|
|
158
|
-
}
|
|
159
|
-
|
|
143
|
+
}
|
|
160
144
|
|
|
145
|
+
// Dispatch changes to the document
|
|
161
146
|
dispatchViewChanges(_ref) {
|
|
162
147
|
let changes = _ref.changes,
|
|
163
|
-
|
|
164
|
-
|
|
148
|
+
selection = _ref.selection,
|
|
149
|
+
userEvent = _ref.userEvent;
|
|
165
150
|
if (!this._editorView || !changes) return;
|
|
166
|
-
|
|
167
151
|
this._editorView.dispatch({
|
|
168
152
|
changes,
|
|
169
153
|
...(selection ? {
|
|
@@ -173,28 +157,24 @@ let SourceCodeEditor = (_dec = withDeterministicId(), _dec2 = withStyle(generate
|
|
|
173
157
|
userEvent
|
|
174
158
|
} : void 0)
|
|
175
159
|
});
|
|
176
|
-
}
|
|
177
|
-
|
|
160
|
+
}
|
|
178
161
|
|
|
162
|
+
// Select a portion of the document
|
|
179
163
|
dispatchViewSelection(selection) {
|
|
180
164
|
if (!this._editorView || !selection) return;
|
|
181
|
-
|
|
182
165
|
this._editorView.dispatch({
|
|
183
166
|
selection
|
|
184
167
|
});
|
|
185
168
|
}
|
|
186
|
-
|
|
187
169
|
get currentDocValue() {
|
|
188
170
|
var _this$_editorView4;
|
|
189
|
-
|
|
190
171
|
return (_this$_editorView4 = this._editorView) === null || _this$_editorView4 === void 0 ? void 0 : _this$_editorView4.state.doc;
|
|
191
|
-
}
|
|
192
|
-
|
|
172
|
+
}
|
|
193
173
|
|
|
174
|
+
// when value is passed, the editor should be controlled
|
|
194
175
|
get isControlled() {
|
|
195
176
|
return typeof this.props.value === 'string';
|
|
196
177
|
}
|
|
197
|
-
|
|
198
178
|
constructor(props) {
|
|
199
179
|
super(props);
|
|
200
180
|
this._id = void 0;
|
|
@@ -203,36 +183,29 @@ let SourceCodeEditor = (_dec = withDeterministicId(), _dec2 = withStyle(generate
|
|
|
203
183
|
this._editorView = void 0;
|
|
204
184
|
this._raf = [];
|
|
205
185
|
this._newSelectionAfterValueChange = void 0;
|
|
206
|
-
|
|
207
186
|
this.handleRef = el => {
|
|
208
187
|
const elementRef = this.props.elementRef;
|
|
209
188
|
this.ref = el;
|
|
210
|
-
|
|
211
189
|
if (typeof elementRef === 'function') {
|
|
212
190
|
elementRef(el);
|
|
213
191
|
}
|
|
214
192
|
};
|
|
215
|
-
|
|
216
193
|
this.handleContainerRef = el => {
|
|
217
194
|
const containerRef = this.props.containerRef;
|
|
218
195
|
this._containerRef = el || void 0;
|
|
219
|
-
|
|
220
196
|
if (typeof containerRef === 'function') {
|
|
221
197
|
containerRef(el);
|
|
222
198
|
}
|
|
223
199
|
};
|
|
224
|
-
|
|
225
200
|
this._id = props.deterministicId();
|
|
226
201
|
}
|
|
227
|
-
|
|
228
202
|
componentDidMount() {
|
|
229
203
|
var _this$props$makeStyle, _this$props2;
|
|
230
|
-
|
|
231
204
|
const _this$props = this.props,
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
205
|
+
value = _this$props.value,
|
|
206
|
+
defaultValue = _this$props.defaultValue,
|
|
207
|
+
autofocus = _this$props.autofocus,
|
|
208
|
+
indentOnLoad = _this$props.indentOnLoad;
|
|
236
209
|
(_this$props$makeStyle = (_this$props2 = this.props).makeStyles) === null || _this$props$makeStyle === void 0 ? void 0 : _this$props$makeStyle.call(_this$props2);
|
|
237
210
|
const state = EditorState.create({
|
|
238
211
|
doc: value || defaultValue,
|
|
@@ -242,115 +215,92 @@ let SourceCodeEditor = (_dec = withDeterministicId(), _dec2 = withStyle(generate
|
|
|
242
215
|
state,
|
|
243
216
|
parent: this._containerRef
|
|
244
217
|
});
|
|
245
|
-
|
|
246
218
|
if (autofocus) {
|
|
247
219
|
this.focus();
|
|
248
220
|
}
|
|
249
|
-
|
|
250
221
|
if (indentOnLoad) {
|
|
251
222
|
this.indentAll();
|
|
252
223
|
}
|
|
253
224
|
}
|
|
254
|
-
|
|
255
225
|
componentWillUnmount() {
|
|
256
226
|
var _this$_editorView5;
|
|
257
|
-
|
|
258
227
|
(_this$_editorView5 = this._editorView) === null || _this$_editorView5 === void 0 ? void 0 : _this$_editorView5.destroy();
|
|
259
228
|
this.cancelAnimationFrames();
|
|
260
229
|
}
|
|
261
|
-
|
|
262
230
|
componentDidUpdate(prevProps) {
|
|
263
231
|
var _this$props$makeStyle2, _this$props3;
|
|
264
|
-
|
|
265
232
|
(_this$props$makeStyle2 = (_this$props3 = this.props).makeStyles) === null || _this$props$makeStyle2 === void 0 ? void 0 : _this$props$makeStyle2.call(_this$props3);
|
|
266
|
-
|
|
267
233
|
if (this._editorView) {
|
|
268
234
|
if (this.props.value !== prevProps.value) {
|
|
269
235
|
this.refreshEditorValue();
|
|
270
236
|
}
|
|
271
|
-
|
|
272
237
|
if (this.shouldUpdateExtensions(prevProps)) {
|
|
273
238
|
this.refreshExtensions();
|
|
274
239
|
}
|
|
275
240
|
}
|
|
276
241
|
}
|
|
277
|
-
|
|
278
242
|
shouldUpdateExtensions(prevProps) {
|
|
279
|
-
const propsToObserve = ['styles',
|
|
243
|
+
const propsToObserve = ['styles',
|
|
244
|
+
// needed for theme update
|
|
280
245
|
'themeOverride', 'language', 'readOnly', 'editable', 'lineNumbers', 'highlightActiveLineGutter', 'foldGutter', 'lineWrapping', 'autofocus', 'spellcheck', 'direction', 'dir', 'rtlMoveVisually', 'indentOnLoad', 'indentWithTab', 'indentUnit', 'highlightActiveLine', 'attachment'];
|
|
281
|
-
|
|
282
246
|
for (const prop of propsToObserve) {
|
|
283
247
|
if (!isEqual(this.props[prop], prevProps[prop])) {
|
|
284
248
|
return true;
|
|
285
249
|
}
|
|
286
250
|
}
|
|
287
|
-
|
|
288
251
|
return false;
|
|
289
252
|
}
|
|
290
|
-
|
|
291
253
|
get direction() {
|
|
292
254
|
// comes from the `direction` prop and
|
|
293
255
|
// falls back to the `dir` prop coming from the bidirectional decorator
|
|
294
256
|
return this.props.direction || this.props.dir;
|
|
295
257
|
}
|
|
296
|
-
|
|
297
258
|
get extensions() {
|
|
298
|
-
const extensions = [...this.baseExtensions,
|
|
259
|
+
const extensions = [...this.baseExtensions,
|
|
260
|
+
// our custom extensions
|
|
299
261
|
this.languageExtension, this.onChangeExtension, this.focusListenerExtension, this.announceLineNumberExtension];
|
|
300
|
-
|
|
301
262
|
if (this.themeExtension) {
|
|
302
263
|
extensions.push(this.themeExtension);
|
|
303
264
|
}
|
|
304
|
-
|
|
305
265
|
if (this.props.lineNumbers) {
|
|
306
266
|
extensions.push(lineNumbers());
|
|
307
267
|
}
|
|
308
|
-
|
|
309
268
|
if (this.props.highlightActiveLine) {
|
|
310
269
|
extensions.push(highlightActiveLine());
|
|
311
270
|
}
|
|
312
|
-
|
|
313
271
|
if (this.props.highlightActiveLineGutter) {
|
|
314
272
|
extensions.push(highlightActiveLineGutter());
|
|
315
273
|
}
|
|
316
|
-
|
|
317
274
|
if (this.props.foldGutter) {
|
|
318
275
|
extensions.push(foldGutter());
|
|
319
276
|
}
|
|
320
|
-
|
|
321
277
|
if (this.props.lineWrapping) {
|
|
322
278
|
extensions.push(EditorView.lineWrapping);
|
|
323
279
|
}
|
|
324
|
-
|
|
325
280
|
if (this.props.editable === false) {
|
|
326
281
|
extensions.push(EditorView.editable.of(false));
|
|
327
282
|
}
|
|
328
|
-
|
|
329
283
|
if (this.props.readOnly) {
|
|
330
284
|
extensions.push(EditorState.readOnly.of(true));
|
|
331
285
|
}
|
|
332
|
-
|
|
333
286
|
if (this.props.spellcheck) {
|
|
334
287
|
extensions.push(EditorView.contentAttributes.of({
|
|
335
288
|
spellcheck: 'true'
|
|
336
289
|
}));
|
|
337
290
|
}
|
|
338
|
-
|
|
339
291
|
if (this.direction) {
|
|
340
292
|
extensions.push(EditorView.contentAttributes.of({
|
|
341
293
|
dir: this.direction
|
|
342
294
|
}));
|
|
343
295
|
}
|
|
344
|
-
|
|
345
296
|
if (this.props.indentUnit) {
|
|
346
297
|
extensions.push(indentUnit.of(this.props.indentUnit));
|
|
347
298
|
}
|
|
348
|
-
|
|
349
299
|
return extensions;
|
|
350
300
|
}
|
|
351
|
-
|
|
352
301
|
get baseExtensions() {
|
|
353
|
-
return [
|
|
302
|
+
return [
|
|
303
|
+
// The extensions are based on codemirrors basic setup from 'codemirror'.
|
|
354
304
|
// It is recommended by CodeMirror, that if we want to configure
|
|
355
305
|
// our editor more precisely, we have to copy the source
|
|
356
306
|
// and adjust it as desired.
|
|
@@ -358,10 +308,11 @@ let SourceCodeEditor = (_dec = withDeterministicId(), _dec2 = withStyle(generate
|
|
|
358
308
|
fallback: true
|
|
359
309
|
}), bracketMatching(), closeBrackets(), autocompletion(), rectangularSelection(), crosshairCursor(), highlightSelectionMatches(), indentOnInput(), keymap.of(this.keymaps)];
|
|
360
310
|
}
|
|
361
|
-
|
|
362
311
|
get keymaps() {
|
|
363
312
|
// TODO: if more keymaps are added, list them in the docs as well (#Command keybinding)
|
|
364
|
-
const keymaps = [...closeBracketsKeymap, ...this.commandKeybinding, ...historyKeymap, ...foldKeymap, ...completionKeymap, ...lintKeymap
|
|
313
|
+
const keymaps = [...closeBracketsKeymap, ...this.commandKeybinding, ...historyKeymap, ...foldKeymap, ...completionKeymap, ...lintKeymap
|
|
314
|
+
|
|
315
|
+
// TODO: style and include search & replace toolbar feature
|
|
365
316
|
// Note: the search & replace toolbar is not styled.
|
|
366
317
|
// If this feature is needed in the future, we need a decision about the styling.
|
|
367
318
|
// For now we turned the feature off, since RCE doesn't need it.
|
|
@@ -371,33 +322,28 @@ let SourceCodeEditor = (_dec = withDeterministicId(), _dec2 = withStyle(generate
|
|
|
371
322
|
if (this.props.indentWithTab) {
|
|
372
323
|
keymaps.push(indentWithTab);
|
|
373
324
|
}
|
|
374
|
-
|
|
375
325
|
return keymaps;
|
|
376
326
|
}
|
|
377
|
-
|
|
378
327
|
get commandKeybinding() {
|
|
379
328
|
const rtlMoveVisually = this.props.rtlMoveVisually;
|
|
380
|
-
|
|
381
329
|
if (this.direction === 'rtl' && !rtlMoveVisually) {
|
|
382
|
-
const overrideableKeys = rtlHorizontalArrowKeymap.map(binding => binding.key ? binding.key : binding.mac ? binding.mac : binding);
|
|
330
|
+
const overrideableKeys = rtlHorizontalArrowKeymap.map(binding => binding.key ? binding.key : binding.mac ? binding.mac : binding);
|
|
331
|
+
// we have to remove the binding we want to override from the original,
|
|
383
332
|
// otherwise all will be merged and the defaults will still apply
|
|
384
|
-
|
|
385
333
|
const filteredOriginal = defaultKeymap.filter(binding => binding.key ? overrideableKeys.indexOf(binding.key) < 0 : binding.mac ? overrideableKeys.indexOf(binding.mac) < 0 : false);
|
|
386
334
|
return [...filteredOriginal, ...rtlHorizontalArrowKeymap];
|
|
387
335
|
}
|
|
388
|
-
|
|
389
336
|
return defaultKeymap;
|
|
390
337
|
}
|
|
391
|
-
|
|
392
338
|
get themeExtension() {
|
|
393
339
|
const styles = this.props.styles;
|
|
394
|
-
|
|
395
340
|
if (!(styles !== null && styles !== void 0 && styles.theme) || !styles.highlightStyle) {
|
|
396
341
|
return;
|
|
397
342
|
}
|
|
398
|
-
|
|
399
343
|
const theme = EditorView.theme(styles === null || styles === void 0 ? void 0 : styles.theme);
|
|
400
|
-
const highlightStyle = syntaxHighlighting(HighlightStyle.define(styles === null || styles === void 0 ? void 0 : styles.highlightStyle));
|
|
344
|
+
const highlightStyle = syntaxHighlighting(HighlightStyle.define(styles === null || styles === void 0 ? void 0 : styles.highlightStyle));
|
|
345
|
+
|
|
346
|
+
// see notes in props.ts
|
|
401
347
|
// if (darkTheme) {
|
|
402
348
|
// theme = oneDarkTheme
|
|
403
349
|
// highlightStyle = syntaxHighlighting(oneDarkHighlightStyle)
|
|
@@ -405,14 +351,11 @@ let SourceCodeEditor = (_dec = withDeterministicId(), _dec2 = withStyle(generate
|
|
|
405
351
|
|
|
406
352
|
return [theme, highlightStyle];
|
|
407
353
|
}
|
|
408
|
-
|
|
409
354
|
get languageExtension() {
|
|
410
355
|
const language = this.props.language;
|
|
411
|
-
|
|
412
356
|
switch (language) {
|
|
413
357
|
case 'json':
|
|
414
358
|
return json();
|
|
415
|
-
|
|
416
359
|
case 'js':
|
|
417
360
|
case 'jsx':
|
|
418
361
|
case 'javascript':
|
|
@@ -420,29 +363,23 @@ let SourceCodeEditor = (_dec = withDeterministicId(), _dec2 = withStyle(generate
|
|
|
420
363
|
jsx: true,
|
|
421
364
|
typescript: true
|
|
422
365
|
});
|
|
423
|
-
|
|
424
366
|
case 'html':
|
|
425
367
|
return html({
|
|
426
368
|
matchClosingTags: true,
|
|
427
369
|
autoCloseTags: true
|
|
428
370
|
});
|
|
429
|
-
|
|
430
371
|
case 'css':
|
|
431
372
|
return css();
|
|
432
|
-
|
|
433
373
|
case 'markdown':
|
|
434
374
|
return markdown();
|
|
435
|
-
|
|
436
375
|
case 'sh':
|
|
437
376
|
case 'shell':
|
|
438
377
|
case 'bash':
|
|
439
378
|
// ????
|
|
440
379
|
return StreamLanguage.define(shell);
|
|
441
|
-
|
|
442
380
|
case 'yml':
|
|
443
381
|
case 'yaml':
|
|
444
382
|
return StreamLanguage.define(yaml);
|
|
445
|
-
|
|
446
383
|
default:
|
|
447
384
|
return javascript({
|
|
448
385
|
jsx: true,
|
|
@@ -450,27 +387,23 @@ let SourceCodeEditor = (_dec = withDeterministicId(), _dec2 = withStyle(generate
|
|
|
450
387
|
});
|
|
451
388
|
}
|
|
452
389
|
}
|
|
453
|
-
|
|
454
390
|
callOnChangeHandler(newValue) {
|
|
455
391
|
const _this$props4 = this.props,
|
|
456
|
-
|
|
457
|
-
|
|
392
|
+
onChange = _this$props4.onChange,
|
|
393
|
+
value = _this$props4.value;
|
|
458
394
|
this.addAnimationFrame(() => {
|
|
459
395
|
if (typeof onChange === 'function' && newValue !== value) {
|
|
460
396
|
onChange(newValue);
|
|
461
397
|
}
|
|
462
398
|
});
|
|
463
399
|
}
|
|
464
|
-
|
|
465
400
|
get onChangeExtension() {
|
|
466
401
|
return EditorState.changeFilter.of(transaction => {
|
|
467
402
|
if (!this._editorView) {
|
|
468
403
|
return false;
|
|
469
404
|
}
|
|
470
|
-
|
|
471
405
|
if (transaction.docChanged) {
|
|
472
406
|
const newDoc = transaction.newDoc.toString();
|
|
473
|
-
|
|
474
407
|
if (this.isControlled) {
|
|
475
408
|
// the value will be changed by the onChange handler,
|
|
476
409
|
// refreshEditorValue has to run first
|
|
@@ -486,15 +419,13 @@ let SourceCodeEditor = (_dec = withDeterministicId(), _dec2 = withStyle(generate
|
|
|
486
419
|
this.callOnChangeHandler(newDoc);
|
|
487
420
|
}
|
|
488
421
|
}
|
|
489
|
-
|
|
490
422
|
return true;
|
|
491
423
|
});
|
|
492
424
|
}
|
|
493
|
-
|
|
494
425
|
get focusListenerExtension() {
|
|
495
426
|
const _this$props5 = this.props,
|
|
496
|
-
|
|
497
|
-
|
|
427
|
+
onFocus = _this$props5.onFocus,
|
|
428
|
+
onBlur = _this$props5.onBlur;
|
|
498
429
|
return EditorView.updateListener.of(update => {
|
|
499
430
|
if (update.focusChanged && this._editorView) {
|
|
500
431
|
if (this.hasFocus) {
|
|
@@ -509,12 +440,10 @@ let SourceCodeEditor = (_dec = withDeterministicId(), _dec2 = withStyle(generate
|
|
|
509
440
|
}
|
|
510
441
|
});
|
|
511
442
|
}
|
|
512
|
-
|
|
513
443
|
get announceLineNumberExtension() {
|
|
514
444
|
return EditorState.transactionExtender.of(tr => {
|
|
515
445
|
const selection = tr.selection;
|
|
516
446
|
const oldSelection = tr.startState.selection.main;
|
|
517
|
-
|
|
518
447
|
if (selection && selection.main.empty && oldSelection.empty) {
|
|
519
448
|
const oldLine = tr.startState.doc.lineAt(oldSelection.head);
|
|
520
449
|
const newLine = tr.newDoc.lineAt(selection.main.head);
|
|
@@ -522,32 +451,27 @@ let SourceCodeEditor = (_dec = withDeterministicId(), _dec2 = withStyle(generate
|
|
|
522
451
|
effects: EditorView.announce.of(tr.startState.phrase('line ') + newLine.number + '.')
|
|
523
452
|
};
|
|
524
453
|
}
|
|
525
|
-
|
|
526
454
|
return null;
|
|
527
455
|
});
|
|
528
456
|
}
|
|
529
|
-
|
|
530
457
|
refreshExtensions() {
|
|
531
458
|
this.dispatchViewEffects(StateEffect.reconfigure.of(this.extensions));
|
|
532
459
|
}
|
|
533
|
-
|
|
534
460
|
refreshEditorValue() {
|
|
535
461
|
if (!this._editorView) return;
|
|
536
462
|
const value = this.props.value;
|
|
537
|
-
|
|
538
463
|
const currentValue = this._editorView.state.doc.toString();
|
|
539
|
-
|
|
540
464
|
if (value && currentValue !== value) {
|
|
541
465
|
let userEvent;
|
|
542
|
-
const lengthDiff = value.length - currentValue.length;
|
|
543
|
-
// (only these 2 events, autocomplete doesn't work on paste, etc.)
|
|
466
|
+
const lengthDiff = value.length - currentValue.length;
|
|
544
467
|
|
|
468
|
+
// setting user events are needed for the autocomplete to work
|
|
469
|
+
// (only these 2 events, autocomplete doesn't work on paste, etc.)
|
|
545
470
|
if (lengthDiff === 1) {
|
|
546
471
|
userEvent = 'input.type';
|
|
547
472
|
} else if (lengthDiff === -1) {
|
|
548
473
|
userEvent = 'delete.backward';
|
|
549
474
|
}
|
|
550
|
-
|
|
551
475
|
this.dispatchViewChanges({
|
|
552
476
|
changes: {
|
|
553
477
|
from: 0,
|
|
@@ -559,18 +483,15 @@ let SourceCodeEditor = (_dec = withDeterministicId(), _dec2 = withStyle(generate
|
|
|
559
483
|
});
|
|
560
484
|
this._newSelectionAfterValueChange = void 0;
|
|
561
485
|
}
|
|
562
|
-
|
|
563
486
|
if (this.props.indentOnLoad) {
|
|
564
487
|
this.indentAll();
|
|
565
488
|
}
|
|
566
489
|
}
|
|
567
|
-
|
|
568
490
|
render() {
|
|
569
491
|
const _this$props6 = this.props,
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
492
|
+
label = _this$props6.label,
|
|
493
|
+
styles = _this$props6.styles,
|
|
494
|
+
restProps = _objectWithoutProperties(_this$props6, _excluded);
|
|
574
495
|
return jsx("div", Object.assign({
|
|
575
496
|
ref: this.handleRef,
|
|
576
497
|
css: styles === null || styles === void 0 ? void 0 : styles.codeEditor
|
|
@@ -581,7 +502,6 @@ let SourceCodeEditor = (_dec = withDeterministicId(), _dec2 = withStyle(generate
|
|
|
581
502
|
css: styles === null || styles === void 0 ? void 0 : styles.codeEditorContainer
|
|
582
503
|
})));
|
|
583
504
|
}
|
|
584
|
-
|
|
585
505
|
}, _class2.displayName = "SourceCodeEditor", _class2.componentId = 'SourceCodeEditor', _class2.propTypes = propTypes, _class2.allowedProps = allowedProps, _class2.defaultProps = {
|
|
586
506
|
language: 'jsx',
|
|
587
507
|
readOnly: false,
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
|
+
|
|
24
25
|
import PropTypes from 'prop-types';
|
|
25
26
|
import { controllable } from '@instructure/ui-prop-types';
|
|
26
27
|
const propTypes = {
|
|
@@ -50,6 +51,7 @@ const propTypes = {
|
|
|
50
51
|
elementRef: PropTypes.func,
|
|
51
52
|
containerRef: PropTypes.func
|
|
52
53
|
};
|
|
53
|
-
const allowedProps = ['label', 'language', 'readOnly', 'editable', 'lineNumbers', 'foldGutter', 'highlightActiveLineGutter', 'highlightActiveLine', 'lineWrapping', 'autofocus', 'spellcheck', 'direction', 'rtlMoveVisually', 'indentOnLoad', 'indentWithTab', 'indentUnit', 'defaultValue', 'value', 'onChange', 'onFocus', 'onBlur', 'attachment',
|
|
54
|
+
const allowedProps = ['label', 'language', 'readOnly', 'editable', 'lineNumbers', 'foldGutter', 'highlightActiveLineGutter', 'highlightActiveLine', 'lineWrapping', 'autofocus', 'spellcheck', 'direction', 'rtlMoveVisually', 'indentOnLoad', 'indentWithTab', 'indentUnit', 'defaultValue', 'value', 'onChange', 'onFocus', 'onBlur', 'attachment',
|
|
55
|
+
// 'darkTheme',
|
|
54
56
|
'elementRef', 'containerRef'];
|
|
55
57
|
export { propTypes, allowedProps };
|