@syncfusion/ej2-filemanager 29.2.4 → 30.1.37

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 (163) hide show
  1. package/.eslintrc.json +2 -0
  2. package/dist/ej2-filemanager.min.js +2 -2
  3. package/dist/ej2-filemanager.umd.min.js +2 -2
  4. package/dist/ej2-filemanager.umd.min.js.map +1 -1
  5. package/dist/es6/ej2-filemanager.es2015.js +181 -20
  6. package/dist/es6/ej2-filemanager.es2015.js.map +1 -1
  7. package/dist/es6/ej2-filemanager.es5.js +182 -20
  8. package/dist/es6/ej2-filemanager.es5.js.map +1 -1
  9. package/dist/global/ej2-filemanager.min.js +2 -2
  10. package/dist/global/ej2-filemanager.min.js.map +1 -1
  11. package/dist/global/index.d.ts +1 -1
  12. package/dist/ts/file-manager/actions/breadcrumb-bar.d.ts +60 -0
  13. package/dist/ts/file-manager/actions/breadcrumb-bar.ts +423 -0
  14. package/dist/ts/file-manager/actions/index.d.ts +6 -0
  15. package/dist/ts/file-manager/actions/index.ts +6 -0
  16. package/dist/ts/file-manager/actions/toolbar.d.ts +54 -0
  17. package/dist/ts/file-manager/actions/toolbar.ts +609 -0
  18. package/dist/ts/file-manager/actions/virtualization.d.ts +93 -0
  19. package/dist/ts/file-manager/actions/virtualization.ts +324 -0
  20. package/dist/ts/file-manager/base/classes.d.ts +224 -0
  21. package/dist/ts/file-manager/base/classes.ts +225 -0
  22. package/dist/ts/file-manager/base/constant.d.ts +136 -0
  23. package/dist/ts/file-manager/base/constant.ts +137 -0
  24. package/dist/ts/file-manager/base/file-manager-model.d.ts +520 -0
  25. package/dist/ts/file-manager/base/file-manager.d.ts +867 -0
  26. package/dist/ts/file-manager/base/file-manager.ts +2061 -0
  27. package/dist/ts/file-manager/base/index.d.ts +8 -0
  28. package/dist/ts/file-manager/base/index.ts +8 -0
  29. package/dist/ts/file-manager/base/interface.d.ts +952 -0
  30. package/dist/ts/file-manager/base/interface.ts +931 -0
  31. package/dist/ts/file-manager/common/index.d.ts +5 -0
  32. package/dist/ts/file-manager/common/index.ts +5 -0
  33. package/dist/ts/file-manager/common/operations.d.ts +122 -0
  34. package/dist/ts/file-manager/common/operations.ts +1369 -0
  35. package/dist/ts/file-manager/common/utility.d.ts +644 -0
  36. package/dist/ts/file-manager/common/utility.ts +1728 -0
  37. package/dist/ts/file-manager/index.d.ts +9 -0
  38. package/dist/ts/file-manager/index.ts +9 -0
  39. package/dist/ts/file-manager/layout/details-view.d.ts +152 -0
  40. package/dist/ts/file-manager/layout/details-view.ts +1990 -0
  41. package/dist/ts/file-manager/layout/index.d.ts +6 -0
  42. package/dist/ts/file-manager/layout/index.ts +6 -0
  43. package/dist/ts/file-manager/layout/large-icons-view.d.ts +157 -0
  44. package/dist/ts/file-manager/layout/large-icons-view.ts +1684 -0
  45. package/dist/ts/file-manager/layout/navigation-pane.d.ts +104 -0
  46. package/dist/ts/file-manager/layout/navigation-pane.ts +919 -0
  47. package/dist/ts/file-manager/models/ajax-settings-model.d.ts +36 -0
  48. package/dist/ts/file-manager/models/ajax-settings.d.ts +30 -0
  49. package/dist/ts/file-manager/models/ajax-settings.ts +39 -0
  50. package/dist/ts/file-manager/models/column-model.d.ts +155 -0
  51. package/dist/ts/file-manager/models/column.d.ts +179 -0
  52. package/dist/ts/file-manager/models/column.ts +216 -0
  53. package/dist/ts/file-manager/models/contextMenu-settings-model.d.ts +36 -0
  54. package/dist/ts/file-manager/models/contextMenu-settings.d.ts +33 -0
  55. package/dist/ts/file-manager/models/contextMenu-settings.ts +44 -0
  56. package/dist/ts/file-manager/models/default-locale.d.ts +4 -0
  57. package/dist/ts/file-manager/models/default-locale.ts +101 -0
  58. package/dist/ts/file-manager/models/details-view-settings-model.d.ts +30 -0
  59. package/dist/ts/file-manager/models/details-view-settings.d.ts +31 -0
  60. package/dist/ts/file-manager/models/details-view-settings.ts +54 -0
  61. package/dist/ts/file-manager/models/index.d.ts +19 -0
  62. package/dist/ts/file-manager/models/index.ts +19 -0
  63. package/dist/ts/file-manager/models/navigation-pane-settings-model.d.ts +40 -0
  64. package/dist/ts/file-manager/models/navigation-pane-settings.d.ts +34 -0
  65. package/dist/ts/file-manager/models/navigation-pane-settings.ts +42 -0
  66. package/dist/ts/file-manager/models/search-settings-model.d.ts +42 -0
  67. package/dist/ts/file-manager/models/search-settings.d.ts +44 -0
  68. package/dist/ts/file-manager/models/search-settings.ts +53 -0
  69. package/dist/ts/file-manager/models/toolbar-settings-model.d.ts +197 -0
  70. package/dist/ts/file-manager/models/toolbar-settings.d.ts +174 -0
  71. package/dist/ts/file-manager/models/toolbar-settings.ts +198 -0
  72. package/dist/ts/file-manager/models/upload-settings-model.d.ts +70 -0
  73. package/dist/ts/file-manager/models/upload-settings.d.ts +61 -0
  74. package/dist/ts/file-manager/models/upload-settings.ts +75 -0
  75. package/dist/ts/file-manager/pop-up/context-menu.d.ts +64 -0
  76. package/dist/ts/file-manager/pop-up/context-menu.ts +693 -0
  77. package/dist/ts/file-manager/pop-up/dialog.d.ts +31 -0
  78. package/dist/ts/file-manager/pop-up/dialog.ts +1009 -0
  79. package/dist/ts/file-manager/pop-up/index.d.ts +5 -0
  80. package/dist/ts/file-manager/pop-up/index.ts +5 -0
  81. package/dist/ts/index.d.ts +4 -0
  82. package/dist/ts/index.ts +4 -0
  83. package/package.json +16 -17
  84. package/src/file-manager/base/interface.d.ts +10 -0
  85. package/src/file-manager/common/operations.d.ts +18 -1
  86. package/src/file-manager/common/operations.js +59 -0
  87. package/src/file-manager/common/utility.d.ts +3 -3
  88. package/src/file-manager/common/utility.js +20 -6
  89. package/src/file-manager/layout/details-view.js +4 -3
  90. package/src/file-manager/layout/large-icons-view.d.ts +3 -0
  91. package/src/file-manager/layout/large-icons-view.js +67 -9
  92. package/src/file-manager/layout/navigation-pane.js +2 -0
  93. package/src/file-manager/pop-up/dialog.d.ts +3 -3
  94. package/src/file-manager/pop-up/dialog.js +34 -6
  95. package/styles/bds-lite.css +51 -1
  96. package/styles/bds.css +51 -1
  97. package/styles/bootstrap-dark-lite.css +51 -0
  98. package/styles/bootstrap-dark.css +51 -0
  99. package/styles/bootstrap-lite.css +51 -0
  100. package/styles/bootstrap.css +51 -0
  101. package/styles/bootstrap4-lite.css +51 -0
  102. package/styles/bootstrap4.css +51 -0
  103. package/styles/bootstrap5-dark-lite.css +51 -1
  104. package/styles/bootstrap5-dark.css +51 -1
  105. package/styles/bootstrap5-lite.css +51 -1
  106. package/styles/bootstrap5.3-lite.css +51 -0
  107. package/styles/bootstrap5.3.css +51 -0
  108. package/styles/bootstrap5.css +51 -1
  109. package/styles/fabric-dark-lite.css +51 -0
  110. package/styles/fabric-dark.css +51 -0
  111. package/styles/fabric-lite.css +51 -0
  112. package/styles/fabric.css +51 -0
  113. package/styles/file-manager/_bds-definition.scss +1 -0
  114. package/styles/file-manager/_bootstrap5-definition.scss +1 -0
  115. package/styles/file-manager/_layout.scss +46 -4
  116. package/styles/file-manager/_material3-definition.scss +2 -2
  117. package/styles/file-manager/_tailwind-definition.scss +1 -0
  118. package/styles/file-manager/_tailwind3-definition.scss +1 -0
  119. package/styles/file-manager/bds.css +51 -1
  120. package/styles/file-manager/bootstrap-dark.css +51 -0
  121. package/styles/file-manager/bootstrap.css +51 -0
  122. package/styles/file-manager/bootstrap4.css +51 -0
  123. package/styles/file-manager/bootstrap5-dark.css +51 -1
  124. package/styles/file-manager/bootstrap5.3.css +51 -0
  125. package/styles/file-manager/bootstrap5.css +51 -1
  126. package/styles/file-manager/fabric-dark.css +51 -0
  127. package/styles/file-manager/fabric.css +51 -0
  128. package/styles/file-manager/fluent-dark.css +51 -0
  129. package/styles/file-manager/fluent.css +51 -0
  130. package/styles/file-manager/fluent2.css +51 -0
  131. package/styles/file-manager/highcontrast-light.css +51 -0
  132. package/styles/file-manager/highcontrast.css +51 -0
  133. package/styles/file-manager/material-dark.css +51 -0
  134. package/styles/file-manager/material.css +51 -0
  135. package/styles/file-manager/material3-dark.css +53 -2
  136. package/styles/file-manager/material3.css +53 -2
  137. package/styles/file-manager/tailwind-dark.css +51 -1
  138. package/styles/file-manager/tailwind.css +51 -1
  139. package/styles/file-manager/tailwind3.css +51 -0
  140. package/styles/fluent-dark-lite.css +51 -0
  141. package/styles/fluent-dark.css +51 -0
  142. package/styles/fluent-lite.css +51 -0
  143. package/styles/fluent.css +51 -0
  144. package/styles/fluent2-lite.css +51 -0
  145. package/styles/fluent2.css +51 -0
  146. package/styles/highcontrast-light-lite.css +51 -0
  147. package/styles/highcontrast-light.css +51 -0
  148. package/styles/highcontrast-lite.css +51 -0
  149. package/styles/highcontrast.css +51 -0
  150. package/styles/material-dark-lite.css +51 -0
  151. package/styles/material-dark.css +51 -0
  152. package/styles/material-lite.css +51 -0
  153. package/styles/material.css +51 -0
  154. package/styles/material3-dark-lite.css +51 -0
  155. package/styles/material3-dark.css +53 -2
  156. package/styles/material3-lite.css +51 -0
  157. package/styles/material3.css +53 -2
  158. package/styles/tailwind-dark-lite.css +51 -1
  159. package/styles/tailwind-dark.css +51 -1
  160. package/styles/tailwind-lite.css +51 -1
  161. package/styles/tailwind.css +51 -1
  162. package/styles/tailwind3-lite.css +51 -0
  163. package/styles/tailwind3.css +51 -0
