Full document, spreadsheet, slideshow, and diagram tooling
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(docs): markdown task-list autoformat + safer autolink (#721 #722) (#424)

scott 8c731e62 02c37621

+53 -9
+2
CHANGELOG.md
··· 8 8 ## [Unreleased] 9 9 10 10 ### Fixed 11 + - Docs: typing `- [ ] ` or `- [x] ` at the start of a paragraph now autoformats into a GFM task-list item with a checkbox — previously only the `- ` prefix triggered a plain bullet list and `[ ]` appeared as literal text (v0.62.18, #722). Added an InputRule in `src/docs/extensions/markdown-autoformat.ts` that replaces the current paragraph with a `taskList > taskItem > paragraph` node and sets `checked` based on `[x]` vs `[ ]`. (#722) 12 + - Docs: TipTap autolink no longer false-positives on `Y.Map`, `U.S.`, or other `word.word` patterns that aren't real URLs (v0.62.18, #721). Tightened the Link extension config in `src/docs/main.ts` to only autolink URLs starting with `http://`, `https://`, or `mailto:` via an explicit `validate` callback + `protocols: ['http', 'https', 'mailto']`. Manual link insertion via Cmd+K / toolbar remains unrestricted. (#721) 11 13 - Slides: thumbnail element-count badge no longer visually merges with the slide-number, so two slides with single elements used to read as "11"/"22" etc. (v0.62.17, #727). The thumbnail previously rendered `<span class="slides-thumb-num">{N}</span>` followed by a bare `<span class="slides-thumb-count">{M}</span>` inside the preview — with no separator they appeared flush together. Prefixed the count with a `▦` glyph + space and added `aria-label="{M} element(s)"` so screen readers hear "N elements" rather than the number alone. (#727) 12 14 - Slides: each click of "Add text" now offsets the new box by 20×N where N is the current element count on the slide, so repeated clicks don't stack boxes at the identical (100, 100) default position where the second would silently cover the first (v0.62.17, #728). (#728) 13 15 - Forms: Preview and Responses modes hide the "+ Add Question" button and the editable form-description textarea, leaving only the mode-switch bar so the author can toggle back (v0.62.17, #715). Before: Preview mixed builder controls with respondent UI, making it unclear what a real respondent would see. (#715)
+1 -1
package.json
··· 1 1 { 2 2 "name": "tools", 3 - "version": "0.62.17", 3 + "version": "0.62.18", 4 4 "private": true, 5 5 "type": "module", 6 6 "main": "electron/main.js",
+41 -6
src/docs/extensions/markdown-autoformat.ts
··· 2 2 * Markdown autoformat extension for TipTap. 3 3 * 4 4 * Adds custom input rules that are NOT provided by built-in TipTap extensions. 5 - * Currently adds: 6 - * - [text](url) → clickable link 5 + * - [text](url) → clickable link 6 + * - `- [ ] ` → checkbox task-list item (GFM task list). See #722. 7 + * - `- [x] ` → checked task-list item. See #722. 7 8 * 8 - * All other markdown autoformat rules (headings, lists, code blocks, bold, 9 - * italic, strikethrough, inline code, blockquote, horizontal rule, task lists) 10 - * are already handled by StarterKit and the individual TipTap extensions. 9 + * Other rules (headings, bullet/ordered lists, code blocks, bold, italic, 10 + * strikethrough, inline code, blockquote, horizontal rule) are already 11 + * provided by StarterKit. 11 12 */ 12 13 13 14 import { Extension, InputRule } from '@tiptap/core'; 14 - import { linkInputRegex } from '../autoformat-rules.js'; 15 + import { linkInputRegex as _unusedLinkRegex } from '../autoformat-rules.js'; 16 + void _unusedLinkRegex; 15 17 16 18 export const MarkdownAutoformat = Extension.create({ 17 19 name: 'markdownAutoformat', ··· 41 43 42 44 const tr = state.tr; 43 45 tr.replaceWith(start, range.to, textNode); 46 + }, 47 + }) 48 + ); 49 + } 50 + 51 + // GFM task-list autoformat: `- [ ] ` or `- [x] ` at the very start of 52 + // an empty paragraph transforms the paragraph into a single-item 53 + // TaskList. #722 — TaskList's built-in input rule doesn't accept the 54 + // GFM markdown form (it only reacts to literal `- [ ] ` but only as a 55 + // child of an existing bullet-list context in some versions). 56 + const taskListType = this.editor.schema.nodes.taskList; 57 + const taskItemType = this.editor.schema.nodes.taskItem; 58 + const paragraphType = this.editor.schema.nodes.paragraph; 59 + if (taskListType && taskItemType && paragraphType) { 60 + rules.push( 61 + new InputRule({ 62 + // Match at the very start of a paragraph: - [ ] or * [x] etc. 63 + find: /^\s*(?:[-*+])\s+\[([xX ])\]\s$/, 64 + handler: ({ state, range, match, chain: _c, commands }) => { 65 + void _c; void commands; 66 + const checked = /[xX]/.test(match[1] ?? ' '); 67 + const { tr } = state; 68 + const $from = state.doc.resolve(range.from); 69 + // Replace the whole paragraph start (from block start) with a 70 + // taskList > taskItem > paragraph (empty). Delete the "- [ ] " 71 + // literal prefix so the cursor sits inside the task item ready 72 + // for the user to type. 73 + const blockStart = $from.before($from.depth); 74 + const blockEnd = $from.after($from.depth); 75 + const emptyPara = paragraphType.create(); 76 + const taskItem = taskItemType.create({ checked }, emptyPara); 77 + const taskList = taskListType.create(null, taskItem); 78 + tr.replaceRangeWith(blockStart, blockEnd, taskList); 44 79 }, 45 80 }) 46 81 );
+9 -2
src/docs/main.ts
··· 185 185 // CodeBlockLowlight handles code blocks with syntax highlighting. 186 186 codeBlock: false, 187 187 // StarterKit v3 vendors Link — pass our config through instead of 188 - // registering a second Link extension. 189 - link: { openOnClick: false }, 188 + // registering a second Link extension. Require http(s):// protocol 189 + // on autolinks so JS class names like `Y.Map` or acronyms like 190 + // "U.S." don't silently become fake URLs. See #721. 191 + link: { 192 + openOnClick: false, 193 + autolink: true, 194 + protocols: ['http', 'https', 'mailto'], 195 + validate: (url: string) => /^(https?:\/\/|mailto:)/i.test(url), 196 + }, 190 197 }), 191 198 CodeBlockLowlight.configure({ 192 199 lowlight: createLowlight(common),