106 lines
3.5 KiB
106 lines
3.5 KiB
import { Editor } from "@tiptap/core";
|
|
import StarterKit from "@tiptap/starter-kit";
|
|
import CharacterCount from "@tiptap/extension-character-count";
|
|
import BubbleMenu, { BubbleMenuPlugin } from "@tiptap/extension-bubble-menu";
|
|
import Image from "@tiptap/extension-image";
|
|
import { Markdown } from "tiptap-markdown";
|
|
import { getDom } from "./utils.js";
|
|
|
|
import "./style/index.scss";
|
|
|
|
class Inkeon {
|
|
constructor(dom: string | Element) {
|
|
const domEl = getDom(dom);
|
|
this.#init(domEl);
|
|
}
|
|
|
|
#editor: Editor;
|
|
|
|
#init(dom: Element) {
|
|
const BubbleMenuElement = document.querySelector(
|
|
".bubble-menu"
|
|
) as HTMLElement;
|
|
BubbleMenuElement.querySelector("button").addEventListener("click", () => {
|
|
if (!this.#editor) return;
|
|
const altInput = BubbleMenuElement.querySelector(
|
|
".alt-input"
|
|
) as HTMLInputElement;
|
|
const altText = altInput.value;
|
|
if (altText) {
|
|
const { state, view } = this.#editor;
|
|
const { from, to } = state.selection;
|
|
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
if (node.type.name === "image") {
|
|
// 创建一个新的事务来修改节点属性
|
|
const tr = state.tr.setNodeMarkup(pos, undefined, {
|
|
...node.attrs,
|
|
alt: altText,
|
|
});
|
|
// 应用事务到视图
|
|
view.dispatch(tr);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
this.#editor = new Editor({
|
|
element: getDom(dom),
|
|
autofocus: true,
|
|
extensions: [
|
|
StarterKit,
|
|
Markdown,
|
|
Image.configure({
|
|
inline: true,
|
|
}),
|
|
CharacterCount.configure({
|
|
limit: 240,
|
|
}),
|
|
BubbleMenu.configure({
|
|
element: BubbleMenuElement,
|
|
shouldShow: ({ editor, view, state, oldState, from, to }) => {
|
|
console.log(editor, view, state, oldState, from, to);
|
|
//如果是图片或链接才显示菜单
|
|
if (editor.isActive("image")) {
|
|
const altInput = BubbleMenuElement.querySelector(
|
|
".alt-input"
|
|
) as HTMLInputElement;
|
|
const currentImage = editor.getAttributes("image");
|
|
altInput.value = currentImage.alt || "";
|
|
const srcInput = BubbleMenuElement.querySelector(
|
|
".src-input"
|
|
) as HTMLInputElement;
|
|
srcInput.value = currentImage.src || "";
|
|
}
|
|
return editor.isActive("image") || editor.isActive("link");
|
|
},
|
|
}),
|
|
],
|
|
});
|
|
document.querySelector(".aa").addEventListener("click", () => {
|
|
// console.log(this.#editor.getJSON());
|
|
// console.log(this.#editor.getHTML());
|
|
console.log(this.#editor.getText());
|
|
console.log(this.#editor.getHTML());
|
|
console.log(this.#editor);
|
|
console.log(this.#editor.storage);
|
|
console.log(this.#editor.storage.markdown.getMarkdown());
|
|
});
|
|
// this.#editor.options.element = getDom(dom)
|
|
// setTimeout(() => {
|
|
// this.#editor.registerPlugin(BubbleMenuPlugin({
|
|
// updateDelay: 0,
|
|
// editor: this.#editor,
|
|
// pluginKey: "bubbleMenu",
|
|
// element: document.querySelector('.bubble-menu'),
|
|
// }))
|
|
// }, 0);
|
|
this.#editor
|
|
.chain()
|
|
.setContent(
|
|
`<p>Hello World!</p> <img src="https://cd2.boardgamesmaker.com/AttachFiles/WebsiteImages/Product_Show/FI_8807.jpg" />阿松大`
|
|
)
|
|
.run();
|
|
}
|
|
}
|
|
|
|
export { Inkeon };
|
|
export default Inkeon;
|
|
|