mirror of
https://github.com/ankitects/anki.git
synced 2025-09-19 06:22:22 -04:00
Use Unicode delimiter character
This commit is contained in:
parent
6ccf75a077
commit
3de1d6e604
3 changed files with 48 additions and 38 deletions
|
@ -16,18 +16,28 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
import ButtonToolbar from "components/ButtonToolbar.svelte";
|
||||
import { controlPressed } from "lib/keys";
|
||||
import type { Tag as TagType } from "./tags";
|
||||
import { attachId, getName } from "./tags";
|
||||
import {
|
||||
attachId,
|
||||
getName,
|
||||
delimChar,
|
||||
replaceWithDelimChar,
|
||||
replaceWithColon,
|
||||
} from "./tags";
|
||||
|
||||
export let size = isApplePlatform() ? 1.6 : 2.0;
|
||||
|
||||
export let tags: TagType[] = [];
|
||||
|
||||
export function resetTags(names: string[]): void {
|
||||
tags = names.map(attachId);
|
||||
tags = names.map(replaceWithDelimChar).map(attachId);
|
||||
}
|
||||
|
||||
function saveTags(): void {
|
||||
bridgeCommand(`saveTags:${JSON.stringify(tags.map((tag) => tag.name))}`);
|
||||
bridgeCommand(
|
||||
`saveTags:${JSON.stringify(
|
||||
tags.map((tag) => tag.name).map(replaceWithColon)
|
||||
)}`
|
||||
);
|
||||
}
|
||||
|
||||
let active: number | null = null;
|
||||
|
@ -43,7 +53,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
"en::vocabulary",
|
||||
"en::idioms",
|
||||
Math.random().toString(36).substring(2),
|
||||
]);
|
||||
]).then((names: string[]): string[] => names.map(replaceWithDelimChar));
|
||||
}
|
||||
|
||||
function onAutocomplete(selected: string): void {
|
||||
|
@ -369,17 +379,17 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
$: shortenTags = shortenTags || assumedRows > 2;
|
||||
|
||||
function processTagName(name: string): string {
|
||||
const parts = name.split("::");
|
||||
const parts = name.split(delimChar);
|
||||
|
||||
if (parts.length === 1) {
|
||||
return name;
|
||||
}
|
||||
|
||||
return "…::" + parts[parts.length - 1];
|
||||
return `…${delimChar}` + parts[parts.length - 1];
|
||||
}
|
||||
|
||||
function hasMultipleParts(name: string): boolean {
|
||||
return name.split("::").length > 1;
|
||||
return name.split(delimChar).length > 1;
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
-->
|
||||
<script lang="typescript">
|
||||
import { onMount, createEventDispatcher, tick } from "svelte";
|
||||
import { normalizeTagname } from "./tags";
|
||||
import { normalizeTagname, delimChar } from "./tags";
|
||||
|
||||
export let id: string | undefined = undefined;
|
||||
let className: string = "";
|
||||
|
@ -55,11 +55,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
|
||||
const nameUptoCaret = name.slice(0, position);
|
||||
|
||||
if (nameUptoCaret.endsWith("::")) {
|
||||
name = name.slice(0, position - 2) + name.slice(position, name.length);
|
||||
if (nameUptoCaret.endsWith(delimChar)) {
|
||||
name = name.slice(0, position - 1) + name.slice(position, name.length);
|
||||
await tick();
|
||||
|
||||
setPosition(position - 2);
|
||||
setPosition(position - 1);
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
@ -106,36 +106,30 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
}
|
||||
|
||||
async function onDelimiter(event: Event, single: boolean = false): Promise<void> {
|
||||
event.preventDefault();
|
||||
|
||||
const positionStart = input.selectionStart!;
|
||||
const positionEnd = input.selectionEnd!;
|
||||
|
||||
const before = name.slice(0, positionStart);
|
||||
if (before.endsWith("::")) {
|
||||
|
||||
if (before.endsWith(delimChar)) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
return;
|
||||
} else if (before.endsWith(":")) {
|
||||
event.preventDefault();
|
||||
name = `${before.slice(0, -1)}${delimChar}${name.slice(
|
||||
positionEnd,
|
||||
name.length
|
||||
)}`;
|
||||
} else if (single) {
|
||||
return;
|
||||
} else {
|
||||
event.preventDefault();
|
||||
name = `${before}${delimChar}${name.slice(positionEnd, name.length)}`;
|
||||
}
|
||||
|
||||
name = `${before}${single ? ":" : "::"}${name.slice(positionEnd, name.length)}`;
|
||||
|
||||
await tick();
|
||||
setPosition(positionStart + (single ? 1 : 2));
|
||||
}
|
||||
|
||||
function maybeMovePastDelimiter(event: Event, forwards: boolean): void {
|
||||
const position = input.selectionStart!;
|
||||
|
||||
const before = name.slice(0, position);
|
||||
const after = name.slice(position, name.length);
|
||||
|
||||
if (!forwards && before.endsWith("::")) {
|
||||
setPosition(position - 2);
|
||||
event.preventDefault();
|
||||
} else if (forwards && after.startsWith("::")) {
|
||||
setPosition(position + 2);
|
||||
event.preventDefault();
|
||||
}
|
||||
setPosition(positionStart + 1);
|
||||
}
|
||||
|
||||
function onKeydown(event: KeyboardEvent): void {
|
||||
|
@ -166,8 +160,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
} else if (caretAtStart()) {
|
||||
dispatch("tagmoveprevious");
|
||||
event.preventDefault();
|
||||
} else if (isCollapsed()) {
|
||||
maybeMovePastDelimiter(event, false);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -177,8 +169,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
} else if (caretAtEnd()) {
|
||||
dispatch("tagmovenext");
|
||||
event.preventDefault();
|
||||
} else if (isCollapsed()) {
|
||||
maybeMovePastDelimiter(event, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,23 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
export const delimChar = "\u2237";
|
||||
|
||||
export function replaceWithDelimChar(name: string): string {
|
||||
return name.replace(/::/g, delimChar);
|
||||
}
|
||||
|
||||
export function replaceWithColon(name: string): string {
|
||||
return name.replace(/\u2237/gu, "::");
|
||||
}
|
||||
|
||||
export function normalizeTagname(tagname: string): string {
|
||||
let trimmed = tagname.trim();
|
||||
|
||||
while (true) {
|
||||
if (trimmed.startsWith(":")) {
|
||||
if (trimmed.startsWith(":") || trimmed.startsWith(delimChar)) {
|
||||
trimmed = trimmed.slice(1).trimStart();
|
||||
} else if (trimmed.endsWith(":")) {
|
||||
} else if (trimmed.endsWith(":") || trimmed.endsWith(delimChar)) {
|
||||
trimmed = trimmed.slice(0, -1).trimEnd();
|
||||
} else {
|
||||
return trimmed;
|
||||
|
|
Loading…
Reference in a new issue