diff --git a/TODO.md b/TODO.md index 20642dc9..6d625866 100644 --- a/TODO.md +++ b/TODO.md @@ -7,7 +7,7 @@ - [ ] 在通过 Aganippe 打开文件时,无法通过右键选择 Aganippe。(严重 bug) - [ ] 在通过 Aganippe 打开文件时,通过右键选择软件,但是打开无内容。(严重 bug) - [ ] 行内样式,链接小括号中的文本没法复制。 -- [ ] task item: (1)处理方向键 (2)task item 只能和 task item 在一个 ul 中。所以需要优化 update 模块(3)输出和输入。(4)复制黏贴(5) 处理 task item 点击 +- [ ] task item: ~~(1)处理方向键~~ (2)task item 只能和 task item 在一个 ul 中。所以需要优化 update 模块(3)输出和输入。(4)复制黏贴(5) 处理 task item 点击 **菜单** diff --git a/package-lock.json b/package-lock.json index 2bec4cff..70c27939 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,9 +16,18 @@ "integrity": "sha512-s2ZfgRWXeNUQTQE3O85CDDrU2Uo90pMlMkTxkz85wQOuzVxB8t4cubMPup3WlTPFKHQgb6lDkAHS3ljkUSFO6A==", "dev": true, "requires": { - "7zip-bin-mac": "1.0.1" + "7zip-bin-linux": "1.2.0", + "7zip-bin-mac": "1.0.1", + "7zip-bin-win": "2.1.1" } }, + "7zip-bin-linux": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/7zip-bin-linux/-/7zip-bin-linux-1.2.0.tgz", + "integrity": "sha512-umB98LN18XBGKPw4EKET2zPDqVhEU1mxXA1Gx0BM+DoBt4hnlZPNkpSMNzmuNbQshi9SzLhqlTAyKcAgNrbV3Q==", + "dev": true, + "optional": true + }, "7zip-bin-mac": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/7zip-bin-mac/-/7zip-bin-mac-1.0.1.tgz", @@ -26,6 +35,13 @@ "dev": true, "optional": true }, + "7zip-bin-win": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/7zip-bin-win/-/7zip-bin-win-2.1.1.tgz", + "integrity": "sha512-6VGEW7PXGroTsoI2QW3b0ea95HJmbVBHvfANKLLMzSzFA1zKqVX5ybNuhmeGpf6vA0x8FJTt6twpprDANsY5WQ==", + "dev": true, + "optional": true + }, "@types/node": { "version": "8.0.58", "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.58.tgz", @@ -8633,6 +8649,11 @@ "uc.micro": "1.0.3" } }, + "markdown-it-task-lists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/markdown-it-task-lists/-/markdown-it-task-lists-2.1.0.tgz", + "integrity": "sha512-3mT1oQ/brZiV719l3iY/ZIEQLIn60Y9U840l4hh3sA1seHM+ZZjzE5Env1+V1bWqKE1BeVffiuE7qNALzh7r2Q==" + }, "math-expression-evaluator": { "version": "1.2.17", "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz", diff --git a/package.json b/package.json index 18acd482..2af46110 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "codemirror": "^5.31.0", "electron-window-state": "^4.1.1", "markdown-it": "^8.4.0", + "markdown-it-task-lists": "^2.1.0", "mousetrap": "^1.6.1", "parse5": "^3.0.3", "snabbdom": "^0.7.0", diff --git a/src/editor/utils/exportMarkdown.js b/src/editor/utils/exportMarkdown.js index 4a352042..5bfc66a1 100644 --- a/src/editor/utils/exportMarkdown.js +++ b/src/editor/utils/exportMarkdown.js @@ -14,6 +14,7 @@ class ExportMarkdown { const result = [] const len = blocks.length let i + for (i = 0; i < len; i++) { const block = blocks[i] switch (block.type) { @@ -62,6 +63,9 @@ class ExportMarkdown { this.insertLineBreak(result, indent) result.push(this.normalizeBlockquote(block, indent)) break + default: + console.log(block.type) + break } } return result.join('') @@ -113,8 +117,20 @@ class ExportMarkdown { normalizeListItem (block, indent) { const result = [] const listInfo = this.listType[this.listType.length - 1] - const itemMarker = listInfo.type === 'ul' ? '- ' : `${listInfo.listCount++}. ` - const { children } = block + let { children } = block + let itemMarker + + if (listInfo.type === 'ul') { + itemMarker = '- ' + if (block.isTask) { + const firstChild = children[0] + itemMarker += firstChild.checked ? '[x] ' : '[ ] ' + children = children.slice(1) + } + } else { + itemMarker = `${listInfo.listCount++}. ` + } + const newIndent = indent + ' '.repeat(itemMarker.length) result.push(`${indent}${itemMarker}`) diff --git a/src/editor/utils/importMarkdown.js b/src/editor/utils/importMarkdown.js index e19eeac4..b8e68df8 100644 --- a/src/editor/utils/importMarkdown.js +++ b/src/editor/utils/importMarkdown.js @@ -2,6 +2,7 @@ * translate markdown format to content state used by editor */ import MarkdownIt from 'markdown-it' +import taskLists from 'markdown-it-task-lists' import parse5 from 'parse5' import TurndownService from 'turndown' // To be disabled rules when parse markdown, Because content state don't need to parse inline rules @@ -11,6 +12,8 @@ const turndownPluginGfm = require('turndown-plugin-gfm') const md = new MarkdownIt() md.disable(INLINE_RULES) +// use `taskLists` plugin +md.use(taskLists, { enabled: true }) // turn html to markdown const turndownService = new TurndownService(turndownConfig) const gfm = turndownPluginGfm.gfm @@ -88,6 +91,18 @@ const importRegister = ContentState => { this.appendChild(parent, block) break + case 'input': + const isCheckbox = child.attrs.some(attr => attr.name === 'type' && attr.value === 'checkbox') + const checked = child.attrs.some(attr => attr.name === 'checked' && attr.value === '') + + if (isCheckbox && parent.type === 'li') { + parent.isTask = true + block = this.createBlock('input') + block.checked = checked + this.appendChild(parent, block) + } + break + case 'hr': const initValue = '---' block = this.createBlock(child.nodeName, initValue) @@ -95,6 +110,7 @@ const importRegister = ContentState => { break case 'li': + console.log(child) block = this.createBlock('li') this.appendChild(parent, block) if (child.childNodes.length === 1) { @@ -160,6 +176,7 @@ const importRegister = ContentState => { } ContentState.prototype.importMarkdown = function (markdown) { + // empty the blocks and codeBlocks this.keys = new Set() this.codeBlocks = new Map() this.blocks = this.getStateFragment(markdown)