@gravity-ui/markdown-editor 13.14.0 → 13.16.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.
@@ -63,6 +63,8 @@ export declare type MarkupConfig = {
63
63
  * See more https://codemirror.net/docs/ref/#state.EditorState.languageDataAt
64
64
  */
65
65
  languageData?: YfmLangOptions['languageData'];
66
+ /** Config for @codemirror/autocomplete https://codemirror.net/docs/ref/#autocomplete.autocompletion%5Econfig */
67
+ autocompletion?: CreateCodemirrorParams['autocompletion'];
66
68
  };
67
69
  export declare type EscapeConfig = {
68
70
  commonEscape?: RegExp;
@@ -3,6 +3,7 @@ var _EditorImpl_markup, _EditorImpl_editorMode, _EditorImpl_toolbarVisible, _Edi
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.EditorImpl = void 0;
5
5
  const tslib_1 = require("tslib");
6
+ const view_1 = require("@codemirror/view");
6
7
  const prosemirror_state_1 = require("prosemirror-state");
7
8
  const core_1 = require("../core");
8
9
  const bundle_1 = require("../i18n/bundle");
@@ -165,6 +166,7 @@ class EditorImpl extends event_emitter_1.SafeEventEmitter {
165
166
  disabledExtensions: tslib_1.__classPrivateFieldGet(this, _EditorImpl_markupConfig, "f").disabledExtensions,
166
167
  keymaps: tslib_1.__classPrivateFieldGet(this, _EditorImpl_markupConfig, "f").keymaps,
167
168
  yfmLangOptions: { languageData: tslib_1.__classPrivateFieldGet(this, _EditorImpl_markupConfig, "f").languageData },
169
+ autocompletion: tslib_1.__classPrivateFieldGet(this, _EditorImpl_markupConfig, "f").autocompletion,
168
170
  receiver: this,
169
171
  })), "f");
170
172
  }
@@ -264,11 +266,28 @@ class EditorImpl extends event_emitter_1.SafeEventEmitter {
264
266
  let cmLine = line + 1; // lines in codemirror is 1-based
265
267
  cmLine = Math.max(cmLine, 1);
266
268
  cmLine = Math.min(cmLine, view.state.doc.lines);
269
+ const yMargin = getTopOffset();
270
+ const anchor = view.state.doc.line(cmLine).from;
267
271
  view.dispatch({
268
272
  scrollIntoView: true,
269
- selection: { anchor: view.state.doc.line(cmLine).from },
273
+ selection: { anchor },
274
+ effects: [
275
+ view_1.EditorView.scrollIntoView(anchor, { y: 'start', x: 'start', yMargin }),
276
+ ],
270
277
  });
271
278
  break;
279
+ // eslint-disable-next-line no-inner-declarations
280
+ function getTopOffset() {
281
+ const TOOLBAR_HEIGHT = 36; //px
282
+ const TOOLBAR_BOTTOM_OFFSET = 8; // px
283
+ const TOOLBAR_TOP_ADDITIONAL_OFFSET = 8; // px
284
+ const TOOLBAR_TOP_OFFSET_VAR = '--g-md-toolbar-sticky-offset';
285
+ const topOffsetValue = window
286
+ .getComputedStyle(view.dom)
287
+ .getPropertyValue(TOOLBAR_TOP_OFFSET_VAR);
288
+ const toolbarTopOffset = calculateCSSNumberValue(topOffsetValue) + TOOLBAR_TOP_ADDITIONAL_OFFSET;
289
+ return toolbarTopOffset + TOOLBAR_HEIGHT + TOOLBAR_BOTTOM_OFFSET;
290
+ }
272
291
  }
