feat!: Replace defaultOptions with addOptions (#2088)

* add new addOptions option

* replace defaultOptions with addOptions for all extensions

* replace defaultOptions with addOptions for all demos

* replace defaultOptions with addOptions in docs

* refactoring

* refactoring

* drop object support for addOptions

* fix optional options

* fix tests
This commit is contained in:
Philipp Kühn 2021-10-26 18:31:13 +02:00 committed by GitHub
parent 2fff9c264b
commit 9afadeb7fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
57 changed files with 622 additions and 233 deletions

View File

@ -59,20 +59,22 @@ declare module '@tiptap/core' {
}
}
export const CollaborationAnnotation = Extension.create({
export const CollaborationAnnotation = Extension.create<AnnotationOptions>({
name: 'annotation',
priority: 1000,
defaultOptions: <AnnotationOptions>{
HTMLAttributes: {
class: 'annotation',
},
onUpdate: decorations => decorations,
document: null,
field: 'annotations',
map: null,
instance: '',
addOptions() {
return {
HTMLAttributes: {
class: 'annotation',
},
onUpdate: decorations => decorations,
document: null,
field: 'annotations',
map: null,
instance: '',
}
},
onCreate() {

View File

@ -2,16 +2,17 @@ import { Extension } from '@tiptap/core'
import Suggestion from '@tiptap/suggestion'
export default Extension.create({
name: 'mention',
name: 'commands',
defaultOptions: {
suggestion: {
char: '/',
startOfLine: false,
command: ({ editor, range, props }) => {
props.command({ editor, range })
addOptions() {
return {
suggestion: {
char: '/',
command: ({ editor, range, props }) => {
props.command({ editor, range })
},
},
},
}
},
addProseMirrorPlugins() {

View File

@ -17,8 +17,10 @@ export default Node.create<DetailsSummaryOptions>({
isolating: true,
defaultOptions: {
HTMLAttributes: {},
addOptions() {
return {
HTMLAttributes: {},
}
},
parseHTML() {

View File

@ -34,8 +34,10 @@ export default Node.create<DetailsOptions>({
// defining: true,
defaultOptions: {
HTMLAttributes: {},
addOptions() {
return {
HTMLAttributes: {},
}
},
parseHTML() {

View File

@ -18,18 +18,20 @@ declare module '@tiptap/core' {
}
}
export default Node.create({
export default Node.create<IframeOptions>({
name: 'iframe',
group: 'block',
atom: true,
defaultOptions: <IframeOptions>{
allowFullscreen: true,
HTMLAttributes: {
class: 'iframe-wrapper',
},
addOptions() {
return {
allowFullscreen: true,
HTMLAttributes: {
class: 'iframe-wrapper',
},
}
},
addAttributes() {

View File

@ -41,8 +41,10 @@ export const inputRegex = /!\[(.+|:?)]\((\S+)(?:(?:\s+)["'](\S+)["'])?\)/
export const Figure = Node.create<FigureOptions>({
name: 'figure',
defaultOptions: {
HTMLAttributes: {},
addOptions() {
return {
HTMLAttributes: {},
}
},
group: 'block',

View File

@ -3,8 +3,10 @@ import { Node, mergeAttributes } from '@tiptap/core'
export const Figcaption = Node.create({
name: 'figcaption',
defaultOptions: {
HTMLAttributes: {},
addOptions() {
return {
HTMLAttributes: {},
}
},
content: 'inline*',

View File

@ -4,8 +4,10 @@ import { Plugin } from 'prosemirror-state'
export const Figure = Node.create({
name: 'figure',
defaultOptions: {
HTMLAttributes: {},
addOptions() {
return {
HTMLAttributes: {},
}
},
group: 'block',

View File

@ -39,11 +39,13 @@ export interface LinterOptions {
plugins: Array<typeof LinterPlugin>,
}
export const Linter = Extension.create({
export const Linter = Extension.create<LinterOptions>({
name: 'linter',
defaultOptions: <LinterOptions>{
plugins: [],
addOptions() {
return {
plugins: [],
}
},
addProseMirrorPlugins() {

View File

@ -20,11 +20,13 @@ export interface TrailingNodeOptions {
export const TrailingNode = Extension.create<TrailingNodeOptions>({
name: 'trailingNode',
defaultOptions: {
node: 'paragraph',
notAfter: [
'paragraph',
],
addOptions() {
return {
node: 'paragraph',
notAfter: [
'paragraph',
],
}
},
addProseMirrorPlugins() {

View File

@ -71,9 +71,11 @@ All settings can be configured through the extension anyway, but if you want to
import Heading from '@tiptap/extension-heading'
const CustomHeading = Heading.extend({
defaultOptions: {
...Heading.options,
levels: [1, 2, 3],
addOptions() {
return {
...this.parent(),
levels: [1, 2, 3],
}
},
})
```

View File

@ -26,8 +26,10 @@ export interface CustomExtensionOptions {
}
const CustomExtension = Extension.create<CustomExtensionOptions>({
defaultOptions: {
awesomeness: 100,
addOptions() {
return {
awesomeness: 100,
}
},
})
```

View File

@ -103,7 +103,7 @@ import { Node } from '@tiptap/core'
const CustomExtension = Node.create({
name: 'custom_extension',
defaultOptions: {
addOptions() {
},
addAttributes() {

View File

@ -36,13 +36,21 @@ declare module '@tiptap/core' {
*/
defaultOptions?: Options,
/**
* Default Options
*/
addOptions?: (this: {
name: string,
parent: Exclude<ParentConfig<ExtensionConfig<Options, Storage>>['addOptions'], undefined>,
}) => Options,
/**
* Default Storage
*/
addStorage?: (this: {
name: string,
options: Options,
parent: ParentConfig<ExtensionConfig<Options, Storage>>['addGlobalAttributes'],
parent: Exclude<ParentConfig<ExtensionConfig<Options, Storage>>['addStorage'], undefined>,
}) => Storage,
/**
@ -278,7 +286,24 @@ export class Extension<Options = any, Storage = any> {
}
this.name = this.config.name
if (config.defaultOptions) {
console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${this.name}".`)
}
// TODO: remove `addOptions` fallback
this.options = this.config.defaultOptions
if (this.config.addOptions) {
this.options = callOrReturn(getExtensionField<AnyConfig['addOptions']>(
this,
'addOptions',
{
name: this.name,
},
))
}
this.storage = callOrReturn(getExtensionField<AnyConfig['addStorage']>(
this,
'addStorage',
@ -286,7 +311,7 @@ export class Extension<Options = any, Storage = any> {
name: this.name,
options: this.options,
},
))
)) || {}
}
static create<O = any, S = any>(config: Partial<ExtensionConfig<O, S>> = {}) {
@ -323,10 +348,25 @@ export class Extension<Options = any, Storage = any> {
? extendedConfig.name
: extension.parent.name
if (extendedConfig.defaultOptions) {
console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${extension.name}".`)
}
// TODO: remove `addOptions` fallback
extension.options = extendedConfig.defaultOptions
? extendedConfig.defaultOptions
: extension.parent.options
if (extendedConfig.addOptions) {
extension.options = callOrReturn(getExtensionField<AnyConfig['addOptions']>(
extension,
'addOptions',
{
name: extension.name,
},
))
}
extension.storage = callOrReturn(getExtensionField<AnyConfig['addStorage']>(
extension,
'addStorage',

View File

@ -42,13 +42,21 @@ declare module '@tiptap/core' {
*/
defaultOptions?: Options,
/**
* Default Options
*/
addOptions?: (this: {
name: string,
parent: Exclude<ParentConfig<MarkConfig<Options, Storage>>['addOptions'], undefined>,
}) => Options,
/**
* Default Storage
*/
addStorage?: (this: {
addStorage?: (this: {
name: string,
options: Options,
parent: ParentConfig<MarkConfig<Options, Storage>>['addGlobalAttributes'],
parent: Exclude<ParentConfig<MarkConfig<Options, Storage>>['addStorage'], undefined>,
}) => Storage,
/**
@ -392,7 +400,24 @@ export class Mark<Options = any, Storage = any> {
}
this.name = this.config.name
if (config.defaultOptions) {
console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${this.name}".`)
}
// TODO: remove `addOptions` fallback
this.options = this.config.defaultOptions
if (this.config.addOptions) {
this.options = callOrReturn(getExtensionField<AnyConfig['addOptions']>(
this,
'addOptions',
{
name: this.name,
},
))
}
this.storage = callOrReturn(getExtensionField<AnyConfig['addStorage']>(
this,
'addStorage',
@ -400,7 +425,7 @@ export class Mark<Options = any, Storage = any> {
name: this.name,
options: this.options,
},
))
)) || {}
}
static create<O = any, S = any>(config: Partial<MarkConfig<O, S>> = {}) {
@ -437,10 +462,25 @@ export class Mark<Options = any, Storage = any> {
? extendedConfig.name
: extension.parent.name
if (extendedConfig.defaultOptions) {
console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${extension.name}".`)
}
// TODO: remove `addOptions` fallback
extension.options = extendedConfig.defaultOptions
? extendedConfig.defaultOptions
: extension.parent.options
if (extendedConfig.addOptions) {
extension.options = callOrReturn(getExtensionField<AnyConfig['addOptions']>(
extension,
'addOptions',
{
name: extension.name,
},
))
}
extension.storage = callOrReturn(getExtensionField<AnyConfig['addStorage']>(
extension,
'addStorage',

View File

@ -42,13 +42,21 @@ declare module '@tiptap/core' {
*/
defaultOptions?: Options,
/**
* Default Options
*/
addOptions?: (this: {
name: string,
parent: Exclude<ParentConfig<NodeConfig<Options, Storage>>['addOptions'], undefined>,
}) => Options,
/**
* Default Storage
*/
addStorage?: (this: {
name: string,
options: Options,
parent: ParentConfig<NodeConfig<Options, Storage>>['addGlobalAttributes'],
parent: Exclude<ParentConfig<NodeConfig<Options, Storage>>['addStorage'], undefined>,
}) => Storage,
/**
@ -472,7 +480,24 @@ export class Node<Options = any, Storage = any> {
}
this.name = this.config.name
if (config.defaultOptions) {
console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${this.name}".`)
}
// TODO: remove `addOptions` fallback
this.options = this.config.defaultOptions
if (this.config.addOptions) {
this.options = callOrReturn(getExtensionField<AnyConfig['addOptions']>(
this,
'addOptions',
{
name: this.name,
},
))
}
this.storage = callOrReturn(getExtensionField<AnyConfig['addStorage']>(
this,
'addStorage',
@ -480,7 +505,7 @@ export class Node<Options = any, Storage = any> {
name: this.name,
options: this.options,
},
))
)) || {}
}
static create<O = any, S = any>(config: Partial<NodeConfig<O, S>> = {}) {
@ -517,10 +542,25 @@ export class Node<Options = any, Storage = any> {
? extendedConfig.name
: extension.parent.name
if (extendedConfig.defaultOptions) {
console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${extension.name}".`)
}
// TODO: remove `addOptions` fallback
extension.options = extendedConfig.defaultOptions
? extendedConfig.defaultOptions
: extension.parent.options
if (extendedConfig.addOptions) {
extension.options = callOrReturn(getExtensionField<AnyConfig['addOptions']>(
extension,
'addOptions',
{
name: extension.name,
},
))
}
extension.storage = callOrReturn(getExtensionField<AnyConfig['addStorage']>(
extension,
'addStorage',

View File

@ -29,8 +29,10 @@ export const Blockquote = Node.create<BlockquoteOptions>({
name: 'blockquote',
defaultOptions: {
HTMLAttributes: {},
addOptions() {
return {
HTMLAttributes: {},
}
},
content: 'block*',

View File

@ -36,8 +36,10 @@ export const underscorePasteRegex = /(?:^|\s)((?:__)((?:[^__]+))(?:__))/g
export const Bold = Mark.create<BoldOptions>({
name: 'bold',
defaultOptions: {
HTMLAttributes: {},
addOptions() {
return {
HTMLAttributes: {},
}
},
parseHTML() {

View File

@ -8,11 +8,13 @@ export type BubbleMenuOptions = Omit<BubbleMenuPluginProps, 'editor' | 'element'
export const BubbleMenu = Extension.create<BubbleMenuOptions>({
name: 'bubbleMenu',
defaultOptions: {
element: null,
tippyOptions: {},
pluginKey: 'bubbleMenu',
shouldShow: null,
addOptions() {
return {
element: null,
tippyOptions: {},
pluginKey: 'bubbleMenu',
shouldShow: null,
}
},
addProseMirrorPlugins() {

View File

@ -20,8 +20,10 @@ export const inputRegex = /^\s*([-+*])\s$/
export const BulletList = Node.create<BulletListOptions>({
name: 'bulletList',
defaultOptions: {
HTMLAttributes: {},
addOptions() {
return {
HTMLAttributes: {},
}
},
group: 'block list',

View File

@ -10,8 +10,10 @@ export interface CharacterCountOptions {
export const CharacterCount = Extension.create<CharacterCountOptions>({
name: 'characterCount',
defaultOptions: {
limit: 0,
addOptions() {
return {
limit: 0,
}
},
addProseMirrorPlugins() {

View File

@ -7,9 +7,11 @@ export interface CodeBlockLowlightOptions extends CodeBlockOptions {
}
export const CodeBlockLowlight = CodeBlock.extend<CodeBlockLowlightOptions>({
defaultOptions: {
...CodeBlock.options,
lowlight,
addOptions() {
return {
...this.parent?.(),
lowlight,
}
},
addProseMirrorPlugins() {

View File

@ -27,9 +27,11 @@ export const tildeInputRegex = /^~~~(?<language>[a-z]*)?[\s\n]$/
export const CodeBlock = Node.create<CodeBlockOptions>({
name: 'codeBlock',
defaultOptions: {
languageClassPrefix: 'language-',
HTMLAttributes: {},
addOptions() {
return {
languageClassPrefix: 'language-',
HTMLAttributes: {},
}
},
content: 'text*',

View File

@ -34,8 +34,10 @@ export const pasteRegex = /(?:^|\s)((?:`)((?:[^`]+))(?:`))/g
export const Code = Mark.create<CodeOptions>({
name: 'code',
defaultOptions: {
HTMLAttributes: {},
addOptions() {
return {
HTMLAttributes: {},
}
},
excludes: '_',

View File

@ -31,26 +31,28 @@ const awarenessStatesToArray = (states: Map<number, Record<string, any>>) => {
export const CollaborationCursor = Extension.create<CollaborationCursorOptions>({
name: 'collaborationCursor',
defaultOptions: {
provider: null,
user: {
name: null,
color: null,
},
render: user => {
const cursor = document.createElement('span')
cursor.classList.add('collaboration-cursor__caret')
cursor.setAttribute('style', `border-color: ${user.color}`)
addOptions() {
return {
provider: null,
user: {
name: null,
color: null,
},
render: user => {
const cursor = document.createElement('span')
cursor.classList.add('collaboration-cursor__caret')
cursor.setAttribute('style', `border-color: ${user.color}`)
const label = document.createElement('div')
label.classList.add('collaboration-cursor__label')
label.setAttribute('style', `background-color: ${user.color}`)
label.insertBefore(document.createTextNode(user.name), null)
cursor.insertBefore(label, null)
const label = document.createElement('div')
label.classList.add('collaboration-cursor__label')
label.setAttribute('style', `background-color: ${user.color}`)
label.insertBefore(document.createTextNode(user.name), null)
cursor.insertBefore(label, null)
return cursor
},
onUpdate: () => null,
return cursor
},
onUpdate: () => null,
}
},
addCommands() {

View File

@ -43,10 +43,12 @@ export const Collaboration = Extension.create<CollaborationOptions>({
priority: 1000,
defaultOptions: {
document: null,
field: 'default',
fragment: null,
addOptions() {
return {
document: null,
field: 'default',
fragment: null,
}
},
onCreate() {

View File

@ -23,8 +23,10 @@ declare module '@tiptap/core' {
export const Color = Extension.create<ColorOptions>({
name: 'color',
defaultOptions: {
types: ['textStyle'],
addOptions() {
return {
types: ['textStyle'],
}
},
addGlobalAttributes() {

View File

@ -10,10 +10,12 @@ export interface DropcursorOptions {
export const Dropcursor = Extension.create<DropcursorOptions>({
name: 'dropCursor',
defaultOptions: {
color: 'currentColor',
width: 1,
class: null,
addOptions() {
return {
color: 'currentColor',
width: 1,
class: null,
}
},
addProseMirrorPlugins() {

View File

@ -8,11 +8,13 @@ export type FloatingMenuOptions = Omit<FloatingMenuPluginProps, 'editor' | 'elem
export const FloatingMenu = Extension.create<FloatingMenuOptions>({
name: 'floatingMenu',
defaultOptions: {
element: null,
tippyOptions: {},
pluginKey: 'floatingMenu',
shouldShow: null,
addOptions() {
return {
element: null,
tippyOptions: {},
pluginKey: 'floatingMenu',
shouldShow: null,
}
},
addProseMirrorPlugins() {

View File

@ -10,9 +10,11 @@ export interface FocusOptions {
export const FocusClasses = Extension.create<FocusOptions>({
name: 'focus',
defaultOptions: {
className: 'has-focus',
mode: 'all',
addOptions() {
return {
className: 'has-focus',
mode: 'all',
}
},
addProseMirrorPlugins() {

View File

@ -23,8 +23,10 @@ declare module '@tiptap/core' {
export const FontFamily = Extension.create<FontFamilyOptions>({
name: 'fontFamily',
defaultOptions: {
types: ['textStyle'],
addOptions() {
return {
types: ['textStyle'],
}
},
addGlobalAttributes() {

View File

@ -19,9 +19,11 @@ declare module '@tiptap/core' {
export const HardBreak = Node.create<HardBreakOptions>({
name: 'hardBreak',
defaultOptions: {
keepMarks: true,
HTMLAttributes: {},
addOptions() {
return {
keepMarks: true,
HTMLAttributes: {},
}
},
inline: true,

View File

@ -25,9 +25,11 @@ declare module '@tiptap/core' {
export const Heading = Node.create<HeadingOptions>({
name: 'heading',
defaultOptions: {
levels: [1, 2, 3, 4, 5, 6],
HTMLAttributes: {},
addOptions() {
return {
levels: [1, 2, 3, 4, 5, 6],
HTMLAttributes: {},
}
},
content: 'inline*',

View File

@ -35,9 +35,11 @@ export const pasteRegex = /(?:^|\s)((?:==)((?:[^~]+))(?:==))/g
export const Highlight = Mark.create<HighlightOptions>({
name: 'highlight',
defaultOptions: {
multicolor: false,
HTMLAttributes: {},
addOptions() {
return {
multicolor: false,
HTMLAttributes: {},
}
},
addAttributes() {

View File

@ -24,9 +24,11 @@ declare module '@tiptap/core' {
export const History = Extension.create<HistoryOptions>({
name: 'history',
defaultOptions: {
depth: 100,
newGroupDelay: 500,
addOptions() {
return {
depth: 100,
newGroupDelay: 500,
}
},
addCommands() {

View File

@ -23,8 +23,10 @@ declare module '@tiptap/core' {
export const HorizontalRule = Node.create<HorizontalRuleOptions>({
name: 'horizontalRule',
defaultOptions: {
HTMLAttributes: {},
addOptions() {
return {
HTMLAttributes: {},
}
},
group: 'block',

View File

@ -25,9 +25,11 @@ export const inputRegex = /(!\[(.+|:?)]\((\S+)(?:(?:\s+)["'](\S+)["'])?\))/
export const Image = Node.create<ImageOptions>({
name: 'image',
defaultOptions: {
inline: false,
HTMLAttributes: {},
addOptions() {
return {
inline: false,
HTMLAttributes: {},
}
},
inline() {

View File

@ -36,8 +36,10 @@ export const underscorePasteRegex = /(?:^|\s)((?:_)((?:[^_]+))(?:_))/g
export const Italic = Mark.create<ItalicOptions>({
name: 'italic',
defaultOptions: {
HTMLAttributes: {},
addOptions() {
return {
HTMLAttributes: {},
}
},
parseHTML() {

View File

@ -47,13 +47,15 @@ export const Link = Mark.create<LinkOptions>({
inclusive: false,
defaultOptions: {
openOnClick: true,
linkOnPaste: true,
HTMLAttributes: {
target: '_blank',
rel: 'noopener noreferrer nofollow',
},
addOptions() {
return {
openOnClick: true,
linkOnPaste: true,
HTMLAttributes: {
target: '_blank',
rel: 'noopener noreferrer nofollow',
},
}
},
addAttributes() {

View File

@ -7,8 +7,10 @@ export interface ListItemOptions {
export const ListItem = Node.create<ListItemOptions>({
name: 'listItem',
defaultOptions: {
HTMLAttributes: {},
addOptions() {
return {
HTMLAttributes: {},
}
},
content: 'paragraph block*',

View File

@ -17,47 +17,49 @@ export const MentionPluginKey = new PluginKey('mention')
export const Mention = Node.create<MentionOptions>({
name: 'mention',
defaultOptions: {
HTMLAttributes: {},
renderLabel({ options, node }) {
return `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`
},
suggestion: {
char: '@',
pluginKey: MentionPluginKey,
command: ({ editor, range, props }) => {
// increase range.to by one when the next node is of type "text"
// and starts with a space character
const nodeAfter = editor.view.state.selection.$to.nodeAfter
const overrideSpace = nodeAfter?.text?.startsWith(' ')
if (overrideSpace) {
range.to += 1
}
editor
.chain()
.focus()
.insertContentAt(range, [
{
type: 'mention',
attrs: props,
},
{
type: 'text',
text: ' ',
},
])
.run()
addOptions() {
return {
HTMLAttributes: {},
renderLabel({ options, node }) {
return `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`
},
allow: ({ editor, range }) => {
const $from = editor.state.doc.resolve(range.from)
const type = editor.schema.nodes.mention
const allow = !!$from.parent.type.contentMatch.matchType(type)
suggestion: {
char: '@',
pluginKey: MentionPluginKey,
command: ({ editor, range, props }) => {
// increase range.to by one when the next node is of type "text"
// and starts with a space character
const nodeAfter = editor.view.state.selection.$to.nodeAfter
const overrideSpace = nodeAfter?.text?.startsWith(' ')
return allow
if (overrideSpace) {
range.to += 1
}
editor
.chain()
.focus()
.insertContentAt(range, [
{
type: this.name,
attrs: props,
},
{
type: 'text',
text: ' ',
},
])
.run()
},
allow: ({ editor, range }) => {
const $from = editor.state.doc.resolve(range.from)
const type = editor.schema.nodes[this.name]
const allow = !!$from.parent.type.contentMatch.matchType(type)
return allow
},
},
},
}
},
group: 'inline',

View File

@ -20,8 +20,10 @@ export const inputRegex = /^(\d+)\.\s$/
export const OrderedList = Node.create<OrderedListOptions>({
name: 'orderedList',
defaultOptions: {
HTMLAttributes: {},
addOptions() {
return {
HTMLAttributes: {},
}
},
group: 'block list',

View File

@ -20,8 +20,10 @@ export const Paragraph = Node.create<ParagraphOptions>({
priority: 1000,
defaultOptions: {
HTMLAttributes: {},
addOptions() {
return {
HTMLAttributes: {},
}
},
group: 'block',

View File

@ -19,13 +19,15 @@ export interface PlaceholderOptions {
export const Placeholder = Extension.create<PlaceholderOptions>({
name: 'placeholder',
defaultOptions: {
emptyEditorClass: 'is-editor-empty',
emptyNodeClass: 'is-empty',
placeholder: 'Write something …',
showOnlyWhenEditable: true,
showOnlyCurrent: true,
includeChildren: false,
addOptions() {
return {
emptyEditorClass: 'is-editor-empty',
emptyNodeClass: 'is-empty',
placeholder: 'Write something …',
showOnlyWhenEditable: true,
showOnlyCurrent: true,
includeChildren: false,
}
},
addProseMirrorPlugins() {

View File

@ -34,8 +34,10 @@ export const pasteRegex = /(?:^|\s)((?:~~)((?:[^~]+))(?:~~))/g
export const Strike = Mark.create<StrikeOptions>({
name: 'strike',
defaultOptions: {
HTMLAttributes: {},
addOptions() {
return {
HTMLAttributes: {},
}
},
parseHTML() {

View File

@ -26,8 +26,10 @@ declare module '@tiptap/core' {
export const Subscript = Mark.create<SubscriptExtensionOptions>({
name: 'subscript',
defaultOptions: {
HTMLAttributes: {},
addOptions() {
return {
HTMLAttributes: {},
}
},
parseHTML() {

View File

@ -26,8 +26,10 @@ declare module '@tiptap/core' {
export const Superscript = Mark.create<SuperscriptExtensionOptions>({
name: 'superscript',
defaultOptions: {
HTMLAttributes: {},
addOptions() {
return {
HTMLAttributes: {},
}
},
parseHTML() {

View File

@ -7,8 +7,10 @@ export interface TableCellOptions {
export const TableCell = Node.create<TableCellOptions>({
name: 'tableCell',
defaultOptions: {
HTMLAttributes: {},
addOptions() {
return {
HTMLAttributes: {},
}
},
content: 'block+',

View File

@ -6,8 +6,10 @@ export interface TableHeaderOptions {
export const TableHeader = Node.create<TableHeaderOptions>({
name: 'tableHeader',
defaultOptions: {
HTMLAttributes: {},
addOptions() {
return {
HTMLAttributes: {},
}
},
content: 'block+',

View File

@ -7,8 +7,10 @@ export interface TableRowOptions {
export const TableRow = Node.create<TableRowOptions>({
name: 'tableRow',
defaultOptions: {
HTMLAttributes: {},
addOptions() {
return {
HTMLAttributes: {},
}
},
content: '(tableCell | tableHeader)*',

View File

@ -82,16 +82,18 @@ declare module '@tiptap/core' {
export const Table = Node.create<TableOptions>({
name: 'table',
defaultOptions: {
HTMLAttributes: {},
resizable: false,
handleWidth: 5,
cellMinWidth: 25,
// TODO: fix
// @ts-ignore
View: TableView,
lastColumnResizable: true,
allowTableNodeSelection: false,
// @ts-ignore
addOptions() {
return {
HTMLAttributes: {},
resizable: false,
handleWidth: 5,
cellMinWidth: 25,
// TODO: fix
View: TableView,
lastColumnResizable: true,
allowTableNodeSelection: false,
}
},
content: 'tableRow+',

View File

@ -10,9 +10,11 @@ export const inputRegex = /^\s*(\[([ |x])\])\s$/
export const TaskItem = Node.create<TaskItemOptions>({
name: 'taskItem',
defaultOptions: {
nested: false,
HTMLAttributes: {},
addOptions() {
return {
nested: false,
HTMLAttributes: {},
}
},
content() {

View File

@ -18,8 +18,10 @@ declare module '@tiptap/core' {
export const TaskList = Node.create<TaskListOptions>({
name: 'taskList',
defaultOptions: {
HTMLAttributes: {},
addOptions() {
return {
HTMLAttributes: {},
}
},
group: 'block list',

View File

@ -24,10 +24,12 @@ declare module '@tiptap/core' {
export const TextAlign = Extension.create<TextAlignOptions>({
name: 'textAlign',
defaultOptions: {
types: [],
alignments: ['left', 'center', 'right', 'justify'],
defaultAlignment: 'left',
addOptions() {
return {
types: [],
alignments: ['left', 'center', 'right', 'justify'],
defaultAlignment: 'left',
}
},
addGlobalAttributes() {

View File

@ -22,8 +22,10 @@ declare module '@tiptap/core' {
export const TextStyle = Mark.create<TextStyleOptions>({
name: 'textStyle',
defaultOptions: {
HTMLAttributes: {},
addOptions() {
return {
HTMLAttributes: {},
}
},
parseHTML() {

View File

@ -26,8 +26,10 @@ declare module '@tiptap/core' {
export const Underline = Mark.create<UnderlineOptions>({
name: 'underline',
defaultOptions: {
HTMLAttributes: {},
addOptions() {
return {
HTMLAttributes: {},
}
},
parseHTML() {

View File

@ -3,7 +3,7 @@
import { Extension } from '@tiptap/core/src/Extension'
describe('extension options', () => {
it('should set options', () => {
it('should set options (deprecated)', () => {
const extension = Extension.create({
defaultOptions: {
foo: 1,
@ -17,7 +17,23 @@ describe('extension options', () => {
})
})
it('should pass through', () => {
it('should set options', () => {
const extension = Extension.create({
addOptions() {
return {
foo: 1,
bar: 1,
}
},
})
expect(extension.options).to.deep.eq({
foo: 1,
bar: 1,
})
})
it('should pass through (deprecated)', () => {
const extension = Extension
.create({
defaultOptions: {
@ -34,7 +50,26 @@ describe('extension options', () => {
})
})
it('should be configurable', () => {
it('should pass through', () => {
const extension = Extension
.create({
addOptions() {
return {
foo: 1,
bar: 1,
}
},
})
.extend()
.configure()
expect(extension.options).to.deep.eq({
foo: 1,
bar: 1,
})
})
it('should be configurable (deprecated)', () => {
const extension = Extension
.create({
defaultOptions: {
@ -52,7 +87,27 @@ describe('extension options', () => {
})
})
it('should be extendable', () => {
it('should be configurable', () => {
const extension = Extension
.create({
addOptions() {
return {
foo: 1,
bar: 1,
}
},
})
.configure({
bar: 2,
})
expect(extension.options).to.deep.eq({
foo: 1,
bar: 2,
})
})
it('should be extendable (deprecated)', () => {
const extension = Extension.create({
defaultOptions: {
foo: 1,
@ -74,7 +129,33 @@ describe('extension options', () => {
})
})
it('should be overwritable', () => {
it('should be extendable', () => {
const extension = Extension.create({
addOptions() {
return {
foo: 1,
bar: 1,
}
},
})
const newExtension = extension.extend({
addOptions() {
return {
...this.parent?.(),
baz: 1,
}
},
})
expect(newExtension.options).to.deep.eq({
foo: 1,
bar: 1,
baz: 1,
})
})
it('should be overwritable (deprecated)', () => {
const extension = Extension
.create({
defaultOptions: {
@ -93,7 +174,30 @@ describe('extension options', () => {
})
})
it('should configure nested objects', () => {
it('should be overwritable', () => {
const extension = Extension
.create({
addOptions() {
return {
foo: 1,
bar: 1,
}
},
})
.extend({
addOptions() {
return {
baz: 1,
}
},
})
expect(extension.options).to.deep.eq({
baz: 1,
})
})
it('should configure nested objects (deprecated)', () => {
const extension = Extension
.create<{
foo: number[],
@ -122,7 +226,38 @@ describe('extension options', () => {
})
})
it('should create its own instance on configure', () => {
it('should configure nested objects', () => {
const extension = Extension
.create<{
foo: number[],
HTMLAttributes: Record<string, any>,
}>({
addOptions() {
return {
foo: [1, 2, 3],
HTMLAttributes: {
class: 'foo',
},
}
},
})
.configure({
foo: [1],
HTMLAttributes: {
id: 'bar',
},
})
expect(extension.options).to.deep.eq({
foo: [1],
HTMLAttributes: {
class: 'foo',
id: 'bar',
},
})
})
it('should create its own instance on configure (deprecated)', () => {
const extension = Extension
.create({
defaultOptions: {
@ -150,4 +285,35 @@ describe('extension options', () => {
bar: 2,
})
})
it('should create its own instance on configure', () => {
const extension = Extension
.create({
addOptions() {
return {
foo: 1,
bar: 2,
}
},
})
const extension1 = extension.configure({
foo: 2,
bar: 4,
})
const extension2 = extension.configure({
foo: 3,
})
expect(extension1.options).to.deep.eq({
foo: 2,
bar: 4,
})
expect(extension2.options).to.deep.eq({
foo: 3,
bar: 2,
})
})
})