canvas-datagrid 0.25.3 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +328 -1
- package/README.md +85 -67
- package/dist/canvas-datagrid.debug.js +7606 -3099
- package/dist/canvas-datagrid.debug.map +1 -1
- package/dist/canvas-datagrid.js +1 -1
- package/dist/canvas-datagrid.module.js +1 -1
- package/dist/canvas-datagrid.module.js.map +1 -1
- package/dist/types.d.ts +2508 -0
- package/lib/button.js +326 -0
- package/lib/component.js +51 -13
- package/lib/contextMenu.js +408 -30
- package/lib/defaults.js +100 -7
- package/lib/docs.js +121 -11
- package/lib/dom.js +239 -18
- package/lib/draw.js +1446 -206
- package/lib/events/index.js +2640 -0
- package/lib/events/util.js +165 -0
- package/lib/groups/util.js +42 -0
- package/lib/intf.js +908 -87
- package/lib/main.js +8 -1
- package/lib/publicMethods.js +773 -377
- package/lib/selections/index.js +989 -0
- package/lib/selections/type.d.ts +38 -0
- package/lib/selections/util.js +1320 -0
- package/lib/touch.js +20 -47
- package/package.json +32 -21
- package/lib/events.js +0 -1741
package/lib/contextMenu.js
CHANGED
|
@@ -173,6 +173,33 @@ export default function (self) {
|
|
|
173
173
|
self.parentDOMNode.appendChild(downArrow);
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
|
+
function fade(element) {
|
|
177
|
+
var opacity = 1;
|
|
178
|
+
var timer = setInterval(function () {
|
|
179
|
+
if (opacity <= 0.1) {
|
|
180
|
+
clearInterval(timer);
|
|
181
|
+
element.style.display = 'none';
|
|
182
|
+
if (element.parentNode) {
|
|
183
|
+
element.parentNode.removeChild(element);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
element.style.opacity = opacity;
|
|
187
|
+
element.style.filter = 'alpha(opacity=' + opacity * 100 + ')';
|
|
188
|
+
opacity -= opacity * 0.1;
|
|
189
|
+
}, self.attributes.animationDurationHideContextMenu * 0.1);
|
|
190
|
+
}
|
|
191
|
+
function unfade(element) {
|
|
192
|
+
var opacity = 0.1;
|
|
193
|
+
element.style.display = 'block';
|
|
194
|
+
var timer = setInterval(function () {
|
|
195
|
+
if (opacity >= 1) {
|
|
196
|
+
clearInterval(timer);
|
|
197
|
+
}
|
|
198
|
+
element.style.opacity = opacity;
|
|
199
|
+
element.style.filter = 'alpha(opacity=' + opacity * 100 + ')';
|
|
200
|
+
opacity += opacity * 0.1;
|
|
201
|
+
}, self.attributes.animationDurationShowContextMenu * 0.1);
|
|
202
|
+
}
|
|
176
203
|
function startHoverScroll(type) {
|
|
177
204
|
return function t() {
|
|
178
205
|
var a = self.attributes.contextHoverScrollAmount;
|
|
@@ -210,6 +237,7 @@ export default function (self) {
|
|
|
210
237
|
loc.y = pos.top - s.top;
|
|
211
238
|
loc.height = 0;
|
|
212
239
|
zIndexTop += 1;
|
|
240
|
+
container.style.opacity = 0;
|
|
213
241
|
container.style.position = 'absolute';
|
|
214
242
|
upArrow.style.color = self.style.contextMenuArrowColor;
|
|
215
243
|
downArrow.style.color = self.style.contextMenuArrowColor;
|
|
@@ -246,6 +274,7 @@ export default function (self) {
|
|
|
246
274
|
container.appendChild(upArrow);
|
|
247
275
|
document.body.appendChild(downArrow);
|
|
248
276
|
document.body.appendChild(container);
|
|
277
|
+
unfade(container);
|
|
249
278
|
rect = container.getBoundingClientRect();
|
|
250
279
|
// TODO: fix !(parentContextMenu && parentContextMenu.inputDropdown) state (autocomplete)
|
|
251
280
|
if (rect.bottom > window.innerHeight) {
|
|
@@ -307,9 +336,7 @@ export default function (self) {
|
|
|
307
336
|
c.dispose();
|
|
308
337
|
});
|
|
309
338
|
[downArrow, upArrow, container].forEach(function (el) {
|
|
310
|
-
|
|
311
|
-
el.parentNode.removeChild(el);
|
|
312
|
-
}
|
|
339
|
+
fade(el);
|
|
313
340
|
});
|
|
314
341
|
};
|
|
315
342
|
Object.defineProperty(intf, 'selectedIndex', {
|
|
@@ -317,7 +344,7 @@ export default function (self) {
|
|
|
317
344
|
return selectedIndex;
|
|
318
345
|
},
|
|
319
346
|
set: function (value) {
|
|
320
|
-
if (typeof value !== 'number' || isNaN(value || !isFinite(value))
|
|
347
|
+
if (typeof value !== 'number' || isNaN(value) || !isFinite(value)) {
|
|
321
348
|
throw new Error('Context menu selected index must be a sane number.');
|
|
322
349
|
}
|
|
323
350
|
selectedIndex = value;
|
|
@@ -367,7 +394,7 @@ export default function (self) {
|
|
|
367
394
|
var items = {};
|
|
368
395
|
var blanksItem = [];
|
|
369
396
|
|
|
370
|
-
self.
|
|
397
|
+
self.viewData.forEach(function (row) {
|
|
371
398
|
var cellValue =
|
|
372
399
|
row[e.cell.header.name] == null
|
|
373
400
|
? row[e.cell.header.name]
|
|
@@ -511,8 +538,23 @@ export default function (self) {
|
|
|
511
538
|
});
|
|
512
539
|
}
|
|
513
540
|
}
|
|
541
|
+
|
|
514
542
|
function addDefaultContextMenuItem(e) {
|
|
515
|
-
|
|
543
|
+
const schema = self.getSchema();
|
|
544
|
+
/**
|
|
545
|
+
* A map between columnIndex and column data
|
|
546
|
+
* @type {Map<string,any>}
|
|
547
|
+
*/
|
|
548
|
+
let columns;
|
|
549
|
+
const getColumnsMap = () => {
|
|
550
|
+
if (!columns)
|
|
551
|
+
columns = new Map(schema.map((_col) => [_col.columnIndex, _col]));
|
|
552
|
+
return columns;
|
|
553
|
+
};
|
|
554
|
+
const isSorting =
|
|
555
|
+
self.orderings.columns && self.orderings.columns.length > 0;
|
|
556
|
+
|
|
557
|
+
const isNormalCell =
|
|
516
558
|
!(
|
|
517
559
|
e.cell.isBackground ||
|
|
518
560
|
e.cell.isColumnHeaderCellCap ||
|
|
@@ -523,12 +565,7 @@ export default function (self) {
|
|
|
523
565
|
if (self.attributes.showFilter && isNormalCell) {
|
|
524
566
|
createFilterContextMenuItems(e);
|
|
525
567
|
}
|
|
526
|
-
if (
|
|
527
|
-
self.attributes.showCopy &&
|
|
528
|
-
self.selections.reduce(function (p, r) {
|
|
529
|
-
return p + r.length;
|
|
530
|
-
}, 0) > 0
|
|
531
|
-
) {
|
|
568
|
+
if (self.attributes.showCopy && self.canSelectionsBeCopied()) {
|
|
532
569
|
e.items.push({
|
|
533
570
|
title: self.attributes.copyText,
|
|
534
571
|
click: function () {
|
|
@@ -542,7 +579,11 @@ export default function (self) {
|
|
|
542
579
|
e.items.push({
|
|
543
580
|
title: self.attributes.pasteText,
|
|
544
581
|
click: function () {
|
|
545
|
-
|
|
582
|
+
// Original function call:
|
|
583
|
+
// self.paste(self.clipBoardData, e.cell.columnIndex, e.cell.rowIndex);
|
|
584
|
+
// We can remove the last two parameters follow
|
|
585
|
+
// because this function only need one parameter by following the function declaration
|
|
586
|
+
self.paste(self.clipBoardData);
|
|
546
587
|
self.draw();
|
|
547
588
|
},
|
|
548
589
|
});
|
|
@@ -582,20 +623,35 @@ export default function (self) {
|
|
|
582
623
|
},
|
|
583
624
|
});
|
|
584
625
|
if (e.cell && e.cell.header && e.cell.columnIndex > -1) {
|
|
626
|
+
// This variable represents the order index because of the following codes from `draw.js`:
|
|
627
|
+
// columnIndex: columnOrderIndex,
|
|
628
|
+
const columnOrderIndex = e.cell.columnIndex;
|
|
629
|
+
const columnIndex = self.orders.columns[columnOrderIndex];
|
|
630
|
+
|
|
631
|
+
const contiguousColumns = self.getSelectedContiguousColumns(schema);
|
|
632
|
+
let title = '';
|
|
633
|
+
if (contiguousColumns) {
|
|
634
|
+
title = contiguousColumns
|
|
635
|
+
.map((col) => col.title || col.name)
|
|
636
|
+
.join('-');
|
|
637
|
+
} else {
|
|
638
|
+
const column = schema[columnIndex];
|
|
639
|
+
if (column) title = column.title || column.name;
|
|
640
|
+
}
|
|
585
641
|
e.items.push({
|
|
586
|
-
title: self.attributes.hideColumnText.replace(
|
|
587
|
-
/%s/gi,
|
|
588
|
-
e.cell.header.title || e.cell.header.name,
|
|
589
|
-
),
|
|
642
|
+
title: self.attributes.hideColumnText.replace(/%s/gi, title),
|
|
590
643
|
click: function (ev) {
|
|
591
|
-
self.getSchema()[e.cell.columnIndex].hidden = true;
|
|
592
644
|
ev.preventDefault();
|
|
593
645
|
self.stopPropagation(ev);
|
|
594
646
|
self.disposeContextMenu();
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
647
|
+
if (contiguousColumns) {
|
|
648
|
+
self.hideColumns(
|
|
649
|
+
contiguousColumns[0].orderIndex,
|
|
650
|
+
contiguousColumns[1].orderIndex,
|
|
651
|
+
);
|
|
652
|
+
} else {
|
|
653
|
+
self.hideColumns(columnOrderIndex);
|
|
654
|
+
}
|
|
599
655
|
},
|
|
600
656
|
});
|
|
601
657
|
}
|
|
@@ -618,8 +674,8 @@ export default function (self) {
|
|
|
618
674
|
self.dispatchEvent('resizecolumn', {
|
|
619
675
|
columnWidth: self.style.cellWidth,
|
|
620
676
|
});
|
|
621
|
-
self.
|
|
622
|
-
|
|
677
|
+
self.dispatchResizeRow({
|
|
678
|
+
height: self.style.cellHeight,
|
|
623
679
|
});
|
|
624
680
|
self.setStorageData();
|
|
625
681
|
self.resize(true);
|
|
@@ -657,6 +713,254 @@ export default function (self) {
|
|
|
657
713
|
},
|
|
658
714
|
});
|
|
659
715
|
}
|
|
716
|
+
|
|
717
|
+
//#region hide rows
|
|
718
|
+
const canHideRows = !isSorting && e.cell.isRowHeader && e.cell.header;
|
|
719
|
+
if (canHideRows) {
|
|
720
|
+
const range = self.getSelectedContiguousRows(true);
|
|
721
|
+
if (range) {
|
|
722
|
+
const boundRowIndexes = range.map((viewRowIndex) =>
|
|
723
|
+
self.getBoundRowIndexFromViewRowIndex(viewRowIndex),
|
|
724
|
+
);
|
|
725
|
+
let title;
|
|
726
|
+
if (boundRowIndexes.length === 1) {
|
|
727
|
+
if (typeof boundRowIndexes[0] === 'number')
|
|
728
|
+
title = boundRowIndexes[0] + 1;
|
|
729
|
+
else title = range[0] + 1;
|
|
730
|
+
|
|
731
|
+
title = self.attributes.showHideRow.replace('%s', title);
|
|
732
|
+
// hide one row
|
|
733
|
+
e.items.push({
|
|
734
|
+
title,
|
|
735
|
+
click: function (ev) {
|
|
736
|
+
ev.preventDefault();
|
|
737
|
+
self.hideRows(boundRowIndexes[0], boundRowIndexes[0]);
|
|
738
|
+
},
|
|
739
|
+
});
|
|
740
|
+
} else if (boundRowIndexes[0] <= boundRowIndexes[1]) {
|
|
741
|
+
title = boundRowIndexes
|
|
742
|
+
.map((it, index) => {
|
|
743
|
+
if (typeof it === 'number') return it + 1;
|
|
744
|
+
return range[index] + 1;
|
|
745
|
+
})
|
|
746
|
+
.join('-');
|
|
747
|
+
title = self.attributes.showHideRows.replace('%s', title);
|
|
748
|
+
// hide rows
|
|
749
|
+
e.items.push({
|
|
750
|
+
title,
|
|
751
|
+
click: function (ev) {
|
|
752
|
+
ev.preventDefault();
|
|
753
|
+
self.hideRows(boundRowIndexes[0], boundRowIndexes[1]);
|
|
754
|
+
},
|
|
755
|
+
});
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
//#endregion hide rows
|
|
760
|
+
|
|
761
|
+
//#region group/ungroup columns
|
|
762
|
+
const groupAreaHeight = self.getColumnGroupAreaHeight();
|
|
763
|
+
const groupAreaWidth = self.getRowGroupAreaWidth();
|
|
764
|
+
const setCollapseStateForAllGroups = (allGroups, collapsed) => {
|
|
765
|
+
if (allGroups.length === 0) return;
|
|
766
|
+
for (let i = 0; i < allGroups.length; i++) {
|
|
767
|
+
const groups = allGroups[i];
|
|
768
|
+
for (let j = 0; j < groups.length; j++) {
|
|
769
|
+
const group = groups[j];
|
|
770
|
+
group.collapsed = collapsed;
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
self.refresh();
|
|
774
|
+
};
|
|
775
|
+
if (e.pos && e.pos.y < groupAreaHeight) {
|
|
776
|
+
e.items.push({
|
|
777
|
+
title: self.attributes.showRemoveAllGroupColumns,
|
|
778
|
+
click: function (ev) {
|
|
779
|
+
ev.preventDefault();
|
|
780
|
+
self.groupedColumns = [];
|
|
781
|
+
self.refresh();
|
|
782
|
+
},
|
|
783
|
+
});
|
|
784
|
+
e.items.push({
|
|
785
|
+
title: self.attributes.showExpandAllGroupColumns,
|
|
786
|
+
click: function (ev) {
|
|
787
|
+
ev.preventDefault();
|
|
788
|
+
setCollapseStateForAllGroups(self.groupedColumns, false);
|
|
789
|
+
},
|
|
790
|
+
});
|
|
791
|
+
e.items.push({
|
|
792
|
+
title: self.attributes.showCollapseAllGroupColumns,
|
|
793
|
+
click: function (ev) {
|
|
794
|
+
ev.preventDefault();
|
|
795
|
+
setCollapseStateForAllGroups(self.groupedColumns, true);
|
|
796
|
+
},
|
|
797
|
+
});
|
|
798
|
+
}
|
|
799
|
+
if (e.pos && e.pos.x < groupAreaWidth) {
|
|
800
|
+
e.items.push({
|
|
801
|
+
title: self.attributes.showRemoveAllGroupRows,
|
|
802
|
+
click: function (ev) {
|
|
803
|
+
ev.preventDefault();
|
|
804
|
+
self.groupedRows = [];
|
|
805
|
+
self.refresh();
|
|
806
|
+
},
|
|
807
|
+
});
|
|
808
|
+
e.items.push({
|
|
809
|
+
title: self.attributes.showExpandAllGroupRows,
|
|
810
|
+
click: function (ev) {
|
|
811
|
+
ev.preventDefault();
|
|
812
|
+
setCollapseStateForAllGroups(self.groupedRows, false);
|
|
813
|
+
},
|
|
814
|
+
});
|
|
815
|
+
e.items.push({
|
|
816
|
+
title: self.attributes.showCollapseAllGroupRows,
|
|
817
|
+
click: function (ev) {
|
|
818
|
+
ev.preventDefault();
|
|
819
|
+
setCollapseStateForAllGroups(self.groupedRows, true);
|
|
820
|
+
},
|
|
821
|
+
});
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
const canGroupByColumns =
|
|
825
|
+
self.attributes.allowGroupingColumns &&
|
|
826
|
+
e.cell.isColumnHeader &&
|
|
827
|
+
e.cell.header &&
|
|
828
|
+
e.cell.header.index > 0;
|
|
829
|
+
const canUngroupColumns =
|
|
830
|
+
self.attributes.allowGroupingColumns && e.cell.isColumnHeader;
|
|
831
|
+
const canGroupByRows =
|
|
832
|
+
!isSorting &&
|
|
833
|
+
self.attributes.allowGroupingRows &&
|
|
834
|
+
e.cell.isRowHeader &&
|
|
835
|
+
e.cell.header;
|
|
836
|
+
const canUngroupRows =
|
|
837
|
+
self.attributes.allowGroupingRows && e.cell.isRowHeader;
|
|
838
|
+
|
|
839
|
+
if (canGroupByColumns) {
|
|
840
|
+
/** @type {number[]} */
|
|
841
|
+
const groupIndexes = [];
|
|
842
|
+
/** @type {number} */
|
|
843
|
+
const headerIndex = e.cell.header.index;
|
|
844
|
+
let col = headerIndex;
|
|
845
|
+
for (; col >= 0; col--) {
|
|
846
|
+
if (!self.isColumnSelected(col)) break;
|
|
847
|
+
groupIndexes[0] = col;
|
|
848
|
+
}
|
|
849
|
+
for (col = headerIndex; ; col++) {
|
|
850
|
+
if (!self.isColumnSelected(col)) break;
|
|
851
|
+
groupIndexes[1] = col;
|
|
852
|
+
}
|
|
853
|
+
if (
|
|
854
|
+
col !== headerIndex &&
|
|
855
|
+
groupIndexes.length === 2 &&
|
|
856
|
+
groupIndexes[1] > groupIndexes[0] &&
|
|
857
|
+
self.isNewGroupRangeValid(
|
|
858
|
+
self.groupedColumns,
|
|
859
|
+
groupIndexes[0],
|
|
860
|
+
groupIndexes[1],
|
|
861
|
+
)
|
|
862
|
+
) {
|
|
863
|
+
const columns = getColumnsMap();
|
|
864
|
+
const groupTitles = [];
|
|
865
|
+
const groupNames = [];
|
|
866
|
+
for (let i = 0; i < groupIndexes.length; i++) {
|
|
867
|
+
const columnIndex = groupIndexes[i];
|
|
868
|
+
const column = columns.get(columnIndex);
|
|
869
|
+
if (column) {
|
|
870
|
+
groupNames.push(column.name);
|
|
871
|
+
groupTitles.push(column.title || column.name || column.index);
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
if (groupNames[0] && groupNames[1]) {
|
|
875
|
+
// show group options
|
|
876
|
+
e.items.push({
|
|
877
|
+
title: self.attributes.showGroupColumns.replace(
|
|
878
|
+
'%s',
|
|
879
|
+
groupTitles[0] + '-' + groupTitles[1],
|
|
880
|
+
),
|
|
881
|
+
click: function (ev) {
|
|
882
|
+
ev.preventDefault();
|
|
883
|
+
self.groupColumns(groupNames[0], groupNames[1]);
|
|
884
|
+
self.controlInput.focus();
|
|
885
|
+
},
|
|
886
|
+
});
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
if (canUngroupColumns) {
|
|
891
|
+
const columnIndex = e.cell.columnIndex;
|
|
892
|
+
const groups = self.getGroupsColumnBelongsTo(columnIndex);
|
|
893
|
+
const columns = getColumnsMap();
|
|
894
|
+
for (let i = 0; i < groups.length; i++) {
|
|
895
|
+
const { from, to } = groups[i];
|
|
896
|
+
const cell0 = columns.get(from);
|
|
897
|
+
const cell1 = columns.get(to);
|
|
898
|
+
if (cell0 && cell1) {
|
|
899
|
+
const formatArgs =
|
|
900
|
+
(cell0.title || cell0.name || cell0.index) +
|
|
901
|
+
'-' +
|
|
902
|
+
(cell1.title || cell1.name || cell1.index);
|
|
903
|
+
e.items.push({
|
|
904
|
+
title: self.attributes.showRemoveGroupColumns.replace(
|
|
905
|
+
'%s',
|
|
906
|
+
formatArgs,
|
|
907
|
+
),
|
|
908
|
+
click: function (ev) {
|
|
909
|
+
ev.preventDefault();
|
|
910
|
+
self.removeGroupColumns(cell0.name, cell1.name);
|
|
911
|
+
self.controlInput.focus();
|
|
912
|
+
},
|
|
913
|
+
});
|
|
914
|
+
} else {
|
|
915
|
+
console.warn(`Cannot find column ${from} or column ${to}`);
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
if (canGroupByRows) {
|
|
920
|
+
const range = self.getSelectedContiguousRows(false) || [];
|
|
921
|
+
const rangeTitle = range
|
|
922
|
+
.map((rowIndex) => {
|
|
923
|
+
const index = self.getBoundRowIndexFromViewRowIndex(rowIndex);
|
|
924
|
+
if (typeof index === 'number') return index + 1;
|
|
925
|
+
return rowIndex + 1;
|
|
926
|
+
})
|
|
927
|
+
.join('-');
|
|
928
|
+
if (
|
|
929
|
+
range.length === 2 &&
|
|
930
|
+
self.isNewGroupRangeValid(self.groupedRows, range[0], range[1])
|
|
931
|
+
) {
|
|
932
|
+
e.items.push({
|
|
933
|
+
title: self.attributes.showGroupRows.replace('%s', rangeTitle),
|
|
934
|
+
click: function (ev) {
|
|
935
|
+
ev.preventDefault();
|
|
936
|
+
self.groupRows(range[0], range[1]);
|
|
937
|
+
},
|
|
938
|
+
});
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
if (canUngroupRows) {
|
|
942
|
+
const rowIndex = e.cell.rowIndex;
|
|
943
|
+
const groups = self.getGroupsRowBelongsTo(rowIndex);
|
|
944
|
+
for (let i = 0; i < groups.length; i++) {
|
|
945
|
+
const { from, to } = groups[i];
|
|
946
|
+
const rangeTitle = [from, to]
|
|
947
|
+
.map((rowIndex) => {
|
|
948
|
+
const index = self.getBoundRowIndexFromViewRowIndex(rowIndex);
|
|
949
|
+
if (typeof index === 'number') return index + 1;
|
|
950
|
+
return rowIndex + 1;
|
|
951
|
+
})
|
|
952
|
+
.join('-');
|
|
953
|
+
e.items.push({
|
|
954
|
+
title: self.attributes.showRemoveGroupRows.replace('%s', rangeTitle),
|
|
955
|
+
click: function (ev) {
|
|
956
|
+
ev.preventDefault();
|
|
957
|
+
self.removeGroupRows(from, to);
|
|
958
|
+
self.controlInput.focus();
|
|
959
|
+
},
|
|
960
|
+
});
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
//#endregion group/ungroup columns
|
|
660
964
|
}
|
|
661
965
|
self.disposeAutocomplete = function () {
|
|
662
966
|
if (autoCompleteContext) {
|
|
@@ -664,7 +968,18 @@ export default function (self) {
|
|
|
664
968
|
autoCompleteContext = undefined;
|
|
665
969
|
}
|
|
666
970
|
};
|
|
667
|
-
self.disposeContextMenu = function () {
|
|
971
|
+
self.disposeContextMenu = function (event) {
|
|
972
|
+
if (
|
|
973
|
+
event &&
|
|
974
|
+
event.type === 'click' &&
|
|
975
|
+
event.ctrlKey &&
|
|
976
|
+
self.contextMenuOpenedAt !== undefined &&
|
|
977
|
+
performance.now() - self.contextMenuOpenedAt < 500
|
|
978
|
+
) {
|
|
979
|
+
// macOS Safari dispatches a click right after a ctrl-click contextmenu,
|
|
980
|
+
// which would close the menu immediately (#521)
|
|
981
|
+
return;
|
|
982
|
+
}
|
|
668
983
|
document.removeEventListener('click', self.disposeContextMenu);
|
|
669
984
|
zIndexTop = self.style.contextMenuZIndex;
|
|
670
985
|
self.disposeAutocomplete();
|
|
@@ -672,15 +987,67 @@ export default function (self) {
|
|
|
672
987
|
self.contextMenu.dispose();
|
|
673
988
|
}
|
|
674
989
|
self.contextMenu = undefined;
|
|
990
|
+
if (event) {
|
|
991
|
+
self.canvas.focus();
|
|
992
|
+
self.mousedown(event);
|
|
993
|
+
self.mouseup(event);
|
|
994
|
+
}
|
|
675
995
|
};
|
|
676
996
|
self.contextmenuEvent = function (e, overridePos) {
|
|
677
997
|
if (!self.hasFocus && e.target !== self.canvas) {
|
|
678
998
|
return;
|
|
679
999
|
}
|
|
680
|
-
|
|
1000
|
+
// don't create context menu for parents if current position is located in child grid
|
|
1001
|
+
const children = Object.keys(self.childGrids);
|
|
1002
|
+
for (let i = 0; i < children.length; i++) {
|
|
1003
|
+
const childGrid = self.childGrids[children[i]];
|
|
1004
|
+
const parentNode = childGrid && childGrid.parentNode;
|
|
1005
|
+
if (!parentNode) continue;
|
|
1006
|
+
const { offsetLeft, offsetWidth, offsetTop, offsetHeight } = parentNode;
|
|
1007
|
+
if ((e.x >= offsetLeft && e.x <= offsetLeft + offsetWidth) === false)
|
|
1008
|
+
continue;
|
|
1009
|
+
if ((e.y >= offsetTop && e.y <= offsetTop + offsetHeight) === false)
|
|
1010
|
+
continue;
|
|
1011
|
+
return; // in child grid
|
|
1012
|
+
}
|
|
1013
|
+
// don't create context menu for child if current position is located in parent grid
|
|
1014
|
+
if (self.isChildGrid && self.parentNode) {
|
|
1015
|
+
//#region check is current child grid closed
|
|
1016
|
+
const childGridsOfParent = self.parentGrid && self.parentGrid.childGrids;
|
|
1017
|
+
if (!childGridsOfParent || !Array.isArray(childGridsOfParent)) return;
|
|
1018
|
+
const matchedMe = childGridsOfParent.find((grid) => {
|
|
1019
|
+
const nodeA = grid.parentNode;
|
|
1020
|
+
const nodeB = self.parentNode;
|
|
1021
|
+
return (
|
|
1022
|
+
nodeA.offsetTop == nodeB.offsetTop &&
|
|
1023
|
+
nodeA.offsetLeft === nodeB.offsetLeft
|
|
1024
|
+
);
|
|
1025
|
+
});
|
|
1026
|
+
if (!matchedMe) return;
|
|
1027
|
+
//#endregion
|
|
1028
|
+
|
|
1029
|
+
let x0 = self.parentNode.offsetLeft;
|
|
1030
|
+
let x1 = self.parentNode.offsetLeft + self.parentNode.offsetWidth;
|
|
1031
|
+
let y0 = self.parentNode.offsetTop;
|
|
1032
|
+
let y1 = self.parentNode.offsetTop + self.parentNode.offsetHeight;
|
|
1033
|
+
let node = self.parentNode.parentNode;
|
|
1034
|
+
while (node) {
|
|
1035
|
+
const { offsetLeft, offsetWidth, offsetTop, offsetHeight } = node;
|
|
1036
|
+
if (offsetLeft > x0) x0 = offsetLeft;
|
|
1037
|
+
if (offsetTop > y0) y0 = offsetTop;
|
|
1038
|
+
const newX1 = offsetLeft + offsetWidth;
|
|
1039
|
+
const newY1 = offsetTop + offsetHeight;
|
|
1040
|
+
if (newX1 < x1) x1 = newX1;
|
|
1041
|
+
if (newY1 < y1) y1 = newY1;
|
|
1042
|
+
if (node.nodeType !== 'canvas-datagrid-tree') break;
|
|
1043
|
+
node = node.parentNode;
|
|
1044
|
+
}
|
|
1045
|
+
if ((e.x >= x0 && e.x <= x1 && e.y >= y0 && e.y <= y1) === false) return;
|
|
1046
|
+
}
|
|
1047
|
+
function createDisposeEvent() {
|
|
681
1048
|
requestAnimationFrame(function () {
|
|
682
1049
|
document.addEventListener('click', self.disposeContextMenu);
|
|
683
|
-
|
|
1050
|
+
window.removeEventListener('mouseup', createDisposeEvent);
|
|
684
1051
|
});
|
|
685
1052
|
}
|
|
686
1053
|
var contextPosition,
|
|
@@ -689,12 +1056,13 @@ export default function (self) {
|
|
|
689
1056
|
ev = {
|
|
690
1057
|
NativeEvent: e,
|
|
691
1058
|
cell: self.getCellAt(pos.x, pos.y),
|
|
1059
|
+
pos,
|
|
692
1060
|
items: items,
|
|
693
1061
|
};
|
|
694
1062
|
if (!ev.cell.isGrid) {
|
|
695
1063
|
addDefaultContextMenuItem(ev);
|
|
696
1064
|
}
|
|
697
|
-
if (self.dispatchEvent('contextmenu', ev)) {
|
|
1065
|
+
if (e.type !== 'mousedown' && self.dispatchEvent('contextmenu', ev)) {
|
|
698
1066
|
return;
|
|
699
1067
|
}
|
|
700
1068
|
if (!ev.cell.isGrid) {
|
|
@@ -722,8 +1090,18 @@ export default function (self) {
|
|
|
722
1090
|
contextPosition.width =
|
|
723
1091
|
self.width - self.style.mobileContextMenuMargin * 2 + 'px';
|
|
724
1092
|
}
|
|
725
|
-
|
|
726
|
-
|
|
1093
|
+
if (e.type == 'mousedown') {
|
|
1094
|
+
contextPosition.top += self.style.filterButtonMenuOffsetTop;
|
|
1095
|
+
}
|
|
1096
|
+
// use ev.items, not the captured array: a listener may assign a new
|
|
1097
|
+
// array to e.items (#263)
|
|
1098
|
+
self.contextMenu = createContextMenu(ev, contextPosition, ev.items);
|
|
1099
|
+
self.contextMenuOpenedAt = performance.now();
|
|
1100
|
+
if (e.type == 'mousedown') {
|
|
1101
|
+
window.addEventListener('mouseup', createDisposeEvent);
|
|
1102
|
+
} else {
|
|
1103
|
+
createDisposeEvent();
|
|
1104
|
+
}
|
|
727
1105
|
e.preventDefault();
|
|
728
1106
|
}
|
|
729
1107
|
};
|