all files / directives/ class.hover.active.js

100% Statements 72/72
92.16% Branches 47/51
100% Functions 7/7
100% Lines 72/72
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125        69× 69× 75× 75× 75× 25× 50× 28× 22×           69×           41× 41× 41× 41× 39×   41×   41×   41× 33×   33× 33×       33× 33×   33× 33× 33× 33× 33×       33×   33× 33× 99× 66× 33× 30×                                           30× 30× 25× 25×            
//根据VM的属性值或表达式的值切换类名,ms-class='xxx yyy zzz:flag'
//http://www.cnblogs.com/rubylouvre/archive/2012/12/17/2818540.html
import { avalon, directives, getLongID as markID } from '../seed/core'
 
function classNames() {
    var classes = []
    for (var i = 0; i < arguments.length; i++) {
        var arg = arguments[i]
        var argType = typeof arg
        if (argType === 'string' || argType === 'number' || arg === true) {
            classes.push(arg)
        } else if (Array.isArray(arg)) {
            classes.push(classNames.apply(null, arg))
        } else if (argType === 'object') {
            for (var key in arg) {
                if (arg.hasOwnProperty(key) && arg[key]) {
                    classes.push(key)
                }
            }
        }
    }
 
    return classes.join(' ')
}
 
 
 
avalon.directive('class', {
    diff: function (newVal, oldVal) {
        var type = this.type
        var vdom = this.node
        var classEvent = vdom.classEvent || {}
        if (type === 'hover') {//在移出移入时切换类名
            classEvent.mouseenter = activateClass
            classEvent.mouseleave = abandonClass
        } else if (type === 'active') {//在获得焦点时切换类名
            classEvent.tabIndex = vdom.props.tabindex || -1
            classEvent.mousedown = activateClass
            classEvent.mouseup = abandonClass
            classEvent.mouseleave = abandonClass
        }
        vdom.classEvent = classEvent
 
        var className = classNames(newVal)
 
        if (typeof oldVal === void 0 || oldVal !== className) {
            this.value = className
 
            vdom['change-' + type] = className
            return true
        }
    },
    update: function (vdom, value) {
        var dom = vdom.dom
        Eif (dom && dom.nodeType == 1) {
 
            var dirType = this.type
            var change = 'change-' + dirType
            var classEvent = vdom.classEvent
            Eif (classEvent) {
                for (var i in classEvent) {
                    if (i === 'tabIndex') {
                        dom[i] = classEvent[i]
                    } else {
                        avalon.bind(dom, i, classEvent[i])
                    }
                }
                vdom.classEvent = {}
            }
            var names = ['class', 'hover', 'active']
            names.forEach(function (type) {
                if (dirType !== type)
                    return
                if (type === 'class') {
                    dom && setClass(dom, value)
                } else {
                    var oldClass = dom.getAttribute(change)
                    if (oldClass) {
                        avalon(dom).removeClass(oldClass)
                    }
                    var name = 'change-' + type
                    dom.setAttribute(name, value)
                }
            })
        }
    }
})
 
directives.active = directives.hover = directives['class']
 
 
var classMap = {
    mouseenter: 'change-hover',
    mouseleave: 'change-hover',
    mousedown: 'change-active',
    mouseup: 'change-active'
}
 
function activateClass(e) {
    var elem = e.target
    avalon(elem).addClass(elem.getAttribute(classMap[e.type]) || '')
}
 
function abandonClass(e) {
    var elem = e.target
    var name = classMap[e.type]
    avalon(elem).removeClass(elem.getAttribute(name) || '')
    if (name !== 'change-active') {
        avalon(elem).removeClass(elem.getAttribute('change-active') || '')
    }
}
 
function setClass(dom, neo) {
    var old = dom.getAttribute('change-class')
    if (old !== neo) {
        avalon(dom).removeClass(old).addClass(neo)
        dom.setAttribute('change-class', neo)
    }
 
}
 
markID(activateClass)
markID(abandonClass)