@teriusu/rich-editor 0.7.1 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,16 +0,0 @@
1
- import { Node } from "@tiptap/core";
2
- export interface VideoBlockOptions {
3
- HTMLAttributes: Record<string, unknown>;
4
- }
5
- declare module "@tiptap/core" {
6
- interface Commands<ReturnType> {
7
- videoBlock: {
8
- setVideoBlock: (attrs: {
9
- src: string;
10
- name?: string;
11
- }) => ReturnType;
12
- };
13
- }
14
- }
15
- export declare const VideoBlock: Node<VideoBlockOptions, any>;
16
- //# sourceMappingURL=VideoBlock.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"VideoBlock.d.ts","sourceRoot":"","sources":["../../src/extensions/VideoBlock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,cAAc,CAAC;AAErD,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACzC;AAED,OAAO,QAAQ,cAAc,CAAC;IAC5B,UAAU,QAAQ,CAAC,UAAU;QAC3B,UAAU,EAAE;YACV,aAAa,EAAE,CAAC,KAAK,EAAE;gBAAE,GAAG,EAAE,MAAM,CAAC;gBAAC,IAAI,CAAC,EAAE,MAAM,CAAA;aAAE,KAAK,UAAU,CAAC;SACtE,CAAC;KACH;CACF;AAED,eAAO,MAAM,UAAU,8BAkGrB,CAAC"}
@@ -1,87 +0,0 @@
1
- import { Node, mergeAttributes } from "@tiptap/core";
2
- export const VideoBlock = Node.create({
3
- name: "videoBlock",
4
- group: "block",
5
- atom: true,
6
- draggable: true,
7
- addOptions() {
8
- return { HTMLAttributes: {} };
9
- },
10
- addAttributes() {
11
- return {
12
- src: { default: null },
13
- name: { default: "" },
14
- };
15
- },
16
- parseHTML() {
17
- return [
18
- {
19
- tag: 'div[data-video-src]',
20
- getAttrs: (dom) => {
21
- const el = dom;
22
- return {
23
- src: el.getAttribute("data-video-src"),
24
- name: el.getAttribute("data-video-name") || "",
25
- };
26
- },
27
- },
28
- ];
29
- },
30
- renderHTML({ HTMLAttributes }) {
31
- return [
32
- "div",
33
- mergeAttributes(this.options.HTMLAttributes, {
34
- "data-video-src": HTMLAttributes.src,
35
- "data-video-name": HTMLAttributes.name || "",
36
- }),
37
- ];
38
- },
39
- addNodeView() {
40
- return ({ node, editor }) => {
41
- const dom = document.createElement("div");
42
- dom.style.cssText = "margin:8px 0;position:relative;";
43
- const video = document.createElement("video");
44
- video.src = node.attrs.src;
45
- video.controls = true;
46
- video.preload = "metadata";
47
- video.style.cssText =
48
- "width:100%;max-height:480px;border-radius:8px;background:#0b1020;";
49
- video.setAttribute("controlslist", "nodownload");
50
- video.setAttribute("playsinline", "");
51
- dom.appendChild(video);
52
- if (node.attrs.name) {
53
- const label = document.createElement("p");
54
- label.textContent = node.attrs.name;
55
- label.style.cssText =
56
- "margin:4px 0 0;font-size:12px;color:var(--muted-foreground, #718096);";
57
- dom.appendChild(label);
58
- }
59
- if (editor.isEditable) {
60
- const del = document.createElement("button");
61
- del.type = "button";
62
- del.textContent = "\u00D7";
63
- del.style.cssText =
64
- "position:absolute;top:8px;right:8px;width:28px;height:28px;border:none;background:rgba(0,0,0,0.6);color:#fff;font-size:18px;cursor:pointer;border-radius:50%;display:flex;align-items:center;justify-content:center;z-index:2;";
65
- del.addEventListener("mouseenter", () => {
66
- del.style.background = "var(--destructive, #FF6B6B)";
67
- });
68
- del.addEventListener("mouseleave", () => {
69
- del.style.background = "rgba(0,0,0,0.6)";
70
- });
71
- del.addEventListener("click", () => {
72
- const pos = editor.view.posAtDOM(dom, 0);
73
- editor.chain().focus().deleteRange({ from: pos, to: pos + 1 }).run();
74
- });
75
- dom.appendChild(del);
76
- }
77
- return { dom };
78
- };
79
- },
80
- addCommands() {
81
- return {
82
- setVideoBlock: (attrs) => ({ chain }) => {
83
- return chain().insertContent({ type: this.name, attrs }).run();
84
- },
85
- };
86
- },
87
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=VideoBlock.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"VideoBlock.test.d.ts","sourceRoot":"","sources":["../../src/extensions/VideoBlock.test.ts"],"names":[],"mappings":""}
@@ -1,54 +0,0 @@
1
- import { describe, it, expect, afterEach } from 'vitest';
2
- import { Editor } from '@tiptap/core';
3
- import StarterKit from '@tiptap/starter-kit';
4
- import { VideoBlock } from './VideoBlock';
5
- describe('VideoBlock extension', () => {
6
- let editor;
7
- function createEditor(content = '<p></p>') {
8
- editor = new Editor({
9
- element: document.createElement('div'),
10
- extensions: [StarterKit, VideoBlock],
11
- content
12
- });
13
- return editor;
14
- }
15
- afterEach(() => {
16
- editor?.destroy();
17
- });
18
- it('registers with name "videoBlock"', () => {
19
- createEditor();
20
- const ext = editor.extensionManager.extensions.find((e) => e.name === 'videoBlock');
21
- expect(ext).toBeDefined();
22
- });
23
- it('parses <div data-video-src="url">', () => {
24
- createEditor('<div data-video-src="https://example.com/video.mp4" data-video-name="demo"></div>');
25
- const doc = editor.getJSON();
26
- const videoNode = doc.content?.find((n) => n.type === 'videoBlock');
27
- expect(videoNode).toBeDefined();
28
- expect(videoNode?.attrs?.src).toBe('https://example.com/video.mp4');
29
- expect(videoNode?.attrs?.name).toBe('demo');
30
- });
31
- it('renders correct HTML', () => {
32
- createEditor('<div data-video-src="https://example.com/video.mp4" data-video-name="demo"></div>');
33
- const html = editor.getHTML();
34
- expect(html).toContain('data-video-src="https://example.com/video.mp4"');
35
- expect(html).toContain('data-video-name="demo"');
36
- });
37
- it('defaults name to empty string', () => {
38
- createEditor('<div data-video-src="https://example.com/video.mp4"></div>');
39
- const doc = editor.getJSON();
40
- const videoNode = doc.content?.find((n) => n.type === 'videoBlock');
41
- expect(videoNode?.attrs?.name).toBe('');
42
- });
43
- it('inserts via setVideoBlock command', () => {
44
- createEditor();
45
- editor.commands.setVideoBlock({
46
- src: 'https://example.com/v.mp4',
47
- name: 'My Video'
48
- });
49
- const doc = editor.getJSON();
50
- const videoNode = doc.content?.find((n) => n.type === 'videoBlock');
51
- expect(videoNode).toBeDefined();
52
- expect(videoNode?.attrs?.src).toBe('https://example.com/v.mp4');
53
- });
54
- });