@@ -0,0 +1,693 @@
1
+ import { ContextMenu as Menu, BeforeOpenCloseMenuEventArgs, MenuItemModel } from '@syncfusion/ej2-navigations';
2
+ import { IFileManager, MenuClickEventArgs, MenuCloseEventArgs, MenuOpenEventArgs, NotifyArgs } from '../base/interface';
3
+ import { isNullOrUndefined as isNOU, KeyboardEventArgs, createElement, closest, KeyboardEvents } from '@syncfusion/ej2-base';
4
+ import { getValue, select } from '@syncfusion/ej2-base';
5
+ import { MenuEventArgs } from '@syncfusion/ej2-splitbuttons';
6
+ import { Download, GetDetails } from './../common/operations';
7
+ import { createDialog } from './dialog';
8
+ import { cutFiles, copyFiles, refresh, getPathObject, getLocaleText, updateLayout, getFullPath } from './../common/utility';
9
+ import { getCssClass, sortbyClickHandler, pasteHandler } from './../common/utility';
10
+ import { createDeniedDialog, createNewFolder, uploadItem, hasEditAccess, hasDownloadAccess } from './../common/utility';
11
+ import * as events from './../base/constant';
12
+ import * as CLS from '../base/classes';
13
+
14
+ /**
15
+ * ContextMenu module
16
+ */
17
+ export class ContextMenu {
18
+ private parent: IFileManager;
19
+ private targetElement: HTMLElement;
20
+ public contextMenu: Menu;
21
+ public menuTarget: HTMLElement;
22
+ public isMenuItemClicked: boolean = false;
23
+ private keyConfigs: { [key: string]: string };
24
+ private keyboardModule: KeyboardEvents;
25
+ private menuType: string;
26
+ private currentItems: MenuItemModel[] = [];
27
+ private currentElement: HTMLElement = null;
28
+ private disabledItems: string[] = [];
29
+ private targetNodeElement: HTMLElement;
30
+ private navUid: string;
31
+ public menuItemData: object;
32
+ /**
33
+ * Constructor for the ContextMenu module
34
+ *
35
+ * @param {IFileManager} parent - Specifies the parent element.
36
+ * @hidden
37
+ */
38
+ constructor(parent?: IFileManager) {
39
+ this.parent = parent;
40
+ this.render();
41
+ }
42
+
43
+ private render(): void {
44
+ this.keyConfigs = {
45
+ downarrow: 'downarrow',
46
+ uparrow: 'uparrown'
47
+ };
48
+ this.contextMenu = new Menu({
49
+ enableRtl: this.parent.enableRtl,
50
+ locale: this.parent.locale,
51
+ target: '#' + this.parent.element.id,
52
+ enableHtmlSanitizer: this.parent.enableHtmlSanitizer,
53
+ beforeItemRender: this.onBeforeItemRender.bind(this),
54
+ select: this.onSelect.bind(this),
55
+ beforeOpen: this.onBeforeOpen.bind(this),
56
+ beforeClose: this.onBeforeClose.bind(this),
57
+ cssClass: getCssClass(this.parent, CLS.ROOT_POPUP)
58
+ });
59
+ this.contextMenu.isStringTemplate = true;
60
+ this.contextMenu.appendTo('#' + this.parent.element.id + CLS.CONTEXT_MENU_ID);
61
+ this.addEventListener();
62
+ }
63
+
64
+ /* istanbul ignore next */
65
+ public onBeforeItemRender(args: MenuEventArgs): void {
66
+ if (args.item.id === this.getMenuId('largeiconsview')) {
67
+ const iconSpan: HTMLElement = createElement('span');
68
+ const element: HTMLElement = args.element;
69
+ element.insertBefore(iconSpan, this.parent.view === 'LargeIcons' ? element.childNodes[1] : element.childNodes[0]);
70
+ iconSpan.setAttribute('class', CLS.ICON_LARGE + ' ' + CLS.MENU_ICON);
71
+ }
72
+ if (args.item.id === this.getMenuId('detailsview')) {
73
+ const iconSpan: HTMLElement = createElement('span');
74
+ const element: HTMLElement = args.element;
75
+ element.insertBefore(iconSpan, this.parent.view === 'Details' ? element.childNodes[1] : element.childNodes[0]);
76
+ iconSpan.setAttribute('class', CLS.ICON_GRID + ' ' + CLS.MENU_ICON);
77
+ }
78
+ }
79
+
80
+ public onBeforeClose(args: BeforeOpenCloseMenuEventArgs): void {
81
+ const eventArgs: MenuCloseEventArgs = {
82
+ cancel: false,
83
+ element: args.element,
84
+ event: args.event,
85
+ isFocused: args.isFocused,
86
+ fileDetails: [this.menuItemData],
87
+ items: args.items,
88
+ parentItem: args.parentItem,
89
+ menuType: this.menuType
90
+ };
91
+ this.parent.trigger('menuClose', eventArgs, (menuCloseArgs: MenuCloseEventArgs) => {
92
+ if (menuCloseArgs.cancel){
93
+ args.cancel = menuCloseArgs.cancel;
94
+ return;
95
+ }
96
+ });
97
+ this.menuTarget = null;
98
+ if (!this.isMenuItemClicked && this.parent.pathId.length > 1 && this.parent.activeModule === 'navigationpane') {
99
+ this.parent.pathId.pop();
100
+ const parentKey: string[] = [];
101
+ const itemKeys: string[] = Object.keys(this.parent.feParent);
102
+ for (const item of itemKeys) {
103
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
104
+ const itemData: any = getValue(item, this.parent.feParent);
105
+ if (this.parent.pathNames.indexOf(itemData.name) !== -1) {
106
+ parentKey.push(itemData._fm_id);
107
+ }
108
+ }
109
+ this.parent.pathId.push(parentKey[parentKey.length - 1]);
110
+ this.parent.navigationpaneModule.treeObj.setProperties({selectedNodes: [this.parent.pathId[this.parent.pathId.length - 1]]});
111
+ }
112
+ this.isMenuItemClicked = false;
113
+ }
114
+
115
+ /* istanbul ignore next */
116
+ public onBeforeOpen(args: BeforeOpenCloseMenuEventArgs): void {
117
+ let selected: boolean = false;
118
+ let uid: string;
119
+ let data: { [key: string]: Object };
120
+ let treeFolder: boolean = false;
121
+ let target: Element = args.event.target as Element;
122
+ this.menuTarget = this.targetNodeElement = <HTMLElement>target;
123
+ this.currentElement = args.element;
124
+ if (target.classList.contains('e-spinner-pane')) {
125
+ target = this.parent.navigationpaneModule.activeNode.getElementsByClassName(CLS.FULLROW)[0];
126
+ this.menuTarget = this.targetNodeElement = <HTMLElement>target;
127
+ }
128
+ this.targetElement = this.parent.view === 'Details' ? closest(target, 'tr.e-row') as HTMLElement : target as HTMLElement;
129
+ if (this.parent.enableVirtualization && (target.classList.contains('e-virtual-bottom') || target.classList.contains('e-virtualtable'))) {
130
+ target = target.parentElement.closest('div');
131
+ }
132
+ const view: string = this.getTargetView(target);
133
+ this.updateActiveModule();
134
+ /* istanbul ignore next */
135
+ if (target.classList.contains(CLS.TREE_VIEW) || closest(target, 'th') ||
136
+ (closest(target, '#' + this.parent.element.id + CLS.BREADCRUMBBAR_ID)) ||
137
+ (closest(target, '#' + this.parent.element.id + CLS.TOOLBAR_ID))) {
138
+ args.cancel = true;
139
+ } else if (!(this.parent.view === 'LargeIcons') && this.targetElement &&
140
+ this.targetElement.classList.contains('e-emptyrow')) {
141
+ this.setLayoutItem(target);
142
+ /* istanbul ignore next */
143
+ } else if (closest(target, '.' + CLS.EMPTY)) {
144
+ this.setLayoutItem(target);
145
+ } else if (!target.classList.contains(CLS.MENU_ITEM) &&
146
+ !target.classList.contains(CLS.MENU_ICON) && !target.classList.contains(CLS.SUBMENU_ICON)) {
147
+ /* istanbul ignore next */
148
+ if (this.parent.view === 'LargeIcons' && !isNOU(closest(target, 'li')) && !closest(target, '#' + this.parent.element.id + CLS.TREE_ID)) {
149
+ const eveArgs: KeyboardEventArgs = { ctrlKey: true, shiftKey: true } as KeyboardEventArgs;
150
+ if (!closest(target, 'li').classList.contains('e-active')) {
151
+ this.parent.largeiconsviewModule.doSelection(target, eveArgs);
152
+ }
153
+ data = this.parent.visitedData as { [key: string]: Object };
154
+ selected = true;
155
+ } else if (!isNOU(closest(target, 'tr.e-row'))) {
156
+ uid = this.targetElement.getAttribute('data-uid');
157
+ data = this.parent.detailsviewModule.gridObj.getRowObjectFromUID(uid).data as { [key: string]: Object };
158
+ if (isNOU(this.targetElement.getAttribute('aria-selected'))) {
159
+ /* istanbul ignore next */
160
+ this.parent.detailsviewModule.gridObj.selectRows([parseInt(this.targetElement.getAttribute('aria-rowindex'), 10) - 1]);
161
+ }
162
+ selected = true;
163
+ /* istanbul ignore next */
164
+ } else if (closest(target, '#' + this.parent.element.id + CLS.TREE_ID)) {
165
+ uid = closest(target, 'li').getAttribute('data-uid');
166
+ if (!isNOU(uid)) {
167
+ this.navUid = uid;
168
+ }
169
+ treeFolder = true;
170
+ }
171
+ /* istanbul ignore next */
172
+ if (selected) {
173
+ if (getValue('isFile', data) === true) {
174
+ this.setFileItem();
175
+ } else {
176
+ this.setFolderItem(false);
177
+ }
178
+ /* istanbul ignore next */
179
+ } else if (treeFolder) {
180
+ this.setFolderItem(true);
181
+ if (uid === this.parent.pathId[0]) {
182
+ this.disabledItems.push('Delete', 'Rename', 'Cut', 'Copy');
183
+ } else {
184
+ const itemsToRemove: string[] = ['Delete', 'Rename', 'Cut', 'Copy'];
185
+ for (let i: number = 0; i < this.disabledItems.length; i++) {
186
+ const item: string = this.disabledItems[i as number];
187
+ if (itemsToRemove.indexOf(item) !== -1) {
188
+ this.disabledItems.splice(i, 1);
189
+ i--;
190
+ }
191
+ }
192
+ }
193
+ /* istanbul ignore next */
194
+ } else if (view === 'TreeView' || view === 'GridView' || view === 'LargeIcon') {
195
+ this.setLayoutItem(target);
196
+ /* istanbul ignore next */
197
+ } else {
198
+ args.cancel = true;
199
+ }
200
+ }
201
+ const pasteEle: Element = select('#' + this.getMenuId('Paste'), this.contextMenu.element);
202
+ if (!args.cancel && !this.parent.enablePaste &&
203
+ pasteEle && !pasteEle.classList.contains('e-disabled')) {
204
+ if (this.disabledItems.indexOf('Paste') === -1) {
205
+ this.disabledItems.push('Paste');
206
+ }
207
+ }
208
+ else {
209
+ const pasteIndex: number = this.disabledItems.indexOf('Paste');
210
+ if (pasteIndex !== -1) {
211
+ this.disabledItems.splice(pasteIndex, 1);
212
+ }
213
+ }
214
+ if (args.cancel) {
215
+ this.menuTarget = this.currentElement = null;
216
+ return;
217
+ }
218
+ this.contextMenu.dataBind();
219
+ let isSubMenu: boolean = false;
220
+ if (target.classList.contains(CLS.MENU_ITEM) ||
221
+ target.classList.contains(CLS.MENU_ICON) || target.classList.contains(CLS.SUBMENU_ICON)) {
222
+ isSubMenu = true;
223
+ }
224
+ this.menuItemData = isSubMenu ? this.menuItemData : this.getMenuItemData();
225
+ const eventArgs: MenuOpenEventArgs = {
226
+ fileDetails: [this.menuItemData],
227
+ element: args.element,
228
+ target: target,
229
+ items: isSubMenu ? args.items : this.contextMenu.items,
230
+ menuModule: this.contextMenu,
231
+ cancel: false,
232
+ menuType: this.menuType,
233
+ isSubMenu: isSubMenu
234
+ };
235
+ this.currentItems = eventArgs.items;
236
+ this.parent.trigger('menuOpen', eventArgs, (menuOpenArgs: MenuOpenEventArgs) => {
237
+ if (!isSubMenu) {
238
+ this.contextMenu.dataBind();
239
+ this.contextMenu.items = menuOpenArgs.items;
240
+ this.contextMenu.dataBind();
241
+ }
242
+ this.enableItems(this.disabledItems, false, true);
243
+ args.cancel = menuOpenArgs.cancel;
244
+ if (menuOpenArgs.cancel) {
245
+ this.menuTarget = this.targetNodeElement = this.currentElement = null;
246
+ }
247
+ });
248
+ }
249
+
250
+ private updateActiveModule(): void {
251
+ this.parent.activeModule = closest(this.menuTarget, '#' + this.parent.element.id + CLS.TREE_ID) ?
252
+ 'navigationpane' : closest(this.menuTarget, '#' + this.parent.element.id + CLS.GRID_ID) ?
253
+ 'detailsview' : closest(this.menuTarget, '#' + this.parent.element.id + CLS.LARGEICON_ID) ?
254
+ 'largeiconsview' : this.parent.activeModule;
255
+ }
256
+
257
+ /* istanbul ignore next */
258
+ /**
259
+ *
260
+ * @param {Element} target - specifies the target element.
261
+ * @returns {string} -returns the target view.
262
+ * @hidden
263
+ */
264
+ public getTargetView(target: Element): string {
265
+ return target.classList.contains(CLS.TREE_VIEW) ?
266
+ 'TreeView' : target.classList.contains(CLS.GRID_VIEW) ?
267
+ 'GridView' : target.classList.contains(CLS.ICON_VIEW) ?
268
+ 'LargeIcon' : target.classList.contains(CLS.LARGE_ICONS) ?
269
+ 'LargeIcon' : '';
270
+ }
271
+
272
+ public getItemIndex(item: string): number {
273
+ const itemId: string = this.getMenuId(item);
274
+ for (let i: number = 0; i < this.currentItems.length; i++) {
275
+ if ((this.currentItems[i as number].id === itemId) || (this.currentItems[i as number].id === item)) {
276
+ return i;
277
+ }
278
+ }
279
+ return -1;
280
+ }
281
+
282
+ public disableItem(items: string[]): void {
283
+ if (items.length !== 0) {
284
+ this.disabledItems = this.disabledItems.concat(items);
285
+ }
286
+ }
287
+
288
+ public enableItems(items: string[], enable?: boolean, isUniqueId?: boolean): void {
289
+ if (enable) {
290
+ this.disabledItems = this.disabledItems.filter((item: string) => { return items.indexOf(item) === -1; });
291
+ }
292
+ for (let i: number = 0; i < items.length; i++) {
293
+ const validItem: number = this.checkValidItem(items[i as number]);
294
+ if (validItem === 1) {
295
+ this.contextMenu.enableItems([this.getMenuId(items[i as number])], enable, isUniqueId);
296
+ } else if (validItem === 2) {
297
+ this.contextMenu.enableItems([items[i as number]], enable, isUniqueId);
298
+ }
299
+ }
300
+ }
301
+
302
+ private setFolderItem(isTree: boolean): void {
303
+ this.menuType = 'folder';
304
+ this.contextMenu.items = this.getItemData(this.parent.contextMenuSettings.folder.map((item: string) => item.trim()));
305
+ this.contextMenu.dataBind();
306
+ if (isTree) {
307
+ const selectedTreeNode: Element = select('[data-uid="' + this.navUid + '"]', this.parent.navigationpaneModule.treeObj.element);
308
+ if (!isNOU(selectedTreeNode) &&
309
+ this.parent.pathNames[this.parent.pathNames.length - 1] === selectedTreeNode.querySelector('.e-list-text').innerHTML && this.parent.activeModule === 'navigationpane') {
310
+ this.disabledItems.push('Open');
311
+ } else {
312
+ const indexToRemove: number = this.disabledItems.indexOf('Open');
313
+ if (indexToRemove !== -1) {
314
+ this.disabledItems.splice(indexToRemove, 1);
315
+ }
316
+ }
317
+ if (this.parent.selectedItems.length === 0) {
318
+ const renameIndex: number = this.disabledItems.indexOf('Rename');
319
+ if (renameIndex !== -1) {
320
+ this.disabledItems.splice(renameIndex, 1);
321
+ }
322
+ }
323
+ } else if (this.parent.activeModule !== 'navigationpane') {
324
+ if (this.parent.selectedItems.length === 1) {
325
+ const renameIndex: number = this.disabledItems.indexOf('Rename');
326
+ if (renameIndex !== -1) {
327
+ this.disabledItems.splice(renameIndex, 1);
328
+ }
329
+ }
330
+ else {
331
+ this.disabledItems.push('Rename', 'Paste');
332
+ }
333
+ }
334
+ }
335
+
336
+ private setFileItem(): void {
337
+ this.menuType = 'file';
338
+ this.contextMenu.items = this.getItemData(this.parent.contextMenuSettings.file.map((item: string) => item.trim()));
339
+ this.contextMenu.dataBind();
340
+ if (this.parent.selectedItems.length === 1) {
341
+ const renameIndex: number = this.disabledItems.indexOf('Rename');
342
+ if (renameIndex !== -1) {
343
+ this.disabledItems.splice(renameIndex, 1);
344
+ }
345
+ }
346
+ else {
347
+ this.disabledItems.push('Rename');
348
+ }
349
+ }
350
+
351
+ private setLayoutItem(target: Element): void {
352
+ this.menuType = 'layout';
353
+ this.contextMenu.items = this.getItemData(this.parent.contextMenuSettings.layout.map((item: string) => item.trim()));
354
+ this.contextMenu.dataBind();
355
+ if (!this.parent.allowMultiSelection || ((this.parent.view === 'LargeIcons' &&
356
+ (closest(target, '#' + this.parent.element.id + CLS.LARGEICON_ID).getElementsByClassName(CLS.EMPTY).length !== 0))
357
+ || (this.parent.view === 'Details' &&
358
+ (closest(target, '#' + this.parent.element.id + CLS.GRID_ID).getElementsByClassName(CLS.EMPTY).length !== 0)))) {
359
+ this.disabledItems.push('SelectAll');
360
+ }
361
+ else {
362
+ this.disabledItems = this.disabledItems.filter((item: string) => item !== 'SelectAll');
363
+
364
+ }
365
+ if (this.parent.selectedNodes.length === 0) {
366
+ if (this.disabledItems.indexOf('Paste') === -1) {
367
+ this.disabledItems.push('Paste');
368
+ }
369
+ }
370
+ this.contextMenu.dataBind();
371
+ }
372
+
373
+ private checkValidItem(nameEle: string): number {
374
+ if (!isNOU(this.currentElement)) {
375
+ if (!isNOU(select('#' + this.getMenuId(nameEle), this.currentElement))) {
376
+ return 1;
377
+ } else if (!isNOU(select('#' + nameEle, this.currentElement))) {
378
+ return 2;
379
+ }
380
+ }
381
+ return -1;
382
+ }
383
+
384
+ private getMenuItemData(): object {
385
+ if (this.menuType === 'layout') {
386
+ return getPathObject(this.parent);
387
+ } else {
388
+ const args: { [key: string]: Object; } = { target: this.menuTarget };
389
+ this.parent.notify(events.menuItemData, args);
390
+ return this.parent.itemData[0];
391
+ }
392
+ }
393
+
394
+ /* istanbul ignore next */
395
+ private onSelect(args: MenuEventArgs): void {
396
+ if (isNOU(args.item) || !args.item.id) { return; }
397
+ const itemText: string = args.item.id.substr((this.parent.element.id + '_cm_').length);
398
+ let details: Object[];
399
+ if (itemText === 'refresh' || itemText === 'newfolder' || itemText === 'upload') {
400
+ details = [getPathObject(this.parent)];
401
+ this.parent.itemData = details;
402
+ } else {
403
+ this.parent.notify(events.selectedData, {});
404
+ if (this.parent.activeModule === 'navigationpane' && itemText === 'open') {
405
+ details = [this.menuItemData];
406
+ } else {
407
+ details = this.parent.itemData;
408
+ }
409
+ }
410
+ const eventArgs: MenuClickEventArgs = {
411
+ cancel: false,
412
+ element: args.element,
413
+ fileDetails: details,
414
+ item: args.item
415
+ };
416
+ this.parent.trigger('menuClick', eventArgs, (menuClickArgs: MenuClickEventArgs) => {
417
+ let sItems: string[];
418
+ if (!menuClickArgs.cancel) {
419
+ if (itemText !== 'cut' && itemText !== 'copy') {
420
+ this.isMenuItemClicked = true;
421
+ }
422
+ switch (itemText) {
423
+ case 'cut':
424
+ cutFiles(this.parent);
425
+ break;
426
+ case 'copy':
427
+ copyFiles(this.parent);
428
+ break;
429
+ case 'paste':
430
+ if (this.menuType === 'folder') {
431
+ if (this.parent.activeModule === 'navigationpane') {
432
+ this.parent.navigationpaneModule.openFileOnContextMenuClick(closest(this.targetNodeElement, 'li') as HTMLLIElement);
433
+ this.parent.folderPath = this.parent.path;
434
+ }
435
+ else {
436
+ this.parent.folderPath = getFullPath(this.parent, this.menuItemData, this.parent.path);
437
+ }
438
+ } else {
439
+ this.parent.folderPath = '';
440
+ }
441
+ pasteHandler(this.parent);
442
+ break;
443
+ case 'delete':
444
+ for (let j: number = 0; j < details.length; j++) {
445
+ if (!hasEditAccess(details[j as number])) {
446
+ createDeniedDialog(this.parent, details[j as number], events.permissionEdit);
447
+ return;
448
+ }
449
+ }
450
+ createDialog(this.parent, 'Delete');
451
+ break;
452
+ /* istanbul ignore next */
453
+ case 'download':
454
+ for (let i: number = 0; i < details.length; i++) {
455
+ if (!hasDownloadAccess(details[i as number])) {
456
+ createDeniedDialog(this.parent, details[i as number], events.permissionDownload);
457
+ return;
458
+ }
459
+ }
460
+ if (this.parent.activeModule === 'navigationpane') {
461
+ this.parent.notify(events.downloadInit, {});
462
+ } else if (this.parent.selectedItems.length > 0) {
463
+ Download(this.parent, this.parent.path, this.parent.selectedItems);
464
+ }
465
+ break;
466
+ case 'rename':
467
+ if (!hasEditAccess(details[0])) {
468
+ createDeniedDialog(this.parent, details[0], events.permissionEdit);
469
+ } else {
470
+ this.parent.notify(events.renameInit, {});
471
+ createDialog(this.parent, 'Rename');
472
+ }
473
+ break;
474
+ case 'selectall':
475
+ /* istanbul ignore next */
476
+ this.parent.notify(events.selectAllInit, {});
477
+ break;
478
+ case 'refresh':
479
+ refresh(this.parent);
480
+ break;
481
+ case 'open':
482
+ if (this.parent.visitedItem && this.parent.activeModule !== 'navigationpane') {
483
+ this.parent.notify(events.openInit, { target: this.parent.visitedItem });
484
+ } else if (this.parent.activeModule === 'navigationpane') {
485
+ if (this.parent.visitedItem){
486
+ this.parent.notify(events.openInit, { target: this.parent.visitedItem });
487
+ }
488
+ this.parent.navigationpaneModule.openFileOnContextMenuClick(closest(this.targetNodeElement, 'li') as HTMLLIElement);
489
+ }
490
+ break;
491
+ case 'details':
492
+ this.parent.notify(events.detailsInit, {});
493
+ sItems = this.parent.selectedItems;
494
+ if (this.parent.activeModule === 'navigationpane') {
495
+ sItems = [];
496
+ this.parent.navigationpaneModule.openFileOnContextMenuClick(closest(this.targetNodeElement, 'li') as HTMLLIElement);
497
+ }
498
+ GetDetails(this.parent, sItems, this.parent.path, 'details');
499
+ break;
500
+ case 'newfolder':
501
+ createNewFolder(this.parent);
502
+ break;
503
+ case 'upload':
504
+ uploadItem(this.parent);
505
+ break;
506
+ case 'name':
507
+ case 'size':
508
+ case 'date':
509
+ case 'ascending':
510
+ case 'descending':
511
+ /* istanbul ignore next */
512
+ sortbyClickHandler(this.parent, args);
513
+ break;
514
+ /* istanbul ignore next */
515
+ case 'none':
516
+ /* istanbul ignore next */
517
+ sortbyClickHandler(this.parent, args);
518
+ break;
519
+ /* istanbul ignore next */
520
+ case 'largeiconsview':
521
+ updateLayout(this.parent, 'LargeIcons');
522
+ break;
523
+ /* istanbul ignore next */
524
+ case 'detailsview':
525
+ updateLayout(this.parent, 'Details');
526
+ break;
527
+ }
528
+ }
529
+ });
530
+ }
531
+
532
+ private onPropertyChanged(e: NotifyArgs): void {
533
+ if (e.module !== this.getModuleName() && e.module !== 'common') {
534
+ /* istanbul ignore next */
535
+ return;
536
+ }
537
+ for (const prop of Object.keys(e.newProp)) {
538
+ switch (prop) {
539
+ case 'cssClass':
540
+ this.contextMenu.cssClass = getCssClass(this.parent, CLS.ROOT_POPUP);
541
+ break;
542
+ }
543
+ }
544
+ }
545
+
546
+ private addEventListener(): void {
547
+ this.parent.on(events.destroy, this.destroy, this);
548
+ this.parent.on(events.modelChanged, this.onPropertyChanged, this);
549
+ this.keyboardModule = new KeyboardEvents(
550
+ this.contextMenu.element,
551
+ {
552
+ keyAction: this.keyActionHandler.bind(this),
553
+ keyConfigs: this.keyConfigs,
554
+ eventName: 'keydown'
555
+ }
556
+ );
557
+ }
558
+
559
+ private removeEventListener(): void {
560
+ this.parent.off(events.destroy, this.destroy);
561
+ this.parent.off(events.modelChanged, this.onPropertyChanged);
562
+ this.keyboardModule.destroy();
563
+ }
564
+ private keyActionHandler(e: KeyboardEventArgs): void {
565
+ switch (e.action) {
566
+ case 'uparrow':
567
+ case 'downarrow':
568
+ e.preventDefault();
569
+ }
570
+ }
571
+
572
+ /**
573
+ * For internal use only - Get the module name.
574
+ *
575
+ * @returns {string} - returns the module name.
576
+ * @private
577
+ */
578
+ private getModuleName(): string {
579
+ return 'contextmenu';
580
+ }
581
+
582
+ private destroy(): void {
583
+ if (this.parent.isDestroyed) { return; }
584
+ this.removeEventListener();
585
+ this.contextMenu.destroy();
586
+ this.targetElement = null;
587
+ }
588
+ /* istanbul ignore next */
589
+ private getItemData(data: string[]): MenuItemModel[] {
590
+ const items: MenuItemModel[] = [];
591
+ for (let i: number = 0; i < data.length; i++) {
592
+ let item: MenuItemModel;
593
+ const itemId: string = this.getMenuId(data[i as number]);
594
+ const itemText: string = getLocaleText(this.parent, data[i as number]);
595
+ switch (data[i as number]) {
596
+ case '|':
597
+ item = { separator: true };
598
+ break;
599
+ case 'Open':
600
+ item = { id: itemId, text: itemText, iconCss: CLS.ICON_OPEN };
601
+ break;
602
+ case 'Upload':
603
+ item = { id: itemId, text: itemText, iconCss: CLS.ICON_UPLOAD };
604
+ break;
605
+ case 'Cut':
606
+ item = { id: itemId, text: itemText, iconCss: CLS.ICON_CUT };
607
+ break;
608
+ case 'Copy':
609
+ item = { id: itemId, text: itemText, iconCss: CLS.ICON_COPY };
610
+ break;
611
+ case 'Paste':
612
+ item = { id: itemId, text: itemText, iconCss: CLS.ICON_PASTE };
613
+ break;
614
+ case 'Delete':
615
+ item = { id: itemId, text: itemText, iconCss: CLS.ICON_DELETE }; break;
616
+ case 'Rename':
617
+ item = { id: itemId, text: itemText, iconCss: CLS.ICON_RENAME }; break;
618
+ case 'NewFolder':
619
+ item = { id: itemId, text: itemText, iconCss: CLS.ICON_NEWFOLDER }; break;
620
+ case 'Details':
621
+ item = { id: itemId, text: itemText, iconCss: CLS.ICON_DETAILS }; break;
622
+ case 'SortBy':
623
+ item = {
624
+ id: itemId, text: itemText, iconCss: CLS.ICON_SHORTBY,
625
+ items: [
626
+ {
627
+ id: this.getMenuId('Name'), text: getLocaleText(this.parent, 'Name'),
628
+ iconCss: this.parent.sortBy === 'name' ? CLS.TB_OPTION_DOT : null
629
+ },
630
+ {
631
+ id: this.getMenuId('Size'), text: getLocaleText(this.parent, 'Size'),
632
+ iconCss: this.parent.sortBy === 'size' ? CLS.TB_OPTION_DOT : null
633
+ },
634
+ {
635
+ id: this.getMenuId('Date'), text: getLocaleText(this.parent, 'DateModified'),
636
+ iconCss: this.parent.sortBy === '_fm_modified' ? CLS.TB_OPTION_DOT : null
637
+ },
638
+ { separator: true },
639
+ {
640
+ id: this.getMenuId('Ascending'), text: getLocaleText(this.parent, 'Ascending'),
641
+ iconCss: this.parent.sortOrder === 'Ascending' ? CLS.TB_OPTION_TICK : null
642
+ },
643
+ {
644
+ id: this.getMenuId('Descending'), text: getLocaleText(this.parent, 'Descending'),
645
+ iconCss: this.parent.sortOrder === 'Descending' ? CLS.TB_OPTION_TICK : null
646
+ },
647
+ {
648
+ id: this.getMenuId('None'), text: getLocaleText(this.parent, 'None'),
649
+ iconCss: this.parent.sortOrder === 'None' ? CLS.TB_OPTION_TICK : null
650
+ }
651
+ ]
652
+ };
653
+ break;
654
+ /* istanbul ignore next */
655
+ case 'View':
656
+ item = {
657
+ id: itemId, text: itemText, iconCss: this.parent.view === 'Details' ? CLS.ICON_GRID : CLS.ICON_LARGE,
658
+ items: [
659
+ {
660
+ id: this.getMenuId('largeiconsview'), text: getLocaleText(this.parent, 'View-LargeIcons'),
661
+ iconCss: this.parent.view === 'Details' ? null : CLS.TB_OPTION_TICK
662
+ },
663
+ {
664
+ id: this.getMenuId('detailsview'), text: getLocaleText(this.parent, 'View-Details'),
665
+ iconCss: this.parent.view === 'Details' ? CLS.TB_OPTION_TICK : null
666
+ }
667
+ ]
668
+ };
669
+ break;
670
+ case 'Refresh':
671
+ item = { id: itemId, text: itemText, iconCss: CLS.ICON_REFRESH };
672
+ break;
673
+ case 'SelectAll':
674
+ item = { id: itemId, text: itemText, iconCss: CLS.ICON_SELECTALL };
675
+ break;
676
+ /* istanbul ignore next */
677
+ case 'Download':
678
+ item = { id: itemId, text: itemText, iconCss: CLS.ICON_DOWNLOAD };
679
+ break;
680
+ /* istanbul ignore next */
681
+ default:
682
+ item = { id: itemId, text: itemText };
683
+ break;
684
+ }
685
+ items.push(item);
686
+ }
687
+ return items;
688
+ }
689
+
690
+ private getMenuId(id: string): string {
691
+ return this.parent.element.id + '_cm_' + id.split(' ').join('').toLowerCase();
692
+ }
693
+ }