|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;(function ($, window, document) { |
|
|
|
|
|
var pluginName = "tooltipster", |
|
|
defaults = { |
|
|
animation: 'fade', |
|
|
arrow: true, |
|
|
arrowColor: '', |
|
|
autoClose: true, |
|
|
content: null, |
|
|
contentAsHTML: false, |
|
|
contentCloning: true, |
|
|
debug: true, |
|
|
delay: 200, |
|
|
minWidth: 0, |
|
|
maxWidth: null, |
|
|
functionInit: function(origin, content) {}, |
|
|
functionBefore: function(origin, continueTooltip) { |
|
|
continueTooltip(); |
|
|
}, |
|
|
functionReady: function(origin, tooltip) {}, |
|
|
functionAfter: function(origin) {}, |
|
|
hideOnClick: false, |
|
|
icon: '(?)', |
|
|
iconCloning: true, |
|
|
iconDesktop: false, |
|
|
iconTouch: false, |
|
|
iconTheme: 'tooltipster-icon', |
|
|
interactive: false, |
|
|
interactiveTolerance: 350, |
|
|
multiple: false, |
|
|
offsetX: 0, |
|
|
offsetY: 0, |
|
|
onlyOne: false, |
|
|
position: 'top', |
|
|
positionTracker: false, |
|
|
positionTrackerCallback: function(origin){ |
|
|
|
|
|
|
|
|
if(this.option('trigger') == 'hover' && this.option('autoClose')) { |
|
|
this.hide(); |
|
|
} |
|
|
}, |
|
|
restoration: 'current', |
|
|
speed: 350, |
|
|
timer: 0, |
|
|
theme: 'tooltipster-default', |
|
|
touchDevices: true, |
|
|
trigger: 'hover', |
|
|
updateAnimation: true |
|
|
}; |
|
|
|
|
|
function Plugin(element, options) { |
|
|
|
|
|
|
|
|
|
|
|
this.bodyOverflowX; |
|
|
|
|
|
this.callbacks = { |
|
|
hide: [], |
|
|
show: [] |
|
|
}; |
|
|
this.checkInterval = null; |
|
|
|
|
|
this.Content; |
|
|
|
|
|
this.$el = $(element); |
|
|
|
|
|
|
|
|
this.$elProxy; |
|
|
this.elProxyPosition; |
|
|
this.enabled = true; |
|
|
this.options = $.extend({}, defaults, options); |
|
|
this.mouseIsOverProxy = false; |
|
|
|
|
|
this.namespace = 'tooltipster-'+ Math.round(Math.random()*100000); |
|
|
|
|
|
this.Status = 'hidden'; |
|
|
this.timerHide = null; |
|
|
this.timerShow = null; |
|
|
|
|
|
this.$tooltip; |
|
|
|
|
|
|
|
|
this.options.iconTheme = this.options.iconTheme.replace('.', ''); |
|
|
this.options.theme = this.options.theme.replace('.', ''); |
|
|
|
|
|
|
|
|
|
|
|
this._init(); |
|
|
} |
|
|
|
|
|
Plugin.prototype = { |
|
|
|
|
|
_init: function() { |
|
|
|
|
|
var self = this; |
|
|
|
|
|
|
|
|
if (document.querySelector) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var initialTitle = null; |
|
|
|
|
|
if (self.$el.data('tooltipster-initialTitle') === undefined) { |
|
|
|
|
|
initialTitle = self.$el.attr('title'); |
|
|
|
|
|
|
|
|
if (initialTitle === undefined) initialTitle = null; |
|
|
|
|
|
self.$el.data('tooltipster-initialTitle', initialTitle); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (self.options.content !== null){ |
|
|
self._content_set(self.options.content); |
|
|
} |
|
|
else { |
|
|
self._content_set(initialTitle); |
|
|
} |
|
|
|
|
|
var c = self.options.functionInit.call(self.$el, self.$el, self.Content); |
|
|
if(typeof c !== 'undefined') self._content_set(c); |
|
|
|
|
|
self.$el |
|
|
|
|
|
.removeAttr('title') |
|
|
|
|
|
.addClass('tooltipstered'); |
|
|
|
|
|
|
|
|
|
|
|
if ((!deviceHasTouchCapability && self.options.iconDesktop) || (deviceHasTouchCapability && self.options.iconTouch)) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(typeof self.options.icon === 'string'){ |
|
|
|
|
|
self.$elProxy = $('<span class="'+ self.options.iconTheme +'"></span>'); |
|
|
self.$elProxy.text(self.options.icon); |
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
if (self.options.iconCloning) self.$elProxy = self.options.icon.clone(true); |
|
|
else self.$elProxy = self.options.icon; |
|
|
} |
|
|
|
|
|
self.$elProxy.insertAfter(self.$el); |
|
|
} |
|
|
else { |
|
|
self.$elProxy = self.$el; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (self.options.trigger == 'hover') { |
|
|
|
|
|
|
|
|
self.$elProxy |
|
|
.on('mouseenter.'+ self.namespace, function() { |
|
|
if (!deviceIsPureTouch() || self.options.touchDevices) { |
|
|
self.mouseIsOverProxy = true; |
|
|
self._show(); |
|
|
} |
|
|
}) |
|
|
.on('mouseleave.'+ self.namespace, function() { |
|
|
if (!deviceIsPureTouch() || self.options.touchDevices) { |
|
|
self.mouseIsOverProxy = false; |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
if (deviceHasTouchCapability && self.options.touchDevices) { |
|
|
|
|
|
|
|
|
self.$elProxy.on('touchstart.'+ self.namespace, function() { |
|
|
self._showNow(); |
|
|
}); |
|
|
} |
|
|
} |
|
|
else if (self.options.trigger == 'click') { |
|
|
|
|
|
|
|
|
self.$elProxy.on('click.'+ self.namespace, function() { |
|
|
if (!deviceIsPureTouch() || self.options.touchDevices) { |
|
|
self._show(); |
|
|
} |
|
|
}); |
|
|
} |
|
|
} |
|
|
}, |
|
|
|
|
|
|
|
|
_show: function() { |
|
|
|
|
|
var self = this; |
|
|
|
|
|
if (self.Status != 'shown' && self.Status != 'appearing') { |
|
|
|
|
|
if (self.options.delay) { |
|
|
self.timerShow = setTimeout(function(){ |
|
|
|
|
|
|
|
|
if (self.options.trigger == 'click' || (self.options.trigger == 'hover' && self.mouseIsOverProxy)) { |
|
|
self._showNow(); |
|
|
} |
|
|
}, self.options.delay); |
|
|
} |
|
|
else self._showNow(); |
|
|
} |
|
|
}, |
|
|
|
|
|
|
|
|
_showNow: function(callback) { |
|
|
|
|
|
var self = this; |
|
|
|
|
|
|
|
|
self.options.functionBefore.call(self.$el, self.$el, function() { |
|
|
|
|
|
|
|
|
if (self.enabled && self.Content !== null) { |
|
|
|
|
|
|
|
|
if (callback) self.callbacks.show.push(callback); |
|
|
self.callbacks.hide = []; |
|
|
|
|
|
|
|
|
clearTimeout(self.timerShow); |
|
|
self.timerShow = null; |
|
|
clearTimeout(self.timerHide); |
|
|
self.timerHide = null; |
|
|
|
|
|
|
|
|
if (self.options.onlyOne) { |
|
|
$('.tooltipstered').not(self.$el).each(function(i,el) { |
|
|
|
|
|
var $el = $(el), |
|
|
nss = $el.data('tooltipster-ns'); |
|
|
|
|
|
|
|
|
$.each(nss, function(i, ns){ |
|
|
var instance = $el.data(ns), |
|
|
|
|
|
s = instance.status(), |
|
|
ac = instance.option('autoClose'); |
|
|
|
|
|
if (s !== 'hidden' && s !== 'disappearing' && ac) { |
|
|
instance.hide(); |
|
|
} |
|
|
}); |
|
|
}); |
|
|
} |
|
|
|
|
|
var finish = function() { |
|
|
self.Status = 'shown'; |
|
|
|
|
|
|
|
|
$.each(self.callbacks.show, function(i,c) { c.call(self.$el); }); |
|
|
self.callbacks.show = []; |
|
|
}; |
|
|
|
|
|
|
|
|
if (self.Status !== 'hidden') { |
|
|
|
|
|
|
|
|
var extraTime = 0; |
|
|
|
|
|
|
|
|
if (self.Status === 'disappearing') { |
|
|
|
|
|
self.Status = 'appearing'; |
|
|
|
|
|
if (supportsTransitions()) { |
|
|
|
|
|
self.$tooltip |
|
|
.clearQueue() |
|
|
.removeClass('tooltipster-dying') |
|
|
.addClass('tooltipster-'+ self.options.animation +'-show'); |
|
|
|
|
|
if (self.options.speed > 0) self.$tooltip.delay(self.options.speed); |
|
|
|
|
|
self.$tooltip.queue(finish); |
|
|
} |
|
|
else { |
|
|
|
|
|
self.$tooltip |
|
|
.stop() |
|
|
.fadeIn(finish); |
|
|
} |
|
|
} |
|
|
|
|
|
else if(self.Status === 'shown') { |
|
|
finish(); |
|
|
} |
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
self.Status = 'appearing'; |
|
|
|
|
|
|
|
|
var extraTime = self.options.speed; |
|
|
|
|
|
|
|
|
self.bodyOverflowX = $('body').css('overflow-x'); |
|
|
$('body').css('overflow-x', 'hidden'); |
|
|
|
|
|
|
|
|
var animation = 'tooltipster-' + self.options.animation, |
|
|
animationSpeed = '-webkit-transition-duration: '+ self.options.speed +'ms; -webkit-animation-duration: '+ self.options.speed +'ms; -moz-transition-duration: '+ self.options.speed +'ms; -moz-animation-duration: '+ self.options.speed +'ms; -o-transition-duration: '+ self.options.speed +'ms; -o-animation-duration: '+ self.options.speed +'ms; -ms-transition-duration: '+ self.options.speed +'ms; -ms-animation-duration: '+ self.options.speed +'ms; transition-duration: '+ self.options.speed +'ms; animation-duration: '+ self.options.speed +'ms;', |
|
|
minWidth = self.options.minWidth ? 'min-width:'+ Math.round(self.options.minWidth) +'px;' : '', |
|
|
maxWidth = self.options.maxWidth ? 'max-width:'+ Math.round(self.options.maxWidth) +'px;' : '', |
|
|
pointerEvents = self.options.interactive ? 'pointer-events: auto;' : ''; |
|
|
|
|
|
|
|
|
self.$tooltip = $('<div class="tooltipster-base '+ self.options.theme +'" style="'+ minWidth +' '+ maxWidth +' '+ pointerEvents +' '+ animationSpeed +'"><div class="tooltipster-content"></div></div>'); |
|
|
|
|
|
|
|
|
if (supportsTransitions()) self.$tooltip.addClass(animation); |
|
|
|
|
|
|
|
|
self._content_insert(); |
|
|
|
|
|
|
|
|
self.$tooltip.appendTo('body'); |
|
|
|
|
|
|
|
|
self.reposition(); |
|
|
|
|
|
|
|
|
self.options.functionReady.call(self.$el, self.$el, self.$tooltip); |
|
|
|
|
|
|
|
|
if (supportsTransitions()) { |
|
|
|
|
|
self.$tooltip.addClass(animation + '-show'); |
|
|
|
|
|
if(self.options.speed > 0) self.$tooltip.delay(self.options.speed); |
|
|
|
|
|
self.$tooltip.queue(finish); |
|
|
} |
|
|
else { |
|
|
self.$tooltip.css('display', 'none').fadeIn(self.options.speed, finish); |
|
|
} |
|
|
|
|
|
|
|
|
self._interval_set(); |
|
|
|
|
|
|
|
|
$(window).on('scroll.'+ self.namespace +' resize.'+ self.namespace, function() { |
|
|
self.reposition(); |
|
|
}); |
|
|
|
|
|
|
|
|
if (self.options.autoClose) { |
|
|
|
|
|
|
|
|
$('body').off('.'+ self.namespace); |
|
|
|
|
|
|
|
|
if (self.options.trigger == 'hover') { |
|
|
|
|
|
|
|
|
if (deviceHasTouchCapability) { |
|
|
|
|
|
setTimeout(function() { |
|
|
|
|
|
$('body').on('touchstart.'+ self.namespace, function() { |
|
|
self.hide(); |
|
|
}); |
|
|
}, 0); |
|
|
} |
|
|
|
|
|
|
|
|
if (self.options.interactive) { |
|
|
|
|
|
|
|
|
if (deviceHasTouchCapability) { |
|
|
self.$tooltip.on('touchstart.'+ self.namespace, function(event) { |
|
|
event.stopPropagation(); |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
var tolerance = null; |
|
|
|
|
|
self.$elProxy.add(self.$tooltip) |
|
|
|
|
|
.on('mouseleave.'+ self.namespace + '-autoClose', function() { |
|
|
clearTimeout(tolerance); |
|
|
tolerance = setTimeout(function(){ |
|
|
self.hide(); |
|
|
}, self.options.interactiveTolerance); |
|
|
}) |
|
|
|
|
|
.on('mouseenter.'+ self.namespace + '-autoClose', function() { |
|
|
clearTimeout(tolerance); |
|
|
}); |
|
|
} |
|
|
|
|
|
else { |
|
|
self.$elProxy.on('mouseleave.'+ self.namespace + '-autoClose', function() { |
|
|
self.hide(); |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
if (self.options.hideOnClick) { |
|
|
|
|
|
self.$elProxy.on('click.'+ self.namespace + '-autoClose', function() { |
|
|
self.hide(); |
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
else if(self.options.trigger == 'click'){ |
|
|
|
|
|
|
|
|
setTimeout(function() { |
|
|
$('body').on('click.'+ self.namespace +' touchstart.'+ self.namespace, function() { |
|
|
self.hide(); |
|
|
}); |
|
|
}, 0); |
|
|
|
|
|
|
|
|
if (self.options.interactive) { |
|
|
|
|
|
|
|
|
self.$tooltip.on('click.'+ self.namespace +' touchstart.'+ self.namespace, function(event) { |
|
|
event.stopPropagation(); |
|
|
}); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (self.options.timer > 0) { |
|
|
|
|
|
self.timerHide = setTimeout(function() { |
|
|
self.timerHide = null; |
|
|
self.hide(); |
|
|
}, self.options.timer + extraTime); |
|
|
} |
|
|
} |
|
|
}); |
|
|
}, |
|
|
|
|
|
_interval_set: function() { |
|
|
|
|
|
var self = this; |
|
|
|
|
|
self.checkInterval = setInterval(function() { |
|
|
|
|
|
|
|
|
if ( |
|
|
|
|
|
$('body').find(self.$el).length === 0 |
|
|
|
|
|
|| $('body').find(self.$elProxy).length === 0 |
|
|
|
|
|
|| self.Status == 'hidden' |
|
|
|
|
|
|| $('body').find(self.$tooltip).length === 0 |
|
|
) { |
|
|
|
|
|
if (self.Status == 'shown' || self.Status == 'appearing') self.hide(); |
|
|
|
|
|
|
|
|
self._interval_cancel(); |
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
if(self.options.positionTracker){ |
|
|
|
|
|
var p = self._repositionInfo(self.$elProxy), |
|
|
identical = false; |
|
|
|
|
|
|
|
|
if(areEqual(p.dimension, self.elProxyPosition.dimension)){ |
|
|
|
|
|
|
|
|
if(self.$elProxy.css('position') === 'fixed'){ |
|
|
if(areEqual(p.position, self.elProxyPosition.position)) identical = true; |
|
|
} |
|
|
|
|
|
else { |
|
|
if(areEqual(p.offset, self.elProxyPosition.offset)) identical = true; |
|
|
} |
|
|
} |
|
|
|
|
|
if(!identical){ |
|
|
self.reposition(); |
|
|
self.options.positionTrackerCallback.call(self, self.$el); |
|
|
} |
|
|
} |
|
|
} |
|
|
}, 200); |
|
|
}, |
|
|
|
|
|
_interval_cancel: function() { |
|
|
clearInterval(this.checkInterval); |
|
|
|
|
|
this.checkInterval = null; |
|
|
}, |
|
|
|
|
|
_content_set: function(content) { |
|
|
|
|
|
|
|
|
if (typeof content === 'object' && content !== null && this.options.contentCloning) { |
|
|
content = content.clone(true); |
|
|
} |
|
|
this.Content = content; |
|
|
}, |
|
|
|
|
|
_content_insert: function() { |
|
|
|
|
|
var self = this, |
|
|
$d = this.$tooltip.find('.tooltipster-content'); |
|
|
|
|
|
if (typeof self.Content === 'string' && !self.options.contentAsHTML) { |
|
|
$d.text(self.Content); |
|
|
} |
|
|
else { |
|
|
$d |
|
|
.empty() |
|
|
.append(self.Content); |
|
|
} |
|
|
}, |
|
|
|
|
|
_update: function(content) { |
|
|
|
|
|
var self = this; |
|
|
|
|
|
|
|
|
self._content_set(content); |
|
|
|
|
|
if (self.Content !== null) { |
|
|
|
|
|
|
|
|
if (self.Status !== 'hidden') { |
|
|
|
|
|
|
|
|
self._content_insert(); |
|
|
|
|
|
|
|
|
self.reposition(); |
|
|
|
|
|
|
|
|
if (self.options.updateAnimation) { |
|
|
|
|
|
if (supportsTransitions()) { |
|
|
|
|
|
self.$tooltip.css({ |
|
|
'width': '', |
|
|
'-webkit-transition': 'all ' + self.options.speed + 'ms, width 0ms, height 0ms, left 0ms, top 0ms', |
|
|
'-moz-transition': 'all ' + self.options.speed + 'ms, width 0ms, height 0ms, left 0ms, top 0ms', |
|
|
'-o-transition': 'all ' + self.options.speed + 'ms, width 0ms, height 0ms, left 0ms, top 0ms', |
|
|
'-ms-transition': 'all ' + self.options.speed + 'ms, width 0ms, height 0ms, left 0ms, top 0ms', |
|
|
'transition': 'all ' + self.options.speed + 'ms, width 0ms, height 0ms, left 0ms, top 0ms' |
|
|
}).addClass('tooltipster-content-changing'); |
|
|
|
|
|
|
|
|
setTimeout(function() { |
|
|
|
|
|
if(self.Status != 'hidden'){ |
|
|
|
|
|
self.$tooltip.removeClass('tooltipster-content-changing'); |
|
|
|
|
|
|
|
|
setTimeout(function() { |
|
|
|
|
|
if(self.Status !== 'hidden'){ |
|
|
self.$tooltip.css({ |
|
|
'-webkit-transition': self.options.speed + 'ms', |
|
|
'-moz-transition': self.options.speed + 'ms', |
|
|
'-o-transition': self.options.speed + 'ms', |
|
|
'-ms-transition': self.options.speed + 'ms', |
|
|
'transition': self.options.speed + 'ms' |
|
|
}); |
|
|
} |
|
|
}, self.options.speed); |
|
|
} |
|
|
}, self.options.speed); |
|
|
} |
|
|
else { |
|
|
self.$tooltip.fadeTo(self.options.speed, 0.5, function() { |
|
|
if(self.Status != 'hidden'){ |
|
|
self.$tooltip.fadeTo(self.options.speed, 1); |
|
|
} |
|
|
}); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
else { |
|
|
self.hide(); |
|
|
} |
|
|
}, |
|
|
|
|
|
_repositionInfo: function($el) { |
|
|
return { |
|
|
dimension: { |
|
|
height: $el.outerHeight(false), |
|
|
width: $el.outerWidth(false) |
|
|
}, |
|
|
offset: $el.offset(), |
|
|
position: { |
|
|
left: parseInt($el.css('left')), |
|
|
top: parseInt($el.css('top')) |
|
|
} |
|
|
}; |
|
|
}, |
|
|
|
|
|
hide: function(callback) { |
|
|
|
|
|
var self = this; |
|
|
|
|
|
|
|
|
if (callback) self.callbacks.hide.push(callback); |
|
|
self.callbacks.show = []; |
|
|
|
|
|
|
|
|
clearTimeout(self.timerShow); |
|
|
self.timerShow = null; |
|
|
clearTimeout(self.timerHide); |
|
|
self.timerHide = null; |
|
|
|
|
|
var finishCallbacks = function() { |
|
|
|
|
|
$.each(self.callbacks.hide, function(i,c) { c.call(self.$el); }); |
|
|
self.callbacks.hide = []; |
|
|
}; |
|
|
|
|
|
|
|
|
if (self.Status == 'shown' || self.Status == 'appearing') { |
|
|
|
|
|
self.Status = 'disappearing'; |
|
|
|
|
|
var finish = function() { |
|
|
|
|
|
self.Status = 'hidden'; |
|
|
|
|
|
|
|
|
if (typeof self.Content == 'object' && self.Content !== null) { |
|
|
self.Content.detach(); |
|
|
} |
|
|
|
|
|
self.$tooltip.remove(); |
|
|
self.$tooltip = null; |
|
|
|
|
|
|
|
|
$(window).off('.'+ self.namespace); |
|
|
|
|
|
$('body') |
|
|
|
|
|
.off('.'+ self.namespace) |
|
|
.css('overflow-x', self.bodyOverflowX); |
|
|
|
|
|
|
|
|
$('body').off('.'+ self.namespace); |
|
|
|
|
|
|
|
|
self.$elProxy.off('.'+ self.namespace + '-autoClose'); |
|
|
|
|
|
|
|
|
self.options.functionAfter.call(self.$el, self.$el); |
|
|
|
|
|
|
|
|
finishCallbacks(); |
|
|
}; |
|
|
|
|
|
if (supportsTransitions()) { |
|
|
|
|
|
self.$tooltip |
|
|
.clearQueue() |
|
|
.removeClass('tooltipster-' + self.options.animation + '-show') |
|
|
|
|
|
.addClass('tooltipster-dying'); |
|
|
|
|
|
if(self.options.speed > 0) self.$tooltip.delay(self.options.speed); |
|
|
|
|
|
self.$tooltip.queue(finish); |
|
|
} |
|
|
else { |
|
|
self.$tooltip |
|
|
.stop() |
|
|
.fadeOut(self.options.speed, finish); |
|
|
} |
|
|
} |
|
|
|
|
|
else if(self.Status == 'hidden') { |
|
|
finishCallbacks(); |
|
|
} |
|
|
|
|
|
return self; |
|
|
}, |
|
|
|
|
|
|
|
|
show: function(callback) { |
|
|
this._showNow(callback); |
|
|
return this; |
|
|
}, |
|
|
|
|
|
|
|
|
update: function(c) { |
|
|
return this.content(c); |
|
|
}, |
|
|
content: function(c) { |
|
|
|
|
|
if(typeof c === 'undefined'){ |
|
|
return this.Content; |
|
|
} |
|
|
|
|
|
else { |
|
|
this._update(c); |
|
|
return this; |
|
|
} |
|
|
}, |
|
|
|
|
|
reposition: function() { |
|
|
|
|
|
var self = this; |
|
|
|
|
|
|
|
|
if ($('body').find(self.$tooltip).length !== 0) { |
|
|
|
|
|
|
|
|
self.$tooltip.css('width', ''); |
|
|
|
|
|
|
|
|
self.elProxyPosition = self._repositionInfo(self.$elProxy); |
|
|
var arrowReposition = null, |
|
|
windowWidth = $(window).width(), |
|
|
|
|
|
proxy = self.elProxyPosition, |
|
|
tooltipWidth = self.$tooltip.outerWidth(false), |
|
|
tooltipInnerWidth = self.$tooltip.innerWidth() + 1, |
|
|
tooltipHeight = self.$tooltip.outerHeight(false); |
|
|
|
|
|
|
|
|
if (self.$elProxy.is('area')) { |
|
|
var areaShape = self.$elProxy.attr('shape'), |
|
|
mapName = self.$elProxy.parent().attr('name'), |
|
|
map = $('img[usemap="#'+ mapName +'"]'), |
|
|
mapOffsetLeft = map.offset().left, |
|
|
mapOffsetTop = map.offset().top, |
|
|
areaMeasurements = self.$elProxy.attr('coords') !== undefined ? self.$elProxy.attr('coords').split(',') : undefined; |
|
|
|
|
|
if (areaShape == 'circle') { |
|
|
var areaLeft = parseInt(areaMeasurements[0]), |
|
|
areaTop = parseInt(areaMeasurements[1]), |
|
|
areaWidth = parseInt(areaMeasurements[2]); |
|
|
proxy.dimension.height = areaWidth * 2; |
|
|
proxy.dimension.width = areaWidth * 2; |
|
|
proxy.offset.top = mapOffsetTop + areaTop - areaWidth; |
|
|
proxy.offset.left = mapOffsetLeft + areaLeft - areaWidth; |
|
|
} |
|
|
else if (areaShape == 'rect') { |
|
|
var areaLeft = parseInt(areaMeasurements[0]), |
|
|
areaTop = parseInt(areaMeasurements[1]), |
|
|
areaRight = parseInt(areaMeasurements[2]), |
|
|
areaBottom = parseInt(areaMeasurements[3]); |
|
|
proxy.dimension.height = areaBottom - areaTop; |
|
|
proxy.dimension.width = areaRight - areaLeft; |
|
|
proxy.offset.top = mapOffsetTop + areaTop; |
|
|
proxy.offset.left = mapOffsetLeft + areaLeft; |
|
|
} |
|
|
else if (areaShape == 'poly') { |
|
|
var areaXs = [], |
|
|
areaYs = [], |
|
|
areaSmallestX = 0, |
|
|
areaSmallestY = 0, |
|
|
areaGreatestX = 0, |
|
|
areaGreatestY = 0, |
|
|
arrayAlternate = 'even'; |
|
|
|
|
|
for (var i = 0; i < areaMeasurements.length; i++) { |
|
|
var areaNumber = parseInt(areaMeasurements[i]); |
|
|
|
|
|
if (arrayAlternate == 'even') { |
|
|
if (areaNumber > areaGreatestX) { |
|
|
areaGreatestX = areaNumber; |
|
|
if (i === 0) { |
|
|
areaSmallestX = areaGreatestX; |
|
|
} |
|
|
} |
|
|
|
|
|
if (areaNumber < areaSmallestX) { |
|
|
areaSmallestX = areaNumber; |
|
|
} |
|
|
|
|
|
arrayAlternate = 'odd'; |
|
|
} |
|
|
else { |
|
|
if (areaNumber > areaGreatestY) { |
|
|
areaGreatestY = areaNumber; |
|
|
if (i == 1) { |
|
|
areaSmallestY = areaGreatestY; |
|
|
} |
|
|
} |
|
|
|
|
|
if (areaNumber < areaSmallestY) { |
|
|
areaSmallestY = areaNumber; |
|
|
} |
|
|
|
|
|
arrayAlternate = 'even'; |
|
|
} |
|
|
} |
|
|
|
|
|
proxy.dimension.height = areaGreatestY - areaSmallestY; |
|
|
proxy.dimension.width = areaGreatestX - areaSmallestX; |
|
|
proxy.offset.top = mapOffsetTop + areaSmallestY; |
|
|
proxy.offset.left = mapOffsetLeft + areaSmallestX; |
|
|
} |
|
|
else { |
|
|
proxy.dimension.height = map.outerHeight(false); |
|
|
proxy.dimension.width = map.outerWidth(false); |
|
|
proxy.offset.top = mapOffsetTop; |
|
|
proxy.offset.left = mapOffsetLeft; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
var myLeft = 0, |
|
|
myLeftMirror = 0, |
|
|
myTop = 0, |
|
|
offsetY = parseInt(self.options.offsetY), |
|
|
offsetX = parseInt(self.options.offsetX), |
|
|
|
|
|
practicalPosition = self.options.position; |
|
|
|
|
|
|
|
|
function dontGoOffScreenX() { |
|
|
|
|
|
var windowLeft = $(window).scrollLeft(); |
|
|
|
|
|
|
|
|
if((myLeft - windowLeft) < 0) { |
|
|
arrowReposition = myLeft - windowLeft; |
|
|
myLeft = windowLeft; |
|
|
} |
|
|
|
|
|
|
|
|
if (((myLeft + tooltipWidth) - windowLeft) > windowWidth) { |
|
|
arrowReposition = myLeft - ((windowWidth + windowLeft) - tooltipWidth); |
|
|
myLeft = (windowWidth + windowLeft) - tooltipWidth; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function dontGoOffScreenY(switchTo, switchFrom) { |
|
|
|
|
|
if(((proxy.offset.top - $(window).scrollTop() - tooltipHeight - offsetY - 12) < 0) && (switchFrom.indexOf('top') > -1)) { |
|
|
practicalPosition = switchTo; |
|
|
} |
|
|
|
|
|
|
|
|
if (((proxy.offset.top + proxy.dimension.height + tooltipHeight + 12 + offsetY) > ($(window).scrollTop() + $(window).height())) && (switchFrom.indexOf('bottom') > -1)) { |
|
|
practicalPosition = switchTo; |
|
|
myTop = (proxy.offset.top - tooltipHeight) - offsetY - 12; |
|
|
} |
|
|
} |
|
|
|
|
|
if(practicalPosition == 'top') { |
|
|
var leftDifference = (proxy.offset.left + tooltipWidth) - (proxy.offset.left + proxy.dimension.width); |
|
|
myLeft = (proxy.offset.left + offsetX) - (leftDifference / 2); |
|
|
myTop = (proxy.offset.top - tooltipHeight) - offsetY - 12; |
|
|
dontGoOffScreenX(); |
|
|
dontGoOffScreenY('bottom', 'top'); |
|
|
} |
|
|
|
|
|
if(practicalPosition == 'top-left') { |
|
|
myLeft = proxy.offset.left + offsetX; |
|
|
myTop = (proxy.offset.top - tooltipHeight) - offsetY - 12; |
|
|
dontGoOffScreenX(); |
|
|
dontGoOffScreenY('bottom-left', 'top-left'); |
|
|
} |
|
|
|
|
|
if(practicalPosition == 'top-right') { |
|
|
myLeft = (proxy.offset.left + proxy.dimension.width + offsetX) - tooltipWidth; |
|
|
myTop = (proxy.offset.top - tooltipHeight) - offsetY - 12; |
|
|
dontGoOffScreenX(); |
|
|
dontGoOffScreenY('bottom-right', 'top-right'); |
|
|
} |
|
|
|
|
|
if(practicalPosition == 'bottom') { |
|
|
var leftDifference = (proxy.offset.left + tooltipWidth) - (proxy.offset.left + proxy.dimension.width); |
|
|
myLeft = proxy.offset.left - (leftDifference / 2) + offsetX; |
|
|
myTop = (proxy.offset.top + proxy.dimension.height) + offsetY + 12; |
|
|
dontGoOffScreenX(); |
|
|
dontGoOffScreenY('top', 'bottom'); |
|
|
} |
|
|
|
|
|
if(practicalPosition == 'bottom-left') { |
|
|
myLeft = proxy.offset.left + offsetX; |
|
|
myTop = (proxy.offset.top + proxy.dimension.height) + offsetY + 12; |
|
|
dontGoOffScreenX(); |
|
|
dontGoOffScreenY('top-left', 'bottom-left'); |
|
|
} |
|
|
|
|
|
if(practicalPosition == 'bottom-right') { |
|
|
myLeft = (proxy.offset.left + proxy.dimension.width + offsetX) - tooltipWidth; |
|
|
myTop = (proxy.offset.top + proxy.dimension.height) + offsetY + 12; |
|
|
dontGoOffScreenX(); |
|
|
dontGoOffScreenY('top-right', 'bottom-right'); |
|
|
} |
|
|
|
|
|
if(practicalPosition == 'left') { |
|
|
myLeft = proxy.offset.left - offsetX - tooltipWidth - 12; |
|
|
myLeftMirror = proxy.offset.left + offsetX + proxy.dimension.width + 12; |
|
|
var topDifference = (proxy.offset.top + tooltipHeight) - (proxy.offset.top + proxy.dimension.height); |
|
|
myTop = proxy.offset.top - (topDifference / 2) - offsetY; |
|
|
|
|
|
|
|
|
if((myLeft < 0) && ((myLeftMirror + tooltipWidth) > windowWidth)) { |
|
|
var borderWidth = parseFloat(self.$tooltip.css('border-width')) * 2, |
|
|
newWidth = (tooltipWidth + myLeft) - borderWidth; |
|
|
self.$tooltip.css('width', newWidth + 'px'); |
|
|
|
|
|
tooltipHeight = self.$tooltip.outerHeight(false); |
|
|
myLeft = proxy.offset.left - offsetX - newWidth - 12 - borderWidth; |
|
|
topDifference = (proxy.offset.top + tooltipHeight) - (proxy.offset.top + proxy.dimension.height); |
|
|
myTop = proxy.offset.top - (topDifference / 2) - offsetY; |
|
|
} |
|
|
|
|
|
|
|
|
else if(myLeft < 0) { |
|
|
myLeft = proxy.offset.left + offsetX + proxy.dimension.width + 12; |
|
|
arrowReposition = 'left'; |
|
|
} |
|
|
} |
|
|
|
|
|
if(practicalPosition == 'right') { |
|
|
myLeft = proxy.offset.left + offsetX + proxy.dimension.width + 12; |
|
|
myLeftMirror = proxy.offset.left - offsetX - tooltipWidth - 12; |
|
|
var topDifference = (proxy.offset.top + tooltipHeight) - (proxy.offset.top + proxy.dimension.height); |
|
|
myTop = proxy.offset.top - (topDifference / 2) - offsetY; |
|
|
|
|
|
|
|
|
if(((myLeft + tooltipWidth) > windowWidth) && (myLeftMirror < 0)) { |
|
|
var borderWidth = parseFloat(self.$tooltip.css('border-width')) * 2, |
|
|
newWidth = (windowWidth - myLeft) - borderWidth; |
|
|
self.$tooltip.css('width', newWidth + 'px'); |
|
|
|
|
|
tooltipHeight = self.$tooltip.outerHeight(false); |
|
|
topDifference = (proxy.offset.top + tooltipHeight) - (proxy.offset.top + proxy.dimension.height); |
|
|
myTop = proxy.offset.top - (topDifference / 2) - offsetY; |
|
|
} |
|
|
|
|
|
|
|
|
else if((myLeft + tooltipWidth) > windowWidth) { |
|
|
myLeft = proxy.offset.left - offsetX - tooltipWidth - 12; |
|
|
arrowReposition = 'right'; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (self.options.arrow) { |
|
|
|
|
|
var arrowClass = 'tooltipster-arrow-' + practicalPosition; |
|
|
|
|
|
|
|
|
if(self.options.arrowColor.length < 1) { |
|
|
var arrowColor = self.$tooltip.css('background-color'); |
|
|
} |
|
|
else { |
|
|
var arrowColor = self.options.arrowColor; |
|
|
} |
|
|
|
|
|
|
|
|
if (!arrowReposition) { |
|
|
arrowReposition = ''; |
|
|
} |
|
|
else if (arrowReposition == 'left') { |
|
|
arrowClass = 'tooltipster-arrow-right'; |
|
|
arrowReposition = ''; |
|
|
} |
|
|
else if (arrowReposition == 'right') { |
|
|
arrowClass = 'tooltipster-arrow-left'; |
|
|
arrowReposition = ''; |
|
|
} |
|
|
else { |
|
|
arrowReposition = 'left:'+ Math.round(arrowReposition) +'px;'; |
|
|
} |
|
|
|
|
|
|
|
|
if ((practicalPosition == 'top') || (practicalPosition == 'top-left') || (practicalPosition == 'top-right')) { |
|
|
var tooltipBorderWidth = parseFloat(self.$tooltip.css('border-bottom-width')), |
|
|
tooltipBorderColor = self.$tooltip.css('border-bottom-color'); |
|
|
} |
|
|
else if ((practicalPosition == 'bottom') || (practicalPosition == 'bottom-left') || (practicalPosition == 'bottom-right')) { |
|
|
var tooltipBorderWidth = parseFloat(self.$tooltip.css('border-top-width')), |
|
|
tooltipBorderColor = self.$tooltip.css('border-top-color'); |
|
|
} |
|
|
else if (practicalPosition == 'left') { |
|
|
var tooltipBorderWidth = parseFloat(self.$tooltip.css('border-right-width')), |
|
|
tooltipBorderColor = self.$tooltip.css('border-right-color'); |
|
|
} |
|
|
else if (practicalPosition == 'right') { |
|
|
var tooltipBorderWidth = parseFloat(self.$tooltip.css('border-left-width')), |
|
|
tooltipBorderColor = self.$tooltip.css('border-left-color'); |
|
|
} |
|
|
else { |
|
|
var tooltipBorderWidth = parseFloat(self.$tooltip.css('border-bottom-width')), |
|
|
tooltipBorderColor = self.$tooltip.css('border-bottom-color'); |
|
|
} |
|
|
|
|
|
if (tooltipBorderWidth > 1) { |
|
|
tooltipBorderWidth++; |
|
|
} |
|
|
|
|
|
var arrowBorder = ''; |
|
|
if (tooltipBorderWidth !== 0) { |
|
|
var arrowBorderSize = '', |
|
|
arrowBorderColor = 'border-color: '+ tooltipBorderColor +';'; |
|
|
if (arrowClass.indexOf('bottom') !== -1) { |
|
|
arrowBorderSize = 'margin-top: -'+ Math.round(tooltipBorderWidth) +'px;'; |
|
|
} |
|
|
else if (arrowClass.indexOf('top') !== -1) { |
|
|
arrowBorderSize = 'margin-bottom: -'+ Math.round(tooltipBorderWidth) +'px;'; |
|
|
} |
|
|
else if (arrowClass.indexOf('left') !== -1) { |
|
|
arrowBorderSize = 'margin-right: -'+ Math.round(tooltipBorderWidth) +'px;'; |
|
|
} |
|
|
else if (arrowClass.indexOf('right') !== -1) { |
|
|
arrowBorderSize = 'margin-left: -'+ Math.round(tooltipBorderWidth) +'px;'; |
|
|
} |
|
|
arrowBorder = '<span class="tooltipster-arrow-border" style="'+ arrowBorderSize +' '+ arrowBorderColor +';"></span>'; |
|
|
} |
|
|
|
|
|
|
|
|
self.$tooltip.find('.tooltipster-arrow').remove(); |
|
|
|
|
|
|
|
|
var arrowConstruct = '<div class="'+ arrowClass +' tooltipster-arrow" style="'+ arrowReposition +'">'+ arrowBorder +'<span style="border-color:'+ arrowColor +';"></span></div>'; |
|
|
self.$tooltip.append(arrowConstruct); |
|
|
} |
|
|
|
|
|
|
|
|
self.$tooltip.css({'top': Math.round(myTop) + 'px', 'left': Math.round(myLeft) + 'px'}); |
|
|
} |
|
|
|
|
|
return self; |
|
|
}, |
|
|
|
|
|
enable: function() { |
|
|
this.enabled = true; |
|
|
return this; |
|
|
}, |
|
|
|
|
|
disable: function() { |
|
|
|
|
|
this.hide(); |
|
|
this.enabled = false; |
|
|
return this; |
|
|
}, |
|
|
|
|
|
destroy: function() { |
|
|
|
|
|
var self = this; |
|
|
|
|
|
self.hide(); |
|
|
|
|
|
|
|
|
if (self.$el[0] !== self.$elProxy[0]) { |
|
|
self.$elProxy.remove(); |
|
|
} |
|
|
|
|
|
self.$el |
|
|
.removeData(self.namespace) |
|
|
.off('.'+ self.namespace); |
|
|
|
|
|
var ns = self.$el.data('tooltipster-ns'); |
|
|
|
|
|
|
|
|
if(ns.length === 1){ |
|
|
|
|
|
|
|
|
var title = null; |
|
|
if (self.options.restoration === 'previous'){ |
|
|
title = self.$el.data('tooltipster-initialTitle'); |
|
|
} |
|
|
else if(self.options.restoration === 'current'){ |
|
|
|
|
|
|
|
|
title = |
|
|
(typeof self.Content === 'string') ? |
|
|
self.Content : |
|
|
$('<div></div>').append(self.Content).html(); |
|
|
} |
|
|
|
|
|
if (title) { |
|
|
self.$el.attr('title', title); |
|
|
} |
|
|
|
|
|
|
|
|
self.$el |
|
|
.removeClass('tooltipstered') |
|
|
.removeData('tooltipster-ns') |
|
|
.removeData('tooltipster-initialTitle'); |
|
|
} |
|
|
else { |
|
|
|
|
|
ns = $.grep(ns, function(el, i){ |
|
|
return el !== self.namespace; |
|
|
}); |
|
|
self.$el.data('tooltipster-ns', ns); |
|
|
} |
|
|
|
|
|
return self; |
|
|
}, |
|
|
|
|
|
elementIcon: function() { |
|
|
return (this.$el[0] !== this.$elProxy[0]) ? this.$elProxy[0] : undefined; |
|
|
}, |
|
|
|
|
|
elementTooltip: function() { |
|
|
return this.$tooltip ? this.$tooltip[0] : undefined; |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
option: function(o, val) { |
|
|
if (typeof val == 'undefined') return this.options[o]; |
|
|
else { |
|
|
this.options[o] = val; |
|
|
return this; |
|
|
} |
|
|
}, |
|
|
status: function() { |
|
|
return this.Status; |
|
|
} |
|
|
}; |
|
|
|
|
|
$.fn[pluginName] = function () { |
|
|
|
|
|
|
|
|
var args = arguments; |
|
|
|
|
|
|
|
|
|
|
|
if (this.length === 0) { |
|
|
|
|
|
|
|
|
if (typeof args[0] === 'string') { |
|
|
|
|
|
var methodIsStatic = true; |
|
|
|
|
|
|
|
|
switch (args[0]) { |
|
|
|
|
|
case 'setDefaults': |
|
|
|
|
|
$.extend(defaults, args[1]); |
|
|
break; |
|
|
|
|
|
default: |
|
|
methodIsStatic = false; |
|
|
break; |
|
|
} |
|
|
|
|
|
|
|
|
if (methodIsStatic) return true; |
|
|
|
|
|
else return this; |
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
return this; |
|
|
} |
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
|
|
|
if (typeof args[0] === 'string') { |
|
|
|
|
|
var v = '#*$~&'; |
|
|
|
|
|
this.each(function() { |
|
|
|
|
|
|
|
|
var ns = $(this).data('tooltipster-ns'), |
|
|
|
|
|
self = ns ? $(this).data(ns[0]) : null; |
|
|
|
|
|
|
|
|
if (self) { |
|
|
|
|
|
if (typeof self[args[0]] === 'function') { |
|
|
|
|
|
var resp = self[args[0]](args[1], args[2]); |
|
|
} |
|
|
else { |
|
|
throw new Error('Unknown method .tooltipster("' + args[0] + '")'); |
|
|
} |
|
|
|
|
|
|
|
|
if (resp !== self){ |
|
|
v = resp; |
|
|
|
|
|
return false; |
|
|
} |
|
|
} |
|
|
else { |
|
|
throw new Error('You called Tooltipster\'s "' + args[0] + '" method on an uninitialized element'); |
|
|
} |
|
|
}); |
|
|
|
|
|
return (v !== '#*$~&') ? v : this; |
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
var instances = [], |
|
|
|
|
|
multipleIsSet = args[0] && typeof args[0].multiple !== 'undefined', |
|
|
|
|
|
multiple = (multipleIsSet && args[0].multiple) || (!multipleIsSet && defaults.multiple), |
|
|
|
|
|
debugIsSet = args[0] && typeof args[0].debug !== 'undefined', |
|
|
debug = (debugIsSet && args[0].debug) || (!debugIsSet && defaults.debug); |
|
|
|
|
|
|
|
|
this.each(function () { |
|
|
|
|
|
var go = false, |
|
|
ns = $(this).data('tooltipster-ns'), |
|
|
instance = null; |
|
|
|
|
|
if (!ns) { |
|
|
go = true; |
|
|
} |
|
|
else if (multiple) { |
|
|
go = true; |
|
|
} |
|
|
else if (debug) { |
|
|
console.log('Tooltipster: one or more tooltips are already attached to this element: ignoring. Use the "multiple" option to attach more tooltips.'); |
|
|
} |
|
|
|
|
|
if (go) { |
|
|
instance = new Plugin(this, args[0]); |
|
|
|
|
|
|
|
|
if (!ns) ns = []; |
|
|
ns.push(instance.namespace); |
|
|
$(this).data('tooltipster-ns', ns) |
|
|
|
|
|
|
|
|
$(this).data(instance.namespace, instance); |
|
|
} |
|
|
|
|
|
instances.push(instance); |
|
|
}); |
|
|
|
|
|
if (multiple) return instances; |
|
|
else return this; |
|
|
} |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
function areEqual(a,b) { |
|
|
var same = true; |
|
|
$.each(a, function(i, el){ |
|
|
if(typeof b[i] === 'undefined' || a[i] !== b[i]){ |
|
|
same = false; |
|
|
return false; |
|
|
} |
|
|
}); |
|
|
return same; |
|
|
} |
|
|
|
|
|
|
|
|
var deviceHasTouchCapability = !!('ontouchstart' in window); |
|
|
|
|
|
|
|
|
var deviceHasMouse = false; |
|
|
$('body').one('mousemove', function() { |
|
|
deviceHasMouse = true; |
|
|
}); |
|
|
|
|
|
function deviceIsPureTouch() { |
|
|
return (!deviceHasMouse && deviceHasTouchCapability); |
|
|
} |
|
|
|
|
|
|
|
|
function supportsTransitions() { |
|
|
var b = document.body || document.documentElement, |
|
|
s = b.style, |
|
|
p = 'transition'; |
|
|
|
|
|
if(typeof s[p] == 'string') {return true; } |
|
|
|
|
|
v = ['Moz', 'Webkit', 'Khtml', 'O', 'ms'], |
|
|
p = p.charAt(0).toUpperCase() + p.substr(1); |
|
|
for(var i=0; i<v.length; i++) { |
|
|
if(typeof s[v[i] + p] == 'string') { return true; } |
|
|
} |
|
|
return false; |
|
|
} |
|
|
})( jQuery, window, document ); |
|
|
|