// Alg. Funktionen function getTickCount () { var T = new Date(); return T.getMilliseconds() + T.getSeconds() * 1000 + T.getMinutes() * 60000 + T.getHours() * 3600000 + T.getDay() * 86400000; } function clone (obj, runConstructors, chain) { // Abgeaendert von http://forum.de.selfhtml.org/archiv/2009/3/t185276/ if (obj == null || typeof(obj) != 'object') return obj; if (!chain) chain = new Array(obj); else { for (var i = 0; i < chain.length; i++) if (chain[i] == obj) return obj; chain.push(obj); } if (runConstructors) var c = new obj.constructor(); else var c = new Object(); for (var key in obj) if (typeof(obj) == 'object') c[key] = clone(obj[key], runConstructors, chain); else c[key] = obj[key]; return c; } function JSWEffect_terminate (win, _break) { if (!win.effect) return; if (win.effect['interval']) window.clearInterval(win.effect['interval']); win.effect['interval'] = null; win.effect['stop'] = Number.NaN; var b = false; if (!_break) b = win.effect['fkt'](win); win.effect = null; return b; } // Effekte function JSWEffect_Blend (win, duration, onTerminate, opacity) { if (duration) { // start if (!window.getComputedStyle) return; // Keinen Effekt fuer alten IE var style = window.getComputedStyle(win.el['OuterBox']); if (JSWEffect_terminate(win, (win.effect && win.effect['fkt'] == JSWEffect_Blend && !win.effect.onTerminate)?true:false)) return; // Falls aktiv, laufenden Effekt beenden; falls laufender Effekt JSWEffect_Blend ist, nur abbrechen win.effect = new Object(); win.effect['fkt'] = JSWEffect_Blend; win.effect['onTerminate'] = onTerminate; win.effect['start'] = getTickCount(); win.effect['stop'] = win.effect['start'] + duration; if (style && style['visibility'] == 'visible') win.effect['startOP'] = parseFloat(style['opacity']); else { win.effect['startOP'] = 0; win.el['OuterBox'].style.opacity = 0; win.el['OuterBox'].style.visibility = 'visible'; } win.effect['stopOP'] = opacity; win.effect['interval'] = window.setInterval(JSWEffect_Blend, 20, win); } var t = getTickCount(); if (isNaN(win.effect['stop']) || t >= win.effect['stop']) { // stop if (win.effect['interval']) window.clearInterval(win.effect['interval']); win.effect['interval'] = null; win.el['OuterBox'].style.opacity = win.effect['stopOP']; var onTerm = win.effect['onTerminate']; win.effect = null; if (onTerm) return onTerm(win); } else { // effect var s = (t - win.effect['start']) / (win.effect['stop'] - win.effect['start']); win.el['OuterBox'].style.opacity = s * win.effect['stopOP'] + (1-s) * win.effect['startOP']; } } function JSWEffect_ThrowBorder (win, duration, onTerminate, top, left, width, height, reverse) { if (duration) { // start if (JSWEffect_terminate(win)) return; // Falls aktiv, laufenden Effekt beenden win.effect = new Object(); win.effect['fkt'] = JSWEffect_ThrowBorder; win.effect['start'] = getTickCount(); win.effect['stop'] = win.effect['start'] + duration; win.effect['onTerminate'] = onTerminate; var p = win.getWindowPos(); win.effect['startTop'] = (reverse)?top:p[1]; win.effect['startLeft'] = (reverse)?left:p[0]; win.effect['startWidth'] = (reverse)?width:win.el['OuterBox'].offsetWidth; win.effect['startHeight'] = (reverse)?height:win.el['OuterBox'].offsetHeight; win.effect['stopTop'] = (reverse)?p[1]:top; win.effect['stopLeft'] = (reverse)?p[0]:left; win.effect['stopWidth'] = (reverse)?win.el['OuterBox'].offsetWidth:width; win.effect['stopHeight'] = (reverse)?win.el['OuterBox'].offsetHeight:height; win.effect['border'] = document.createElement('div'); win.effect['border'].className = 'JSW ThrowingBorder'; document.body.appendChild(win.effect['border']); win.effect['border'].style.top = win.effect['startTop'] + 'px'; win.effect['border'].style.left = win.effect['startLeft'] + 'px'; win.effect['border'].style.width = win.effect['startWidth'] + 'px'; win.effect['border'].style.height = win.effect['startHeight'] + 'px'; if (win.mgr) win.effect['border'].style.zIndex = win.mgr.maxZ + 1; win.effect['interval'] = window.setInterval(JSWEffect_ThrowBorder, 20, win); } var t = getTickCount(); if (isNaN(win.effect['stop']) || t >= win.effect['stop']) { // stop if (win.effect['interval']) window.clearInterval(win.effect['interval']); win.effect['interval'] = null; document.body.removeChild(win.effect['border']); win.effect['border'] = null; win.setOffsetPosition(win.effect['stopTop'], win.effect['stopLeft'], win.effect['stopWidth'], win.effect['stopHeight']); var onTerm = win.effect['onTerminate']; win.effect = null; if (onTerm) return onTerm(win); } else { // effect var s = (t - win.effect['start']) / (win.effect['stop'] - win.effect['start']); win.effect['border'].style.top = s * win.effect['stopTop'] + (1-s) * win.effect['startTop'] + 'px'; win.effect['border'].style.left = s * win.effect['stopLeft'] + (1-s) * win.effect['startLeft'] + 'px'; win.effect['border'].style.width = s * win.effect['stopWidth'] + (1-s) * win.effect['startWidth'] + 'px'; win.effect['border'].style.height = s * win.effect['stopHeight'] + (1-s) * win.effect['startHeight'] + 'px'; } } // JSWindow function JSWindow (_el) { // Objekte/Arrays initialisieren this.eventListeners = new Array(); this.selfEventListeners = new Object(); this.parentElement = (_el)?_el.parentElement:null; this.appended = (this.parentElement)?true:false; this.el = new Object(); this.el['OuterBox'] = _el; this.visible = this.appended; this.pos = new Object(); this.pos['position'] = 'absolute'; // Alle Elemente verlinken/erstellen var search = true; // falls (spaeter) auf falls gesetzt, so spart sich autoCreateEl die Suche und erstellt das ELement sofort. var _this = this; function autoCreateEl(tag, className, parentEl) { // versucht, ein Element vom typ tag und mit entsprechendem className in parentEl zu finden. Wenn nicht vorhanden, wird ein entsprechendes Element erstellt. if (search) for (var i = 0; i < parentEl.childNodes.length; i++) { if (parentEl.childNodes[i].nodeType != 1) continue; if (parentEl.childNodes[i].nodeName.toLowerCase() != tag) continue; var _className = ' '+parentEl.childNodes[i].className+' '; if (_className.indexOf(' '+className+' ') < 0) continue; if (_className.indexOf(' JSW ') < 0) continue; _this.el[className] = parentEl.childNodes[i]; return; } _this.el[className] = document.createElement(tag); _this.el[className].className = 'JSW ' + className; if (parentEl) parentEl.appendChild(_this.el[className]); } if (!this.el['OuterBox']) { search = false; this.el['OuterBox'] = document.createElement('div'); this.el['OuterBox'].className = 'JSW OuterBox'; } this.el['OuterBox'].jswLinkedWindow = this; autoCreateEl('div', 'InnerBox', this.el['OuterBox']); autoCreateEl('div', 'BorderTop', this.el['OuterBox']); autoCreateEl('div', 'BorderLeft', this.el['OuterBox']); autoCreateEl('div', 'BorderRight', this.el['OuterBox']); autoCreateEl('div', 'BorderBottom', this.el['OuterBox']); autoCreateEl('div', 'EdgeTopLeft', this.el['OuterBox']); autoCreateEl('div', 'EdgeTopRight', this.el['OuterBox']); autoCreateEl('div', 'EdgeBottomLeft', this.el['OuterBox']); autoCreateEl('div', 'EdgeBottomRight', this.el['OuterBox']); autoCreateEl('div', 'Bar', this.el['OuterBox']); autoCreateEl('span', 'Title', this.el['Bar']); autoCreateEl('div', 'Buttons', this.el['Bar']); autoCreateEl('a', 'ButtonExclude', this.el['Buttons']); this.el['ButtonExclude'].href = 'javascript: \/* '+this.lang.get('newWin')+' *\/'; autoCreateEl('a', 'ButtonMinimize', this.el['Buttons']); this.el['ButtonMinimize'].href = 'javascript: \/* '+this.lang.get('minimize')+' *\/'; autoCreateEl('a', 'ButtonMaximize', this.el['Buttons']); this.el['ButtonMaximize'].href = 'javascript: \/* '+this.lang.get('maximize')+' *\/'; autoCreateEl('a', 'ButtonClose', this.el['Buttons']); this.el['ButtonClose'].href = 'javascript: \/* '+this.lang.get('close')+' *\/'; // Kontextmenue this.el['Bar'].contextmenu = new Array( {'text':this.lang.get('newWin'), 'obj':this, 'fkt':this.exclude, 'isenabled':function(){return _this.excludable;}}, {'text':this.lang.get('minimize'), 'obj':this, 'fkt':this.minimize, 'isenabled':function(){return _this.minimizable;}}, {'text':this.lang.get('maximize'), 'obj':this, 'fkt':this.maximize, 'isenabled':function(){return _this.maximizable;}}, {'text':this.lang.get('close'), 'obj':this, 'fkt':this.hide, 'isenabled':function(){return _this.closable;}} ); // Positionsstyle feststellen if (_el) { this.offsetParent = this.el['OuterBox'].offsetParent; var style = (window.getComputedStyle)?window.getComputedStyle(this.el['OuterBox'], null):this.el['OuterBox'].currentStyle; if (!style) throw 'Existing Element is not completely initialized. This can be the case, if the element is not inserted into the document or sometimes if the site is in an iframe.'; var realStyle = new Object(); var s = this.el['OuterBox'].getAttribute('style', false).replace(/\s/g, '').toLowerCase().split(';'); for (var i = 0; i < s.length; i++) { s[i] = s[i].split(':'); if (!s[i][0]) continue; realStyle[s[i][0]] = s[i][1]; } var posNumX = 0; var posNumY = 0; this.pos['position'] = style.position; function positionToInt (p, x) { if (realStyle[p] && realStyle[p] != 'auto') { if (x) posNumX++; else posNumY++; _this.pos[p] = parseInt(style[p]); if (realStyle[p].indexOf('%') > 0) _this.pos[p+'Percent'] = true; else _this.pos[p+'Percent'] = false; } else { _this.pos[p] = Number.NaN; _this.pos[p+'Percent'] = false; } } positionToInt('top', false); positionToInt('left', true); positionToInt('right', true); positionToInt('bottom', false); positionToInt('width', true); positionToInt('height', false); if (posNumX == 0) { posNumX++; this.pos['left'] = this.el['OuterBox'].offsetLeft; } if (posNumY == 0) { posNumY++; this.pos['top'] = this.el['OuterBox'].offsetTop; } if (posNumX == 1) { if (isNaN(this.pos['width'])) this.pos['width'] = this.el['OuterBox'].offsetWidth; else this.pos['left'] = this.el['OuterBox'].offsetLeft; } if (posNumY == 1) { if (isNaN(this.pos['height'])) this.pos['height'] = this.el['OuterBox'].offsetHeight; else this.pos['top'] = this.el['OuterBox'].offsetTop; } if (posNumX == 3) this.pos['right'] = Number.NaN; if (posNumY == 3) this.pos['bottom'] = Number.NaN; } else { this.pos.top = 0; this.pos.left = 0; this.pos.width = this.minWidth; this.pos.height = this.minHeight; } // Event-Listener setzen this.onEvent(this.el['OuterBox'], 'mousedown', this.mouseDown); this.onEvent(document, 'resize', this.documentResize); this.onEvent(this.el['ButtonExclude'], 'click', function () { this.exclude(true); }); this.onEvent(this.el['ButtonMinimize'], 'click', this.minimize); this.onEvent(this.el['ButtonMaximize'], 'click', function () { if (this.maximized) this.normalize(); else this.maximize(); }); this.onEvent(this.el['ButtonClose'], 'click', this.hide); // setter aufrufen var s = ' '+this.el['Buttons'].className+' '; if (s.indexOf(' nonmaximizable ') >= 0) this.maximizable = false; if (s.indexOf(' nonminimizable ') >= 0) this.minimizable = false; if (s.indexOf(' nonclosable ') >= 0) this.closable = false; if (s.indexOf(' nonexcludable ') >= 0) this.excludable = false; s = ' '+this.el['OuterBox'].className+' '; if (s.indexOf(' nonresizable ') >= 0) this.resizable = false; if (s.indexOf(' nonmovable ') >= 0) this.movable = false; if (s.indexOf(' autoheight ') >= 0) this.autoHeight = true; if (s.indexOf(' autowidth ') >= 0) this.autoWidth = true; if (this.el['Title'].innerHTML != '') this.title = this.el['Title'].innerHTML; for (var i = 0; i < this.el['Bar'].getElementsByTagName('img'); i++) { var ic = this.el['Bar'].getElementsByTagName('img')[i]; if ((' '+ic.className+' ').indexOf('Icon') >= 0) { this.el['Bar'].removeChild(ic); this.icon = ic.src; } } // sonstiges if (this.hasAtr(this.el['OuterBox'], 'maximized')) this.maximize(); this.setOrRmAtr(this.el['Buttons'], 'nonexcludable', !this._excludable); if (_el) this.freeOnHide = false; } JSWindow.prototype = { lang : { de : { minimize:'Minimieren', maximize:'Maximieren', close:'Schliessen', newWin:'In neuem Fenster oeffnen' }, en : { minimize:'minimize', maximize:'maximize', close:'close', newWin:'open in new window' }, get : function (key) { if (!this.l) { this.l = navigator.language; if (!this[this.l]) this.l = 'en'; } return (this[this.l][key])?this[this.l][key]:key; } }, // private eventListeners : null, // EventListener, die von diesem Objekt gesetzt wurden selfEventListeners : null, // EventListener, die auf dieses Objekt gesetzt wurden disabledCount : 0, // public readonly (darf von public gelesen werden, aber nur von ausgewaehlten Scripts geschrieben) parentElement : null, appended : false, el : null, visible : false, pos : null, effect : null, maximized : false, minimized : false, excluded : false, freed : false, // public _resizable : true, get resizable () { return this._resizable; }, set resizable (v) { this._resizable = v; this.setOrRmAtr(this.el['OuterBox'], 'nonresizable', !v); }, _movable : true, get movable () { return this._movable; }, set movable (v) { this._movable = v; this.setOrRmAtr(this.el['OuterBox'], 'nonmovable', !v); }, effects : null, mainFrame : null, minWidth : 40, minHeight : 25, freeOnHide : true, _maximizable : true, get maximizable () { return this._maximizable; }, set maximizable (v) { this._maximizable = v; this.setOrRmAtr(this.el['Buttons'], 'nonmaximizable', !v); }, _minimizable : true, get minimizable () { return this._minimizable; }, set minimizable (v) { this._minimizable = v; this.setOrRmAtr(this.el['Buttons'], 'nonminimizable', !v); }, _closable : true, get closable () { return this._closable; }, set closable (v) { this._closable = v; this.setOrRmAtr(this.el['Buttons'], 'nonclosable', !v); }, _excludable : false, get excludable () { return this._excludable; }, set excludable (v) { this._excludable = v; this.setOrRmAtr(this.el['Buttons'], 'nonexcludable', !v); }, minimizePoint : function () { return new Array(0, 0); }, minimalVisible : new Array(0, -10, -10, -10), _title : '', get title () { return this._title; }, set title (v) { this.setTitle(v); }, _icon : '', get icon () { return this._icon; }, set icon (v) { this.setIcon(v); }, _autoHeight : false, get autoHeight () { return this._autoHeight; }, set autoHeight (v) { if (this.freed) throw 'Object is freed'; if (v == this._autoHeight) return; this._autoHeight = v; this.setOrRmAtr(this.el['OuterBox'], 'autoheight', v); if (this.mainFrame && this.mainFrame.communicator) this.mainFrame.communicator.autoHeight = v; if (v) { if (isNaN(this.pos.height)) this.el['OuterBox'].style.bottom = 'auto'; else this.el['OuterBox'].style.height = 'auto'; } else { this.actualizePos(); this.setPos(); if (this.mainFrame) this.mainFrame.style.height = '100%'; } }, _autoWidth : false, get autoWidth () { return this._autoWidth; }, set autoWidth (v) { if (this.freed) throw 'Object is freed'; if (v == this._autoWidth) return; this._autoWidth = v; this.setOrRmAtr(this.el['OuterBox'], 'autowidth', v); if (this.mainFrame && this.mainFrame.communicator) this.mainFrame.communicator.autoWidth = v; if (v) { if (isNaN(this.pos.width)) this.el['OuterBox'].style.right = 'auto'; else this.el['OuterBox'].style.width = 'auto'; } else { this.actualizePos(); this.setPos(); if (this.mainFrame) this.mainFrame.style.width = '100%'; } }, extendBar : /* public */ function () { if (this.el.BarExtension) return this.el.BarExtension; this.el.BarExtension = document.createElement('div'); this.el.BarExtension.className = 'JSW BarExtension'; function onResize () { this.el.BarExtension.style.height = this.el.BarExtension.scrollHeight + 'px'; this.el.OuterBox.style.paddingTop = (this.el.BorderTop.offsetHeight + this.el.Bar.offsetHeight + this.el.BarExtension.offsetHeight) + 'px'; } this.onEvent(this.el.BarExtension, 'overflow', onResize); this.onEvent(this.el.BarExtension, 'underflow', onResize); this.el.OuterBox.appendChild(this.el.BarExtension); return this.el.BarExtension; }, setIcon : /* protected */ function (v) { // to be overridden if (v == '' && this.el['Icon']) { this.el['Bar'].removeChild(this.el['Icon']); delete this.el['Icon']; } if (v != '' && !this.el['Icon']) { this.el['Icon'] = document.createElement('img'); this.el['Icon'].className = 'JSW Icon'; this.el['Bar'].insertBefore(this.el['Icon'], this.el['Title']); } this._icon = v; if (v != '') this.el['Icon'].src = v; }, setTitle : /* protected */ function (v) { // to be overridden if (this.freed) throw 'Object is freed'; this.el['Title'].innerHTML = v; this._title = v; }, addEventListener : /* public */ function (type, fkt) { if (this.freed) throw 'Object is freed'; if (!this.selfEventListeners[type]) this.selfEventListeners[type] = new Array(); this.selfEventListeners[type].push(fkt); }, removeEventListener : /* public */ function (type, fkt) { if (this.freed) throw 'Object is freed'; if (!this.selfEventListeners[type]) return; var i = 0; while (i < this.selfEventListeners[type].length) if (this.selfEventListeners[type][i] == fkt) this.selfEventListeners[type].splice(i, 1); else i++; if (this.selfEventListeners[type].length == 0) delete this.selfEventListeners[type]; }, callEventListener : /* protected */ function (type, param) { try { // try notwendig, weil Fenster durch einen EventListener freigegeben werden koennte if (this.selfEventListeners[type]) for (var i = 0; i < this.selfEventListeners[type].length; i++) this.selfEventListeners[type][i](this, param); if (this.mgr && this.mgr.eventListeners[type]) for (var i = 0; i < this.mgr.eventListeners[type].length; i++) this.mgr.eventListeners[type][i](this, param); } catch (e) {} }, disable : /* public */ function () { if (this.freed) throw 'Object is freed'; if (this.disabledCount == 0) { this.el['Disabled'] = document.createElement('div'); this.el['Disabled'].className = 'JSW Disabled'; this.el['OuterBox'].appendChild(this.el['Disabled']); } this.disabledCount++; }, enable : /* public */ function () { if (this.freed) throw 'Object is freed'; this.disabledCount--; if (this.disabledCount <= 0) { this.disabledCount = 0; this.el['OuterBox'].removeChild(this.el['Disabled']); } }, hiddenCover : /* protected */ function (covered) { if (covered) { if (this.el['FrameCover']) return; this.el['FrameCover'] = document.createElement('div'); this.el['FrameCover'].className = 'JSW FrameCover'; this.el['OuterBox'].appendChild(this.el['FrameCover']); } else if (this.el['FrameCover']) { this.el['OuterBox'].removeChild(this.el['FrameCover']); this.el['FrameCover'] = null; } }, showFrameload : /* public */ function (parent) { if (this.freed) throw 'Object is freed'; if (this.appended) return; if (parent) this.parentElement = parent; this.el['OuterBox'].style.visibility = 'hidden'; this.parentElement.appendChild(this.el['OuterBox']); this.appended = true; }, show : /* public */ function (parent) { if (this.freed) throw 'Object is freed'; JSWEffect_terminate(this); // falls gerade ein hide-Effekt laeuft, muss dieser beendet werden, damit appended auf false gesetzt wird, bevor show durchlaeuft! if ((this.visible && (!parent || parent == this.parentElement)) || (!this.parentElement && !parent)) return; if (parent) { if (this.parentElement && (this.parentElement != parent)) this.appended = false; this.parentElement = parent; } this.visible = true; if (!this.excluded) this.el['OuterBox'].style.visibility = 'hidden'; if (!this.appended) { if (!this.parentElement) throw 'Parent element of the window is not specified!'; try { this.parentElement.appendChild(this.el['OuterBox']); } catch (e) { // Fuer IE: Alle Elemente neu erstellen statt umhaengen this.parentElement.innerHTML = this.el['OuterBox'].outerHTML; var oldEl = this.el; this.el = new Object(); this.el['OuterBox'] = this.parentElement.getElementsByTagName('div')[0]; var found; do { found = false; for (var key in oldEl) { if (this.el[key]) continue; var n = oldEl[key].nodeName; for (var i = 0; i < oldEl['OuterBox'].getElementsByTagName(n).length; i++) if (oldEl['OuterBox'].getElementsByTagName(n)[i] == oldEl[key]) { this.el[key] = this.el['OuterBox'].getElementsByTagName(n)[i]; found = true; break; } } } while (found); } this.appended = true; } if (!this.excluded) { this.setPos(); if (this.effects && this.effects['Show']) this.effects['Show'](this, this.effects['duration'], null, this.effects['ShowParams']); else this.el['OuterBox'].style.visibility = 'visible'; } this.documentResize(); this.callEventListener('show'); this.callEventListener('move'); }, hide : /* public */ function () { if (this.freed) throw 'Object is freed'; if (!this.visible || !this.closable) return; this.visible = false; if (this.excluded) { this.excludedWindow.close(); return; } var onEffectTerminate = function (win) { win.el['OuterBox'].style.visibility = 'hidden'; win.callEventListener('hide'); if (win.parentElement /* ToDo: wenn win.effects = null tritt hier ohne if ein Fehler auf */) win.parentElement.removeChild(win.el['OuterBox']); win.appended = false; var b = win.freeOnHide; if (b) win.free(); return b; } if (this.effects && this.effects['Hide']) this.effects['Hide'](this, this.effects['duration'], onEffectTerminate, this.effects['HideParams']); else window.setTimeout(onEffectTerminate, 0, this); }, setPos : /* public */ function (newPos) { // Wendet den in Pos gespeicherten Style auf OuterBox an // Hinweis: Neben setPos greift auch mouseMove:applyChange auf die Positionsstyles von OuterBox zu! if (this.freed) throw 'Object is freed'; var pw = this.parentOffsetWidth(); var ph = this.parentOffsetHeight(); if (newPos) { var _this = this; var i, s; var rect = function (site) { if (site == -1) return 0; if (_this.minimalVisible[site] < 0) return 0; else return _this.minimalVisible[site]; } var interpret = function (type, ps, site) { i = newPos.indexOf(';' + type + ':'); if (i == -1) _this.pos[type] = Number.NaN; else { s = newPos.substring(i+2+type.length, newPos.indexOf(';', i+2+type.length)); if (s.indexOf('%') == -1) _this.pos[type+'Percent'] = false; else { s = ps*parseFloat(s)/100; _this.pos[type+'Percent'] = true; } _this.pos[type] = parseFloat(s) + rect(site); } } newPos = ';'+newPos.split(' ').join(''); interpret('top', ph, 0); interpret('left', pw, 1); interpret('right', pw, 2); interpret('bottom', ph, 3); interpret('width', pw, -1); interpret('height', ph, -1); i = newPos.indexOf(';position:'); if (i >= 0 && newPos.substring(i+10, newPos.indexOf(';', i+10)).indexOf('fixed') >= 0) this.pos.position = 'fixed'; else this.pos.position = 'absolute'; } if (this.excluded) { // ToDo return; } if (!this.appended) return; if (!this.pos['position']) this.pos['position'] = 'absolute'; this.el['OuterBox'].style.position = this.pos['position']; if (this.maximized) { this.el['OuterBox'].style.top = ((this.minimalVisible[0] > 0)?this.minimalVisible[0]:0) + 'px'; this.el['OuterBox'].style.left = ((this.minimalVisible[1] > 0)?this.minimalVisible[1]:0) + 'px'; this.el['OuterBox'].style.right = ((this.minimalVisible[2] > 0)?this.minimalVisible[2]:0) + 'px'; this.el['OuterBox'].style.bottom = ((this.minimalVisible[3] > 0)?this.minimalVisible[3]:0) + 'px'; this.el['OuterBox'].style.width = 'auto'; this.el['OuterBox'].style.height = 'auto'; return; } this.el['OuterBox'].style.top = (isNaN(this.pos['top'])) ?'auto':((this.pos['topPercent']) ?(this.pos['top'] / ph * 100 + '%'):(this.pos['top'] + 'px')); this.el['OuterBox'].style.left = (isNaN(this.pos['left'])) ?'auto':((this.pos['leftPercent']) ?(this.pos['left'] / pw * 100 + '%'):(this.pos['left'] + 'px')); if (!this.autoWidth || isNaN(this.pos.left)) this.el['OuterBox'].style.right = (isNaN(this.pos['right'])) ?'auto':((this.pos['rightPercent']) ?(this.pos['right'] / pw * 100 + '%'):(this.pos['right'] + 'px')); else this.el['OuterBox'].style.right = 'auto'; if (!this.autoHeight || isNaN(this.pos.top)) this.el['OuterBox'].style.bottom = (isNaN(this.pos['bottom']))?'auto':((this.pos['bottomPercent'])?(this.pos['bottom'] / ph * 100 + '%'):(this.pos['bottom'] + 'px')); else this.el['OuterBox'].style.bottom = 'auto'; if (!this.autoWidth) this.el['OuterBox'].style.width = (isNaN(this.pos['width'])) ?'auto':((this.pos['widthPercent']) ?(this.pos['width'] / pw * 100 + '%'):(this.pos['width'] + 'px')); if (!this.autoHeight) this.el['OuterBox'].style.height = (isNaN(this.pos['height']))?'auto':((this.pos['heightPercent'])?(this.pos['height'] / ph * 100 + '%'):(this.pos['height'] + 'px')); this.callEventListener('move'); }, getWindowPos : /* protected */ function () { // Returns an Array, that contains the Position of OuterBox, seen from the inner Window if (this.freed) throw 'Object is freed'; var pos; if (window.getComputedStyle(this.el['OuterBox']).position == 'fixed') pos = new Array(this.el['OuterBox'].offsetLeft, this.el['OuterBox'].offsetTop); else pos = new Array(this.offsetLeftFrom(this.el['OuterBox'], document.body) - window.pageXOffset, this.offsetTopFrom(this.el['OuterBox'], document.body) - window.pageYOffset); return pos; }, hasAtr : /* private */ function (el, atr) { if (!el) return false; if ((' '+el.className+' ').indexOf(' '+atr+' ') >= 0) return true; else return false; }, setAtr : /* private */ function (el, atr) { if (!el) return; if ((' '+el.className+' ').indexOf(' '+atr+' ') >= 0) return; el.className += ' '+atr; }, rmAtr : /* private */ function (el, atr) { if (!el) return; var a = el.className.split(' '); var s = ''; for (var i = 0; i < a.length; i++) { if (!a[i] || a[i] == atr) continue; if (i > 0) s += ' '; s += a[i]; } el.className = s; }, setOrRmAtr : /* private */ function (el, atr, set) { if (this.freed) throw 'Object is freed'; if (set) this.setAtr(el, atr); else this.rmAtr(el, atr); }, onEvent : /* private */ function (el, event, fkt, bubbles) { // provides easy eventListeners. el: Element to set the listener; event: string-name of the event(without "on"); fkt: a Function to call if the event occours, fkt is called in the scope of _this if (!el) return; var _this = this; var oev = new Object(); oev['f'] = function (ev) { // Browseruebergreifende Kompatibilitaet if (!ev) ev = window.event; if (!ev.target) ev.target = ev.srcElement; if (!ev.offsetX && ev.pageX) { ev.offsetX = ev.pageX - _this.offsetLeftFrom(ev.target, document.body); ev.offsetY = ev.pageY - _this.offsetTopFrom(ev.target, document.body); } fkt.call(_this, ev); } oev['event'] = event; oev['el'] = el; el.addEventListener(event, oev['f'], bubbles); this.eventListeners.push(oev); return oev; }, rmEvent : function (oev) { // oev wird von onEvent zurueckgegeben var nr = oev; if (isNaN(nr)) { nr = 0; while (nr < this.eventListeners.length) if (this.eventListeners[nr] == oev) break; else nr++; if (nr >= this.eventListeners.length || this.eventListeners[nr] != oev) return; } else { if (nr < 0 || nr >= this.eventListeners.length) return; oev = this.eventListeners[nr]; } if (document.removeEventListener) oev['el'].removeEventListener(oev['event'], oev['f'], false); else oev['el'].detachEvent('on'+oev['event'], oev['f']); this.eventListeners.splice(nr, 1); }, actualizePos : /* private */ function () { // falls prozentuale Angaben oder autoHeight/autoWidth verwendet werden, wird die Pixelposition neu berechnet // Falls prozentuale Angaben verwendet werden, Position aktualisieren if (!this.visible || this.excluded || this.minimized || this.maximized) return; var style = null; var _this = this; function checkStyle (type) { if (isNaN(_this.pos[type])) return; if (!style) style = window.getComputedStyle(_this.el['OuterBox']); _this.pos[type] = parseInt(style[type]); } checkStyle('top'); checkStyle('left'); checkStyle('right'); checkStyle('bottom'); checkStyle('width'); checkStyle('height'); }, offsetLeftFrom : /* private */ function (el, offsetEl) { // Ermittelt den Linken Abstand eines Elements bis zu einem bestimmten Eltern-ELement var r = 0; do { r += el.offsetLeft; el = el.offsetParent; } while (el && el != offsetEl); return r; }, offsetTopFrom : /* private */ function (el, offsetEl) { // Ermittelt den Oberen Abstand eines Elements bis zu einem bestimmten Eltern-ELement var r = 0; do { r += el.offsetTop; el = el.offsetParent; } while (el && el != offsetEl); return r; }, parentOffsetWidth : /* private */ function () { // Gibt die Breite des fuer das Fenster verfuegbaren Anzeigebereiches zurueck if (this.excluded) return screen.availWidth; if (!this.el['OuterBox'].offsetParent || this.el['OuterBox'].offsetParent == document.body) return window.innerWidth; else return this.el['OuterBox'].offsetParent.offsetWidth; }, parentOffsetHeight : /* private */ function () { // Gibt die Hoehe des fuer das Fenster verfuegbaren Anzeigebereiches zurueck if (this.excluded) return screen.availHeight; if (!this.el['OuterBox'].offsetParent || this.el['OuterBox'].offsetParent == document.body) return window.innerHeight; else return this.el['OuterBox'].offsetParent.offsetHeight; }, offsetTop : /* private */ function () { // Gibt den Abstand von oben bis zum offsetParent des normalisierten Fensters in Pixeln zurueck if (!isNaN(this.pos.top)) return this.pos.top; return this.parentOffsetHeight() - this.pos.height - this.pos.bottom; }, offsetLeft : /* private */ function () { // Gibt den Abstand von links bis zum offsetParent des normalisierten Fensters in Pixeln zurueck if (!isNaN(this.pos.left)) return this.pos.left; return this.parentOffsetWidth() - this.pos.width - this.pos.right; }, offsetWidth : /* private */ function () { // Gibt die Breite des normalisierten Fensters in Pixeln zurueck if (!isNaN(this.pos.width)) return this.pos.width; return this.parentOffsetWidth() - this.pos.left - this.pos.right; }, offsetHeight : /* private */ function () { // Gibt die Hoehe des normalisierten Fensters in Pixeln zurueck if (!isNaN(this.pos.height)) return this.pos.height; return this.parentOffsetHeight() - this.pos.top - this.pos.bottom; }, setOffsetPosition : /* public */ function (top, left, width, height) { // rechnet die gegebenen Parameter auf die Positionierung des Fensters um, sodass Anker und prozentuale Angaben erhalten bleiben if (this.freed) throw 'Object is freed'; if (!this.visible || this.maximized || this.minimized) return; if (this.excluded) { // ToDo return; } var pw = this.parentOffsetWidth(); var ph = this.parentOffsetHeight(); if (!isNaN(this.pos['top'])) this.pos['top'] = top; if (!isNaN(this.pos['left'])) this.pos['left'] = left; if (!isNaN(this.pos['right'])) this.pos['right'] = (isNaN(pw))?0:(pw - width - left); if (!isNaN(this.pos['bottom'])) this.pos['bottom'] = (isNaN(ph))?0:(ph - height - top); if (!isNaN(this.pos['width'])) this.pos['width'] = width; if (!isNaN(this.pos['height'])) this.pos['height'] = height; this.setPos(); }, mouseDown : /* private */ function (ev) { if (ev.button && ev.button != 0) return; this.lastMouseDown = ev; if (this.maximized) return; // Aktion fuer move und resize einrichten var p = ev.target; var target = p; ev.target = null; do { p = p.parentElement; if (p == this.el['Bar'] || p == this.el['Buttons']) { target = p; break; } } while (p); var b = false; if ((target == this.el['EdgeTopLeft'] || target == this.el['EdgeTopRight'] || target == this.el['EdgeBottomLeft'] || target == this.el['EdgeBottomRight']) && this.resizable) { this.autoHeight = false; this.autoWidth = false; b = true; } else if ((target == this.el['BorderTop'] || target == this.el['BorderBottom']) && this.resizable) { this.autoHeight = false; b = true; } else if ((target == this.el['BorderLeft'] || target == this.el['BorderRight']) && this.resizable) { this.autoWidth = false; b = true; } else if (target == this.el['Bar'] && this.movable) b = true; if (b) { // Ein Element fuer resize/move wurde angeklickt this.actualizePos(); // Startposition festhalten this.startPos = clone(this.pos); this.startPos['mausX'] = ev.clientX; this.startPos['mausY'] = ev.clientY; this.startPos['target'] = target; // Cursor-Element und Events setzen this.hiddenCover(true); this.el['FrameCover'].style.margin = '-50px'; this.startPos['oldMouseDown'] = document.onmousedown; document.onmousedown = function () { return false; } this.startPos['mouseUpOev'] = this.onEvent(document, 'mouseup', this.mouseUp); this.startPos['mouseMoveOev'] = this.onEvent(document, 'mousemove', this.mouseMove, true); } }, documentResize : /* private */ function () { if (!this.visible || this.excluded || this.maximized || this.minimized) return; // falls ausserhalb von Anzeigebereich, zuruecksetzen if (this.minimalVisible) { if (this.minimalVisible[0] >= 0) { if (this.el['OuterBox'].offsetTop < this.minimalVisible[0]) this.setOffsetPosition(this.minimalVisible[0], this.el['OuterBox'].offsetLeft, this.el['OuterBox'].offsetWidth, this.el['OuterBox'].offsetHeight); } else { /* ToDo */ } if (this.minimalVisible[1] >= 0) { /* ToDo */ } else { if (this.el['OuterBox'].offsetLeft + this.el['OuterBox'].offsetWidth < - this.minimalVisible[1]) this.setOffsetPosition(this.el['OuterBox'].offsetTop, - this.minimalVisible[1] - this.el['OuterBox'].offsetWidth, this.el['OuterBox'].offsetWidth, this.el['OuterBox'].offsetHeight); } if (this.minimalVisible[2] >= 0) { /* ToDo */ } else { if (this.el['OuterBox'].offsetLeft > this.parentOffsetWidth() + this.minimalVisible[2] && (window.getComputedStyle(this.el['OuterBox'].offsetParent).overflow == 'hidden' || this.pos.position == 'fixed')) this.setOffsetPosition(this.el['OuterBox'].offsetTop, this.parentOffsetWidth() + this.minimalVisible[2], this.el['OuterBox'].offsetWidth, this.el['OuterBox'].offsetHeight); } if (this.minimalVisible[3] >= 0) { /* ToDo */ } else { if (this.el['OuterBox'].offsetTop > this.parentOffsetHeight() + this.minimalVisible[3] && (window.getComputedStyle(this.el['OuterBox'].offsetParent).overflow == 'hidden' || this.pos.position == 'fixed')) this.setOffsetPosition(this.parentOffsetHeight() + this.minimalVisible[3], this.el['OuterBox'].offsetLeft, this.el['OuterBox'].offsetWidth, this.el['OuterBox'].offsetHeight); } } }, mouseUp : /* private */ function (ev) { if (this.startPos) { // Move-Events und Einstellungen zuruecknehmen this.el['FrameCover'].style.margin = '0px'; this.hiddenCover(false); this.rmEvent(this.startPos['mouseUpOev']); this.rmEvent(this.startPos['mouseMoveOev']); document.onmousedown = this.startPos['oldMouseDown']; this.startPos = null; this.documentResize(); } }, mouseMove : /* private */ function (ev) { if (!this.startPos) return; // OuterBox bewegen var _this = this; function applyChange (type, horizontal, invert) { _this.pos[type] = _this.startPos[type] + (-_this.startPos['maus'+(horizontal?'X':'Y')] + (horizontal?ev.clientX:ev.clientY)) * (invert?(-1):(1)); if (_this.startPos[type+'Percent']) { var size; size = (horizontal?_this.parentOffsetWidth():_this.parentOffsetHeight()); _this.el['OuterBox'].style[type] = _this.pos[type] / size * 100 + '%'; } else _this.el['OuterBox'].style[type] = _this.pos[type] + 'px'; } if (this.startPos['target'] == this.el['Bar']) { if (isNaN(this.startPos['right'])) { applyChange('left', true, false); } else if (isNaN(this.startPos['left'])) { applyChange('right', true, true); } else if (isNaN(this.startPos['width'])) { applyChange('left', true, false); if (!this.autoWidth) applyChange('right', true, true); } if (isNaN(this.startPos['bottom'])) { applyChange('top', false, false); } else if (isNaN(this.startPos['top'])) { applyChange('bottom', false, true); } else if (isNaN(this.startPos['height'])) { applyChange('top', false, false); if (!this.autoHeight) applyChange('bottom', false, true); } } if (this.startPos['target'] == this.el['BorderTop'] || this.startPos['target'] == this.el['EdgeTopLeft'] || this.startPos['target'] == this.el['EdgeTopRight']) { if (isNaN(this.startPos['bottom'])) { applyChange('top', false, false); applyChange('height', false, true); } else if (isNaN(this.startPos['top'])) { applyChange('height', false, true); } else if (isNaN(this.startPos['height'])) { applyChange('top', false, false); } this.autoHeight = false; } if (this.startPos['target'] == this.el['BorderLeft'] || this.startPos['target'] == this.el['EdgeTopLeft'] || this.startPos['target'] == this.el['EdgeBottomLeft']) { if (isNaN(this.startPos['right'])) { applyChange('left', true, false); applyChange('width', true, true); } else if (isNaN(this.startPos['left'])) { applyChange('width', true, true); } else if (isNaN(this.startPos['width'])) { applyChange('left', true, false); } this.autoWidth = false; } if (this.startPos['target'] == this.el['BorderRight'] || this.startPos['target'] == this.el['EdgeTopRight'] || this.startPos['target'] == this.el['EdgeBottomRight']) { if (isNaN(this.startPos['right'])) { applyChange('width', true, false); } else if (isNaN(this.startPos['left'])) { applyChange('width', true, false); applyChange('right', true, true); } else if (isNaN(this.startPos['width'])) { applyChange('right', true, true); } this.autoWidth = false; } if (this.startPos['target'] == this.el['BorderBottom'] || this.startPos['target'] == this.el['EdgeBottomLeft'] || this.startPos['target'] == this.el['EdgeBottomRight']) { if (isNaN(this.startPos['bottom'])) { applyChange('height', false, false); } else if (isNaN(this.startPos['top'])) { applyChange('height', false, false); applyChange('bottom', false, true); } else if (isNaN(this.startPos['height'])) { applyChange('bottom', false, true); } this.autoHeight = false; } this.callEventListener('move'); }, exclude : /* public */ function (click) { if (this.freed) throw 'Object is freed'; if (!this.excludable || this.excluded) return; // Fenster oeffnen var p = this.getWindowPos(); var pos = new Array(this.el['OuterBox'].offsetWidth, this.el['OuterBox'].offsetHeight, p[0], p[1]); var w = window.open('', '', 'width='+pos[0]+',height='+pos[1]+',left='+pos[2]+',top='+pos[3]); if (!w) return; // Popup blockiert! if (click) { if (window.opera) { // Nur im echten Opera kann die Position pixelgenau berechnet werden! var zoom = pos[0] / w.innerWidth; pos[2] = pos[2] * zoom + (w.outerWidth - w.innerWidth * zoom) / 2; pos[3] = pos[3] * zoom + w.outerHeight - w.innerHeight * zoom - (w.outerWidth - w.innerWidth * zoom) / 2; pos[0] = pos[0] * zoom; pos[1] = pos[1] * zoom; w.resizeTo(pos[0], pos[1]); } else if (w.innerWidth > 0) { var zoom = w.innerWidth / pos[0]; // Annahme: Neues Fenster hat gleichen Zoomfaktor, wie Hauptfenster pos[2] = this.lastMouseDown.screenX - (this.lastMouseDown.clientX - pos[2]) * zoom; pos[3] = this.lastMouseDown.screenY - (this.lastMouseDown.clientY - pos[3]) * zoom; } w.moveTo(pos[2], pos[3]); } this.excludedWindow = w; // Fenster umhaengen this.parentElement.removeChild(this.el['OuterBox']); this.appended = false; this.el['OuterBox'].className += ' excluded'; this.el['OuterBox'].style.position = 'absolute'; this.el['OuterBox'].style.top = '0px'; this.el['OuterBox'].style.left = '0px'; this.el['OuterBox'].style.width = '100%'; this.el['OuterBox'].style.height = '100%'; for (var i = 0; i < this.el['OuterBox'].childNodes.length; i++) if (this.el['OuterBox'].childNodes[i].nodeType == 1) this.el['OuterBox'].childNodes[i].style.display = 'none'; this.el['InnerBox'].style.display = 'block'; this.el['InnerBox'].style.position = 'absolute'; this.el['InnerBox'].style.top = '0px'; this.el['InnerBox'].style.left = '0px'; this.el['InnerBox'].style.right = '0px'; this.el['InnerBox'].style.bottom = '0px'; w.document.title = this.el['Title'].innerHTML; var sty = document.getElementsByTagName('head')[0].getElementsByTagName('link'); for (var i = 0; i < sty.length; i++) { if (sty[i].rel.toLowerCase() != 'stylesheet') continue; var cloneSty = document.createElement('link'); cloneSty.rel = 'stylesheet'; cloneSty.href = sty[i].href; w.document.getElementsByTagName('head')[0].appendChild(cloneSty); } sty = document.getElementsByTagName('head')[0].getElementsByTagName('style'); for (var i = 0; i < sty.length; i++) w.document.getElementsByTagName('head')[0].innerHTML += sty[i].outerHTML; this.excluded = true; this.show(w.document.body); var _this = this; this.onEvent(w, 'beforeunload', function () { _this.free(); }); this.excludedClosedTimer = window.setInterval(function () { if (w.closed) _this.free(); }, 100); this.callEventListener('exclude'); }, maximize : /* public */ function () { if (this.freed) throw 'Object is freed'; if (!this.maximizable) return; if (this.excluded) { // Todo return; } this.maximized = true; var t = (this.minimalVisible[0] > 0)?this.minimalVisible[0]:0; var l = (this.minimalVisible[1] > 0)?this.minimalVisible[1]:0; var r = (this.minimalVisible[2] > 0)?this.minimalVisible[2]:0; var b = (this.minimalVisible[3] > 0)?this.minimalVisible[3]:0; var onEffectTerminate = function (win) { win.el['OuterBox'].style.top = t+'px'; win.el['OuterBox'].style.left = l+'px'; win.el['OuterBox'].style.right = r+'px'; win.el['OuterBox'].style.bottom = b+'px'; win.el['OuterBox'].style.width = 'auto'; win.el['OuterBox'].style.height = 'auto'; win.el['OuterBox'].style.position = (this.parentElement == document.body)?'fixed':'absolute'; win.setAtr(win.el['OuterBox'], 'maximized'); win.callEventListener('move'); } if (this.visible && this.effects && this.effects['Maximize']) this.effects['Maximize'](this, this.effects['duration'], onEffectTerminate, t, l, this.parentOffsetWidth()-r, this.parentOffsetHeight()-b, this.effects['MaximizeParams']); else onEffectTerminate(this); this.callEventListener('maximize'); }, normalize : /* public */ function () { if (this.freed) throw 'Object is freed'; if (!this.visible) { this.maximized = false; return; } if (this.excluded) { // ToDo return; } var onEffectTerminate = function (win) { win.maximized = false; win.rmAtr(win.el['OuterBox'], 'maximized'); win.setPos(); } var fixed = this.pos['position'] == 'fixed'; if (this.effects && this.effects['Normalize']) this.effects['Normalize'](this, this.effects['duration'], onEffectTerminate, this.offsetTop() - ((fixed)?0:window.pageYOffset), this.offsetLeft() - ((fixed)?0:window.pageXOffset), this.offsetWidth(), this.offsetHeight(), this.effects['NormalizeParams']); else onEffectTerminate(this); this.callEventListener('normalize'); }, minimize : /* public */ function () { if (this.freed) throw 'Object is freed'; if (!this.visible || !this.minimizable) return; if (this.excluded) { // ToDo return; } this.minimized = true; var p = this.minimizePoint(); var onEffectTerminate = function (win) { win.el['OuterBox'].style.visibility = 'hidden'; } if (this.effects && this.effects['Minimize']) this.effects['Minimize'](this, this.effects['duration'], onEffectTerminate, p[0], p[1], this.effects['MinimizeParams']); else onEffectTerminate(this); this.callEventListener('minimize'); }, unminimize : /* public */ function () { if (this.freed) throw 'Object is freed'; if (!this.visible || !this.minimized) return; if (this.excluded) { // ToDo return; } var p = this.minimizePoint(); var onEffectTerminate = function (win) { win.minimized = false; win.el['OuterBox'].style.visibility = 'visible'; } if (this.effects && this.effects['Unminimize']) this.effects['Unminimize'](this, this.effects['duration'], onEffectTerminate, p[0], p[1], this.effects['UnminimizeParams']); else onEffectTerminate(this); this.callEventListener('unminimize'); }, free : /* public */ function () { try { if (this.excludedClosedTimer) window.clearInterval(this.excludedClosedTimer); for (var i = this.eventListeners.length-1; i >= 0; i--) this.rmEvent(i); JSWEffect_terminate(this); if (this.scrollRectListener) this.scrollRectListener.free(); if (this.appended) this.parentElement.removeChild(this.el['OuterBox']); } catch (e) {} this.callEventListener('free'); this.freed = true; for (var key in this) if (typeof this[key] == 'object') this[key] = null; } }