-
Notifications
You must be signed in to change notification settings - Fork 9
/
tools.tooltip.dynamic.js
159 lines (127 loc) · 4.48 KB
/
tools.tooltip.dynamic.js
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/**
* tools.tooltip "Dynamic Plugin" 1.0.1
*
* Copyright (c) 2009 Tero Piirainen
* http://flowplayer.org/tools/tooltip.html#dynamic
*
* Dual licensed under MIT and GPL 2+ licenses
* http://www.opensource.org/licenses
*
* Since : July 2009
* Date: ${date}
* Revision: ${revision}
*/
(function($) {
// version number
var t = $.tools.tooltip;
t.plugins = t.plugins || {};
t.plugins.dynamic = {
version: '1.0.1',
conf: {
api: false,
classNames: "top right bottom left"
}
};
/*
* See if element is on the viewport. Returns an boolean array specifying which
* edges are hidden. Edges are in following order:
*
* [top, right, bottom, left]
*
* For example following return value means that top and right edges are hidden
*
* [true, true, false, false]
*
*/
function getCropping(el) {
var w = $(window);
var right = w.width() + w.scrollLeft();
var bottom = w.height() + w.scrollTop();
return [
el.offset().top <= w.scrollTop(), // top
right <= el.offset().left + el.width(), // right
bottom <= el.offset().top + el.height(), // bottom
w.scrollLeft() >= el.offset().left // left
];
}
/*
Returns true if all edges of an element are on viewport. false if not
@param crop the cropping array returned by getCropping function
*/
function isVisible(crop) {
var i = crop.length;
while (i--) {
if (crop[i]) { return false; }
}
return true;
}
// scrollable mousewheel implementation
$.fn.dynamic = function(conf) {
var globals = $.extend({}, t.plugins.dynamic.conf), ret;
if (typeof conf == 'number') { conf = {speed: conf}; }
conf = $.extend(globals, conf);
var cls = conf.classNames.split(/\s/), orig;
this.each(function() {
if ($(this).tooltip().jquery) {
throw "Lazy feature not supported by dynamic plugin. set lazy: false for tooltip";
}
var api = $(this).tooltip().onBeforeShow(function(e, pos) {
// get nessessary variables
var tip = this.getTip(), tipConf = this.getConf();
/*
We store the original configuration and use it to restore back to the original state.
*/
if (!orig) {
orig = [
tipConf.position[0],
tipConf.position[1],
tipConf.offset[0],
tipConf.offset[1],
$.extend({}, tipConf)
];
}
/*
display tip in it's default position and by setting visibility to hidden.
this way we can check whether it will be on the viewport
*/
$.extend(tipConf, orig[4]);
tipConf.position = [orig[0], orig[1]];
tipConf.offset = [orig[2], orig[3]];
tip.css({
visibility: 'hidden',
position: 'absolute',
top: pos.top,
left: pos.left
}).show();
// now let's see for hidden edges
var crop = getCropping(tip);
// possibly alter the configuration
if (!isVisible(crop)) {
// change the position and add class
if (crop[2]) { $.extend(tipConf, conf.top); tipConf.position[0] = 'top'; tip.addClass(cls[0]); }
if (crop[3]) { $.extend(tipConf, conf.right); tipConf.position[1] = 'right'; tip.addClass(cls[1]); }
if (crop[0]) { $.extend(tipConf, conf.bottom); tipConf.position[0] = 'bottom'; tip.addClass(cls[2]); }
if (crop[1]) { $.extend(tipConf, conf.left); tipConf.position[1] = 'left'; tip.addClass(cls[3]); }
// vertical offset
if (crop[0] || crop[2]) { tipConf.offset[0] *= -1; }
// horizontal offset
if (crop[1] || crop[3]) { tipConf.offset[1] *= -1; }
}
tip.css({visibility: 'visible'}).hide();
});
// restore positioning
api.onShow(function() {
var c = this.getConf(), tip = this.getTip();
c.position = [orig[0], orig[1]];
c.offset = [orig[2], orig[3]];
});
// remove custom class names and restore original effect
api.onHide(function() {
var tip = this.getTip();
tip.removeClass(conf.classNames);
});
ret = api;
});
return conf.api ? ret : this;
};
}) (jQuery);