X-Git-Url: https://git.toastfreeware.priv.at/philipp/winterrodeln/wradmin.git/blobdiff_plain/c2d2b07d134a64271aede4886b8c1d0f6960cb4d..582150b643140e3e670d66f244812e314c7aa0c1:/wradmin/static/yui/container/container.js diff --git a/wradmin/static/yui/container/container.js b/wradmin/static/yui/container/container.js new file mode 100644 index 0000000..620e954 --- /dev/null +++ b/wradmin/static/yui/container/container.js @@ -0,0 +1,9064 @@ +/* +Copyright (c) 2009, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.net/yui/license.txt +version: 2.7.0 +*/ +(function () { + + /** + * Config is a utility used within an Object to allow the implementer to + * maintain a list of local configuration properties and listen for changes + * to those properties dynamically using CustomEvent. The initial values are + * also maintained so that the configuration can be reset at any given point + * to its initial state. + * @namespace YAHOO.util + * @class Config + * @constructor + * @param {Object} owner The owner Object to which this Config Object belongs + */ + YAHOO.util.Config = function (owner) { + + if (owner) { + this.init(owner); + } + + + }; + + + var Lang = YAHOO.lang, + CustomEvent = YAHOO.util.CustomEvent, + Config = YAHOO.util.Config; + + + /** + * Constant representing the CustomEvent type for the config changed event. + * @property YAHOO.util.Config.CONFIG_CHANGED_EVENT + * @private + * @static + * @final + */ + Config.CONFIG_CHANGED_EVENT = "configChanged"; + + /** + * Constant representing the boolean type string + * @property YAHOO.util.Config.BOOLEAN_TYPE + * @private + * @static + * @final + */ + Config.BOOLEAN_TYPE = "boolean"; + + Config.prototype = { + + /** + * Object reference to the owner of this Config Object + * @property owner + * @type Object + */ + owner: null, + + /** + * Boolean flag that specifies whether a queue is currently + * being executed + * @property queueInProgress + * @type Boolean + */ + queueInProgress: false, + + /** + * Maintains the local collection of configuration property objects and + * their specified values + * @property config + * @private + * @type Object + */ + config: null, + + /** + * Maintains the local collection of configuration property objects as + * they were initially applied. + * This object is used when resetting a property. + * @property initialConfig + * @private + * @type Object + */ + initialConfig: null, + + /** + * Maintains the local, normalized CustomEvent queue + * @property eventQueue + * @private + * @type Object + */ + eventQueue: null, + + /** + * Custom Event, notifying subscribers when Config properties are set + * (setProperty is called without the silent flag + * @event configChangedEvent + */ + configChangedEvent: null, + + /** + * Initializes the configuration Object and all of its local members. + * @method init + * @param {Object} owner The owner Object to which this Config + * Object belongs + */ + init: function (owner) { + + this.owner = owner; + + this.configChangedEvent = + this.createEvent(Config.CONFIG_CHANGED_EVENT); + + this.configChangedEvent.signature = CustomEvent.LIST; + this.queueInProgress = false; + this.config = {}; + this.initialConfig = {}; + this.eventQueue = []; + + }, + + /** + * Validates that the value passed in is a Boolean. + * @method checkBoolean + * @param {Object} val The value to validate + * @return {Boolean} true, if the value is valid + */ + checkBoolean: function (val) { + return (typeof val == Config.BOOLEAN_TYPE); + }, + + /** + * Validates that the value passed in is a number. + * @method checkNumber + * @param {Object} val The value to validate + * @return {Boolean} true, if the value is valid + */ + checkNumber: function (val) { + return (!isNaN(val)); + }, + + /** + * Fires a configuration property event using the specified value. + * @method fireEvent + * @private + * @param {String} key The configuration property's name + * @param {value} Object The value of the correct type for the property + */ + fireEvent: function ( key, value ) { + var property = this.config[key]; + + if (property && property.event) { + property.event.fire(value); + } + }, + + /** + * Adds a property to the Config Object's private config hash. + * @method addProperty + * @param {String} key The configuration property's name + * @param {Object} propertyObject The Object containing all of this + * property's arguments + */ + addProperty: function ( key, propertyObject ) { + key = key.toLowerCase(); + + this.config[key] = propertyObject; + + propertyObject.event = this.createEvent(key, { scope: this.owner }); + propertyObject.event.signature = CustomEvent.LIST; + + + propertyObject.key = key; + + if (propertyObject.handler) { + propertyObject.event.subscribe(propertyObject.handler, + this.owner); + } + + this.setProperty(key, propertyObject.value, true); + + if (! propertyObject.suppressEvent) { + this.queueProperty(key, propertyObject.value); + } + + }, + + /** + * Returns a key-value configuration map of the values currently set in + * the Config Object. + * @method getConfig + * @return {Object} The current config, represented in a key-value map + */ + getConfig: function () { + + var cfg = {}, + currCfg = this.config, + prop, + property; + + for (prop in currCfg) { + if (Lang.hasOwnProperty(currCfg, prop)) { + property = currCfg[prop]; + if (property && property.event) { + cfg[prop] = property.value; + } + } + } + + return cfg; + }, + + /** + * Returns the value of specified property. + * @method getProperty + * @param {String} key The name of the property + * @return {Object} The value of the specified property + */ + getProperty: function (key) { + var property = this.config[key.toLowerCase()]; + if (property && property.event) { + return property.value; + } else { + return undefined; + } + }, + + /** + * Resets the specified property's value to its initial value. + * @method resetProperty + * @param {String} key The name of the property + * @return {Boolean} True is the property was reset, false if not + */ + resetProperty: function (key) { + + key = key.toLowerCase(); + + var property = this.config[key]; + + if (property && property.event) { + + if (this.initialConfig[key] && + !Lang.isUndefined(this.initialConfig[key])) { + + this.setProperty(key, this.initialConfig[key]); + + return true; + + } + + } else { + + return false; + } + + }, + + /** + * Sets the value of a property. If the silent property is passed as + * true, the property's event will not be fired. + * @method setProperty + * @param {String} key The name of the property + * @param {String} value The value to set the property to + * @param {Boolean} silent Whether the value should be set silently, + * without firing the property event. + * @return {Boolean} True, if the set was successful, false if it failed. + */ + setProperty: function (key, value, silent) { + + var property; + + key = key.toLowerCase(); + + if (this.queueInProgress && ! silent) { + // Currently running through a queue... + this.queueProperty(key,value); + return true; + + } else { + property = this.config[key]; + if (property && property.event) { + if (property.validator && !property.validator(value)) { + return false; + } else { + property.value = value; + if (! silent) { + this.fireEvent(key, value); + this.configChangedEvent.fire([key, value]); + } + return true; + } + } else { + return false; + } + } + }, + + /** + * Sets the value of a property and queues its event to execute. If the + * event is already scheduled to execute, it is + * moved from its current position to the end of the queue. + * @method queueProperty + * @param {String} key The name of the property + * @param {String} value The value to set the property to + * @return {Boolean} true, if the set was successful, false if + * it failed. + */ + queueProperty: function (key, value) { + + key = key.toLowerCase(); + + var property = this.config[key], + foundDuplicate = false, + iLen, + queueItem, + queueItemKey, + queueItemValue, + sLen, + supercedesCheck, + qLen, + queueItemCheck, + queueItemCheckKey, + queueItemCheckValue, + i, + s, + q; + + if (property && property.event) { + + if (!Lang.isUndefined(value) && property.validator && + !property.validator(value)) { // validator + return false; + } else { + + if (!Lang.isUndefined(value)) { + property.value = value; + } else { + value = property.value; + } + + foundDuplicate = false; + iLen = this.eventQueue.length; + + for (i = 0; i < iLen; i++) { + queueItem = this.eventQueue[i]; + + if (queueItem) { + queueItemKey = queueItem[0]; + queueItemValue = queueItem[1]; + + if (queueItemKey == key) { + + /* + found a dupe... push to end of queue, null + current item, and break + */ + + this.eventQueue[i] = null; + + this.eventQueue.push( + [key, (!Lang.isUndefined(value) ? + value : queueItemValue)]); + + foundDuplicate = true; + break; + } + } + } + + // this is a refire, or a new property in the queue + + if (! foundDuplicate && !Lang.isUndefined(value)) { + this.eventQueue.push([key, value]); + } + } + + if (property.supercedes) { + + sLen = property.supercedes.length; + + for (s = 0; s < sLen; s++) { + + supercedesCheck = property.supercedes[s]; + qLen = this.eventQueue.length; + + for (q = 0; q < qLen; q++) { + queueItemCheck = this.eventQueue[q]; + + if (queueItemCheck) { + queueItemCheckKey = queueItemCheck[0]; + queueItemCheckValue = queueItemCheck[1]; + + if (queueItemCheckKey == + supercedesCheck.toLowerCase() ) { + + this.eventQueue.push([queueItemCheckKey, + queueItemCheckValue]); + + this.eventQueue[q] = null; + break; + + } + } + } + } + } + + + return true; + } else { + return false; + } + }, + + /** + * Fires the event for a property using the property's current value. + * @method refireEvent + * @param {String} key The name of the property + */ + refireEvent: function (key) { + + key = key.toLowerCase(); + + var property = this.config[key]; + + if (property && property.event && + + !Lang.isUndefined(property.value)) { + + if (this.queueInProgress) { + + this.queueProperty(key); + + } else { + + this.fireEvent(key, property.value); + + } + + } + }, + + /** + * Applies a key-value Object literal to the configuration, replacing + * any existing values, and queueing the property events. + * Although the values will be set, fireQueue() must be called for their + * associated events to execute. + * @method applyConfig + * @param {Object} userConfig The configuration Object literal + * @param {Boolean} init When set to true, the initialConfig will + * be set to the userConfig passed in, so that calling a reset will + * reset the properties to the passed values. + */ + applyConfig: function (userConfig, init) { + + var sKey, + oConfig; + + if (init) { + oConfig = {}; + for (sKey in userConfig) { + if (Lang.hasOwnProperty(userConfig, sKey)) { + oConfig[sKey.toLowerCase()] = userConfig[sKey]; + } + } + this.initialConfig = oConfig; + } + + for (sKey in userConfig) { + if (Lang.hasOwnProperty(userConfig, sKey)) { + this.queueProperty(sKey, userConfig[sKey]); + } + } + }, + + /** + * Refires the events for all configuration properties using their + * current values. + * @method refresh + */ + refresh: function () { + + var prop; + + for (prop in this.config) { + if (Lang.hasOwnProperty(this.config, prop)) { + this.refireEvent(prop); + } + } + }, + + /** + * Fires the normalized list of queued property change events + * @method fireQueue + */ + fireQueue: function () { + + var i, + queueItem, + key, + value, + property; + + this.queueInProgress = true; + for (i = 0;i < this.eventQueue.length; i++) { + queueItem = this.eventQueue[i]; + if (queueItem) { + + key = queueItem[0]; + value = queueItem[1]; + property = this.config[key]; + + property.value = value; + + // Clear out queue entry, to avoid it being + // re-added to the queue by any queueProperty/supercedes + // calls which are invoked during fireEvent + this.eventQueue[i] = null; + + this.fireEvent(key,value); + } + } + + this.queueInProgress = false; + this.eventQueue = []; + }, + + /** + * Subscribes an external handler to the change event for any + * given property. + * @method subscribeToConfigEvent + * @param {String} key The property name + * @param {Function} handler The handler function to use subscribe to + * the property's event + * @param {Object} obj The Object to use for scoping the event handler + * (see CustomEvent documentation) + * @param {Boolean} override Optional. If true, will override "this" + * within the handler to map to the scope Object passed into the method. + * @return {Boolean} True, if the subscription was successful, + * otherwise false. + */ + subscribeToConfigEvent: function (key, handler, obj, override) { + + var property = this.config[key.toLowerCase()]; + + if (property && property.event) { + if (!Config.alreadySubscribed(property.event, handler, obj)) { + property.event.subscribe(handler, obj, override); + } + return true; + } else { + return false; + } + + }, + + /** + * Unsubscribes an external handler from the change event for any + * given property. + * @method unsubscribeFromConfigEvent + * @param {String} key The property name + * @param {Function} handler The handler function to use subscribe to + * the property's event + * @param {Object} obj The Object to use for scoping the event + * handler (see CustomEvent documentation) + * @return {Boolean} True, if the unsubscription was successful, + * otherwise false. + */ + unsubscribeFromConfigEvent: function (key, handler, obj) { + var property = this.config[key.toLowerCase()]; + if (property && property.event) { + return property.event.unsubscribe(handler, obj); + } else { + return false; + } + }, + + /** + * Returns a string representation of the Config object + * @method toString + * @return {String} The Config object in string format. + */ + toString: function () { + var output = "Config"; + if (this.owner) { + output += " [" + this.owner.toString() + "]"; + } + return output; + }, + + /** + * Returns a string representation of the Config object's current + * CustomEvent queue + * @method outputEventQueue + * @return {String} The string list of CustomEvents currently queued + * for execution + */ + outputEventQueue: function () { + + var output = "", + queueItem, + q, + nQueue = this.eventQueue.length; + + for (q = 0; q < nQueue; q++) { + queueItem = this.eventQueue[q]; + if (queueItem) { + output += queueItem[0] + "=" + queueItem[1] + ", "; + } + } + return output; + }, + + /** + * Sets all properties to null, unsubscribes all listeners from each + * property's change event and all listeners from the configChangedEvent. + * @method destroy + */ + destroy: function () { + + var oConfig = this.config, + sProperty, + oProperty; + + + for (sProperty in oConfig) { + + if (Lang.hasOwnProperty(oConfig, sProperty)) { + + oProperty = oConfig[sProperty]; + + oProperty.event.unsubscribeAll(); + oProperty.event = null; + + } + + } + + this.configChangedEvent.unsubscribeAll(); + + this.configChangedEvent = null; + this.owner = null; + this.config = null; + this.initialConfig = null; + this.eventQueue = null; + + } + + }; + + + + /** + * Checks to determine if a particular function/Object pair are already + * subscribed to the specified CustomEvent + * @method YAHOO.util.Config.alreadySubscribed + * @static + * @param {YAHOO.util.CustomEvent} evt The CustomEvent for which to check + * the subscriptions + * @param {Function} fn The function to look for in the subscribers list + * @param {Object} obj The execution scope Object for the subscription + * @return {Boolean} true, if the function/Object pair is already subscribed + * to the CustomEvent passed in + */ + Config.alreadySubscribed = function (evt, fn, obj) { + + var nSubscribers = evt.subscribers.length, + subsc, + i; + + if (nSubscribers > 0) { + i = nSubscribers - 1; + do { + subsc = evt.subscribers[i]; + if (subsc && subsc.obj == obj && subsc.fn == fn) { + return true; + } + } + while (i--); + } + + return false; + + }; + + YAHOO.lang.augmentProto(Config, YAHOO.util.EventProvider); + +}()); + +(function () { + + /** + * The Container family of components is designed to enable developers to + * create different kinds of content-containing modules on the web. Module + * and Overlay are the most basic containers, and they can be used directly + * or extended to build custom containers. Also part of the Container family + * are four UI controls that extend Module and Overlay: Tooltip, Panel, + * Dialog, and SimpleDialog. + * @module container + * @title Container + * @requires yahoo, dom, event + * @optional dragdrop, animation, button + */ + + /** + * Module is a JavaScript representation of the Standard Module Format. + * Standard Module Format is a simple standard for markup containers where + * child nodes representing the header, body, and footer of the content are + * denoted using the CSS classes "hd", "bd", and "ft" respectively. + * Module is the base class for all other classes in the YUI + * Container package. + * @namespace YAHOO.widget + * @class Module + * @constructor + * @param {String} el The element ID representing the Module OR + * @param {HTMLElement} el The element representing the Module + * @param {Object} userConfig The configuration Object literal containing + * the configuration that should be set for this module. See configuration + * documentation for more details. + */ + YAHOO.widget.Module = function (el, userConfig) { + if (el) { + this.init(el, userConfig); + } else { + } + }; + + var Dom = YAHOO.util.Dom, + Config = YAHOO.util.Config, + Event = YAHOO.util.Event, + CustomEvent = YAHOO.util.CustomEvent, + Module = YAHOO.widget.Module, + UA = YAHOO.env.ua, + + m_oModuleTemplate, + m_oHeaderTemplate, + m_oBodyTemplate, + m_oFooterTemplate, + + /** + * Constant representing the name of the Module's events + * @property EVENT_TYPES + * @private + * @final + * @type Object + */ + EVENT_TYPES = { + "BEFORE_INIT": "beforeInit", + "INIT": "init", + "APPEND": "append", + "BEFORE_RENDER": "beforeRender", + "RENDER": "render", + "CHANGE_HEADER": "changeHeader", + "CHANGE_BODY": "changeBody", + "CHANGE_FOOTER": "changeFooter", + "CHANGE_CONTENT": "changeContent", + "DESTORY": "destroy", + "BEFORE_SHOW": "beforeShow", + "SHOW": "show", + "BEFORE_HIDE": "beforeHide", + "HIDE": "hide" + }, + + /** + * Constant representing the Module's configuration properties + * @property DEFAULT_CONFIG + * @private + * @final + * @type Object + */ + DEFAULT_CONFIG = { + + "VISIBLE": { + key: "visible", + value: true, + validator: YAHOO.lang.isBoolean + }, + + "EFFECT": { + key: "effect", + suppressEvent: true, + supercedes: ["visible"] + }, + + "MONITOR_RESIZE": { + key: "monitorresize", + value: true + }, + + "APPEND_TO_DOCUMENT_BODY": { + key: "appendtodocumentbody", + value: false + } + }; + + /** + * Constant representing the prefix path to use for non-secure images + * @property YAHOO.widget.Module.IMG_ROOT + * @static + * @final + * @type String + */ + Module.IMG_ROOT = null; + + /** + * Constant representing the prefix path to use for securely served images + * @property YAHOO.widget.Module.IMG_ROOT_SSL + * @static + * @final + * @type String + */ + Module.IMG_ROOT_SSL = null; + + /** + * Constant for the default CSS class name that represents a Module + * @property YAHOO.widget.Module.CSS_MODULE + * @static + * @final + * @type String + */ + Module.CSS_MODULE = "yui-module"; + + /** + * Constant representing the module header + * @property YAHOO.widget.Module.CSS_HEADER + * @static + * @final + * @type String + */ + Module.CSS_HEADER = "hd"; + + /** + * Constant representing the module body + * @property YAHOO.widget.Module.CSS_BODY + * @static + * @final + * @type String + */ + Module.CSS_BODY = "bd"; + + /** + * Constant representing the module footer + * @property YAHOO.widget.Module.CSS_FOOTER + * @static + * @final + * @type String + */ + Module.CSS_FOOTER = "ft"; + + /** + * Constant representing the url for the "src" attribute of the iframe + * used to monitor changes to the browser's base font size + * @property YAHOO.widget.Module.RESIZE_MONITOR_SECURE_URL + * @static + * @final + * @type String + */ + Module.RESIZE_MONITOR_SECURE_URL = "javascript:false;"; + + /** + * Constant representing the buffer amount (in pixels) to use when positioning + * the text resize monitor offscreen. The resize monitor is positioned + * offscreen by an amount eqaul to its offsetHeight + the buffer value. + * + * @property YAHOO.widget.Module.RESIZE_MONITOR_BUFFER + * @static + * @type Number + */ + // Set to 1, to work around pixel offset in IE8, which increases when zoom is used + Module.RESIZE_MONITOR_BUFFER = 1; + + /** + * Singleton CustomEvent fired when the font size is changed in the browser. + * Opera's "zoom" functionality currently does not support text + * size detection. + * @event YAHOO.widget.Module.textResizeEvent + */ + Module.textResizeEvent = new CustomEvent("textResize"); + + /** + * Helper utility method, which forces a document level + * redraw for Opera, which can help remove repaint + * irregularities after applying DOM changes. + * + * @method YAHOO.widget.Module.forceDocumentRedraw + * @static + */ + Module.forceDocumentRedraw = function() { + var docEl = document.documentElement; + if (docEl) { + docEl.className += " "; + docEl.className = YAHOO.lang.trim(docEl.className); + } + }; + + function createModuleTemplate() { + + if (!m_oModuleTemplate) { + m_oModuleTemplate = document.createElement("div"); + + m_oModuleTemplate.innerHTML = ("
" + "
"); + + m_oHeaderTemplate = m_oModuleTemplate.firstChild; + m_oBodyTemplate = m_oHeaderTemplate.nextSibling; + m_oFooterTemplate = m_oBodyTemplate.nextSibling; + } + + return m_oModuleTemplate; + } + + function createHeader() { + if (!m_oHeaderTemplate) { + createModuleTemplate(); + } + return (m_oHeaderTemplate.cloneNode(false)); + } + + function createBody() { + if (!m_oBodyTemplate) { + createModuleTemplate(); + } + return (m_oBodyTemplate.cloneNode(false)); + } + + function createFooter() { + if (!m_oFooterTemplate) { + createModuleTemplate(); + } + return (m_oFooterTemplate.cloneNode(false)); + } + + Module.prototype = { + + /** + * The class's constructor function + * @property contructor + * @type Function + */ + constructor: Module, + + /** + * The main module element that contains the header, body, and footer + * @property element + * @type HTMLElement + */ + element: null, + + /** + * The header element, denoted with CSS class "hd" + * @property header + * @type HTMLElement + */ + header: null, + + /** + * The body element, denoted with CSS class "bd" + * @property body + * @type HTMLElement + */ + body: null, + + /** + * The footer element, denoted with CSS class "ft" + * @property footer + * @type HTMLElement + */ + footer: null, + + /** + * The id of the element + * @property id + * @type String + */ + id: null, + + /** + * A string representing the root path for all images created by + * a Module instance. + * @deprecated It is recommend that any images for a Module be applied + * via CSS using the "background-image" property. + * @property imageRoot + * @type String + */ + imageRoot: Module.IMG_ROOT, + + /** + * Initializes the custom events for Module which are fired + * automatically at appropriate times by the Module class. + * @method initEvents + */ + initEvents: function () { + + var SIGNATURE = CustomEvent.LIST; + + /** + * CustomEvent fired prior to class initalization. + * @event beforeInitEvent + * @param {class} classRef class reference of the initializing + * class, such as this.beforeInitEvent.fire(Module) + */ + this.beforeInitEvent = this.createEvent(EVENT_TYPES.BEFORE_INIT); + this.beforeInitEvent.signature = SIGNATURE; + + /** + * CustomEvent fired after class initalization. + * @event initEvent + * @param {class} classRef class reference of the initializing + * class, such as this.beforeInitEvent.fire(Module) + */ + this.initEvent = this.createEvent(EVENT_TYPES.INIT); + this.initEvent.signature = SIGNATURE; + + /** + * CustomEvent fired when the Module is appended to the DOM + * @event appendEvent + */ + this.appendEvent = this.createEvent(EVENT_TYPES.APPEND); + this.appendEvent.signature = SIGNATURE; + + /** + * CustomEvent fired before the Module is rendered + * @event beforeRenderEvent + */ + this.beforeRenderEvent = this.createEvent(EVENT_TYPES.BEFORE_RENDER); + this.beforeRenderEvent.signature = SIGNATURE; + + /** + * CustomEvent fired after the Module is rendered + * @event renderEvent + */ + this.renderEvent = this.createEvent(EVENT_TYPES.RENDER); + this.renderEvent.signature = SIGNATURE; + + /** + * CustomEvent fired when the header content of the Module + * is modified + * @event changeHeaderEvent + * @param {String/HTMLElement} content String/element representing + * the new header content + */ + this.changeHeaderEvent = this.createEvent(EVENT_TYPES.CHANGE_HEADER); + this.changeHeaderEvent.signature = SIGNATURE; + + /** + * CustomEvent fired when the body content of the Module is modified + * @event changeBodyEvent + * @param {String/HTMLElement} content String/element representing + * the new body content + */ + this.changeBodyEvent = this.createEvent(EVENT_TYPES.CHANGE_BODY); + this.changeBodyEvent.signature = SIGNATURE; + + /** + * CustomEvent fired when the footer content of the Module + * is modified + * @event changeFooterEvent + * @param {String/HTMLElement} content String/element representing + * the new footer content + */ + this.changeFooterEvent = this.createEvent(EVENT_TYPES.CHANGE_FOOTER); + this.changeFooterEvent.signature = SIGNATURE; + + /** + * CustomEvent fired when the content of the Module is modified + * @event changeContentEvent + */ + this.changeContentEvent = this.createEvent(EVENT_TYPES.CHANGE_CONTENT); + this.changeContentEvent.signature = SIGNATURE; + + /** + * CustomEvent fired when the Module is destroyed + * @event destroyEvent + */ + this.destroyEvent = this.createEvent(EVENT_TYPES.DESTORY); + this.destroyEvent.signature = SIGNATURE; + + /** + * CustomEvent fired before the Module is shown + * @event beforeShowEvent + */ + this.beforeShowEvent = this.createEvent(EVENT_TYPES.BEFORE_SHOW); + this.beforeShowEvent.signature = SIGNATURE; + + /** + * CustomEvent fired after the Module is shown + * @event showEvent + */ + this.showEvent = this.createEvent(EVENT_TYPES.SHOW); + this.showEvent.signature = SIGNATURE; + + /** + * CustomEvent fired before the Module is hidden + * @event beforeHideEvent + */ + this.beforeHideEvent = this.createEvent(EVENT_TYPES.BEFORE_HIDE); + this.beforeHideEvent.signature = SIGNATURE; + + /** + * CustomEvent fired after the Module is hidden + * @event hideEvent + */ + this.hideEvent = this.createEvent(EVENT_TYPES.HIDE); + this.hideEvent.signature = SIGNATURE; + }, + + /** + * String representing the current user-agent platform + * @property platform + * @type String + */ + platform: function () { + var ua = navigator.userAgent.toLowerCase(); + + if (ua.indexOf("windows") != -1 || ua.indexOf("win32") != -1) { + return "windows"; + } else if (ua.indexOf("macintosh") != -1) { + return "mac"; + } else { + return false; + } + }(), + + /** + * String representing the user-agent of the browser + * @deprecated Use YAHOO.env.ua + * @property browser + * @type String + */ + browser: function () { + var ua = navigator.userAgent.toLowerCase(); + /* + Check Opera first in case of spoof and check Safari before + Gecko since Safari's user agent string includes "like Gecko" + */ + if (ua.indexOf('opera') != -1) { + return 'opera'; + } else if (ua.indexOf('msie 7') != -1) { + return 'ie7'; + } else if (ua.indexOf('msie') != -1) { + return 'ie'; + } else if (ua.indexOf('safari') != -1) { + return 'safari'; + } else if (ua.indexOf('gecko') != -1) { + return 'gecko'; + } else { + return false; + } + }(), + + /** + * Boolean representing whether or not the current browsing context is + * secure (https) + * @property isSecure + * @type Boolean + */ + isSecure: function () { + if (window.location.href.toLowerCase().indexOf("https") === 0) { + return true; + } else { + return false; + } + }(), + + /** + * Initializes the custom events for Module which are fired + * automatically at appropriate times by the Module class. + */ + initDefaultConfig: function () { + // Add properties // + /** + * Specifies whether the Module is visible on the page. + * @config visible + * @type Boolean + * @default true + */ + this.cfg.addProperty(DEFAULT_CONFIG.VISIBLE.key, { + handler: this.configVisible, + value: DEFAULT_CONFIG.VISIBLE.value, + validator: DEFAULT_CONFIG.VISIBLE.validator + }); + + /** + *

