1 /** 2 * @file Window window 3 * 4 * @author Dominik Kocuj 5 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License v2 or later 6 * @copyright Copyright (c) 2016-2018 kocuj.pl 7 */ 8 9 (function() {})(); // empty function for correct minify with comments 10 //'use strict'; // for jshint uncomment this and comment line above 11 12 /* jshint strict: true */ 13 /* jshint -W034 */ 14 15 /* global document */ 16 /* global jQuery */ 17 /* global window */ 18 19 /* global kocujILV12aHelper */ 20 /* global kocujILV12aAllJsAjax */ 21 22 /* global kocujILV12aAllWindowVals */ 23 24 /** 25 * Windows types 26 * 27 * @namespace kocujILV12aAllWindowType 28 * @public 29 */ 30 var kocujILV12aAllWindowType = { 31 /** 32 * Window with standard content 33 * 34 * @public 35 * @const {number} 36 */ 37 STANDARD : 0, 38 39 /** 40 * Window with AJAX content 41 * 42 * @public 43 * @const {number} 44 */ 45 AJAX : 1, 46 47 /** 48 * Information about maximum constant value; it should not be used in executing the window script methods 49 * 50 * @public 51 * @const {number} 52 */ 53 LAST : 1 54 }; 55 56 /** 57 * Window window prototype constructor 58 * 59 * @constructs 60 * @namespace kocujILV12aCAllWindow 61 * @public 62 * @return {void} 63 */ 64 function kocujILV12aCAllWindow() { 65 'use strict'; 66 /* jshint validthis: true */ 67 // get this object 68 var self = this; 69 // initialize objects 70 self._objHelper = kocujILV12aHelper; 71 self._objAllJsAjax = kocujILV12aAllJsAjax; 72 // get current script filename 73 self._thisFilename = document.scripts[document.scripts.length-1].src; 74 // get settings 75 var vals = kocujILV12aAllWindowVals; 76 if (vals.throwErrors === '1') { 77 self._valsThrowErrors = true; 78 } else { 79 self._valsThrowErrors = false; 80 } 81 self._valsPrefix = vals.prefix; 82 self._valsDialogCssUrl = vals.dialogCssUrl; 83 self._valsTextLoading = vals.textLoading; 84 self._valsTextLoadingError = vals.textLoadingError; 85 } 86 87 /** 88 * Window prototype 89 * 90 * @namespace kocujILV12aCAllWindow 91 * @public 92 */ 93 kocujILV12aCAllWindow.prototype = { 94 /** 95 * Object kocujILV12aHelper 96 * 97 * @private 98 * @type {Object} 99 */ 100 _objHelper : null, 101 102 /** 103 * Object kocujILV12aAllJsAjax 104 * 105 * @private 106 * @type {Object} 107 */ 108 _objAllJsAjax : null, 109 110 /** 111 * Current script filename 112 * 113 * @private 114 * @type {string} 115 */ 116 _thisFilename : '', 117 118 /** 119 * Projects list 120 * 121 * @private 122 * @type {Array} 123 */ 124 _prj : [], 125 126 /** 127 * Script settings - throw errors (true) or not (false) 128 * 129 * @private 130 * @type {string} 131 */ 132 _valsThrowErrors : false, 133 134 /** 135 * Script settings - prefix 136 * 137 * @private 138 * @type {string} 139 */ 140 _valsPrefix : '', 141 142 /** 143 * Script settings - dialog window CSS URL 144 * 145 * @private 146 * @type {string} 147 */ 148 _valsDialogCssUrl : '', 149 150 /** 151 * Script settings - text for loading 152 * 153 * @private 154 * @type {string} 155 */ 156 _valsTextLoading : '', 157 158 /** 159 * Script settings - text for loading error 160 * 161 * @private 162 * @type {string} 163 */ 164 _valsTextLoadingError : '', 165 166 /** 167 * Add project 168 * 169 * @public 170 * @param {string} projectId Project identifier 171 * @return {void} 172 * @throws {kocujILV12aCException} kocujILV12aExceptionCode.PROJECT_ALREADY_EXISTS if project identifier entered in projectId already exists 173 */ 174 addProject : function(projectId) { 175 'use strict'; 176 // parse arguments 177 var args = this._checkAddProject(projectId); 178 // add project 179 if (this._prj['prj_' + args.projectId] === undefined) { 180 this.addProjectIfNotExists(args.projectId); 181 } else { 182 this._throwError('PROJECT_ALREADY_EXISTS', args.projectId); 183 return; 184 } 185 }, 186 187 /** 188 * Add project if not exists 189 * 190 * @public 191 * @param {string} projectId Project identifier 192 * @return {void} 193 */ 194 addProjectIfNotExists : function(projectId) { 195 'use strict'; 196 // get this object 197 var self = this; 198 (function($) { 199 // parse arguments 200 var args = self._checkAddProject(projectId); 201 // add project 202 if (self._prj['prj_' + args.projectId] === undefined) { 203 // add project 204 self._prj['prj_' + args.projectId] = { 205 timer : null, 206 cssLoaded : false, 207 windowsTimers : [] 208 }; 209 // add stylesheet 210 var stylesheet = $('<link id="' + self._getHTMLNameStylesheet(args.projectId) + '" rel="stylesheet" href="' + self._valsDialogCssUrl + '" type="text/css" media="all" />'); 211 stylesheet.load(function() { 212 self._checkStylesheet(args.projectId); 213 }); 214 $('head').append(stylesheet); 215 // add dummy element for checking style loading 216 $('body').prepend('<div id="' + self._getHTMLNameDummy(args.projectId) + '" class="ui-dialog" style="display:none;"></div>'); 217 // set timer for waiting 218 if (!self._checkStylesheet(args.projectId)) { 219 self._prj['prj_' + args.projectId].timer = window.setInterval(function() { 220 // check stylesheet 221 if (self._checkStylesheet(args.projectId)) { 222 // clear timer 223 window.clearInterval(self._prj['prj_' + args.projectId].timer); 224 self._prj['prj_' + args.projectId].timer = null; 225 } 226 }, 100); 227 } 228 } 229 self._objAllJsAjax.addProjectIfNotExists(args.projectId); 230 }(jQuery)); 231 }, 232 233 /** 234 * Get HTML selector for stylesheet 235 * 236 * @public 237 * @param {string} projectId Project identifier 238 * @return {string} HTML selector for stylesheet 239 */ 240 getHTMLSelectorStylesheet : function(projectId) { 241 'use strict'; 242 // parse arguments 243 projectId = this._parseProjectId(projectId); 244 // exit 245 return '#' + this._getHTMLNameStylesheet(projectId); 246 }, 247 248 /** 249 * Get HTML selector for dummy element 250 * 251 * @public 252 * @param {string} projectId Project identifier 253 * @return {string} HTML selector for dummy element 254 */ 255 getHTMLSelectorDummy : function(projectId) { 256 'use strict'; 257 // parse arguments 258 projectId = this._parseProjectId(projectId); 259 // exit 260 return '#' + this._getHTMLNameDummy(projectId); 261 }, 262 263 /** 264 * Get HTML selector for window 265 * 266 * @public 267 * @param {string} projectId Project identifier 268 * @param {string} windowId Window identifier 269 * @return {string} HTML selector for window 270 */ 271 getHTMLSelectorWindow : function(projectId, windowId) { 272 'use strict'; 273 // parse arguments 274 projectId = this._parseProjectId(projectId); 275 windowId = this._objHelper.initString(windowId); 276 // exit 277 return '#' + this._getHTMLNameWindow(projectId, windowId); 278 }, 279 280 /** 281 * Get HTML selector for window content 282 * 283 * @public 284 * @param {string} projectId Project identifier 285 * @param {string} windowId Window identifier 286 * @return {string} HTML selector for window content 287 */ 288 getHTMLSelectorContent : function(projectId, windowId) { 289 'use strict'; 290 // parse arguments 291 projectId = this._parseProjectId(projectId); 292 windowId = this._objHelper.initString(windowId); 293 // exit 294 return '#' + this._getHTMLNameContent(projectId, windowId); 295 }, 296 297 /** 298 * Get HTML selector for window content inside 299 * 300 * @public 301 * @param {string} projectId Project identifier 302 * @param {string} windowId Window identifier 303 * @return {string} HTML selector for window content inside 304 */ 305 getHTMLSelectorContentInside : function(projectId, windowId) { 306 'use strict'; 307 // parse arguments 308 projectId = this._parseProjectId(projectId); 309 windowId = this._objHelper.initString(windowId); 310 // exit 311 return '#' + this._getHTMLNameContentInside(projectId, windowId); 312 }, 313 314 /** 315 * Show window 316 * 317 * @public 318 * @param {string} projectId Project identifier 319 * @param {string} windowId Window identifier 320 * @param {number} type Window type 321 * @param {Object} attr Window attributes 322 * @return {void} 323 */ 324 show : function(projectId, windowId, type, attr) { 325 'use strict'; 326 // get this object 327 var self = this; 328 (function($) { 329 // parse arguments 330 projectId = self._parseProjectId(projectId); 331 windowId = self._objHelper.initString(windowId); 332 type = self._objHelper.initNumeric(type); 333 if (type > kocujILV12aAllWindowType.LAST) { 334 self._throwError('WINDOW_WRONG_TYPE'); 335 return; 336 } 337 attr = self._objHelper.initObject(attr); 338 switch (type) { 339 case kocujILV12aAllWindowType.STANDARD: 340 if (!('content' in attr)) { 341 self._throwError('WINDOW_WRONG_ATTRIBUTES'); 342 return; 343 } 344 break; 345 case kocujILV12aAllWindowType.AJAX: 346 if ((!('url' in attr)) || (!('ajaxData' in attr))) { 347 self._throwError('WINDOW_WRONG_ATTRIBUTES'); 348 return; 349 } 350 break; 351 } 352 // show window 353 if (self._checkStylesheet(projectId)) { 354 self._showWindow(projectId, windowId, type, attr); 355 } else { 356 self._prj['prj_' + projectId].windowsTimers['win_' + windowId] = window.setInterval(function() { 357 // optionally show window 358 if (self._checkStylesheet(projectId)) { 359 // clear timer 360 window.clearInterval(self._prj['prj_' + projectId].windowsTimers['win_' + windowId]); 361 self._prj['prj_' + projectId].windowsTimers['win_' + windowId] = null; 362 // show window 363 self._showWindow(projectId, windowId, type, attr); 364 } 365 }, 2000); 366 } 367 }(jQuery)); 368 }, 369 370 /** 371 * AJAX loading success callback 372 * 373 * @public 374 * @param {string} projectId Project identifier 375 * @param {string} connectionId Connection identifier 376 * @param {anything} data Data 377 * @param {string} status Text status 378 * @param {Object} obj Request object 379 * @return {void} 380 */ 381 ajaxSuccessCallback : function(projectId, connectionId, data, status, obj) { 382 'use strict'; 383 // get this object 384 var self = kocujILV12aAllWindow; 385 (function($) { 386 // parse parameters 387 data = self._objHelper.initString(data); 388 // get window identifier 389 var tmp = connectionId.split('__'); 390 var windowId = tmp[tmp.length-1]; 391 // set HTML data 392 $(self.getHTMLSelectorContentInside(projectId, windowId)).html(data); 393 }(jQuery)); 394 }, 395 396 /** 397 * AJAX loading error callback 398 * 399 * @public 400 * @param {string} projectId Project identifier 401 * @param {string} connectionId Connection identifier 402 * @param {Object} obj Request object 403 * @param {string} status Text status 404 * @param {string} err Error 405 * @return {void} 406 */ 407 ajaxErrorCallback : function(projectId, connectionId, obj, status, err) { 408 'use strict'; 409 // get this object 410 var self = kocujILV12aAllWindow; 411 (function($) { 412 // get window identifier 413 var tmp = connectionId.split('__'); 414 var windowId = tmp[tmp.length-1]; 415 // set HTML data 416 $(self.getHTMLSelectorContentInside(projectId, windowId)).html(self._valsTextLoadingError); 417 }(jQuery)); 418 }, 419 420 /** 421 * Get HTML prefix 422 * 423 * @private 424 * @param {string} projectId Project identifier 425 * @return {string} HTML prefix 426 */ 427 _getHTMLPrefix : function(projectId) { 428 'use strict'; 429 // exit 430 return this._valsPrefix + '_' + projectId + '__'; 431 }, 432 433 /** 434 * Get HTML prefix for stylesheet 435 * 436 * @private 437 * @param {string} projectId Project identifier 438 * @return {string} HTML prefix for stylesheet 439 */ 440 _getHTMLNameStylesheet : function(projectId) { 441 'use strict'; 442 // exit 443 return this._getHTMLPrefix(projectId) + 'window_stylesheet'; 444 }, 445 446 /** 447 * Get HTML prefix for dummy element 448 * 449 * @private 450 * @param {string} projectId Project identifier 451 * @return {string} HTML prefix for dummy element 452 */ 453 _getHTMLNameDummy : function(projectId) { 454 'use strict'; 455 // exit 456 return this._getHTMLPrefix(projectId) + 'window_dummy'; 457 }, 458 459 /** 460 * Get HTML prefix for window 461 * 462 * @private 463 * @param {string} projectId Project identifier 464 * @param {string} windowId Window identifier 465 * @return {string} HTML prefix for window 466 */ 467 _getHTMLNameWindow : function(projectId, windowId) { 468 'use strict'; 469 // exit 470 return this._getHTMLPrefix(projectId) + 'window__' + windowId; 471 }, 472 473 /** 474 * Get HTML prefix for window content 475 * 476 * @private 477 * @param {string} projectId Project identifier 478 * @param {string} windowId Window identifier 479 * @return {string} HTML prefix for window content 480 */ 481 _getHTMLNameContent : function(projectId, windowId) { 482 'use strict'; 483 // exit 484 return this._getHTMLPrefix(projectId) + 'window_content__' + windowId; 485 }, 486 487 /** 488 * Get HTML prefix for window content inside 489 * 490 * @private 491 * @param {string} projectId Project identifier 492 * @param {string} windowId Window identifier 493 * @return {string} HTML prefix for window content inside 494 */ 495 _getHTMLNameContentInside : function(projectId, windowId) { 496 'use strict'; 497 // exit 498 return this._getHTMLPrefix(projectId) + 'window_content_inside__' + windowId; 499 }, 500 501 /** 502 * Parse project identifier 503 * 504 * @private 505 * @param {string} projectId Project identifier 506 * @return {string} Parsed project identifier 507 * @throws {kocujILV12aCException} kocujILV12aExceptionCode.EMPTY_PROJECT_ID if project identifier entered in projectId is empty 508 * @throws {kocujILV12aCException} kocujILV12aExceptionCode.PROJECT_DOES_NOT_EXIST if project identifier entered in projectId does not exist 509 */ 510 _parseProjectId : function(projectId) { 511 'use strict'; 512 // parse project identifier 513 projectId = this._objHelper.initString(projectId); 514 if (projectId === '') { 515 this._throwError('EMPTY_PROJECT_ID'); 516 return; 517 } 518 // check if project exists 519 if (this._prj['prj_' + projectId] === undefined) { 520 this._throwError('PROJECT_DOES_NOT_EXIST', projectId); 521 return; 522 } 523 // exit 524 return projectId; 525 }, 526 527 /** 528 * Check arguments for adding project 529 * 530 * @private 531 * @param {string} projectId Project identifier 532 * @return {Object} Parsed arguments for adding project 533 * @throws {kocujILV12aCException} kocujILV12aExceptionCode.EMPTY_PROJECT_ID if project identifier entered in projectId is empty 534 */ 535 _checkAddProject : function(projectId) { 536 'use strict'; 537 // parse arguments 538 projectId = this._objHelper.initString(projectId); 539 if (projectId === '') { 540 this._throwError('EMPTY_PROJECT_ID'); 541 return; 542 } 543 // exit 544 return { 545 projectId : projectId 546 }; 547 }, 548 549 /** 550 * Throw an error if debugging is enabled 551 * 552 * @private 553 * @param {string} codeString Error code in string format 554 * @param {string} [param] Parameter for error information 555 * @return {void} 556 */ 557 _throwError : function(codeString, param) { 558 'use strict'; 559 // parse arguments 560 codeString = this._objHelper.initString(codeString); 561 if (codeString === '') { 562 return; 563 } 564 param = this._objHelper.initString(param); 565 // throw an error 566 if (this._valsThrowErrors) { 567 /* jshint evil: true */ 568 eval('throw new kocujILV12aCException(kocujILV12aExceptionCode.' + codeString + ', this._thisFilename, param);'); 569 } 570 }, 571 572 /** 573 * Check window stylesheet 574 * 575 * @private 576 * @param {string} projectId Project identifier 577 * @return {boolean} Stylesheet has been loaded (true) or not (false) 578 */ 579 _checkStylesheet : function(projectId) { 580 'use strict'; 581 // check if stylesheet has not been loaded already 582 if (this._prj['prj_' + projectId].cssLoaded) { 583 return true; 584 } 585 // get this object 586 var self = this; 587 (function($) { 588 // set flag for loaded CSS 589 if ($(self.getHTMLSelectorDummy(projectId)).css('position') === 'absolute') { 590 self._prj['prj_' + projectId].cssLoaded = true; 591 } 592 }(jQuery)); 593 // exit 594 return this._prj['prj_' + projectId].cssLoaded; 595 }, 596 597 /** 598 * Show window now 599 * 600 * @private 601 * @param {string} projectId Project identifier 602 * @param {string} windowId Window identifier 603 * @param {number} type Window type 604 * @param {Object} attr Window attributes 605 * @return {void} 606 */ 607 _showWindow : function(projectId, windowId, type, attr) { 608 'use strict'; 609 // get this object 610 var self = this; 611 (function($) { 612 // remove old dialog content 613 if ($(self.getHTMLSelectorWindow(projectId, windowId)).length !== 0) { 614 $(self.getHTMLSelectorWindow(projectId, windowId)).remove(); 615 } 616 // add dialog content 617 $('body').append('<div id="' + self._getHTMLNameWindow(projectId, windowId) + '" style="padding:0;"><div id="' + self._getHTMLNameContent(projectId, windowId) + '" style="height:100%;padding:0;margin:0;overflow-x:hidden;overflow-y:scroll;"><div id="' + self._getHTMLNameContentInside(projectId, windowId) + '" style="padding:10px;"></div></div></div>'); 618 $(self.getHTMLSelectorContentInside(projectId, windowId)).html(''); 619 switch (type) { 620 case kocujILV12aAllWindowType.STANDARD: 621 $(self.getHTMLSelectorContentInside(projectId, windowId)).html(attr.content); 622 break; 623 case kocujILV12aAllWindowType.AJAX: 624 $(self.getHTMLSelectorContentInside(projectId, windowId)).html(self._valsTextLoading); 625 break; 626 } 627 // set dialog content styles 628 if ('contentCss' in attr) { 629 $.each(attr.contentCss, function(key, value) { 630 $(self.getHTMLSelectorContentInside(projectId, windowId)).css(key, value.split('"').join('"')); 631 }); 632 } 633 // show window 634 $(self.getHTMLSelectorWindow(projectId, windowId)).dialog({ 635 width : attr.width, 636 height : attr.height, 637 title : attr.title, 638 modal : true, 639 draggable : false, 640 resizable : false, 641 responsive : true, 642 show : 'fade', 643 hide : 'fade', 644 open : function() { 645 $('.ui-widget-overlay').hide().fadeIn(); 646 }, 647 beforeClose : function() { 648 $('.ui-widget-overlay').remove(); 649 $('<div />', { 650 'class' : 'ui-widget-overlay' 651 }).css({ 652 width : $(document).width(), 653 height : $(document).height(), 654 zIndex : 1001 655 }).appendTo('body').fadeOut(function(){ 656 $(this).remove(); 657 }); 658 } 659 }); 660 // change title bar style 661 $(self.getHTMLSelectorWindow(projectId, windowId)).parent().find('.ui-dialog-title').css({ 662 'overflow' : 'hidden', 663 'display' : 'block', 664 'height' : '100%' 665 }); 666 // optionally send AJAX request 667 if (type === kocujILV12aAllWindowType.AJAX) { 668 self._objAllJsAjax.sendPost(projectId, 'window__' + windowId, attr.url, 'text', attr.ajaxData, { 669 success : self.ajaxSuccessCallback, 670 error : self.ajaxErrorCallback 671 }); 672 } 673 }(jQuery)); 674 } 675 }; 676 677 // initialize 678 var kocujILV12aAllWindow = new kocujILV12aCAllWindow(); 679