/**
* @description <p>Creates a rich Toolbar widget based on Button. Primarily used with the Rich Text Editor</p>
* @namespace YAHOO.widget
* @requires yahoo, dom, element, event, toolbarbutton
* @optional container_core, dragdrop
* @beta
*/
(function() {
/**
* @private
**/
var Dom = YAHOO.util.Dom,
Event = YAHOO.util.Event,
Lang = YAHOO.lang;
var getButton = function(id) {
var button = id;
if (Lang.isString(id)) {
button = this.getButtonById(id);
}
if (Lang.isNumber(id)) {
button = this.getButtonByIndex(id);
}
if ((!(button instanceof YAHOO.widget.ToolbarButton)) && (!(button instanceof YAHOO.widget.ToolbarButtonAdvanced))) {
button = this.getButtonByValue(id);
}
if ((button instanceof YAHOO.widget.ToolbarButton) || (button instanceof YAHOO.widget.ToolbarButtonAdvanced)) {
return button;
}
return false;
};
/**
* Provides a rich toolbar widget based on the button and menu widgets
* @constructor
* @class Toolbar
* @extends YAHOO.util.Element
* @param {String/HTMLElement} el The element to turn into a toolbar.
* @param {Object} attrs Object liternal containing configuration parameters.
*/
YAHOO.widget.Toolbar = function(el, attrs) {
YAHOO.log('Toolbar Initalizing', 'info', 'Toolbar');
YAHOO.log(arguments.length + ' arguments passed to constructor', 'info', 'Toolbar');
if (Lang.isObject(arguments[0]) && !Dom.get(el).nodeType) {
attrs = el;
}
var local_attrs = {};
if (attrs) {
Lang.augmentObject(local_attrs, attrs); //Break the config reference
}
var oConfig = {
element: null,
attributes: local_attrs
};
if (Lang.isString(el) && Dom.get(el)) {
oConfig.element = Dom.get(el);
} else if (Lang.isObject(el) && Dom.get(el) && Dom.get(el).nodeType) {
oConfig.element = Dom.get(el);
}
if (!oConfig.element) {
YAHOO.log('No element defined, creating toolbar container', 'warn', 'Toolbar');
oConfig.element = document.createElement('DIV');
oConfig.element.id = Dom.generateId();
if (local_attrs.container && Dom.get(local_attrs.container)) {
YAHOO.log('Container found in config appending to it (' + Dom.get(local_attrs.container).id + ')', 'info', 'Toolbar');
Dom.get(local_attrs.container).appendChild(oConfig.element);
}
}
if (!oConfig.element.id) {
oConfig.element.id = ((Lang.isString(el)) ? el : Dom.generateId());
YAHOO.log('No element ID defined for toolbar container, creating..', 'warn', 'Toolbar');
}
YAHOO.log('Initing toolbar with id: ' + oConfig.element.id, 'info', 'Toolbar');
var fs = document.createElement('fieldset');
var lg = document.createElement('legend');
lg.innerHTML = 'Toolbar';
fs.appendChild(lg);
var cont = document.createElement('DIV');
oConfig.attributes.cont = cont;
Dom.addClass(cont, 'yui-toolbar-subcont');
fs.appendChild(cont);
oConfig.element.appendChild(fs);
oConfig.element.tabIndex = -1;
oConfig.attributes.element = oConfig.element;
oConfig.attributes.id = oConfig.element.id;
YAHOO.widget.Toolbar.superclass.constructor.call(this, oConfig.element, oConfig.attributes);
};
YAHOO.extend(YAHOO.widget.Toolbar, YAHOO.util.Element, {
/**
* @method _addMenuClasses
* @private
* @description This method is called from Menu's renderEvent to add a few more classes to the menu items
* @param {String} ev The event that fired.
* @param {Array} na Array of event information.
* @param {Object} o Button config object.
*/
_addMenuClasses: function(ev, na, o) {
Dom.addClass(this.element, 'yui-toolbar-' + o.get('value') + '-menu');
if (Dom.hasClass(o._button.parentNode.parentNode, 'yui-toolbar-select')) {
Dom.addClass(this.element, 'yui-toolbar-select-menu');
}
var items = this.getItems();
for (var i = 0; i < items.length; i++) {
Dom.addClass(items[i].element, 'yui-toolbar-' + o.get('value') + '-' + ((items[i].value) ? items[i].value.replace(/ /g, '-').toLowerCase() : items[i]._oText.nodeValue.replace(/ /g, '-').toLowerCase()));
Dom.addClass(items[i].element, 'yui-toolbar-' + o.get('value') + '-' + ((items[i].value) ? items[i].value.replace(/ /g, '-') : items[i]._oText.nodeValue.replace(/ /g, '-')));
}
},
/**
* @property buttonType
* @description The default button to use
* @type Object
*/
buttonType: YAHOO.widget.ToolbarButton,
/**
* @property dd
* @description The DragDrop instance associated with the Toolbar
* @type Object
*/
dd: null,
/**
* @property _colorData
* @description Object reference containing colors hex and text values.
* @type Object
*/
_colorData: {
/* {{{ _colorData */
'#111111': 'Obsidian',
'#2D2D2D': 'Dark Gray',
'#434343': 'Shale',
'#5B5B5B': 'Flint',
'#737373': 'Gray',
'#8B8B8B': 'Concrete',
'#A2A2A2': 'Gray',
'#B9B9B9': 'Titanium',
'#000000': 'Black',
'#D0D0D0': 'Light Gray',
'#E6E6E6': 'Silver',
'#FFFFFF': 'White',
'#BFBF00': 'Pumpkin',
'#FFFF00': 'Yellow',
'#FFFF40': 'Banana',
'#FFFF80': 'Pale Yellow',
'#FFFFBF': 'Butter',
'#525330': 'Raw Siena',
'#898A49': 'Mildew',
'#AEA945': 'Olive',
'#7F7F00': 'Paprika',
'#C3BE71': 'Earth',
'#E0DCAA': 'Khaki',
'#FCFAE1': 'Cream',
'#60BF00': 'Cactus',
'#80FF00': 'Chartreuse',
'#A0FF40': 'Green',
'#C0FF80': 'Pale Lime',
'#DFFFBF': 'Light Mint',
'#3B5738': 'Green',
'#668F5A': 'Lime Gray',
'#7F9757': 'Yellow',
'#407F00': 'Clover',
'#8A9B55': 'Pistachio',
'#B7C296': 'Light Jade',
'#E6EBD5': 'Breakwater',
'#00BF00': 'Spring Frost',
'#00FF80': 'Pastel Green',
'#40FFA0': 'Light Emerald',
'#80FFC0': 'Sea Foam',
'#BFFFDF': 'Sea Mist',
'#033D21': 'Dark Forrest',
'#438059': 'Moss',
'#7FA37C': 'Medium Green',
'#007F40': 'Pine',
'#8DAE94': 'Yellow Gray Green',
'#ACC6B5': 'Aqua Lung',
'#DDEBE2': 'Sea Vapor',
'#00BFBF': 'Fog',
'#00FFFF': 'Cyan',
'#40FFFF': 'Turquoise Blue',
'#80FFFF': 'Light Aqua',
'#BFFFFF': 'Pale Cyan',
'#033D3D': 'Dark Teal',
'#347D7E': 'Gray Turquoise',
'#609A9F': 'Green Blue',
'#007F7F': 'Seaweed',
'#96BDC4': 'Green Gray',
'#B5D1D7': 'Soapstone',
'#E2F1F4': 'Light Turquoise',
'#0060BF': 'Summer Sky',
'#0080FF': 'Sky Blue',
'#40A0FF': 'Electric Blue',
'#80C0FF': 'Light Azure',
'#BFDFFF': 'Ice Blue',
'#1B2C48': 'Navy',
'#385376': 'Biscay',
'#57708F': 'Dusty Blue',
'#00407F': 'Sea Blue',
'#7792AC': 'Sky Blue Gray',
'#A8BED1': 'Morning Sky',
'#DEEBF6': 'Vapor',
'#0000BF': 'Deep Blue',
'#0000FF': 'Blue',
'#4040FF': 'Cerulean Blue',
'#8080FF': 'Evening Blue',
'#BFBFFF': 'Light Blue',
'#212143': 'Deep Indigo',
'#373E68': 'Sea Blue',
'#444F75': 'Night Blue',
'#00007F': 'Indigo Blue',
'#585E82': 'Dockside',
'#8687A4': 'Blue Gray',
'#D2D1E1': 'Light Blue Gray',
'#6000BF': 'Neon Violet',
'#8000FF': 'Blue Violet',
'#A040FF': 'Violet Purple',
'#C080FF': 'Violet Dusk',
'#DFBFFF': 'Pale Lavender',
'#302449': 'Cool Shale',
'#54466F': 'Dark Indigo',
'#655A7F': 'Dark Violet',
'#40007F': 'Violet',
'#726284': 'Smoky Violet',
'#9E8FA9': 'Slate Gray',
'#DCD1DF': 'Violet White',
'#BF00BF': 'Royal Violet',
'#FF00FF': 'Fuchsia',
'#FF40FF': 'Magenta',
'#FF80FF': 'Orchid',
'#FFBFFF': 'Pale Magenta',
'#4A234A': 'Dark Purple',
'#794A72': 'Medium Purple',
'#936386': 'Cool Granite',
'#7F007F': 'Purple',
'#9D7292': 'Purple Moon',
'#C0A0B6': 'Pale Purple',
'#ECDAE5': 'Pink Cloud',
'#BF005F': 'Hot Pink',
'#FF007F': 'Deep Pink',
'#FF409F': 'Grape',
'#FF80BF': 'Electric Pink',
'#FFBFDF': 'Pink',
'#451528': 'Purple Red',
'#823857': 'Purple Dino',
'#A94A76': 'Purple Gray',
'#7F003F': 'Rose',
'#BC6F95': 'Antique Mauve',
'#D8A5BB': 'Cool Marble',
'#F7DDE9': 'Pink Granite',
'#C00000': 'Apple',
'#FF0000': 'Fire Truck',
'#FF4040': 'Pale Red',
'#FF8080': 'Salmon',
'#FFC0C0': 'Warm Pink',
'#441415': 'Sepia',
'#82393C': 'Rust',
'#AA4D4E': 'Brick',
'#800000': 'Brick Red',
'#BC6E6E': 'Mauve',
'#D8A3A4': 'Shrimp Pink',
'#F8DDDD': 'Shell Pink',
'#BF5F00': 'Dark Orange',
'#FF7F00': 'Orange',
'#FF9F40': 'Grapefruit',
'#FFBF80': 'Canteloupe',
'#FFDFBF': 'Wax',
'#482C1B': 'Dark Brick',
'#855A40': 'Dirt',
'#B27C51': 'Tan',
'#7F3F00': 'Nutmeg',
'#C49B71': 'Mustard',
'#E1C4A8': 'Pale Tan',
'#FDEEE0': 'Marble'
/* }}} */
},
/**
* @property _colorPicker
* @description The HTML Element containing the colorPicker
* @type HTMLElement
*/
_colorPicker: null,
/**
* @property STR_COLLAPSE
* @description String for Toolbar Collapse Button
* @type String
*/
STR_COLLAPSE: 'Collapse Toolbar',
/**
* @property STR_SPIN_LABEL
* @description String for spinbutton dynamic label. Note the {VALUE} will be replaced with YAHOO.lang.substitute
* @type String
*/
STR_SPIN_LABEL: 'Spin Button with value {VALUE}. Use Control Shift Up Arrow and Control Shift Down arrow keys to increase or decrease the value.',
/**
* @property STR_SPIN_UP
* @description String for spinbutton up
* @type String
*/
STR_SPIN_UP: 'Click to increase the value of this input',
/**
* @property STR_SPIN_DOWN
* @description String for spinbutton down
* @type String
*/
STR_SPIN_DOWN: 'Click to decrease the value of this input',
/**
* @property _titlebar
* @description Object reference to the titlebar
* @type HTMLElement
*/
_titlebar: null,
/**
* @property browser
* @description Standard browser detection
* @type Object
*/
browser: YAHOO.env.ua,
/**
* @protected
* @property _buttonList
* @description Internal property list of current buttons in the toolbar
* @type Array
*/
_buttonList: null,
/**
* @protected
* @property _buttonGroupList
* @description Internal property list of current button groups in the toolbar
* @type Array
*/
_buttonGroupList: null,
/**
* @protected
* @property _sep
* @description Internal reference to the separator HTML Element for cloning
* @type HTMLElement
*/
_sep: null,
/**
* @protected
* @property _sepCount
* @description Internal refernce for counting separators, so we can give them a useful class name for styling
* @type Number
*/
_sepCount: null,
/**
* @protected
* @property draghandle
* @type HTMLElement
*/
_dragHandle: null,
/**
* @protected
* @property _toolbarConfigs
* @type Object
*/
_toolbarConfigs: {
renderer: true
},
/**
* @protected
* @property CLASS_CONTAINER
* @description Default CSS class to apply to the toolbar container element
* @type String
*/
CLASS_CONTAINER: 'yui-toolbar-container',
/**
* @protected
* @property CLASS_DRAGHANDLE
* @description Default CSS class to apply to the toolbar's drag handle element
* @type String
*/
CLASS_DRAGHANDLE: 'yui-toolbar-draghandle',
/**
* @protected
* @property CLASS_SEPARATOR
* @description Default CSS class to apply to all separators in the toolbar
* @type String
*/
CLASS_SEPARATOR: 'yui-toolbar-separator',
/**
* @protected
* @property CLASS_DISABLED
* @description Default CSS class to apply when the toolbar is disabled
* @type String
*/
CLASS_DISABLED: 'yui-toolbar-disabled',
/**
* @protected
* @property CLASS_PREFIX
* @description Default prefix for dynamically created class names
* @type String
*/
CLASS_PREFIX: 'yui-toolbar',
/**
* @method init
* @description The Toolbar class's initialization method
*/
init: function(p_oElement, p_oAttributes) {
YAHOO.widget.Toolbar.superclass.init.call(this, p_oElement, p_oAttributes);
},
/**
* @method initAttributes
* @description Initializes all of the configuration attributes used to create
* the toolbar.
* @param {Object} attr Object literal specifying a set of
* configuration attributes used to create the toolbar.
*/
initAttributes: function(attr) {
YAHOO.widget.Toolbar.superclass.initAttributes.call(this, attr);
this.addClass(this.CLASS_CONTAINER);
/**
* @attribute buttonType
* @description The buttonType to use (advanced or basic)
* @type String
*/
this.setAttributeConfig('buttonType', {
value: attr.buttonType || 'basic',
writeOnce: true,
validator: function(type) {
switch (type) {
case 'advanced':
case 'basic':
return true;
}
return false;
},
method: function(type) {
if (type == 'advanced') {
if (YAHOO.widget.Button) {
this.buttonType = YAHOO.widget.ToolbarButtonAdvanced;
} else {
YAHOO.log('Can not find YAHOO.widget.Button', 'error', 'Toolbar');
this.buttonType = YAHOO.widget.ToolbarButton;
}
} else {
this.buttonType = YAHOO.widget.ToolbarButton;
}
}
});
/**
* @attribute buttons
* @description Object specifying the buttons to include in the toolbar
* Example:
* <code><pre>
* {
* { id: 'b3', type: 'button', label: 'Underline', value: 'underline' },
* { type: 'separator' },
* { id: 'b4', type: 'menu', label: 'Align', value: 'align',
* menu: [
* { text: "Left", value: 'alignleft' },
* { text: "Center", value: 'aligncenter' },
* { text: "Right", value: 'alignright' }
* ]
* }
* }
* </pre></code>
* @type Array
*/
this.setAttributeConfig('buttons', {
value: [],
writeOnce: true,
method: function(data) {
for (var i in data) {
if (Lang.hasOwnProperty(data, i)) {
if (data[i].type == 'separator') {
this.addSeparator();
} else if (data[i].group !== undefined) {
this.addButtonGroup(data[i]);
} else {
this.addButton(data[i]);
}
}
}
}
});
/**
* @attribute disabled
* @description Boolean indicating if the toolbar should be disabled. It will also disable the draggable attribute if it is on.
* @default false
* @type Boolean
*/
this.setAttributeConfig('disabled', {
value: false,
method: function(disabled) {
if (this.get('disabled') === disabled) {
return false;
}
if (disabled) {
this.addClass(this.CLASS_DISABLED);
this.set('draggable', false);
this.disableAllButtons();
} else {
this.removeClass(this.CLASS_DISABLED);
if (this._configs.draggable._initialConfig.value) {
//Draggable by default, set it back
this.set('draggable', true);
}
this.resetAllButtons();
}
}
});
/**
* @config cont
* @description The container for the toolbar.
* @type HTMLElement
*/
this.setAttributeConfig('cont', {
value: attr.cont,
readOnly: true
});
/**
* @attribute grouplabels
* @description Boolean indicating if the toolbar should show the group label's text string.
* @default true
* @type Boolean
*/
this.setAttributeConfig('grouplabels', {
value: ((attr.grouplabels === false) ? false : true),
method: function(grouplabels) {
if (grouplabels) {
Dom.removeClass(this.get('cont'), (this.CLASS_PREFIX + '-nogrouplabels'));
} else {
Dom.addClass(this.get('cont'), (this.CLASS_PREFIX + '-nogrouplabels'));
}
}
});
/**
* @attribute titlebar
* @description Boolean indicating if the toolbar should have a titlebar. If
* passed a string, it will use that as the titlebar text
* @default false
* @type Boolean or String
*/
this.setAttributeConfig('titlebar', {
value: false,
method: function(titlebar) {
if (titlebar) {
if (this._titlebar && this._titlebar.parentNode) {
this._titlebar.parentNode.removeChild(this._titlebar);
}
this._titlebar = document.createElement('DIV');
this._titlebar.tabIndex = '-1';
Event.on(this._titlebar, 'focus', function() {
this._handleFocus();
}, this, true);
Dom.addClass(this._titlebar, this.CLASS_PREFIX + '-titlebar');
if (Lang.isString(titlebar)) {
var h2 = document.createElement('h2');
h2.tabIndex = '-1';
h2.innerHTML = '<a href="#" tabIndex="0">' + titlebar + '</a>';
this._titlebar.appendChild(h2);
Event.on(h2.firstChild, 'click', function(ev) {
Event.stopEvent(ev);
});
Event.on([h2, h2.firstChild], 'focus', function() {
this._handleFocus();
}, this, true);
}
if (this.get('firstChild')) {
this.insertBefore(this._titlebar, this.get('firstChild'));
} else {
this.appendChild(this._titlebar);
}
if (this.get('collapse')) {
this.set('collapse', true);
}
} else if (this._titlebar) {
if (this._titlebar && this._titlebar.parentNode) {
this._titlebar.parentNode.removeChild(this._titlebar);
}
}
}
});
/**
* @attribute collapse
* @description Boolean indicating if the the titlebar should have a collapse button.
* The collapse button will not remove the toolbar, it will minimize it to the titlebar
* @default false
* @type Boolean
*/
this.setAttributeConfig('collapse', {
value: false,
method: function(collapse) {
if (this._titlebar) {
var collapseEl = null;
var el = Dom.getElementsByClassName('collapse', 'span', this._titlebar);
if (collapse) {
if (el.length > 0) {
//There is already a collapse button
return true;
}
collapseEl = document.createElement('SPAN');
collapseEl.innerHTML = 'X';
collapseEl.title = this.STR_COLLAPSE;
Dom.addClass(collapseEl, 'collapse');
this._titlebar.appendChild(collapseEl);
Event.addListener(collapseEl, 'click', function() {
if (Dom.hasClass(this.get('cont').parentNode, 'yui-toolbar-container-collapsed')) {
this.collapse(false); //Expand Toolbar
} else {
this.collapse(); //Collapse Toolbar
}
}, this, true);
} else {
collapseEl = Dom.getElementsByClassName('collapse', 'span', this._titlebar);
if (collapseEl[0]) {
if (Dom.hasClass(this.get('cont').parentNode, 'yui-toolbar-container-collapsed')) {
//We are closed, reopen the titlebar..
this.collapse(false); //Expand Toolbar
}
collapseEl[0].parentNode.removeChild(collapseEl[0]);
}
}
}
}
});
/**
* @attribute draggable
* @description Boolean indicating if the toolbar should be draggable.
* @default false
* @type Boolean
*/
this.setAttributeConfig('draggable', {
value: (attr.draggable || false),
method: function(draggable) {
if (draggable && !this.get('titlebar')) {
YAHOO.log('Dragging enabled', 'info', 'Toolbar');
if (!this._dragHandle) {
this._dragHandle = document.createElement('SPAN');
this._dragHandle.innerHTML = '|';
this._dragHandle.setAttribute('title', 'Click to drag the toolbar');
this._dragHandle.id = this.get('id') + '_draghandle';
Dom.addClass(this._dragHandle, this.CLASS_DRAGHANDLE);
if (this.get('cont').hasChildNodes()) {
this.get('cont').insertBefore(this._dragHandle, this.get('cont').firstChild);
} else {
this.get('cont').appendChild(this._dragHandle);
}
/**
* @property dd
* @description The DragDrop instance associated with the Toolbar
* @type Object
*/
this.dd = new YAHOO.util.DD(this.get('id'));
this.dd.setHandleElId(this._dragHandle.id);
}
} else {
YAHOO.log('Dragging disabled', 'info', 'Toolbar');
if (this._dragHandle) {
this._dragHandle.parentNode.removeChild(this._dragHandle);
this._dragHandle = null;
this.dd = null;
}
}
if (this._titlebar) {
if (draggable) {
this.dd = new YAHOO.util.DD(this.get('id'));
this.dd.setHandleElId(this._titlebar);
Dom.addClass(this._titlebar, 'draggable');
} else {
Dom.removeClass(this._titlebar, 'draggable');
if (this.dd) {
this.dd.unreg();
this.dd = null;
}
}
}
},
validator: function(value) {
var ret = true;
if (!YAHOO.util.DD) {
ret = false;
}
return ret;
}
});
},
/**
* @method addButtonGroup
* @description Add a new button group to the toolbar. (uses addButton)
* @param {Object} oGroup Object literal reference to the Groups Config (contains an array of button configs as well as the group label)
*/
addButtonGroup: function(oGroup) {
if (!this.get('element')) {
this._queue[this._queue.length] = ['addButtonGroup', arguments];
return false;
}
if (!this.hasClass(this.CLASS_PREFIX + '-grouped')) {
this.addClass(this.CLASS_PREFIX + '-grouped');
}
var div = document.createElement('DIV');
Dom.addClass(div, this.CLASS_PREFIX + '-group');
Dom.addClass(div, this.CLASS_PREFIX + '-group-' + oGroup.group);
if (oGroup.label) {
var label = document.createElement('h3');
label.innerHTML = oGroup.label;
div.appendChild(label);
}
if (!this.get('grouplabels')) {
Dom.addClass(this.get('cont'), this.CLASS_PREFIX, '-nogrouplabels');
}
this.get('cont').appendChild(div);
//For accessibility, let's put all of the group buttons in an Unordered List
var ul = document.createElement('ul');
div.appendChild(ul);
if (!this._buttonGroupList) {
this._buttonGroupList = {};
}
this._buttonGroupList[oGroup.group] = ul;
for (var i = 0; i < oGroup.buttons.length; i++) {
var li = document.createElement('li');
li.className = this.CLASS_PREFIX + '-groupitem';
ul.appendChild(li);
if ((oGroup.buttons[i].type !== undefined) && oGroup.buttons[i].type == 'separator') {
this.addSeparator(li);
} else {
oGroup.buttons[i].container = li;
this.addButton(oGroup.buttons[i]);
}
}
},
/**
* @method addButtonToGroup
* @description Add a new button to a toolbar group. Buttons supported:
* push, split, menu, select, color, spin
* @param {Object} oButton Object literal reference to the Button's Config
* @param {String} group The Group identifier passed into the initial config
* @param {HTMLElement} after Optional HTML element to insert this button after in the DOM.
*/
addButtonToGroup: function(oButton, group, after) {
var groupCont = this._buttonGroupList[group];
var li = document.createElement('li');
li.className = this.CLASS_PREFIX + '-groupitem';
oButton.container = li;
this.addButton(oButton, after);
groupCont.appendChild(li);
},
/**
* @method addButton
* @description Add a new button to the toolbar. Buttons supported:
* push, split, menu, select, color, spin
* @param {Object} oButton Object literal reference to the Button's Config
* @param {HTMLElement} after Optional HTML element to insert this button after in the DOM.
*/
addButton: function(oButton, after) {
if (!this.get('element')) {
this._queue[this._queue.length] = ['addButton', arguments];
return false;
}
if (!this._buttonList) {
this._buttonList = [];
}
YAHOO.log('Adding button of type: ' + oButton.type, 'info', 'Toolbar');
if (!oButton.container) {
oButton.container = this.get('cont');
}
if ((oButton.type == 'menu') || (oButton.type == 'split') || (oButton.type == 'select')) {
if (Lang.isArray(oButton.menu)) {
for (var i in oButton.menu) {
if (Lang.hasOwnProperty(oButton.menu, i)) {
var funcObject = {
fn: function(ev, x, oMenu) {
if (!oButton.menucmd) {
oButton.menucmd = oButton.value;
}
oButton.value = ((oMenu.value) ? oMenu.value : oMenu._oText.nodeValue);
},
scope: this
};
oButton.menu[i].onclick = funcObject;
}
}
}
}
var _oButton = {}, skip = false;
for (var o in oButton) {
if (Lang.hasOwnProperty(oButton, o)) {
if (!this._toolbarConfigs[o]) {
_oButton[o] = oButton[o];
}
}
}
if (oButton.type == 'select') {
_oButton.type = 'menu';
}
if (oButton.type == 'spin') {
_oButton.type = 'push';
}
if (_oButton.type == 'color') {
if (YAHOO.widget.Overlay) {
_oButton = this._makeColorButton(_oButton);
} else {
skip = true;
}
}
if (_oButton.menu) {
if ((YAHOO.widget.Overlay) && (oButton.menu instanceof YAHOO.widget.Overlay)) {
oButton.menu.showEvent.subscribe(function() {
this._button = _oButton;
});
} else {
for (var m = 0; m < _oButton.menu.length; m++) {
if (!_oButton.menu[m].value) {
_oButton.menu[m].value = _oButton.menu[m].text;
}
}
if (this.browser.webkit) {
_oButton.focusmenu = false;
}
}
}
if (skip) {
oButton = false;
} else {
//Add to .get('buttons') manually
this._configs.buttons.value[this._configs.buttons.value.length] = oButton;
var tmp = new this.buttonType(_oButton);
tmp.get('element').tabIndex = '-1';
tmp.get('element').setAttribute('role', 'button');
tmp._selected = true;
if (this.get('disabled')) {
//Toolbar is disabled, disable the new button too!
tmp.set('disabled', true);
}
if (!oButton.id) {
oButton.id = tmp.get('id');
}
YAHOO.log('Button created (' + oButton.type + ')', 'info', 'Toolbar');
if (after) {
var el = tmp.get(