Some checks failed
CodeQL / Analyze (javascript) (push) Failing after 16s
CodeQL / Analyze (python) (push) Failing after 3s
i18n sync check / check:sync (push) Failing after 3s
React Doctor / react-doctor (push) Failing after 16s
Branch Build CE / Build-Push Admin Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Admin Manifest (push) Has been cancelled
Branch Build CE / Build-Push Web Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Web Manifest (push) Has been cancelled
Branch Build CE / Build-Push Space Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Proxy Manifest (push) Has been cancelled
Branch Build CE / Merge Space Manifest (push) Has been cancelled
Branch Build CE / Prepare AIO Assets (push) Has been cancelled
Branch Build CE / Build Setup (push) Has been cancelled
Branch Build CE / Build-Push Live Collaboration Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge Live Collaboration Manifest (push) Has been cancelled
Branch Build CE / Build-Push API Server Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge API Server Manifest (push) Has been cancelled
Branch Build CE / Build-Push Proxy Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Build-Push AIO Docker Image (${{ matrix.arch }}) (push) Has been cancelled
Branch Build CE / Merge AIO Manifest (push) Has been cancelled
Branch Build CE / Upload Build Assets (push) Has been cancelled
Branch Build CE / Build Release (push) Has been cancelled
85 lines
2.6 KiB
TypeScript
85 lines
2.6 KiB
TypeScript
/**
|
|
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
|
* See the LICENSE file for details.
|
|
*/
|
|
|
|
import { Node, mergeAttributes } from "@tiptap/core";
|
|
import type { MarkdownSerializerState } from "@tiptap/pm/markdown";
|
|
import type { Node as ProseMirrorNode } from "@tiptap/pm/model";
|
|
// constants
|
|
import { CORE_EXTENSIONS } from "@/constants/extension";
|
|
// types
|
|
import { ECalloutAttributeNames } from "./types";
|
|
import type { CustomCalloutExtensionType, TCalloutBlockAttributes } from "./types";
|
|
// utils
|
|
import { DEFAULT_CALLOUT_BLOCK_ATTRIBUTES } from "./utils";
|
|
|
|
declare module "@tiptap/core" {
|
|
interface Commands<ReturnType> {
|
|
[CORE_EXTENSIONS.CALLOUT]: {
|
|
insertCallout: () => ReturnType;
|
|
};
|
|
}
|
|
}
|
|
|
|
export const CustomCalloutExtensionConfig: CustomCalloutExtensionType = Node.create({
|
|
name: CORE_EXTENSIONS.CALLOUT,
|
|
group: "block",
|
|
content: "block+",
|
|
|
|
addAttributes() {
|
|
const attributes = {
|
|
// Reduce instead of map to accumulate the attributes directly into an object
|
|
...Object.values(ECalloutAttributeNames).reduce(
|
|
(acc, value) => {
|
|
acc[value] = {
|
|
default: DEFAULT_CALLOUT_BLOCK_ATTRIBUTES[value],
|
|
};
|
|
return acc;
|
|
},
|
|
{} as Record<ECalloutAttributeNames, { default: TCalloutBlockAttributes[ECalloutAttributeNames] }>
|
|
),
|
|
};
|
|
|
|
return attributes;
|
|
},
|
|
|
|
addStorage() {
|
|
return {
|
|
markdown: {
|
|
serialize(state: MarkdownSerializerState, node: ProseMirrorNode) {
|
|
const attrs = node.attrs as TCalloutBlockAttributes;
|
|
const logoInUse = attrs["data-logo-in-use"];
|
|
// add callout logo
|
|
if (logoInUse === "emoji") {
|
|
state.write(
|
|
`> <img src="${attrs["data-emoji-url"]}" alt="${attrs["data-emoji-unicode"]}" width="30px" />\n`
|
|
);
|
|
} else {
|
|
state.write(`> <icon>${attrs["data-icon-name"]} icon</icon>\n`);
|
|
}
|
|
// add an empty line after the logo
|
|
state.write("> \n");
|
|
// add '> ' before each line of the callout content
|
|
state.wrapBlock("> ", null, node, () => state.renderContent(node));
|
|
state.closeBlock(node);
|
|
},
|
|
},
|
|
};
|
|
},
|
|
|
|
parseHTML() {
|
|
return [
|
|
{
|
|
tag: `div[${ECalloutAttributeNames.BLOCK_TYPE}="${DEFAULT_CALLOUT_BLOCK_ATTRIBUTES[ECalloutAttributeNames.BLOCK_TYPE]}"]`,
|
|
},
|
|
];
|
|
},
|
|
|
|
// Render HTML for the callout node
|
|
renderHTML({ HTMLAttributes }) {
|
|
return ["div", mergeAttributes(HTMLAttributes), 0];
|
|
},
|
|
});
|