diff --git a/e107_files/jslib/core/dialog.js b/e107_files/jslib/core/dialog.js index f08bbba99..3b7eeaaa6 100644 --- a/e107_files/jslib/core/dialog.js +++ b/e107_files/jslib/core/dialog.js @@ -5,9 +5,10 @@ e107Base.setPrefs('core-dialog', { id: null, theme : '', + shadow: false, + shadowTheme: '', top: null, left: null, - zIndex: 2000, width: 300, height: 200, minWidth: 200, @@ -22,13 +23,15 @@ e107Base.setPrefs('core-dialog', { activeOnClick : true, show: Element.show, hide: Element.hide, + maximizeEffects: true, dialogManager: null, positionningStrategyOffset: null, - close: 'destroy' // e107Widgets.Dialog method for closing dialog + close: 'destroy', // e107Widgets.Dialog method for closing dialog or false to disable + maximize: 'toggleMaximize', // e107Widgets.Dialog method for closing dialog or false to disable }); -e107Widgets.Dialog = Class.create(e107WidgetAbstract,{ +e107Widgets.Dialog = Class.create(e107WidgetAbstract, { Version : '1.0', style : "position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0;", wiredElement: null, @@ -41,6 +44,7 @@ e107Widgets.Dialog = Class.create(e107WidgetAbstract,{ focused: false, // windows on focus modal: false, // modal window zIndex: 0, + shadow: null, action: function(name) { var action = this.options[name]; @@ -50,14 +54,12 @@ e107Widgets.Dialog = Class.create(e107WidgetAbstract,{ initialize : function(options) { this.events = new e107EventManager(this); - this.events.observe('create', this.createButtons)//bind create and createButtons - .observe('destroy', this.destroyButtons); //bind destroy and destroyButtons this.initMod('core-dialog', options); - // TODO - check e107Widgets.DialogManagerDefault presence, create if not found this.dialogManager = this.options.dialogManager || e107Widgets.DialogManagerDefault; - if(this.options.id && this.dialogManager.getWindow($(this.options.id))) return; + + this.setMethodChains(); this.create(); this.id = this.element.id; @@ -88,6 +90,25 @@ e107Widgets.Dialog = Class.create(e107WidgetAbstract,{ getShadowTheme: function() { return this.options.shadowTheme || this.dialogManager.getShadowTheme(); }, + + setMethodChains: function() { + + this.events.observe('create', this.createButtons)//bind create and createButtons + .observe('destroy', this.destroyButtons); //bind destroy and destroyButtons + + + if(Object.isUndefined(e107Widgets.Shadow)) + this.options.shadow = false; + + if(this.options.shadow) { + this.events.observe('create', this.createShadow) + .observe('addElements', this.addElementsShadow) + .observe('setZIndex:pre', this.setZIndexShadow) + .observe('setPosition', this.setPositionShadow) + .observe('setSize', this.setSizeShadow) + .observe('setBounds', this.setBoundsShadow); + } + }, create : function() { function createDiv(className, options) { @@ -160,7 +181,7 @@ e107Widgets.Dialog = Class.create(e107WidgetAbstract,{ return this.setBounds(this.options); }, - show : function(modal) { + show: function(modal) { if (this.visible) return this; @@ -247,8 +268,6 @@ e107Widgets.Dialog = Class.create(e107WidgetAbstract,{ /* * Method: blur Blurs the window (without changing windows order) - * - * Returns: this */ blur: function() { if (!this.focused) @@ -268,6 +287,75 @@ e107Widgets.Dialog = Class.create(e107WidgetAbstract,{ return this; }, + /* + * Method: maximize Maximizes window inside its viewport (managed by + * WindowManager) Makes window take full size of its viewport + */ + maximize: function() { + if (this.maximized) + return this; + + // Get bounds has to be before this.dialogManager.maximize for IE!! + // this.dialogManager.maximize remove overflow + // and it breaks this.getBounds() + var bounds = this.getBounds(); + if (this.dialogManager.maximize(this)) { + this.disableButton('minimize').setResizable(false).setDraggable(false); + + this.activate(); + this.maximized = true; + this.savedArea = bounds; + var newBounds = Object.extend(this.dialogManager.viewport.getDimensions(), { + top: 0, + left: 0 + }); + this[this.options.maximizeEffects && !e107API.Browser.IE ? "morph" : "setBounds"](newBounds); + + this.fire('maximized'); + return this; + } + }, + + /* + * Function: restore Restores a maximized window to its initial size + */ + restore: function() { + if (!this.maximized) + return this; + + if (this.dialogManager.restore(this)) { + this[this.options.maximizeEffects && !e107API.Browser.IE ? "morph" : "setBounds"](this.savedArea); + this.enableButton("minimize").setResizable(true).setDraggable(true); + + this.maximized = false; + + this.fire('restored'); + return this; + } + }, + + /* + * Function: toggleMaximize Maximizes/Restores window inside it's + * viewport (managed by DialogManager) + */ + toggleMaximize: function() { + return this.maximized ? this.restore() : this.maximize(); + }, + + /* + * Function: adapt Adapts window size to fit its content + * + * Returns: this + */ + adapt: function() { + var dimensions = this.content.getScrollDimensions(); + if (this.options.superflousEffects) + this.morph(dimensions, true); + else + this.setSize(dimensions.width, dimensions.height, true); + return this; + }, + /* * Method: destroy Destructor, closes window, cleans up DOM and memory */ @@ -277,8 +365,8 @@ e107Widgets.Dialog = Class.create(e107WidgetAbstract,{ Event.stopObserving(this.dialogManager.scrollContainer, "scroll", this.centerOptions.handler); this.dialogManager.unregister(this); - this.fire('destroyed'); this.events.notify('destroy'); + this.fire('destroyed'); }, setHeader: function(header) { @@ -333,6 +421,7 @@ e107Widgets.Dialog = Class.create(e107WidgetAbstract,{ elementStyle.top = pos.top + 'px'; elementStyle.left = pos.left + 'px'; + this.events.notify('setPosition', top, left); this.fire('position:changed'); return this; }, @@ -365,8 +454,8 @@ e107Widgets.Dialog = Class.create(e107WidgetAbstract,{ } else return { - width: this.options.width, - height: this.options.height + width: this.options.width, + height: this.options.height }; }, @@ -385,6 +474,7 @@ e107Widgets.Dialog = Class.create(e107WidgetAbstract,{ contentStyle.width = size.innerWidth + "px", contentStyle.height = size.innerHeight + "px"; this.overlay.style.height = size.innerHeight + "px"; + this.events.notify('setSize', width, height, innerSize); this.fire('size:changed'); return this; }, @@ -409,7 +499,50 @@ e107Widgets.Dialog = Class.create(e107WidgetAbstract,{ * Returns: Hash {top:, left:, width:, height:} */ setBounds: function(bounds, innerSize) { - return this.setPosition(bounds.top, bounds.left).setSize(bounds.width, bounds.height, innerSize); + var ret = this.setPosition(bounds.top, bounds.left).setSize(bounds.width, bounds.height, innerSize); + this.events.notify('setBounds', bounds, innerSize); + return ret; + }, + + morph: function(bounds, innerSize) { + bounds = Object.extend(this.getBounds(innerSize), bounds || {}); + + if (this.centerOptions && this.centerOptions.auto) + bounds = Object.extend(bounds, this.computeRecenter(bounds)); + + if (innerSize) { + bounds.width += this.borderSize.width; + bounds.height += this.borderSize.height; + } + + if (this.options.wired) { + this.createWiredElement(); + if(this.shadow) this.shadow.hide(); + this.wiredElement.style.cssText = this.element.style.cssText; + this.element.hide(); + this.savedElement = this.element; + this.dialogManager.container.appendChild(this.wiredElement); + this.element = this.wiredElement; + } + + this.animating = true; + + new e107Widgets.Dialog.Effects.Morph(this, bounds, { + duration: 0.3, + afterFinish: function() { + this.animating = false; + if (this.options.wired) { + this.savedElement.style.cssText = this.wiredElement.style.cssText; + this.wiredElement.remove(); + this.element = this.savedElement; + if(this.shadow) this.shadow.show(); + this.savedElement = false; + } + }.bind(this) + }); + + Object.extend(this.options, bounds); + return this; }, /* @@ -432,21 +565,23 @@ e107Widgets.Dialog = Class.create(e107WidgetAbstract,{ }, setDraggable : function(draggable) { + var element = this.savedElement || this.element; this.options.draggable = draggable; - this.element[(draggable ? 'add' : 'remove') + 'ClassName']('draggable'); + element[(draggable ? 'add' : 'remove') + 'ClassName']('draggable'); return this; }, setResizable: function(resizable) { this.options.resizable = resizable; - var toggleClassName = (resizable ? 'add' : 'remove') + 'ClassName'; + var toggleClassName = (resizable ? 'add' : 'remove') + 'ClassName', + element = this.savedElement || this.element; - this.element[toggleClassName]('resizable').select('div:[class*=_sizer]').invoke(resizable ? 'show' : 'hide'); + element[toggleClassName]('resizable').select('div:[class*=_sizer]').invoke(resizable ? 'show' : 'hide'); if (resizable) this.createResizeHandles(); - this.element.select('div.se').first()[toggleClassName]('se_resize_handle'); + element.select('div.se').first()[toggleClassName]('se_resize_handle'); return this; }, @@ -457,12 +592,13 @@ e107Widgets.Dialog = Class.create(e107WidgetAbstract,{ }, observe: function(eventName, handler) { - this.element.observe('edialog:' + eventName, handler.bind(this)); + (this.savedElement || this.element).observe('edialog:' + eventName, handler.bind(this)); return this; }, addElements: function() { this.dialogManager.container.appendChild(this.element); + this.events.notify('addElements'); }, effect: function(name, element, options) { @@ -473,11 +609,13 @@ e107Widgets.Dialog = Class.create(e107WidgetAbstract,{ // Set z-index to all window elements setZIndex: function(zIndex) { if (this.zIndex != zIndex) { + this.events.notify('setZIndex:pre', zIndex); this.zIndex = zIndex; [ this.element ].concat(this.element.childElements()).each(function(element) { element.style.zIndex = zIndex++; }); this.lastZIndex = zIndex; + this.events.notify('setZIndex', zIndex); } return this; }, @@ -575,6 +713,207 @@ e107Widgets.Dialog = Class.create(e107WidgetAbstract,{ } }); +e107Widgets.URLDialog = Class.create(e107Widgets.Dialog, { + + setAjaxContent: function() { + return this; + }, + + initialize: function($super, url, options) { + $super(options); + this.options.url = url || this.options.url; + this.createIFrame(); + }, + + destroy: function($super) { + this.iframe.src = null; + $super(); + }, + + getUrl: function() { + return this.iframe.src; + }, + + setUrl: function(url) { + this.iframe.src = url; + return this; + }, + + createIFrame: function($super) { + this.iframe = new Element('iframe', { + style: this.style, + frameborder: 0, + src: this.options.url, + name: this.element.id + "_frame", + id: this.element.id + "_frame" + }); + + this.content.insert(this.iframe); + } +}); + +e107Base.setPrefs('core-confirm-dialog', { + buttons: null, // default = ok/cancel button + beforeSelect: function() { + return true; + }, + close: false, + resizable: false, + activeOnClick: false +}); + +e107Widgets.ConfirmDialog = Class.create(e107Widgets.Dialog, { + + initialize: function($super, options) { + options = Object.extend(e107Base.getPrefs('core-confirm-dialog'), options || {}); + $super(options); + + }, + + disableDialogButton: function(index) { + var button = this.getDialogButton(index); + if (button) + button.addClassName("disabled"); + return this; + }, + + enableDialogButton: function(index) { + var button = this.getDialogButton(index); + if (button) + button.removeClassName("disabled"); + return this; + }, + + getDialogButton: function(index) { + var buttons = this.buttonContainer.childElements(); + if (index >= 0 && index < buttons.length) + return buttons[index]; + else + return null; + }, + + // Override create to add dialog buttons + create: function($super) { + $super(); + + // Create buttons + this.buttonContainer = this.createButtons(); + // Add a new content for dialog content + this.dialogContent = new Element('div', { + className: 'ui-dialog-confirm-content' + }); + + this.content.update(this.dialogContent); + this.content.insert(this.buttonContainer); + }, + + addElements: function($super) { + $super(); + // Pre compute buttons height + this.buttonsHeight = this.buttonContainer.getHeight() || this.buttonsHeight; + this.setDialogSize(); + }, + + setContent: function(content, withoutButton) { + this.dialogContent.update(content); + + // Remove button if need be + if (withoutButton && this.buttonContainer.parentNode) + this.buttonContainer.remove(); + else + this.content.insert(this.buttonContainer); + + // Update dialog size + this.setDialogSize(); + return this; + }, + + onSelect: function(e) { + var element = e.element(); + + if (element.callback && !element.hasClassName('disabled')) { + if (this.options.beforeSelect(element)) + element.callback(this); + } + }, + + createButtons: function(dialogButtons) { + var buttonContainer = new Element('div', { + className: 'ui-dialog-confirm-buttons' + }); + + (this.options.buttons || e107Widgets.ConfirmDialog.okCancelButtons).each(function(item) { + var button; + if (item.separator) + button = new Element('span', { + className: 'separator' + }); + else + button = new Element('button', { + title: item.title, + className: (item.className || '') + (item.disabled ? ' disabled' : '') + }).observe('click', this.onSelect.bind(this)).update(item.title); + + buttonContainer.insert(button); + button.callback = item.callback; + }.bind(this)); + return buttonContainer; + }, + + setDialogSize: function() { + // Do not compute dialog size if window is not completly ready + if (!this.borderSize) + return; + + this.buttonsHeight = this.buttonContainer.getHeight() || this.buttonsHeight; + var style = this.dialogContent.style, size = this.getSize(true); + style.width = size.width + "px", style.height = size.height - this.buttonsHeight + "px"; + }, + + setSize: function($super, width, height, innerSize) { + $super(width, height, innerSize); + this.setDialogSize(); + return this; + } +}); + +e107Widgets.ConfirmDialog = Object.extend(e107Widgets.ConfirmDialog, { + okButton : [{title: 'Ok', className: 'ok', callback: function(win) { win.destroy(); }}], + okCancelButtons : [{title: 'Ok', className: 'ok', callback: function(win) { win.destroy(); }}, + {title: 'Cancel', className: 'cancel', callback: function(win) { win.destroy(); }}] +}); + +if (!Object.isUndefined(window.Effect)) { + e107Widgets.Dialog.Effects = e107Widgets.Dialog.Effects || {}; + e107Widgets.Dialog.Effects.Morph = Class.create(Effect.Base, { + initialize: function(window, bounds) { + this.window = window; + var options = Object.extend( { + fromBounds: this.window.getBounds(), + toBounds: bounds, + from: 0, + to: 1 + }, arguments[2] || {}); + this.start(options); + }, + + update: function(position) { + var t = this.options.fromBounds.top + (this.options.toBounds.top - this.options.fromBounds.top) * position; + var l = this.options.fromBounds.left + (this.options.toBounds.left - this.options.fromBounds.left) * position; + + var ow = this.options.fromBounds.width + (this.options.toBounds.width - this.options.fromBounds.width) * position; + var oh = this.options.fromBounds.height + (this.options.toBounds.height - this.options.fromBounds.height) * position; + + this.window.setBounds( { + top: t, + left: l, + width: ow, + height: oh + }) + } + }); +} + e107Widgets.Dialog.addMethods( { startDrag: function(handle) { @@ -585,7 +924,8 @@ e107Widgets.Dialog.addMethods( { this.createWiredElement(); this.wiredElement.style.cssText = this.element.style.cssText; this.element.hide(); - this.saveElement = this.element; + if(this.shadow) this.shadow.hide(); + this.savedElement = this.element; this.dialogManager.container.appendChild(this.wiredElement); this.element = this.wiredElement; } @@ -597,10 +937,11 @@ e107Widgets.Dialog.addMethods( { this.element.hasClassName('resized') ? this.endResize() : this.endMove(); if (this.options.wired) { - this.saveElement.style.cssText = this.wiredElement.style.cssText; + this.savedElement.style.cssText = this.wiredElement.style.cssText; this.wiredElement.remove(); - this.element = this.saveElement; - this.saveElement = false; + this.element = this.savedElement; + if(this.shadow) this.shadow.show(); + this.savedElement = false; } }, @@ -674,6 +1015,7 @@ e107Widgets.Dialog.addMethods( { }); e107Widgets.Dialog.addMethods( { + createButtons: function() { this.buttons = new Element("div", { className: "buttons" @@ -690,10 +1032,11 @@ e107Widgets.Dialog.addMethods( { }, destroyButtons: function() { - this.buttons.stopObserving(); + if(this.buttons) + this.buttons.stopObserving(); }, - defaultButtons: $w('close'), + defaultButtons: $w('maximize close'), getButtonElement: function(buttonName) { return this.buttons.down("." + buttonName); @@ -717,17 +1060,20 @@ e107Widgets.Dialog.addMethods( { }, removeButton: function(buttonName) { - this.getButtonElement(buttonName).remove(); + var b = this.getButtonElement(buttonName); + if(b) b.remove(); return this; }, disableButton: function(buttonName) { - this.getButtonElement(buttonName).addClassName("disabled"); + var b = this.getButtonElement(buttonName); + if(b) b.addClassName("disabled"); return this; }, enableButton: function(buttonName) { - this.getButtonElement(buttonName).removeClassName("disabled"); + var b = this.getButtonElement(buttonName); + if(b) b.removeClassName("disabled"); return this; }, @@ -748,6 +1094,7 @@ e107Widgets.Dialog.addMethods( { }, updateButtonsOrder: function() { + if(!this.buttons) return; var buttons = this.buttons.childElements(); buttons.inject(new Array(buttons.length), function(array, button) { @@ -759,12 +1106,95 @@ e107Widgets.Dialog.addMethods( { } }); +e107Widgets.Dialog.addMethods( { + + showShadow: function() { + if (this.shadow) { + this.shadow.hide(); + this.effect('show', this.shadow.shadow); + } + }, + + hideShadow: function() { + if (this.shadow) + this.effect('hide', this.shadow.shadow); + }, + + removeShadow: function() { + if (this.shadow) + this.shadow.remove(); + }, + + focusShadow: function() { + if (this.shadow) + this.shadow.focus(); + }, + + blurShadow: function() { + if (this.shadow) + this.shadow.blur(); + }, + + // Private Functions + createShadow: function() { + if (!this.options.shadow || Object.isUndefined(e107Widgets.Shadow)) return; + + this.observe('showing', this.showShadow) + .observe('hiding', this.hideShadow) + .observe('hidden', this.removeShadow) + .observe('focused', this.focusShadow) + .observe('blurred', this.blurShadow); + + this.shadow = new e107Widgets.Shadow(this.element, { + theme: this.getShadowTheme() + }); + }, + + addElementsShadow: function() { + if (this.shadow) { + this.shadow.setBounds(this.options).render(); + } + }, + + setZIndexShadow: function(zIndex) { + if (this.zIndex != zIndex) { + if (this.shadow) + this.shadow.setZIndex(zIndex - 1); + + this.zIndex = zIndex; + } + return this; + }, + + setPositionShadow: function(top, left) { + if (this.shadow) { + var pos = this.getPosition(); + this.shadow.setPosition(pos.top, pos.left); + } + return this; + }, + + setSizeShadow: function(width, height, innerSize) { + if (this.shadow) { + var size = this.getSize(); + this.shadow.setSize(size.width, size.height); + } + return this; + }, + + setBoundsShadow: function(bounds, innerSize) { + if (this.shadow) + this.shadow.setBounds(this.getBounds()); + } +}); + + e107Base.setPrefs('core-dialogmanager', { className : 'e-dialog', container: null, // will default to document.body zIndex: 2000, theme: "e107", - shadowTheme: "e107", + shadowTheme: "e107_shadow", showOverlay: Element.show, hideOverlay: Element.hide, positionningStrategyOffset: null, diff --git a/e107_files/jslib/core/dialog/e107/e107.css b/e107_files/jslib/core/dialog/e107/e107.css index 44d1700e7..d8293cbe1 100644 --- a/e107_files/jslib/core/dialog/e107/e107.css +++ b/e107_files/jslib/core/dialog/e107/e107.css @@ -24,9 +24,9 @@ height:22px; margin:0; padding:0; - text-align:center; + text-align: left; overflow: hidden; - padding-left:60px; + padding-right: 60px; line-height: 20px; color: #000; } @@ -112,7 +112,7 @@ } .e107 .buttons a.close { - float:left; + float: right; background:transparent url(icons/button_unactive.gif) no-repeat 0 0; background-repeat: no-repeat; height:15px; @@ -132,7 +132,7 @@ } .e107 .buttons a.maximize { - float:left; + float: right; background:transparent url(icons/button_unactive.gif) no-repeat 0 0; height:15px; width:14px; @@ -149,13 +149,15 @@ background:transparent url(icons/buttons_over.gif) no-repeat 0 -30px !important; } +/* padding-top = buttons order, it will be reset to 0, do not use padding, use margin*/ +/* not implemented .e107 .buttons a.minimize { - float:left; + float: right; background:transparent url(icons/button_unactive.gif) no-repeat 0 0; height:15px; width:14px; margin: 3px 7px 0 0; - padding-top:1px; /* padding-top = buttons order, it will be reset to 0, do not use padding, use margin*/ + padding-top:1px; overflow:hidden; } @@ -170,6 +172,7 @@ .e107 .buttons a.minimize.disabled, .e107 .buttons.over a.minimize.disabled { background:transparent url(icons/button_unactive.gif) no-repeat 0 0 !important; } +*/ .e107_overlay { position:absolute; diff --git a/e107_files/jslib/core/shadow.js b/e107_files/jslib/core/shadow.js new file mode 100644 index 000000000..ea9984090 --- /dev/null +++ b/e107_files/jslib/core/shadow.js @@ -0,0 +1,295 @@ + +/** + * Global prefs + */ +e107Base.setPrefs('core-shadow', { + theme: "e107_shadow", + focus: false, + zIndex: 100 +}); + +/* + * Class: e107Widgets.Shadow Add shadow around a DOM element. The element MUST BE in + * ABSOLUTE position. + * + * Shadow can be skinned by CSS (see e107_shadow.css). CSS + * must be included to see shadow. + * + * A shadow can have two states: focused and blur. Shadow shifts are set in CSS + * file as margin and padding of shadow_container to add visual information. + * + * Example: new e107Widgets.Shadow("element_id"); + */ +e107Widgets.Shadow = Class.create(e107WidgetAbstract, { + /* + * Method: initialize Constructor, adds shadow elements to the DOM if + * element is in the DOM. Element MUST BE in ABSOLUTE position. + * Parameters: element - DOM element options - Hashmap of options - + * theme (default: mac_shadow) - focus (default: true) - zIndex + * (default: 100) + */ + initialize: function(element, options) { + this.initMod('core-shadow', options); + + this.element = $(element); + this.create(); + this.iframe = e107API.Browser.IE && e107API.Browser.IE < 7 ? new e107Utils.IframeShim() : null; + + this.render(); + }, + + /* + * Method: destroy Destructor, removes elements from the DOM + */ + destroy: function() { + if (this.shadow.parentNode) + this.remove(); + }, + + // Group: Size and Position + /* + * Method: setPosition Sets top/left shadow position in pixels + * Parameters: top - top position in pixel left - left position in pixel + */ + setPosition: function(top, left) { + if (this.shadowSize) { + var shadowStyle = this.shadow.style; + top = parseInt(top) - this.shadowSize.top + this.shadowShift.top; + left = parseInt(left) - this.shadowSize.left + this.shadowShift.left; + shadowStyle.top = top + 'px'; + shadowStyle.left = left + 'px'; + if (this.iframe) + this.iframe.setPosition(top, left); + } + return this; + }, + + /* + * Method: setSize Sets width/height shadow in pixels + * Parameters: width - width in pixel height - height in pixel + */ + setSize: function(width, height) { + if (this.shadowSize) { + try { + var w = Math.max(0, parseInt(width) + this.shadowSize.width - this.shadowShift.width) + "px"; + this.shadow.style.width = w; + var h = Math.max(0, parseInt(height) - this.shadowShift.height) + "px"; + + // this.shadowContents[1].style.height = h; + this.shadowContents[1].childElements().each(function(e) { + e.style.height = h + }); + this.shadowContents.each(function(item) { + item.style.width = w + }); + if (this.iframe) + this.iframe.setSize(width + this.shadowSize.width - this.shadowShift.width, height + this.shadowSize.height - this.shadowShift.height); + + } catch (e) { + // IE could throw an exception if called to early + } + } + return this; + }, + + /* + * Method: setBounds Sets shadow bounds in pixels + * Parameters: bounds - an Hash {top:, left:, width:, height:} + */ + setBounds: function(bounds) { + return this.setPosition(bounds.top, bounds.left).setSize(bounds.width, bounds.height); + }, + + /* + * Method: setZIndex Sets shadow z-index + * Parameters: zIndex - zIndex value + */ + setZIndex: function(zIndex) { + this.shadow.style.zIndex = zIndex; + return this; + }, + + // Group: Render + /* + * Method: show Displays shadow + */ + show: function() { + this.render(); + this.shadow.show(); + if (this.iframe) + this.iframe.show(); + return this; + }, + + /* + * Method: hide Hides shadow + */ + hide: function() { + this.shadow.hide(); + if (this.iframe) + this.iframe.hide(); + return this; + }, + + /* + * Method: remove Removes shadow from the DOM + */ + remove: function() { + this.shadow.remove(); + return this; + }, + + // Group: Status + /* + * Method: focus Focus shadow. + * Change shadow shift. Shift values are set in CSS file as margin and + * padding of shadow_container to add visual information of shadow + * status. + */ + focus: function() { + this.options.focus = true; + this.updateShadow(); + return this; + }, + + /* + * Method: blur Blurs shadow. + * Change shadow shift. Shift values are set in CSS file as margin and + * padding of shadow_container to add visual information of shadow + * status. + */ + blur: function() { + this.options.focus = false; + this.updateShadow(); + return this; + }, + + // Private Functions + // Adds shadow elements to DOM, computes shadow size and displays it + render: function() { + if (this.element.parentNode && !Object.isElement(this.shadow.parentNode)) { + this.element.parentNode.appendChild(this.shadow); + this.computeSize(); + this.setBounds(Object.extend(this.element.getDimensions(), this.getElementPosition())); + this.shadow.show(); + } + return this; + }, + + // Creates HTML elements without inserting them into the DOM + create: function() { + var zIndex = this.element.getStyle('zIndex'); + zIndex = (zIndex || this.options.zIndex) - 1; + this.element.setStyle( { + zIndex: zIndex + }); + + this.shadowContents = new Array(3); + this.shadowContents[0] = new Element("div").insert(new Element("div", { + className: "shadow_center_wrapper" + }).insert(new Element("div", { + className: "n_shadow" + }))).insert(new Element("div", { + className: "shadow_right ne_shadow" + })).insert(new Element("div", { + className: "shadow_left nw_shadow" + })); + + this.shadowContents[1] = new Element("div").insert(new Element("div", { + className: "shadow_center_wrapper c_shadow" + })).insert(new Element("div", { + className: "shadow_right e_shadow" + })).insert(new Element("div", { + className: "shadow_left w_shadow" + })); + this.centerElements = this.shadowContents[1].childElements(); + + this.shadowContents[2] = new Element("div").insert(new Element("div", { + className: "shadow_center_wrapper" + }).insert(new Element("div", { + className: "s_shadow" + }))).insert(new Element("div", { + className: "shadow_right se_shadow" + })).insert(new Element("div", { + className: "shadow_left sw_shadow" + })); + + this.shadow = new Element("div", { + className: "shadow_container " + this.options.theme, + style: "position:absolute; top:-10000px; left:-10000px; display:none; z-index:" + zIndex + }).insert(this.shadowContents[0]).insert(this.shadowContents[1]).insert(this.shadowContents[2]); + }, + + // Compute shadow size + computeSize: function() { + if (this.focusedShadowShift) + return; + this.shadow.show(); + + // Trick to get shadow shift designed in CSS as padding + var content = this.shadowContents[1].select("div.c_shadow").first(); + this.unfocusedShadowShift = {}; + this.focusedShadowShift = {}; + + $w("top left bottom right").each(function(pos) { + this.unfocusedShadowShift[pos] = content.getNumStyle("padding-" + pos) || 0 + }.bind(this)); + this.unfocusedShadowShift.width = this.unfocusedShadowShift.left + this.unfocusedShadowShift.right; + this.unfocusedShadowShift.height = this.unfocusedShadowShift.top + this.unfocusedShadowShift.bottom; + + $w("top left bottom right").each(function(pos) { + this.focusedShadowShift[pos] = content.getNumStyle("margin-" + pos) || 0 + }.bind(this)); + this.focusedShadowShift.width = this.focusedShadowShift.left + this.focusedShadowShift.right; + this.focusedShadowShift.height = this.focusedShadowShift.top + this.focusedShadowShift.bottom; + + this.shadowShift = this.options.focus ? this.focusedShadowShift : this.unfocusedShadowShift; + + // Get shadow size + this.shadowSize = { + top: this.shadowContents[0].childElements()[1].getNumStyle("height"), + left: this.shadowContents[0].childElements()[1].getNumStyle("width"), + bottom: this.shadowContents[2].childElements()[1].getNumStyle("height"), + right: this.shadowContents[0].childElements()[2].getNumStyle("width") + }; + + this.shadowSize.width = this.shadowSize.left + this.shadowSize.right; + this.shadowSize.height = this.shadowSize.top + this.shadowSize.bottom; + + // Remove padding + content.setStyle("padding:0; margin:0"); + this.shadow.hide(); + }, + + // Update shadow size (called when it changes from focused to blur and + // vice-versa) + updateShadow: function() { + this.shadowShift = this.options.focus ? this.focusedShadowShift : this.unfocusedShadowShift; + var shadowStyle = this.shadow.style, + pos = this.getElementPosition(), + size = this.element.getDimensions(); + + shadowStyle.top = pos.top - this.shadowSize.top + this.shadowShift.top + 'px'; + shadowStyle.left = pos.left - this.shadowSize.left + this.shadowShift.left + 'px'; + shadowStyle.width = size.width + this.shadowSize.width - this.shadowShift.width + "px"; + + var h = parseInt(size.height - this.shadowShift.height) + "px"; + this.centerElements.each(function(e) { + e.style.height = h + }); + + var w = parseInt(size.width + this.shadowSize.width - this.shadowShift.width) + "px"; + this.shadowContents.each(function(item) { + item.style.width = w + }); + }, + + // Get element position in integer values + getElementPosition: function() { + return { + top: this.element.getNumStyle("top"), + left: this.element.getNumStyle("left") + } + } +}); + \ No newline at end of file diff --git a/e107_files/jslib/core/shadow/e107_shadow/e107_shadow.css b/e107_files/jslib/core/shadow/e107_shadow/e107_shadow.css new file mode 100644 index 000000000..6d843bdcc --- /dev/null +++ b/e107_files/jslib/core/shadow/e107_shadow/e107_shadow.css @@ -0,0 +1,67 @@ +.shadow_container.e107_shadow .shadow_center_wrapper { + float:left; + width:100%; +} + +.shadow_container.e107_shadow .shadow_right { + float:left; + width:30px; + margin-left:-30px +} + +.shadow_container.e107_shadow .shadow_left { + float:left; + margin-left:-100%; + width:30px; +} + +.shadow_container.e107_shadow .se_shadow { + background:url(icons/se.png); + height:30px; +} + +.shadow_container.e107_shadow .s_shadow { + background:url(icons/s.png); + height:30px; + margin: 0 30px; +} + +.shadow_container.e107_shadow .sw_shadow { + background:url(icons/sw.png); + height:30px; +} + +.shadow_container.e107_shadow .ne_shadow { + background:url(icons/ne.png); + height:30px; +} + +.shadow_container.e107_shadow .n_shadow { + background:url(icons/n.png); + height:30px; + margin: 0 30px; +} + +.shadow_container.e107_shadow .nw_shadow { + background:url(icons/nw.png); + height:30px; +} + +.shadow_container.e107_shadow .e_shadow { + background:url(icons/e.png) repeat-y; +} + +.shadow_container.e107_shadow .w_shadow { + background:url(icons/w.png) repeat-y; +} + +.shadow_container.e107_shadow .c_shadow { + /* Padding is used to set shift values for unfocused window */ + padding:20px 17px 17px 17px; + /* Maring is used to set shift values for focused window */ + margin:17px 12px 12px 12px; +} + +.shadow_container.e107_shadow { + font-size: 2px; +} diff --git a/e107_files/jslib/core/shadow/e107_shadow/icons/e.png b/e107_files/jslib/core/shadow/e107_shadow/icons/e.png new file mode 100644 index 000000000..573090e1d Binary files /dev/null and b/e107_files/jslib/core/shadow/e107_shadow/icons/e.png differ diff --git a/e107_files/jslib/core/shadow/e107_shadow/icons/n.png b/e107_files/jslib/core/shadow/e107_shadow/icons/n.png new file mode 100644 index 000000000..3b9623f62 Binary files /dev/null and b/e107_files/jslib/core/shadow/e107_shadow/icons/n.png differ diff --git a/e107_files/jslib/core/shadow/e107_shadow/icons/ne.png b/e107_files/jslib/core/shadow/e107_shadow/icons/ne.png new file mode 100644 index 000000000..729e050e5 Binary files /dev/null and b/e107_files/jslib/core/shadow/e107_shadow/icons/ne.png differ diff --git a/e107_files/jslib/core/shadow/e107_shadow/icons/nw.png b/e107_files/jslib/core/shadow/e107_shadow/icons/nw.png new file mode 100644 index 000000000..5fe15a5fc Binary files /dev/null and b/e107_files/jslib/core/shadow/e107_shadow/icons/nw.png differ diff --git a/e107_files/jslib/core/shadow/e107_shadow/icons/s.png b/e107_files/jslib/core/shadow/e107_shadow/icons/s.png new file mode 100644 index 000000000..a1668d0f8 Binary files /dev/null and b/e107_files/jslib/core/shadow/e107_shadow/icons/s.png differ diff --git a/e107_files/jslib/core/shadow/e107_shadow/icons/se.png b/e107_files/jslib/core/shadow/e107_shadow/icons/se.png new file mode 100644 index 000000000..811cef051 Binary files /dev/null and b/e107_files/jslib/core/shadow/e107_shadow/icons/se.png differ diff --git a/e107_files/jslib/core/shadow/e107_shadow/icons/sw.png b/e107_files/jslib/core/shadow/e107_shadow/icons/sw.png new file mode 100644 index 000000000..336a91555 Binary files /dev/null and b/e107_files/jslib/core/shadow/e107_shadow/icons/sw.png differ diff --git a/e107_files/jslib/core/shadow/e107_shadow/icons/w.png b/e107_files/jslib/core/shadow/e107_shadow/icons/w.png new file mode 100644 index 000000000..b78560664 Binary files /dev/null and b/e107_files/jslib/core/shadow/e107_shadow/icons/w.png differ diff --git a/e107_files/jslib/e107.js.php b/e107_files/jslib/e107.js.php index 5afa4631e..3d05d231d 100644 --- a/e107_files/jslib/e107.js.php +++ b/e107_files/jslib/e107.js.php @@ -8,8 +8,8 @@ * e107 Javascript API * * $Source: /cvs_backup/e107_0.8/e107_files/jslib/e107.js.php,v $ - * $Revision: 1.39 $ - * $Date: 2009-12-16 18:34:01 $ + * $Revision: 1.40 $ + * $Date: 2009-12-17 17:15:20 $ * $Author: secretr $ * */ @@ -273,7 +273,6 @@ var e107EventManager = Class.create({ var i = this.events.get(name).keys().length; observers.set(i, callback.bind(this.scope)); - return this; }, @@ -302,7 +301,6 @@ var e107EventManager = Class.create({ */ notify: function(name) { var observers = this.events.get(name); - //console.log('notifying ' + name); if(observers) { var args = $A(arguments).slice(1); //Fix - preserve order @@ -313,7 +311,6 @@ var e107EventManager = Class.create({ } }); } - return this; } @@ -1313,18 +1310,18 @@ e107Utils.IframeShim = Class.create({ return this; }, positionUnder: function(element) { - var element = $(element); - var offset = element.cumulativeOffset(); - var dimensions = element.getDimensions(); - - this.element.setStyle({ - left: offset[0] + 'px', - top: offset[1] + 'px', - width: dimensions.width + 'px', - height: dimensions.height + 'px', - zIndex: element.getStyle('zIndex') - 1 - }).show(); + var element = $(element), + offset = element.cumulativeOffset(), + dimensions = element.getDimensions(), + style = { + left: offset[0] + 'px', + top: offset[1] + 'px', + width: dimensions.width + 'px', + height: dimensions.height + 'px', + zIndex: element.getStyle('zIndex') - 1 + }; + this.element.setStyle(style).show(); return this; }, setBounds: function(bounds) { @@ -1333,6 +1330,16 @@ e107Utils.IframeShim = Class.create({ this.element.setStyle(bounds); return this; }, + setSize: function(width, height) { + this.element.style.width = parseInt(width) + 'px'; + this.element.style.height = parseInt(height) + 'px'; + return this; + }, + setPosition: function(top, left) { + this.element.style.top = parseInt(top) + 'px'; + this.element.style.left = parseInt(left) + 'px'; + return this; + }, destroy: function() { if(this.element) this.element.remove();