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_keyboard_navigation", [], factory); 18 else if(typeof exports === 'object') 19 exports["ext/dhtmlxgantt_keyboard_navigation"] = factory(); 20 else 21 root["ext/dhtmlxgantt_keyboard_navigation"] = 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/keyboard_navigation.js"); 107/******/ }) 108/************************************************************************/ 109/******/ ({ 110 111/***/ "./sources/ext/keyboard_navigation.js": 112/*!********************************************!*\ 113 !*** ./sources/ext/keyboard_navigation.js ***! 114 \********************************************/ 115/*! no static exports found */ 116/***/ (function(module, exports, __webpack_require__) { 117 118(function(){ 119 var eventable = __webpack_require__(/*! ../utils/eventable */ "./sources/utils/eventable.js"); 120 function setupKeyNav(gantt){ 121 gantt.config.keyboard_navigation = true; 122 gantt.config.keyboard_navigation_cells = false; 123 124 gantt.$keyboardNavigation = {}; 125 126 gantt._compose = function(){ 127 var parts = Array.prototype.slice.call(arguments, 0); 128 var res = {}; 129 for(var i = 0; i < parts.length; i++){ 130 var obj = parts[i]; 131 if(typeof obj == "function"){ 132 obj = new obj(); 133 } 134 135 for(var p in obj){ 136 res[p] = obj[p]; 137 } 138 } 139 return res; 140 }; 141 142 __webpack_require__ (/*! ./keyboard_navigation/common/keyboard_shortcuts */ "./sources/ext/keyboard_navigation/common/keyboard_shortcuts.js")(gantt); 143 __webpack_require__ (/*! ./keyboard_navigation/common/eventhandler */ "./sources/ext/keyboard_navigation/common/eventhandler.js")(gantt); 144 __webpack_require__ (/*! ./keyboard_navigation/common/trap_modal_focus */ "./sources/ext/keyboard_navigation/common/trap_modal_focus.js")(gantt); 145 __webpack_require__ (/*! ./keyboard_navigation/elements/gantt_node */ "./sources/ext/keyboard_navigation/elements/gantt_node.js")(gantt); 146 __webpack_require__ (/*! ./keyboard_navigation/elements/nav_node */ "./sources/ext/keyboard_navigation/elements/nav_node.js")(gantt); 147 __webpack_require__ (/*! ./keyboard_navigation/elements/header_cell */ "./sources/ext/keyboard_navigation/elements/header_cell.js")(gantt); 148 __webpack_require__ (/*! ./keyboard_navigation/elements/task_row */ "./sources/ext/keyboard_navigation/elements/task_row.js")(gantt); 149 __webpack_require__ (/*! ./keyboard_navigation/elements/task_cell */ "./sources/ext/keyboard_navigation/elements/task_cell.js")(gantt); 150 __webpack_require__ (/*! ./keyboard_navigation/modals */ "./sources/ext/keyboard_navigation/modals.js")(gantt); 151 __webpack_require__ (/*! ./keyboard_navigation/core */ "./sources/ext/keyboard_navigation/core.js")(gantt); 152 153 var domHelpers = __webpack_require__(/*! ../utils/dom_helpers */ "./sources/utils/dom_helpers.js"); 154 155 (function(){ 156 var dispatcher = gantt.$keyboardNavigation.dispatcher; 157 158 dispatcher.isTaskFocused = function(id){ 159 var node = dispatcher.activeNode; 160 if(node instanceof gantt.$keyboardNavigation.TaskRow || node instanceof gantt.$keyboardNavigation.TaskCell) { 161 if (node.taskId == id) { 162 return true; 163 } 164 } 165 return false; 166 }; 167 168 var keyDownHandler = function(e){ 169 if(!gantt.config.keyboard_navigation) return; 170 171 return dispatcher.keyDownHandler(e); 172 }; 173 174 var focusHandler = function(e){ 175 if(dispatcher.$preventDefault){ 176 e.preventDefault(); 177 gantt.$container.blur(); 178 return false; 179 // do nothing if key-nav focus is already planned 180 } else if (!dispatcher.awaitsFocus()) { 181 // otherwise - re-focus key-nav element on gantt focus 182 dispatcher.focusGlobalNode(); 183 } 184 185 }; 186 187 var reFocusActiveNode = function(){ 188 if(!dispatcher.isEnabled()) 189 return; 190 191 var activeNode = dispatcher.getActiveNode(); 192 if(!activeNode) 193 return; 194 195 var domElement = activeNode.getNode(); 196 var top, left; 197 if(domElement && domElement.parentNode){ 198 top = domElement.parentNode.scrollTop; 199 left = domElement.parentNode.scrollLeft; 200 201 } 202 203 activeNode.focus(true); 204 205 if(domElement && domElement.parentNode){ 206 domElement.parentNode.scrollTop = top; 207 domElement.parentNode.scrollLeft = left; 208 } 209 }; 210 211 212 gantt.attachEvent("onDataRender", function(){ 213 if(!gantt.config.keyboard_navigation) return; 214 reFocusActiveNode(); 215 }); 216 217 gantt.attachEvent("onGanttRender", function(){ 218 gantt.eventRemove(document, "keydown", keyDownHandler); 219 gantt.eventRemove(gantt.$container, "focus", focusHandler); 220 gantt.eventRemove(gantt.$container, "mousedown", mousedownHandler); 221 222 if(gantt.config.keyboard_navigation){ 223 224 gantt.event(document, "keydown", keyDownHandler); 225 gantt.event(gantt.$container, "focus", focusHandler); 226 gantt.event(gantt.$container, "mousedown", mousedownHandler); 227 gantt.$container.setAttribute("tabindex", "0"); 228 229 }else{ 230 gantt.$container.removeAttribute("tabindex"); 231 } 232 }); 233 234 function getTaskNodeConstructor(){ 235 if (gantt.config.keyboard_navigation_cells) { 236 return gantt.$keyboardNavigation.TaskCell; 237 } else { 238 return gantt.$keyboardNavigation.TaskRow; 239 } 240 } 241 242 function mousedownHandler(e){ 243 if(!gantt.config.keyboard_navigation) return true; 244 245 var focusNode; 246 var locateTask = dispatcher.fromDomElement(e); 247 if(locateTask){ 248 //var node = getTaskNodeConstructor(); 249 if(dispatcher.activeNode instanceof gantt.$keyboardNavigation.TaskCell && domHelpers.isChildOf(e.target, gantt.$task)){ 250 locateTask = new gantt.$keyboardNavigation.TaskCell(locateTask.taskId, dispatcher.activeNode.columnIndex); 251 } 252 focusNode = locateTask; 253 } 254 if (focusNode) { 255 if (!dispatcher.isEnabled()) { 256 dispatcher.activeNode = focusNode; 257 } else { 258 dispatcher.delay(function () { 259 dispatcher.setActiveNode(focusNode); 260 }); 261 } 262 } else { 263 // empty click should drop focus from gantt, insert of reselecting default node 264 dispatcher.$preventDefault = true; 265 setTimeout(function(){ 266 dispatcher.$preventDefault = false; 267 }, 300); 268 } 269 } 270 271 var onReady = gantt.attachEvent("onGanttReady", function(){ 272 // restore focus on repainted tasks 273 gantt.detachEvent(onReady); 274 275 gantt.$data.tasksStore.attachEvent("onStoreUpdated", function(id){ 276 if (gantt.config.keyboard_navigation && dispatcher.isEnabled()) { 277 var currentNode = dispatcher.getActiveNode(); 278 if(currentNode && currentNode.taskId == id){ 279 reFocusActiveNode(); 280 } 281 } 282 }); 283 284 if(gantt._smart_render){ 285 var updateRender = gantt._smart_render._redrawTasks; 286 gantt._smart_render._redrawTasks = function(renderers, items){ 287 if(gantt.config.keyboard_navigation && dispatcher.isEnabled()){ 288 var currentNode = dispatcher.getActiveNode(); 289 if(currentNode && currentNode.taskId !== undefined){ 290 var focusedItemVisible = false; 291 for(var i = 0; i < items.length; i++){ 292 if(items[i].id == currentNode.taskId && items[i].start_date){ 293 focusedItemVisible = true; 294 break; 295 } 296 } 297 if(!focusedItemVisible){ 298 items.push(gantt.getTask(currentNode.taskId)); 299 } 300 } 301 } 302 var res = updateRender.apply(this, arguments); 303 304 return res; 305 }; 306 } 307 }); 308 309 310 311 gantt.attachEvent("onAfterTaskAdd", function(id,item){ 312 if(!gantt.config.keyboard_navigation) return true; 313 if(dispatcher.isEnabled()){ 314 315 var columnIndex = 0; 316 var node = dispatcher.activeNode; 317 if(node instanceof gantt.$keyboardNavigation.TaskCell){ 318 columnIndex = node.columnIndex; 319 } 320 var nodeConstructor = getTaskNodeConstructor(); 321 322 dispatcher.setActiveNode(new nodeConstructor(id, columnIndex)); 323 324 325 } 326 }); 327 328 gantt.attachEvent("onTaskIdChange", function(oldId, newId){ 329 if(!gantt.config.keyboard_navigation) return true; 330 331 var node = dispatcher.activeNode; 332 if(dispatcher.isTaskFocused(oldId)){ 333 node.taskId = newId; 334 } 335 336 return true; 337 }); 338 339 function getActiveNode(){ 340 341 var activeElement = document.activeElement; 342 if(activeElement === document.body && document.getSelection){ 343 activeElement = document.getSelection().focusNode || document.body; 344 } 345 346 return activeElement; 347 } 348 349 var interval = setInterval(function(){ 350 if(!gantt.config.keyboard_navigation) return; 351 352 var enable; 353 var focusElement = getActiveNode(); 354 355 var parent = gantt.$container; 356 // halt key nav when focus is outside gantt or in quick info popup 357 if(!focusElement || gantt._locate_css(focusElement, "gantt_cal_quick_info")){ 358 enable = false; 359 }else{ 360 while(focusElement != parent && focusElement){ 361 focusElement = focusElement.parentNode; 362 } 363 364 if(focusElement == parent){ 365 enable = true; 366 }else{ 367 enable = false; 368 } 369 } 370 371 if(enable && !dispatcher.isEnabled()){ 372 dispatcher.enable(); 373 }else if(!enable && dispatcher.isEnabled()){ 374 dispatcher.disable(); 375 } 376 377 }, 500); 378 379 gantt.attachEvent("onDestroy", function(){ 380 clearInterval(interval); 381 }); 382 383 function getScopeName(obj){ 384 if(obj instanceof gantt.$keyboardNavigation.GanttNode){ 385 return "gantt"; 386 }else if(obj instanceof gantt.$keyboardNavigation.HeaderCell){ 387 return "headerCell"; 388 }else if(obj instanceof gantt.$keyboardNavigation.TaskRow){ 389 return "taskRow"; 390 }else if(obj instanceof gantt.$keyboardNavigation.TaskCell){ 391 return "taskCell"; 392 } 393 return null; 394 } 395 396 function getScope(mode){ 397 var scopes = { 398 "gantt":gantt.$keyboardNavigation.GanttNode, 399 "headerCell": gantt.$keyboardNavigation.HeaderCell, 400 "taskRow": gantt.$keyboardNavigation.TaskRow, 401 "taskCell": gantt.$keyboardNavigation.TaskCell 402 }; 403 404 return scopes[mode] || scopes.gantt; 405 } 406 407 function findVisibleColumnIndex(columnName) { 408 var columns = gantt.getGridColumns(); 409 for (var i = 0; i < columns.length; i++){ 410 if(columns[i].name == columnName){ 411 return i; 412 } 413 } 414 return 0; 415 } 416 417 var keyNavFacade = {}; 418 eventable(keyNavFacade); 419 gantt.mixin(keyNavFacade, { 420 addShortcut: function(shortcut, handler, scope){ 421 var scopeObject = getScope(scope); 422 if(scopeObject){ 423 scopeObject.prototype.bind(shortcut, handler); 424 } 425 }, 426 getShortcutHandler: function(shortcut, scope){ 427 var commands = gantt.$keyboardNavigation.shortcuts.parse(shortcut); 428 if(commands.length){ 429 return this.getCommandHandler(commands[0], scope); 430 } 431 }, 432 getCommandHandler: function(command, scope){ 433 var scopeObject = getScope(scope); 434 if(scopeObject){ 435 if(command){ 436 return scopeObject.prototype.findHandler(command); 437 } 438 } 439 }, 440 removeShortcut: function(shortcut, scope){ 441 var scopeObject = getScope(scope); 442 if(scopeObject){ 443 scopeObject.prototype.unbind(shortcut); 444 } 445 }, 446 focus: function(config){ 447 var type = config ? config.type : null; 448 var constructor = getScope(type); 449 var node; 450 switch (type){ 451 case "taskCell": 452 node = new constructor(config.id, findVisibleColumnIndex(config.column)); 453 break; 454 case "taskRow": 455 node = new constructor(config.id); 456 break; 457 case "headerCell": 458 node = new constructor(findVisibleColumnIndex(config.column)); 459 break; 460 default: 461 462 break; 463 } 464 dispatcher.delay(function(){ 465 if(node){ 466 dispatcher.setActiveNode(node); 467 }else{ 468 dispatcher.enable(); 469 if(!dispatcher.getActiveNode()){ 470 471 dispatcher.setDefaultNode(); 472 }else{ 473 474 if(!dispatcher.awaitsFocus()){ 475 dispatcher.enable(); 476 } 477 478 } 479 } 480 481 }); 482 }, 483 484 getActiveNode: function(){ 485 if(dispatcher.isEnabled()){ 486 var node = dispatcher.getActiveNode(); 487 var scope = getScopeName(node); 488 var columns = gantt.getGridColumns(); 489 switch (scope){ 490 case "taskCell": 491 return {type:"taskCell", id:node.taskId, column:columns[node.columnIndex].name}; 492 case "taskRow": 493 return {type:"taskRow", id:node.taskId}; 494 case "headerCell": 495 return {type:"headerCell", column:columns[node.index].name}; 496 } 497 } 498 return null; 499 } 500 }); 501 502 gantt.$keyboardNavigation.facade = keyNavFacade; 503 504 gantt.ext.keyboardNavigation = keyNavFacade; 505 gantt.focus = function(){ 506 keyNavFacade.focus(); 507 }; 508 gantt.addShortcut = keyNavFacade.addShortcut; 509 gantt.getShortcutHandler = keyNavFacade.getShortcutHandler; 510 gantt.removeShortcut = keyNavFacade.removeShortcut; 511 })(); 512 513 514 } 515 516 setupKeyNav(gantt); 517 518 519 520})(); 521 522/***/ }), 523 524/***/ "./sources/ext/keyboard_navigation/common/eventhandler.js": 525/*!****************************************************************!*\ 526 !*** ./sources/ext/keyboard_navigation/common/eventhandler.js ***! 527 \****************************************************************/ 528/*! no static exports found */ 529/***/ (function(module, exports) { 530 531module.exports = function(gantt) { 532 533 gantt.$keyboardNavigation.EventHandler = { 534 _handlers: null, 535 findHandler: function (command) { 536 if (!this._handlers) this._handlers = {}; 537 var shortcuts = gantt.$keyboardNavigation.shortcuts; 538 var hash = shortcuts.getHash(command); 539 540 return this._handlers[hash]; 541 }, 542 543 doAction: function (command, e) { 544 var handler = this.findHandler(command); 545 if (handler) { 546 var eventFacade = gantt.$keyboardNavigation.facade; 547 548 if(eventFacade.callEvent("onBeforeAction", [command, e]) === false){ 549 return; 550 } 551 552 handler.call(this, e); 553 554 if (e.preventDefault) e.preventDefault(); 555 else e.returnValue = false; 556 557 } 558 }, 559 bind: function (shortcut, handler) { 560 if (!this._handlers) this._handlers = {}; 561 562 var shortcuts = gantt.$keyboardNavigation.shortcuts; 563 564 var commands = shortcuts.parse(shortcut); 565 for (var i = 0; i < commands.length; i++) { 566 this._handlers[shortcuts.getHash(commands[i])] = handler; 567 } 568 }, 569 unbind: function (shortcut) { 570 var shortcuts = gantt.$keyboardNavigation.shortcuts; 571 572 var commands = shortcuts.parse(shortcut); 573 for (var i = 0; i < commands.length; i++) { 574 if (this._handlers[shortcuts.getHash(commands[i])]) { 575 delete this._handlers[shortcuts.getHash(commands[i])]; 576 } 577 } 578 }, 579 580 bindAll: function (map) { 581 for (var i in map) { 582 this.bind(i, map[i]); 583 } 584 }, 585 initKeys: function () { 586 if (!this._handlers) 587 this._handlers = {}; 588 if (this.keys) { 589 this.bindAll(this.keys); 590 } 591 } 592 }; 593 594}; 595 596/***/ }), 597 598/***/ "./sources/ext/keyboard_navigation/common/keyboard_shortcuts.js": 599/*!**********************************************************************!*\ 600 !*** ./sources/ext/keyboard_navigation/common/keyboard_shortcuts.js ***! 601 \**********************************************************************/ 602/*! no static exports found */ 603/***/ (function(module, exports) { 604 605module.exports = function(gantt) { 606 607 gantt.$keyboardNavigation.shortcuts = { 608 createCommand: function () { 609 return { 610 modifiers: { 611 "shift": false, 612 "alt": false, 613 "ctrl": false, 614 "meta": false 615 }, 616 keyCode: null 617 }; 618 }, 619 parse: function (shortcut) { 620 var commands = []; 621 622 var expr = this.getExpressions(this.trim(shortcut)); 623 for (var i = 0; i < expr.length; i++) { 624 var words = this.getWords(expr[i]); 625 626 var command = this.createCommand(); 627 628 for (var j = 0; j < words.length; j++) { 629 if (this.commandKeys[words[j]]) { 630 command.modifiers[words[j]] = true; 631 } else if (this.specialKeys[words[j]]) { 632 command.keyCode = this.specialKeys[words[j]]; 633 } else { 634 command.keyCode = words[j].charCodeAt(0); 635 } 636 } 637 638 commands.push(command); 639 } 640 return commands; 641 }, 642 643 getCommandFromEvent: function (domEvent) { 644 var command = this.createCommand(); 645 command.modifiers.shift = !!domEvent.shiftKey; 646 command.modifiers.alt = !!domEvent.altKey; 647 command.modifiers.ctrl = !!domEvent.ctrlKey; 648 command.modifiers.meta = !!domEvent.metaKey; 649 command.keyCode = domEvent.which || domEvent.keyCode; 650 651 if(command.keyCode >= 96 && command.keyCode <= 105){ 652 // numpad keys 96-105 -> 48-57 653 command.keyCode -= 48;//convert numpad number code to regular number code 654 } 655 656 var printableKey = String.fromCharCode(command.keyCode); 657 if (printableKey) { 658 command.keyCode = printableKey.toLowerCase().charCodeAt(0); 659 } 660 return command; 661 }, 662 663 getHashFromEvent: function (domEvent) { 664 return this.getHash(this.getCommandFromEvent(domEvent)); 665 }, 666 667 getHash: function (command) { 668 var parts = []; 669 for (var i in command.modifiers) { 670 if (command.modifiers[i]) { 671 parts.push(i); 672 } 673 } 674 parts.push(command.keyCode); 675 676 return parts.join(this.junctionChar); 677 }, 678 679 getExpressions: function (shortcut) { 680 return shortcut.split(this.junctionChar); 681 }, 682 getWords: function (term) { 683 return term.split(this.combinationChar); 684 }, 685 trim: function (shortcut) { 686 return shortcut.replace(/\s/g, ""); 687 }, 688 junctionChar: ",", 689 combinationChar: "+", 690 commandKeys: { 691 "shift": 16, 692 "alt": 18, 693 "ctrl": 17, 694 "meta": true 695 }, 696 specialKeys: { 697 "backspace": 8, 698 "tab": 9, 699 "enter": 13, 700 "esc": 27, 701 "space": 32, 702 "up": 38, 703 "down": 40, 704 "left": 37, 705 "right": 39, 706 "home": 36, 707 "end": 35, 708 "pageup": 33, 709 "pagedown": 34, 710 "delete": 46, 711 "insert": 45, 712 "plus": 107, 713 "f1": 112, 714 "f2": 113, 715 "f3": 114, 716 "f4": 115, 717 "f5": 116, 718 "f6": 117, 719 "f7": 118, 720 "f8": 119, 721 "f9": 120, 722 "f10": 121, 723 "f11": 122, 724 "f12": 123 725 } 726 }; 727}; 728 729/***/ }), 730 731/***/ "./sources/ext/keyboard_navigation/common/trap_modal_focus.js": 732/*!********************************************************************!*\ 733 !*** ./sources/ext/keyboard_navigation/common/trap_modal_focus.js ***! 734 \********************************************************************/ 735/*! no static exports found */ 736/***/ (function(module, exports, __webpack_require__) { 737 738module.exports = function(gantt) { 739 740 (function () { 741 var domHelpers = __webpack_require__(/*! ../../../utils/dom_helpers */ "./sources/utils/dom_helpers.js"); 742 gantt.$keyboardNavigation.getFocusableNodes = domHelpers.getFocusableNodes; 743 744 gantt.$keyboardNavigation.trapFocus = function trapFocus(root, e) { 745 if (e.keyCode != 9) return false; 746 747 var focusable = gantt.$keyboardNavigation.getFocusableNodes(root); 748 var currentFocus = document.activeElement; 749 var currentIndex = -1; 750 for (var i = 0; i < focusable.length; i++) { 751 if (focusable[i] == currentFocus) { 752 currentIndex = i; 753 break; 754 } 755 } 756 757 if (e.shiftKey) { 758 // back tab 759 if (currentIndex <= 0) { 760 // go to the last element if we focused on the first 761 var lastItem = focusable[focusable.length - 1]; 762 if (lastItem) { 763 lastItem.focus(); 764 e.preventDefault(); 765 return true; 766 } 767 } 768 769 } else { 770 // forward tab 771 if (currentIndex >= focusable.length - 1) { 772 // forward tab from last element should go back to the first element 773 var firstItem = focusable[0]; 774 if (firstItem) { 775 firstItem.focus(); 776 e.preventDefault(); 777 return true; 778 } 779 } 780 } 781 782 return false; 783 }; 784 })(); 785 786}; 787 788/***/ }), 789 790/***/ "./sources/ext/keyboard_navigation/core.js": 791/*!*************************************************!*\ 792 !*** ./sources/ext/keyboard_navigation/core.js ***! 793 \*************************************************/ 794/*! no static exports found */ 795/***/ (function(module, exports) { 796 797module.exports = function(gantt) { 798 799 gantt.$keyboardNavigation.dispatcher = { 800 isActive: false, 801 activeNode: null, 802 globalNode: new gantt.$keyboardNavigation.GanttNode(), 803 804 enable: function () { 805 this.isActive = true; 806 this.globalNode.enable(); 807 this.setActiveNode(this.getActiveNode()); 808 }, 809 810 disable: function () { 811 this.isActive = false; 812 this.globalNode.disable(); 813 }, 814 815 isEnabled: function () { 816 return !!this.isActive; 817 }, 818 819 getDefaultNode: function () { 820 var node; 821 if (gantt.config.keyboard_navigation_cells) { 822 node = new gantt.$keyboardNavigation.TaskCell(); 823 } else { 824 node = new gantt.$keyboardNavigation.TaskRow(); 825 } 826 827 if (!node.isValid()) { 828 node = node.fallback(); 829 } 830 return node; 831 }, 832 833 setDefaultNode: function () { 834 this.setActiveNode(this.getDefaultNode()); 835 }, 836 837 getActiveNode: function () { 838 var node = this.activeNode; 839 if (node && !node.isValid()) { 840 node = node.fallback(); 841 } 842 return node; 843 }, 844 845 fromDomElement: function(e){ 846 var inputs = [ 847 gantt.$keyboardNavigation.TaskRow, 848 gantt.$keyboardNavigation.TaskCell, 849 gantt.$keyboardNavigation.HeaderCell 850 ]; 851 for(var i = 0; i < inputs.length; i++){ 852 if(inputs[i].prototype.fromDomElement){ 853 var node = inputs[i].prototype.fromDomElement(e); 854 if(node) return node; 855 } 856 } 857 return null; 858 }, 859 860 focusGlobalNode: function () { 861 this.blurNode(this.globalNode); 862 this.focusNode(this.globalNode); 863 }, 864 865 setActiveNode: function (el) { 866 //console.trace() 867 var focusChanged = true; 868 if (this.activeNode) { 869 if (this.activeNode.compareTo(el)) { 870 focusChanged = false; 871 } 872 } 873 if (this.isEnabled()) { 874 if(focusChanged) 875 this.blurNode(this.activeNode); 876 877 this.activeNode = el; 878 this.focusNode(this.activeNode, !focusChanged); 879 } 880 }, 881 882 focusNode: function (el, keptFocus) { 883 if (el && el.focus) { 884 el.focus(keptFocus); 885 } 886 }, 887 blurNode: function (el) { 888 if (el && el.blur) { 889 el.blur(); 890 } 891 }, 892 893 keyDownHandler: function (e) { 894 895 if (gantt.$keyboardNavigation.isModal()) 896 return; 897 898 if (!this.isEnabled()) 899 return; 900 901 e = e || window.event; 902 903 904 if(e.defaultPrevented){ 905 return; 906 } 907 908 var ganttNode = this.globalNode; 909 910 var command = gantt.$keyboardNavigation.shortcuts.getCommandFromEvent(e); 911 912 var activeElement = this.getActiveNode(); 913 var eventFacade = gantt.$keyboardNavigation.facade; 914 if(eventFacade.callEvent("onKeyDown", [command, e]) === false){ 915 return; 916 } 917 918 if (!activeElement) { 919 this.setDefaultNode(); 920 } else if (activeElement.findHandler(command)) { 921 activeElement.doAction(command, e); 922 } else if (ganttNode.findHandler(command)) { 923 ganttNode.doAction(command, e); 924 } 925 926 }, 927 _timeout: null, 928 awaitsFocus: function(){ 929 return this._timeout !== null; 930 }, 931 delay: function(callback, delay){ 932 933 clearTimeout(this._timeout); 934 this._timeout = setTimeout(gantt.bind(function(){ 935 this._timeout = null; 936 callback(); 937 }, this) , delay || 1); 938 939 }, 940 clearDelay: function(){ 941 clearTimeout(this._timeout); 942 } 943 }; 944 945}; 946 947/***/ }), 948 949/***/ "./sources/ext/keyboard_navigation/elements/gantt_node.js": 950/*!****************************************************************!*\ 951 !*** ./sources/ext/keyboard_navigation/elements/gantt_node.js ***! 952 \****************************************************************/ 953/*! no static exports found */ 954/***/ (function(module, exports) { 955 956module.exports = function(gantt) { 957 958 gantt.$keyboardNavigation.GanttNode = function () { 959 }; 960 961 gantt.$keyboardNavigation.GanttNode.prototype = gantt._compose( 962 gantt.$keyboardNavigation.EventHandler, 963 { 964 965 focus: function () { 966 gantt.focus(); 967 }, 968 969 blur: function () { 970 971 }, 972 973 disable: function () { 974 gantt.$container.setAttribute("tabindex", "0"); 975 }, 976 enable: function () { 977 if (gantt.$container) 978 gantt.$container.removeAttribute("tabindex"); 979 }, 980 isEnabled: function () { 981 return gantt.$container.hasAttribute("tabindex"); 982 }, 983 984 scrollHorizontal: function scrollHorizontal(dir) { 985 var date = gantt.dateFromPos(gantt.getScrollState().x); 986 var scale = gantt.getScale(); 987 var step = dir < 0 ? -scale.step : scale.step; 988 date = gantt.date.add(date, step, scale.unit); 989 gantt.scrollTo(gantt.posFromDate(date)); 990 }, 991 992 scrollVertical: function scrollVertical(dir) { 993 var top = gantt.getScrollState().y; 994 var step = gantt.config.row_height; 995 gantt.scrollTo(null, top + (dir < 0 ? -1 : 1) * step); 996 }, 997 998 keys: { 999 "alt+left": function (e) { 1000 this.scrollHorizontal(-1); 1001 }, 1002 "alt+right": function (e) { 1003 this.scrollHorizontal(1); 1004 }, 1005 "alt+up": function (e) { 1006 this.scrollVertical(-1); 1007 }, 1008 "alt+down": function (e) { 1009 this.scrollVertical(1); 1010 }, 1011 1012 // undo 1013 "ctrl+z": function () { 1014 if (gantt.undo) gantt.undo(); 1015 }, 1016 1017 // redo 1018 "ctrl+r": function () { 1019 if (gantt.redo) gantt.redo(); 1020 } 1021 } 1022 } 1023 ); 1024 1025 gantt.$keyboardNavigation.GanttNode.prototype.bindAll(gantt.$keyboardNavigation.GanttNode.prototype.keys); 1026 1027}; 1028 1029/***/ }), 1030 1031/***/ "./sources/ext/keyboard_navigation/elements/header_cell.js": 1032/*!*****************************************************************!*\ 1033 !*** ./sources/ext/keyboard_navigation/elements/header_cell.js ***! 1034 \*****************************************************************/ 1035/*! no static exports found */ 1036/***/ (function(module, exports, __webpack_require__) { 1037 1038module.exports = function(gantt) { 1039 var domHelpers = __webpack_require__(/*! ../../../utils/dom_helpers */ "./sources/utils/dom_helpers.js"); 1040 1041 gantt.$keyboardNavigation.HeaderCell = function (index) { 1042 this.index = index || 0; 1043 }; 1044 1045 gantt.$keyboardNavigation.HeaderCell.prototype = gantt._compose( 1046 gantt.$keyboardNavigation.KeyNavNode, 1047 { 1048 _handlers: null, 1049 1050 isValid: function () { 1051 if (!gantt.config.show_grid) { 1052 if (gantt.getVisibleTaskCount()) 1053 return false; 1054 } 1055 return !!gantt.getGridColumns()[this.index] || !gantt.getVisibleTaskCount(); 1056 }, 1057 fallback: function () { 1058 if (!gantt.config.show_grid) { 1059 if (gantt.getVisibleTaskCount()) { 1060 return new gantt.$keyboardNavigation.TaskRow(); 1061 } 1062 return null; 1063 } 1064 var visibleColumns = gantt.getGridColumns(); 1065 var index = this.index; 1066 while (index >= 0) { 1067 if (visibleColumns[index]) 1068 break; 1069 index--; 1070 } 1071 if (visibleColumns[index]) { 1072 return new gantt.$keyboardNavigation.HeaderCell(index); 1073 } else { 1074 return null; 1075 } 1076 }, 1077 1078 fromDomElement: function(el){ 1079 var cellElement = domHelpers.locateClassName(el, "gantt_grid_head_cell"); 1080 if(cellElement){ 1081 var index = 0; 1082 while(cellElement && cellElement.previousSibling){ 1083 cellElement = cellElement.previousSibling; 1084 index += 1; 1085 } 1086 return new gantt.$keyboardNavigation.HeaderCell(index); 1087 }else{ 1088 return null; 1089 } 1090 }, 1091 1092 getNode: function () { 1093 var cells = gantt.$grid_scale.childNodes; 1094 return cells[this.index]; 1095 }, 1096 1097 1098 keys: { 1099 1100 "left": function () { 1101 if (this.index > 0) { 1102 this.moveTo(new gantt.$keyboardNavigation.HeaderCell(this.index - 1)); 1103 } 1104 }, 1105 "right": function () { 1106 var columns = gantt.getGridColumns(); 1107 if (this.index < columns.length - 1) { 1108 this.moveTo(new gantt.$keyboardNavigation.HeaderCell(this.index + 1)); 1109 } 1110 }, 1111 "down": function () { 1112 var taskRow; 1113 var rootLevel = gantt.getChildren(gantt.config.root_id); 1114 if (rootLevel[0]) { 1115 taskRow = rootLevel[0]; 1116 } 1117 if (taskRow) { 1118 if (gantt.config.keyboard_navigation_cells) { 1119 this.moveTo(new gantt.$keyboardNavigation.TaskCell(taskRow, this.index)); 1120 } else { 1121 this.moveTo(new gantt.$keyboardNavigation.TaskRow(taskRow)); 1122 } 1123 } 1124 }, 1125 1126 "end": function () { 1127 var columns = gantt.getGridColumns(); 1128 this.moveTo(new gantt.$keyboardNavigation.HeaderCell(columns.length - 1)); 1129 }, 1130 "home": function () { 1131 this.moveTo(new gantt.$keyboardNavigation.HeaderCell(0)); 1132 }, 1133 1134 1135 // press header button 1136 "enter, space": function () { 1137 var node = document.activeElement; 1138 node.click(); 1139 }, 1140 1141 // add new task 1142 "ctrl+enter": function () { 1143 if (gantt.isReadonly(this)) { 1144 return; 1145 } 1146 gantt.createTask({}, this.taskId); 1147 } 1148 } 1149 } 1150 ); 1151 1152 gantt.$keyboardNavigation.HeaderCell.prototype.bindAll(gantt.$keyboardNavigation.HeaderCell.prototype.keys); 1153 1154}; 1155 1156/***/ }), 1157 1158/***/ "./sources/ext/keyboard_navigation/elements/nav_node.js": 1159/*!**************************************************************!*\ 1160 !*** ./sources/ext/keyboard_navigation/elements/nav_node.js ***! 1161 \**************************************************************/ 1162/*! no static exports found */ 1163/***/ (function(module, exports) { 1164 1165module.exports = function(gantt) { 1166 1167 gantt.$keyboardNavigation.KeyNavNode = function () { 1168 }; 1169 1170 gantt.$keyboardNavigation.KeyNavNode.prototype = gantt._compose( 1171 gantt.$keyboardNavigation.EventHandler, 1172 { 1173 isValid: function () { 1174 return true; 1175 }, 1176 fallback: function () { 1177 return null; 1178 }, 1179 1180 moveTo: function (element) { 1181 gantt.$keyboardNavigation.dispatcher.setActiveNode(element); 1182 }, 1183 1184 compareTo: function (b) { 1185 // good enough comparison of two random objects 1186 if (!b) return false; 1187 for (var i in this) { 1188 if (!!this[i] != !!b[i]) return false; 1189 1190 var canStringifyThis = !!(this[i] && this[i].toString); 1191 var canStringifyThat = !!(b[i] && b[i].toString); 1192 if (canStringifyThat != canStringifyThis) return false; 1193 if (!(canStringifyThat && canStringifyThis)) { 1194 if (b[i] != this[i]) return false; 1195 } else { 1196 if (b[i].toString() != this[i].toString()) 1197 return false; 1198 } 1199 } 1200 return true; 1201 }, 1202 1203 getNode: function () { 1204 }, 1205 focus: function () { 1206 var node = this.getNode(); 1207 if(!node) 1208 return; 1209 1210 var eventFacade = gantt.$keyboardNavigation.facade; 1211 1212 if(eventFacade.callEvent("onBeforeFocus", [node]) === false){ 1213 return; 1214 } 1215 1216 if (node) { 1217 node.setAttribute("tabindex", "-1"); 1218 if(!node.$eventAttached){ 1219 node.$eventAttached = true; 1220 gantt.event(node, "focus",function(e){ 1221 e = e || event; 1222 e.preventDefault(); 1223 return false; 1224 }, false); 1225 } 1226 //node.className += " gantt_focused"; 1227 if (node.focus) node.focus(); 1228 1229 eventFacade.callEvent("onFocus", [this.getNode()]); 1230 } 1231 1232 }, 1233 blur: function () { 1234 var node = this.getNode(); 1235 if (node) { 1236 var eventFacade = gantt.$keyboardNavigation.facade; 1237 eventFacade.callEvent("onBlur", [node]); 1238 node.setAttribute("tabindex", "-1"); 1239 //node.className = (node.className || "").replace(/ ?gantt_focused/g, ""); 1240 } 1241 } 1242 } 1243 ); 1244 1245}; 1246 1247/***/ }), 1248 1249/***/ "./sources/ext/keyboard_navigation/elements/task_cell.js": 1250/*!***************************************************************!*\ 1251 !*** ./sources/ext/keyboard_navigation/elements/task_cell.js ***! 1252 \***************************************************************/ 1253/*! no static exports found */ 1254/***/ (function(module, exports, __webpack_require__) { 1255 1256module.exports = function(gantt) { 1257 var domHelpers = __webpack_require__(/*! ../../../utils/dom_helpers */ "./sources/utils/dom_helpers.js"); 1258 1259 gantt.$keyboardNavigation.TaskCell = function (taskId, index) { 1260 if (!taskId) { 1261 var rootLevel = gantt.getChildren(gantt.config.root_id); 1262 if (rootLevel[0]) { 1263 taskId = rootLevel[0]; 1264 } 1265 } 1266 this.taskId = taskId; 1267 this.columnIndex = index || 0; 1268 // provided task may not exist, in this case node will be detectes as invalid 1269 if (gantt.isTaskExists(this.taskId)) { 1270 this.index = gantt.getTaskIndex(this.taskId); 1271 } 1272 }; 1273 1274 gantt.$keyboardNavigation.TaskCell.prototype = gantt._compose( 1275 gantt.$keyboardNavigation.TaskRow, 1276 { 1277 _handlers: null, 1278 isValid: function () { 1279 1280 return gantt.$keyboardNavigation.TaskRow.prototype.isValid.call(this) && !!gantt.getGridColumns()[this.columnIndex]; 1281 }, 1282 fallback: function () { 1283 1284 var node = gantt.$keyboardNavigation.TaskRow.prototype.fallback.call(this); 1285 var result = node; 1286 if (node instanceof gantt.$keyboardNavigation.TaskRow) { 1287 var visibleColumns = gantt.getGridColumns(); 1288 var index = this.columnIndex; 1289 while (index >= 0) { 1290 if (visibleColumns[index]) 1291 break; 1292 index--; 1293 } 1294 if (visibleColumns[index]) { 1295 result = new gantt.$keyboardNavigation.TaskCell(node.taskId, index); 1296 } 1297 } 1298 1299 return result; 1300 }, 1301 1302 fromDomElement: function(el){ 1303 if(!gantt.config.keyboard_navigation_cells){ 1304 return null; 1305 } 1306 1307 var taskId = gantt.locate(el); 1308 if(gantt.isTaskExists(taskId)){ 1309 var index = 0; 1310 var cellElement = domHelpers.locateAttribute(el, "data-column-index"); 1311 1312 if(cellElement){ 1313 index = cellElement.getAttribute("data-column-index")*1; 1314 } 1315 1316 return new gantt.$keyboardNavigation.TaskCell(taskId, index); 1317 }else{ 1318 return null; 1319 } 1320 }, 1321 1322 getNode: function () { 1323 if (gantt.isTaskExists(this.taskId) && gantt.isTaskVisible(this.taskId)) { 1324 if (gantt.config.show_grid) { 1325 var row = gantt.$grid.querySelector(".gantt_row[" + gantt.config.task_attribute + "='" + this.taskId + "']"); 1326 if(!row) 1327 return null; 1328 return row.querySelector("[data-column-index='"+this.columnIndex+"']"); 1329 } else { 1330 return gantt.getTaskNode(this.taskId); 1331 } 1332 } 1333 }, 1334 1335 keys: { 1336 "up": function () { 1337 1338 var nextElement = null; 1339 var prevTask = gantt.getPrev(this.taskId); 1340 if (!prevTask) { 1341 nextElement = new gantt.$keyboardNavigation.HeaderCell(this.columnIndex); 1342 } else { 1343 nextElement = new gantt.$keyboardNavigation.TaskCell(prevTask, this.columnIndex); 1344 } 1345 this.moveTo(nextElement); 1346 }, 1347 "down": function () { 1348 var nextTask = gantt.getNext(this.taskId); 1349 if (nextTask) { 1350 this.moveTo(new gantt.$keyboardNavigation.TaskCell(nextTask, this.columnIndex)); 1351 } 1352 }, 1353 "left": function () { 1354 if (this.columnIndex > 0) { 1355 this.moveTo(new gantt.$keyboardNavigation.TaskCell(this.taskId, this.columnIndex - 1)); 1356 } 1357 }, 1358 "right": function () { 1359 var columns = gantt.getGridColumns(); 1360 if (this.columnIndex < columns.length - 1) { 1361 this.moveTo(new gantt.$keyboardNavigation.TaskCell(this.taskId, this.columnIndex + 1)); 1362 } 1363 }, 1364 1365 "end": function () { 1366 var columns = gantt.getGridColumns(); 1367 this.moveTo(new gantt.$keyboardNavigation.TaskCell(this.taskId, columns.length - 1)); 1368 }, 1369 "home": function () { 1370 this.moveTo(new gantt.$keyboardNavigation.TaskCell(this.taskId, 0)); 1371 }, 1372 "pagedown": function () { 1373 if (gantt.getVisibleTaskCount()) { 1374 this.moveTo(new gantt.$keyboardNavigation.TaskCell(gantt.getTaskByIndex(gantt.getVisibleTaskCount() - 1).id, this.columnIndex)); 1375 } 1376 }, 1377 "pageup": function () { 1378 if (gantt.getVisibleTaskCount()) { 1379 this.moveTo(new gantt.$keyboardNavigation.TaskCell(gantt.getTaskByIndex(0).id, this.columnIndex)); 1380 } 1381 } 1382 } 1383 } 1384 ); 1385 1386 1387 gantt.$keyboardNavigation.TaskCell.prototype.bindAll(gantt.$keyboardNavigation.TaskRow.prototype.keys); 1388 gantt.$keyboardNavigation.TaskCell.prototype.bindAll(gantt.$keyboardNavigation.TaskCell.prototype.keys); 1389 1390}; 1391 1392/***/ }), 1393 1394/***/ "./sources/ext/keyboard_navigation/elements/task_row.js": 1395/*!**************************************************************!*\ 1396 !*** ./sources/ext/keyboard_navigation/elements/task_row.js ***! 1397 \**************************************************************/ 1398/*! no static exports found */ 1399/***/ (function(module, exports) { 1400 1401module.exports = function(gantt) { 1402 1403 gantt.$keyboardNavigation.TaskRow = function (taskId) { 1404 if (!taskId) { 1405 var rootLevel = gantt.getChildren(gantt.config.root_id); 1406 if (rootLevel[0]) { 1407 taskId = rootLevel[0]; 1408 } 1409 } 1410 this.taskId = taskId; 1411 if (gantt.isTaskExists(this.taskId)) { 1412 this.index = gantt.getTaskIndex(this.taskId); 1413 } 1414 }; 1415 1416 gantt.$keyboardNavigation.TaskRow.prototype = gantt._compose( 1417 gantt.$keyboardNavigation.KeyNavNode, 1418 { 1419 _handlers: null, 1420 isValid: function () { 1421 return gantt.isTaskExists(this.taskId) && (gantt.getTaskIndex(this.taskId) > -1); 1422 }, 1423 fallback: function () { 1424 if (!gantt.getVisibleTaskCount()) { 1425 var header = new gantt.$keyboardNavigation.HeaderCell(); 1426 if (!header.isValid()) return null; 1427 else return header; 1428 } else { 1429 1430 var nextIndex = -1; 1431 if (gantt.getTaskByIndex(this.index - 1)) { 1432 nextIndex = this.index - 1; 1433 } else if (gantt.getTaskByIndex(this.index + 1)) { 1434 nextIndex = this.index + 1; 1435 } else { 1436 var index = this.index; 1437 while (index >= 0) { 1438 if (gantt.getTaskByIndex(index)) { 1439 nextIndex = index; 1440 break; 1441 } 1442 index--; 1443 } 1444 1445 } 1446 if (nextIndex > -1) { 1447 return new gantt.$keyboardNavigation.TaskRow(gantt.getTaskByIndex(nextIndex).id); 1448 } 1449 } 1450 }, 1451 1452 fromDomElement: function(el){ 1453 if(gantt.config.keyboard_navigation_cells){ 1454 return null; 1455 } 1456 1457 var taskId = gantt.locate(el); 1458 if(gantt.isTaskExists(taskId)){ 1459 return new gantt.$keyboardNavigation.TaskRow(taskId); 1460 }else{ 1461 return null; 1462 } 1463 }, 1464 1465 getNode: function () { 1466 if (gantt.isTaskExists(this.taskId) && gantt.isTaskVisible(this.taskId)) { 1467 if (gantt.config.show_grid) { 1468 return gantt.$grid.querySelector(".gantt_row[" + gantt.config.task_attribute + "='" + this.taskId + "']"); 1469 } else { 1470 return gantt.getTaskNode(this.taskId); 1471 } 1472 } 1473 }, 1474 1475 focus: function (keptFocus) { 1476 if(!keptFocus) { 1477 var pos = gantt.getTaskPosition(gantt.getTask(this.taskId)); 1478 var height = gantt.config.row_height; 1479 var scroll = gantt.getScrollState(); 1480 1481 var viewWidth; 1482 if(gantt.$task){ 1483 viewWidth = gantt.$task.offsetWidth; 1484 }else{ 1485 viewWidth = scroll.inner_width; 1486 } 1487 1488 var viewHeight; 1489 if(gantt.$grid_data || gantt.$task_data){ 1490 viewHeight = (gantt.$grid_data || gantt.$task_data).offsetHeight; 1491 }else{ 1492 viewHeight = scroll.inner_height; 1493 } 1494 1495 if (pos.top < scroll.y || pos.top + height > (scroll.y + viewHeight)) { 1496 1497 gantt.scrollTo(null, pos.top - height * 5); 1498 1499 } else if (gantt.config.show_chart && (pos.left < scroll.x || pos.left > (scroll.x + viewWidth))) { 1500 gantt.scrollTo(pos.left - gantt.config.task_scroll_offset); 1501 1502 } 1503 } 1504 1505 gantt.$keyboardNavigation.KeyNavNode.prototype.focus.apply(this, [keptFocus]); 1506 }, 1507 1508 keys: { 1509 "pagedown": function () { 1510 if (gantt.getVisibleTaskCount()) { 1511 this.moveTo(new gantt.$keyboardNavigation.TaskRow(gantt.getTaskByIndex(gantt.getVisibleTaskCount() - 1).id)); 1512 } 1513 }, 1514 "pageup": function () { 1515 if (gantt.getVisibleTaskCount()) { 1516 this.moveTo(new gantt.$keyboardNavigation.TaskRow(gantt.getTaskByIndex(0).id)); 1517 } 1518 }, 1519 "up": function () { 1520 var nextElement = null; 1521 var prevTask = gantt.getPrev(this.taskId); 1522 if (!prevTask) { 1523 nextElement = new gantt.$keyboardNavigation.HeaderCell(); 1524 } else { 1525 nextElement = new gantt.$keyboardNavigation.TaskRow(prevTask); 1526 } 1527 this.moveTo(nextElement); 1528 }, 1529 "down": function () { 1530 var nextTask = gantt.getNext(this.taskId); 1531 if (nextTask) { 1532 this.moveTo(new gantt.$keyboardNavigation.TaskRow(nextTask)); 1533 } 1534 }, 1535 1536 "shift+down": function(){ 1537 if(gantt.hasChild(this.taskId) && !gantt.getTask(this.taskId).$open){ 1538 gantt.open(this.taskId); 1539 } 1540 }, 1541 "shift+up": function(){ 1542 if(gantt.hasChild(this.taskId) && gantt.getTask(this.taskId).$open){ 1543 gantt.close(this.taskId); 1544 } 1545 }, 1546 "shift+right": function() { 1547 if (gantt.isReadonly(this)) { 1548 return; 1549 } 1550 var prevId = gantt.getPrevSibling(this.taskId); 1551 if(gantt.isTaskExists(prevId) && !gantt.isChildOf(this.taskId, prevId)){ 1552 var parent = gantt.getTask(prevId); 1553 parent.$open = true; 1554 var result = gantt.moveTask(this.taskId, -1, prevId); 1555 if(result !== false) 1556 gantt.updateTask(this.taskId); 1557 } 1558 }, 1559 "shift+left": function() { 1560 if (gantt.isReadonly(this)) { 1561 return; 1562 } 1563 var parent = gantt.getParent(this.taskId); 1564 if(gantt.isTaskExists(parent)){ 1565 var result = gantt.moveTask(this.taskId, gantt.getTaskIndex(parent) + 1, gantt.getParent(parent)); 1566 if(result !== false) 1567 gantt.updateTask(this.taskId); 1568 } 1569 }, 1570 1571 // select 1572 "space": function (e) { 1573 if (!gantt.isSelectedTask(this.taskId)) { 1574 gantt.selectTask(this.taskId); 1575 } else { 1576 gantt.unselectTask(this.taskId); 1577 } 1578 }, 1579 1580 // collapse 1581 "ctrl+left": function (e) { 1582 gantt.close(this.taskId); 1583 }, 1584 // expand 1585 "ctrl+right": function (e) { 1586 gantt.open(this.taskId); 1587 }, 1588 1589 // delete task 1590 "delete": function (e) { 1591 if (gantt.isReadonly(this)) { 1592 return; 1593 } 1594 gantt.$click.buttons["delete"](this.taskId); 1595 }, 1596 1597 // open lightbox 1598 "enter": function () { 1599 if (gantt.isReadonly(this)) { 1600 return; 1601 } 1602 gantt.showLightbox(this.taskId); 1603 }, 1604 1605 // add subtask 1606 "ctrl+enter": function () { 1607 if (gantt.isReadonly(this)) { 1608 return; 1609 } 1610 gantt.createTask({}, this.taskId); 1611 } 1612 } 1613 } 1614 ); 1615 gantt.$keyboardNavigation.TaskRow.prototype.bindAll(gantt.$keyboardNavigation.TaskRow.prototype.keys); 1616 1617}; 1618 1619/***/ }), 1620 1621/***/ "./sources/ext/keyboard_navigation/modals.js": 1622/*!***************************************************!*\ 1623 !*** ./sources/ext/keyboard_navigation/modals.js ***! 1624 \***************************************************/ 1625/*! no static exports found */ 1626/***/ (function(module, exports) { 1627 1628module.exports = function(gantt) { 1629 1630 (function () { 1631 var modalsStack = []; 1632 1633 function isModal() { 1634 return !!modalsStack.length; 1635 } 1636 1637 function afterPopup(box) { 1638 setTimeout(function () { 1639 if (!isModal()) 1640 gantt.focus(); 1641 }, 1); 1642 } 1643 1644 function startModal(box) { 1645 gantt.eventRemove(box, "keydown", trapFocus); 1646 gantt.event(box, "keydown", trapFocus); 1647 modalsStack.push(box); 1648 //gantt.$keyboardNavigation.dispatcher.disable(); 1649 } 1650 1651 function endModal() { 1652 var box = modalsStack.pop(); 1653 if (box) { 1654 gantt.eventRemove(box, "keydown", trapFocus); 1655 } 1656 afterPopup(box); 1657 1658 } 1659 1660 1661 function isTopModal(box) { 1662 return box == modalsStack[modalsStack.length - 1]; 1663 } 1664 1665 function trapFocus(event) { 1666 var event = event || window.event; 1667 var target = event.currentTarget; 1668 if (!isTopModal(target)) return; 1669 1670 gantt.$keyboardNavigation.trapFocus(target, event); 1671 } 1672 1673 function traceLightbox() { 1674 startModal(gantt.getLightbox()); 1675 } 1676 1677 gantt.attachEvent("onLightbox", traceLightbox); 1678 gantt.attachEvent("onAfterLightbox", endModal); 1679 gantt.attachEvent("onLightboxChange", function () { 1680 endModal(); 1681 traceLightbox(); 1682 }); 1683 1684 1685 gantt.attachEvent("onAfterQuickInfo", function () { 1686 afterPopup(); 1687 }); 1688 1689 gantt.attachEvent("onMessagePopup", function (box) { 1690 saveFocus(); 1691 startModal(box); 1692 }); 1693 gantt.attachEvent("onAfterMessagePopup", function () { 1694 endModal(); 1695 restoreFocus(); 1696 }); 1697 1698 var focusElement = null; 1699 1700 function saveFocus() { 1701 focusElement = document.activeElement; 1702 } 1703 1704 function restoreFocus() { 1705 setTimeout(function () { 1706 if (focusElement) { 1707 focusElement.focus(); 1708 focusElement = null; 1709 } 1710 }, 1); 1711 } 1712 1713 gantt.$keyboardNavigation.isModal = isModal; 1714 1715 1716 })(); 1717 1718}; 1719 1720/***/ }), 1721 1722/***/ "./sources/utils/dom_helpers.js": 1723/*!**************************************!*\ 1724 !*** ./sources/utils/dom_helpers.js ***! 1725 \**************************************/ 1726/*! no static exports found */ 1727/***/ (function(module, exports) { 1728 1729//returns position of html element on the page 1730function elementPosition(elem) { 1731 var top=0, left=0, right=0, bottom=0; 1732 if (elem.getBoundingClientRect) { //HTML5 method 1733 var box = elem.getBoundingClientRect(); 1734 var body = document.body; 1735 var docElem = (document.documentElement || 1736 document.body.parentNode || 1737 document.body); 1738 1739 var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop; 1740 var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft; 1741 var clientTop = docElem.clientTop || body.clientTop || 0; 1742 var clientLeft = docElem.clientLeft || body.clientLeft || 0; 1743 top = box.top + scrollTop - clientTop; 1744 left = box.left + scrollLeft - clientLeft; 1745 1746 right = document.body.offsetWidth - box.right; 1747 bottom = document.body.offsetHeight - box.bottom; 1748 } else { //fallback to naive approach 1749 while(elem) { 1750 top = top + parseInt(elem.offsetTop,10); 1751 left = left + parseInt(elem.offsetLeft,10); 1752 elem = elem.offsetParent; 1753 } 1754 1755 right = document.body.offsetWidth - elem.offsetWidth - left; 1756 bottom = document.body.offsetHeight - elem.offsetHeight - top; 1757 } 1758 return { y: Math.round(top), x: Math.round(left), width:elem.offsetWidth, height:elem.offsetHeight, right: Math.round(right), bottom: Math.round(bottom) }; 1759} 1760 1761function isVisible(node){ 1762 var display = false, 1763 visibility = false; 1764 if(window.getComputedStyle){ 1765 var style = window.getComputedStyle(node, null); 1766 display = style["display"]; 1767 visibility = style["visibility"]; 1768 }else if(node.currentStyle){ 1769 display = node.currentStyle["display"]; 1770 visibility = node.currentStyle["visibility"]; 1771 } 1772 return (display != "none" && visibility != "hidden"); 1773} 1774 1775function hasNonNegativeTabIndex(node){ 1776 return !isNaN(node.getAttribute("tabindex")) && (node.getAttribute("tabindex")*1 >= 0); 1777} 1778 1779function hasHref(node){ 1780 var canHaveHref = {"a": true, "area": true}; 1781 if(canHaveHref[node.nodeName.loLowerCase()]){ 1782 return !!node.getAttribute("href"); 1783 } 1784 return true; 1785} 1786 1787function isEnabled(node){ 1788 var canDisable = {"input":true, "select":true, "textarea":true, "button":true, "object":true}; 1789 if(canDisable[node.nodeName.toLowerCase()]){ 1790 return !node.hasAttribute("disabled"); 1791 } 1792 1793 return true; 1794} 1795 1796function getFocusableNodes(root){ 1797 var nodes = root.querySelectorAll([ 1798 "a[href]", 1799 "area[href]", 1800 "input", 1801 "select", 1802 "textarea", 1803 "button", 1804 "iframe", 1805 "object", 1806 "embed", 1807 "[tabindex]", 1808 "[contenteditable]" 1809 ].join(", ")); 1810 1811 var nodesArray = Array.prototype.slice.call(nodes, 0); 1812 for(var i = 0; i < nodesArray.length; i++){ 1813 var node = nodesArray[i]; 1814 var isValid = (hasNonNegativeTabIndex(node) || isEnabled(node) || hasHref(node)) && isVisible(node); 1815 if(!isValid){ 1816 nodesArray.splice(i, 1); 1817 i--; 1818 } 1819 } 1820 return nodesArray; 1821} 1822 1823function getScrollSize(){ 1824 var div = document.createElement("div"); 1825 div.style.cssText="visibility:hidden;position:absolute;left:-1000px;width:100px;padding:0px;margin:0px;height:110px;min-height:100px;overflow-y:scroll;"; 1826 1827 document.body.appendChild(div); 1828 var width = div.offsetWidth-div.clientWidth; 1829 document.body.removeChild(div); 1830 1831 return width; 1832} 1833 1834function getClassName(node){ 1835 if(!node) return ""; 1836 1837 var className = node.className || ""; 1838 if(className.baseVal)//'className' exist but not a string - IE svg element in DOM 1839 className = className.baseVal; 1840 1841 if(!className.indexOf) 1842 className = ""; 1843 1844 return _trimString(className); 1845} 1846 1847function addClassName(node, className){ 1848 if (className && node.className.indexOf(className) === -1) { 1849 node.className += " " + className; 1850 } 1851} 1852 1853function removeClassName(node, name) { 1854 name = name.split(" "); 1855 for (var i = 0; i < name.length; i++) { 1856 var regEx = new RegExp("\\s?\\b" + name[i] + "\\b(?![-_.])", ""); 1857 node.className = node.className.replace(regEx, ""); 1858 } 1859} 1860 1861function hasClass(element, className){ 1862 if ('classList' in element) { 1863 return element.classList.contains(className); 1864 } else { 1865 return new RegExp("\\b" + className + "\\b").test(element.className); 1866 } 1867} 1868 1869function toNode(node) { 1870 if (typeof node === "string") { 1871 return (document.getElementById(node) || document.querySelector(node) || document.body); 1872 } 1873 return node || document.body; 1874} 1875 1876var _slave = document.createElement("div"); 1877function insert(node, newone) { 1878 _slave.innerHTML = newone; 1879 var child = _slave.firstChild; 1880 node.appendChild(child); 1881 return child; 1882} 1883 1884function remove(node) { 1885 if (node && node.parentNode) { 1886 node.parentNode.removeChild(node); 1887 } 1888} 1889 1890function getChildren(node, css) { 1891 var ch = node.childNodes; 1892 var len = ch.length; 1893 var out = []; 1894 for (var i = 0; i < len; i++) { 1895 var obj = ch[i]; 1896 if (obj.className && obj.className.indexOf(css) !== -1) { 1897 out.push(obj); 1898 } 1899 } 1900 return out; 1901} 1902 1903function getTargetNode(e){ 1904 var trg; 1905 if (e.tagName) 1906 trg = e; 1907 else { 1908 e=e||window.event; 1909 trg=e.target||e.srcElement; 1910 } 1911 return trg; 1912} 1913 1914function locateAttribute(e, attribute) { 1915 if(!attribute) return; 1916 1917 var trg = getTargetNode(e); 1918 1919 while (trg){ 1920 if (trg.getAttribute){ //text nodes has not getAttribute 1921 var test = trg.getAttribute(attribute); 1922 if (test) return trg; 1923 } 1924 trg=trg.parentNode; 1925 } 1926 return null; 1927} 1928 1929function _trimString(str){ 1930 var func = String.prototype.trim || function(){ return this.replace(/^\s+|\s+$/g, ""); }; 1931 return func.apply(str); 1932} 1933 1934function locateClassName(e, classname, strict){ 1935 var trg = getTargetNode(e); 1936 var css = ""; 1937 1938 if(strict === undefined) 1939 strict = true; 1940 1941 while (trg){ 1942 css = getClassName(trg); 1943 if(css){ 1944 var ind = css.indexOf(classname); 1945 if (ind >= 0){ 1946 if (!strict) 1947 return trg; 1948 1949 //check that we have exact match 1950 var left = (ind === 0) || (!_trimString(css.charAt(ind - 1))); 1951 var right = ((ind + classname.length >= css.length)) || (!_trimString(css.charAt(ind + classname.length))); 1952 1953 if (left && right) 1954 return trg; 1955 } 1956 } 1957 trg=trg.parentNode; 1958 } 1959 return null; 1960} 1961 1962/* 1963event position relatively to DOM element 1964 */ 1965function getRelativeEventPosition(ev, node){ 1966 var d = document.documentElement; 1967 var box = elementPosition(node); 1968 1969 return { 1970 x: ev.clientX + d.scrollLeft - d.clientLeft - box.x + node.scrollLeft, 1971 y: ev.clientY + d.scrollTop - d.clientTop - box.y + node.scrollTop 1972 }; 1973} 1974 1975function isChildOf(child, parent){ 1976 if(!child || !parent){ 1977 return false; 1978 } 1979 1980 while(child && child != parent) { 1981 child = child.parentNode; 1982 } 1983 1984 return child === parent; 1985} 1986 1987function closest(element, selector){ 1988 if(element.closest){ 1989 return element.closest(selector); 1990 }else if(element.matches || element.msMatchesSelector || element.webkitMatchesSelector){ 1991 var el = element; 1992 if (!document.documentElement.contains(el)) return null; 1993 do { 1994 var method = el.matches || el.msMatchesSelector || el.webkitMatchesSelector; 1995 1996 if (method.call(el, selector)) return el; 1997 el = el.parentElement || el.parentNode; 1998 } while (el !== null && el.nodeType === 1); 1999 return null; 2000 }else{ 2001 // eslint-disable-next-line no-console 2002 console.error("Your browser is not supported"); 2003 return null; 2004 } 2005} 2006 2007module.exports = { 2008 getNodePosition: elementPosition, 2009 getFocusableNodes: getFocusableNodes, 2010 getScrollSize: getScrollSize, 2011 getClassName: getClassName, 2012 addClassName: addClassName, 2013 removeClassName: removeClassName, 2014 insertNode: insert, 2015 removeNode: remove, 2016 getChildNodes: getChildren, 2017 toNode: toNode, 2018 locateClassName:locateClassName, 2019 locateAttribute: locateAttribute, 2020 getTargetNode: getTargetNode, 2021 getRelativeEventPosition: getRelativeEventPosition, 2022 isChildOf: isChildOf, 2023 hasClass: hasClass, 2024 closest: closest 2025}; 2026 2027/***/ }), 2028 2029/***/ "./sources/utils/eventable.js": 2030/*!************************************!*\ 2031 !*** ./sources/utils/eventable.js ***! 2032 \************************************/ 2033/*! no static exports found */ 2034/***/ (function(module, exports) { 2035 2036var EventHost = function(){ 2037 this._connected = []; 2038 this._silent_mode = false; 2039}; 2040 2041EventHost.prototype = { 2042 _silentStart: function() { 2043 this._silent_mode = true; 2044 }, 2045 _silentEnd: function() { 2046 this._silent_mode = false; 2047 } 2048}; 2049 2050var createEventStorage = function(obj) { 2051 var dhx_catch = []; 2052 var z = function(){ 2053 var res = true; 2054 for (var i = 0; i < dhx_catch.length; i++){ 2055 if (dhx_catch[i]){ 2056 var zr = dhx_catch[i].apply(obj, arguments); 2057 res=res&&zr; 2058 } 2059 } 2060 return res; 2061 }; 2062 z.addEvent=function(ev){ 2063 if (typeof (ev) == "function") 2064 return dhx_catch.push(ev)-1; 2065 return false; 2066 }; 2067 z.removeEvent=function(id){ 2068 dhx_catch[id]=null; 2069 }; 2070 return z; 2071}; 2072 2073function makeEventable(obj){ 2074 2075 var eventHost = new EventHost(); 2076 obj.attachEvent=function(name, catcher, callObj){ 2077 name='ev_'+name.toLowerCase(); 2078 if (!eventHost[name]) 2079 eventHost[name] = createEventStorage(callObj||this); 2080 2081 return(name+':'+eventHost[name].addEvent(catcher)); //return ID (event name & event ID) 2082 }; 2083 obj.attachAll = function(callback, callObj){ 2084 this.attachEvent('listen_all', callback, callObj); 2085 }; 2086 2087 obj.callEvent=function(name, arg0, callObj){ 2088 if (eventHost._silent_mode) return true; 2089 2090 var handlerName = 'ev_'+name.toLowerCase(); 2091 2092 if (eventHost['ev_listen_all']){ 2093 eventHost['ev_listen_all'].apply(callObj || this, [name].concat(arg0)); 2094 } 2095 2096 if (eventHost[handlerName]) 2097 return eventHost[handlerName].apply(callObj || this, arg0); 2098 return true; 2099 }; 2100 obj.checkEvent=function(name){ 2101 return (!!eventHost['ev_'+name.toLowerCase()]); 2102 }; 2103 obj.detachEvent=function(id){ 2104 if (id){ 2105 var list = id.split(':');//get EventName and ID 2106 var eventName = list[0]; 2107 var eventId = list[1]; 2108 2109 if(eventHost[eventName]){ 2110 eventHost[eventName].removeEvent(eventId); //remove event 2111 } 2112 } 2113 }; 2114 obj.detachAllEvents = function(){ 2115 for (var name in eventHost){ 2116 if (name.indexOf("ev_") === 0) 2117 delete eventHost[name]; 2118 } 2119 }; 2120 2121} 2122 2123module.exports = makeEventable; 2124 2125/***/ }) 2126 2127/******/ }); 2128});