@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,1684 @@
1
+ import { ListBase, ListBaseOptions, ItemCreatedArgs } from '@syncfusion/ej2-lists';
2
+ import { createElement, select, selectAll, EventHandler, KeyboardEvents, closest, DragEventArgs, Draggable, Fetch } from '@syncfusion/ej2-base';
3
+ import { isNullOrUndefined as isNOU, addClass, removeClass, Touch, TapEventArgs, isVisible } from '@syncfusion/ej2-base';
4
+ import { TouchEventArgs, MouseEventArgs, KeyboardEventArgs, getValue, setValue, remove } from '@syncfusion/ej2-base';
5
+ import { IFileManager, FileOpenEventArgs, FileLoadEventArgs } from '../base/interface';
6
+ import { FileSelectEventArgs, NotifyArgs, FileSelectionEventArgs } from '../base/interface';
7
+ import { DataManager, Query, DataUtil } from '@syncfusion/ej2-data';
8
+ import { hideSpinner, showSpinner } from '@syncfusion/ej2-popups';
9
+ import * as events from '../base/constant';
10
+ import { ReadArgs, MouseArgs, BeforeImageLoadEventArgs } from '../../index';
11
+ import * as CLS from '../base/classes';
12
+ import { createCheckBox } from '@syncfusion/ej2-buttons';
13
+ import { read, GetDetails, Delete, triggerFetchFailure, triggerFetchSuccess } from '../common/operations';
14
+ import { doRename, getAccessClass, getPathObject, getFullPath, getDirectoryPath, rename, doDownload, getItemName } from '../common/index';
15
+ import { removeBlur, cutFiles, copyFiles, addBlur, openSearchFolder, removeActive, pasteHandler } from '../common/index';
16
+ import { createVirtualDragElement, dragStopHandler, dragStartHandler, draggingHandler, getModule } from '../common/index';
17
+ import { updateRenamingData, doDeleteFiles, doDownloadFiles } from '../common/index';
18
+ import { openAction, fileType, refresh, getImageUrl, getSortedData, createDeniedDialog, updateLayout, getLocaleText } from '../common/utility';
19
+ import { createEmptyElement, hasReadAccess, hasEditAccess } from '../common/utility';
20
+ import { createDialog, createImageDialog } from '../pop-up/dialog';
21
+
22
+ /**
23
+ * LargeIconsView module
24
+ */
25
+ export class LargeIconsView {
26
+
27
+ /* Internal variables */
28
+ private parent: IFileManager;
29
+ public element: HTMLElement;
30
+ public listObj: ListBaseOptions;
31
+ private keyboardModule: KeyboardEvents;
32
+ private keyboardDownModule: KeyboardEvents;
33
+ private keyConfigs: { [key: string]: string };
34
+ private isInteraction: boolean = true;
35
+ public itemList: HTMLElement[];
36
+ // specifies the current view items in large icon
37
+ public items: Object[];
38
+ public allItems: Object[];
39
+ private clickObj: Touch;
40
+ private perRow: number;
41
+ private startItem: Element;
42
+ private multiSelect: boolean;
43
+ public listElements: HTMLElement;
44
+ public uploadOperation: boolean = false;
45
+ private count: number = 0;
46
+ private isRendered: boolean = true;
47
+ private tapCount: number = 0;
48
+ private isSelectAllCalled: boolean = false;
49
+ private tapEvent: TapEventArgs;
50
+ private isPasteOperation: boolean = false;
51
+ private dragObj: Draggable;
52
+ private isInteracted: boolean = true;
53
+ private imageEventArgsMap: Map<string, BeforeImageLoadEventArgs> = new Map<string, BeforeImageLoadEventArgs>();
54
+ private imageUrlCache: Map<string, string> = new Map<string, string>();
55
+
56
+ /**
57
+ * Constructor for the LargeIcons module.
58
+ *
59
+ * @param {IFileManager} parent - specifies the parent element.
60
+ * @hidden
61
+ */
62
+ constructor(parent?: IFileManager) {
63
+ this.parent = parent;
64
+ this.element = <HTMLElement>select('#' + this.parent.element.id + CLS.LARGEICON_ID, this.parent.element);
65
+ addClass([this.element], CLS.LARGE_ICONS);
66
+ this.addEventListener();
67
+ this.keyConfigs = {
68
+ end: 'end',
69
+ home: 'home',
70
+ tab: 'tab',
71
+ moveDown: 'downarrow',
72
+ moveLeft: 'leftarrow',
73
+ moveRight: 'rightarrow',
74
+ moveUp: 'uparrow',
75
+ ctrlEnd: 'ctrl+end',
76
+ ctrlHome: 'ctrl+home',
77
+ ctrlDown: 'ctrl+downarrow',
78
+ ctrlLeft: 'ctrl+leftarrow',
79
+ ctrlRight: 'ctrl+rightarrow',
80
+ ctrlUp: 'ctrl+uparrow',
81
+ shiftEnd: 'shift+end',
82
+ shiftHome: 'shift+home',
83
+ shiftDown: 'shift+downarrow',
84
+ shiftLeft: 'shift+leftarrow',
85
+ shiftRight: 'shift+rightarrow',
86
+ shiftUp: 'shift+uparrow',
87
+ csEnd: 'ctrl+shift+end',
88
+ csHome: 'ctrl+shift+home',
89
+ csDown: 'ctrl+shift+downarrow',
90
+ csLeft: 'ctrl+shift+leftarrow',
91
+ csRight: 'ctrl+shift+rightarrow',
92
+ csUp: 'ctrl+shift+uparrow',
93
+ space: 'space',
94
+ ctrlSpace: 'ctrl+space',
95
+ shiftSpace: 'shift+space',
96
+ csSpace: 'ctrl+shift+space',
97
+ ctrlA: 'ctrl+a',
98
+ enter: 'enter',
99
+ altEnter: 'alt+enter',
100
+ esc: 'escape',
101
+ del: 'delete',
102
+ ctrlX: this.parent.isMac ? 'cmd+x' : 'ctrl+x',
103
+ ctrlC: this.parent.isMac ? 'cmd+c' : 'ctrl+c',
104
+ ctrlV: this.parent.isMac ? 'cmd+v' : 'ctrl+v',
105
+ f2: 'f2',
106
+ shiftdel: 'shift+delete',
107
+ back: 'backspace',
108
+ ctrlD: 'ctrl+d'
109
+ };
110
+ }
111
+
112
+ private render(args: ReadArgs): void {
113
+ this.parent.visitedItem = null;
114
+ this.startItem = null;
115
+ showSpinner(this.parent.element);
116
+ if (this.parent.view === 'LargeIcons') {
117
+ this.resetMultiSelect();
118
+ this.element.setAttribute('tabindex', '0');
119
+ if (this.listObj) {
120
+ this.unWireEvents();
121
+ this.removeEventListener();
122
+ }
123
+ this.parent.notify(events.hideLayout, {});
124
+ const iconsView: Element = select('#' + this.parent.element.id + CLS.LARGEICON_ID, this.parent.element);
125
+ const ul: HTMLUListElement = select('ul', iconsView) as HTMLUListElement;
126
+ if (ul) {
127
+ remove(ul);
128
+ }
129
+ this.listObj = {
130
+ ariaAttributes: {
131
+ itemRole: 'option', listRole: 'listbox', itemText: '',
132
+ groupItemRole: 'group', wrapperRole: ''
133
+ },
134
+ showIcon: true,
135
+ fields: { text: 'name', iconCss: '_fm_icon', imageUrl: '_fm_imageUrl', imageAttributes: '_fm_imageAttr', htmlAttributes: '_fm_htmlAttr' },
136
+ sortOrder: this.parent.sortOrder,
137
+ itemCreated: this.onItemCreated.bind(this),
138
+ enableHtmlSanitizer: this.parent.enableHtmlSanitizer
139
+ };
140
+ this.items = [];
141
+ this.items = this.renderList(args);
142
+ if (this.parent.sortComparer && this.parent.sortBy !== 'None'){
143
+ this.items = this.allItems = DataUtil.sort(this.items, this.parent.sortBy, this.comparer.bind(this) as Function);
144
+ } else { this.items = this.allItems = getSortedData(this.parent, this.items); }
145
+ iconsView.classList.remove(CLS.DISPLAY_NONE);
146
+ if (this.parent.enableVirtualization && this.allItems.length > 0 && !isNOU(this.parent.virtualizationModule)) {
147
+ this.parent.virtualizationModule.setUIVirtualization();
148
+ }
149
+ this.listElements = ListBase.createListFromJson(createElement, <{ [key: string]: Object; }[]>this.items, this.listObj);
150
+ this.itemList = Array.prototype.slice.call(selectAll('.' + CLS.LIST_ITEM, this.listElements));
151
+ this.element.appendChild(this.listElements);
152
+ if (this.imageEventArgsMap.size > 0) {
153
+ this.loadImages();
154
+ }
155
+ this.listElements.setAttribute('aria-label', 'listbox');
156
+ this.preventImgDrag();
157
+ this.createDragObj();
158
+ if (this.itemList.length === 0) {
159
+ const emptyList: Element = this.element.querySelector('.' + CLS.LIST_PARENT);
160
+ this.element.removeChild(emptyList);
161
+ createEmptyElement(this.parent, this.element, args);
162
+ } else if (this.itemList.length !== 0 && this.element.querySelector('.' + CLS.EMPTY)) {
163
+ this.element.removeChild(this.element.querySelector('.' + CLS.EMPTY));
164
+ }
165
+ if (this.isPasteOperation === true) {
166
+ this.selectItems(this.parent.pasteNodes);
167
+ this.isPasteOperation = false;
168
+ }
169
+ /* istanbul ignore next */
170
+ if (this.uploadOperation === true) {
171
+ this.selectItems(this.parent.uploadItem);
172
+ this.parent.setProperties({ selectedItems: [] }, true);
173
+ this.count++;
174
+ if (this.count === this.parent.uploadItem.length) {
175
+ this.uploadOperation = false;
176
+ this.parent.uploadItem = [];
177
+ }
178
+ }
179
+ const activeEle: NodeListOf<Element> = this.element.querySelectorAll('.' + CLS.ACTIVE);
180
+ if (activeEle.length !== 0) {
181
+ this.parent.activeModule = 'largeiconsview';
182
+ }
183
+ for (let i: number = 0; i < activeEle.length; i++) {
184
+ activeEle[i as number].setAttribute('aria-selected', 'true');
185
+ }
186
+ this.element.style.maxHeight = '100%';
187
+ this.getItemCount();
188
+ this.addEventListener();
189
+ this.wireEvents();
190
+ if (this.parent.enableVirtualization && this.allItems.length > 0 && !isNOU(this.parent.virtualizationModule)) {
191
+ this.parent.virtualizationModule.setUlElementHeight();
192
+ this.parent.virtualizationModule.wireScrollEvent(false);
193
+ }
194
+ this.isRendered = true;
195
+ hideSpinner(this.parent.element);
196
+ if (this.parent.selectedItems.length) { this.checkItem(); }
197
+ }
198
+ }
199
+ private loadImages(): void {
200
+ const imageEle: NodeListOf<Element> = this.parent.element.querySelectorAll('.e-list-img');
201
+ imageEle.forEach((imgElement: HTMLElement) => {
202
+ const imageKey: string = imgElement.getAttribute('data-image-key');
203
+ if (!imageKey) {return; }
204
+ if (this.imageUrlCache.has(imageKey)) {
205
+ imgElement.setAttribute('src', this.imageUrlCache.get(imageKey));
206
+ imgElement.classList.remove('image-blur');
207
+ return;
208
+ }
209
+ const imageDetails: BeforeImageLoadEventArgs = this.imageEventArgsMap.get(imageKey);
210
+ if (!imageDetails) {return; }
211
+ const fetch: Fetch = new Fetch({
212
+ url: getValue('url', imageDetails.ajaxSettings),
213
+ type: getValue('type', imageDetails.ajaxSettings),
214
+ contentType: getValue('contentType', imageDetails.ajaxSettings),
215
+ responseType: getValue('responseType', imageDetails.ajaxSettings),
216
+ beforeSend: getValue('beforeSend', imageDetails.ajaxSettings),
217
+ onSuccess: (blob: Blob) => {
218
+ const blobUrl: string = URL.createObjectURL(blob);
219
+ this.imageUrlCache.set(imageKey, blobUrl);
220
+ imgElement.setAttribute('src', blobUrl);
221
+ imgElement.classList.remove('image-blur');
222
+ triggerFetchSuccess(this.parent, imageDetails.ajaxSettings);
223
+ },
224
+ onFailure: (response: Response) => {
225
+ const result: ReadArgs = {
226
+ files: null,
227
+ error: {
228
+ code: response.status ? response.status.toString() : '404',
229
+ message: getLocaleText(this.parent, 'Network-Error') + ' ' + getValue('url', imageDetails.ajaxSettings),
230
+ fileExists: null
231
+ }
232
+ };
233
+ triggerFetchFailure(this.parent, imageDetails.ajaxSettings, result);
234
+ }
235
+ });
236
+ fetch.send(getValue('data', imageDetails.ajaxSettings));
237
+ });
238
+ }
239
+ private comparer (x: number | string, y: number | string): number | string {
240
+ if (this.parent.sortOrder === 'Descending') {
241
+ const z: number | string = x;
242
+ x = y;
243
+ y = z;
244
+ }
245
+ return (this.parent.sortComparer as Function)(x, y);
246
+ }
247
+
248
+ private preventImgDrag(): void {
249
+ let i: number = 0;
250
+ while (i < this.itemList.length) {
251
+ if (this.itemList[i as number].querySelector('img')) {
252
+ /* istanbul ignore next */
253
+ this.itemList[i as number].ondragstart = () => { return false; };
254
+ }
255
+ i++;
256
+ }
257
+ }
258
+
259
+ private createDragObj(): void {
260
+ if (this.listObj) {
261
+ if (this.parent.allowDragAndDrop) {
262
+ if (this.dragObj) { this.dragObj.destroy(); }
263
+ this.dragObj = new Draggable(this.listElements, {
264
+ enableTailMode: true,
265
+ distance: 5,
266
+ enableAutoScroll: false,
267
+ dragTarget: '.' + CLS.LARGE_ICON,
268
+ helper: this.dragHelper.bind(this),
269
+ cursorAt: this.parent.dragCursorPosition,
270
+ dragArea: this.parent.element,
271
+ dragStop: dragStopHandler.bind(this, this.parent),
272
+ drag: draggingHandler.bind(this, this.parent),
273
+ clone: true,
274
+ dragStart: (args: DragEventArgs) => {
275
+ dragStartHandler(this.parent, args, this.dragObj);
276
+ }
277
+ });
278
+ } else if (this.dragObj && !this.parent.allowDragAndDrop) {
279
+ this.dragObj.destroy();
280
+ }
281
+ }
282
+ }
283
+
284
+ public dragHelper(args: { element: HTMLElement, sender: MouseEvent & TouchEvent }): HTMLElement {
285
+ const dragTarget: Element = <Element>args.sender.target;
286
+ const dragLi: Element = closest(dragTarget, '.e-list-item');
287
+ if (!dragLi) { return null; }
288
+ if (dragLi && !dragLi.classList.contains('e-active')) {
289
+ this.setFocus(dragLi);
290
+ }
291
+ const activeEle: NodeListOf<Element> = this.element.querySelectorAll('.' + CLS.ACTIVE);
292
+ this.parent.activeElements = [];
293
+ this.parent.dragData = [];
294
+ for (let i: number = 0; i < activeEle.length; i++) {
295
+ this.parent.dragData.push(<{ [key: string]: Object; }>this.getItemObject(activeEle[parseInt(i.toString(), 10)]));
296
+ this.parent.activeElements.push(activeEle[i as number]);
297
+ }
298
+ getModule(this.parent, dragLi);
299
+ this.parent.dragPath = this.parent.path;
300
+ createVirtualDragElement(this.parent);
301
+ return this.parent.virtualDragElement;
302
+ }
303
+
304
+ private onDropInit(args: DragEventArgs): void {
305
+ if (this.parent.targetModule === this.getModuleName()) {
306
+ const dropLi: Element = closest(args.target, '.e-list-item');
307
+ const cwdData: Object = getValue(this.parent.pathId[this.parent.pathId.length - 1], this.parent.feParent);
308
+ if (dropLi) {
309
+ const info: { [key: string]: Object; } = <{ [key: string]: Object; }>this.getItemObject(dropLi);
310
+ this.parent.dropPath = info.isFile ? this.parent.path : getFullPath(this.parent, info, this.parent.path);
311
+ this.parent.dropData = info.isFile ? cwdData : info;
312
+ } else {
313
+ this.parent.dropPath = this.parent.path;
314
+ this.parent.dropData = cwdData;
315
+ }
316
+ }
317
+ }
318
+
319
+ /**
320
+ * For internal use only - Get the module name.
321
+ *
322
+ * @returns {string} - returns the module name.
323
+ * @private
324
+ */
325
+ private getModuleName(): string {
326
+ return 'largeiconsview';
327
+ }
328
+
329
+ private onItemCreated(args: ItemCreatedArgs): void {
330
+ args.item.removeAttribute('aria-level');
331
+ if (!this.parent.showFileExtension && getValue('isFile', args.curData)) {
332
+ const textEle: Element = args.item.querySelector('.' + CLS.LIST_TEXT);
333
+ const txt: string = getValue('name', args.curData);
334
+ const type: string = getValue('type', args.curData);
335
+ if (txt.indexOf(type) !== -1) {
336
+ textEle.innerHTML = txt.substr(0, txt.length - type.length);
337
+ }
338
+ }
339
+ this.renderCheckbox(args);
340
+ const eventArgs: FileLoadEventArgs = {
341
+ element: args.item,
342
+ fileDetails: args.curData,
343
+ module: 'LargeIconsView'
344
+ };
345
+ this.parent.trigger('fileLoad', eventArgs);
346
+ }
347
+
348
+ private renderCheckbox(args: ItemCreatedArgs): void {
349
+ if (!this.parent.showItemCheckBoxes) { return; }
350
+ const checkElement: Element = createCheckBox(createElement, false, {
351
+ checked: false,
352
+ cssClass: 'e-small'
353
+ });
354
+ checkElement.setAttribute('role', 'checkbox');
355
+ checkElement.setAttribute('aria-checked', 'false');
356
+ checkElement.setAttribute('aria-label', 'checkbox');
357
+ args.item.firstElementChild.insertBefore(checkElement, args.item.firstElementChild.childNodes[0]);
358
+ }
359
+
360
+ private onLayoutChange(args: ReadArgs): void {
361
+ if (this.parent.view === 'LargeIcons') {
362
+ this.destroy();
363
+ if (this.parent.enableVirtualization) { this.parent.setProperties({ selectedItems: [] }, true); }
364
+ this.render(args);
365
+ /* istanbul ignore next */
366
+ if (getValue('name', args) === 'layout-change' && this.parent.fileAction === 'move' &&
367
+ this.parent.isCut && this.parent.selectedNodes && this.parent.selectedNodes.length !== 0) {
368
+ const indexes: number[] = this.getIndexes(this.parent.selectedNodes);
369
+ let length: number = 0;
370
+ while (length < indexes.length) {
371
+ addBlur(this.itemList[indexes[length as number]]);
372
+ length++;
373
+ }
374
+ }
375
+ const activeEle: NodeListOf<Element> = this.element.querySelectorAll('.' + CLS.ACTIVE);
376
+ if (activeEle.length !== 0) {
377
+ this.element.focus();
378
+ }
379
+ this.checkItem();
380
+ this.parent.isLayoutChange = false;
381
+ } else {
382
+ this.element.setAttribute('tabindex', '-1');
383
+ }
384
+ }
385
+
386
+ private checkItem(): void {
387
+ const checkEle: NodeListOf<Element> = this.element.querySelectorAll('.' + CLS.ACTIVE);
388
+ if (checkEle) {
389
+ let checkLength: number = 0;
390
+ while (checkLength < checkEle.length) {
391
+ this.checkState(checkEle[checkLength as number], true);
392
+ checkLength++;
393
+ }
394
+ }
395
+ }
396
+
397
+ private renderList(args?: ReadArgs): Object[] {
398
+ let i: number = 0;
399
+ const items: Object[] = JSON.parse(JSON.stringify(args.files));
400
+ while (i < items.length) {
401
+ const icon: string = fileType(items[i as number]);
402
+ const name: string = getValue('name', items[i as number]);
403
+ const selected: string = getItemName(this.parent, items[i as number]);
404
+ let className: string = ((this.parent.selectedItems &&
405
+ this.parent.selectedItems.indexOf(selected) !== -1)) ?
406
+ CLS.LARGE_ICON + ' e-active' : CLS.LARGE_ICON;
407
+ if (!hasEditAccess(items[i as number])) {
408
+ className += ' ' + getAccessClass(items[i as number]);
409
+ }
410
+ if (icon === CLS.ICON_IMAGE && this.parent.showThumbnail && hasReadAccess(items[i as number])) {
411
+ const imageData: BeforeImageLoadEventArgs = getImageUrl(this.parent, items[i as number]);
412
+ if (imageData.useImageAsUrl) {
413
+ setValue('_fm_imageUrl', imageData.imageUrl, items[i as number]);
414
+ setValue('_fm_imageAttr', { alt: name }, items[i as number]);
415
+ }
416
+ else {
417
+ const uniqueKey: string = `img_${name}_${i}`;
418
+ this.imageEventArgsMap.set(uniqueKey, imageData);
419
+ setValue('_fm_imageUrl', '', items[i as number]);
420
+ setValue('_fm_imageAttr', {alt: name, class: 'e-list-img image-blur', 'data-image-key': uniqueKey }, items[i as number]);
421
+
422
+ }
423
+ } else {
424
+ setValue('_fm_icon', icon, items[i as number]);
425
+ }
426
+ setValue('_fm_htmlAttr', { class: className, title: name }, items[i as number]);
427
+ i++;
428
+ }
429
+ return items;
430
+ }
431
+
432
+ private onFinalizeEnd(args: ReadArgs): void {
433
+ this.render(args);
434
+ }
435
+
436
+ private onCreateEnd(args: ReadArgs): void {
437
+ if (this.parent.view !== 'LargeIcons') { return; }
438
+ this.onLayoutChange(args);
439
+ this.clearSelect();
440
+ this.selectItems([getValue(this.parent.hasId ? 'id' : 'name', this.parent.createdItem)]);
441
+ this.parent.createdItem = null;
442
+ this.parent.largeiconsviewModule.element.focus();
443
+ this.parent.activeModule = 'largeiconsview';
444
+ }
445
+
446
+ private onSelectedData(): void {
447
+ if (this.parent.activeModule === 'largeiconsview') {
448
+ this.updateSelectedData();
449
+ }
450
+ }
451
+
452
+ private onDeleteInit(): void {
453
+ if (this.parent.activeModule === 'largeiconsview') {
454
+ Delete(this.parent, this.parent.selectedItems, this.parent.path, 'delete');
455
+ }
456
+ }
457
+
458
+ /* istanbul ignore next */
459
+ private onDeleteEnd(args: ReadArgs): void {
460
+ if (this.parent.view !== 'LargeIcons') { return; }
461
+ this.onLayoutChange(args);
462
+ this.parent.setProperties({ selectedItems: [] }, true);
463
+ this.clearSelect();
464
+ }
465
+
466
+ private onRefreshEnd(args: ReadArgs): void {
467
+ if (this.parent.view !== 'LargeIcons') { return; }
468
+ this.onLayoutChange(args);
469
+ }
470
+
471
+ private onRenameInit(): void {
472
+ if (this.parent.activeModule === 'largeiconsview' && this.parent.selectedItems.length === 1) {
473
+ this.updateRenameData();
474
+ }
475
+ }
476
+
477
+ private onPathChanged(args: ReadArgs): void {
478
+ this.parent.isCut = false;
479
+ /* istanbul ignore next */
480
+ if (this.parent.breadcrumbbarModule.searchObj.element.value === '') {
481
+ this.parent.searchedItems = [];
482
+ }
483
+ if (this.parent.view === 'LargeIcons') {
484
+ removeBlur(this.parent);
485
+ this.parent.setProperties({ selectedItems: [] }, true);
486
+ this.onLayoutChange(args);
487
+ if (this.parent.renamedItem && this.parent.activeModule === 'largeiconsview') {
488
+ this.clearSelect();
489
+ this.addSelection(this.parent.renamedItem);
490
+ }
491
+ }
492
+ }
493
+
494
+ private onOpenInit(args: NotifyArgs): void {
495
+ if (this.parent.activeModule === 'largeiconsview') {
496
+ this.doOpenAction(args.target);
497
+ }
498
+ }
499
+
500
+ private onHideLayout(): void {
501
+ if (this.parent.view !== 'LargeIcons' && this.element) {
502
+ this.element.classList.add(CLS.DISPLAY_NONE);
503
+ }
504
+ }
505
+
506
+ private onSelectAllInit(): void {
507
+ if (this.parent.view === 'LargeIcons') {
508
+ this.startItem = this.getFirstItem();
509
+ const lastItem: Element = this.getLastItem();
510
+ const eveArgs: KeyboardEventArgs = { ctrlKey: true, shiftKey: true } as KeyboardEventArgs;
511
+ this.doSelection(lastItem, eveArgs);
512
+ this.isInteraction = true;
513
+ this.isInteracted = true;
514
+ }
515
+ }
516
+
517
+ private onClearAllInit(): void {
518
+ if (this.parent.view === 'LargeIcons') {
519
+ this.clearSelection();
520
+ this.isInteraction = true;
521
+ this.isInteracted = true;
522
+ }
523
+ }
524
+
525
+ private onBeforeRequest(): void {
526
+ this.isRendered = false;
527
+ }
528
+
529
+ private onAfterRequest(): void {
530
+ this.isRendered = true;
531
+ }
532
+
533
+ /* istanbul ignore next */
534
+ private onSearch(args: ReadArgs): void {
535
+ if (this.parent.view === 'LargeIcons') {
536
+ this.parent.setProperties({ selectedItems: [] }, true);
537
+ this.parent.notify(events.selectionChanged, {});
538
+ this.parent.searchedItems = args.files;
539
+ this.onLayoutChange(args);
540
+ }
541
+ }
542
+
543
+ private onLayoutRefresh(): void {
544
+ if (this.parent.view !== 'LargeIcons') { return; }
545
+ }
546
+
547
+ private onUpdateSelectionData(): void {
548
+ if (this.parent.view !== 'LargeIcons') { return; }
549
+ this.updateSelectedData();
550
+ }
551
+
552
+ private onPathColumn(): void {
553
+ if (this.parent.view === 'LargeIcons' && !isNOU(this.listObj) &&
554
+ this.parent.breadcrumbbarModule.searchObj.element.value === '' && !this.parent.isFiltered
555
+ && this.parent.sortBy === 'filterPath') {
556
+ this.parent.sortBy = 'name';
557
+ this.parent.notify(events.sortByChange, {});
558
+
559
+ }
560
+ }
561
+
562
+ private removeEventListener(): void {
563
+ if (this.parent.isDestroyed) { return; }
564
+ this.parent.off(events.pathColumn, this.onPathColumn);
565
+ this.parent.off(events.finalizeEnd, this.onFinalizeEnd);
566
+ this.parent.off(events.createEnd, this.onCreateEnd);
567
+ this.parent.off(events.selectedData, this.onSelectedData);
568
+ this.parent.off(events.deleteInit, this.onDeleteInit);
569
+ this.parent.off(events.deleteEnd, this.onDeleteEnd);
570
+ this.parent.off(events.refreshEnd, this.onRefreshEnd);
571
+ this.parent.off(events.pathChanged, this.onPathChanged);
572
+ this.parent.off(events.layoutChange, this.onLayoutChange);
573
+ this.parent.off(events.search, this.onSearch);
574
+ this.parent.off(events.openInit, this.onOpenInit);
575
+ this.parent.off(events.openEnd, this.onPathChanged);
576
+ this.parent.off(events.modelChanged, this.onPropertyChanged);
577
+ this.parent.off(events.methodCall, this.onMethodCall);
578
+ this.parent.off(events.actionFailure, this.onActionFailure);
579
+ this.parent.off(events.renameInit, this.onRenameInit);
580
+ this.parent.off(events.renameEnd, this.onPathChanged);
581
+ this.parent.off(events.hideLayout, this.onHideLayout);
582
+ this.parent.off(events.selectAllInit, this.onSelectAllInit);
583
+ this.parent.off(events.clearAllInit, this.onClearAllInit);
584
+ this.parent.off(events.menuItemData, this.onMenuItemData);
585
+ this.parent.off(events.beforeRequest, this.onBeforeRequest);
586
+ this.parent.off(events.afterRequest, this.onAfterRequest);
587
+ this.parent.off(events.splitterResize, this.splitterResizeHandler);
588
+ this.parent.off(events.resizeEnd, this.resizeHandler);
589
+ this.parent.off(events.pasteInit, this.onpasteInit);
590
+ this.parent.off(events.pasteEnd, this.onpasteEnd);
591
+ this.parent.off(events.cutCopyInit, this.oncutCopyInit);
592
+ this.parent.off(events.dropInit, this.onDropInit);
593
+ this.parent.off(events.detailsInit, this.onDetailsInit);
594
+ this.parent.off(events.layoutRefresh, this.onLayoutRefresh);
595
+ this.parent.off(events.dropPath, this.onDropPath);
596
+ this.parent.off(events.updateSelectionData, this.onUpdateSelectionData);
597
+ this.parent.off(events.filterEnd, this.onPathChanged);
598
+ }
599
+
600
+ private addEventListener(): void {
601
+ this.parent.on(events.pathColumn, this.onPathColumn, this);
602
+ this.parent.on(events.finalizeEnd, this.onFinalizeEnd, this);
603
+ this.parent.on(events.createEnd, this.onCreateEnd, this);
604
+ this.parent.on(events.refreshEnd, this.onRefreshEnd, this);
605
+ this.parent.on(events.selectedData, this.onSelectedData, this);
606
+ this.parent.on(events.pathChanged, this.onPathChanged, this);
607
+ this.parent.on(events.deleteInit, this.onDeleteInit, this);
608
+ this.parent.on(events.pasteInit, this.onpasteInit, this);
609
+ this.parent.on(events.deleteEnd, this.onDeleteEnd, this);
610
+ this.parent.on(events.layoutChange, this.onLayoutChange, this);
611
+ this.parent.on(events.search, this.onSearch, this);
612
+ this.parent.on(events.openInit, this.onOpenInit, this);
613
+ this.parent.on(events.renameInit, this.onRenameInit, this);
614
+ this.parent.on(events.renameEnd, this.onPathChanged, this);
615
+ this.parent.on(events.openEnd, this.onPathChanged, this);
616
+ this.parent.on(events.modelChanged, this.onPropertyChanged, this);
617
+ this.parent.on(events.methodCall, this.onMethodCall, this);
618
+ this.parent.on(events.actionFailure, this.onActionFailure, this);
619
+ this.parent.on(events.hideLayout, this.onHideLayout, this);
620
+ this.parent.on(events.selectAllInit, this.onSelectAllInit, this);
621
+ this.parent.on(events.clearAllInit, this.onClearAllInit, this);
622
+ this.parent.on(events.menuItemData, this.onMenuItemData, this);
623
+ this.parent.on(events.beforeRequest, this.onBeforeRequest, this);
624
+ this.parent.on(events.afterRequest, this.onAfterRequest, this);
625
+ this.parent.on(events.dropInit, this.onDropInit, this);
626
+ this.parent.on(events.detailsInit, this.onDetailsInit, this);
627
+ this.parent.on(events.splitterResize, this.splitterResizeHandler, this);
628
+ this.parent.on(events.resizeEnd, this.resizeHandler, this);
629
+ this.parent.on(events.pasteEnd, this.onpasteEnd, this);
630
+ this.parent.on(events.cutCopyInit, this.oncutCopyInit, this);
631
+ this.parent.on(events.layoutRefresh, this.onLayoutRefresh, this);
632
+ this.parent.on(events.dropPath, this.onDropPath, this);
633
+ this.parent.on(events.updateSelectionData, this.onUpdateSelectionData, this);
634
+ this.parent.on(events.filterEnd, this.onPathChanged, this);
635
+ }
636
+
637
+ private onActionFailure(): void { this.isInteraction = true; this.isInteracted = true; }
638
+
639
+ private onMenuItemData(args: { [key: string]: Object; }): void {
640
+ if (this.parent.activeModule === this.getModuleName()) {
641
+ const ele: Element = closest(<Element>args.target, 'li');
642
+ this.parent.itemData = [this.getItemObject(ele)];
643
+ }
644
+ }
645
+
646
+ private onDetailsInit(): void {
647
+ if (this.parent.activeModule === this.getModuleName()) {
648
+ if (this.parent.selectedItems.length !== 0) {
649
+ this.updateSelectedData();
650
+ } else {
651
+ this.parent.itemData = [getValue(this.parent.pathId[this.parent.pathId.length - 1], this.parent.feParent)];
652
+ }
653
+ }
654
+ }
655
+
656
+ private onpasteInit(): void {
657
+ if (this.parent.activeModule === this.getModuleName()) {
658
+ this.parent.itemData = (this.parent.folderPath === '') ? [getPathObject(this.parent)] :
659
+ [this.getItemObject(select('.e-active', this.element))];
660
+ }
661
+ }
662
+
663
+ private oncutCopyInit(): void {
664
+ if (this.parent.activeModule === this.getModuleName()) {
665
+ const activeEle: NodeListOf<Element> = this.element.querySelectorAll('.' + CLS.ACTIVE);
666
+ this.parent.activeRecords = [];
667
+ this.parent.activeElements = [];
668
+ for (let i: number = 0; i < activeEle.length; i++) {
669
+ this.parent.activeElements.push(activeEle[i as number]);
670
+ this.parent.activeRecords.push(this.getItemObject(activeEle[i as number]));
671
+ }
672
+ }
673
+ }
674
+
675
+ private onpasteEnd(args: ReadArgs): void {
676
+ if (this.parent.view === 'LargeIcons') {
677
+ this.isPasteOperation = true;
678
+ if (this.parent.path === this.parent.destinationPath ||
679
+ this.parent.path === getDirectoryPath(this.parent, args) || this.parent.hasId) {
680
+ this.onPathChanged(args);
681
+ }
682
+ }
683
+ }
684
+
685
+ private onDropPath(args: ReadArgs): void {
686
+ if (this.parent.view === 'LargeIcons') {
687
+ this.isPasteOperation = true;
688
+ this.onPathChanged(args);
689
+ }
690
+ }
691
+
692
+ private onPropertyChanged(e: NotifyArgs): void {
693
+ let currentSelected: string[];
694
+ if (e.module !== this.getModuleName() && e.module !== 'common') {
695
+ return;
696
+ }
697
+ for (const prop of Object.keys(e.newProp)) {
698
+ switch (prop) {
699
+ case 'allowDragAndDrop':
700
+ this.createDragObj();
701
+ break;
702
+ case 'selectedItems':
703
+ this.isInteraction = false;
704
+ this.isInteracted = false;
705
+ currentSelected = isNOU(this.parent.selectedItems) ? [] : this.parent.selectedItems.slice(0);
706
+ currentSelected = this.parent.allowMultiSelection ? currentSelected :
707
+ currentSelected.slice(currentSelected.length - 1);
708
+ this.parent.setProperties({ selectedItems: [] }, true);
709
+ this.onClearAllInit();
710
+ if (currentSelected.length) {
711
+ this.selectItems(currentSelected);
712
+ }
713
+ this.parent.setProperties({ selectedItems: this.parent.selectedItems }, true);
714
+ this.isInteraction = true;
715
+ this.isInteracted = true;
716
+ break;
717
+ case 'showThumbnail':
718
+ refresh(this.parent);
719
+ break;
720
+ case 'showFileExtension':
721
+ read(this.parent, events.pathChanged, this.parent.path);
722
+ break;
723
+ case 'showHiddenItems':
724
+ read(this.parent, events.pathChanged, this.parent.path);
725
+ break;
726
+ case 'allowMultiSelection':
727
+ case 'showItemCheckBoxes':
728
+ if (this.parent.view !== 'LargeIcons') { break; }
729
+ refresh(this.parent);
730
+ break;
731
+ case 'view':
732
+ updateLayout(this.parent, 'LargeIcons');
733
+ break;
734
+ }
735
+ }
736
+ }
737
+
738
+ public destroy(): void {
739
+ if (this.parent.isDestroyed) { return; }
740
+ this.removeEventListener();
741
+ if (this.listObj) {
742
+ this.unWireEvents();
743
+ }
744
+ this.startItem = null;
745
+ this.listElements = null;
746
+ }
747
+
748
+ private wireEvents(): void {
749
+ this.wireClickEvent(true);
750
+ this.keyboardModule = new KeyboardEvents(
751
+ this.element,
752
+ {
753
+ keyAction: this.keyActionHandler.bind(this),
754
+ keyConfigs: this.keyConfigs,
755
+ eventName: 'keyup'
756
+ }
757
+ );
758
+ this.keyboardDownModule = new KeyboardEvents(
759
+ this.element,
760
+ {
761
+ keyAction: this.keydownActionHandler.bind(this),
762
+ keyConfigs: this.keyConfigs,
763
+ eventName: 'keydown'
764
+ }
765
+ );
766
+ EventHandler.add(this.element, 'mouseover', this.onMouseOver, this);
767
+ }
768
+
769
+ private unWireEvents(): void {
770
+ this.wireClickEvent(false);
771
+ EventHandler.remove(this.element, 'mouseover', this.onMouseOver);
772
+ this.keyboardModule.destroy();
773
+ this.keyboardDownModule.destroy();
774
+ }
775
+
776
+ /* istanbul ignore next */
777
+ private onMouseOver(e: MouseArgs): void {
778
+ const targetEle: Element = closest(e.target, '.e-list-item');
779
+ removeBlur(this.parent, 'hover');
780
+ if (targetEle !== null) {
781
+ targetEle.classList.add(CLS.HOVER);
782
+ }
783
+ }
784
+
785
+ private wireClickEvent(toBind: boolean): void {
786
+ if (toBind) {
787
+ this.clickObj = new Touch(this.element, {
788
+ tap: (eve: TapEventArgs) => {
789
+ if (this.parent.isDevice) {
790
+ this.tapCount = eve.tapCount;
791
+ this.tapEvent = eve;
792
+ setTimeout(
793
+ () => {
794
+ if (this.tapCount > 0) {
795
+ this.doTapAction(this.tapEvent);
796
+ }
797
+ this.tapCount = 0;
798
+ },
799
+ 350);
800
+ } else {
801
+ if (eve.tapCount === 2 && eve.originalEvent.which !== 3) {
802
+ this.dblClickHandler(eve);
803
+ } else {
804
+ this.clickHandler(eve);
805
+ }
806
+ }
807
+ },
808
+ tapHold: (e: TapEventArgs) => {
809
+ if (this.parent.isDevice) {
810
+ this.multiSelect = this.parent.allowMultiSelection ? true : false;
811
+ if (this.parent.allowMultiSelection) {
812
+ addClass([this.parent.element], CLS.MULTI_SELECT);
813
+ }
814
+ this.clickHandler(e);
815
+ }
816
+ }
817
+ });
818
+ } else {
819
+ if (this.clickObj) {
820
+ this.clickObj.destroy();
821
+ }
822
+ }
823
+ }
824
+
825
+ private doTapAction(eve: TapEventArgs): void {
826
+ const target: Element = <Element>eve.originalEvent.target;
827
+ const item: Element = closest(target, '.' + CLS.LIST_ITEM);
828
+ if (this.multiSelect || target.classList.contains(CLS.LIST_PARENT) || isNOU(item)) {
829
+ this.clickHandler(eve);
830
+ } else {
831
+ this.parent.isFile = false;
832
+ this.updateType(item);
833
+ if (!this.parent.isFile) {
834
+ this.dblClickHandler(eve);
835
+ } else if (eve.tapCount === 2) {
836
+ this.clickHandler(eve);
837
+ this.dblClickHandler(eve);
838
+ } else {
839
+ this.clickHandler(eve);
840
+ }
841
+ }
842
+ }
843
+
844
+ private clickHandler(e: TapEventArgs): void {
845
+ const target: Element = <Element>e.originalEvent.target;
846
+ removeBlur(this.parent, 'hover');
847
+ this.doSelection(target, e.originalEvent);
848
+ this.parent.activeModule = 'largeiconsview';
849
+ }
850
+ /**
851
+ *
852
+ * @param {Element} target - specifies the target element.
853
+ * @param {TouchEventArgs | MouseEventArgs | KeyboardEventArgs} e - specifies event arguements.
854
+ * @returns {void}
855
+ * @hidden
856
+ */
857
+ public doSelection(target: Element, e: TouchEventArgs | MouseEventArgs | KeyboardEventArgs): void {
858
+ const ctrlKey: boolean = this.parent.isMac ? e.metaKey : e.ctrlKey;
859
+ const isMacRightClick: boolean = this.parent.isMac && e.ctrlKey && e.shiftKey;
860
+ const item: Element = closest(target, '.' + CLS.LIST_ITEM);
861
+ const cList: DOMTokenList = target.classList;
862
+ this.parent.isFile = false;
863
+ let action: string = 'select';
864
+ if ((e.which === 3 || isMacRightClick) && !isNOU(item) && item.classList.contains(CLS.ACTIVE)) {
865
+ this.addActive(item);
866
+ this.updateType(item);
867
+ return;
868
+ } else if (!isNOU(item)) {
869
+ if (this.parent.allowMultiSelection && item.classList.contains(CLS.ACTIVE)
870
+ && (ctrlKey || target.classList.contains(CLS.CHECK))) {
871
+ action = 'unselect';
872
+ }
873
+ if (ctrlKey && e.shiftKey && !isMacRightClick) {
874
+ this.isSelectAllCalled = true;
875
+ }
876
+ const fileSelectionArgs: FileSelectionEventArgs = this.triggerSelection(action, item);
877
+ if (fileSelectionArgs.cancel !== true) {
878
+ if ((!this.parent.allowMultiSelection || (!this.multiSelect && (e && !ctrlKey)))
879
+ && !cList.contains(CLS.FRAME)) {
880
+ this.updateType(item);
881
+ this.clearSelect();
882
+ }
883
+ if (this.parent.allowMultiSelection && e.shiftKey && !isMacRightClick) {
884
+ if (!(e && ctrlKey)) { this.clearSelect(); }
885
+ if (!this.startItem) {
886
+ this.startItem = item;
887
+ }
888
+ const startIndex: number = this.itemList.indexOf(<HTMLElement>this.startItem);
889
+ const endIndex: number = this.itemList.indexOf(<HTMLElement>item);
890
+ if (startIndex > endIndex) {
891
+ for (let i: number = startIndex; i >= endIndex; i--) {
892
+ this.addActive(this.itemList[i as number]);
893
+ }
894
+ } else {
895
+ for (let i: number = startIndex; i <= endIndex; i++) {
896
+ this.addActive(this.itemList[i as number]);
897
+ }
898
+ }
899
+ this.addFocus(this.itemList[endIndex as number]);
900
+ } else {
901
+ this.startItem = item;
902
+ if (this.parent.allowMultiSelection && item.classList.contains(CLS.ACTIVE)) {
903
+ this.removeActive(item);
904
+ } else {
905
+ this.addActive(item);
906
+ }
907
+ this.addFocus(item);
908
+ }
909
+ if (this.parent.selectedItems.length === 0) {
910
+ this.resetMultiSelect();
911
+ }
912
+ this.parent.notify(events.selectionChanged, {});
913
+ this.triggerSelect(action, item);
914
+ }
915
+ } else {
916
+ if (this.parent.selectedItems.length === this.itemList.length) {
917
+ this.isSelectAllCalled = true;
918
+ }
919
+ this.clearSelection();
920
+ }
921
+ if (!isNOU(item)) {
922
+ this.isSelectAllCalled = false;
923
+ this.updateType(item);
924
+ }
925
+ }
926
+
927
+ private dblClickHandler(e: TapEventArgs): void {
928
+ this.parent.activeModule = 'largeiconsview';
929
+ const target: Element = <Element>e.originalEvent.target;
930
+ this.doOpenAction(target);
931
+ }
932
+
933
+ private clearSelection(): void {
934
+ this.clearSelect();
935
+ this.resetMultiSelect();
936
+ this.parent.notify(events.selectionChanged, {});
937
+ }
938
+
939
+ private resetMultiSelect(): void {
940
+ this.multiSelect = false;
941
+ removeClass([this.parent.element], CLS.MULTI_SELECT);
942
+ }
943
+
944
+ private doOpenAction(target: Element): void {
945
+ if (isNOU(target)) { return; }
946
+ const item: Element = closest(target, '.' + CLS.LIST_ITEM);
947
+ this.parent.isFile = false;
948
+ if (!isNOU(item)) {
949
+ this.updateType(item);
950
+ const details: Object = this.getItemObject(item);
951
+ if (!hasReadAccess(details)) {
952
+ createDeniedDialog(this.parent, details, events.permissionRead);
953
+ return;
954
+ }
955
+ const eventArgs: FileOpenEventArgs = { cancel: false, fileDetails: details, module: 'LargeIconsView' };
956
+ this.parent.trigger('fileOpen', eventArgs, (fileOpenArgs: FileOpenEventArgs) => {
957
+ if (!fileOpenArgs.cancel) {
958
+ const text: string = getValue('name', details);
959
+ if (!this.parent.isFile) {
960
+ const val: string = this.parent.breadcrumbbarModule.searchObj.element.value;
961
+ if (val === '' && !this.parent.isFiltered) {
962
+ const id: string = getValue('id', details);
963
+ this.parent.oldPath = this.parent.path;
964
+ const newPath: string = this.parent.path + (isNOU(id) ? text : id) + '/';
965
+ this.parent.setProperties({ path: newPath }, true);
966
+ this.parent.pathNames.push(text);
967
+ this.parent.pathId.push(getValue('_fm_id', details));
968
+ this.parent.itemData = [details];
969
+ openAction(this.parent);
970
+ } else {
971
+ openSearchFolder(this.parent, details);
972
+ }
973
+ this.parent.isFiltered = false;
974
+ this.parent.setProperties({ selectedItems: [] }, true);
975
+ } else {
976
+ const icon: string = fileType(details);
977
+ if (icon === CLS.ICON_IMAGE) {
978
+ const imageData: BeforeImageLoadEventArgs = getImageUrl(this.parent, details);
979
+ createImageDialog(this.parent, text, imageData);
980
+ }
981
+ }
982
+ }
983
+ });
984
+ }
985
+ }
986
+
987
+ private updateType(item: Element): void {
988
+ const folder: Element = select('.' + CLS.FOLDER, item);
989
+ this.parent.isFile = isNOU(folder) ? true : false;
990
+ }
991
+
992
+ /* istanbul ignore next */
993
+ private keydownActionHandler(e: KeyboardEventArgs): void {
994
+ if (!this.isRendered) { return; }
995
+ switch (e.action) {
996
+ case 'end':
997
+ case 'home':
998
+ case 'moveDown':
999
+ case 'moveLeft':
1000
+ case 'moveRight':
1001
+ case 'moveUp':
1002
+ case 'ctrlEnd':
1003
+ case 'shiftEnd':
1004
+ case 'csEnd':
1005
+ case 'ctrlHome':
1006
+ case 'shiftHome':
1007
+ case 'csHome':
1008
+ case 'ctrlDown':
1009
+ case 'shiftDown':
1010
+ case 'csDown':
1011
+ case 'ctrlLeft':
1012
+ case 'shiftLeft':
1013
+ case 'csLeft':
1014
+ case 'ctrlRight':
1015
+ case 'shiftRight':
1016
+ case 'csRight':
1017
+ case 'space':
1018
+ case 'ctrlSpace':
1019
+ case 'shiftSpace':
1020
+ case 'csSpace':
1021
+ case 'ctrlA':
1022
+ case 'enter':
1023
+ case 'altEnter':
1024
+ case 'esc':
1025
+ case 'del':
1026
+ case 'shiftdel':
1027
+ case 'ctrlC':
1028
+ case 'ctrlV':
1029
+ case 'ctrlX':
1030
+ case 'f2':
1031
+ case 'ctrlD':
1032
+ e.preventDefault();
1033
+ break;
1034
+ default:
1035
+ break;
1036
+ }
1037
+ }
1038
+
1039
+ /* istanbul ignore next */
1040
+ private keyActionHandler(e: KeyboardEventArgs): void {
1041
+ if (!this.isRendered) { return; }
1042
+ const fItem: Element = this.getFocusedItem();
1043
+ const firstItem: Element = this.getFirstItem();
1044
+ const lastItem: Element = this.getLastItem();
1045
+ switch (e.action) {
1046
+ case 'end':
1047
+ if (this.parent.enableVirtualization) {
1048
+ this.clearSelect();
1049
+ this.element.firstElementChild.scrollTo(0, this.element.firstElementChild.scrollHeight);
1050
+ setTimeout(() => {
1051
+ this.navigateItem(this.itemList[this.itemList.length - 1]);
1052
+ }, 10);
1053
+ } else {
1054
+ this.navigateItem(lastItem);
1055
+ }
1056
+ break;
1057
+ case 'home':
1058
+ if (this.parent.enableVirtualization) {
1059
+ this.clearSelect();
1060
+ this.element.firstElementChild.scrollTop = 0;
1061
+ setTimeout(() => {
1062
+ this.navigateItem(this.itemList[0]);
1063
+ }, 10);
1064
+ } else {
1065
+ this.navigateItem(firstItem);
1066
+ }
1067
+ break;
1068
+ case 'tab':
1069
+ if (!isNOU(fItem)) {
1070
+ this.addFocus(fItem);
1071
+ } else if (!isNOU(firstItem)) {
1072
+ this.addFocus(firstItem);
1073
+ }
1074
+ break;
1075
+ case 'moveDown':
1076
+ this.navigateDown(fItem, true);
1077
+ break;
1078
+ case 'moveLeft':
1079
+ this.navigateRight(fItem, false);
1080
+ break;
1081
+ case 'moveRight':
1082
+ this.navigateRight(fItem, true);
1083
+ break;
1084
+ case 'moveUp':
1085
+ this.navigateDown(fItem, false);
1086
+ break;
1087
+ case 'ctrlEnd':
1088
+ case 'shiftEnd':
1089
+ case 'csEnd':
1090
+ this.csEndKey(lastItem, e);
1091
+ break;
1092
+ case 'ctrlHome':
1093
+ case 'shiftHome':
1094
+ case 'csHome':
1095
+ this.csHomeKey(firstItem, e);
1096
+ break;
1097
+ case 'ctrlDown':
1098
+ case 'shiftDown':
1099
+ case 'csDown':
1100
+ this.csDownKey(fItem, e);
1101
+ break;
1102
+ case 'ctrlLeft':
1103
+ case 'shiftLeft':
1104
+ case 'csLeft':
1105
+ this.csLeftKey(fItem, e);
1106
+ break;
1107
+ case 'ctrlRight':
1108
+ case 'shiftRight':
1109
+ case 'csRight':
1110
+ this.csRightKey(fItem, e);
1111
+ break;
1112
+ case 'ctrlUp':
1113
+ case 'shiftUp':
1114
+ case 'csUp':
1115
+ this.csUpKey(fItem, e);
1116
+ break;
1117
+ case 'space':
1118
+ this.spaceKey(fItem);
1119
+ break;
1120
+ case 'ctrlSpace':
1121
+ case 'shiftSpace':
1122
+ case 'csSpace':
1123
+ if (!isNOU(fItem)) { this.doSelection(fItem, e); }
1124
+ break;
1125
+ case 'ctrlA':
1126
+ this.ctrlAKey(firstItem, lastItem);
1127
+ break;
1128
+ case 'enter':
1129
+ this.doOpenAction(this.parent.visitedItem ? this.parent.visitedItem : this.getVisitedItem());
1130
+ break;
1131
+ case 'altEnter':
1132
+ this.parent.notify(events.detailsInit, {});
1133
+ GetDetails(this.parent, this.parent.selectedItems, this.parent.path, 'details');
1134
+ break;
1135
+ case 'esc':
1136
+ removeActive(this.parent);
1137
+ break;
1138
+ case 'del':
1139
+ case 'shiftdel':
1140
+ this.performDelete();
1141
+ break;
1142
+ case 'ctrlC':
1143
+ copyFiles(this.parent);
1144
+ break;
1145
+ case 'ctrlV':
1146
+ this.parent.folderPath = '';
1147
+ pasteHandler(this.parent);
1148
+ break;
1149
+ case 'ctrlX':
1150
+ cutFiles(this.parent);
1151
+ break;
1152
+ case 'f2':
1153
+ this.performRename();
1154
+ break;
1155
+ case 'ctrlD':
1156
+ this.doDownload();
1157
+ break;
1158
+ case 'back':
1159
+ this.parent.traverseBackward();
1160
+ break;
1161
+ }
1162
+ }
1163
+
1164
+ private doDownload(): void {
1165
+ this.updateSelectedData();
1166
+ doDownload(this.parent);
1167
+ }
1168
+
1169
+ private performDelete(): void {
1170
+ if (this.parent.selectedItems && this.parent.selectedItems.length > 0) {
1171
+ this.updateSelectedData();
1172
+ const data: Object[] = this.parent.itemData;
1173
+ for (let i: number = 0; i < data.length; i++) {
1174
+ if (!hasEditAccess(data[i as number])) {
1175
+ createDeniedDialog(this.parent, data[i as number], events.permissionEdit);
1176
+ return;
1177
+ }
1178
+ }
1179
+ createDialog(this.parent, 'Delete');
1180
+ }
1181
+ }
1182
+
1183
+ private performRename(): void {
1184
+ if (this.parent.selectedItems.length === 1) {
1185
+ this.updateRenameData();
1186
+ doRename(this.parent);
1187
+ }
1188
+ }
1189
+
1190
+ private updateRenameData(): void {
1191
+ const item: Element = select('.' + CLS.LIST_ITEM + '.' + CLS.ACTIVE, this.element);
1192
+ const data: Object = this.getItemObject(item);
1193
+ updateRenamingData(this.parent, data);
1194
+ }
1195
+
1196
+ private getVisitedItem(): Element {
1197
+ const item: string = this.parent.selectedItems[this.parent.selectedItems.length - 1];
1198
+ const indexes: number[] = this.getIndexes([item], this.parent.hasId);
1199
+ return this.itemList[indexes[0]];
1200
+ }
1201
+
1202
+ private getFocusedItem(): Element {
1203
+ return select('.' + CLS.LIST_ITEM + '.' + CLS.FOCUS, this.element);
1204
+ }
1205
+
1206
+ private getActiveItem(): Element {
1207
+ return select('.' + CLS.LIST_ITEM + '.' + CLS.ACTIVE, this.element);
1208
+ }
1209
+
1210
+ private getFirstItem(): Element {
1211
+ return this.itemList[0];
1212
+ }
1213
+
1214
+ private getLastItem(): Element {
1215
+ return this.itemList[this.itemList.length - 1];
1216
+ }
1217
+
1218
+ private navigateItem(item: Element): void {
1219
+ this.setFocus(item);
1220
+ }
1221
+
1222
+ private navigateDown(fItem: Element, isTowards: boolean): void {
1223
+ const nItem: Element = this.getNextItem(fItem, isTowards, this.perRow);
1224
+ this.setFocus(nItem);
1225
+ }
1226
+
1227
+ private navigateRight(fItem: Element, isTowards: boolean): void {
1228
+ const nItem: Element = this.getNextItem(fItem, isTowards);
1229
+ this.setFocus(nItem);
1230
+ }
1231
+
1232
+ private getNextItem(li: Element, isTowards: boolean, perRow?: number): Element {
1233
+ if (isNOU(li)) { return this.getFocusedItem() || this.getActiveItem() || this.getFirstItem(); }
1234
+ let index: number = this.itemList.indexOf(<HTMLElement>li);
1235
+ let nextItem: Element;
1236
+ do {
1237
+ if (isTowards) {
1238
+ index = perRow ? index + perRow : index + 1;
1239
+ } else {
1240
+ index = perRow ? index - perRow : index - 1;
1241
+ }
1242
+ nextItem = this.itemList[index as number];
1243
+ if (this.parent.enableVirtualization && isNOU(nextItem)) {
1244
+ const marginValue: number = parseInt(window.getComputedStyle(this.itemList[0]).getPropertyValue('margin-top'), 10) +
1245
+ parseInt(window.getComputedStyle(this.itemList[0]).getPropertyValue('margin-bottom'), 10);
1246
+ const scrollHeight: number = this.itemList[0].getBoundingClientRect().height + marginValue ;
1247
+ this.element.firstElementChild.scrollTo(
1248
+ this.element.firstElementChild.scrollTop, this.element.firstElementChild.scrollTop + scrollHeight);
1249
+ }
1250
+ if (isNOU(nextItem)) {
1251
+ return li;
1252
+ }
1253
+ }
1254
+ while (!isVisible(nextItem));
1255
+ return nextItem;
1256
+ }
1257
+
1258
+ private setFocus(nextItem: Element): void {
1259
+ if (!isNOU(nextItem)) {
1260
+ const fileSelectionArgs: FileSelectionEventArgs = this.triggerSelection('select', nextItem);
1261
+ if (fileSelectionArgs.cancel !== true) {
1262
+ this.startItem = nextItem;
1263
+ this.clearSelect();
1264
+ this.addActive(nextItem);
1265
+ this.addFocus(nextItem);
1266
+ this.parent.notify(events.selectionChanged, {});
1267
+ this.triggerSelect('select', nextItem);
1268
+ }
1269
+ }
1270
+ }
1271
+
1272
+ private spaceKey(fItem: Element): void {
1273
+ if (!isNOU(fItem) && !fItem.classList.contains(CLS.ACTIVE)) {
1274
+ const fileSelectionArgs: FileSelectionEventArgs = this.triggerSelection('select', fItem);
1275
+ if (fileSelectionArgs.cancel !== true) {
1276
+ this.addActive(fItem);
1277
+ this.parent.notify(events.selectionChanged, {});
1278
+ this.triggerSelect('select', fItem);
1279
+ }
1280
+ }
1281
+ }
1282
+
1283
+ private ctrlAKey(firstItem: Element, lastItem: Element): void {
1284
+ if (this.parent.allowMultiSelection && !isNOU(firstItem)) {
1285
+ this.startItem = firstItem;
1286
+ const eveArgs: KeyboardEventArgs = { ctrlKey: true, shiftKey: true } as KeyboardEventArgs;
1287
+ const liParent: HTMLElement = this.element.querySelector('.' + CLS.LIST_PARENT);
1288
+ const liScrPos: number = liParent.scrollTop;
1289
+ const getCurFocusedItem: Element = this.getFocusedItem();
1290
+ this.doSelection(lastItem, eveArgs);
1291
+ liParent.scrollTop = liScrPos;
1292
+ if (!isNOU(getCurFocusedItem)) {
1293
+ this.addFocus(getCurFocusedItem);
1294
+ }
1295
+ }
1296
+ }
1297
+
1298
+ private csEndKey(lastItem: Element, e: KeyboardEventArgs): void {
1299
+ if (!this.parent.allowMultiSelection) {
1300
+ this.navigateItem(lastItem);
1301
+ } else if (!isNOU(lastItem)) {
1302
+ if (e.action === 'ctrlEnd') { this.addFocus(lastItem); } else { this.doSelection(lastItem, e); }
1303
+ }
1304
+ }
1305
+
1306
+ private csHomeKey(firstItem: Element, e: KeyboardEventArgs): void {
1307
+ if (!this.parent.allowMultiSelection) {
1308
+ this.navigateItem(firstItem);
1309
+ } else if (!isNOU(firstItem)) {
1310
+ if (e.action === 'ctrlHome') {
1311
+ this.addFocus(firstItem);
1312
+ } else{
1313
+ this.doSelection(firstItem, e);
1314
+ }
1315
+ }
1316
+ }
1317
+
1318
+ private csDownKey(fItem: Element, e: KeyboardEventArgs): void {
1319
+ if (!this.parent.allowMultiSelection) {
1320
+ this.navigateDown(fItem, true);
1321
+ } else {
1322
+ const dItem: Element = this.getNextItem(fItem, true, this.perRow);
1323
+ if (!isNOU(dItem)) {
1324
+ if (e.action === 'ctrlDown') {
1325
+ this.addFocus(dItem);
1326
+ } else {
1327
+ this.doSelection(dItem, e);
1328
+ }
1329
+ }
1330
+ }
1331
+ }
1332
+
1333
+ private csLeftKey(fItem: Element, e: KeyboardEventArgs): void {
1334
+ if (!this.parent.allowMultiSelection) {
1335
+ this.navigateRight(fItem, false);
1336
+ } else {
1337
+ const lItem: Element = this.getNextItem(fItem, false);
1338
+ if (!isNOU(lItem)) {
1339
+ if (e.action === 'ctrlLeft') {
1340
+ this.addFocus(lItem);
1341
+ } else {
1342
+ this.doSelection(lItem, e);
1343
+ }
1344
+ }
1345
+ }
1346
+ }
1347
+
1348
+ private csRightKey(fItem: Element, e: KeyboardEventArgs): void {
1349
+ if (!this.parent.allowMultiSelection) {
1350
+ this.navigateRight(fItem, true);
1351
+ } else {
1352
+ const rItem: Element = this.getNextItem(fItem, true);
1353
+ if (!isNOU(rItem)) {
1354
+ if (e.action === 'ctrlRight'){
1355
+ this.addFocus(rItem);
1356
+ } else{
1357
+ this.doSelection(rItem, e);
1358
+ }
1359
+ }
1360
+ }
1361
+ }
1362
+
1363
+ private csUpKey(fItem: Element, e: KeyboardEventArgs): void {
1364
+ if (!this.parent.allowMultiSelection) {
1365
+ this.navigateDown(fItem, false);
1366
+ } else {
1367
+ const uItem: Element = this.getNextItem(fItem, false, this.perRow);
1368
+ if (!isNOU(uItem)) {
1369
+ if (e.action === 'ctrlUp') {
1370
+ this.addFocus(uItem);
1371
+ } else{
1372
+ this.doSelection(uItem, e);
1373
+ }
1374
+ }
1375
+ }
1376
+ }
1377
+
1378
+ private addActive(nextItem: Element): void {
1379
+ if (!isNOU(nextItem)) {
1380
+ if (!nextItem.classList.contains(CLS.ACTIVE)) {
1381
+ this.parent.selectedItems.push(this.getDataName(nextItem));
1382
+ this.parent.setProperties({ selectedItems: this.parent.selectedItems }, true);
1383
+ addClass([nextItem], [CLS.ACTIVE]);
1384
+ nextItem.setAttribute('aria-selected', 'true');
1385
+ this.checkState(nextItem, true);
1386
+ }
1387
+ this.parent.visitedItem = nextItem;
1388
+ }
1389
+ }
1390
+
1391
+ private removeActive(preItem: Element): void {
1392
+ if (!isNOU(preItem)) {
1393
+ removeClass([preItem], [CLS.ACTIVE]);
1394
+ if (this.parent.allowMultiSelection) {
1395
+ preItem.setAttribute('aria-selected', 'false');
1396
+ } else {
1397
+ preItem.removeAttribute('aria-selected');
1398
+ }
1399
+ this.checkState(preItem, false);
1400
+ const index: number = this.parent.selectedItems.indexOf(this.getDataName(preItem));
1401
+ if (index > -1) {
1402
+ this.parent.selectedItems.splice(index, 1);
1403
+ this.parent.setProperties({ selectedItems: this.parent.selectedItems }, true);
1404
+ }
1405
+ this.parent.visitedItem = null;
1406
+ }
1407
+ }
1408
+
1409
+ private getDataName(item: Element): string {
1410
+ const data: Object = this.getItemObject(item);
1411
+ return getItemName(this.parent, data);
1412
+ }
1413
+
1414
+ private addFocus(item: Element): void {
1415
+ this.element.setAttribute('tabindex', '-1');
1416
+ const fItem: Element = this.getFocusedItem();
1417
+ if (fItem) {
1418
+ fItem.removeAttribute('tabindex');
1419
+ removeClass([fItem], [CLS.FOCUS]);
1420
+ }
1421
+ addClass([item], [CLS.FOCUS]);
1422
+ item.setAttribute('tabindex', '0');
1423
+ (item as HTMLElement).focus();
1424
+ }
1425
+
1426
+ private checkState(item: Element, toCheck: boolean): void {
1427
+ if (!this.parent.showItemCheckBoxes) { return; }
1428
+ const checkEle: Element = select('.' + CLS.FRAME, item);
1429
+ if (isNOU(checkEle)) { return; }
1430
+ if (toCheck) {
1431
+ if (!checkEle.classList.contains(CLS.CHECK)) {
1432
+ addClass([checkEle], CLS.CHECK);
1433
+ closest(checkEle, '.' + CLS.CB_WRAP).setAttribute('aria-checked', 'true');
1434
+ }
1435
+ } else {
1436
+ if (checkEle.classList.contains(CLS.CHECK)) {
1437
+ removeClass([checkEle], CLS.CHECK);
1438
+ closest(checkEle, '.' + CLS.CB_WRAP).setAttribute('aria-checked', 'false');
1439
+ }
1440
+ }
1441
+ }
1442
+
1443
+ private clearSelect(): void {
1444
+ const eles: Element[] = Array.prototype.slice.call(selectAll('.' + CLS.ACTIVE, this.listElements));
1445
+ let fileSelectionArgs: FileSelectionEventArgs;
1446
+ if (eles.length !== 0) {
1447
+ fileSelectionArgs = this.triggerSelection('unselect', eles[0]);
1448
+ if (fileSelectionArgs.cancel !== true) {
1449
+ for (let i: number = 0, len: number = eles.length; i < len; i++) {
1450
+ this.removeActive(eles[i as number]);
1451
+ }
1452
+ }
1453
+ this.triggerSelect('unselect', eles[0]);
1454
+ }
1455
+ }
1456
+
1457
+ private resizeHandler(): void {
1458
+ this.getItemCount();
1459
+ }
1460
+
1461
+ private splitterResizeHandler(): void {
1462
+ this.getItemCount();
1463
+ }
1464
+
1465
+ private getItemCount(): void {
1466
+ let perRow: number = 1;
1467
+ if (this.itemList) {
1468
+ for (let i: number = 0, len: number = this.itemList.length - 1; i < len; i++) {
1469
+ if (this.itemList[i as number].getBoundingClientRect().top === this.itemList[i + 1].getBoundingClientRect().top) {
1470
+ perRow++;
1471
+ } else {
1472
+ break;
1473
+ }
1474
+ }
1475
+ }
1476
+ this.perRow = perRow;
1477
+ }
1478
+ private triggerSelection(action: string, item: Element): FileSelectionEventArgs {
1479
+ const data: object[] = [];
1480
+ if (this.isSelectAllCalled){
1481
+ for (let i: number = 0, len: number = this.itemList.length; i < len; i++ ) {
1482
+ data[i as number] = this.getItemObject(this.itemList[i as number]);
1483
+ }
1484
+ }else{
1485
+ data[0] = this.getItemObject(item);
1486
+ }
1487
+ const eventArgs: FileSelectionEventArgs = { action: action, fileDetails: data.length > 1
1488
+ ? data : data[0], isInteracted: this.isInteraction, cancel: false, target: this.isSelectAllCalled ? null
1489
+ : item
1490
+ };
1491
+ this.parent.trigger('fileSelection', eventArgs);
1492
+ this.isInteraction = true;
1493
+ return eventArgs;
1494
+ }
1495
+
1496
+ private triggerSelect(action: string, item: Element): void {
1497
+ const data: object[] = [];
1498
+ if (this.isSelectAllCalled){
1499
+ for (let i: number = 0, len: number = this.itemList.length; i < len; i++ ) {
1500
+ data[i as number] = this.getItemObject(this.itemList[i as number]);
1501
+ }
1502
+ this.isSelectAllCalled = false;
1503
+ }else{
1504
+ data[0] = this.getItemObject(item);
1505
+ }
1506
+ this.parent.visitedData = data.length > 1 ? data[data.length - 1] : data[0];
1507
+ const eventArgs: FileSelectEventArgs = { action: action, fileDetails: data.length > 1
1508
+ ? data
1509
+ : data[0], isInteracted: this.isInteracted };
1510
+ this.parent.trigger('fileSelect', eventArgs);
1511
+ this.isInteracted = true;
1512
+ }
1513
+
1514
+ private selectItems(items: string[]): void {
1515
+ const indexes: number[] = this.getIndexes(items, this.parent.hasId);
1516
+ for (let j: number = 0, len: number = indexes.length; j < len; j++) {
1517
+ const eveArgs: KeyboardEventArgs = { ctrlKey: true, shiftKey: false } as KeyboardEventArgs;
1518
+ this.doSelection(this.itemList[indexes[j as number]], eveArgs);
1519
+ }
1520
+ }
1521
+
1522
+ private getIndexes(items: string[], byId?: boolean): number[] {
1523
+ const indexes: number[] = [];
1524
+ const filter: string = byId ? 'id' : 'name';
1525
+ for (let i: number = 0, len: number = this.items.length; i < len; i++) {
1526
+ if (items.indexOf(getValue(filter, this.items[i as number])) !== -1) {
1527
+ indexes.push(i);
1528
+ }
1529
+ }
1530
+ return indexes;
1531
+ }
1532
+
1533
+ private getItemObject(item: Element): Object {
1534
+ const index: number = this.itemList.indexOf(<HTMLElement>item);
1535
+ return this.items[index as number];
1536
+ }
1537
+
1538
+ private addSelection(data: Object): void {
1539
+ let resultData: Object[] = [];
1540
+ if (this.parent.hasId) {
1541
+ resultData = new DataManager(this.items).
1542
+ executeLocal(new Query().where('id', 'equal', this.parent.renamedId, false));
1543
+ } else {
1544
+ const newData: Object[] = new DataManager(this.items).
1545
+ executeLocal(new Query().where('name', 'equal', getValue('name', data), false));
1546
+ if (newData.length > 0) {
1547
+ resultData = new DataManager(newData).
1548
+ executeLocal(new Query().where('filterPath', 'equal', this.parent.filterPath, false));
1549
+ }
1550
+ }
1551
+ if (resultData.length > 0) {
1552
+ const index: number = this.items.indexOf(resultData[0]);
1553
+ const eveArgs: KeyboardEventArgs = { ctrlKey: true, shiftKey: false } as KeyboardEventArgs;
1554
+ this.doSelection(this.itemList[index as number], eveArgs);
1555
+ }
1556
+ }
1557
+
1558
+ private updateSelectedData(): void {
1559
+ const data: object[] = [];
1560
+ const items: Element[] = selectAll('.' + CLS.LIST_ITEM + '.' + CLS.ACTIVE, this.element);
1561
+ for (let i: number = 0; i < items.length; i++) {
1562
+ data[i as number] = this.getItemObject(items[i as number]);
1563
+ }
1564
+ this.parent.itemData = data;
1565
+ }
1566
+
1567
+ private onMethodCall(args: Object): void {
1568
+ if (this.parent.view !== 'LargeIcons') { return; }
1569
+ const action: string = getValue('action', args);
1570
+ switch (action) {
1571
+ case 'deleteFiles':
1572
+ this.deleteFiles(getValue('ids', args));
1573
+ break;
1574
+ case 'downloadFiles':
1575
+ this.downloadFiles(getValue('ids', args));
1576
+ break;
1577
+ case 'openFile':
1578
+ this.openFile(getValue('id', args));
1579
+ break;
1580
+ case 'renameFile':
1581
+ this.isInteraction = false;
1582
+ this.isInteracted = false;
1583
+ this.renameFile(getValue('id', args), getValue('newName', args));
1584
+ break;
1585
+ case 'createFolder':
1586
+ this.isInteraction = false;
1587
+ this.isInteracted = false;
1588
+ break;
1589
+ case 'clearSelection':
1590
+ this.isInteraction = false;
1591
+ this.isInteracted = false;
1592
+ this.onClearAllInit();
1593
+ break;
1594
+ case 'selectAll':
1595
+ this.isInteraction = false;
1596
+ this.isInteracted = false;
1597
+ this.onSelectAllInit();
1598
+ break;
1599
+ }
1600
+ }
1601
+
1602
+ private getItemsIndex(items: string[]): number[] {
1603
+ const indexes: number[] = [];
1604
+ const isFilter: boolean = (this.parent.breadcrumbbarModule.searchObj.element.value !== '' || this.parent.isFiltered) ? true : false;
1605
+ const filterName: string = this.parent.hasId ? 'id' : 'name';
1606
+ if (this.parent.hasId || !isFilter) {
1607
+ for (let i: number = 0, len: number = this.items.length; i < len; i++) {
1608
+ if (items.indexOf(getValue(filterName, this.items[i as number])) !== -1) {
1609
+ indexes.push(i);
1610
+ }
1611
+ }
1612
+ } else {
1613
+ for (let i: number = 0, len: number = this.items.length; i < len; i++) {
1614
+ const name: string = getValue('filterPath', this.items[i as number]) + getValue('name', this.items[i as number]);
1615
+ if ((items.indexOf(name) !== -1) || (items.indexOf(getValue(filterName, this.items[i as number])) !== -1)) {
1616
+ indexes.push(i);
1617
+ }
1618
+ }
1619
+ }
1620
+ return indexes;
1621
+ }
1622
+
1623
+ private deleteFiles(ids: string[]): void {
1624
+ this.parent.activeModule = 'largeiconsview';
1625
+ if (isNOU(ids)) {
1626
+ this.performDelete();
1627
+ return;
1628
+ }
1629
+ const indexes: number[] = this.getItemsIndex(ids);
1630
+ if (indexes.length === 0) { return; }
1631
+ const data: Object[] = [];
1632
+ const newIds: string[] = [];
1633
+ for (let i: number = 0; i < indexes.length; i++) {
1634
+ data[i as number] = this.items[indexes[i as number]];
1635
+ newIds[i as number] = getItemName(this.parent, data[i as number]);
1636
+ }
1637
+ doDeleteFiles(this.parent, data, newIds);
1638
+ }
1639
+
1640
+ private downloadFiles(ids: string[]): void {
1641
+ if (isNOU(ids)) {
1642
+ this.doDownload();
1643
+ return;
1644
+ }
1645
+ const index: number[] = this.getItemsIndex(ids);
1646
+ if (index.length === 0) { return; }
1647
+ const data: Object[] = [];
1648
+ const newIds: string[] = [];
1649
+ for (let i: number = 0; i < index.length; i++) {
1650
+ data[i as number] = this.items[index[i as number]];
1651
+ newIds[i as number] = getItemName(this.parent, data[i as number]);
1652
+ }
1653
+ doDownloadFiles(this.parent, data, newIds);
1654
+ }
1655
+
1656
+ private openFile(id: string): void {
1657
+ if (isNOU(id)) { return; }
1658
+ const indexes: number[] = this.getItemsIndex([id]);
1659
+ if (indexes.length > 0) {
1660
+ this.doOpenAction(this.itemList[indexes[0]]);
1661
+ }
1662
+ }
1663
+
1664
+ private renameFile(id: string, name: string): void {
1665
+ this.parent.activeModule = 'largeiconsview';
1666
+ if (isNOU(id)) {
1667
+ this.performRename();
1668
+ return;
1669
+ }
1670
+ const indexes: number[] = this.getItemsIndex([id]);
1671
+ if (indexes.length > 0) {
1672
+ updateRenamingData(this.parent, this.items[indexes[0]]);
1673
+ if (isNOU(name)) {
1674
+ doRename(this.parent);
1675
+ } else {
1676
+ if (!hasEditAccess(this.parent.itemData[0])) {
1677
+ createDeniedDialog(this.parent, this.parent.itemData[0], events.permissionEdit);
1678
+ } else {
1679
+ rename(this.parent, this.parent.path, name);
1680
+ }
1681
+ }
1682
+ }
1683
+ }
1684
+ }