UNPKG

@blocknote/core

Version:

A "Notion-style" block-based extensible text editor built on top of Prosemirror and Tiptap.

1 lines 25.1 kB
{"version":3,"file":"BlockNoteSchema-CzZbr4Ed.cjs","sources":["../src/util/topo-sort.ts","../src/schema/schema.ts","../src/blocks/PageBreak/block.ts","../src/blocks/File/helpers/uploadToTmpFilesDotOrg_DEV_ONLY.ts","../src/blocks/PageBreak/getPageBreakSlashMenuItems.ts","../src/blocks/BlockNoteSchema.ts"],"sourcesContent":["/**\n * Instead of depending on the NPM package, we vendor this file from https://github.com/n1ru4l/toposort/blob/main/src/toposort.ts (MIT)\n *\n * There was a recent publish, despite not having been updated in 2 years, which is suspicious.\n *\n * This file is also simple enough that we can maintain it ourselves.\n */\n\nexport type DirectedAcyclicGraph = Map<string, Iterable<string>>;\nexport type DependencyGraph = DirectedAcyclicGraph;\n\nexport type TaskList = Array<Set<string>>;\n\n// Add more specific types for better type safety\nexport type NodeId = string;\nexport type DependencyMap = Map<NodeId, Set<NodeId>>;\n\nexport function toposort(dag: DirectedAcyclicGraph): TaskList {\n const inDegrees = countInDegrees(dag);\n\n let { roots, nonRoots } = getRootsAndNonRoots(inDegrees);\n\n const sorted: TaskList = [];\n\n while (roots.size) {\n sorted.push(roots);\n\n const newRoots = new Set<NodeId>();\n for (const root of roots) {\n const dependents = dag.get(root);\n if (!dependents) {\n // Handle case where node has no dependents\n continue;\n }\n\n for (const dependent of dependents) {\n const currentDegree = inDegrees.get(dependent);\n if (currentDegree === undefined) {\n // Handle case where dependent node is not in inDegrees\n continue;\n }\n\n const newDegree = currentDegree - 1;\n inDegrees.set(dependent, newDegree);\n\n if (newDegree === 0) {\n newRoots.add(dependent);\n }\n }\n }\n\n roots = newRoots;\n }\n nonRoots = getRootsAndNonRoots(inDegrees).nonRoots;\n\n if (nonRoots.size) {\n throw new Error(\n `Cycle(s) detected; toposort only works on acyclic graphs. Cyclic nodes: ${Array.from(nonRoots).join(\", \")}`,\n );\n }\n\n return sorted;\n}\n\nexport function toposortReverse(deps: DependencyGraph): TaskList {\n const dag = reverse(deps);\n return toposort(dag);\n}\n\ntype InDegrees = Map<NodeId, number>;\n\nfunction countInDegrees(dag: DirectedAcyclicGraph): InDegrees {\n const counts: InDegrees = new Map();\n\n for (const [vx, dependents] of dag.entries()) {\n // Initialize count for current node if not present\n if (!counts.has(vx)) {\n counts.set(vx, 0);\n }\n\n for (const dependent of dependents) {\n const currentCount = counts.get(dependent) ?? 0;\n counts.set(dependent, currentCount + 1);\n }\n }\n\n return counts;\n}\n\nfunction getRootsAndNonRoots(counts: InDegrees) {\n const roots = new Set<NodeId>();\n const nonRoots = new Set<NodeId>();\n\n for (const [id, deg] of counts.entries()) {\n if (deg === 0) {\n roots.add(id);\n } else {\n nonRoots.add(id);\n }\n }\n\n return { roots, nonRoots };\n}\n\nfunction reverse(deps: DirectedAcyclicGraph): DependencyGraph {\n const reversedDeps: DependencyMap = new Map();\n\n for (const [name, dependsOn] of deps.entries()) {\n // Ensure the source node exists in the reversed map\n if (!reversedDeps.has(name)) {\n reversedDeps.set(name, new Set());\n }\n\n for (const dependsOnName of dependsOn) {\n if (!reversedDeps.has(dependsOnName)) {\n reversedDeps.set(dependsOnName, new Set());\n }\n reversedDeps.get(dependsOnName)!.add(name);\n }\n }\n\n return reversedDeps;\n}\n\nexport function createDependencyGraph(): DependencyMap {\n return new Map();\n}\n\nexport function addDependency(\n graph: DependencyMap,\n from: NodeId,\n to: NodeId,\n): DependencyMap {\n if (!graph.has(from)) {\n graph.set(from, new Set());\n }\n graph.get(from)!.add(to);\n return graph;\n}\n\nexport function removeDependency(\n graph: DependencyMap,\n from: NodeId,\n to: NodeId,\n): boolean {\n const dependents = graph.get(from);\n if (!dependents) {\n return false;\n }\n return dependents.delete(to);\n}\n\nexport function hasDependency(\n graph: DependencyMap,\n from: NodeId,\n to: NodeId,\n): boolean {\n const dependents = graph.get(from);\n return dependents ? dependents.has(to) : false;\n}\n\n/**\n * Sorts a list of items by their dependencies\n * @returns A function which can retrieve the priority of an item\n */\nexport function sortByDependencies(\n items: { key: string; runsBefore?: ReadonlyArray<string> }[],\n) {\n const dag = createDependencyGraph();\n\n for (const item of items) {\n if (Array.isArray(item.runsBefore) && item.runsBefore.length > 0) {\n item.runsBefore.forEach((runBefore) => {\n addDependency(dag, item.key, runBefore);\n });\n } else {\n addDependency(dag, \"default\", item.key);\n }\n }\n const sortedSpecs = toposortReverse(dag);\n const defaultIndex = sortedSpecs.findIndex((set) => set.has(\"default\"));\n\n /**\n * The priority of an item is described relative to the \"default\" (an arbitrary string which can be used as the reference)\n *\n * Since items are topologically sorted, we can see what their relative position is to the \"default\"\n * Each layer away from the default is 10 priority points (arbitrarily chosen)\n * The default is fixed at 101 (1 point higher than any tiptap extension, giving priority to custom blocks than any defaults)\n *\n * This is a bit of a hack, but it's a simple way to ensure that custom items are always rendered with higher priority than default items\n * and that custom items are rendered in the order they are defined in the list\n */\n\n /**\n * Retrieves the priority of an item based on its position in the topologically sorted list\n * @param key - The key of the item to get the priority of\n * @returns The priority of the item\n */\n return (key: string) => {\n const index = sortedSpecs.findIndex((set) => set.has(key));\n // the default index should map to 101\n // one before the default index is 91\n // one after is 111\n return 91 + (index + defaultIndex) * 10;\n };\n}\n","import { BlockNoteEditor } from \"../editor/BlockNoteEditor.js\";\nimport { sortByDependencies } from \"../util/topo-sort.js\";\nimport {\n BlockNoDefaults,\n BlockSchema,\n BlockSpecs,\n InlineContentConfig,\n InlineContentSchema,\n InlineContentSpec,\n InlineContentSpecs,\n LooseBlockSpec,\n PartialBlockNoDefaults,\n StyleSchema,\n StyleSpecs,\n addNodeAndExtensionsToSpec,\n getInlineContentSchemaFromSpecs,\n getStyleSchemaFromSpecs,\n} from \"./index.js\";\n\nfunction removeUndefined<T extends Record<string, any> | undefined>(obj: T): T {\n if (!obj) {\n return obj;\n }\n return Object.fromEntries(\n Object.entries(obj).filter(([, value]) => value !== undefined),\n ) as T;\n}\n\nexport class CustomBlockNoteSchema<\n BSchema extends BlockSchema,\n ISchema extends InlineContentSchema,\n SSchema extends StyleSchema,\n> {\n // Helper so that you can use typeof schema.BlockNoteEditor\n public readonly BlockNoteEditor: BlockNoteEditor<BSchema, ISchema, SSchema> =\n \"only for types\" as any;\n\n public readonly Block: BlockNoDefaults<BSchema, ISchema, SSchema> =\n \"only for types\" as any;\n\n public readonly PartialBlock: PartialBlockNoDefaults<\n BSchema,\n ISchema,\n SSchema\n > = \"only for types\" as any;\n\n public inlineContentSpecs: InlineContentSpecs;\n public styleSpecs: StyleSpecs;\n public blockSpecs: {\n [K in keyof BSchema]: K extends string\n ? LooseBlockSpec<K, BSchema[K][\"propSchema\"], BSchema[K][\"content\"]>\n : never;\n };\n\n public blockSchema: BSchema;\n public inlineContentSchema: ISchema;\n public styleSchema: SSchema;\n\n constructor(\n private opts: {\n blockSpecs: BlockSpecs;\n inlineContentSpecs: InlineContentSpecs;\n styleSpecs: StyleSpecs;\n },\n ) {\n const {\n blockSpecs,\n inlineContentSpecs,\n styleSpecs,\n blockSchema,\n inlineContentSchema,\n styleSchema,\n } = this.init();\n this.blockSpecs = blockSpecs;\n this.styleSpecs = styleSpecs;\n this.styleSchema = styleSchema;\n this.inlineContentSpecs = inlineContentSpecs;\n this.blockSchema = blockSchema;\n this.inlineContentSchema = inlineContentSchema;\n }\n\n private init() {\n const getPriority = sortByDependencies(\n Object.entries({\n ...this.opts.blockSpecs,\n ...this.opts.inlineContentSpecs,\n ...this.opts.styleSpecs,\n }).map(([key, val]) => ({\n key: key,\n runsBefore: val.implementation?.runsBefore ?? [],\n })),\n );\n\n const blockSpecs = Object.fromEntries(\n Object.entries(this.opts.blockSpecs).map(([key, blockSpec]) => {\n return [\n key,\n addNodeAndExtensionsToSpec(\n blockSpec.config,\n blockSpec.implementation,\n blockSpec.extensions,\n getPriority(key),\n ),\n ];\n }),\n ) as {\n [K in keyof BSchema]: K extends string\n ? LooseBlockSpec<K, BSchema[K][\"propSchema\"], BSchema[K][\"content\"]>\n : never;\n };\n\n const inlineContentSpecs = Object.fromEntries(\n Object.entries(this.opts.inlineContentSpecs).map(\n ([key, inlineContentSpec]) => {\n // Case for text and links.\n if (typeof inlineContentSpec.config !== \"object\") {\n return [key, inlineContentSpec];\n }\n\n return [\n key,\n {\n ...inlineContentSpec,\n implementation: {\n ...inlineContentSpec.implementation,\n node: inlineContentSpec.implementation?.node.extend({\n priority: getPriority(key),\n }),\n },\n },\n ];\n },\n ),\n ) as InlineContentSpecs;\n\n const styleSpecs = Object.fromEntries(\n Object.entries(this.opts.styleSpecs).map(([key, styleSpec]) => [\n key,\n {\n ...styleSpec,\n implementation: {\n ...styleSpec.implementation,\n mark: styleSpec.implementation?.mark.extend({\n priority: getPriority(key),\n }),\n },\n },\n ]),\n ) as StyleSpecs;\n\n return {\n blockSpecs,\n blockSchema: Object.fromEntries(\n Object.entries(blockSpecs).map(([key, blockDef]) => {\n return [key, blockDef.config];\n }),\n ) as any,\n inlineContentSpecs: removeUndefined(inlineContentSpecs),\n styleSpecs: removeUndefined(styleSpecs),\n inlineContentSchema: getInlineContentSchemaFromSpecs(\n inlineContentSpecs,\n ) as any,\n styleSchema: getStyleSchemaFromSpecs(styleSpecs) as any,\n };\n }\n\n /**\n * Adds additional block specs to the current schema in a builder pattern.\n * This method allows extending the schema after it has been created.\n *\n * @param additionalBlockSpecs - Additional block specs to add to the schema\n * @returns The current schema instance for chaining\n */\n public extend<\n AdditionalBlockSpecs extends BlockSpecs = Record<string, never>,\n AdditionalInlineContentSpecs extends Record<\n string,\n InlineContentSpec<InlineContentConfig>\n > = Record<string, never>,\n AdditionalStyleSpecs extends StyleSpecs = Record<string, never>,\n >(opts: {\n blockSpecs?: AdditionalBlockSpecs;\n inlineContentSpecs?: AdditionalInlineContentSpecs;\n styleSpecs?: AdditionalStyleSpecs;\n }): CustomBlockNoteSchema<\n AdditionalBlockSpecs extends undefined | Record<string, never>\n ? BSchema\n : BSchema & {\n [K in keyof AdditionalBlockSpecs]: K extends string\n ? AdditionalBlockSpecs[K][\"config\"]\n : never;\n },\n AdditionalInlineContentSpecs extends undefined | Record<string, never>\n ? ISchema\n : ISchema & {\n [K in keyof AdditionalInlineContentSpecs]: AdditionalInlineContentSpecs[K][\"config\"];\n },\n AdditionalStyleSpecs extends undefined | Record<string, never>\n ? SSchema\n : SSchema & {\n [K in keyof AdditionalStyleSpecs]: AdditionalStyleSpecs[K][\"config\"];\n }\n > {\n // Merge the new specs with existing ones\n Object.assign(this.opts.blockSpecs, opts.blockSpecs);\n Object.assign(this.opts.inlineContentSpecs, opts.inlineContentSpecs);\n Object.assign(this.opts.styleSpecs, opts.styleSpecs);\n\n // Reinitialize the block specs with the merged specs\n const {\n blockSpecs,\n inlineContentSpecs,\n styleSpecs,\n blockSchema,\n inlineContentSchema,\n styleSchema,\n } = this.init();\n this.blockSpecs = blockSpecs;\n this.styleSpecs = styleSpecs;\n this.styleSchema = styleSchema;\n this.inlineContentSpecs = inlineContentSpecs;\n this.blockSchema = blockSchema;\n this.inlineContentSchema = inlineContentSchema;\n\n return this as any;\n }\n}\n","import {\n BlockSchema,\n createBlockConfig,\n createBlockSpec,\n InlineContentSchema,\n StyleSchema,\n} from \"../../schema/index.js\";\nimport { BlockNoteSchema } from \"../BlockNoteSchema.js\";\n\nexport type PageBreakBlockConfig = ReturnType<\n typeof createPageBreakBlockConfig\n>;\n\nexport const createPageBreakBlockConfig = createBlockConfig(\n () =>\n ({\n type: \"pageBreak\" as const,\n propSchema: {},\n content: \"none\",\n }) as const,\n);\n\nexport const createPageBreakBlockSpec = createBlockSpec(\n createPageBreakBlockConfig,\n {\n parse(element) {\n if (\n element.tagName === \"DIV\" &&\n element.hasAttribute(\"data-page-break\")\n ) {\n return {};\n }\n\n return undefined;\n },\n render() {\n const pageBreak = document.createElement(\"div\");\n\n pageBreak.setAttribute(\"data-page-break\", \"\");\n\n return {\n dom: pageBreak,\n };\n },\n toExternalHTML() {\n const pageBreak = document.createElement(\"div\");\n\n pageBreak.setAttribute(\"data-page-break\", \"\");\n\n return {\n dom: pageBreak,\n };\n },\n },\n);\n\n/**\n * Adds page break support to the given schema.\n */\nexport const withPageBreak = <\n B extends BlockSchema,\n I extends InlineContentSchema,\n S extends StyleSchema,\n>(\n schema: BlockNoteSchema<B, I, S>,\n) => {\n return schema.extend({\n blockSpecs: {\n pageBreak: createPageBreakBlockSpec(),\n },\n });\n};\n","/**\n * Uploads a file to tmpfiles.org and returns the URL to the uploaded file.\n *\n * @warning This function should only be used for development purposes, replace with your own backend!\n */\nexport const uploadToTmpFilesDotOrg_DEV_ONLY = async (\n file: File,\n): Promise<string> => {\n const body = new FormData();\n body.append(\"file\", file);\n\n const ret = await fetch(\"https://tmpfiles.org/api/v1/upload\", {\n method: \"POST\",\n body: body,\n });\n return (await ret.json()).data.url.replace(\n \"tmpfiles.org/\",\n \"tmpfiles.org/dl/\",\n );\n};\n","import { BlockNoteEditor } from \"../../editor/BlockNoteEditor.js\";\nimport { DefaultSuggestionItem } from \"../../extensions/SuggestionMenu/DefaultSuggestionItem.js\";\nimport { insertOrUpdateBlockForSlashMenu } from \"../../extensions/SuggestionMenu/getDefaultSlashMenuItems.js\";\nimport {\n BlockSchema,\n InlineContentSchema,\n StyleSchema,\n} from \"../../schema/index.js\";\nimport { createPageBreakBlockConfig } from \"./block.js\";\n\nexport function checkPageBreakBlocksInSchema<\n I extends InlineContentSchema,\n S extends StyleSchema,\n>(\n editor: BlockNoteEditor<any, I, S>,\n): editor is BlockNoteEditor<\n {\n pageBreak: ReturnType<typeof createPageBreakBlockConfig>;\n },\n I,\n S\n> {\n return \"pageBreak\" in editor.schema.blockSchema;\n}\n\nexport function getPageBreakSlashMenuItems<\n BSchema extends BlockSchema,\n I extends InlineContentSchema,\n S extends StyleSchema,\n>(editor: BlockNoteEditor<BSchema, I, S>) {\n const items: (Omit<DefaultSuggestionItem, \"key\"> & { key: \"page_break\" })[] =\n [];\n\n if (checkPageBreakBlocksInSchema(editor)) {\n items.push({\n ...editor.dictionary.slash_menu.page_break,\n onItemClick: () => {\n insertOrUpdateBlockForSlashMenu(editor, {\n type: \"pageBreak\",\n });\n },\n key: \"page_break\",\n });\n }\n\n return items;\n}\n","import {\n BlockSchema,\n BlockSchemaFromSpecs,\n BlockSpecs,\n CustomBlockNoteSchema,\n InlineContentSchema,\n InlineContentSchemaFromSpecs,\n InlineContentSpecs,\n StyleSchema,\n StyleSchemaFromSpecs,\n StyleSpecs,\n} from \"../schema/index.js\";\nimport {\n defaultBlockSpecs,\n defaultInlineContentSpecs,\n defaultStyleSpecs,\n} from \"./defaultBlocks.js\";\n\nexport class BlockNoteSchema<\n BSchema extends BlockSchema,\n ISchema extends InlineContentSchema,\n SSchema extends StyleSchema,\n> extends CustomBlockNoteSchema<BSchema, ISchema, SSchema> {\n public static create<\n BSpecs extends BlockSpecs | undefined = undefined,\n ISpecs extends InlineContentSpecs | undefined = undefined,\n SSpecs extends StyleSpecs | undefined = undefined,\n >(options?: {\n /**\n * A list of custom block types that should be available in the editor.\n */\n blockSpecs?: BSpecs;\n /**\n * A list of custom InlineContent types that should be available in the editor.\n */\n inlineContentSpecs?: ISpecs;\n /**\n * A list of custom Styles that should be available in the editor.\n */\n styleSpecs?: SSpecs;\n }): BlockNoteSchema<\n BSpecs extends undefined\n ? BlockSchemaFromSpecs<typeof defaultBlockSpecs>\n : BlockSchemaFromSpecs<NonNullable<BSpecs>>,\n ISpecs extends undefined\n ? InlineContentSchemaFromSpecs<typeof defaultInlineContentSpecs>\n : InlineContentSchemaFromSpecs<NonNullable<ISpecs>>,\n SSpecs extends undefined\n ? StyleSchemaFromSpecs<typeof defaultStyleSpecs>\n : StyleSchemaFromSpecs<NonNullable<SSpecs>>\n > {\n return new BlockNoteSchema<any, any, any>({\n blockSpecs: options?.blockSpecs ?? defaultBlockSpecs,\n inlineContentSpecs:\n options?.inlineContentSpecs ?? defaultInlineContentSpecs,\n styleSpecs: options?.styleSpecs ?? defaultStyleSpecs,\n });\n }\n}\n"],"names":["toposort","dag","inDegrees","countInDegrees","roots","nonRoots","getRootsAndNonRoots","sorted","newRoots","root","dependents","dependent","currentDegree","newDegree","toposortReverse","deps","reverse","counts","vx","currentCount","id","deg","reversedDeps","name","dependsOn","dependsOnName","createDependencyGraph","addDependency","graph","from","to","sortByDependencies","items","item","runBefore","sortedSpecs","defaultIndex","set","key","removeUndefined","obj","value","CustomBlockNoteSchema","opts","__publicField","blockSpecs","inlineContentSpecs","styleSpecs","blockSchema","inlineContentSchema","styleSchema","getPriority","val","_a","blockSpec","addNodeAndExtensionsToSpec","inlineContentSpec","styleSpec","blockDef","getInlineContentSchemaFromSpecs","getStyleSchemaFromSpecs","createPageBreakBlockConfig","createBlockConfig","createPageBreakBlockSpec","createBlockSpec","element","pageBreak","withPageBreak","schema","uploadToTmpFilesDotOrg_DEV_ONLY","file","body","checkPageBreakBlocksInSchema","editor","getPageBreakSlashMenuItems","insertOrUpdateBlockForSlashMenu","BlockNoteSchema","options","defaultBlockSpecs","defaultInlineContentSpecs","defaultStyleSpecs"],"mappings":"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"}