<commit_before>import "./style/index.less";
let tipVm;
export default {
    install(Vue, options){
        // tip组件模板
        const TipComponent = Vue.extend({
            template: `
                <transition name="fade">
                    <div :class="warpPlace" v-if="show">
                        <div class="ant-tooltip-content">
                                <div class="ant-tooltip-arrow"></div>
                                <div class="ant-tooltip-inner"><span v-html="tip"></span></div>
                        </div>
                    </div>
                </transition>`,
            computed:{
                warpPlace(){
                    return [
                        `ant-tooltip`,
                        `ant-tooltip-placement-${this.place}`
                    ]
                }
            }
        });

        /**
         * 获取元素的坐标位置
         * @param el
         * @returns {{top: number, left: number}}
         */
        function getOffset(el) {
            let x = 0;
            let y = 0;
            let ele = el;
            while (ele) {
                x += parseInt(ele.offsetLeft, 10);
                y += parseInt(ele.offsetTop, 10);
                ele = ele.offsetParent;
            }
            return { top: y, left: x };
        }
        /**
         * 关闭方法
         */
        function closeTooltip(el,binding){
            if (el.vm){
                if(!binding.controled)
                    // 延时关闭,给tip本身的鼠标事件留出时间
                    el.closeTimer = setTimeout(() => {
                        // show设置为false,触发view改变
                        el.vm.show = false;
                }, 100);
            }
        }

        /**
         * 显示方法
         */
        function openTooltip(el,binding){
            if(!el) return;

            // 创建一个新的tip组件实例,插入到body中
            tipVm = el.vm = new TipComponent({
                data : {
                    tip : binding.value, // 支持html内容
                    show: true,
                    place : binding.place
                }
            }).$mount();

            document.getElementsByTagName('body')[0].appendChild(el.vm.$el);

            //this.tooltipd = tooltipOptions.tipVm.$el;

            // 给tip组件本身绑定鼠标事件,鼠标移上去之后停止关闭操作（从而允许复制tip中的内容）,鼠标移开后关闭
            el.vm.$el.addEventListener('mouseover', () => {
                clearTimeout(el.closeTimer);
        });
            el.vm.$el.addEventListener('mouseout', function(){closeTooltip(el,binding)});
            el.vm.$el.addEventListener('click', function(){closeTooltip(el,binding)});

            //设置tooltip的位置
            const offset = getOffset(el);
            const eleWidth = el.offsetWidth;
            const eleHeight = el.offsetHeight;
            var left = offset.left  ;
            var top = offset.top  ;
            const tooltipHeight = el.vm.$el.offsetHeight;
            const tooltipWidth = el.vm.$el.offsetWidth;

            switch(binding.place.toUpperCase()){
                case 'TOP':
                    top = offset.top - tooltipHeight;
                    left = offset.left + eleWidth/2 - tooltipWidth/2;
                    break;
                case 'TOPLEFT':
                    top = offset.top - tooltipHeight;
                    left = offset.left  ;
                    break;
                case 'TOPRIGHT':
                    top = offset.top - tooltipHeight;
                    left = offset.left + eleWidth - tooltipWidth;
                    break;
                case 'BOTTOM':
                    top = offset.top + eleHeight;
                    left = offset.left + eleWidth/2 - tooltipWidth/2;
                    break;
                case 'BOTTOMLEFT':
                    top = offset.top + eleHeight;
                    left = offset.left;
                    break;
                case 'BOTTOMRIGHT':
                    top = offset.top + eleHeight;
                    left = offset.left + eleWidth - tooltipWidth;
                    break;
                case 'LEFT':
                    top = offset.top + eleHeight/2 - tooltipHeight/2;
                    left = offset.left - tooltipWidth;
                    break;
                case 'LEFTTOP':
                    top = offset.top
                    left = offset.left - tooltipWidth;
                    break;
                case 'LEFTBOTTOM':
                    top = offset.top + eleHeight - tooltipHeight;
                    left = offset.left - tooltipWidth;
                    break;
                case 'RIGHT':
                    top = offset.top + eleHeight/2 - tooltipHeight/2;
                    left = offset.left + eleWidth;
                    break;
                case 'RIGHTTOP':
                    top = offset.top
                    left = offset.left + eleWidth;
                    break;
                case 'RIGHTBOTTOM':
                    top = offset.top + eleHeight - tooltipHeight;
                    left = offset.left + eleWidth;
                    break;

            }
            // 设置位置
            el.vm.$el.style['left'] = left+'px';
            el.vm.$el.style['top'] = top+'px';
            el.vm.$el.style['position'] = 'absolute';
        }

        /**
         * 注册自定义指令tooltip
         */
        const tooltip = Vue.directive('tooltip', {
            /**
             * 指令第一次绑定到元素时调用
             * @param el
             * @param binding
             */
            bind: function (el,binding) {
                // 准备工作
                // 识别触发事件
                if (binding.arg === 'focus'){
                    binding.openTrigger = 'focus';
                    binding.closeTrigger = 'blur';
                }else{
                    binding.openTrigger = 'mouseenter';
                    binding.closeTrigger = 'mouseleave';
                }
                // 获取位置
                binding.place = Object.keys(binding.modifiers)[0] || 'top';
                binding.controled = Object.keys(binding.modifiers)[1] == 'controlled' ? true : false;
                // 绑定触发事件
                el.addEventListener(binding.openTrigger, function(){openTooltip(el,binding)});
                el.addEventListener(binding.closeTrigger, function(){closeTooltip(el,binding)});
                el.addEventListener('click', closeTooltip(el,binding));
            },

            /**
             *被绑定元素所在的模板更新时调用
             * @param value
             */
            update: function (bind) {
                //this.value = value;
                // 值更新时的工作
            },

            /**
             *指令与元素解绑时调用
             * @param binding
             */
            unbind: function (el,binding) {
                // 清理工作
                // 例如，删除 bind() 添加的事件监听器
                /*this.el.removeEventListener(binding.openTrigger,function(){openTooltip(el,binding)});
                 this.el.removeEventListener(binding.closeTrigger, function(){closeTooltip(el)});*/
            },
        });
    }
}<commit_msg>优化tooltip<commit_after>import "./style/index.less";
let tipVm;
export default {
    install(Vue, options){
        // tip组件模板
        const TipComponent = Vue.extend({
            template: `
                <transition name="fade">
                    <div :class="warpPlace" v-if="show">
                        <div class="ant-tooltip-content">
                                <div class="ant-tooltip-arrow"></div>
                                <div class="ant-tooltip-inner"><span v-html="tip"></span></div>
                        </div>
                    </div>
                </transition>`,
            computed:{
                warpPlace(){
                    return [
                        `ant-tooltip`,
                        `ant-tooltip-placement-${this.place}`
                    ]
                }
            }
        });

        /**
         * 获取元素的坐标位置
         * @param el
         * @returns {{top: number, left: number}}
         */
        function getOffset(el) {
            let x = 0;
            let y = 0;
            let ele = el;
            while (ele) {
                x += parseInt(ele.offsetLeft, 10);
                y += parseInt(ele.offsetTop, 10);
                ele = ele.offsetParent;
            }
            return { top: y, left: x };
        }
        /**
         * 关闭方法
         */
        function closeTooltip(el,binding,directClose=false){
            if (el.vm){
                if(!binding.controled) {
                    if (directClose) {
                        console.log('direct')
                        el.vm.show = false;
                    } else {
                        console.log('time out')
                        // 延时关闭,给tip本身的鼠标事件留出时间
                        el.closeTimer = setTimeout(() => {
                            // show设置为false,触发view改变
                            el.vm.show = false;
                        }, 100);
                    }
                }
            }
        }

        /**
         * 显示方法
         */
        function openTooltip(el,binding){
            if(!el) return;

            // 创建一个新的tip组件实例,插入到body中
            tipVm = el.vm = new TipComponent({
                data : {
                    tip : binding.value, // 支持html内容
                    show: true,
                    place : binding.place
                }
            }).$mount();

            document.getElementsByTagName('body')[0].appendChild(el.vm.$el);

            //this.tooltipd = tooltipOptions.tipVm.$el;

            // 给tip组件本身绑定鼠标事件,鼠标移上去之后停止关闭操作（从而允许复制tip中的内容）,鼠标移开后关闭
            el.vm.$el.addEventListener('mouseover', () => {
                clearTimeout(el.closeTimer);
            });
            el.vm.$el.addEventListener('mouseleave', function(){closeTooltip(el,binding,true)});
            el.vm.$el.addEventListener('click', function(){closeTooltip(el,binding,true)});

            //设置tooltip的位置
            const offset = getOffset(el);
            const eleWidth = el.offsetWidth;
            const eleHeight = el.offsetHeight;
            var left = offset.left  ;
            var top = offset.top  ;
            const tooltipHeight = el.vm.$el.offsetHeight;
            const tooltipWidth = el.vm.$el.offsetWidth;

            switch(binding.place.toUpperCase()){
                case 'TOP':
                    top = offset.top - tooltipHeight;
                    left = offset.left + eleWidth/2 - tooltipWidth/2;
                    break;
                case 'TOPLEFT':
                    top = offset.top - tooltipHeight;
                    left = offset.left  ;
                    break;
                case 'TOPRIGHT':
                    top = offset.top - tooltipHeight;
                    left = offset.left + eleWidth - tooltipWidth;
                    break;
                case 'BOTTOM':
                    top = offset.top + eleHeight;
                    left = offset.left + eleWidth/2 - tooltipWidth/2;
                    break;
                case 'BOTTOMLEFT':
                    top = offset.top + eleHeight;
                    left = offset.left;
                    break;
                case 'BOTTOMRIGHT':
                    top = offset.top + eleHeight;
                    left = offset.left + eleWidth - tooltipWidth;
                    break;
                case 'LEFT':
                    top = offset.top + eleHeight/2 - tooltipHeight/2;
                    left = offset.left - tooltipWidth;
                    break;
                case 'LEFTTOP':
                    top = offset.top
                    left = offset.left - tooltipWidth;
                    break;
                case 'LEFTBOTTOM':
                    top = offset.top + eleHeight - tooltipHeight;
                    left = offset.left - tooltipWidth;
                    break;
                case 'RIGHT':
                    top = offset.top + eleHeight/2 - tooltipHeight/2;
                    left = offset.left + eleWidth;
                    break;
                case 'RIGHTTOP':
                    top = offset.top
                    left = offset.left + eleWidth;
                    break;
                case 'RIGHTBOTTOM':
                    top = offset.top + eleHeight - tooltipHeight;
                    left = offset.left + eleWidth;
                    break;

            }
            // 设置位置
            el.vm.$el.style['left'] = left+'px';
            el.vm.$el.style['top'] = top+'px';
            el.vm.$el.style['position'] = 'absolute';
        }

        /**
         * 注册自定义指令tooltip
         */
        const tooltip = Vue.directive('tooltip', {
            /**
             * 指令第一次绑定到元素时调用
             * @param el
             * @param binding
             */
            bind: function (el,binding) {
                // 准备工作
                // 识别触发事件
                if (binding.arg === 'focus'){
                    binding.openTrigger = 'focus';
                    binding.closeTrigger = 'blur';
                }else{
                    binding.openTrigger = 'mouseenter';
                    binding.closeTrigger = 'mouseleave';
                }
                // 获取位置
                binding.place = Object.keys(binding.modifiers)[0] || 'top';
                binding.controled = Object.keys(binding.modifiers)[1] == 'controlled' ? true : false;
                // 绑定触发事件
                el.addEventListener(binding.openTrigger, function(){openTooltip(el,binding)});
                el.addEventListener(binding.closeTrigger, function(){closeTooltip(el,binding)});
                el.addEventListener('click', closeTooltip(el,binding));
            },

            /**
             *指令与元素解绑时调用
             * @param binding
             */
            unbind: function (el,binding) {
                // 清理工作
                // 例如，删除 bind() 添加的事件监听器
                /*this.el.removeEventListener(binding.openTrigger,function(){openTooltip(el,binding)});
                 this.el.removeEventListener(binding.closeTrigger, function(){closeTooltip(el,binding)});*/
            },
        });
    }
}
{'fraction_non_alphanumeric': 0.11069271758436945, 'fraction_numerical': 0.002841918294849023, 'mean_word_length': 1.0285343709468222, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5865973', 'n_tokens_mistral': 3835, 'n_tokens_neox': 3737, 'n_words': 629}