// jQuery protip - Simple tooltip from Propeller Communications
// version 0.0.2 (uber alpha) (do not use) (pain of death)
// See README for details. https://github.com/Propcom/Protip
(function($) {
var preset = {};
preset.next = function() {
return $(this).next();
};
function position(what, where, anchor, offset) {
var relPos = where.split(' ');
switch (relPos[0]) {
case 'bottom':
anchor.top += anchor.height;
break;
case 'top':
anchor.top -= what.outerHeight();
break;
case 'centre':
anchor.top += (anchor.height - what.outerHeight()) / 2;
break;
}
switch (relPos[1]) {
case 'right':
anchor.left += anchor.width;
break;
case 'left':
anchor.left -= what.outerWidth();
break;
case 'centre':
anchor.left += (anchor.width - what.outerWidth()) / 2;
break;
}
what.offset({
'top': anchor.top + offset[1],
'left': anchor.left + offset[0]
});
}
$.fn.protip = function(opts){
var self = this,
args = opts,
tip, fixed,
api;
if (api = self.data('protip')) {
if (typeof args == 'object') {
return;
}
var a = [].slice.apply(arguments);
a.shift();
// The events get called on single objects, but the API could be called on
// a collection, so in this case we have to pick one.
var ret = api[args].apply(self.first(),a);
if (ret === undefined)
return self;
else
return ret;
}
api = {
show: function(mouseEvent) {
var anchor = args.anchor;
tip = args.tip.apply(this);
if (tip === false) {
return;
}
if (tip.is(':visible') && fix) {
return;
}
if (anchor == 'mouse') {
anchor = {
'top': mouseEvent.pageY,
'left': mouseEvent.pageX,
'height': 1,
'width': 1
};
}
else if (anchor == 'element') {
anchor = this.offset();
anchor.height = this.outerHeight();
anchor.width = this.outerWidth();
}
tip.css({
display: 'inline-block',
position: 'absolute'
}); // have to show it first or we can't find its size
position(tip, args.position, anchor, args.offset);
this.trigger('protip.show');
},
hide: function() {
if (fixed) return;
if (tip) {
tip.hide();
this.trigger('protip.hide');
}
},
reposition: function(mouseEvent) {
if (fixed) return;
var anchor = {
'top': mouseEvent.pageY,
'left': mouseEvent.pageX,
'height': 1,
'width': 1
};
position(tip, args.position, anchor, args.offset);
},
cohort: function() {
return self;
},
fix: function() {
fixed = true;
},
unfix: function() {
fixed = false;
}
};
args = $.extend({}, {
position: 'top right',
anchor: 'mouse',
offset: [10, -10],
tip: 'next',
showEvents: 'mouseenter',
hideEvents: 'mouseleave'
}, args);
if (typeof args.tip != 'function') {
args.tip = preset[args.tip];
}
self.bind(args.showEvents, function(event) {
if (! args.onBeforeShow
|| args.onBeforeShow.call($(this)) !== false) {
api.show.call($(this), event);
}
}).bind(args.hideEvents, function() {
if (! args.onBeforeHide
|| args.onBeforeHide.call($(this)) !== false) {
api.hide.call($(this));
}
}).bind('mousemove', function(event) {
if (tip && args.anchor == 'mouse') {
api.reposition.call($(this), event);
}
});
if (args.onShow)
self.bind('protip.show', args.onShow);
if (args.onHide)
self.bind('protip.hide', args.onHide);
self.data('protip', api);
return self;
};
})(jQuery);