@progress/kendo-angular-editor 2.5.0-dev.202111261548 → 3.0.0-dev.202201121058

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 (55) hide show
  1. package/dist/cdn/js/kendo-angular-editor.js +2 -2
  2. package/dist/cdn/main.js +1 -1
  3. package/dist/es/common/error-messages.js +3 -2
  4. package/dist/es/config/commands.js +2 -2
  5. package/dist/es/config/schema.js +1 -2
  6. package/dist/es/config/table-commands.js +1 -363
  7. package/dist/es/editor.component.js +99 -71
  8. package/dist/es/main.js +1 -0
  9. package/dist/es/package-metadata.js +1 -1
  10. package/dist/{es2015/config/table-nodes.d.ts → es/preventable-events/paste-event-data.js} +0 -5
  11. package/dist/es/preventable-events/paste-event.js +25 -0
  12. package/dist/es2015/common/error-messages.js +3 -2
  13. package/dist/es2015/common/paste-cleanup-settings.d.ts +14 -0
  14. package/dist/es2015/config/commands.js +2 -2
  15. package/dist/es2015/config/schema.js +1 -2
  16. package/dist/es2015/config/table-commands.d.ts +0 -36
  17. package/dist/es2015/config/table-commands.js +1 -357
  18. package/dist/es2015/editor.component.d.ts +15 -10
  19. package/dist/es2015/editor.component.js +99 -71
  20. package/dist/es2015/index.metadata.json +1 -1
  21. package/dist/es2015/main.d.ts +2 -0
  22. package/dist/es2015/main.js +1 -0
  23. package/dist/es2015/package-metadata.js +1 -1
  24. package/dist/es2015/preventable-events/paste-event-data.d.ts +21 -0
  25. package/dist/es2015/preventable-events/paste-event-data.js +4 -0
  26. package/dist/es2015/preventable-events/paste-event.d.ts +27 -0
  27. package/dist/es2015/preventable-events/paste-event.js +20 -0
  28. package/dist/fesm2015/index.js +263 -1596
  29. package/dist/fesm5/index.js +285 -1641
  30. package/dist/npm/common/error-messages.js +3 -1
  31. package/dist/npm/config/commands.js +1 -1
  32. package/dist/npm/config/schema.js +1 -2
  33. package/dist/npm/config/table-commands.js +1 -368
  34. package/dist/npm/editor.component.js +95 -67
  35. package/dist/npm/main.js +2 -0
  36. package/dist/npm/package-metadata.js +1 -1
  37. package/dist/npm/preventable-events/paste-event-data.js +6 -0
  38. package/dist/npm/preventable-events/paste-event.js +27 -0
  39. package/dist/systemjs/kendo-angular-editor.js +1 -1
  40. package/package.json +5 -5
  41. package/dist/es/config/table-nodes.js +0 -146
  42. package/dist/es/config/tables/CellSelection.js +0 -268
  43. package/dist/es/config/tables/TableMap.js +0 -333
  44. package/dist/es/config/tables/table-utils.js +0 -302
  45. package/dist/es2015/config/table-nodes.js +0 -145
  46. package/dist/es2015/config/tables/CellSelection.d.ts +0 -35
  47. package/dist/es2015/config/tables/CellSelection.js +0 -256
  48. package/dist/es2015/config/tables/TableMap.d.ts +0 -35
  49. package/dist/es2015/config/tables/TableMap.js +0 -329
  50. package/dist/es2015/config/tables/table-utils.d.ts +0 -77
  51. package/dist/es2015/config/tables/table-utils.js +0 -299
  52. package/dist/npm/config/table-nodes.js +0 -157
  53. package/dist/npm/config/tables/CellSelection.js +0 -270
  54. package/dist/npm/config/tables/TableMap.js +0 -338
  55. package/dist/npm/config/tables/table-utils.js +0 -307
@@ -2,11 +2,7 @@
2
2
  * Copyright © 2021 Progress Software Corporation. All rights reserved.
3
3
  * Licensed under commercial license. See LICENSE.md in the project root for more information