273
292
  case 'wysiwyg': {
274
293
  const node = this.wysiwygEditor.dom.querySelector(`[data-line="${line}"]`);
@@ -291,3 +310,14 @@ class EditorImpl extends event_emitter_1.SafeEventEmitter {
291
310
  }
292
311
  exports.EditorImpl = EditorImpl;
293
312
  _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(), _EditorImpl_beforeEditorModeChange = new WeakMap();
313
+ function calculateCSSNumberValue(cssValue) {
314
+ const tmp = document.createElement('div');
315
+ tmp.style.position = 'absolute';
316
+ tmp.style.top = '-99999px';
317
+ tmp.style.left = '-99999px';
318
+ tmp.style.width = `calc(${cssValue})`;
319
+ document.body.appendChild(tmp);
320
+ const value = tmp.getBoundingClientRect().width;
321
+ tmp.remove();
322
+ return value;
323
+ }
@@ -23,12 +23,20 @@ const YfmHeadingSpecs = (builder, opts) => {
23
23
  defining: true,
24
24
  selectable: true,
25
25
  parseDOM: [
26
- { tag: 'h1', getAttrs: (0, utils_1.getNodeAttrs)(1) },
27
- { tag: 'h2', getAttrs: (0, utils_1.getNodeAttrs)(2) },
28
- { tag: 'h3', getAttrs: (0, utils_1.getNodeAttrs)(3) },
29
- { tag: 'h4', getAttrs: (0, utils_1.getNodeAttrs)(4) },
30
- { tag: 'h5', getAttrs: (0, utils_1.getNodeAttrs)(5) },
31
- { tag: 'h6', getAttrs: (0, utils_1.getNodeAttrs)(6) },
26
+ { tag: 'h1', getAttrs: (0, utils_1.getNodeAttrs)(1), priority: 100, consuming: true },
27
+ { tag: 'h2', getAttrs: (0, utils_1.getNodeAttrs)(2), priority: 100, consuming: true },
28
+ { tag: 'h3', getAttrs: (0, utils_1.getNodeAttrs)(3), priority: 100, consuming: true },
29
+ { tag: 'h4', getAttrs: (0, utils_1.getNodeAttrs)(4), priority: 100, consuming: true },
30
+ { tag: 'h5', getAttrs: (0, utils_1.getNodeAttrs)(5), priority: 100, consuming: true },
31
+ { tag: 'h6', getAttrs: (0, utils_1.getNodeAttrs)(6), priority: 100, consuming: true },
32
+ {
33
+ // ignore anchor link inside headings
34
+ tag: 'a.yfm-anchor',
35
+ context: `${const_1.headingNodeName}/`,
36
+ skip: true,
37
+ ignore: true,
38
+ priority: 1000,
39
+ },
32
40
  ],
33
41
  toDOM(node) {
34
42
  const id = node.attrs[const_1.YfmHeadingAttr.Id];
@@ -1,12 +1,9 @@
1
- import { BaseTarget, StylesObject } from '@diplodoc/html-extension/plugin';
1
+ import { PluginOptions } from '@diplodoc/html-extension/plugin/transform';
2
2
  import type { ExtensionNodeSpec } from '../../../../core';
3
3
  export { yfmHtmlBlockNodeName } from './const';
4
- export declare type YfmHtmlBlockSpecsOptions = {
4
+ export interface YfmHtmlBlockSpecsOptions extends Omit<PluginOptions, 'runtimeJsPath' | 'containerClasses' | 'bundle'> {
5
5
  nodeView?: ExtensionNodeSpec['view'];
6
- sanitize?: (dirtyHtml: string) => string;
7
- styles?: string | StylesObject;
8
- baseTarget?: BaseTarget;
9
- };
6
+ }
10
7
  export declare const YfmHtmlBlockSpecs: import("../../../../core").ExtensionWithOptions<YfmHtmlBlockSpecsOptions> & {
11
8
  readonly NodeName: "yfm_html_block";
12
9
  readonly NodeAttrs: typeof import("./const").YfmHtmlBlockAttrs;
@@ -1,14 +1,10 @@
1
- import { BaseTarget, StylesObject } from '@diplodoc/html-extension/plugin';
1
+ import { PluginOptions } from '@diplodoc/html-extension/plugin/transform';
2
2
  import type { IHTMLIFrameElementConfig } from '@diplodoc/html-extension/runtime';
3
3
  import { Action, ExtensionAuto } from '../../../core';
4
4
  import { YfmHtmlBlockAction } from './YfmHtmlBlockSpecs/const';
5
- export declare type YfmHtmlBlockOptions = {
5
+ export interface YfmHtmlBlockOptions extends Omit<PluginOptions, 'runtimeJsPath' | 'containerClasses' | 'bundle'> {
6
6
  useConfig?: () => IHTMLIFrameElementConfig | undefined;
7
- sanitize?: (dirtyHtml: string) => string;
8
- styles?: string | StylesObject;
9
- baseTarget?: BaseTarget;
10
- head?: string;
11
- };
7
+ }
12
8
  export declare const YfmHtmlBlock: ExtensionAuto<YfmHtmlBlockOptions>;
13
9
  declare global {
14
10
  namespace WysiwygEditor {
@@ -6,6 +6,7 @@ const sanitize_1 = tslib_1.__importDefault(require("@diplodoc/transform/lib/sani
6
6
  // yfmHtmlBlock additional css properties white list
7
7
  const getYfmHtmlBlockWhiteList = () => {
8
8
  const whiteList = {};
9
+ // flex, grid, column
9
10
  whiteList['align-content'] = true; // default: auto
10
11
  whiteList['align-items'] = true; // default: auto
11
12
  whiteList['align-self'] = true; // default: auto
@@ -51,6 +52,24 @@ const getYfmHtmlBlockWhiteList = () => {
51
52
  whiteList.order = true; // default: 0
52
53
  whiteList.orphans = true; // default: 2
53
54
  whiteList['row-gap'] = true;
55
+ // position, opacity, overflow
56
+ whiteList['all'] = true; // default: depending on individual properties
57
+ whiteList['bottom'] = true; // default: auto
58
+ whiteList['content'] = true; // default: normal
59
+ whiteList['cursor'] = true; // default: auto
60
+ whiteList['direction'] = true; // default: ltr
61
+ whiteList['left'] = true; // default: auto
62
+ whiteList['line-break'] = true; // default: auto
63
+ whiteList['opacity'] = true; // default: 1
64
+ whiteList['overflow'] = true; // default: depending on individual properties
65
+ whiteList['overflow-wrap'] = true; // default: normal
66
+ whiteList['overflow-x'] = true; // default: visible
67
+ whiteList['overflow-y'] = true; // default: visible
68
+ whiteList['position'] = true; // default: static
69
+ whiteList['right'] = true; // default: auto
70
+ whiteList['top'] = true; // default: auto
71
+ whiteList['white-space'] = true; // default: normal
72
+ whiteList['z-index'] = true; // default: auto
54
73
  return whiteList;
55
74
  };
56
75
  // yfmHtmlBlock additional allowedTags
@@ -1,3 +1,4 @@
1
+ import { autocompletion } from '@codemirror/autocomplete';
1
2
  import type { Extension, StateCommand } from '@codemirror/state';
2
3
  import { EditorView, EditorViewConfig, KeyBinding } from '@codemirror/view';
3
4
  import { EventMap } from '../../bundle/Editor';
@@ -6,6 +7,7 @@ import { Receiver } from '../../utils';
6
7
  import { FileUploadHandler } from './files-upload-facet';
7
8
  import { type YfmLangOptions } from './yfm';
8
9
  export type { YfmLangOptions };
10
+ declare type Autocompletion = Parameters<typeof autocompletion>[0];
9
11
  export declare type CreateCodemirrorParams = {
10
12
  doc: EditorViewConfig['doc'];
11
13
  placeholderText: string;
@@ -24,6 +26,7 @@ export declare type CreateCodemirrorParams = {
24
26
  keymaps?: readonly KeyBinding[];
25
27
  receiver?: Receiver<EventMap>;
26
28
  yfmLangOptions?: YfmLangOptions;
29
+ autocompletion?: Autocompletion;
27
30
  };
28
31
  export declare function createCodemirror(params: CreateCodemirrorParams): EditorView;
29
32
  export declare function withLogger(action: string, command: StateCommand): StateCommand;
@@ -16,7 +16,7 @@ const react_facet_1 = require("./react-facet");
16
16
  const plugin_1 = require("./search-plugin/plugin");
17
17
  const yfm_1 = require("./yfm");
18
18
  function createCodemirror(params) {
19
- const { doc, placeholderText, reactRenderer, onCancel, onScroll, onSubmit, onChange, onDocChange, extensions: extraExtensions, disabledExtensions = {}, keymaps = [], receiver, yfmLangOptions, } = params;
19
+ const { doc, placeholderText, reactRenderer, onCancel, onScroll, onSubmit, onChange, onDocChange, extensions: extraExtensions, disabledExtensions = {}, keymaps = [], receiver, yfmLangOptions, autocompletion: autocompletionConfig, } = params;
20
20
  const extensions = [gravity_1.gravityTheme, (0, view_1.placeholder)(placeholderText)];
21
21
  if (!disabledExtensions.history) {
22
22
  extensions.push((0, commands_1.history)());
@@ -58,7 +58,7 @@ function createCodemirror(params) {
58
58
  ...commands_1.defaultKeymap,
59
59
  ...(disabledExtensions.history ? [] : commands_1.historyKeymap),
60
60
  ...keymaps,
61
- ]), (0, autocomplete_1.autocompletion)(), (0, yfm_1.yfmLang)(yfmLangOptions), react_facet_1.ReactRendererFacet.of(reactRenderer), pairing_chars_1.PairingCharactersExtension, view_1.EditorView.lineWrapping, view_1.EditorView.contentAttributes.of({ spellcheck: 'true' }), view_1.EditorView.domEventHandlers({
61
+ ]), (0, autocomplete_1.autocompletion)(autocompletionConfig), (0, yfm_1.yfmLang)(yfmLangOptions), react_facet_1.ReactRendererFacet.of(reactRenderer), pairing_chars_1.PairingCharactersExtension, view_1.EditorView.lineWrapping, view_1.EditorView.contentAttributes.of({ spellcheck: 'true' }), view_1.EditorView.domEventHandlers({
62
62
  scroll(event) {
63
63
  onScroll(event);
64
64
  },
@@ -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.14.0' !== 'undefined' ? '13.14.0' : 'unknown';
5
+ exports.VERSION = typeof '13.16.0' !== 'undefined' ? '13.16.0' : 'unknown';
@@ -63,6 +63,8 @@ export declare type MarkupConfig = {
63
63
  * See more https://codemirror.net/docs/ref/#state.EditorState.languageDataAt
64
64
  */
65
65
  languageData?: YfmLangOptions['languageData'];
66
+ /** Config for @codemirror/autocomplete https://codemirror.net/docs/ref/#autocomplete.autocompletion%5Econfig */
67
+ autocompletion?: CreateCodemirrorParams['autocompletion'];
66
68
  };
67
69
  export declare type EscapeConfig = {
68
70
  commonEscape?: RegExp;
@@ -1,5 +1,6 @@
1
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, _EditorImpl_beforeEditorModeChange;
2
2
  import { __classPrivateFieldGet, __classPrivateFieldSet, __rest } from "tslib";
3
+ import { EditorView as CMEditorView } from '@codemirror/view';
3
4
  import { TextSelection } from 'prosemirror-state';
4
5
  import { WysiwygEditor } from '../core';
5
6
  import { i18n } from '../i18n/bundle';
@@ -162,6 +163,7 @@ export class EditorImpl extends SafeEventEmitter {
162
163
  disabledExtensions: __classPrivateFieldGet(this, _EditorImpl_markupConfig, "f").disabledExtensions,
163
164
  keymaps: __classPrivateFieldGet(this, _EditorImpl_markupConfig, "f").keymaps,
164
165
  yfmLangOptions: { languageData: __classPrivateFieldGet(this, _EditorImpl_markupConfig, "f").languageData },
166
+ autocompletion: __classPrivateFieldGet(this, _EditorImpl_markupConfig, "f").autocompletion,
165
167
  receiver: this,
166
168
  })), "f");
167
169
  }
@@ -261,11 +263,28 @@ export class EditorImpl extends SafeEventEmitter {
261
263
  let cmLine = line + 1; // lines in codemirror is 1-based
262
264
  cmLine = Math.max(cmLine, 1);
263
265
  cmLine = Math.min(cmLine, view.state.doc.lines);
266
+ const yMargin = getTopOffset();
267
+ const anchor = view.state.doc.line(cmLine).from;
264
268
  view.dispatch({
265
269
  scrollIntoView: true,
266
- selection: { anchor: view.state.doc.line(cmLine).from },
270
+ selection: { anchor },
271
+ effects: [
272
+ CMEditorView.scrollIntoView(anchor, { y: 'start', x: 'start', yMargin }),
273
+ ],
267
274
  });
268
275
  break;
276
+ // eslint-disable-next-line no-inner-declarations
277
+ function getTopOffset() {
278
+ const TOOLBAR_HEIGHT = 36; //px
279
+ const TOOLBAR_BOTTOM_OFFSET = 8; // px
280
+ const TOOLBAR_TOP_ADDITIONAL_OFFSET = 8; // px
281
+ const TOOLBAR_TOP_OFFSET_VAR = '--g-md-toolbar-sticky-offset';
282
+ const topOffsetValue = window
283
+ .getComputedStyle(view.dom)
284
+ .getPropertyValue(TOOLBAR_TOP_OFFSET_VAR);
285
+ const toolbarTopOffset = calculateCSSNumberValue(topOffsetValue) + TOOLBAR_TOP_ADDITIONAL_OFFSET;
286
+ return toolbarTopOffset + TOOLBAR_HEIGHT + TOOLBAR_BOTTOM_OFFSET;
287
+ }
269
288
  }
270
289
  case 'wysiwyg': {
271
290
  const node = this.wysiwygEditor.dom.querySelector(`[data-line="${line}"]`);
@@ -287,3 +306,14 @@ export class EditorImpl extends SafeEventEmitter {
287
306
  }
288
307
  }
289
308
  _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(), _EditorImpl_beforeEditorModeChange = new WeakMap();
309
+ function calculateCSSNumberValue(cssValue) {
310
+ const tmp = document.createElement('div');
311
+ tmp.style.position = 'absolute';
312
+ tmp.style.top = '-99999px';
313
+ tmp.style.left = '-99999px';
314
+ tmp.style.width = `calc(${cssValue})`;
315
+ document.body.appendChild(tmp);
316
+ const value = tmp.getBoundingClientRect().width;
317
+ tmp.remove();
318
+ return value;
319
+ }
@@ -19,12 +19,20 @@ export const YfmHeadingSpecs = (builder, opts) => {
19
19
  defining: true,
20
20
  selectable: true,
21
21
  parseDOM: [
22
- { tag: 'h1', getAttrs: getNodeAttrs(1) },
23
- { tag: 'h2', getAttrs: getNodeAttrs(2) },
24
- { tag: 'h3', getAttrs: getNodeAttrs(3) },
25
- { tag: 'h4', getAttrs: getNodeAttrs(4) },
26
- { tag: 'h5', getAttrs: getNodeAttrs(5) },
27
- { tag: 'h6', getAttrs: getNodeAttrs(6) },
22
+ { tag: 'h1', getAttrs: getNodeAttrs(1), priority: 100, consuming: true },
23
+ { tag: 'h2', getAttrs: getNodeAttrs(2), priority: 100, consuming: true },
24
+ { tag: 'h3', getAttrs: getNodeAttrs(3), priority: 100, consuming: true },
25
+ { tag: 'h4', getAttrs: getNodeAttrs(4), priority: 100, consuming: true },
26
+ { tag: 'h5', getAttrs: getNodeAttrs(5), priority: 100, consuming: true },
27
+ { tag: 'h6', getAttrs: getNodeAttrs(6), priority: 100, consuming: true },
28
+ {
29
+ // ignore anchor link inside headings
30
+ tag: 'a.yfm-anchor',
31
+ context: `${headingNodeName}/`,
32
+ skip: true,
33
+ ignore: true,
34
+ priority: 1000,
35
+ },
28
36
  ],
29
37
  toDOM(node) {
30
38
  const id = node.attrs[YfmHeadingAttr.Id];
@@ -1,12 +1,9 @@
1
- import { BaseTarget, StylesObject } from '@diplodoc/html-extension/plugin';
1
+ import { PluginOptions } from '@diplodoc/html-extension/plugin/transform';
2
2
  import type { ExtensionNodeSpec } from '../../../../core';
3
3
  export { yfmHtmlBlockNodeName } from './const';
4
- export declare type YfmHtmlBlockSpecsOptions = {
4
+ export interface YfmHtmlBlockSpecsOptions extends Omit<PluginOptions, 'runtimeJsPath' | 'containerClasses' | 'bundle'> {
5
5
  nodeView?: ExtensionNodeSpec['view'];
6
- sanitize?: (dirtyHtml: string) => string;
7
- styles?: string | StylesObject;
8
- baseTarget?: BaseTarget;
9
- };
6
+ }
10
7
  export declare const YfmHtmlBlockSpecs: import("../../../../core").ExtensionWithOptions<YfmHtmlBlockSpecsOptions> & {
11
8
  readonly NodeName: "yfm_html_block";
12
9
  readonly NodeAttrs: typeof import("./const").YfmHtmlBlockAttrs;
@@ -1,14 +1,10 @@
1
- import { BaseTarget, StylesObject } from '@diplodoc/html-extension/plugin';
1
+ import { PluginOptions } from '@diplodoc/html-extension/plugin/transform';
2
2
  import type { IHTMLIFrameElementConfig } from '@diplodoc/html-extension/runtime';
3
3
  import { Action, ExtensionAuto } from '../../../core';
4
4
  import { YfmHtmlBlockAction } from './YfmHtmlBlockSpecs/const';
5
- export declare type YfmHtmlBlockOptions = {
5
+ export interface YfmHtmlBlockOptions extends Omit<PluginOptions, 'runtimeJsPath' | 'containerClasses' | 'bundle'> {
6
6
  useConfig?: () => IHTMLIFrameElementConfig | undefined;
7
- sanitize?: (dirtyHtml: string) => string;
8
- styles?: string | StylesObject;
9
- baseTarget?: BaseTarget;
10
- head?: string;
11
- };
7
+ }
12
8
  export declare const YfmHtmlBlock: ExtensionAuto<YfmHtmlBlockOptions>;
13
9
  declare global {
14
10
  namespace WysiwygEditor {
@@ -2,6 +2,7 @@ import diplodocSanitize from '@diplodoc/transform/lib/sanitize';
2
2
  // yfmHtmlBlock additional css properties white list
3
3
  const getYfmHtmlBlockWhiteList = () => {
4
4
  const whiteList = {};
5
+ // flex, grid, column
5
6
  whiteList['align-content'] = true; // default: auto
6
7
  whiteList['align-items'] = true; // default: auto
7
8
  whiteList['align-self'] = true; // default: auto
@@ -47,6 +48,24 @@ const getYfmHtmlBlockWhiteList = () => {
47
48
  whiteList.order = true; // default: 0
48
49
  whiteList.orphans = true; // default: 2
49
50
  whiteList['row-gap'] = true;
51
+ // position, opacity, overflow
52
+ whiteList['all'] = true; // default: depending on individual properties
53
+ whiteList['bottom'] = true; // default: auto
54
+ whiteList['content'] = true; // default: normal
55
+ whiteList['cursor'] = true; // default: auto
56
+ whiteList['direction'] = true; // default: ltr
57
+ whiteList['left'] = true; // default: auto
58
+ whiteList['line-break'] = true; // default: auto
59
+ whiteList['opacity'] = true; // default: 1
60
+ whiteList['overflow'] = true; // default: depending on individual properties
61
+ whiteList['overflow-wrap'] = true; // default: normal
62
+ whiteList['overflow-x'] = true; // default: visible
63
+ whiteList['overflow-y'] = true; // default: visible
64
+ whiteList['position'] = true; // default: static
65
+ whiteList['right'] = true; // default: auto
66
+ whiteList['top'] = true; // default: auto
67
+ whiteList['white-space'] = true; // default: normal
68
+ whiteList['z-index'] = true; // default: auto
50
69
  return whiteList;
51
70
  };
52
71
  // yfmHtmlBlock additional allowedTags
@@ -1,3 +1,4 @@
1
+ import { autocompletion } from '@codemirror/autocomplete';
1
2
  import type { Extension, StateCommand } from '@codemirror/state';
2
3
  import { EditorView, EditorViewConfig, KeyBinding } from '@codemirror/view';
3
4
  import { EventMap } from '../../bundle/Editor';
@@ -6,6 +7,7 @@ import { Receiver } from '../../utils';
6
7
  import { FileUploadHandler } from './files-upload-facet';
7
8
  import { type YfmLangOptions } from './yfm';
8
9
  export type { YfmLangOptions };
10
+ declare type Autocompletion = Parameters<typeof autocompletion>[0];
9
11
  export declare type CreateCodemirrorParams = {
10
12
  doc: EditorViewConfig['doc'];
11
13
  placeholderText: string;
@@ -24,6 +26,7 @@ export declare type CreateCodemirrorParams = {
24
26
  keymaps?: readonly KeyBinding[];
25
27
  receiver?: Receiver<EventMap>;
26
28
  yfmLangOptions?: YfmLangOptions;
29
+ autocompletion?: Autocompletion;
27
30
  };
28
31
  export declare function createCodemirror(params: CreateCodemirrorParams): EditorView;
29
32
  export declare function withLogger(action: string, command: StateCommand): StateCommand;
@@ -13,7 +13,7 @@ import { ReactRendererFacet } from './react-facet';
13
13
  import { SearchPanelPlugin } from './search-plugin/plugin';
14
14
  import { yfmLang } from './yfm';
15
15
  export function createCodemirror(params) {
16
- const { doc, placeholderText, reactRenderer, onCancel, onScroll, onSubmit, onChange, onDocChange, extensions: extraExtensions, disabledExtensions = {}, keymaps = [], receiver, yfmLangOptions, } = params;
16
+ const { doc, placeholderText, reactRenderer, onCancel, onScroll, onSubmit, onChange, onDocChange, extensions: extraExtensions, disabledExtensions = {}, keymaps = [], receiver, yfmLangOptions, autocompletion: autocompletionConfig, } = params;
17
17
  const extensions = [gravityTheme, placeholder(placeholderText)];
18
18
  if (!disabledExtensions.history) {
19
19
  extensions.push(history());
@@ -55,7 +55,7 @@ export function createCodemirror(params) {
55
55
  ...defaultKeymap,
56
56
  ...(disabledExtensions.history ? [] : historyKeymap),
57
57
  ...keymaps,
58
- ]), autocompletion(), yfmLang(yfmLangOptions), ReactRendererFacet.of(reactRenderer), PairingCharactersExtension, EditorView.lineWrapping, EditorView.contentAttributes.of({ spellcheck: 'true' }), EditorView.domEventHandlers({
58
+ ]), autocompletion(autocompletionConfig), yfmLang(yfmLangOptions), ReactRendererFacet.of(reactRenderer), PairingCharactersExtension, EditorView.lineWrapping, EditorView.contentAttributes.of({ spellcheck: 'true' }), EditorView.domEventHandlers({
59
59
  scroll(event) {
60
60
  onScroll(event);
61
61
  },
@@ -1,2 +1,2 @@
1
1
  /** During build process, the current version will be injected here */
2
- export const VERSION = typeof '13.14.0' !== 'undefined' ? '13.14.0' : 'unknown';
2
+ export const VERSION = typeof '13.16.0' !== 'undefined' ? '13.16.0' : 'unknown';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/markdown-editor",
3
- "version": "13.14.0",
3
+ "version": "13.16.0",
4
4
  "description": "Markdown wysiwyg and markup editor",
5
5
  "license": "MIT",
6
6
  "repository": {