diff options
Diffstat (limited to 'public/javascripts/vendor/ContentFlow/contentflow_src.js')
| -rw-r--r-- | public/javascripts/vendor/ContentFlow/contentflow_src.js | 2584 | 
1 files changed, 2584 insertions, 0 deletions
| diff --git a/public/javascripts/vendor/ContentFlow/contentflow_src.js b/public/javascripts/vendor/ContentFlow/contentflow_src.js new file mode 100644 index 0000000..b6a5968 --- /dev/null +++ b/public/javascripts/vendor/ContentFlow/contentflow_src.js @@ -0,0 +1,2584 @@ +/*  ContentFlow, version 1.0.2  + *  (c) 2007 - 2010 Sebastian Kutsch + *  <http://www.jacksasylum.eu/ContentFlow/> + * + *  ContentFlow is distributed under the terms of the MIT license. + *  (see http://www.jacksasylum.eu/ContentFlow/LICENSE) + * + *--------------------------------------------------------------------------*/ +/*  + * ============================================================ + * Global configutaion and initilization object + * ============================================================ + */ +var ContentFlowGlobal = { +    Flows: new Array, +    AddOns: {},  +    scriptName: 'contentflow.js', +    scriptElement:  null, +    Browser: new (function () { +        this.Opera = window.opera ? true : false; +        this.IE = document.all && !this.Opera ? true : false; +        this.IE6 = this.IE && typeof(window.XMLHttpRequest) == "undefined" ? true : false; +        this.IE8 = this.IE && typeof(document.querySelectorAll) != "undefined" ? true : false; +        this.IE7 = this.IE && ! this.IE6 && !this.IE8 ? true : false; +        this.WebKit = /WebKit/i.test(navigator.userAgent) ? true : false,  +        this.iPhone = /iPhone|iPod/i.test(navigator.userAgent)? true : false; +        this.Chrome = /Chrome/i.test(navigator.userAgent) ? true : false; +        this.Safari = /Safari/i.test(navigator.userAgent) && !this.Chrome ? true : false; +        this.Konqueror = navigator.vendor == "KDE" ? true : false; +        this.Konqueror4 = this.Konqueror && /native code/.test(document.getElementsByClassName) ? true : false; +        this.Gecko = !this.WebKit && navigator.product == "Gecko" ? true : false; +        this.Gecko19 = this.Gecko && Array.reduce ? true : false; +    })(), + +    getAddOnConf: function(name) { +        if(this.AddOns[name]) +            return this.AddOns[name].conf; +        else +            return {}; +    }, + +    setAddOnConf: function (name, conf) { +        this.AddOns[name].setConfig(conf); +    }, + +    getScriptElement:function (scriptName) { +        var regex = new RegExp(scriptName); +        var scripts = document.getElementsByTagName('script'); +        for (var i=0; i<scripts.length; i++) { +            if (scripts[i].src && regex.test(scripts[i].src)) +                return scripts[i]; +        } +        return ''; +    }, + +    getScriptPath: function (scriptElement, scriptName) { +        var regex = new RegExp(scriptName+".*"); +        return scriptElement.src.replace(regex, ''); +    }, + +    addScript: function  (path) { +        if (this.Browser.IE || this.Browser.WebKit || this.Browser.Konqueror) { +            document.write('<script type="text/javascript" src="'+path+'"><\/script>'); +        } +        else { +            var script = document.createElement('script'); +            script.src = path; +            script.setAttribute('type', 'text/javascript'); +            document.getElementsByTagName('head')[0].appendChild(script); +        } +    }, + +    addScripts: function  (basePath, filenames) { +        for (var i=0; i<filename.length; i++) +            this.addScript(basepath+filenames[i]); +    }, + +    addStylesheet: function (path) { +        if (this.Browser.Gecko19) { +            var link = document.createElement('link'); +            link.setAttribute('rel', 'stylesheet'); +            link.setAttribute('href', path); +            link.setAttribute('type', 'text/css'); +            link.setAttribute('media', 'screen'); +            document.getElementsByTagName('head')[0].appendChild(link); +        } +        else { +            document.write('<link rel="stylesheet" href="'+path+'" type="text/css" media="screen" />'); +        } + +    }, + +    addStylesheets: function  (basePath, filenames) { +        for (var i=0; i<filename.length; i++) +            this.addStylesheet(basepath+filenames[i]); +    }, + +    initPath: function () { +        /* get / set basic values */ +        this.scriptElement = this.getScriptElement(this.scriptName); +        if (!this.scriptElement) { +            this.scriptName = 'contentflow_src.js'; +            this.scriptElement = this.getScriptElement(this.scriptName); +        } + +        this.BaseDir = this.getScriptPath(this.scriptElement, this.scriptName) ; +        if (!this.AddOnBaseDir) this.AddOnBaseDir = this.BaseDir; +        if (!this.CSSBaseDir) this.CSSBaseDir = this.BaseDir; +    }, + +    init: function () { +        /* add default stylesheets */ +        this.addStylesheet(this.CSSBaseDir+'contentflow.css'); +        this.addStylesheet(this.CSSBaseDir+'mycontentflow.css');    // FF2: without adding a css-file FF2 hangs on a reload. +                                                                    //      I don't have the slidest idea why +                                                                    //      Could be timing problem +        this.loadAddOns = new Array(); +        /* add AddOns scripts */ +        if (this.scriptElement.getAttribute('load')) { +            var AddOns = this.loadAddOns = this.scriptElement.getAttribute('load').replace(/\ +/g,' ').split(' '); +            for (var i=0; i<AddOns.length; i++) { +                if (AddOns[i] == '') continue; +                //if (AddOns[i] == 'myStyle') { +                    //this.addStylesheet(this.BaseDir+'mycontentflow.css'); +                    //continue; +                //} +                this.addScript(this.AddOnBaseDir+'ContentFlowAddOn_'+AddOns[i]+'.js'); +            } +        } + +        /* ========== ContentFlow auto initialization on document load ========== +         * thanks to Dean Edwards +         * http://dean.edwards.name/weblog/2005/02/order-of-events/ +         */ +        var CFG = this; + +        /* for Mozilla, Opera 9, Safari */ +        if (document.addEventListener) { +            /* for Safari */ +            if (this.Browser.WebKit) { +                var _timer = setInterval(function() { +                    if (/loaded|complete/.test(document.readyState)) { +                        clearInterval(_timer); +                        CFG.onloadInit(); // call the onload handler +                    } +                }, 10); +            } +            else { +              document.addEventListener("DOMContentLoaded", CFG.onloadInit, false); +            } +        } +        else if (this.Browser.IE) { +            document.write("<script id=__ie_cf_onload defer src=javascript:void(0)><\/script>"); +            var script = document.getElementById("__ie_cf_onload"); +            script.onreadystatechange = function() { +                if (this.readyState == "complete") { +                    CFG.onloadInit(); // call the onload handler +                } +            }; +        } + +        /* for all other browsers */ +        window.addEvent('load', CFG.onloadInit, false); + +        /* ================================================================== */ + +    }, + +    onloadInit: function () { +        // quit if this function has already been called +        if (arguments.callee.done) return; +        for (var i=0; i< ContentFlowGlobal.loadAddOns.length; i++) { +            var a = ContentFlowGlobal.loadAddOns[i]; +            if (!ContentFlowGlobal.AddOns[a]) { +                var CFG = ContentFlowGlobal; +                window.setTimeout( CFG.onloadInit, 10); +                return; +            } +        } +        // flag this function so we don't do the same thing twice +        arguments.callee.done = true; +         +        /* fix for mootools */ +        if (window.Element && Element.implement && document.all && !window.opera) { +            for (var prop in window.CFElement.prototype) { +                if(!window.Element.prototype[prop]) { +                    var implement = {}; +                    implement[prop] = window.CFElement.prototype[prop]; +                    Element.implement(implement); +                } +            } +        } + +        /* init all manualy created flows */ +        for (var i=0; i< ContentFlowGlobal.Flows.length; i++) { +            ContentFlowGlobal.Flows[i].init();  +        } + +        /* init the rest */ +        var divs = document.getElementsByTagName('div'); +        DIVS: for (var i = 0; i < divs.length; i++) { +            if (divs[i].className.match(/\bContentFlow\b/)) { +                for (var j=0; j<ContentFlowGlobal.Flows.length; j++) { +                    if (divs[i] == ContentFlowGlobal.Flows[j].Container) continue DIVS; +                } +                var CF = new ContentFlow(divs[i],{}, false); +                CF.init(); +            } +        } +    } + +}; + +ContentFlowGlobal.initPath(); + + +/* + * ============================================================ + * ContentFlowAddOn + * ============================================================ + */ +var ContentFlowAddOn = function (name, methods, register) { +    if (typeof register == "undefined" || register != false) +        ContentFlowGlobal.AddOns[name] = this; +         +    this.name = name; +    if (!methods) methods = {}; +    this.methods = methods; +    this.conf = {}; +    if (this.methods.conf) { +       this.setConfig(this.methods.conf); +       delete this.methods.conf; +    } + + +    this.scriptpath = ContentFlowGlobal.AddOnBaseDir; +    if (methods.init) { +        var init = methods.init.bind(this); +        init(this); +    } +}; + +ContentFlowAddOn.prototype = { +    Browser: ContentFlowGlobal.Browser, + +    addScript: ContentFlowGlobal.addScript, +    addScripts: ContentFlowGlobal.addScripts, + +    addStylesheet: function (path) { +        if (!path) +            path = this.scriptpath+'ContentFlowAddOn_'+this.name+'.css'; +        ContentFlowGlobal.addStylesheet(path); +    }, +    addStylesheets: ContentFlowGlobal.addStylesheets, + +    setConfig: function (conf) { +        for (var c in conf) { +            this.conf[c] = conf[c]; +        } +    }, + +    _init: function (flow) { +        if (this.methods.ContentFlowConf) { +            flow.setConfig(this.methods.ContentFlowConf); +        } +    } + + +}; + + + +/*  + * ============================================================ + * ContentFlowGUIElement + * ============================================================ + */ + +var ContentFlowGUIElement = function (CFobj, element) { +    element.setDimensions = function () { +        this.dimensions = this.getDimensions(); +        this.center = {x: this.dimensions.width/2, y:this.dimensions.height/2}; +        this.position = this.findPos(); +    }; +    element.addObserver = function (eventName, method) { +        var m = this.eventMethod = method.bind(CFobj); +        this.observedEvent = eventName; +        this.addEvent(eventName, m, false); +    }; +     +    element.makeDraggable = function (onDrag, beforeDrag, afterDrag) { + +        this.stopDrag = function(event) { +            if (!event) var event = window.event; +            if (this.Browser.iPhone)  { +                window.removeEvent('touchemove', onDrag, false); +                if (!this.ontochmove) { +                    var t = event.target; +                    if (t.firstChild) t = t.firstChild; +                    var e = document.createEvent('MouseEvents'); +                    e.initEvent('click', true, true); +                    t.dispatchEvent(e); +                } +            } +            else { +                window.removeEvent('mousemove', onDrag, false); +            } +            afterDrag(event);  +        }.bind(this); + +        this.initDrag = function (event) { +            if (!event) var event = window.event; +            var e = event; +            if (event.touches) e = event.touches[0]; + +            this.mouseX = e.clientX;  +            this.mouseY = e.clientY;  + +            beforeDrag(event); + +        }.bind(this); + +        this.startDrag = function (event) { +            if (!event) var event = window.event; + +            var stopDrag = this.stopDrag; + +            if (this.Browser.iPhone)  { +                var s = this; +                s.ontouchmove = false +                window.addEvent('touchmove', function (e) { +                        s.ontouchmove = true;  +                        onDrag(e); +                }, false); +                event.preventDefault(); +                window.addEvent('touchend', stopDrag, false); +            } +            else { +                window.addEvent('mousemove', onDrag, false); +                window.addEvent('mouseup', stopDrag, false); +            } +            if(event.preventDefault) { event.preventDefault() } + +        }.bind(this); + +        var startDrag = this.startDrag; +        if (this.Browser.iPhone)  { +            this.addEventListener('touchstart', startDrag, false); +        } +        else { +            this.addEvent('mousedown', startDrag, false);  +        } +         +    }; + +    element.Browser = ContentFlowGlobal.Browser; +    $CF(element).setDimensions(); +    return element; +}; + + +/*  + * ============================================================ + * ContentFlowItem + * ============================================================ + */ +var ContentFlowItem  = function (CFobj, element, index) { +    this.CFobj = CFobj; +    this._activeElement = CFobj.conf.activeElement; +    this.pre = null; +    this.next = null; +    /* +     * ==================== item click events ==================== +     * handles the click event on an active and none active item +     */ + +    this.clickItem = function (event) { +        if(!event) var event = window.event; +        var el = event.target ? event.target : event.srcElement; +        var index = el.itemIndex ? el.itemIndex : el.parentNode.itemIndex; +        var item = this.items[index]; +        if (this._activeItem == item) { +            this.conf.onclickActiveItem(item); +        } +        else { +            if (this.conf.onclickInactiveItem(item) != false ) this.moveToIndex(index); +        } +    }.bind(CFobj), + +    this.setIndex = function (index) { +        this.index = index; +        this.element.itemIndex = index; +    }; +    this.getIndex = function () { +        return this.index; +    }; + + +    /* generate deault HTML structure if item is an image */ +    if ($CF(element).nodeName == "IMG") { +        var el = document.createElement('div'); +        el.className = "item"; + +        var cont = element.parentNode.replaceChild( el, element); +        cont.className = "content"; +        el.appendChild(cont); + +        if (element.title) { +            var cap = document.createElement('div'); +            cap.className = "caption"; +            cap.innerHTML = element.title; +            el.appendChild(cap); +        } +        element = el; +    } + +    /* create item object */ +    this.element = $CF(element); +    this.item = element; +    if (typeof index != "undefined") this.setIndex(index); +    this.content = this.element.getChildrenByClassName('content')[0]; +    this.caption = this.element.getChildrenByClassName('caption')[0]; +    this.label = this.element.getChildrenByClassName('label')[0]; + +    /* if content is image set properties */ +    if (this.content.nodeName == "IMG") { +        CFobj._imagesToLoad++; + +        var foobar = function () {  +            CFobj._imagesToLoad--; +            this.image = this.content; +            this.setImageFormat(this.image); +            if ( CFobj.conf.reflectionHeight > 0) { +                this.addReflection(); +            } +            this.initClick(); +            CFobj._addItemCueProcess(true); +        }.bind(this); + +        if (this.content.complete && this.content.width > 0) +            window.setTimeout(foobar, 100); +        else if (this.Browser.IE && !this.content.onload) { +            var self = this; +            var t = window.setInterval( function () { +                if (self.content.complete && self.content.width > 0) { +                    window.clearInterval(t); +                    foobar(); +                } +            }, 10); +        } +        else +            this.content.onload = window.setTimeout(foobar, 100); +    } +    else { +        this.initClick(); +        CFobj._addItemCueProcess(true); +    } + +}; + +ContentFlowItem.prototype = { +     +    Browser: ContentFlowGlobal.Browser, + +    makeActive: function () { +        this.element.addClassName('active'); +        this.CFobj.conf.onMakeActive(this); +    }, +     +    makeInactive: function () { +        this.element.removeClassName('active'); +        this.CFobj.conf.onMakeInactive(this); +    }, + +    initClick: function () { +        var cItem = this.clickItem; +        this[this._activeElement].addEvent('click', cItem, false); +    }, +     +    setImageFormat: function (img) { +        if (this.Browser.IE6 || this.Browser.IE7) img.style.width = "auto"; +        img.origProportion =  img.width / img.height; +        img.setAttribute('origProportion', img.width / img.height); +        if (this.Browser.IE6 || this.Browser.IE7) img.style.width = ""; +        //img.origWidth = img.width; +        //img.origHeight = img.height; +        if (img.origProportion <= 1) +            img.addClassName('portray'); +        else +            img.addClassName('landscape'); +    }, + +    /* +     * add reflection to item +     */ +    addReflection: function() { +        var CFobj = this.CFobj; +        var reflection; +        var image = this.content; + + +        if (this.Browser.IE) { +            var filterString = 'progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)'; +            if (CFobj._reflectionColorRGB) { +                // transparent gradient +                if (CFobj.conf.reflectionColor == "transparent") { +                    var RefImg = reflection = this.reflection = document.createElement('img'); +                    reflection.src = image.src; +                } +                // color gradient +                else { +                    reflection = this.reflection = document.createElement('div'); +                    var RefImg = document.createElement('img'); +                    RefImg.src = image.src; +                    reflection.width = RefImg.width; +                    reflection.height = RefImg.height; +                    RefImg.style.width = '100%'; +                    RefImg.style.height = '100%'; +                    var color = CFobj._reflectionColorRGB; +                    reflection.style.backgroundColor = '#'+color.hR+color.hG+color.hB; +                    reflection.appendChild(RefImg); +                } +                filterString += ' progid:DXImageTransform.Microsoft.Alpha(opacity=0, finishOpacity=50, style=1, finishX=0, startY='+CFobj.conf.reflectionHeight*100+' finishY=0)'; +            } else { +                var RefImg = reflection = this.reflection = document.createElement('img'); +                reflection.src = image.src; +            } +            // crop image (streches and crops (clip on default dimensions), original proportions will be restored through CSS) +            filterString += ' progid:DXImageTransform.Microsoft.Matrix(M11=1, M12=0, M21=0, M22='+1/CFobj.conf.reflectionHeight+')'; + +            if (ContentFlowGlobal.Browser.IE6) { +                if (image.src.match(/\.png$/) ) { +                    image.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+image.src+"', sizingMethod=scale )"; +                    image.filterString = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+image.src+"', sizingMethod=scale )"; +                    filterString += " progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+image.src+"', sizingMethod=scale )"; +                    image.origSrc = image.src; +                    image.src='img/blank.gif'; +                    RefImg.src="img/blank.gif"; +                } +            } + +            reflection.filterString = filterString; +            RefImg.style.filter = filterString; + +        } else { +            if (CFobj._reflectionWithinImage) +                var canvas = this.canvas = $CF(document.createElement('canvas')); +            else  +                var canvas = reflection = this.reflection = document.createElement('canvas'); + +            if (canvas.getContext) { +                if (CFobj._reflectionWithinImage) { +                    for (var i=0; i <image.attributes.length; i++) { +                        canvas.setAttributeNode(image.attributes[i].cloneNode(true)); +                    } +                } + +                var context = canvas.getContext("2d"); + +                /* calc image size */ +                var max = CFobj.maxHeight; +                var size = CFobj._scaleImageSize(this, {width: max, height: max }, max) +                var width = size.width; +                var height = size.height; + +                // overwrite default height and width +                if (CFobj._reflectionWithinImage) { +                    canvas.width = width; +                    canvas.height = height;  +                    this.setImageFormat(canvas); +                    canvas.height = height * (1 + CFobj.conf.reflectionHeight + CFobj.conf.reflectionGap); + +                } +                else { +                    canvas.width = width; +                    canvas.height = height * CFobj.conf.reflectionHeight; +                } +                     +                context.save(); /* save default context */ + +                /* draw image into canvas */ +                if (CFobj._reflectionWithinImage) { +                    context.drawImage(image, 0, 0, width, height); +                } + +                /* mirror image by transformation of context and image drawing */ +                if (CFobj._reflectionWithinImage) { +                    var contextHeight = height * ( 1 + CFobj.conf.reflectionGap/2) * 2; +                } +                else { +                    var contextHeight = image.height; +                } +                // -1 for FF 1.5 +                contextHeight -= 1; +                 +                context.translate(0, contextHeight); +                context.scale(1, -1); +                /* draw reflection image into canvas */ +                context.drawImage(image, 0, 0, width, height); + +                /* restore default context for simpler further canvas manupulation */ +                context.restore(); +                     +                if (CFobj._reflectionColorRGB) { +                    var gradient = context.createLinearGradient(0, 0, 0, canvas.height); + +                    var alpha = [0, 0.5, 1]; +                    if (CFobj._reflectionColor == "transparent") { +                        context.globalCompositeOperation = "destination-in"; +                        alpha = [1, 0.5, 0]; +                    } + +                    var red = CFobj._reflectionColorRGB.iR; +                    var green = CFobj._reflectionColorRGB.iG; +                    var blue = CFobj._reflectionColorRGB.iB; +                    if (CFobj._reflectionWithinImage) { +                        gradient.addColorStop(0, 'rgba('+red+','+green+','+blue+','+alpha[0]+')'); +                        gradient.addColorStop(height/canvas.height, 'rgba('+red+','+green+','+blue+','+alpha[0]+')'); +                        gradient.addColorStop(height/canvas.height, 'rgba('+red+','+green+','+blue+','+alpha[1]+')'); +                    } +                    else { +                        gradient.addColorStop(0, 'rgba('+red+','+green+','+blue+','+alpha[1]+')'); +                    } +                    gradient.addColorStop(1, 'rgba('+red+','+green+','+blue+','+alpha[2]+')'); + +                    context.fillStyle = gradient; +                    context.fillRect(0, 0, canvas.width, canvas.height); +                     +                } + +                if (CFobj._reflectionWithinImage) { +                    image.parentNode.replaceChild(canvas, image); +                    this.content = canvas; +                    this.origContent = canvas; +                    delete this.image;// = true; + +                } +                 +            } else { +                CFobj._reflectionWithinImage = false; +                delete this.reflection; +            } + +        } +        if (reflection) { +            reflection.className = "reflection"; +            this.element.appendChild(reflection); + +            /* be shure that caption is last child */ +            if (this.caption) this.element.appendChild(this.caption); +        }  + +    } + + + }; + +/* + * ============================================================ + * ContentFlow + * ============================================================ + */ +var ContentFlow = function (container, config) { + +    if (container) { +        ContentFlowGlobal.Flows.push(this); +        this.Container = container; +        this._userConf = config?config:{}; +        this.conf = {}; +        this._loadedAddOns = new Array(); +    } else { +        throw ('ContentFlow ERROR: No flow container node or id given'); +    } + +}; + +ContentFlow.prototype = { +    _imagesToLoad: 0, +    _activeItem: 0, +    _currentPosition: 0, +    _targetPosition: 0, +    _stepLock: false, +    _millisecondsPerStep: 40,  +    _reflectionWithinImage: true, +    Browser: ContentFlowGlobal.Browser, +     +    _defaultConf: {  +        /* pre conf */ +        useAddOns: 'all', // all, none, [AddOn1, ... , AddOnN] + +        biggestItemPos: 0, +        loadingTimeout: 30000, //milliseconds +        activeElement: 'content', // item or content + +        maxItemHeight: 0, +        scaleFactor: 1, +        scaleFactorLandscape: 1.33, +        scaleFactorPortrait: 1.0, +        fixItemSize: false, +        relativeItemPosition: "top center", // align top/above, bottom/below, left, right, center of position coordinate + +        circularFlow: true, +        verticalFlow: false, +        visibleItems: -1, +        endOpacity: 1, +        startItem:  "center", +        scrollInFrom: "pre", + +        flowSpeedFactor: 1.0, +        flowDragFriction: 1.0, +        scrollWheelSpeed: 1.0, +        keys: { +            13: function () { this.conf.onclickActiveItem(this._activeItem) }, +            37: function () { this.moveTo('pre') },  +            38: function () { this.moveTo('visibleNext') }, +            39: function () { this.moveTo('next') }, +            40: function () { this.moveTo('visiblePre') } +        }, + +        reflectionColor: "transparent", // none, transparent or hex RGB CSS style #RRGGBB +        reflectionHeight: 0.5,          // float (relative to original image height) +        reflectionGap: 0.0, + +        /* ==================== actions ==================== */ + +        onInit: function () {}, + +        onclickInactiveItem: function (item) {}, + +        onclickActiveItem: function (item) { +            var url, target; + +            if (url = item.content.getAttribute('href')) { +                target = item.content.getAttribute('target'); +            } +            else if (url = item.element.getAttribute('href')) { +                target = item.element.getAttribute('target'); +            } +            else if (url = item.content.getAttribute('src')) { +                target = item.content.getAttribute('target'); +            } + +            if (url) { +                if (target) +                    window.open(url, target).focus(); +                else +                    window.location.href = url; +            } +        }, + +        onMakeInactive: function (item) {}, + +        onMakeActive: function (item) {}, + +        onReachTarget: function(item) {}, + +        onMoveTo: function(item) {}, + +        //onDrawItem: function(item, relativePosition, relativePositionNormed, side, size) {}, +        onDrawItem: function(item) {}, +         +        onclickPreButton: function (event) { +            this.moveToIndex('pre'); +            return Event.stop(event); +        }, +         +        onclickNextButton: function (event) { +            this.moveToIndex('next'); +            return Event.stop(event); +        }, + +        /* ==================== calculations ==================== */ + +        calcStepWidth: function(diff) { +            var vI = this.conf.visibleItems; +            var items = this.items.length; +            items = items == 0 ? 1 : items; +            if (Math.abs(diff) > vI) { +                if (diff > 0) { +                    var stepwidth = diff - vI; +                } else { +                    var stepwidth = diff + vI; +                } +            } else if (vI >= this.items.length) { +                var stepwidth = diff / items; +            } else { +                var stepwidth = diff * ( vI / items); +                //var stepwidth = diff/absDiff * Math.max(diff * diff,Math.min(absDiff,0.3)) * ( vI / this.items.length); +                //var stepwidth = this.flowSpeedFactor * diff / this.visibleItems; +                //var stepwidth = this.flowSpeedFactor * diff * ( this.visibleItems / this.items.length) +                //var stepwidth = this.flowSpeedFactor * diff / this._millisecondsPerStep * 2; // const. speed +            } +            return stepwidth; +        }, +         +        calcSize: function (item) { +            var rP = item.relativePosition; +            //var rPN = relativePositionNormed; +            //var vI = this.conf.visibleItems;  + +            var h = 1/(Math.abs(rP)+1); +            var w = h; +            return {width: w, height: h}; +        }, + +        calcCoordinates: function (item) { +            var rP = item.relativePosition; +            //var rPN = item.relativePositionNormed; +            var vI = this.conf.visibleItems;  + +            var f = 1 - 1/Math.exp( Math.abs(rP)*0.75); +            var x =  item.side * vI/(vI+1)* f;  +            var y = 1; + +            return {x: x, y: y}; +        }, + +        /* +        calcRelativeItemPosition: function (item) { +            var x = 0; +            var y = -1; +            return {x: x, y: y}; +        }, +        */ + +        calcZIndex: function (item) { +            return -Math.abs(item.relativePositionNormed); +        }, + +        calcFontSize: function (item) { +            return item.size.height; +        }, +    +        calcOpacity: function (item) { +            return Math.max(1 - ((1 - this.conf.endOpacity ) * Math.sqrt(Math.abs(item.relativePositionNormed))), this.conf.endOpacity); +        } +    }, + +    /* ---------- end of defaultConf ---------- */ + +     +    /* +     * ==================== index helper methods ==================== +     */ + +    /* +     * checks if index is within the index range of the this.items array +     * returns a value that is within this range +     */ +    _checkIndex: function (index) { +        index = Math.max(index, 0); +        index = Math.min(index, this.itemsLastIndex); +        return index; +    }, + +    /* +     * sets the object property itemsLastIndex +     */ +    _setLastIndex: function () { +        this.itemsLastIndex = this.items.length - 1; +    }, + +    /* +*/ +    _getItemByIndex: function (index) { +        return this.items[this._checkIndex(index)]; +    }, + +    _getItemByPosition: function (position) { +        return this._getItemByIndex(this._getIndexByPosition(position)); +    }, + +    /* returns the position of an item-index relative to current position */ +    _getPositionByIndex: function(index) { +        if (!this.conf.circularFlow) return this._checkIndex(index); +        var cI = this._getIndexByPosition(this._currentPosition); +        var dI = index - cI; +        if (Math.abs(dI) > dI+this.items.length) +            dI += this.items.length; +        else if (Math.abs(dI) > (Math.abs(dI-this.items.length))) +            dI -= this.items.length; + +        return this._currentPosition + dI; + +    }, + +    /* returns the index an item at position p would have */ +    _getIndexByPosition: function (position) { +        if (position < 0) var mod = 0; +        else var mod = 1; + +        var I = (Math.round(position) + mod) % this.items.length; +        if (I>0) I -= mod; +        else if(I<0) I += this.items.length - mod; +        else if(position<0) I = 0; +        else I = this.items.length - 1; + +        return I; +    }, + +    _getIndexByKeyWord: function (keyword, relativeTo, check) { +        if (relativeTo) +            var index = relativeTo; +        else if (this._activeItem) +            var index = this._activeItem.index; +        else +            var index = 0; + +        if (isNaN(keyword)) { +            switch (keyword) { +                case "first": +                case "start": +                    index = 0; +                    break; +                case "last": +                case "end": +                    index = this.itemsLastIndex; +                    break; +                case "middle": +                case "center": +                    index = Math.round(this.itemsLastIndex/2); +                    break; +                case "right": +                case "next": +                    index += 1; +                    break; +                case "left": +                case "pre": +                case "previous": +                    index -= 1; +                    break; +                case 'visible': +                case 'visiblePre': +                case 'visibleLeft': +                    index -= this.conf.visibleItems; +                    break; +                case 'visibleNext': +                case 'visibleRight': +                    index += this.conf.visibleItems; +                    break; +                default: +                    index = index; +            } +        } +        else { +            index = keyword; +        } +        if (check != false) +            index = this._checkIndex(index); +         +        return index; +    }, + + +    _setCaptionLabel: function (index) { +        if(this.Position && !this.Slider.locked) +            this.Position.setLabel(index); +        this._setGlobalCaption(); +    }, + + +    /* +     * ==================== public methods ====================  +     */ +    getAddOnConf: function(name) { +          return ContentFlowGlobal.getAddOnConf(name); +    }, + +    setAddOnConf: function(name, conf) { +          ContentFlowGlobal.setAddOnConf(name, conf); +    }, + + +    /* +     * calls _init() if ContentFlow has not been initialized before +     * needed if ContentFlow is not automatically initialized on window.load +     */ +    init: function () { +        if(this.isInit) return; +        this._init(); +    }, + +    /* +     * parses configuration object and initializes configuration values +     */ +    setConfig: function(config) { +        if (!config) return; +        var dC = this._defaultConf; +        for (var option in config) { +            if (dC[option] == "undefined" ) continue; +            switch (option) { +                case "scrollInFrom": +                case "startItem": +                    if (typeof(config[option]) == "number"  || typeof(config[option]) == "string") { +                        //this["_"+option] = config[option]; +                        this.conf[option] = config[option]; +                    } +                    break; +                default: +                    if (typeof(dC[option] == config[option])) { +                        //this["_"+option] = config[option]; +                        if (typeof config[option] == "function") { +                            this.conf[option] = config[option].bind(this); +                        } +                        else { +                            this.conf[option] = config[option]; +                        } +                    } +            } +        } +        switch (this.conf.reflectionColor) { +            case this.conf.reflectionColor.search(/#[0-9a-fA-F]{6}/)>= 0?this.conf.reflectionColor:this.conf.reflectionColor+"x": +                this._reflectionColorRGB = { +                    hR: this.conf.reflectionColor.slice(1,3), +                    hG: this.conf.reflectionColor.slice(3,5), +                    hB: this.conf.reflectionColor.slice(5,7), +                    iR: parseInt(this.conf.reflectionColor.slice(1,3), 16), +                    iG: parseInt(this.conf.reflectionColor.slice(3,5), 16), +                    iB: parseInt(this.conf.reflectionColor.slice(5,7), 16) +                }; +                break; +            case "none": +            case "transparent": +            default: +                this._reflectionColor = "transparent";  +                this._reflectionColorRGB = { +                    hR: 0, hG: 0, hB:0, +                    iR: 0, iG: 0, iB:0 +                }; +                break; +        } +        if (this.items) { +            if (this.conf.visibleItems <  0) +                this.conf.visibleItems = Math.round(Math.sqrt(this.items.length)); +            this.conf.visibleItems = Math.min(this.conf.visibleItems, this.items.length - 1); +        } + +        if (this.conf.relativeItemPosition) { +            var calcRP = { +                x: { +                    left: function(size) { return -1 }, +                    center: function(size) { return 0 }, +                    right: function(size) { return 1 } +                }, +                y: { +                    top: function(size) { return -1 }, +                    center: function(size) { return 0 }, +                    bottom: function(size) { return 1 } +                } +            }; + +            var iP = this.conf.relativeItemPosition; +            iP = iP.replace(/above/,"top").replace(/below/,"bottom"); +            var x, y = null; +            x = iP.match(/left|right/); +            y = iP.match(/top|bottom/); +            c = iP.match(/center/); +            if (!x) { +                if (c) x = "center"; +                else x = "center"; +            } +            if (!y) { +                if (c) y = "center"; +                else y = "top"; +            } +            var calcX = calcRP.x[x]; +            var calcY = calcRP.y[y]; +            this.conf.calcRelativeItemPosition = function (item) { +                var x = calcX(item.size); +                var y = calcY(item.size); +                return {x: x, y: y}; +            }; +            this.conf.relativeItemPosition = null; +        } + +        if (this._reflectionType && this._reflectionType != "clientside") { +            this.conf.reflectionHeight = 0; +        } + +    }, + +    getItem: function (index) { +        return this.items[this._checkIndex(Math.round(index))];  +    }, + +    /* +     * returns the index number of the active item +     */ +    getActiveItem: function() { +        return this._activeItem; +    }, + +    /* +     * returns the number of items the flow contains +     */ +    getNumberOfItems: function () { +        return this.items.length; +    }, + +    /* +     * reinitializes sizes. +     * called on window.resize +     */ +    resize: function () { +        this._initSizes(); +        this._initStep(); +    },  + +    /* +     * scrolls flow to item i +     */ +    moveToPosition: function (p, holdPos) { +        if (!this.conf.circularFlow) p = this._checkIndex(p); +        this._targetPosition = p; +        this.conf.onMoveTo(this._getItemByPosition(p)); +        this._initStep(false, holdPos); +    }, +    moveToIndex: function (index) { +        this._targetPosition = Math.round(this._getPositionByIndex(this._getIndexByKeyWord(index, this._activeItem.index, !this.conf.circularFlow))); +        this.conf.onMoveTo(this._getItemByPosition(this._targetPosition)); +        this._initStep(); +    }, +    moveToItem: function (item) { +        var i; +        if (item.itemIndex) i = item.itemIndex; +        else i = item.index; +        this.moveToIndex(i); +    }, +    moveTo: function (i) { +        if (typeof i == "object") this.moveToItem(i); +        else if (isNaN(i) || (i == Math.floor(i) && i < this.items.length) ) this.moveToIndex(i); +        else this.moveToPosition(i); +    },  + +    /* +     * initializes item and adds it at index position +     */ +    _addItemCue: [], +    _addItemCueProcess: function (deleteFirst) { +        var c = this._addItemCue; +        if (deleteFirst == true)  +            c.shift(); +        if (c.length > 0 && ! c[0].p) { +            c[0].p = true; +            var self = this; +            var t = c.length > 5 ? 1 : 40; +            window.setTimeout(function () { self._addItem(c[0].el, c[0].i)}, t) ; +        } +    }, +    addItem: function(el, index) { +        this._addItemCue.push({ el: el, i: index, p: false}); +        if (this._addItemCue.length == 1)  +            this._addItemCueProcess(); +    }, + +    _addItem: function(el, index) { +        if (typeof index == "string") { +            switch (index) { +                case "first": +                case "start": +                    index = 0; +                    break; +                case "last": +                case "end": +                    index = isNaN(this.itemsLastIndex) ? 0 : this.itemsLastIndex; +                    index += 1; +                    break; +                default: +                    index = this._getIndexByKeyWord(index); +            } +        } + +        index = Math.max(index, 0); +        index = Math.min(index, this.itemsLastIndex + 1); +        index = isNaN(index) ? 0 : index; +         +        this.Flow.appendChild(el); + +        /* init item after insertion. that way it's part of the document and all styles are applied */ +        var item = new ContentFlowItem(this, el, index); +        if (this.items.length == 0 ) { +            this.resize(); +            if (this.conf.circularFlow) { +                item.pre = item; +                item.next = item; +            } +        } +        else { +            if (index == this.itemsLastIndex + 1) { +                item.pre = this.items[this.itemsLastIndex]; +                item.next = item.pre.next; +            } +            else { +                item.next = this.items[index]; +                item.pre = item.next.pre; +            } +            if (item.pre) item.pre.next = item; +            if (item.next) item.next.pre = item; +        } +        this.items.splice(index,0, item); + +        /* adjust item indices */ +        for (var i = index; i < this.items.length; i++) { +            this.items[i].setIndex(i); +        } +        this._setLastIndex(); + +        if (this.conf.origVisibleItems < 0) { +            this.conf.visibleItems = Math.round(Math.sqrt(this.items.length)); +        } +        this.conf.visibleItems = Math.min(this.conf.visibleItems, this.items.length - 1); + +        /* adjust targetItem, currentPos so that current view does not change*/ +        if (Math.round(this._getPositionByIndex(index)) <= Math.round(this._targetPosition)) { +            this._targetPosition++; +            if (!this.conf.circularFlow) +                this._targetPosition = Math.min(this._targetPosition, this.itemsLastIndex); +        }  +        if (this._getPositionByIndex(index) <= this._currentPosition) { +            this._currentPosition++; +            if (!this.conf.circularFlow) +                this._currentPosition = Math.min(this._currentPosition, this.itemsLastIndex); +        } +         +        // avoid display errors (wrong sizing) +        var CF = this; +        window.setTimeout(function () { +            if(CF.items.length == 1 ) { +                CF._currentPosition = -0.01; +                CF._targetPosition = 0; +                CF.resize();  +            } +            else { +                CF._initStep(); +            } +        }, 100); + +        return index; +         +    }, +         +    /* +     * removes item at index position, cleans it up and returns it +     */ +    rmItem: function(index) { +        if  (index == "undefined") index = this._activeItem.index; +        index = this._getIndexByKeyWord(index); +        if (!this.items[index]) return null; + +        var item = this.items[index]; + +        if (item.pre) item.pre.next = item.next; +        if (item.next) item.next.pre = item.pre; +        this.items.splice(index,1); + +        /* adjust item indices */ +        for (var i = index ; i < this.items.length; i++) { +            this.items[i].setIndex(i); +        } +        this._setLastIndex(); +         +        /* adjust targetItem, currentPos and activeItem so that current view does not change*/ +        if (Math.round(this._getPositionByIndex(index)) < Math.round(this._targetPosition)) { +            this._targetPosition--; +            if (!this.conf.circularFlow) +                this._targetPosition = this._checkIndex(this._targetPosition); +        } +        if (this._getPositionByIndex(index) < this._currentPosition) { +            this._currentPosition--; +            if (!this.conf.circularFlow) +                this._currentPosition = this._checkIndex(this._currentPosition); +        } +        this._activeItem = this._getItemByPosition(this._currentPosition); + +        /* remove item from DOM tree, take the next step and return removed item  */ +        var removedItem = item.element.parentNode.removeChild(item.element); +        // avoid display errors (wrong sizing) +        var CF = this; +        window.setTimeout(function () { CF._initStep() }, 10); +        return removedItem; + +    }, + + +    /* +     * ==================== initialization ==================== +     */ +     + +    /* -------------------- main init -------------------- */ +    _init: function () { + +        if (typeof(this.Container) == 'string') { // no node +            var container = document.getElementById(this.Container); +            if (container) { +                this.Container = container; +            } else { +                throw ('ContentFlow ERROR: No element with id \''+this.Container+'\' found!'); +                return; +            } +        } +         +        /* ----------  reserve CSS namespace */ + +        $CF(this.Container).addClassName('ContentFlow'); + +        /* ---------- detect GUI elements */ +        var flow = $CF(this.Container).getChildrenByClassName('flow')[0]; +        if (!flow) { +            throw ('ContentFlow ERROR: No element with class\'flow\' found!'); +            return; +        } +        this.Flow = new ContentFlowGUIElement(this, flow); + +        var scrollbar = this.Container.getChildrenByClassName('scrollbar')[0]; +        if (scrollbar) { +            this.Scrollbar = new ContentFlowGUIElement(this, scrollbar); +            var slider = this.Scrollbar.getChildrenByClassName('slider')[0]; +            if (slider) { +                this.Slider = new ContentFlowGUIElement(this, slider); +                var position = this.Slider.getChildrenByClassName('position')[0]; +                if (position) { +                    this.Position = new ContentFlowGUIElement(this, position); +                } +            } + +        } + +        /* ----------  init configuration */  +        this.setConfig(this._defaultConf); +        this._initAddOns(); /* init AddOns */ +        this.setConfig(this._userConf); +         +        this._initSizes(); // ...... + + +        /* ---------- init item lists ---------- */ +        var items = this.Flow.getChildrenByClassName('item'); + +        this.items = new Array(); +        for (var i=0; i<items.length; i++) { +            var item = this.items[i] = new ContentFlowItem(this, items[i], i); +            if (i > 0) {  +                item.pre = this.items[i-1]; +                item.pre.next = item; +            } +        } +        this._setLastIndex(); +        if (this.conf.circularFlow && this.items.length > 0) { +            var s = this.items[0]; +            s.pre = this.items[this.items.length-1]; +            s.pre.next = s; +        } + +        /* ----------  init GUI */ +        this._initGUI(); + +        /* ---------- init start parameters ---------- */ +        if (this._activeElement != "content") +            this._activeElement = "element"; + +        this.conf.origVisibleItems = this.conf.visibleItems; +        if (this.conf.visibleItems < 0) { +            this.conf.visibleItems = Math.round(Math.sqrt(this.items.length)); +        } +        this.conf.visibleItems = Math.min(this.conf.visibleItems, this.items.length - 1); + +        this._targetPosition = this._getIndexByKeyWord(this.conf.startItem, 0); + +        var index = this._getIndexByKeyWord(this.conf.scrollInFrom, this._targetPosition); +        switch (this.conf.scrollInFrom) { +            case "next": +            case "right": +                index -= 0.5; +                break; +            case "pre": +            case "previous": +            case "left": +                index += 0.5; +                break; +        }  +        this._currentPosition = index; +         + +        /* ---------- wait till all images are loaded or  +         * grace time is up to show all and take the first step   +        */ +        var now = new Date(); +        var cf = this; +        var timer = window.setInterval ( +            function() { +                if ( cf._imagesToLoad == 0 || new Date() - now > cf._loadingTimeout ) { +                    clearInterval(timer); + +                    cf._activeItem = cf.getItem(cf._currentPosition); +                    if (cf._activeItem) { +                        cf._activeItem.makeActive(); +                        cf._setCaptionLabel(cf._activeItem.index); +                    } +                     +                    cf.Flow.style.visibility = "visible"; // show flow after images are loaded +                    if (cf.loadIndicator) cf.loadIndicator.style.display = "none"; +                    if (cf.Scrollbar) cf.Scrollbar.style.visibility = "visible"; + +                    cf.resize(); +                    for (var i=0; i < cf._loadedAddOns.length; i++) { +                        var a = ContentFlowGlobal.AddOns[cf._loadedAddOns[i]]; +                        if (a.methods.afterContentFlowInit) +                            a.methods.afterContentFlowInit(cf); +                    } +                    cf.conf.onInit(); +                } +            }, 10 +        ); +         +        this.isInit = true; + +    }, +     +    /* ---------- init AddOns ---------- */  +    _initAddOns: function () { + +        // get an array of names of all AddOns that should be used +        var loadAddOns = []; +        if (this._userConf.useAddOns) { +            if (typeof this._userConf.useAddOns == "string") { +                loadAddOns = this._userConf.useAddOns.split(" "); +            } +            else if (typeof this._userConf.useAddOns == "array") { +                loadAddOns = this._userConf.useAddOns; +            } +        } +        else if (this.Container.getAttribute("useAddOns")) { +            loadAddOns = this.Container.getAttribute("useAddOns").split(" "); +        } +        else { +            loadAddOns = this.conf.useAddOns.split(' '); +        } + + +        // check the names for keywords +        for (var i=0; i<loadAddOns.length; i++) { +            if (loadAddOns[i] == "none") { +                loadAddOns = new Array(); +                break; +            } +            else if (loadAddOns[i] == "all") { +                loadAddOns = new Array(); +                for (var AddOn in ContentFlowGlobal.AddOns) +                    loadAddOns.push(AddOn); +                break; +            } +        } + +        // init all AddOns that should be used and exist +        for (var i=0; i<loadAddOns.length; i++) { +            var AddOn = ContentFlowGlobal.AddOns[loadAddOns[i]]; +            if (AddOn) { +                this._loadedAddOns.push(loadAddOns[i]); +                AddOn._init(this); +                this.Container.addClassName('ContentFlowAddOn_'+AddOn.name); +                if (AddOn.methods.onloadInit) +                    AddOn.methods.onloadInit(this); +            } +        } + +    }, + + +    _initGUI: function () { +         +        // resize +        //if (!this.Browser.iPhone) { +            var resize = this.resize.bind(this); +            window.addEvent('resize', resize, false); +        //} +        //else { +            //var g = this; +            //window.addEvent('resize', function () { +                //g._initSizes(); +                //g._initStep(); +            //} , false); +        //} +         +        // pre and next buttons +        var divs = this.Container.getElementsByTagName('div'); +        for (var i = 0; i < divs.length; i++) { +            if ($CF(divs[i]).hasClassName('preButton')) { +                var pre = divs[i]; +                var mt = this.conf.onclickPreButton; +                pre.addEvent('click', mt, false); +            } +            else if (divs[i].hasClassName('nextButton')) { +                var next = divs[i]; +                var mt = this.conf.onclickNextButton; +                next.addEvent('click', mt, false); +            } +        } + +        // Container object +        // mousewheel +        if (this.conf.scrollWheelSpeed != 0) { +            var wheel = this._wheel.bind(this); +            if(window.addEventListener) this.Container.addEventListener('DOMMouseScroll', wheel, false); +            this.Container.onmousewheel = wheel; +        } + +        // key strokes +        var key = this._keyStroke.bind(this); +        if (this.conf.keys && !this.Browser.iPhone) { +            if (document.addEventListener) { +                if (!this.Browser.Opera) { +                    var mouseoverCheck = document.createElement('div'); +                    mouseoverCheck.addClassName('mouseoverCheckElement'); +                    this.Container.appendChild(mouseoverCheck); + +                    if (this.Browser.WebKit) { +                        document.body.addEvent('keydown',  function (event) { +                            if (mouseoverCheck.offsetLeft > 0) key(event) ; +                        }); +                    } else { +                        window.addEvent('keydown',  function (event) { +                            if (mouseoverCheck.offsetLeft > 0) key(event) ; +                        }); +                    } +                }  +                else { +                    this.Container.addEvent('keydown', key); +                } +            } +            else { +               this.Container.onkeydown = key; +            } +        } + + +        // Flow object +        if (this.conf.flowDragFriction > 0) { +            var onDrag = function (event) { +                var e = event; +                if (event.touches) e = event.touches[0]; +                var mouseX = e.clientX; +                var mouseY = e.clientY; +                 +                if (this.conf.verticalFlow) { +                    var dist = mouseY - this.Flow.mouseY; // px / or px per sec because _dragFlow wil be called in shorter intervalls if draged fast +                    var dim = this.Flow.dimensions.height; +                } +                else { +                    var dist = mouseX - this.Flow.mouseX; // px / or px per sec because _dragFlow wil be called in shorter intervalls if draged fast +                    var dim = this.Flow.dimensions.width; +                } +                var itemDist = (dist / dim )* (2*this.conf.visibleItems +1); // items +                var target = this._currentPosition - itemDist * 2*this.conf.visibleItems / this.conf.flowDragFriction ; + +                this.Flow.mouseX = mouseX;  +                this.Flow.mouseY = mouseY;  + +                this.moveToPosition(target, true); +            }.bind(this); + +            var beforeDrag = function () {}; + +            var afterDrag = function (event) { +                var t = Math.round(this._targetPosition); +                if (Math.abs( t - this._currentPosition) > 0.001 ) +                    this.moveToPosition(t); +            }.bind(this); + + +            this.Flow.makeDraggable(onDrag, beforeDrag, afterDrag); +        } + +        // Scrollbar Object +        if (this.Scrollbar) { +            var click = function(event) { +                if (!event) var event = window.event; + +                if (!this.Scrollbar.clickLocked) { +                    var mouseX = event.clientX;  +                    var positionOnScrollbar = mouseX - this.Scrollbar.position.left; +                    var targetIndex = Math.round(positionOnScrollbar/this.Scrollbar.dimensions.width * this.itemsLastIndex); +                    this.moveToIndex(targetIndex); +                } +                else +                    this.Scrollbar.clickLocked = false; +            }.bind(this); +            this.Scrollbar.addObserver('click', click); +        } + +        // Slider Object +        if (this.Slider) { + +            if (this.Browser.IE6) { +                var virtualSlider = document.createElement('div'); +                virtualSlider.className = 'virtualSlider'; +                this.Slider.appendChild(virtualSlider); +            } + +            // position slider on scrollbar +            this.Slider.setPosition = function (relPos) { +                relPos = relPos - Math.floor(relPos) + this._getIndexByPosition(Math.floor(relPos)); +                if (Math.round(relPos) < 0) +                    relPos = this.itemsLastIndex; +                else if (relPos <= 0) +                    relPos = 0; +                else if (Math.round(relPos) > this.itemsLastIndex) +                    relPos = 0; +                else if (relPos >= this.itemsLastIndex) +                    relPos = this.itemsLastIndex; + + +                if (this.items.length > 1) { +                    var sPos = (relPos / this.itemsLastIndex)* this.Scrollbar.dimensions.width; +                } else { +                    var sPos = 0.5 * this.Scrollbar.dimensions.width; +                } +                this.Slider.style.left = sPos - this.Slider.center.x+ "px"; +                this.Slider.style.top = this.Scrollbar.center.y - this.Slider.center.y +"px"; + +            }.bind(this); + +            // make slider draggable +            var beforeDrag = function (event) { +                this.Scrollbar.clickLocked = true; +            }.bind(this); + +            var onDrag = function (event) { +                var e = event; +                if (event.touches) e = event.touches[0]; +                var selectedIndex = this._checkIndex((e.clientX - this.Scrollbar.position.left) / this.Scrollbar.dimensions.width * this.itemsLastIndex); +                this._targetPosition = this._getPositionByIndex(selectedIndex); +                this.Slider.setPosition(selectedIndex); +                if (this.Position) this.Position.setLabel(selectedIndex); +                this._initStep(true, true); +            }.bind(this); + +            var afterDrag = function (event) { +                this._targetPosition = Math.round(this._targetPosition); +                this.conf.onMoveTo(this._getItemByPosition(this._targetPosition)); +                this._initStep(true); +            }.bind(this); + +            this.Slider.makeDraggable(onDrag, beforeDrag, afterDrag); +        } + +                 +        // Position object +        if (this.Position) { +            this.Position.setLabel = function (index) { +                index = this._checkIndex(Math.round(index)); +                if (this.items && this.items[index].label) +                    this.Position.innerHTML = this.items[index].label.innerHTML; +                else +                    this.Position.innerHTML = index + 1; +            }.bind(this); +        } + + +        this.globalCaption = this.Container.getChildrenByClassName('globalCaption')[0]; +        this.loadIndicator = this.Container.getChildrenByClassName('loadIndicator')[0]; +    }, + +    /* ---------- init element sizes ---------- */  +    _initSizes: function (x) { +        //if (this.Browser.Konqueror4 && x != true) { +            //var t = this; +            //window.setTimeout( function () { t._initSizes(true) }, 0); +            //return; +        //} + +        // sets this.maxHeight +        this._initMaxHeight(); + +        var scrollbarHeight = this._initScrollbarSize(); + +        // reduce maxHeit if container has a fixed height +        if (!this.conf.verticalFlow && this.Container.style.height && this.Container.style.height != "auto") +            this.maxHeight -= scrollbarHeight;  + +        if (!this._activeItem) return; + +        var mFS = this._findBiggestItem(); + +        var pF = this.Flow.findPos(); + +        /* set height / width of flow */ +        if (this.conf.verticalFlow) { +            this.Flow.style.width = mFS.width.width+"px"; +            this.Flow.style.height =3* mFS.width.width * (1 + this.conf.reflectionHeight + this.conf.reflectionGap) + "px"; +        } else { +            this.Flow.style.height = mFS.height.height +(mFS.height.top - pF.top)+"px"; +        } + +        /* remove gap */ +        var s = this.conf.verticalFlow ? mFS.width.width : mFS.height.height; +        var cH = s /(1 + this.conf.reflectionHeight + this.conf.reflectionGap); +        this.Flow.style.marginBottom = - (s - cH)+ "px"; + +        this.Flow.dimensions = this.Flow.getDimensions(); + +        if (!this.Browser.IE6) { +            if (this.conf.verticalFlow && this.Container.clientWidth < this.Flow.dimensions.width) { +                //this.Container.style.width = this.Flow.dimensions.width+"px"; +            } +            else if (this.Container.clientHeight < this.Flow.dimensions.height) { +                this.Container.style.height = this.Flow.dimensions.height+"px"; +            } +        } + +        if (this.conf.verticalFlow) { +           this.Flow.center = {x: this.Flow.dimensions.height/2, y:mFS.width.width/2}; +        } else { +           this.Flow.center = {x: this.Flow.dimensions.width/2, y:mFS.height.height/2}; +        } + +    }, + +    /* -------------------------------------------------------------------------------- */ + +    _initScrollbarSize: function () { +        var SB; +        var SL; +        var PO; +        if (SB = this.Scrollbar) { +            SB.setDimensions(); +            var scrollbarHeight = SB.dimensions.height; + +            if (SL = this.Slider) { +                SL.setDimensions(); +                scrollbarHeight += SL.dimensions.height; + +                if (PO = this.Position) { +                     +                    var oldLabel = PO.innerHTML; +                    var maxH = maxW = 0; +                    PO.style.width = "auto"; + +                    if (this.items) { +                        for (var i=0; i < this.items.length; i++) { +                            var item = this.items[i]; +                            if (item.label) { +                                PO.innerHTML = item.label.innerHTML; +                            } +                            else { +                                PO.innerHTML = item.index; +                            } +                            var h = PO.clientHeight; +                            var w = PO.clientWidth; +                            if ( h >  maxH) maxH = h; +                            if ( w >  maxW) maxW = w; +                        } +                    } +                    else { +                        PO.innerHTML = " "; +                        maxH = PO.clientHeight; +                        maxW = PO.clientWidth; +                    } + +                    PO.innerHTML = oldLabel; + +                    PO.setDimensions(); + +                    PO.style.width = maxW +"px"; +                    PO.style.left = (SL.dimensions.width - maxW)/2 + "px"; + +                    var extraSpace = PO.position.top - SL.position.top; +                    if (extraSpace > 0) { +                        extraSpace += -SB.dimensions.height + maxH; +                        SB.style.marginBottom = extraSpace + "px"; +                    } +                    else { +                        extraSpace *= -1; +                        SB.style.marginTop = extraSpace + "px"; +                    } +                    scrollbarHeight += extraSpace; +                } +            } +        } +        else { +            scrollbarHeight = 0; +        } + +        return scrollbarHeight; + +    }, + +    /* -------------------------------------------------------------------------------- */ + +    _initMaxHeight: function () { + +        if (this.conf.verticalFlow) { +            var proportion = screen.width/screen.height; +            var Csd = this.Container.style.width; +            var Cdim = this.Container.clientWidth; +            var Fsd = this.Flow.style.width; +            var Fdim = this.Flow.clientWidth; +            var Fdim_o = this.Flow.clientHeight; +        } else { +            var proportion = screen.height/screen.width; +            var Csd = this.Container.style.height; +            var Cdim = this.Container.clientHeight; +            var Fsd = this.Flow.style.height; +            var Fdim = this.Flow.clientHeight; +            var Fdim_o = this.Flow.clientWidth; +        } + +        // set height of container and flow +        if (this.ContainerOldDim)  +            Csd = this.ContainerOldDim; +        if (this.FlowOldDim)  +            Fsd = this.FlowOldDim; + +        this.ContainerOldDim = "auto"; +        this.FlowOldDim = "auto"; +         + +        /* calc maxHeight */ +        if (this.conf.maxItemHeight <= 0) { + +            this.maxHeight = Fdim_o / 3 * proportion/1 * this.conf.scaleFactor;  // divided by 3 because of left/center/right, yes it's a magic number + +            if (this.conf.verticalFlow && (this.maxHeight == 0 || this.maxHeight > Fdim)) { +                this.maxHeight = Fdim; +            } + +            if (Csd && Csd != "auto") { +                var gap = this.conf.verticalFlow  ? 0 : this.conf.reflectionGap; +                var rH = this.conf.verticalFlow  ? 0 : this.conf.reflectionHeight; +                this.maxHeight = Cdim/ (this.conf.scaleFactor* (1 + rH + gap));  +                this.ContainerOldDim = Csd; +            } +            else if (Fsd && Fsd != "auto") { +                var gap = this.conf.verticalFlow  ? 0 : this.conf.reflectionGap; +                this.maxHeight = Fdim / (this.conf.scaleFactor* (1 + this.conf.reflectionHeight + gap)); +                this.FlowOldDim = Fsd; +            } +        } +        else { +            this.maxHeight = this.conf.maxItemHeight; +        } +    }, + +    /* -------------------------------------------------------------------------------- */ + +    _findBiggestItem: function () { + +        var currentItem = this._activeItem; + +        var itemP = currentItem.pre; +        var itemN = currentItem.next; +        var mFS = maxFlowSize = { +            width: { width: 0, left: 0, height:0, top: 0, item: null, rI: 0 }, +            height: { width: 0, left: 0, height:0, top: 0, item: null, rI: 0 } +        } + + +        var checkMax = function (item, rI) { +            var el = item.element; +            el.style.display = "block"; +            var p = el.findPos(); +            var h =  el.clientHeight; +            var w = el.clientWidth; +            if (h + p.top >= mFS.height.height + mFS.height.top) { +                mFS.height.height = h; +                mFS.height.top = p.top; +                mFS.height.item = item; +                mFS.height.rI = rI; +            } +            if (w + p.left >= mFS.width.width + mFS.width.left) { +                mFS.width.width = w; +                mFS.width.left = p.left; +                mFS.width.item = item; +                mFS.width.rI = rI; +            } +            el.style.display = "none"; +        } + +        var ocp = this._currentPosition; +        this._currentPosition = this.conf.visibleItems+1; + +        // find the position with highest y-value +        for (var i=-this.conf.visibleItems; i <= this.conf.visibleItems; i++) { +            currentItem.element.style.display = "none"; +            this._positionItem(currentItem, i); +            checkMax(currentItem, i); +        } + +        // find the biggest item +        var index = mFS.height.rI; +        for (var i=0; i < this.items.length; i++) { +            var item = this.items[i]; +            item.element.style.display = "none"; +            this._positionItem(item, index); +            checkMax(item, index); +        } + +        this._currentPosition = ocp; + +        return mFS +    }, + + + +    /* +     * ==================== Key strok ==================== +     */ + +    /* +     * handles keystroke events +     */ +    _keyStroke: function(event) { +        if(!event) var event = window.event; + +        if (event.which) { +            var keyCode = event.which; +        } else if (event.keyCode) { +            var keyCode = event.keyCode; +        } + +        if (this.conf.keys[keyCode]) { +            this.conf.keys[keyCode].bind(this)(); +            return Event.stop(event); +        } +        else { +            return true; +        } +    }, +     +    /* +     * ==================== mouse wheel ==================== +     * Event handler for mouse wheel event +     * http://adomas.org/javascript-mouse-wheel/ +     */ + +    _wheel: function (event) { +        if (!event) var event = window.event; // MS +         +        var delta = 0; +        if (event.wheelDelta) { +            delta = event.wheelDelta/120;  +        } else if (event.detail) { +            delta = -event.detail/3; +        } + +        if (delta) { +            var target = this._targetPosition ; +            if (delta < 0 ) { +                target += (1 * this.conf.scrollWheelSpeed); +            } else { +                target -= (1 * this.conf.scrollWheelSpeed); +            }  +            this.moveToPosition(Math.round(target)); +        } + +        return Event.stop(event); +    }, + + +    /* +     * ==================== set global Caption ==================== +     */ +    _setGlobalCaption: function () { +        if (this.globalCaption) { +            this.globalCaption.innerHTML = ''; +            if(this._activeItem && this._activeItem.caption) +                this.globalCaption.appendChild(this._activeItem.caption.cloneNode(true)); +        } +    }, + +    /* +     * ==================== move items ==================== +     */ + +    /* +     * intend to make a step  +     */ +    _initStep: function (holdSlider, holdPos) { +        if (this.Slider) { +            if(holdSlider) { +                this.Slider.locked = true; +            } else { +                this.Slider.locked = false; +            } +        } +        this._holdPos = holdPos == true ? true : false; +        if (!this._stepLock) { +            this._stepLock = true; +            this._step(); +        } +    }, + +    /* +     * make a step +     */ +    _step: function () { + +        var diff = this._targetPosition - this._currentPosition;  +        var absDiff = Math.abs(diff); +        if ( absDiff > 0.001) { // till activeItem is nearly at position 0 + +            this._currentPosition += this.conf.flowSpeedFactor * this.conf.calcStepWidth(diff, absDiff, this.items.length, this.conf.visibleItems); + +            var AI = this.items[(this._getIndexByPosition(this._currentPosition))]; + +            if (AI && AI != this._activeItem) { +                if (this._activeItem) this._activeItem.makeInactive(); +                this._activeItem = AI; +                this._activeItem.makeActive(); +                this._setCaptionLabel(this._activeItem.index); +                if (Math.abs(this._targetPosition - this._currentPosition) <= 0.5 ) this.conf.onReachTarget(this._activeItem); +            } +             +            this._positionItems(); + +            var st = this._step.bind(this); +            window.setTimeout(st,this._millisecondsPerStep); + +        } else if (!this._holdPos) { +            if (this.Slider) this.Slider.locked = false; +            this._currentPosition = Math.round(this._currentPosition); +            if(this.Position && !this.Slider.locked && this._activeItem) { +                this._setCaptionLabel(this._activeItem.index); +            } +            this._positionItems(); +            this._stepLock = false; +        } else { +            this._stepLock = false; +        } + +        if (this.Slider && !this.Slider.locked) { +            this.Slider.setPosition(this._currentPosition); +        } +    }, +     + + +/* ------------------------------------------------------------------------------------------------------ */ +     +    /* +     * position items +     */ +    _positionItems: function () { + +        if (this._lastStart) { +            var item = this._lastStart; +            while (item) { +                item.element.style.display="none"; +                item = item.next; +                if (item == this._lastStart) break; +                if (item && item.pre == this._lastEnd) break; +            } +        } +        else { +            this._lastStart = this._activeItem; +        } + +        if (!this._activeItem) return; +        var currentItem = this._activeItem; +        var itemP = currentItem.pre; +        var itemN = currentItem.next; + +        this._positionItem(currentItem, 0); +        for (var i=1; i <= this.conf.visibleItems && 2*i < this.items.length ; i++) { +            if (itemP) { +                this._positionItem(itemP, -i); +                this._lastStart = itemP; +                itemP = itemP.pre; +            } +            if (itemN) { +                this._positionItem(itemN, i); +                this._lastEnd = itemN; +                itemN = itemN.next; +            } +        } + +    }, + +    _positionItem: function (item, relativeIndex) { + +        var conf = this.conf; +        var vF = conf.verticalFlow; + +        var els = item.element.style; +        //els.display =" none"; +        //if (els.display != "none") return; + +        /* Index and position relative to activeItem */ +        var p = item.position = this._currentPosition + relativeIndex; +        var relativePosition = item.relativePosition = Math.round(p) - this._currentPosition; +        var relativePositionNormed = item.relativePositionNormed = conf.visibleItems > 0 ? relativePosition/conf.visibleItems : 0; +        var side = relativePosition < 0 ? -1 : 1; +        side *= relativePosition == 0 ? 0 : 1; +        item.side = side; + +        var size = conf.calcSize(item); +        size.height = Math.max(size.height, 0); +        size.width = Math.max(size.width, 0); +        if (item.content.origProportion) size = this._scaleImageSize(item, size); +        item.size = size; + +        var coords = item.coordinates = conf.calcCoordinates (item); +        var relItemPos = item.relativeItemPosition = conf.calcRelativeItemPosition(item); +        var zIndex = item.zIndex = conf.calcZIndex (item); +        var fontSize = item.fontSize = conf.calcFontSize (item); +        var opacity = item.opacity = conf.calcOpacity(item); + +        size.height *= this.maxHeight; +        size.width *= this.maxHeight; + +        /* set position */ +        var sA = vF ? size.height : size.width; +        var sB = vF ? size.width : size.height; +        var pX = this.Flow.center.x * ( 1 + coords.x )  + (relItemPos.x - 1)  * sA/2; +        var pY = this.maxHeight/2 * ( 1 + coords.y ) + (relItemPos.y - 1 )* sB/2; +        els.left = (vF ? pY : pX)+"px"; +        els.top = (vF ? pX : pY)+"px"; +         +        this._setItemSize(item, size); + +        /* set opacity */ +        if (conf.endOpacity != 1) { +            this._setItemOpacity(item); +        } + +        /* set font size */ +        if (!this.Browser.IE) els.fontSize = (fontSize * 100) +"%"; + +        /* set z-index */ +        els.zIndex = 32768 + Math.round(zIndex * this.items.length); // just for FF + +        conf.onDrawItem(item); + +        els.visibility = "visible"; +        els.display = "block"; +    }, + +    _scaleImageSize: function (item, size, max) { +        var sFL = this.conf.scaleFactorLandscape; +        var sFP = this.conf.scaleFactorPortrait; +        var vF = this.conf.verticalFlow; +        var prop = item.content.origProportion; +        var width = size.width; +        var height = size.height; +        var c = item.content; + +        if (vF) { +            if (prop <= 1) { +                if (sFL != "max" && sFL != 1) { +                    height *= sFL; +                    width = Math.min(height * prop, max ? max : 1 ); +                } +                height = width / prop; +            } +            else if (prop > 1) { +                if (sFP == "max") { +                    height = max ? max : 1; +                } +                else if (sFP != 1) { +                    width *= sFP; +                    height = Math.min(width/prop, max ? max : 1)  +                } +                else { +                    height = width / prop; +                } +                width = height * prop; +            } +        } +        else { +            if (prop > 1) { +                if (sFL != "max" && sFL != 1) { +                    width *= sFL; +                    height = Math.min(width / prop, max ? max : 1); +                } +                width = height * prop; +            } +            else if (prop <= 1) { +                if (sFP == "max") { +                    width = max ? max : 1; +                }  +                else if (sFP != 1) { +                    height *= sFP; +                    width = Math.min(height*prop, max ? max : 1); +                } +                else { +                    width = height * prop; +                } +                height = width / prop; +            } +        } + +        height = isNaN(height) ? 0 : height; +        width = isNaN(width) ? 0 : width; + +        if (!max && this.conf.fixItemSize) { + +            var propS = size.width / size.height; + +            var max = Math.max(size.width, size.height); +            var s = this._scaleImageSize(item, {width: max, height: max}, max); + +            if (propS < 1) { +                height = s.height/size.height; +                width = height * prop / propS; +            } +            else { +                width = s.width/size.width; +                height = width / prop * propS; +            } + +            var h = height * 100; +            var w = width * 100; +            var mL= (1 - width)/2 * 100; +            var mT= ( 1 - height ) / propS * 100 * (vF ? 0.5 : 1 ); +            c.style.height = h+"%"; +            if (item.reflection) item.reflection.style.height = h*this.conf.reflectionHeight+"%"; +            c.style.width = w+"%"; +            if (item.reflection) item.reflection.style.width = w+"%"; +            c.style.marginLeft = mL+"%"; +            if (item.reflection) item.reflection.style.marginLeft = mL+"%"; +            c.style.marginTop = mT+"%"; + +            item.element.style.overflow = "hidden"; + +            return size; +        } +        else { +            return {width: width, height: height}; +        } + +    }, + +    _setItemSize: (function () { +        if (ContentFlowGlobal.Browser.IE) { +            var _setItemSize = function (item, size) { +                if (!this.conf.fixItemSize) { +                    item.content.style.height = size.height+"px"; +                } +                else if (ContentFlowGlobal.Browser.IE6) { +                    var h = parseInt(item.content.style.height)/100; +                    item.content.style.height = size.height*h+"px";  +                    var mT = parseInt(item.content.style.marginTop)/100; +                    item.content.style.marginTop = size.height*mT+"px"; +                } +                if (item.reflection) { +                    var h = parseInt(item.content.style.height); +                    item.reflection.style.height = h*this.conf.reflectionHeight+"px"; +                    item.reflection.style.marginTop = h * this.conf.reflectionGap + "px"; +                } +                item.element.style.width = size.width +"px"; +                item.element.style.height = size.height*(1+this.conf.reflectionHeight+this.conf.reflectionGap)+"px"; +            } +        } +        else { +            var _setItemSize = function (item, size) { +                if (item.reflection) { +                    item.element.style.height = size.height*(1+this.conf.reflectionHeight + this.conf.reflectionGap) +"px"; +                    item.reflection.style.marginTop = size.height * this.conf.reflectionGap + "px"; +                } +                else if (this._reflectionWithinImage) { +                    item.element.style.height = size.height*(1+this.conf.reflectionHeight + this.conf.reflectionGap) +"px"; +                } +                else { +                    item.element.style.height = size.height +"px"; +                } +                item.element.style.width = size.width +"px"; +            } +        } +        return _setItemSize; + +    })(), + +    _setItemOpacity: (function () { +            if (ContentFlowGlobal.Browser.IE6) { +                var _setItemOpacity = function (item) {  +                    if (item.content.origSrc && item.content.origSrc.match(/\.png$/) ) { +                        var s = item.content.src; +                        item.content.src = item.content.origSrc; +                        item.content.style.filter = item.content.filterString+" progid:DXImageTransform.Microsoft.BasicImage(opacity="+item.opacity+")"; +                        item.content.src = s; +                    } +                    else { +                        item.content.style.filter = "progid:DXImageTransform.Microsoft.BasicImage(opacity="+item.opacity+")"; +                    } +                    if (item.reflection) item.reflection.style.filter = item.reflection.filterString+"progid:DXImageTransform.Microsoft.BasicImage(opacity="+item.opacity+")";  +                } +            } +            else if (ContentFlowGlobal.Browser.IE) { +                var _setItemOpacity = function (item) { item.element.style.filter = "progid:DXImageTransform.Microsoft.BasicImage(opacity="+item.opacity+")"; } +            } +            else { +                var _setItemOpacity = function (item) { item.element.style.opacity = item.opacity; } +            } +            return  _setItemOpacity; +    })() + + +}; + + +/* ==================== extendig javascript/DOM objects ==================== */ + +/* + *  adds bind method to Function class + *  http://www.digital-web.com/articles/scope_in_javascript/ + */ + +if (!Function.bind) { +    Function.prototype.bind = function(obj) { +        var method = this; +        return function () { +            return method.apply(obj, arguments); +        }; +    }; +} + + +/* + * extending Math object + */ +if (!Math.erf2) { +    // error function (http://en.wikipedia.org/wiki/Error_function), implemented as erf(x)^2 +    Math.erf2 = function (x) { +        var a = - (8*(Math.PI -3)/(3*Math.PI*(Math.PI -4))); +        var x2 = x*x; +        var f = 1 - Math.pow(Math.E, -x2 * (4/Math.PI + a*x2)/(1+a*x2)); +        return f; +    }; +} + +if (!Math._2PI05) { +    Math._2PI05 = Math.sqrt(2*Math.PI); +} + +if (!Math.normDist) { +    // normal distribution +    Math.normDist = function (x, sig, mu) { +        if (!sig) var sig = 1; +        if (!mu) var mu = 0; +        if (!x) var x = - mu; +        return 1/(sig * Math._2PI05) * Math.pow(Math.E, - (x-mu)*(x-mu)/(2*sig*sig) ); +    }; +} + +if (!Math.normedNormDist) { +    Math.normedNormDist = function (x, sig, mu) { +        return this.normDist(x, sig, mu)/this.normDist(mu, sig, mu); +    }; +} + +if (!Math.exp) { +    Math.exp = function(x) { +        return Math.pow(Math.E, x); +    }; +} + +if (!Math.ln) { +    Math.ln = Math.log; +} + +if (!Math.log2) { +    Math.log2 = function (x) { +        return Math.log(x)/Math.LN2; +    }; +} + +if (!Math.log10) { +    Math.log10 = function (x) { +        return Math.log(x)/Math.LN10; +    }; +} + +if (!Math.logerithm) { +    Math.logerithm = function (x, b) { +        if (!b || b == Math.E) +            return Math.log(x); +        else if (b == 2) +            return Math.log2(x); +        else if (b == 10) +            return Math.log10(x); +        else +            return Math.log(x)/Math.log(b); +    }; +} + + +/* + * extending Event object + */ +if (!Event) var Event = {}; + +if (!Event.stop) { +    Event.stop = function (event) { +        event.cancelBubble = true; +        if (event.preventDefault) event.preventDefault(); +        if (event.stopPropagation) event.stopPropagation(); +        return false; +    }; +} + +/* + * extending Element object + */ +if (document.all && !window.opera) { +    window.$CF = function (el) { +        if (typeof el == "string") { +            return window.$CF(document.getElementById(el)); +        } +        else { +            if (CFElement.prototype.extend && el && !el.extend) CFElement.prototype.extend(el); +        } +        return el; +    }; +} else { +    window.$CF = function (el) { +        return el; +    }; +} + +if (!window.HTMLElement) { +    CFElement = {}; +    CFElement.prototype = {}; +    CFElement.prototype.extend = function (el) { +        for (var method in this) { +            if (!el[method]) el[method] = this[method]; +        } +    }; +} +else { +    CFElement = window.HTMLElement; +} + + +/* + * Thanks to Peter-Paul Koch + * http://www.quirksmode.org/js/findpos.html + */ +if (!CFElement.findPos) { +    CFElement.prototype.findPos = function() { +        var obj = this; +        var curleft = curtop = 0; +        try { +            if (obj.offsetParent) { +                curleft = obj.offsetLeft; +                curtop = obj.offsetTop; +                while (obj = obj.offsetParent) { +                    curleft += obj.offsetLeft; +                    curtop += obj.offsetTop; +                } +            } +        } +        catch (ex) {} +        return {left:curleft, top:curtop}; +    }; +} + +if (!CFElement.getDimensions) { +    CFElement.prototype.getDimensions = function() { +        return {width: this.clientWidth, height: this.clientHeight}; +    }; +} + +/* + * checks if an element has the class className + */ +if (!CFElement.hasClassName) { +    CFElement.prototype.hasClassName = function(className) { +        return (new RegExp('\\b'+className+'\\b').test(this.className)); +    }; +} + +/* + * adds the class className to the element + */  +if (!CFElement.addClassName) { +    CFElement.prototype.addClassName = function(className) { +        if(!this.hasClassName(className)) { +           this.className += (this.className ? ' ':'') + className ; +        } +    }; +} + +/* + * removes the class className from the element el + */  +if (!CFElement.removeClassName) { +    CFElement.prototype.removeClassName = function(className) { +        this.className = this.className.replace(new RegExp('\\b'+className+'\\b'), '').replace(/\s\s/g,' '); +    }; +} + +/* + * removes or adds the class className from/to the element el + * depending if the element has the class className or not. + */ +if (!CFElement.toggleClassName) { +    CFElement.prototype.toggleClassName = function(className) { +        if(this.hasClassName(className)) { +            this.removeClassName(className); +        } else { +            this.addClassName(className); +        } +    }; +} + +/* + * returns all children of element el, which have the class className + */ +if (!CFElement.getChildrenByClassName) { +    CFElement.prototype.getChildrenByClassName = function(className) { +        var children = new Array(); +        for (var i=0; i < this.childNodes.length; i++) { +            var c = this.childNodes[i]; +            if (c.nodeType == 1 && $CF(c).hasClassName(className)) { +                children.push(c); +            } +        } +        return children; +    }; +} + +/* + * Browser independent event handling method. + * adds the eventListener  eventName to element el and attaches the function method to it. + */ +if (!CFElement.addEvent) { +    CFElement.prototype.addEvent = function(eventName, method, capture) { +        if (this.addEventListener) +            this.addEventListener(eventName, method, capture); +        else +            this.attachEvent('on'+eventName, method); +    }; +} +    +/* + * Browser independent event handling method. + * removes the eventListener  eventName with the attached function method from element el. + */ +if (!CFElement.removeEvent) { +    CFElement.prototype.removeEvent = function(eventName, method, capture) { +        if (this.removeEventListener) +            this.removeEventListener(eventName, method, capture); +        else +            this.detachEvent('on'+eventName, method); +    }; +} + +/* + * Browser independent event handling method. + * adds the eventListener  eventName to element el and attaches the function method to it. + */ +if (!window.addEvent) { +    window.addEvent = function(eventName, method, capture) { +        if (this.addEventListener) { +            this.addEventListener(eventName, method, capture); +        } else { +            if (eventName != 'load' && eventName != 'resize') +                document.attachEvent('on'+eventName, method); +            else +                this.attachEvent('on'+eventName, method); +        } +    }; +} +    +/* + * Browser independent event handling method. + * removes the eventListener  eventName with the attached function method from element el. + */ +if (!window.removeEvent) { +    window.removeEvent = function(eventName, method, capture) { +        if (this.removeEventListener) { +            this.removeEventListener(eventName, method, capture); +        } else { +            if (eventName != 'load' && eventName != 'resize') +                document.detachEvent('on'+eventName, method); +            else +                this.detachEvent('on'+eventName, method); +        } +    }; +} + +/* ==================== start it all up ==================== */ +ContentFlowGlobal.init(); + | 
