Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@tiptap/core

Package Overview
Dependencies
Maintainers
5
Versions
331
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tiptap/core - npm Package Compare versions

Comparing version 2.5.0-beta.0 to 2.5.0-beta.1

10

dist/packages/core/src/commands/insertContentAt.d.ts

@@ -31,4 +31,14 @@ import { ParseOptions } from '@tiptap/pm/model';

updateSelection?: boolean;
/**
* Whether to apply input rules after inserting the content.
*/
applyInputRules?: boolean;
/**
* Whether to apply paste rules after inserting the content.
*/
applyPasteRules?: boolean;
/**
* Whether to throw an error if the content is invalid.
*/
errorOnInvalidContent?: boolean;
}) => ReturnType;

@@ -35,0 +45,0 @@ };

11

dist/packages/core/src/commands/setContent.d.ts

@@ -27,3 +27,12 @@ import { ParseOptions } from '@tiptap/pm/model';

*/
parseOptions?: ParseOptions) => ReturnType;
parseOptions?: ParseOptions,
/**
* Options for `setContent`.
*/
options?: {
/**
* Whether to throw an error if the content is invalid.
*/
errorOnInvalidContent?: boolean;
}) => ReturnType;
};

@@ -30,0 +39,0 @@ }

6

dist/packages/core/src/Editor.d.ts

@@ -9,4 +9,6 @@ import { MarkType, NodeType, Schema } from '@tiptap/pm/model';

