symfony-expression-editor 0.1.1 → 0.2.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/CHANGELOG.md +7 -0
- package/dist/index.cjs +37 -17
- package/dist/index.d.cts +3 -0
- package/dist/index.d.mts +3 -0
- package/dist/index.mjs +37 -17
- package/example.html +24 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -1162,10 +1162,9 @@ class LintState {
|
|
|
1162
1162
|
this.selected = selected;
|
|
1163
1163
|
}
|
|
1164
1164
|
static init(diagnostics, panel, state$1) {
|
|
1165
|
-
let markedDiagnostics = diagnostics;
|
|
1166
1165
|
let diagnosticFilter = state$1.facet(lintConfig).markerFilter;
|
|
1167
1166
|
if (diagnosticFilter)
|
|
1168
|
-
|
|
1167
|
+
diagnostics = diagnosticFilter(diagnostics, state$1);
|
|
1169
1168
|
let sorted = diagnostics.slice().sort((a, b) => a.from - b.from || a.to - b.to);
|
|
1170
1169
|
let deco = new state.RangeSetBuilder(), active = [], pos = 0;
|
|
1171
1170
|
for (let i = 0; ; ) {
|
|
@@ -1749,7 +1748,8 @@ const bootstrap = view.EditorView.theme({
|
|
|
1749
1748
|
padding: "0 0.75rem"
|
|
1750
1749
|
},
|
|
1751
1750
|
".cm-content": {
|
|
1752
|
-
padding: "0.375rem 0"
|
|
1751
|
+
padding: "0.375rem 0",
|
|
1752
|
+
animation: "fade-to-colors 0.5s ease-out 0s forwards"
|
|
1753
1753
|
},
|
|
1754
1754
|
"&:not(.cm-focused) .cm-selectionBackground, &:not(.cm-focused) .cm-activeLine, &:not(.cm-focused) .cm-activeLineGutter": {
|
|
1755
1755
|
backgroundColor: "transparent"
|
|
@@ -1764,13 +1764,17 @@ const bootstrap = view.EditorView.theme({
|
|
|
1764
1764
|
overflow: "auto",
|
|
1765
1765
|
height: "100%",
|
|
1766
1766
|
lineHeight: 1.85,
|
|
1767
|
-
flexGrow: 1
|
|
1767
|
+
flexGrow: 1,
|
|
1768
|
+
animation: "fade 0.5s ease-out 0s forwards"
|
|
1768
1769
|
},
|
|
1769
1770
|
".cm-gutters": {
|
|
1770
1771
|
height: "100% !important",
|
|
1771
1772
|
color: "var(--bs-tertiary-color)",
|
|
1772
1773
|
backgroundColor: "var(--bs-tertiary-bg)"
|
|
1773
|
-
}
|
|
1774
|
+
},
|
|
1775
|
+
"@keyframes slide-left": { from: { transform: "translateX(-100%)", opacity: 0 } },
|
|
1776
|
+
"@keyframes fade-to-colors": { from: { filter: "grayscale(100%)" } },
|
|
1777
|
+
"@keyframes fade": { from: { opacity: 0 } }
|
|
1774
1778
|
});
|
|
1775
1779
|
|
|
1776
1780
|
const darkTheme = view.EditorView.theme({
|
|
@@ -1843,41 +1847,57 @@ var light = [
|
|
|
1843
1847
|
|
|
1844
1848
|
const getTheme = (el) => ({ light, dark })[el.dataset.bsTheme || "light"];
|
|
1845
1849
|
const mutationObserver = new MutationObserver(
|
|
1846
|
-
(changes) => changes.map((mutation) => mutation.target).filter((mutationTarget) => mutationTarget instanceof HTMLElement).map((themeContainer) =>
|
|
1850
|
+
(changes) => changes.map((mutation) => mutation.target).filter((mutationTarget) => mutationTarget instanceof HTMLElement).map((themeContainer) => editors.get(themeContainer).forEach((editor) => setTheme(themeContainer, editor)))
|
|
1847
1851
|
);
|
|
1852
|
+
const setTheme = (themeContainer, editor) => editor.dispatch({ effects: themes.get(editor).reconfigure(getTheme(themeContainer)) });
|
|
1848
1853
|
const themes = /* @__PURE__ */ new WeakMap();
|
|
1849
1854
|
const editors = /* @__PURE__ */ new WeakMap();
|
|
1850
1855
|
class ExpressionEditor extends HTMLTextAreaElement {
|
|
1851
1856
|
constructor() {
|
|
1852
1857
|
super();
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
mutationObserver.observe(themeContainer, { attributes: true, attributeFilter: ["data-bs-theme"] });
|
|
1856
|
-
themes.set(themeContainer, new state.Compartment());
|
|
1857
|
-
editors.set(themeContainer, /* @__PURE__ */ new Set());
|
|
1858
|
-
}
|
|
1858
|
+
this.theme = new state.Compartment();
|
|
1859
|
+
this.instanceStyles = new state.Compartment();
|
|
1859
1860
|
this.dom = document.createElement("div");
|
|
1861
|
+
const shadow = this.dom.attachShadow({ mode: "closed" });
|
|
1860
1862
|
this.editorView = new view.EditorView({
|
|
1861
1863
|
extensions: [
|
|
1862
|
-
|
|
1864
|
+
this.instanceStyles.of(view.EditorView.theme({})),
|
|
1863
1865
|
basicSetup({
|
|
1864
1866
|
useLineNumbers: JSON.parse(this.dataset.lineNumbers || "false")
|
|
1865
1867
|
}),
|
|
1866
|
-
|
|
1868
|
+
this.theme.of(light),
|
|
1867
1869
|
view.keymap.of([...commands.defaultKeymap, { key: "Tab", run: autocomplete.acceptCompletion }]),
|
|
1868
|
-
codemirrorLangEl.expressionlanguage(JSON.parse(this.dataset.config || "{}")
|
|
1870
|
+
codemirrorLangEl.expressionlanguage(JSON.parse(this.dataset.config || "{}")),
|
|
1869
1871
|
view.EditorView.updateListener.of((e) => {
|
|
1870
1872
|
if (e.docChanged) {
|
|
1871
1873
|
this.value = e.state.doc.toString();
|
|
1872
1874
|
}
|
|
1873
1875
|
})
|
|
1874
1876
|
],
|
|
1875
|
-
|
|
1877
|
+
root: shadow,
|
|
1878
|
+
parent: shadow,
|
|
1876
1879
|
doc: this.value.trim()
|
|
1877
1880
|
});
|
|
1881
|
+
themes.set(this.editorView, this.theme);
|
|
1882
|
+
}
|
|
1883
|
+
connectedCallback() {
|
|
1884
|
+
const themeContainer = this.closest("[data-bs-theme]") || document.documentElement;
|
|
1885
|
+
if (!editors.has(themeContainer)) {
|
|
1886
|
+
editors.set(themeContainer, /* @__PURE__ */ new Set());
|
|
1887
|
+
mutationObserver.observe(themeContainer, { attributes: true, attributeFilter: ["data-bs-theme"] });
|
|
1888
|
+
}
|
|
1889
|
+
if (editors.get(themeContainer).has(this.editorView)) {
|
|
1890
|
+
return;
|
|
1891
|
+
}
|
|
1892
|
+
setTheme(themeContainer, this.editorView);
|
|
1878
1893
|
editors.get(themeContainer).add(this.editorView);
|
|
1894
|
+
this.editorView.dispatch({
|
|
1895
|
+
effects: this.instanceStyles.reconfigure(view.EditorView.theme({
|
|
1896
|
+
"&": { minHeight: this.getBoundingClientRect().height + "px" },
|
|
1897
|
+
"& .cm-gutter": { minHeight: `${this.getBoundingClientRect().height - 2}px` }
|
|
1898
|
+
}))
|
|
1899
|
+
});
|
|
1879
1900
|
this.replaceWith(this.dom);
|
|
1880
|
-
this.hidden = true;
|
|
1881
1901
|
this.dom.appendChild(this);
|
|
1882
1902
|
}
|
|
1883
1903
|
}
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.mts
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -1160,10 +1160,9 @@ class LintState {
|
|
|
1160
1160
|
this.selected = selected;
|
|
1161
1161
|
}
|
|
1162
1162
|
static init(diagnostics, panel, state) {
|
|
1163
|
-
let markedDiagnostics = diagnostics;
|
|
1164
1163
|
let diagnosticFilter = state.facet(lintConfig).markerFilter;
|
|
1165
1164
|
if (diagnosticFilter)
|
|
1166
|
-
|
|
1165
|
+
diagnostics = diagnosticFilter(diagnostics, state);
|
|
1167
1166
|
let sorted = diagnostics.slice().sort((a, b) => a.from - b.from || a.to - b.to);
|
|
1168
1167
|
let deco = new RangeSetBuilder(), active = [], pos = 0;
|
|
1169
1168
|
for (let i = 0; ; ) {
|
|
@@ -1747,7 +1746,8 @@ const bootstrap = EditorView.theme({
|
|
|
1747
1746
|
padding: "0 0.75rem"
|
|
1748
1747
|
},
|
|
1749
1748
|
".cm-content": {
|
|
1750
|
-
padding: "0.375rem 0"
|
|
1749
|
+
padding: "0.375rem 0",
|
|
1750
|
+
animation: "fade-to-colors 0.5s ease-out 0s forwards"
|
|
1751
1751
|
},
|
|
1752
1752
|
"&:not(.cm-focused) .cm-selectionBackground, &:not(.cm-focused) .cm-activeLine, &:not(.cm-focused) .cm-activeLineGutter": {
|
|
1753
1753
|
backgroundColor: "transparent"
|
|
@@ -1762,13 +1762,17 @@ const bootstrap = EditorView.theme({
|
|
|
1762
1762
|
overflow: "auto",
|
|
1763
1763
|
height: "100%",
|
|
1764
1764
|
lineHeight: 1.85,
|
|
1765
|
-
flexGrow: 1
|
|
1765
|
+
flexGrow: 1,
|
|
1766
|
+
animation: "fade 0.5s ease-out 0s forwards"
|
|
1766
1767
|
},
|
|
1767
1768
|
".cm-gutters": {
|
|
1768
1769
|
height: "100% !important",
|
|
1769
1770
|
color: "var(--bs-tertiary-color)",
|
|
1770
1771
|
backgroundColor: "var(--bs-tertiary-bg)"
|
|
1771
|
-
}
|
|
1772
|
+
},
|
|
1773
|
+
"@keyframes slide-left": { from: { transform: "translateX(-100%)", opacity: 0 } },
|
|
1774
|
+
"@keyframes fade-to-colors": { from: { filter: "grayscale(100%)" } },
|
|
1775
|
+
"@keyframes fade": { from: { opacity: 0 } }
|
|
1772
1776
|
});
|
|
1773
1777
|
|
|
1774
1778
|
const darkTheme = EditorView.theme({
|
|
@@ -1841,41 +1845,57 @@ var light = [
|
|
|
1841
1845
|
|
|
1842
1846
|
const getTheme = (el) => ({ light, dark })[el.dataset.bsTheme || "light"];
|
|
1843
1847
|
const mutationObserver = new MutationObserver(
|
|
1844
|
-
(changes) => changes.map((mutation) => mutation.target).filter((mutationTarget) => mutationTarget instanceof HTMLElement).map((themeContainer) =>
|
|
1848
|
+
(changes) => changes.map((mutation) => mutation.target).filter((mutationTarget) => mutationTarget instanceof HTMLElement).map((themeContainer) => editors.get(themeContainer).forEach((editor) => setTheme(themeContainer, editor)))
|
|
1845
1849
|
);
|
|
1850
|
+
const setTheme = (themeContainer, editor) => editor.dispatch({ effects: themes.get(editor).reconfigure(getTheme(themeContainer)) });
|
|
1846
1851
|
const themes = /* @__PURE__ */ new WeakMap();
|
|
1847
1852
|
const editors = /* @__PURE__ */ new WeakMap();
|
|
1848
1853
|
class ExpressionEditor extends HTMLTextAreaElement {
|
|
1849
1854
|
constructor() {
|
|
1850
1855
|
super();
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
mutationObserver.observe(themeContainer, { attributes: true, attributeFilter: ["data-bs-theme"] });
|
|
1854
|
-
themes.set(themeContainer, new Compartment());
|
|
1855
|
-
editors.set(themeContainer, /* @__PURE__ */ new Set());
|
|
1856
|
-
}
|
|
1856
|
+
this.theme = new Compartment();
|
|
1857
|
+
this.instanceStyles = new Compartment();
|
|
1857
1858
|
this.dom = document.createElement("div");
|
|
1859
|
+
const shadow = this.dom.attachShadow({ mode: "closed" });
|
|
1858
1860
|
this.editorView = new EditorView({
|
|
1859
1861
|
extensions: [
|
|
1860
|
-
|
|
1862
|
+
this.instanceStyles.of(EditorView.theme({})),
|
|
1861
1863
|
basicSetup({
|
|
1862
1864
|
useLineNumbers: JSON.parse(this.dataset.lineNumbers || "false")
|
|
1863
1865
|
}),
|
|
1864
|
-
|
|
1866
|
+
this.theme.of(light),
|
|
1865
1867
|
keymap.of([...defaultKeymap, { key: "Tab", run: acceptCompletion }]),
|
|
1866
|
-
expressionlanguage(JSON.parse(this.dataset.config || "{}")
|
|
1868
|
+
expressionlanguage(JSON.parse(this.dataset.config || "{}")),
|
|
1867
1869
|
EditorView.updateListener.of((e) => {
|
|
1868
1870
|
if (e.docChanged) {
|
|
1869
1871
|
this.value = e.state.doc.toString();
|
|
1870
1872
|
}
|
|
1871
1873
|
})
|
|
1872
1874
|
],
|
|
1873
|
-
|
|
1875
|
+
root: shadow,
|
|
1876
|
+
parent: shadow,
|
|
1874
1877
|
doc: this.value.trim()
|
|
1875
1878
|
});
|
|
1879
|
+
themes.set(this.editorView, this.theme);
|
|
1880
|
+
}
|
|
1881
|
+
connectedCallback() {
|
|
1882
|
+
const themeContainer = this.closest("[data-bs-theme]") || document.documentElement;
|
|
1883
|
+
if (!editors.has(themeContainer)) {
|
|
1884
|
+
editors.set(themeContainer, /* @__PURE__ */ new Set());
|
|
1885
|
+
mutationObserver.observe(themeContainer, { attributes: true, attributeFilter: ["data-bs-theme"] });
|
|
1886
|
+
}
|
|
1887
|
+
if (editors.get(themeContainer).has(this.editorView)) {
|
|
1888
|
+
return;
|
|
1889
|
+
}
|
|
1890
|
+
setTheme(themeContainer, this.editorView);
|
|
1876
1891
|
editors.get(themeContainer).add(this.editorView);
|
|
1892
|
+
this.editorView.dispatch({
|
|
1893
|
+
effects: this.instanceStyles.reconfigure(EditorView.theme({
|
|
1894
|
+
"&": { minHeight: this.getBoundingClientRect().height + "px" },
|
|
1895
|
+
"& .cm-gutter": { minHeight: `${this.getBoundingClientRect().height - 2}px` }
|
|
1896
|
+
}))
|
|
1897
|
+
});
|
|
1877
1898
|
this.replaceWith(this.dom);
|
|
1878
|
-
this.hidden = true;
|
|
1879
1899
|
this.dom.appendChild(this);
|
|
1880
1900
|
}
|
|
1881
1901
|
}
|
package/example.html
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
<html>
|
|
2
|
+
<head>
|
|
3
|
+
<style>
|
|
4
|
+
textarea[is="expression-editor"] {
|
|
5
|
+
animation: fadeTextIn 1.0s ease-in-out 0s forwards;
|
|
6
|
+
font-family: monospace;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
@keyframes fadeTextIn { from { color: rgba(var(--bs-body-color-rgb), 0); } }
|
|
10
|
+
</style>
|
|
11
|
+
</head>
|
|
2
12
|
<body class="bg-body-secondary container">
|
|
3
13
|
<script type="importmap">
|
|
4
14
|
{
|
|
@@ -34,13 +44,22 @@
|
|
|
34
44
|
<input class="form-check-input" type="checkbox" role="switch" id="light-switch" onchange="this.closest('.section').dataset.bsTheme=this.checked ? 'light' : 'dark'">
|
|
35
45
|
<label class="form-check-label" for="light-switch">Lights</label>
|
|
36
46
|
</div>
|
|
37
|
-
<div>
|
|
38
|
-
<textarea rows="
|
|
39
|
-
x == x + 1
|
|
47
|
+
<div id="template">
|
|
48
|
+
<textarea rows="3" class="form-control" is="expression-editor" data-line-numbers="true" data-config="{"identifiers":[{"name":"x"}]}">x == x + 1
|
|
40
49
|
&& 'foobar' starts with 'foo'
|
|
41
|
-
&& x == x + 1
|
|
42
|
-
|
|
50
|
+
&& x == x + 1</textarea>
|
|
51
|
+
</div>
|
|
52
|
+
<div>
|
|
53
|
+
<button type="button" class="btn btn-sm btn-secondary mt-3" id="clone">Clone</button>
|
|
43
54
|
</div>
|
|
44
55
|
</div>
|
|
56
|
+
<script type="module">
|
|
57
|
+
document.getElementById('clone').addEventListener('click', function () {
|
|
58
|
+
const template = document.getElementById('template');
|
|
59
|
+
const clone = template.cloneNode(true);
|
|
60
|
+
clone.removeAttribute('id');
|
|
61
|
+
template.parentNode.insertBefore(clone, this.parentElement);
|
|
62
|
+
});
|
|
63
|
+
</script>
|
|
45
64
|
</body>
|
|
46
65
|
</html>
|
package/package.json
CHANGED