//////////////////////////////////////////////////////////////////////////////// // Constants //////////////////////////////////////////////////////////////////////////////// var __CFPOPUP_ERROR_HIDDEN = "popup is already hidden"; var __CFPOPUP_ERROR_ID = "invalid CFPopup id"; var __CFPOPUP_ERROR_VISIBLE = "popup is already visible"; var __CFPOPUP_WARNING_REFRESH = "windowed element hiding is disabled"; var __CFPOPUP_HIDE_TIME = 0; var __CFPOPUP_SHOW_TIME = 0; var __CFPOPUP_WINDOWED_TAGS = []; //////////////////////////////////////////////////////////////////////////////// // Static Variables //////////////////////////////////////////////////////////////////////////////// var __cfPopupHiddenElements = new Array(); var __cfPopupMap = {}; //////////////////////////////////////////////////////////////////////////////// // Classes //////////////////////////////////////////////////////////////////////////////// function CFPopup(id) { CFWidget.call(this, id); this.__bottomPosition = undefined; this.__hideTimer = undefined; this.__leftPosition = 0; this.__rightPosition = undefined; this.__showTimer = undefined; this.__topPosition = 0; this.__hideStyle(); __cfPopupMap[id] = this; var f = cfEventHandlerCreate(this.__hide.bind(this)); this.__hideEvent = f; f = cfEventHandlerCreate(this.__show.bind(this)); this.__showEvent = f; } CFPopup.extendClasses(CFWidget); CFPopup.prototype.__clearHideTimer = function() { var timer = this.__hideTimer; if (timer) { window.clearTimeout(timer); this.__hideTimer = undefined; } } CFPopup.prototype.__clearShowTimer = function() { var timer = this.__showTimer; if (timer) { window.clearTimeout(timer); this.__showTimer = undefined; } } CFPopup.prototype.__hide = function() { this.__clearHideTimer(); this.__hideStyle(); this.refresh(); this.__triggerEvent(CFWIDGET_EVENT_HIDE); __cfPopupRefreshHiddenElements(); } CFPopup.prototype.__hideStyle = function() { var style = this.getElement().style; style.display = "none"; style.bottom = ''; style.left = ''; style.right = ''; style.top = ''; this.__visible = false; } CFPopup.prototype.__setPosition = function(bottom, left, right, top) { this.__bottomPosition = bottom; this.__leftPosition = left; this.__rightPosition = right; this.__topPosition = top; if (this.isVisible()) { var style = this.getElement().style; style.bottom = (typeof(bottom) == "undefined") ? '' : bottom + "px"; style.left = (typeof(left) == "undefined") ? '' : left + "px"; style.right = (typeof(right) == "undefined") ? '' : right + "px"; style.top = (typeof(top) == "undefined") ? '' : top + "px"; __cfPopupRefreshHiddenElements(); } } CFPopup.prototype.__show = function() { this.__clearShowTimer(); var style = this.getElement().style; var bottom = this.__bottomPosition; style.bottom = (typeof(bottom) == "undefined") ? '' : bottom + "px"; var left = this.__leftPosition; style.left = (typeof(left) == "undefined") ? '' : left + "px"; var right = this.__rightPosition; style.right = (typeof(right) == "undefined") ? '' : right + "px"; var top = this.__topPosition; style.top = (typeof(top) == "undefined") ? '' : top + "px"; style.display = "block"; this.__visible = true; this.refresh(); this.__triggerEvent(CFWIDGET_EVENT_SHOW); __cfPopupRefreshHiddenElements(); } CFPopup.prototype.getHideTime = function() { return __CFPOPUP_HIDE_TIME; } CFPopup.prototype.getShowTime = function() { return __CFPOPUP_SHOW_TIME; } CFPopup.prototype.hide = function() { this.__clearShowTimer(); if (this.isVisible() && (typeof(this.__hideTimer) == "undefined")) { this.__hideTimer = window.setTimeout(this.__hideEvent, this.getHideTime()); } } CFPopup.prototype.isVisible = function() { return this.__visible; } CFPopup.prototype.setBottomLeftPosition = function(bottom, left) { this.__setPosition(bottom, left, undefined, undefined); } CFPopup.prototype.setBottomRightPosition = function(bottom, right) { this.__setPosition(bottom, undefined, right, undefined); } CFPopup.prototype.setTopLeftPosition = function(top, left) { this.__setPosition(undefined, left, undefined, top); } CFPopup.prototype.setTopRightPosition = function(top, right) { this.__setPosition(undefined, undefined, right, top); } CFPopup.prototype.show = function() { this.__clearHideTimer(); if ((! this.isVisible()) && (typeof(this.__showTimer) == "undefined")) { this.__showTimer = window.setTimeout(this.__showEvent, this.getShowTime()); } } //////////////////////////////////////////////////////////////////////////////// // Private functions //////////////////////////////////////////////////////////////////////////////// function __cfPopupRefreshHiddenElementsDisabled() { // Nothing to do. } function __cfPopupRefreshHiddenElementsEnabled() { var candidateElements = new Array(); for (var i = 0; i < __CFPOPUP_WINDOWED_TAGS.length; i++) { var tag = __CFPOPUP_WINDOWED_TAGS[i]; var tagElements = document.getElementsByTagName(tag); for (var j = 0; j < tagElements.length; j++) { candidateElements.push(tagElements[j]); } } var newHiddenElements = new Array(); var oldHiddenElements = __cfPopupHiddenElements; for (var id in __cfPopupMap) { var win = __cfPopupMap[id]; if (! win.isVisible()) { continue; } var windowElement = win.getElement(); var elements = cfElementIntersectsElements(windowElement, candidateElements); for (var i = 0; i < elements.length; i++) { var element = elements[i]; if (cfElementHasDescendant(windowElement, element)) { continue; } if (! newHiddenElements.contains(element)) { newHiddenElements.push(element); } } } for (var i = 0; i < newHiddenElements.length; i++) { var element = newHiddenElements[i]; if (! oldHiddenElements.contains(element)) { cfElementAddClass(element, CFELEMENT_INVISIBLE_CLASS); } } for (var i = 0; i < oldHiddenElements.length; i++) { var element = oldHiddenElements[i]; if (! newHiddenElements.contains(element)) { cfElementRemoveClass(element, CFELEMENT_INVISIBLE_CLASS); } } __cfPopupHiddenElements = newHiddenElements; } //////////////////////////////////////////////////////////////////////////////// // Public API //////////////////////////////////////////////////////////////////////////////// function cfPopupGet(id) { var popup = __cfPopupMap[id]; if (! popup) { return cfErrorTrigger("cfPopupGet: '" + id + "': " + __CFPOPUP_ERROR_ID); } return popup; } //////////////////////////////////////////////////////////////////////////////// // Initialization //////////////////////////////////////////////////////////////////////////////// // Windowed components are browser-dependent. Here's a list of windowed // components discovered thus far: applet, button (?), embed, iframe, input, // isindex, object, select, textarea var browserOS = cfBrowserGetOS(); var browserVersion = cfBrowserGetVersion(); switch (cfBrowserGetName()) { case CFBROWSER_EXPLORER: if (browserVersion < 7) { __CFPOPUP_WINDOWED_TAGS.push("select"); if (browserVersion < 5.5) { __CFPOPUP_WINDOWED_TAGS.push("iframe"); } } break; case CFBROWSER_NETSCAPE: if (browserVersion < 7) { __CFPOPUP_WINDOWED_TAGS.extend(["iframe", "select"]); if (browserVersion < 6) { __CFPOPUP_WINDOWED_TAGS.extend(["input", "isindex", "textarea"]); } } break; case CFBROWSER_OPERA: // XX: The browser version is a guess. Check this later. __CFPOPUP_WINDOWED_TAGS.push("iframe"); if (browserVersion < 8.5) { __CFPOPUP_WINDOWED_TAGS.extend(["input", "isindex", "select", "textarea"]); } break; // Webkit-based browsers case CFBROWSER_OMNIWEB: case CFBROWSER_SAFARI: break; // Gecko-based browsers case CFBROWSER_CAMINO: case CFBROWSER_FIREFOX: case CFBROWSER_MOZILLA: case CFBROWSER_ICAB: case CFBROWSER_KONQUEROR: default: // Nothing to do. } var __cfPopupRefreshHiddenElements; if (! __CFPOPUP_WINDOWED_TAGS.length) { __cfPopupRefreshHiddenElements = __cfPopupRefreshHiddenElementsDisabled; } else if (document.getElementsByTagName) { __cfPopupRefreshHiddenElements = __cfPopupRefreshHiddenElementsEnabled; } else { cfWarningTrigger("[popup]: " + __CFPOPUP_WARNING_REFRESH); __cfPopupRefreshHiddenElements = __cfPopupRefreshHiddenElementsDisabled; }