diff --git a/docs/src/demos/Marks/Subscript/index.spec.js b/docs/src/demos/Marks/Subscript/index.spec.js new file mode 100644 index 00000000..58ebd939 --- /dev/null +++ b/docs/src/demos/Marks/Subscript/index.spec.js @@ -0,0 +1,42 @@ +context('/demos/Marks/Subscript', () => { + before(() => { + cy.visit('/demos/Marks/Subscript') + }) + + beforeEach(() => { + cy.get('.ProseMirror').then(([{ editor }]) => { + editor.commands.setContent('

Example Text

') + cy.get('.ProseMirror').type('{selectall}') + }) + }) + + it('should transform inline style to sub tags', () => { + cy.get('.ProseMirror').then(([{ editor }]) => { + editor.commands.setContent('

Example Text

') + expect(editor.getHTML()).to.eq('

Example Text

') + }) + }) + + it('sould omit inline style with a different vertical align', () => { + cy.get('.ProseMirror').then(([{ editor }]) => { + editor.commands.setContent('

Example Text

') + expect(editor.getHTML()).to.eq('

Example Text

') + }) + }) + + it('the button should make the selected text bold', () => { + cy.get('button:first') + .click() + + cy.get('.ProseMirror') + .find('sub') + .should('contain', 'Example Text') + }) + + it('the button should toggle the selected text bold', () => { + cy.get('button:first').click() + cy.get('.ProseMirror').type('{selectall}') + cy.get('button:first').click() + cy.get('.ProseMirror sub').should('not.exist') + }) +}) diff --git a/docs/src/demos/Marks/Subscript/index.vue b/docs/src/demos/Marks/Subscript/index.vue new file mode 100644 index 00000000..74c19056 --- /dev/null +++ b/docs/src/demos/Marks/Subscript/index.vue @@ -0,0 +1,49 @@ + + + diff --git a/docs/src/demos/Marks/Superscript/index.spec.js b/docs/src/demos/Marks/Superscript/index.spec.js new file mode 100644 index 00000000..9c642cc4 --- /dev/null +++ b/docs/src/demos/Marks/Superscript/index.spec.js @@ -0,0 +1,42 @@ +context('/demos/Marks/Superscript', () => { + before(() => { + cy.visit('/demos/Marks/Superscript') + }) + + beforeEach(() => { + cy.get('.ProseMirror').then(([{ editor }]) => { + editor.commands.setContent('

Example Text

') + cy.get('.ProseMirror').type('{selectall}') + }) + }) + + it('should transform inline style to sup tags', () => { + cy.get('.ProseMirror').then(([{ editor }]) => { + editor.commands.setContent('

Example Text

') + expect(editor.getHTML()).to.eq('

Example Text

') + }) + }) + + it('sould omit inline style with a different vertical align', () => { + cy.get('.ProseMirror').then(([{ editor }]) => { + editor.commands.setContent('

Example Text

') + expect(editor.getHTML()).to.eq('

Example Text

') + }) + }) + + it('the button should make the selected text bold', () => { + cy.get('button:first') + .click() + + cy.get('.ProseMirror') + .find('sup') + .should('contain', 'Example Text') + }) + + it('the button should toggle the selected text bold', () => { + cy.get('button:first').click() + cy.get('.ProseMirror').type('{selectall}') + cy.get('button:first').click() + cy.get('.ProseMirror sup').should('not.exist') + }) +}) diff --git a/docs/src/demos/Marks/Superscript/index.vue b/docs/src/demos/Marks/Superscript/index.vue new file mode 100644 index 00000000..dbea51ce --- /dev/null +++ b/docs/src/demos/Marks/Superscript/index.vue @@ -0,0 +1,49 @@ + + + diff --git a/docs/src/docPages/api/marks.md b/docs/src/docPages/api/marks.md index 9ff4dc1a..48094aee 100644 --- a/docs/src/docPages/api/marks.md +++ b/docs/src/docPages/api/marks.md @@ -6,13 +6,15 @@ One or multiple marks can be applied to [nodes](/api/nodes), for example to add inline formatting like bold and italic, or other additional information. ## List of supported marks -| Title | Default Extension | Source Code | -| ---------------------------------- | ----------------- | -------------------------------------------------------------------------------------------- | -| [Bold](/api/marks/bold) | Yes | [GitHub](https://github.com/ueberdosis/tiptap/blob/main/packages/extension-bold/) | -| [Code](/api/marks/code) | Yes | [GitHub](https://github.com/ueberdosis/tiptap/blob/main/packages/extension-code/) | -| [Highlight](/api/marks/highlight) | – | [GitHub](https://github.com/ueberdosis/tiptap/blob/main/packages/extension-highlight/) | -| [Italic](/api/marks/italic) | Yes | [GitHub](https://github.com/ueberdosis/tiptap/blob/main/packages/extension-italic/) | -| [Link](/api/marks/link) | – | [GitHub](https://github.com/ueberdosis/tiptap/blob/main/packages/extension-link/) | -| [Strike](/api/marks/strike) | Yes | [GitHub](https://github.com/ueberdosis/tiptap/blob/main/packages/extension-strike/) | -| [TextStyle](/api/marks/text-style) | Yes | [GitHub](https://github.com/ueberdosis/tiptap/blob/main/packages/extension-text-style/) | -| [Underline](/api/marks/underline) | – | [GitHub](https://github.com/ueberdosis/tiptap/blob/main/packages/extension-underline/) | +| Title | Default Extension | Source Code | +| ------------------------------------- | ----------------- | ---------------------------------------------------------------------------------------- | +| [Bold](/api/marks/bold) | Yes | [GitHub](https://github.com/ueberdosis/tiptap/blob/main/packages/extension-bold/) | +| [Code](/api/marks/code) | Yes | [GitHub](https://github.com/ueberdosis/tiptap/blob/main/packages/extension-code/) | +| [Highlight](/api/marks/highlight) | – | [GitHub](https://github.com/ueberdosis/tiptap/blob/main/packages/extension-highlight/) | +| [Italic](/api/marks/italic) | Yes | [GitHub](https://github.com/ueberdosis/tiptap/blob/main/packages/extension-italic/) | +| [Link](/api/marks/link) | – | [GitHub](https://github.com/ueberdosis/tiptap/blob/main/packages/extension-link/) | +| [Strike](/api/marks/strike) | Yes | [GitHub](https://github.com/ueberdosis/tiptap/blob/main/packages/extension-strike/) | +| [Subscript](/api/marks/subscript) | – | [GitHub](https://github.com/ueberdosis/tiptap/blob/main/packages/extension-subscript/) | +| [Superscript](/api/marks/superscript) | – | [GitHub](https://github.com/ueberdosis/tiptap/blob/main/packages/extension-superscript/) | +| [TextStyle](/api/marks/text-style) | Yes | [GitHub](https://github.com/ueberdosis/tiptap/blob/main/packages/extension-text-style/) | +| [Underline](/api/marks/underline) | – | [GitHub](https://github.com/ueberdosis/tiptap/blob/main/packages/extension-underline/) | diff --git a/docs/src/docPages/api/marks/subscript.md b/docs/src/docPages/api/marks/subscript.md new file mode 100644 index 00000000..64778343 --- /dev/null +++ b/docs/src/docPages/api/marks/subscript.md @@ -0,0 +1,32 @@ +# Subscript +[![Version](https://img.shields.io/npm/v/@tiptap/extension-subscript.svg?label=version)](https://www.npmjs.com/package/@tiptap/extension-subscript) +[![Downloads](https://img.shields.io/npm/dm/@tiptap/extension-subscript.svg)](https://npmcharts.com/compare/@tiptap/extension-subscript?minimal=true) + +Use this extension to render text in subscript. If you pass `` or text with `vertical-align: sub` as inline style in the editor’s initial content, both will be normalized to a `` HTML tag. + +## Installation +```bash +# with npm +npm install @tiptap/extension-subscript + +# with Yarn +yarn add @tiptap/extension-subscript +``` + +## Settings +| Option | Type | Default | Description | +| -------------- | -------- | ------- | --------------------------------------------------------------------- | +| HTMLAttributes | `Object` | `{}` | Custom HTML attributes that should be added to the rendered HTML tag. | + +## Commands +| Command | Parameters | Description | +| --------------- | ---------- | ------------------------- | +| setSubscript | — | Mark text as subscript. | +| toggleSubscript | — | Toggle subscript mark. | +| unsetSubscript | — | Remove subscript mark. | + +## Source code +[packages/extension-subscript/](https://github.com/ueberdosis/tiptap/blob/main/packages/extension-subscript/) + +## Usage + diff --git a/docs/src/docPages/api/marks/superscript.md b/docs/src/docPages/api/marks/superscript.md new file mode 100644 index 00000000..5a0a9c53 --- /dev/null +++ b/docs/src/docPages/api/marks/superscript.md @@ -0,0 +1,32 @@ +# Superscript +[![Version](https://img.shields.io/npm/v/@tiptap/extension-superscript.svg?label=version)](https://www.npmjs.com/package/@tiptap/extension-superscript) +[![Downloads](https://img.shields.io/npm/dm/@tiptap/extension-superscript.svg)](https://npmcharts.com/compare/@tiptap/extension-superscript?minimal=true) + +Use this extension to render text in superscript. If you pass `` or text with `vertical-align: super` as inline style in the editor’s initial content, both will be normalized to a `` HTML tag. + +## Installation +```bash +# with npm +npm install @tiptap/extension-superscript + +# with Yarn +yarn add @tiptap/extension-superscript +``` + +## Settings +| Option | Type | Default | Description | +| -------------- | -------- | ------- | --------------------------------------------------------------------- | +| HTMLAttributes | `Object` | `{}` | Custom HTML attributes that should be added to the rendered HTML tag. | + +## Commands +| Command | Parameters | Description | +| ----------------- | ---------- | ------------------------- | +| setSuperscript | — | Mark text as superscript. | +| toggleSuperscript | — | Toggle superscript mark. | +| unsetSuperscript | — | Remove superscript mark. | + +## Source code +[packages/extension-superscript/](https://github.com/ueberdosis/tiptap/blob/main/packages/extension-superscript/) + +## Usage + diff --git a/docs/src/links.yaml b/docs/src/links.yaml index 83f1ffdb..8808035e 100644 --- a/docs/src/links.yaml +++ b/docs/src/links.yaml @@ -320,6 +320,12 @@ link: /api/marks/link - title: Strike link: /api/marks/strike + - title: Subscript + link: /api/marks/subscript + type: new + - title: Superscript + link: /api/marks/superscript + type: new - title: TextStyle link: /api/marks/text-style - title: Underline diff --git a/packages/extension-subscript/README.md b/packages/extension-subscript/README.md new file mode 100644 index 00000000..c231aebc --- /dev/null +++ b/packages/extension-subscript/README.md @@ -0,0 +1,14 @@ +# @tiptap/extension-superscript +[![Version](https://img.shields.io/npm/v/@tiptap/extension-superscript.svg?label=version)](https://www.npmjs.com/package/@tiptap/extension-superscript) +[![Downloads](https://img.shields.io/npm/dm/@tiptap/extension-superscript.svg)](https://npmcharts.com/compare/tiptap?minimal=true) +[![License](https://img.shields.io/npm/l/@tiptap/extension-superscript.svg)](https://www.npmjs.com/package/@tiptap/extension-superscript) +[![Sponsor](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub)](https://github.com/sponsors/ueberdosis) + +## Introduction +tiptap is a headless wrapper around [ProseMirror](https://ProseMirror.net) – a toolkit for building rich text WYSIWYG editors, which is already in use at many well-known companies such as *New York Times*, *The Guardian* or *Atlassian*. + +## Official Documentation +Documentation can be found on the [tiptap website](https://tiptap.dev). + +## License +tiptap is open sourced software licensed under the [MIT license](https://github.com/ueberdosis/tiptap/blob/main/LICENSE.md). diff --git a/packages/extension-subscript/package.json b/packages/extension-subscript/package.json new file mode 100644 index 00000000..f0840062 --- /dev/null +++ b/packages/extension-subscript/package.json @@ -0,0 +1,26 @@ +{ + "name": "@tiptap/extension-subscript", + "description": "subscript extension for tiptap", + "version": "2.0.0-beta.1", + "homepage": "https://tiptap.dev", + "keywords": [ + "tiptap", + "tiptap extension" + ], + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "main": "dist/tiptap-extension-subscript.cjs.js", + "umd": "dist/tiptap-extension-subscript.umd.js", + "module": "dist/tiptap-extension-subscript.esm.js", + "types": "dist/packages/extension-subscript/src/index.d.ts", + "files": [ + "src", + "dist" + ], + "peerDependencies": { + "@tiptap/core": "^2.0.0-beta.1" + } +} diff --git a/packages/extension-subscript/src/index.ts b/packages/extension-subscript/src/index.ts new file mode 100644 index 00000000..f1056848 --- /dev/null +++ b/packages/extension-subscript/src/index.ts @@ -0,0 +1,5 @@ +import { Subscript } from './subscript' + +export * from './subscript' + +export default Subscript diff --git a/packages/extension-subscript/src/subscript.ts b/packages/extension-subscript/src/subscript.ts new file mode 100644 index 00000000..06636207 --- /dev/null +++ b/packages/extension-subscript/src/subscript.ts @@ -0,0 +1,69 @@ +import { Command, Mark, mergeAttributes } from '@tiptap/core' + +export interface SubscriptExtensionOptions { + HTMLAttributes: Object, +} + +declare module '@tiptap/core' { + interface Commands { + subscript: { + /** + * Set a subscript mark + */ + setSubscript: () => Command, + /** + * Toggle a subscript mark + */ + toggleSubscript: () => Command, + /** + * Unset a subscript mark + */ + unsetSubscript: () => Command, + } + } +} + +export const Subscript = Mark.create({ + name: 'subscript', + + defaultOptions: { + HTMLAttributes: {}, + }, + + parseHTML() { + return [ + { + tag: 'sub', + }, + { + style: 'vertical-align', + getAttrs(value) { + // Don’t match this rule if the vertical align isn’t sub. + if (value !== 'sub') { + return false + } + + // If it falls through we’ll match, and this mark will be applied. + }, + }, + ] + }, + + renderHTML({ HTMLAttributes }) { + return ['sub', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0] + }, + + addCommands() { + return { + setSubscript: () => ({ commands }) => { + return commands.setMark('subscript') + }, + toggleSubscript: () => ({ commands }) => { + return commands.toggleMark('subscript') + }, + unsetSubscript: () => ({ commands }) => { + return commands.unsetMark('subscript') + }, + } + }, +}) diff --git a/packages/extension-superscript/README.md b/packages/extension-superscript/README.md new file mode 100644 index 00000000..c231aebc --- /dev/null +++ b/packages/extension-superscript/README.md @@ -0,0 +1,14 @@ +# @tiptap/extension-superscript +[![Version](https://img.shields.io/npm/v/@tiptap/extension-superscript.svg?label=version)](https://www.npmjs.com/package/@tiptap/extension-superscript) +[![Downloads](https://img.shields.io/npm/dm/@tiptap/extension-superscript.svg)](https://npmcharts.com/compare/tiptap?minimal=true) +[![License](https://img.shields.io/npm/l/@tiptap/extension-superscript.svg)](https://www.npmjs.com/package/@tiptap/extension-superscript) +[![Sponsor](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub)](https://github.com/sponsors/ueberdosis) + +## Introduction +tiptap is a headless wrapper around [ProseMirror](https://ProseMirror.net) – a toolkit for building rich text WYSIWYG editors, which is already in use at many well-known companies such as *New York Times*, *The Guardian* or *Atlassian*. + +## Official Documentation +Documentation can be found on the [tiptap website](https://tiptap.dev). + +## License +tiptap is open sourced software licensed under the [MIT license](https://github.com/ueberdosis/tiptap/blob/main/LICENSE.md). diff --git a/packages/extension-superscript/package.json b/packages/extension-superscript/package.json new file mode 100644 index 00000000..e3a1fd2b --- /dev/null +++ b/packages/extension-superscript/package.json @@ -0,0 +1,26 @@ +{ + "name": "@tiptap/extension-superscript", + "description": "superscript extension for tiptap", + "version": "2.0.0-beta.1", + "homepage": "https://tiptap.dev", + "keywords": [ + "tiptap", + "tiptap extension" + ], + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "main": "dist/tiptap-extension-superscript.cjs.js", + "umd": "dist/tiptap-extension-superscript.umd.js", + "module": "dist/tiptap-extension-superscript.esm.js", + "types": "dist/packages/extension-superscript/src/index.d.ts", + "files": [ + "src", + "dist" + ], + "peerDependencies": { + "@tiptap/core": "^2.0.0-beta.1" + } +} diff --git a/packages/extension-superscript/src/index.ts b/packages/extension-superscript/src/index.ts new file mode 100644 index 00000000..23c2140e --- /dev/null +++ b/packages/extension-superscript/src/index.ts @@ -0,0 +1,5 @@ +import { Superscript } from './superscript' + +export * from './superscript' + +export default Superscript diff --git a/packages/extension-superscript/src/superscript.ts b/packages/extension-superscript/src/superscript.ts new file mode 100644 index 00000000..26a348aa --- /dev/null +++ b/packages/extension-superscript/src/superscript.ts @@ -0,0 +1,69 @@ +import { Command, Mark, mergeAttributes } from '@tiptap/core' + +export interface SuperscriptExtensionOptions { + HTMLAttributes: Object, +} + +declare module '@tiptap/core' { + interface Commands { + superscript: { + /** + * Set a superscript mark + */ + setSuperscript: () => Command, + /** + * Toggle a superscript mark + */ + toggleSuperscript: () => Command, + /** + * Unset a superscript mark + */ + unsetSuperscript: () => Command, + } + } +} + +export const Superscript = Mark.create({ + name: 'superscript', + + defaultOptions: { + HTMLAttributes: {}, + }, + + parseHTML() { + return [ + { + tag: 'sup', + }, + { + style: 'vertical-align', + getAttrs(value) { + // Don’t match this rule if the vertical align isn’t super. + if (value !== 'super') { + return false + } + + // If it falls through we’ll match, and this mark will be applied. + }, + }, + ] + }, + + renderHTML({ HTMLAttributes }) { + return ['sup', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0] + }, + + addCommands() { + return { + setSuperscript: () => ({ commands }) => { + return commands.setMark('superscript') + }, + toggleSuperscript: () => ({ commands }) => { + return commands.toggleMark('superscript') + }, + unsetSuperscript: () => ({ commands }) => { + return commands.unsetMark('superscript') + }, + } + }, +})