px-jspreadsheet-ce 0.0.1

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 (44) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +292 -0
  3. package/dist/index.d.ts +2382 -0
  4. package/dist/index.js +11286 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/jspreadsheet.css +723 -0
  7. package/dist/jspreadsheet.themes.css +104 -0
  8. package/package.json +57 -0
  9. package/src/index.js +95 -0
  10. package/src/test.js +50 -0
  11. package/src/utils/cells.js +36 -0
  12. package/src/utils/columns.js +742 -0
  13. package/src/utils/comments.js +87 -0
  14. package/src/utils/config.js +46 -0
  15. package/src/utils/copyPaste.js +438 -0
  16. package/src/utils/data.js +419 -0
  17. package/src/utils/dispatch.js +115 -0
  18. package/src/utils/download.js +38 -0
  19. package/src/utils/editor.js +430 -0
  20. package/src/utils/events.js +1639 -0
  21. package/src/utils/factory.js +216 -0
  22. package/src/utils/filter.js +128 -0
  23. package/src/utils/footer.js +51 -0
  24. package/src/utils/freeze.js +19 -0
  25. package/src/utils/headers.js +74 -0
  26. package/src/utils/helpers.js +409 -0
  27. package/src/utils/history.js +336 -0
  28. package/src/utils/internal.js +1299 -0
  29. package/src/utils/internalHelpers.js +96 -0
  30. package/src/utils/keys.js +406 -0
  31. package/src/utils/lazyLoading.js +143 -0
  32. package/src/utils/libraryBase.js +5 -0
  33. package/src/utils/merges.js +275 -0
  34. package/src/utils/meta.js +81 -0
  35. package/src/utils/orderBy.js +185 -0
  36. package/src/utils/pagination.js +181 -0
  37. package/src/utils/rows.js +624 -0
  38. package/src/utils/search.js +83 -0
  39. package/src/utils/selection.js +744 -0
  40. package/src/utils/style.js +147 -0
  41. package/src/utils/toolbar.js +566 -0
  42. package/src/utils/version.js +9 -0
  43. package/src/utils/worksheets.js +731 -0
  44. package/src/webcomponent.js +59 -0
