From 576f3e1caa9cc5d4b880b3863463162cc80592f9 Mon Sep 17 00:00:00 2001 From: Hans Pagel Date: Wed, 30 Sep 2020 16:25:32 +0200 Subject: [PATCH 1/4] add language support to code blocks --- .../demos/Extensions/CodeBlock/index.spec.js | 10 ++++++++++ packages/extension-code-block/index.ts | 20 ++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/docs/src/demos/Extensions/CodeBlock/index.spec.js b/docs/src/demos/Extensions/CodeBlock/index.spec.js index 657878a1..746605c0 100644 --- a/docs/src/demos/Extensions/CodeBlock/index.spec.js +++ b/docs/src/demos/Extensions/CodeBlock/index.spec.js @@ -69,6 +69,16 @@ context('/api/extensions/code-block', () => { }) }) + it('should parse the language from a HTML code block', () => { + cy.get('.ProseMirror').then(([{ editor }]) => { + editor.setContent('
body { display: none; }
') + + cy.get('.ProseMirror') + .find('pre>code.language-css') + .should('have.length', 1) + }) + }) + it('should make a code block for js', () => { cy.get('.ProseMirror').then(([{ editor }]) => { editor.clearContent() diff --git a/packages/extension-code-block/index.ts b/packages/extension-code-block/index.ts index ab2bf10a..66a670d1 100644 --- a/packages/extension-code-block/index.ts +++ b/packages/extension-code-block/index.ts @@ -26,7 +26,25 @@ export default new Node() defining: true, draggable: false, parseDOM: [ - { tag: 'pre', preserveWhitespace: 'full' }, + { + tag: 'pre', + preserveWhitespace: 'full', + getAttrs(dom) { + const code = (dom as HTMLElement).firstChild + + if (!code) { + return null + } + + const classAttribute = ((code as HTMLElement).getAttribute('class') as string) + + if (!classAttribute) { + return null + } + + return { language: classAttribute.replace(/^(language-)/, '') } + }, + }, ], toDOM: node => ['pre', ['code', { class: node.attrs.language && `language-${node.attrs.language}` }, 0]], })) From ecfa26b28adbfde4c18f749e0bb838fadebf3494 Mon Sep 17 00:00:00 2001 From: Hans Pagel Date: Wed, 30 Sep 2020 16:33:13 +0200 Subject: [PATCH 2/4] add support to configure the languageClassPrefix --- docs/src/docPages/api/extensions/code-block.md | 7 ++++--- packages/extension-code-block/index.ts | 17 +++++++++++++---- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/docs/src/docPages/api/extensions/code-block.md b/docs/src/docPages/api/extensions/code-block.md index 7f58eff6..6608c521 100644 --- a/docs/src/docPages/api/extensions/code-block.md +++ b/docs/src/docPages/api/extensions/code-block.md @@ -17,9 +17,10 @@ yarn add @tiptap/extension-code-block ``` ## Settings -| Option | Type | Default | Description | -| ------ | ------ | ------- | -------------------------------------------- | -| class | string | – | Add a custom class to the rendered HTML tag. | +| Option | Type | Default | Description | +| ------------------- | ------ | --------- | ---------------------------------------------------------------- | +| class | string | – | Add a custom class to the rendered HTML tag. | +| languageClassPrefix | string | language- | Adds a prefix to language classes that are applied to code tags. | ## Commands | Command | Options | Description | diff --git a/packages/extension-code-block/index.ts b/packages/extension-code-block/index.ts index 66a670d1..4ee60c57 100644 --- a/packages/extension-code-block/index.ts +++ b/packages/extension-code-block/index.ts @@ -1,6 +1,10 @@ import { Command, Node } from '@tiptap/core' import { textblockTypeInputRule } from 'prosemirror-inputrules' +export interface CodeBlockOptions { + languageClassPrefix: string, +} + export type CodeBlockCommand = () => Command declare module '@tiptap/core/src/Editor' { @@ -11,9 +15,12 @@ declare module '@tiptap/core/src/Editor' { export const inputRegex = /^```(?[a-z]*)? $/ -export default new Node() +export default new Node() .name('code_block') - .schema(() => ({ + .defaults({ + languageClassPrefix: 'language-', + }) + .schema(({ options }) => ({ attrs: { language: { default: null, @@ -42,11 +49,13 @@ export default new Node() return null } - return { language: classAttribute.replace(/^(language-)/, '') } + const regexLanguageClassPrefix = new RegExp(`^(${options.languageClassPrefix})`) + + return { language: classAttribute.replace(regexLanguageClassPrefix, '') } }, }, ], - toDOM: node => ['pre', ['code', { class: node.attrs.language && `language-${node.attrs.language}` }, 0]], + toDOM: node => ['pre', ['code', { class: node.attrs.language && options.languageClassPrefix + node.attrs.language }, 0]], })) .commands(({ name }) => ({ codeBlock: attrs => ({ commands }) => { From f61c9883e31f2083a8d79c916fd1fd7f5c199810 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Wed, 30 Sep 2020 19:19:42 +0200 Subject: [PATCH 3/4] fix optional chaining --- babel.config.js | 1 + package.json | 1 + tsconfig.json | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/babel.config.js b/babel.config.js index ba993da5..016cb186 100644 --- a/babel.config.js +++ b/babel.config.js @@ -3,6 +3,7 @@ module.exports = { '@babel/preset-env', ], plugins: [ + '@babel/plugin-proposal-nullish-coalescing-operator', '@babel/plugin-proposal-optional-chaining', ], } diff --git a/package.json b/package.json index 40e28492..5c95f518 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "reset": "yarn clean:packages && rm -rf ./**/.cache && rm -rf ./**/node_modules && rm -rf ./yarn.lock && yarn install" }, "devDependencies": { + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4", "@babel/plugin-proposal-optional-chaining": "^7.11.0", "@babel/preset-env": "^7.11.5", "@types/prosemirror-commands": "^1.0.3", diff --git a/tsconfig.json b/tsconfig.json index 107fcef6..96ec68b1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "esnext", + "target": "es2019", "module": "esnext", "strict": true, "jsx": "preserve", From 5010abb01b51a0c07c3c2f26999c8f126011ba43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Wed, 30 Sep 2020 19:19:51 +0200 Subject: [PATCH 4/4] refactoring --- packages/extension-code-block/index.ts | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/packages/extension-code-block/index.ts b/packages/extension-code-block/index.ts index 4ee60c57..4119e7ec 100644 --- a/packages/extension-code-block/index.ts +++ b/packages/extension-code-block/index.ts @@ -36,14 +36,8 @@ export default new Node() { tag: 'pre', preserveWhitespace: 'full', - getAttrs(dom) { - const code = (dom as HTMLElement).firstChild - - if (!code) { - return null - } - - const classAttribute = ((code as HTMLElement).getAttribute('class') as string) + getAttrs(node) { + const classAttribute = (node as Element).firstElementChild?.getAttribute('class') if (!classAttribute) { return null @@ -55,7 +49,9 @@ export default new Node() }, }, ], - toDOM: node => ['pre', ['code', { class: node.attrs.language && options.languageClassPrefix + node.attrs.language }, 0]], + toDOM: node => ['pre', ['code', { + class: node.attrs.language && options.languageClassPrefix + node.attrs.language, + }, 0]], })) .commands(({ name }) => ({ codeBlock: attrs => ({ commands }) => {