Version 3.18.1
Show:

File: button/js/core.js

            /**
             * Provides an interface for working with button-like DOM nodes
             *
             * @module button-core
             * @since 3.5.0
             */
            var getClassName = Y.ClassNameManager.getClassName,
                AttributeCore = Y.AttributeCore;
            
            /**
             * Creates a button
             *
             * @class ButtonCore
             * @uses AttributeCore
             * @param config {Object} Configuration object
             * @constructor
             */
            function ButtonCore(config) {
                this.initializer(config);
            }
            
            ButtonCore.prototype = {
            
                /**
                 *
                 * @property TEMPLATE
                 * @type {String}
                 * @default <button/>
                 */
                TEMPLATE: '<button/>',
            
                /**
                 *
                 * @property constructor
                 * @type {Object}
                 * @default ButtonCore
                 * @private
                 */
                constructor: ButtonCore,
            
                /**
                 * @method initializer
                 * @description Internal init() handler.
                 * @param config {Object} Config object.
                 * @private
                 */
                initializer: function(config) {
                    this._initNode(config);
                    this._initAttributes(config);
                    this._renderUI(config);
                },
            
                /**
                 * @method _initNode
                 * @description Node initializer
                 * @param config {Object} Config object.
                 * @private
                 */
                _initNode: function(config) {
                    if (config.host) {
                        this._host = Y.one(config.host);
                    } else {
                        this._host = Y.Node.create(this.TEMPLATE);
                    }
                },
            
                /**
                 * @method _initAttributes
                 * @description  Attribute initializer
                 * @param config {Object} Config object.
                 * @private
                 */
                _initAttributes: function(config) {
                    AttributeCore.call(this, ButtonCore.ATTRS, config);
                },
            
                /**
                 * @method renderUI
                 * @description Renders any UI/DOM elements for Button instances
                 * @param config {Object} Config object.
                 * @private
                 */
                _renderUI: function() {
                    var node = this.getNode(),
                        nodeName = node.get('nodeName').toLowerCase();
            
                    // Set some default node attributes
                    node.addClass(ButtonCore.CLASS_NAMES.BUTTON);
            
                    if (nodeName !== 'button' && nodeName !== 'input') {
                        node.set('role', 'button');
                    }
                },
            
                /**
                 * @method enable
                 * @description Sets the button's `disabled` DOM attribute to `false`
                 * @public
                 */
                enable: function() {
                    this.set('disabled', false);
                },
            
                /**
                 * @method disable
                 * @description Sets the button's `disabled` DOM attribute to `true`
                 * @public
                 */
                disable: function() {
                    this.set('disabled', true);
                },
            
                /**
                 * @method getNode
                 * @description Gets the button's host node
                 * @return {Node} The host node instance
                 * @public
                 */
                getNode: function() {
                    if (!this._host) {
                        // If this._host doesn't exist, that means this._initNode
                        // was never executed, meaning this is likely a Widget and
                        // the host node should point to the boundingBox.
                        this._host = this.get('boundingBox');
                    }
            
                    return this._host;
                },
            
                /**
                 * @method _getLabel
                 * @description Getter for a button's `label` ATTR
                 * @return {String} The text label of the button
                 * @private
                 */
                _getLabel: function () {
                    var node = this.getNode(),
                        label = ButtonCore._getTextLabelFromNode(node);
            
                    return label;
                },
            
                /**
                 * @method _getLabelHTML
                 * @description Getter for a button's `labelHTML` ATTR
                 * @return {String} The HTML label of the button
                 * @private
                 */
                _getLabelHTML: function () {
                    var node = this.getNode(),
                        labelHTML = ButtonCore._getHTMLFromNode(node);
            
                    return labelHTML;
                },
            
                /**
                 * @method _setLabel
                 * @description Setter for a button's `label` ATTR
                 * @param value {String} The value to set for `label`
                 * @param name {String} The name of this ATTR (`label`)
                 * @param opts {Object} Additional options
                 *    @param opts.src {String} A string identifying the callee.
                 *        `internal` will not sync this value with the `labelHTML` ATTR
                 * @return {String} The text label for the given node
                 * @private
                 */
                _setLabel: function (value, name, opts) {
                    var label = Y.Escape.html(value);
            
                    if (!opts || opts.src !== 'internal') {
                        this.set('labelHTML', label, {src: 'internal'});
                    }
            
                    return label;
                },
            
                /**
                 * @method _setLabelHTML
                 * @description Setter for a button's `labelHTML` ATTR
                 * @param value {String} The value to set for `labelHTML`
                 * @param name {String} The name of this ATTR (`labelHTML`)
                 * @param opts {Object} Additional options
                 *    @param opts.src {String} A string identifying the callee.
                 *        `internal` will not sync this value with the `label` ATTR
                 * @return {String} The HTML label for the given node
                 * @private
                 */
                _setLabelHTML: function (value, name, opts) {
                    var node = this.getNode(),
                        labelNode = ButtonCore._getLabelNodeFromParent(node),
                        nodeName = node.get('nodeName').toLowerCase();
            
                    if (nodeName === 'input') {
                        labelNode.set('value', value);
                    }
                    else {
                        labelNode.setHTML(value);
                    }
            
                    if (!opts || opts.src !== 'internal') {
                        this.set('label', value, {src: 'internal'});
                    }
            
                    return value;
                },
            
                /**
                 * @method _setDisabled
                 * @description Setter for the `disabled` ATTR
                 * @param value {boolean}
                 * @private
                 */
                _setDisabled: function(value) {
                    var node = this.getNode();
            
                    node.getDOMNode().disabled = value; // avoid rerunning setter when this === node
                    node.toggleClass(ButtonCore.CLASS_NAMES.DISABLED, value);
            
                    return value;
                }
            };
            
            // ButtonCore inherits from AttributeCore
            Y.mix(ButtonCore.prototype, AttributeCore.prototype);
            
            /**
             * Attribute configuration.
             *
             * @property ATTRS
             * @type {Object}
             * @protected
             * @static
             */
            ButtonCore.ATTRS = {
            
                /**
                 * The text of the button's label
                 *
                 * @config label
                 * @type String
                 */
                label: {
                    setter: '_setLabel',
                    getter: '_getLabel',
                    lazyAdd: false
                },
            
                /**
                 * The HTML of the button's label
                 *
                 * This attribute accepts HTML and inserts it into the DOM **without**
                 * sanitization.  This attribute should only be used with HTML that has
                 * either been escaped (using `Y.Escape.html`), or sanitized according to
                 * the requirements of your application.
                 *
                 * If all you need is support for text labels, please use the `label`
                 * attribute instead.
                 *
                 * @config labelHTML
                 * @type HTML
                 */
                labelHTML: {
                    setter: '_setLabelHTML',
                    getter: '_getLabelHTML',
                    lazyAdd: false
                },
            
                /**
                 * The button's enabled/disabled state
                 *
                 * @config disabled
                 * @type Boolean
                 */
                disabled: {
                    value: false,
                    setter: '_setDisabled',
                    lazyAdd: false
                }
            };
            
            /**
             * Name of this component.
             *
             * @property NAME
             * @type String
             * @static
             */
            ButtonCore.NAME = "button";
            
            /**
             * Array of static constants used to identify the classnames applied to DOM nodes
             *
             * @property CLASS_NAMES
             * @type {Object}
             * @public
             * @static
             */
            ButtonCore.CLASS_NAMES = {
                BUTTON  : getClassName('button'),
                DISABLED: getClassName('button', 'disabled'),
                SELECTED: getClassName('button', 'selected'),
                LABEL   : getClassName('button', 'label')
            };
            
            /**
             * Array of static constants used to for applying ARIA states
             *
             * @property ARIA_STATES
             * @type {Object}
             * @private
             * @static
             */
            ButtonCore.ARIA_STATES = {
                PRESSED : 'aria-pressed',
                CHECKED : 'aria-checked'
            };
            
            /**
             * Array of static constants used to for applying ARIA roles
             *
             * @property ARIA_ROLES
             * @type {Object}
             * @private
             * @static
             */
            ButtonCore.ARIA_ROLES = {
                BUTTON  : 'button',
                CHECKBOX: 'checkbox',
                TOGGLE  : 'toggle'
            };
            
            /**
             * Finds the label node within a button
             *
             * @method _getLabelNodeFromParent
             * @param node {Node} The parent node
             * @return {Node} The label node
             * @private
             * @static
             */
            ButtonCore._getLabelNodeFromParent = function (node) {
                var labelNode = (node.one('.' + ButtonCore.CLASS_NAMES.LABEL) || node);
            
                return labelNode;
            };
            
            /**
             * Gets a text label from a node
             *
             * @method _getTextLabelFromNode
             * @param node {Node} The parent node
             * @return {String} The text label for a given node
             * @private
             * @static
             */
            ButtonCore._getTextLabelFromNode = function (node) {
                var labelNode = ButtonCore._getLabelNodeFromParent(node),
                    nodeName = labelNode.get('nodeName').toLowerCase(),
                    label = labelNode.get(nodeName === 'input' ? 'value' : 'text');
            
                return label;
            };
            
            /**
             * A utility method that gets an HTML label from a given node
             *
             * @method _getHTMLFromNode
             * @param node {Node} The parent node
             * @return {String} The HTML label for a given node
             * @private
             * @static
             */
            ButtonCore._getHTMLFromNode = function (node) {
                var labelNode = ButtonCore._getLabelNodeFromParent(node),
                    label = labelNode.getHTML();
            
                return label;
            };
            
            /**
             * Gets the disabled attribute from a node
             *
             * @method _getDisabledFromNode
             * @param node {Node} The parent node
             * @return {boolean} The disabled state for a given node
             * @private
             * @static
             */
            ButtonCore._getDisabledFromNode = function (node) {
                return node.get('disabled');
            };
            
            // Export ButtonCore
            Y.ButtonCore = ButtonCore;