@progress/kendo-angular-editor 2.5.0 → 3.0.0-dev.202201191455
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +1 -1
- package/NOTICE.txt +119 -79
- package/README.md +1 -1
- package/dist/cdn/js/kendo-angular-editor.js +2 -2
- package/dist/cdn/main.js +1 -1
- package/dist/es/common/error-messages.js +4 -3
- package/dist/es/config/command-icons.js +1 -0
- package/dist/es/config/commands.js +18 -17
- package/dist/es/config/schema.js +2 -4
- package/dist/es/config/table-commands.js +1 -363
- package/dist/es/dialogs/colorpicker-dialog.component.js +1 -1
- package/dist/es/dialogs/file-link-dialog.component.js +1 -1
- package/dist/es/dialogs/image-dialog.component.js +1 -1
- package/dist/es/editor-toolbar-state.js +12 -2
- package/dist/es/editor.component.js +103 -75
- package/dist/es/editor.module.js +6 -3
- package/dist/es/index.js +2 -0
- package/dist/es/localization/messages.js +4 -0
- package/dist/es/main.js +1 -0
- package/dist/es/package-metadata.js +1 -1
- package/dist/{es2015/config/table-nodes.d.ts → es/preventable-events/paste-event-data.js} +0 -5
- package/dist/es/preventable-events/paste-event.js +25 -0
- package/dist/es/tools/blockquote/editor-blockquote-button.directive.js +48 -0
- package/dist/es/tools/colorpicker/editor-colorpicker.component.js +24 -7
- package/dist/es/tools/format/editor-format-dropdownlist.component.js +1 -1
- package/dist/es/tools/format/editor-format.component.js +0 -1
- package/dist/es/tools/tables/popup-table-grid.component.js +1 -1
- package/dist/es2015/common/commands.d.ts +1 -1
- package/dist/es2015/common/error-messages.js +4 -3
- package/dist/es2015/common/format-item.interface.d.ts +1 -1
- package/dist/es2015/common/paste-cleanup-settings.d.ts +14 -0
- package/dist/es2015/config/command-icons.js +1 -0
- package/dist/es2015/config/commands.js +18 -17
- package/dist/es2015/config/schema.d.ts +1 -1
- package/dist/es2015/config/schema.js +2 -3
- package/dist/es2015/config/table-commands.d.ts +0 -36
- package/dist/es2015/config/table-commands.js +1 -357
- package/dist/es2015/dialogs/colorpicker-dialog.component.js +1 -1
- package/dist/es2015/dialogs/file-link-dialog.component.js +4 -4
- package/dist/es2015/dialogs/image-dialog.component.js +4 -4
- package/dist/es2015/editor-toolbar-state.js +12 -2
- package/dist/es2015/editor.component.d.ts +16 -11
- package/dist/es2015/editor.component.js +105 -75
- package/dist/es2015/editor.module.js +6 -3
- package/dist/es2015/index.d.ts +2 -0
- package/dist/es2015/index.js +2 -0
- package/dist/es2015/index.metadata.json +1 -1
- package/dist/es2015/localization/messages.d.ts +4 -0
- package/dist/es2015/localization/messages.js +4 -0
- package/dist/es2015/main.d.ts +2 -0
- package/dist/es2015/main.js +1 -0
- package/dist/es2015/package-metadata.js +1 -1
- package/dist/es2015/preventable-events/paste-event-data.d.ts +21 -0
- package/dist/es2015/preventable-events/paste-event-data.js +4 -0
- package/dist/es2015/preventable-events/paste-event.d.ts +27 -0
- package/dist/es2015/preventable-events/paste-event.js +20 -0
- package/dist/es2015/tools/blockquote/editor-blockquote-button.directive.d.ts +30 -0
- package/dist/es2015/tools/blockquote/editor-blockquote-button.directive.js +45 -0
- package/dist/es2015/tools/colorpicker/editor-colorpicker.component.d.ts +8 -2
- package/dist/es2015/tools/colorpicker/editor-colorpicker.component.js +20 -7
- package/dist/es2015/tools/format/editor-format-dropdownlist.component.js +0 -4
- package/dist/es2015/tools/format/editor-format.component.js +0 -1
- package/dist/es2015/tools/tables/popup-table-grid.component.js +2 -2
- package/dist/fesm2015/index.js +354 -1624
- package/dist/fesm5/index.js +365 -1649
- package/dist/npm/common/error-messages.js +4 -2
- package/dist/npm/config/command-icons.js +1 -0
- package/dist/npm/config/commands.js +16 -14
- package/dist/npm/config/schema.js +2 -4
- package/dist/npm/config/table-commands.js +1 -368
- package/dist/npm/dialogs/colorpicker-dialog.component.js +1 -1
- package/dist/npm/dialogs/file-link-dialog.component.js +1 -1
- package/dist/npm/dialogs/image-dialog.component.js +1 -1
- package/dist/npm/editor-toolbar-state.js +11 -1
- package/dist/npm/editor.component.js +99 -71
- package/dist/npm/editor.module.js +7 -4
- package/dist/npm/index.js +5 -0
- package/dist/npm/localization/messages.js +4 -0
- package/dist/npm/main.js +2 -0
- package/dist/npm/package-metadata.js +1 -1
- package/dist/npm/preventable-events/paste-event-data.js +6 -0
- package/dist/npm/preventable-events/paste-event.js +27 -0
- package/dist/npm/tools/blockquote/editor-blockquote-button.directive.js +50 -0
- package/dist/npm/tools/colorpicker/editor-colorpicker.component.js +24 -7
- package/dist/npm/tools/format/editor-format-dropdownlist.component.js +1 -1
- package/dist/npm/tools/format/editor-format.component.js +0 -1
- package/dist/npm/tools/tables/popup-table-grid.component.js +1 -1
- package/dist/systemjs/kendo-angular-editor.js +1 -1
- package/package.json +18 -18
- package/dist/es/config/table-nodes.js +0 -146
- package/dist/es/config/tables/CellSelection.js +0 -268
- package/dist/es/config/tables/TableMap.js +0 -333
- package/dist/es/config/tables/table-utils.js +0 -302
- package/dist/es2015/config/table-nodes.js +0 -145
- package/dist/es2015/config/tables/CellSelection.d.ts +0 -35
- package/dist/es2015/config/tables/CellSelection.js +0 -256
- package/dist/es2015/config/tables/TableMap.d.ts +0 -35
- package/dist/es2015/config/tables/TableMap.js +0 -329
- package/dist/es2015/config/tables/table-utils.d.ts +0 -77
- package/dist/es2015/config/tables/table-utils.js +0 -299
- package/dist/npm/config/table-nodes.js +0 -157
- package/dist/npm/config/tables/CellSelection.js +0 -270
- package/dist/npm/config/tables/TableMap.js +0 -338
- package/dist/npm/config/tables/table-utils.js +0 -307
|
@@ -1,329 +0,0 @@
|
|
|
1
|
-
/**-----------------------------------------------------------------------------------------
|
|
2
|
-
* Copyright © 2021 Progress Software Corporation. All rights reserved.
|
|
3
|
-
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
|
-
*-------------------------------------------------------------------------------------------*/
|
|
5
|
-
import { isTable, isTableBody, isTableHead, isTableFoot } from '../utils';
|
|
6
|
-
// Because working with row and column-spanning cells is not quite
|
|
7
|
-
// trivial, this code builds up a descriptive structure for a given
|
|
8
|
-
// table node. The structures are cached with the (persistent) table
|
|
9
|
-
// nodes as key, so that they only have to be recomputed when the
|
|
10
|
-
// content of the table changes.
|
|
11
|
-
//
|
|
12
|
-
// This does mean that they have to store table-relative, not
|
|
13
|
-
// document-relative positions. So code that uses them will typically
|
|
14
|
-
// compute the start position of the table and offset positions passed
|
|
15
|
-
// to or gotten from this structure by that amount.
|
|
16
|
-
let readFromCache;
|
|
17
|
-
let addToCache;
|
|
18
|
-
// Prefer using a weak map to cache table maps. Fall back on a
|
|
19
|
-
// fixed-size cache if that's not supported.
|
|
20
|
-
if (typeof WeakMap !== 'undefined') {
|
|
21
|
-
let cache = new WeakMap();
|
|
22
|
-
readFromCache = key => cache.get(key);
|
|
23
|
-
addToCache = (key, value) => {
|
|
24
|
-
cache.set(key, value);
|
|
25
|
-
return value;
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
let cache = [];
|
|
30
|
-
let cacheSize = 10;
|
|
31
|
-
let cachePos = 0;
|
|
32
|
-
readFromCache = key => {
|
|
33
|
-
for (let i = 0; i < cache.length; i += 2) {
|
|
34
|
-
if (cache[i] === key) {
|
|
35
|
-
return cache[i + 1];
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
addToCache = (key, value) => {
|
|
40
|
-
if (cachePos === cacheSize) {
|
|
41
|
-
cachePos = 0;
|
|
42
|
-
}
|
|
43
|
-
cache[cachePos++] = key;
|
|
44
|
-
return (cache[cachePos++] = value);
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
const findWidth = (table) => {
|
|
48
|
-
let width = -1;
|
|
49
|
-
let hasRowSpan = false;
|
|
50
|
-
for (let row = 0; row < table.childCount; row++) {
|
|
51
|
-
const rowNode = table.child(row);
|
|
52
|
-
let rowWidth = 0;
|
|
53
|
-
if (hasRowSpan) {
|
|
54
|
-
for (let j = 0; j < row; j++) {
|
|
55
|
-
const prevRow = table.child(j);
|
|
56
|
-
for (let i = 0; i < prevRow.childCount; i++) {
|
|
57
|
-
const cell = prevRow.child(i);
|
|
58
|
-
if (j + cell.attrs.rowspan > row) {
|
|
59
|
-
rowWidth += cell.attrs.colspan;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
// check if the cell spans accross multiple columns
|
|
65
|
-
for (let i = 0; i < rowNode.childCount; i++) {
|
|
66
|
-
const cell = rowNode.child(i);
|
|
67
|
-
rowWidth += cell.attrs.colspan;
|
|
68
|
-
if (cell.attrs.rowspan > 1) {
|
|
69
|
-
hasRowSpan = true;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
if (width === -1) {
|
|
73
|
-
width = rowWidth;
|
|
74
|
-
}
|
|
75
|
-
else if (width !== rowWidth) {
|
|
76
|
-
width = Math.max(width, rowWidth);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return width;
|
|
80
|
-
};
|
|
81
|
-
const ɵ0 = findWidth;
|
|
82
|
-
const freshColWidth = attrs => {
|
|
83
|
-
if (attrs.colwidth) {
|
|
84
|
-
return attrs.colwidth.slice();
|
|
85
|
-
}
|
|
86
|
-
const result = [];
|
|
87
|
-
for (let i = 0; i < attrs.colspan; i++) {
|
|
88
|
-
result.push(0);
|
|
89
|
-
}
|
|
90
|
-
return result;
|
|
91
|
-
};
|
|
92
|
-
const ɵ1 = freshColWidth;
|
|
93
|
-
const findBadColWidths = (map, colWidths, table) => {
|
|
94
|
-
if (!map.problems) {
|
|
95
|
-
map.problems = [];
|
|
96
|
-
}
|
|
97
|
-
for (let i = 0, seen = {}; i < map.map.length; i++) {
|
|
98
|
-
const pos = map.map[i];
|
|
99
|
-
if (seen[pos]) {
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
102
|
-
seen[pos] = true;
|
|
103
|
-
let node = table.nodeAt(pos);
|
|
104
|
-
let updated = null;
|
|
105
|
-
for (let j = 0; j < node.attrs.colspan; j++) {
|
|
106
|
-
const col = (i + j) % map.width;
|
|
107
|
-
const colWidth = colWidths[col * 2];
|
|
108
|
-
if (colWidth != null && (!node.attrs.colwidth || node.attrs.colwidth[j] !== colWidth)) {
|
|
109
|
-
(updated || (updated = freshColWidth(node.attrs)))[j] = colWidth;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
if (updated) {
|
|
113
|
-
map.problems.unshift({ type: 'colwidth mismatch', pos, colwidth: updated });
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
const ɵ2 = findBadColWidths;
|
|
118
|
-
// Compute a table map.
|
|
119
|
-
const computeMap = tableNode => {
|
|
120
|
-
if (!isTable(tableNode) && !isTableBody(tableNode) && !isTableHead(tableNode) && !isTableFoot(tableNode)) {
|
|
121
|
-
throw new RangeError('Not a table node: ' + tableNode.type.name);
|
|
122
|
-
}
|
|
123
|
-
const width = findWidth(tableNode);
|
|
124
|
-
const height = tableNode.childCount;
|
|
125
|
-
const map = [];
|
|
126
|
-
let mapPos = 0;
|
|
127
|
-
let problems = null;
|
|
128
|
-
const colWidths = [];
|
|
129
|
-
for (let i = 0, e = width * height; i < e; i++) {
|
|
130
|
-
map[i] = 0;
|
|
131
|
-
}
|
|
132
|
-
for (let row = 0, pos = 0; row < height; row++) {
|
|
133
|
-
const rowNode = tableNode.child(row);
|
|
134
|
-
pos++;
|
|
135
|
-
for (let i = 0;; i++) {
|
|
136
|
-
while (mapPos < map.length && map[mapPos] !== 0) {
|
|
137
|
-
mapPos++;
|
|
138
|
-
}
|
|
139
|
-
if (i === rowNode.childCount) {
|
|
140
|
-
break;
|
|
141
|
-
}
|
|
142
|
-
const cellNode = rowNode.child(i);
|
|
143
|
-
const { colspan, rowspan, colwidth } = cellNode.attrs;
|
|
144
|
-
for (let h = 0; h < rowspan; h++) {
|
|
145
|
-
if (h + row >= height) {
|
|
146
|
-
(problems || (problems = [])).push({ type: 'overlong_rowspan', pos, n: rowspan - h });
|
|
147
|
-
break;
|
|
148
|
-
}
|
|
149
|
-
const start = mapPos + h * width;
|
|
150
|
-
for (let w = 0; w < colspan; w++) {
|
|
151
|
-
if (map[start + w] === 0) {
|
|
152
|
-
map[start + w] = pos;
|
|
153
|
-
}
|
|
154
|
-
else {
|
|
155
|
-
(problems || (problems = [])).push({ type: 'collision', row, pos, n: colspan - w });
|
|
156
|
-
}
|
|
157
|
-
const colW = colwidth && colwidth[w];
|
|
158
|
-
if (colW) {
|
|
159
|
-
const widthIndex = ((start + w) % width) * 2, prev = colWidths[widthIndex];
|
|
160
|
-
if (prev == null || (prev !== colW && colWidths[widthIndex + 1] === 1)) {
|
|
161
|
-
colWidths[widthIndex] = colW;
|
|
162
|
-
colWidths[widthIndex + 1] = 1;
|
|
163
|
-
}
|
|
164
|
-
else if (prev === colW) {
|
|
165
|
-
colWidths[widthIndex + 1]++;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
mapPos += colspan;
|
|
171
|
-
pos += cellNode.nodeSize;
|
|
172
|
-
}
|
|
173
|
-
const expectedPos = (row + 1) * width;
|
|
174
|
-
let missing = 0;
|
|
175
|
-
while (mapPos < expectedPos) {
|
|
176
|
-
if (map[mapPos++] === 0) {
|
|
177
|
-
missing++;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
if (missing) {
|
|
181
|
-
(problems || (problems = [])).push({ type: 'missing', row, n: missing });
|
|
182
|
-
}
|
|
183
|
-
pos++;
|
|
184
|
-
}
|
|
185
|
-
const tableMap = new TableMap(width, height, map, problems);
|
|
186
|
-
let badWidths = false;
|
|
187
|
-
// For columns that have defined widths, but whose widths disagree
|
|
188
|
-
// between rows, fix up the cells whose width doesn't match the
|
|
189
|
-
// computed one.
|
|
190
|
-
for (let i = 0; !badWidths && i < colWidths.length; i += 2) {
|
|
191
|
-
if (colWidths[i] != null && colWidths[i + 1] < height) {
|
|
192
|
-
badWidths = true;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
if (badWidths) {
|
|
196
|
-
findBadColWidths(tableMap, colWidths, tableNode);
|
|
197
|
-
}
|
|
198
|
-
return tableMap;
|
|
199
|
-
};
|
|
200
|
-
const ɵ3 = computeMap;
|
|
201
|
-
/**
|
|
202
|
-
* @hidden
|
|
203
|
-
*/
|
|
204
|
-
export class Rect {
|
|
205
|
-
constructor(left, top, right, bottom) {
|
|
206
|
-
this.left = left;
|
|
207
|
-
this.top = top;
|
|
208
|
-
this.right = right;
|
|
209
|
-
this.bottom = bottom;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* @hidden
|
|
214
|
-
*/
|
|
215
|
-
export class TableMap {
|
|
216
|
-
// :: (Node) → TableMap
|
|
217
|
-
// Find the table map for the given table node.
|
|
218
|
-
static get(table) {
|
|
219
|
-
return readFromCache(table) || addToCache(table, computeMap(table));
|
|
220
|
-
}
|
|
221
|
-
constructor(width, height, map, problems) {
|
|
222
|
-
// :: number The width of the table
|
|
223
|
-
this.width = width;
|
|
224
|
-
// :: number The table's height
|
|
225
|
-
this.height = height;
|
|
226
|
-
// :: [number] A width * height array with the start position of
|
|
227
|
-
// the cell covering that part of the table in each slot
|
|
228
|
-
this.map = map;
|
|
229
|
-
// An optional array of problems (cell overlap or non-rectangular
|
|
230
|
-
// shape) for the table, used by the table normalizer.
|
|
231
|
-
this.problems = problems;
|
|
232
|
-
}
|
|
233
|
-
// :: (number) → Rect
|
|
234
|
-
// Find the dimensions of the cell at the given position.
|
|
235
|
-
findCell(pos) {
|
|
236
|
-
for (let i = 0; i < this.map.length; i++) {
|
|
237
|
-
const curPos = this.map[i];
|
|
238
|
-
if (curPos !== pos) {
|
|
239
|
-
continue;
|
|
240
|
-
}
|
|
241
|
-
const left = i % this.width;
|
|
242
|
-
const top = Math.floor(i / this.width);
|
|
243
|
-
let right = left + 1;
|
|
244
|
-
let bottom = top + 1;
|
|
245
|
-
for (let j = 1; right < this.width && this.map[i + j] === curPos; j++) {
|
|
246
|
-
right++;
|
|
247
|
-
}
|
|
248
|
-
for (let j = 1; bottom < this.height && this.map[i + this.width * j] === curPos; j++) {
|
|
249
|
-
bottom++;
|
|
250
|
-
}
|
|
251
|
-
return new Rect(left, top, right, bottom);
|
|
252
|
-
}
|
|
253
|
-
throw new RangeError('No cell with offset ' + pos + ' found');
|
|
254
|
-
}
|
|
255
|
-
// :: (number) → number
|
|
256
|
-
// Find the left side of the cell at the given position.
|
|
257
|
-
colCount(pos) {
|
|
258
|
-
for (let i = 0; i < this.map.length; i++) {
|
|
259
|
-
if (this.map[i] === pos) {
|
|
260
|
-
return i % this.width;
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
throw new RangeError('No cell with offset ' + pos + ' found');
|
|
264
|
-
}
|
|
265
|
-
// :: (number, string, number) → ?number
|
|
266
|
-
// Find the next cell in the given direction, starting from the cell
|
|
267
|
-
// at `pos`, if any.
|
|
268
|
-
nextCell(pos, axis, dir) {
|
|
269
|
-
const { left, right, top, bottom } = this.findCell(pos);
|
|
270
|
-
if (axis === 'horiz') {
|
|
271
|
-
if (dir < 0 ? left === 0 : right === this.width) {
|
|
272
|
-
return null;
|
|
273
|
-
}
|
|
274
|
-
return this.map[top * this.width + (dir < 0 ? left - 1 : right)];
|
|
275
|
-
}
|
|
276
|
-
else {
|
|
277
|
-
if (dir < 0 ? top === 0 : bottom === this.height) {
|
|
278
|
-
return null;
|
|
279
|
-
}
|
|
280
|
-
return this.map[left + this.width * (dir < 0 ? top - 1 : bottom)];
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
// :: (number, number) → Rect
|
|
284
|
-
// Get the rectangle spanning the two given cells.
|
|
285
|
-
rectBetween(a, b) {
|
|
286
|
-
const { left: leftA, right: rightA, top: topA, bottom: bottomA } = this.findCell(a);
|
|
287
|
-
const { left: leftB, right: rightB, top: topB, bottom: bottomB } = this.findCell(b);
|
|
288
|
-
return new Rect(Math.min(leftA, leftB), Math.min(topA, topB), Math.max(rightA, rightB), Math.max(bottomA, bottomB));
|
|
289
|
-
}
|
|
290
|
-
// :: (Rect) → [number]
|
|
291
|
-
// Return the position of all cells that have the top left corner in
|
|
292
|
-
// the given rectangle.
|
|
293
|
-
cellsInRect(rect) {
|
|
294
|
-
const result = [];
|
|
295
|
-
const seen = {};
|
|
296
|
-
for (let row = rect.top; row < rect.bottom; row++) {
|
|
297
|
-
for (let col = rect.left; col < rect.right; col++) {
|
|
298
|
-
const index = row * this.width + col, pos = this.map[index];
|
|
299
|
-
if (seen[pos]) {
|
|
300
|
-
continue;
|
|
301
|
-
}
|
|
302
|
-
seen[pos] = true;
|
|
303
|
-
if ((col !== rect.left || !col || this.map[index - 1] !== pos) &&
|
|
304
|
-
(row !== rect.top || !row || this.map[index - this.width] !== pos)) {
|
|
305
|
-
result.push(pos);
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
return result;
|
|
310
|
-
}
|
|
311
|
-
// :: (number, number, Node) → number
|
|
312
|
-
// Return the position at which the cell at the given row and column
|
|
313
|
-
// starts, or would start, if a cell started there.
|
|
314
|
-
positionAt(row, col, table) {
|
|
315
|
-
for (let i = 0, rowStart = 0;; i++) {
|
|
316
|
-
const rowEnd = rowStart + table.child(i).nodeSize;
|
|
317
|
-
if (i === row) {
|
|
318
|
-
let index = col + row * this.width, rowEndIndex = (row + 1) * this.width;
|
|
319
|
-
// Skip past cells from previous rows (via rowspan)
|
|
320
|
-
while (index < rowEndIndex && this.map[index] < rowStart) {
|
|
321
|
-
index++;
|
|
322
|
-
}
|
|
323
|
-
return index === rowEndIndex ? rowEnd - 1 : this.map[index];
|
|
324
|
-
}
|
|
325
|
-
rowStart = rowEnd;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
export { ɵ0, ɵ1, ɵ2, ɵ3 };
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
/**-----------------------------------------------------------------------------------------
|
|
2
|
-
* Copyright © 2021 Progress Software Corporation. All rights reserved.
|
|
3
|
-
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
|
-
*-------------------------------------------------------------------------------------------*/
|
|
5
|
-
import { NodeType, Node, EditorState, ResolvedPos, Schema, Selection } from '@progress/kendo-editor-common';
|
|
6
|
-
import { Rect } from './TableMap';
|
|
7
|
-
import { Predicate } from '../../common/predicate';
|
|
8
|
-
/**
|
|
9
|
-
* @hidden
|
|
10
|
-
*/
|
|
11
|
-
export declare const findParentNodeClosestToPos: ($pos: ResolvedPos<any>, predicate: Predicate<any>) => {
|
|
12
|
-
start: number;
|
|
13
|
-
pos: number;
|
|
14
|
-
depth: number;
|
|
15
|
-
node: Node<any>;
|
|
16
|
-
};
|
|
17
|
-
/**
|
|
18
|
-
* @hidden
|
|
19
|
-
*/
|
|
20
|
-
export declare const createTable: (nodes: {
|
|
21
|
-
table: NodeType<any>;
|
|
22
|
-
table_row: NodeType<any>;
|
|
23
|
-
table_cell: NodeType<any>;
|
|
24
|
-
table_body: NodeType<any>;
|
|
25
|
-
}, rows: number, columns: number) => Node<any>;
|
|
26
|
-
/**
|
|
27
|
-
* @hidden
|
|
28
|
-
*/
|
|
29
|
-
export declare const isInTable: (state: EditorState<any>) => boolean;
|
|
30
|
-
/**
|
|
31
|
-
* @hidden
|
|
32
|
-
*/
|
|
33
|
-
export declare const setAttr: (attrs: any, name: any, value: any) => {};
|
|
34
|
-
/**
|
|
35
|
-
* @hidden
|
|
36
|
-
*/
|
|
37
|
-
export declare const selectedRect: (sel: Selection<any>) => Rect;
|
|
38
|
-
/**
|
|
39
|
-
* @hidden
|
|
40
|
-
*/
|
|
41
|
-
export declare const tableNodeTypes: (schema: Schema<any, any>) => any;
|
|
42
|
-
/**
|
|
43
|
-
* @hidden
|
|
44
|
-
*/
|
|
45
|
-
export declare const rowIsHeader: (map: any, table: any, row: any) => boolean;
|
|
46
|
-
/**
|
|
47
|
-
* @hidden
|
|
48
|
-
*/
|
|
49
|
-
export declare const addColSpan: (attrs: any, pos: any, n?: number) => any;
|
|
50
|
-
/**
|
|
51
|
-
* @hidden
|
|
52
|
-
*/
|
|
53
|
-
export declare const removeColSpan: (attrs: any, pos: any, n?: number) => any;
|
|
54
|
-
/**
|
|
55
|
-
* @hidden
|
|
56
|
-
*/
|
|
57
|
-
export declare const isCellEmpty: (cell: any) => boolean;
|
|
58
|
-
/**
|
|
59
|
-
* @hidden
|
|
60
|
-
*/
|
|
61
|
-
export declare const splitCellWithType: (getCellType: any) => (state: any, dispatch: any) => boolean;
|
|
62
|
-
/**
|
|
63
|
-
* @hidden
|
|
64
|
-
*/
|
|
65
|
-
export declare const pointsAtCell: ($pos: ResolvedPos<any>) => Node<any>;
|
|
66
|
-
/**
|
|
67
|
-
* @hidden
|
|
68
|
-
*/
|
|
69
|
-
export declare const inSameTable: ($a: ResolvedPos<any>, $b: ResolvedPos<any>) => boolean;
|
|
70
|
-
/**
|
|
71
|
-
* @hidden
|
|
72
|
-
*/
|
|
73
|
-
export declare const cellsOverlapRectangle: ({ width, height, map }: {
|
|
74
|
-
width: any;
|
|
75
|
-
height: any;
|
|
76
|
-
map: any;
|
|
77
|
-
}, rect: any) => boolean;
|
|
@@ -1,299 +0,0 @@
|
|
|
1
|
-
/**-----------------------------------------------------------------------------------------
|
|
2
|
-
* Copyright © 2021 Progress Software Corporation. All rights reserved.
|
|
3
|
-
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
|
-
*-------------------------------------------------------------------------------------------*/
|
|
5
|
-
import { NodeSelection } from '@progress/kendo-editor-common';
|
|
6
|
-
import { isTableRow, isTableCell } from '../utils';
|
|
7
|
-
import { TableMap } from './TableMap';
|
|
8
|
-
import { CellSelection } from './CellSelection';
|
|
9
|
-
/**
|
|
10
|
-
* @hidden
|
|
11
|
-
*/
|
|
12
|
-
export const findParentNodeClosestToPos = ($pos, predicate) => {
|
|
13
|
-
for (let i = $pos.depth; i > 0; i--) {
|
|
14
|
-
const node = $pos.node(i);
|
|
15
|
-
if (predicate(node)) {
|
|
16
|
-
return {
|
|
17
|
-
start: $pos.start(i),
|
|
18
|
-
pos: i > 0 ? $pos.before(i) : 0,
|
|
19
|
-
depth: i,
|
|
20
|
-
node
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* @hidden
|
|
27
|
-
*/
|
|
28
|
-
export const createTable = (nodes, rows, columns) => {
|
|
29
|
-
const { table, table_body, table_row, table_cell } = nodes;
|
|
30
|
-
const tableRows = [];
|
|
31
|
-
let cells;
|
|
32
|
-
for (let r = 0; r < rows + 1; r++) {
|
|
33
|
-
cells = [];
|
|
34
|
-
for (let c = 0; c < columns + 1; c++) {
|
|
35
|
-
cells.push(table_cell.createAndFill());
|
|
36
|
-
}
|
|
37
|
-
tableRows.push(table_row.createAndFill(undefined, cells));
|
|
38
|
-
}
|
|
39
|
-
const body = table_body.createAndFill(undefined, tableRows);
|
|
40
|
-
return table.createAndFill(undefined, body);
|
|
41
|
-
};
|
|
42
|
-
/**
|
|
43
|
-
* @hidden
|
|
44
|
-
*/
|
|
45
|
-
export const isInTable = (state) => {
|
|
46
|
-
const $head = state.selection.$head;
|
|
47
|
-
for (let d = $head.depth; d > 0; d--) {
|
|
48
|
-
if (isTableRow($head.node(d))) {
|
|
49
|
-
return true;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
return false;
|
|
53
|
-
};
|
|
54
|
-
/**
|
|
55
|
-
* @hidden
|
|
56
|
-
*/
|
|
57
|
-
export const setAttr = (attrs, name, value) => {
|
|
58
|
-
const result = {};
|
|
59
|
-
// tslint:disable-next-line
|
|
60
|
-
for (const prop in attrs) {
|
|
61
|
-
result[prop] = attrs[prop];
|
|
62
|
-
}
|
|
63
|
-
result[name] = value;
|
|
64
|
-
return result;
|
|
65
|
-
};
|
|
66
|
-
const cellNear = ($pos) => {
|
|
67
|
-
for (let after = $pos.nodeAfter, pos = $pos.pos; after; after = after.firstChild, pos++) {
|
|
68
|
-
const role = after.type.spec.tableRole;
|
|
69
|
-
if (role === 'cell' || role === 'header_cell') {
|
|
70
|
-
return $pos.doc.resolve(pos);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
for (let before = $pos.nodeBefore, pos = $pos.pos; before; before = before.lastChild, pos--) {
|
|
74
|
-
const role = before.type.spec.tableRole;
|
|
75
|
-
if (role === 'cell' || role === 'header_cell') {
|
|
76
|
-
return $pos.doc.resolve(pos - before.nodeSize);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
const ɵ0 = cellNear;
|
|
81
|
-
const cellAround = ($pos) => {
|
|
82
|
-
for (let d = $pos.depth - 1; d > 0; d--) {
|
|
83
|
-
if (isTableRow($pos.node(d))) {
|
|
84
|
-
return $pos.node(0).resolve($pos.before(d + 1));
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
return null;
|
|
88
|
-
};
|
|
89
|
-
const ɵ1 = cellAround;
|
|
90
|
-
const selectionCell = (sel) => {
|
|
91
|
-
if (sel instanceof CellSelection && sel.$anchorCell) {
|
|
92
|
-
return sel.$anchorCell.pos > sel.$headCell.pos ? sel.$anchorCell : sel.$headCell;
|
|
93
|
-
}
|
|
94
|
-
else if (sel instanceof NodeSelection && sel.node && isTableCell(sel.node)) {
|
|
95
|
-
return sel.$anchor;
|
|
96
|
-
}
|
|
97
|
-
return cellAround(sel.$head) || cellNear(sel.$head);
|
|
98
|
-
};
|
|
99
|
-
const ɵ2 = selectionCell;
|
|
100
|
-
/**
|
|
101
|
-
* @hidden
|
|
102
|
-
*/
|
|
103
|
-
// Helper to get the selected rectangle in a table, if any. Adds table
|
|
104
|
-
// map, table node, and table start offset to the object for
|
|
105
|
-
// convenience.
|
|
106
|
-
export const selectedRect = (sel) => {
|
|
107
|
-
// create arr of rect for each table section
|
|
108
|
-
// there has to be a rect for thead, tbody and tfoot(if each exists)
|
|
109
|
-
// and NOT for colgroups
|
|
110
|
-
const $pos = selectionCell(sel);
|
|
111
|
-
const table = $pos.node(-1);
|
|
112
|
-
const tableStart = $pos.start(-1);
|
|
113
|
-
const map = TableMap.get(table);
|
|
114
|
-
const rect = sel instanceof CellSelection
|
|
115
|
-
? map.rectBetween(sel.$anchorCell.pos - tableStart, sel.$headCell.pos - tableStart)
|
|
116
|
-
: map.findCell($pos.pos - tableStart);
|
|
117
|
-
rect.tableStart = tableStart;
|
|
118
|
-
rect.map = map;
|
|
119
|
-
rect.table = table;
|
|
120
|
-
return rect;
|
|
121
|
-
};
|
|
122
|
-
/**
|
|
123
|
-
* @hidden
|
|
124
|
-
*/
|
|
125
|
-
// this has to be removed since the schema should not have roles inside NodeSpec.
|
|
126
|
-
export const tableNodeTypes = (schema) => {
|
|
127
|
-
let result = schema.cached.tableNodeTypes;
|
|
128
|
-
if (!result) {
|
|
129
|
-
result = schema.cached.tableNodeTypes = {};
|
|
130
|
-
// tslint:disable-next-line
|
|
131
|
-
for (const name in schema.nodes) {
|
|
132
|
-
const type = schema.nodes[name];
|
|
133
|
-
const role = type.spec.tableRole;
|
|
134
|
-
if (role) {
|
|
135
|
-
result[role] = type;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
return result;
|
|
140
|
-
};
|
|
141
|
-
/**
|
|
142
|
-
* @hidden
|
|
143
|
-
*/
|
|
144
|
-
export const rowIsHeader = (map, table, row) => {
|
|
145
|
-
const headerCell = tableNodeTypes(table.type.schema).header_cell;
|
|
146
|
-
for (let col = 0; col < map.width; col++) {
|
|
147
|
-
if (table.nodeAt(map.map[col + row * map.width]).type !== headerCell) {
|
|
148
|
-
return false;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
return true;
|
|
152
|
-
};
|
|
153
|
-
/**
|
|
154
|
-
* @hidden
|
|
155
|
-
*/
|
|
156
|
-
export const addColSpan = (attrs, pos, n = 1) => {
|
|
157
|
-
const result = setAttr(attrs, 'colspan', attrs.colspan + n);
|
|
158
|
-
if (result.colwidth) {
|
|
159
|
-
result.colwidth = result.colwidth.slice();
|
|
160
|
-
for (let i = 0; i < n; i++) {
|
|
161
|
-
result.colwidth.splice(pos, 0, 0);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
return result;
|
|
165
|
-
};
|
|
166
|
-
/**
|
|
167
|
-
* @hidden
|
|
168
|
-
*/
|
|
169
|
-
export const removeColSpan = (attrs, pos, n = 1) => {
|
|
170
|
-
const result = setAttr(attrs, 'colspan', attrs.colspan - n);
|
|
171
|
-
if (result.colwidth) {
|
|
172
|
-
result.colwidth = result.colwidth.slice();
|
|
173
|
-
result.colwidth.splice(pos, n);
|
|
174
|
-
if (!result.colwidth.some(w => w > 0)) {
|
|
175
|
-
result.colwidth = null;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
return result;
|
|
179
|
-
};
|
|
180
|
-
/**
|
|
181
|
-
* @hidden
|
|
182
|
-
*/
|
|
183
|
-
export const isCellEmpty = cell => {
|
|
184
|
-
const c = cell.content;
|
|
185
|
-
return c.childCount === 1 && c.firstChild.isTextblock && c.firstChild.childCount === 0;
|
|
186
|
-
};
|
|
187
|
-
const cellWrapping = ($pos) => {
|
|
188
|
-
for (let d = $pos.depth; d > 0; d--) {
|
|
189
|
-
// Sometimes the cell can be in the same depth.
|
|
190
|
-
const role = $pos.node(d).type.spec.tableRole;
|
|
191
|
-
if (role === 'cell' || role === 'header_cell') {
|
|
192
|
-
return $pos.node(d);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
return null;
|
|
196
|
-
};
|
|
197
|
-
const ɵ3 = cellWrapping;
|
|
198
|
-
/**
|
|
199
|
-
* @hidden
|
|
200
|
-
*/
|
|
201
|
-
// Split a selected cell, whose rowpan or colspan is greater than one,
|
|
202
|
-
// into smaller cells with the cell type (th, td) returned by getType function.
|
|
203
|
-
export const splitCellWithType = getCellType => {
|
|
204
|
-
return (state, dispatch) => {
|
|
205
|
-
const sel = state.selection;
|
|
206
|
-
let cellNode;
|
|
207
|
-
let cellPos;
|
|
208
|
-
if (!(sel instanceof CellSelection)) {
|
|
209
|
-
cellNode = cellWrapping(sel.$from);
|
|
210
|
-
if (!cellNode) {
|
|
211
|
-
return false;
|
|
212
|
-
}
|
|
213
|
-
cellPos = cellAround(sel.$from).pos;
|
|
214
|
-
}
|
|
215
|
-
else {
|
|
216
|
-
if (sel.$anchorCell.pos !== sel.$headCell.pos) {
|
|
217
|
-
return false;
|
|
218
|
-
}
|
|
219
|
-
cellNode = sel.$anchorCell.nodeAfter;
|
|
220
|
-
cellPos = sel.$anchorCell.pos;
|
|
221
|
-
}
|
|
222
|
-
if (cellNode.attrs.colspan === 1 && cellNode.attrs.rowspan === 1) {
|
|
223
|
-
return false;
|
|
224
|
-
}
|
|
225
|
-
if (dispatch) {
|
|
226
|
-
let baseAttrs = cellNode.attrs;
|
|
227
|
-
const attrs = [];
|
|
228
|
-
const colwidth = baseAttrs.colwidth;
|
|
229
|
-
if (baseAttrs.rowspan > 1) {
|
|
230
|
-
baseAttrs = setAttr(baseAttrs, 'rowspan', 1);
|
|
231
|
-
}
|
|
232
|
-
if (baseAttrs.colspan > 1) {
|
|
233
|
-
baseAttrs = setAttr(baseAttrs, 'colspan', 1);
|
|
234
|
-
}
|
|
235
|
-
const rect = selectedRect(state);
|
|
236
|
-
const tr = state.tr;
|
|
237
|
-
for (let i = 0; i < rect.right - rect.left; i++) {
|
|
238
|
-
attrs.push(colwidth ? setAttr(baseAttrs, 'colwidth', colwidth && colwidth[i] ? [colwidth[i]] : null) : baseAttrs);
|
|
239
|
-
}
|
|
240
|
-
let lastCell;
|
|
241
|
-
for (let row = rect.top; row < rect.bottom; row++) {
|
|
242
|
-
let pos = rect.map.positionAt(row, rect.left, rect.table);
|
|
243
|
-
if (row === rect.top) {
|
|
244
|
-
pos += cellNode.nodeSize;
|
|
245
|
-
}
|
|
246
|
-
for (let col = rect.left, i = 0; col < rect.right; col++, i++) {
|
|
247
|
-
if (col === rect.left && row === rect.top) {
|
|
248
|
-
continue;
|
|
249
|
-
}
|
|
250
|
-
tr.insert((lastCell = tr.mapping.map(pos + rect.tableStart, 1)), getCellType({ node: cellNode, row, col }).createAndFill(attrs[i]));
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
tr.setNodeMarkup(cellPos, getCellType({ node: cellNode, row: rect.top, col: rect.left }), attrs[0]);
|
|
254
|
-
if (sel instanceof CellSelection) {
|
|
255
|
-
tr.setSelection(new CellSelection(tr.doc.resolve(sel.$anchorCell.pos), lastCell && tr.doc.resolve(lastCell)));
|
|
256
|
-
}
|
|
257
|
-
dispatch(tr);
|
|
258
|
-
}
|
|
259
|
-
return true;
|
|
260
|
-
};
|
|
261
|
-
};
|
|
262
|
-
/**
|
|
263
|
-
* @hidden
|
|
264
|
-
*/
|
|
265
|
-
export const pointsAtCell = ($pos) => {
|
|
266
|
-
return isTableRow($pos.parent) && $pos.nodeAfter;
|
|
267
|
-
};
|
|
268
|
-
/**
|
|
269
|
-
* @hidden
|
|
270
|
-
*/
|
|
271
|
-
export const inSameTable = ($a, $b) => {
|
|
272
|
-
return $a.depth === $b.depth && $a.pos >= $b.start(-1) && $a.pos <= $b.end(-1);
|
|
273
|
-
};
|
|
274
|
-
/**
|
|
275
|
-
* @hidden
|
|
276
|
-
*/
|
|
277
|
-
export const cellsOverlapRectangle = ({ width, height, map }, rect) => {
|
|
278
|
-
let indexTop = rect.top * width + rect.left;
|
|
279
|
-
let indexLeft = indexTop;
|
|
280
|
-
let indexBottom = (rect.bottom - 1) * width + rect.left;
|
|
281
|
-
let indexRight = indexTop + (rect.right - rect.left - 1);
|
|
282
|
-
for (let i = rect.top; i < rect.bottom; i++) {
|
|
283
|
-
if ((rect.left > 0 && map[indexLeft] === map[indexLeft - 1]) || (rect.right < width && map[indexRight] === map[indexRight + 1])) {
|
|
284
|
-
return true;
|
|
285
|
-
}
|
|
286
|
-
indexLeft += width;
|
|
287
|
-
indexRight += width;
|
|
288
|
-
}
|
|
289
|
-
for (let i = rect.left; i < rect.right; i++) {
|
|
290
|
-
if ((rect.top > 0 && map[indexTop] === map[indexTop - width]) ||
|
|
291
|
-
(rect.bottom < height && map[indexBottom] === map[indexBottom + width])) {
|
|
292
|
-
return true;
|
|
293
|
-
}
|
|
294
|
-
indexTop++;
|
|
295
|
-
indexBottom++;
|
|
296
|
-
}
|
|
297
|
-
return false;
|
|
298
|
-
};
|
|
299
|
-
export { ɵ0, ɵ1, ɵ2, ɵ3 };
|