diff --git a/ts/editor/Tag.svelte b/ts/editor/Tag.svelte
index c19ee4820..d896f9e77 100644
--- a/ts/editor/Tag.svelte
+++ b/ts/editor/Tag.svelte
@@ -40,6 +40,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
bind:input
on:focusout={() => (active = false)}
on:tagupdate={updateTag}
+ on:tagadd
on:mount={(event) => event.detail.input.focus()}
/>
{:else}
diff --git a/ts/editor/TagAutocomplete.svelte b/ts/editor/TagAutocomplete.svelte
index 1179dc949..33e90247b 100644
--- a/ts/editor/TagAutocomplete.svelte
+++ b/ts/editor/TagAutocomplete.svelte
@@ -8,7 +8,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import DropdownMenu from "components/DropdownMenu.svelte";
import DropdownItem from "components/DropdownItem.svelte";
- export let name: string;
export const suggestions = ["en::idioms", "anki::functionality", "math"];
const dispatch = createEventDispatcher();
@@ -16,10 +15,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const triggerClass = "dropdown-toggle";
let menu: HTMLDivElement;
- let dropdown;
- let activeItem = -1;
-
- $: tagValues = [...suggestions, name];
function onItemClick(event: Event) {
dispatch("nameChosen", { name: event.currentTarget!.innerText });
@@ -29,11 +24,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
function switchUpDown(event: KeyboardEvent): void {
const target = event.currentTarget as HTMLButtonElement;
- console.log(
- event.code,
- target.nextElementSibling,
- target.previousElementSibling
- );
if (event.code === "ArrowUp") {
if (target.nextElementSibling) {
(target.nextElementSibling as HTMLButtonElement).focus();
@@ -50,23 +40,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
function updateActiveItem(even: FocusEvent): void {}
-
- /* else if (event.code === "Enter") { */
- /* const dropdownActive = dropdown._element.classList.contains("show"); */
- /* if (dropdownActive) { */
- /* if (typeof activeItem === "number") { */
- /* name = tagValues[activeItem]; */
- /* activeItem = null; */
- /* } */
- /* dropdown.hide(); */
- /* } else { */
- /* dispatch("accept"); */
- /* } */
- /* } */
-
+
{#each suggestions as tag}
diff --git a/ts/editor/TagEditor.svelte b/ts/editor/TagEditor.svelte
index ae14c9d8f..f3d509078 100644
--- a/ts/editor/TagEditor.svelte
+++ b/ts/editor/TagEditor.svelte
@@ -8,7 +8,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import Tag from "./Tag.svelte";
import TagInput from "./TagInput.svelte";
- export let tags = ["en::foobar", "zh::あっちこっち", "test", "def"];
+ export let tags = ["en::foobar", "test", "def"];
let tagInputNew: HTMLInputElement;
let newName: string = "";
@@ -17,12 +17,24 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
tagInputNew.focus();
}
- function deleteTag(index: number): void {
+ const insertTagAt = (index: number) => () => {
+ const copy = tags.slice(0);
+ copy.splice(index, 1);
+
+ if (copy.includes(tags[index])) {
+ return;
+ }
+
+ tags.splice(index - 1, 0, tags[index]);
+ tags = tags;
+ };
+
+ const deleteTagAt = (index: number) => () => {
tags.splice(index, 1);
tags = tags;
- }
+ };
- function addTag(): void {
+ function appendTag(): void {
if (!tags.includes(newName) && newName.length > 0) {
tags.push(newName);
}
@@ -36,10 +48,19 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
{#each tags as tag, index}
- deleteTag(index)} />
+
{/each}
-
+
diff --git a/ts/editor/TagInput.svelte b/ts/editor/TagInput.svelte
index 0cc88bea2..c9e449489 100644
--- a/ts/editor/TagInput.svelte
+++ b/ts/editor/TagInput.svelte
@@ -40,17 +40,36 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
}
- function onPaste({ clipboardData }: ClipboardEvent): void {
- const pasted = name + clipboardData!.getData("text/plain");
- const splitted = pasted.split(" ");
- const last = splitted.pop();
- for (const token of splitted) {
- const name = normalizeTagname(token);
- if (name) {
- dispatch("tagadd", { name });
- }
+ function onPaste(event: ClipboardEvent): void {
+ event.preventDefault();
+
+ if (!event.clipboardData) {
+ return;
+ }
+
+ const pasted = name + event.clipboardData.getData("text/plain");
+ const splitted = pasted
+ .split(/\s+/)
+ .map(normalizeTagname)
+ .filter((name: string) => name.length > 0);
+
+ if (splitted.length === 0) {
+ return;
+ } else if (splitted.length === 1) {
+ name = splitted.shift()!;
+ } else {
+ name = splitted.shift()!;
+ dispatch("tagadd");
+
+ const last = splitted.pop()!;
+
+ for (const pastedName of splitted) {
+ name = pastedName;
+ dispatch("tagadd");
+ }
+
+ name = last;
}
- name = last!;
}
function setTagname({ detail }: CustomEvent): void {