1/*
2@license
3
4dhtmlxGantt v.6.3.5 Standard
5
6This version of dhtmlxGantt is distributed under GPL 2.0 license and can be legally used in GPL projects.
7
8To use dhtmlxGantt in non-GPL projects (and get Pro version of the product), please obtain Commercial/Enterprise or Ultimate license on our site https://dhtmlx.com/docs/products/dhtmlxGantt/#licensing or contact us at sales@dhtmlx.com
9
10(c) XB Software Ltd.
11
12*/
13(function webpackUniversalModuleDefinition(root, factory) {
14	if(typeof exports === 'object' && typeof module === 'object')
15		module.exports = factory();
16	else if(typeof define === 'function' && define.amd)
17		define("ext/dhtmlxgantt_multiselect", [], factory);
18	else if(typeof exports === 'object')
19		exports["ext/dhtmlxgantt_multiselect"] = factory();
20	else
21		root["ext/dhtmlxgantt_multiselect"] = factory();
22})(window, function() {
23return /******/ (function(modules) { // webpackBootstrap
24/******/ 	// The module cache
25/******/ 	var installedModules = {};
26/******/
27/******/ 	// The require function
28/******/ 	function __webpack_require__(moduleId) {
29/******/
30/******/ 		// Check if module is in cache
31/******/ 		if(installedModules[moduleId]) {
32/******/ 			return installedModules[moduleId].exports;
33/******/ 		}
34/******/ 		// Create a new module (and put it into the cache)
35/******/ 		var module = installedModules[moduleId] = {
36/******/ 			i: moduleId,
37/******/ 			l: false,
38/******/ 			exports: {}
39/******/ 		};
40/******/
41/******/ 		// Execute the module function
42/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
43/******/
44/******/ 		// Flag the module as loaded
45/******/ 		module.l = true;
46/******/
47/******/ 		// Return the exports of the module
48/******/ 		return module.exports;
49/******/ 	}
50/******/
51/******/
52/******/ 	// expose the modules object (__webpack_modules__)
53/******/ 	__webpack_require__.m = modules;
54/******/
55/******/ 	// expose the module cache
56/******/ 	__webpack_require__.c = installedModules;
57/******/
58/******/ 	// define getter function for harmony exports
59/******/ 	__webpack_require__.d = function(exports, name, getter) {
60/******/ 		if(!__webpack_require__.o(exports, name)) {
61/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
62/******/ 		}
63/******/ 	};
64/******/
65/******/ 	// define __esModule on exports
66/******/ 	__webpack_require__.r = function(exports) {
67/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
68/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
69/******/ 		}
70/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
71/******/ 	};
72/******/
73/******/ 	// create a fake namespace object
74/******/ 	// mode & 1: value is a module id, require it
75/******/ 	// mode & 2: merge all properties of value into the ns
76/******/ 	// mode & 4: return value when already ns object
77/******/ 	// mode & 8|1: behave like require
78/******/ 	__webpack_require__.t = function(value, mode) {
79/******/ 		if(mode & 1) value = __webpack_require__(value);
80/******/ 		if(mode & 8) return value;
81/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
82/******/ 		var ns = Object.create(null);
83/******/ 		__webpack_require__.r(ns);
84/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
85/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
86/******/ 		return ns;
87/******/ 	};
88/******/
89/******/ 	// getDefaultExport function for compatibility with non-harmony modules
90/******/ 	__webpack_require__.n = function(module) {
91/******/ 		var getter = module && module.__esModule ?
92/******/ 			function getDefault() { return module['default']; } :
93/******/ 			function getModuleExports() { return module; };
94/******/ 		__webpack_require__.d(getter, 'a', getter);
95/******/ 		return getter;
96/******/ 	};
97/******/
98/******/ 	// Object.prototype.hasOwnProperty.call
99/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
100/******/
101/******/ 	// __webpack_public_path__
102/******/ 	__webpack_require__.p = "/codebase/sources/";
103/******/
104/******/
105/******/ 	// Load entry module and return exports
106/******/ 	return __webpack_require__(__webpack_require__.s = "./sources/ext/multiselect.js");
107/******/ })
108/************************************************************************/
109/******/ ({
110
111/***/ "./sources/ext/multiselect.js":
112/*!************************************!*\
113  !*** ./sources/ext/multiselect.js ***!
114  \************************************/
115/*! no static exports found */
116/***/ (function(module, exports) {
117
118gantt.config.multiselect = true;
119gantt.config.multiselect_one_level = false;
120
121gantt._multiselect = {
122	_selected: {},
123	_one_level: false,
124	_active: true,
125	_first_selected_when_shift: null,
126	getDefaultSelected: function() {
127		var selected = this.getSelected();
128		return selected.length ? selected[selected.length - 1] : null;
129	},
130	setFirstSelected: function(id) {
131		this._first_selected_when_shift = id;
132	},
133	getFirstSelected: function() {
134		return this._first_selected_when_shift;
135	},
136	isActive: function() {
137		this.updateState();
138		return this._active;
139	},
140	updateState: function() {
141		this._one_level = gantt.config.multiselect_one_level;
142		var active = this._active;
143		this._active = gantt.config.multiselect;
144		if (this._active != active) {
145			this.reset();
146		}
147	},
148	reset: function () {
149		this._selected = {};
150	},
151	setLastSelected: function (id) {
152		gantt.$data.tasksStore.silent(function(){
153			var store = gantt.$data.tasksStore;
154			if (id)
155				store.select(id+"");
156			else
157				store.unselect(null);
158		});
159	},
160	getLastSelected: function () {
161		var last = gantt.$data.tasksStore.getSelectedId();
162		if (last && gantt.isTaskExists(last))
163			return last;
164		return null;
165	},
166	select: function (id, e) {
167		if (id && gantt.callEvent("onBeforeTaskMultiSelect", [id, true, e]) && gantt.callEvent("onBeforeTaskSelected", [id])) {
168			this._selected[id] = true;
169			this.setLastSelected(id);
170			this.afterSelect(id);
171			gantt.callEvent("onTaskMultiSelect", [id, true, e]);
172			gantt.callEvent("onTaskSelected", [id]);
173			return true;
174		}
175		return false;
176	},
177	toggle: function (id, e) {
178		if (this._selected[id]) {
179			this.unselect(id, e);
180		} else {
181			this.select(id, e);
182		}
183	},
184	unselect: function (id, e) {
185		if (id && gantt.callEvent("onBeforeTaskMultiSelect", [id, false, e])) {
186			this._selected[id] = false;
187			if (this.getLastSelected() == id)
188				this.setLastSelected(this.getDefaultSelected());
189			this.afterSelect(id);
190			gantt.callEvent("onTaskMultiSelect", [id, false, e]);
191			gantt.callEvent("onTaskUnselected", [id]);
192		}
193	},
194	isSelected: function (id) {
195		return !!(gantt.isTaskExists(id) && this._selected[id]);
196	},
197	getSelected: function () {
198		var res = [];
199		for (var i in this._selected) {
200			if (this._selected[i] && gantt.isTaskExists(i)) {
201				res.push(i);
202			} else {
203				this._selected[i] = false;
204			}
205		}
206		res.sort(function(a, b) {
207			return gantt.getGlobalTaskIndex(a) > gantt.getGlobalTaskIndex(b) ? 1 : -1;
208		});
209		return res;
210	},
211	forSelected: function (callback) {
212		var selected = this.getSelected();
213		for (var i = 0; i < selected.length; i++) {
214			callback(selected[i]);
215		}
216	},
217	isSameLevel: function(id) {
218		if (!this._one_level)
219			return true;
220		var last = this.getLastSelected();
221		if (!last)
222			return true;
223		if (!(gantt.isTaskExists(last) && gantt.isTaskExists(id)))
224			return true;
225		return !!(gantt.calculateTaskLevel(gantt.getTask(last)) == gantt.calculateTaskLevel(gantt.getTask(id)));
226	},
227	afterSelect: function(id) {
228		if (gantt.isTaskExists(id))
229			gantt.refreshTask(id);
230	},
231	doSelection: function(e) {
232		if (!this.isActive())
233			return false;
234
235		// deny selection when click on 'expand' or 'collapse' icons
236		if (gantt._is_icon_open_click(e))
237			return false;
238
239		var target_ev = gantt.locate(e);
240		if (!target_ev)
241			return false;
242
243		if (!gantt.callEvent("onBeforeMultiSelect", [e]))
244			return false;
245
246		var selected = this.getSelected();
247		var defaultLast = this.getFirstSelected();
248		var isLast = false;
249		var last = this.getLastSelected();
250
251		if (e.shiftKey) {
252			if (!gantt.isTaskExists(this.getFirstSelected()) || this.getFirstSelected() === null) {
253				this.setFirstSelected(target_ev);
254			}
255		} else if (e.ctrlKey || e.metaKey) {
256			if (!this.isSelected(target_ev))
257				this.setFirstSelected(target_ev);
258		} else {
259			this.setFirstSelected(target_ev);
260		}
261		if (e.ctrlKey || e.metaKey) {
262			if (target_ev) {
263				this.toggle(target_ev, e);
264			}
265		} else if (e.shiftKey && selected.length) {
266			if (!last)
267				last = target_ev;
268			else if (target_ev) {
269				var first_indx = gantt.getGlobalTaskIndex(this.getFirstSelected());
270				var target_indx = gantt.getGlobalTaskIndex(target_ev);
271				var last_indx = gantt.getGlobalTaskIndex(last);
272
273				// clear prev selection
274				var tmp = last;
275				while (gantt.getGlobalTaskIndex(tmp) !== first_indx) {
276					this.unselect(tmp, e);
277					tmp = (first_indx > last_indx) ? gantt.getNext(tmp) : gantt.getPrev(tmp);
278				}
279				tmp = target_ev;
280				while (gantt.getGlobalTaskIndex(tmp) !== first_indx) {
281					if (this.select(tmp, e) && !isLast) {
282						isLast = true;
283						defaultLast = tmp;
284					}
285					tmp = (first_indx > target_indx) ? gantt.getNext(tmp) : gantt.getPrev(tmp);
286				}
287			}
288		} else { // no key press when mouse click
289			if (!this.isSelected(target_ev)) {
290				this.select(target_ev, e);
291			}
292			selected = this.getSelected();
293			for (var i=0; i<selected.length; i++) {
294				if (selected[i] !== target_ev) {
295					this.unselect(selected[i], e);
296				}
297			}
298		}
299
300		if (this.isSelected(target_ev)) {
301			this.setLastSelected(target_ev);
302		} else if (defaultLast) {
303			if (target_ev == last)
304				this.setLastSelected(e.shiftKey ? defaultLast : this.getDefaultSelected());
305		} else {
306			this.setLastSelected(null);
307		}
308
309		if (!this.getSelected().length)
310			this.setLastSelected(null);
311
312		if (!this.getLastSelected() || !this.isSelected(this.getFirstSelected()))
313			this.setFirstSelected(this.getLastSelected());
314
315		return true;
316	}
317};
318
319(function(){
320	var old_selectTask = gantt.selectTask;
321	gantt.selectTask = function(id) {
322		if (!id)
323			return false;
324		var multiselect = gantt._multiselect;
325		var res = id;
326		if (multiselect.isActive()) {
327			if (multiselect.select(id, null)) {
328				multiselect.setLastSelected(id);
329			}
330			multiselect.setFirstSelected(multiselect.getLastSelected());
331		} else {
332			res = old_selectTask.call(this, id);
333		}
334		return res;
335	};
336
337	var old_unselectTask = gantt.unselectTask;
338	gantt.unselectTask = function(id) {
339		var multiselect = gantt._multiselect;
340		var isActive = multiselect.isActive();
341		id = id || multiselect.getLastSelected();
342		if(id && isActive) {
343			multiselect.unselect(id, null);
344			if (id == multiselect.getLastSelected())
345				multiselect.setLastSelected(null);
346			gantt.refreshTask(id);
347			multiselect.setFirstSelected(multiselect.getLastSelected());
348		}
349		var res = id;
350		if (!isActive)
351			res = old_unselectTask.call(this, id);
352		return res;
353	};
354
355	gantt.toggleTaskSelection = function(id) {
356		var multiselect = gantt._multiselect;
357		if (id && multiselect.isActive()) {
358			multiselect.toggle(id);
359			multiselect.setFirstSelected(multiselect.getLastSelected());
360		}
361	};
362	gantt.getSelectedTasks = function() {
363		var multiselect = gantt._multiselect;
364		multiselect.isActive();
365		return multiselect.getSelected();
366	};
367	gantt.eachSelectedTask = function(callback){
368		return this._multiselect.forSelected(callback);
369	};
370	gantt.isSelectedTask = function(id){
371		return this._multiselect.isSelected(id);
372	};
373	gantt.getLastSelectedTask = function(){
374		return this._multiselect.getLastSelected();
375	};
376	gantt.attachEvent("onGanttReady", function(){
377		gantt.$data.tasksStore.isSelected = function(id){
378			return gantt._multiselect.isSelected(id);
379		};
380	});
381})();
382
383gantt.attachEvent("onTaskIdChange", function (id, new_id) {
384	var multiselect = gantt._multiselect;
385	if (!multiselect.isActive())
386		return true;
387	if (gantt.isSelectedTask(id)) {
388		multiselect.unselect(id, null);
389		multiselect.select(new_id, null);
390	}
391});
392
393gantt.attachEvent("onAfterTaskDelete", function (id, item) {
394	var multiselect = gantt._multiselect;
395	if (!multiselect.isActive())
396		return true;
397
398	if (multiselect._selected[id]) {
399		multiselect.unselect(id, null);
400		multiselect._selected[id] = false;
401		multiselect.setLastSelected(multiselect.getDefaultSelected());
402	}
403
404	multiselect.forSelected(function (task_id) {
405		if (!gantt.isTaskExists(task_id))
406			multiselect.unselect(task_id, null);
407	});
408});
409
410gantt.attachEvent("onBeforeTaskMultiSelect", function(id, state, e){
411	var multiselect = gantt._multiselect;
412	if (state && multiselect.isActive()) {
413		if (multiselect._one_level) {
414			return multiselect.isSameLevel(id);
415		}
416	}
417	return true;
418});
419
420gantt.attachEvent("onTaskClick", function(id, e) {
421	if (gantt._multiselect.doSelection(e))
422		gantt.callEvent("onMultiSelect", [e]);
423	return true;
424});
425
426/***/ })
427
428/******/ });
429});