+ * Object or array of objects representing the ContainerEffect + * classes that are active for animating the container. + *

+ *

+ * NOTE: Although this configuration + * property is introduced at the Module level, an out of the box + * implementation is not shipped for the Module class so setting + * the proroperty on the Module class has no effect. The Overlay + * class is the first class to provide out of the box ContainerEffect + * support. + *

+ * @config effect + * @type Object + * @default null + */ + this.cfg.addProperty(DEFAULT_CONFIG.EFFECT.key, { + suppressEvent: DEFAULT_CONFIG.EFFECT.suppressEvent, + supercedes: DEFAULT_CONFIG.EFFECT.supercedes + }); + + /** + * Specifies whether to create a special proxy iframe to monitor + * for user font resizing in the document + * @config monitorresize + * @type Boolean + * @default true + */ + this.cfg.addProperty(DEFAULT_CONFIG.MONITOR_RESIZE.key, { + handler: this.configMonitorResize, + value: DEFAULT_CONFIG.MONITOR_RESIZE.value + }); + + /** + * Specifies if the module should be rendered as the first child + * of document.body or appended as the last child when render is called + * with document.body as the "appendToNode". + *

+ * Appending to the body while the DOM is still being constructed can + * lead to Operation Aborted errors in IE hence this flag is set to + * false by default. + *

+ * + * @config appendtodocumentbody + * @type Boolean + * @default false + */ + this.cfg.addProperty(DEFAULT_CONFIG.APPEND_TO_DOCUMENT_BODY.key, { + value: DEFAULT_CONFIG.APPEND_TO_DOCUMENT_BODY.value + }); + }, + + /** + * The Module class's initialization method, which is executed for + * Module and all of its subclasses. This method is automatically + * called by the constructor, and sets up all DOM references for + * pre-existing markup, and creates required markup if it is not + * already present. + *

+ * If the element passed in does not have an id, one will be generated + * for it. + *

+ * @method init + * @param {String} el The element ID representing the Module OR + * @param {HTMLElement} el The element representing the Module + * @param {Object} userConfig The configuration Object literal + * containing the configuration that should be set for this module. + * See configuration documentation for more details. + */ + init: function (el, userConfig) { + + var elId, child; + + this.initEvents(); + this.beforeInitEvent.fire(Module); + + /** + * The Module's Config object used for monitoring + * configuration properties. + * @property cfg + * @type YAHOO.util.Config + */ + this.cfg = new Config(this); + + if (this.isSecure) { + this.imageRoot = Module.IMG_ROOT_SSL; + } + + if (typeof el == "string") { + elId = el; + el = document.getElementById(el); + if (! el) { + el = (createModuleTemplate()).cloneNode(false); + el.id = elId; + } + } + + this.id = Dom.generateId(el); + this.element = el; + + child = this.element.firstChild; + + if (child) { + var fndHd = false, fndBd = false, fndFt = false; + do { + // We're looking for elements + if (1 == child.nodeType) { + if (!fndHd && Dom.hasClass(child, Module.CSS_HEADER)) { + this.header = child; + fndHd = true; + } else if (!fndBd && Dom.hasClass(child, Module.CSS_BODY)) { + this.body = child; + fndBd = true; + } else if (!fndFt && Dom.hasClass(child, Module.CSS_FOOTER)){ + this.footer = child; + fndFt = true; + } + } + } while ((child = child.nextSibling)); + } + + this.initDefaultConfig(); + + Dom.addClass(this.element, Module.CSS_MODULE); + + if (userConfig) { + this.cfg.applyConfig(userConfig, true); + } + + /* + Subscribe to the fireQueue() method of Config so that any + queued configuration changes are excecuted upon render of + the Module + */ + + if (!Config.alreadySubscribed(this.renderEvent, this.cfg.fireQueue, this.cfg)) { + this.renderEvent.subscribe(this.cfg.fireQueue, this.cfg, true); + } + + this.initEvent.fire(Module); + }, + + /** + * Initialize an empty IFRAME that is placed out of the visible area + * that can be used to detect text resize. + * @method initResizeMonitor + */ + initResizeMonitor: function () { + + var isGeckoWin = (UA.gecko && this.platform == "windows"); + if (isGeckoWin) { + // Help prevent spinning loading icon which + // started with FireFox 2.0.0.8/Win + var self = this; + setTimeout(function(){self._initResizeMonitor();}, 0); + } else { + this._initResizeMonitor(); + } + }, + + /** + * Create and initialize the text resize monitoring iframe. + * + * @protected + * @method _initResizeMonitor + */ + _initResizeMonitor : function() { + + var oDoc, + oIFrame, + sHTML; + + function fireTextResize() { + Module.textResizeEvent.fire(); + } + + if (!UA.opera) { + oIFrame = Dom.get("_yuiResizeMonitor"); + + var supportsCWResize = this._supportsCWResize(); + + if (!oIFrame) { + oIFrame = document.createElement("iframe"); + + if (this.isSecure && Module.RESIZE_MONITOR_SECURE_URL && UA.ie) { + oIFrame.src = Module.RESIZE_MONITOR_SECURE_URL; + } + + if (!supportsCWResize) { + // Can't monitor on contentWindow, so fire from inside iframe + sHTML = ["