1// Copyright (c) 2006 Sébastien Gruhier (http://xilinus.com, http://itseb.com) 2// 3// Permission is hereby granted, free of charge, to any person obtaining 4// a copy of this software and associated documentation files (the 5// "Software"), to deal in the Software without restriction, including 6// without limitation the rights to use, copy, modify, merge, publish, 7// distribute, sublicense, and/or sell copies of the Software, and to 8// permit persons to whom the Software is furnished to do so, subject to 9// the following conditions: 10// 11// The above copyright notice and this permission notice shall be 12// included in all copies or substantial portions of the Software. 13// 14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21// 22// VERSION 0.80 23 24var Window = Class.create(); 25Window.prototype = { 26 // Constructor 27 // Available parameters : className, title, minWidth, minHeight, maxWidth, maxHeight, width, height, top, left, bottom, right, resizable, zIndex, opacity, 28 // hideEffect, showEffect, showEffectOptions, hideEffectOptions, effectOptions, url, draggable, closable, minimizable, maximizable, parent, onload 29 initialize: function(id, parameters) { 30 this.hasEffectLib = String.prototype.parseColor != null; 31 this.minWidth = parameters.minWidth || 100; 32 this.minHeight = parameters.minHeight || 20; 33 this.maxWidth = parameters.maxWidth; 34 this.maxHeight = parameters.maxHeight; 35 this.showEffect = parameters.showEffect || (this.hasEffectLib ? Effect.Appear : Element.show); 36 this.hideEffect = parameters.hideEffect || (this.hasEffectLib ? Effect.Fade : Element.hide); 37 38 this.showEffectOptions = parameters.showEffectOptions || parameters.effectOptions; 39 this.hideEffectOptions = parameters.hideEffectOptions || parameters.effectOptions; 40 this.draggable = parameters.draggable != null ? parameters.draggable : true; 41 this.userData = parameters.userData; 42 43 var resizable = parameters.resizable != null ? parameters.resizable : true; 44 var closable = parameters.closable != null ? parameters.closable : true; 45 var minimizable = parameters.minimizable != null ? parameters.minimizable : true; 46 var maximizable = parameters.maximizable != null ? parameters.maximizable : true; 47 var className = parameters.className != null ? parameters.className : "dialog"; 48 this.className = className; 49 50 var parent = parameters.parent || document.getElementsByTagName("body").item(0); 51 this.element = this.createWindow(id, className, parent, resizable, closable, minimizable, maximizable, parameters.title, parameters.url, parameters.onload); 52 this.isIFrame = parameters.url != null; 53 54 // Bind event listener 55 this.eventMouseDown = this.initDrag.bindAsEventListener(this); 56 this.eventMouseUp = this.endDrag.bindAsEventListener(this); 57 this.eventMouseMove = this.updateDrag.bindAsEventListener(this); 58 this.eventKeyPress = this.keyPress.bindAsEventListener(this); 59 this.eventOnLoad = this._getWindowBorderSize.bindAsEventListener(this); 60 61 this.topbar = $(this.element.id + "_top"); 62 this.bottombar = $(this.element.id + "_bottom"); 63 64 Event.observe(this.topbar, "mousedown", this.eventMouseDown); 65 Event.observe(this.bottombar, "mousedown", this.eventMouseDown); 66 Event.observe(window, "load", this.eventOnLoad); 67 68 if (this.draggable) { 69 this.bottombar.addClassName("bottom_draggable"); 70 this.topbar.addClassName("top_draggable"); 71 } 72 73 var offset = [0,0]; 74 if (resizable) { 75 this.sizer = $(this.element.id + "_sizer"); 76 Event.observe(this.sizer, "mousedown", this.eventMouseDown); 77 } 78 var width = parseFloat(parameters.width) || 200; 79 var height = parseFloat(parameters.height) || 200; 80 81 if (parameters.left != null) { 82 this.element.setStyle({left: parseFloat(parameters.left) + offset[0] + 'px'}); 83 this.useLeft = true; 84 } 85 86 if (parameters.right != null) { 87 this.element.setStyle({right: parseFloat(parameters.right) + 'px'}); 88 this.useLeft = false;
89 } 90 91 if (parameters.top != null) { 92 this.element.setStyle({top: parseFloat(parameters.top) + 'px'}); 93 this.useTop = true; 94 } 95 96 if (parameters.bottom != null) { 97 this.element.setStyle({bottom: parseFloat(parameters.bottom) + 'px'}); 98 this.useTop = false; 99 } 100 101 this.storedLocation = null; 102 103 if (parameters.opacity) 104 this.setOpacity(parameters.opacity); 105 if (parameters.zIndex) 106 this.setZIndex(parameters.zIndex) 107 108 this.destroyOnClose = false; 109 110 this._getWindowBorderSize(); 111 this.setSize(width, height); 112 Windows.register(this); 113 }, 114 115 // Destructor 116 destroy: function() { 117 Windows.notify("onDestroy", this); 118 Event.stopObserving(this.topbar, "mousedown", this.eventMouseDown); 119 Event.stopObserving(this.bottombar, "mousedown", this.eventMouseDown); 120 Event.stopObserving(window, "load", this.eventOnLoad); 121 122 if (this.sizer) 123 Event.stopObserving(this.sizer, "mousedown", this.eventMouseDown); 124 125 if(this.iefix) 126 Element.hide(this.iefix); 127 128 Element.remove(this.element); 129 130 Windows.unregister(this); 131 }, 132 133 // Sets window deleagte, should have functions: "canClose(window)" 134 setDelegate: function(delegate) { 135 this.delegate = delegate 136 }, 137 138 // Gets current window delegate 139 getDelegate: function() { 140 return this.delegate; 141 }, 142 143 // Gets window content 144 getContent: function () { 145 return $(this.element.id + "_content"); 146 }, 147 148 // Sets the content with an element id 149 setContent: function(id, autoresize, autoposition) { 150 var d = null; 151 var p = null; 152 153 if (autoresize) 154 d = Element.getDimensions(id); 155 if (autoposition) 156 p = Position.cumulativeOffset($(id)); 157 158 var content = this.getContent() 159 content.appendChild($(id)); 160 161 if (autoresize) 162 this.setSize(d.width, d.height); 163 if (autoposition) 164 this.setLocation(p[1] - this.heightN, p[0] - this.widthW); 165 }, 166 167 // Stores position/size in a cookie, by default named with window id 168 setCookie: function(name, expires, path, domain, secure) { 169 name = name || this.element.id; 170 this.cookie = [name, expires, path, domain, secure]; 171 172 // Get cookie 173 var value = WindowUtilities.getCookie(name) 174 // If exists 175 if (value) { 176 var values = value.split(','); 177 var x = values[0].split(':'); 178 var y = values[1].split(':'); 179 180 var w = parseFloat(values[2]), h = parseFloat(values[3]); 181 var mini = values[4]; 182 var maxi = values[5]; 183 184 this.setSize(w, h); 185 if (mini == "true") 186 this.minimize(); 187 else if (maxi == "true") 188 this.doMaximize = true // Maiximize will be done at onload window event 189 190 this.useLeft = x[0] == "l"; 191 this.useTop = y[0] == "t"; 192 193 this.element.setStyle(this.useLeft ? {left: x[1]} : {right: x[1]}); 194 this.element.setStyle(this.useTop ? {top: y[1]} : {bottom: y[1]}); 195 } 196 }, 197 198 // Gets window ID 199 getId: function() { 200 return this.element.id; 201 }, 202 203 // Detroys itself when closing 204 setDestroyOnClose: function() { 205 this.destroyOnClose = true; 206 }, 207 208 // initDrag event 209 initDrag: function(event) { 210 // Get pointer X,Y 211 this.pointer = [Event.pointerX(event), Event.pointerY(event)]; 212 this.doResize = false; 213 214 // Check if click on close button, 215 var closeButton = $(this.getId() + '_close'); 216 if (closeButton && Position.within(closeButton, this.pointer[0], this.pointer[1])) { 217 return; 218 } 219 this.toFront(); 220 221 // Check if click on sizer 222 if (this.sizer && Position.within(this.sizer, this.pointer[0], this.pointer[1])) { 223 this.doResize = true; 224 this.widthOrg = this.width; 225 this.heightOrg = this.height; 226 this.bottomOrg = parseFloat(this.element.getStyle('bottom')); 227 this.rightOrg = parseFloat(this.element.getStyle('right')); 228 Windows.notify("onStartResize", this); 229 } 230 else { 231 if (! this.draggable) 232 return; 233 Windows.notify("onStartMove", this); 234 } 235 236 // Register global event to capture mouseUp and mouseMove 237 Event.observe(document, "mouseup", this.eventMouseUp); 238 Event.observe(document, "mousemove", this.eventMouseMove); 239 240 // Add an invisible div to keep catching mouse event over the iframe 241 if (this.isIFrame) { 242 var objBody = document.getElementsByTagName("body").item(0); 243 var div = document.createElement("div"); 244 div.style.position = "absolute"; 245 div.style.top = this.heightN + "px"; 246 div.style.left = this.widthW + "px"; 247 div.style.zIndex = Windows.maxZIndex; 248 div.style.height = this.height + "px"; 249 div.style.width = this.width + "px"; 250 this.element.appendChild(div); 251 this.tmpDiv = div; 252 } 253 Event.stop(event); 254 }, 255 256 // updateDrag event 257 updateDrag: function(event) { 258 var pointer = [Event.pointerX(event), Event.pointerY(event)]; 259 var dx = pointer[0] - this.pointer[0]; 260 var dy = pointer[1] - this.pointer[1]; 261
262 // Resize case, update width/height 263 if (this.doResize) { 264 this.setSize(this.widthOrg + dx , this.heightOrg + dy); 265 266 dx = this.width - this.widthOrg 267 dy = this.height - this.heightOrg 268 269 // Check if it's a right position, update it to keep upper-left corner at the same position 270 if (! this.useLeft) 271 this.element.setStyle({right: (this.rightOrg -dx) + 'px'}); 272 // Check if it's a bottom position, update it to keep upper-left corner at the same position 273 if (! this.useTop) 274 this.element.setStyle({bottom: (this.bottomOrg -dy) + 'px'}); 275 276 if (this.tmpDiv) 277 Element.setStyle(this.tmpDiv, {width: this.width + "px", height: this.height + "px"}) 278 } 279 // Move case, update top/left 280 else { 281 this.pointer = pointer; 282 283 if (this.useLeft) 284 this.element.setStyle({left: parseFloat(this.element.getStyle('left')) + dx + 'px'}); 285 else 286 this.element.setStyle({right: parseFloat(this.element.getStyle('right')) - dx + 'px'}); 287 288 if (this.useTop) 289 this.element.setStyle({top: parseFloat(this.element.getStyle('top')) + dy + 'px'}); 290 else 291 this.element.setStyle({bottom: parseFloat(this.element.getStyle('bottom')) - dy + 'px'}); 292 } 293 if (this.iefix) 294 this._fixIEOverlapping(); 295 296 this._removeStoreLocation(); 297 Event.stop(event); 298 }, 299 300 // endDrag callback 301 endDrag: function(event) { 302 if (this.doResize) 303 Windows.notify("onEndResize", this); 304 else 305 Windows.notify("onEndMove", this); 306 307 // Release event observing 308 Event.stopObserving(document, "mouseup", this.eventMouseUp); 309 Event.stopObserving(document, "mousemove", this.eventMouseMove); 310 311 // Remove temporary div 312 if (this.isIFrame) { 313 this.tmpDiv.parentNode.removeChild(this.tmpDiv); 314 this.tmpDiv = null; 315 } 316 // Store new location/size if need be 317 this._saveCookie() 318 319 Event.stop(event); 320 }, 321 322 keyPress: function(event) { 323 //Dialog.cancelCallback(); 324 }, 325 326 // Creates HTML window code 327 createWindow: function(id, className, parent, resizable, closable, minimizable, maximizable, title, url, onload) { 328 win = document.createElement("div"); 329 win.setAttribute('id', id); 330 win.className = "dialog"; 331 if (!title) 332 title = " "; 333 334 var content; 335 if (url) 336 content= "<IFRAME name=\"" + id + "_content\" id=\"" + id + "_content\" SRC=\"" + url + "\" onload=\"" + onload + "\" > </IFRAME>"; 337 else 338 content ="<DIV id=\"" + id + "_content\" class=\"" +className + "_content\" onload=\"" + onload + "\"> </DIV>"; 339 340 win.innerHTML = "\ 341 <div class='"+ className +"_close' id='"+ id +"_close' onclick='Windows.close(\""+ id +"\")'> </div>\ 342 <div class='"+ className +"_minimize' id='"+ id +"_minimize' onclick='minEme(\""+ id +"\")'> </div>\ 343 <div class='"+ className +"_maximize' id='"+ id +"_maximize' onclick='Windows.maximize(\""+ id +"\")'> </div>\ 344 <table id='"+ id +"_header' class='"+ className +"_header'>\ 345 <tr id='"+ id +"_row1'>\ 346 <td>\ 347 <table>\ 348 <tr>\ 349 <td id='"+ id +"_nw' class='"+ className +"_nw'><div class='"+ className +"_nw'> </div></td>\ 350 <td class='"+ className +"_n' valign='middle'><div id='"+ id +"_top' class='"+ className +"_title'>"+ title +"</div></td>\ 351 <td class='"+ className +"_ne'> <div class='"+ className +"_ne'></div></td>\ 352 </tr>\ 353 </table>\ 354 </td>\ 355 </tr>\ 356 <tr id='"+ id +"_row2'>\ 357 <td>\ 358 <table >\ 359 <tr>\ 360 <td class='"+ className +"_w'><div class='"+ className +"_w'> </div></td>\ 361 <td class='"+ className +"_content'>"+ content +"</td>\ 362 <td class='"+ className +"_e'><div class='"+ className +"_e'> </div></td>\ 363 </tr>\ 364 </table>\ 365 </td>\ 366 </tr>\ 367 <tr id='"+ id +"_row3'>\ 368 <td>\ 369 <table>\ 370 <tr>\ 371 <td class='"+ className +"_sw' id='"+ id +"_sw'><div class='"+ className +"_sw'></div> </td>\ 372 <td class='"+ className +"_s'><div id='"+ id +"_bottom' class='"+ className +"_s'></div></td>\ 373 <td class='"+ className +"_se'>"+ (resizable ? "<div id='"+ id + "_sizer' class='"+ className +"_sizer'></div>" : "<div class='"+ className +"_se'></div>") +"</td>\ 374 </tr>\ 375 </table>\ 376 </td>\ 377 </tr>\ 378 </table>\ 379 "; 380 381 Element.hide(win); 382 parent.insertBefore(win, parent.firstChild); 383 384 if (!closable) 385 Element.hide(id +"_close") 386 if (!minimizable) 387 Element.hide(id +"_minimize") 388 if (!maximizable) 389 Element.hide(id +"_maximize") 390 391 return win; 392 }, 393 394 // Sets window location 395 setLocation: function(top, left) { 396 if (top < 0) 397 top = 0; 398 if (left < 0) 399 left= 0 400 this.element.setStyle({top: top + 'px'}); 401 this.element.setStyle({left: left + 'px'}); 402 this.useLeft = true; 403 this.useTop = true; 404 }, 405 406 // Sets window size 407 setSize: function(width, height) { 408 // Check min and max size 409 if (width < this.minWidth) 410 width = this.minWidth; 411 412 if (height < this.minHeight) 413 height = this.minHeight; 414 415 if (this.maxHeight && height > this.maxHeight) 416 height = this.maxHeight; 417 418 if (this.maxWidth && width > this.maxWidth) 419 width = this.maxWidth; 420 421 this.width = width; 422 this.height = height; 423 this.element.setStyle({width: width + this.widthW + this.widthE + "px"}) 424 this.element.setStyle({height: height + this.heightN + this.heightS + "px"}) 425 426 // Update content height
427 var content = $(this.element.id + '_content') 428 content.setStyle({height: height + 'px'}); 429 content.setStyle({width: width + 'px'}); 430 }, 431 432 // Brings window to front 433 toFront: function() { 434 this.setZIndex(Windows.maxZIndex + 20); 435 }, 436 437 // Displays window modal state or not 438 show: function(modal) { 439 if (modal) { 440 WindowUtilities.disableScreen(this.className); 441 this.modal = true; 442 this.setZIndex(Windows.maxZIndex + 20); 443 Windows.unsetOverflow(this); 444 Event.observe(document, "keypress", this.eventKeyPress); 445 } 446 447 // To restore overflow if need be 448 if (this.oldStyle) 449 this.getContent().setStyle({overflow: this.oldStyle}); 450 451 this.setSize(this.width, this.height); 452 if (this.showEffect != Element.show && this.showEffectOptions ) 453 this.showEffect(this.element, this.showEffectOptions); 454 else 455 this.showEffect(this.element); 456 457 this._checkIEOverlapping(); 458 }, 459 460 // Displays window modal state or not at the center of the page 461 showCenter: function(modal) { 462 this.setSize(this.width, this.height); 463 this.center(); 464 465 this.show(modal); 466 }, 467 468 center: function() { 469 var windowScroll = WindowUtilities.getWindowScroll(); 470 var pageSize = WindowUtilities.getPageSize(); 471 472 this.setLocation(windowScroll.top + (pageSize.windowHeight - (this.height + this.heightN + this.heightS))/2, 473 windowScroll.left + (pageSize.windowWidth - (this.width + this.widthW + this.widthE))/2); 474 this.toFront(); 475 }, 476 477 // Hides window 478 hide: function() { 479 if (this.modal) { 480 WindowUtilities.enableScreen(); 481 Windows.resetOverflow(); 482 Event.stopObserving(document, "keypress", this.eventKeyPress); 483 } 484 // To avoid bug on scrolling bar 485 this.getContent().setStyle({overflow: "hidden"}); 486 this.oldStyle = this.getContent().getStyle('overflow'); 487 488 if (this.hideEffect != Element.hide && this.hideEffectOptions) 489 this.hideEffect(this.element, this.hideEffectOptions); 490 else 491 this.hideEffect(this.element); 492 493 if(this.iefix) 494 this.iefix.hide(); 495 }, 496 497 minimize: function() { 498 var r2 = $(this.getId() + "_row2"); 499 var r3 = $(this.getId() + "_row3"); 500 if (r2.visible()) { 501 r2.hide(); 502 r3.hide(); 503 } else { 504 r2.show(); 505 r3.show(); 506 } 507 508 // Store new location/size if need be 509 this._saveCookie() 510 }, 511 512 maximize: function() { 513 if (this.storedLocation != null) { 514 this._restoreLocation(); 515 if(this.iefix) 516 this.iefix.hide(); 517 } 518 else { 519 this._storeLocation(); 520 Windows.unsetOverflow(this); 521 522 var windowScroll = WindowUtilities.getWindowScroll(); 523 var pageSize = WindowUtilities.getPageSize(); 524 525 this.element.setStyle(this.useLeft ? {left: windowScroll.left} : {right: windowScroll.left}); 526 this.element.setStyle(this.useTop ? {top: windowScroll.top} : {bottom: windowScroll.top}); 527 528 this.setSize(pageSize.windowWidth - this.widthW - this.widthE, pageSize.windowHeight - this.heightN - this.heightS) 529 this.toFront(); 530 if (this.iefix) 531 this._fixIEOverlapping(); 532 } 533 534 // Store new location/size if need be 535 this._saveCookie() 536 }, 537 538 isMinimized: function() { 539 var r2 = $(this.getId() + "_row2"); 540 return !r2.visible(); 541 }, 542 543 isMaximized: function() { 544 return (this.storedLocation != null); 545 }, 546 547 setOpacity: function(opacity) { 548 if (Element.setOpacity) 549 Element.setOpacity(this.element, opacity); 550 }, 551 552 setZIndex: function(zindex) { 553 this.element.setStyle({zIndex: zindex}); 554 Windows.updateZindex(zindex, this); 555 }, 556 557 setTitle: function(newTitle) { 558 if (!newTitle) 559 newTitle = " "; 560 Element.update(this.element.id + '_top', newTitle); 561 }, 562 563 setStatusBar: function(element) { 564 var statusBar = $(this.getId() + "_bottom"); 565 566 if (typeof(element) == "object") { 567 if (this.bottombar.firstChild) 568 this.bottombar.replaceChild(element, this.bottombar.firstChild); 569 else 570 this.bottombar.appendChild(element); 571 } 572 else 573 this.bottombar.innerHTML = element; 574 }, 575 576 _checkIEOverlapping: function() { 577 if(!this.iefix && (navigator.appVersion.indexOf('MSIE')>0) && (navigator.userAgent.indexOf('Opera')<0) && (this.element.getStyle('position')=='absolute')) {
578 new Insertion.After(this.element.id, '<iframe id="' + this.element.id + '_iefix" '+ 'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' + 'src="javascript:false;" frameborder="0" scrolling="no"></iframe>'); 579 this.iefix = $(this.element.id+'_iefix'); 580 } 581 if(this.iefix) 582 setTimeout(this._fixIEOverlapping.bind(this), 50); 583 }, 584 585 _fixIEOverlapping: function() { 586 Position.clone(this.element, this.iefix); 587 this.iefix.style.zIndex = this.element.style.zIndex - 1; 588 this.iefix.show(); 589 }, 590 591 _getWindowBorderSize: function(event) { 592 // Hack to get real window border size!! 593 var div = this._createHiddenDiv(this.className + "_n") 594 this.heightN = Element.getDimensions(div).height; 595 div.parentNode.removeChild(div) 596 597 var div = this._createHiddenDiv(this.className + "_s") 598 this.heightS = Element.getDimensions(div).height; 599 div.parentNode.removeChild(div) 600 601 var div = this._createHiddenDiv(this.className + "_e") 602 this.widthE = Element.getDimensions(div).width; 603 div.parentNode.removeChild(div) 604 605 var div = this._createHiddenDiv(this.className + "_w") 606 this.widthW = Element.getDimensions(div).width; 607 div.parentNode.removeChild(div); 608 609 if (this.doMaximize) 610 this.maximize(); 611 }, 612 613 _createHiddenDiv: function(className) { 614 var objBody = document.getElementsByTagName("body").item(0); 615 var win = document.createElement("div"); 616 win.setAttribute('id', this.element.id+ "_tmp"); 617 win.className = className; 618 win.style.display = 'none' 619 win.innerHTML = '' 620 objBody.insertBefore(win, objBody.firstChild) 621 return win 622 }, 623 624 _storeLocation: function() { 625 if (this.storedLocation == null) { 626 this.storedLocation = {useTop: this.useTop, useLeft: this.useLeft, 627 top: this.element.getStyle('top'), bottom: this.element.getStyle('bottom'), 628 left: this.element.getStyle('left'), right: this.element.getStyle('right'), 629 width: this.width, height: this.height }; 630 } 631 }, 632 633 _restoreLocation: function() { 634 if (this.storedLocation != null) { 635 this.useLeft = this.storedLocation.useLeft; 636 this.useTop = this.storedLocation.useTop; 637 638 this.element.setStyle(this.useLeft ? {left: this.storedLocation.left} : {right: this.storedLocation.right}); 639 this.element.setStyle(this.useTop ? {top: this.storedLocation.top} : {bottom: this.storedLocation.bottom}); 640 this.setSize(this.storedLocation.width, this.storedLocation.height); 641 642 Windows.resetOverflow(); 643 this._removeStoreLocation(); 644 } 645 }, 646 647 _removeStoreLocation: function() { 648 this.storedLocation = null; 649 }, 650 651 _saveCookie: function() { 652 if (this.cookie) { 653 var value = ""; 654 if (this.useLeft) 655 value += "l:" + (this.storedLocation ? this.storedLocation.left : this.element.getStyle('left')) 656 else 657 value += "r:" + (this.storedLocation ? this.storedLocation.right : this.element.getStyle('right')) 658 if (this.useTop) 659 value += ",t:" + (this.storedLocation ? this.storedLocation.top : this.element.getStyle('top')) 660 else 661 value += ",b:" + (this.storedLocation ? this.storedLocation.bottom :this.element.getStyle('bottom')) 662 663 value += "," + (this.storedLocation ? this.storedLocation.width : this.width); 664 value += "," + (this.storedLocation ? this.storedLocation.height : this.height); 665 value += "," + this.isMinimized(); 666 value += "," + this.isMaximized();
667 WindowUtilities.setCookie(value, this.cookie) 668 } 669 } 670}; 671 672// Windows containers, register all page windows 673var Windows = { 674 windows: [], 675 observers: [], 676 focusedWindow: null, 677 maxZIndex: 0, 678 679 addObserver: function(observer) { 680 this.observers.push(observer); 681 }, 682 683 removeObserver: function(observer) { 684 this.observers = this.observers.reject( function(o) { return o==observer }); 685 }, 686 687 notify: function(eventName, win) { // onStartResize(), onEndResize(), onStartMove(), onEndMove(), onClose(), onDestroy() 688 this.observers.each( function(o) {if(o[eventName]) o[eventName](eventName, win);}); 689 }, 690 691 // Gets window from its id 692 getWindow: function(id) { 693 return this.windows.detect(function(d) { return d.getId() ==id }); 694 }, 695 696 // Registers a new window (called by Windows constructor) 697 register: function(win) { 698 this.windows.push(win); 699 }, 700 701 // Unregisters a window (called by Windows destructor) 702 unregister: function(win) { 703 this.windows = this.windows.reject(function(d) { return d==win }); 704 }, 705 706 // Closes a window with its id 707 close: function(id) { 708 win = this.getWindow(id); 709 // Asks delegate if exists 710 if (win) { 711 if (win.getDelegate() && ! win.getDelegate().canClose(win)) 712 return; 713 714 this.notify("onClose", win); 715 win.hide(); 716 if (win.destroyOnClose) 717 win.destroy(); 718 } 719 }, 720 721 // Closes all windows 722 closeAll: function() { 723 this.windows.each( function(w) {Windows.close(w.getId())} ); 724 }, 725 726 // Minimizes a window with its id 727 minimize: function(id) { 728 win = this.getWindow(id); 729 win.minimize(); 730 }, 731 732 // Maximizes a window with its id 733 maximize: function(id) { 734 win = this.getWindow(id); 735 win.maximize(); 736 }, 737 738 unsetOverflow: function(except) { 739 this.windows.each(function(d) { d.oldOverflow = d.getContent().getStyle("overflow") || "auto" ; d.getContent().setStyle({overflow: "hidden"}) }); 740 if (except && except.oldOverflow) 741 except.getContent().setStyle({overflow: except.oldOverflow}); 742 }, 743 744 resetOverflow: function() { 745 this.windows.each(function(d) { if (d.oldOverflow) d.getContent().setStyle({overflow: d.oldOverflow}) }); 746 }, 747 748 updateZindex: function(zindex, win) { 749 if (zindex > this.maxZIndex) 750 this.maxZIndex = zindex; 751 this.focusedWindow = win; 752 } 753}; 754 755var Dialog = { 756 win: null, 757 758 confirm: function(message, parameters) { 759 parameters = parameters || {}; 760 var okLabel = parameters.okLabel ? parameters.okLabel : "Ok"; 761 var cancelLabel = parameters.cancelLabel ? parameters.cancelLabel : "Cancel"; 762 763 var windowParam = parameters.windowParameters || {}; 764 windowParam.className = windowParam.className || "alert"; 765 766 buttonClass = parameters.buttonClass ? "class=" + parameters.buttonClass : "" 767 var content = "\ 768 <div class='" + windowParam.className + "_message'>" + message + "</div>\ 769 <div class='" + windowParam.className + "_buttons'>\ 770 <input type='button' value='" + okLabel + "' onclick='Dialog.okCallback()'" + buttonClass + "/>\ 771 <input type='button' value='" + cancelLabel + "' onclick='Dialog.cancelCallback()" + buttonClass + "'/>\ 772 </div>\ 773 "; 774 this.openDialog(content, parameters) 775 return this.win 776 }, 777 778 alert: function(message, parameters) { 779 parameters = parameters || {}; 780 var okLabel = parameters.okLabel ? parameters.okLabel : "Ok"; 781 782 var windowParam = parameters.windowParameters || {}; 783 windowParam.className = windowParam.className || "alert"; 784 785 buttonClass = parameters.buttonClass ? "class=" + parameters.buttonClass : "" 786 var content = "\ 787 <div class='" + windowParam.className + "_message'>" + message + "</div>\ 788 <div class='" + windowParam.className + "_buttons'>\ 789 <input type='button' value='" + okLabel + "' onclick='Dialog.okCallback()" + buttonClass + "'/>\ 790 </div>"; 791 return this.openDialog(content, parameters) 792 }, 793 794 info: function(message, parameters) { 795 parameters = parameters || {}; 796 parameters.windowParameters = parameters.windowParameters || {}; 797 798 var className = parameters.windowParameters.className || "alert"; 799 800 var content = "<div id='modal_dialog_message' class='" + className + "_message'>" + message + "</div>"; 801 if (parameters.showProgress) 802 content += "<div id='modal_dialog_progress' class='" + className + "_progress'> </div>"; 803 804 parameters.windowParameters.ok = null; 805 parameters.windowParameters.cancel = null; 806 parameters.windowParameters.className = className; 807 808 return this.openDialog(content, parameters) 809 }, 810 811 setInfoMessage: function(message) { 812 $('modal_dialog_message').update(message); 813 }, 814 815 closeInfo: function() {
816 Windows.close('modal_dialog'); 817 }, 818 819 openDialog: function(content, parameters) { 820 // remove old dialog 821 if (this.win) 822 this.win.destroy(); 823 824 var windowParam = parameters && parameters.windowParameters ? parameters.windowParameters : {}; 825 windowParam.resizable = windowParam.resizable || false; 826 827 windowParam.effectOptions = windowParam.effectOptions || {duration: 1}; 828 829 this.win = new Window('modal_dialog', windowParam); 830 this.win.getContent().innerHTML = content; 831 this.win.showCenter(true); 832 833 this.win.cancelCallback = parameters.cancel; 834 this.win.okCallback = parameters.ok; 835 836 if (! this.eventResize) 837 this.eventResize = this.recenter.bindAsEventListener(this); 838 839 Event.observe(window, "resize", this.eventResize); 840 Event.observe(window, "scroll", this.eventResize); 841 842 return this.win; 843 }, 844 845 okCallback: function() { 846 this.win.hide(); 847 Event.stopObserving(window, "resize", this.eventResize); 848 Event.stopObserving(window, "scroll", this.eventResize); 849 850 if (this.win.okCallback) 851 this.win.okCallback(this.win); 852 }, 853 854 cancelCallback: function() { 855 this.win.hide(); 856 Event.stopObserving(window, "resize", this.eventResize); 857 Event.stopObserving(window, "scroll", this.eventResize); 858 859 if (this.win.cancelCallback) 860 this.win.cancelCallback(this.win); 861 }, 862 863 recenter: function(event) { 864 var pageSize = WindowUtilities.getPageSize(); 865 // set height of Overlay to take up whole page and show 866 if ($('overlay_modal')) 867 $('overlay_modal').style.height = (pageSize.pageHeight + 'px'); 868 869 this.win.center(); 870 } 871} 872/* 873 Based on Lightbox JS: Fullsize Image Overlays 874 by Lokesh Dhakar - http://www.huddletogether.com 875 876 For more information on this script, visit: 877 http://huddletogether.com/projects/lightbox/ 878 879 Licensed under the Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/ 880 (basically, do anything you want, just leave my name and link) 881*/ 882 883var isIE = navigator.appVersion.match(/MSIE/) == "MSIE"; 884 885var WindowUtilities = { 886 // From script.aculo.us 887 getWindowScroll: function() { 888 var w = window; 889 var T, L, W, H; 890 with (w.document) { 891 if (w.document.documentElement && documentElement.scrollTop) { 892 T = documentElement.scrollTop; 893 L = documentElement.scrollLeft; 894 } else if (w.document.body) { 895 T = body.scrollTop; 896 L = body.scrollLeft; 897 } 898 if (w.innerWidth) { 899 W = w.innerWidth; 900 H = w.innerHeight; 901 } else if (w.document.documentElement && documentElement.clientWidth) { 902 W = documentElement.clientWidth; 903 H = documentElement.clientHeight; 904 } else { 905 W = body.offsetWidth; 906 H = body.offsetHeight 907 } 908 } 909 return { top: T, left: L, width: W, height: H }; 910 911 }, 912 // 913 // getPageSize() 914 // Returns array with page width, height and window width, height 915 // Core code from - quirksmode.org 916 // Edit for Firefox by pHaez 917 // 918 getPageSize: function(){ 919 var xScroll, yScroll; 920 921 if (window.innerHeight && window.scrollMaxY) { 922 xScroll = document.body.scrollWidth; 923 yScroll = window.innerHeight + window.scrollMaxY; 924 } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac 925 xScroll = document.body.scrollWidth; 926 yScroll = document.body.scrollHeight; 927 } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari 928 xScroll = document.body.offsetWidth; 929 yScroll = document.body.offsetHeight; 930 } 931 932 var windowWidth, windowHeight; 933 934 if (self.innerHeight) { // all except Explorer 935 windowWidth = self.innerWidth; 936 windowHeight = self.innerHeight; 937 } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode 938 windowWidth = document.documentElement.clientWidth; 939 windowHeight = document.documentElement.clientHeight; 940 } else if (document.body) { // other Explorers 941 windowWidth = document.body.clientWidth; 942 windowHeight = document.body.clientHeight; 943 } 944 var pageHeight, pageWidth; 945 946 // for small pages with total height less then height of the viewport 947 if(yScroll < windowHeight){ 948 pageHeight = windowHeight; 949 } else { 950 pageHeight = yScroll; 951 } 952 953 // for small pages with total width less then width of the viewport 954 if(xScroll < windowWidth){ 955 pageWidth = windowWidth; 956 } else { 957 pageWidth = xScroll; 958 } 959 960 return {pageWidth: pageWidth ,pageHeight: pageHeight , windowWidth: windowWidth, windowHeight: windowHeight}; 961 }, 962 963 disableScreen: function(className) { 964 WindowUtilities.initLightbox(className);
965 var objBody = document.getElementsByTagName("body").item(0); 966 967 // prep objects 968 var objOverlay = $('overlay_modal'); 969 970 var pageSize = WindowUtilities.getPageSize(); 971 972 // Hide select boxes as they will 'peek' through the image in IE 973 if (isIE) { 974 selects = document.getElementsByTagName("select"); 975 for (var i = 0; i != selects.length; i++) { 976 selects[i].style.visibility = "hidden"; 977 } 978 } 979 980 // set height of Overlay to take up whole page and show 981 objOverlay.style.height = (pageSize.pageHeight + 'px'); 982 objOverlay.style.display = 'block'; 983 }, 984 985 enableScreen: function() { 986 var objOverlay = $('overlay_modal'); 987 if (objOverlay) { 988 // hide lightbox and overlay 989 objOverlay.style.display = 'none'; 990 991 // make select boxes visible 992 if (isIE) { 993 selects = document.getElementsByTagName("select"); 994 for (var i = 0; i != selects.length; i++) { 995 selects[i].style.visibility = "visible"; 996 } 997 } 998 objOverlay.parentNode.removeChild(objOverlay); 999 } 1000 }, 1001 1002 // initLightbox() 1003 // Function runs on window load, going through link tags looking for rel="lightbox". 1004 // These links receive onclick events that enable the lightbox display for their targets. 1005 // The function also inserts html markup at the top of the page which will be used as a 1006 // container for the overlay pattern and the inline image. 1007 initLightbox: function(className) { 1008 // Already done, just update zIndex 1009 if ($('overlay_modal')) { 1010 Element.setStyle('overlay_modal', {zIndex: Windows.maxZIndex + 10}); 1011 } 1012 // create overlay div and hardcode some functional styles (aesthetic styles are in CSS file) 1013 else { 1014 var objBody = document.getElementsByTagName("body").item(0); 1015 var objOverlay = document.createElement("div"); 1016 objOverlay.setAttribute('id', 'overlay_modal'); 1017 objOverlay.className = "overlay_" + className 1018 objOverlay.style.display = 'none'; 1019 objOverlay.style.position = 'absolute'; 1020 objOverlay.style.top = '0'; 1021 objOverlay.style.left = '0'; 1022 objOverlay.style.zIndex = Windows.maxZIndex + 10; 1023 objOverlay.style.width = '100%'; 1024 1025 objBody.insertBefore(objOverlay, objBody.firstChild); 1026 } 1027 }, 1028 1029 setCookie: function(value, parameters) { 1030 document.cookie= parameters[0] + "=" + escape(value) + 1031 ((parameters[1]) ? "; expires=" + parameters[1].toGMTString() : "") + 1032 ((parameters[2]) ? "; path=" + parameters[2] : "") + 1033 ((parameters[3]) ? "; domain=" + parameters[3] : "") + 1034 ((parameters[4]) ? "; secure" : ""); 1035 }, 1036 1037 getCookie: function(name) { 1038 var dc = document.cookie; 1039 var prefix = name + "="; 1040 var begin = dc.indexOf("; " + prefix); 1041 if (begin == -1) { 1042 begin = dc.indexOf(prefix); 1043 if (begin != 0) return null; 1044 } else { 1045 begin += 2; 1046 } 1047 var end = document.cookie.indexOf(";", begin); 1048 if (end == -1) { 1049 end = dc.length; 1050 } 1051 return unescape(dc.substring(begin + prefix.length, end)); 1052 } 1053} 1054 1055
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.