@bpmn-io/feel-editor 1.12.0 → 2.0.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/dist/index.js +86 -85
- package/dist/index.js.map +1 -0
- package/package.json +38 -26
- package/dist/index.es.js +0 -725
package/dist/index.js
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
var
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const baseTheme = view.EditorView.theme({
|
|
1
|
+
import { snippetCompletion, completeFromList, autocompletion, closeBrackets } from '@codemirror/autocomplete';
|
|
2
|
+
import { defaultKeymap } from '@codemirror/commands';
|
|
3
|
+
import { syntaxHighlighting, HighlightStyle, syntaxTree, bracketMatching, indentOnInput } from '@codemirror/language';
|
|
4
|
+
import { linter as linter$1, setDiagnosticsEffect } from '@codemirror/lint';
|
|
5
|
+
import { Facet, Compartment, EditorState } from '@codemirror/state';
|
|
6
|
+
import { EditorView, tooltips, keymap, placeholder } from '@codemirror/view';
|
|
7
|
+
import { cmFeelLinter } from '@bpmn-io/feel-lint';
|
|
8
|
+
import { tags } from '@lezer/highlight';
|
|
9
|
+
import { keywordCompletions, snippets, feel } from '@bpmn-io/lang-feel';
|
|
10
|
+
import { domify } from 'min-dom';
|
|
11
|
+
import { camundaBuiltins } from '@camunda/feel-builtins';
|
|
12
|
+
|
|
13
|
+
var linter = [ linter$1(cmFeelLinter()) ];
|
|
14
|
+
|
|
15
|
+
const baseTheme = EditorView.theme({
|
|
18
16
|
'& .cm-content': {
|
|
19
17
|
padding: '0px',
|
|
20
18
|
},
|
|
@@ -53,7 +51,7 @@ const baseTheme = view.EditorView.theme({
|
|
|
53
51
|
}
|
|
54
52
|
});
|
|
55
53
|
|
|
56
|
-
const highlightTheme =
|
|
54
|
+
const highlightTheme = EditorView.baseTheme({
|
|
57
55
|
'& .variableName': {
|
|
58
56
|
color: '#10f'
|
|
59
57
|
},
|
|
@@ -75,17 +73,17 @@ const highlightTheme = view.EditorView.baseTheme({
|
|
|
75
73
|
}
|
|
76
74
|
});
|
|
77
75
|
|
|
78
|
-
const syntaxClasses =
|
|
79
|
-
|
|
80
|
-
{ tag:
|
|
81
|
-
{ tag:
|
|
82
|
-
{ tag:
|
|
83
|
-
{ tag:
|
|
84
|
-
{ tag:
|
|
85
|
-
{ tag:
|
|
86
|
-
{ tag:
|
|
87
|
-
{ tag:
|
|
88
|
-
{ tag:
|
|
76
|
+
const syntaxClasses = syntaxHighlighting(
|
|
77
|
+
HighlightStyle.define([
|
|
78
|
+
{ tag: tags.variableName, class: 'variableName' },
|
|
79
|
+
{ tag: tags.name, class: 'variableName' },
|
|
80
|
+
{ tag: tags.number, class: 'number' },
|
|
81
|
+
{ tag: tags.string, class: 'string' },
|
|
82
|
+
{ tag: tags.bool, class: 'bool' },
|
|
83
|
+
{ tag: tags.function(tags.variableName), class: 'function' },
|
|
84
|
+
{ tag: tags.function(tags.special(tags.variableName)), class: 'function' },
|
|
85
|
+
{ tag: tags.controlKeyword, class: 'control' },
|
|
86
|
+
{ tag: tags.operatorKeyword, class: 'control' }
|
|
89
87
|
])
|
|
90
88
|
);
|
|
91
89
|
|
|
@@ -147,10 +145,10 @@ function pathExpressionCompletion({ variables }) {
|
|
|
147
145
|
|
|
148
146
|
return (context) => {
|
|
149
147
|
|
|
150
|
-
const nodeBefore =
|
|
148
|
+
const nodeBefore = syntaxTree(context.state).resolve(context.pos, -1);
|
|
151
149
|
|
|
152
150
|
if (!isPathExpression(nodeBefore)) {
|
|
153
|
-
return;
|
|
151
|
+
return null;
|
|
154
152
|
}
|
|
155
153
|
|
|
156
154
|
const expression = findPathExpression(nodeBefore);
|
|
@@ -171,26 +169,27 @@ function pathExpressionCompletion({ variables }) {
|
|
|
171
169
|
// only suggest if variable type matches
|
|
172
170
|
if (
|
|
173
171
|
childVar.isList !== 'optional' &&
|
|
174
|
-
|
|
172
|
+
!!childVar.isList !== path[i].isList
|
|
175
173
|
) {
|
|
176
|
-
return;
|
|
174
|
+
return null;
|
|
177
175
|
}
|
|
178
176
|
|
|
179
177
|
options = childVar.entries;
|
|
180
178
|
}
|
|
181
179
|
|
|
182
|
-
if (!options) return;
|
|
180
|
+
if (!options) return null;
|
|
183
181
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
182
|
+
const completionOptions = options.map(option => (
|
|
183
|
+
{
|
|
184
|
+
label: option.name,
|
|
185
|
+
type: 'variable',
|
|
186
|
+
info: option.info,
|
|
187
|
+
detail: option.detail
|
|
188
|
+
}));
|
|
190
189
|
|
|
191
190
|
const result = {
|
|
192
191
|
from: from,
|
|
193
|
-
options:
|
|
192
|
+
options: completionOptions
|
|
194
193
|
};
|
|
195
194
|
|
|
196
195
|
return result;
|
|
@@ -278,7 +277,7 @@ function variableCompletion({ variables = [], builtins = [] }) {
|
|
|
278
277
|
} = context;
|
|
279
278
|
|
|
280
279
|
// in most cases, use what is typed before the cursor
|
|
281
|
-
const nodeBefore =
|
|
280
|
+
const nodeBefore = syntaxTree(state).resolve(pos, -1);
|
|
282
281
|
|
|
283
282
|
if (isEmpty(nodeBefore, pos)) {
|
|
284
283
|
return context.explicit ? {
|
|
@@ -314,8 +313,8 @@ function getVariableSuggestions(variables, builtins) {
|
|
|
314
313
|
|
|
315
314
|
/**
|
|
316
315
|
* @param {import('..').Variable} variable
|
|
317
|
-
* @param {number} boost
|
|
318
|
-
|
|
316
|
+
* @param {number} [boost]
|
|
317
|
+
*
|
|
319
318
|
* @returns {import('@codemirror/autocomplete').Completion}
|
|
320
319
|
*/
|
|
321
320
|
function createVariableSuggestion(variable, boost) {
|
|
@@ -358,7 +357,7 @@ function createFunctionVariable(variable, boost) {
|
|
|
358
357
|
)).join(', ');
|
|
359
358
|
const label = `${name}(${paramsSignature})`;
|
|
360
359
|
|
|
361
|
-
return
|
|
360
|
+
return snippetCompletion(template, {
|
|
362
361
|
label,
|
|
363
362
|
type: 'function',
|
|
364
363
|
info,
|
|
@@ -385,8 +384,8 @@ function completions({ variables = [], builtins = [] }) {
|
|
|
385
384
|
return [
|
|
386
385
|
pathExpressionCompletion({ variables }),
|
|
387
386
|
variableCompletion({ variables, builtins }),
|
|
388
|
-
|
|
389
|
-
...
|
|
387
|
+
completeFromList(snippets),
|
|
388
|
+
...keywordCompletions
|
|
390
389
|
];
|
|
391
390
|
}
|
|
392
391
|
|
|
@@ -409,7 +408,7 @@ function completions({ variables = [], builtins = [] }) {
|
|
|
409
408
|
* @return { import('@codemirror/language').LanguageSupport }
|
|
410
409
|
*/
|
|
411
410
|
function language(options) {
|
|
412
|
-
return
|
|
411
|
+
return feel(options);
|
|
413
412
|
}
|
|
414
413
|
|
|
415
414
|
/**
|
|
@@ -434,32 +433,32 @@ function createContext(variables) {
|
|
|
434
433
|
/**
|
|
435
434
|
* @type {Facet<Variable[]>}
|
|
436
435
|
*/
|
|
437
|
-
const builtinsFacet =
|
|
436
|
+
const builtinsFacet = Facet.define();
|
|
438
437
|
|
|
439
438
|
/**
|
|
440
439
|
* @type {Facet<Variable[]>}
|
|
441
440
|
*/
|
|
442
|
-
const variablesFacet =
|
|
441
|
+
const variablesFacet = Facet.define();
|
|
443
442
|
|
|
444
443
|
/**
|
|
445
444
|
* @type {Facet<Dialect>}
|
|
446
445
|
*/
|
|
447
|
-
const dialectFacet =
|
|
446
|
+
const dialectFacet = Facet.define();
|
|
448
447
|
|
|
449
448
|
/**
|
|
450
449
|
* @type {Facet<ParserDialect>}
|
|
451
450
|
*/
|
|
452
|
-
const parserDialectFacet =
|
|
451
|
+
const parserDialectFacet = Facet.define();
|
|
453
452
|
|
|
454
453
|
/**
|
|
455
454
|
* @typedef {object} Variable
|
|
456
455
|
* @property {string} name name or key of the variable
|
|
457
|
-
* @property {string} [info] short information about the variable, e.g. type
|
|
456
|
+
* @property {string | (() => HTMLElement)} [info] short information about the variable, e.g. type
|
|
458
457
|
* @property {string} [detail] longer description of the variable content
|
|
459
|
-
* @property {boolean} [isList] whether the variable is a list
|
|
460
|
-
* @property {Array<Variable>} [
|
|
458
|
+
* @property {boolean|'optional'} [isList] whether the variable is a list
|
|
459
|
+
* @property {Array<Variable>} [entries] array of child variables if the variable is a context or list
|
|
461
460
|
* @property {'function'|'variable'} [type] type of the variable
|
|
462
|
-
* @property {Array<{name: string, type
|
|
461
|
+
* @property {Array<{name: string, type?: string}>} [params] function parameters
|
|
463
462
|
*/
|
|
464
463
|
|
|
465
464
|
/**
|
|
@@ -523,9 +522,9 @@ function get(state) {
|
|
|
523
522
|
};
|
|
524
523
|
}
|
|
525
524
|
|
|
526
|
-
const domifiedBuiltins =
|
|
525
|
+
const domifiedBuiltins = camundaBuiltins.map(builtin => ({
|
|
527
526
|
...builtin,
|
|
528
|
-
info: () =>
|
|
527
|
+
info: () => domify(builtin.info),
|
|
529
528
|
}));
|
|
530
529
|
|
|
531
530
|
/**
|
|
@@ -537,8 +536,8 @@ const domifiedBuiltins = feelBuiltins.camundaBuiltins.map(builtin => ({
|
|
|
537
536
|
* @typedef { import('./language').ParserDialect } ParserDialect
|
|
538
537
|
*/
|
|
539
538
|
|
|
540
|
-
const coreConf = new
|
|
541
|
-
const placeholderConf = new
|
|
539
|
+
const coreConf = new Compartment();
|
|
540
|
+
const placeholderConf = new Compartment();
|
|
542
541
|
|
|
543
542
|
|
|
544
543
|
/**
|
|
@@ -551,12 +550,14 @@ const placeholderConf = new state.Compartment();
|
|
|
551
550
|
* @param {ParserDialect} [config.parserDialect]
|
|
552
551
|
* @param {DOMNode|String} [config.tooltipContainer]
|
|
553
552
|
* @param {Function} [config.onChange]
|
|
554
|
-
* @param {
|
|
553
|
+
* @param {(event: KeyboardEvent, view: import('@codemirror/view').EditorView) => boolean | void} [config.onKeyDown]
|
|
555
554
|
* @param {Function} [config.onLint]
|
|
556
555
|
* @param {Boolean} [config.readOnly]
|
|
557
556
|
* @param {String} [config.value]
|
|
558
557
|
* @param {Variable[]} [config.variables]
|
|
559
558
|
* @param {Variable[]} [config.builtins]
|
|
559
|
+
* @param {Object} [config.contentAttributes]
|
|
560
|
+
* @param {String} [config.placeholder]
|
|
560
561
|
*/
|
|
561
562
|
function FeelEditor({
|
|
562
563
|
extensions: editorExtensions = [],
|
|
@@ -568,23 +569,23 @@ function FeelEditor({
|
|
|
568
569
|
onChange = () => {},
|
|
569
570
|
onKeyDown = () => {},
|
|
570
571
|
onLint = () => {},
|
|
571
|
-
placeholder = '',
|
|
572
|
+
placeholder: placeholder$1 = '',
|
|
572
573
|
readOnly = false,
|
|
573
574
|
value = '',
|
|
574
575
|
builtins = domifiedBuiltins,
|
|
575
576
|
variables = []
|
|
576
577
|
}) {
|
|
577
578
|
|
|
578
|
-
const changeHandler =
|
|
579
|
+
const changeHandler = EditorView.updateListener.of((update) => {
|
|
579
580
|
if (update.docChanged) {
|
|
580
581
|
onChange(update.state.doc.toString());
|
|
581
582
|
}
|
|
582
583
|
});
|
|
583
584
|
|
|
584
|
-
const lintHandler =
|
|
585
|
+
const lintHandler = EditorView.updateListener.of((update) => {
|
|
585
586
|
const diagnosticEffects = update.transactions
|
|
586
587
|
.flatMap(t => t.effects)
|
|
587
|
-
.filter(effect => effect.is(
|
|
588
|
+
.filter(effect => effect.is(setDiagnosticsEffect));
|
|
588
589
|
|
|
589
590
|
if (!diagnosticEffects.length) {
|
|
590
591
|
return;
|
|
@@ -595,53 +596,53 @@ function FeelEditor({
|
|
|
595
596
|
onLint(messages);
|
|
596
597
|
});
|
|
597
598
|
|
|
598
|
-
const keyHandler =
|
|
599
|
+
const keyHandler = EditorView.domEventHandlers(
|
|
599
600
|
{
|
|
600
601
|
keydown: onKeyDown
|
|
601
602
|
}
|
|
602
603
|
);
|
|
603
604
|
|
|
604
605
|
if (typeof tooltipContainer === 'string') {
|
|
605
|
-
tooltipContainer = document.querySelector(tooltipContainer);
|
|
606
|
+
tooltipContainer = /** @type {HTMLElement} */ (document.querySelector(tooltipContainer));
|
|
606
607
|
}
|
|
607
608
|
|
|
608
|
-
const tooltipLayout = tooltipContainer ?
|
|
609
|
+
const tooltipLayout = tooltipContainer ? tooltips({
|
|
609
610
|
tooltipSpace: function() {
|
|
610
|
-
return tooltipContainer.getBoundingClientRect();
|
|
611
|
+
return /** @type {HTMLElement} */ (tooltipContainer).getBoundingClientRect();
|
|
611
612
|
}
|
|
612
613
|
}) : [];
|
|
613
614
|
|
|
614
615
|
const extensions = [
|
|
615
|
-
|
|
616
|
+
autocompletion(),
|
|
616
617
|
coreConf.of(configure({
|
|
617
618
|
dialect,
|
|
618
619
|
builtins,
|
|
619
620
|
variables,
|
|
620
621
|
parserDialect
|
|
621
622
|
})),
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
623
|
+
bracketMatching(),
|
|
624
|
+
indentOnInput(),
|
|
625
|
+
closeBrackets(),
|
|
626
|
+
EditorView.contentAttributes.of(contentAttributes),
|
|
626
627
|
changeHandler,
|
|
627
628
|
keyHandler,
|
|
628
|
-
|
|
629
|
-
...
|
|
629
|
+
keymap.of([
|
|
630
|
+
...defaultKeymap,
|
|
630
631
|
]),
|
|
631
632
|
linter,
|
|
632
633
|
lintHandler,
|
|
633
634
|
tooltipLayout,
|
|
634
|
-
placeholderConf.of(
|
|
635
|
+
placeholderConf.of(placeholder(placeholder$1)),
|
|
635
636
|
theme,
|
|
636
637
|
...editorExtensions
|
|
637
638
|
];
|
|
638
639
|
|
|
639
640
|
if (readOnly) {
|
|
640
|
-
extensions.push(
|
|
641
|
+
extensions.push(EditorView.editable.of(false));
|
|
641
642
|
}
|
|
642
643
|
|
|
643
|
-
this._cmEditor = new
|
|
644
|
-
state:
|
|
644
|
+
this._cmEditor = new EditorView({
|
|
645
|
+
state: EditorState.create({
|
|
645
646
|
doc: value,
|
|
646
647
|
extensions
|
|
647
648
|
}),
|
|
@@ -687,8 +688,7 @@ FeelEditor.prototype.focus = function(position) {
|
|
|
687
688
|
* Returns the current selection ranges. If no text is selected, a single
|
|
688
689
|
* range with the start and end index at the cursor position will be returned.
|
|
689
690
|
*
|
|
690
|
-
* @returns {
|
|
691
|
-
* @returns {Array} selection.ranges
|
|
691
|
+
* @returns {import('@codemirror/state').EditorSelection} selection - Selection object with ranges array
|
|
692
692
|
*/
|
|
693
693
|
FeelEditor.prototype.getSelection = function() {
|
|
694
694
|
return this._cmEditor.state.selection;
|
|
@@ -718,10 +718,11 @@ FeelEditor.prototype.setVariables = function(variables) {
|
|
|
718
718
|
*
|
|
719
719
|
* @param {string} placeholder
|
|
720
720
|
*/
|
|
721
|
-
FeelEditor.prototype.setPlaceholder = function(placeholder) {
|
|
721
|
+
FeelEditor.prototype.setPlaceholder = function(placeholder$1) {
|
|
722
722
|
this._cmEditor.dispatch({
|
|
723
|
-
effects: placeholderConf.reconfigure(
|
|
723
|
+
effects: placeholderConf.reconfigure(placeholder(placeholder$1))
|
|
724
724
|
});
|
|
725
725
|
};
|
|
726
726
|
|
|
727
|
-
|
|
727
|
+
export { FeelEditor as default };
|
|
728
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/lint/index.js","../src/theme/theme.js","../src/theme/index.js","../src/autocompletion/util.js","../src/autocompletion/pathExpression.js","../src/autocompletion/variable.js","../src/autocompletion/index.js","../src/language/index.js","../src/core/facets.js","../src/core/index.js","../src/builtins/index.js","../src/index.js"],"sourcesContent":["import { cmFeelLinter } from '@bpmn-io/feel-lint';\nimport { linter } from '@codemirror/lint';\n\nexport default [ linter(cmFeelLinter()) ];","import { HighlightStyle, syntaxHighlighting } from '@codemirror/language';\nimport { EditorView } from '@codemirror/view';\nimport { tags as t } from '@lezer/highlight';\n\nexport const baseTheme = EditorView.theme({\n '& .cm-content': {\n padding: '0px',\n },\n '& .cm-line': {\n padding: '0px',\n },\n '&.cm-editor.cm-focused': {\n outline: 'none',\n },\n '& .cm-completionInfo': {\n whiteSpace: 'pre-wrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis'\n },\n '&.cm-editor': {\n height: '100%',\n },\n\n // Don't wrap whitespace for custom HTML\n '& .cm-completionInfo > *': {\n whiteSpace: 'normal'\n },\n '& .cm-completionInfo ul': {\n margin: 0,\n paddingLeft: '15px'\n },\n '& .cm-completionInfo pre': {\n marginBottom: 0,\n whiteSpace: 'pre-wrap'\n },\n '& .cm-completionInfo p': {\n marginTop: 0,\n },\n '& .cm-completionInfo p:not(:last-of-type)': {\n marginBottom: 0,\n }\n});\n\nexport const highlightTheme = EditorView.baseTheme({\n '& .variableName': {\n color: '#10f'\n },\n '& .number': {\n color: '#164'\n },\n '& .string': {\n color: '#a11'\n },\n '& .bool': {\n color: '#219'\n },\n '& .function': {\n color: '#aa3731',\n fontWeight: 'bold'\n },\n '& .control': {\n color: '#708'\n }\n});\n\nexport const syntaxClasses = syntaxHighlighting(\n HighlightStyle.define([\n { tag: t.variableName, class: 'variableName' },\n { tag: t.name, class: 'variableName' },\n { tag: t.number, class: 'number' },\n { tag: t.string, class: 'string' },\n { tag: t.bool, class: 'bool' },\n { tag: t.function(t.variableName), class: 'function' },\n { tag: t.function(t.special(t.variableName)), class: 'function' },\n { tag: t.controlKeyword, class: 'control' },\n { tag: t.operatorKeyword, class: 'control' }\n ])\n);","import { baseTheme, highlightTheme, syntaxClasses } from './theme.js';\n\nexport default [ baseTheme, highlightTheme, syntaxClasses ];","// helpers ///////////////////////////////\n\nfunction _isEmpty(node) {\n return node && node.from === node.to;\n}\n\n/**\n * @param {any} node\n * @param {number} pos\n *\n * @return {boolean}\n */\nexport function isEmpty(node, pos) {\n\n // For the special case of empty nodes, we need to check the current node\n // as well. The previous node could be part of another token, e.g.\n // when typing functions \"abs(\".\n const nextNode = node.nextSibling;\n\n return _isEmpty(node) || (\n nextNode && nextNode.from === pos && _isEmpty(nextNode)\n );\n}\n\nexport function isVariableName(node) {\n return node && node.parent && node.parent.name === 'VariableName';\n}\n\nexport function isPathExpression(node) {\n if (!node) {\n return false;\n }\n\n if (node.name === 'PathExpression') {\n return true;\n }\n\n return isPathExpression(node.parent);\n}\n","import { syntaxTree } from '@codemirror/language';\nimport { isPathExpression } from './util.js';\n\n/**\n * @typedef { import('../core').Variable } Variable\n * @typedef { import('@codemirror/autocomplete').CompletionSource } CompletionSource\n */\n\n/**\n * @param { {\n * variables?: Variable[],\n * } } options\n *\n * @return { CompletionSource }\n */\nexport function pathExpressionCompletion({ variables }) {\n\n return (context) => {\n\n const nodeBefore = syntaxTree(context.state).resolve(context.pos, -1);\n\n if (!isPathExpression(nodeBefore)) {\n return null;\n }\n\n const expression = findPathExpression(nodeBefore);\n\n // if the cursor is directly after the `.`, variable starts at the cursor position\n const from = nodeBefore === expression ? context.pos : nodeBefore.from;\n\n const path = getPath(expression, context);\n\n let options = variables;\n for (var i = 0; i < path.length - 1; i++) {\n var childVar = options.find(val => val.name === path[i].name);\n\n if (!childVar) {\n return null;\n }\n\n // only suggest if variable type matches\n if (\n childVar.isList !== 'optional' &&\n !!childVar.isList !== path[i].isList\n ) {\n return null;\n }\n\n options = childVar.entries;\n }\n\n if (!options) return null;\n\n const completionOptions = options.map(option => (\n {\n label: option.name,\n type: 'variable',\n info: option.info,\n detail: option.detail\n }));\n\n const result = {\n from: from,\n options: completionOptions\n };\n\n return result;\n };\n}\n\n\nfunction findPathExpression(node) {\n while (node) {\n if (node.name === 'PathExpression') {\n return node;\n }\n node = node.parent;\n }\n}\n\n// parses the path expression into a list of variable names with type information\n// e.g. foo[0].bar => [ { name: 'foo', isList: true }, { name: 'bar', isList: false } ]\nfunction getPath(node, context) {\n let path = [];\n\n for (let child = node.firstChild; child; child = child.nextSibling) {\n if (child.name === 'PathExpression') {\n path.push(...getPath(child, context));\n } else if (child.name === 'FilterExpression') {\n path.push(...getFilter(child, context));\n }\n else {\n path.push({\n name: getNodeContent(child, context),\n isList: false\n });\n }\n }\n return path;\n}\n\nfunction getFilter(node, context) {\n const list = node.firstChild;\n\n if (list.name === 'PathExpression') {\n const path = getPath(list, context);\n const last = path[path.length - 1];\n last.isList = true;\n\n return path;\n }\n\n return [ {\n name: getNodeContent(list, context),\n isList: true\n } ];\n}\n\nfunction getNodeContent(node, context) {\n return context.state.sliceDoc(node.from, node.to);\n}","import { syntaxTree } from '@codemirror/language';\nimport { snippetCompletion } from '@codemirror/autocomplete';\nimport { isEmpty, isPathExpression, isVariableName } from './util.js';\n\n/**\n * @typedef { import('../core').Variable } Variable\n * @typedef { import('@codemirror/autocomplete').CompletionSource } CompletionSource\n */\n\n/**\n * @param { {\n * variables?: Variable[],\n * builtins?: Variable[]\n * } } options\n *\n * @return { CompletionSource }\n */\nexport function variableCompletion({ variables = [], builtins = [] }) {\n\n const options = getVariableSuggestions(variables, builtins);\n\n if (!options.length) {\n return (context) => null;\n }\n\n return (context) => {\n\n const {\n pos,\n state\n } = context;\n\n // in most cases, use what is typed before the cursor\n const nodeBefore = syntaxTree(state).resolve(pos, -1);\n\n if (isEmpty(nodeBefore, pos)) {\n return context.explicit ? {\n from: pos,\n options\n } : null;\n }\n\n // only auto-complete variables\n if (!isVariableName(nodeBefore) || isPathExpression(nodeBefore)) {\n return null;\n }\n\n return {\n from: nodeBefore.from,\n options\n };\n };\n}\n\n/**\n * @param { Variable[] } variables\n * @param { Variable[] } builtins\n *\n * @returns {import('@codemirror/autocomplete').Completion[]}\n */\nfunction getVariableSuggestions(variables, builtins) {\n return [].concat(\n variables.map(v => createVariableSuggestion(v)),\n builtins.map(b => createVariableSuggestion(b))\n );\n}\n\n/**\n * @param {import('..').Variable} variable\n * @param {number} [boost]\n *\n * @returns {import('@codemirror/autocomplete').Completion}\n */\nfunction createVariableSuggestion(variable, boost) {\n if (variable.type === 'function') {\n return createFunctionVariable(variable, boost);\n }\n\n return {\n label: variable.name,\n type: 'variable',\n info: variable.info,\n detail: variable.detail,\n boost\n };\n}\n\n/**\n * @param {import('..').Variable} variable\n * @param {number} boost\n *\n * @returns {import('@codemirror/autocomplete').Completion}\n */\nfunction createFunctionVariable(variable, boost) {\n const {\n name,\n info,\n detail,\n params = []\n } = variable;\n\n const paramsWithNames = params.map(({ name, type }, index) => ({\n name: name || `param ${index + 1}`,\n type\n }));\n\n const template = `${name}(${paramsWithNames.map(p => '${' + p.name + '}').join(', ')})`;\n\n const paramsSignature = paramsWithNames.map(({ name, type }) => (\n type ? `${name}: ${type}` : name\n )).join(', ');\n const label = `${name}(${paramsSignature})`;\n\n return snippetCompletion(template, {\n label,\n type: 'function',\n info,\n detail,\n boost\n });\n}\n","import { snippets, keywordCompletions } from '@bpmn-io/lang-feel';\nimport { completeFromList } from '@codemirror/autocomplete';\n\nimport { pathExpressionCompletion } from './pathExpression.js';\nimport { variableCompletion } from './variable.js';\n\n/**\n * @typedef { import('../core').Variable } Variable\n * @typedef { import('@codemirror/autocomplete').CompletionSource } CompletionSource\n */\n\n/**\n * @param { {\n * variables?: Variable[],\n * builtins?: Variable[]\n * } } options\n *\n * @return { CompletionSource[] }\n */\nexport function completions({ variables = [], builtins = [] }) {\n\n return [\n pathExpressionCompletion({ variables }),\n variableCompletion({ variables, builtins }),\n completeFromList(snippets),\n ...keywordCompletions\n ];\n}","import { feel } from '@bpmn-io/lang-feel';\n\n/**\n * @typedef { 'expression' | 'unaryTests' } Dialect\n */\n\n/**\n * @typedef { 'camunda' | undefined } ParserDialect\n */\n\n/**\n * @param { {\n * dialect?: Dialect,\n * parserDialect?: ParserDialect,\n * context?: Record<string, any>,\n * completions?: import('@codemirror/autocomplete').CompletionSource[]\n * } } options\n *\n * @return { import('@codemirror/language').LanguageSupport }\n */\nexport function language(options) {\n return feel(options);\n}\n\n/**\n * @param { import('../core').Variable[] } variables\n *\n * @return {Record<string, any>}\n */\nexport function createContext(variables) {\n return variables.slice().reverse().reduce((context, builtin) => {\n context[builtin.name] = () => {};\n\n return context;\n }, {});\n}","import { Facet } from '@codemirror/state';\n\n/**\n * @typedef { import('../language').Dialect } Dialect\n * @typedef { import('../language').ParserDialect } ParserDialect\n * @typedef { import('..').Variable } Variable\n */\n\n/**\n * @type {Facet<Variable[]>}\n */\nexport const builtinsFacet = Facet.define();\n\n/**\n * @type {Facet<Variable[]>}\n */\nexport const variablesFacet = Facet.define();\n\n/**\n * @type {Facet<Dialect>}\n */\nexport const dialectFacet = Facet.define();\n\n/**\n * @type {Facet<ParserDialect>}\n */\nexport const parserDialectFacet = Facet.define();\n\n","import { completions as feelCompletions } from '../autocompletion/index.js';\n\nimport { createContext, language } from '../language/index.js';\n\nimport {\n variablesFacet,\n builtinsFacet,\n parserDialectFacet,\n dialectFacet\n} from './facets.js';\n\n\n/**\n * @typedef {object} Variable\n * @property {string} name name or key of the variable\n * @property {string | (() => HTMLElement)} [info] short information about the variable, e.g. type\n * @property {string} [detail] longer description of the variable content\n * @property {boolean|'optional'} [isList] whether the variable is a list\n * @property {Array<Variable>} [entries] array of child variables if the variable is a context or list\n * @property {'function'|'variable'} [type] type of the variable\n * @property {Array<{name: string, type?: string}>} [params] function parameters\n */\n\n/**\n * @typedef { {\n * dialect?: import('../language').Dialect,\n * parserDialect?: import('../language').ParserDialect,\n * variables?: Variable[],\n * builtins?: Variable[]\n * } } CoreConfig\n *\n * @typedef { import('@codemirror/autocomplete').CompletionSource } CompletionSource\n * @typedef { import('@codemirror/state').Extension } Extension\n */\n\n/**\n * @param { CoreConfig & { completions?: CompletionSource[] } } config\n *\n * @return { Extension }\n */\nexport function configure({\n dialect = 'expression',\n parserDialect,\n variables = [],\n builtins = [],\n completions = feelCompletions({ builtins, variables })\n}) {\n\n const context = createContext([ ...variables, ...builtins ]);\n\n return [\n dialectFacet.of(dialect),\n builtinsFacet.of(builtins),\n variablesFacet.of(variables),\n parserDialectFacet.of(parserDialect),\n language({\n dialect,\n parserDialect,\n context,\n completions\n })\n ];\n}\n\n/**\n * @param {import('@codemirror/state').EditorState } state\n *\n * @return { CoreConfig }\n */\nexport function get(state) {\n\n const builtins = state.facet(builtinsFacet)[0];\n const variables = state.facet(variablesFacet)[0];\n const dialect = state.facet(dialectFacet)[0];\n const parserDialect = state.facet(parserDialectFacet)[0];\n\n return {\n builtins,\n variables,\n dialect,\n parserDialect\n };\n}","import { domify } from 'min-dom';\nimport { camundaBuiltins } from '@camunda/feel-builtins';\n\nexport const domifiedBuiltins = camundaBuiltins.map(builtin => ({\n ...builtin,\n info: () => domify(builtin.info),\n}));","import { autocompletion, closeBrackets } from '@codemirror/autocomplete';\nimport { defaultKeymap } from '@codemirror/commands';\nimport { bracketMatching, indentOnInput } from '@codemirror/language';\nimport { setDiagnosticsEffect } from '@codemirror/lint';\nimport { Compartment, EditorState } from '@codemirror/state';\nimport { EditorView, keymap, placeholder as placeholderExt, tooltips } from '@codemirror/view';\n\nimport linter from './lint/index.js';\nimport theme from './theme/index.js';\n\nimport * as Core from './core/index.js';\n\nimport { domifiedBuiltins } from './builtins/index.js';\n\n/**\n * @typedef { import('./core').Variable } Variable\n */\n\n/**\n * @typedef { import('./language').Dialect } Dialect\n * @typedef { import('./language').ParserDialect } ParserDialect\n */\n\nconst coreConf = new Compartment();\nconst placeholderConf = new Compartment();\n\n\n/**\n * Creates a FEEL editor in the supplied container\n *\n * @param {Object} config\n * @param {DOMNode} config.container\n * @param {Extension[]} [config.extensions]\n * @param {Dialect} [config.dialect='expression']\n * @param {ParserDialect} [config.parserDialect]\n * @param {DOMNode|String} [config.tooltipContainer]\n * @param {Function} [config.onChange]\n * @param {(event: KeyboardEvent, view: import('@codemirror/view').EditorView) => boolean | void} [config.onKeyDown]\n * @param {Function} [config.onLint]\n * @param {Boolean} [config.readOnly]\n * @param {String} [config.value]\n * @param {Variable[]} [config.variables]\n * @param {Variable[]} [config.builtins]\n * @param {Object} [config.contentAttributes]\n * @param {String} [config.placeholder]\n */\nexport default function FeelEditor({\n extensions: editorExtensions = [],\n dialect = 'expression',\n parserDialect,\n container,\n contentAttributes = {},\n tooltipContainer,\n onChange = () => {},\n onKeyDown = () => {},\n onLint = () => {},\n placeholder = '',\n readOnly = false,\n value = '',\n builtins = domifiedBuiltins,\n variables = []\n}) {\n\n const changeHandler = EditorView.updateListener.of((update) => {\n if (update.docChanged) {\n onChange(update.state.doc.toString());\n }\n });\n\n const lintHandler = EditorView.updateListener.of((update) => {\n const diagnosticEffects = update.transactions\n .flatMap(t => t.effects)\n .filter(effect => effect.is(setDiagnosticsEffect));\n\n if (!diagnosticEffects.length) {\n return;\n }\n\n const messages = diagnosticEffects.flatMap(effect => effect.value);\n\n onLint(messages);\n });\n\n const keyHandler = EditorView.domEventHandlers(\n {\n keydown: onKeyDown\n }\n );\n\n if (typeof tooltipContainer === 'string') {\n tooltipContainer = /** @type {HTMLElement} */ (document.querySelector(tooltipContainer));\n }\n\n const tooltipLayout = tooltipContainer ? tooltips({\n tooltipSpace: function() {\n return /** @type {HTMLElement} */ (tooltipContainer).getBoundingClientRect();\n }\n }) : [];\n\n const extensions = [\n autocompletion(),\n coreConf.of(Core.configure({\n dialect,\n builtins,\n variables,\n parserDialect\n })),\n bracketMatching(),\n indentOnInput(),\n closeBrackets(),\n EditorView.contentAttributes.of(contentAttributes),\n changeHandler,\n keyHandler,\n keymap.of([\n ...defaultKeymap,\n ]),\n linter,\n lintHandler,\n tooltipLayout,\n placeholderConf.of(placeholderExt(placeholder)),\n theme,\n ...editorExtensions\n ];\n\n if (readOnly) {\n extensions.push(EditorView.editable.of(false));\n }\n\n this._cmEditor = new EditorView({\n state: EditorState.create({\n doc: value,\n extensions\n }),\n parent: container\n });\n\n return this;\n}\n\n/**\n * Replaces the content of the Editor\n *\n * @param {String} value\n */\nFeelEditor.prototype.setValue = function(value) {\n this._cmEditor.dispatch({\n changes: {\n from: 0,\n to: this._cmEditor.state.doc.length,\n insert: value,\n }\n });\n};\n\n/**\n * Sets the focus in the editor.\n */\nFeelEditor.prototype.focus = function(position) {\n const cmEditor = this._cmEditor;\n\n // the Codemirror `focus` method always calls `focus` with `preventScroll`,\n // so we have to focus + scroll manually\n cmEditor.contentDOM.focus();\n cmEditor.focus();\n\n if (typeof position === 'number') {\n const end = cmEditor.state.doc.length;\n cmEditor.dispatch({ selection: { anchor: position <= end ? position : end } });\n }\n};\n\n/**\n * Returns the current selection ranges. If no text is selected, a single\n * range with the start and end index at the cursor position will be returned.\n *\n * @returns {import('@codemirror/state').EditorSelection} selection - Selection object with ranges array\n */\nFeelEditor.prototype.getSelection = function() {\n return this._cmEditor.state.selection;\n};\n\n/**\n * Set variables to be used for autocompletion.\n *\n * @param {Variable[]} variables\n */\nFeelEditor.prototype.setVariables = function(variables) {\n\n const config = Core.get(this._cmEditor.state);\n\n this._cmEditor.dispatch({\n effects: [\n coreConf.reconfigure(Core.configure({\n ...config,\n variables\n }))\n ]\n });\n};\n\n/**\n * Update placeholder text.\n *\n * @param {string} placeholder\n */\nFeelEditor.prototype.setPlaceholder = function(placeholder) {\n this._cmEditor.dispatch({\n effects: placeholderConf.reconfigure(placeholderExt(placeholder))\n });\n};"],"names":["linter","t","completions","feelCompletions","placeholder","Core.configure","placeholderExt","Core.get"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bpmn-io/feel-editor",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Editor for FEEL expressions.",
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
"
|
|
9
|
-
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"source": "./src/index.js",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./dist/index.js",
|
|
10
|
+
"./package.json": "./package.json"
|
|
11
|
+
},
|
|
10
12
|
"scripts": {
|
|
11
|
-
"all": "run-s lint test build",
|
|
12
|
-
"test": "karma start",
|
|
13
|
+
"all": "run-s lint check-types test build",
|
|
14
|
+
"test": "karma start karma.conf.cjs",
|
|
13
15
|
"build": "rollup -c --bundleConfigAsCjs",
|
|
14
16
|
"build:watch": "npm run build -- -w",
|
|
15
17
|
"lint": "eslint .",
|
|
18
|
+
"check-types": "run-s check-types:*",
|
|
19
|
+
"check-types:src": "tsc",
|
|
20
|
+
"check-types:test": "tsc -p test",
|
|
16
21
|
"start": "cross-env SINGLE_START=true npm run dev",
|
|
17
22
|
"start:camunda": "cross-env SINGLE_START=camunda npm run dev",
|
|
18
23
|
"dev": "npm test -- --auto-watch --no-single-run",
|
|
@@ -26,8 +31,11 @@
|
|
|
26
31
|
"access": "public"
|
|
27
32
|
},
|
|
28
33
|
"engines": {
|
|
29
|
-
"node": ">=
|
|
34
|
+
"node": ">= 20"
|
|
30
35
|
},
|
|
36
|
+
"files": [
|
|
37
|
+
"dist"
|
|
38
|
+
],
|
|
31
39
|
"keywords": [
|
|
32
40
|
"bpmn-io",
|
|
33
41
|
"feel",
|
|
@@ -45,16 +53,16 @@
|
|
|
45
53
|
],
|
|
46
54
|
"license": "MIT",
|
|
47
55
|
"dependencies": {
|
|
48
|
-
"@bpmn-io/feel-lint": "^
|
|
56
|
+
"@bpmn-io/feel-lint": "^3.0.0",
|
|
57
|
+
"@bpmn-io/lang-feel": "^3.0.0",
|
|
49
58
|
"@camunda/feel-builtins": "^0.2.0",
|
|
50
|
-
"@codemirror/autocomplete": "^6.
|
|
51
|
-
"@codemirror/commands": "^6.
|
|
52
|
-
"@codemirror/language": "^6.
|
|
53
|
-
"@codemirror/lint": "^6.
|
|
54
|
-
"@codemirror/state": "^6.5.
|
|
55
|
-
"@codemirror/view": "^6.
|
|
56
|
-
"@lezer/highlight": "^1.2.
|
|
57
|
-
"@bpmn-io/lang-feel": "^2.4.0",
|
|
59
|
+
"@codemirror/autocomplete": "^6.20.0",
|
|
60
|
+
"@codemirror/commands": "^6.10.0",
|
|
61
|
+
"@codemirror/language": "^6.11.3",
|
|
62
|
+
"@codemirror/lint": "^6.9.2",
|
|
63
|
+
"@codemirror/state": "^6.5.2",
|
|
64
|
+
"@codemirror/view": "^6.38.8",
|
|
65
|
+
"@lezer/highlight": "^1.2.3",
|
|
58
66
|
"min-dom": "^4.2.1"
|
|
59
67
|
},
|
|
60
68
|
"devDependencies": {
|
|
@@ -63,12 +71,16 @@
|
|
|
63
71
|
"@rollup/plugin-json": "^6.1.0",
|
|
64
72
|
"@testing-library/dom": "^10.4.0",
|
|
65
73
|
"@testing-library/user-event": "^14.6.1",
|
|
74
|
+
"@types/chai": "^5.2.3",
|
|
75
|
+
"@types/mocha": "^10.0.10",
|
|
76
|
+
"@types/sinon": "^21.0.0",
|
|
77
|
+
"@types/sinon-chai": "^4.0.0",
|
|
66
78
|
"babel-loader": "^9.2.1",
|
|
67
79
|
"babel-plugin-istanbul": "^7.0.0",
|
|
68
|
-
"chai": "^
|
|
80
|
+
"chai": "^6.2.1",
|
|
69
81
|
"cross-env": "^7.0.3",
|
|
70
|
-
"eslint": "^
|
|
71
|
-
"eslint-plugin-bpmn-io": "^
|
|
82
|
+
"eslint": "^9.39.1",
|
|
83
|
+
"eslint-plugin-bpmn-io": "^2.2.0",
|
|
72
84
|
"karma": "^6.4.4",
|
|
73
85
|
"karma-chrome-launcher": "^3.2.0",
|
|
74
86
|
"karma-coverage": "^2.2.1",
|
|
@@ -76,15 +88,15 @@
|
|
|
76
88
|
"karma-env-preprocessor": "^0.1.1",
|
|
77
89
|
"karma-firefox-launcher": "^2.1.3",
|
|
78
90
|
"karma-mocha": "^2.0.1",
|
|
79
|
-
"karma-sinon-chai": "^2.0.2",
|
|
80
91
|
"karma-webpack": "^5.0.1",
|
|
81
|
-
"mocha": "^
|
|
92
|
+
"mocha": "^11.7.5",
|
|
82
93
|
"mocha-test-container-support": "^0.2.0",
|
|
83
94
|
"npm-run-all": "^4.1.5",
|
|
84
|
-
"puppeteer": "^
|
|
95
|
+
"puppeteer": "^24.32.1",
|
|
85
96
|
"rollup": "^4.31.0",
|
|
86
|
-
"sinon": "^
|
|
87
|
-
"sinon-chai": "^
|
|
97
|
+
"sinon": "^21.0.0",
|
|
98
|
+
"sinon-chai": "^4.0.1",
|
|
99
|
+
"typescript": "^5.9.3",
|
|
88
100
|
"webpack": "^5.97.1"
|
|
89
101
|
}
|
|
90
102
|
}
|
package/dist/index.es.js
DELETED
|
@@ -1,725 +0,0 @@
|
|
|
1
|
-
import { snippetCompletion, autocompletion, closeBrackets } from '@codemirror/autocomplete';
|
|
2
|
-
import { defaultKeymap } from '@codemirror/commands';
|
|
3
|
-
import { syntaxHighlighting, HighlightStyle, syntaxTree, bracketMatching, indentOnInput } from '@codemirror/language';
|
|
4
|
-
import { linter as linter$1, setDiagnosticsEffect } from '@codemirror/lint';
|
|
5
|
-
import { Facet, Compartment, EditorState } from '@codemirror/state';
|
|
6
|
-
import { EditorView, tooltips, keymap, placeholder } from '@codemirror/view';
|
|
7
|
-
import { cmFeelLinter } from '@bpmn-io/feel-lint';
|
|
8
|
-
import { tags } from '@lezer/highlight';
|
|
9
|
-
import { snippets, keywordCompletions, feel } from '@bpmn-io/lang-feel';
|
|
10
|
-
import { domify } from 'min-dom';
|
|
11
|
-
import { camundaBuiltins } from '@camunda/feel-builtins';
|
|
12
|
-
|
|
13
|
-
var linter = [ linter$1(cmFeelLinter()) ];
|
|
14
|
-
|
|
15
|
-
const baseTheme = EditorView.theme({
|
|
16
|
-
'& .cm-content': {
|
|
17
|
-
padding: '0px',
|
|
18
|
-
},
|
|
19
|
-
'& .cm-line': {
|
|
20
|
-
padding: '0px',
|
|
21
|
-
},
|
|
22
|
-
'&.cm-editor.cm-focused': {
|
|
23
|
-
outline: 'none',
|
|
24
|
-
},
|
|
25
|
-
'& .cm-completionInfo': {
|
|
26
|
-
whiteSpace: 'pre-wrap',
|
|
27
|
-
overflow: 'hidden',
|
|
28
|
-
textOverflow: 'ellipsis'
|
|
29
|
-
},
|
|
30
|
-
'&.cm-editor': {
|
|
31
|
-
height: '100%',
|
|
32
|
-
},
|
|
33
|
-
|
|
34
|
-
// Don't wrap whitespace for custom HTML
|
|
35
|
-
'& .cm-completionInfo > *': {
|
|
36
|
-
whiteSpace: 'normal'
|
|
37
|
-
},
|
|
38
|
-
'& .cm-completionInfo ul': {
|
|
39
|
-
margin: 0,
|
|
40
|
-
paddingLeft: '15px'
|
|
41
|
-
},
|
|
42
|
-
'& .cm-completionInfo pre': {
|
|
43
|
-
marginBottom: 0,
|
|
44
|
-
whiteSpace: 'pre-wrap'
|
|
45
|
-
},
|
|
46
|
-
'& .cm-completionInfo p': {
|
|
47
|
-
marginTop: 0,
|
|
48
|
-
},
|
|
49
|
-
'& .cm-completionInfo p:not(:last-of-type)': {
|
|
50
|
-
marginBottom: 0,
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
const highlightTheme = EditorView.baseTheme({
|
|
55
|
-
'& .variableName': {
|
|
56
|
-
color: '#10f'
|
|
57
|
-
},
|
|
58
|
-
'& .number': {
|
|
59
|
-
color: '#164'
|
|
60
|
-
},
|
|
61
|
-
'& .string': {
|
|
62
|
-
color: '#a11'
|
|
63
|
-
},
|
|
64
|
-
'& .bool': {
|
|
65
|
-
color: '#219'
|
|
66
|
-
},
|
|
67
|
-
'& .function': {
|
|
68
|
-
color: '#aa3731',
|
|
69
|
-
fontWeight: 'bold'
|
|
70
|
-
},
|
|
71
|
-
'& .control': {
|
|
72
|
-
color: '#708'
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
const syntaxClasses = syntaxHighlighting(
|
|
77
|
-
HighlightStyle.define([
|
|
78
|
-
{ tag: tags.variableName, class: 'variableName' },
|
|
79
|
-
{ tag: tags.name, class: 'variableName' },
|
|
80
|
-
{ tag: tags.number, class: 'number' },
|
|
81
|
-
{ tag: tags.string, class: 'string' },
|
|
82
|
-
{ tag: tags.bool, class: 'bool' },
|
|
83
|
-
{ tag: tags.function(tags.variableName), class: 'function' },
|
|
84
|
-
{ tag: tags.function(tags.special(tags.variableName)), class: 'function' },
|
|
85
|
-
{ tag: tags.controlKeyword, class: 'control' },
|
|
86
|
-
{ tag: tags.operatorKeyword, class: 'control' }
|
|
87
|
-
])
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
var theme = [ baseTheme, highlightTheme, syntaxClasses ];
|
|
91
|
-
|
|
92
|
-
// helpers ///////////////////////////////
|
|
93
|
-
|
|
94
|
-
function _isEmpty(node) {
|
|
95
|
-
return node && node.from === node.to;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* @param {any} node
|
|
100
|
-
* @param {number} pos
|
|
101
|
-
*
|
|
102
|
-
* @return {boolean}
|
|
103
|
-
*/
|
|
104
|
-
function isEmpty(node, pos) {
|
|
105
|
-
|
|
106
|
-
// For the special case of empty nodes, we need to check the current node
|
|
107
|
-
// as well. The previous node could be part of another token, e.g.
|
|
108
|
-
// when typing functions "abs(".
|
|
109
|
-
const nextNode = node.nextSibling;
|
|
110
|
-
|
|
111
|
-
return _isEmpty(node) || (
|
|
112
|
-
nextNode && nextNode.from === pos && _isEmpty(nextNode)
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function isVariableName(node) {
|
|
117
|
-
return node && node.parent && node.parent.name === 'VariableName';
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
function isPathExpression(node) {
|
|
121
|
-
if (!node) {
|
|
122
|
-
return false;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
if (node.name === 'PathExpression') {
|
|
126
|
-
return true;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
return isPathExpression(node.parent);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* @typedef { import('../core').Variable } Variable
|
|
134
|
-
* @typedef { import('@codemirror/autocomplete').CompletionSource } CompletionSource
|
|
135
|
-
*/
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* @param { {
|
|
139
|
-
* variables?: Variable[],
|
|
140
|
-
* } } options
|
|
141
|
-
*
|
|
142
|
-
* @return { CompletionSource }
|
|
143
|
-
*/
|
|
144
|
-
function pathExpressionCompletion({ variables }) {
|
|
145
|
-
|
|
146
|
-
return (context) => {
|
|
147
|
-
|
|
148
|
-
const nodeBefore = syntaxTree(context.state).resolve(context.pos, -1);
|
|
149
|
-
|
|
150
|
-
if (!isPathExpression(nodeBefore)) {
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const expression = findPathExpression(nodeBefore);
|
|
155
|
-
|
|
156
|
-
// if the cursor is directly after the `.`, variable starts at the cursor position
|
|
157
|
-
const from = nodeBefore === expression ? context.pos : nodeBefore.from;
|
|
158
|
-
|
|
159
|
-
const path = getPath(expression, context);
|
|
160
|
-
|
|
161
|
-
let options = variables;
|
|
162
|
-
for (var i = 0; i < path.length - 1; i++) {
|
|
163
|
-
var childVar = options.find(val => val.name === path[i].name);
|
|
164
|
-
|
|
165
|
-
if (!childVar) {
|
|
166
|
-
return null;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// only suggest if variable type matches
|
|
170
|
-
if (
|
|
171
|
-
childVar.isList !== 'optional' &&
|
|
172
|
-
!!childVar.isList !== path[i].isList
|
|
173
|
-
) {
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
options = childVar.entries;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
if (!options) return;
|
|
181
|
-
|
|
182
|
-
options = options.map(v => ({
|
|
183
|
-
label: v.name,
|
|
184
|
-
type: 'variable',
|
|
185
|
-
info: v.info,
|
|
186
|
-
detail: v.detail
|
|
187
|
-
}));
|
|
188
|
-
|
|
189
|
-
const result = {
|
|
190
|
-
from: from,
|
|
191
|
-
options: options
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
return result;
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
function findPathExpression(node) {
|
|
200
|
-
while (node) {
|
|
201
|
-
if (node.name === 'PathExpression') {
|
|
202
|
-
return node;
|
|
203
|
-
}
|
|
204
|
-
node = node.parent;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// parses the path expression into a list of variable names with type information
|
|
209
|
-
// e.g. foo[0].bar => [ { name: 'foo', isList: true }, { name: 'bar', isList: false } ]
|
|
210
|
-
function getPath(node, context) {
|
|
211
|
-
let path = [];
|
|
212
|
-
|
|
213
|
-
for (let child = node.firstChild; child; child = child.nextSibling) {
|
|
214
|
-
if (child.name === 'PathExpression') {
|
|
215
|
-
path.push(...getPath(child, context));
|
|
216
|
-
} else if (child.name === 'FilterExpression') {
|
|
217
|
-
path.push(...getFilter(child, context));
|
|
218
|
-
}
|
|
219
|
-
else {
|
|
220
|
-
path.push({
|
|
221
|
-
name: getNodeContent(child, context),
|
|
222
|
-
isList: false
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
return path;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
function getFilter(node, context) {
|
|
230
|
-
const list = node.firstChild;
|
|
231
|
-
|
|
232
|
-
if (list.name === 'PathExpression') {
|
|
233
|
-
const path = getPath(list, context);
|
|
234
|
-
const last = path[path.length - 1];
|
|
235
|
-
last.isList = true;
|
|
236
|
-
|
|
237
|
-
return path;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
return [ {
|
|
241
|
-
name: getNodeContent(list, context),
|
|
242
|
-
isList: true
|
|
243
|
-
} ];
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
function getNodeContent(node, context) {
|
|
247
|
-
return context.state.sliceDoc(node.from, node.to);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* @typedef { import('../core').Variable } Variable
|
|
252
|
-
* @typedef { import('@codemirror/autocomplete').CompletionSource } CompletionSource
|
|
253
|
-
*/
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* @param { {
|
|
257
|
-
* variables?: Variable[],
|
|
258
|
-
* builtins?: Variable[]
|
|
259
|
-
* } } options
|
|
260
|
-
*
|
|
261
|
-
* @return { CompletionSource }
|
|
262
|
-
*/
|
|
263
|
-
function variableCompletion({ variables = [], builtins = [] }) {
|
|
264
|
-
|
|
265
|
-
const options = getVariableSuggestions(variables, builtins);
|
|
266
|
-
|
|
267
|
-
if (!options.length) {
|
|
268
|
-
return (context) => null;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
return (context) => {
|
|
272
|
-
|
|
273
|
-
const {
|
|
274
|
-
pos,
|
|
275
|
-
state
|
|
276
|
-
} = context;
|
|
277
|
-
|
|
278
|
-
// in most cases, use what is typed before the cursor
|
|
279
|
-
const nodeBefore = syntaxTree(state).resolve(pos, -1);
|
|
280
|
-
|
|
281
|
-
if (isEmpty(nodeBefore, pos)) {
|
|
282
|
-
return context.explicit ? {
|
|
283
|
-
from: pos,
|
|
284
|
-
options
|
|
285
|
-
} : null;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
// only auto-complete variables
|
|
289
|
-
if (!isVariableName(nodeBefore) || isPathExpression(nodeBefore)) {
|
|
290
|
-
return null;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
return {
|
|
294
|
-
from: nodeBefore.from,
|
|
295
|
-
options
|
|
296
|
-
};
|
|
297
|
-
};
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
/**
|
|
301
|
-
* @param { Variable[] } variables
|
|
302
|
-
* @param { Variable[] } builtins
|
|
303
|
-
*
|
|
304
|
-
* @returns {import('@codemirror/autocomplete').Completion[]}
|
|
305
|
-
*/
|
|
306
|
-
function getVariableSuggestions(variables, builtins) {
|
|
307
|
-
return [].concat(
|
|
308
|
-
variables.map(v => createVariableSuggestion(v)),
|
|
309
|
-
builtins.map(b => createVariableSuggestion(b))
|
|
310
|
-
);
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* @param {import('..').Variable} variable
|
|
315
|
-
* @param {number} boost
|
|
316
|
-
|
|
317
|
-
* @returns {import('@codemirror/autocomplete').Completion}
|
|
318
|
-
*/
|
|
319
|
-
function createVariableSuggestion(variable, boost) {
|
|
320
|
-
if (variable.type === 'function') {
|
|
321
|
-
return createFunctionVariable(variable, boost);
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
return {
|
|
325
|
-
label: variable.name,
|
|
326
|
-
type: 'variable',
|
|
327
|
-
info: variable.info,
|
|
328
|
-
detail: variable.detail,
|
|
329
|
-
boost
|
|
330
|
-
};
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
/**
|
|
334
|
-
* @param {import('..').Variable} variable
|
|
335
|
-
* @param {number} boost
|
|
336
|
-
*
|
|
337
|
-
* @returns {import('@codemirror/autocomplete').Completion}
|
|
338
|
-
*/
|
|
339
|
-
function createFunctionVariable(variable, boost) {
|
|
340
|
-
const {
|
|
341
|
-
name,
|
|
342
|
-
info,
|
|
343
|
-
detail,
|
|
344
|
-
params = []
|
|
345
|
-
} = variable;
|
|
346
|
-
|
|
347
|
-
const paramsWithNames = params.map(({ name, type }, index) => ({
|
|
348
|
-
name: name || `param ${index + 1}`,
|
|
349
|
-
type
|
|
350
|
-
}));
|
|
351
|
-
|
|
352
|
-
const template = `${name}(${paramsWithNames.map(p => '${' + p.name + '}').join(', ')})`;
|
|
353
|
-
|
|
354
|
-
const paramsSignature = paramsWithNames.map(({ name, type }) => (
|
|
355
|
-
type ? `${name}: ${type}` : name
|
|
356
|
-
)).join(', ');
|
|
357
|
-
const label = `${name}(${paramsSignature})`;
|
|
358
|
-
|
|
359
|
-
return snippetCompletion(template, {
|
|
360
|
-
label,
|
|
361
|
-
type: 'function',
|
|
362
|
-
info,
|
|
363
|
-
detail,
|
|
364
|
-
boost
|
|
365
|
-
});
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
/**
|
|
369
|
-
* @typedef { import('../core').Variable } Variable
|
|
370
|
-
* @typedef { import('@codemirror/autocomplete').CompletionSource } CompletionSource
|
|
371
|
-
*/
|
|
372
|
-
|
|
373
|
-
/**
|
|
374
|
-
* @param { {
|
|
375
|
-
* variables?: Variable[],
|
|
376
|
-
* builtins?: Variable[]
|
|
377
|
-
* } } options
|
|
378
|
-
*
|
|
379
|
-
* @return { CompletionSource[] }
|
|
380
|
-
*/
|
|
381
|
-
function completions({ variables = [], builtins = [] }) {
|
|
382
|
-
|
|
383
|
-
return [
|
|
384
|
-
pathExpressionCompletion({ variables }),
|
|
385
|
-
variableCompletion({ variables, builtins }),
|
|
386
|
-
snippets,
|
|
387
|
-
...keywordCompletions
|
|
388
|
-
];
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
/**
|
|
392
|
-
* @typedef { 'expression' | 'unaryTests' } Dialect
|
|
393
|
-
*/
|
|
394
|
-
|
|
395
|
-
/**
|
|
396
|
-
* @typedef { 'camunda' | undefined } ParserDialect
|
|
397
|
-
*/
|
|
398
|
-
|
|
399
|
-
/**
|
|
400
|
-
* @param { {
|
|
401
|
-
* dialect?: Dialect,
|
|
402
|
-
* parserDialect?: ParserDialect,
|
|
403
|
-
* context?: Record<string, any>,
|
|
404
|
-
* completions?: import('@codemirror/autocomplete').CompletionSource[]
|
|
405
|
-
* } } options
|
|
406
|
-
*
|
|
407
|
-
* @return { import('@codemirror/language').LanguageSupport }
|
|
408
|
-
*/
|
|
409
|
-
function language(options) {
|
|
410
|
-
return feel(options);
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
/**
|
|
414
|
-
* @param { import('../core').Variable[] } variables
|
|
415
|
-
*
|
|
416
|
-
* @return {Record<string, any>}
|
|
417
|
-
*/
|
|
418
|
-
function createContext(variables) {
|
|
419
|
-
return variables.slice().reverse().reduce((context, builtin) => {
|
|
420
|
-
context[builtin.name] = () => {};
|
|
421
|
-
|
|
422
|
-
return context;
|
|
423
|
-
}, {});
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
/**
|
|
427
|
-
* @typedef { import('../language').Dialect } Dialect
|
|
428
|
-
* @typedef { import('../language').ParserDialect } ParserDialect
|
|
429
|
-
* @typedef { import('..').Variable } Variable
|
|
430
|
-
*/
|
|
431
|
-
|
|
432
|
-
/**
|
|
433
|
-
* @type {Facet<Variable[]>}
|
|
434
|
-
*/
|
|
435
|
-
const builtinsFacet = Facet.define();
|
|
436
|
-
|
|
437
|
-
/**
|
|
438
|
-
* @type {Facet<Variable[]>}
|
|
439
|
-
*/
|
|
440
|
-
const variablesFacet = Facet.define();
|
|
441
|
-
|
|
442
|
-
/**
|
|
443
|
-
* @type {Facet<Dialect>}
|
|
444
|
-
*/
|
|
445
|
-
const dialectFacet = Facet.define();
|
|
446
|
-
|
|
447
|
-
/**
|
|
448
|
-
* @type {Facet<ParserDialect>}
|
|
449
|
-
*/
|
|
450
|
-
const parserDialectFacet = Facet.define();
|
|
451
|
-
|
|
452
|
-
/**
|
|
453
|
-
* @typedef {object} Variable
|
|
454
|
-
* @property {string} name name or key of the variable
|
|
455
|
-
* @property {string} [info] short information about the variable, e.g. type
|
|
456
|
-
* @property {string} [detail] longer description of the variable content
|
|
457
|
-
* @property {boolean} [isList] whether the variable is a list
|
|
458
|
-
* @property {Array<Variable>} [schema] array of child variables if the variable is a context or list
|
|
459
|
-
* @property {'function'|'variable'} [type] type of the variable
|
|
460
|
-
* @property {Array<{name: string, type: string}>} [params] function parameters
|
|
461
|
-
*/
|
|
462
|
-
|
|
463
|
-
/**
|
|
464
|
-
* @typedef { {
|
|
465
|
-
* dialect?: import('../language').Dialect,
|
|
466
|
-
* parserDialect?: import('../language').ParserDialect,
|
|
467
|
-
* variables?: Variable[],
|
|
468
|
-
* builtins?: Variable[]
|
|
469
|
-
* } } CoreConfig
|
|
470
|
-
*
|
|
471
|
-
* @typedef { import('@codemirror/autocomplete').CompletionSource } CompletionSource
|
|
472
|
-
* @typedef { import('@codemirror/state').Extension } Extension
|
|
473
|
-
*/
|
|
474
|
-
|
|
475
|
-
/**
|
|
476
|
-
* @param { CoreConfig & { completions?: CompletionSource[] } } config
|
|
477
|
-
*
|
|
478
|
-
* @return { Extension }
|
|
479
|
-
*/
|
|
480
|
-
function configure({
|
|
481
|
-
dialect = 'expression',
|
|
482
|
-
parserDialect,
|
|
483
|
-
variables = [],
|
|
484
|
-
builtins = [],
|
|
485
|
-
completions: completions$1 = completions({ builtins, variables })
|
|
486
|
-
}) {
|
|
487
|
-
|
|
488
|
-
const context = createContext([ ...variables, ...builtins ]);
|
|
489
|
-
|
|
490
|
-
return [
|
|
491
|
-
dialectFacet.of(dialect),
|
|
492
|
-
builtinsFacet.of(builtins),
|
|
493
|
-
variablesFacet.of(variables),
|
|
494
|
-
parserDialectFacet.of(parserDialect),
|
|
495
|
-
language({
|
|
496
|
-
dialect,
|
|
497
|
-
parserDialect,
|
|
498
|
-
context,
|
|
499
|
-
completions: completions$1
|
|
500
|
-
})
|
|
501
|
-
];
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
/**
|
|
505
|
-
* @param {import('@codemirror/state').EditorState } state
|
|
506
|
-
*
|
|
507
|
-
* @return { CoreConfig }
|
|
508
|
-
*/
|
|
509
|
-
function get(state) {
|
|
510
|
-
|
|
511
|
-
const builtins = state.facet(builtinsFacet)[0];
|
|
512
|
-
const variables = state.facet(variablesFacet)[0];
|
|
513
|
-
const dialect = state.facet(dialectFacet)[0];
|
|
514
|
-
const parserDialect = state.facet(parserDialectFacet)[0];
|
|
515
|
-
|
|
516
|
-
return {
|
|
517
|
-
builtins,
|
|
518
|
-
variables,
|
|
519
|
-
dialect,
|
|
520
|
-
parserDialect
|
|
521
|
-
};
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
const domifiedBuiltins = camundaBuiltins.map(builtin => ({
|
|
525
|
-
...builtin,
|
|
526
|
-
info: () => domify(builtin.info),
|
|
527
|
-
}));
|
|
528
|
-
|
|
529
|
-
/**
|
|
530
|
-
* @typedef { import('./core').Variable } Variable
|
|
531
|
-
*/
|
|
532
|
-
|
|
533
|
-
/**
|
|
534
|
-
* @typedef { import('./language').Dialect } Dialect
|
|
535
|
-
* @typedef { import('./language').ParserDialect } ParserDialect
|
|
536
|
-
*/
|
|
537
|
-
|
|
538
|
-
const coreConf = new Compartment();
|
|
539
|
-
const placeholderConf = new Compartment();
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
/**
|
|
543
|
-
* Creates a FEEL editor in the supplied container
|
|
544
|
-
*
|
|
545
|
-
* @param {Object} config
|
|
546
|
-
* @param {DOMNode} config.container
|
|
547
|
-
* @param {Extension[]} [config.extensions]
|
|
548
|
-
* @param {Dialect} [config.dialect='expression']
|
|
549
|
-
* @param {ParserDialect} [config.parserDialect]
|
|
550
|
-
* @param {DOMNode|String} [config.tooltipContainer]
|
|
551
|
-
* @param {Function} [config.onChange]
|
|
552
|
-
* @param {Function} [config.onKeyDown]
|
|
553
|
-
* @param {Function} [config.onLint]
|
|
554
|
-
* @param {Boolean} [config.readOnly]
|
|
555
|
-
* @param {String} [config.value]
|
|
556
|
-
* @param {Variable[]} [config.variables]
|
|
557
|
-
* @param {Variable[]} [config.builtins]
|
|
558
|
-
*/
|
|
559
|
-
function FeelEditor({
|
|
560
|
-
extensions: editorExtensions = [],
|
|
561
|
-
dialect = 'expression',
|
|
562
|
-
parserDialect,
|
|
563
|
-
container,
|
|
564
|
-
contentAttributes = {},
|
|
565
|
-
tooltipContainer,
|
|
566
|
-
onChange = () => {},
|
|
567
|
-
onKeyDown = () => {},
|
|
568
|
-
onLint = () => {},
|
|
569
|
-
placeholder: placeholder$1 = '',
|
|
570
|
-
readOnly = false,
|
|
571
|
-
value = '',
|
|
572
|
-
builtins = domifiedBuiltins,
|
|
573
|
-
variables = []
|
|
574
|
-
}) {
|
|
575
|
-
|
|
576
|
-
const changeHandler = EditorView.updateListener.of((update) => {
|
|
577
|
-
if (update.docChanged) {
|
|
578
|
-
onChange(update.state.doc.toString());
|
|
579
|
-
}
|
|
580
|
-
});
|
|
581
|
-
|
|
582
|
-
const lintHandler = EditorView.updateListener.of((update) => {
|
|
583
|
-
const diagnosticEffects = update.transactions
|
|
584
|
-
.flatMap(t => t.effects)
|
|
585
|
-
.filter(effect => effect.is(setDiagnosticsEffect));
|
|
586
|
-
|
|
587
|
-
if (!diagnosticEffects.length) {
|
|
588
|
-
return;
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
const messages = diagnosticEffects.flatMap(effect => effect.value);
|
|
592
|
-
|
|
593
|
-
onLint(messages);
|
|
594
|
-
});
|
|
595
|
-
|
|
596
|
-
const keyHandler = EditorView.domEventHandlers(
|
|
597
|
-
{
|
|
598
|
-
keydown: onKeyDown
|
|
599
|
-
}
|
|
600
|
-
);
|
|
601
|
-
|
|
602
|
-
if (typeof tooltipContainer === 'string') {
|
|
603
|
-
tooltipContainer = document.querySelector(tooltipContainer);
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
const tooltipLayout = tooltipContainer ? tooltips({
|
|
607
|
-
tooltipSpace: function() {
|
|
608
|
-
return tooltipContainer.getBoundingClientRect();
|
|
609
|
-
}
|
|
610
|
-
}) : [];
|
|
611
|
-
|
|
612
|
-
const extensions = [
|
|
613
|
-
autocompletion(),
|
|
614
|
-
coreConf.of(configure({
|
|
615
|
-
dialect,
|
|
616
|
-
builtins,
|
|
617
|
-
variables,
|
|
618
|
-
parserDialect
|
|
619
|
-
})),
|
|
620
|
-
bracketMatching(),
|
|
621
|
-
indentOnInput(),
|
|
622
|
-
closeBrackets(),
|
|
623
|
-
EditorView.contentAttributes.of(contentAttributes),
|
|
624
|
-
changeHandler,
|
|
625
|
-
keyHandler,
|
|
626
|
-
keymap.of([
|
|
627
|
-
...defaultKeymap,
|
|
628
|
-
]),
|
|
629
|
-
linter,
|
|
630
|
-
lintHandler,
|
|
631
|
-
tooltipLayout,
|
|
632
|
-
placeholderConf.of(placeholder(placeholder$1)),
|
|
633
|
-
theme,
|
|
634
|
-
...editorExtensions
|
|
635
|
-
];
|
|
636
|
-
|
|
637
|
-
if (readOnly) {
|
|
638
|
-
extensions.push(EditorView.editable.of(false));
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
this._cmEditor = new EditorView({
|
|
642
|
-
state: EditorState.create({
|
|
643
|
-
doc: value,
|
|
644
|
-
extensions
|
|
645
|
-
}),
|
|
646
|
-
parent: container
|
|
647
|
-
});
|
|
648
|
-
|
|
649
|
-
return this;
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
/**
|
|
653
|
-
* Replaces the content of the Editor
|
|
654
|
-
*
|
|
655
|
-
* @param {String} value
|
|
656
|
-
*/
|
|
657
|
-
FeelEditor.prototype.setValue = function(value) {
|
|
658
|
-
this._cmEditor.dispatch({
|
|
659
|
-
changes: {
|
|
660
|
-
from: 0,
|
|
661
|
-
to: this._cmEditor.state.doc.length,
|
|
662
|
-
insert: value,
|
|
663
|
-
}
|
|
664
|
-
});
|
|
665
|
-
};
|
|
666
|
-
|
|
667
|
-
/**
|
|
668
|
-
* Sets the focus in the editor.
|
|
669
|
-
*/
|
|
670
|
-
FeelEditor.prototype.focus = function(position) {
|
|
671
|
-
const cmEditor = this._cmEditor;
|
|
672
|
-
|
|
673
|
-
// the Codemirror `focus` method always calls `focus` with `preventScroll`,
|
|
674
|
-
// so we have to focus + scroll manually
|
|
675
|
-
cmEditor.contentDOM.focus();
|
|
676
|
-
cmEditor.focus();
|
|
677
|
-
|
|
678
|
-
if (typeof position === 'number') {
|
|
679
|
-
const end = cmEditor.state.doc.length;
|
|
680
|
-
cmEditor.dispatch({ selection: { anchor: position <= end ? position : end } });
|
|
681
|
-
}
|
|
682
|
-
};
|
|
683
|
-
|
|
684
|
-
/**
|
|
685
|
-
* Returns the current selection ranges. If no text is selected, a single
|
|
686
|
-
* range with the start and end index at the cursor position will be returned.
|
|
687
|
-
*
|
|
688
|
-
* @returns {Object} selection
|
|
689
|
-
* @returns {Array} selection.ranges
|
|
690
|
-
*/
|
|
691
|
-
FeelEditor.prototype.getSelection = function() {
|
|
692
|
-
return this._cmEditor.state.selection;
|
|
693
|
-
};
|
|
694
|
-
|
|
695
|
-
/**
|
|
696
|
-
* Set variables to be used for autocompletion.
|
|
697
|
-
*
|
|
698
|
-
* @param {Variable[]} variables
|
|
699
|
-
*/
|
|
700
|
-
FeelEditor.prototype.setVariables = function(variables) {
|
|
701
|
-
|
|
702
|
-
const config = get(this._cmEditor.state);
|
|
703
|
-
|
|
704
|
-
this._cmEditor.dispatch({
|
|
705
|
-
effects: [
|
|
706
|
-
coreConf.reconfigure(configure({
|
|
707
|
-
...config,
|
|
708
|
-
variables
|
|
709
|
-
}))
|
|
710
|
-
]
|
|
711
|
-
});
|
|
712
|
-
};
|
|
713
|
-
|
|
714
|
-
/**
|
|
715
|
-
* Update placeholder text.
|
|
716
|
-
*
|
|
717
|
-
* @param {string} placeholder
|
|
718
|
-
*/
|
|
719
|
-
FeelEditor.prototype.setPlaceholder = function(placeholder$1) {
|
|
720
|
-
this._cmEditor.dispatch({
|
|
721
|
-
effects: placeholderConf.reconfigure(placeholder(placeholder$1))
|
|
722
|
-
});
|
|
723
|
-
};
|
|
724
|
-
|
|
725
|
-
export { FeelEditor as default };
|