@gravity-ui/markdown-editor 13.12.0 → 13.13.0

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.
@@ -59,6 +59,10 @@ export declare type MarkupConfig = {
59
59
  */
60
60
  languageData?: YfmLangOptions['languageData'];
61
61
  };
62
+ export declare type EscapeConfig = {
63
+ commonEscape?: RegExp;
64
+ startOfLineEscape?: RegExp;
65
+ };
62
66
  export declare type EditorOptions = Pick<WysiwygEditorOptions, 'allowHTML' | 'linkify' | 'linkifyTlds' | 'extensions'> & {
63
67
  initialMarkup?: MarkupString;
64
68
  /** @default 'wysiwyg' */
@@ -88,5 +92,6 @@ export declare type EditorOptions = Pick<WysiwygEditorOptions, 'allowHTML' | 'li
88
92
  /** @deprecated Put extra extensions via MarkdownEditorMarkupConfig */
89
93
  extraMarkupExtensions?: CodemirrorExtension[];
90
94
  markupConfig?: MarkupConfig;
95
+ escapeConfig?: EscapeConfig;
91
96
  };
92
97
  export {};
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- var _EditorImpl_markup, _EditorImpl_editorMode, _EditorImpl_toolbarVisible, _EditorImpl_splitModeEnabled, _EditorImpl_splitMode, _EditorImpl_renderPreview, _EditorImpl_wysiwygEditor, _EditorImpl_markupEditor, _EditorImpl_markupConfig, _EditorImpl_preset, _EditorImpl_allowHTML, _EditorImpl_linkify, _EditorImpl_linkifyTlds, _EditorImpl_extensions, _EditorImpl_renderStorage, _EditorImpl_fileUploadHandler, _EditorImpl_needToSetDimensionsForUploadedImages, _EditorImpl_prepareRawMarkup;
2
+ var _EditorImpl_markup, _EditorImpl_editorMode, _EditorImpl_toolbarVisible, _EditorImpl_splitModeEnabled, _EditorImpl_splitMode, _EditorImpl_renderPreview, _EditorImpl_wysiwygEditor, _EditorImpl_markupEditor, _EditorImpl_markupConfig, _EditorImpl_escapeConfig, _EditorImpl_preset, _EditorImpl_allowHTML, _EditorImpl_linkify, _EditorImpl_linkifyTlds, _EditorImpl_extensions, _EditorImpl_renderStorage, _EditorImpl_fileUploadHandler, _EditorImpl_needToSetDimensionsForUploadedImages, _EditorImpl_prepareRawMarkup;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.EditorImpl = void 0;
5
5
  const tslib_1 = require("tslib");
@@ -25,6 +25,7 @@ class EditorImpl extends event_emitter_1.SafeEventEmitter {
25
25
  _EditorImpl_wysiwygEditor.set(this, void 0);
26
26
  _EditorImpl_markupEditor.set(this, void 0);
27
27
  _EditorImpl_markupConfig.set(this, void 0);
28
+ _EditorImpl_escapeConfig.set(this, void 0);
28
29
  _EditorImpl_preset.set(this, void 0);
29
30
  _EditorImpl_allowHTML.set(this, void 0);
30
31
  _EditorImpl_linkify.set(this, void 0);
@@ -52,6 +53,7 @@ class EditorImpl extends event_emitter_1.SafeEventEmitter {
52
53
  tslib_1.__classPrivateFieldSet(this, _EditorImpl_fileUploadHandler, opts.fileUploadHandler, "f");
53
54
  tslib_1.__classPrivateFieldSet(this, _EditorImpl_needToSetDimensionsForUploadedImages, Boolean(opts.needToSetDimensionsForUploadedImages), "f");
54
55
  tslib_1.__classPrivateFieldSet(this, _EditorImpl_prepareRawMarkup, opts.prepareRawMarkup, "f");
56
+ tslib_1.__classPrivateFieldSet(this, _EditorImpl_escapeConfig, opts.escapeConfig, "f");
55
57
  }
56
58
  get _wysiwygView() {
57
59
  var _a;
@@ -137,6 +139,7 @@ class EditorImpl extends event_emitter_1.SafeEventEmitter {
137
139
  allowHTML: tslib_1.__classPrivateFieldGet(this, _EditorImpl_allowHTML, "f"),
138
140
  linkify: tslib_1.__classPrivateFieldGet(this, _EditorImpl_linkify, "f"),
139
141
  linkifyTlds: tslib_1.__classPrivateFieldGet(this, _EditorImpl_linkifyTlds, "f"),
142
+ escapeConfig: tslib_1.__classPrivateFieldGet(this, _EditorImpl_escapeConfig, "f"),
140
143
  onChange: () => this.emit('rerender-toolbar', null),
141
144
  onDocChange: () => this.emit('change', null),
142
145
  }), "f");
@@ -276,9 +279,9 @@ class EditorImpl extends event_emitter_1.SafeEventEmitter {
276
279
  }
277
280
  shouldReplaceMarkupEditorValue(markupValue, wysiwygValue) {
278
281
  var _a;
279
- const serializedEditorMarkup = (_a = tslib_1.__classPrivateFieldGet(this, _EditorImpl_wysiwygEditor, "f")) === null || _a === void 0 ? void 0 : _a.serializer.serialize(tslib_1.__classPrivateFieldGet(this, _EditorImpl_wysiwygEditor, "f").parser.parse(markupValue));
282
+ const serializedEditorMarkup = (_a = tslib_1.__classPrivateFieldGet(this, _EditorImpl_wysiwygEditor, "f")) === null || _a === void 0 ? void 0 : _a.serializer.serialize(tslib_1.__classPrivateFieldGet(this, _EditorImpl_wysiwygEditor, "f").parser.parse(markupValue), tslib_1.__classPrivateFieldGet(this, _EditorImpl_escapeConfig, "f"));
280
283
  return (serializedEditorMarkup === null || serializedEditorMarkup === void 0 ? void 0 : serializedEditorMarkup.trim()) !== wysiwygValue.trim();
281
284
  }
282
285
  }
283
286
  exports.EditorImpl = EditorImpl;
