From 511cf2384a64965346cdcfa78ef8a79998d93e8a Mon Sep 17 00:00:00 2001 From: Baivab Sarkar Date: Mon, 21 Sep 2026 22:54:33 +0530 Subject: [PATCH 01/11] feat(editor): add Document Outline sidebar --- CHANGELOG.md | 2 + README.md | 1 + assets/i18n/bg.json | 7 +- assets/i18n/de.json | 7 +- assets/i18n/en.json | 7 +- assets/i18n/es.json | 7 +- assets/i18n/fr.json | 7 +- assets/i18n/generate-ui-locales.mjs | 1 + assets/i18n/it.json | 7 +- assets/i18n/ja.json | 7 +- assets/i18n/ko.json | 7 +- assets/i18n/pl.json | 7 +- assets/i18n/pt.json | 7 +- assets/i18n/ru.json | 7 +- assets/i18n/tr.json | 7 +- assets/i18n/tw.json | 7 +- assets/i18n/uk.json | 7 +- assets/i18n/zh.json | 7 +- assets/lucide-icons.css | 1 + desktop-app/resources/index.html | 13 +++ desktop-app/resources/js/script.js | 135 +++++++++++++++++++++++- desktop-app/resources/styles.css | 107 +++++++++++++++++++ index.html | 13 +++ script.js | 135 +++++++++++++++++++++++- styles.css | 107 +++++++++++++++++++ tests/e2e/document-outline.spec.js | 143 ++++++++++++++++++++++++++ tests/e2e/share-live.spec.js | 4 + tests/e2e/ui-toolbar-redesign.spec.js | 2 +- wiki/Features.md | 1 + wiki/Usage-Guide.md | 10 ++ wiki/images/document-outline.png | Bin 0 -> 84199 bytes 31 files changed, 760 insertions(+), 20 deletions(-) create mode 100644 tests/e2e/document-outline.spec.js create mode 100644 wiki/images/document-outline.png diff --git a/CHANGELOG.md b/CHANGELOG.md index c5122dd4..75adfee5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ Non-code commits (documentation, planning, README-only updates) are excluded. ## Unreleased +- Added Document Outline: a right sidebar with automatically updated, indented headings, section navigation, and a square-menu toolbar button beside Full Screen. + --- ## v3.10.2 diff --git a/README.md b/README.md index f3e8c414..a6649eda 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,7 @@ Turn a document into a Share Snapshot link for quick handoffs, or start access-c - **Backup and restore:** export or import a folder-preserving workspace ZIP; encrypted Secret Workspace files are optional, while trash and desktop history stay outside the backup. - **Editing and review:** switch among Editor, Split view, and Preview; use formatting tools, an 8×8 quick table selector, productivity shortcuts, custom undo/redo, Find and Replace, LTR/RTL direction, per-document Preview positions, selection-anchored comments, and threaded replies. - **Markdown rendering:** use CommonMark-style Markdown, GitHub-Flavored Markdown (GFM), tables, task lists, alerts, footnotes, definition lists, syntax highlighting, sanitized HTML, and MathJax. +- **Document Outline:** open the right sidebar beside Full Screen to browse headings and jump to a section; the outline follows the current document as you edit or switch tabs. - **Visual content:** render Mermaid, PlantUML, Graphviz/DOT, D2, Vega-Lite, WaveDrom, Markmap, GeoJSON, TopoJSON, STL, and ABC notation.

