@gravity-ui/markdown-editor 13.8.0 → 13.10.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.
Files changed (25) hide show
  1. package/build/cjs/extensions/yfm/Checkbox/CheckboxSpecs/index.js +1 -1
  2. package/build/cjs/extensions/yfm/YfmHtmlBlock/YfmHtmlBlockSpecs/index.d.ts +3 -0
  3. package/build/cjs/extensions/yfm/YfmHtmlBlock/YfmHtmlBlockSpecs/index.js +4 -2
  4. package/build/cjs/extensions/yfm/YfmHtmlBlock/index.d.ts +3 -0
  5. package/build/cjs/extensions/yfm/YfmHtmlBlock/index.js +4 -5
  6. package/build/cjs/extensions/yfm/YfmTable/YfmTableSpecs/const.d.ts +5 -0
  7. package/build/cjs/extensions/yfm/YfmTable/YfmTableSpecs/const.js +7 -1
  8. package/build/cjs/extensions/yfm/YfmTable/YfmTableSpecs/parser.js +12 -1
  9. package/build/cjs/extensions/yfm/YfmTable/YfmTableSpecs/schema.js +7 -2
  10. package/build/cjs/extensions/yfm/YfmTable/YfmTableSpecs/serializer.js +57 -17
  11. package/build/cjs/extensions/yfm/YfmTable/plugins/YfmTableControls/yfmTableCellView.js +9 -0
  12. package/build/cjs/version.js +1 -1
  13. package/build/esm/extensions/yfm/Checkbox/CheckboxSpecs/index.js +1 -1
  14. package/build/esm/extensions/yfm/YfmHtmlBlock/YfmHtmlBlockSpecs/index.d.ts +3 -0
  15. package/build/esm/extensions/yfm/YfmHtmlBlock/YfmHtmlBlockSpecs/index.js +4 -2
  16. package/build/esm/extensions/yfm/YfmHtmlBlock/index.d.ts +3 -0
  17. package/build/esm/extensions/yfm/YfmHtmlBlock/index.js +4 -5
  18. package/build/esm/extensions/yfm/YfmTable/YfmTableSpecs/const.d.ts +5 -0
  19. package/build/esm/extensions/yfm/YfmTable/YfmTableSpecs/const.js +6 -0
  20. package/build/esm/extensions/yfm/YfmTable/YfmTableSpecs/parser.js +13 -2
  21. package/build/esm/extensions/yfm/YfmTable/YfmTableSpecs/schema.js +8 -3
  22. package/build/esm/extensions/yfm/YfmTable/YfmTableSpecs/serializer.js +57 -18
  23. package/build/esm/extensions/yfm/YfmTable/plugins/YfmTableControls/yfmTableCellView.js +9 -0
  24. package/build/esm/version.js +1 -1
  25. package/package.json +3 -3