export * as extensions from './extensions/index.js';
export interface HTMLElement {
editor?: Editor;
declare global {
interface HTMLElement {
editor?: Editor;
}
}

@@ -13,0 +15,0 @@ export declare class Editor extends EventEmitter<EditorEvents> {

@@ -10,2 +10,4 @@ import { Node as ProseMirrorNode, ParseOptions, Schema } from '@tiptap/pm/model';

*/
export declare function createDocument(content: Content, schema: Schema, parseOptions?: ParseOptions): ProseMirrorNode;
export declare function createDocument(content: Content, schema: Schema, parseOptions?: ParseOptions, options?: {
errorOnInvalidContent?: boolean;
}): ProseMirrorNode;

@@ -6,2 +6,3 @@ import { Fragment, Node as ProseMirrorNode, ParseOptions, Schema } from '@tiptap/pm/model';

parseOptions?: ParseOptions;
errorOnInvalidContent?: boolean;
};

@@ -8,0 +9,0 @@ /**

@@ -26,2 +26,11 @@ import { Mark as ProseMirrorMark, Node as ProseMirrorNode, NodeType, ParseOptions } from '@tiptap/pm/model';

};
contentError: {
editor: Editor;
error: Error;
/**
* If called, will re-initialize the editor with the collaboration extension removed.
* This will prevent syncing back deletions of content not present in the current schema.
*/
disableCollaboration: () => void;
};
update: {

@@ -70,4 +79,16 @@ editor: Editor;

enableCoreExtensions: boolean;
/**
* If `true`, the editor will check the content for errors on initialization.
* Emitting the `contentError` event if the content is invalid.
* Which can be used to show a warning or error message to the user.
* @default false
*/
enableContentCheck: boolean;
onBeforeCreate: (props: EditorEvents['beforeCreate']) => void;
onCreate: (props: EditorEvents['create']) => void;
/**
* Called when the editor encounters an error while parsing the content.
* Only enabled if `enableContentCheck` is `true`.
*/
onContentError: (props: EditorEvents['contentError']) => void;
onUpdate: (props: EditorEvents['update']) => void;

@@ -74,0 +95,0 @@ onSelectionUpdate: (props: EditorEvents['selectionUpdate']) => void;

{
"name": "@tiptap/core",
"description": "headless rich text editor",
"version": "2.5.0-beta.0",
"version": "2.5.0-beta.1",
"homepage": "https://tiptap.dev",

@@ -35,3 +35,3 @@ "keywords": [

"devDependencies": {
"@tiptap/pm": "^2.5.0-beta.0"
"@tiptap/pm": "^2.5.0-beta.1"
},

@@ -38,0 +38,0 @@ "peerDependencies": {

@@ -38,4 +38,17 @@ import { Fragment, Node as ProseMirrorNode, ParseOptions } from '@tiptap/pm/model'

updateSelection?: boolean
/**
* Whether to apply input rules after inserting the content.
*/
applyInputRules?: boolean
/**
* Whether to apply paste rules after inserting the content.
*/
applyPasteRules?: boolean
/**
* Whether to throw an error if the content is invalid.
*/
errorOnInvalidContent?: boolean
},

@@ -61,9 +74,16 @@ ) => ReturnType

const content = createNodeFromContent(value, editor.schema, {
parseOptions: {
preserveWhitespace: 'full',
...options.parseOptions,
},
})
let content: Fragment | ProseMirrorNode
try {
content = createNodeFromContent(value, editor.schema, {
parseOptions: {
preserveWhitespace: 'full',
...options.parseOptions,
},
errorOnInvalidContent: options.errorOnInvalidContent ?? editor.options.enableContentCheck,
})
} catch (e) {
return false
}
// don’t dispatch an empty fragment because this can lead to strange errors

@@ -70,0 +90,0 @@ if (content.toString() === '<>') {

@@ -1,2 +0,2 @@

import { ParseOptions } from '@tiptap/pm/model'
import { Fragment, Node as ProseMirrorNode, ParseOptions } from '@tiptap/pm/model'

@@ -33,2 +33,11 @@ import { createDocument } from '../helpers/createDocument.js'

parseOptions?: ParseOptions,
/**
* Options for `setContent`.
*/
options?: {
/**
* Whether to throw an error if the content is invalid.
*/
errorOnInvalidContent?: boolean
},
) => ReturnType

@@ -39,6 +48,15 @@ }

export const setContent: RawCommands['setContent'] = (content, emitUpdate = false, parseOptions = {}) => ({ tr, editor, dispatch }) => {
export const setContent: RawCommands['setContent'] = (content, emitUpdate = false, parseOptions = {}, options = {}) => ({ tr, editor, dispatch }) => {
const { doc } = tr
const document = createDocument(content, editor.schema, parseOptions)
let document: Fragment | ProseMirrorNode
try {
document = createDocument(content, editor.schema, parseOptions, {
errorOnInvalidContent: options.errorOnInvalidContent ?? editor.options.enableContentCheck,
})
} catch (e) {
return false
}
if (dispatch) {

@@ -45,0 +63,0 @@ tr.replaceWith(0, doc.content.size, document).setMeta('preventUpdate', !emitUpdate)

import {
MarkType, NodeType, Schema,
MarkType,
Node as ProseMirrorNode,
NodeType,
Schema,
} from '@tiptap/pm/model'

@@ -39,4 +42,6 @@ import {

export interface HTMLElement {
editor?: Editor
declare global {
interface HTMLElement {
editor?: Editor;
}
}

@@ -73,2 +78,3 @@

enableCoreExtensions: true,
enableContentCheck: false,
onBeforeCreate: () => null,

@@ -82,2 +88,3 @@ onCreate: () => null,

onDestroy: () => null,
onContentError: ({ error }) => { throw error },
}

@@ -93,2 +100,3 @@

this.emit('beforeCreate', { editor: this })
this.on('contentError', this.options.onContentError)
this.createView()

@@ -283,3 +291,36 @@ this.injectCSS()

private createView(): void {
const doc = createDocument(this.options.content, this.schema, this.options.parseOptions)
let doc: ProseMirrorNode
try {
doc = createDocument(
this.options.content,
this.schema,
this.options.parseOptions,
{ errorOnInvalidContent: this.options.enableContentCheck },
)
} catch (e) {
if (!(e instanceof Error) || !['[tiptap error]: Invalid JSON content', '[tiptap error]: Invalid HTML content'].includes(e.message)) {
// Not the content error we were expecting
throw e
}
this.emit('contentError', {
editor: this,
error: e as Error,
disableCollaboration: () => {
// To avoid syncing back invalid content, reinitialize the extensions without the collaboration extension
this.options.extensions = this.options.extensions.filter(extension => extension.name !== 'collaboration')
// Restart the initialization process by recreating the extension manager with the new set of extensions
this.createExtensionManager()
},
})
// Content is invalid, but attempt to create it anyway, stripping out the invalid parts
doc = createDocument(
this.options.content,
this.schema,
this.options.parseOptions,
{ errorOnInvalidContent: false },
)
}
const selection = resolveFocusPosition(doc, this.options.autofocus)

@@ -286,0 +327,0 @@

@@ -17,4 +17,9 @@ import { Node as ProseMirrorNode, ParseOptions, Schema } from '@tiptap/pm/model'

parseOptions: ParseOptions = {},
options: { errorOnInvalidContent?: boolean } = {},
): ProseMirrorNode {
return createNodeFromContent(content, schema, { slice: false, parseOptions }) as ProseMirrorNode
return createNodeFromContent(content, schema, {
slice: false,
parseOptions,
errorOnInvalidContent: options.errorOnInvalidContent,
}) as ProseMirrorNode
}

@@ -15,2 +15,3 @@ import {

parseOptions?: ParseOptions
errorOnInvalidContent?: boolean
}

@@ -50,2 +51,6 @@

} catch (error) {
if (options.errorOnInvalidContent) {
throw new Error('[tiptap error]: Invalid JSON content', { cause: error as Error })
}
console.warn('[tiptap warn]: Invalid content.', 'Passed value:', content, 'Error:', error)

@@ -58,7 +63,42 @@

if (isTextContent) {
const parser = DOMParser.fromSchema(schema)
let schemaToUse = schema
let hasInvalidContent = false
return options.slice
// Only ever check for invalid content if we're supposed to throw an error
if (options.errorOnInvalidContent) {
schemaToUse = new Schema({
topNode: schema.spec.topNode,
marks: schema.spec.marks,
// Prosemirror's schemas are executed such that: the last to execute, matches last
// This means that we can add a catch-all node at the end of the schema to catch any content that we don't know how to handle
nodes: schema.spec.nodes.append({
__tiptap__private__unknown__catch__all__node: {
content: 'inline*',
group: 'block',
parseDOM: [
{
tag: '*',
getAttrs: () => {
// If this is ever called, we know that the content has something that we don't know how to handle in the schema
hasInvalidContent = true
return null
},
},
],
},
}),
})
}
const parser = DOMParser.fromSchema(schemaToUse)
const response = options.slice
? parser.parseSlice(elementFromString(content), options.parseOptions).content
: parser.parse(elementFromString(content), options.parseOptions)
if (options.errorOnInvalidContent && hasInvalidContent) {
throw new Error('[tiptap error]: Invalid HTML content')
}
return response
}

@@ -65,0 +105,0 @@

@@ -42,2 +42,11 @@ import {

create: { editor: Editor }
contentError: {
editor: Editor,
error: Error,
/**
* If called, will re-initialize the editor with the collaboration extension removed.
* This will prevent syncing back deletions of content not present in the current schema.
*/
disableCollaboration: () => void
}
update: { editor: Editor; transaction: Transaction }

@@ -71,4 +80,16 @@ selectionUpdate: { editor: Editor; transaction: Transaction }

enableCoreExtensions: boolean
/**
* If `true`, the editor will check the content for errors on initialization.
* Emitting the `contentError` event if the content is invalid.
* Which can be used to show a warning or error message to the user.
* @default false
*/
enableContentCheck: boolean
onBeforeCreate: (props: EditorEvents['beforeCreate']) => void
onCreate: (props: EditorEvents['create']) => void
/**
* Called when the editor encounters an error while parsing the content.
* Only enabled if `enableContentCheck` is `true`.
*/
onContentError: (props: EditorEvents['contentError']) => void
onUpdate: (props: EditorEvents['update']) => void

@@ -75,0 +96,0 @@ onSelectionUpdate: (props: EditorEvents['selectionUpdate']) => void

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc