Update to Svelte 4, and update most other JS deps (#2565)

* eslint-plugin-svelte3 -> eslint-plugin-svelte

The former is deprecated, and blocks an update to Svelte 4.

Also drop unused svelte2tsx and types package.

* Drop unused symbols code for now

It may be added back in the future, but for now dropping it will save
200k from our editor bundle.

* Remove sass and caniuse-lite pins

The latter no longer seems to be required. The former was added to
suppress deprecation warnings when compiling the old bootstrap version
we have pinned. Those are hidden by the build tool now (though we really
need to address them at one point: https://github.com/ankitects/anki/issues/1385)

Also removed unused files section.

* Prevent proto compile from looking in node_modules/@types/sass

When deps are updated, tsc aborts because @types/sass is a dummy package
without an index.d.ts file.

* Filter Svelte warnings out of ./run

* Update to latest Bootstrap

This fixes the deprecation warnings we were getting during build:
bootstrap doesn't accept runtime CSS variables being set in Sass, as
it wants to apply transforms to the colors.

Closes #1385

* Start port to Svelte 4

- svelte-check tests have a bunch of failures; ./run works
- Svelte no longer exposes internals, so we can't use create_in_transition
- Also update esbuild and related components like esbuild-svelte

* Fix test failures

Had to add some more a11y warning ignores - have added
https://github.com/ankitects/anki/issues/2564 to address that in the
future.

* Remove some dependency pins

+ Remove sass, we don't need it directly

* Bump remaining JS deps that have a current semver

* Upgrade dprint/license-checker/marked

The new helper method avoids marked printing deprecation warnings to
the console.

Also remove unused lodash/long types, and move lodahs-es to devdeps

* Upgrade eslint and fluent packages

* Update @floating-ui/dom

The only dependencies remaining are currently blocked:

- Jest 29 gives some error about require vs import; may not be worth
investigating if we switch to Deno for the tests
- CodeMirror 6 is a big API change and will need work.

* Roll dprint back to an earlier version

GitHub dropped support for Ubuntu 18 runners, causing dprint's artifacts
to require a glibc version greater than what Anki CI currently has.
This commit is contained in:
Damien Elmes 2023-07-01 16:21:53 +10:00 committed by GitHub
parent baa631c6ef
commit c8458fce16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 2564 additions and 2859 deletions

View File

@ -1,9 +1,11 @@
module.exports = {
root: true,
extends: ["eslint:recommended", "plugin:compat/recommended"],
extends: ["eslint:recommended", "plugin:compat/recommended", "plugin:svelte/recommended"],
parser: "@typescript-eslint/parser",
parserOptions: {
extraFileExtensions: [".svelte"],
},
plugins: [
"svelte3",
"import",
"simple-import-sort",
"@typescript-eslint",
@ -36,11 +38,14 @@ module.exports = {
},
},
{
files: "**/*.svelte",
processor: "svelte3/svelte3",
files: ["*.svelte"],
parser: "svelte-eslint-parser",
parserOptions: {
parser: "@typescript-eslint/parser",
},
rules: {
"no-redeclare": "off",
"no-global-assign": "off",
"svelte/no-at-html-tags": "off",
"svelte/valid-compile": ["error", { "ignoreWarnings": true }],
},
},
],
@ -49,9 +54,6 @@ module.exports = {
globals: {
globalThis: false,
NodeListOf: false,
},
settings: {
"svelte3/typescript": () => require("typescript"),
"svelte3/ignore-warnings": (warning) => warning.code.startsWith("a11y-"),
$$Generic: "readonly",
},
};

View File

@ -215,7 +215,7 @@ pub struct SvelteCheck {
impl BuildAction for SvelteCheck {
fn command(&self) -> &str {
"$svelte-check --tsconfig $tsconfig $
--fail-on-warnings --threshold warning --use-new-transformation $
--fail-on-warnings --threshold warning $
--compiler-warnings $compiler_warnings"
}
@ -229,6 +229,8 @@ impl BuildAction for SvelteCheck {
[
"a11y-click-events-have-key-events",
"a11y-no-noninteractive-tabindex",
"a11y-no-static-element-interactions",
"a11y-no-noninteractive-element-interactions",
]
.iter()
.map(|warning| format!("{}$:ignore", warning))
@ -423,7 +425,7 @@ pub struct CompileTypescript<'a> {
impl BuildAction for CompileTypescript<'_> {
fn command(&self) -> &str {
"$tsc $in --outDir $out_dir -d --skipLibCheck"
"$tsc $in --outDir $out_dir -d --skipLibCheck --types node"
}
fn files(&mut self, build: &mut impl build::FilesHandle) {

View File

@ -7,7 +7,6 @@
"description": "Anki JS support files",
"devDependencies": {
"@bufbuild/protoc-gen-es": "^1.2.1",
"@pyoner/svelte-types": "^3.4.4-2",
"@sqltools/formatter": "^1.2.2",
"@types/bootstrap": "^5.0.12",
"@types/codemirror": "^5.60.0",
@ -16,76 +15,64 @@
"@types/jest": "^27.0.2",
"@types/jquery": "^3.5.0",
"@types/jqueryui": "^1.12.13",
"@types/lodash": "^4.14.162",
"@types/long": "^4.0.1",
"@types/lodash-es": "^4.17.4",
"@types/marked": "^5.0.0",
"@types/node": "^16.10.2",
"@typescript-eslint/eslint-plugin": "^4.22.0",
"@typescript-eslint/parser": "^4.22.0",
"@typescript-eslint/eslint-plugin": "^5.60.1",
"@typescript-eslint/parser": "^5.60.1",
"caniuse-lite": "^1.0.30001431",
"cross-env": "^7.0.2",
"diff": "^5.0.0",
"dprint": "^0.32.2",
"esbuild": "^0.15.13",
"esbuild-sass-plugin": "2",
"esbuild-svelte": "^0.7.1",
"eslint": "^7.24.0",
"eslint-plugin-compat": "^3.13.0",
"dprint": "=0.35.3",
"esbuild": "^0.18.10",
"esbuild-sass-plugin": "^2",
"esbuild-svelte": "^0.7.4",
"eslint": "^8.44.0",
"eslint-plugin-compat": "^4.1.4",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-simple-import-sort": "^7.0.0",
"eslint-plugin-svelte3": "^3.4.0",
"eslint-plugin-simple-import-sort": "^10.0.0",
"eslint-plugin-svelte": "^2",
"jest-cli": "^28.0.0-alpha.5",
"jest-environment-jsdom": "^28.0.0-alpha.5",
"license-checker-rseidelsohn": "^2.1.1",
"prettier": "2.4.1",
"prettier-plugin-svelte": "2.6.0",
"sass": "1.43.5",
"svelte": "^3.25.0",
"svelte-check": "^2.2.6",
"svelte-preprocess": "^5.0.3",
"license-checker-rseidelsohn": "^4.2.6",
"prettier": "^2.4.1",
"prettier-plugin-svelte": "^2.10.1",
"svelte": "^4.0.1",
"svelte-check": "^3.4.4",
"svelte-preprocess": "^5.0.4",
"svelte-preprocess-esbuild": "^3.0.1",
"svelte2tsx": "^0.4.6",
"tslib": "^2.0.3",
"tsx": "^3.12.0",
"typescript": "^5.0.4"
},
"dependencies": {
"@bufbuild/protobuf": "^1.2.1",
"@floating-ui/dom": "^0.3.0",
"@fluent/bundle": "^0.17.0",
"@floating-ui/dom": "^1.4.3",
"@fluent/bundle": "^0.18.0",
"@mdi/svg": "^7.0.96",
"@popperjs/core": "^2.9.2",
"@types/lodash-es": "^4.17.4",
"@types/marked": "^4.0.1",
"bootstrap": "=5.0.2",
"bootstrap-icons": "^1.4.0",
"character-entities": "^2.0.2",
"@popperjs/core": "^2.11.8",
"bootstrap": "^5.3.0",
"bootstrap-icons": "^1.10.5",
"codemirror": "^5.63.1",
"css-browser-selector": "^0.6.5",
"d3": "^7.0.0",
"fabric": "^5.3.0",
"fuse.js": "^6.6.2",
"gemoji": "^7.1.0",
"intl-pluralrules": "^1.2.2",
"intl-pluralrules": "^2.0.0",
"jquery": "^3.5.1",
"jquery-ui-dist": "^1.12.1",
"lodash-es": "^4.17.21",
"marked": "^4.0.0",
"marked": "^5.1.0",
"mathjax": "^3.1.2",
"panzoom": "^9.4.3"
},
"resolutions": {
"sass": "=1.45.0",
"caniuse-lite": "^1.0.30001431",
"canvas": "npm:empty-npm-package"
},
"files": [
"dist/*"
],
"browserslist": [
"defaults",
"not op_mini all",
"not < 1%",
"Chrome 77",
"iOS 13.4"
"iOS 14.5"
]
}

View File

@ -554,9 +554,6 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
sticky = [field["sticky"] for field in self.note.note_type()["flds"]]
js += " setSticky(%s);" % json.dumps(sticky)
if os.getenv("ANKI_EDITOR_INSERT_SYMBOLS"):
js += " setInsertSymbolsEnabled();"
js = gui_hooks.editor_will_load_note(js, self.note, self)
self.web.evalWithCallback(
f'require("anki/ui").loaded.then(() => {{ {js} }})', oncallback

View File

@ -546,8 +546,10 @@ html {{ {font} }}
if theme_manager.night_mode:
doc_class = "night-mode"
bs_theme = "dark"
else:
doc_class = ""
bs_theme = "light"
if is_rtl(anki.lang.current_lang):
lang_dir = "rtl"
@ -556,7 +558,7 @@ html {{ {font} }}
html = f"""
<!doctype html>
<html class="{doc_class}" dir="{lang_dir}">
<html class="{doc_class}" dir="{lang_dir}" data-bs-theme="{bs_theme}">
<head>
<title>{self.title}</title>
{head}
@ -760,15 +762,17 @@ html {{ {font} }}
self.eval(
f"""
(function() {{
const doc = document.documentElement.classList;
const doc = document.documentElement;
const body = document.body.classList;
if ({1 if theme_manager.night_mode else 0}) {{
doc.add("night-mode");
doc.dataset.bsTheme = "dark";
doc.classList.add("night-mode");
body.add("night_mode");
body.add("nightMode");
{"body.add('macos-dark-mode');" if theme_manager.macos_dark_mode() else ""}
}} else {{
doc.remove("night-mode");
doc.dataset.bsTheme = "light";
doc.classList.remove("night-mode");
body.remove("night_mode");
body.remove("nightMode");
body.remove("macos-dark-mode");

View File

@ -3,10 +3,10 @@
@use "button-mixins" as button;
@use "sass/scrollbar";
$body-color: color(fg);
$body-bg: color(canvas);
$link-hover-color: color(fg-link);
$body-color: palette(darkgray, 9);
$body-color-dark: palette(lightgray, 0);
$body-bg: palette(lightgray, 2);
$body-bg-dark: palette(darkgray, 5);
$link-hover-decoration: none;
$utilities: (

View File

@ -56,6 +56,8 @@ build({
sveltePlugin({
compilerOptions: { css: inlineCss },
preprocess: sveltePlugins,
// let us focus on errors; we can see the warnings with svelte-check
filterWarnings: (_warning) => false,
}),
],
target,

View File

@ -4,12 +4,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="ts">
import * as tr from "@tslib/ftl";
import { marked } from "marked";
import Col from "../components/Col.svelte";
import Container from "../components/Container.svelte";
import Row from "../components/Row.svelte";
import StickyContainer from "../components/StickyContainer.svelte";
import { renderMarkdown } from "../lib/helpers";
import type { ChangeNotetypeState } from "./lib";
import { MapContext } from "./lib";
import Mapper from "./Mapper.svelte";
@ -46,7 +46,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
{#if $info.templates}
<Mapper {state} ctx={MapContext.Template} />
{:else}
<div>{@html marked(tr.changeNotetypeToFromCloze())}</div>
<div>
{@html renderMarkdown(tr.changeNotetypeToFromCloze())}
</div>
{/if}
</Container>
</Col>

View File

@ -5,9 +5,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<script lang="ts">
import type { Placement } from "@floating-ui/dom";
import { getContext, onMount } from "svelte";
import { create_in_transition } from "svelte/internal";
import type { Writable } from "svelte/store";
import { slide } from "svelte/transition";
import { floatingKey } from "./context-keys";
@ -26,8 +24,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
$placementStore.then((computedPlacement) => {
if (placement != computedPlacement) {
placement = computedPlacement;
/* use internal function to animate popover */
create_in_transition(element, slide, { duration: 200 }).start();
hidden = false;
}
});

View File

@ -7,7 +7,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export { className as class };
export let scrollX = false;
export let scrollY = false;
let scrollBarWidth = 0;
let scrollBarHeight = 0;
let measuring = true;
@ -19,7 +18,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
};
function measureScrollbar(el: HTMLDivElement) {
scrollBarWidth = el.offsetWidth - el.clientWidth;
scrollBarHeight = el.offsetHeight - el.clientHeight;
measuring = false;
}

View File

@ -12,6 +12,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import Popover from "./Popover.svelte";
import WithFloating from "./WithFloating.svelte";
// eslint-disable
type T = $$Generic;
export let id: string | undefined = undefined;
@ -68,7 +69,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
class="{className} select-container"
class:rtl
class:hover
{disabled}
class:disabled
title={tooltip}
tabindex="0"
on:keypress={handleKey}
@ -123,6 +124,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
}
.disabled {
pointer-events: none;
opacity: 0.5;
}
.chevron {
height: 100%;
align-self: flex-end;

View File

@ -32,6 +32,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
.form-check-input {
-webkit-appearance: none;
appearance: none;
height: 1.5em;
/* otherwise the switch circle shows slightly off-centered */
margin-top: 0;

View File

@ -61,7 +61,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
hideCallback: (reason: string) => dispatch("close", { reason }),
});
let autoAction: ActionReturn = {};
let autoAction: ActionReturn<any> = {};
$: {
positionCurried;
@ -184,7 +184,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<div bind:this={floating} class="floating" class:show use:portal={portalTarget}>
{#if show}
<slot name="floating" />
<slot name="floating" {position} />
{/if}
<div bind:this={arrow} class="floating-arrow" hidden={!show}>

View File

@ -43,7 +43,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
hideCallback: (reason: string) => dispatch("close", { reason }),
});
let autoAction: ActionReturn = {};
let autoAction: ActionReturn<any> = {};
$: {
positionCurried;
@ -154,7 +154,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<div bind:this={floating} class="overlay" class:show>
{#if show}
<slot name="overlay" />
<slot name="overlay" {position} />
{/if}
</div>

View File

@ -4,7 +4,7 @@
-->
<script lang="ts">
import * as tr from "@tslib/ftl";
import { marked } from "marked";
import { renderMarkdown } from "@tslib/helpers";
import Row from "../components/Row.svelte";
import type { DeckOption } from "./types";
@ -21,9 +21,9 @@
{/if}
</h2>
{#if section.help}
{@html marked(section.help)}
{@html renderMarkdown(section.help)}
{:else}
{@html marked(
{@html renderMarkdown(
tr.helpNoExplanation({
link: "[GitHub](https://github.com/ankitects/anki)",
}),
@ -33,7 +33,7 @@
{#if section.url}
<hr />
<div class="chapter-redirect">
{@html marked(
{@html renderMarkdown(
tr.helpForMoreInfo({
link: `<a href="${section.url}" title="${tr.helpOpenManualChapter({
name: section.title,

View File

@ -41,6 +41,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<anki-editable
contenteditable="true"
role="textbox"
tabindex="0"
use:resolve
use:setupFocusHandling
use:preventBuiltinShortcuts

View File

@ -67,7 +67,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import PlainTextBadge from "./PlainTextBadge.svelte";
import RichTextInput, { editingInputIsRichText } from "./rich-text-input";
import RichTextBadge from "./RichTextBadge.svelte";
import SymbolsOverlay from "./symbols-overlay";
import type { NotetypeIdAndModTime, SessionOptions } from "./types";
function quoteFontFamily(fontFamily: string): string {
@ -234,12 +233,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
}
let insertSymbols = false;
function setInsertSymbolsEnabled() {
insertSymbols = true;
}
function getNoteId(): number | null {
return noteId;
}
@ -415,7 +408,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
setNotetypeMeta,
wrap,
setMathjaxEnabled,
setInsertSymbolsEnabled,
setShrinkImages,
setCloseHTMLTags,
triggerChanges,
@ -585,9 +577,6 @@ the AddCards dialog) should be implemented in the user of this component.
<MathjaxOverlay />
<ImageOverlay maxWidth={250} maxHeight={125} />
{#if insertSymbols}
<SymbolsOverlay />
{/if}
</Fields>
<Shortcut

View File

@ -32,7 +32,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
return registerShortcut(toggle, keyCombination, { target });
}
onMount(() => editorField.element.then(shortcut));
onMount(() => {
editorField.element.then(shortcut);
});
</script>
<span

View File

@ -249,7 +249,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
inline
hideIfReferenceHidden
portalTarget={document.body}
let:position={positionFloating}
on:close={async ({ detail }) => {
const { reason, originalEvent } = detail;
@ -264,7 +263,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
}}
>
<Popover slot="floating">
<Popover slot="floating" let:position={positionFloating}>
<ButtonToolbar>
<FloatButtons
image={activeImage}
@ -291,7 +290,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</Popover>
</WithFloating>
<svelte:fragment slot="overlay">
<svelte:fragment slot="overlay" let:position={positionOverlay}>
<HandleBackground
on:dblclick={() => {
if (shrinkingDisabled) {

View File

@ -211,10 +211,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
offset={20}
keepOnKeyup
portalTarget={document.body}
let:position={positionFloating}
on:close={resetHandle}
>
<Popover slot="floating">
<Popover slot="floating" let:position={positionFloating}>
<MathjaxEditor
{acceptShortcut}
{newlineShortcut}

View File

@ -24,11 +24,20 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
element: StyleHTMLTag;
}
interface CustomStylesContext {
register: (id: string, object: StyleObject) => void;
deregister: (id: string) => void;
}
export function getCustomStylesContext(): CustomStylesContext {
return getContext(customStylesKey);
}
export const customStylesKey = Symbol("customStyles");
</script>
<script lang="ts">
import { setContext } from "svelte";
import { getContext, setContext } from "svelte";
import StyleLink from "./StyleLink.svelte";
import StyleTag from "./StyleTag.svelte";

View File

@ -3,14 +3,14 @@ Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="ts">
import { getContext, onDestroy } from "svelte";
import { onDestroy } from "svelte";
import { customStylesKey } from "./CustomStyles.svelte";
import { getCustomStylesContext } from "./CustomStyles.svelte";
export let id: string;
export let href: string;
const { register, deregister } = getContext(customStylesKey);
const { register, deregister } = getCustomStylesContext();
function onLoad(event: Event): void {
const link = event.target! as HTMLLinkElement;

View File

@ -3,13 +3,13 @@ Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="ts">
import { getContext, onDestroy } from "svelte";
import { onDestroy } from "svelte";
import { customStylesKey } from "./CustomStyles.svelte";
import { getCustomStylesContext } from "./CustomStyles.svelte";
export let id: string;
const { register, deregister } = getContext(customStylesKey);
const { register, deregister } = getCustomStylesContext();
function onLoad(event: Event): void {
const style = event.target! as HTMLStyleElement;

View File

@ -1,58 +0,0 @@
<!--
Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="ts">
export let symbol: string;
export let containsHTML: boolean;
export let fontFamily: string;
export let names: string[];
// Emojis can have a string length of up to 5 characters.
// This could be done better with Intl.Segmenter once it has wider support:
// const segmenter = new Intl.Segmenter();
// const displayInTwoRows = [...segmenter.segment(symbol)].length;
$: displayInTwoRows = symbol.length > 6;
</script>
<div class="symbols-entry" style:flex-direction={displayInTwoRows ? "column" : "row"}>
<div class="symbol" style:font-family={fontFamily}>
{#if containsHTML}
{@html symbol}
{:else}
{symbol}
{/if}
</div>
<div class="description">
{#each names as name}
<span class="name">
<slot symbolName={name} />
</span>
{/each}
</div>
</div>
<style lang="scss">
.symbols-entry {
display: flex;
}
.symbol {
transform: scale(1.1);
font-size: 150%;
/* The widest emojis I could find were couple_with_heart_ */
/* We should make sure it can still be properly displayed */
width: 38px;
}
.description {
align-self: center;
}
.name {
margin-left: 3px;
}
</style>

View File

@ -1,421 +0,0 @@
<!--
Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="ts">
import { fontFamilyKey } from "@tslib/context-keys";
import { getRange, getSelection } from "@tslib/cross-browser";
import { createDummyDoc } from "@tslib/parsing";
import type { Callback } from "@tslib/typing";
import { singleCallback } from "@tslib/typing";
import { getContext } from "svelte";
import type { Readable } from "svelte/store";
import DropdownItem from "../../components/DropdownItem.svelte";
import Popover from "../../components/Popover.svelte";
import WithFloating from "../../components/WithFloating.svelte";
import type { SpecialKeyParams } from "../../sveltelib/input-handler";
import type { EditingInputAPI } from "../EditingArea.svelte";
import { context } from "../NoteEditor.svelte";
import type { RichTextInputAPI } from "../rich-text-input/RichTextInput.svelte";
import { editingInputIsRichText } from "../rich-text-input/RichTextInput.svelte";
import { findSymbols, getAutoInsertSymbol, getExactSymbol } from "./symbols-table";
import type {
SymbolsEntry as SymbolsEntryType,
SymbolsTable,
} from "./symbols-types";
import SymbolsEntry from "./SymbolsEntry.svelte";
const symbolsDelimiter = ":";
const queryMinLength = 2;
const autoInsertQueryMaxLength = 5;
const whitespaceCharacters = [" ", "\u00a0"];
const { focusedInput } = context.get();
let cleanup: Callback;
let richTextInput: RichTextInputAPI | null = null;
async function initialize(input: EditingInputAPI | null): Promise<void> {
cleanup?.();
if (!input || !editingInputIsRichText(input)) {
richTextInput = null;
return;
}
cleanup = input.inputHandler.beforeInput.on(
async (input: { event: Event }): Promise<void> => onBeforeInput(input),
);
richTextInput = input;
}
$: initialize($focusedInput);
const fontFamily = getContext<Readable<string>>(fontFamilyKey);
let foundSymbols: SymbolsTable = [];
let referenceRange: Range | null = null;
let activeItem: number | null = null;
let cleanupReferenceRange: Callback;
function unsetReferenceRange() {
referenceRange = null;
activeItem = null;
cleanupReferenceRange?.();
}
function replaceText(selection: Selection, text: Text, nodes: Node[]): void {
text.deleteData(0, text.length);
text.after(...nodes);
unsetReferenceRange();
// Place caret behind it
const range = new Range();
range.setEndAfter(nodes[nodes.length - 1]);
range.collapse(false);
selection.removeAllRanges();
selection.addRange(range);
}
const parser = new DOMParser();
function symbolsEntryToReplacement(entry: SymbolsEntryType): Node[] {
if (entry.containsHTML) {
const doc = parser.parseFromString(
createDummyDoc(entry.symbol),
"text/html",
);
return [...doc.body.childNodes];
} else {
return [new Text(entry.symbol)];
}
}
function tryAutoInsert(selection: Selection, range: Range, query: string): boolean {
if (
query.length >= queryMinLength &&
query.length <= autoInsertQueryMaxLength
) {
const symbolEntry = getAutoInsertSymbol(query);
if (symbolEntry) {
const commonAncestor = range.commonAncestorContainer as Text;
const replacementLength = query.length;
commonAncestor.parentElement?.normalize();
commonAncestor.deleteData(
range.endOffset - replacementLength + 1,
replacementLength,
);
richTextInput!.inputHandler.insertText.on(
async ({ text }) => {
replaceText(
selection,
text,
symbolsEntryToReplacement(symbolEntry),
);
},
{
once: true,
},
);
return true;
}
}
return false;
}
function findValidSearchQuery(
selection: Selection,
range: Range,
startQuery = "",
shouldFinishEarly: (
selection: Selection,
range: Range,
query: string,
) => boolean = () => false,
): string | null {
if (
whitespaceCharacters.includes(startQuery) ||
startQuery === symbolsDelimiter
) {
return null;
}
const offset = range.endOffset;
if (!(range.commonAncestorContainer instanceof Text)) {
return null;
}
if (range.commonAncestorContainer.parentElement) {
// This call can change range.commonAncestor
range.commonAncestorContainer.parentElement.normalize();
}
const commonAncestorContainer = range.commonAncestorContainer;
let query = startQuery;
for (let index = offset - 1; index >= 0; index--) {
const currentCharacter = commonAncestorContainer.wholeText[index];
if (whitespaceCharacters.includes(currentCharacter)) {
return null;
} else if (currentCharacter === symbolsDelimiter) {
if (query.length < queryMinLength) {
return null;
}
return query;
}
query = currentCharacter + query;
if (shouldFinishEarly(selection, range, query)) {
return null;
}
}
return null;
}
function onSpecialKey({ event, action }): void {
if (!activeItem) {
return;
}
if (["caretLeft", "caretRight"].includes(action)) {
return unsetReferenceRange();
}
event.preventDefault();
if (action === "caretUp") {
if (activeItem === 0) {
activeItem = foundSymbols.length - 1;
} else {
activeItem--;
}
} else if (action === "caretDown") {
if (activeItem >= foundSymbols.length - 1) {
activeItem = 0;
} else {
activeItem++;
}
} else if (action === "enter" || action === "tab") {
replaceTextOnDemand(foundSymbols[activeItem]);
} else if (action === "escape") {
unsetReferenceRange();
}
}
function maybeShowOverlay(selection: Selection, event: InputEvent): void {
if (!event.data) {
return;
}
const currentRange = getRange(selection)!;
// The input event opening the overlay or triggering the auto-insert
// must be an insertion, so event.data must be a string.
// If the inputType is insertCompositionText, the event.data will
// contain the current composition, but the document will also
// contain the whole composition except the last character.
// So we only take the last character from event.data and retrieve the
// rest from the document
const startQuery = event.data[event.data.length - 1];
const query = findValidSearchQuery(
selection,
currentRange,
startQuery,
tryAutoInsert,
);
if (query) {
foundSymbols = findSymbols(query);
if (foundSymbols.length > 0) {
referenceRange = currentRange;
activeItem = 0;
cleanupReferenceRange = singleCallback(
richTextInput!.editable.focusHandler.blur.on(
async () => unsetReferenceRange(),
{
once: true,
},
),
richTextInput!.inputHandler.pointerDown.on(async () =>
unsetReferenceRange(),
),
richTextInput!.inputHandler.specialKey.on(
async (input: SpecialKeyParams) => onSpecialKey(input),
),
);
}
}
}
function replaceTextOnDemand(entry: SymbolsEntryType): void {
const commonAncestor = referenceRange!.commonAncestorContainer as Text;
const selection = getSelection(commonAncestor)!;
const replacementLength =
commonAncestor.data
.substring(0, referenceRange!.endOffset)
.split("")
.reverse()
.join("")
.indexOf(symbolsDelimiter) + 1;
commonAncestor.deleteData(
referenceRange!.endOffset - replacementLength,
replacementLength + 1,
);
const nodes = symbolsEntryToReplacement(entry);
commonAncestor.after(...nodes);
const range = new Range();
range.setEndAfter(nodes[nodes.length - 1]);
range.collapse(false);
selection.removeAllRanges();
selection.addRange(range);
unsetReferenceRange();
}
function prepareInsertion(selection: Selection, query: string): void {
const symbolEntry = getExactSymbol(query);
if (!symbolEntry) {
return unsetReferenceRange();
}
const currentRange = getRange(selection)!;
const offset = currentRange.endOffset;
if (
!(currentRange.commonAncestorContainer instanceof Text) ||
offset < queryMinLength
) {
return unsetReferenceRange();
}
const commonAncestor = currentRange.commonAncestorContainer;
const replacementLength =
commonAncestor.data
.substring(0, currentRange.endOffset)
.split("")
.reverse()
.join("")
.indexOf(symbolsDelimiter) + 1;
commonAncestor.deleteData(
currentRange.endOffset - replacementLength,
replacementLength,
);
richTextInput!.inputHandler.insertText.on(
async ({ text }) =>
replaceText(selection, text, symbolsEntryToReplacement(symbolEntry)),
{
once: true,
},
);
}
function updateOverlay(selection: Selection, event: InputEvent): void {
if (event.data === symbolsDelimiter) {
const query = findValidSearchQuery(selection, getRange(selection)!);
if (query) {
prepareInsertion(selection, query);
} else {
unsetReferenceRange();
}
}
// We have to wait for afterInput to update the symbols, because we also
// want to update in the case of a deletion
richTextInput!.inputHandler.afterInput.on(
async (): Promise<void> => {
const currentRange = getRange(selection)!;
const query = findValidSearchQuery(selection, currentRange);
if (!query) {
return unsetReferenceRange();
}
foundSymbols = findSymbols(query);
if (foundSymbols.length === 0) {
unsetReferenceRange();
} else {
referenceRange = currentRange;
}
},
{ once: true },
);
}
function onBeforeInput({ event }): void {
const selection = getSelection(event.target)!;
if (referenceRange) {
updateOverlay(selection, event);
} else {
maybeShowOverlay(selection, event);
}
}
</script>
<div class="symbols-overlay">
{#if referenceRange}
<WithFloating reference={referenceRange} preferredPlacement="top" offset={10}>
<Popover slot="floating" --popover-padding-inline="0">
<div class="symbols-menu">
{#each foundSymbols as found, index (found.symbol)}
<DropdownItem
active={index === activeItem}
on:click={() => replaceTextOnDemand(found)}
>
<SymbolsEntry
let:symbolName
symbol={found.symbol}
names={found.names}
containsHTML={Boolean(found.containsHTML)}
fontFamily={$fontFamily}
>
{symbolsDelimiter}{symbolName}{symbolsDelimiter}
</SymbolsEntry>
</DropdownItem>
{/each}
</div>
</Popover>
</WithFloating>
{/if}
</div>
<style lang="scss">
.symbols-menu {
display: flex;
flex-flow: column nowrap;
min-width: 140px;
max-height: 15rem;
font-size: 12px;
overflow: hidden auto;
text-overflow: ellipsis;
}
</style>

View File

@ -1,33 +0,0 @@
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import { characterEntities } from "character-entities";
import type { SymbolsTable } from "./symbols-types";
// Not all characters work well in the editor field
delete characterEntities["Tab"];
// A single character entity can be present under different names
// So we change the mapping to symbol => name[]
const characterTable: Record<string, string[]> = {};
for (const [name, character] of Object.entries(characterEntities)) {
if (character in characterTable) {
characterTable[character].push(name);
} else {
characterTable[character] = [name];
}
}
const characterSymbolsTable: SymbolsTable = [];
for (const [character, names] of Object.entries(characterTable)) {
characterSymbolsTable.push({
symbol: character,
names,
tags: [],
});
}
export default characterSymbolsTable;

View File

@ -1,18 +0,0 @@
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import { gemoji } from "gemoji";
import type { SymbolsTable } from "./symbols-types";
const gemojiSymbolsTable: SymbolsTable = [];
for (const { emoji, names, tags } of gemoji) {
gemojiSymbolsTable.push({
symbol: emoji,
names,
tags,
});
}
export default gemojiSymbolsTable;

View File

@ -1,6 +0,0 @@
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import SymbolsOverlay from "./SymbolsOverlay.svelte";
export default SymbolsOverlay;

View File

@ -1,54 +0,0 @@
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import Fuse from "fuse.js";
import characterEntities from "./character-entities";
import gemoji from "./gemoji";
import type { SymbolsEntry, SymbolsTable } from "./symbols-types";
const symbolsTable: SymbolsTable = [...characterEntities, ...gemoji];
const symbolsFuse = new Fuse(symbolsTable, {
threshold: 0.2,
minMatchCharLength: 2,
useExtendedSearch: true,
isCaseSensitive: true,
keys: [
{
name: "names",
weight: 7,
},
{
name: "tags",
weight: 3,
},
{
name: "autoInsert",
weight: 0.1,
},
{
name: "containsHTML",
weight: 0.1,
},
],
});
export function findSymbols(query: string): SymbolsTable {
return symbolsFuse.search(query).map(({ item }) => item);
}
export function getExactSymbol(query: string): SymbolsEntry | null {
const [found] = symbolsFuse.search({ names: `="${query}"` }, { limit: 1 });
return found ? found.item : null;
}
export function getAutoInsertSymbol(query: string): SymbolsEntry | null {
const [found] = symbolsFuse.search({
names: `="${query}"`,
autoInsert: "=autoInsert",
});
return found ? found.item : null;
}

View File

@ -1,27 +0,0 @@
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export interface SymbolsEntry {
symbol: string;
/**
* Used for searching and direct insertion
*/
names: string[];
/**
* Used for searching
*/
tags: string[];
/**
* If symbols contain HTML, they need to be treated specially.
*/
containsHTML?: "containsHTML";
/**
* Symbols can be automak inserted, when you enter a full name within delimiters.
* If you enable auto insertion, you can use direction insertion without
* using the delimiter and triggering the search dropdown.
* To falicitate interacting with fuse.js this is a string value rather than a boolean.
*/
autoInsert?: "autoInsert";
}
export type SymbolsTable = SymbolsEntry[];

View File

@ -4,7 +4,6 @@
"*",
"image-overlay/*",
"mathjax-overlay/*",
"symbols-overlay/*",
"plain-text-input/*",
"rich-text-input/*",
"editor-toolbar/*"

View File

@ -4,7 +4,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="ts">
import { bridgeCommand } from "@tslib/bridgecommand";
import type { SvelteComponentDev } from "svelte/internal";
import type { SvelteComponent } from "svelte";
import { writable } from "svelte/store";
import { pageTheme } from "../sveltelib/theme";
@ -16,9 +16,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const search = writable(initialSearch);
const days = writable(initialDays);
export let graphs: typeof SvelteComponentDev[];
export let graphs: typeof SvelteComponent<any>[];
/** See RangeBox */
export let controller: typeof SvelteComponentDev | null;
export let controller: typeof SvelteComponent<any> | null;
function browserSearch(event: CustomEvent) {
bridgeCommand(`browserSearch: ${$search} ${event.detail.query}`);

View File

@ -1,22 +1,26 @@
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
/* eslint
@typescript-eslint/no-explicit-any: "off",
*/
import "./graphs-base.scss";
import { ModuleName, setupI18n } from "@tslib/i18n";
import { checkNightMode } from "@tslib/nightmode";
import type { SvelteComponentDev } from "svelte/internal";
import type { SvelteComponent } from "svelte";
import GraphsPage from "./GraphsPage.svelte";
const i18n = setupI18n({ modules: [ModuleName.STATISTICS, ModuleName.SCHEDULING] });
export async function setupGraphs(
graphs: typeof SvelteComponentDev[],
graphs: typeof SvelteComponent<any>[],
{
search = "deck:current",
days = 365,
controller = null as typeof SvelteComponentDev | null,
controller = null as typeof SvelteComponent<any> | null,
} = {},
): Promise<GraphsPage> {
checkNightMode();

View File

@ -12,5 +12,5 @@ module.exports = {
"<rootDir>/lib$1",
],
},
transformIgnorePatterns: ["/node_modules/(?!(lodash-es)/)"],
transformIgnorePatterns: ["/node_modules/(?!(lodash-es|svelte)/)"],
};

View File

@ -1,6 +1,8 @@
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import { marked } from "marked";
export type Callback = () => void;
export function removeItem<T>(items: T[], item: T): void {
@ -10,3 +12,7 @@ export function removeItem<T>(items: T[], item: T): void {
items.splice(index, 1);
}
}
export function renderMarkdown(text: string): string {
return marked(text, { mangle: false, headerIds: false });
}

View File

@ -7,6 +7,7 @@ export function checkNightMode(): boolean {
const nightMode = window.location.hash == "#night";
if (nightMode) {
document.documentElement.className = "night-mode";
document.documentElement.dataset.bsTheme = "dark";
}
return nightMode;
}

View File

@ -5,21 +5,21 @@
"path": "node_modules/@bufbuild/protobuf",
"licenseFile": "node_modules/@bufbuild/protobuf/README.md"
},
"@floating-ui/core@0.5.1": {
"@floating-ui/core@1.3.1": {
"licenses": "MIT",
"repository": "https://github.com/floating-ui/floating-ui",
"publisher": "atomiks",
"path": "node_modules/@floating-ui/core",
"licenseFile": "node_modules/@floating-ui/core/README.md"
"licenseFile": "node_modules/@floating-ui/core/LICENSE"
},
"@floating-ui/dom@0.3.1": {
"@floating-ui/dom@1.4.3": {
"licenses": "MIT",
"repository": "https://github.com/floating-ui/floating-ui",
"publisher": "atomiks",
"path": "node_modules/@floating-ui/dom",
"licenseFile": "node_modules/@floating-ui/dom/README.md"
"licenseFile": "node_modules/@floating-ui/dom/LICENSE"
},
"@fluent/bundle@0.17.1": {
"@fluent/bundle@0.18.0": {
"licenses": "Apache-2.0",
"repository": "https://github.com/projectfluent/fluent.js",
"publisher": "Mozilla",
@ -27,14 +27,14 @@
"path": "node_modules/@fluent/bundle",
"licenseFile": "node_modules/@fluent/bundle/README.md"
},
"@mdi/svg@7.0.96": {
"@mdi/svg@7.2.96": {
"licenses": "Apache-2.0",
"repository": "https://github.com/Templarian/MaterialDesign-SVG",
"publisher": "Austin Andrews",
"path": "node_modules/@mdi/svg",
"licenseFile": "node_modules/@mdi/svg/LICENSE"
},
"@popperjs/core@2.11.4": {
"@popperjs/core@2.11.8": {
"licenses": "MIT",
"repository": "https://github.com/popperjs/popper-core",
"publisher": "Federico Zivolo",
@ -47,29 +47,10 @@
"repository": "https://github.com/TooTallNate/once",
"publisher": "Nathan Rajlich",
"email": "nathan@tootallnate.net",
"url": "http://n8.io/",
"path": "node_modules/@tootallnate/once",
"licenseFile": "node_modules/@tootallnate/once/LICENSE"
},
"@types/lodash-es@4.17.6": {
"licenses": "MIT",
"repository": "https://github.com/DefinitelyTyped/DefinitelyTyped",
"path": "node_modules/@types/lodash-es",
"licenseFile": "node_modules/@types/lodash-es/LICENSE"
},
"@types/lodash@4.14.180": {
"licenses": "MIT",
"repository": "https://github.com/DefinitelyTyped/DefinitelyTyped",
"path": "node_modules/@types/lodash",
"licenseFile": "node_modules/@types/lodash/LICENSE"
},
"@types/marked@4.0.3": {
"licenses": "MIT",
"repository": "https://github.com/DefinitelyTyped/DefinitelyTyped",
"path": "node_modules/@types/marked",
"licenseFile": "node_modules/@types/marked/LICENSE"
},
"abab@2.0.5": {
"abab@2.0.6": {
"licenses": "BSD-3-Clause",
"repository": "https://github.com/jsdom/abab",
"publisher": "Jeff Carpenter",
@ -93,21 +74,20 @@
"acorn@7.4.1": {
"licenses": "MIT",
"repository": "https://github.com/acornjs/acorn",
"path": "node_modules/acorn",
"licenseFile": "node_modules/acorn/LICENSE"
"path": "node_modules/acorn-globals/node_modules/acorn",
"licenseFile": "node_modules/acorn-globals/node_modules/acorn/LICENSE"
},
"acorn@8.7.0": {
"acorn@8.9.0": {
"licenses": "MIT",
"repository": "https://github.com/acornjs/acorn",
"path": "node_modules/jsdom/node_modules/acorn",
"licenseFile": "node_modules/jsdom/node_modules/acorn/LICENSE"
"path": "node_modules/acorn",
"licenseFile": "node_modules/acorn/LICENSE"
},
"agent-base@6.0.2": {
"licenses": "MIT",
"repository": "https://github.com/TooTallNate/node-agent-base",
"publisher": "Nathan Rajlich",
"email": "nathan@tootallnate.net",
"url": "http://n8.io/",
"path": "node_modules/agent-base",
"licenseFile": "node_modules/agent-base/README.md"
},
@ -134,18 +114,17 @@
"path": "node_modules/bezier-easing",
"licenseFile": "node_modules/bezier-easing/LICENSE"
},
"bootstrap-icons@1.8.1": {
"bootstrap-icons@1.10.5": {
"licenses": "MIT",
"repository": "https://github.com/twbs/icons",
"publisher": "mdo",
"path": "node_modules/bootstrap-icons",
"licenseFile": "node_modules/bootstrap-icons/LICENSE.md"
"licenseFile": "node_modules/bootstrap-icons/LICENSE"
},
"bootstrap@5.0.2": {
"bootstrap@5.3.0": {
"licenses": "MIT",
"repository": "https://github.com/twbs/bootstrap",
"publisher": "The Bootstrap Authors",
"url": "https://github.com/twbs/bootstrap/graphs/contributors",
"path": "node_modules/bootstrap",
"licenseFile": "node_modules/bootstrap/LICENSE"
},
@ -156,21 +135,11 @@
"path": "node_modules/browser-process-hrtime",
"licenseFile": "node_modules/browser-process-hrtime/LICENSE"
},
"character-entities@2.0.2": {
"licenses": "MIT",
"repository": "https://github.com/wooorm/character-entities",
"publisher": "Titus Wormer",
"email": "tituswormer@gmail.com",
"url": "https://wooorm.com",
"path": "node_modules/character-entities",
"licenseFile": "node_modules/character-entities/license"
},
"codemirror@5.65.2": {
"codemirror@5.65.13": {
"licenses": "MIT",
"repository": "https://github.com/codemirror/CodeMirror",
"publisher": "Marijn Haverbeke",
"email": "marijnh@gmail.com",
"url": "http://marijnhaverbeke.nl",
"email": "marijn@haverbeke.berlin",
"path": "node_modules/codemirror",
"licenseFile": "node_modules/codemirror/LICENSE"
},
@ -179,7 +148,6 @@
"repository": "https://github.com/felixge/node-combined-stream",
"publisher": "Felix Geisendörfer",
"email": "felix@debuggable.com",
"url": "http://debuggable.com/",
"path": "node_modules/combined-stream",
"licenseFile": "node_modules/combined-stream/License"
},
@ -220,11 +188,10 @@
"path": "node_modules/cssstyle",
"licenseFile": "node_modules/cssstyle/LICENSE"
},
"d3-array@3.2.0": {
"d3-array@3.2.4": {
"licenses": "ISC",
"repository": "https://github.com/d3/d3-array",
"publisher": "Mike Bostock",
"url": "http://bost.ocks.org/mike",
"path": "node_modules/d3-array",
"licenseFile": "node_modules/d3-array/LICENSE"
},
@ -232,7 +199,6 @@
"licenses": "ISC",
"repository": "https://github.com/d3/d3-axis",
"publisher": "Mike Bostock",
"url": "https://bost.ocks.org/mike",
"path": "node_modules/d3-axis",
"licenseFile": "node_modules/d3-axis/LICENSE"
},
@ -240,7 +206,6 @@
"licenses": "ISC",
"repository": "https://github.com/d3/d3-brush",
"publisher": "Mike Bostock",
"url": "https://bost.ocks.org/mike",
"path": "node_modules/d3-brush",
"licenseFile": "node_modules/d3-brush/LICENSE"
},
@ -248,7 +213,6 @@
"licenses": "ISC",
"repository": "https://github.com/d3/d3-chord",
"publisher": "Mike Bostock",
"url": "http://bost.ocks.org/mike",
"path": "node_modules/d3-chord",
"licenseFile": "node_modules/d3-chord/LICENSE"
},
@ -256,23 +220,20 @@
"licenses": "ISC",
"repository": "https://github.com/d3/d3-color",
"publisher": "Mike Bostock",
"url": "http://bost.ocks.org/mike",
"path": "node_modules/d3-color",
"licenseFile": "node_modules/d3-color/LICENSE"
},
"d3-contour@4.0.0": {
"d3-contour@4.0.2": {
"licenses": "ISC",
"repository": "https://github.com/d3/d3-contour",
"publisher": "Mike Bostock",
"url": "http://bost.ocks.org/mike",
"path": "node_modules/d3-contour",
"licenseFile": "node_modules/d3-contour/LICENSE"
},
"d3-delaunay@6.0.2": {
"d3-delaunay@6.0.4": {
"licenses": "ISC",
"repository": "https://github.com/d3/d3-delaunay",
"publisher": "Mike Bostock",
"url": "https://bost.ocks.org/mike",
"path": "node_modules/d3-delaunay",
"licenseFile": "node_modules/d3-delaunay/LICENSE"
},
@ -280,7 +241,6 @@
"licenses": "ISC",
"repository": "https://github.com/d3/d3-dispatch",
"publisher": "Mike Bostock",
"url": "http://bost.ocks.org/mike",
"path": "node_modules/d3-dispatch",
"licenseFile": "node_modules/d3-dispatch/LICENSE"
},
@ -288,7 +248,6 @@
"licenses": "ISC",
"repository": "https://github.com/d3/d3-drag",
"publisher": "Mike Bostock",
"url": "https://bost.ocks.org/mike",
"path": "node_modules/d3-drag",
"licenseFile": "node_modules/d3-drag/LICENSE"
},
@ -296,7 +255,6 @@
"licenses": "ISC",
"repository": "https://github.com/d3/d3-dsv",
"publisher": "Mike Bostock",
"url": "http://bost.ocks.org/mike",
"path": "node_modules/d3-dsv",
"licenseFile": "node_modules/d3-dsv/LICENSE"
},
@ -304,7 +262,6 @@
"licenses": "BSD-3-Clause",
"repository": "https://github.com/d3/d3-ease",
"publisher": "Mike Bostock",
"url": "http://bost.ocks.org/mike",
"path": "node_modules/d3-ease",
"licenseFile": "node_modules/d3-ease/LICENSE"
},
@ -312,7 +269,6 @@
"licenses": "ISC",
"repository": "https://github.com/d3/d3-fetch",
"publisher": "Mike Bostock",
"url": "http://bost.ocks.org/mike",
"path": "node_modules/d3-fetch",
"licenseFile": "node_modules/d3-fetch/LICENSE"
},
@ -320,7 +276,6 @@
"licenses": "ISC",
"repository": "https://github.com/d3/d3-force",
"publisher": "Mike Bostock",
"url": "https://bost.ocks.org/mike",
"path": "node_modules/d3-force",
"licenseFile": "node_modules/d3-force/LICENSE"
},
@ -328,15 +283,13 @@
"licenses": "ISC",
"repository": "https://github.com/d3/d3-format",
"publisher": "Mike Bostock",
"url": "http://bost.ocks.org/mike",
"path": "node_modules/d3-format",
"licenseFile": "node_modules/d3-format/LICENSE"
},
"d3-geo@3.0.1": {
"d3-geo@3.1.0": {
"licenses": "ISC",
"repository": "https://github.com/d3/d3-geo",
"publisher": "Mike Bostock",
"url": "https://bost.ocks.org/mike",
"path": "node_modules/d3-geo",
"licenseFile": "node_modules/d3-geo/LICENSE"
},
@ -344,7 +297,6 @@
"licenses": "ISC",
"repository": "https://github.com/d3/d3-hierarchy",
"publisher": "Mike Bostock",
"url": "http://bost.ocks.org/mike",
"path": "node_modules/d3-hierarchy",
"licenseFile": "node_modules/d3-hierarchy/LICENSE"
},
@ -352,15 +304,13 @@
"licenses": "ISC",
"repository": "https://github.com/d3/d3-interpolate",
"publisher": "Mike Bostock",
"url": "http://bost.ocks.org/mike",
"path": "node_modules/d3-interpolate",
"licenseFile": "node_modules/d3-interpolate/LICENSE"
},
"d3-path@3.0.1": {
"d3-path@3.1.0": {
"licenses": "ISC",
"repository": "https://github.com/d3/d3-path",
"publisher": "Mike Bostock",
"url": "http://bost.ocks.org/mike",
"path": "node_modules/d3-path",
"licenseFile": "node_modules/d3-path/LICENSE"
},
@ -368,7 +318,6 @@
"licenses": "ISC",
"repository": "https://github.com/d3/d3-polygon",
"publisher": "Mike Bostock",
"url": "http://bost.ocks.org/mike",
"path": "node_modules/d3-polygon",
"licenseFile": "node_modules/d3-polygon/LICENSE"
},
@ -376,7 +325,6 @@
"licenses": "ISC",
"repository": "https://github.com/d3/d3-quadtree",
"publisher": "Mike Bostock",
"url": "http://bost.ocks.org/mike",
"path": "node_modules/d3-quadtree",
"licenseFile": "node_modules/d3-quadtree/LICENSE"
},
@ -384,7 +332,6 @@
"licenses": "ISC",
"repository": "https://github.com/d3/d3-random",
"publisher": "Mike Bostock",
"url": "http://bost.ocks.org/mike",
"path": "node_modules/d3-random",
"licenseFile": "node_modules/d3-random/LICENSE"
},
@ -392,7 +339,6 @@
"licenses": "ISC",
"repository": "https://github.com/d3/d3-scale-chromatic",
"publisher": "Mike Bostock",
"url": "https://bost.ocks.org/mike",
"path": "node_modules/d3-scale-chromatic",
"licenseFile": "node_modules/d3-scale-chromatic/LICENSE"
},
@ -400,7 +346,6 @@
"licenses": "ISC",
"repository": "https://github.com/d3/d3-scale",
"publisher": "Mike Bostock",
"url": "https://bost.ocks.org/mike",
"path": "node_modules/d3-scale",
"licenseFile": "node_modules/d3-scale/LICENSE"
},
@ -408,15 +353,13 @@
"licenses": "ISC",
"repository": "https://github.com/d3/d3-selection",
"publisher": "Mike Bostock",
"url": "https://bost.ocks.org/mike",
"path": "node_modules/d3-selection",
"licenseFile": "node_modules/d3-selection/LICENSE"
},
"d3-shape@3.1.0": {
"d3-shape@3.2.0": {
"licenses": "ISC",
"repository": "https://github.com/d3/d3-shape",
"publisher": "Mike Bostock",
"url": "http://bost.ocks.org/mike",
"path": "node_modules/d3-shape",
"licenseFile": "node_modules/d3-shape/LICENSE"
},
@ -424,15 +367,13 @@
"licenses": "ISC",
"repository": "https://github.com/d3/d3-time-format",
"publisher": "Mike Bostock",
"url": "http://bost.ocks.org/mike",
"path": "node_modules/d3-time-format",
"licenseFile": "node_modules/d3-time-format/LICENSE"
},
"d3-time@3.0.0": {
"d3-time@3.1.0": {
"licenses": "ISC",
"repository": "https://github.com/d3/d3-time",
"publisher": "Mike Bostock",
"url": "http://bost.ocks.org/mike",
"path": "node_modules/d3-time",
"licenseFile": "node_modules/d3-time/LICENSE"
},
@ -440,7 +381,6 @@
"licenses": "ISC",
"repository": "https://github.com/d3/d3-timer",
"publisher": "Mike Bostock",
"url": "http://bost.ocks.org/mike",
"path": "node_modules/d3-timer",
"licenseFile": "node_modules/d3-timer/LICENSE"
},
@ -448,7 +388,6 @@
"licenses": "ISC",
"repository": "https://github.com/d3/d3-transition",
"publisher": "Mike Bostock",
"url": "https://bost.ocks.org/mike",
"path": "node_modules/d3-transition",
"licenseFile": "node_modules/d3-transition/LICENSE"
},
@ -456,24 +395,21 @@
"licenses": "ISC",
"repository": "https://github.com/d3/d3-zoom",
"publisher": "Mike Bostock",
"url": "https://bost.ocks.org/mike",
"path": "node_modules/d3-zoom",
"licenseFile": "node_modules/d3-zoom/LICENSE"
},
"d3@7.6.1": {
"d3@7.8.5": {
"licenses": "ISC",
"repository": "https://github.com/d3/d3",
"publisher": "Mike Bostock",
"url": "https://bost.ocks.org/mike",
"path": "node_modules/d3",
"licenseFile": "node_modules/d3/LICENSE"
},
"data-urls@3.0.1": {
"data-urls@3.0.2": {
"licenses": "MIT",
"repository": "https://github.com/jsdom/data-urls",
"publisher": "Domenic Denicola",
"email": "d@domenic.me",
"url": "https://domenic.me/",
"path": "node_modules/data-urls",
"licenseFile": "node_modules/data-urls/LICENSE.txt"
},
@ -485,7 +421,7 @@
"path": "node_modules/debug",
"licenseFile": "node_modules/debug/LICENSE"
},
"decimal.js@10.3.1": {
"decimal.js@10.4.3": {
"licenses": "MIT",
"repository": "https://github.com/MikeMcl/decimal.js",
"publisher": "Michael Mclaughlin",
@ -493,15 +429,6 @@
"path": "node_modules/decimal.js",
"licenseFile": "node_modules/decimal.js/LICENCE.md"
},
"deep-is@0.1.4": {
"licenses": "MIT",
"repository": "https://github.com/thlorenz/deep-is",
"publisher": "Thorsten Lorenz",
"email": "thlorenz@gmx.de",
"url": "http://thlorenz.com",
"path": "node_modules/deep-is",
"licenseFile": "node_modules/deep-is/LICENSE"
},
"delaunator@5.0.0": {
"licenses": "ISC",
"repository": "https://github.com/mapbox/delaunator",
@ -514,7 +441,6 @@
"repository": "https://github.com/felixge/node-delayed-stream",
"publisher": "Felix Geisendörfer",
"email": "felix@debuggable.com",
"url": "http://debuggable.com/",
"path": "node_modules/delayed-stream",
"licenseFile": "node_modules/delayed-stream/License"
},
@ -523,7 +449,6 @@
"repository": "https://github.com/jsdom/domexception",
"publisher": "Domenic Denicola",
"email": "d@domenic.me",
"url": "https://domenic.me/",
"path": "node_modules/domexception",
"licenseFile": "node_modules/domexception/LICENSE.txt"
},
@ -531,7 +456,7 @@
"licenses": "ISC",
"path": "node_modules/canvas"
},
"escodegen@2.0.0": {
"escodegen@2.1.0": {
"licenses": "BSD-2-Clause",
"repository": "https://github.com/estools/escodegen",
"path": "node_modules/escodegen",
@ -565,48 +490,19 @@
"path": "node_modules/fabric",
"licenseFile": "node_modules/fabric/LICENSE"
},
"fast-levenshtein@2.0.6": {
"licenses": "MIT",
"repository": "https://github.com/hiddentao/fast-levenshtein",
"publisher": "Ramesh Nair",
"email": "ram@hiddentao.com",
"url": "http://www.hiddentao.com/",
"path": "node_modules/fast-levenshtein",
"licenseFile": "node_modules/fast-levenshtein/LICENSE.md"
},
"form-data@4.0.0": {
"licenses": "MIT",
"repository": "https://github.com/form-data/form-data",
"publisher": "Felix Geisendörfer",
"email": "felix@debuggable.com",
"url": "http://debuggable.com/",
"path": "node_modules/form-data",
"licenseFile": "node_modules/form-data/License"
},
"fuse.js@6.6.2": {
"licenses": "Apache-2.0",
"repository": "https://github.com/krisk/Fuse",
"publisher": "Kiro Risk",
"email": "kirollos@gmail.com",
"url": "http://kiro.me",
"path": "node_modules/fuse.js",
"licenseFile": "node_modules/fuse.js/LICENSE"
},
"gemoji@7.1.0": {
"licenses": "MIT",
"repository": "https://github.com/wooorm/gemoji",
"publisher": "Titus Wormer",
"email": "tituswormer@gmail.com",
"url": "https://wooorm.com",
"path": "node_modules/gemoji",
"licenseFile": "node_modules/gemoji/license"
},
"html-encoding-sniffer@3.0.0": {
"licenses": "MIT",
"repository": "https://github.com/jsdom/html-encoding-sniffer",
"publisher": "Domenic Denicola",
"email": "d@domenic.me",
"url": "https://domenic.me/",
"path": "node_modules/html-encoding-sniffer",
"licenseFile": "node_modules/html-encoding-sniffer/LICENSE.txt"
},
@ -615,16 +511,14 @@
"repository": "https://github.com/TooTallNate/node-http-proxy-agent",
"publisher": "Nathan Rajlich",
"email": "nathan@tootallnate.net",
"url": "http://n8.io/",
"path": "node_modules/http-proxy-agent",
"licenseFile": "node_modules/http-proxy-agent/README.md"
},
"https-proxy-agent@5.0.0": {
"https-proxy-agent@5.0.1": {
"licenses": "MIT",
"repository": "https://github.com/TooTallNate/node-https-proxy-agent",
"publisher": "Nathan Rajlich",
"email": "nathan@tootallnate.net",
"url": "http://n8.io/",
"path": "node_modules/https-proxy-agent",
"licenseFile": "node_modules/https-proxy-agent/README.md"
},
@ -640,11 +534,10 @@
"licenses": "ISC",
"repository": "https://github.com/mbostock/internmap",
"publisher": "Mike Bostock",
"url": "https://bost.ocks.org/mike",
"path": "node_modules/internmap",
"licenseFile": "node_modules/internmap/LICENSE"
},
"intl-pluralrules@1.3.1": {
"intl-pluralrules@2.0.0": {
"licenses": "ISC",
"repository": "https://github.com/eemeli/intl-pluralrules",
"publisher": "Eemeli Aro",
@ -656,23 +549,20 @@
"licenses": "MIT",
"repository": "https://github.com/mathiasbynens/is-potential-custom-element-name",
"publisher": "Mathias Bynens",
"url": "https://mathiasbynens.be/",
"path": "node_modules/is-potential-custom-element-name",
"licenseFile": "node_modules/is-potential-custom-element-name/LICENSE-MIT.txt"
},
"jquery-ui-dist@1.13.1": {
"jquery-ui-dist@1.13.2": {
"licenses": "MIT",
"repository": "https://github.com/jquery/jquery-ui",
"publisher": "jQuery Foundation and other contributors",
"url": "https://github.com/jquery/jquery-ui/blob/1.13.1/AUTHORS.txt",
"path": "node_modules/jquery-ui-dist",
"licenseFile": "node_modules/jquery-ui-dist/LICENSE.txt"
},
"jquery@3.6.0": {
"jquery@3.7.0": {
"licenses": "MIT",
"repository": "https://github.com/jquery/jquery",
"publisher": "OpenJS Foundation and other contributors",
"url": "https://github.com/jquery/jquery/blob/3.6.0/AUTHORS.txt",
"path": "node_modules/jquery",
"licenseFile": "node_modules/jquery/LICENSE.txt"
},
@ -682,14 +572,6 @@
"path": "node_modules/jsdom",
"licenseFile": "node_modules/jsdom/LICENSE.txt"
},
"levn@0.3.0": {
"licenses": "MIT",
"repository": "https://github.com/gkz/levn",
"publisher": "George Zahariev",
"email": "z@georgezahariev.com",
"path": "node_modules/escodegen/node_modules/levn",
"licenseFile": "node_modules/escodegen/node_modules/levn/LICENSE"
},
"lodash-es@4.17.21": {
"licenses": "MIT",
"repository": "https://github.com/lodash/lodash",
@ -698,7 +580,7 @@
"path": "node_modules/lodash-es",
"licenseFile": "node_modules/lodash-es/LICENSE"
},
"marked@4.0.12": {
"marked@5.1.0": {
"licenses": "MIT",
"repository": "https://github.com/markedjs/marked",
"publisher": "Christopher Jeffrey",
@ -736,23 +618,14 @@
"path": "node_modules/ngraph.events",
"licenseFile": "node_modules/ngraph.events/LICENSE"
},
"nwsapi@2.2.0": {
"nwsapi@2.2.5": {
"licenses": "MIT",
"repository": "https://github.com/dperini/nwsapi",
"publisher": "Diego Perini",
"email": "diego.perini@gmail.com",
"url": "http://www.iport.it/",
"path": "node_modules/nwsapi",
"licenseFile": "node_modules/nwsapi/LICENSE"
},
"optionator@0.8.3": {
"licenses": "MIT",
"repository": "https://github.com/gkz/optionator",
"publisher": "George Zahariev",
"email": "z@georgezahariev.com",
"path": "node_modules/escodegen/node_modules/optionator",
"licenseFile": "node_modules/escodegen/node_modules/optionator/LICENSE"
},
"panzoom@9.4.3": {
"licenses": "MIT",
"repository": "https://github.com/anvaka/panzoom",
@ -765,36 +638,39 @@
"repository": "https://github.com/inikulin/parse5",
"publisher": "Ivan Nikulin",
"email": "ifaaan@gmail.com",
"url": "https://github.com/inikulin",
"path": "node_modules/parse5",
"licenseFile": "node_modules/parse5/LICENSE"
},
"prelude-ls@1.1.2": {
"licenses": "MIT",
"repository": "https://github.com/gkz/prelude-ls",
"publisher": "George Zahariev",
"email": "z@georgezahariev.com",
"path": "node_modules/prelude-ls",
"licenseFile": "node_modules/prelude-ls/LICENSE"
},
"psl@1.8.0": {
"psl@1.9.0": {
"licenses": "MIT",
"repository": "https://github.com/lupomontero/psl",
"publisher": "Lupo Montero",
"email": "lupomontero@gmail.com",
"url": "https://lupomontero.com/",
"path": "node_modules/psl",
"licenseFile": "node_modules/psl/LICENSE"
},
"punycode@2.1.1": {
"punycode@2.3.0": {
"licenses": "MIT",
"repository": "https://github.com/bestiejs/punycode.js",
"repository": "https://github.com/mathiasbynens/punycode.js",
"publisher": "Mathias Bynens",
"url": "https://mathiasbynens.be/",
"path": "node_modules/punycode",
"licenseFile": "node_modules/punycode/LICENSE-MIT.txt"
},
"robust-predicates@3.0.1": {
"querystringify@2.2.0": {
"licenses": "MIT",
"repository": "https://github.com/unshiftio/querystringify",
"publisher": "Arnout Kazemier",
"path": "node_modules/querystringify",
"licenseFile": "node_modules/querystringify/LICENSE"
},
"requires-port@1.0.0": {
"licenses": "MIT",
"repository": "https://github.com/unshiftio/requires-port",
"publisher": "Arnout Kazemier",
"path": "node_modules/requires-port",
"licenseFile": "node_modules/requires-port/LICENSE"
},
"robust-predicates@3.0.2": {
"licenses": "Unlicense",
"repository": "https://github.com/mourner/robust-predicates",
"publisher": "Vladimir Agafonkin",
@ -805,7 +681,6 @@
"licenses": "BSD-3-Clause",
"repository": "https://github.com/mbostock/rw",
"publisher": "Mike Bostock",
"url": "http://bost.ocks.org/mike",
"path": "node_modules/rw",
"licenseFile": "node_modules/rw/LICENSE"
},
@ -814,7 +689,6 @@
"repository": "https://github.com/ChALkeR/safer-buffer",
"publisher": "Nikita Skovoroda",
"email": "chalkerx@gmail.com",
"url": "https://github.com/ChALkeR",
"path": "node_modules/safer-buffer",
"licenseFile": "node_modules/safer-buffer/LICENSE"
},
@ -842,7 +716,7 @@
"path": "node_modules/symbol-tree",
"licenseFile": "node_modules/symbol-tree/LICENSE"
},
"tough-cookie@4.0.0": {
"tough-cookie@4.1.3": {
"licenses": "BSD-3-Clause",
"repository": "https://github.com/salesforce/tough-cookie",
"publisher": "Jeremy Stashewsky",
@ -858,15 +732,7 @@
"path": "node_modules/tr46",
"licenseFile": "node_modules/tr46/LICENSE.md"
},
"type-check@0.3.2": {
"licenses": "MIT",
"repository": "https://github.com/gkz/type-check",
"publisher": "George Zahariev",
"email": "z@georgezahariev.com",
"path": "node_modules/type-check",
"licenseFile": "node_modules/type-check/LICENSE"
},
"universalify@0.1.2": {
"universalify@0.2.0": {
"licenses": "MIT",
"repository": "https://github.com/RyanZim/universalify",
"publisher": "Ryan Zimmerman",
@ -874,6 +740,13 @@
"path": "node_modules/universalify",
"licenseFile": "node_modules/universalify/LICENSE"
},
"url-parse@1.5.10": {
"licenses": "MIT",
"repository": "https://github.com/unshiftio/url-parse",
"publisher": "Arnout Kazemier",
"path": "node_modules/url-parse",
"licenseFile": "node_modules/url-parse/LICENSE"
},
"w3c-hr-time@1.0.2": {
"licenses": "MIT",
"repository": "https://github.com/jsdom/w3c-hr-time",
@ -893,7 +766,6 @@
"repository": "https://github.com/jsdom/webidl-conversions",
"publisher": "Domenic Denicola",
"email": "d@domenic.me",
"url": "https://domenic.me/",
"path": "node_modules/webidl-conversions",
"licenseFile": "node_modules/webidl-conversions/LICENSE.md"
},
@ -902,7 +774,6 @@
"repository": "https://github.com/jsdom/whatwg-encoding",
"publisher": "Domenic Denicola",
"email": "d@domenic.me",
"url": "https://domenic.me/",
"path": "node_modules/whatwg-encoding",
"licenseFile": "node_modules/whatwg-encoding/LICENSE.txt"
},
@ -911,7 +782,6 @@
"repository": "https://github.com/jsdom/whatwg-mimetype",
"publisher": "Domenic Denicola",
"email": "d@domenic.me",
"url": "https://domenic.me/",
"path": "node_modules/whatwg-mimetype",
"licenseFile": "node_modules/whatwg-mimetype/LICENSE.txt"
},
@ -923,6 +793,14 @@
"path": "node_modules/whatwg-url",
"licenseFile": "node_modules/whatwg-url/LICENSE.txt"
},
"whatwg-url@11.0.0": {
"licenses": "MIT",
"repository": "https://github.com/jsdom/whatwg-url",
"publisher": "Sebastian Mayr",
"email": "github@smayr.name",
"path": "node_modules/data-urls/node_modules/whatwg-url",
"licenseFile": "node_modules/data-urls/node_modules/whatwg-url/LICENSE.txt"
},
"wheel@1.0.0": {
"licenses": "MIT",
"repository": "https://github.com/anvaka/wheel",
@ -930,20 +808,11 @@
"path": "node_modules/wheel",
"licenseFile": "node_modules/wheel/LICENSE"
},
"word-wrap@1.2.3": {
"licenses": "MIT",
"repository": "https://github.com/jonschlinkert/word-wrap",
"publisher": "Jon Schlinkert",
"url": "https://github.com/jonschlinkert",
"path": "node_modules/word-wrap",
"licenseFile": "node_modules/word-wrap/LICENSE"
},
"ws@8.5.0": {
"ws@8.13.0": {
"licenses": "MIT",
"repository": "https://github.com/websockets/ws",
"publisher": "Einar Otto Stangvik",
"email": "einaros@gmail.com",
"url": "http://2x.io",
"path": "node_modules/ws",
"licenseFile": "node_modules/ws/LICENSE"
},
@ -952,7 +821,6 @@
"repository": "https://github.com/jsdom/xml-name-validator",
"publisher": "Domenic Denicola",
"email": "d@domenic.me",
"url": "https://domenic.me/",
"path": "node_modules/xml-name-validator",
"licenseFile": "node_modules/xml-name-validator/LICENSE.txt"
},

View File

@ -1,5 +1,10 @@
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
/* eslint
@typescript-eslint/no-explicit-any: "off",
*/
import type { Identifier } from "@tslib/children-access";
import type { ChildrenAccess } from "@tslib/children-access";
import childrenAccess from "@tslib/children-access";
@ -12,7 +17,7 @@ import type { Readable, Writable } from "svelte/store";
import { writable } from "svelte/store";
export interface DynamicSvelteComponent {
component: typeof SvelteComponent;
component: typeof SvelteComponent<any>;
/**
* Props that are passed to the component
*/

View File

@ -1,16 +1,21 @@
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import type { SvelteComponentDev } from "svelte/internal";
/* eslint
@typescript-eslint/no-explicit-any: "off",
*/
import type { SvelteComponent } from "svelte";
export interface DynamicSvelteComponent<
T extends typeof SvelteComponentDev = typeof SvelteComponentDev,
T extends typeof SvelteComponent<any> = typeof SvelteComponent<any>,
> {
component: T;
[k: string]: unknown;
}
export const dynamicComponent = <
Comp extends typeof SvelteComponentDev,
Comp extends typeof SvelteComponent<any>,
DefaultProps = NonNullable<ConstructorParameters<Comp>[0]["props"]>,
>(
component: Comp,

View File

@ -6,8 +6,8 @@
// would not work.
import { registerPackageRaw } from "@tslib/runtime-require";
import * as svelteRuntime from "svelte/internal";
import * as svelteRuntime from "svelte";
import * as svelteStore from "svelte/store";
registerPackageRaw("svelte/internal", svelteRuntime);
registerPackageRaw("svelte", svelteRuntime);
registerPackageRaw("svelte/store", svelteStore);

View File

@ -255,7 +255,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
input.focus();
});
function updateCurrent(input: HTMLInputElement): ActionReturn {
function updateCurrent(input: HTMLInputElement): ActionReturn<any> {
$currentTagInput = input;
return {
destroy(): void {

View File

@ -14,7 +14,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export let keyCombination: string;
const dispatch = createEventDispatcher<{ tagappend: CustomEvent<void> }>();
const dispatch = createEventDispatcher<{ tagappend: null }>();
function appendTag() {
dispatch("tagappend");

4277
yarn.lock

File diff suppressed because it is too large Load Diff