4
4
  *-------------------------------------------------------------------------------------------*/
5
- import { insertNode, Fragment, Selection } from '@progress/kendo-editor-common';
6
- import { createTable, isInTable, selectedRect, tableNodeTypes, rowIsHeader, setAttr, addColSpan, removeColSpan, isCellEmpty, splitCellWithType, cellsOverlapRectangle, findParentNodeClosestToPos } from './tables/table-utils';
7
- import { isTable, isTableBody, isTableHead, isTableFoot, isTableHeaderCell, isTableCell } from './utils';
8
- import { TableMap } from './tables/TableMap';
9
- import { CellSelection } from './tables/CellSelection';
5
+ import { insertNode, createTable } from '@progress/kendo-editor-common';
10
6
  /**
11
7
  * @hidden
12
8
  */
@@ -16,355 +12,3 @@ export const insertTable = (attrs) => (state, dispatch) => {
16
12
  insertNode(newTable, true)(state, dispatch);
17
13
  }
18
14
  };
19
- const addTableGroupColumn = (tr, { left, right }, col, mainTable, requiredGroup, doc) => {
20
- let refColumn = col > 0 ? -1 : 0;
21
- // not sure if this should be deleted
22
- // if (columnIsHeader(map, table, col + refColumn)) {
23
- // refColumn = col === 0 || col === map.width ? null : 0;
24
- // }
25
- let rect;
26
- mainTable.node.descendants((tableChildNode, offset) => {
27
- if (requiredGroup(tableChildNode)) {
28
- let i = -1;
29
- tableChildNode.firstChild.descendants((childNode, pos) => {
30
- if (isTableCell(childNode) || isTableHeaderCell(childNode)) {
31
- i = i + 1;
32
- if (i === right || i === left) {
33
- const selection = new Selection(doc.resolve(pos + offset + mainTable.start), doc.resolve(pos + offset + mainTable.start));
34
- rect = selectedRect(selection);
35
- }
36
- }
37
- });
38
- }
39
- });
40
- // Do nothing if thead, tfoot or tbody is missing
41
- if (!rect) {
42
- return tr;
43
- }
44
- for (let row = 0; row < rect.map.height; row++) {
45
- const index = row * rect.map.width + col;
46
- // If this position falls inside a col-spanning cell
47
- if (col > 0 && col < rect.map.width && rect.map.map[index - 1] === rect.map.map[index]) {
48
- const pos = rect.map.map[index];
49
- const cell = rect.table.nodeAt(pos);
50
- tr.setNodeMarkup(tr.mapping.map(rect.tableStart + pos), null, addColSpan(cell.attrs, col - rect.map.colCount(pos)));
51
- // Skip ahead if rowspan > 1
52
- row += cell.attrs.rowspan - 1;
53
- }
54
- else {
55
- const type = rect.table.nodeAt(rect.map.map[index + refColumn]).type;
56
- const pos = rect.map.positionAt(row, col, rect.table);
57
- tr.insert(tr.mapping.map(rect.tableStart + pos), type.createAndFill());
58
- }
59
- }
60
- return tr;
61
- };
62
- const ɵ0 = addTableGroupColumn;
63
- const removeTableGroupColumn = (tr, { right, left }, mainTable, requiredGroup, doc) => {
64
- let rect;
65
- mainTable.node.descendants((tableChildNode, offset) => {
66
- if (requiredGroup(tableChildNode)) {
67
- let i = -1;
68
- tableChildNode.firstChild.descendants((childNode, pos) => {
69
- if (isTableCell(childNode) || isTableHeaderCell(childNode)) {
70
- i = i + 1;
71
- if (i >= left && i < right) {
72
- const resolvedPos = doc.resolve(pos + offset + mainTable.start + childNode.nodeSize);
73
- const selection = new Selection(resolvedPos, resolvedPos);
74
- rect = selectedRect(selection);
75
- }
76
- }
77
- });
78
- }
79
- });
80
- // Do nothing if thead, tfoot or tbody is missing
81
- if (!rect) {
82
- return;
83
- }
84
- for (let i = rect.right - 1;; i--) {
85
- removeColumn(tr, rect, i);
86
- if (i === rect.left) {
87
- break;
88
- }
89
- rect.table = rect.tableStart ? tr.doc.nodeAt(rect.tableStart - 1) : tr.doc;
90
- rect.map = TableMap.get(rect.table);
91
- }
92
- return;
93
- };
94
- const ɵ1 = removeTableGroupColumn;
95
- const removeColumn = (tr, { map, table, tableStart }, col) => {
96
- for (let row = 0; row < map.height;) {
97
- const index = row * map.width + col;
98
- const pos = map.map[index];
99
- const cell = table.nodeAt(pos);
100
- // If this is part of a col-spanning cell
101
- if ((col > 0 && map.map[index - 1] === pos) || (col < map.width - 1 && map.map[index + 1] === pos)) {
102
- tr.setNodeMarkup(tr.mapping.map(tableStart + pos), null, removeColSpan(cell.attrs, col - map.colCount(pos)));
103
- }
104
- else {
105
- const start = tr.mapping.map(tableStart + pos);
106
- tr.delete(start, start + cell.nodeSize);
107
- }
108
- row += cell.attrs.rowspan;
109
- }
110
- };
111
- const ɵ2 = removeColumn;
112
- /**
113
- * @hidden
114
- */
115
- // Command to add a column before the column with the selection.
116
- export const addColumnBefore = (state, dispatch) => {
117
- if (!isInTable(state)) {
118
- return false;
119
- }
120
- if (dispatch) {
121
- const rect = selectedRect(state.selection);
122
- const mainTable = findParentNodeClosestToPos(state.selection.$anchor, isTable);
123
- const tHeadTr = addTableGroupColumn(state.tr, rect, rect.left, mainTable, isTableHead, state.doc);
124
- const tBodyTr = addTableGroupColumn(tHeadTr, rect, rect.left, mainTable, isTableBody, state.doc);
125
- const tFootTr = addTableGroupColumn(tBodyTr, rect, rect.left, mainTable, isTableFoot, state.doc);
126
- dispatch(tFootTr);
127
- }
128
- return true;
129
- };
130
- /**
131
- * @hidden
132
- */
133
- // Command to add a column after the column with the selection.
134
- export const addColumnAfter = (state, dispatch) => {
135
- if (!isInTable(state)) {
136
- return false;
137
- }
138
- if (dispatch) {
139
- const rect = selectedRect(state.selection);
140
- const mainTable = findParentNodeClosestToPos(state.selection.$anchor, isTable);
141
- const theadTr = addTableGroupColumn(state.tr, rect, rect.right, mainTable, isTableHead, state.doc);
142
- const tBodyTr = addTableGroupColumn(theadTr, rect, rect.right, mainTable, isTableBody, state.doc);
143
- const tFootTr = addTableGroupColumn(tBodyTr, rect, rect.right, mainTable, isTableFoot, state.doc);
144
- dispatch(tFootTr);
145
- }
146
- return true;
147
- };
148
- const addRow = (tr, { map, tableStart, table }, row) => {
149
- let rowPos = tableStart;
150
- for (let i = 0; i < row; i++) {
151
- rowPos += table.child(i).nodeSize;
152
- }
153
- const cells = [];
154
- let refRow = row > 0 ? -1 : 0;
155
- if (rowIsHeader(map, table, row + refRow)) {
156
- refRow = row === 0 || row === map.height ? null : 0;
157
- }
158
- for (let col = 0, index = map.width * row; col < map.width; col++, index++) {
159
- // Covered by a rowspan cell
160
- if (row > 0 && row < map.height && map.map[index] === map.map[index - map.width]) {
161
- const pos = map.map[index];
162
- const attrs = table.nodeAt(pos).attrs;
163
- tr.setNodeMarkup(tableStart + pos, null, setAttr(attrs, 'rowspan', attrs.rowspan + 1));
164
- col += attrs.colspan - 1;
165
- }
166
- else {
167
- const type = refRow == null ? tableNodeTypes(table.type.schema).cell : table.nodeAt(map.map[index + refRow * map.width]).type;
168
- cells.push(type.createAndFill());
169
- }
170
- }
171
- tr.insert(rowPos, tableNodeTypes(table.type.schema).row.create(null, cells));
172
- return tr;
173
- };
174
- const ɵ3 = addRow;
175
- /**
176
- * @hidden
177
- */
178
- // Add a table row before the selection.
179
- export const addRowBefore = (state, dispatch) => {
180
- if (!isInTable(state)) {
181
- return false;
182
- }
183
- if (dispatch) {
184
- const rect = selectedRect(state.selection);
185
- dispatch(addRow(state.tr, rect, rect.top));
186
- }
187
- return true;
188
- };
189
- /**
190
- * @hidden
191
- */
192
- // Add a table row after the selection.
193
- export const addRowAfter = (state, dispatch) => {
194
- if (!isInTable(state)) {
195
- return false;
196
- }
197
- if (dispatch) {
198
- const rect = selectedRect(state.selection);
199
- dispatch(addRow(state.tr, rect, rect.bottom));
200
- }
201
- return true;
202
- };
203
- /**
204
- * @hidden
205
- */
206
- // Command function that removes the selected columns from a table.
207
- export const deleteColumn = (state, dispatch) => {
208
- if (!isInTable(state)) {
209
- return false;
210
- }
211
- if (dispatch) {
212
- const rect = selectedRect(state.selection);
213
- // if only one column left - delete the whole table
214
- if (rect.left === 0 && rect.right === rect.map.width) {
215
- return deleteTable(state, dispatch);
216
- }
217
- const mainTable = findParentNodeClosestToPos(state.selection.$anchor, isTable);
218
- const tr = state.tr;
219
- removeTableGroupColumn(tr, rect, mainTable, isTableFoot, tr.doc);
220
- removeTableGroupColumn(tr, rect, mainTable, isTableBody, tr.doc);
221
- removeTableGroupColumn(tr, rect, mainTable, isTableHead, tr.doc);
222
- dispatch(tr);
223
- }
224
- return true;
225
- };
226
- const removeRow = (tr, { map, table, tableStart }, row) => {
227
- let rowPos = 0;
228
- for (let i = 0; i < row; i++) {
229
- rowPos += table.child(i).nodeSize;
230
- }
231
- const nextRow = rowPos + table.child(row).nodeSize;
232
- const mapFrom = tr.mapping.maps.length;
233
- tr.delete(rowPos + tableStart, nextRow + tableStart);
234
- for (let col = 0, index = row * map.width; col < map.width; col++, index++) {
235
- const pos = map.map[index];
236
- if (row > 0 && pos === map.map[index - map.width]) {
237
- // If this cell starts in the row above, simply reduce its rowspan
238
- const attrs = table.nodeAt(pos).attrs;
239
- tr.setNodeMarkup(tr.mapping.slice(mapFrom).map(pos + tableStart), null, setAttr(attrs, 'rowspan', attrs.rowspan - 1));
240
- col += attrs.colspan - 1;
241
- }
242
- else if (row < map.width && pos === map.map[index + map.width]) {
243
- // Else, if it continues in the row below, it has to be moved down
244
- const cell = table.nodeAt(pos);
245
- const copy = cell.type.create(setAttr(cell.attrs, 'rowspan', cell.attrs.rowspan - 1), cell.content);
246
- const newPos = map.positionAt(row + 1, col, table);
247
- tr.insert(tr.mapping.slice(mapFrom).map(tableStart + newPos), copy);
248
- col += cell.attrs.colspan - 1;
249
- }
250
- }
251
- };
252
- const ɵ4 = removeRow;
253
- /**
254
- * @hidden
255
- */
256
- // Remove the selected rows from a table.
257
- export const deleteRow = (state, dispatch) => {
258
- if (!isInTable(state)) {
259
- return false;
260
- }
261
- if (dispatch) {
262
- const rect = selectedRect(state.selection);
263
- const tr = state.tr;
264
- if (rect.top === 0 && rect.bottom === rect.map.height) {
265
- const mainTable = findParentNodeClosestToPos(state.selection.$anchor, isTable);
266
- if (mainTable.node.childCount === 1) {
267
- deleteTable(state, dispatch);
268
- }
269
- else {
270
- deleteTableElement(n => n.type.name === rect.table.type.name)(state, dispatch);
271
- }
272
- return true;
273
- }
274
- for (let i = rect.bottom - 1;; i--) {
275
- removeRow(tr, rect, i);
276
- if (i === rect.top) {
277
- break;
278
- }
279
- rect.table = rect.tableStart ? tr.doc.nodeAt(rect.tableStart - 1) : tr.doc;
280
- rect.map = TableMap.get(rect.table);
281
- }
282
- dispatch(tr);
283
- }
284
- return true;
285
- };
286
- /**
287
- * @hidden
288
- */
289
- // Merge the selected cells into a single cell. Only available when
290
- // the selected cells' outline forms a rectangle.
291
- export const mergeCells = (state, dispatch) => {
292
- const sel = state.selection;
293
- if (!(sel instanceof CellSelection) || sel.$anchorCell.pos === sel.$headCell.pos) {
294
- return false;
295
- }
296
- const rect = selectedRect(state.selection);
297
- const { map } = rect;
298
- if (cellsOverlapRectangle(map, rect)) {
299
- return false;
300
- }
301
- if (dispatch) {
302
- const tr = state.tr;
303
- const seen = {};
304
- let content = Fragment.empty;
305
- let mergedPos;
306
- let mergedCell;
307
- for (let row = rect.top; row < rect.bottom; row++) {
308
- for (let col = rect.left; col < rect.right; col++) {
309
- const cellPos = map.map[row * map.width + col], cell = rect.table.nodeAt(cellPos);
310
- if (seen[cellPos]) {
311
- continue;
312
- }
313
- seen[cellPos] = true;
314
- if (mergedPos === null) {
315
- mergedPos = cellPos;
316
- mergedCell = cell;
317
- }
318
- else {
319
- if (!isCellEmpty(cell)) {
320
- content = content.append(cell.content);
321
- }
322
- const mapped = tr.mapping.map(cellPos + rect.tableStart);
323
- tr.delete(mapped, mapped + cell.nodeSize);
324
- }
325
- }
326
- }
327
- tr.setNodeMarkup(mergedPos + rect.tableStart, null, setAttr(addColSpan(mergedCell.attrs, mergedCell.attrs.colspan, rect.right - rect.left - mergedCell.attrs.colspan), 'rowspan', rect.bottom - rect.top));
328
- if (content.size) {
329
- const end = mergedPos + 1 + mergedCell.content.size;
330
- const start = isCellEmpty(mergedCell) ? mergedPos + 1 : end;
331
- tr.replaceWith(start + rect.tableStart, end + rect.tableStart, content);
332
- }
333
- tr.setSelection(new CellSelection(tr.doc.resolve(mergedPos + rect.tableStart)));
334
- dispatch(tr);
335
- }
336
- return true;
337
- };
338
- /**
339
- * @hidden
340
- */
341
- // Split a selected cell, whose rowpan or colspan is greater than one,
342
- // into smaller cells. Use the first cell type for the new cells.
343
- export const splitCell = (state, dispatch) => {
344
- const nodeTypes = tableNodeTypes(state.schema);
345
- return splitCellWithType(({ node }) => {
346
- return nodeTypes[node.type.spec.tableRole];
347
- })(state, dispatch);
348
- };
349
- const deleteTableElement = (selector) => (state, dispatch) => {
350
- const $pos = state.selection.$anchor;
351
- for (let d = $pos.depth; d > 0; d--) {
352
- const node = $pos.node(d);
353
- if (selector(node)) {
354
- if (dispatch) {
355
- const tr = state.tr;
356
- tr.delete($pos.before(d), $pos.after(d)).scrollIntoView();
357
- dispatch(tr);
358
- }
359
- return true;
360
- }
361
- }
362
- return false;
363
- };
364
- const ɵ5 = deleteTableElement;
365
- /**
366
- * @hidden
367
- */
368
- // Deletes the table around the selection, if any.
369
- export const deleteTable = deleteTableElement(isTable);
370
- export { ɵ0, ɵ1, ɵ2, ɵ3, ɵ4, ɵ5 };
@@ -16,6 +16,7 @@ import { PluginsFn } from './common/plugins-function';
16
16
  import { ApplyToWordOptions } from './common/apply-to-word-options';
