/* @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