@@ -0,0 +1,1639 @@
1
+ import jSuites from 'jsuites';
2
+
3
+ import { closeEditor, openEditor, setCheckRadioValue } from './editor.js';
4
+ import libraryBase from './libraryBase.js';
5
+ import { down, first, last, left, right, up } from './keys.js';
6
+ import { isColMerged, isRowMerged } from './merges.js';
7
+ import { copyData, removeCopySelection, resetSelection, selectAll, updateCornerPosition, updateSelectionFromCoords } from './selection.js';
8
+ import { copy, paste } from './copyPaste.js';
9
+ import { openFilter } from './filter.js';
10
+ import { loadDown, loadUp } from './lazyLoading.js';
11
+ import { setWidth } from './columns.js';
12
+ import { moveRow, setHeight } from './rows.js';
13
+ import version from './version.js';
14
+ import { getCellNameFromCoords } from './helpers.js';
15
+
16
+ const getElement = function (element) {
17
+ let jssSection = 0;
18
+ let jssElement = 0;
19
+
20
+ function path(element) {
21
+ if (element.className) {
22
+ if (element.classList.contains('jss_container')) {
23
+ jssElement = element;
24
+ }
25
+
26
+ if (element.classList.contains('jss_spreadsheet')) {
27
+ jssElement = element.querySelector(':scope > .jtabs-content > .jtabs-selected');
28
+ }
29
+ }
30
+
31
+ if (element.tagName == 'THEAD') {
32
+ jssSection = 1;
33
+ } else if (element.tagName == 'TBODY') {
34
+ jssSection = 2;
35
+ }
36
+
37
+ if (element.parentNode) {
38
+ if (!jssElement) {
39
+ path(element.parentNode);
40
+ }
41
+ }
42
+ }
43
+
44
+ path(element);
45
+
46
+ return [jssElement, jssSection];
47
+ };
48
+
49
+ const mouseUpControls = function (e) {
50
+ if (libraryBase.jspreadsheet.current) {
51
+ // Update cell size
52
+ if (libraryBase.jspreadsheet.current.resizing) {
53
+ // Columns to be updated
54
+ if (libraryBase.jspreadsheet.current.resizing.column) {
55
+ // New width
56
+ const newWidth = parseInt(
57
+ libraryBase.jspreadsheet.current.cols[libraryBase.jspreadsheet.current.resizing.column].colElement.getAttribute('width')
58
+ );
59
+ // Columns
60
+ const columns = libraryBase.jspreadsheet.current.getSelectedColumns();
61
+ if (columns.length > 1) {
62
+ const currentWidth = [];
63
+ for (let i = 0; i < columns.length; i++) {
64
+ currentWidth.push(parseInt(libraryBase.jspreadsheet.current.cols[columns[i]].colElement.getAttribute('width')));
65
+ }
66
+ // Previous width
67
+ const index = columns.indexOf(parseInt(libraryBase.jspreadsheet.current.resizing.column));
68
+ currentWidth[index] = libraryBase.jspreadsheet.current.resizing.width;
69
+ setWidth.call(libraryBase.jspreadsheet.current, columns, newWidth, currentWidth);
70
+ } else {
71
+ setWidth.call(
72
+ libraryBase.jspreadsheet.current,
73
+ parseInt(libraryBase.jspreadsheet.current.resizing.column),
74
+ newWidth,
75
+ libraryBase.jspreadsheet.current.resizing.width
76
+ );
77
+ }
78
+ // Remove border
79
+ libraryBase.jspreadsheet.current.headers[libraryBase.jspreadsheet.current.resizing.column].classList.remove('resizing');
80
+ for (let j = 0; j < libraryBase.jspreadsheet.current.records.length; j++) {
81
+ if (libraryBase.jspreadsheet.current.records[j][libraryBase.jspreadsheet.current.resizing.column]) {
82
+ libraryBase.jspreadsheet.current.records[j][libraryBase.jspreadsheet.current.resizing.column].element.classList.remove('resizing');
83
+ }
84
+ }
85
+ } else {
86
+ // Remove Class
87
+ libraryBase.jspreadsheet.current.rows[libraryBase.jspreadsheet.current.resizing.row].element.children[0].classList.remove('resizing');
88
+ let newHeight = libraryBase.jspreadsheet.current.rows[libraryBase.jspreadsheet.current.resizing.row].element.getAttribute('height');
89
+ setHeight.call(
90
+ libraryBase.jspreadsheet.current,
91
+ libraryBase.jspreadsheet.current.resizing.row,
92
+ newHeight,
93
+ libraryBase.jspreadsheet.current.resizing.height
94
+ );
95
+ // Remove border
96
+ libraryBase.jspreadsheet.current.resizing.element.classList.remove('resizing');
97
+ }
98
+ // Reset resizing helper
99
+ libraryBase.jspreadsheet.current.resizing = null;
100
+ } else if (libraryBase.jspreadsheet.current.dragging) {
101
+ // Reset dragging helper
102
+ if (libraryBase.jspreadsheet.current.dragging) {
103
+ if (libraryBase.jspreadsheet.current.dragging.column) {
104
+ // Target
105
+ const columnId = e.target.getAttribute('data-x');
106
+ // Remove move style
107
+ libraryBase.jspreadsheet.current.headers[libraryBase.jspreadsheet.current.dragging.column].classList.remove('dragging');
108
+ for (let j = 0; j < libraryBase.jspreadsheet.current.rows.length; j++) {
109
+ if (libraryBase.jspreadsheet.current.records[j][libraryBase.jspreadsheet.current.dragging.column]) {
110
+ libraryBase.jspreadsheet.current.records[j][libraryBase.jspreadsheet.current.dragging.column].element.classList.remove('dragging');
111
+ }
112
+ }
113
+ for (let i = 0; i < libraryBase.jspreadsheet.current.headers.length; i++) {
114
+ libraryBase.jspreadsheet.current.headers[i].classList.remove('dragging-left');
115
+ libraryBase.jspreadsheet.current.headers[i].classList.remove('dragging-right');
116
+ }
117
+ // Update position
118
+ if (columnId) {
119
+ if (libraryBase.jspreadsheet.current.dragging.column != libraryBase.jspreadsheet.current.dragging.destination) {
120
+ libraryBase.jspreadsheet.current.moveColumn(
121
+ libraryBase.jspreadsheet.current.dragging.column,
122
+ libraryBase.jspreadsheet.current.dragging.destination
123
+ );
124
+ }
125
+ }
126
+ } else {
127
+ let position;
128
+
129
+ if (libraryBase.jspreadsheet.current.dragging.element.nextSibling) {
130
+ position = parseInt(libraryBase.jspreadsheet.current.dragging.element.nextSibling.getAttribute('data-y'));
131
+ if (libraryBase.jspreadsheet.current.dragging.row < position) {
132
+ position -= 1;
133
+ }
134
+ } else {
135
+ position = parseInt(libraryBase.jspreadsheet.current.dragging.element.previousSibling.getAttribute('data-y'));
136
+ }
137
+ if (libraryBase.jspreadsheet.current.dragging.row != libraryBase.jspreadsheet.current.dragging.destination) {
138
+ moveRow.call(libraryBase.jspreadsheet.current, libraryBase.jspreadsheet.current.dragging.row, position, true);
139
+ }
140
+ libraryBase.jspreadsheet.current.dragging.element.classList.remove('dragging');
141
+ }
142
+ libraryBase.jspreadsheet.current.dragging = null;
143
+ }
144
+ } else {
145
+ // Close any corner selection
146
+ if (libraryBase.jspreadsheet.current.selectedCorner) {
147
+ libraryBase.jspreadsheet.current.selectedCorner = false;
148
+
149
+ // Data to be copied
150
+ if (libraryBase.jspreadsheet.current.selection.length > 0) {
151
+ // Copy data
152
+ copyData.call(
153
+ libraryBase.jspreadsheet.current,
154
+ libraryBase.jspreadsheet.current.selection[0],
155
+ libraryBase.jspreadsheet.current.selection[libraryBase.jspreadsheet.current.selection.length - 1]
156
+ );
157
+
158
+ // Remove selection
159
+ removeCopySelection.call(libraryBase.jspreadsheet.current);
160
+ }
161
+ }
162
+ }
163
+ }
164
+
165
+ // Clear any time control
166
+ if (libraryBase.jspreadsheet.timeControl) {
167
+ clearTimeout(libraryBase.jspreadsheet.timeControl);
168
+ libraryBase.jspreadsheet.timeControl = null;
169
+ }
170
+
171
+ // Mouse up
172
+ libraryBase.jspreadsheet.isMouseAction = false;
173
+ };
174
+
175
+ const mouseDownControls = function (e) {
176
+ e = e || window.event;
177
+
178
+ let mouseButton;
179
+
180
+ if (e.buttons) {
181
+ mouseButton = e.buttons;
182
+ } else if (e.button) {
183
+ mouseButton = e.button;
184
+ } else {
185
+ mouseButton = e.which;
186
+ }
187
+
188
+ // Get elements
189
+ const jssTable = getElement(e.target);
190
+
191
+ if (jssTable[0]) {
192
+ if (libraryBase.jspreadsheet.current != jssTable[0].jssWorksheet) {
193
+ if (libraryBase.jspreadsheet.current) {
194
+ if (libraryBase.jspreadsheet.current.edition) {
195
+ closeEditor.call(libraryBase.jspreadsheet.current, libraryBase.jspreadsheet.current.edition[0], true);
196
+ }
197
+ libraryBase.jspreadsheet.current.resetSelection();
198
+ }
199
+ libraryBase.jspreadsheet.current = jssTable[0].jssWorksheet;
200
+ }
201
+ } else {
202
+ if (libraryBase.jspreadsheet.current) {
203
+ if (libraryBase.jspreadsheet.current.edition) {
204
+ closeEditor.call(libraryBase.jspreadsheet.current, libraryBase.jspreadsheet.current.edition[0], true);
205
+ }
206
+
207
+ if (!e.target.classList.contains('jss_object')) {
208
+ resetSelection.call(libraryBase.jspreadsheet.current, true);
209
+ libraryBase.jspreadsheet.current = null;
210
+ }
211
+ }
212
+ }
213
+
214
+ if (libraryBase.jspreadsheet.current && mouseButton == 1) {
215
+ if (e.target.classList.contains('jss_selectall')) {
216
+ if (libraryBase.jspreadsheet.current) {
217
+ selectAll.call(libraryBase.jspreadsheet.current);
218
+ }
219
+ } else if (e.target.classList.contains('jss_corner')) {
220
+ if (libraryBase.jspreadsheet.current.options.editable != false) {
221
+ libraryBase.jspreadsheet.current.selectedCorner = true;
222
+ }
223
+ } else {
224
+ // Header found
225
+ if (jssTable[1] == 1) {
226
+ const columnId = e.target.getAttribute('data-x');
227
+ if (columnId) {
228
+ // Update cursor
229
+ const info = e.target.getBoundingClientRect();
230
+ if (libraryBase.jspreadsheet.current.options.columnResize != false && info.width - e.offsetX < 6) {
231
+ // Resize helper
232
+ libraryBase.jspreadsheet.current.resizing = {
233
+ mousePosition: e.pageX,
234
+ column: columnId,
235
+ width: info.width,
236
+ };
237
+
238
+ // Border indication
239
+ libraryBase.jspreadsheet.current.headers[columnId].classList.add('resizing');
240
+ for (let j = 0; j < libraryBase.jspreadsheet.current.records.length; j++) {
241
+ if (libraryBase.jspreadsheet.current.records[j][columnId]) {
242
+ libraryBase.jspreadsheet.current.records[j][columnId].element.classList.add('resizing');
243
+ }
244
+ }
245
+ } else if (libraryBase.jspreadsheet.current.options.columnDrag != false && info.height - e.offsetY < 6) {
246
+ if (isColMerged.call(libraryBase.jspreadsheet.current, columnId).length) {
247
+ console.error('Jspreadsheet: This column is part of a merged cell.');
248
+ } else {
249
+ // Reset selection
250
+ libraryBase.jspreadsheet.current.resetSelection();
251
+ // Drag helper
252
+ libraryBase.jspreadsheet.current.dragging = {
253
+ element: e.target,
254
+ column: columnId,
255
+ destination: columnId,
256
+ };
257
+ // Border indication
258
+ libraryBase.jspreadsheet.current.headers[columnId].classList.add('dragging');
259
+ for (let j = 0; j < libraryBase.jspreadsheet.current.records.length; j++) {
260
+ if (libraryBase.jspreadsheet.current.records[j][columnId]) {
261
+ libraryBase.jspreadsheet.current.records[j][columnId].element.classList.add('dragging');
262
+ }
263
+ }
264
+ }
265
+ } else {
266
+ let o, d;
267
+
268
+ if (libraryBase.jspreadsheet.current.selectedHeader && (e.shiftKey || e.ctrlKey)) {
269
+ o = libraryBase.jspreadsheet.current.selectedHeader;
270
+ d = columnId;
271
+ } else {
272
+ // Press to rename
273
+ if (
274
+ libraryBase.jspreadsheet.current.selectedHeader == columnId &&
275
+ libraryBase.jspreadsheet.current.options.allowRenameColumn != false
276
+ ) {
277
+ libraryBase.jspreadsheet.timeControl = setTimeout(function () {
278
+ libraryBase.jspreadsheet.current.setHeader(columnId);
279
+ }, 800);
280
+ }
281
+
282
+ // Keep track of which header was selected first
283
+ libraryBase.jspreadsheet.current.selectedHeader = columnId;
284
+
285
+ // Update selection single column
286
+ o = columnId;
287
+ d = columnId;
288
+ }
289
+
290
+ // Update selection
291
+ updateSelectionFromCoords.call(libraryBase.jspreadsheet.current, o, 0, d, libraryBase.jspreadsheet.current.options.data.length - 1, e);
292
+ }
293
+ } else {
294
+ if (e.target.parentNode.classList.contains('jss_nested')) {
295
+ let c1, c2;
296
+
297
+ if (e.target.getAttribute('data-column')) {
298
+ const column = e.target.getAttribute('data-column').split(',');
299
+ c1 = parseInt(column[0]);
300
+ c2 = parseInt(column[column.length - 1]);
301
+ } else {
302
+ c1 = 0;
303
+ c2 = libraryBase.jspreadsheet.current.options.columns.length - 1;
304
+ }
305
+ updateSelectionFromCoords.call(
306
+ libraryBase.jspreadsheet.current,
307
+ c1,
308
+ 0,
309
+ c2,
310
+ libraryBase.jspreadsheet.current.options.data.length - 1,
311
+ e
312
+ );
313
+ }
314
+ }
315
+ } else {
316
+ libraryBase.jspreadsheet.current.selectedHeader = false;
317
+ }
318
+
319
+ // Body found
320
+ if (jssTable[1] == 2) {
321
+ const rowId = parseInt(e.target.getAttribute('data-y'));
322
+
323
+ if (e.target.classList.contains('jss_row')) {
324
+ const info = e.target.getBoundingClientRect();
325
+ if (libraryBase.jspreadsheet.current.options.rowResize != false && info.height - e.offsetY < 6) {
326
+ // Resize helper
327
+ libraryBase.jspreadsheet.current.resizing = {
328
+ element: e.target.parentNode,
329
+ mousePosition: e.pageY,
330
+ row: rowId,
331
+ height: info.height,
332
+ };
333
+ // Border indication
334
+ e.target.parentNode.classList.add('resizing');
335
+ } else if (libraryBase.jspreadsheet.current.options.rowDrag != false && info.width - e.offsetX < 6) {
336
+ if (isRowMerged.call(libraryBase.jspreadsheet.current, rowId).length) {
337
+ console.error('Jspreadsheet: This row is part of a merged cell');
338
+ } else if (libraryBase.jspreadsheet.current.options.search == true && libraryBase.jspreadsheet.current.results) {
339
+ console.error('Jspreadsheet: Please clear your search before perform this action');
340
+ } else {
341
+ // Reset selection
342
+ libraryBase.jspreadsheet.current.resetSelection();
343
+ // Drag helper
344
+ libraryBase.jspreadsheet.current.dragging = {
345
+ element: e.target.parentNode,
346
+ row: rowId,
347
+ destination: rowId,
348
+ };
349
+ // Border indication
350
+ e.target.parentNode.classList.add('dragging');
351
+ }
352
+ } else {
353
+ let o, d;
354
+ if (libraryBase.jspreadsheet.current.selectedRow != null && (e.shiftKey || e.ctrlKey)) {
355
+ o = libraryBase.jspreadsheet.current.selectedRow;
356
+ d = rowId;
357
+ } else {
358
+ // Keep track of which header was selected first
359
+ libraryBase.jspreadsheet.current.selectedRow = rowId;
360
+
361
+ // Update selection single column
362
+ o = rowId;
363
+ d = rowId;
364
+ }
365
+
366
+ // Update selection
367
+ updateSelectionFromCoords.call(libraryBase.jspreadsheet.current, null, o, null, d, e);
368
+ }
369
+ } else {
370
+ // Jclose
371
+ if (e.target.classList.contains('jclose') && e.target.clientWidth - e.offsetX < 50 && e.offsetY < 50) {
372
+ closeEditor.call(libraryBase.jspreadsheet.current, libraryBase.jspreadsheet.current.edition[0], true);
373
+ } else {
374
+ const getCellCoords = function (element) {
375
+ const x = element.getAttribute('data-x');
376
+ const y = element.getAttribute('data-y');
377
+ if (x && y) {
378
+ return [x, y];
379
+ } else {
380
+ if (element.parentNode) {
381
+ return getCellCoords(element.parentNode);
382
+ }
383
+ }
384
+ };
385
+
386
+ const position = getCellCoords(e.target);
387
+ if (position) {
388
+ const columnId = position[0];
389
+ const rowId = position[1];
390
+ // Close edition
391
+ if (libraryBase.jspreadsheet.current.edition) {
392
+ if (libraryBase.jspreadsheet.current.edition[2] != columnId || libraryBase.jspreadsheet.current.edition[3] != rowId) {
393
+ closeEditor.call(libraryBase.jspreadsheet.current, libraryBase.jspreadsheet.current.edition[0], true);
394
+ }
395
+ }
396
+
397
+ if (!libraryBase.jspreadsheet.current.edition) {
398
+ // Update cell selection
399
+ if (e.shiftKey) {
400
+ updateSelectionFromCoords.call(
401
+ libraryBase.jspreadsheet.current,
402
+ libraryBase.jspreadsheet.current.selectedCell[0],
403
+ libraryBase.jspreadsheet.current.selectedCell[1],
404
+ columnId,
405
+ rowId,
406
+ e
407
+ );
408
+ } else {
409
+ updateSelectionFromCoords.call(libraryBase.jspreadsheet.current, columnId, rowId, undefined, undefined, e);
410
+ }
411
+ }
412
+
413
+ // No full row selected
414
+ libraryBase.jspreadsheet.current.selectedHeader = null;
415
+ libraryBase.jspreadsheet.current.selectedRow = null;
416
+ }
417
+ }
418
+ }
419
+ } else {
420
+ libraryBase.jspreadsheet.current.selectedRow = false;
421
+ }
422
+
423
+ // Pagination
424
+ if (e.target.classList.contains('jss_page')) {
425
+ if (e.target.textContent == '<') {
426
+ libraryBase.jspreadsheet.current.page(0);
427
+ } else if (e.target.textContent == '>') {
428
+ libraryBase.jspreadsheet.current.page(e.target.getAttribute('title') - 1);
429
+ } else {
430
+ libraryBase.jspreadsheet.current.page(e.target.textContent - 1);
431
+ }
432
+ }
433
+ }
434
+
435
+ if (libraryBase.jspreadsheet.current.edition) {
436
+ libraryBase.jspreadsheet.isMouseAction = false;
437
+ } else {
438
+ libraryBase.jspreadsheet.isMouseAction = true;
439
+ }
440
+ } else {
441
+ libraryBase.jspreadsheet.isMouseAction = false;
442
+ }
443
+ };
444
+
445
+ // Mouse move controls
446
+ const mouseMoveControls = function (e) {
447
+ e = e || window.event;
448
+
449
+ let mouseButton;
450
+
451
+ if (e.buttons) {
452
+ mouseButton = e.buttons;
453
+ } else if (e.button) {
454
+ mouseButton = e.button;
455
+ } else {
456
+ mouseButton = e.which;
457
+ }
458
+
459
+ if (!mouseButton) {
460
+ libraryBase.jspreadsheet.isMouseAction = false;
461
+ }
462
+
463
+ if (libraryBase.jspreadsheet.current) {
464
+ if (libraryBase.jspreadsheet.isMouseAction == true) {
465
+ // Resizing is ongoing
466
+ if (libraryBase.jspreadsheet.current.resizing) {
467
+ if (libraryBase.jspreadsheet.current.resizing.column) {
468
+ const width = e.pageX - libraryBase.jspreadsheet.current.resizing.mousePosition;
469
+
470
+ if (libraryBase.jspreadsheet.current.resizing.width + width > 0) {
471
+ const tempWidth = libraryBase.jspreadsheet.current.resizing.width + width;
472
+ libraryBase.jspreadsheet.current.cols[libraryBase.jspreadsheet.current.resizing.column].colElement.setAttribute('width', tempWidth);
473
+
474
+ updateCornerPosition.call(libraryBase.jspreadsheet.current);
475
+ }
476
+ } else {
477
+ const height = e.pageY - libraryBase.jspreadsheet.current.resizing.mousePosition;
478
+
479
+ if (libraryBase.jspreadsheet.current.resizing.height + height > 0) {
480
+ const tempHeight = libraryBase.jspreadsheet.current.resizing.height + height;
481
+ libraryBase.jspreadsheet.current.rows[libraryBase.jspreadsheet.current.resizing.row].element.setAttribute('height', tempHeight);
482
+
483
+ updateCornerPosition.call(libraryBase.jspreadsheet.current);
484
+ }
485
+ }
486
+ } else if (libraryBase.jspreadsheet.current.dragging) {
487
+ if (libraryBase.jspreadsheet.current.dragging.column) {
488
+ const columnId = e.target.getAttribute('data-x');
489
+ if (columnId) {
490
+ if (isColMerged.call(libraryBase.jspreadsheet.current, columnId).length) {
491
+ console.error('Jspreadsheet: This column is part of a merged cell.');
492
+ } else {
493
+ for (let i = 0; i < libraryBase.jspreadsheet.current.headers.length; i++) {
494
+ libraryBase.jspreadsheet.current.headers[i].classList.remove('dragging-left');
495
+ libraryBase.jspreadsheet.current.headers[i].classList.remove('dragging-right');
496
+ }
497
+
498
+ if (libraryBase.jspreadsheet.current.dragging.column == columnId) {
499
+ libraryBase.jspreadsheet.current.dragging.destination = parseInt(columnId);
500
+ } else {
501
+ if (e.target.clientWidth / 2 > e.offsetX) {
502
+ if (libraryBase.jspreadsheet.current.dragging.column < columnId) {
503
+ libraryBase.jspreadsheet.current.dragging.destination = parseInt(columnId) - 1;
504
+ } else {
505
+ libraryBase.jspreadsheet.current.dragging.destination = parseInt(columnId);
506
+ }
507
+ libraryBase.jspreadsheet.current.headers[columnId].classList.add('dragging-left');
508
+ } else {
509
+ if (libraryBase.jspreadsheet.current.dragging.column < columnId) {
510
+ libraryBase.jspreadsheet.current.dragging.destination = parseInt(columnId);
511
+ } else {
512
+ libraryBase.jspreadsheet.current.dragging.destination = parseInt(columnId) + 1;
513
+ }
514
+ libraryBase.jspreadsheet.current.headers[columnId].classList.add('dragging-right');
515
+ }
516
+ }
517
+ }
518
+ }
519
+ } else {
520
+ const rowId = e.target.getAttribute('data-y');
521
+ if (rowId) {
522
+ if (isRowMerged.call(libraryBase.jspreadsheet.current, rowId).length) {
523
+ console.error('Jspreadsheet: This row is part of a merged cell.');
524
+ } else {
525
+ const target = e.target.clientHeight / 2 > e.offsetY ? e.target.parentNode.nextSibling : e.target.parentNode;
526
+ if (libraryBase.jspreadsheet.current.dragging.element != target) {
527
+ e.target.parentNode.parentNode.insertBefore(libraryBase.jspreadsheet.current.dragging.element, target);
528
+ libraryBase.jspreadsheet.current.dragging.destination = Array.prototype.indexOf.call(
529
+ libraryBase.jspreadsheet.current.dragging.element.parentNode.children,
530
+ libraryBase.jspreadsheet.current.dragging.element
531
+ );
532
+ }
533
+ }
534
+ }
535
+ }
536
+ }
537
+ } else {
538
+ const x = e.target.getAttribute('data-x');
539
+ const y = e.target.getAttribute('data-y');
540
+ const rect = e.target.getBoundingClientRect();
541
+
542
+ if (libraryBase.jspreadsheet.current.cursor) {
543
+ libraryBase.jspreadsheet.current.cursor.style.cursor = '';
544
+ libraryBase.jspreadsheet.current.cursor = null;
545
+ }
546
+
547
+ if (e.target.parentNode.parentNode && e.target.parentNode.parentNode.className) {
548
+ if (e.target.parentNode.parentNode.classList.contains('resizable')) {
549
+ if (e.target && x && !y && rect.width - (e.clientX - rect.left) < 6) {
550
+ libraryBase.jspreadsheet.current.cursor = e.target;
551
+ libraryBase.jspreadsheet.current.cursor.style.cursor = 'col-resize';
552
+ } else if (e.target && !x && y && rect.height - (e.clientY - rect.top) < 6) {
553
+ libraryBase.jspreadsheet.current.cursor = e.target;
554
+ libraryBase.jspreadsheet.current.cursor.style.cursor = 'row-resize';
555
+ }
556
+ }
557
+
558
+ if (e.target.parentNode.parentNode.classList.contains('draggable')) {
559
+ if (e.target && !x && y && rect.width - (e.clientX - rect.left) < 6) {
560
+ libraryBase.jspreadsheet.current.cursor = e.target;
561
+ libraryBase.jspreadsheet.current.cursor.style.cursor = 'move';
562
+ } else if (e.target && x && !y && rect.height - (e.clientY - rect.top) < 6) {
563
+ libraryBase.jspreadsheet.current.cursor = e.target;
564
+ libraryBase.jspreadsheet.current.cursor.style.cursor = 'move';
565
+ }
566
+ }
567
+ }
568
+ }
569
+ }
570
+ };
571
+
572
+ /**
573
+ * Update copy selection
574
+ *
575
+ * @param int x, y
576
+ * @return void
577
+ */
578
+ const updateCopySelection = function (x3, y3) {
579
+ const obj = this;
580
+
581
+ // Remove selection
582
+ removeCopySelection.call(obj);
583
+
584
+ // Get elements first and last
585
+ const x1 = obj.selectedContainer[0];
586
+ const y1 = obj.selectedContainer[1];
587
+ const x2 = obj.selectedContainer[2];
588
+ const y2 = obj.selectedContainer[3];
589
+
590
+ if (x3 != null && y3 != null) {
591
+ let px, ux;
592
+
593
+ if (x3 - x2 > 0) {
594
+ px = parseInt(x2) + 1;
595
+ ux = parseInt(x3);
596
+ } else {
597
+ px = parseInt(x3);
598
+ ux = parseInt(x1) - 1;
599
+ }
600
+
601
+ let py, uy;
602
+
603
+ if (y3 - y2 > 0) {
604
+ py = parseInt(y2) + 1;
605
+ uy = parseInt(y3);
606
+ } else {
607
+ py = parseInt(y3);
608
+ uy = parseInt(y1) - 1;
609
+ }
610
+
611
+ if (ux - px <= uy - py) {
612
+ px = parseInt(x1);
613
+ ux = parseInt(x2);
614
+ } else {
615
+ py = parseInt(y1);
616
+ uy = parseInt(y2);
617
+ }
618
+
619
+ for (let j = py; j <= uy; j++) {
620
+ for (let i = px; i <= ux; i++) {
621
+ if (obj.records[j][i] && obj.rows[j].element.style.display != 'none' && obj.records[j][i].element.style.display != 'none') {
622
+ obj.records[j][i].element.classList.add('selection');
623
+ obj.records[py][i].element.classList.add('selection-top');
624
+ obj.records[uy][i].element.classList.add('selection-bottom');
625
+ obj.records[j][px].element.classList.add('selection-left');
626
+ obj.records[j][ux].element.classList.add('selection-right');
627
+
628
+ // Persist selected elements
629
+ obj.selection.push(obj.records[j][i].element);
630
+ }
631
+ }
632
+ }
633
+ }
634
+ };
635
+
636
+ const mouseOverControls = function (e) {
637
+ e = e || window.event;
638
+
639
+ let mouseButton;
640
+
641
+ if (e.buttons) {
642
+ mouseButton = e.buttons;
643
+ } else if (e.button) {
644
+ mouseButton = e.button;
645
+ } else {
646
+ mouseButton = e.which;
647
+ }
648
+
649
+ if (!mouseButton) {
650
+ libraryBase.jspreadsheet.isMouseAction = false;
651
+ }
652
+
653
+ if (libraryBase.jspreadsheet.current && libraryBase.jspreadsheet.isMouseAction == true) {
654
+ // Get elements
655
+ const jssTable = getElement(e.target);
656
+
657
+ if (jssTable[0]) {
658
+ // Avoid cross reference
659
+ if (libraryBase.jspreadsheet.current != jssTable[0].jssWorksheet) {
660
+ if (libraryBase.jspreadsheet.current) {
661
+ return false;
662
+ }
663
+ }
664
+
665
+ let columnId = e.target.getAttribute('data-x');
666
+ const rowId = e.target.getAttribute('data-y');
667
+ if (libraryBase.jspreadsheet.current.resizing || libraryBase.jspreadsheet.current.dragging) {
668
+ // ignore
669
+ } else {
670
+ // Header found
671
+ if (jssTable[1] == 1) {
672
+ if (libraryBase.jspreadsheet.current.selectedHeader) {
673
+ columnId = e.target.getAttribute('data-x');
674
+ const o = libraryBase.jspreadsheet.current.selectedHeader;
675
+ const d = columnId;
676
+ // Update selection
677
+ updateSelectionFromCoords.call(libraryBase.jspreadsheet.current, o, 0, d, libraryBase.jspreadsheet.current.options.data.length - 1, e);
678
+ }
679
+ }
680
+
681
+ // Body found
682
+ if (jssTable[1] == 2) {
683
+ if (e.target.classList.contains('jss_row')) {
684
+ if (libraryBase.jspreadsheet.current.selectedRow != null) {
685
+ const o = libraryBase.jspreadsheet.current.selectedRow;
686
+ const d = rowId;
687
+ // Update selection
688
+ updateSelectionFromCoords.call(
689
+ libraryBase.jspreadsheet.current,
690
+ 0,
691
+ o,
692
+ libraryBase.jspreadsheet.current.options.data[0].length - 1,
693
+ d,
694
+ e
695
+ );
696
+ }
697
+ } else {
698
+ // Do not select edtion is in progress
699
+ if (!libraryBase.jspreadsheet.current.edition) {
700
+ if (columnId && rowId) {
701
+ if (libraryBase.jspreadsheet.current.selectedCorner) {
702
+ updateCopySelection.call(libraryBase.jspreadsheet.current, columnId, rowId);
703
+ } else {
704
+ if (libraryBase.jspreadsheet.current.selectedCell) {
705
+ updateSelectionFromCoords.call(
706
+ libraryBase.jspreadsheet.current,
707
+ libraryBase.jspreadsheet.current.selectedCell[0],
708
+ libraryBase.jspreadsheet.current.selectedCell[1],
709
+ columnId,
710
+ rowId,
711
+ e
712
+ );
713
+ }
714
+ }
715
+ }
716
+ }
717
+ }
718
+ }
719
+ }
720
+ }
721
+ }
722
+
723
+ // Clear any time control
724
+ if (libraryBase.jspreadsheet.timeControl) {
725
+ clearTimeout(libraryBase.jspreadsheet.timeControl);
726
+ libraryBase.jspreadsheet.timeControl = null;
727
+ }
728
+ };
729
+
730
+ const doubleClickControls = function (e) {
731
+ // Jss is selected
732
+ if (libraryBase.jspreadsheet.current) {
733
+ // Corner action
734
+ if (e.target.classList.contains('jss_corner')) {
735
+ // Any selected cells
736
+ if (libraryBase.jspreadsheet.current.highlighted.length > 0) {
737
+ // Copy from this
738
+ const x1 = libraryBase.jspreadsheet.current.highlighted[0].element.getAttribute('data-x');
739
+ const y1 =
740
+ parseInt(
741
+ libraryBase.jspreadsheet.current.highlighted[libraryBase.jspreadsheet.current.highlighted.length - 1].element.getAttribute('data-y')
742
+ ) + 1;
743
+ // Until this
744
+ const x2 = libraryBase.jspreadsheet.current.highlighted[libraryBase.jspreadsheet.current.highlighted.length - 1].element.getAttribute('data-x');
745
+ const y2 = libraryBase.jspreadsheet.current.records.length - 1;
746
+ // Execute copy
747
+ copyData.call(
748
+ libraryBase.jspreadsheet.current,
749
+ libraryBase.jspreadsheet.current.records[y1][x1].element,
750
+ libraryBase.jspreadsheet.current.records[y2][x2].element
751
+ );
752
+ }
753
+ } else if (e.target.classList.contains('jss_column_filter')) {
754
+ // Column
755
+ const columnId = e.target.getAttribute('data-x');
756
+ // Open filter
757
+ openFilter.call(libraryBase.jspreadsheet.current, columnId);
758
+ } else {
759
+ // Get table
760
+ const jssTable = getElement(e.target);
761
+
762
+ // Double click over header
763
+ if (jssTable[1] == 1 && libraryBase.jspreadsheet.current.options.columnSorting != false) {
764
+ // Check valid column header coords
765
+ const columnId = e.target.getAttribute('data-x');
766
+ if (columnId) {
767
+ libraryBase.jspreadsheet.current.orderBy(parseInt(columnId));
768
+ }
769
+ }
770
+
771
+ // Double click over body
772
+ if (jssTable[1] == 2 && libraryBase.jspreadsheet.current.options.editable != false) {
773
+ if (!libraryBase.jspreadsheet.current.edition) {
774
+ const getCellCoords = function (element) {
775
+ if (element.parentNode) {
776
+ const x = element.getAttribute('data-x');
777
+ const y = element.getAttribute('data-y');
778
+ if (x && y) {
779
+ return element;
780
+ } else {
781
+ return getCellCoords(element.parentNode);
782
+ }
783
+ }
784
+ };
785
+ const cell = getCellCoords(e.target);
786
+ if (cell && cell.classList.contains('highlight')) {
787
+ openEditor.call(libraryBase.jspreadsheet.current, cell, undefined, e);
788
+ }
789
+ }
790
+ }
791
+ }
792
+ }
793
+ };
794
+
795
+ const pasteControls = function (e) {
796
+ if (libraryBase.jspreadsheet.current && libraryBase.jspreadsheet.current.selectedCell) {
797
+ if (!libraryBase.jspreadsheet.current.edition) {
798
+ if (libraryBase.jspreadsheet.current.options.editable != false) {
799
+ if (e && e.clipboardData) {
800
+ paste.call(
801
+ libraryBase.jspreadsheet.current,
802
+ libraryBase.jspreadsheet.current.selectedCell[0],
803
+ libraryBase.jspreadsheet.current.selectedCell[1],
804
+ e.clipboardData.getData('text')
805
+ );
806
+ e.preventDefault();
807
+ } else if (window.clipboardData) {
808
+ paste.call(
809
+ libraryBase.jspreadsheet.current,
810
+ libraryBase.jspreadsheet.current.selectedCell[0],
811
+ libraryBase.jspreadsheet.current.selectedCell[1],
812
+ window.clipboardData.getData('text')
813
+ );
814
+ }
815
+ }
816
+ }
817
+ }
818
+ };
819
+
820
+ const getRole = function (element) {
821
+ if (element.classList.contains('jss_selectall')) {
822
+ return 'select-all';
823
+ }
824
+
825
+ if (element.classList.contains('jss_corner')) {
826
+ return 'fill-handle';
827
+ }
828
+
829
+ let tempElement = element;
830
+
831
+ while (!tempElement.classList.contains('jss_spreadsheet')) {
832
+ if (tempElement.classList.contains('jss_row')) {
833
+ return 'row';
834
+ }
835
+
836
+ if (tempElement.classList.contains('jss_nested')) {
837
+ return 'nested';
838
+ }
839
+
840
+ if (tempElement.classList.contains('jtabs-headers')) {
841
+ return 'tabs';
842
+ }
843
+
844
+ if (tempElement.classList.contains('jtoolbar')) {
845
+ return 'toolbar';
846
+ }
847
+
848
+ if (tempElement.classList.contains('jss_pagination')) {
849
+ return 'pagination';
850
+ }
851
+
852
+ if (tempElement.tagName === 'TBODY') {
853
+ return 'cell';
854
+ }
855
+
856
+ if (tempElement.tagName === 'TFOOT') {
857
+ return getElementIndex(element) === 0 ? 'grid' : 'footer';
858
+ }
859
+
860
+ if (tempElement.tagName === 'THEAD') {
861
+ return 'header';
862
+ }
863
+
864
+ tempElement = tempElement.parentElement;
865
+ }
866
+
867
+ return 'applications';
868
+ };
869
+
870
+ const defaultContextMenu = function (worksheet, x, y, role) {
871
+ const items = [];
872
+
873
+ if (role === 'header') {
874
+ // Insert a new column
875
+ if (worksheet.options.allowInsertColumn != false) {
876
+ items.push({
877
+ title: jSuites.translate('Insert a new column before'),
878
+ onclick: function () {
879
+ worksheet.insertColumn(1, parseInt(x), 1);
880
+ },
881
+ });
882
+ }
883
+
884
+ if (worksheet.options.allowInsertColumn != false) {
885
+ items.push({
886
+ title: jSuites.translate('Insert a new column after'),
887
+ onclick: function () {
888
+ worksheet.insertColumn(1, parseInt(x), 0);
889
+ },
890
+ });
891
+ }
892
+
893
+ // Delete a column
894
+ if (worksheet.options.allowDeleteColumn != false) {
895
+ items.push({
896
+ title: jSuites.translate('Delete selected columns'),
897
+ onclick: function () {
898
+ worksheet.deleteColumn(worksheet.getSelectedColumns().length ? undefined : parseInt(x));
899
+ },
900
+ });
901
+ }
902
+
903
+ // Rename column
904
+ if (worksheet.options.allowRenameColumn != false) {
905
+ items.push({
906
+ title: jSuites.translate('Rename this column'),
907
+ onclick: function () {
908
+ const oldValue = worksheet.getHeader(x);
909
+
910
+ const newValue = prompt(jSuites.translate('Column name'), oldValue);
911
+
912
+ worksheet.setHeader(x, newValue);
913
+ },
914
+ });
915
+ }
916
+
917
+ // Sorting
918
+ if (worksheet.options.columnSorting != false) {
919
+ // Line
920
+ items.push({ type: 'line' });
921
+
922
+ items.push({
923
+ title: jSuites.translate('Order ascending'),
924
+ onclick: function () {
925
+ worksheet.orderBy(x, 0);
926
+ },
927
+ });
928
+ items.push({
929
+ title: jSuites.translate('Order descending'),
930
+ onclick: function () {
931
+ worksheet.orderBy(x, 1);
932
+ },
933
+ });
934
+ }
935
+ }
936
+
937
+ if (role === 'row' || role === 'cell') {
938
+ // Insert new row
939
+ if (worksheet.options.allowInsertRow != false) {
940
+ items.push({
941
+ title: jSuites.translate('Insert a new row before'),
942
+ onclick: function () {
943
+ worksheet.insertRow(1, parseInt(y), 1);
944
+ },
945
+ });
946
+
947
+ items.push({
948
+ title: jSuites.translate('Insert a new row after'),
949
+ onclick: function () {
950
+ worksheet.insertRow(1, parseInt(y));
951
+ },
952
+ });
953
+ }
954
+
955
+ if (worksheet.options.allowDeleteRow != false) {
956
+ items.push({
957
+ title: jSuites.translate('Delete selected rows'),
958
+ onclick: function () {
959
+ worksheet.deleteRow(worksheet.getSelectedRows().length ? undefined : parseInt(y));
960
+ },
961
+ });
962
+ }
963
+ }
964
+
965
+ if (role === 'cell') {
966
+ if (worksheet.options.allowComments != false) {
967
+ items.push({ type: 'line' });
968
+
969
+ const title = worksheet.records[y][x].element.getAttribute('title') || '';
970
+
971
+ items.push({
972
+ title: jSuites.translate(title ? 'Edit comments' : 'Add comments'),
973
+ onclick: function () {
974
+ const comment = prompt(jSuites.translate('Comments'), title);
975
+ if (comment) {
976
+ worksheet.setComments(getCellNameFromCoords(x, y), comment);
977
+ }
978
+ },
979
+ });
980
+
981
+ if (title) {
982
+ items.push({
983
+ title: jSuites.translate('Clear comments'),
984
+ onclick: function () {
985
+ worksheet.setComments(getCellNameFromCoords(x, y), '');
986
+ },
987
+ });
988
+ }
989
+ }
990
+ }
991
+
992
+ // Line
993
+ if (items.length !== 0) {
994
+ items.push({ type: 'line' });
995
+ }
996
+
997
+ // Copy
998
+ if (role === 'header' || role === 'row' || role === 'cell') {
999
+ items.push({
1000
+ title: jSuites.translate('Copy') + '...',
1001
+ shortcut: 'Ctrl + C',
1002
+ onclick: function () {
1003
+ copy.call(worksheet, true);
1004
+ },
1005
+ });
1006
+
1007
+ // Paste
1008
+ if (navigator && navigator.clipboard) {
1009
+ items.push({
1010
+ title: jSuites.translate('Paste') + '...',
1011
+ shortcut: 'Ctrl + V',
1012
+ onclick: function () {
1013
+ if (worksheet.selectedCell) {
1014
+ navigator.clipboard.readText().then(function (text) {
1015
+ if (text) {
1016
+ paste.call(worksheet, worksheet.selectedCell[0], worksheet.selectedCell[1], text);
1017
+ }
1018
+ });
1019
+ }
1020
+ },
1021
+ });
1022
+ }
1023
+ }
1024
+
1025
+ // Save
1026
+ if (worksheet.parent.config.allowExport != false) {
1027
+ items.push({
1028
+ title: jSuites.translate('Save as') + '...',
1029
+ shortcut: 'Ctrl + S',
1030
+ onclick: function () {
1031
+ worksheet.download();
1032
+ },
1033
+ });
1034
+ }
1035
+
1036
+ // About
1037
+ if (worksheet.parent.config.about != false) {
1038
+ items.push({
1039
+ title: jSuites.translate('About'),
1040
+ onclick: function () {
1041
+ if (typeof worksheet.parent.config.about === 'undefined' || worksheet.parent.config.about === true) {
1042
+ alert(version.print());
1043
+ } else {
1044
+ alert(worksheet.parent.config.about);
1045
+ }
1046
+ },
1047
+ });
1048
+ }
1049
+
1050
+ return items;
1051
+ };
1052
+
1053
+ const getElementIndex = function (element) {
1054
+ const parentChildren = element.parentElement.children;
1055
+
1056
+ for (let i = 0; i < parentChildren.length; i++) {
1057
+ const currentElement = parentChildren[i];
1058
+
1059
+ if (element === currentElement) {
1060
+ return i;
1061
+ }
1062
+ }
1063
+
1064
+ return -1;
1065
+ };
1066
+
1067
+ const contextMenuControls = function (e) {
1068
+ e = e || window.event;
1069
+
1070
+ let mouseButton;
1071
+
1072
+ if ('buttons' in e) {
1073
+ mouseButton = e.buttons;
1074
+ } else {
1075
+ mouseButton = e.which || e.button;
1076
+ }
1077
+
1078
+ if (libraryBase.jspreadsheet.current) {
1079
+ const spreadsheet = libraryBase.jspreadsheet.current.parent;
1080
+
1081
+ if (libraryBase.jspreadsheet.current.edition) {
1082
+ e.preventDefault();
1083
+ } else {
1084
+ spreadsheet.contextMenu.contextmenu.close();
1085
+
1086
+ if (libraryBase.jspreadsheet.current) {
1087
+ const role = getRole(e.target);
1088
+
1089
+ let x = null,
1090
+ y = null;
1091
+
1092
+ if (role === 'cell') {
1093
+ let cellElement = e.target;
1094
+ while (cellElement.tagName !== 'TD') {
1095
+ cellElement = cellElement.parentNode;
1096
+ }
1097
+
1098
+ y = cellElement.getAttribute('data-y');
1099
+ x = cellElement.getAttribute('data-x');
1100
+
1101
+ if (
1102
+ !libraryBase.jspreadsheet.current.selectedCell ||
1103
+ x < parseInt(libraryBase.jspreadsheet.current.selectedCell[0]) ||
1104
+ x > parseInt(libraryBase.jspreadsheet.current.selectedCell[2]) ||
1105
+ y < parseInt(libraryBase.jspreadsheet.current.selectedCell[1]) ||
1106
+ y > parseInt(libraryBase.jspreadsheet.current.selectedCell[3])
1107
+ ) {
1108
+ updateSelectionFromCoords.call(libraryBase.jspreadsheet.current, x, y, x, y, e);
1109
+ }
1110
+ } else if (role === 'row' || role === 'header') {
1111
+ if (role === 'row') {
1112
+ y = e.target.getAttribute('data-y');
1113
+ } else {
1114
+ x = e.target.getAttribute('data-x');
1115
+ }
1116
+
1117
+ if (
1118
+ !libraryBase.jspreadsheet.current.selectedCell ||
1119
+ x < parseInt(libraryBase.jspreadsheet.current.selectedCell[0]) ||
1120
+ x > parseInt(libraryBase.jspreadsheet.current.selectedCell[2]) ||
1121
+ y < parseInt(libraryBase.jspreadsheet.current.selectedCell[1]) ||
1122
+ y > parseInt(libraryBase.jspreadsheet.current.selectedCell[3])
1123
+ ) {
1124
+ updateSelectionFromCoords.call(libraryBase.jspreadsheet.current, x, y, x, y, e);
1125
+ }
1126
+ } else if (role === 'nested') {
1127
+ const columns = e.target.getAttribute('data-column').split(',');
1128
+
1129
+ x = getElementIndex(e.target) - 1;
1130
+ y = getElementIndex(e.target.parentElement);
1131
+
1132
+ if (
1133
+ !libraryBase.jspreadsheet.current.selectedCell ||
1134
+ columns[0] != parseInt(libraryBase.jspreadsheet.current.selectedCell[0]) ||
1135
+ columns[columns.length - 1] != parseInt(libraryBase.jspreadsheet.current.selectedCell[2]) ||
1136
+ libraryBase.jspreadsheet.current.selectedCell[1] != null ||
1137
+ libraryBase.jspreadsheet.current.selectedCell[3] != null
1138
+ ) {
1139
+ updateSelectionFromCoords.call(libraryBase.jspreadsheet.current, columns[0], null, columns[columns.length - 1], null, e);
1140
+ }
1141
+ } else if (role === 'select-all') {
1142
+ selectAll.call(libraryBase.jspreadsheet.current);
1143
+ } else if (role === 'tabs') {
1144
+ x = getElementIndex(e.target);
1145
+ } else if (role === 'footer') {
1146
+ x = getElementIndex(e.target) - 1;
1147
+ y = getElementIndex(e.target.parentElement);
1148
+ }
1149
+
1150
+ // Table found
1151
+ let items = defaultContextMenu(libraryBase.jspreadsheet.current, parseInt(x), parseInt(y), role);
1152
+
1153
+ if (typeof spreadsheet.config.contextMenu === 'function') {
1154
+ const result = spreadsheet.config.contextMenu(libraryBase.jspreadsheet.current, x, y, e, items, role, x, y);
1155
+
1156
+ if (result) {
1157
+ items = result;
1158
+ } else if (result === false) {
1159
+ return;
1160
+ }
1161
+ }
1162
+
1163
+ if (typeof spreadsheet.plugins === 'object') {
1164
+ Object.entries(spreadsheet.plugins).forEach(function ([, plugin]) {
1165
+ if (typeof plugin.contextMenu === 'function') {
1166
+ const result = plugin.contextMenu(
1167
+ libraryBase.jspreadsheet.current,
1168
+ x !== null ? parseInt(x) : null,
1169
+ y !== null ? parseInt(y) : null,
1170
+ e,
1171
+ items,
1172
+ role,
1173
+ x !== null ? parseInt(x) : null,
1174
+ y !== null ? parseInt(y) : null
1175
+ );
1176
+
1177
+ if (result) {
1178
+ items = result;
1179
+ }
1180
+ }
1181
+ });
1182
+ }
1183
+
1184
+ // The id is depending on header and body
1185
+ spreadsheet.contextMenu.contextmenu.open(e, items);
1186
+ // Avoid the real one
1187
+ e.preventDefault();
1188
+ }
1189
+ }
1190
+ }
1191
+ };
1192
+
1193
+ const touchStartControls = function (e) {
1194
+ const jssTable = getElement(e.target);
1195
+
1196
+ if (jssTable[0]) {
1197
+ if (libraryBase.jspreadsheet.current != jssTable[0].jssWorksheet) {
1198
+ if (libraryBase.jspreadsheet.current) {
1199
+ libraryBase.jspreadsheet.current.resetSelection();
1200
+ }
1201
+ libraryBase.jspreadsheet.current = jssTable[0].jssWorksheet;
1202
+ }
1203
+ } else {
1204
+ if (libraryBase.jspreadsheet.current) {
1205
+ libraryBase.jspreadsheet.current.resetSelection();
1206
+ libraryBase.jspreadsheet.current = null;
1207
+ }
1208
+ }
1209
+
1210
+ if (libraryBase.jspreadsheet.current) {
1211
+ if (!libraryBase.jspreadsheet.current.edition) {
1212
+ const columnId = e.target.getAttribute('data-x');
1213
+ const rowId = e.target.getAttribute('data-y');
1214
+
1215
+ if (columnId && rowId) {
1216
+ updateSelectionFromCoords.call(libraryBase.jspreadsheet.current, columnId, rowId, undefined, undefined, e);
1217
+
1218
+ libraryBase.jspreadsheet.timeControl = setTimeout(function () {
1219
+ // Keep temporary reference to the element
1220
+ if (libraryBase.jspreadsheet.current.options.columns[columnId].type == 'color') {
1221
+ libraryBase.jspreadsheet.tmpElement = null;
1222
+ } else {
1223
+ libraryBase.jspreadsheet.tmpElement = e.target;
1224
+ }
1225
+ openEditor.call(libraryBase.jspreadsheet.current, e.target, false, e);
1226
+ }, 500);
1227
+ }
1228
+ }
1229
+ }
1230
+ };
1231
+
1232
+ const touchEndControls = function (e) {
1233
+ // Clear any time control
1234
+ if (libraryBase.jspreadsheet.timeControl) {
1235
+ clearTimeout(libraryBase.jspreadsheet.timeControl);
1236
+ libraryBase.jspreadsheet.timeControl = null;
1237
+ // Element
1238
+ if (libraryBase.jspreadsheet.tmpElement && libraryBase.jspreadsheet.tmpElement.children[0].tagName == 'INPUT') {
1239
+ libraryBase.jspreadsheet.tmpElement.children[0].focus();
1240
+ }
1241
+ libraryBase.jspreadsheet.tmpElement = null;
1242
+ }
1243
+ };
1244
+
1245
+ export const cutControls = function (e) {
1246
+ if (libraryBase.jspreadsheet.current) {
1247
+ if (!libraryBase.jspreadsheet.current.edition) {
1248
+ copy.call(libraryBase.jspreadsheet.current, true, undefined, undefined, undefined, undefined, true);
1249
+ if (libraryBase.jspreadsheet.current.options.editable != false) {
1250
+ libraryBase.jspreadsheet.current.setValue(
1251
+ libraryBase.jspreadsheet.current.highlighted.map(function (record) {
1252
+ return record.element;
1253
+ }),
1254
+ ''
1255
+ );
1256
+ }
1257
+ }
1258
+ }
1259
+ };
1260
+
1261
+ const copyControls = function (e) {
1262
+ if (libraryBase.jspreadsheet.current && copyControls.enabled) {
1263
+ if (!libraryBase.jspreadsheet.current.edition) {
1264
+ copy.call(libraryBase.jspreadsheet.current, true);
1265
+ }
1266
+ }
1267
+ };
1268
+
1269
+ const isMac = function () {
1270
+ return navigator.platform.toUpperCase().indexOf('MAC') >= 0;
1271
+ };
1272
+
1273
+ const isCtrl = function (e) {
1274
+ if (isMac()) {
1275
+ return e.metaKey;
1276
+ } else {
1277
+ return e.ctrlKey;
1278
+ }
1279
+ };
1280
+
1281
+ const keyDownControls = function (e) {
1282
+ if (libraryBase.jspreadsheet.current) {
1283
+ if (libraryBase.jspreadsheet.current.edition) {
1284
+ if (e.which == 27) {
1285
+ // Escape
1286
+ if (libraryBase.jspreadsheet.current.edition) {
1287
+ // Exit without saving
1288
+ closeEditor.call(libraryBase.jspreadsheet.current, libraryBase.jspreadsheet.current.edition[0], false);
1289
+ }
1290
+ e.preventDefault();
1291
+ } else if (e.which == 13) {
1292
+ // Enter
1293
+ if (
1294
+ libraryBase.jspreadsheet.current.options.columns &&
1295
+ libraryBase.jspreadsheet.current.options.columns[libraryBase.jspreadsheet.current.edition[2]] &&
1296
+ libraryBase.jspreadsheet.current.options.columns[libraryBase.jspreadsheet.current.edition[2]].type == 'calendar'
1297
+ ) {
1298
+ closeEditor.call(libraryBase.jspreadsheet.current, libraryBase.jspreadsheet.current.edition[0], true);
1299
+ } else if (
1300
+ libraryBase.jspreadsheet.current.options.columns &&
1301
+ libraryBase.jspreadsheet.current.options.columns[libraryBase.jspreadsheet.current.edition[2]] &&
1302
+ libraryBase.jspreadsheet.current.options.columns[libraryBase.jspreadsheet.current.edition[2]].type == 'dropdown'
1303
+ ) {
1304
+ // Do nothing
1305
+ } else {
1306
+ // Alt enter -> do not close editor
1307
+ if (
1308
+ (libraryBase.jspreadsheet.current.options.wordWrap == true ||
1309
+ (libraryBase.jspreadsheet.current.options.columns &&
1310
+ libraryBase.jspreadsheet.current.options.columns[libraryBase.jspreadsheet.current.edition[2]] &&
1311
+ libraryBase.jspreadsheet.current.options.columns[libraryBase.jspreadsheet.current.edition[2]].wordWrap == true) ||
1312
+ (libraryBase.jspreadsheet.current.options.data[libraryBase.jspreadsheet.current.edition[3]][
1313
+ libraryBase.jspreadsheet.current.edition[2]
1314
+ ] &&
1315
+ libraryBase.jspreadsheet.current.options.data[libraryBase.jspreadsheet.current.edition[3]][
1316
+ libraryBase.jspreadsheet.current.edition[2]
1317
+ ].length > 200)) &&
1318
+ e.altKey
1319
+ ) {
1320
+ // Add new line to the editor
1321
+ const editorTextarea = libraryBase.jspreadsheet.current.edition[0].children[0];
1322
+ let editorValue = libraryBase.jspreadsheet.current.edition[0].children[0].value;
1323
+ const editorIndexOf = editorTextarea.selectionStart;
1324
+ editorValue = editorValue.slice(0, editorIndexOf) + '\n' + editorValue.slice(editorIndexOf);
1325
+ editorTextarea.value = editorValue;
1326
+ editorTextarea.focus();
1327
+ editorTextarea.selectionStart = editorIndexOf + 1;
1328
+ editorTextarea.selectionEnd = editorIndexOf + 1;
1329
+ } else {
1330
+ libraryBase.jspreadsheet.current.edition[0].children[0].blur();
1331
+ }
1332
+ }
1333
+ } else if (e.which == 9) {
1334
+ // Tab
1335
+ if (
1336
+ libraryBase.jspreadsheet.current.options.columns &&
1337
+ libraryBase.jspreadsheet.current.options.columns[libraryBase.jspreadsheet.current.edition[2]] &&
1338
+ ['calendar', 'html'].includes(libraryBase.jspreadsheet.current.options.columns[libraryBase.jspreadsheet.current.edition[2]].type)
1339
+ ) {
1340
+ closeEditor.call(libraryBase.jspreadsheet.current, libraryBase.jspreadsheet.current.edition[0], true);
1341
+ } else {
1342
+ libraryBase.jspreadsheet.current.edition[0].children[0].blur();
1343
+ }
1344
+ }
1345
+ }
1346
+
1347
+ if (!libraryBase.jspreadsheet.current.edition && libraryBase.jspreadsheet.current.selectedCell) {
1348
+ // Which key
1349
+ if (e.which == 37) {
1350
+ left.call(libraryBase.jspreadsheet.current, e.shiftKey, e.ctrlKey);
1351
+ e.preventDefault();
1352
+ } else if (e.which == 39) {
1353
+ right.call(libraryBase.jspreadsheet.current, e.shiftKey, e.ctrlKey);
1354
+ e.preventDefault();
1355
+ } else if (e.which == 38) {
1356
+ up.call(libraryBase.jspreadsheet.current, e.shiftKey, e.ctrlKey);
1357
+ e.preventDefault();
1358
+ } else if (e.which == 40) {
1359
+ down.call(libraryBase.jspreadsheet.current, e.shiftKey, e.ctrlKey);
1360
+ e.preventDefault();
1361
+ } else if (e.which == 36) {
1362
+ first.call(libraryBase.jspreadsheet.current, e.shiftKey, e.ctrlKey);
1363
+ e.preventDefault();
1364
+ } else if (e.which == 35) {
1365
+ last.call(libraryBase.jspreadsheet.current, e.shiftKey, e.ctrlKey);
1366
+ e.preventDefault();
1367
+ } else if (e.which == 46 || e.which == 8) {
1368
+ // Delete
1369
+ if (libraryBase.jspreadsheet.current.options.editable != false) {
1370
+ if (libraryBase.jspreadsheet.current.selectedRow != null) {
1371
+ if (libraryBase.jspreadsheet.current.options.allowDeleteRow != false) {
1372
+ if (confirm(jSuites.translate('Are you sure to delete the selected rows?'))) {
1373
+ libraryBase.jspreadsheet.current.deleteRow();
1374
+ }
1375
+ }
1376
+ } else if (libraryBase.jspreadsheet.current.selectedHeader) {
1377
+ if (libraryBase.jspreadsheet.current.options.allowDeleteColumn != false) {
1378
+ if (confirm(jSuites.translate('Are you sure to delete the selected columns?'))) {
1379
+ libraryBase.jspreadsheet.current.deleteColumn();
1380
+ }
1381
+ }
1382
+ } else {
1383
+ // Change value
1384
+ libraryBase.jspreadsheet.current.setValue(
1385
+ libraryBase.jspreadsheet.current.highlighted.map(function (record) {
1386
+ return record.element;
1387
+ }),
1388
+ ''
1389
+ );
1390
+ }
1391
+ }
1392
+ } else if (e.which == 13) {
1393
+ // Move cursor
1394
+ if (e.shiftKey) {
1395
+ up.call(libraryBase.jspreadsheet.current);
1396
+ } else {
1397
+ if (libraryBase.jspreadsheet.current.options.allowInsertRow != false) {
1398
+ if (libraryBase.jspreadsheet.current.options.allowManualInsertRow != false) {
1399
+ if (libraryBase.jspreadsheet.current.selectedCell[1] == libraryBase.jspreadsheet.current.options.data.length - 1) {
1400
+ // New record in case selectedCell in the last row
1401
+ libraryBase.jspreadsheet.current.insertRow();
1402
+ }
1403
+ }
1404
+ }
1405
+
1406
+ down.call(libraryBase.jspreadsheet.current);
1407
+ }
1408
+ e.preventDefault();
1409
+ } else if (e.which == 9) {
1410
+ // Tab
1411
+ if (e.shiftKey) {
1412
+ left.call(libraryBase.jspreadsheet.current);
1413
+ } else {
1414
+ if (libraryBase.jspreadsheet.current.options.allowInsertColumn != false) {
1415
+ if (libraryBase.jspreadsheet.current.options.allowManualInsertColumn != false) {
1416
+ if (libraryBase.jspreadsheet.current.selectedCell[0] == libraryBase.jspreadsheet.current.options.data[0].length - 1) {
1417
+ // New record in case selectedCell in the last column
1418
+ libraryBase.jspreadsheet.current.insertColumn();
1419
+ }
1420
+ }
1421
+ }
1422
+
1423
+ right.call(libraryBase.jspreadsheet.current);
1424
+ }
1425
+ e.preventDefault();
1426
+ } else {
1427
+ if ((e.ctrlKey || e.metaKey) && !e.shiftKey) {
1428
+ if (e.which == 65) {
1429
+ // Ctrl + A
1430
+ selectAll.call(libraryBase.jspreadsheet.current);
1431
+ e.preventDefault();
1432
+ } else if (e.which == 83) {
1433
+ // Ctrl + S
1434
+ libraryBase.jspreadsheet.current.download();
1435
+ e.preventDefault();
1436
+ } else if (e.which == 89) {
1437
+ // Ctrl + Y
1438
+ libraryBase.jspreadsheet.current.redo();
1439
+ e.preventDefault();
1440
+ } else if (e.which == 90) {
1441
+ // Ctrl + Z
1442
+ libraryBase.jspreadsheet.current.undo();
1443
+ e.preventDefault();
1444
+ } else if (e.which == 67) {
1445
+ // Ctrl + C
1446
+ copy.call(libraryBase.jspreadsheet.current, true);
1447
+ e.preventDefault();
1448
+ } else if (e.which == 88) {
1449
+ // Ctrl + X
1450
+ if (libraryBase.jspreadsheet.current.options.editable != false) {
1451
+ cutControls();
1452
+ } else {
1453
+ copyControls();
1454
+ }
1455
+ e.preventDefault();
1456
+ } else if (e.which == 86) {
1457
+ // Ctrl + V
1458
+ pasteControls();
1459
+ }
1460
+ } else {
1461
+ if (libraryBase.jspreadsheet.current.selectedCell) {
1462
+ if (libraryBase.jspreadsheet.current.options.editable != false) {
1463
+ const rowId = libraryBase.jspreadsheet.current.selectedCell[1];
1464
+ const columnId = libraryBase.jspreadsheet.current.selectedCell[0];
1465
+
1466
+ // Characters able to start a edition
1467
+ if (e.keyCode == 32) {
1468
+ // Space
1469
+ e.preventDefault();
1470
+ if (
1471
+ libraryBase.jspreadsheet.current.options.columns[columnId].type == 'checkbox' ||
1472
+ libraryBase.jspreadsheet.current.options.columns[columnId].type == 'radio'
1473
+ ) {
1474
+ setCheckRadioValue.call(libraryBase.jspreadsheet.current);
1475
+ } else {
1476
+ // Start edition
1477
+ openEditor.call(
1478
+ libraryBase.jspreadsheet.current,
1479
+ libraryBase.jspreadsheet.current.records[rowId][columnId].element,
1480
+ true,
1481
+ e
1482
+ );
1483
+ }
1484
+ } else if (e.keyCode == 113) {
1485
+ // Start edition with current content F2
1486
+ openEditor.call(libraryBase.jspreadsheet.current, libraryBase.jspreadsheet.current.records[rowId][columnId].element, false, e);
1487
+ } else if ((e.key.length === 1 || e.key === 'Process') && !(e.altKey || isCtrl(e))) {
1488
+ // Start edition
1489
+ openEditor.call(libraryBase.jspreadsheet.current, libraryBase.jspreadsheet.current.records[rowId][columnId].element, true, e);
1490
+ // Prevent entries in the calendar
1491
+ if (
1492
+ libraryBase.jspreadsheet.current.options.columns &&
1493
+ libraryBase.jspreadsheet.current.options.columns[columnId] &&
1494
+ libraryBase.jspreadsheet.current.options.columns[columnId].type == 'calendar'
1495
+ ) {
1496
+ e.preventDefault();
1497
+ }
1498
+ }
1499
+ }
1500
+ }
1501
+ }
1502
+ }
1503
+ } else {
1504
+ if (e.target.classList.contains('jss_search')) {
1505
+ if (libraryBase.jspreadsheet.timeControl) {
1506
+ clearTimeout(libraryBase.jspreadsheet.timeControl);
1507
+ }
1508
+
1509
+ libraryBase.jspreadsheet.timeControl = setTimeout(function () {
1510
+ libraryBase.jspreadsheet.current.search(e.target.value);
1511
+ }, 200);
1512
+ }
1513
+ }
1514
+ }
1515
+ };
1516
+
1517
+ export const wheelControls = function (e) {
1518
+ const obj = this;
1519
+
1520
+ if (obj.options.lazyLoading == true) {
1521
+ if (libraryBase.jspreadsheet.timeControlLoading == null) {
1522
+ libraryBase.jspreadsheet.timeControlLoading = setTimeout(function () {
1523
+ if (obj.content.scrollTop + obj.content.clientHeight >= obj.content.scrollHeight - 10) {
1524
+ if (loadDown.call(obj)) {
1525
+ if (obj.content.scrollTop + obj.content.clientHeight > obj.content.scrollHeight - 10) {
1526
+ obj.content.scrollTop = obj.content.scrollTop - obj.content.clientHeight;
1527
+ }
1528
+ updateCornerPosition.call(obj);
1529
+ }
1530
+ } else if (obj.content.scrollTop <= obj.content.clientHeight) {
1531
+ if (loadUp.call(obj)) {
1532
+ if (obj.content.scrollTop < 10) {
1533
+ obj.content.scrollTop = obj.content.scrollTop + obj.content.clientHeight;
1534
+ }
1535
+ updateCornerPosition.call(obj);
1536
+ }
1537
+ }
1538
+
1539
+ libraryBase.jspreadsheet.timeControlLoading = null;
1540
+ }, 100);
1541
+ }
1542
+ }
1543
+ };
1544
+
1545
+ let scrollLeft = 0;
1546
+
1547
+ const updateFreezePosition = function () {
1548
+ const obj = this;
1549
+
1550
+ scrollLeft = obj.content.scrollLeft;
1551
+ let width = 0;
1552
+ if (scrollLeft > 50) {
1553
+ for (let i = 0; i < obj.options.freezeColumns; i++) {
1554
+ if (i > 0) {
1555
+ // Must check if the previous column is hidden or not to determin whether the width shoule be added or not!
1556
+ if (!obj.options.columns || !obj.options.columns[i - 1] || obj.options.columns[i - 1].type !== 'hidden') {
1557
+ let columnWidth;
1558
+ if (obj.options.columns && obj.options.columns[i - 1] && obj.options.columns[i - 1].width !== undefined) {
1559
+ columnWidth = parseInt(obj.options.columns[i - 1].width);
1560
+ } else {
1561
+ columnWidth = obj.options.defaultColWidth !== undefined ? parseInt(obj.options.defaultColWidth) : 100;
1562
+ }
1563
+
1564
+ width += parseInt(columnWidth);
1565
+ }
1566
+ }
1567
+ obj.headers[i].classList.add('jss_freezed');
1568
+ obj.headers[i].style.left = width + 'px';
1569
+ for (let j = 0; j < obj.rows.length; j++) {
1570
+ if (obj.rows[j] && obj.records[j][i]) {
1571
+ const shifted = scrollLeft + (i > 0 ? obj.records[j][i - 1].element.style.width : 0) - 51 + 'px';
1572
+ obj.records[j][i].element.classList.add('jss_freezed');
1573
+ obj.records[j][i].element.style.left = shifted;
1574
+ }
1575
+ }
1576
+ }
1577
+ } else {
1578
+ for (let i = 0; i < obj.options.freezeColumns; i++) {
1579
+ obj.headers[i].classList.remove('jss_freezed');
1580
+ obj.headers[i].style.left = '';
1581
+ for (let j = 0; j < obj.rows.length; j++) {
1582
+ if (obj.records[j][i]) {
1583
+ obj.records[j][i].element.classList.remove('jss_freezed');
1584
+ obj.records[j][i].element.style.left = '';
1585
+ }
1586
+ }
1587
+ }
1588
+ }
1589
+
1590
+ // Place the corner in the correct place
1591
+ updateCornerPosition.call(obj);
1592
+ };
1593
+
1594
+ export const scrollControls = function (e) {
1595
+ const obj = this;
1596
+
1597
+ wheelControls.call(obj);
1598
+
1599
+ if (obj.options.freezeColumns > 0 && obj.content.scrollLeft != scrollLeft) {
1600
+ updateFreezePosition.call(obj);
1601
+ }
1602
+
1603
+ // Close editor
1604
+ if (obj.options.lazyLoading == true || obj.options.tableOverflow == true) {
1605
+ if (obj.edition && e.target.className.substr(0, 9) != 'jdropdown') {
1606
+ closeEditor.call(obj, obj.edition[0], true);
1607
+ }
1608
+ }
1609
+ };
1610
+
1611
+ export const setEvents = function (root) {
1612
+ destroyEvents(root);
1613
+ root.addEventListener('mouseup', mouseUpControls);
1614
+ root.addEventListener('mousedown', mouseDownControls);
1615
+ root.addEventListener('mousemove', mouseMoveControls);
1616
+ root.addEventListener('mouseover', mouseOverControls);
1617
+ root.addEventListener('dblclick', doubleClickControls);
1618
+ root.addEventListener('paste', pasteControls);
1619
+ root.addEventListener('contextmenu', contextMenuControls);
1620
+ root.addEventListener('touchstart', touchStartControls);
1621
+ root.addEventListener('touchend', touchEndControls);
1622
+ root.addEventListener('touchcancel', touchEndControls);
1623
+ root.addEventListener('touchmove', touchEndControls);
1624
+ document.addEventListener('keydown', keyDownControls);
1625
+ };
1626
+
1627
+ export const destroyEvents = function (root) {
1628
+ root.removeEventListener('mouseup', mouseUpControls);
1629
+ root.removeEventListener('mousedown', mouseDownControls);
1630
+ root.removeEventListener('mousemove', mouseMoveControls);
1631
+ root.removeEventListener('mouseover', mouseOverControls);
1632
+ root.removeEventListener('dblclick', doubleClickControls);
1633
+ root.removeEventListener('paste', pasteControls);
1634
+ root.removeEventListener('contextmenu', contextMenuControls);
1635
+ root.removeEventListener('touchstart', touchStartControls);
1636
+ root.removeEventListener('touchend', touchEndControls);
1637
+ root.removeEventListener('touchcancel', touchEndControls);
1638
+ document.removeEventListener('keydown', keyDownControls);
1639
+ };