#

API Docs for: 3.10.3
Show: Inherited Protected Private Deprecated

# File: dom/js/dom-attrs.js

    /**
    * @for DOM
    * @module dom
    */
    var documentElement = Y.config.doc.documentElement,
        Y_DOM = Y.DOM,
        TAG_NAME = 'tagName',
        OWNER_DOCUMENT = 'ownerDocument',
        EMPTY_STRING = '',
        addFeature = Y.Features.add,
        testFeature = Y.Features.test;

    Y.mix(Y_DOM, {
        /**
         * Returns the text content of the HTMLElement.
         * @method getText
         * @param {HTMLElement} element The html element.
         * @return {String} The text content of the element (includes text of any descending elements).
         */
        getText: (documentElement.textContent !== undefined) ?
            function(element) {
                var ret = '';
                if (element) {
                    ret = element.textContent;
                }
                return ret || '';
            } : function(element) {
                var ret = '';
                if (element) {
                    ret = element.innerText || element.nodeValue; // might be a textNode
                }
                return ret || '';
            },

        /**
         * Sets the text content of the HTMLElement.
         * @method setText
         * @param {HTMLElement} element The html element.
         * @param {String} content The content to add.
         */
        setText: (documentElement.textContent !== undefined) ?
            function(element, content) {
                if (element) {
                    element.textContent = content;
                }
            } : function(element, content) {
                if ('innerText' in element) {
                    element.innerText = content;
                } else if ('nodeValue' in element) {
                    element.nodeValue = content;
                }
        },

        CUSTOM_ATTRIBUTES: (!documentElement.hasAttribute) ? { // IE < 8
            'for': 'htmlFor',
            'class': 'className'
        } : { // w3c
            'htmlFor': 'for',
            'className': 'class'
        },

        /**
         * Provides a normalized attribute interface.
         * @method setAttribute
         * @param {HTMLElement} el The target element for the attribute.
         * @param {String} attr The attribute to set.
         * @param {String} val The value of the attribute.
         */
        setAttribute: function(el, attr, val, ieAttr) {
            if (el && attr && el.setAttribute) {
                attr = Y_DOM.CUSTOM_ATTRIBUTES[attr] || attr;
                el.setAttribute(attr, val, ieAttr);
            }
            else { Y.log('bad input to setAttribute', 'warn', 'dom'); }
        },

        /**
         * Provides a normalized attribute interface.
         * @method getAttribute
         * @param {HTMLElement} el The target element for the attribute.
         * @param {String} attr The attribute to get.
         * @return {String} The current value of the attribute.
         */
        getAttribute: function(el, attr, ieAttr) {
            ieAttr = (ieAttr !== undefined) ? ieAttr : 2;
            var ret = '';
            if (el && attr && el.getAttribute) {
                attr = Y_DOM.CUSTOM_ATTRIBUTES[attr] || attr;
                ret = el.getAttribute(attr, ieAttr);

                if (ret === null) {
                    ret = ''; // per DOM spec
                }
            }
            else { Y.log('bad input to getAttribute', 'warn', 'dom'); }
            return ret;
        },

        VALUE_SETTERS: {},

        VALUE_GETTERS: {},

        getValue: function(node) {
            var ret = '', // TODO: return null?
                getter;

            if (node && node[TAG_NAME]) {
                getter = Y_DOM.VALUE_GETTERS[node[TAG_NAME].toLowerCase()];

                if (getter) {
                    ret = getter(node);
                } else {
                    ret = node.value;
                }
            }

            // workaround for IE8 JSON stringify bug
            // which converts empty string values to null
            if (ret === EMPTY_STRING) {
                ret = EMPTY_STRING; // for real
            }

            return (typeof ret === 'string') ? ret : '';
        },

        setValue: function(node, val) {
            var setter;

            if (node && node[TAG_NAME]) {
                setter = Y_DOM.VALUE_SETTERS[node[TAG_NAME].toLowerCase()];

                if (setter) {
                    setter(node, val);
                } else {
                    node.value = val;
                }
            }
        },

        creators: {}
    });

    addFeature('value-set', 'select', {
        test: function() {
            var node = Y.config.doc.createElement('select');
            node.innerHTML = '<option>1</option><option>2</option>';
            node.value = '2';
            return (node.value && node.value === '2');
        }
    });

    if (!testFeature('value-set', 'select')) {
        Y_DOM.VALUE_SETTERS.select = function(node, val) {
            for (var i = 0, options = node.getElementsByTagName('option'), option;
                    option = options[i++];) {
                if (Y_DOM.getValue(option) === val) {
                    option.selected = true;
                    //Y_DOM.setAttribute(option, 'selected', 'selected');
                    break;
                }
            }
        };
    }

    Y.mix(Y_DOM.VALUE_GETTERS, {
        button: function(node) {
            return (node.attributes && node.attributes.value) ? node.attributes.value.value : '';
        }
    });

    Y.mix(Y_DOM.VALUE_SETTERS, {
        // IE: node.value changes the button text, which should be handled via innerHTML
        button: function(node, val) {
            var attr = node.attributes.value;
            if (!attr) {
                attr = node[OWNER_DOCUMENT].createAttribute('value');
                node.setAttributeNode(attr);
            }

            attr.value = val;
        }
    });

    Y.mix(Y_DOM.VALUE_GETTERS, {
        option: function(node) {
            var attrs = node.attributes;
            return (attrs.value && attrs.value.specified) ? node.value : node.text;
        },

        select: function(node) {
            var val = node.value,
                options = node.options;

            if (options && options.length) {
                // TODO: implement multipe select
                if (node.multiple) {
                    Y.log('multiple select normalization not implemented', 'warn', 'DOM');
                } else if (node.selectedIndex > -1) {
                    val = Y_DOM.getValue(options[node.selectedIndex]);
                }
            }

            return val;
        }
    });