17
17
  import { EditorResizableOptions } from './common/resizable-options.interface';
18
18
  import { EditorToolsService } from './tools/tools.service';
19
+ import { EditorPasteEvent } from './preventable-events/paste-event';
19
20
  /**
20
21
  * Represents the [Kendo UI Editor component for Angular]({% slug overview_editor %}).
21
22
  */
@@ -70,14 +71,6 @@ export declare class EditorComponent implements AfterViewInit, ControlValueAcces
70
71
  * The hint, which is displayed when the component is empty.
71
72
  */
72
73
  placeholder: string;
73
- /**
74
- * By design, the Editor emits `valueChange`, updates the model and the ToolBar state on each keystroke.
75
- * When you are interested in ignoring the new values for a given amout of time and take only the most recent one, you can use the `updateInterval` property.
76
- * A possible use case is to get the new values and to update the ToolBar state at a maximum rate per second in order to speed up your application.
77
- * The specified interval (in milliseconds) should be a positive number.
78
- * By default the `updateInterval` is set to 100 miliseconds. If set to zero the delay will be disabled entirely.
79
- */
80
- updateInterval: number;
81
74
  /**
82
75
  * By default, whitespace is collapsed as per HTML's rules.
83
76
  * Set to `true` to preserve whitespace, but normalize newlines to spaces.
@@ -107,6 +100,11 @@ export declare class EditorComponent implements AfterViewInit, ControlValueAcces
107
100
  * Fires when the content area of the Editor is focused ([see example]({% slug overview_editor %}#toc-events)).
108
101
  */