diff --git a/assets/i18n/bg.json b/assets/i18n/bg.json index 683b7a11..9b6ebae4 100644 --- a/assets/i18n/bg.json +++ b/assets/i18n/bg.json @@ -1168,5 +1168,10 @@ "Zoom In": "Увеличаване", "Zoom model": "Увеличен модел", "Zoom out": "Намаляване", - "Zoom Out": "Намаляване" + "Zoom Out": "Намаляване", + "Document Outline": "Структура на документа", + "Close Document Outline": "Затваряне на структурата на документа", + "Document headings": "Заглавия в документа", + "No headings in this document.": "В този документ няма заглавия.", + "Untitled heading": "Неозаглавено заглавие" } diff --git a/assets/i18n/de.json b/assets/i18n/de.json index b6931bf7..0267aeac 100644 --- a/assets/i18n/de.json +++ b/assets/i18n/de.json @@ -1168,5 +1168,10 @@ "Release notes are available in the tab list.": "Versionshinweise sind in der Registerkartenliste verfügbar.", "Release Notes: 3.10.2": "Versionshinweise: 3.10.2", "Skip update navigation": "Update-Navigation überspringen", - "1 file": "1 Datei" + "1 file": "1 Datei", + "Document Outline": "Dokumentgliederung", + "Close Document Outline": "Dokumentgliederung schließen", + "Document headings": "Dokumentüberschriften", + "No headings in this document.": "Dieses Dokument enthält keine Überschriften.", + "Untitled heading": "Unbenannte Überschrift" } diff --git a/assets/i18n/en.json b/assets/i18n/en.json index 9b6df2a8..f88665fe 100644 --- a/assets/i18n/en.json +++ b/assets/i18n/en.json @@ -1168,5 +1168,10 @@ "Zoom In": "Zoom In", "Zoom model": "Zoom model", "Zoom out": "Zoom out", - "Zoom Out": "Zoom Out" + "Zoom Out": "Zoom Out", + "Document Outline": "Document Outline", + "Close Document Outline": "Close Document Outline", + "Document headings": "Document headings", + "No headings in this document.": "No headings in this document.", + "Untitled heading": "Untitled heading" } diff --git a/assets/i18n/es.json b/assets/i18n/es.json index 68d4a435..66b004ad 100644 --- a/assets/i18n/es.json +++ b/assets/i18n/es.json @@ -1168,5 +1168,10 @@ "Release notes are available in the tab list.": "Las notas de la versión están disponibles en la lista de pestañas.", "Release Notes: 3.10.2": "Notas de la versión: 3.10.2", "Skip update navigation": "Saltar navegación de actualización", - "1 file": "1 archivo" + "1 file": "1 archivo", + "Document Outline": "Esquema del documento", + "Close Document Outline": "Cerrar esquema del documento", + "Document headings": "Encabezados del documento", + "No headings in this document.": "Este documento no tiene encabezados.", + "Untitled heading": "Encabezado sin título" } diff --git a/assets/i18n/fr.json b/assets/i18n/fr.json index 2502c797..5f622d84 100644 --- a/assets/i18n/fr.json +++ b/assets/i18n/fr.json @@ -1168,5 +1168,10 @@ "Release notes are available in the tab list.": "Les notes de version sont disponibles dans la liste des onglets.", "Release Notes: 3.10.2": "Notes de version : 3.10.2", "Skip update navigation": "Ignorer la navigation de mise à jour", - "1 file": "1 fichier" + "1 file": "1 fichier", + "Document Outline": "Plan du document", + "Close Document Outline": "Fermer le plan du document", + "Document headings": "Titres du document", + "No headings in this document.": "Ce document ne contient aucun titre.", + "Untitled heading": "Titre sans nom" } diff --git a/assets/i18n/generate-ui-locales.mjs b/assets/i18n/generate-ui-locales.mjs index abb320ae..a45ff1b9 100644 --- a/assets/i18n/generate-ui-locales.mjs +++ b/assets/i18n/generate-ui-locales.mjs @@ -171,6 +171,7 @@ const CURATED_OVERRIDES = { }; const EXTRA_STRINGS = [ + 'Document Outline', 'Close Document Outline', 'Document headings', 'No headings in this document.', 'Untitled heading', 'All changes saved', 'Saving...', 'Saved', 'Copied!', 'Copy failed', 'Import complete', 'Import completed with errors', 'Import failed', 'Preparing import…', 'No data is stored', 'Data is stored locally', 'Use light mode', 'Use dark mode', diff --git a/assets/i18n/it.json b/assets/i18n/it.json index 58fde7a0..56b3f62a 100644 --- a/assets/i18n/it.json +++ b/assets/i18n/it.json @@ -1168,5 +1168,10 @@ "Release notes are available in the tab list.": "Le note sulla versione sono disponibili nell'elenco delle schede.", "Release Notes: 3.10.2": "Note sulla versione: 3.10.2", "Skip update navigation": "Salta la navigazione degli aggiornamenti", - "1 file": "1 file" + "1 file": "1 file", + "Document Outline": "Struttura del documento", + "Close Document Outline": "Chiudi struttura del documento", + "Document headings": "Titoli del documento", + "No headings in this document.": "Questo documento non contiene titoli.", + "Untitled heading": "Titolo senza nome" } diff --git a/assets/i18n/ja.json b/assets/i18n/ja.json index fb2e0d12..1a377e27 100644 --- a/assets/i18n/ja.json +++ b/assets/i18n/ja.json @@ -1168,5 +1168,10 @@ "Release notes are available in the tab list.": "リリースノートはタブ一覧からご覧いただけます。", "Release Notes: 3.10.2": "リリースノート: 3.10.2", "Skip update navigation": "アップデートナビゲーションをスキップ", - "1 file": "1ファイル" + "1 file": "1ファイル", + "Document Outline": "ドキュメントのアウトライン", + "Close Document Outline": "ドキュメントのアウトラインを閉じる", + "Document headings": "ドキュメントの見出し", + "No headings in this document.": "このドキュメントには見出しがありません。", + "Untitled heading": "無題の見出し" } diff --git a/assets/i18n/ko.json b/assets/i18n/ko.json index 6d50af8b..da588cb7 100644 --- a/assets/i18n/ko.json +++ b/assets/i18n/ko.json @@ -1168,5 +1168,10 @@ "Release notes are available in the tab list.": "릴리스 노트는 탭 목록에서 확인할 수 있습니다.", "Release Notes: 3.10.2": "출시 노트: 3.10.2", "Skip update navigation": "업데이트 탐색 건너뛰기", - "1 file": "파일 1개" + "1 file": "파일 1개", + "Document Outline": "문서 개요", + "Close Document Outline": "문서 개요 닫기", + "Document headings": "문서 제목", + "No headings in this document.": "이 문서에는 제목이 없습니다.", + "Untitled heading": "이름 없는 제목" } diff --git a/assets/i18n/pl.json b/assets/i18n/pl.json index 721f6389..080cd574 100644 --- a/assets/i18n/pl.json +++ b/assets/i18n/pl.json @@ -1168,5 +1168,10 @@ "Release notes are available in the tab list.": "Informacje o wydaniu są dostępne na liście zakładek.", "Release Notes: 3.10.2": "Informacje o wydaniu: 3.10.2", "Skip update navigation": "Pomiń nawigację po aktualizacji", - "1 file": "1 plik" + "1 file": "1 plik", + "Document Outline": "Konspekt dokumentu", + "Close Document Outline": "Zamknij konspekt dokumentu", + "Document headings": "Nagłówki dokumentu", + "No headings in this document.": "Ten dokument nie zawiera nagłówków.", + "Untitled heading": "Nagłówek bez tytułu" } diff --git a/assets/i18n/pt.json b/assets/i18n/pt.json index fd15be10..4d929965 100644 --- a/assets/i18n/pt.json +++ b/assets/i18n/pt.json @@ -1168,5 +1168,10 @@ "Release notes are available in the tab list.": "As notas de versão estão disponíveis na lista de guias.", "Release Notes: 3.10.2": "Notas de versão: 3.10.2", "Skip update navigation": "Pular navegação de atualização", - "1 file": "1 arquivo" + "1 file": "1 arquivo", + "Document Outline": "Estrutura do documento", + "Close Document Outline": "Fechar estrutura do documento", + "Document headings": "Títulos do documento", + "No headings in this document.": "Este documento não contém títulos.", + "Untitled heading": "Título sem nome" } diff --git a/assets/i18n/ru.json b/assets/i18n/ru.json index d6ac45fe..6f7ff44c 100644 --- a/assets/i18n/ru.json +++ b/assets/i18n/ru.json @@ -1168,5 +1168,10 @@ "Release notes are available in the tab list.": "Примечания к выпуску доступны в списке вкладок.", "Release Notes: 3.10.2": "Примечания к выпуску: 3.10.2", "Skip update navigation": "Пропустить навигацию по обновлению", - "1 file": "1 файл" + "1 file": "1 файл", + "Document Outline": "Структура документа", + "Close Document Outline": "Закрыть структуру документа", + "Document headings": "Заголовки документа", + "No headings in this document.": "В этом документе нет заголовков.", + "Untitled heading": "Заголовок без названия" } diff --git a/assets/i18n/tr.json b/assets/i18n/tr.json index 980fd490..01cc97b8 100644 --- a/assets/i18n/tr.json +++ b/assets/i18n/tr.json @@ -1168,5 +1168,10 @@ "Release notes are available in the tab list.": "Sürüm notları sekme listesinde mevcuttur.", "Release Notes: 3.10.2": "Sürüm Notları: 3.10.2", "Skip update navigation": "Güncelleme gezinmesini atla", - "1 file": "1 dosya" + "1 file": "1 dosya", + "Document Outline": "Belge ana hattı", + "Close Document Outline": "Belge ana hattını kapat", + "Document headings": "Belge başlıkları", + "No headings in this document.": "Bu belgede başlık yok.", + "Untitled heading": "Adsız başlık" } diff --git a/assets/i18n/tw.json b/assets/i18n/tw.json index e39e0103..80a3df8c 100644 --- a/assets/i18n/tw.json +++ b/assets/i18n/tw.json @@ -1168,5 +1168,10 @@ "Release notes are available in the tab list.": "發行說明可在選項卡清單中找到。", "Release Notes: 3.10.2": "發行說明:3.10.2", "Skip update navigation": "跳過更新導航", - "1 file": "1 份文件" + "1 file": "1 份文件", + "Document Outline": "文件大綱", + "Close Document Outline": "關閉文件大綱", + "Document headings": "文件標題", + "No headings in this document.": "此文件沒有標題。", + "Untitled heading": "未命名標題" } diff --git a/assets/i18n/uk.json b/assets/i18n/uk.json index 2e6d125e..41e10c08 100644 --- a/assets/i18n/uk.json +++ b/assets/i18n/uk.json @@ -1168,5 +1168,10 @@ "Release notes are available in the tab list.": "Примітки до випуску доступні у списку вкладок.", "Release Notes: 3.10.2": "Примітки до випуску: 3.10.2", "Skip update navigation": "Пропустити оновлення навігації", - "1 file": "1 файл" + "1 file": "1 файл", + "Document Outline": "Структура документа", + "Close Document Outline": "Закрити структуру документа", + "Document headings": "Заголовки документа", + "No headings in this document.": "У цьому документі немає заголовків.", + "Untitled heading": "Заголовок без назви" } diff --git a/assets/i18n/zh.json b/assets/i18n/zh.json index cb12d746..7ce8542a 100644 --- a/assets/i18n/zh.json +++ b/assets/i18n/zh.json @@ -1168,5 +1168,10 @@ "Release notes are available in the tab list.": "发行说明可在选项卡列表中找到。", "Release Notes: 3.10.2": "发行说明:3.10.2", "Skip update navigation": "跳过更新导航", - "1 file": "1 个文件" + "1 file": "1 个文件", + "Document Outline": "文档大纲", + "Close Document Outline": "关闭文档大纲", + "Document headings": "文档标题", + "No headings in this document.": "此文档没有标题。", + "Untitled heading": "未命名标题" } diff --git a/assets/lucide-icons.css b/assets/lucide-icons.css index 65b1628b..9605109c 100644 --- a/assets/lucide-icons.css +++ b/assets/lucide-icons.css @@ -150,3 +150,4 @@ .lucide-x { --lucide-icon: url("data:image/svg+xml;base64,PCEtLSBAbGljZW5zZSBsdWNpZGUtc3RhdGljIHYxLjI1LjAgLSBJU0MgLS0+IDxzdmcgY2xhc3M9Imx1Y2lkZSBsdWNpZGUteCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgPiA8cGF0aCBkPSJNMTggNiA2IDE4IiAvPiA8cGF0aCBkPSJtNiA2IDEyIDEyIiAvPiA8L3N2Zz4="); } .lucide-zoom-in { --lucide-icon: url("data:image/svg+xml;base64,PCEtLSBAbGljZW5zZSBsdWNpZGUtc3RhdGljIHYxLjI1LjAgLSBJU0MgLS0+IDxzdmcgY2xhc3M9Imx1Y2lkZSBsdWNpZGUtem9vbS1pbiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgPiA8Y2lyY2xlIGN4PSIxMSIgY3k9IjExIiByPSI4IiAvPiA8bGluZSB4MT0iMjEiIHgyPSIxNi42NSIgeTE9IjIxIiB5Mj0iMTYuNjUiIC8+IDxsaW5lIHgxPSIxMSIgeDI9IjExIiB5MT0iOCIgeTI9IjE0IiAvPiA8bGluZSB4MT0iOCIgeDI9IjE0IiB5MT0iMTEiIHkyPSIxMSIgLz4gPC9zdmc+"); } .lucide-zoom-out { --lucide-icon: url("data:image/svg+xml;base64,PCEtLSBAbGljZW5zZSBsdWNpZGUtc3RhdGljIHYxLjI1LjAgLSBJU0MgLS0+IDxzdmcgY2xhc3M9Imx1Y2lkZSBsdWNpZGUtem9vbS1vdXQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiID4gPGNpcmNsZSBjeD0iMTEiIGN5PSIxMSIgcj0iOCIgLz4gPGxpbmUgeDE9IjIxIiB4Mj0iMTYuNjUiIHkxPSIyMSIgeTI9IjE2LjY1IiAvPiA8bGluZSB4MT0iOCIgeDI9IjE0IiB5MT0iMTEiIHkyPSIxMSIgLz4gPC9zdmc+"); } +.lucide-square-menu { --lucide-icon: url("data:image/svg+xml;base64,PCEtLSBAbGljZW5zZSBsdWNpZGUtc3RhdGljIHYxLjI1LjAgLSBJU0MgLS0+CjxzdmcKICBjbGFzcz0ibHVjaWRlIGx1Y2lkZS1zcXVhcmUtbWVudSIKICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgd2lkdGg9IjI0IgogIGhlaWdodD0iMjQiCiAgdmlld0JveD0iMCAwIDI0IDI0IgogIGZpbGw9Im5vbmUiCiAgc3Ryb2tlPSJjdXJyZW50Q29sb3IiCiAgc3Ryb2tlLXdpZHRoPSIxLjUiCiAgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIgogIHN0cm9rZS1saW5lam9pbj0icm91bmQiCj4KICA8cmVjdCB3aWR0aD0iMTgiIGhlaWdodD0iMTgiIHg9IjMiIHk9IjMiIHJ4PSIyIiAvPgogIDxwYXRoIGQ9Ik03IDhoMTAiIC8+CiAgPHBhdGggZD0iTTcgMTJoMTAiIC8+CiAgPHBhdGggZD0iTTcgMTZoMTAiIC8+Cjwvc3ZnPgo="); } diff --git a/desktop-app/resources/index.html b/desktop-app/resources/index.html index cd38dfdb..33551fea 100644 --- a/desktop-app/resources/index.html +++ b/desktop-app/resources/index.html @@ -484,6 +484,7 @@

Explorer

+
@@ -1657,6 +1658,18 @@

Where your content goes

+