Rewrite paste behavior

This commit is contained in:
Henrik Giesel 2021-06-25 02:22:10 +02:00
parent d705d049ce
commit 6e25a3d424
4 changed files with 58 additions and 40 deletions

View file

@ -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}

View file

@ -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"); */
/* } */
/* } */
</script>
<div bind:this={menu} class="dropup dropdown-reverse">
<slot {triggerId} {triggerClass} {dropdown} />
<slot {triggerId} {triggerClass} />
<DropdownMenu labelledby={triggerId}>
{#each suggestions as tag}

View file

@ -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
<AddTagBadge on:click={focusInputNew} />
{#each tags as tag, index}
<Tag bind:name={tag} on:tagdelete={() => deleteTag(index)} />
<Tag
bind:name={tag}
on:tagadd={insertTagAt(index)}
on:tagdelete={deleteTagAt(index)}
/>
{/each}
<TagInput bind:input={tagInputNew} bind:name={newName} on:tagupdate={addTag} />
<TagInput
bind:input={tagInputNew}
bind:name={newName}
on:tagupdate={appendTag}
on:tagadd={appendTag}
/>
</div>
</StickyBottom>

View file

@ -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 {