/* @flow */
import { isIE, isIE9, isEdge } from 'core/util/env'
import {
extend,
isDef,
isUndef
} from 'shared/util'
import {
isXlink,
xlinkNS,
getXlinkProp,
isBooleanAttr,
isEnumeratedAttr,
isFalsyAttrValue,
convertEnumeratedValue
} from 'web/util/index'
function updateAttrs (oldVnode: VNodeWithData, vnode: VNodeWithData) {
const opts = vnode.componentOptions
if (isDef(opts) && opts.Ctor.options.inheritAttrs === false) {
return
}
if (isUndef(oldVnode.data.attrs) && isUndef(vnode.data.attrs)) {
return
}
let key, cur, old
const elm = vnode.elm
const oldAttrs = oldVnode.data.attrs || {}
let attrs: any = vnode.data.attrs || {}
// clone observed objects, as the user probably wants to mutate it
if (isDef(attrs.__ob__)) {
attrs = vnode.data.attrs = extend({}, attrs)
}
for (key in attrs) {
cur = attrs[key]
old = oldAttrs[key]
if (old !== cur) {
setAttr(elm, key, cur, vnode.data.pre)
}
}
// #4391: in IE9, setting type can reset value for input[type=radio]
// #6666: IE/Edge forces progress value down to 1 before setting a max
/* istanbul ignore if */
if ((isIE || isEdge) && attrs.value !== oldAttrs.value) {
setAttr(elm, 'value', attrs.value)
}
for (key in oldAttrs) {
if (isUndef(attrs[key])) {
if (isXlink(key)) {
elm.removeAttributeNS(xlinkNS, getXlinkProp(key))
} else if (!isEnumeratedAttr(key)) {
elm.removeAttribute(key)
}
}
}
}
function setAttr (el: Element, key: string, value: any, isInPre: any) {
if (isInPre || el.tagName.indexOf('-') > -1) {
baseSetAttr(el, key, value)
} else if (isBooleanAttr(key)) {
// set attribute for blank value
// e.g.
if (isFalsyAttrValue(value)) {
el.removeAttribute(key)
} else {
// technically allowfullscreen is a boolean attribute for