update cv2

This commit is contained in:
2026-03-26 10:28:25 +01:00
parent d85405dd79
commit 2d2ba31923
7 changed files with 1198 additions and 1377 deletions

View File

@@ -35,19 +35,19 @@
"typesafe-i18n": "typesafe-i18n"
},
"devDependencies": {
"@codemirror/autocomplete": "^6.20.0",
"@codemirror/autocomplete": "^6.20.1",
"@codemirror/collab": "^6.1.1",
"@codemirror/commands": "^6.10.1",
"@codemirror/lang-javascript": "^6.2.4",
"@codemirror/language": "^6.12.1",
"@codemirror/lint": "^6.9.2",
"@codemirror/merge": "^6.11.2",
"@codemirror/commands": "^6.10.3",
"@codemirror/lang-javascript": "^6.2.5",
"@codemirror/language": "^6.12.2",
"@codemirror/lint": "^6.9.5",
"@codemirror/merge": "^6.12.1",
"@codemirror/search": "^6.6.0",
"@codemirror/state": "^6.5.3",
"@codemirror/view": "^6.39.9",
"@fontsource-variable/material-symbols-rounded": "^5.2.30",
"@codemirror/state": "^6.6.0",
"@codemirror/view": "6.39.13",
"@fontsource-variable/material-symbols-rounded": "^5.2.38",
"@fontsource-variable/noto-sans-mono": "^5.2.10",
"@lezer/common": "^1.5.0",
"@lezer/common": "^1.5.1",
"@lezer/generator": "^1.8.0",
"@lezer/highlight": "^1.2.3",
"@lezer/lr": "^1.4.7",
@@ -56,8 +56,8 @@
"@melt-ui/svelte": "^0.86.6",
"@modyfi/vite-plugin-yaml": "^1.1.1",
"@sveltejs/adapter-static": "^3.0.10",
"@sveltejs/kit": "^2.49.3",
"@sveltejs/vite-plugin-svelte": "^6.2.3",
"@sveltejs/kit": "^2.55.0",
"@sveltejs/vite-plugin-svelte": "^7.0.0",
"@tauri-apps/api": "^1.6.0",
"@tauri-apps/cli": "^1.6.0",
"@types/dom-view-transitions": "^1.0.6",
@@ -67,40 +67,40 @@
"@types/w3c-web-usb": "^1.0.13",
"@types/wicg-file-system-access": "^2023.10.7",
"@vite-pwa/sveltekit": "^1.1.0",
"autoprefixer": "^10.4.23",
"autoprefixer": "^10.4.27",
"codemirror": "^6.0.2",
"cypress": "^14.5.3",
"cypress": "^15.12.0",
"d3": "^7.9.0",
"esptool-js": "^0.5.7",
"flexsearch": "^0.8.212",
"fontkit": "^2.0.4",
"glob": "^11.0.3",
"glob": "^13.0.6",
"js-yaml": "^4.1.1",
"jsdom": "^26.1.0",
"jsdom": "^29.0.1",
"jszip": "^3.10.1",
"npm-run-all": "^4.1.5",
"prettier": "^3.7.4",
"prettier": "^3.5.1",
"prettier-plugin-css-order": "^2.2.0",
"prettier-plugin-svelte": "^3.4.1",
"rxjs": "^7.8.2",
"sass": "^1.97.2",
"semver": "^7.7.3",
"sass": "^1.98.0",
"semver": "^7.7.4",
"socket.io-client": "^4.8.3",
"stylelint": "^16.26.1",
"stylelint": "^17.5.0",
"stylelint-config-html": "^1.1.0",
"stylelint-config-prettier-scss": "^1.0.0",
"stylelint-config-recommended-scss": "^16.0.2",
"stylelint-config-standard-scss": "^16.0.0",
"svelte": "5.46.1",
"svelte-check": "^4.3.5",
"stylelint-config-recommended-scss": "^17.0.0",
"stylelint-config-standard-scss": "^17.0.0",
"svelte": "5.55.0",
"svelte-check": "^4.4.5",
"svelte-preprocess": "^6.0.3",
"tippy.js": "^6.3.7",
"typesafe-i18n": "^5.26.2",
"typesafe-i18n": "^5.27.1",
"typescript": "^5.9.3",
"vite": "^7.3.1",
"vite-plugin-mkcert": "^1.17.9",
"vite": "^8.0.2",
"vite-plugin-mkcert": "^1.17.10",
"vite-plugin-pwa": "^1.2.0",
"vitest": "^4.0.16",
"vitest": "^4.1.1",
"web-serial-polyfill": "^1.0.15",
"workbox-window": "^7.4.0"
},

