RubyLouvre/avalon

View on GitHub
src/dom/attr/compact.js

Summary

Maintainability
C
1 day
Test Coverage
import { avalon, window, document } from '../../seed/core'
import { propMap } from './propMap'
import { isVML } from './isVML'
import { compactParseJSON } from './parseJSON.compact'

var rsvg = /^\[object SVG\w*Element\]$/
var ramp = /&/g
export function updateAttrs(node, attrs) {
    for (var attrName in attrs) {
        try {
            var val = attrs[attrName]
                // 处理路径属性
                /* istanbul ignore if*/

            //处理HTML5 data-*属性 SVG
            if (attrName.indexOf('data-') === 0 || rsvg.test(node)) {
                node.setAttribute(attrName, val)
            } else {
                var propName = propMap[attrName] || attrName
                    /* istanbul ignore if */
                if (typeof node[propName] === 'boolean') {
                    if(propName === 'checked'){
                        node.defaultChecked = !!val
                    }
                    node[propName] = !!val
                        //布尔属性必须使用el.xxx = true|false方式设值
                        //如果为false, IE全系列下相当于setAttribute(xxx,''),
                        //会影响到样式,需要进一步处理
                }

                if (val === false) { //移除属性
                    node.removeAttribute(propName)
                    continue
                }
                //IE6中classNamme, htmlFor等无法检测它们为内建属性 
                if (avalon.msie < 8 && /[A-Z]/.test(propName)) {
                    node[propName] = val + ''
                    continue
                }
                //SVG只能使用setAttribute(xxx, yyy), VML只能使用node.xxx = yyy ,
                //HTML的固有属性必须node.xxx = yyy
                /* istanbul ignore next */
                var isInnate = (!avalon.modern && isVML(node)) ? true :
                    isInnateProps(node.nodeName, attrName)
                if (isInnate) {
                    if (attrName === 'href' || attrName === 'src') {
                        /* istanbul ignore if */
                        if (avalon.msie < 8) {
                            val = String(val).replace(ramp, '&') //处理IE67自动转义的问题
                        }
                    }
                    node[propName] = val + ''
                } else {
                    node.setAttribute(attrName, val)
                }
            }
        } catch (e) {
            // 对象不支持此属性或方法 src https://github.com/ecomfe/zrender 
            // 未知名称。\/n
            // e.message大概这样,需要trim
            //IE6-8,元素节点不支持其他元素节点的内置属性,如src, href, for
            /* istanbul ignore next */
            avalon.log(String(e.message).trim(), attrName, val)
        }
    }
}
var innateMap = {}

function isInnateProps(nodeName, attrName) {
    var key = nodeName + ":" + attrName
    if (key in innateMap) {
        return innateMap[key]
    }
    return innateMap[key] = (attrName in document.createElement(nodeName))
}
try {
    avalon.parseJSON = JSON.parse
} catch (e) {
    /* istanbul ignore next */
    avalon.parseJSON = compactParseJSON
}

avalon.fn.attr = function(name, value) {
    if (arguments.length === 2) {
        this[0].setAttribute(name, value)
        return this
    } else {
        return this[0].getAttribute(name)
    }
}