function Tooltip(ele, tmpl, opts) { 'use strict' if(!(this instanceof Tooltip)) return new Tooltip(ele, opts); var events = new EventManager(), paused = false, tt = getElementFromString(''), te = tt.querySelector('view'), o = opts || {}, setup; if(!tmpl) tmpl = ele.getAttribute('title'); ele.removeAttribute('title'); this.exit = function exit() { events.reset(); if(tt.parentNode) tt.parentNode.removeChild(tt); events = tt = o = null; }; this.show = show; this.hide = hide; this.update = function update(data) { te.innerHTML = !!data ? render(tmpl, data) : tmpl; } this.pause = function(){ paused = true; hide(); }; this.resume = function(){ paused = false; }; te.classList.add(o.arrow || 'left'); te.classList.add(o.className || 'royal'); if(o.showOnFocus) { events.add(ele, 'focus', this.show.bind(this)); events.add(ele, 'blur', this.hide.bind(this)); } if(o.showOnHover) { events.add(ele, 'mouseover', this.show.bind(this)); events.add(ele, 'mouseout', this.hide.bind(this)); } function show() { if(paused){ return } if(typeof opts.onShow === 'function'){ opts.onShow(); } tt.classList.remove('noDisplay'); updatePos(); } function hide() { tt.classList.add('noDisplay'); } function updatePos() { if(setup) return; document.body.appendChild(tt); if(!te.innerHTML.length) te.innerHTML = tmpl; var er = ele.getBoundingClientRect(), tr = te.getBoundingClientRect(); tt.style.top = (er.top + (er.height / 2)) + 'px'; tt.style.left = (er.left + er.width) + 'px'; te.style.top = -(tr.height / 2) + 'px'; te.style.left = '25px'; } }