2328
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -24,7 +24,7 @@ export class ActionWidget extends WidgetType {
unmount(this.component);
}
const element = document.createElement("span");
element.style.paddingInline = "2px";
//element.style.paddingInline = "2px";
this.component = mount(Action, {
target: element,
@@ -43,6 +43,10 @@ export class ActionWidget extends WidgetType {
unmount(this.component);
}
}
override ignoreEvent() {
return false;
}
}
function actionWidgets(view: EditorView) {
@@ -51,13 +55,6 @@ function actionWidgets(view: EditorView) {
for (const chord of view.state.field(parsedChordsField).chords) {
if (chord.range[1] < from || chord.range[0] > to) continue;
iterActions(chord, (action) => {
if (
view.state.selection.ranges.some(
(r) => r.from <= action.range[1] && r.to > action.range[0],
)
) {
return;
}
if (action.info && action.explicit) {
const deco = Decoration.replace({
widget: new ActionWidget(action.info),

View File

@@ -4,104 +4,83 @@ import {
ViewPlugin,
ViewUpdate,
WidgetType,
type DecorationSet,
} from "@codemirror/view";
import { syntaxTree } from "@codemirror/language";
import type { Range } from "@codemirror/state";
import { mount, unmount } from "svelte";
import Action from "../components/Action.svelte";
import type { SyntaxNodeRef } from "@lezer/common";
import classNames from "./concatenator-button.module.scss";
export class DelimWidget extends WidgetType {
component?: {};
element?: HTMLElement;
constructor(readonly hasConcatenator: boolean) {
constructor() {
super();
}
override eq(other: DelimWidget) {
return this.hasConcatenator == other.hasConcatenator;
}
toDOM() {
if (!this.element) {
/*this.element = document.createElement("span");
this.element.innerHTML =
"&emsp;⇛" + (this.hasConcatenator ? "" : "&emsp;");
this.element.style.scale = "1.8";
this.element.style.color =
"color-mix(in srgb, currentColor 50%, transparent)";
if (this.hasConcatenator) {
const button = document.createElement("button");
button.className = classNames["concatenator-button"]!;
this.component = mount(Action, {
target: button,
props: { action: 574, display: "keys", inText: true, ghost: true },
});
this.element.appendChild(button);
}*/
this.element = document.createElement("div");
this.element.style.breakAfter = "column";
}
return this.element;
}
override ignoreEvent() {
return false;
}
override destroy() {
if (this.component) {
unmount(this.component);
}
const element = document.createElement("div");
element.style.breakAfter = "column";
return element;
}
}
function getJoinNode(
view: EditorView,
phraseDelimNode: SyntaxNodeRef,
): SyntaxNodeRef | null | undefined {
const firstPhraseAction = phraseDelimNode.node.nextSibling
?.getChild("ActionString")
?.node.firstChild?.node.getChild("ExplicitAction");
const idNode = firstPhraseAction?.node.getChild("ActionId");
const actionId = idNode
? view.state.doc.sliceString(idNode.from, idNode.to)
: null;
const isJoinAction =
actionId === "JOIN" &&
!!firstPhraseAction!.node.getChild("ExplicitDelimEnd");
return isJoinAction ? firstPhraseAction : null;
}
function actionWidgets(view: EditorView) {
const widgets: Range<Decoration>[] = [];
function delimWidgets(view: EditorView): {
delims: DecorationSet;
surrounding: DecorationSet;
} {
const delims: Range<Decoration>[] = [];
const surrounding: Range<Decoration>[] = [];
for (const { from, to } of view.visibleRanges) {
let chord: { from: number; to: number } | null = null;
syntaxTree(view.state).iterate({
from,
to,
enter: (node) => {
if (node.name !== "PhraseDelim") return;
const joinNode = getJoinNode(view, node);
console.log(node.name, node.from, node.to);
if (node.name === "Chord") {
chord = { from: node.from, to: node.to };
}
if (node.name !== "PhraseDelim" || chord === null) return;
let deco = Decoration.replace({
widget: new DelimWidget(!joinNode),
});
widgets.push(deco.range(node.from, node.to));
delims.push(
Decoration.mark({
class: "chord-delim",
}).range(node.from, node.to),
);
if (chord.from < node.from) {
surrounding.push(
Decoration.mark({
tagName: "div",
class: "chord-input",
}).range(chord.from, node.from),
);
}
if (chord.to > node.to) {
surrounding.push(
Decoration.mark({
tagName: "div",
class: "chord-phrase",
}).range(node.to, chord.to),
);
}
chord = null;
},
});
}
return Decoration.set(widgets);
return {
delims: Decoration.set(delims),
surrounding: Decoration.set([...surrounding, ...delims], true),
};
}
export const delimPlugin = ViewPlugin.fromClass(
class {
decorations = Decoration.none;
delims = Decoration.none;
surrounding = Decoration.none;
constructor(view: EditorView) {
this.decorations = actionWidgets(view);
const { delims, surrounding } = delimWidgets(view);
this.delims = delims;
this.surrounding = surrounding;
}
update(update: ViewUpdate) {
@@ -109,51 +88,21 @@ export const delimPlugin = ViewPlugin.fromClass(
update.docChanged ||
update.viewportChanged ||
syntaxTree(update.startState) != syntaxTree(update.state)
)
this.decorations = actionWidgets(update.view);
) {
const { delims, surrounding } = delimWidgets(update.view);
this.delims = delims;
this.surrounding = surrounding;
}
}
},
{
decorations(instance) {
return instance.decorations;
return instance.delims;
},
provide(plugin) {
return EditorView.atomicRanges.of(
(view) => view.plugin(plugin)?.decorations ?? Decoration.none,
(view) => view.plugin(plugin)?.delims ?? Decoration.none,
);
},
eventHandlers: {
click: (event, view) => {
if (!(event.target instanceof HTMLElement)) return;
if (
!(
event.target instanceof HTMLButtonElement ||
(event.target as HTMLElement).parentElement instanceof
HTMLButtonElement
)
)
return;
const chordNode = syntaxTree(view.state).resolve(
view.posAtDOM(event.target),
);
const delimNode = (
chordNode.name === "ActionString"
? chordNode.parent?.parent
: chordNode
)?.getChild("PhraseDelim");
if (!delimNode) return;
const joinNode = getJoinNode(view, delimNode);
if (!event.target.checked && !joinNode) {
view.dispatch({
changes: {
from: delimNode.to,
insert: "<JOIN>",
},
selection: { anchor: delimNode.to + "<JOIN>".length },
});
}
},
},
},
);

View File

@@ -51,10 +51,9 @@ export function createConfig(params: EditorConfig) {
actionHover,
changesPanel(),
lintGutter(),
params.rawCode ? [lineNumbers()] : [delimPlugin, actionPlugin],
params.rawCode ? [lineNumbers()] : [/*delimPlugin,*/ actionPlugin],
chordLanguageSupport(),
actionLinter({
delay: 100,
markerFilter(diagnostics) {
return diagnostics.filter((it) => it.from !== it.to);
},

View File

@@ -118,6 +118,10 @@
{/if}
<style lang="scss">
:global(*):has(> kbd:not(.inline-kbd).in-text) {
--ch: 1ch;
}
kbd:not(.inline-kbd) {
transition: color 250ms ease;
padding-block: auto;
@@ -126,8 +130,11 @@
&.in-text {
display: inline-flex;
vertical-align: middle;
margin-inline: calc(var(--ch) * 0.25);
margin-block: auto;
padding-inline: 0;
padding-block: revert;
width: calc(var(--ch) * 1.5);
}
}

View File

@@ -169,9 +169,6 @@
}
&:not(.raw) :global(.cm-line) {
vertical-align: middle;
columns: 2;
text-align: center;
}
&.dense-spacing :global(.cm-line) {
@@ -180,7 +177,7 @@
:global(.cm-line) {
padding-block: 8px;
width: 100%;
width: fit-content;
text-wrap: wrap;
text-wrap-style: stable;
white-space: pre-wrap;