@@ -16,7 +16,7 @@ exports.checkboxInputType = (0, schema_1.nodeTypeFactory)(const_1.CheckboxNode.I
16
16
  const CheckboxSpecs = (builder, opts) => {
17
17
  const schemaSpecs = (0, schema_2.getSchemaSpecs)(opts, builder.context.get('placeholder'));
18
18
  builder
19
- .configureMd((md) => (0, checkbox_1.default)(md, { idPrefix: const_1.idPrefix, divClass: (0, const_1.b)() }))
19
+ .configureMd((md) => md.use(checkbox_1.default, { idPrefix: const_1.idPrefix, divClass: (0, const_1.b)() }))
20
20
  .addNode(const_1.CheckboxNode.Checkbox, () => ({
21
21
  spec: schemaSpecs[const_1.CheckboxNode.Checkbox],
22
22
  toMd: serializer_1.serializerTokens[const_1.CheckboxNode.Checkbox],
@@ -1,8 +1,11 @@
1
+ import { BaseTarget, StylesObject } from '@diplodoc/html-extension/plugin';
1
2
  import type { ExtensionNodeSpec } from '../../../../core';
2
3
  export { yfmHtmlBlockNodeName } from './const';
3
4
  export declare type YfmHtmlBlockSpecsOptions = {
4
5
  nodeView?: ExtensionNodeSpec['view'];
5
6
  sanitize?: (dirtyHtml: string) => string;
7
+ styles?: string | StylesObject;
8
+ baseTarget?: BaseTarget;
6
9
  };
7
10
  export declare const YfmHtmlBlockSpecs: import("../../../../core").ExtensionWithOptions<YfmHtmlBlockSpecsOptions> & {
8
11
  readonly NodeName: "yfm_html_block";
@@ -1,14 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.YfmHtmlBlockSpecs = exports.yfmHtmlBlockNodeName = void 0;
4
+ const tslib_1 = require("tslib");
4
5
  // eslint-disable-next-line import/no-extraneous-dependencies
5
6
  const html_extension_1 = require("@diplodoc/html-extension");
6
7
  const const_1 = require("./const");
7
8
  var const_2 = require("./const");
8
9
  Object.defineProperty(exports, "yfmHtmlBlockNodeName", { enumerable: true, get: function () { return const_2.yfmHtmlBlockNodeName; } });
9
- const YfmHtmlBlockSpecsExtension = (builder, { nodeView, sanitize }) => {
10
+ const YfmHtmlBlockSpecsExtension = (builder, _a) => {
11
+ var { nodeView } = _a, options = tslib_1.__rest(_a, ["nodeView"]);
10
12
  builder
11
- .configureMd((md) => md.use((0, html_extension_1.transform)({ bundle: false, sanitize }), {}))
13
+ .configureMd((md) => md.use((0, html_extension_1.transform)(Object.assign({ bundle: false }, options)), {}))
12
14
  .addNode(const_1.YfmHtmlBlockConsts.NodeName, () => ({
13
15
  fromMd: {
14
16
  tokenSpec: {
@@ -1,9 +1,12 @@
1
+ import { BaseTarget, StylesObject } from '@diplodoc/html-extension/plugin';
1
2
  import type { IHTMLIFrameElementConfig } from '@diplodoc/html-extension/runtime';
2
3
  import { Action, ExtensionAuto } from '../../../core';
3
4
  import { YfmHtmlBlockAction } from './YfmHtmlBlockSpecs/const';
4
5
  export declare type YfmHtmlBlockOptions = {
5
6
  useConfig?: () => IHTMLIFrameElementConfig | undefined;
6
7
  sanitize?: (dirtyHtml: string) => string;
8
+ styles?: string | StylesObject;
9
+ baseTarget?: BaseTarget;
7
10
  };
8
11
  export declare const YfmHtmlBlock: ExtensionAuto<YfmHtmlBlockOptions>;
9
12
  declare global {
@@ -1,15 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.YfmHtmlBlock = void 0;
4
+ const tslib_1 = require("tslib");
4
5
  const YfmHtmlBlockNodeView_1 = require("./YfmHtmlBlockNodeView");
5
6
  const YfmHtmlBlockSpecs_1 = require("./YfmHtmlBlockSpecs");
6
7
  const const_1 = require("./YfmHtmlBlockSpecs/const");
7
8
  const actions_1 = require("./actions");
8
- const YfmHtmlBlock = (builder, options) => {
9
- builder.use(YfmHtmlBlockSpecs_1.YfmHtmlBlockSpecs, {
10
- nodeView: YfmHtmlBlockNodeViewFactory(options),
11
- sanitize: options.sanitize,
12
- });
9
+ const YfmHtmlBlock = (builder, _a) => {
10
+ var { useConfig: _ } = _a, options = tslib_1.__rest(_a, ["useConfig"]);
11
+ builder.use(YfmHtmlBlockSpecs_1.YfmHtmlBlockSpecs, Object.assign({ nodeView: YfmHtmlBlockNodeViewFactory(options) }, options));
13
12
  builder.addAction(const_1.YfmHtmlBlockAction, () => actions_1.addYfmHtmlBlock);
14
13
  };
15
14
  exports.YfmHtmlBlock = YfmHtmlBlock;
@@ -4,3 +4,8 @@ export declare enum YfmTableNode {
4
4
  Row = "yfm_tr",
5
5
  Cell = "yfm_td"
6
6
  }
7
+ export declare enum YfmTableAttr {
8
+ Colspan = "colspan",
9
+ Rowspan = "rowspan",
10
+ CellAlign = "data-cell-align"
11
+ }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.YfmTableNode = void 0;
3
+ exports.YfmTableAttr = exports.YfmTableNode = void 0;
4
4
  var YfmTableNode;
5
5
  (function (YfmTableNode) {
6
6
  YfmTableNode["Table"] = "yfm_table";
@@ -8,3 +8,9 @@ var YfmTableNode;
8
8
  YfmTableNode["Row"] = "yfm_tr";
9
9
  YfmTableNode["Cell"] = "yfm_td";
10
10
  })(YfmTableNode = exports.YfmTableNode || (exports.YfmTableNode = {}));
11
+ var YfmTableAttr;
12
+ (function (YfmTableAttr) {
13
+ YfmTableAttr["Colspan"] = "colspan";
14
+ YfmTableAttr["Rowspan"] = "rowspan";
15
+ YfmTableAttr["CellAlign"] = "data-cell-align";
16
+ })(YfmTableAttr = exports.YfmTableAttr || (exports.YfmTableAttr = {}));
@@ -6,5 +6,16 @@ exports.parserTokens = {
6
6
  [const_1.YfmTableNode.Table]: { name: const_1.YfmTableNode.Table, type: 'block' },
7
7
  [const_1.YfmTableNode.Body]: { name: const_1.YfmTableNode.Body, type: 'block' },
8
8
  [const_1.YfmTableNode.Row]: { name: const_1.YfmTableNode.Row, type: 'block' },
9
- [const_1.YfmTableNode.Cell]: { name: const_1.YfmTableNode.Cell, type: 'block' },
9
+ [const_1.YfmTableNode.Cell]: {
10
+ name: const_1.YfmTableNode.Cell,
11
+ type: 'block',
12
+ getAttrs: (token) => {
13
+ var _a, _b;
14
+ const attrs = Object.fromEntries(token.attrs || []);
15
+ const align = (_b = (_a = token.attrGet('class')) === null || _a === void 0 ? void 0 : _a.match(/cell-align-[a-z-]*/)) === null || _b === void 0 ? void 0 : _b[0];
16
+ if (align)
17
+ attrs[const_1.YfmTableAttr.CellAlign] = align;
18
+ return attrs;
19
+ },
20
+ },
10
21
  };
@@ -57,12 +57,17 @@ const getSchemaSpecs = (opts, placeholder) => {
57
57
  content: 'block+',
58
58
  isolating: true,
59
59
  definingAsContext: true,
60
+ attrs: {
61
+ [const_1.YfmTableAttr.Colspan]: { default: null },
62
+ [const_1.YfmTableAttr.Rowspan]: { default: null },
63
+ [const_1.YfmTableAttr.CellAlign]: { default: null },
64
+ },
60
65
  parseDOM: [
61
66
  { tag: 'td', priority: 200 },
62
67
  { tag: 'th', priority: 200 },
63
68
  ],
64
- toDOM() {
65
- return ['td', 0];
69
+ toDOM(node) {
70
+ return ['td', node.attrs, 0];
66
71
  },
67
72
  placeholder: {
68
73
  content: (_b = (_a = placeholder === null || placeholder === void 0 ? void 0 : placeholder[const_1.YfmTableNode.Cell]) !== null && _a !== void 0 ? _a : opts === null || opts === void 0 ? void 0 : opts.yfmTableCellPlaceholder) !== null && _b !== void 0 ? _b : DEFAULT_CELL_PLACEHOLDER,
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.serializerTokens = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const is_number_1 = tslib_1.__importDefault(require("is-number"));
4
6
  const const_1 = require("./const");
5
7
  exports.serializerTokens = {
6
8
  [const_1.YfmTableNode.Table]: (state, node) => {
@@ -13,24 +15,62 @@ exports.serializerTokens = {
13
15
  state.closeBlock();
14
16
  state.write('\n');
15
17
  },
16
- [const_1.YfmTableNode.Body]: (state, node) => {
17
- state.renderContent(node);
18
- },
19
- [const_1.YfmTableNode.Row]: (state, node) => {
20
- state.write('||');
21
- state.ensureNewLine();
22
- state.write('\n');
23
- state.renderContent(node);
24
- state.write('||');
25
- state.ensureNewLine();
26
- },
27
- [const_1.YfmTableNode.Cell]: (state, node, parent) => {
28
- state.renderContent(node);
29
- const isLastCell = parent.lastChild === node;
30
- if (!isLastCell) {
31
- state.write('|');
18
+ [const_1.YfmTableNode.Body]: (state, tbody) => {
19
+ const rowspanStack = {};
20
+ tbody.forEach((trow) => {
21
+ state.write('||');
32
22
  state.ensureNewLine();
33
23
  state.write('\n');
34
- }
24
+ let colIndex = 0;
25
+ trow.forEach((td) => {
26
+ while (colIndex in rowspanStack && rowspanStack[colIndex] > 0) {
27
+ state.write(colIndex === 0 ? '^' : '|^');
28
+ rowspanStack[colIndex]--;
29
+ colIndex++;
30
+ }
31
+ let rowspan = -1;
32
+ if ((0, is_number_1.default)(td.attrs[const_1.YfmTableAttr.Rowspan])) {
33
+ rowspan = Math.max(0, Number.parseInt(td.attrs[const_1.YfmTableAttr.Rowspan], 10));
34
+ rowspanStack[colIndex] = rowspan - 1;
35
+ }
36
+ if (colIndex > 0) {
37
+ state.write('|');
38
+ state.ensureNewLine();
39
+ state.write('\n');
40
+ }
41
+ state.renderContent(td);
42
+ if (td.attrs[const_1.YfmTableAttr.CellAlign]) {
43
+ state.write(`{.${td.attrs[const_1.YfmTableAttr.CellAlign]}}`);
44
+ state.ensureNewLine();
45
+ }
46
+ colIndex++;
47
+ if ((0, is_number_1.default)(td.attrs[const_1.YfmTableAttr.Colspan])) {
48
+ let colspan = Math.max(0, Number.parseInt(td.attrs[const_1.YfmTableAttr.Colspan], 10));
49
+ while (--colspan > 0) {
50
+ state.write('|>');
51
+ if (rowspan > 0)
52
+ rowspanStack[colIndex] = rowspan - 1;
53
+ colIndex++;
54
+ }
55
+ }
56
+ const isLastCell = trow.lastChild === td;
57
+ if (isLastCell) {
58
+ while (colIndex in rowspanStack && rowspanStack[colIndex] > 0) {
59
+ state.write('|^');
60
+ rowspanStack[colIndex]--;
61
+ colIndex++;
62
+ }
63
+ }
64
+ });
65
+ state.ensureNewLine();
66
+ state.write('||');
67
+ state.ensureNewLine();
68
+ });
69
+ },
70
+ [const_1.YfmTableNode.Row]: (_state, node) => {
71
+ throw new Error(`Should not serialize ${node.type.name} node via serialize-token`);
72
+ },
73
+ [const_1.YfmTableNode.Cell]: (_state, node) => {
74
+ throw new Error(`Should not serialize ${node.type.name} node via serialize-token`);
35
75
  },
36
76
  };
@@ -14,6 +14,7 @@ const table_utils_1 = require("../../../../../table-utils");
14
14
  const node_children_1 = require("../../../../../utils/node-children");
15
15
  const nodes_1 = require("../../../../../utils/nodes");
16
16
  const ReactRenderer_1 = require("../../../../behavior/ReactRenderer");
17
+ const const_1 = require("../../const");
17
18
  const actions_1 = require("./actions");
18
19
  exports.yfmTableCellCn = (0, classname_1.cn)('table-cell-view');
19
20
  const b = exports.yfmTableCellCn;
@@ -179,6 +180,14 @@ const yfmTableCellView = (node, view, getPos) => {
179
180
  return {};
180
181
  }
181
182
  const dom = document.createElement('td');
183
+ if (node.attrs[const_1.YfmTableAttr.Colspan])
184
+ dom.setAttribute('colspan', node.attrs[const_1.YfmTableAttr.Colspan]);
185
+ if (node.attrs[const_1.YfmTableAttr.Rowspan])
186
+ dom.setAttribute('rowspan', node.attrs[const_1.YfmTableAttr.Rowspan]);
187
+ if (node.attrs[const_1.YfmTableAttr.CellAlign]) {
188
+ dom.classList.add(node.attrs[const_1.YfmTableAttr.CellAlign]);
189
+ dom.setAttribute(const_1.YfmTableAttr.CellAlign, node.attrs[const_1.YfmTableAttr.Rowspan]);
190
+ }
182
191
  const contentDOM = document.createElement('div');
183
192
  const control = document.createElement('span');
184
193
  control.setAttribute('style', 'width: 0; height: 0; float: left;');
@@ -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.8.0' !== 'undefined' ? '13.8.0' : 'unknown';
5
+ exports.VERSION = typeof '13.10.0' !== 'undefined' ? '13.10.0' : 'unknown';
@@ -11,7 +11,7 @@ export const checkboxInputType = nodeTypeFactory(CheckboxNode.Input);
11
11
  export const CheckboxSpecs = (builder, opts) => {
12
12
  const schemaSpecs = getSchemaSpecs(opts, builder.context.get('placeholder'));
13
13
  builder
14
- .configureMd((md) => checkboxPlugin(md, { idPrefix, divClass: b() }))
14
+ .configureMd((md) => md.use(checkboxPlugin, { idPrefix, divClass: b() }))
15
15
  .addNode(CheckboxNode.Checkbox, () => ({
16
16
  spec: schemaSpecs[CheckboxNode.Checkbox],
17
17
  toMd: serializerTokens[CheckboxNode.Checkbox],
@@ -1,8 +1,11 @@
1
+ import { BaseTarget, StylesObject } from '@diplodoc/html-extension/plugin';
1
2
  import type { ExtensionNodeSpec } from '../../../../core';
2
3
  export { yfmHtmlBlockNodeName } from './const';
3
4
  export declare type YfmHtmlBlockSpecsOptions = {
4
5
  nodeView?: ExtensionNodeSpec['view'];
5
6
  sanitize?: (dirtyHtml: string) => string;
7
+ styles?: string | StylesObject;
8
+ baseTarget?: BaseTarget;
6
9
  };
7
10
  export declare const YfmHtmlBlockSpecs: import("../../../../core").ExtensionWithOptions<YfmHtmlBlockSpecsOptions> & {
8
11
  readonly NodeName: "yfm_html_block";
@@ -1,10 +1,12 @@
1
+ import { __rest } from "tslib";
1
2
  // eslint-disable-next-line import/no-extraneous-dependencies
2
3
  import { transform } from '@diplodoc/html-extension';
3
4
  import { YfmHtmlBlockConsts } from './const';
4
5
  export { yfmHtmlBlockNodeName } from './const';
5
- const YfmHtmlBlockSpecsExtension = (builder, { nodeView, sanitize }) => {
6
+ const YfmHtmlBlockSpecsExtension = (builder, _a) => {
7
+ var { nodeView } = _a, options = __rest(_a, ["nodeView"]);
6
8
  builder
7
- .configureMd((md) => md.use(transform({ bundle: false, sanitize }), {}))
9
+ .configureMd((md) => md.use(transform(Object.assign({ bundle: false }, options)), {}))
8
10
  .addNode(YfmHtmlBlockConsts.NodeName, () => ({
9
11
  fromMd: {
10
12
  tokenSpec: {
@@ -1,9 +1,12 @@
1
+ import { BaseTarget, StylesObject } from '@diplodoc/html-extension/plugin';
1
2
  import type { IHTMLIFrameElementConfig } from '@diplodoc/html-extension/runtime';
2
3
  import { Action, ExtensionAuto } from '../../../core';
3
4
  import { YfmHtmlBlockAction } from './YfmHtmlBlockSpecs/const';
4
5
  export declare type YfmHtmlBlockOptions = {
5
6
  useConfig?: () => IHTMLIFrameElementConfig | undefined;
6
7
  sanitize?: (dirtyHtml: string) => string;
8
+ styles?: string | StylesObject;
9
+ baseTarget?: BaseTarget;
7
10
  };
8
11
  export declare const YfmHtmlBlock: ExtensionAuto<YfmHtmlBlockOptions>;
9
12
  declare global {
@@ -1,12 +1,11 @@
1
+ import { __rest } from "tslib";
1
2
  import { WYfmHtmlBlockNodeView } from './YfmHtmlBlockNodeView';
2
3
  import { YfmHtmlBlockSpecs } from './YfmHtmlBlockSpecs';
3
4
  import { YfmHtmlBlockAction } from './YfmHtmlBlockSpecs/const';
4
5
  import { addYfmHtmlBlock } from './actions';
5
- export const YfmHtmlBlock = (builder, options) => {
6
- builder.use(YfmHtmlBlockSpecs, {
7
- nodeView: YfmHtmlBlockNodeViewFactory(options),
8
- sanitize: options.sanitize,
9
- });
6
+ export const YfmHtmlBlock = (builder, _a) => {
7
+ var { useConfig: _ } = _a, options = __rest(_a, ["useConfig"]);
8
+ builder.use(YfmHtmlBlockSpecs, Object.assign({ nodeView: YfmHtmlBlockNodeViewFactory(options) }, options));
10
9
  builder.addAction(YfmHtmlBlockAction, () => addYfmHtmlBlock);
11
10
  };
12
11
  const YfmHtmlBlockNodeViewFactory = (options) => () => (node, view, getPos) => {
@@ -4,3 +4,8 @@ export declare enum YfmTableNode {
4
4
  Row = "yfm_tr",
5
5
  Cell = "yfm_td"
6
6
  }
7
+ export declare enum YfmTableAttr {
8
+ Colspan = "colspan",
9
+ Rowspan = "rowspan",
10
+ CellAlign = "data-cell-align"
11
+ }
@@ -5,3 +5,9 @@ export var YfmTableNode;
5
5
  YfmTableNode["Row"] = "yfm_tr";
6
6
  YfmTableNode["Cell"] = "yfm_td";
7
7
  })(YfmTableNode || (YfmTableNode = {}));
8
+ export var YfmTableAttr;
9
+ (function (YfmTableAttr) {
10
+ YfmTableAttr["Colspan"] = "colspan";
11
+ YfmTableAttr["Rowspan"] = "rowspan";
12
+ YfmTableAttr["CellAlign"] = "data-cell-align";
13
+ })(YfmTableAttr || (YfmTableAttr = {}));
@@ -1,7 +1,18 @@
1
- import { YfmTableNode } from './const';
1
+ import { YfmTableAttr, YfmTableNode } from './const';
2
2
  export const parserTokens = {
3
3
  [YfmTableNode.Table]: { name: YfmTableNode.Table, type: 'block' },
4
4
  [YfmTableNode.Body]: { name: YfmTableNode.Body, type: 'block' },
5
5
  [YfmTableNode.Row]: { name: YfmTableNode.Row, type: 'block' },
6
- [YfmTableNode.Cell]: { name: YfmTableNode.Cell, type: 'block' },
6
+ [YfmTableNode.Cell]: {
7
+ name: YfmTableNode.Cell,
8
+ type: 'block',
9
+ getAttrs: (token) => {
10
+ var _a, _b;
11
+ const attrs = Object.fromEntries(token.attrs || []);
12
+ const align = (_b = (_a = token.attrGet('class')) === null || _a === void 0 ? void 0 : _a.match(/cell-align-[a-z-]*/)) === null || _b === void 0 ? void 0 : _b[0];
13
+ if (align)
14
+ attrs[YfmTableAttr.CellAlign] = align;
15
+ return attrs;
16
+ },
17
+ },
7
18
  };
@@ -1,5 +1,5 @@
1
1
  import { TableRole } from '../../../../table-utils';
2
- import { YfmTableNode } from './const';
2
+ import { YfmTableAttr, YfmTableNode } from './const';
3
3
  const DEFAULT_CELL_PLACEHOLDER = 'Table cell';
4
4
  export const getSchemaSpecs = (opts, placeholder) => {
5
5
  var _a, _b;
@@ -54,12 +54,17 @@ export const getSchemaSpecs = (opts, placeholder) => {
54
54
  content: 'block+',
55
55
  isolating: true,
56
56
  definingAsContext: true,
57
+ attrs: {
58
+ [YfmTableAttr.Colspan]: { default: null },
59
+ [YfmTableAttr.Rowspan]: { default: null },
60
+ [YfmTableAttr.CellAlign]: { default: null },
61
+ },
57
62
  parseDOM: [
58
63
  { tag: 'td', priority: 200 },
59
64
  { tag: 'th', priority: 200 },
60
65
  ],
61
- toDOM() {
62
- return ['td', 0];
66
+ toDOM(node) {
67
+ return ['td', node.attrs, 0];
63
68
  },
64
69
  placeholder: {
65
70
  content: (_b = (_a = placeholder === null || placeholder === void 0 ? void 0 : placeholder[YfmTableNode.Cell]) !== null && _a !== void 0 ? _a : opts === null || opts === void 0 ? void 0 : opts.yfmTableCellPlaceholder) !== null && _b !== void 0 ? _b : DEFAULT_CELL_PLACEHOLDER,
@@ -1,4 +1,5 @@
1
- import { YfmTableNode } from './const';
1
+ import isNumber from 'is-number';
2
+ import { YfmTableAttr, YfmTableNode } from './const';
2
3
  export const serializerTokens = {
3
4
  [YfmTableNode.Table]: (state, node) => {
4
5
  state.ensureNewLine();
@@ -10,24 +11,62 @@ export const serializerTokens = {
10
11
  state.closeBlock();
11
12
  state.write('\n');
12
13
  },
13
- [YfmTableNode.Body]: (state, node) => {
14
- state.renderContent(node);
15
- },
16
- [YfmTableNode.Row]: (state, node) => {
17
- state.write('||');
18
- state.ensureNewLine();
19
- state.write('\n');
20
- state.renderContent(node);
21
- state.write('||');
22
- state.ensureNewLine();
23
- },
24
- [YfmTableNode.Cell]: (state, node, parent) => {
25
- state.renderContent(node);
26
- const isLastCell = parent.lastChild === node;
27
- if (!isLastCell) {
28
- state.write('|');
14
+ [YfmTableNode.Body]: (state, tbody) => {
15
+ const rowspanStack = {};
16
+ tbody.forEach((trow) => {
17
+ state.write('||');
29
18
  state.ensureNewLine();
30
19
  state.write('\n');
31
- }
20
+ let colIndex = 0;
21
+ trow.forEach((td) => {
22
+ while (colIndex in rowspanStack && rowspanStack[colIndex] > 0) {
23
+ state.write(colIndex === 0 ? '^' : '|^');
24
+ rowspanStack[colIndex]--;
25
+ colIndex++;
26
+ }
27
+ let rowspan = -1;
28
+ if (isNumber(td.attrs[YfmTableAttr.Rowspan])) {
29
+ rowspan = Math.max(0, Number.parseInt(td.attrs[YfmTableAttr.Rowspan], 10));
30
+ rowspanStack[colIndex] = rowspan - 1;
31
+ }
32
+ if (colIndex > 0) {
33
+ state.write('|');
34
+ state.ensureNewLine();
35
+ state.write('\n');
36
+ }
37
+ state.renderContent(td);
38
+ if (td.attrs[YfmTableAttr.CellAlign]) {
39
+ state.write(`{.${td.attrs[YfmTableAttr.CellAlign]}}`);
40
+ state.ensureNewLine();
41
+ }
42
+ colIndex++;
43
+ if (isNumber(td.attrs[YfmTableAttr.Colspan])) {
44
+ let colspan = Math.max(0, Number.parseInt(td.attrs[YfmTableAttr.Colspan], 10));
45
+ while (--colspan > 0) {
46
+ state.write('|>');
47
+ if (rowspan > 0)
48
+ rowspanStack[colIndex] = rowspan - 1;
49
+ colIndex++;
50
+ }
51
+ }
52
+ const isLastCell = trow.lastChild === td;
53
+ if (isLastCell) {
54
+ while (colIndex in rowspanStack && rowspanStack[colIndex] > 0) {
55
+ state.write('|^');
56
+ rowspanStack[colIndex]--;
57
+ colIndex++;
58
+ }
59
+ }
60
+ });
61
+ state.ensureNewLine();
62
+ state.write('||');
63
+ state.ensureNewLine();
64
+ });
65
+ },
66
+ [YfmTableNode.Row]: (_state, node) => {
67
+ throw new Error(`Should not serialize ${node.type.name} node via serialize-token`);
68
+ },
69
+ [YfmTableNode.Cell]: (_state, node) => {
70
+ throw new Error(`Should not serialize ${node.type.name} node via serialize-token`);
32
71
  },
33
72
  };
@@ -10,6 +10,7 @@ import { getTableDimensions, isTableNode } from '../../../../../table-utils';
10
10
  import { getChildByNode } from '../../../../../utils/node-children';
11
11
  import { getChildrenOfNode } from '../../../../../utils/nodes';
12
12
  import { getReactRendererFromState } from '../../../../behavior/ReactRenderer';
13
+ import { YfmTableAttr } from '../../const';
13
14
  import { controlActions } from './actions';
14
15
  import './yfmTableCellView.css';
15
16
  export const yfmTableCellCn = cn('table-cell-view');
@@ -176,6 +177,14 @@ export const yfmTableCellView = (node, view, getPos) => {
176
177
  return {};
177
178
  }
178
179
  const dom = document.createElement('td');
180
+ if (node.attrs[YfmTableAttr.Colspan])
181
+ dom.setAttribute('colspan', node.attrs[YfmTableAttr.Colspan]);
182
+ if (node.attrs[YfmTableAttr.Rowspan])
183
+ dom.setAttribute('rowspan', node.attrs[YfmTableAttr.Rowspan]);
184
+ if (node.attrs[YfmTableAttr.CellAlign]) {
185
+ dom.classList.add(node.attrs[YfmTableAttr.CellAlign]);
186
+ dom.setAttribute(YfmTableAttr.CellAlign, node.attrs[YfmTableAttr.Rowspan]);
187
+ }
179
188
  const contentDOM = document.createElement('div');
180
189
  const control = document.createElement('span');
181
190
  control.setAttribute('style', 'width: 0; height: 0; float: left;');
@@ -1,2 +1,2 @@
1
1
  /** During build process, the current version will be injected here */
2
- export const VERSION = typeof '13.8.0' !== 'undefined' ? '13.8.0' : 'unknown';
2
+ export const VERSION = typeof '13.10.0' !== 'undefined' ? '13.10.0' : 'unknown';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/markdown-editor",
3
- "version": "13.8.0",
3
+ "version": "13.10.0",
4
4
  "description": "Markdown wysiwyg and markup editor",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -200,10 +200,10 @@
200
200
  },
201
201
  "devDependencies": {
202
202
  "@diplodoc/folding-headings-extension": "0.1.0",
203
- "@diplodoc/html-extension": "1.2.7",
203
+ "@diplodoc/html-extension": "1.3.1",
204
204
  "@diplodoc/latex-extension": "1.0.3",
205
205
  "@diplodoc/mermaid-extension": "1.2.1",
206
- "@diplodoc/transform": "4.5.0",
206
+ "@diplodoc/transform": "4.22.0",
207
207
  "@gravity-ui/components": "3.0.0",
208
208
  "@gravity-ui/eslint-config": "3.1.1",
209
209
  "@gravity-ui/prettier-config": "1.1.0",