284
- _EditorImpl_markup = new WeakMap(), _EditorImpl_editorMode = new WeakMap(), _EditorImpl_toolbarVisible = new WeakMap(), _EditorImpl_splitModeEnabled = new WeakMap(), _EditorImpl_splitMode = new WeakMap(), _EditorImpl_renderPreview = new WeakMap(), _EditorImpl_wysiwygEditor = new WeakMap(), _EditorImpl_markupEditor = new WeakMap(), _EditorImpl_markupConfig = new WeakMap(), _EditorImpl_preset = new WeakMap(), _EditorImpl_allowHTML = new WeakMap(), _EditorImpl_linkify = new WeakMap(), _EditorImpl_linkifyTlds = new WeakMap(), _EditorImpl_extensions = new WeakMap(), _EditorImpl_renderStorage = new WeakMap(), _EditorImpl_fileUploadHandler = new WeakMap(), _EditorImpl_needToSetDimensionsForUploadedImages = new WeakMap(), _EditorImpl_prepareRawMarkup = new WeakMap();
287
+ _EditorImpl_markup = new WeakMap(), _EditorImpl_editorMode = new WeakMap(), _EditorImpl_toolbarVisible = new WeakMap(), _EditorImpl_splitModeEnabled = new WeakMap(), _EditorImpl_splitMode = new WeakMap(), _EditorImpl_renderPreview = new WeakMap(), _EditorImpl_wysiwygEditor = new WeakMap(), _EditorImpl_markupEditor = new WeakMap(), _EditorImpl_markupConfig = new WeakMap(), _EditorImpl_escapeConfig = new WeakMap(), _EditorImpl_preset = new WeakMap(), _EditorImpl_allowHTML = new WeakMap(), _EditorImpl_linkify = new WeakMap(), _EditorImpl_linkifyTlds = new WeakMap(), _EditorImpl_extensions = new WeakMap(), _EditorImpl_renderStorage = new WeakMap(), _EditorImpl_fileUploadHandler = new WeakMap(), _EditorImpl_needToSetDimensionsForUploadedImages = new WeakMap(), _EditorImpl_prepareRawMarkup = new WeakMap();
@@ -5,6 +5,10 @@ import type { Extension } from './types/extension';
5
5
  import type { Parser } from './types/parser';
6
6
  import type { Serializer } from './types/serializer';
7
7
  declare type OnChange = (editor: WysiwygEditor) => void;
