(function () { var Event = YAHOO.util.Event, Dom = YAHOO.util.Dom, Lang = YAHOO.lang, UA = YAHOO.env.ua, Panel = YAHOO.widget.Panel, Tooltip = YAHOO.widget.Tooltip, SimpleDialog = YAHOO.widget.SimpleDialog, ModulePrototype = YAHOO.widget.Module.prototype, fnModuleInitDefaultConfig = ModulePrototype.initDefaultConfig, fnModuleInitResizeMonitor = ModulePrototype._initResizeMonitor, OverlayPrototype = YAHOO.widget.Overlay.prototype, fnOverlayShowIframe = OverlayPrototype.showIframe, PanelPrototype, fnPanelInitDefaultConfig, SimpleDialogPrototype, fnSimpleDialogConfigIcon, m_bPanelDocumentListenersAdded = false, m_oFocusedElement, // Currently focused element in the DOM m_oOverlayManager, // An OverlayManager instance m_bToolTipDocumentListenersAdded = false, m_oContextElements = {}, // Hash of Tooltip context elements, indexed by Tooltip id m_oTooltips = {}, // Hash of Tooltips indexed by context element id // Private constants for strings _ARIA_PREFIX = "aria-", _ROLE = "role", _PRESENTATION = "presentation", _USE_ARIA = "usearia", _BLUR = "blur", _FOCUS = "focus", _VISIBLE = "visible", _BEFORE_HIDE = "beforeHide", _ALERT_DIALOG = "alertdialog", _DIALOG = "dialog", _DESCRIBED_BY = "describedby", _CONTEXT = "context", _HIDDEN = "hidden", _CONTAINER_CLOSE = "container-close", _A = "a", _HREF = "href", _BUTTON = "button", _KEY_DOWN = "keydown", _BEFORE_SHOW = "beforeShow", _CLOSE = "close", _LABELLED_BY = "labelledby", _XY = "xy", _TOOLTIP = "tooltip", _DESTROY = "destroy"; var setARIARole = function (element, role) { element.setAttribute(_ROLE, role); }; var setARIAProperty = function (element, property, value) { element.setAttribute((_ARIA_PREFIX + property), value); }; // Module ARIA plugin - augments YAHOO.widget.Module Lang.augmentObject(ModulePrototype, { _initResizeMonitor: function () { fnModuleInitResizeMonitor.call(this); var oIFrame = this.resizeMonitor; if (oIFrame) { setARIARole(oIFrame, _PRESENTATION); oIFrame.tabIndex = -1; } }, configUseARIA: function (type, args) { // Stub for subclasses }, configDescribedBy: function (type, args) { var sID = args[0]; if (this.cfg.getProperty(_USE_ARIA) && sID) { setARIAProperty(this.element, _DESCRIBED_BY, sID); } }, configLabelledBy: function (type, args) { var sID = args[0]; if (this.cfg.getProperty(_USE_ARIA) && sID) { setARIAProperty(this.element, _LABELLED_BY, sID); } }, initDefaultConfig: function () { /** * @config usearia * @description Boolean indicating if use of the WAI-ARIA Roles and States should * be enabled. * @type Boolean * @default true for Firefox 3 and IE 8, false for all other browsers. */ this.cfg.addProperty( _USE_ARIA, { handler: this.configUseARIA, value: (UA.gecko && UA.gecko >= 1.9) || (UA.ie && UA.ie >= 8), validator: Lang.isBoolean } ); /** * @config labelledby * @description String representing the id of the element that labels the Module. * Maps directly to the * aria-labelledby attribute. * @type String * @default null */ this.cfg.addProperty( _LABELLED_BY, { handler: this.configLabelledBy, validator: Lang.isString } ); /** * @attribute describedby * @description String representing the id of the element that describes the Module. * Maps directly to the * aria-describedby attribute. * @type String * @default null */ this.cfg.addProperty( _DESCRIBED_BY, { handler: this.configDescribedBy, validator: Lang.isString } ); fnModuleInitDefaultConfig.call(this); } }, "initDefaultConfig", "configUseARIA", "configLabelledBy", "configDescribedBy", "_initResizeMonitor"); // Overlay ARIA plugin - augments YAHOO.widget.Overlay OverlayPrototype.showIframe = function () { fnOverlayShowIframe.call(this); var oIFrame = this.iframe; if (this.cfg.getProperty(_USE_ARIA) && oIFrame && !oIFrame.getAttribute(_ROLE)) { setARIARole(oIFrame, _PRESENTATION); oIFrame.tabIndex = -1; } }; // Panel ARIA plugin - augments YAHOO.widget.Panel var onPanelKeyDown = function (event) { var nCharCode = Event.getCharCode(event); if (nCharCode === 27) { if (this.cancel) { // Dialog this.cancel(); } else { // Panel this.hide(); } } }; var onPanelDOMFocus = function (event) { this.fireEvent(_FOCUS, event); }; var onPanelDOMBlur = function (event) { this.fireEvent(_BLUR, event); }; var onPanelFocus = function (type, args) { var oEvent = args[0]; // DOM event if (m_oOverlayManager._manageFocus(this)) { if (this.cfg.getProperty(_VISIBLE) && this.focusFirst) { // If the event was not sourced from the UI, focus the first element in the Panel if (!oEvent) { this.focusFirst(); } } } }; var onPanelBlur = function (type, args) { var oEvent = args[0]; // DOM event // If the event was not sourced from the UI fire the blur event if (m_oOverlayManager._manageBlur(this) && !oEvent) { this.fireEvent(_BLUR); } }; var restoreFocus = function (type, args, element) { this.blur(); if (element && element.focus) { try { element.focus(); } catch(e) { } } this.unsubscribe(type, restoreFocus, element); }; var onPanelBeforeShow = function () { // If the Panel is modal it is necessary to wait until the modality // mask has been hidden before attempting to restore focus to the // element in the DOM that had focus before the Panel was made visible. var sEvent = (this.cfg.getProperty("modal") === true) ? "hideMask" : _BEFORE_HIDE; this.subscribe(sEvent, restoreFocus, m_oFocusedElement); }; var setPanelHiddenRole = function () { setARIAProperty(this.innerElement, _HIDDEN, !this.cfg.getProperty(_VISIBLE)); }; var setRoleForCloseButton = function () { Dom.getElementsByClassName(_CONTAINER_CLOSE, _A, this.element, function (element) { element.removeAttribute(_HREF); setARIARole(element, _BUTTON); element.tabIndex = 0; }); }; var onPanelConfigClose = function (type, args) { var bClose = args[0]; if (bClose) { setRoleForCloseButton.call(this); } }; if (Panel) { PanelPrototype = Panel.prototype; fnPanelInitDefaultConfig = PanelPrototype.initDefaultConfig; Lang.augmentObject(PanelPrototype, { hasFocus: function () { return (m_oOverlayManager && this === m_oOverlayManager.getActive()); }, configUseARIA: function (type, args) { var bUseARIA = args[0]; if (bUseARIA) { if (!m_oOverlayManager) { m_oOverlayManager = new YAHOO.widget.OverlayManager(); } m_oOverlayManager.register(this); this.focus = function () { if (!this.hasFocus()) { this.fireEvent(_FOCUS); } }; this.blur = function () { if (this.hasFocus()) { this.fireEvent(_BLUR); } }; Event.onFocus(this.element, onPanelDOMFocus, null, this); Event.onBlur(this.element, onPanelDOMBlur, null, this); this.subscribe(_FOCUS, onPanelFocus); this.subscribe(_BLUR, onPanelBlur); Event.on(this.element, _KEY_DOWN, onPanelKeyDown, null, this); this.subscribe(_BEFORE_SHOW, onPanelBeforeShow); setPanelHiddenRole.call(this); this.cfg.subscribeToConfigEvent(_VISIBLE, setPanelHiddenRole); this.cfg.subscribeToConfigEvent(_CLOSE, onPanelConfigClose); if (!m_bPanelDocumentListenersAdded) { Event.onFocus(document, function (event) { m_oFocusedElement = Event.getTarget(event); }); m_bPanelDocumentListenersAdded = true; } } }, configDescribedBy: function (type, args) { var sID = args[0]; if (this.cfg.getProperty(_USE_ARIA) && sID) { setARIAProperty(this.innerElement, _DESCRIBED_BY, sID); } }, configLabelledBy: function (type, args) { var sID = args[0]; if (this.cfg.getProperty(_USE_ARIA) && sID) { setARIAProperty(this.innerElement, _LABELLED_BY, sID); } }, configRole: function (type, args) { var sRole = args[0], oBody, oHeader, sID; if (sRole) { switch (sRole) { case _ALERT_DIALOG: oBody = this.body; sID = oBody.id || Dom.generateId(oBody); this.cfg.setProperty(_DESCRIBED_BY, sID); break; case _DIALOG: oHeader = this.header; sID = oHeader.id || Dom.generateId(oHeader); this.cfg.setProperty(_LABELLED_BY, sID); break; } setARIARole(this.innerElement, sRole); setRoleForCloseButton.call(this); } }, initDefaultConfig: function () { fnPanelInitDefaultConfig.call(this); this.cfg.addProperty( _ROLE, { handler: this.configRole, value: _DIALOG, validator: Lang.isString } ); } }, "initDefaultConfig", "configRole", "configUseARIA", "configLabelledBy", "configDescribedBy", "hasFocus"); } // SimpleDialog ARIA plugin - augments YAHOO.widget.SimpleDialog if (SimpleDialog) { SimpleDialogPrototype = SimpleDialog.prototype; fnSimpleDialogConfigIcon = SimpleDialogPrototype.configIcon; SimpleDialogPrototype.configIcon = function (type, args, obj) { fnSimpleDialogConfigIcon.apply(this, arguments); var sIcon = args[0], sCSSClass = SimpleDialog.ICON_CSS_CLASSNAME, oIcon; if (sIcon && sIcon != "none") { oIcon = Dom.getElementsByClassName(sCSSClass, "*" , this.body); if (oIcon) { setARIARole(oIcon[0], _PRESENTATION); } } }; } // Tooltip ARIA plugin - augments YAHOO.widget.Tooltip var onDocumentFocus = function (event) { var oTarget = Event.getTarget(event), oTooltip = m_oTooltips[oTarget.id], aXY; if (oTooltip) { aXY = Dom.getXY(oTarget); oTooltip.cfg.setProperty(_XY, [aXY[0], (aXY[1] + oTarget.offsetHeight + 5)]); oTooltip.show(); } }; var onDocumentBlur = function (event) { var oTarget = Event.getTarget(event), oTooltip = m_oTooltips[oTarget.id]; if (oTooltip && oTooltip.cfg.getProperty(_VISIBLE)) { oTooltip.hide(); } }; var unregisterContextElement = function (element) { var sContextElId = element.id, oTooltip = m_oTooltips[sContextElId]; if (oTooltip === this) { delete m_oTooltips[sContextElId]; element.removeAttribute(_DESCRIBED_BY); } }; var unregisterContextElements = function () { var sId = this.element.id, aContextElements = m_oContextElements[sId]; Dom.batch(aContextElements, unregisterContextElement, this, true); m_oContextElements[sId] = null; }; var registerContextElement = function (element) { var sContextElId = element.id || Dom.generateId(element); m_oTooltips[sContextElId] = this; setARIAProperty(element, _DESCRIBED_BY, this.element.id); }; var registerContextElements = function () { var aContextElements = this.cfg.getProperty(_CONTEXT); Dom.batch(aContextElements, registerContextElement, this, true); m_oContextElements[this.element.id] = aContextElements; }; var onTooltipContextChange = function (type, args) { unregisterContextElements.call(this); var context = args[0]; if (context) { registerContextElements.call(this); } }; var setTooltipHiddenRole = function () { setARIAProperty(this.body, _HIDDEN, !this.cfg.getProperty(_VISIBLE)); }; if (Tooltip) { Tooltip.prototype.configUseARIA = function (type, args) { var bUseARIA = args[0]; if (bUseARIA) { setARIARole(this.body, _TOOLTIP); this.cfg.subscribeToConfigEvent(_CONTEXT, onTooltipContextChange); setTooltipHiddenRole.call(this); this.cfg.subscribeToConfigEvent(_VISIBLE, setTooltipHiddenRole); this.subscribe(_DESTROY, unregisterContextElements); if (!m_bToolTipDocumentListenersAdded) { Event.onFocus(document, onDocumentFocus); Event.onBlur(document, onDocumentBlur); m_bToolTipDocumentListenersAdded = true; } } }; } }()); YAHOO.register("containerariaplugin", YAHOO.widget.Module, {version: "@VERSION@", build: "@BUILD@"});