From 08d703e3afad2e99ae09e4374ca19ae3da465f98 Mon Sep 17 00:00:00 2001 From: kristianwind Date: Mon, 7 Sep 2026 21:50:12 +0200 Subject: [PATCH] =?UTF-8?q?fix(noter):=20f=C3=B8lg=20note-links=20i=20en?= =?UTF-8?q?=20delt=20note,=20og=20lad=20=20v=C3=A6re=20kode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To ting meldt af en, der havde en note delt med sig. Note-linkene i den delte note gjorde ingenting. Opslaget faldt tilbage på det første søgeresultat, når ingen titel passede — og i en delt note er det første resultat næsten altid noten selv, fordi den nævner den titel, den peger på. Så åbnede linket den note, man allerede stod i. Kun en titel, der passer helt, tæller nu; og rammer den forbi, siger beskeden den rigtige grund: en note, der deles, deler ikke de noter, den peger på, så modtageren kan se linket uden at kunne åbne det. Og `` sad på kildevisningen med teksten "Vis som kode" på. Tegnet betyder inline kode i ethvert andet program, så et markeret ord plus et tryk gav hele noten som Markdown. Nu gør `` det, det siger — ⌘E, en kontakt, og ordet under markøren når der ikke er markeret noget — og kilden har fået Markdown-mærket og sin egen tekst. Kode indsættes som en node frem for med execCommand: Chromium renser den HTML gennem indsætningsvejen og gav et med skrifttypen skrevet ind i sig, som htmlToMarkdown ikke kan skrive ned som kode. To e2e-prøver, som begge fejler på koden før den her. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_013r4DxpUZcSShxfCZZaeMGZ --- web/e2e/smoke.spec.js | 136 +++++++++++++++++++ web/kristians-link.png | Bin 0 -> 59656 bytes web/src/lib/components/NoteEditor.svelte | 164 ++++++++++++++++++++++- web/src/lib/locales/da.js | 5 +- web/src/lib/locales/en.js | 5 +- web/src/routes/noter/+page.svelte | 27 +++- 6 files changed, 326 insertions(+), 11 deletions(-) create mode 100644 web/kristians-link.png diff --git a/web/e2e/smoke.spec.js b/web/e2e/smoke.spec.js index a67da63..a6dfb59 100644 --- a/web/e2e/smoke.spec.js +++ b/web/e2e/smoke.spec.js @@ -2838,6 +2838,142 @@ test('en note kan deles med en person direkte, og dukker op hos dem', async ({ b expect(trouble).toEqual([]); }); +/** + * Note-links i en delt note. + * + * Meldt af en, der havde en note delt med sig: linkene i den gjorde ingenting. + * Det var to ting. Opslaget faldt tilbage på det første søgeresultat, når titlen + * ikke passede — og i en delt note er det første resultat næsten altid noten selv, + * fordi den nævner den titel, den linker til. Så åbnede linket den note, man + * allerede stod i, hvilket ser ud som ingenting. Og når det så endelig ikke fandt + * noget, sagde beskeden "blev ikke fundet", som var den forkerte grund: noten + * findes, den er bare ikke delt med. + */ +test('note links i en delt note fører til den rigtige note, eller siger hvorfor ikke', async ({ + browser, + page +}) => { + const trouble = watchForTrouble(page); + + await page.goto('/indstillinger/brugere'); + await page.getByLabel('E-mailadresse').fill('link@example.dk'); + await page.getByRole('button', { name: 'Send invitation' }).click(); + const link = await page.locator('.link-out').textContent(); + + const gæstCtx = await browser.newContext({ storageState: { cookies: [], origins: [] } }); + const gæst = await gæstCtx.newPage(); + await gæst.goto(link); + await gæst.getByLabel('Navn', { exact: true }).fill('Linnea'); + await gæst.getByLabel(/Adgangskode/).fill('et langt kodeord til test'); + await gæst.getByRole('button', { name: 'Opret konto' }).click(); + await expect(gæst.getByRole('navigation', { name: 'Hovedmenu' })).toBeVisible(); + const noterURL = new URL('/noter', link).href; + + // Ejeren skriver to noter: en, der bliver delt, og en, der ikke gør — og den + // delte peger på den anden. + const sidebar = page.getByRole('navigation', { name: 'Hovedmenu' }); + await sidebar.getByRole('link', { name: 'Noter', exact: true }).click(); + await page.getByRole('button', { name: 'Ny note' }).click(); + await page.getByRole('textbox', { name: 'Notens tekst' }).click(); + await page.keyboard.type('Prisliste for foraaret'); + await page.getByRole('textbox', { name: 'Notens tekst' }).blur(); + + await page.getByRole('button', { name: 'Ny note' }).click(); + await page.getByRole('textbox', { name: 'Notens tekst' }).click(); + await page.keyboard.type('Aftale om levering\n'); + await page.keyboard.type('[[Prisliste for foraaret]]'); + await page.getByRole('textbox', { name: 'Notens tekst' }).blur(); + + // Gæsten har en note af sin egen, som hun kan pege på. + await gæst.goto(noterURL); + await gæst.getByRole('button', { name: 'Ny note' }).click(); + await gæst.getByRole('textbox', { name: 'Notens tekst' }).click(); + await gæst.keyboard.type('Linneas egne maal'); + await gæst.getByRole('textbox', { name: 'Notens tekst' }).blur(); + + await page.locator('.notes').getByRole('button', { name: /Aftale om levering/ }).click(); + await page.locator('.sharewrap > button').click(); + const share = page.locator('.sharepanel'); + await expect(share).toBeVisible(); + await share.locator('.addshare select').first().selectOption({ label: 'Linnea' }); + await share.getByRole('button', { name: 'Tilføj' }).click(); + const row = share.locator('.sharelist li').filter({ hasText: 'Linnea' }); + await expect(row).toBeVisible(); + await row.locator('select').selectOption('editor'); + + // Hun skriver sit eget link ind i den delte note. + await gæst.goto(noterURL); + await gæst.locator('.notes').getByRole('button', { name: /Aftale om levering/ }).click(); + const body = gæst.getByRole('textbox', { name: 'Notens tekst' }); + await expect(body).toContainText('Prisliste for foraaret'); + await body.click(); + await gæst.keyboard.press('Control+End'); + await gæst.keyboard.type('\n[[Linneas egne maal]]'); + await body.blur(); + await expect(gæst.locator('footer .hint')).toHaveText('Gemt'); + + await gæst.goto(noterURL); + await gæst.locator('.notes').getByRole('button', { name: /Aftale om levering/ }).click(); + const delt = gæst.getByRole('textbox', { name: 'Notens tekst' }); + + // Hendes eget link fører derhen, det siger. + await delt.locator('a.notelink', { hasText: 'Linneas egne maal' }).click(); + await expect(gæst.getByRole('textbox', { name: 'Notens tekst' })).toContainText( + 'Linneas egne maal' + ); + + // Ejerens link peger på en note, hun ikke har fået. Den må ikke lande et + // tilfældigt sted — og den må sige hvorfor. + await gæst.locator('.notes').getByRole('button', { name: /Aftale om levering/ }).click(); + const igen = gæst.getByRole('textbox', { name: 'Notens tekst' }); + await expect(igen).toContainText('Prisliste for foraaret'); + await igen.locator('a.notelink', { hasText: 'Prisliste for foraaret' }).click(); + await expect(gæst.locator('.toast')).toContainText('ikke delt med dig'); + // Stadig i den delte note: linket flyttede hende ingen steder hen. + await expect(gæst.getByRole('textbox', { name: 'Notens tekst' })).toContainText( + 'Aftale om levering' + ); + + await gæstCtx.close(); + expect(trouble).toEqual([]); +}); + +/** + * `` er kode, ikke kilde. + * + * Sådan blev den læst af den første, der så den — markér et ord, tryk på tegnet, + * og hele noten skiftede til Markdown. Tegnet betyder kode i ethvert andet + * program, så det er knappen, der skal give efter, ikke brugeren. + */ +test(' sætter markeringen som kode, og kilden har sin egen knap', async ({ page }) => { + const trouble = watchForTrouble(page); + await page.goto('/noter'); + + await page.getByRole('button', { name: 'Ny note' }).click(); + const body = page.getByRole('textbox', { name: 'Notens tekst' }); + await body.click(); + await page.keyboard.type('Kodenote\n'); + await page.keyboard.type('kør kommandoen npm først'); + + // Markér ét ord og gør det til kode. + await page.keyboard.press('Shift+Home'); + await page.keyboard.press('Shift+ArrowRight'); + await page.getByRole('button', { name: 'Kode', exact: true }).click(); + await expect(body.locator('code')).toHaveCount(1); + + // Noten er stadig rig tekst — kildevisningen er ikke slået til. + await expect(page.locator('textarea.source')).toHaveCount(0); + + // Og den anden knap gør stadig det, den altid har gjort: viser filen, med + // baktikkerne i, som er beviset på at koden nåede hele vejen ned. + await body.blur(); + await expect(page.locator('footer .hint')).toHaveText('Gemt'); + await page.getByRole('button', { name: /Vis kilden/ }).click(); + await expect(page.locator('textarea.source')).toHaveValue(/`/); + + expect(trouble).toEqual([]); +}); + test('udseendet kan skiftes uafhængigt af temaet, og overlever en genindlæsning', async ({ page }) => { diff --git a/web/kristians-link.png b/web/kristians-link.png new file mode 100644 index 0000000000000000000000000000000000000000..15e581dc94b9af1437393391680bb2d86b942de2 GIT binary patch literal 59656 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, som i ethvert andet program betyder netop + * kode, sad på kildevisningen med teksten "Vis som kode" på. Så markerede man et + * ord og trykkede på den, og hele noten skiftede til Markdown. Det blev meldt + * som en fejl, og det var det også: knappen sagde ét og gjorde et andet. Nu gør + * `` det, tegnet siger, og kilden har fået sit eget mærke. + * + * Skrevet i hånden, fordi execCommand ikke har en kommando for kode. Markeringen + * læses som ren tekst — det er hele meningen med kode, at det ikke er formateret + * — og lægges tilbage inde i et , som konverteringen allerede kender + * begge veje. + */ + function codeAround() { + const selection = window.getSelection(); + let node = selection?.anchorNode; + while (node && node !== editor) { + if (node.nodeType === Node.ELEMENT_NODE && node.tagName === 'CODE') return node; + node = node.parentNode; + } + return null; + } + + /** Markerer ordet, markøren står i. Bruges når der ikke er markeret noget. */ + function selectWordAtCaret() { + const selection = window.getSelection(); + const node = selection?.anchorNode; + if (!node || node.nodeType !== Node.TEXT_NODE) return; + const text = node.textContent ?? ''; + let start = selection.anchorOffset; + let end = start; + while (start > 0 && !/\s/.test(text[start - 1])) start--; + while (end < text.length && !/\s/.test(text[end])) end++; + if (start === end) return; + const range = document.createRange(); + range.setStart(node, start); + range.setEnd(node, end); + selection.removeAllRanges(); + selection.addRange(range); + } + + function selectContents(node) { + const range = document.createRange(); + range.selectNodeContents(node); + const selection = window.getSelection(); + selection.removeAllRanges(); + selection.addRange(range); + } + + function toggleCode() { + editor?.focus(); + const selection = window.getSelection(); + if (!selection?.rangeCount) return; + + // Inde i en kodeblok er alting allerede kode; en derinde kan hverken + // ses eller skrives ned, for en hegnet blok er tekst hele vejen igennem. + const block = currentBlock(); + if (block?.tagName === 'PRE') return; + + const existing = codeAround(); + if (existing) { + // Ud igen: teksten bliver stående, mærkerne forsvinder. Markeringen lægges + // om den, så et tryk mere sætter den tilbage — knappen er en kontakt. + const text = document.createTextNode(existing.textContent ?? ''); + existing.replaceWith(text); + selectContents(text); + readState(); + changed(); + return; + } + + // Uden en markering er det ordet, markøren står i. Det er det, ⌘B gør i et + // tekstprogram, og bedre end et tomt , der ikke kan ses og ikke kan + // skrives ned. + if (selection.isCollapsed) selectWordAtCaret(); + const live = window.getSelection(); + const text = live.toString(); + if (!text) return; + + // Bygget som en node frem for med `insertHTML`. + // + // Chromium renser den HTML, den får dér, gennem den samme vej som en + // indsætning: `` kom ud som et `` med skrifttypen og farven + // skrevet ind i sig, og et span er ikke noget, htmlToMarkdown kan skrive ned + // som kode. Målt — mærket forsvandt hver gang, og noten så rigtig ud, indtil + // den blev gemt. + const range = live.getRangeAt(0); + range.deleteContents(); + const code = document.createElement('code'); + code.textContent = text; + range.insertNode(code); + + // Markøren efter mærket, ikke inde i det: ellers bliver det næste ord, man + // skriver, også til kode. + const after = document.createRange(); + after.setStartAfter(code); + after.collapse(true); + live.removeAllRanges(); + live.addRange(after); + + readState(); + changed(); + } + /** * Steps out of a code block on Enter. * @@ -223,7 +328,11 @@ underline: document.queryCommandState('underline'), strike: document.queryCommandState('strikeThrough'), bullet: document.queryCommandState('insertUnorderedList'), - numbered: document.queryCommandState('insertOrderedList') + numbered: document.queryCommandState('insertOrderedList'), + // Læst af DOM'en og ikke af execCommand: der findes ingen kommando + // for kode, hvilket er hele grunden til at knappen er skrevet i + // hånden herunder. + code: !!codeAround() }; } catch { // Some browsers throw on queryCommandState with no selection. The toolbar @@ -641,6 +750,9 @@ if (key === 'u') { event.preventDefault(); apply('underline'); + } else if (key === 'e') { + event.preventDefault(); + toggleCode(); } else if (key === 'x' && event.shiftKey) { event.preventDefault(); apply('strikeThrough'); @@ -788,19 +900,50 @@ + + + anden måde at se det hele på — og med Markdown-mærket på, som er præcis + det, den viser. Et tegn, ingen forveksler med et format. --> + + {#if asSource} @@ -1132,11 +1275,24 @@ resize: none; } - .src { + /* Kodeknappen bærer sit eget tegn i monospace — `` sat med brødskriften + ligner en tastefejl frem for et mærke. */ + .codemark { font-family: var(--font-mono); font-size: var(--text-xs); } + .src { + display: inline-flex; + align-items: center; + justify-content: center; + } + + .src svg { + width: 17px; + height: auto; + } + /* The document styles. These are the whole of "it should look like Apple Notes": a title that is a title, and body text that is comfortable to read for a page at a time. */ diff --git a/web/src/lib/locales/da.js b/web/src/lib/locales/da.js index 26c1ebf..e415eef 100644 --- a/web/src/lib/locales/da.js +++ b/web/src/lib/locales/da.js @@ -23,7 +23,7 @@ export const da = { // Deling med enkeltpersoner, ved siden af projektet. 'notes.groupSharedWithMe': 'Delt med mig', 'notes.linkOpen': 'Åbn', - 'notes.linkMissing': 'Noten blev ikke fundet.', + 'notes.linkMissing': 'Noten findes ikke, eller den er ikke delt med dig.', 'notes.sharedBy': 'Delt af {name}', 'notes.sharePeople': 'Del med personer', 'notes.sharePick': 'Vælg en person …', @@ -76,7 +76,8 @@ export const da = { 'notes.copied': 'Kopieret', 'notes.copyFailed': 'Kunne ikke kopiere', 'notes.strike': 'Gennemstreget', - 'notes.showSource': 'Vis som kode', + 'notes.code': 'Kode', + 'notes.showSource': 'Vis kilden (Markdown)', 'notes.source': 'Notens kildetekst', 'notes.styleTitle': 'Titel', 'notes.styleHeading': 'Overskrift', diff --git a/web/src/lib/locales/en.js b/web/src/lib/locales/en.js index 0b317d3..def0814 100644 --- a/web/src/lib/locales/en.js +++ b/web/src/lib/locales/en.js @@ -19,7 +19,7 @@ export const en = { // Sharing with individual people, alongside the project. 'notes.groupSharedWithMe': 'Shared with me', 'notes.linkOpen': 'Open', - 'notes.linkMissing': 'That note could not be found.', + 'notes.linkMissing': 'That note does not exist, or it is not shared with you.', 'notes.sharedBy': 'Shared by {name}', 'notes.sharePeople': 'Share with people', 'notes.sharePick': 'Choose someone …', @@ -72,7 +72,8 @@ export const en = { 'notes.copied': 'Copied', 'notes.copyFailed': 'Could not copy', 'notes.strike': 'Strikethrough', - 'notes.showSource': 'Show as code', + 'notes.code': 'Code', + 'notes.showSource': 'Show the source (Markdown)', 'notes.source': 'Note source', 'notes.styleTitle': 'Title', 'notes.styleHeading': 'Heading', diff --git a/web/src/routes/noter/+page.svelte b/web/src/routes/noter/+page.svelte index 90d9044..49c6153 100644 --- a/web/src/routes/noter/+page.svelte +++ b/web/src/routes/noter/+page.svelte @@ -665,17 +665,38 @@ * to their own pages. Until now these were text and nothing else: the note said * it pointed somewhere and there was no way to go. */ + /** + * Følger et link — og siger det, når det ikke kan følges. + * + * Et `[[link]]` peger på en note ved dens *titel*, så det skal slås op. Først i + * listen, der allerede er hentet, og ellers med en søgning, fordi listen kan + * være snævret ind af et søgeord. + * + * Kun en titel, der passer helt. Der stod `?? found[0]` her, så et link, der + * ikke kunne findes, åbnede den første note, søgningen tilfældigvis gav — og i + * en *delt* note er det næsten altid den note, man allerede står i: den nævner + * jo titlen, den linker til. Så linket så ud til ikke at gøre noget som helst, + * hvilket er præcis sådan det blev meldt. Et link, der rammer forbi, skal sige + * det, ikke ramme et andet sted. + * + * Beskeden nævner delingen, fordi det er den almindelige årsag: en note, der + * deles, deler ikke de noter, den peger på, og modtageren kan derfor se linket + * uden at kunne åbne det. Herfra kan de to tilfælde ikke skelnes — svaret er + * det samme, hvad enten noten ikke findes eller bare ikke er ens egen — og + * sætningen siger dem begge frem for at gætte på den ene. + */ async function openLink(link) { if (link.kind === 'note') { - const wanted = link.target_id.toLowerCase(); - const here = notes.find((n) => (n.title ?? '').toLowerCase() === wanted); + const wanted = link.target_id.trim().toLowerCase(); + const titled = (n) => (n.title ?? '').trim().toLowerCase(); + const here = notes.find((n) => titled(n) === wanted); if (here) { open(here); return; } try { const found = (await api.notes({ q: link.target_id })).notes ?? []; - const hit = found.find((n) => (n.title ?? '').toLowerCase() === wanted) ?? found[0]; + const hit = found.find((n) => titled(n) === wanted); if (hit) open(hit); else app.toast(t('notes.linkMissing')); } catch (e) {