8
+ declare type EscapeConfig = {
9
+ commonEscape?: RegExp;
10
+ startOfLineEscape?: RegExp;
11
+ };
8
12
  export declare type WysiwygEditorOptions = {
9
13
  domElem?: Element;
10
14
  /** markdown markup */
@@ -15,6 +19,7 @@ export declare type WysiwygEditorOptions = {
15
19
  allowHTML?: boolean;
16
20
  linkify?: boolean;
17
21
  linkifyTlds?: string | string[];
22
+ escapeConfig?: EscapeConfig;
18
23
  /** Call on any state change (move cursor, change selection, etc...) */
19
24
  onChange?: OnChange;
20
25
  /** Call only if document change */
@@ -26,7 +31,7 @@ export declare class WysiwygEditor implements CommonEditor, ActionStorage {
26
31
  get serializer(): Serializer;
27
32
  get parser(): Parser;
28
33
  get actions(): WysiwygEditor.Actions;
29
- constructor({ domElem, initialContent, extensions, allowHTML, mdPreset, linkify, linkifyTlds, onChange, onDocChange, }: WysiwygEditorOptions);
34
+ constructor({ domElem, initialContent, extensions, allowHTML, mdPreset, linkify, linkifyTlds, escapeConfig, onChange, onDocChange, }: WysiwygEditorOptions);
30
35
  action<T extends keyof WysiwygEditor.Actions>(actionName: T): WysiwygEditor.Actions[T];
31
36
  focus(): void;
32
37
  hasFocus(): boolean;
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- var _WysiwygEditor_view, _WysiwygEditor_serializer, _WysiwygEditor_parser, _WysiwygEditor_actions, _WysiwygEditor_contentHandler;
2
+ var _WysiwygEditor_view, _WysiwygEditor_serializer, _WysiwygEditor_parser, _WysiwygEditor_actions, _WysiwygEditor_contentHandler, _WysiwygEditor_escapeConfig;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.WysiwygEditor = void 0;
5
5
  const tslib_1 = require("tslib");
@@ -10,12 +10,13 @@ const ExtensionsManager_1 = require("./ExtensionsManager");
10
10
  const actions_1 = require("./utils/actions");
11
11
  const metrics_1 = require("./utils/metrics");
12
12
  class WysiwygEditor {
13
- constructor({ domElem, initialContent = '', extensions = () => { }, allowHTML, mdPreset, linkify, linkifyTlds, onChange, onDocChange, }) {
13
+ constructor({ domElem, initialContent = '', extensions = () => { }, allowHTML, mdPreset, linkify, linkifyTlds, escapeConfig, onChange, onDocChange, }) {
14
14
  _WysiwygEditor_view.set(this, void 0);
15
15
  _WysiwygEditor_serializer.set(this, void 0);
16
16
  _WysiwygEditor_parser.set(this, void 0);
17
17
  _WysiwygEditor_actions.set(this, void 0);
18
18
  _WysiwygEditor_contentHandler.set(this, void 0);
19
+ _WysiwygEditor_escapeConfig.set(this, void 0);
19
20
  const { schema, markupParser: parser, serializer, nodeViews, markViews, plugins, rawActions, actions, } = ExtensionsManager_1.ExtensionsManager.process(extensions, {
20
21
  // "breaks" option only affects the renderer, but not the parser
21
22
  mdOpts: { html: allowHTML, linkify, breaks: true, preset: mdPreset },
@@ -47,6 +48,7 @@ class WysiwygEditor {
47
48
  tslib_1.__classPrivateFieldSet(this, _WysiwygEditor_serializer, serializer, "f");
48
49
  tslib_1.__classPrivateFieldSet(this, _WysiwygEditor_parser, parser, "f");
49
50
  tslib_1.__classPrivateFieldSet(this, _WysiwygEditor_contentHandler, new ContentHandler_1.WysiwygContentHandler(tslib_1.__classPrivateFieldGet(this, _WysiwygEditor_view, "f"), parser), "f");
51
+ tslib_1.__classPrivateFieldSet(this, _WysiwygEditor_escapeConfig, escapeConfig, "f");
50
52
  }
51
53
  get dom() {
52
54
  return tslib_1.__classPrivateFieldGet(this, _WysiwygEditor_view, "f").dom;
@@ -74,7 +76,7 @@ class WysiwygEditor {
74
76
  return tslib_1.__classPrivateFieldGet(this, _WysiwygEditor_view, "f").hasFocus();
75
77
  }
76
78
  getValue() {
77
- return tslib_1.__classPrivateFieldGet(this, _WysiwygEditor_serializer, "f").serialize(tslib_1.__classPrivateFieldGet(this, _WysiwygEditor_view, "f").state.doc);
79
+ return tslib_1.__classPrivateFieldGet(this, _WysiwygEditor_serializer, "f").serialize(tslib_1.__classPrivateFieldGet(this, _WysiwygEditor_view, "f").state.doc, tslib_1.__classPrivateFieldGet(this, _WysiwygEditor_escapeConfig, "f"));
78
80
  }
79
81
  isEmpty() {
80
82
  var _a;
@@ -113,4 +115,4 @@ class WysiwygEditor {
113
115
  }
114
116
  }
115
117
  exports.WysiwygEditor = WysiwygEditor;
116
- _WysiwygEditor_view = new WeakMap(), _WysiwygEditor_serializer = new WeakMap(), _WysiwygEditor_parser = new WeakMap(), _WysiwygEditor_actions = new WeakMap(), _WysiwygEditor_contentHandler = new WeakMap();
118
+ _WysiwygEditor_view = new WeakMap(), _WysiwygEditor_serializer = new WeakMap(), _WysiwygEditor_parser = new WeakMap(), _WysiwygEditor_actions = new WeakMap(), _WysiwygEditor_contentHandler = new WeakMap(), _WysiwygEditor_escapeConfig = new WeakMap();
@@ -308,10 +308,12 @@ class MarkdownSerializerState {
308
308
  // content. If `startOfLine` is true, also escape characters that
309
309
  // have special meaning only at the start of the line.
310
310
  esc(str, startOfLine) {
311
- // TODO: add a setting which characters need to be escaped
312
- str = str.replace(/[`\^+*\\\|~\[\]\{\}<>\$]/g, '\\$&');
311
+ var _a, _b;
312
+ const escRegexp = ((_a = this.options) === null || _a === void 0 ? void 0 : _a.commonEscape) || /[`\^+*\\\|~\[\]\{\}<>\$]/g;
313
+ const startOfLineEscRegexp = ((_b = this.options) === null || _b === void 0 ? void 0 : _b.startOfLineEscape) || /^[:#\-*+>]/;
314
+ str = str.replace(escRegexp, '\\$&');
313
315
  if (startOfLine)
314
- str = str.replace(/^[:#\-*+>]/, '\\$&').replace(/^(\s*\d+)\./, '$1\\.');
316
+ str = str.replace(startOfLineEscRegexp, '\\$&').replace(/^(\s*\d+)\./, '$1\\.');
315
317
  return str;
316
318
  }
317
319
  escWhitespace(str) {
@@ -51,7 +51,7 @@ class WYfmHtmlBlockNodeView {
51
51
  this.view.dispatch(tr);
52
52
  }
53
53
  renderYfmHtmlBlock() {
54
- return (0, react_dom_1.createPortal)(react_1.default.createElement(YfmHtmlBlockView_1.YfmHtmlBlockView, { getPos: this.getPos, node: this.node, onChange: this.onChange.bind(this), sanitize: this.options.sanitize, useConfig: this.options.useConfig, view: this.view }), this.dom);
54
+ return (0, react_dom_1.createPortal)(react_1.default.createElement(YfmHtmlBlockView_1.YfmHtmlBlockView, { getPos: this.getPos, node: this.node, onChange: this.onChange.bind(this), options: this.options, view: this.view }), this.dom);
55
55
  }
56
56
  }
57
57
  exports.WYfmHtmlBlockNodeView = WYfmHtmlBlockNodeView;
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
- import type { IHTMLIFrameElementConfig } from '@diplodoc/html-extension/runtime';
3
2
  import { Node } from 'prosemirror-model';
4
3
  import { EditorView } from 'prosemirror-view';
5
4
  import { YfmHtmlBlockConsts } from '../YfmHtmlBlockSpecs/const';
5
+ import { YfmHtmlBlockOptions } from '../index';
6
6
  export declare const cnYfmHtmlBlock: import("@bem-react/classname").ClassNameFormatter;
7
7
  export declare const cnHelper: import("@bem-react/classname").ClassNameFormatter;
8
8
  export declare function generateID(): string;
@@ -12,7 +12,6 @@ export declare const YfmHtmlBlockView: React.FC<{
12
12
  onChange: (attrs: {
13
13
  [YfmHtmlBlockConsts.NodeAttrs.srcdoc]: string;
14
14
  }) => void;
15
- sanitize?: (dirtyHtml: string) => string;
16
- useConfig?: () => IHTMLIFrameElementConfig | undefined;
15
+ options: YfmHtmlBlockOptions;
17
16
  view: EditorView;
18
17
  }>;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.YfmHtmlBlockView = exports.generateID = exports.cnHelper = exports.cnYfmHtmlBlock = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const react_1 = tslib_1.__importStar(require("react"));
6
+ const html_extension_1 = require("@diplodoc/html-extension");
6
7
  const icons_1 = require("@gravity-ui/icons");
7
8
  const uikit_1 = require("@gravity-ui/uikit");
8
9
  const debounce_1 = tslib_1.__importDefault(require("lodash/debounce"));
@@ -137,7 +138,7 @@ const CodeEditMode = ({ initialText, onSave, onCancel }) => {
137
138
  react_1.default.createElement(uikit_1.Button, { onClick: () => onSave(text), view: 'action' },
138
139
  react_1.default.createElement("span", { className: (0, exports.cnHelper)({ 'prosemirror-stop-event': true }) }, (0, common_1.i18n)('save'))))))));
139
140
  };
140
- const YfmHtmlBlockView = ({ onChange, node, getPos, view, useConfig, sanitize }) => {
141
+ const YfmHtmlBlockView = ({ onChange, node, getPos, view, options: { useConfig, sanitize, styles, baseTarget = '_' } }) => {
141
142
  const [editing, setEditing, unsetEditing, toggleEditing] = (0, hooks_1.useBooleanState)(Boolean(node.attrs[const_1.YfmHtmlBlockConsts.NodeAttrs.newCreated]));
142
143
  const config = useConfig === null || useConfig === void 0 ? void 0 : useConfig();
143
144
  const [menuOpen, , , toggleMenuOpen] = (0, hooks_1.useBooleanState)(false);
@@ -151,7 +152,13 @@ const YfmHtmlBlockView = ({ onChange, node, getPos, view, useConfig, sanitize })
151
152
  unsetEditing();
152
153
  } }));
153
154
  }
154
- const dirtyHtml = node.attrs[const_1.YfmHtmlBlockConsts.NodeAttrs.srcdoc];
155
+ let dirtyHtml = `<base target="${baseTarget}">` + node.attrs[const_1.YfmHtmlBlockConsts.NodeAttrs.srcdoc];
156
+ if (styles) {
157
+ const stylesContent = typeof styles === 'string'
158
+ ? `<link rel="stylesheet" href="${styles}" />`
159
+ : `<style>${(0, html_extension_1.getStyles)(styles)}</style>`;
160
+ dirtyHtml = stylesContent + dirtyHtml;
161
+ }
155
162
  const html = sanitize ? sanitize(dirtyHtml) : dirtyHtml;
156
163
  return (react_1.default.createElement("div", { className: b(), onDoubleClick: setEditing },
157
164
  react_1.default.createElement(uikit_1.Label, { className: b('label'), icon: react_1.default.createElement(uikit_1.Icon, { size: 16, data: icons_1.Eye }) }, (0, common_1.i18n)('preview')),
@@ -0,0 +1,7 @@
1
+ import { SanitizeOptions } from '@diplodoc/transform/lib/sanitize';
2
+ export declare const getYfmHtmlBlockOptions: (defaultOptions: SanitizeOptions) => SanitizeOptions;
3
+ export interface GetSanitizeYfmHtmlBlockArgs {
4
+ options: SanitizeOptions;
5
+ sanitize?: (html: string, options?: SanitizeOptions) => string;
6
+ }
7
+ export declare const getSanitizeYfmHtmlBlock: ({ options, sanitize }: GetSanitizeYfmHtmlBlockArgs) => (content: string) => string;
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSanitizeYfmHtmlBlock = exports.getYfmHtmlBlockOptions = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const sanitize_1 = tslib_1.__importDefault(require("@diplodoc/transform/lib/sanitize"));
6
+ // yfmHtmlBlock additional css properties white list
7
+ const getYfmHtmlBlockWhiteList = () => {
8
+ const whiteList = {};
9
+ whiteList['align-content'] = true; // default: auto
10
+ whiteList['align-items'] = true; // default: auto
11
+ whiteList['align-self'] = true; // default: auto
12
+ whiteList.columns = true; // default: depending on individual properties
13
+ whiteList['column-count'] = true; // default: auto
14
+ whiteList['column-fill'] = true; // default: balance
15
+ whiteList['column-gap'] = true; // default: normal
16
+ whiteList['column-rule'] = true; // default: depending on individual properties
17
+ whiteList['column-rule-color'] = true; // default: current color
18
+ whiteList['column-rule-style'] = true; // default: medium
19
+ whiteList['column-rule-width'] = true; // default: medium
20
+ whiteList['column-span'] = true; // default: none
21
+ whiteList['column-width'] = true; // default: auto
22
+ whiteList.flex = true; // default: depending on individual properties
23
+ whiteList['flex-basis'] = true; // default: auto
24
+ whiteList['flex-direction'] = true; // default: row
25
+ whiteList['flex-flow'] = true; // default: depending on individual properties
26
+ whiteList['flex-grow'] = true; // default: 0
27
+ whiteList['flex-shrink'] = true; // default: 1
28
+ whiteList['flex-wrap'] = true; // default: nowrap
29
+ whiteList.gap = true; // default: normal normal
30
+ whiteList.grid = true; // default: depending on individual properties
31
+ whiteList['grid-area'] = true; // default: depending on individual properties
32
+ whiteList['grid-auto-columns'] = true; // default: auto
33
+ whiteList['grid-auto-flow'] = true; // default: none
34
+ whiteList['grid-auto-rows'] = true; // default: auto
35
+ whiteList['grid-column'] = true; // default: depending on individual properties
36
+ whiteList['grid-column-end'] = true; // default: auto
37
+ whiteList['grid-column-start'] = true; // default: auto
38
+ whiteList['grid-row'] = true; // default: depending on individual properties
39
+ whiteList['grid-row-end'] = true; // default: auto
40
+ whiteList['grid-row-start'] = true; // default: auto
41
+ whiteList['grid-template'] = true; // default: depending on individual properties
42
+ whiteList['grid-template-areas'] = true; // default: none
43
+ whiteList['grid-template-columns'] = true; // default: none
44
+ whiteList['grid-template-rows'] = true; // default: none
45
+ whiteList['justify-content'] = true; // default: auto
46
+ whiteList['justify-items'] = true; // default: auto
47
+ whiteList['justify-self'] = true; // default: auto
48
+ whiteList['line-height'] = true; // default: normal
49
+ whiteList['object-fit'] = true; // default: fill
50
+ whiteList['object-position'] = true; // default: 50% 50%
51
+ whiteList.order = true; // default: 0
52
+ whiteList.orphans = true; // default: 2
53
+ whiteList['row-gap'] = true;
54
+ return whiteList;
55
+ };
56
+ // yfmHtmlBlock additional allowedTags
57
+ const yfmHtmlBlockAllowedTags = ['link', 'base', 'style'];
58
+ // yfmHtmlBlock additional allowedTags
59
+ const yfmHtmlBlockAllowedAttributes = {
60
+ link: ['rel', 'href'],
61
+ base: ['target'],
62
+ style: [],
63
+ };
64
+ const getYfmHtmlBlockOptions = (defaultOptions) => {
65
+ var _a;
66
+ const defaultAllowedAttributes = defaultOptions.allowedAttributes;
67
+ return Object.assign(Object.assign({}, defaultOptions), { allowedAttributes: Object.assign(Object.assign({}, defaultAllowedAttributes), yfmHtmlBlockAllowedAttributes), allowedTags: typeof defaultOptions.allowedTags === 'boolean'
68
+ ? defaultOptions.allowedTags
69
+ : [...((_a = defaultOptions.allowedTags) !== null && _a !== void 0 ? _a : []), ...yfmHtmlBlockAllowedTags], cssWhiteList: Object.assign(Object.assign({}, defaultOptions.cssWhiteList), getYfmHtmlBlockWhiteList()) });
70
+ };
71
+ exports.getYfmHtmlBlockOptions = getYfmHtmlBlockOptions;
72
+ const getSanitizeYfmHtmlBlock = ({ options, sanitize = sanitize_1.default }) => (content) => sanitize(content, (0, exports.getYfmHtmlBlockOptions)(options));
73
+ exports.getSanitizeYfmHtmlBlock = getSanitizeYfmHtmlBlock;
@@ -2,4 +2,4 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VERSION = void 0;
4
4
  /** During build process, the current version will be injected here */
5
- exports.VERSION = typeof '13.12.0' !== 'undefined' ? '13.12.0' : 'unknown';
5
+ exports.VERSION = typeof '13.13.0' !== 'undefined' ? '13.13.0' : 'unknown';
@@ -59,6 +59,10 @@ export declare type MarkupConfig = {
59
59
  */
60
60
  languageData?: YfmLangOptions['languageData'];
61
61
  };
62
+ export declare type EscapeConfig = {
63
+ commonEscape?: RegExp;
64
+ startOfLineEscape?: RegExp;
65
+ };
62
66
  export declare type EditorOptions = Pick<WysiwygEditorOptions, 'allowHTML' | 'linkify' | 'linkifyTlds' | 'extensions'> & {
63
67
  initialMarkup?: MarkupString;
64
68
  /** @default 'wysiwyg' */
@@ -88,5 +92,6 @@ export declare type EditorOptions = Pick<WysiwygEditorOptions, 'allowHTML' | 'li
88
92
  /** @deprecated Put extra extensions via MarkdownEditorMarkupConfig */
89
93
  extraMarkupExtensions?: CodemirrorExtension[];
90
94
  markupConfig?: MarkupConfig;
95
+ escapeConfig?: EscapeConfig;
91
96
  };
92
97
  export {};
@@ -1,4 +1,4 @@
1
- var _EditorImpl_markup, _EditorImpl_editorMode, _EditorImpl_toolbarVisible, _EditorImpl_splitModeEnabled, _EditorImpl_splitMode, _EditorImpl_renderPreview, _EditorImpl_wysiwygEditor, _EditorImpl_markupEditor, _EditorImpl_markupConfig, _EditorImpl_preset, _EditorImpl_allowHTML, _EditorImpl_linkify, _EditorImpl_linkifyTlds, _EditorImpl_extensions, _EditorImpl_renderStorage, _EditorImpl_fileUploadHandler, _EditorImpl_needToSetDimensionsForUploadedImages, _EditorImpl_prepareRawMarkup;
1
+ var _EditorImpl_markup, _EditorImpl_editorMode, _EditorImpl_toolbarVisible, _EditorImpl_splitModeEnabled, _EditorImpl_splitMode, _EditorImpl_renderPreview, _EditorImpl_wysiwygEditor, _EditorImpl_markupEditor, _EditorImpl_markupConfig, _EditorImpl_escapeConfig, _EditorImpl_preset, _EditorImpl_allowHTML, _EditorImpl_linkify, _EditorImpl_linkifyTlds, _EditorImpl_extensions, _EditorImpl_renderStorage, _EditorImpl_fileUploadHandler, _EditorImpl_needToSetDimensionsForUploadedImages, _EditorImpl_prepareRawMarkup;
2
2
  import { __classPrivateFieldGet, __classPrivateFieldSet, __rest } from "tslib";
3
3
  import { TextSelection } from 'prosemirror-state';
4
4
  import { WysiwygEditor } from '../core';
@@ -22,6 +22,7 @@ export class EditorImpl extends SafeEventEmitter {
22
22
  _EditorImpl_wysiwygEditor.set(this, void 0);
23
23
  _EditorImpl_markupEditor.set(this, void 0);
24
24
  _EditorImpl_markupConfig.set(this, void 0);
25
+ _EditorImpl_escapeConfig.set(this, void 0);
25
26
  _EditorImpl_preset.set(this, void 0);
26
27
  _EditorImpl_allowHTML.set(this, void 0);
27
28
  _EditorImpl_linkify.set(this, void 0);
@@ -49,6 +50,7 @@ export class EditorImpl extends SafeEventEmitter {
49
50
  __classPrivateFieldSet(this, _EditorImpl_fileUploadHandler, opts.fileUploadHandler, "f");
50
51
  __classPrivateFieldSet(this, _EditorImpl_needToSetDimensionsForUploadedImages, Boolean(opts.needToSetDimensionsForUploadedImages), "f");
51
52
  __classPrivateFieldSet(this, _EditorImpl_prepareRawMarkup, opts.prepareRawMarkup, "f");
53
+ __classPrivateFieldSet(this, _EditorImpl_escapeConfig, opts.escapeConfig, "f");
52
54
  }
53
55
  get _wysiwygView() {
54
56
  var _a;
@@ -134,6 +136,7 @@ export class EditorImpl extends SafeEventEmitter {
134
136
  allowHTML: __classPrivateFieldGet(this, _EditorImpl_allowHTML, "f"),
135
137
  linkify: __classPrivateFieldGet(this, _EditorImpl_linkify, "f"),
136
138
  linkifyTlds: __classPrivateFieldGet(this, _EditorImpl_linkifyTlds, "f"),
139
+ escapeConfig: __classPrivateFieldGet(this, _EditorImpl_escapeConfig, "f"),
137
140
  onChange: () => this.emit('rerender-toolbar', null),
138
141
  onDocChange: () => this.emit('change', null),
139
142
  }), "f");
@@ -273,8 +276,8 @@ export class EditorImpl extends SafeEventEmitter {
273
276
  }
274
277
  shouldReplaceMarkupEditorValue(markupValue, wysiwygValue) {
275
278
  var _a;
276
- const serializedEditorMarkup = (_a = __classPrivateFieldGet(this, _EditorImpl_wysiwygEditor, "f")) === null || _a === void 0 ? void 0 : _a.serializer.serialize(__classPrivateFieldGet(this, _EditorImpl_wysiwygEditor, "f").parser.parse(markupValue));
279
+ const serializedEditorMarkup = (_a = __classPrivateFieldGet(this, _EditorImpl_wysiwygEditor, "f")) === null || _a === void 0 ? void 0 : _a.serializer.serialize(__classPrivateFieldGet(this, _EditorImpl_wysiwygEditor, "f").parser.parse(markupValue), __classPrivateFieldGet(this, _EditorImpl_escapeConfig, "f"));
277
280
  return (serializedEditorMarkup === null || serializedEditorMarkup === void 0 ? void 0 : serializedEditorMarkup.trim()) !== wysiwygValue.trim();
278
281
  }
279
282
  }
280
- _EditorImpl_markup = new WeakMap(), _EditorImpl_editorMode = new WeakMap(), _EditorImpl_toolbarVisible = new WeakMap(), _EditorImpl_splitModeEnabled = new WeakMap(), _EditorImpl_splitMode = new WeakMap(), _EditorImpl_renderPreview = new WeakMap(), _EditorImpl_wysiwygEditor = new WeakMap(), _EditorImpl_markupEditor = new WeakMap(), _EditorImpl_markupConfig = new WeakMap(), _EditorImpl_preset = new WeakMap(), _EditorImpl_allowHTML = new WeakMap(), _EditorImpl_linkify = new WeakMap(), _EditorImpl_linkifyTlds = new WeakMap(), _EditorImpl_extensions = new WeakMap(), _EditorImpl_renderStorage = new WeakMap(), _EditorImpl_fileUploadHandler = new WeakMap(), _EditorImpl_needToSetDimensionsForUploadedImages = new WeakMap(), _EditorImpl_prepareRawMarkup = new WeakMap();
283
+ _EditorImpl_markup = new WeakMap(), _EditorImpl_editorMode = new WeakMap(), _EditorImpl_toolbarVisible = new WeakMap(), _EditorImpl_splitModeEnabled = new WeakMap(), _EditorImpl_splitMode = new WeakMap(), _EditorImpl_renderPreview = new WeakMap(), _EditorImpl_wysiwygEditor = new WeakMap(), _EditorImpl_markupEditor = new WeakMap(), _EditorImpl_markupConfig = new WeakMap(), _EditorImpl_escapeConfig = new WeakMap(), _EditorImpl_preset = new WeakMap(), _EditorImpl_allowHTML = new WeakMap(), _EditorImpl_linkify = new WeakMap(), _EditorImpl_linkifyTlds = new WeakMap(), _EditorImpl_extensions = new WeakMap(), _EditorImpl_renderStorage = new WeakMap(), _EditorImpl_fileUploadHandler = new WeakMap(), _EditorImpl_needToSetDimensionsForUploadedImages = new WeakMap(), _EditorImpl_prepareRawMarkup = new WeakMap();
@@ -5,6 +5,10 @@ import type { Extension } from './types/extension';
5
5
  import type { Parser } from './types/parser';
6
6
  import type { Serializer } from './types/serializer';
7
7
  declare type OnChange = (editor: WysiwygEditor) => void;
8
+ declare type EscapeConfig = {
9
+ commonEscape?: RegExp;
10
+ startOfLineEscape?: RegExp;
11
+ };
8
12
  export declare type WysiwygEditorOptions = {
9
13
  domElem?: Element;
10
14
  /** markdown markup */
@@ -15,6 +19,7 @@ export declare type WysiwygEditorOptions = {
15
19
  allowHTML?: boolean;
16
20
  linkify?: boolean;
17
21
  linkifyTlds?: string | string[];
22
+ escapeConfig?: EscapeConfig;
18
23
  /** Call on any state change (move cursor, change selection, etc...) */
19
24
  onChange?: OnChange;
20
25
  /** Call only if document change */
@@ -26,7 +31,7 @@ export declare class WysiwygEditor implements CommonEditor, ActionStorage {
26
31
  get serializer(): Serializer;
27
32
  get parser(): Parser;
28
33
  get actions(): WysiwygEditor.Actions;
29
- constructor({ domElem, initialContent, extensions, allowHTML, mdPreset, linkify, linkifyTlds, onChange, onDocChange, }: WysiwygEditorOptions);
34
+ constructor({ domElem, initialContent, extensions, allowHTML, mdPreset, linkify, linkifyTlds, escapeConfig, onChange, onDocChange, }: WysiwygEditorOptions);
30
35
  action<T extends keyof WysiwygEditor.Actions>(actionName: T): WysiwygEditor.Actions[T];
31
36
  focus(): void;
32
37
  hasFocus(): boolean;
@@ -1,4 +1,4 @@
1
- var _WysiwygEditor_view, _WysiwygEditor_serializer, _WysiwygEditor_parser, _WysiwygEditor_actions, _WysiwygEditor_contentHandler;
1
+ var _WysiwygEditor_view, _WysiwygEditor_serializer, _WysiwygEditor_parser, _WysiwygEditor_actions, _WysiwygEditor_contentHandler, _WysiwygEditor_escapeConfig;
2
2
  import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib";
3
3
  import { EditorState } from 'prosemirror-state';
4
4
  import { EditorView } from 'prosemirror-view';
@@ -7,12 +7,13 @@ import { ExtensionsManager } from './ExtensionsManager';
7
7
  import { bindActions } from './utils/actions';
8
8
  import { logTransactionMetrics } from './utils/metrics';
9
9
  export class WysiwygEditor {
10
- constructor({ domElem, initialContent = '', extensions = () => { }, allowHTML, mdPreset, linkify, linkifyTlds, onChange, onDocChange, }) {
10
+ constructor({ domElem, initialContent = '', extensions = () => { }, allowHTML, mdPreset, linkify, linkifyTlds, escapeConfig, onChange, onDocChange, }) {
11
11
  _WysiwygEditor_view.set(this, void 0);
12
12
  _WysiwygEditor_serializer.set(this, void 0);
13
13
  _WysiwygEditor_parser.set(this, void 0);
14
14
  _WysiwygEditor_actions.set(this, void 0);
15
15
  _WysiwygEditor_contentHandler.set(this, void 0);
16
+ _WysiwygEditor_escapeConfig.set(this, void 0);
16
17
  const { schema, markupParser: parser, serializer, nodeViews, markViews, plugins, rawActions, actions, } = ExtensionsManager.process(extensions, {
17
18
  // "breaks" option only affects the renderer, but not the parser
18
19
  mdOpts: { html: allowHTML, linkify, breaks: true, preset: mdPreset },
@@ -44,6 +45,7 @@ export class WysiwygEditor {
44
45
  __classPrivateFieldSet(this, _WysiwygEditor_serializer, serializer, "f");
45
46
  __classPrivateFieldSet(this, _WysiwygEditor_parser, parser, "f");
46
47
  __classPrivateFieldSet(this, _WysiwygEditor_contentHandler, new WysiwygContentHandler(__classPrivateFieldGet(this, _WysiwygEditor_view, "f"), parser), "f");
48
+ __classPrivateFieldSet(this, _WysiwygEditor_escapeConfig, escapeConfig, "f");
47
49
  }
48
50
  get dom() {
49
51
  return __classPrivateFieldGet(this, _WysiwygEditor_view, "f").dom;
@@ -71,7 +73,7 @@ export class WysiwygEditor {
71
73
  return __classPrivateFieldGet(this, _WysiwygEditor_view, "f").hasFocus();
72
74
  }
73
75
  getValue() {
74
- return __classPrivateFieldGet(this, _WysiwygEditor_serializer, "f").serialize(__classPrivateFieldGet(this, _WysiwygEditor_view, "f").state.doc);
76
+ return __classPrivateFieldGet(this, _WysiwygEditor_serializer, "f").serialize(__classPrivateFieldGet(this, _WysiwygEditor_view, "f").state.doc, __classPrivateFieldGet(this, _WysiwygEditor_escapeConfig, "f"));
75
77
  }
76
78
  isEmpty() {
77
79
  var _a;
@@ -109,4 +111,4 @@ export class WysiwygEditor {
109
111
  }
110
112
  }
111
113
  }
112
- _WysiwygEditor_view = new WeakMap(), _WysiwygEditor_serializer = new WeakMap(), _WysiwygEditor_parser = new WeakMap(), _WysiwygEditor_actions = new WeakMap(), _WysiwygEditor_contentHandler = new WeakMap();
114
+ _WysiwygEditor_view = new WeakMap(), _WysiwygEditor_serializer = new WeakMap(), _WysiwygEditor_parser = new WeakMap(), _WysiwygEditor_actions = new WeakMap(), _WysiwygEditor_contentHandler = new WeakMap(), _WysiwygEditor_escapeConfig = new WeakMap();
@@ -304,10 +304,12 @@ export class MarkdownSerializerState {
304
304
  // content. If `startOfLine` is true, also escape characters that
305
305
  // have special meaning only at the start of the line.
306
306
  esc(str, startOfLine) {
307
- // TODO: add a setting which characters need to be escaped
308
- str = str.replace(/[`\^+*\\\|~\[\]\{\}<>\$]/g, '\\$&');
307
+ var _a, _b;
308
+ const escRegexp = ((_a = this.options) === null || _a === void 0 ? void 0 : _a.commonEscape) || /[`\^+*\\\|~\[\]\{\}<>\$]/g;
309
+ const startOfLineEscRegexp = ((_b = this.options) === null || _b === void 0 ? void 0 : _b.startOfLineEscape) || /^[:#\-*+>]/;
310
+ str = str.replace(escRegexp, '\\$&');
309
311
  if (startOfLine)
310
- str = str.replace(/^[:#\-*+>]/, '\\$&').replace(/^(\s*\d+)\./, '$1\\.');
312
+ str = str.replace(startOfLineEscRegexp, '\\$&').replace(/^(\s*\d+)\./, '$1\\.');
311
313
  return str;
312
314
  }
313
315
  escWhitespace(str) {
@@ -47,6 +47,6 @@ export class WYfmHtmlBlockNodeView {
47
47
  this.view.dispatch(tr);
48
48
  }
49
49
  renderYfmHtmlBlock() {
50
- return createPortal(React.createElement(YfmHtmlBlockView, { getPos: this.getPos, node: this.node, onChange: this.onChange.bind(this), sanitize: this.options.sanitize, useConfig: this.options.useConfig, view: this.view }), this.dom);
50
+ return createPortal(React.createElement(YfmHtmlBlockView, { getPos: this.getPos, node: this.node, onChange: this.onChange.bind(this), options: this.options, view: this.view }), this.dom);
51
51
  }
52
52
  }
@@ -1,11 +1,11 @@
1
1
  import React from 'react';
2
- import type { IHTMLIFrameElementConfig } from '@diplodoc/html-extension/runtime';
3
2
  import { Node } from 'prosemirror-model';
4
3
  import { EditorView } from 'prosemirror-view';
5
4
  import { YfmHtmlBlockConsts } from '../YfmHtmlBlockSpecs/const';
5
+ import { YfmHtmlBlockOptions } from '../index';
6
+ import './YfmHtmlBlock.css';
6
7
  export declare const cnYfmHtmlBlock: import("@bem-react/classname").ClassNameFormatter;
7
8
  export declare const cnHelper: import("@bem-react/classname").ClassNameFormatter;
8
- import './YfmHtmlBlock.css';
9
9
  export declare function generateID(): string;
10
10
  export declare const YfmHtmlBlockView: React.FC<{
11
11
  getPos: () => number | undefined;
@@ -13,7 +13,6 @@ export declare const YfmHtmlBlockView: React.FC<{
13
13
  onChange: (attrs: {
14
14
  [YfmHtmlBlockConsts.NodeAttrs.srcdoc]: string;
15
15
  }) => void;
16
- sanitize?: (dirtyHtml: string) => string;
17
- useConfig?: () => IHTMLIFrameElementConfig | undefined;
16
+ options: YfmHtmlBlockOptions;
18
17
  view: EditorView;
19
18
  }>;
@@ -1,4 +1,5 @@
1
1
  import React, { useEffect, useRef, useState } from 'react';
2
+ import { getStyles } from '@diplodoc/html-extension';
2
3
  import { Ellipsis as DotsIcon, Eye } from '@gravity-ui/icons';
3
4
  import { Button, Icon, Label, Menu, Popup } from '@gravity-ui/uikit';
4
5
  import debounce from 'lodash/debounce';
@@ -8,9 +9,9 @@ import { i18n } from '../../../../i18n/common';
8
9
  import { useBooleanState } from '../../../../react-utils/hooks';
9
10
  import { removeNode } from '../../../../utils/remove-node';
10
11
  import { YfmHtmlBlockConsts } from '../YfmHtmlBlockSpecs/const';
12
+ import './YfmHtmlBlock.css';
11
13
  export const cnYfmHtmlBlock = cn('yfm-html-block');
12
14
  export const cnHelper = cn('yfm-html-block-helper');
13
- import './YfmHtmlBlock.css';
14
15
  const b = cnYfmHtmlBlock;
15
16
  export function generateID() {
16
17
  return Math.random().toString(36).substr(2, 8);
@@ -133,7 +134,7 @@ const CodeEditMode = ({ initialText, onSave, onCancel }) => {
133
134
  React.createElement(Button, { onClick: () => onSave(text), view: 'action' },
134
135
  React.createElement("span", { className: cnHelper({ 'prosemirror-stop-event': true }) }, i18n('save'))))))));
135
136
  };
136
- export const YfmHtmlBlockView = ({ onChange, node, getPos, view, useConfig, sanitize }) => {
137
+ export const YfmHtmlBlockView = ({ onChange, node, getPos, view, options: { useConfig, sanitize, styles, baseTarget = '_' } }) => {
137
138
  const [editing, setEditing, unsetEditing, toggleEditing] = useBooleanState(Boolean(node.attrs[YfmHtmlBlockConsts.NodeAttrs.newCreated]));
138
139
  const config = useConfig === null || useConfig === void 0 ? void 0 : useConfig();
139
140
  const [menuOpen, , , toggleMenuOpen] = useBooleanState(false);
@@ -147,7 +148,13 @@ export const YfmHtmlBlockView = ({ onChange, node, getPos, view, useConfig, sani
147
148
  unsetEditing();
148
149
  } }));
149
150
  }
150
- const dirtyHtml = node.attrs[YfmHtmlBlockConsts.NodeAttrs.srcdoc];
151
+ let dirtyHtml = `<base target="${baseTarget}">` + node.attrs[YfmHtmlBlockConsts.NodeAttrs.srcdoc];
152
+ if (styles) {
153
+ const stylesContent = typeof styles === 'string'
154
+ ? `<link rel="stylesheet" href="${styles}" />`
155
+ : `<style>${getStyles(styles)}</style>`;
156
+ dirtyHtml = stylesContent + dirtyHtml;
157
+ }
151
158
  const html = sanitize ? sanitize(dirtyHtml) : dirtyHtml;
152
159
  return (React.createElement("div", { className: b(), onDoubleClick: setEditing },
153
160
  React.createElement(Label, { className: b('label'), icon: React.createElement(Icon, { size: 16, data: Eye }) }, i18n('preview')),
@@ -0,0 +1,7 @@
1
+ import { SanitizeOptions } from '@diplodoc/transform/lib/sanitize';
2
+ export declare const getYfmHtmlBlockOptions: (defaultOptions: SanitizeOptions) => SanitizeOptions;
3
+ export interface GetSanitizeYfmHtmlBlockArgs {
4
+ options: SanitizeOptions;
5
+ sanitize?: (html: string, options?: SanitizeOptions) => string;
6
+ }
7
+ export declare const getSanitizeYfmHtmlBlock: ({ options, sanitize }: GetSanitizeYfmHtmlBlockArgs) => (content: string) => string;
@@ -0,0 +1,67 @@
1
+ import diplodocSanitize from '@diplodoc/transform/lib/sanitize';
2
+ // yfmHtmlBlock additional css properties white list
3
+ const getYfmHtmlBlockWhiteList = () => {
4
+ const whiteList = {};
5
+ whiteList['align-content'] = true; // default: auto
6
+ whiteList['align-items'] = true; // default: auto
7
+ whiteList['align-self'] = true; // default: auto
8
+ whiteList.columns = true; // default: depending on individual properties
9
+ whiteList['column-count'] = true; // default: auto
10
+ whiteList['column-fill'] = true; // default: balance
11
+ whiteList['column-gap'] = true; // default: normal
12
+ whiteList['column-rule'] = true; // default: depending on individual properties
13
+ whiteList['column-rule-color'] = true; // default: current color
14
+ whiteList['column-rule-style'] = true; // default: medium
15
+ whiteList['column-rule-width'] = true; // default: medium
16
+ whiteList['column-span'] = true; // default: none
17
+ whiteList['column-width'] = true; // default: auto
18
+ whiteList.flex = true; // default: depending on individual properties
19
+ whiteList['flex-basis'] = true; // default: auto
20
+ whiteList['flex-direction'] = true; // default: row
21
+ whiteList['flex-flow'] = true; // default: depending on individual properties
22
+ whiteList['flex-grow'] = true; // default: 0
23
+ whiteList['flex-shrink'] = true; // default: 1
24
+ whiteList['flex-wrap'] = true; // default: nowrap
25
+ whiteList.gap = true; // default: normal normal
26
+ whiteList.grid = true; // default: depending on individual properties
27
+ whiteList['grid-area'] = true; // default: depending on individual properties
28
+ whiteList['grid-auto-columns'] = true; // default: auto
29
+ whiteList['grid-auto-flow'] = true; // default: none
30
+ whiteList['grid-auto-rows'] = true; // default: auto
31
+ whiteList['grid-column'] = true; // default: depending on individual properties
32
+ whiteList['grid-column-end'] = true; // default: auto
33
+ whiteList['grid-column-start'] = true; // default: auto
34
+ whiteList['grid-row'] = true; // default: depending on individual properties
35
+ whiteList['grid-row-end'] = true; // default: auto
36
+ whiteList['grid-row-start'] = true; // default: auto
37
+ whiteList['grid-template'] = true; // default: depending on individual properties
38
+ whiteList['grid-template-areas'] = true; // default: none
39
+ whiteList['grid-template-columns'] = true; // default: none
40
+ whiteList['grid-template-rows'] = true; // default: none
41
+ whiteList['justify-content'] = true; // default: auto
42
+ whiteList['justify-items'] = true; // default: auto
43
+ whiteList['justify-self'] = true; // default: auto
44
+ whiteList['line-height'] = true; // default: normal
45
+ whiteList['object-fit'] = true; // default: fill
46
+ whiteList['object-position'] = true; // default: 50% 50%
47
+ whiteList.order = true; // default: 0
48
+ whiteList.orphans = true; // default: 2
49
+ whiteList['row-gap'] = true;
50
+ return whiteList;
51
+ };
52
+ // yfmHtmlBlock additional allowedTags
53
+ const yfmHtmlBlockAllowedTags = ['link', 'base', 'style'];
54
+ // yfmHtmlBlock additional allowedTags
55
+ const yfmHtmlBlockAllowedAttributes = {
56
+ link: ['rel', 'href'],
57
+ base: ['target'],
58
+ style: [],
59
+ };
60
+ export const getYfmHtmlBlockOptions = (defaultOptions) => {
61
+ var _a;
62
+ const defaultAllowedAttributes = defaultOptions.allowedAttributes;
63
+ return Object.assign(Object.assign({}, defaultOptions), { allowedAttributes: Object.assign(Object.assign({}, defaultAllowedAttributes), yfmHtmlBlockAllowedAttributes), allowedTags: typeof defaultOptions.allowedTags === 'boolean'
64
+ ? defaultOptions.allowedTags
65
+ : [...((_a = defaultOptions.allowedTags) !== null && _a !== void 0 ? _a : []), ...yfmHtmlBlockAllowedTags], cssWhiteList: Object.assign(Object.assign({}, defaultOptions.cssWhiteList), getYfmHtmlBlockWhiteList()) });
66
+ };
67
+ export const getSanitizeYfmHtmlBlock = ({ options, sanitize = diplodocSanitize }) => (content) => sanitize(content, getYfmHtmlBlockOptions(options));
@@ -1,2 +1,2 @@
1
1
  /** During build process, the current version will be injected here */
2
- export const VERSION = typeof '13.12.0' !== 'undefined' ? '13.12.0' : 'unknown';
2
+ export const VERSION = typeof '13.13.0' !== 'undefined' ? '13.13.0' : 'unknown';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/markdown-editor",
3
- "version": "13.12.0",
3
+ "version": "13.13.0",
4
4
  "description": "Markdown wysiwyg and markup editor",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -200,7 +200,7 @@
200
200
  },
201
201
  "devDependencies": {
202
202
  "@diplodoc/folding-headings-extension": "0.1.0",
203
- "@diplodoc/html-extension": "1.3.1",
203
+ "@diplodoc/html-extension": "1.3.3",
204
204
  "@diplodoc/latex-extension": "1.0.3",
205
205
  "@diplodoc/mermaid-extension": "1.2.1",
206
206
  "@diplodoc/transform": "4.22.0",
@@ -223,6 +223,7 @@
223
223
  "@types/react": "18.0.28",
224
224
  "@types/react-dom": "18.0.11",
225
225
  "@types/rimraf": "3.0.2",
226
+ "@types/sanitize-html": "2.11.0",
226
227
  "bem-cn-lite": "4.1.0",
227
228
  "esbuild-sass-plugin": "2.15.0",
228
229
  "eslint": "8.56.0",