diff --git a/src/lib/components/Checklist.svelte b/src/lib/components/Checklist.svelte
index 070487f..5021589 100644
--- a/src/lib/components/Checklist.svelte
+++ b/src/lib/components/Checklist.svelte
@@ -183,7 +183,7 @@
function handlePaste(e: ClipboardEvent) {
e.preventDefault();
- const text = e.clipboardData?.getData('text/plain') ?? '';
+ const text = (e.clipboardData?.getData('text/plain') ?? '').replace(/[\r\n]+/g, ' ');
const selection = window.getSelection();
if (!selection?.rangeCount) return;
const range = selection.getRangeAt(0);
@@ -327,6 +327,7 @@
onblur={(e) => { (e.target as HTMLElement).innerHTML = linkifyText(item.text); }}
class="flex-1 min-w-0 bg-transparent text-sm outline-none break-words {item.checked ? 'text-[var(--text-muted)] line-through' : 'text-[var(--text)]'}"
data-placeholder="List item"
+ aria-placeholder="List item"
data-testid="checklist-input"
data-item-id={item.id}
role="textbox"
diff --git a/src/lib/components/LinkPopover.svelte b/src/lib/components/LinkPopover.svelte
index 88fd46e..9ee5063 100644
--- a/src/lib/components/LinkPopover.svelte
+++ b/src/lib/components/LinkPopover.svelte
@@ -52,7 +52,7 @@
}
-
+
0}
{ if ((e.target as HTMLElement).closest('a')) e.stopPropagation(); }}>
+ onclick={(e) => { if ((e.target as HTMLElement).closest('a')) e.stopPropagation(); }}
+ onkeydown={(e) => { if ((e.target as HTMLElement).closest('a')) e.stopPropagation(); }}>
{#each sortedChecklistItems.slice(0, 8) as item}
-
diff --git a/src/lib/utils/checklist.test.ts b/src/lib/utils/checklist.test.ts
index d4d5e14..f60fbec 100644
--- a/src/lib/utils/checklist.test.ts
+++ b/src/lib/utils/checklist.test.ts
@@ -224,19 +224,19 @@ describe('outdentItem', () => {
describe('linkifyText', () => {
it('converts https URLs to anchor tags', () => {
expect(linkifyText('visit https://example.com today')).toBe(
- 'visit https://example.com today'
+ 'visit https://example.com today'
);
});
it('converts http URLs to anchor tags', () => {
expect(linkifyText('go to http://example.com')).toBe(
- 'go to http://example.com'
+ 'go to http://example.com'
);
});
it('converts bare www URLs with https href', () => {
expect(linkifyText('check www.example.com')).toBe(
- 'check www.example.com'
+ 'check www.example.com'
);
});
@@ -281,7 +281,7 @@ describe('linkifyText', () => {
it('strips trailing punctuation from URLs', () => {
expect(linkifyText('see https://example.com.')).toBe(
- 'see https://example.com.'
+ 'see https://example.com.'
);
});
diff --git a/src/lib/utils/checklist.ts b/src/lib/utils/checklist.ts
index 2f51a48..a10eddc 100644
--- a/src/lib/utils/checklist.ts
+++ b/src/lib/utils/checklist.ts
@@ -180,7 +180,7 @@ export function linkifyText(text: string): string {
let lastIndex = 0;
for (const { index, match, href } of matches) {
result += escapeHtml(text.slice(lastIndex, index));
- result += `${escapeHtml(match)}`;
+ result += `${escapeHtml(match)}`;
lastIndex = index + match.length;
}
result += escapeHtml(text.slice(lastIndex));
diff --git a/static/api/openapi.json b/static/api/openapi.json
index 55bf71a..7f8e5d1 100644
--- a/static/api/openapi.json
+++ b/static/api/openapi.json
@@ -3,7 +3,7 @@
"info": {
"title": "Crumbs API",
"description": "Auto-generated API spec for crumbs",
- "version": "0.24.0",
+ "version": "0.27.1",
"contact": {
"name": "Bretzel",
"url": "https://bretzel.app"