@gravity-ui/markdown-editor 13.3.0 → 13.4.1
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.
- package/build/cjs/bundle/HorizontalDrag.d.ts +1 -0
- package/build/cjs/bundle/HorizontalDrag.js +2 -1
- package/build/cjs/bundle/config/action-names.d.ts +1 -1
- package/build/cjs/bundle/config/action-names.js +1 -0
- package/build/cjs/bundle/config/icons.d.ts +1 -1
- package/build/cjs/bundle/config/icons.js +1 -0
- package/build/cjs/bundle/config/markup.d.ts +1 -0
- package/build/cjs/bundle/config/markup.js +10 -1
- package/build/cjs/bundle/config/wysiwyg.d.ts +1 -0
- package/build/cjs/bundle/config/wysiwyg.js +10 -1
- package/build/cjs/extensions/yfm/YfmHtmlBlock/YfmHtmlBlockNodeView/NodeView.d.ts +23 -0
- package/build/cjs/extensions/yfm/YfmHtmlBlock/YfmHtmlBlockNodeView/NodeView.js +57 -0
- package/build/cjs/extensions/yfm/YfmHtmlBlock/YfmHtmlBlockNodeView/YfmHtmlBlock.css +66 -0
- package/build/cjs/extensions/yfm/YfmHtmlBlock/YfmHtmlBlockNodeView/YfmHtmlBlockView.d.ts +17 -0
- package/build/cjs/extensions/yfm/YfmHtmlBlock/YfmHtmlBlockNodeView/YfmHtmlBlockView.js +178 -0
- package/build/cjs/extensions/yfm/YfmHtmlBlock/YfmHtmlBlockNodeView/index.d.ts +1 -0
- package/build/cjs/extensions/yfm/YfmHtmlBlock/YfmHtmlBlockNodeView/index.js +4 -0
- package/build/cjs/extensions/yfm/YfmHtmlBlock/YfmHtmlBlockSpecs/const.d.ts +15 -0
- package/build/cjs/extensions/yfm/YfmHtmlBlock/YfmHtmlBlockSpecs/const.js +20 -0
- package/build/cjs/extensions/yfm/YfmHtmlBlock/YfmHtmlBlockSpecs/index.d.ts +10 -0
- package/build/cjs/extensions/yfm/YfmHtmlBlock/YfmHtmlBlockSpecs/index.js +43 -0
- package/build/cjs/extensions/yfm/YfmHtmlBlock/actions.d.ts +2 -0
- package/build/cjs/extensions/yfm/YfmHtmlBlock/actions.js +15 -0
- package/build/cjs/extensions/yfm/YfmHtmlBlock/const.d.ts +2 -0
- package/build/cjs/extensions/yfm/YfmHtmlBlock/const.js +6 -0
- package/build/cjs/extensions/yfm/YfmHtmlBlock/index.d.ts +14 -0
- package/build/cjs/extensions/yfm/YfmHtmlBlock/index.js +17 -0
- package/build/cjs/extensions/yfm/index.d.ts +1 -1
- package/build/cjs/extensions/yfm/index.js +1 -1
- package/build/cjs/i18n/common/en.json +6 -2
- package/build/cjs/i18n/common/index.d.ts +7 -3
- package/build/cjs/i18n/common/ru.json +6 -2
- package/build/cjs/i18n/menubar/en.json +37 -36
- package/build/cjs/i18n/menubar/index.d.ts +38 -37
- package/build/cjs/i18n/menubar/ru.json +37 -36
- package/build/cjs/icons/index.d.ts +1 -1
- package/build/cjs/icons/index.js +2 -1
- package/build/cjs/markup/commands/blocks.d.ts +1 -0
- package/build/cjs/markup/commands/blocks.js +12 -1
- package/build/cjs/table-utils/commands/removeColumn.js +2 -1
- package/build/cjs/version.js +1 -1
- package/build/cjs/view/components/YfmHtml/{YfmHtml.d.ts → YfmStaticView.d.ts} +2 -2
- package/build/cjs/view/components/YfmHtml/{YfmHtml.js → YfmStaticView.js} +2 -2
- package/build/cjs/view/components/YfmHtml/index.d.ts +12 -1
- package/build/cjs/view/components/YfmHtml/index.js +4 -2
- package/build/cjs/view/hocs/withYfmHtml/index.d.ts +13 -0
- package/build/cjs/view/hocs/withYfmHtml/index.js +24 -0
- package/build/cjs/view/hocs/withYfmHtml/types.d.ts +3 -0
- package/build/cjs/view/hocs/withYfmHtml/types.js +2 -0
- package/build/cjs/view/hocs/withYfmHtml/useYfmHtmlBlockRuntime.d.ts +1 -0
- package/build/cjs/view/hocs/withYfmHtml/useYfmHtmlBlockRuntime.js +34 -0
- package/build/cjs/view/hocs/withYfmHtml/utils.d.ts +16 -0
- package/build/cjs/view/hocs/withYfmHtml/utils.js +26 -0
- package/build/esm/bundle/HorizontalDrag.d.ts +1 -0
- package/build/esm/bundle/HorizontalDrag.js +2 -1
- package/build/esm/bundle/config/action-names.d.ts +1 -1
- package/build/esm/bundle/config/action-names.js +1 -0
- package/build/esm/bundle/config/icons.d.ts +1 -1
- package/build/esm/bundle/config/icons.js +2 -1
- package/build/esm/bundle/config/markup.d.ts +1 -0
- package/build/esm/bundle/config/markup.js +10 -1
- package/build/esm/bundle/config/wysiwyg.d.ts +1 -0
- package/build/esm/bundle/config/wysiwyg.js +9 -0
- package/build/esm/extensions/yfm/YfmHtmlBlock/YfmHtmlBlockNodeView/NodeView.d.ts +23 -0
- package/build/esm/extensions/yfm/YfmHtmlBlock/YfmHtmlBlockNodeView/NodeView.js +52 -0
- package/build/esm/extensions/yfm/YfmHtmlBlock/YfmHtmlBlockNodeView/YfmHtmlBlock.css +66 -0
- package/build/esm/extensions/yfm/YfmHtmlBlock/YfmHtmlBlockNodeView/YfmHtmlBlockView.d.ts +18 -0
- package/build/esm/extensions/yfm/YfmHtmlBlock/YfmHtmlBlockNodeView/YfmHtmlBlockView.js +173 -0
- package/build/esm/extensions/yfm/YfmHtmlBlock/YfmHtmlBlockNodeView/index.d.ts +1 -0
- package/build/esm/extensions/yfm/YfmHtmlBlock/YfmHtmlBlockNodeView/index.js +1 -0
- package/build/esm/extensions/yfm/YfmHtmlBlock/YfmHtmlBlockSpecs/const.d.ts +15 -0
- package/build/esm/extensions/yfm/YfmHtmlBlock/YfmHtmlBlockSpecs/const.js +17 -0
- package/build/esm/extensions/yfm/YfmHtmlBlock/YfmHtmlBlockSpecs/index.d.ts +10 -0
- package/build/esm/extensions/yfm/YfmHtmlBlock/YfmHtmlBlockSpecs/index.js +39 -0
- package/build/esm/extensions/yfm/YfmHtmlBlock/actions.d.ts +2 -0
- package/build/esm/extensions/yfm/YfmHtmlBlock/actions.js +12 -0
- package/build/esm/extensions/yfm/YfmHtmlBlock/const.d.ts +2 -0
- package/build/esm/extensions/yfm/YfmHtmlBlock/const.js +2 -0
- package/build/esm/extensions/yfm/YfmHtmlBlock/index.d.ts +14 -0
- package/build/esm/extensions/yfm/YfmHtmlBlock/index.js +13 -0
- package/build/esm/extensions/yfm/index.d.ts +1 -1
- package/build/esm/extensions/yfm/index.js +1 -1
- package/build/esm/i18n/common/en.json +6 -2
- package/build/esm/i18n/common/index.d.ts +7 -3
- package/build/esm/i18n/common/ru.json +6 -2
- package/build/esm/i18n/menubar/en.json +37 -36
- package/build/esm/i18n/menubar/index.d.ts +38 -37
- package/build/esm/i18n/menubar/ru.json +37 -36
- package/build/esm/icons/index.d.ts +1 -1
- package/build/esm/icons/index.js +1 -1
- package/build/esm/markup/commands/blocks.d.ts +1 -0
- package/build/esm/markup/commands/blocks.js +10 -0
- package/build/esm/table-utils/commands/removeColumn.js +2 -1
- package/build/esm/version.js +1 -1
- package/build/esm/view/components/YfmHtml/{YfmHtml.d.ts → YfmStaticView.d.ts} +2 -2
- package/build/esm/view/components/YfmHtml/{YfmHtml.js → YfmStaticView.js} +1 -1
- package/build/esm/view/components/YfmHtml/index.d.ts +12 -1
- package/build/esm/view/components/YfmHtml/index.js +6 -1
- package/build/esm/view/hocs/withYfmHtml/index.d.ts +13 -0
- package/build/esm/view/hocs/withYfmHtml/index.js +19 -0
- package/build/esm/view/hocs/withYfmHtml/types.d.ts +3 -0
- package/build/esm/view/hocs/withYfmHtml/types.js +1 -0
- package/build/esm/view/hocs/withYfmHtml/useYfmHtmlBlockRuntime.d.ts +1 -0
- package/build/esm/view/hocs/withYfmHtml/useYfmHtmlBlockRuntime.js +7 -0
- package/build/esm/view/hocs/withYfmHtml/utils.d.ts +16 -0
- package/build/esm/view/hocs/withYfmHtml/utils.js +22 -0
- package/build/styles.css +66 -0
- package/package.json +6 -1
|
@@ -44,7 +44,7 @@ const useColResize = ({ onStart, onMove, onEnd }) => {
|
|
|
44
44
|
},
|
|
45
45
|
};
|
|
46
46
|
};
|
|
47
|
-
const HorizontalDrag = ({ leftElRef, rightElRef, wrapperRef, editor, }) => {
|
|
47
|
+
const HorizontalDrag = ({ leftElRef, rightElRef, wrapperRef, editor, onEndMove, }) => {
|
|
48
48
|
var _a, _b, _c, _d;
|
|
49
49
|
const cm = editor.cm;
|
|
50
50
|
const [lCardWidth, lSetCardWidth] = useState(((_b = (_a = wrapperRef.current) === null || _a === void 0 ? void 0 : _a.clientWidth) !== null && _b !== void 0 ? _b : 0) / 2);
|
|
@@ -96,6 +96,7 @@ const HorizontalDrag = ({ leftElRef, rightElRef, wrapperRef, editor, }) => {
|
|
|
96
96
|
cm.requestMeasure();
|
|
97
97
|
(_b = rightElRef.current) === null || _b === void 0 ? void 0 : _b.classList.remove(IN_RESIZE_CLASSNAME);
|
|
98
98
|
(_c = leftElRef.current) === null || _c === void 0 ? void 0 : _c.classList.remove(IN_RESIZE_CLASSNAME);
|
|
99
|
+
onEndMove === null || onEndMove === void 0 ? void 0 : onEndMove(rightElRef.current, leftElRef.current);
|
|
99
100
|
}, [calculateWidth, cm, leftElRef, rightElRef, updateWidth, wrapperRef]);
|
|
100
101
|
const { listeners } = useColResize({ onStart, onMove, onEnd });
|
|
101
102
|
return (React.createElement("div", Object.assign({ className: cnEditorComponent('resizer', { horizontal: true }) }, listeners),
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
declare const namesObj: Record<"bold" | "link" | "italic" | "strike" | "underline" | "mark" | "quote" | "mono" | "paragraph" | "anchor" | "table" | "image" | "code_inline" | "code_block" | "file" | "checkbox" | "bulletList" | "orderedList" | "emoji" | "tabs" | "yfm_cut" | "heading1" | "heading2" | "heading3" | "heading4" | "heading5" | "heading6" | "yfm_note" | "undo" | "redo" | "math_inline" | "math_block" | "mermaid" | "liftListItem" | "sinkListItem" | "yfm_block" | "yfm_layout" | "horizontalrule", string>;
|
|
1
|
+
declare const namesObj: Record<"bold" | "link" | "italic" | "strike" | "underline" | "mark" | "quote" | "mono" | "paragraph" | "anchor" | "table" | "image" | "code_inline" | "code_block" | "file" | "checkbox" | "bulletList" | "orderedList" | "emoji" | "tabs" | "yfm_cut" | "heading1" | "heading2" | "heading3" | "heading4" | "heading5" | "heading6" | "yfm_note" | "undo" | "redo" | "math_inline" | "math_block" | "mermaid" | "liftListItem" | "sinkListItem" | "yfm_block" | "yfm_html_block" | "yfm_layout" | "horizontalrule", string>;
|
|
2
2
|
export declare const ActionName: Readonly<typeof namesObj>;
|
|
3
3
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ToolbarIconData } from '../../toolbar/types';
|
|
2
|
-
declare type Icon = 'undo' | 'redo' | 'bold' | 'italic' | 'underline' | 'strikethrough' | 'mono' | 'mark' | 'textColor' | 'text' | 'headline' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'bulletList' | 'orderedList' | 'sink' | 'lift' | 'cut' | 'note' | 'code' | 'codeBlock' | 'link' | 'image' | 'table' | 'quote' | 'checklist' | 'horizontalRule' | 'file' | 'functionInline' | 'functionBlock' | 'emoji' | 'tabs' | 'mermaid';
|
|
2
|
+
declare type Icon = 'undo' | 'redo' | 'bold' | 'italic' | 'underline' | 'strikethrough' | 'mono' | 'mark' | 'textColor' | 'text' | 'headline' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'bulletList' | 'orderedList' | 'sink' | 'lift' | 'cut' | 'note' | 'code' | 'codeBlock' | 'link' | 'image' | 'table' | 'quote' | 'checklist' | 'horizontalRule' | 'file' | 'functionInline' | 'functionBlock' | 'emoji' | 'tabs' | 'mermaid' | 'html';
|
|
3
3
|
declare type Icons = Record<Icon, ToolbarIconData>;
|
|
4
4
|
export declare const icons: Icons;
|
|
5
5
|
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BoldIcon, CheckListIcon, CodeBlockIcon, CodeInlineIcon, CutIcon, EmojiIcon, FileIcon, FunctionBlockIcon, FunctionInlineIcon, HRuleIcon, Heading1Icon, Heading2Icon, Heading3Icon, Heading4Icon, Heading5Icon, Heading6Icon, HeadingIcon, ImageIcon, ItalicIcon, LiftIcon, LinkIcon, ListBlIcon, ListOlIcon, MarkIcon, MermaidIcon, MonoIcon, NoteIcon, QuoteIcon, RedoIcon, SinkIcon, StrikethroughIcon, TableIcon, TabsIcon, TextColorIcon, TextIcon, UnderlineIcon, UndoIcon, } from '../../icons';
|
|
1
|
+
import { BoldIcon, CheckListIcon, CodeBlockIcon, CodeInlineIcon, CutIcon, EmojiIcon, FileIcon, FunctionBlockIcon, FunctionInlineIcon, HRuleIcon, Heading1Icon, Heading2Icon, Heading3Icon, Heading4Icon, Heading5Icon, Heading6Icon, HeadingIcon, HtmlBlockIcon, ImageIcon, ItalicIcon, LiftIcon, LinkIcon, ListBlIcon, ListOlIcon, MarkIcon, MermaidIcon, MonoIcon, NoteIcon, QuoteIcon, RedoIcon, SinkIcon, StrikethroughIcon, TableIcon, TabsIcon, TextColorIcon, TextIcon, UnderlineIcon, UndoIcon, } from '../../icons';
|
|
2
2
|
export const icons = {
|
|
3
3
|
undo: { data: UndoIcon },
|
|
4
4
|
redo: { data: RedoIcon },
|
|
@@ -30,6 +30,7 @@ export const icons = {
|
|
|
30
30
|
table: { data: TableIcon },
|
|
31
31
|
quote: { data: QuoteIcon },
|
|
32
32
|
checklist: { data: CheckListIcon },
|
|
33
|
+
html: { data: HtmlBlockIcon },
|
|
33
34
|
horizontalRule: { data: HRuleIcon },
|
|
34
35
|
file: { data: FileIcon },
|
|
35
36
|
functionInline: { data: FunctionInlineIcon },
|
|
@@ -35,6 +35,7 @@ export declare const mCodeListConfig: MToolbarListButtonData;
|
|
|
35
35
|
export declare const mMathListConfig: MToolbarListButtonData;
|
|
36
36
|
export declare const mMathListItem: MToolbarListItemData;
|
|
37
37
|
export declare const mMermaidButton: MToolbarSingleItemData;
|
|
38
|
+
export declare const mYfmHtmlBlockButton: MToolbarSingleItemData;
|
|
38
39
|
export declare const mImagePopupData: MToolbarButtonPopupData;
|
|
39
40
|
export declare const mFilePopupData: MToolbarButtonPopupData;
|
|
40
41
|
/** prepared markup toolbar config */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { i18n } from '../../i18n/menubar';
|
|
3
|
-
import { insertHRule, insertLink, insertMermaidDiagram, insertYfmTable, insertYfmTabs, liftListItem, redo, redoDepth, sinkListItem, toBulletList, toH1, toH2, toH3, toH4, toH5, toH6, toOrderedList, toggleBold, toggleItalic, toggleMarked, toggleMonospace, toggleStrikethrough, toggleUnderline, undo, undoDepth, wrapToBlockquote, wrapToCheckbox, wrapToCodeBlock, wrapToInlineCode, wrapToMathBlock, wrapToMathInline, wrapToYfmCut, wrapToYfmNote, } from '../../markup/commands';
|
|
3
|
+
import { insertHRule, insertLink, insertMermaidDiagram, insertYfmHtmlBlock, insertYfmTable, insertYfmTabs, liftListItem, redo, redoDepth, sinkListItem, toBulletList, toH1, toH2, toH3, toH4, toH5, toH6, toOrderedList, toggleBold, toggleItalic, toggleMarked, toggleMonospace, toggleStrikethrough, toggleUnderline, undo, undoDepth, wrapToBlockquote, wrapToCheckbox, wrapToCodeBlock, wrapToInlineCode, wrapToMathBlock, wrapToMathInline, wrapToYfmCut, wrapToYfmNote, } from '../../markup/commands';
|
|
4
4
|
import { Action as A, formatter as f } from '../../shortcuts';
|
|
5
5
|
import { ToolbarDataType, } from '../../toolbar/types';
|
|
6
6
|
import { MToolbarColors } from '../toolbar/markup/MToolbarColors';
|
|
@@ -356,6 +356,15 @@ export const mMermaidButton = {
|
|
|
356
356
|
isActive: isActiveFn,
|
|
357
357
|
isEnable: isEnableFn,
|
|
358
358
|
};
|
|
359
|
+
export const mYfmHtmlBlockButton = {
|
|
360
|
+
id: ActionName.yfm_html_block,
|
|
361
|
+
type: ToolbarDataType.SingleButton,
|
|
362
|
+
title: i18n.bind(null, 'html'),
|
|
363
|
+
icon: icons.html,
|
|
364
|
+
exec: (e) => insertYfmHtmlBlock(e.cm),
|
|
365
|
+
isActive: isActiveFn,
|
|
366
|
+
isEnable: isEnableFn,
|
|
367
|
+
};
|
|
359
368
|
export const mImagePopupData = {
|
|
360
369
|
id: 'image',
|
|
361
370
|
type: ToolbarDataType.ButtonPopup,
|
|
@@ -44,6 +44,7 @@ export declare const wTabsItemData: WToolbarSingleItemData;
|
|
|
44
44
|
export declare const wMathBlockItemData: WToolbarSingleItemData;
|
|
45
45
|
export declare const wMathListConfig: WToolbarListButtonData;
|
|
46
46
|
export declare const wMathListItem: WToolbarListItemData;
|
|
47
|
+
export declare const wYfmHtmlBlockItemData: WToolbarSingleItemData;
|
|
47
48
|
export declare const wCommandMenuConfig: WToolbarItemData[];
|
|
48
49
|
export declare const wHiddenData: WToolbarItemData[];
|
|
49
50
|
/** prepared wysiwyg toolbar config */
|
|
@@ -391,6 +391,15 @@ export const wMathListConfig = {
|
|
|
391
391
|
data: [wMathInlineItemData, wMathBlockItemData],
|
|
392
392
|
};
|
|
393
393
|
export const wMathListItem = Object.assign({ id: 'math', type: ToolbarDataType.ListButton }, wMathListConfig);
|
|
394
|
+
export const wYfmHtmlBlockItemData = {
|
|
395
|
+
id: ActionName.yfm_html_block,
|
|
396
|
+
type: ToolbarDataType.SingleButton,
|
|
397
|
+
title: i18n.bind(null, 'html'),
|
|
398
|
+
icon: icons.html,
|
|
399
|
+
exec: (e) => e.actions.createYfmHtmlBlock.run(),
|
|
400
|
+
isActive: (e) => e.actions.createYfmHtmlBlock.isActive(),
|
|
401
|
+
isEnable: (e) => e.actions.createYfmHtmlBlock.isEnable(),
|
|
402
|
+
};
|
|
394
403
|
export const wCommandMenuConfig = [
|
|
395
404
|
...wHeadingListConfig.data,
|
|
396
405
|
...wListsListConfig.data,
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Node } from 'prosemirror-model';
|
|
2
|
+
import { EditorView, NodeView } from 'prosemirror-view';
|
|
3
|
+
import { YfmHtmlBlockOptions } from '../index';
|
|
4
|
+
export declare class WYfmHtmlBlockNodeView implements NodeView {
|
|
5
|
+
readonly dom: HTMLElement;
|
|
6
|
+
private node;
|
|
7
|
+
private readonly view;
|
|
8
|
+
private readonly getPos;
|
|
9
|
+
private readonly options;
|
|
10
|
+
private readonly renderItem;
|
|
11
|
+
constructor({ node, view, getPos, options, }: {
|
|
12
|
+
node: Node;
|
|
13
|
+
view: EditorView;
|
|
14
|
+
getPos: () => number | undefined;
|
|
15
|
+
options: YfmHtmlBlockOptions;
|
|
16
|
+
});
|
|
17
|
+
update(node: Node): boolean;
|
|
18
|
+
destroy(): void;
|
|
19
|
+
ignoreMutation(): boolean;
|
|
20
|
+
stopEvent(e: Event): boolean;
|
|
21
|
+
private onChange;
|
|
22
|
+
private renderYfmHtmlBlock;
|
|
23
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { createPortal } from 'react-dom';
|
|
3
|
+
import { getReactRendererFromState } from '../../../behavior';
|
|
4
|
+
import { YfmHtmlBlockConsts } from '../YfmHtmlBlockSpecs/const';
|
|
5
|
+
import { YfmHtmlBlockView } from './YfmHtmlBlockView';
|
|
6
|
+
export class WYfmHtmlBlockNodeView {
|
|
7
|
+
constructor({ node, view, getPos, options, }) {
|
|
8
|
+
this.options = {};
|
|
9
|
+
this.node = node;
|
|
10
|
+
this.dom = document.createElement('div');
|
|
11
|
+
this.dom.classList.add('yfm-html-block-container');
|
|
12
|
+
this.dom.contentEditable = 'false';
|
|
13
|
+
this.view = view;
|
|
14
|
+
this.getPos = getPos;
|
|
15
|
+
this.options = options;
|
|
16
|
+
this.renderItem = getReactRendererFromState(view.state).createItem('yfmHtmlBlock-view', this.renderYfmHtmlBlock.bind(this));
|
|
17
|
+
}
|
|
18
|
+
update(node) {
|
|
19
|
+
if (node.type !== this.node.type)
|
|
20
|
+
return false;
|
|
21
|
+
if (node.attrs[YfmHtmlBlockConsts.NodeAttrs.newCreated] !==
|
|
22
|
+
this.node.attrs[YfmHtmlBlockConsts.NodeAttrs.newCreated])
|
|
23
|
+
return false;
|
|
24
|
+
this.node = node;
|
|
25
|
+
this.renderItem.rerender();
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
destroy() {
|
|
29
|
+
this.renderItem.remove();
|
|
30
|
+
}
|
|
31
|
+
ignoreMutation() {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
stopEvent(e) {
|
|
35
|
+
const target = e.target;
|
|
36
|
+
if (typeof target.className === 'string' &&
|
|
37
|
+
target.className.includes('prosemirror-stop-event')) {
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
onChange(attrs) {
|
|
43
|
+
const pos = this.getPos();
|
|
44
|
+
if (pos === undefined)
|
|
45
|
+
return;
|
|
46
|
+
const tr = this.view.state.tr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, this.node.attrs), attrs), []);
|
|
47
|
+
this.view.dispatch(tr);
|
|
48
|
+
}
|
|
49
|
+
renderYfmHtmlBlock() {
|
|
50
|
+
return createPortal(React.createElement(YfmHtmlBlockView, { useConfig: this.options.useConfig, view: this.view, onChange: this.onChange.bind(this), node: this.node, getPos: this.getPos }), this.dom);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
.g-md-yfm-html-block {
|
|
2
|
+
position: relative;
|
|
3
|
+
display: flex;
|
|
4
|
+
justify-content: space-between;
|
|
5
|
+
margin-bottom: 15px;
|
|
6
|
+
padding-top: 28px;
|
|
7
|
+
border: 1px solid var(--g-color-line-generic);
|
|
8
|
+
border-radius: var(--g-border-radius-m);
|
|
9
|
+
}
|
|
10
|
+
.g-md-yfm-html-block_editing {
|
|
11
|
+
display: flex;
|
|
12
|
+
padding-top: 0;
|
|
13
|
+
border: 0;
|
|
14
|
+
}
|
|
15
|
+
.g-md-yfm-html-block__label {
|
|
16
|
+
position: absolute;
|
|
17
|
+
top: 8px;
|
|
18
|
+
left: 8px;
|
|
19
|
+
}
|
|
20
|
+
.g-md-yfm-html-block__menu {
|
|
21
|
+
position: absolute;
|
|
22
|
+
top: 0;
|
|
23
|
+
right: 0;
|
|
24
|
+
}
|
|
25
|
+
.g-md-yfm-html-block__preview {
|
|
26
|
+
flex: 1;
|
|
27
|
+
}
|
|
28
|
+
.g-md-yfm-html-block__error {
|
|
29
|
+
flex: 1;
|
|
30
|
+
font-family: var(--g-font-family-monospace);
|
|
31
|
+
color: var(--g-color-text-danger);
|
|
32
|
+
}
|
|
33
|
+
.g-md-yfm-html-block__editor {
|
|
34
|
+
flex: 1;
|
|
35
|
+
width: 50%;
|
|
36
|
+
white-space: nowrap;
|
|
37
|
+
caret-color: auto;
|
|
38
|
+
}
|
|
39
|
+
.g-md-yfm-html-block__editor .g-text-area__content {
|
|
40
|
+
font-size: 1em;
|
|
41
|
+
color: var(--yfm-color-hljs-subst);
|
|
42
|
+
border: 0;
|
|
43
|
+
border-radius: var(--g-border-radius-m);
|
|
44
|
+
background: var(--yfm-color-hljs-background);
|
|
45
|
+
font-feature-settings: normal;
|
|
46
|
+
}
|
|
47
|
+
.g-md-yfm-html-block__editor .g-text-area__control.g-md-YfmHtmlBlockHelper {
|
|
48
|
+
font-family: var(--yfm-font-family-monospace);
|
|
49
|
+
}
|
|
50
|
+
.g-md-yfm-html-block__editor-popover {
|
|
51
|
+
z-index: 1;
|
|
52
|
+
float: right;
|
|
53
|
+
}
|
|
54
|
+
.g-md-yfm-html-block__controls {
|
|
55
|
+
display: flex;
|
|
56
|
+
justify-content: end;
|
|
57
|
+
margin-top: 5px;
|
|
58
|
+
}
|
|
59
|
+
.g-md-yfm-html-block__content {
|
|
60
|
+
flex-grow: 1;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.g-root_theme_dark-hc .g-md-yfm-html-block_editing .g-text-area__content,
|
|
64
|
+
.g-root_theme_dark .g-md-yfm-html-block_editing .g-text-area__content {
|
|
65
|
+
color: var(--g-color-text-primary);
|
|
66
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { IHTMLIFrameElementConfig } from '@diplodoc/html-extension/runtime';
|
|
3
|
+
import { Node } from 'prosemirror-model';
|
|
4
|
+
import { EditorView } from 'prosemirror-view';
|
|
5
|
+
import { YfmHtmlBlockConsts } from '../YfmHtmlBlockSpecs/const';
|
|
6
|
+
export declare const cnYfmHtmlBlock: import("@bem-react/classname").ClassNameFormatter;
|
|
7
|
+
export declare const cnHelper: import("@bem-react/classname").ClassNameFormatter;
|
|
8
|
+
import './YfmHtmlBlock.css';
|
|
9
|
+
export declare function generateID(): string;
|
|
10
|
+
export declare const YfmHtmlBlockView: React.FC<{
|
|
11
|
+
view: EditorView;
|
|
12
|
+
onChange: (attrs: {
|
|
13
|
+
[YfmHtmlBlockConsts.NodeAttrs.srcdoc]: string;
|
|
14
|
+
}) => void;
|
|
15
|
+
node: Node;
|
|
16
|
+
getPos: () => number | undefined;
|
|
17
|
+
useConfig?: () => IHTMLIFrameElementConfig | undefined;
|
|
18
|
+
}>;
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import React, { useEffect, useRef, useState } from 'react';
|
|
2
|
+
import { Ellipsis as DotsIcon, Eye } from '@gravity-ui/icons';
|
|
3
|
+
import { Button, Icon, Label, Menu, Popup } from '@gravity-ui/uikit';
|
|
4
|
+
import debounce from 'lodash/debounce';
|
|
5
|
+
import { cn } from '../../../../classname';
|
|
6
|
+
import { TextAreaFixed as TextArea } from '../../../../forms/TextInput';
|
|
7
|
+
import { i18n } from '../../../../i18n/common';
|
|
8
|
+
import { useBooleanState } from '../../../../react-utils/hooks';
|
|
9
|
+
import { removeNode } from '../../../../utils/remove-node';
|
|
10
|
+
import { YfmHtmlBlockConsts } from '../YfmHtmlBlockSpecs/const';
|
|
11
|
+
export const cnYfmHtmlBlock = cn('yfm-html-block');
|
|
12
|
+
export const cnHelper = cn('yfm-html-block-helper');
|
|
13
|
+
import './YfmHtmlBlock.css';
|
|
14
|
+
const b = cnYfmHtmlBlock;
|
|
15
|
+
export function generateID() {
|
|
16
|
+
return Math.random().toString(36).substr(2, 8);
|
|
17
|
+
}
|
|
18
|
+
const DEFAULT_PADDING = 20;
|
|
19
|
+
const DEFAULT_DELAY = 100;
|
|
20
|
+
const YfmHtmlBlockPreview = ({ html, onСlick, config }) => {
|
|
21
|
+
var _a, _b, _c, _d, _e, _f;
|
|
22
|
+
const ref = useRef(null);
|
|
23
|
+
const styles = useRef({});
|
|
24
|
+
const classNames = useRef([]);
|
|
25
|
+
const resizeConfig = useRef({});
|
|
26
|
+
const [height, setHeight] = useState('100%');
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
var _a, _b;
|
|
29
|
+
resizeConfig.current = {
|
|
30
|
+
padding: (_a = config === null || config === void 0 ? void 0 : config.resizePadding) !== null && _a !== void 0 ? _a : DEFAULT_PADDING,
|
|
31
|
+
delay: (_b = config === null || config === void 0 ? void 0 : config.resizeDelay) !== null && _b !== void 0 ? _b : DEFAULT_DELAY,
|
|
32
|
+
};
|
|
33
|
+
setStyles(config === null || config === void 0 ? void 0 : config.styles);
|
|
34
|
+
setClassNames(config === null || config === void 0 ? void 0 : config.classNames);
|
|
35
|
+
}, [config, (_c = (_b = (_a = ref.current) === null || _a === void 0 ? void 0 : _a.contentWindow) === null || _b === void 0 ? void 0 : _b.document) === null || _c === void 0 ? void 0 : _c.body]);
|
|
36
|
+
const handleLoadIFrame = () => {
|
|
37
|
+
var _a;
|
|
38
|
+
const contentWindow = (_a = ref.current) === null || _a === void 0 ? void 0 : _a.contentWindow;
|
|
39
|
+
handleResizeIFrame();
|
|
40
|
+
if (contentWindow) {
|
|
41
|
+
const frameDocument = contentWindow.document;
|
|
42
|
+
frameDocument.addEventListener('dblclick', () => {
|
|
43
|
+
onСlick();
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const handleResizeIFrame = () => {
|
|
48
|
+
var _a, _b;
|
|
49
|
+
if (ref.current) {
|
|
50
|
+
const contentWindow = (_a = ref.current) === null || _a === void 0 ? void 0 : _a.contentWindow;
|
|
51
|
+
if (contentWindow) {
|
|
52
|
+
const body = contentWindow.document.body;
|
|
53
|
+
if (body) {
|
|
54
|
+
const height = body.scrollHeight +
|
|
55
|
+
(((_b = resizeConfig.current) === null || _b === void 0 ? void 0 : _b.padding) || DEFAULT_PADDING) +
|
|
56
|
+
'px';
|
|
57
|
+
setHeight(height);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
const setClassNames = (newClassNames) => {
|
|
63
|
+
var _a, _b;
|
|
64
|
+
const body = (_b = (_a = ref.current) === null || _a === void 0 ? void 0 : _a.contentWindow) === null || _b === void 0 ? void 0 : _b.document.body;
|
|
65
|
+
if (body && newClassNames) {
|
|
66
|
+
const previousClassNames = classNames.current;
|
|
67
|
+
// remove all classes that were in previousClassNames but are not in classNames
|
|
68
|
+
previousClassNames.forEach((className) => {
|
|
69
|
+
if (!newClassNames.includes(className)) {
|
|
70
|
+
body.classList.remove(className);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
// add classes that are in classNames
|
|
74
|
+
newClassNames.forEach((className) => {
|
|
75
|
+
if (!body.classList.contains(className)) {
|
|
76
|
+
body.classList.add(className);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
classNames.current = newClassNames;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
const setStyles = (newStyles) => {
|
|
83
|
+
var _a, _b;
|
|
84
|
+
const body = (_b = (_a = ref.current) === null || _a === void 0 ? void 0 : _a.contentWindow) === null || _b === void 0 ? void 0 : _b.document.body;
|
|
85
|
+
if (body && newStyles) {
|
|
86
|
+
const previousStyles = styles.current;
|
|
87
|
+
// remove all styles that are in previousStyles but not in styles
|
|
88
|
+
Object.keys(previousStyles).forEach((property) => {
|
|
89
|
+
if (!Object.prototype.hasOwnProperty.call(newStyles, property)) {
|
|
90
|
+
body.style.removeProperty(property);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
// sdd or update styles that are in styles
|
|
94
|
+
Object.keys(newStyles).forEach((property) => {
|
|
95
|
+
body.style.setProperty(property, newStyles[property]);
|
|
96
|
+
});
|
|
97
|
+
// update current styles to the new styles
|
|
98
|
+
styles.current = newStyles;
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
useEffect(() => {
|
|
102
|
+
var _a;
|
|
103
|
+
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.addEventListener('load', handleLoadIFrame);
|
|
104
|
+
return () => {
|
|
105
|
+
var _a;
|
|
106
|
+
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.removeEventListener('load', handleLoadIFrame);
|
|
107
|
+
};
|
|
108
|
+
}, [html]);
|
|
109
|
+
useEffect(() => {
|
|
110
|
+
var _a, _b;
|
|
111
|
+
if (ref.current) {
|
|
112
|
+
const resizeObserver = new window.ResizeObserver(debounce(handleResizeIFrame, (_b = (_a = resizeConfig.current) === null || _a === void 0 ? void 0 : _a.delay) !== null && _b !== void 0 ? _b : DEFAULT_DELAY));
|
|
113
|
+
resizeObserver.observe(ref.current);
|
|
114
|
+
}
|
|
115
|
+
}, [(_f = (_e = (_d = ref.current) === null || _d === void 0 ? void 0 : _d.contentWindow) === null || _e === void 0 ? void 0 : _e.document) === null || _f === void 0 ? void 0 : _f.body]);
|
|
116
|
+
return (React.createElement("iframe", { style: {
|
|
117
|
+
height,
|
|
118
|
+
}, ref: ref, title: generateID(), frameBorder: 0, className: b('content'), srcDoc: html }));
|
|
119
|
+
};
|
|
120
|
+
const CodeEditMode = ({ initialText, onSave, onCancel }) => {
|
|
121
|
+
const [text, setText] = useState(initialText || '\n');
|
|
122
|
+
return (React.createElement("div", { className: b({ editing: true }) },
|
|
123
|
+
React.createElement("div", { className: b('editor') },
|
|
124
|
+
React.createElement(TextArea, { controlProps: {
|
|
125
|
+
className: cnHelper({ 'prosemirror-stop-event': true }),
|
|
126
|
+
}, value: text, onUpdate: (v) => {
|
|
127
|
+
setText(v);
|
|
128
|
+
}, autoFocus: true }),
|
|
129
|
+
React.createElement("div", { className: b('controls') },
|
|
130
|
+
React.createElement("div", null,
|
|
131
|
+
React.createElement(Button, { onClick: onCancel, view: 'flat' },
|
|
132
|
+
React.createElement("span", { className: cnHelper({ 'prosemirror-stop-event': true }) }, i18n('cancel'))),
|
|
133
|
+
React.createElement(Button, { onClick: () => onSave(text), view: 'action' },
|
|
134
|
+
React.createElement("span", { className: cnHelper({ 'prosemirror-stop-event': true }) }, i18n('save'))))))));
|
|
135
|
+
};
|
|
136
|
+
export const YfmHtmlBlockView = ({ onChange, node, getPos, view, useConfig }) => {
|
|
137
|
+
const [editing, setEditing, unsetEditing, toggleEditing] = useBooleanState(Boolean(node.attrs[YfmHtmlBlockConsts.NodeAttrs.newCreated]));
|
|
138
|
+
const config = useConfig === null || useConfig === void 0 ? void 0 : useConfig();
|
|
139
|
+
const [menuOpen, , , toggleMenuOpen] = useBooleanState(false);
|
|
140
|
+
const buttonRef = useRef(null);
|
|
141
|
+
const handleClick = () => {
|
|
142
|
+
setEditing();
|
|
143
|
+
};
|
|
144
|
+
if (editing) {
|
|
145
|
+
return (React.createElement(CodeEditMode, { initialText: node.attrs[YfmHtmlBlockConsts.NodeAttrs.srcdoc], onCancel: unsetEditing, onSave: (v) => {
|
|
146
|
+
onChange({ [YfmHtmlBlockConsts.NodeAttrs.srcdoc]: v });
|
|
147
|
+
unsetEditing();
|
|
148
|
+
} }));
|
|
149
|
+
}
|
|
150
|
+
return (React.createElement("div", { className: b(), onDoubleClick: setEditing },
|
|
151
|
+
React.createElement(Label, { className: b('label'), icon: React.createElement(Icon, { size: 16, data: Eye }) }, i18n('preview')),
|
|
152
|
+
React.createElement(YfmHtmlBlockPreview, { html: node.attrs[YfmHtmlBlockConsts.NodeAttrs.srcdoc], "on\u0421lick": handleClick, config: config }),
|
|
153
|
+
React.createElement("div", { className: b('menu') },
|
|
154
|
+
React.createElement(Button, { onClick: toggleMenuOpen, ref: buttonRef, size: 's', className: cnHelper({ 'prosemirror-stop-event': true }) },
|
|
155
|
+
React.createElement(Icon, { data: DotsIcon, className: cnHelper({ 'prosemirror-stop-event': true }) })),
|
|
156
|
+
React.createElement(Popup, { anchorRef: buttonRef, open: menuOpen, onClose: toggleMenuOpen, placement: ['bottom-end'] },
|
|
157
|
+
React.createElement(Menu, null,
|
|
158
|
+
React.createElement(Menu.Item, { onClick: () => {
|
|
159
|
+
toggleEditing();
|
|
160
|
+
toggleMenuOpen();
|
|
161
|
+
} }, i18n('edit')),
|
|
162
|
+
React.createElement(Menu.Item, { onClick: () => {
|
|
163
|
+
const pos = getPos();
|
|
164
|
+
if (pos === undefined)
|
|
165
|
+
return;
|
|
166
|
+
removeNode({
|
|
167
|
+
node,
|
|
168
|
+
pos,
|
|
169
|
+
tr: view.state.tr,
|
|
170
|
+
dispatch: view.dispatch,
|
|
171
|
+
});
|
|
172
|
+
} }, i18n('remove')))))));
|
|
173
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './NodeView';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './NodeView';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare enum YfmHtmlBlockAttrs {
|
|
2
|
+
class = "class",
|
|
3
|
+
frameborder = "frameborder",
|
|
4
|
+
newCreated = "newCreated",
|
|
5
|
+
srcdoc = "srcdoc",
|
|
6
|
+
style = "style"
|
|
7
|
+
}
|
|
8
|
+
export declare const yfmHtmlBlockNodeName = "yfm_html_block";
|
|
9
|
+
export declare const yfmHtmlBlockNodeType: (schema: import("prosemirror-model").Schema<any, any>) => import("prosemirror-model").NodeType;
|
|
10
|
+
export declare const YfmHtmlBlockAction = "createYfmHtmlBlock";
|
|
11
|
+
export declare const YfmHtmlBlockConsts: {
|
|
12
|
+
readonly NodeName: "yfm_html_block";
|
|
13
|
+
readonly NodeAttrs: typeof YfmHtmlBlockAttrs;
|
|
14
|
+
readonly nodeType: (schema: import("prosemirror-model").Schema<any, any>) => import("prosemirror-model").NodeType;
|
|
15
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { nodeTypeFactory } from '../../../../utils/schema';
|
|
2
|
+
export var YfmHtmlBlockAttrs;
|
|
3
|
+
(function (YfmHtmlBlockAttrs) {
|
|
4
|
+
YfmHtmlBlockAttrs["class"] = "class";
|
|
5
|
+
YfmHtmlBlockAttrs["frameborder"] = "frameborder";
|
|
6
|
+
YfmHtmlBlockAttrs["newCreated"] = "newCreated";
|
|
7
|
+
YfmHtmlBlockAttrs["srcdoc"] = "srcdoc";
|
|
8
|
+
YfmHtmlBlockAttrs["style"] = "style";
|
|
9
|
+
})(YfmHtmlBlockAttrs || (YfmHtmlBlockAttrs = {}));
|
|
10
|
+
export const yfmHtmlBlockNodeName = 'yfm_html_block';
|
|
11
|
+
export const yfmHtmlBlockNodeType = nodeTypeFactory(yfmHtmlBlockNodeName);
|
|
12
|
+
export const YfmHtmlBlockAction = 'createYfmHtmlBlock';
|
|
13
|
+
export const YfmHtmlBlockConsts = {
|
|
14
|
+
NodeName: yfmHtmlBlockNodeName,
|
|
15
|
+
NodeAttrs: YfmHtmlBlockAttrs,
|
|
16
|
+
nodeType: yfmHtmlBlockNodeType,
|
|
17
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ExtensionNodeSpec } from '../../../../core';
|
|
2
|
+
export { yfmHtmlBlockNodeName } from './const';
|
|
3
|
+
export declare type YfmHtmlBlockSpecsOptions = {
|
|
4
|
+
nodeView?: ExtensionNodeSpec['view'];
|
|
5
|
+
};
|
|
6
|
+
export declare const YfmHtmlBlockSpecs: import("../../../../core").ExtensionWithOptions<YfmHtmlBlockSpecsOptions> & {
|
|
7
|
+
readonly NodeName: "yfm_html_block";
|
|
8
|
+
readonly NodeAttrs: typeof import("./const").YfmHtmlBlockAttrs;
|
|
9
|
+
readonly nodeType: (schema: import("prosemirror-model").Schema<any, any>) => import("prosemirror-model").NodeType;
|
|
10
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
2
|
+
import { transform } from '@diplodoc/html-extension';
|
|
3
|
+
import { YfmHtmlBlockConsts } from './const';
|
|
4
|
+
export { yfmHtmlBlockNodeName } from './const';
|
|
5
|
+
const YfmHtmlBlockSpecsExtension = (builder, { nodeView }) => {
|
|
6
|
+
builder
|
|
7
|
+
.configureMd((md) => md.use(transform({ bundle: false }), {}))
|
|
8
|
+
.addNode(YfmHtmlBlockConsts.NodeName, () => ({
|
|
9
|
+
fromMd: {
|
|
10
|
+
tokenSpec: {
|
|
11
|
+
name: YfmHtmlBlockConsts.NodeName,
|
|
12
|
+
type: 'node',
|
|
13
|
+
noCloseToken: true,
|
|
14
|
+
getAttrs: (token) => { var _a; return Object.fromEntries((_a = token.attrs) !== null && _a !== void 0 ? _a : []); },
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
spec: {
|
|
18
|
+
group: 'block',
|
|
19
|
+
attrs: {
|
|
20
|
+
[YfmHtmlBlockConsts.NodeAttrs.class]: { default: 'yfm-html' },
|
|
21
|
+
[YfmHtmlBlockConsts.NodeAttrs.frameborder]: { default: '' },
|
|
22
|
+
[YfmHtmlBlockConsts.NodeAttrs.srcdoc]: { default: '' },
|
|
23
|
+
[YfmHtmlBlockConsts.NodeAttrs.style]: { default: null },
|
|
24
|
+
[YfmHtmlBlockConsts.NodeAttrs.newCreated]: { default: null },
|
|
25
|
+
},
|
|
26
|
+
toDOM: (node) => ['iframe', node.attrs],
|
|
27
|
+
},
|
|
28
|
+
toMd: (state, node) => {
|
|
29
|
+
state.write('::: html');
|
|
30
|
+
state.write('\n');
|
|
31
|
+
state.write(node.attrs[YfmHtmlBlockConsts.NodeAttrs.srcdoc]);
|
|
32
|
+
state.ensureNewLine();
|
|
33
|
+
state.write(':::');
|
|
34
|
+
state.closeBlock(node);
|
|
35
|
+
},
|
|
36
|
+
view: nodeView,
|
|
37
|
+
}));
|
|
38
|
+
};
|
|
39
|
+
export const YfmHtmlBlockSpecs = Object.assign(YfmHtmlBlockSpecsExtension, YfmHtmlBlockConsts);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { YfmHtmlBlockConsts, yfmHtmlBlockNodeType } from './YfmHtmlBlockSpecs/const';
|
|
2
|
+
export const addYfmHtmlBlock = {
|
|
3
|
+
isEnable(state) {
|
|
4
|
+
return state.selection.empty;
|
|
5
|
+
},
|
|
6
|
+
run(state, dispatch, _view) {
|
|
7
|
+
dispatch(state.tr.insert(state.selection.from, yfmHtmlBlockNodeType(state.schema).create({
|
|
8
|
+
[YfmHtmlBlockConsts.NodeAttrs.srcdoc]: '\n',
|
|
9
|
+
[YfmHtmlBlockConsts.NodeAttrs.newCreated]: true,
|
|
10
|
+
})));
|
|
11
|
+
},
|
|
12
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { IHTMLIFrameElementConfig } from '@diplodoc/html-extension/runtime';
|
|
2
|
+
import { Action, ExtensionAuto } from '../../../core';
|
|
3
|
+
import { YfmHtmlBlockAction } from './YfmHtmlBlockSpecs/const';
|
|
4
|
+
export declare type YfmHtmlBlockOptions = {
|
|
5
|
+
useConfig?: () => IHTMLIFrameElementConfig | undefined;
|
|
6
|
+
};
|
|
7
|
+
export declare const YfmHtmlBlock: ExtensionAuto<YfmHtmlBlockOptions>;
|
|
8
|
+
declare global {
|
|
9
|
+
namespace WysiwygEditor {
|
|
10
|
+
interface Actions {
|
|
11
|
+
[YfmHtmlBlockAction]: Action;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { WYfmHtmlBlockNodeView } from './YfmHtmlBlockNodeView';
|
|
2
|
+
import { YfmHtmlBlockSpecs } from './YfmHtmlBlockSpecs';
|
|
3
|
+
import { YfmHtmlBlockAction } from './YfmHtmlBlockSpecs/const';
|
|
4
|
+
import { addYfmHtmlBlock } from './actions';
|
|
5
|
+
export const YfmHtmlBlock = (builder, options) => {
|
|
6
|
+
builder.use(YfmHtmlBlockSpecs, {
|
|
7
|
+
nodeView: YfmHtmlBlockNodeViewFactory(options),
|
|
8
|
+
});
|
|
9
|
+
builder.addAction(YfmHtmlBlockAction, () => addYfmHtmlBlock);
|
|
10
|
+
};
|
|
11
|
+
const YfmHtmlBlockNodeViewFactory = (options) => () => (node, view, getPos) => {
|
|
12
|
+
return new WYfmHtmlBlockNodeView({ node, view, getPos, options });
|
|
13
|
+
};
|
|
@@ -4,8 +4,8 @@ export * from './Emoji';
|
|
|
4
4
|
export * from './ImgSize';
|
|
5
5
|
export * from './Monospace';
|
|
6
6
|
export * from './Video';
|
|
7
|
-
export * from './YfmCut';
|
|
8
7
|
export * from './YfmConfigs';
|
|
8
|
+
export * from './YfmCut';
|
|
9
9
|
export * from './YfmFile';
|
|
10
10
|
export * from './YfmHeading';
|
|
11
11
|
export * from './YfmNote';
|
|
@@ -4,8 +4,8 @@ export * from './Emoji';
|
|
|
4
4
|
export * from './ImgSize';
|
|
5
5
|
export * from './Monospace';
|
|
6
6
|
export * from './Video';
|
|
7
|
-
export * from './YfmCut';
|
|
8
7
|
export * from './YfmConfigs';
|
|
8
|
+
export * from './YfmCut';
|
|
9
9
|
export * from './YfmFile';
|
|
10
10
|
export * from './YfmHeading';
|
|
11
11
|
export * from './YfmNote';
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
2
|
+
"cancel": "Cancel",
|
|
3
|
+
"delete": "Delete",
|
|
3
4
|
"edit": "Edit",
|
|
4
|
-
"
|
|
5
|
+
"preview": "Preview",
|
|
6
|
+
"remove": "Remove",
|
|
7
|
+
"save": "Save",
|
|
8
|
+
"toolbar_action_disabled": "Incompatible markup element"
|
|
5
9
|
}
|