mirror of
https://github.com/makeplane/plane.git
synced 2026-07-14 14:31:37 +02:00
Sync: Community Changes #3324
This commit is contained in:
@@ -1,36 +1,38 @@
|
||||
import { HocuspocusProvider } from "@hocuspocus/provider";
|
||||
import { AnyExtension } from "@tiptap/core";
|
||||
import { AnyExtension, Extensions } from "@tiptap/core";
|
||||
import { SlashCommands } from "@/extensions";
|
||||
// plane editor types
|
||||
import { TIssueEmbedConfig } from "@/plane-editor/types";
|
||||
import { TEmbedConfig } from "@/plane-editor/types";
|
||||
// types
|
||||
import { TExtensions, TUserDetails } from "@/types";
|
||||
import { TExtensions, TFileHandler, TUserDetails } from "@/types";
|
||||
|
||||
type Props = {
|
||||
disabledExtensions?: TExtensions[];
|
||||
issueEmbedConfig: TIssueEmbedConfig | undefined;
|
||||
provider: HocuspocusProvider;
|
||||
export type TDocumentEditorAdditionalExtensionsProps = {
|
||||
disabledExtensions: TExtensions[];
|
||||
embedConfig: TEmbedConfig | undefined;
|
||||
fileHandler: TFileHandler;
|
||||
provider?: HocuspocusProvider;
|
||||
userDetails: TUserDetails;
|
||||
};
|
||||
|
||||
type ExtensionConfig = {
|
||||
export type TDocumentEditorAdditionalExtensionsRegistry = {
|
||||
isEnabled: (disabledExtensions: TExtensions[]) => boolean;
|
||||
getExtension: (props: Props) => AnyExtension;
|
||||
getExtension: (props: TDocumentEditorAdditionalExtensionsProps) => AnyExtension | undefined;
|
||||
};
|
||||
|
||||
const extensionRegistry: ExtensionConfig[] = [
|
||||
const extensionRegistry: TDocumentEditorAdditionalExtensionsRegistry[] = [
|
||||
{
|
||||
isEnabled: (disabledExtensions) => !disabledExtensions.includes("slash-commands"),
|
||||
getExtension: () => SlashCommands({}),
|
||||
getExtension: ({ disabledExtensions }) => SlashCommands({ disabledExtensions }),
|
||||
},
|
||||
];
|
||||
|
||||
export const DocumentEditorAdditionalExtensions = (_props: Props) => {
|
||||
const { disabledExtensions = [] } = _props;
|
||||
export const DocumentEditorAdditionalExtensions = (props: TDocumentEditorAdditionalExtensionsProps) => {
|
||||
const { disabledExtensions = [] } = props;
|
||||
|
||||
const documentExtensions = extensionRegistry
|
||||
const documentExtensions: Extensions = extensionRegistry
|
||||
.filter((config) => config.isEnabled(disabledExtensions))
|
||||
.map((config) => config.getExtension(_props));
|
||||
.map((config) => config.getExtension(props))
|
||||
.filter((extension): extension is AnyExtension => extension !== undefined);
|
||||
|
||||
return documentExtensions;
|
||||
};
|
||||
|
||||
41
packages/editor/src/ce/extensions/rich-text/extensions.tsx
Normal file
41
packages/editor/src/ce/extensions/rich-text/extensions.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
import { AnyExtension, Extensions } from "@tiptap/core";
|
||||
// extensions
|
||||
import { SlashCommands } from "@/extensions/slash-commands/root";
|
||||
// types
|
||||
import { TExtensions, TFileHandler } from "@/types";
|
||||
|
||||
export type TRichTextEditorAdditionalExtensionsProps = {
|
||||
disabledExtensions: TExtensions[];
|
||||
fileHandler: TFileHandler;
|
||||
};
|
||||
|
||||
/**
|
||||
* Registry entry configuration for extensions
|
||||
*/
|
||||
export type TRichTextEditorAdditionalExtensionsRegistry = {
|
||||
/** Determines if the extension should be enabled based on disabled extensions */
|
||||
isEnabled: (disabledExtensions: TExtensions[]) => boolean;
|
||||
/** Returns the extension instance(s) when enabled */
|
||||
getExtension: (props: TRichTextEditorAdditionalExtensionsProps) => AnyExtension | undefined;
|
||||
};
|
||||
|
||||
const extensionRegistry: TRichTextEditorAdditionalExtensionsRegistry[] = [
|
||||
{
|
||||
isEnabled: (disabledExtensions) => !disabledExtensions.includes("slash-commands"),
|
||||
getExtension: ({ disabledExtensions }) =>
|
||||
SlashCommands({
|
||||
disabledExtensions,
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
||||
export const RichTextEditorAdditionalExtensions = (props: TRichTextEditorAdditionalExtensionsProps) => {
|
||||
const { disabledExtensions } = props;
|
||||
|
||||
const extensions: Extensions = extensionRegistry
|
||||
.filter((config) => config.isEnabled(disabledExtensions))
|
||||
.map((config) => config.getExtension(props))
|
||||
.filter((extension): extension is AnyExtension => extension !== undefined);
|
||||
|
||||
return extensions;
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
import { AnyExtension, Extensions } from "@tiptap/core";
|
||||
// types
|
||||
import { TExtensions, TReadOnlyFileHandler } from "@/types";
|
||||
|
||||
export type TRichTextReadOnlyEditorAdditionalExtensionsProps = {
|
||||
disabledExtensions: TExtensions[];
|
||||
fileHandler: TReadOnlyFileHandler;
|
||||
};
|
||||
|
||||
/**
|
||||
* Registry entry configuration for extensions
|
||||
*/
|
||||
export type TRichTextReadOnlyEditorAdditionalExtensionsRegistry = {
|
||||
/** Determines if the extension should be enabled based on disabled extensions */
|
||||
isEnabled: (disabledExtensions: TExtensions[]) => boolean;
|
||||
/** Returns the extension instance(s) when enabled */
|
||||
getExtension: (props: TRichTextReadOnlyEditorAdditionalExtensionsProps) => AnyExtension | undefined;
|
||||
};
|
||||
|
||||
const extensionRegistry: TRichTextReadOnlyEditorAdditionalExtensionsRegistry[] = [];
|
||||
|
||||
export const RichTextReadOnlyEditorAdditionalExtensions = (props: TRichTextReadOnlyEditorAdditionalExtensionsProps) => {
|
||||
const { disabledExtensions } = props;
|
||||
|
||||
const extensions: Extensions = extensionRegistry
|
||||
.filter((config) => config.isEnabled(disabledExtensions))
|
||||
.map((config) => config.getExtension(props))
|
||||
.filter((extension): extension is AnyExtension => extension !== undefined);
|
||||
|
||||
return extensions;
|
||||
};
|
||||
@@ -50,6 +50,7 @@ const DocumentEditor = (props: IDocumentEditor) => {
|
||||
...DocumentEditorAdditionalExtensions({
|
||||
disabledExtensions,
|
||||
embedConfig: embedHandler,
|
||||
fileHandler,
|
||||
userDetails: user,
|
||||
})
|
||||
);
|
||||
|
||||
@@ -15,6 +15,7 @@ export const ReadOnlyEditorWrapper = (props: IReadOnlyEditorProps) => {
|
||||
disabledExtensions,
|
||||
displayConfig = DEFAULT_DISPLAY_CONFIG,
|
||||
editorClassName = "",
|
||||
extensions,
|
||||
fileHandler,
|
||||
forwardedRef,
|
||||
id,
|
||||
@@ -25,6 +26,7 @@ export const ReadOnlyEditorWrapper = (props: IReadOnlyEditorProps) => {
|
||||
const editor = useReadOnlyEditor({
|
||||
disabledExtensions,
|
||||
editorClassName,
|
||||
extensions,
|
||||
fileHandler,
|
||||
forwardedRef,
|
||||
initialValue,
|
||||
|
||||
@@ -3,7 +3,9 @@ import { forwardRef, useCallback } from "react";
|
||||
import { EditorWrapper } from "@/components/editors";
|
||||
import { EditorBubbleMenu } from "@/components/menus";
|
||||
// extensions
|
||||
import { SideMenuExtension, SlashCommands } from "@/extensions";
|
||||
import { SideMenuExtension } from "@/extensions";
|
||||
// plane editor imports
|
||||
import { RichTextEditorAdditionalExtensions } from "@/plane-editor/extensions/rich-text/extensions";
|
||||
// types
|
||||
import { EditorRefApi, IRichTextEditor } from "@/types";
|
||||
|
||||
@@ -11,6 +13,7 @@ const RichTextEditor = (props: IRichTextEditor) => {
|
||||
const {
|
||||
disabledExtensions,
|
||||
dragDropEnabled,
|
||||
fileHandler,
|
||||
bubbleMenuEnabled = true,
|
||||
extensions: externalExtensions = [],
|
||||
isSmoothCursorEnabled,
|
||||
@@ -23,17 +26,14 @@ const RichTextEditor = (props: IRichTextEditor) => {
|
||||
aiEnabled: false,
|
||||
dragDropEnabled: !!dragDropEnabled,
|
||||
}),
|
||||
...RichTextEditorAdditionalExtensions({
|
||||
disabledExtensions,
|
||||
fileHandler,
|
||||
}),
|
||||
];
|
||||
if (!disabledExtensions?.includes("slash-commands")) {
|
||||
extensions.push(
|
||||
SlashCommands({
|
||||
disabledExtensions,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
return extensions;
|
||||
}, [dragDropEnabled, disabledExtensions, externalExtensions]);
|
||||
}, [dragDropEnabled, disabledExtensions, externalExtensions, fileHandler]);
|
||||
|
||||
return (
|
||||
<EditorWrapper {...props} extensions={getExtensions()} isSmoothCursorEnabled={isSmoothCursorEnabled}>
|
||||
|
||||
@@ -1,11 +1,33 @@
|
||||
import { forwardRef } from "react";
|
||||
import { forwardRef, useCallback } from "react";
|
||||
// plane editor extensions
|
||||
import { RichTextReadOnlyEditorAdditionalExtensions } from "@/plane-editor/extensions/rich-text/read-only-extensions";
|
||||
// types
|
||||
import { EditorReadOnlyRefApi, IRichTextReadOnlyEditor } from "@/types";
|
||||
// local imports
|
||||
import { ReadOnlyEditorWrapper } from "../read-only-editor-wrapper";
|
||||
|
||||
const RichTextReadOnlyEditorWithRef = forwardRef<EditorReadOnlyRefApi, IRichTextReadOnlyEditor>((props, ref) => (
|
||||
<ReadOnlyEditorWrapper {...props} forwardedRef={ref as React.MutableRefObject<EditorReadOnlyRefApi | null>} />
|
||||
));
|
||||
const RichTextReadOnlyEditorWithRef = forwardRef<EditorReadOnlyRefApi, IRichTextReadOnlyEditor>((props, ref) => {
|
||||
const { disabledExtensions, fileHandler } = props;
|
||||
|
||||
const getExtensions = useCallback(() => {
|
||||
const extensions = [
|
||||
...RichTextReadOnlyEditorAdditionalExtensions({
|
||||
disabledExtensions,
|
||||
fileHandler,
|
||||
}),
|
||||
];
|
||||
|
||||
return extensions;
|
||||
}, [disabledExtensions, fileHandler]);
|
||||
|
||||
return (
|
||||
<ReadOnlyEditorWrapper
|
||||
{...props}
|
||||
extensions={getExtensions()}
|
||||
forwardedRef={ref as React.MutableRefObject<EditorReadOnlyRefApi | null>}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
RichTextReadOnlyEditorWithRef.displayName = "RichReadOnlyEditorWithRef";
|
||||
|
||||
|
||||
@@ -172,8 +172,9 @@ export const CoreEditorExtensions = (args: TArguments): Extensions => {
|
||||
CustomTextAlignExtension,
|
||||
CustomCalloutExtension,
|
||||
UtilityExtension({
|
||||
isEditable: editable,
|
||||
disabledExtensions,
|
||||
fileHandler,
|
||||
isEditable: editable,
|
||||
}),
|
||||
CustomColorExtension,
|
||||
...CoreEditorAdditionalExtensions({
|
||||
|
||||
@@ -127,8 +127,9 @@ export const CoreReadOnlyEditorExtensions = (props: Props): Extensions => {
|
||||
CustomTextAlignExtension,
|
||||
CustomCalloutReadOnlyExtension,
|
||||
UtilityExtension({
|
||||
isEditable: false,
|
||||
disabledExtensions,
|
||||
fileHandler,
|
||||
isEditable: false,
|
||||
}),
|
||||
...CoreReadOnlyEditorAdditionalExtensions({
|
||||
disabledExtensions,
|
||||
|
||||
@@ -6,7 +6,7 @@ import { DropHandlerPlugin } from "@/plugins/drop";
|
||||
import { FilePlugins } from "@/plugins/file/root";
|
||||
import { MarkdownClipboardPlugin } from "@/plugins/markdown-clipboard";
|
||||
// types
|
||||
import { TFileHandler, TReadOnlyFileHandler } from "@/types";
|
||||
import { TExtensions, TFileHandler, TReadOnlyFileHandler } from "@/types";
|
||||
// prosemirror plugins
|
||||
import { codemark } from "./code-mark";
|
||||
|
||||
@@ -24,13 +24,14 @@ export interface UtilityExtensionStorage {
|
||||
}
|
||||
|
||||
type Props = {
|
||||
disabledExtensions: TExtensions[];
|
||||
fileHandler: TFileHandler | TReadOnlyFileHandler;
|
||||
isEditable: boolean;
|
||||
};
|
||||
|
||||
export const UtilityExtension = (props: Props) => {
|
||||
const { fileHandler, isEditable } = props;
|
||||
const { restore: restoreImageFn } = fileHandler;
|
||||
const { disabledExtensions, fileHandler, isEditable } = props;
|
||||
const { restore } = fileHandler;
|
||||
|
||||
return Extension.create<Record<string, unknown>, UtilityExtensionStorage>({
|
||||
name: "utility",
|
||||
@@ -45,12 +46,15 @@ export const UtilityExtension = (props: Props) => {
|
||||
}),
|
||||
...codemark({ markType: this.editor.schema.marks.code }),
|
||||
MarkdownClipboardPlugin(this.editor),
|
||||
DropHandlerPlugin(this.editor),
|
||||
DropHandlerPlugin({
|
||||
disabledExtensions,
|
||||
editor: this.editor,
|
||||
}),
|
||||
];
|
||||
},
|
||||
|
||||
onCreate() {
|
||||
restorePublicImages(this.editor, restoreImageFn);
|
||||
restorePublicImages(this.editor, restore);
|
||||
},
|
||||
|
||||
addStorage() {
|
||||
|
||||
@@ -153,6 +153,7 @@ export const useCollaborativeEditor = (props: TCollaborativeEditorProps) => {
|
||||
...DocumentEditorAdditionalExtensions({
|
||||
disabledExtensions,
|
||||
embedConfig: embedHandler,
|
||||
fileHandler,
|
||||
provider,
|
||||
userDetails: user,
|
||||
}),
|
||||
|
||||
@@ -3,10 +3,17 @@ import { Plugin, PluginKey } from "@tiptap/pm/state";
|
||||
// constants
|
||||
import { ACCEPTED_ATTACHMENT_MIME_TYPES, ACCEPTED_IMAGE_MIME_TYPES } from "@/constants/config";
|
||||
// types
|
||||
import { TEditorCommands } from "@/types";
|
||||
import { TEditorCommands, TExtensions } from "@/types";
|
||||
|
||||
export const DropHandlerPlugin = (editor: Editor): Plugin =>
|
||||
new Plugin({
|
||||
type Props = {
|
||||
disabledExtensions: TExtensions[];
|
||||
editor: Editor;
|
||||
};
|
||||
|
||||
export const DropHandlerPlugin = (props: Props): Plugin => {
|
||||
const { disabledExtensions, editor } = props;
|
||||
|
||||
return new Plugin({
|
||||
key: new PluginKey("drop-handler-plugin"),
|
||||
props: {
|
||||
handlePaste: (view, event) => {
|
||||
@@ -25,6 +32,7 @@ export const DropHandlerPlugin = (editor: Editor): Plugin =>
|
||||
if (acceptedFiles.length) {
|
||||
const pos = view.state.selection.from;
|
||||
insertFilesSafely({
|
||||
disabledExtensions,
|
||||
editor,
|
||||
files: acceptedFiles,
|
||||
initialPos: pos,
|
||||
@@ -58,6 +66,7 @@ export const DropHandlerPlugin = (editor: Editor): Plugin =>
|
||||
if (coordinates) {
|
||||
const pos = coordinates.pos;
|
||||
insertFilesSafely({
|
||||
disabledExtensions,
|
||||
editor,
|
||||
files: acceptedFiles,
|
||||
initialPos: pos,
|
||||
@@ -71,8 +80,10 @@ export const DropHandlerPlugin = (editor: Editor): Plugin =>
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
type InsertFilesSafelyArgs = {
|
||||
disabledExtensions: TExtensions[];
|
||||
editor: Editor;
|
||||
event: "insert" | "drop";
|
||||
files: File[];
|
||||
@@ -81,7 +92,7 @@ type InsertFilesSafelyArgs = {
|
||||
};
|
||||
|
||||
export const insertFilesSafely = async (args: InsertFilesSafelyArgs) => {
|
||||
const { editor, event, files, initialPos, type } = args;
|
||||
const { disabledExtensions, editor, event, files, initialPos, type } = args;
|
||||
let pos = initialPos;
|
||||
|
||||
for (const file of files) {
|
||||
@@ -100,7 +111,7 @@ export const insertFilesSafely = async (args: InsertFilesSafelyArgs) => {
|
||||
else if (ACCEPTED_ATTACHMENT_MIME_TYPES.includes(file.type)) fileType = "attachment";
|
||||
}
|
||||
// insert file depending on the type at the current position
|
||||
if (fileType === "image") {
|
||||
if (fileType === "image" && !disabledExtensions.includes("image")) {
|
||||
editor.commands.insertImageComponent({
|
||||
file,
|
||||
pos,
|
||||
|
||||
@@ -196,6 +196,7 @@ export interface IReadOnlyEditorProps {
|
||||
disabledExtensions: TExtensions[];
|
||||
displayConfig?: TDisplayConfig;
|
||||
editorClassName?: string;
|
||||
extensions?: Extensions;
|
||||
fileHandler: TReadOnlyFileHandler;
|
||||
forwardedRef?: React.MutableRefObject<EditorReadOnlyRefApi | null>;
|
||||
id: string;
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import { HocuspocusProvider } from "@hocuspocus/provider";
|
||||
import { Extension, Node } from "@tiptap/core";
|
||||
import { Extension } from "@tiptap/core";
|
||||
import { FileText } from "lucide-react";
|
||||
// ui
|
||||
// core imports
|
||||
import {
|
||||
TDocumentEditorAdditionalExtensionsProps,
|
||||
TDocumentEditorAdditionalExtensionsRegistry,
|
||||
} from "src/ce/extensions";
|
||||
// plane imports
|
||||
import { LayersIcon } from "@plane/ui";
|
||||
// extensions
|
||||
import { SlashCommands, TSlashCommandAdditionalOption } from "@/extensions";
|
||||
@@ -9,30 +13,11 @@ import { SlashCommands, TSlashCommandAdditionalOption } from "@/extensions";
|
||||
import { insertPageEmbed } from "@/helpers/editor-commands";
|
||||
// plane editor extensions
|
||||
import { IssueEmbedSuggestions, IssueListRenderer, PageEmbedExtension } from "@/plane-editor/extensions";
|
||||
// plane editor types
|
||||
import { TEmbedConfig } from "@/plane-editor/types";
|
||||
// types
|
||||
import { TExtensions, TUserDetails } from "@/types";
|
||||
// local extensions
|
||||
import { TExtensions } from "@/types";
|
||||
// local imports
|
||||
import { CustomCollaborationCursor } from "./collaboration-cursor";
|
||||
|
||||
type Props = {
|
||||
disabledExtensions?: TExtensions[];
|
||||
embedConfig: TEmbedConfig | undefined;
|
||||
provider?: HocuspocusProvider;
|
||||
userDetails: TUserDetails;
|
||||
};
|
||||
|
||||
/**
|
||||
* Registry entry configuration for extensions
|
||||
*/
|
||||
type ExtensionConfig = {
|
||||
/** Determines if the extension should be enabled based on disabled extensions */
|
||||
isEnabled: (disabledExtensions: TExtensions[]) => boolean;
|
||||
/** Returns the extension instance(s) when enabled */
|
||||
getExtension: (props: Props) => Extension[] | Node[] | undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* Registry for slash commands
|
||||
* Each entry defines a single slash command option with its own enabling logic
|
||||
@@ -58,7 +43,7 @@ const slashCommandRegistry = [
|
||||
{
|
||||
// Page embed slash command
|
||||
isEnabled: (disabledExtensions: TExtensions[]) => !disabledExtensions.includes("nested-pages"),
|
||||
getOption: ({ embedConfig }: Props): TSlashCommandAdditionalOption | null => {
|
||||
getOption: ({ embedConfig }: TDocumentEditorAdditionalExtensionsProps): TSlashCommandAdditionalOption | null => {
|
||||
// Only enable if page config with createCallback exists
|
||||
const pageConfig = embedConfig?.page;
|
||||
if (!pageConfig?.createCallback) return null;
|
||||
@@ -94,7 +79,7 @@ const slashCommandRegistry = [
|
||||
* Main extension registry
|
||||
* Each entry defines a TipTap extension with its own enabling logic
|
||||
*/
|
||||
const extensionRegistry: ExtensionConfig[] = [
|
||||
const extensionRegistry: TDocumentEditorAdditionalExtensionsRegistry[] = [
|
||||
{
|
||||
// Slash commands extension
|
||||
isEnabled: (disabledExtensions) => !disabledExtensions.includes("slash-commands"),
|
||||
@@ -105,12 +90,10 @@ const extensionRegistry: ExtensionConfig[] = [
|
||||
.map((command) => command.getOption(props))
|
||||
.filter((option): option is TSlashCommandAdditionalOption => option !== null);
|
||||
|
||||
return [
|
||||
SlashCommands({
|
||||
additionalOptions: slashCommandOptions,
|
||||
disabledExtensions: props.disabledExtensions,
|
||||
}),
|
||||
];
|
||||
return SlashCommands({
|
||||
additionalOptions: slashCommandOptions,
|
||||
disabledExtensions: props.disabledExtensions,
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -121,27 +104,24 @@ const extensionRegistry: ExtensionConfig[] = [
|
||||
const searchCallback = issueConfig?.searchCallback;
|
||||
|
||||
// Only enable if search callback exists
|
||||
if (!searchCallback) return [];
|
||||
if (!searchCallback) return undefined;
|
||||
|
||||
return [
|
||||
IssueEmbedSuggestions.configure({
|
||||
suggestion: {
|
||||
render: () => IssueListRenderer(searchCallback),
|
||||
},
|
||||
}),
|
||||
];
|
||||
return IssueEmbedSuggestions.configure({
|
||||
suggestion: {
|
||||
render: () => IssueListRenderer(searchCallback),
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
// Collaboration cursor extension
|
||||
isEnabled: (disabledExtensions) => !disabledExtensions.includes("collaboration-cursor"),
|
||||
getExtension: ({ provider, userDetails }) =>
|
||||
provider && [
|
||||
CustomCollaborationCursor({
|
||||
provider,
|
||||
userDetails,
|
||||
}),
|
||||
],
|
||||
provider &&
|
||||
CustomCollaborationCursor({
|
||||
provider,
|
||||
userDetails,
|
||||
}),
|
||||
},
|
||||
{
|
||||
// Page embed extension
|
||||
@@ -150,17 +130,15 @@ const extensionRegistry: ExtensionConfig[] = [
|
||||
const pageConfig = embedConfig?.page;
|
||||
|
||||
// Only enable if widget callback exists
|
||||
if (!pageConfig) return [];
|
||||
if (!pageConfig) return undefined;
|
||||
|
||||
return [
|
||||
PageEmbedExtension({
|
||||
widgetCallback: pageConfig.widgetCallback,
|
||||
archivePage: pageConfig.archivePage,
|
||||
unarchivePage: pageConfig.unarchivePage,
|
||||
deletePage: pageConfig.deletePage,
|
||||
getPageDetailsCallback: pageConfig.getPageDetailsCallback,
|
||||
}),
|
||||
];
|
||||
return PageEmbedExtension({
|
||||
widgetCallback: pageConfig.widgetCallback,
|
||||
archivePage: pageConfig.archivePage,
|
||||
unarchivePage: pageConfig.unarchivePage,
|
||||
deletePage: pageConfig.deletePage,
|
||||
getPageDetailsCallback: pageConfig.getPageDetailsCallback,
|
||||
});
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -168,14 +146,13 @@ const extensionRegistry: ExtensionConfig[] = [
|
||||
/**
|
||||
* Returns all enabled extensions for the document editor
|
||||
*/
|
||||
export const DocumentEditorAdditionalExtensions = (props: Props) => {
|
||||
export const DocumentEditorAdditionalExtensions = (props: TDocumentEditorAdditionalExtensionsProps) => {
|
||||
const { disabledExtensions = [] } = props;
|
||||
|
||||
// Filter enabled extensions and flatten the result
|
||||
const extensions: Extension[] = extensionRegistry
|
||||
.filter((config) => config.isEnabled(disabledExtensions))
|
||||
.map((config) => config.getExtension(props))
|
||||
.flat()
|
||||
.filter((extension): extension is Extension => extension !== undefined);
|
||||
|
||||
return extensions;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export * from "src/ce/extensions/rich-text/extensions";
|
||||
@@ -0,0 +1 @@
|
||||
export * from "src/ce/extensions/rich-text/read-only-extensions";
|
||||
Reference in New Issue
Block a user