 var Waiter = new Class({ options: { baseHref: 'http://www.cnet.com/html/rb/assets/global/waiter/', img: { src: 'waiter.gif', id: 'waitingImg', styles: { position: 'absolute', width: 24, height: 24, display: 'none', opacity: 0, zIndex: 999 } }, imgPosition: {}, layer:{ id: 'waitingDiv', background: '#fff', opacity: 0.9 }, fxOptions: {} }, initialize: function(target, options){ this.target = $(target||document.body); this.setOptions(options); this.waiterImg = $(this.options.img.id) || new Element('img', $merge(this.options.img, { src: this.options.baseHref + this.options.img.src })).injectInside(document.body); this.waiterDiv = $(this.options.layer.id) || new Element('div', { id: this.options.layer.id, styles: { width: 0, height: 0, position: 'absolute', zIndex: 998, display: 'none', opacity: 0, backgroundColor: this.options.layer.background } }).injectInside(document.body); this.waiterFx = this.waiterFx || new Fx.Elements($$(this.waiterImg, this.waiterDiv), this.options.fxOptions); }, toggle: function(element, show) { if (this.inTransit) { this.chain(this.toggle.bind(this, [element, show])); return this; } element = $(element) || $(this.active) || $(this.target); if (!$(element)) return this; if (this.active && element != this.active) return this.stop().chain(this.start.bind(this, element)); if((!this.active || show) && show !== false) this.start(element); else if(this.active && !show) this.stop(); return this; }, start: function(element){ if (this.inTransit) { this.chain(this.start.bind(this, element)); return this; } this.inTransit = true; element = $(element) || $(this.target); var start = function() { var dim = element.getComputedSize(); this.active = element; this.waiterImg.setPosition($merge(this.options.imgPosition, { relativeTo: element })).show(); this.waiterDiv.setStyles({ width: dim.totalWidth, height: dim.totalHeight, display: 'block' }).setPosition({ relativeTo: element, position: 'upperLeft' }); this.waiterFx.start({ 0: { opacity:[1] }, 1: { opacity:[this.options.layer.opacity]} }).chain(function(){ this.inTransit = false; this.fireEvent('onShow', element); this.callChain(); }.bind(this)); }.bind(this); if (this.active && this.active != element) this.stop(start); else start(); return this; }, stop: function(callback){ if (this.inTransit) { this.chain(this.stop.bind(this, callback)); return this; } if (!this.active) return this; this.inTransit = true; this.waiterFx.start({ 0: { opacity:[0]}, 1: { opacity:[0]} }).chain(function(){ this.inTransit = false; this.active = null; this.waiterDiv.hide(); this.waiterImg.hide(); this.fireEvent('onHide', this.active); this.callChain(); if ($type(callback) == "function") callback.attempt(); }.bind(this)); return this; } }); Waiter.implement(new Options, new Events, new Chain); if (typeof Ajax != "undefined") { var Ajax = Ajax.extend({ options: { useWaiter: false, waiterOptions: {} }, initialize: function(url, options){ this.parent(url, options); if (this.options.useWaiter && this.options.update) { this.waiter = new Waiter(this.options.update, this.options.waiterOptions); this.addEvent('onComplete', this.waiter.stop.bind(this.waiter)); this.addEvent('onFailure', this.waiter.stop.bind(this.waiter)); } }, request: function(data) { if (this.waiter) this.waiter.start().chain(this.parent.bind(this, data)); else this.parent(data); return this; } }); } Element.extend({ isVisible: function() { return this.getStyle('display') != 'none'; }, toggle: function() { return this[this.isVisible() ? 'hide' : 'show'](); }, hide: function() { this.originalDisplay = this.getStyle('display'); this.setStyle('display','none'); return this; }, show: function(display) { this.originalDisplay = (this.originalDisplay=="none")?'block':this.originalDisplay; this.setStyle('display',(display || this.originalDisplay || 'block')); return this; }, tidy: function(){ try { if(this.getValue().tidy())this.value = this.getValue().tidy(); }catch(e){dbug.log('element.tidy error: %o', e);} }, findParent: function(collection){ return $$(collection).filter(function(el){ return el.hasChild(this); }, this)[0]; }, fxOpacityOk: function(){ if (!window.ie6)return true; var isColor = false; try { if (new Color(this.getStyle('backgroundColor'))) isColor = true; }catch(e){} return isColor; } }); Element.visible = Element.isVisible; if(!Element.empty) { Element.extend({ empty: function(){ return this.setHTML(''); } }); } var $S = $$; Element.extend({ getDimensions: function(options) { options = $merge({computeSize: false},options); var dim = {}; function getSize(el, options){ if(options.computeSize) dim = el.getComputedSize(options); else { dim.width = el.getSize().size.x; dim.height = el.getSize().size.y; } return dim; } try { dim = getSize(this, options); }catch(e){} if(this.getStyle('display') == 'none'){ var before = {}; ['visibility', 'display', 'position'].each(function(style){ before[style] = this.style[style]||''; }, this); this.setStyles({ visibility: 'hidden', display: 'block', position:'absolute' }); dim = getSize(this, options); this.setStyles(before); } return $merge(dim, {x: dim.width, y: dim.height}); }, getComputedSize: function(options){ options = $merge({ styles: ['padding','border'], plains: {height: ['top','bottom'], width: ['left','right']}, mode: 'both' }, options); var size = {width: 0,height: 0}; switch (options.mode){ case 'vertical': delete size.width; delete options.plains.width; break; case 'horizontal': delete size.height; delete options.plains.height; break; } var getStyles = []; $each(options.plains, function(plain, key){ plain.each(function(edge){ options.styles.each(function(style){ getStyles.push((style=="border")?style+'-'+edge+'-'+'width':style+'-'+edge); }); }); }); var styles = this.getStyles.apply(this, getStyles); var subtracted = []; $each(options.plains, function(plain, key){ size['total'+key.capitalize()] = 0; size['computed'+key.capitalize()] = 0; plain.each(function(edge){ size['computed'+edge.capitalize()] = 0; getStyles.each(function(style,i){ if(style.test(edge)) { styles[style] = styles[style].toInt(); if(isNaN(styles[style]))styles[style]=0; size['total'+key.capitalize()] = size['total'+key.capitalize()]+styles[style]; size['computed'+edge.capitalize()] = size['computed'+edge.capitalize()]+styles[style]; } if(style.test(edge) && key!=style && (style.test('border') || style.test('padding')) && !subtracted.test(style)) { subtracted.push(style); size['computed'+key.capitalize()] = size['computed'+key.capitalize()]-styles[style]; } }); }); }); if($chk(size.width)) { size.width = size.width+this.offsetWidth+size.computedWidth; size.totalWidth = size.width + size.totalWidth; delete size.computedWidth; } if($chk(size.height)) { size.height = size.height+this.offsetHeight+size.computedHeight; size.totalHeight = size.height + size.totalHeight; delete size.computedHeight; } return $merge(styles, size); } }); Element.extend({ setPosition: function(options){ options = $merge({ relativeTo: document.body, position: { x: 'center', y: 'center' }, edge: false, offset: {x:0,y:0}, returnPos: false, relFixedPosition: false, ignoreMargins: false, overflown: [] }, options); var parentOffset = {x: 0, y: 0}; var parentPositioned = false; if(this.getParent() != document.body) { var parent = this.getParent(); while(parent != document.body && parent.getStyle('position') == "static") { parent = parent.getParent(); } if(parent != document.body) { parentOffset = parent.getPosition(); parentPositioned = true; } options.offset.x = options.offset.x - parentOffset.x; options.offset.y = options.offset.y - parentOffset.y; } function fixValue(option) { if($type(option) != "string") return option; option = option.toLowerCase(); var val = {}; if(option.test('left')) val.x = 'left'; else if(option.test('right')) val.x = 'right'; else val.x = 'center'; if(option.test('upper')||option.test('top')) val.y = 'top'; else if (option.test('bottom')) val.y = 'bottom'; else val.y = 'center'; return val; }; options.edge = fixValue(options.edge); options.position = fixValue(options.position); if(!options.edge) { if(options.position.x == 'center' && options.position.y == 'center') options.edge = {x:'center',y:'center'}; else options.edge = {x:'left',y:'top'}; } this.setStyle('position', 'absolute'); var rel = $(options.relativeTo) || document.body; if (window.opera) { var top = (rel == document.body)?window.getScrollTop():rel.getTop(); var left = (rel == document.body)?window.getScrollLeft():rel.getLeft(); } else { var top = (rel == document.body)?window.getScrollTop():rel.getTop(options.overflown); var left = (rel == document.body)?window.getScrollLeft():rel.getLeft(options.overflown); } if (top < 0) top = 0; if (left < 0) left = 0; var dim = this.getDimensions({computeSize: true, styles:['padding', 'border','margin']}); if (options.ignoreMargins) { options.offset.x += ((options.edge && options.edge.x == "right")?dim['margin-right']:-dim['margin-left']); options.offset.y += ((options.edge && options.edge.y == "bottom")?dim['margin-bottom']:-dim['margin-top']); } var pos = {}; var prefY = options.offset.y.toInt(); var prefX = options.offset.x.toInt(); switch(options.position.x) { case 'left': pos.x = left + prefX; break; case 'right': pos.x = left + prefX + rel.offsetWidth; break; default: pos.x = left + (((rel == document.body)?window.getWidth():rel.offsetWidth)/2) + prefX; break; }; switch(options.position.y) { case 'top': pos.y = top + prefY; break; case 'bottom': pos.y = top + prefY + rel.offsetHeight; break; default: pos.y = top + (((rel == document.body)?window.getHeight():rel.offsetHeight)/2) + prefY; break; }; if(options.edge){ var edgeOffset = {}; switch(options.edge.x) { case 'left': edgeOffset.x = 0; break; case 'right': edgeOffset.x = -dim.x-dim.computedRight-dim.computedLeft; break; default: edgeOffset.x = -(dim.x/2); break; }; switch(options.edge.y) { case 'top': edgeOffset.y = 0; break; case 'bottom': edgeOffset.y = -dim.y-dim.computedTop-dim.computedBottom; break; default: edgeOffset.y = -(dim.y/2); break; }; pos.x = pos.x+edgeOffset.x; pos.y = pos.y+edgeOffset.y; } pos = { left: ((pos.x >= 0 || parentPositioned)?pos.x:0).toInt()+'px', top: ((pos.y >= 0 || parentPositioned)?pos.y:0).toInt()+'px' }; if(rel.getStyle('position') == "fixed"||options.relFixedPosition) { pos.top = pos.top.toInt() + window.getScrollTop()+'px'; pos.left = pos.left.toInt() + window.getScrollLeft()+'px'; } if(options.returnPos) return pos; if(options.smoothMove) new Fx.SmoothMove(this, options).start(); else this.setStyles(pos); return this; } }); var Modalizer = new Class({ defaultModalStyle: { 'display':'block', 'position':'fixed', 'top':'0px', 'left':'0px', 'z-index':5000, 'background-color':'#333', 'opacity':.8 }, setModalOptions: function(options){ this.modalOptions = $merge({ 'width':(window.getScrollWidth()+300)+'px', 'height':(window.getScrollHeight()+300)+'px', elementsToHide: 'select', onModalHide: Class.empty, onModalShow: Class.empty, hideOnClick: false, modalStyle: {} }, this.modalOptions, options || {}); }, setModalStyle: function (styleObject){ this.modalOptions.modalStyle = styleObject; this.modalStyle = $merge(this.defaultModalStyle, { 'width':this.modalOptions.width, 'height':this.modalOptions.height }, styleObject); if($('modalOverlay'))$('modalOverlay').setStyles(this.modalStyle); return(this.modalStyle); }, modalShow: function(options){ this.setModalOptions(options||{}); var overlay = null; if($('modalOverlay')) overlay = $('modalOverlay'); if(!overlay) overlay = new Element('div').setProperty('id','modalOverlay').injectInside(document.body); overlay.setStyles(this.setModalStyle(this.modalOptions.modalStyle)); if(window.ie6) overlay.setStyle('position','absolute'); $('modalOverlay').removeEvents('click').addEvent('click', function(){ this.modalHide(this.modalOptions.hideOnClick); }.bind(this)); this.modalOptions.onModalShow(); this.togglePopThroughElements(0); overlay.setStyle('display','block'); return this; }, modalHide: function(override){ if(override === false) return; this.togglePopThroughElements(1); this.modalOptions.onModalHide(); if($('modalOverlay'))$('modalOverlay').setStyle('display','none'); return this; }, togglePopThroughElements: function(opacity){ if((window.ie6 || (window.gecko && navigator.userAgent.test('mac', 'i')))) { $$(this.modalOptions.elementsToHide).each(function(sel){ sel.setStyle('opacity', opacity); }); } } }); var modalizer = Modalizer; window.extend({ supportsPositionFixed: function(){ if(!window.loaded) return null; var test = new Element('div').setStyles({ position: 'fixed', top: '0px', right: '0px' }).injectInside(document.body); var supported = (test.offsetTop === 0); test.remove(); return supported; } }); Element.extend({ pin: function(enable){ var p = this.getPosition(); if(enable!==false) { if(!this.pinned) { var pos = { top: (p.y - window.getScrollTop())+'px', left: (p.x - window.getScrollLeft())+'px' }; if(window.supportsPositionFixed()) { this.setStyle('position','fixed').setStyles(pos); } else { this.setStyles({ position: 'absolute', top: p.y+'px', left: p.x+'px' }); window.addEvent('scroll', function(){ if(this.pinned) { var to = { top: (pos.top.toInt() + window.getScrollTop())+'px', left: (pos.left.toInt() + window.getScrollLeft())+'px' }; this.setStyles(to); } }.bind(this)); } this.pinned = true; } } else { this.pinned = false; var reposition = (window.supportsPositionFixed())? { top: (p.y + window.getScrollTop())+'px', left: (p.x + window.getScrollLeft())+'px' }: { top: (p.y)+'px', left: (p.x)+'px' }; this.setStyles($merge(reposition, {position: 'absolute'})); } return this; }, unpin: function(){ return this.pin(false); }, togglepin: function(){ this.pin(!this.pinned); } }); var StickyWin = new Class({ options: { onDisplay: Class.empty, onClose: Class.empty, closeClassName: 'closeSticky', pinClassName: 'pinSticky', content: '', zIndex: 10000, className: '', edge: false, position: 'center', offset: {x:0,y:0}, relativeTo: document.body, width: false, height: false, timeout: -1, allowMultipleByClass: false, allowMultiple: true, showNow: true, useIframeShim: true, iframeShimSelector: '' }, css: '.SWclearfix:after {content: "."; display: block; height: 0; clear: both; visibility: hidden;}'+ '.SWclearfix {display: inline-table;}'+ '* html .SWclearfix {height: 1%;}'+ '.SWclearfix {display: block;}', initialize: function(options){ this.setOptions(options); this.id = this.options.id || 'StickyWin_'+new Date().getTime(); this.makeWindow(); if(this.options.content) this.setContent(this.options.content); if(this.options.showNow) this.show(); window.addEvent('domready', function(){ try { if(!$('StickyWinClearfix')) { var style = new Element('style').setProperty('id','StickyWinClearfix').injectInside($$('head')[0]); if (!style.setText.attempt(this.css, style)) style.appendText(this.css); } }catch(e){dbug.log('error: %s',e);} }.bind(this)); }, makeWindow: function(){ this.destroyOthers(); if(!$(this.id)) { this.win = new Element('div').setProperty('id', this.id).addClass(this.options.className).addClass('StickyWinInstance').addClass('SWclearfix').setStyles({ 'display':'none', 'position':'absolute', 'zIndex':this.options.zIndex }).injectInside(document.body); } else this.win = $(this.id); if(this.options.width && $type(this.options.width.toInt())=="number") this.win.setStyle('width', this.options.width.toInt() + 'px'); if(this.options.height && $type(this.options.height.toInt())=="number") this.win.setStyle('height', this.options.height.toInt() + 'px'); return this; }, show: function(){ this.fireEvent('onDisplay'); if(!this.positioned) this.position(); this.showWin(); if(this.options.useIframeShim) this.showIframeShim(); this.visible = true; return this; }, showWin: function(){ this.win.setStyle('display','block'); }, hide: function(){ this.fireEvent('onClose'); this.hideWin(); if(this.options.useIframeShim) this.hideIframeShim(); this.visible = false; return this; }, hideWin: function(){ this.win.setStyle('display','none'); }, destroyOthers: function() { if(!this.options.allowMultipleByClass || !this.options.allowMultiple) { $$('div.StickyWinInstance').each(function(sw) { if(!this.options.allowMultiple || (!this.options.allowMultipleByClass && sw.hasClass(this.options.className))) sw.remove(); }, this); } }, setContent: function(html) { if(this.win.getChildren().length>0) this.win.empty(); if($type(html) == "string") this.win.setHTML(html); else if ($(html)) this.win.adopt(html); this.win.getElements('.'+this.options.closeClassName).each(function(el){ el.addEvent('click', this.hide.bind(this)); }, this); this.win.getElements('.'+this.options.pinClassName).each(function(el){ el.addEvent('click', this.togglepin.bind(this)); }, this); return this; }, position: function(){ this.positioned = true; this.win.setPosition({ relativeTo: this.options.relativeTo, position: this.options.position, offset: this.options.offset, edge: this.options.edge }); if(this.shim) this.shim.position(); return this; }, pin: function(pin) { if(!this.win.pin) { dbug.log('you must include element.pin.js!'); return false; } this.pinned = $pick(pin, true); return this.win.pin(pin); }, unpin: function(){ this.pin(false); }, togglepin: function(){ this.pin(!this.pinned); }, makeIframeShim: function(){ if(!this.shim){ this.shim = new IframeShim({ element: (this.options.iframeShimSelector)?this.win.getElement(this.options.iframeShimSelector) : $('StickyWinOverlay') || this.win, display: false, name: 'StickyWinShim' }); } }, showIframeShim: function(){ if(this.options.useIframeShim) { this.makeIframeShim(); this.shim.show(); } }, hideIframeShim: function(){ if(this.options.useIframeShim) this.shim.hide(); }, destroy: function(){ this.win.remove(); if(this.options.useIframeShim) this.shim.remove(); if($('StickyWinOverlay'))$('StickyWinOverlay').remove(); } }); StickyWin.implement(new Options); StickyWin.implement(new Events); var stickyWin = StickyWin; var StickyWinFx = StickyWin.extend({ initialize: function(options){ this.parent($merge({ fade: true, fadeDuration: 150, fadeTransition: Fx.Transitions.sineInOut, draggable: false, dragOptions: {}, dragHandleSelector: 'h1.caption', resizable: false, resizeOptions: {}, resizeHandleSelector: '' }, options)); }, setContent: function(html){ this.parent(html); if(this.options.draggable) this.makeDraggable(); if(this.options.resizable) this.makeResizable(); return this; }, hideWin: function(){ if(this.options.fade) this.fade(1,0); else this.win.hide(); }, showWin: function(){ if(this.options.fade) { this.fade(0,1); } else this.win.show(); }, fade: function(from,to){ if(!this.fadeFx) { this.win.setStyles({ 'opacity':'0', 'display':'block' }); this.fadeFx = this.win.effect('opacity', { duration: this.options.fadeDuration, transition: this.options.fadeTransition }); } if (to > 0) this.win.setStyle('display','block'); this.fadeFx.custom(from,to).chain(function(){ if(to == 0) this.win.setStyle('display', 'none'); }.bind(this)); return this; }, makeDraggable: function(){ dbug.log('you must include Drag.js, cannot make draggable'); }, makeResizable: function(){ dbug.log('you must include Drag.js, cannot make resizable'); } }); var modalWinBase = { initialize: function(options){ options = options||{}; this.setModalOptions($merge(options.modalOptions||{}, { onModalHide: function(){ this.hide(false); }.bind(this) })); this.parent(options); }, show: function(showModal){ if($pick(showModal, true))this.modalShow(); this.parent(); }, hide: function(hideModal){ if($pick(hideModal, true))this.modalHide(); this.parent(); } }; var StickyWinModal = StickyWin.extend(modalWinBase); StickyWinModal.implement(new Modalizer); var StickyWinFxModal = (typeof StickyWinFx != "undefined")?StickyWinFx.extend(modalWinBase):Class.empty; try { StickyWinFxModal.implement(new Modalizer()); }catch(e){}