]> git.parisson.com Git - telemeta.git/commitdiff
Fixed popup, it works in FF and Chrome, added popupdiv.js as separated js file
authorriccardo <riccardo@parisson.com>
Fri, 13 May 2011 14:39:06 +0000 (16:39 +0200)
committerriccardo <riccardo@parisson.com>
Fri, 13 May 2011 14:39:06 +0000 (16:39 +0200)
telemeta/htdocs/js/application.js
telemeta/htdocs/js/popupdiv.js [new file with mode: 0644]
telemeta/htdocs/timeside/src/playlist.js
telemeta/templates/telemeta_default/home.html
telemeta/templates/telemeta_default/mediaitem_detail.html

index dcca5f269d58eaa8a2581a333d0574f53d83218c..da7a24218caa98b2d2ec4cf7dfb2dc26e0b03372 100644 (file)
@@ -315,949 +315,4 @@ function consolelog(text){
             c.log(text);\r
         }\r
     }\r
-}\r
-\r
-\r
-function PopupDiv(){\r
-    var $J = jQuery;\r
-    var me = this;\r
-    var data = arguments.length && arguments[0] || {};\r
-   \r
-    //var wdw = $J(window);\r
-    var div  = $J('<div/>');\r
-    var header = $J('<div/>').append($J('<input/>').attr('type','text')).append($J('<a/>').attr('href','#').click(function(){\r
-        me.close();\r
-        return false;\r
-    })); //.css('float','right');\r
-    var container = $J('<div/>').css('overflow','auto');\r
-    var footer = $J('<div/>').css({\r
-        'textAlign':'right'\r
-    }).append($J('<a/>').attr('href','#').click(function(){\r
-        me.trigger('ok',true);\r
-        return false;\r
-    }));\r
-    header.find('*').add(footer.find('*')).css('display','none');\r
-    div.append(header).append(container).append(footer);\r
-    //defining immediately the method getDiv (because it is used below)\r
-    this.getDiv = function(){\r
-        return div;\r
-    }\r
-    //setting functions:\r
-    \r
-    var listeners = {};\r
-    this.getListeners = function(){\r
-        return listeners;\r
-    }\r
-\r
-    var k;\r
-    //setting static properties, if any:\r
-    for(k in PopupDiv){\r
-        this.__proto__[k] = PopupDiv[k];\r
-        //        consolelog(k+' '+PopupDiv[k]);\r
-        delete PopupDiv[k];\r
-    }\r
-\r
-    //setting instance-specific properties:\r
-    for(k in data){\r
-        if(k == 'onOk' || k == 'onShow' || k == 'onClose'){\r
-            this.bind(k.substring(2).toLowerCase(),data[k]);\r
-        }else if(k == 'content'){\r
-            this.setContent(data[k]);\r
-        }else {\r
-            this[k] = data[k];\r
-        }\r
-    }\r
-\r
-    if(!this.popupCss){\r
-        this.popupCss = {}; //workaround to update css the first time we call show\r
-    //note that {} evaluates to true, but jQueryElement.css({}) is harmless\r
-    }\r
-    \r
-\r
-}\r
-\r
-\r
-(function(p){\r
-    //private static variables\r
-    var $ = jQuery;\r
-    var w_ = window;\r
-    var d_ = document;\r
-    var wdw = $(w_);\r
-    var popupStaticId = 'popup_'+(new Date().getTime());\r
-    //var doc = $(d_);\r
-\r
-\r
-    //in the functions below, this refers to the new Popup instance, not to the prototype\r
-\r
-\r
-\r
-    p.isClickElement = function(element){\r
-        return element && element.length==1 && element instanceof $ && element[0] !== w_ && element[0] !== d_ &&\r
-        (element.is('a') || element.is('input[type=button]') || element.is('button') ||\r
-            element.is('input[type=submit]'));\r
-    };\r
-\r
-    p.getId = function(){\r
-        var div = this.getDiv();\r
-        if(!(div.attr('id'))){\r
-            div.attr('id',popupStaticId+'_'+(new Date().getTime()));\r
-        }\r
-        return div.attr('id');\r
-    };\r
-\r
-\r
-    //default properties which can be overridden\r
-    p.shadowOffset = 4;\r
-    p.invoker = wdw;\r
-    p.bounds = {\r
-        'top':0.25,\r
-        'left':0.25,\r
-        'right':0.25,\r
-        'bottom':0.25\r
-    }; //note that sepcifying top+bottom>=1 there is undefined behaviour (in chrome, offset is set but height takes all available space)\r
-    p.boundsexact = false;\r
-    p.popupClass = '';\r
-    p.popupCss = {};\r
-    p.showok = false;\r
-    p.showclose=false;\r
-    p.title = "";\r
-    p.okButtonClass =  '';\r
-    p.closeButtonClass =  '';\r
-    p.okButtonTitle =  'Ok';\r
-    p.closeButtonTitle =  'x';\r
-    p.defaultCloseOperation = 'hide';\r
-    p.focusable = false;\r
-    p.fadInTime = 'fast',\r
-    p.fadeOutTime = 0,\r
-    p.shadowOpacity = 0.25;\r
-    p.zIndex = 10000;\r
-    // p.listItemClass = '';\r
-\r
-    p.getFormData = function(){\r
-        var elms = this.find('input,select,textarea');\r
-        var ret = {};\r
-        elms.each(function(i,e){\r
-            var ee = $(e);\r
-            var key = ee.attr('name');\r
-            if(key){\r
-                ret[key] = ee.val();\r
-            }\r
-        });\r
-        return ret;\r
-    };\r
-\r
-    p.closeLater = function(millseconds){\r
-        var me = this;\r
-        setTimeout(function(){\r
-            me.close();\r
-        },millseconds);\r
-    },\r
-\r
-    //methods:\r
-    p.find = function(argumentAsInJQueryFind){\r
-        return $(this.getDiv().children()[1]).find(argumentAsInJQueryFind);\r
-    };\r
-\r
-    p.bind = function(eventName, callback){ //eventname: show, close or ok\r
-        var listeners = this.getListeners();\r
-        if(eventName in listeners){\r
-            listeners[eventName].push(callback);\r
-        }else{\r
-            listeners[eventName] = [callback];\r
-        }\r
-    };\r
-\r
-\r
-    p.unbind = function(eventName){\r
-        var listeners = this.getListeners();\r
-        if(eventName && eventName in listeners){\r
-            delete listeners[eventName];\r
-        }else if(!eventName){\r
-            for(var k in listeners){\r
-                delete listeners[k];\r
-            }\r
-        }\r
-    };\r
-\r
-    p.trigger = function(eventName){\r
-        var listeners = this.getListeners();\r
-        var me = this;\r
-        if(eventName in listeners){\r
-            var callbacks = listeners[eventName];\r
-            var i = 0;\r
-            if(eventName == 'ok'){\r
-                var data = this.getFormData();\r
-                for(i=0; i<callbacks.length; i++){\r
-                    callbacks[i].apply(me,[data]);\r
-                }\r
-                if(arguments.length>1 && arguments[1]){\r
-                    //workaround to remove listeners on close:\r
-                    if('close' in listeners){\r
-                        var v = listeners['close'];\r
-                        delete listeners['close'];\r
-                        this.close();\r
-                        listeners['close'] = v;\r
-                    }else{\r
-                        this.close();\r
-                    }\r
-\r
-                }\r
-            }else{\r
-                for(i=0; i<callbacks.length; i++){\r
-                    callbacks[i].apply(me);\r
-                }\r
-            }\r
-        }\r
-    };\r
-\r
-    p.setContent = function(content){\r
-        var div = this.getDiv();\r
-        var container =   $($(div).children()[1]);\r
-        //div.appendTo('body'); //necessary to properly display the div size\r
-        container.empty();\r
-\r
-        if(content instanceof $){\r
-            container.append(content);\r
-        }else if(content instanceof Array){\r
-            var jQ = $;\r
-            var me = this;\r
-            //var name = this.getListItemName();\r
-            var input = $('<input/>').attr('type','hidden').attr('name','selIndex');\r
-            var setEvents = function(idx,anchor,input){\r
-                anchor.click(function(){\r
-                    input.val(idx);\r
-                    me.trigger('ok',true);\r
-                    return false;\r
-                }).focus(function(){ //focus because we need to get the value if ok is present\r
-                    input.val(idx);\r
-                })\r
-            };\r
-            for(var h=0; h<content.length; h++){\r
-                var item = content[h];\r
-                var a = $('<a/>').attr('href','#');\r
-                if('class' in item){\r
-                    a.addClass(item['class']);\r
-                }\r
-                if('html' in item){\r
-                    a.html(item['html']);\r
-                }\r
-                if('name' in item){\r
-                    a.attr('name', item['name']);\r
-                }\r
-                if('id' in item){\r
-                    a.attr('id', item['id']);\r
-                }\r
-                if('css' in item){\r
-                    a.css(item['css']);\r
-                }\r
-                a.css({\r
-                    'display':'block',\r
-                    'margin':'2px'\r
-                }); //margin is used to display the outline (focus)\r
-                setEvents(h,a,input);\r
-                container.append(a);\r
-            }\r
-            container.append(input);\r
-        }else if(content && content.constructor == Object){\r
-            var leftElements = $([]);\r
-            var rightElements = $([]);\r
-            var maxw = [0,0];\r
-            var insert = function(e1,e2){\r
-                var lineDiv = $('<div/>');\r
-                if(!e2){\r
-                    e2=e1;\r
-                    e1 = $('<span/>');\r
-                }\r
-                rightElements = rightElements.add(e2);\r
-                leftElements = leftElements.add(e1);\r
-                container.append(lineDiv.append(e1).append(e2));\r
-                return lineDiv;\r
-            }\r
-            var title, component;\r
-\r
-            var max = Math.max; //instantiate once\r
-            var lineDiv = undefined;\r
-            var lineDivs = $([]);\r
-            for(var k in content){\r
-                var val = content[k];\r
-                if(typeof val == 'string' || typeof val == 'number'){\r
-                    title = $('<span/>').html(k);\r
-                    maxw[0] = max(maxw[0],k.length);\r
-                    maxw[1] = max(maxw[1],val.length);\r
-                    component = $('<input/>').attr('type','text').val(val).attr('name',k);\r
-                    lineDivs = lineDivs.add(insert(title,component));\r
-                }else if(val === true || val === false){\r
-                    var id = this.getId()+"_checkbox";\r
-                    title = $('<input/>').attr('type','checkbox').attr('name',k).attr('id',id);\r
-                    if(val){\r
-                        title.attr('checked','checked');\r
-                    }else{\r
-                        title.removeAttr('checked');\r
-                    }\r
-                    component = $('<label/>').attr('for',id).html(k);\r
-                    maxw[1] = max(maxw[1],k.length);\r
-                    lineDivs = lineDivs.add(insert($('<span/>').append(title),component));\r
-                }else if(val instanceof Array){\r
-                    title = $('<span/>').html(k);\r
-                    maxw[0] = max(maxw[0],k.length);\r
-                    component = $('<select/>').attr('size',1);\r
-                    for(var i=0; i< val.length; i++){\r
-                        component.append($('<option/>').val(val[i]).html(val[i]));\r
-                        maxw[1] = max(maxw[1],val[i].length);\r
-                    }\r
-                    lineDivs = lineDivs.add(insert(title,component));\r
-                }\r
-                if(lineDiv){\r
-                    lineDiv.css('marginBottom','1ex');\r
-                }\r
-            }\r
-            lineDivs.css({\r
-                'white-space': 'nowrap',\r
-                'marginBottom':'0.5ex'\r
-            });\r
-            //last div erase marginBottom\r
-            $(lineDivs[lineDivs.length-1]).css('marginBottom','');\r
-\r
-\r
-            //display: inline-block below assures that width are properly set\r
-            //IE 6/7 accepts the value only on elements with a natural display: inline.\r
-            //(see http://www.quirksmode.org/css/display.html#t03)\r
-            //span and anchors are among them\r
-            //(see http://www.maxdesign.com.au/articles/inline/)\r
-            leftElements.add(rightElements).css({\r
-                'display':'inline-block',\r
-                'margin':'0px',\r
-                'padding':'0px'\r
-            });\r
-            leftElements.css({\r
-                'textAlign':'right',\r
-                'marginRight':'0.5ex',\r
-                'width':Math.round((3/5)*maxw[0])+'em'\r
-            });\r
-            rightElements.css({\r
-                'width':Math.round((3/5)*Math.max(maxw[0], maxw[1]))+'em'\r
-            }); //might be zero if default values are all ""\r
-        }else{\r
-            container.append(""+content);\r
-        }\r
-\r
-    };\r
-\r
-    p.setFocusCycleRoot = function(value){\r
-        //var value = this.focusable;\r
-        var popup = this.getDiv();\r
-        var focusAttr = this.getFocusAttr();\r
-        var invokerIsClickable = this.isClickElement(this.invoker);\r
-        var children_ = popup.children();\r
-        var topDiv = $(children_[0]);\r
-        var centralDiv = $(children_[1]);\r
-        var bottomDiv = $(children_[2]);\r
-        var elementsWithFocus =  centralDiv.find('input[type!=hidden],select,textarea,a'); //input:not(:hidden),select,textarea,a,\r
-\r
-        var ret = elementsWithFocus.length ? $(elementsWithFocus[0]) : popup;\r
-        if(this.showclose){\r
-            elementsWithFocus =elementsWithFocus.add(topDiv.find('a'));\r
-        }\r
-        if(this.showok){\r
-            elementsWithFocus = elementsWithFocus.add(bottomDiv.find('a'));\r
-        }\r
-        elementsWithFocus = elementsWithFocus.add(popup);\r
-        var focusNameSpace = "blur."+this.getId();\r
-        if(!value){\r
-            elementsWithFocus.each(function(i,elm){\r
-                $(elm).unbind(focusNameSpace).removeAttr('tabindex').removeAttr(focusAttr);\r
-            });\r
-            this.getFirstFocusableElement = function(){\r
-                return undefined;\r
-            }\r
-            if(invokerIsClickable){\r
-                this.invoker.removeAttr('tabindex').removeAttr(focusAttr);\r
-            }\r
-            return;\r
-        }\r
-        if(invokerIsClickable){\r
-            this.invoker.attr('tabindex',0).attr(focusAttr,'true');\r
-        }\r
-        var doc_ = d_; //closure (see nested function below)\r
-\r
-        //now all elements (including header and footer)\r
-\r
-        var me = this;\r
-        //bind the blur to each focusable element:\r
-        elementsWithFocus.each(function(i,e){\r
-            var ee = $(e);\r
-            ee.attr(focusAttr,'true');\r
-            ee.attr('tabindex',i+1);\r
-            ee.unbind(focusNameSpace).bind(focusNameSpace,function(){\r
-                //wait 250msec to see if the focus has been given to another popup focusable element: if yes, do nothing\r
-                //otherwise execute callback\r
-                setTimeout(function(){\r
-                    var v = doc_.activeElement;\r
-                    consolelog(v);\r
-                    if((v && $(v).attr(focusAttr)) || me.isClosing){\r
-                        //if we are closing, we will call back this method which removes the focus attributes, bt meanwhile the\r
-                        //timeout should execute\r
-                        return;\r
-                    }\r
-\r
-                    me.close();\r
-                },200)\r
-            }); //set here another time delay. 300 seems to be the good compromise between visual hide and safetiness that\r
-        //meanwhile the focus has already been given to the next component\r
-        });\r
-        this.getFirstFocusableElement = function(){\r
-            return ret;\r
-        }\r
-    };\r
-    p.getFirstFocusableElement = function(){\r
-        return undefined;\r
-    };\r
-    p.show = function(){\r
-        var div = this.getDiv();\r
-        var me = this;\r
-\r
-\r
-        var cssModified = (this.popupClass || this.popupCss);\r
-        if(this.popupClass){\r
-            //which might be the prototype\r
-            div.removeClass().addClass(this.popupClass);\r
-            this.popupClass = ''; //override prototype property\r
-        }\r
-        if(this.popupCss){\r
-            //which might be the prototype\r
-            div.css(this.popupCss);\r
-            this.popupCss = ''; //override prototype property\r
-        }\r
-        //css modified, restore properties we need to be restored:\r
-        if(cssModified){\r
-            div.css({\r
-                'position':'absolute',\r
-                'zIndex':this.zIndex,\r
-                'margin':'0px',\r
-                'overflow':'hidden'\r
-            });\r
-        }\r
-\r
-        //if we have elements of type listitem, add the specified class\r
-        //        var name = this.getListItemName();\r
-        //        var elms = this.find('a[name='+name+']');\r
-        //        if(this.listItemClass){\r
-        //            elms.removeClass().addClass(this.listItemClass);\r
-        //            this.listItemClass = "";\r
-        //        }\r
-        //        elms.css('display','block');\r
-\r
-\r
-        this.setFocusCycleRoot(this.focusable);\r
-        this.setSizable();//this means the popupdiv is display: !none and visibility:hidden, so every element\r
-        //inside it should be visible and therefore sizable. Being visible means that jQuery.is(':visible') returns true\r
-        //start with showing top and bottom if some elements are visible\r
-\r
-        var subdiv = div.children();\r
-\r
-        //configure buttons. Text and classes are added here cause might have been changed\r
-        var topDiv = $(subdiv[0]);\r
-        var titleInput = topDiv.find(':text'); //$(':text') is equivalent to $('[type=text]') (selects all <input type="text"> elements)\r
-        var closeBtn = topDiv.find('a');\r
-        //if title doesn't exist or is hidden, set them to undefined (same for closeBtn).\r
-        //to check visibility, we dont use is(:visible) cause apparently\r
-        //width and height as zero mean hidden (I think that is the cause):\r
-        titleInput = titleInput.length ? $(titleInput.get(0)) : undefined;\r
-        closeBtn = closeBtn.length ? $(closeBtn.get(0)) : undefined;\r
-        if(this.showclose || this.title){\r
-            topDiv.css('paddingBottom','0.5ex').show(); //add padding to bottom\r
-            //is(.. return true if at least one of these elements matches the given arguments.\r
-            if(closeBtn){\r
-                if(this.closeButtonClass){\r
-                    closeBtn.addClass(this.closeButtonClass);\r
-                }\r
-                if(this.closeButtonTitle){\r
-                    closeBtn.html(this.closeButtonTitle);\r
-                }\r
-                closeBtn.css({\r
-                    'display':'inline-block'\r
-                }); //in order to set width and height on the element\r
-            }\r
-            if(titleInput){\r
-                titleInput.val(this.title).css({\r
-                    'display':'inline-block',\r
-                    'padding':'0',\r
-                    'margin':'0',\r
-                    'border':'0',\r
-                    'backgroundColor':'transparent',\r
-                    'marginRight' : '1ex'\r
-                }).attr('readonly','readonly');\r
-            }\r
-        }else{\r
-            topDiv.css('padding','0px');\r
-        }\r
-\r
-        var bottomDiv = $(subdiv[2]);\r
-        //do the same as above, ok must exist and be visible, otherwise is undefined\r
-        var okButton = bottomDiv.find('a');\r
-        okButton = okButton.length ? $(okButton.get(0)) : undefined;\r
-\r
-        //see note above about why we dont use okButton.is(':visible')\r
-        if(this.showok){\r
-            bottomDiv.css('paddingTop','0.5ex').show(); //add padding to bottom\r
-            //is(.. return true if at least one of these elements matches the given arguments.\r
-            if(okButton){\r
-                if(this.okButtonClass){\r
-                    okButton.addClass(this.okButtonClass);\r
-                }\r
-                if(this.okButtonTitle){\r
-                    okButton.html(this.okButtonTitle);\r
-                }\r
-                okButton.css('display','inline-block'); //in order to set width and height on the element\r
-            }\r
-        }else{\r
-            bottomDiv.css('paddingTop','0px');\r
-        }\r
-\r
-        var centralDiv = $(subdiv[1]);\r
-        //reset properties of the central div\r
-        centralDiv.css({\r
-            'maxHeight':'',\r
-            'maxWidth':'',\r
-            'minHeight':'',\r
-            'minWidth':'',\r
-            'height':'',\r
-            'width':''\r
-        });\r
-\r
-\r
-        var invoker = this.invoker;\r
-\r
-        var sizeAsPopup = false;\r
-        if(this.isClickElement(invoker)){\r
-            this.setBoundsAsPopup(invoker, true);\r
-            sizeAsPopup = true;\r
-            //storing click events, when showing clicking on an event must give the focus to the popup\r
-            //old handlers will be restored in close()\r
-            this['_tmpHandlers'+this.getId()] = undefined;\r
-            var focusElm = this.getFirstFocusableElement();\r
-            if(focusElm){\r
-                var oldHandlers = [];\r
-                var type = 'click';\r
-                var clickEvents =invoker.data("events")[type];\r
-                $.each(clickEvents, function(key, value) {\r
-                    oldHandlers.push(value);\r
-                })\r
-                invoker.unbind(type); //remove (temporarily) the binding to the event.\r
-                //for instance, if we show the popup by clicking invoker, when the popup is shown do nothing\r
-                //on clicking invoker until popup.hide is called\r
-\r
-                this['_tmpHandlers'+this.getId()] = oldHandlers;\r
-                invoker.unbind(type).bind(type,function(evt){\r
-                    //let the invoker have focus and let it be recognized as an element which does not blur the popup:\r
-                    //invoker.attr('tabindex',0).attr(focusAttr,'true');\r
-                    if(div.length && div.is(':visible')){\r
-                        focusElm.focus();\r
-                        return false;\r
-                    }\r
-                    //something wrong: close the popup and restore the hanlers\r
-                    me.close.apply(me);\r
-                    return false;\r
-                });\r
-            }\r
-\r
-        }else{\r
-            this.setBoundsInside(invoker, this.bounds, this.boundsexact, true);\r
-        }\r
-\r
-\r
-\r
-        //set central div max height ONLY IF NECESSARY:\r
-        var maxHeight = (div.height()-topDiv.outerHeight(true)-bottomDiv.outerHeight(true)-\r
-            (centralDiv.outerHeight(true)-centralDiv.height()));\r
-        var height = centralDiv.height();\r
-        if(sizeAsPopup && maxHeight<height){\r
-            centralDiv.css('maxHeight',maxHeight+'px');\r
-        }else{\r
-            centralDiv.css({\r
-                'maxHeight': maxHeight+'px',\r
-                'minHeight': maxHeight+'px'\r
-            });\r
-        }\r
-        //set central div max width ONLY IF NECESSARY:\r
-        var maxWidth = div.width();\r
-        var width = $(subdiv[1]).outerWidth(true);\r
-        if(sizeAsPopup && maxWidth<width){\r
-            centralDiv.css('maxWidth',maxWidth+'px');\r
-        }else{\r
-            centralDiv.css({\r
-                'maxWidth': maxWidth+'px',\r
-                'minWidth':maxWidth+'px'\r
-            });\r
-        }\r
-\r
-        //set title and close button to span whole width, if necessary\r
-        if(titleInput || closeBtn){\r
-            var titleW = topDiv.width() - (closeBtn ? closeBtn.outerWidth(true) : 0) - (titleInput ? titleInput.outerWidth(true)-titleInput.width() : 0);\r
-            if(titleInput){\r
-                titleInput.css('width',titleW+'px');\r
-            }\r
-        }\r
-\r
-        //creating shadow. REmove attributes tabindex (unnecessary) and especially focusAttr,\r
-        //so that clicking tab key and setting the shadow focusable hides the popup. If one wants the shadow not to hide the popup. keep\r
-        //focusAttr BUT insert shadow in the focus cycle root (see method)\r
-        var shadow = div.clone(false,false).empty().css({\r
-            'backgroundColor':'#000',\r
-            'borderColor':'#000',\r
-            'visibility':'visible',\r
-            'zIndex':this.zIndex-1\r
-        }).removeAttr('tabindex').removeAttr(this.getFocusAttr()).fadeTo(0,0).\r
-        attr('id',this.getShadowDivId()) //for use in hide\r
-        .insertAfter(div);\r
-\r
-\r
-        var postShowFcn = function(){\r
-            me.trigger('show');\r
-            var rect = me.getBounds.apply(me);\r
-            shadow.css({\r
-                'left':(rect.x + me.shadowOffset)+'px',\r
-                'top':(rect.y + me.shadowOffset)+'px',\r
-                'width':(rect.width)+'px',\r
-                'height':(rect.height)+'px'\r
-            }).fadeTo(me.fadInTime,me.shadowOpacity, function(){\r
-                var v = me.getFirstFocusableElement();\r
-                if(v){\r
-                    v.focus();\r
-                }\r
-            });\r
-        }\r
-\r
-        div.hide().css('visibility','visible').show(this.fadInTime,function(){\r
-\r
-            postShowFcn();\r
-\r
-\r
-        });\r
-    };\r
-\r
-    p.setBoundsAsPopup = function(popupInvoker, isSizable){\r
-        var invoker = popupInvoker;\r
-        var div = this.getDiv();\r
-        var oldCss= isSizable ?  undefined : this.setSizable();\r
-\r
-        var windowRectangle = this.getBoundsOf(wdw); //returns the window rectangle\r
-\r
-        var invokerOffset = invoker.offset();\r
-        var invokerOuterHeight = invoker.outerHeight();\r
-\r
-        //first set the maxwidth,so that we can compute the height according to it:\r
-        this.setMaxSize({\r
-            width: wdw.scrollLeft()+wdw.width()-invokerOffset.left\r
-        },isSizable);\r
-\r
-\r
-        var spaceAbove = invokerOffset.top - windowRectangle.y;\r
-        var spaceBelow = windowRectangle.height - invokerOuterHeight - spaceAbove;\r
-\r
-        var placeAbove = spaceAbove > spaceBelow && div.outerHeight(true) > spaceBelow;\r
-        //note that div.outerHeight() should be  == div.outerHeight(true), as we set margins =0\r
-\r
-        //        alert(div.outerHeight(true)+' '+spaceAbove+' '+spaceBelow);\r
-        //        div.css('visibility','');\r
-        //        return;\r
-\r
-        this.setMaxSize({\r
-            height : (placeAbove ? spaceAbove : spaceBelow)\r
-        },isSizable); //width will be ignored (for the moment)\r
-        //decrement of one pixel cause when the popup has to be reduced and the shadows bounds "touch" the window right or bottom sides,\r
-        //the window scrolls (and it shouldn't)\r
-\r
-        //setting the minimum size to the invoker width, minheight the same as maxHeight (see above)\r
-        this.setMinSize({\r
-            width: invoker.outerWidth()+this.shadowOffset //workaround to NOT consider the shadow, as offset below substracts the shadow\r
-        //height : spaceAbove>spaceBelow ? spaceAbove : spaceBelow //why this? because if we click the popup a\r
-        //computed height CH seems to be set. At subsequent popup show, CH will be the same UNLESS a new maxHeight lower than CH is set\r
-        //however, we want CH to change even if a new maxHeight greater than CH is set\r
-        },isSizable);\r
-\r
-        //setting the top and left. This must be done at last because popupDiv.outerHeight(true)\r
-        //must have been computed according to the height set above...\r
-        this.offset({\r
-            'left': invokerOffset.left,\r
-            'top': (placeAbove ? invokerOffset.top -  div.outerHeight(true) :\r
-                invokerOffset.top + invokerOuterHeight)\r
-        },isSizable);\r
-        if(oldCss){\r
-            div.css({\r
-                'display':oldCss['display'],\r
-                'visibility':oldCss['visibility']\r
-            });\r
-        }\r
-    };\r
-    //places and resize the popupdiv inside parent\r
-    //padding is a dict {top:,left:,bottom:..,right:,...} measuring the distance of the popupdiv from the corners, so that\r
-    //padding={top:0.25,left:0.25,bottom:0.25,right:0.25} will place the popupdiv at the center of parent\r
-    //padding={top:25,left:25,bottom:25,right:25} will place the popupdiv at distances 25 px from parent sides\r
-    //in other words, padding keys lower or euqals to 1 will be conbsidered as percentage, otherwise as absolute measures in px\r
-    p.setBoundsInside = function(parent, pd, boundsExact, isSizable){\r
-\r
-        var div = this.getDiv();\r
-        var oldCss = isSizable ?  undefined : this.setSizable();\r
-\r
-        var bounds = this.getBoundsOf(parent);\r
-\r
-        var x=bounds.x;\r
-        var y = bounds.y;\r
-        var w = bounds.width\r
-        var h = bounds.height;\r
-        var pInt = parseInt;\r
-        //rebuilding:\r
-\r
-        var padding = {\r
-            top: pd['top'],\r
-            left:pd['left'],\r
-            bottom:pd['bottom'],\r
-            right:pd['right']\r
-        };\r
-\r
-        for(var k in padding){\r
-            if(padding[k]<=0){\r
-                padding[k]=0;\r
-            }else if(padding[k]<=1){\r
-                padding[k] = k=='top' || k =='bottom' ? h*padding[k] : w*padding[k];\r
-            }else{\r
-                padding[k] = pInt(padding[k]);\r
-            }\r
-        }\r
-\r
-        var maxSize = {\r
-            'width':w-padding['left']-padding['right']+this.shadowOffset,\r
-            'height':h-padding['top']-padding['bottom']+this.shadowOffset\r
-        };\r
-\r
-        var vvvv ={\r
-            width:maxSize.width,\r
-            height:maxSize.height\r
-        };\r
-        this._convertSize(div, vvvv);\r
-\r
-        if(boundsExact){\r
-            this.setMinSize({\r
-                width:maxSize.width,\r
-                height:maxSize.height\r
-            },isSizable); //a copy cause the argument will be modified\r
-            this.setMaxSize({\r
-                width:maxSize.width,\r
-                height:maxSize.height\r
-            }, isSizable); //a copy cause the argument will be modified\r
-\r
-            this.offset({\r
-                'left':x + padding['left'],\r
-                'top': y + padding['top']\r
-            },isSizable);\r
-        }else{\r
-            this.setMaxSize({\r
-                width:maxSize.width,\r
-                height:maxSize.height\r
-            },isSizable); //a copy cause the argument will be modified\r
-            var spanLeft = maxSize.width - div.outerWidth(true);\r
-            var spanTop = maxSize.height - div.outerHeight(true);\r
-            this.offset({\r
-                'left':x + padding['left'] + (spanLeft > 0 ? spanLeft/2 : 0),\r
-                'top': y + padding['top'] +(spanTop > 0 ? spanTop/2 : 0)\r
-            },isSizable);\r
-\r
-        }\r
-        //convert to percentage in order to keep same dimensions when zooming\r
-\r
-\r
-        if(oldCss){\r
-            div.css({\r
-                'display':oldCss['display'],\r
-                'visibility':oldCss['visibility']\r
-            });\r
-        }\r
-    };\r
-    p.getBounds = function(){\r
-        return this.getBoundsOf(this.getDiv());\r
-    };\r
-    //TODO: change argument\r
-    p.getBoundsOf = function(jQueryElement){\r
-        var ret = {\r
-            x:0,\r
-            y:0,\r
-            width:0,\r
-            height:0\r
-        };\r
-        if(!jQueryElement || !(jQueryElement instanceof $)){\r
-            jQueryElement = wdw;\r
-        }\r
-        if(jQueryElement[0] === w_){\r
-            ret.x = jQueryElement.scrollLeft();\r
-            ret.y = jQueryElement.scrollTop();\r
-        }else{\r
-            var offs = jQueryElement.offset();\r
-            ret.x = offs.left;\r
-            ret.y = offs.top;\r
-        }\r
-        ret.width = jQueryElement.width();\r
-        ret.height = jQueryElement.height();\r
-        return ret;\r
-    };\r
-\r
-    p.setMaxSize = function(size, isSizable){\r
-        var div = this.getDiv();\r
-        var oldCss = isSizable ?  undefined : this.setSizable();\r
-\r
-        this._convertSize(div, size);\r
-        var css = {};\r
-        if('width' in size){\r
-            css.maxWidth = size.width+'px';\r
-        }\r
-        if('height' in size){\r
-            css.maxHeight = size.height+'px';\r
-        }\r
-        if(css){\r
-            div.css(css);\r
-        }\r
-        if(oldCss){\r
-            div.css({\r
-                'display':oldCss['display'],\r
-                'visibility':oldCss['visibility'],\r
-                'top':oldCss['top'],\r
-                'left':oldCss['left']\r
-            });\r
-        }\r
-        return size;\r
-    };\r
-    p.setMinSize = function(size, isSizable){\r
-        var div = this.getDiv();\r
-        var oldCss= isSizable ?  undefined : this.setSizable();\r
-\r
-        this._convertSize(div, size);\r
-        var css = {};\r
-        if('width' in size){\r
-            css.minWidth = size.width+'px';\r
-        }\r
-        if('height' in size){\r
-            css.minHeight = size.height+'px';\r
-        }\r
-        if(css){\r
-            div.css(css);\r
-        }\r
-        if(oldCss){\r
-            div.css({\r
-                'display':oldCss['display'],\r
-                'visibility':oldCss['visibility'],\r
-                'top':oldCss['top'],\r
-                'left':oldCss['left']\r
-            });\r
-        }\r
-        return size;\r
-    };\r
-    //div must be display!=hidden. size is a dict with at least one of the fields 'width' and 'height'\r
-    //TODO: check if div is sizable????\r
-    p._convertSize = function(div, size){\r
-        var eD = {\r
-            'width': div.outerWidth(true)-div.width(),\r
-            'height':div.outerHeight(true)-div.height()\r
-        };\r
-\r
-        if('width' in size){\r
-            size.width -= (eD.width + this.shadowOffset);\r
-        }\r
-        if('height' in size){\r
-            size.height -= (eD.height + this.shadowOffset);\r
-        }\r
-    };\r
-\r
-    p.offset = function(offs, isSizable){\r
-        var div = this.getDiv();\r
-        var oldCss= isSizable?  undefined : this.setSizable();\r
-        //offset does NOT consider margins. Do we have top and left?\r
-\r
-        this.getDiv().offset(offs);\r
-        if(oldCss){\r
-            div.css({\r
-                'display':oldCss['display'],\r
-                'visibility':oldCss['visibility'],\r
-                'maxWidth':oldCss['maxWidth'],\r
-                'maxHeight':oldCss['maxHeight'],\r
-                'minWidth':oldCss['minWidth'],\r
-                'minHeight':oldCss['minHeight']\r
-            });\r
-        }\r
-    };\r
-\r
-    p.isClosing = false;\r
-    p.close = function(){\r
-        this.isClosing = true;\r
-        this.setFocusCycleRoot(false);\r
-        var div = this.getDiv();\r
-        var shadow = $('#'+this.getShadowDivId());\r
-        shadow.remove();\r
-        var me = this;\r
-        var remove = this.defaultCloseOperation == 'remove';\r
-        div.hide(this.fadeOutTime, function(){\r
-\r
-            if(remove){\r
-                div.remove();\r
-            //this is because all bindings will be removed, including blur events\r
-            //we remove this.getFocusAttr() to reupdate focus cycle root when calling show again\r
-            }\r
-\r
-            //restore event data on invoker, if any\r
-            var id = '_tmpHandlers'+me.getId();\r
-            if(me[id]){\r
-                var oldHandlers = me[id];\r
-                delete  me[id];\r
-                me.invoker.unbind('click');\r
-                for(var k =0; k< oldHandlers.length; k++){\r
-                    var h = oldHandlers[k];\r
-                    me.invoker.bind(h.type+(h.namespace ? "."+h.namespace : ""),h.handler);\r
-                }\r
-            }\r
-\r
-            me.isClosing = false;\r
-            me.trigger('close');\r
-        });\r
-\r
-    };\r
-\r
-\r
-    p.setSizable = function(){\r
-        //if false, just update the flag\r
-        var div = this.getDiv();\r
-\r
-        if(!div.parent().length){\r
-            div.appendTo('body');\r
-        }\r
-        var keys = ['display','visibility','left','top','maxWidth','maxHeight','minWidth','minHeight'];\r
-        var css = {};\r
-        for(var i=0; i<keys.length; i++){\r
-            css[keys[i]] = div.css(keys[i]);\r
-        }\r
-        div.offset({\r
-            'left':wdw.scrollLeft(),\r
-            'top':wdw.scrollTop()\r
-        });\r
-        //set the div invisible but displayable to calculate the size (callbackPreShow)\r
-        div.css({\r
-            'visibility':'hidden',\r
-            'maxWidth':'',\r
-            'maxHeight':'',\r
-            'minWidth':'',\r
-            'minHeight':'',\r
-            'height':'',\r
-            'width':''\r
-        }).show();\r
-\r
-\r
-        return css;\r
-    }\r
-    p.getShadowDivId = function(){\r
-        return this.getId()+"_shadow";\r
-    }\r
-\r
-    p.getFocusAttr = function(){\r
-        return this.getId()+"_focus";\r
-    }\r
-\r
-\r
-})(PopupDiv.prototype);
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/telemeta/htdocs/js/popupdiv.js b/telemeta/htdocs/js/popupdiv.js
new file mode 100644 (file)
index 0000000..fd04123
--- /dev/null
@@ -0,0 +1,953 @@
+/**\r
+ * TimeSide - Web Audio Components\r
+ * Copyright (c) 2011 Parisson\r
+ * Author: Riccardo Zaccarelli\r
+ * License: GNU General Public License version 2.0\r
+ */\r
+\r
+/**\r
+ * class for showing non-modal dialogs such as popups or combo lists\r
+ */\r
+function PopupDiv(){\r
+    var $J = jQuery;\r
+    var me = this;\r
+    var data = arguments.length && arguments[0] || {};\r
+\r
+    //var wdw = $J(window);\r
+    var div  = $J('<div/>');\r
+    //we use an input rather than a span for two reasons:\r
+    //1: span with overflow:hidden have problems in vertical align with the close button in FF and IE\r
+    //2: if text title overlaps, with a span it is not selectable, with an input it is\r
+    var header = $J('<div/>').append($J('<input/>')).append($J('<a/>').attr('href','#').click(function(){\r
+        me.close();\r
+        return false;\r
+    })); //.css('float','right');\r
+    var container = $J('<div/>').css('overflow','auto');\r
+    var footer = $J('<div/>').append($J('<a/>').attr('href','#').click(function(){\r
+        me.trigger('ok',true);\r
+        return false;\r
+    }));\r
+    header.find('*').add(footer.find('*')).css('display','none');\r
+    div.append(header).append(container).append(footer);\r
+    //defining immediately the method getDiv (because it is used below)\r
+    this.getDiv = function(){\r
+        return div;\r
+    }\r
+    //setting functions:\r
+\r
+    var listeners = {};\r
+    this.getListeners = function(){\r
+        return listeners;\r
+    }\r
+\r
+    var k;\r
+    //setting static properties, if any:\r
+    for(k in PopupDiv){\r
+        this.__proto__[k] = PopupDiv[k];\r
+        //        consolelog(k+' '+PopupDiv[k]);\r
+        delete PopupDiv[k];\r
+    }\r
+\r
+    //setting instance-specific properties:\r
+    for(k in data){\r
+        if(k == 'onOk' || k == 'onShow' || k == 'onClose'){\r
+            this.bind(k.substring(2).toLowerCase(),data[k]);\r
+        }else if(k == 'content'){\r
+            this.setContent(data[k]);\r
+        }else {\r
+            this[k] = data[k];\r
+        }\r
+    }\r
+\r
+    if(!this.popupCss){\r
+        this.popupCss = {}; //workaround to update css the first time we call show\r
+    //note that {} evaluates to true, but jQueryElement.css({}) is harmless\r
+    }\r
+\r
+\r
+}\r
+\r
+\r
+(function(p){\r
+    //private static variables\r
+    var $ = jQuery;\r
+    var w_ = window;\r
+    var d_ = document;\r
+    var wdw = $(w_);\r
+    var popupStaticId = 'popup_'+(new Date().getTime());\r
+    //var doc = $(d_);\r
+\r
+\r
+    //in the functions below, this refers to the new Popup instance, not to the prototype\r
+\r
+\r
+\r
+    p.isClickElement = function(element){\r
+        return element && element.length==1 && element instanceof $ && element[0] !== w_ && element[0] !== d_ &&\r
+        (element.is('a') || element.is('input[type=button]') || element.is('button') ||\r
+            element.is('input[type=submit]'));\r
+    };\r
+\r
+    p.getId = function(){\r
+        var div = this.getDiv();\r
+        if(!(div.attr('id'))){\r
+            div.attr('id',popupStaticId+'_'+(new Date().getTime()));\r
+        }\r
+        return div.attr('id');\r
+    };\r
+\r
+\r
+    //default properties which can be overridden\r
+    p.shadowOffset = 4;\r
+    p.invoker = wdw;\r
+    p.bounds = {\r
+        'top':0.25,\r
+        'left':0.25,\r
+        'right':0.25,\r
+        'bottom':0.25\r
+    }; //note that sepcifying top+bottom>=1 there is undefined behaviour (in chrome, offset is set but height takes all available space)\r
+    p.boundsExact = false;\r
+    p.popupClass = '';\r
+    p.popupCss = {};\r
+    p.showOk = false;\r
+    p.showClose=false;\r
+    p.title = "";\r
+    p.okButtonClass =  '';\r
+    p.okButtonAlign =  'right';\r
+    p.closeButtonClass =  '';\r
+    p.titleClass =  '';\r
+    p.okButtonTitle =  'Ok';\r
+    p.closeButtonTitle =  'x';\r
+    p.defaultCloseOperation = 'hide';\r
+    p.focusable = false;\r
+    p.fadInTime = 'fast',\r
+    p.fadeOutTime = 0,\r
+    p.shadowOpacity = 0.25;\r
+    p.zIndex = 10000;\r
+    // p.listItemClass = '';\r
+\r
+    p.getFormData = function(){\r
+        var elms = this.find('input,select,textarea');\r
+        var ret = {};\r
+        elms.each(function(i,e){\r
+            var ee = $(e);\r
+            var key = ee.attr('name');\r
+            if(key){\r
+                ret[key] = ee.val();\r
+            }\r
+        });\r
+        return ret;\r
+    };\r
+\r
+    p.closeLater = function(millseconds){\r
+        var me = this;\r
+        setTimeout(function(){\r
+            me.close();\r
+        },millseconds);\r
+    },\r
+\r
+    //methods:\r
+    p.find = function(argumentAsInJQueryFind){\r
+        return $(this.getDiv().children()[1]).find(argumentAsInJQueryFind);\r
+    };\r
+\r
+    p.bind = function(eventName, callback){ //eventname: show, close or ok\r
+        var listeners = this.getListeners();\r
+        if(eventName in listeners){\r
+            listeners[eventName].push(callback);\r
+        }else{\r
+            listeners[eventName] = [callback];\r
+        }\r
+    };\r
+\r
+\r
+    p.unbind = function(eventName){\r
+        var listeners = this.getListeners();\r
+        if(eventName && eventName in listeners){\r
+            delete listeners[eventName];\r
+        }else if(!eventName){\r
+            for(var k in listeners){\r
+                delete listeners[k];\r
+            }\r
+        }\r
+    };\r
+\r
+    p.trigger = function(eventName){\r
+        var listeners = this.getListeners();\r
+        var me = this;\r
+        if(eventName in listeners){\r
+            var callbacks = listeners[eventName];\r
+            var i = 0;\r
+            if(eventName == 'ok'){\r
+                var data = this.getFormData();\r
+                for(i=0; i<callbacks.length; i++){\r
+                    callbacks[i].apply(me,[data]);\r
+                }\r
+                if(arguments.length>1 && arguments[1]){\r
+                    //workaround to remove listeners on close:\r
+                    if('close' in listeners){\r
+                        var v = listeners['close'];\r
+                        delete listeners['close'];\r
+                        this.close();\r
+                        listeners['close'] = v;\r
+                    }else{\r
+                        this.close();\r
+                    }\r
+\r
+                }\r
+            }else{\r
+                for(i=0; i<callbacks.length; i++){\r
+                    callbacks[i].apply(me);\r
+                }\r
+            }\r
+        }\r
+    };\r
+\r
+    p.setContent = function(content){\r
+        var div = this.getDiv();\r
+        var container =   $($(div).children()[1]);\r
+        //div.appendTo('body'); //necessary to properly display the div size\r
+        container.empty();\r
+\r
+        if(content instanceof $){\r
+            container.append(content);\r
+        }else if(content instanceof Array){\r
+            var jQ = $;\r
+            var me = this;\r
+            //var name = this.getListItemName();\r
+            var input = $('<input/>').attr('type','hidden').attr('name','selIndex');\r
+            var setEvents = function(idx,anchor,input){\r
+                anchor.click(function(){\r
+                    input.val(idx);\r
+                    me.trigger('ok',true);\r
+                    return false;\r
+                }).focus(function(){ //focus because we need to get the value if ok is present\r
+                    input.val(idx);\r
+                })\r
+            };\r
+            for(var h=0; h<content.length; h++){\r
+                var item = content[h];\r
+                var a = $('<a/>').attr('href','#');\r
+                if('class' in item){\r
+                    a.addClass(item['class']);\r
+                }\r
+                if('html' in item){\r
+                    a.html(item['html']);\r
+                }\r
+                if('name' in item){\r
+                    a.attr('name', item['name']);\r
+                }\r
+                if('id' in item){\r
+                    a.attr('id', item['id']);\r
+                }\r
+                if('css' in item){\r
+                    a.css(item['css']);\r
+                }\r
+                a.css({\r
+                    'display':'block',\r
+                    'margin':'2px'\r
+                }); //margin is used to display the outline (focus)\r
+                setEvents(h,a,input);\r
+                container.append(a);\r
+            }\r
+            container.append(input);\r
+        }else if(content && content.constructor == Object){\r
+            var leftElements = $([]);\r
+            var rightElements = $([]);\r
+            var maxw = [0,0];\r
+            var insert = function(e1,e2){\r
+                var lineDiv = $('<div/>');\r
+                if(!e2){\r
+                    e2=e1;\r
+                    e1 = $('<span/>');\r
+                }\r
+                rightElements = rightElements.add(e2);\r
+                leftElements = leftElements.add(e1);\r
+                container.append(lineDiv.append(e1).append(e2));\r
+                return lineDiv;\r
+            }\r
+            var title, component;\r
+\r
+            var max = Math.max; //instantiate once\r
+            var lineDiv = undefined;\r
+            var lineDivs = $([]);\r
+            for(var k in content){\r
+                var val = content[k];\r
+                if(typeof val == 'string' || typeof val == 'number'){\r
+                    title = $('<span/>').html(k);\r
+                    maxw[0] = max(maxw[0],k.length);\r
+                    maxw[1] = max(maxw[1],val.length);\r
+                    component = $('<input/>').attr('type','text').val(val).attr('name',k);\r
+                    lineDivs = lineDivs.add(insert(title,component));\r
+                }else if(val === true || val === false){\r
+                    var id = this.getId()+"_checkbox";\r
+                    title = $('<input/>').attr('type','checkbox').attr('name',k).attr('id',id);\r
+                    if(val){\r
+                        title.attr('checked','checked');\r
+                    }else{\r
+                        title.removeAttr('checked');\r
+                    }\r
+                    component = $('<label/>').attr('for',id).html(k);\r
+                    maxw[1] = max(maxw[1],k.length);\r
+                    lineDivs = lineDivs.add(insert($('<span/>').append(title),component));\r
+                }else if(val instanceof Array){\r
+                    title = $('<span/>').html(k);\r
+                    maxw[0] = max(maxw[0],k.length);\r
+                    component = $('<select/>').attr('size',1);\r
+                    for(var i=0; i< val.length; i++){\r
+                        component.append($('<option/>').val(val[i]).html(val[i]));\r
+                        maxw[1] = max(maxw[1],val[i].length);\r
+                    }\r
+                    lineDivs = lineDivs.add(insert(title,component));\r
+                }\r
+                if(lineDiv){\r
+                    lineDiv.css('marginBottom','1ex');\r
+                }\r
+            }\r
+            lineDivs.css({\r
+                'white-space': 'nowrap',\r
+                'marginBottom':'0.5ex'\r
+            });\r
+            //last div erase marginBottom\r
+            $(lineDivs[lineDivs.length-1]).css('marginBottom','');\r
+\r
+\r
+            //display: inline-block below assures that width are properly set\r
+            //IE 6/7 accepts the value only on elements with a natural display: inline.\r
+            //(see http://www.quirksmode.org/css/display.html#t03)\r
+            //span and anchors are among them\r
+            //(see http://www.maxdesign.com.au/articles/inline/)\r
+            leftElements.add(rightElements).css({\r
+                'display':'inline-block',\r
+                'margin':'0px',\r
+                'padding':'0px'\r
+            });\r
+            leftElements.css({\r
+                'textAlign':'right',\r
+                'marginRight':'0.5ex',\r
+                'width':Math.round((3/5)*maxw[0])+'em'\r
+            });\r
+            rightElements.css({\r
+                'width':Math.round((3/5)*Math.max(maxw[0], maxw[1]))+'em'\r
+            }); //might be zero if default values are all ""\r
+        }else{\r
+            container.append(""+content);\r
+        }\r
+\r
+    };\r
+\r
+    p.setFocusCycleRoot = function(value){\r
+        //var value = this.focusable;\r
+        var popup = this.getDiv();\r
+        var focusAttr = this.getFocusAttr();\r
+        var invokerIsClickable = this.isClickElement(this.invoker);\r
+        var children_ = popup.children();\r
+        var topDiv = $(children_[0]);\r
+        var centralDiv = $(children_[1]);\r
+        var bottomDiv = $(children_[2]);\r
+        var elementsWithFocus =  centralDiv.find('input[type!=hidden],select,textarea,a'); //input:not(:hidden),select,textarea,a,\r
+\r
+        var ret = elementsWithFocus.length ? $(elementsWithFocus[0]) : popup;\r
+        if(this.showClose){\r
+            elementsWithFocus =elementsWithFocus.add(topDiv.find('a'));\r
+        }\r
+        if(this.showOk || this.title){\r
+           elementsWithFocus = elementsWithFocus.add(topDiv.find(':text'));\r
+           if(this.showOk){\r
+               elementsWithFocus = elementsWithFocus.add(bottomDiv.find('a'));\r
+           }\r
+       }\r
+        elementsWithFocus = elementsWithFocus.add(popup);\r
+        var focusNameSpace = "blur."+this.getId();\r
+        if(!value){\r
+            elementsWithFocus.each(function(i,elm){\r
+                $(elm).unbind(focusNameSpace).removeAttr('tabindex').removeAttr(focusAttr);\r
+            });\r
+            this.getFirstFocusableElement = function(){\r
+                return undefined;\r
+            }\r
+            if(invokerIsClickable){\r
+                this.invoker.removeAttr('tabindex').removeAttr(focusAttr);\r
+            }\r
+            return;\r
+        }\r
+        if(invokerIsClickable){\r
+            this.invoker.attr('tabindex',0).attr(focusAttr,'true');\r
+        }\r
+        var doc_ = d_; //closure (see nested function below)\r
+\r
+        //now all elements (including header and footer)\r
+\r
+        var me = this;\r
+        //bind the blur to each focusable element:\r
+        elementsWithFocus.each(function(i,e){\r
+            var ee = $(e);\r
+            ee.attr(focusAttr,'true');\r
+            ee.attr('tabindex',i+1);\r
+            ee.unbind(focusNameSpace).bind(focusNameSpace,function(){\r
+                //wait 250msec to see if the focus has been given to another popup focusable element: if yes, do nothing\r
+                //otherwise execute callback\r
+                setTimeout(function(){\r
+                    var v = doc_.activeElement;\r
+                    console.log(v);\r
+                    if((v && $(v).attr(focusAttr)) || me.isClosing){\r
+                        //if we are closing, we will call back this method which removes the focus attributes, bt meanwhile the\r
+                        //timeout should execute\r
+                        return;\r
+                    }\r
+\r
+                    me.close();\r
+                },200)\r
+            }); //set here another time delay. 300 seems to be the good compromise between visual hide and safetiness that\r
+        //meanwhile the focus has already been given to the next component\r
+        });\r
+        this.getFirstFocusableElement = function(){\r
+            return ret;\r
+        }\r
+    };\r
+    p.getFirstFocusableElement = function(){\r
+        return undefined;\r
+    };\r
+\r
+    p.show = function(){\r
+        var div = this.getDiv();\r
+        var me = this;\r
+\r
+        var cssModified = (this.popupClass || this.popupCss);\r
+        if(this.popupClass){\r
+            //this.popupClass might be in the prototype (not set by user)\r
+            div.removeClass().addClass(this.popupClass);\r
+            this.popupClass = ''; //override prototype property\r
+        }\r
+        if(this.popupCss){\r
+            //this.popupCss might be in the prototype (not set by user)\r
+            div.css(this.popupCss);\r
+            this.popupCss = ''; //override prototype property\r
+        }\r
+        //css modified, restore properties we need not to change:\r
+       //cssModified should be true ALL first times we call show, as this.popupCss = {} )ie, it evaluates to TRUE)\r
+        if(cssModified){\r
+            div.css({\r
+                'position':'absolute',\r
+                'zIndex':this.zIndex,\r
+                'margin':'0px',\r
+                'overflow':'hidden'\r
+            });\r
+        }\r
+\r
+        this.setFocusCycleRoot(this.focusable);\r
+\r
+        var subdiv = div.children();\r
+        //configure buttons. Text and classes are added here cause might have been changed\r
+        var topDiv = $(subdiv[0]);\r
+        var titleInput = topDiv.find(':text').eq(0); //$(':text') is equivalent to $('[type=text]') (selects all <input type="text"> elements)\r
+        var closeBtn = topDiv.find('a').eq(0);\r
+        if(!this.showClose && !this.title){\r
+         topDiv.hide();\r
+       }else{\r
+               topDiv.css({'paddingBottom':'1em','whiteSpace': 'nowrap'}).show(); //add padding to bottom\r
+                       //warning: do NOT use real numbers such as 0.5ex cause browsers round it in a different manner\r
+                       //whiteSpace is FUNDAMENTAL in calculating the popup div in case the title is the longest (max width) element\r
+                       //in the popup div. We will set the same whitespace css also on the title (see below)\r
+\r
+               if(this.showClose){\r
+                       closeBtn.attr('class',this.closeButtonClass); //removes all existing classes, if any (see jQuery removeClass doc)\r
+                       closeBtn.html(this.closeButtonTitle);\r
+                       closeBtn.css({\r
+                               'display':'inline-block','visibility':'visible','marginLeft':'1em'\r
+                               //warning: do NOT use real numbers such as 0.5ex cause browsers round it in a different manner\r
+                               //inline-block in order to retrieve/set width and height on the element\r
+                       });\r
+               }else{\r
+                       closeBtn.css({'margin':'0px'}).hide(); //margin:0 is to be sure, as afterwards we must span the title the whole popup width\r
+               }\r
+               //in any case, show titleElement cause even if title="", titleElement is used to position close on the right\r
+               titleInput.val(this.title).attr('readonly','readonly').attr('class',this.titleClass).removeClass().css({\r
+                 'display':'inline-block',\r
+                 'backgroundColor':'transparent',\r
+                 'padding': '0px', 'margin':'0px','border':'0px',\r
+                 'visibility': this.title ? 'visible' : 'hidden',\r
+                 'width':'',\r
+                 'maxWidth':'1px'      //it is too tricky to set the width of the input spanning the whole title (in case of long titles)\r
+                 //we might use a span, but we experienced problems in vertical align with the close button, as stated somewhere above.\r
+                 //Moreover, a long title messes up the calculations in popup mode:\r
+                 //a long title most likely determines the popup size, the latter the popup position, and once\r
+                 //positioned and sized the popup size determines the title width (in order to span the title or letting the close button be visible)\r
+                 //This is not robust at all and in fact it does not render the same popup position in all browsers.\r
+                 //So, finally, set the input to the minimum allowed width, This means that maxWidth and maxHeight\r
+                 //will be calculated based on the centraldiv dimensions, which is anyway the core div we want to properly visualize.\r
+                 //Moreover, this way title resizing does not interfeere with the position\r
+                });\r
+       }\r
+\r
+        var bottomDiv = $(subdiv[2]);\r
+        var okButton = bottomDiv.find('a').eq(0);\r
+        //see note above about why we dont use okButton.is(':visible')\r
+        if(this.showOk){\r
+            bottomDiv.css({'paddingTop':'1em','textAlign':this.okButtonAlign}).show(); //add padding to bottom\r
+           //warning: do NOT use real numbers such as 0.5ex cause browsers round it in a different manner\r
+                okButton.attr('class', this.okButtonClass); //removes all existing classes, if any\r
+                okButton.html(this.okButtonTitle);\r
+                okButton.css({'display':'inline-block','visibility':'visible'}); //in order to set width and height on the element\r
+        }else{\r
+            bottomDiv.hide();\r
+        }\r
+\r
+        var centralDiv = $(subdiv[1]);\r
+        //reset properties of the central div\r
+        centralDiv.css({\r
+           'overflow':'auto',\r
+            'maxHeight':'',\r
+            'maxWidth':'',\r
+            'minHeight':'',\r
+            'minWidth':'',\r
+            'height':'',\r
+            'width':'',\r
+                       'visibility':'visible'\r
+        }).show();\r
+\r
+               this.setSizable();//this means the popupdiv is display: !none and visibility:hidden, so every element\r
+        //inside it should be visible and therefore sizable. Being visible means that jQuery.is(':visible') returns true\r
+        //start with showing top and bottom if some elements are visible\r
+\r
+        var invoker = this.invoker;\r
+\r
+        var sizeAsPopup = false;\r
+        if(this.isClickElement(invoker)){\r
+            this.setBoundsAsPopup(invoker, true);\r
+            sizeAsPopup = true;\r
+            //storing click events, when showing clicking on an event must give the focus to the popup\r
+            //old handlers will be restored in close()\r
+            this['_tmpHandlers'+this.getId()] = undefined;\r
+            var focusElm = this.getFirstFocusableElement();\r
+            if(focusElm){\r
+                var oldHandlers = [];\r
+                var type = 'click';\r
+                var clickEvents =invoker.data("events")[type];\r
+                $.each(clickEvents, function(key, value) {\r
+                    oldHandlers.push(value);\r
+                })\r
+                invoker.unbind(type); //remove (temporarily) the binding to the event.\r
+                //for instance, if we show the popup by clicking invoker, when the popup is shown do nothing\r
+                //on clicking invoker until popup.hide is called\r
+\r
+                this['_tmpHandlers'+this.getId()] = oldHandlers;\r
+                invoker.unbind(type).bind(type,function(evt){\r
+                    //let the invoker have focus and let it be recognized as an element which does not blur the popup:\r
+                    //invoker.attr('tabindex',0).attr(focusAttr,'true');\r
+                    if(div.length && div.is(':visible')){\r
+                        focusElm.focus();\r
+                        return false;\r
+                    }\r
+                    //something wrong: close the popup and restore the hanlers\r
+                    me.close.apply(me);\r
+                    return false;\r
+                });\r
+            }\r
+\r
+        }else{\r
+            this.setBoundsInside(invoker, this.bounds, this.boundsExact, true);\r
+        }\r
+\r
+       //set title and close button to span whole width, if necessary\r
+       //closeButton.outerWidth should be zero if this.showClose = false\r
+       //titleInput.outerWidth(true) should be equal to titleInput.width(), as margins borders and padding are zero, however we want to calculate it safely\r
+        if(this.showClose || this.title){\r
+            var titleW = topDiv.width() - closeBtn.outerWidth(true) - (titleInput.outerWidth(true)-titleInput.width());\r
+               titleInput.css({'maxWidth':'','width':(titleW)+'px'});\r
+        }\r
+\r
+        //set central div max height ONLY IF NECESSARY (overflow). Until here, the main popup is sized and placed\r
+               //but the central div might overflow\r
+               var height = centralDiv.height();\r
+        var maxHeight = (div.height()-topDiv.outerHeight(true)-bottomDiv.outerHeight(true)-\r
+            (centralDiv.outerHeight(true)-centralDiv.height()));\r
+               if(maxHeight<height){\r
+            centralDiv.css('maxHeight',maxHeight+'px');\r
+        }\r
+               //same for width:\r
+               var maxWidth = div.width();\r
+        var width = centralDiv.outerWidth(true);\r
+        if(maxWidth<width){\r
+            centralDiv.css('maxWidth',maxWidth+'px');\r
+        }\r
+\r
+        // var height = centralDiv.height();\r
+        // if(sizeAsPopup && maxHeight<height){\r
+            // centralDiv.css('maxHeight',maxHeight+'px');\r
+        // }else{\r
+            // centralDiv.css({\r
+                // 'maxHeight': maxHeight+'px',\r
+                // 'minHeight': maxHeight+'px'\r
+            // });\r
+        // }\r
+        // //set central div max width ONLY IF NECESSARY:\r
+        // var maxWidth = div.width();\r
+        // var width = $(subdiv[1]).outerWidth(true);\r
+        // if(sizeAsPopup && maxWidth<width){\r
+            // centralDiv.css('maxWidth',maxWidth+'px');\r
+        // }else{\r
+            // centralDiv.css({\r
+                // 'maxWidth': maxWidth+'px',\r
+                // 'minWidth':maxWidth+'px'\r
+            // });\r
+        // }\r
+\r
+\r
+\r
+        //creating shadow. REmove attributes tabindex (unnecessary) and especially focusAttr,\r
+        //so that clicking tab key and setting the shadow focusable hides the popup. If one wants the shadow not to hide the popup. keep\r
+        //focusAttr BUT insert shadow in the focus cycle root (see method)\r
+        var shadow = div.clone(false,false).empty().css({\r
+            'backgroundColor':'#000',\r
+            'borderColor':'#000',\r
+            'visibility':'visible',\r
+            'zIndex':this.zIndex-1\r
+        }).removeAttr('tabindex').removeAttr(this.getFocusAttr()).fadeTo(0,0).\r
+        attr('id',this.getShadowDivId()) //for use in hide\r
+        .insertAfter(div);\r
+\r
+\r
+        var postShowFcn = function(){\r
+            me.trigger('show');\r
+            var rect = me.getBounds.apply(me);\r
+            shadow.css({\r
+                'left':(rect.x + me.shadowOffset)+'px',\r
+                'top':(rect.y + me.shadowOffset)+'px',\r
+                'width':(rect.width)+'px',\r
+                'height':(rect.height)+'px'\r
+            }).fadeTo(me.fadInTime,me.shadowOpacity, function(){\r
+                var v = me.getFirstFocusableElement();\r
+                if(v){\r
+                    v.focus();\r
+                }\r
+            });\r
+        }\r
+\r
+        div.hide().css('visibility','visible').show(this.fadInTime,function(){\r
+            postShowFcn();\r
+        });\r
+    };\r
+\r
+    p.setBoundsAsPopup = function(popupInvoker, isSizable){\r
+        var invoker = popupInvoker;\r
+        var div = this.getDiv();\r
+        var oldCss= isSizable ?  undefined : this.setSizable();\r
+\r
+       var shadowOffset = this.shadowOffset;\r
+        var windowRectangle = this.getBoundsOf(wdw); //returns the window rectangle\r
+\r
+        var invokerOffset = invoker.offset();\r
+\r
+       var invokerOuterHeight = invoker.outerHeight();\r
+       var spaceAbove = invokerOffset.top - windowRectangle.y;\r
+        var spaceBelow = windowRectangle.height - invokerOuterHeight - spaceAbove;\r
+        var placeAbove = spaceAbove > spaceBelow && div.outerHeight(false) + shadowOffset > spaceBelow;\r
+\r
+       var invokerOuterWidth = invoker.outerWidth();\r
+       var spaceRight = windowRectangle.x + windowRectangle.width - invokerOffset.left ;\r
+        var spaceLeft = invokerOffset.left + invokerOuterWidth - windowRectangle.x;\r
+        var placeLeft = spaceLeft > spaceRight && div.outerWidth(false) + shadowOffset > spaceRight;\r
+\r
+        this.setMaxSize({\r
+            height : (placeAbove ? spaceAbove : spaceBelow),\r
+                       width: (placeLeft ? spaceLeft : spaceRight)\r
+        },isSizable); //width will be ignored (for the moment)\r
+        //decrement of one pixel cause when the popup has to be reduced and the shadows bounds "touch" the window right or bottom sides,\r
+        //the window scrolls (and it shouldn't)\r
+\r
+        //setting the minimum size to the invoker width, minheight the same as maxHeight (see above)\r
+        this.setMinSize({\r
+            width: invoker.outerWidth()+this.shadowOffset //workaround to NOT consider the shadow, as offset below substracts the shadow\r
+        //height : spaceAbove>spaceBelow ? spaceAbove : spaceBelow //why this? because if we click the popup a\r
+        //computed height CH seems to be set. At subsequent popup show, CH will be the same UNLESS a new maxHeight lower than CH is set\r
+        //however, we want CH to change even if a new maxHeight greater than CH is set\r
+        },isSizable);\r
+\r
+        //setting the top and left. This must be done at last because popupDiv.outerHeight(true)\r
+        //must have been computed according to the height set above...\r
+        this.offset({\r
+            'left': placeLeft ? invokerOffset.left+ invokerOuterWidth - div.outerWidth(true)-shadowOffset : invokerOffset.left,\r
+            'top': (placeAbove ? invokerOffset.top -  div.outerHeight(true) :\r
+                invokerOffset.top + invokerOuterHeight)\r
+        },isSizable);\r
+\r
+\r
+        if(oldCss){\r
+            div.css({\r
+                'display':oldCss['display'],\r
+                'visibility':oldCss['visibility']\r
+            });\r
+        }\r
+    };\r
+    //places and resize the popupdiv inside parent\r
+    //padding is a dict {top:,left:,bottom:..,right:,...} measuring the distance of the popupdiv from the corners, so that\r
+    //padding={top:0.25,left:0.25,bottom:0.25,right:0.25} will place the popupdiv at the center of parent\r
+    //padding={top:25,left:25,bottom:25,right:25} will place the popupdiv at distances 25 px from parent sides\r
+    //in other words, padding keys lower or euqals to 1 will be conbsidered as percentage, otherwise as absolute measures in px\r
+    p.setBoundsInside = function(parent, pd, boundsExact, isSizable){\r
+\r
+        var div = this.getDiv();\r
+        var oldCss = isSizable ?  undefined : this.setSizable();\r
+\r
+        var bounds = this.getBoundsOf(parent);\r
+\r
+        var x=bounds.x;\r
+        var y = bounds.y;\r
+        var w = bounds.width\r
+        var h = bounds.height;\r
+        var pInt = parseInt;\r
+        //rebuilding:\r
+\r
+        var padding = {\r
+            top: pd['top'],\r
+            left:pd['left'],\r
+            bottom:pd['bottom'],\r
+            right:pd['right']\r
+        };\r
+\r
+        for(var k in padding){\r
+            if(padding[k]<=0){\r
+                padding[k]=0;\r
+            }else if(padding[k]<=1){\r
+                padding[k] = k=='top' || k =='bottom' ? h*padding[k] : w*padding[k];\r
+            }else{\r
+                padding[k] = pInt(padding[k]);\r
+            }\r
+        }\r
+\r
+        var maxSize = {\r
+            'width':w-padding['left']-padding['right']+this.shadowOffset,\r
+            'height':h-padding['top']-padding['bottom']+this.shadowOffset\r
+        };\r
+\r
+        var vvvv ={\r
+            width:maxSize.width,\r
+            height:maxSize.height\r
+        };\r
+        this._convertSize(div, vvvv);\r
+\r
+        if(boundsExact){\r
+            this.setMinSize({\r
+                width:maxSize.width,\r
+                height:maxSize.height\r
+            },isSizable); //a copy cause the argument will be modified\r
+            this.setMaxSize({\r
+                width:maxSize.width,\r
+                height:maxSize.height\r
+            }, isSizable); //a copy cause the argument will be modified\r
+\r
+            this.offset({\r
+                'left':x + padding['left'],\r
+                'top': y + padding['top']\r
+            },isSizable);\r
+        }else{\r
+            this.setMaxSize({\r
+                width:maxSize.width,\r
+                height:maxSize.height\r
+            },isSizable); //a copy cause the argument will be modified\r
+            var spanLeft = maxSize.width - div.outerWidth(true);\r
+            var spanTop = maxSize.height - div.outerHeight(true);\r
+            this.offset({\r
+                'left':x + padding['left'] + (spanLeft > 0 ? spanLeft/2 : 0),\r
+                'top': y + padding['top'] +(spanTop > 0 ? spanTop/2 : 0)\r
+            },isSizable);\r
+\r
+        }\r
+        //convert to percentage in order to keep same dimensions when zooming\r
+\r
+\r
+        if(oldCss){\r
+            div.css({\r
+                'display':oldCss['display'],\r
+                'visibility':oldCss['visibility']\r
+            });\r
+        }\r
+    };\r
+\r
+    p.getBounds = function(){\r
+        return this.getBoundsOf(this.getDiv());\r
+    };\r
+\r
+    p.getBoundsOf = function(jQueryElement){\r
+        var ret = {\r
+            x:0,\r
+            y:0,\r
+            width:0,\r
+            height:0\r
+        };\r
+        if(!jQueryElement || !(jQueryElement instanceof $)){\r
+            jQueryElement = wdw;\r
+        }\r
+        if(jQueryElement[0] === w_){\r
+            ret.x = jQueryElement.scrollLeft();\r
+            ret.y = jQueryElement.scrollTop();\r
+        }else{\r
+            var offs = jQueryElement.offset();\r
+            ret.x = offs.left;\r
+            ret.y = offs.top;\r
+        }\r
+        ret.width = jQueryElement.width();\r
+        ret.height = jQueryElement.height();\r
+        return ret;\r
+    };\r
+\r
+    p.setMaxSize = function(size, isSizable){\r
+        var div = this.getDiv();\r
+        var oldCss = isSizable ?  undefined : this.setSizable();\r
+\r
+        this._convertSize(div, size);\r
+        var css = {};\r
+        if('width' in size){\r
+            css.maxWidth = size.width+'px';\r
+        }\r
+        if('height' in size){\r
+            css.maxHeight = size.height+'px';\r
+        }\r
+        if(css){\r
+            div.css(css);\r
+        }\r
+        if(oldCss){\r
+            div.css({\r
+                'display':oldCss['display'],\r
+                'visibility':oldCss['visibility'],\r
+                'top':oldCss['top'],\r
+                'left':oldCss['left']\r
+            });\r
+        }\r
+        return size;\r
+    };\r
+    p.setMinSize = function(size, isSizable){\r
+        var div = this.getDiv();\r
+        var oldCss= isSizable ?  undefined : this.setSizable();\r
+\r
+        this._convertSize(div, size);\r
+        var css = {};\r
+        if('width' in size){\r
+            css.minWidth = size.width+'px';\r
+        }\r
+        if('height' in size){\r
+            css.minHeight = size.height+'px';\r
+        }\r
+        if(css){\r
+            div.css(css);\r
+        }\r
+        if(oldCss){\r
+            div.css({\r
+                'display':oldCss['display'],\r
+                'visibility':oldCss['visibility'],\r
+                'top':oldCss['top'],\r
+                'left':oldCss['left']\r
+            });\r
+        }\r
+        return size;\r
+    };\r
+    //div must be display!=hidden. size is a dict with at least one of the fields 'width' and 'height'\r
+    p._convertSize = function(div, size){\r
+        var eD = {\r
+            'width': div.outerWidth(true)-div.width(),\r
+            'height':div.outerHeight(true)-div.height()\r
+        };\r
+\r
+        if('width' in size){\r
+            size.width -= (eD.width + this.shadowOffset);\r
+        }\r
+        if('height' in size){\r
+            size.height -= (eD.height + this.shadowOffset);\r
+        }\r
+    };\r
+\r
+    p.offset = function(offs, isSizable){\r
+        var div = this.getDiv();\r
+        var oldCss= isSizable?  undefined : this.setSizable();\r
+        //offset does NOT consider margins. Do we have top and left?\r
+\r
+        this.getDiv().offset(offs);\r
+        if(oldCss){\r
+            div.css({\r
+                'display':oldCss['display'],\r
+                'visibility':oldCss['visibility'],\r
+                'maxWidth':oldCss['maxWidth'],\r
+                'maxHeight':oldCss['maxHeight'],\r
+                'minWidth':oldCss['minWidth'],\r
+                'minHeight':oldCss['minHeight']\r
+            });\r
+        }\r
+    };\r
+\r
+    p.isClosing = false;\r
+    p.close = function(){\r
+        this.isClosing = true;\r
+        this.setFocusCycleRoot(false);\r
+        var div = this.getDiv();\r
+        var shadow = $('#'+this.getShadowDivId());\r
+        shadow.remove();\r
+        var me = this;\r
+        var remove = this.defaultCloseOperation == 'remove';\r
+        div.hide(this.fadeOutTime, function(){\r
+\r
+            if(remove){\r
+                div.remove();\r
+            //this is because all bindings will be removed, including blur events\r
+            //we remove this.getFocusAttr() to reupdate focus cycle root when calling show again\r
+            }\r
+\r
+            //restore event data on invoker, if any\r
+            var id = '_tmpHandlers'+me.getId();\r
+            if(me[id]){\r
+                var oldHandlers = me[id];\r
+                delete  me[id];\r
+                me.invoker.unbind('click');\r
+                for(var k =0; k< oldHandlers.length; k++){\r
+                    var h = oldHandlers[k];\r
+                    me.invoker.bind(h.type+(h.namespace ? "."+h.namespace : ""),h.handler);\r
+                }\r
+            }\r
+\r
+            me.isClosing = false;\r
+            me.trigger('close');\r
+        });\r
+\r
+    };\r
+\r
+\r
+    p.setSizable = function(){\r
+        //if false, just update the flag\r
+        var div = this.getDiv();\r
+\r
+        if(!div.parent().length){\r
+            div.appendTo('body');\r
+        }\r
+        var keys = ['display','visibility','left','top','maxWidth','maxHeight','minWidth','minHeight'];\r
+        var css = {};\r
+        for(var i=0; i<keys.length; i++){\r
+            css[keys[i]] = div.css(keys[i]);\r
+        }\r
+        div.offset({\r
+            'left':wdw.scrollLeft(),\r
+            'top':wdw.scrollTop()\r
+        });\r
+        //set the div invisible but displayable to calculate the size (callbackPreShow)\r
+        div.css({\r
+            'visibility':'hidden',\r
+            'maxWidth':'',\r
+            'maxHeight':'',\r
+            'minWidth':'',\r
+            'minHeight':'',\r
+            'height':'',\r
+            'width':''\r
+        }).show();\r
+\r
+\r
+        return css;\r
+    }\r
+    p.getShadowDivId = function(){\r
+        return this.getId()+"_shadow";\r
+    }\r
+\r
+    p.getFocusAttr = function(){\r
+        return this.getId()+"_focus";\r
+    }\r
+\r
+\r
+})(PopupDiv.prototype);\r
index 02518783d927ac87282bfa5a9216aad672d8b6b4..61736eeee7552d757db1c9433a9d2551ae395b3a 100644 (file)
@@ -45,7 +45,7 @@ var playlistUtils = {
         new PopupDiv({
             'content':dd,
             invoker:anchorElement,
-            showok:true,
+            showOk:true,
             onOk:function(data){
                 if(!data[t] && !data[d]){
                     return;
index 53b0a95e0f4b6606d1c88bc9180b06ff575658e3..a70724c7a2c24770801883785379ab36501b4d87 100644 (file)
@@ -3,6 +3,7 @@
 {% load i18n %}
 
 {% block extra_javascript %}
+<script src="{% url telemeta-js "popupdiv.js" %}" type="text/javascript"></script>
 <script src="{% url telemeta-timeside "src/playlist.js" %}" type="text/javascript"></script>
 <script>
     jQuery(window).ready(function(){
index 23c303e1e92a8a0daff58c02e28e2762ccd57524..bca786ba29e60dcd473b04d3be2953d23e280a34 100644 (file)
@@ -16,6 +16,7 @@
 
       <!--<script src="{% url telemeta-js "wz_jsgraphics.js" %}" type="text/javascript"></script>-->
 <script src="{% url telemeta-js "soundmanager2.js" %}" type="text/javascript"></script>
+<script src="{% url telemeta-js "popupdiv.js" %}" type="text/javascript"></script>
 <script src="{% url telemeta-timeside "src/playlist.js" %}" type="text/javascript"></script>
 <script type="text/javascript">
     soundManager.url = '{% url telemeta-swf "./" %}';