109
102
  onFocus: EventEmitter<undefined>;
103
+ /**
104
+ * Fires when the user performs paste in the content area of the Editor ([see example]({% slug overview_editor %}#toc-events)).
105
+ * The event is preventable. If you cancel it, the Editor content will not change.
106
+ */
107
+ paste: EventEmitter<EditorPasteEvent>;
110
108
  /**
111
109
  * Fires when the content area of the Editor is blurred ([see example]({% slug overview_editor %}#toc-events)).
112
110
  */
@@ -159,13 +157,16 @@ export declare class EditorComponent implements AfterViewInit, ControlValueAcces
159
157
  private subs;
160
158
  private _view;
161
159
  private _value;
162
- private _previousValue;
163
160
  private _disabled;
164
161
  private _readonly;
165
162
  private _schema;
166
163
  private _plugins;
167
164
  private _placeholder;
168
165
  private _styleObserver;
166
+ private trOnChange;
167
+ private htmlOnChange;
168
+ private inForm;
169
+ private _pasteEvent;
169
170
  private afterViewInit;
170
171
  private contentAreaLoaded;
171
172
  constructor(dialogService: DialogService, localization: LocalizationService, cdr: ChangeDetectorRef, ngZone: NgZone, element: ElementRef, toolsService: EditorToolsService);
@@ -279,8 +280,12 @@ export declare class EditorComponent implements AfterViewInit, ControlValueAcces
279
280
  */
280
281
  isEmpty(): boolean;
281
282
  private initialize;
283
+ private dispatchTransaction;
284
+ private transformPastedHTML;
285
+ private changeValue;
286
+ private onChangeCallback;
282
287
  private normalizeSize;
283
288
  private normalizeProperties;
284
- private onChangeCallback;
285
289
  private onTouchedCallback;
290
+ private onPaste;
286
291
  }