webclient.js-ext.yui.build.container.container.js Maven / Gradle / Ivy
/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 2.8.2r1
*/
(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} overrideContext 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, overrideContext) {
var property = this.config[key.toLowerCase()];
if (property && property.event) {
if (!Config.alreadySubscribed(property.event, handler, obj)) {
property.event.subscribe(handler, obj, overrideContext);
}
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",
"DESTROY": "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.DESTROY);
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 = ["