This repository has been archived by the owner on Jun 14, 2020. It is now read-only.
/
toggle.js
157 lines (124 loc) · 4.92 KB
/
toggle.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
PROTOTYPE.toggle = function(state, event) {
var cache = this.cache,
options = this.options,
tooltip = this.tooltip;
// Try to prevent flickering when tooltip overlaps show element
if(event) {
if((/over|enter/).test(event.type) && (/out|leave/).test(cache.event.type) &&
options.show.target.add(event.target).length === options.show.target.length &&
tooltip.has(event.relatedTarget).length) {
return this;
}
// Cache event
cache.event = cloneEvent(event);
}
// If we're currently waiting and we've just hidden... stop it
this.waiting && !state && (this.hiddenDuringWait = TRUE);
// Render the tooltip if showing and it isn't already
if(!this.rendered) { return state ? this.render(1) : this; }
else if(this.destroyed || this.disabled) { return this; }
var type = state ? 'show' : 'hide',
opts = this.options[type],
otherOpts = this.options[ !state ? 'show' : 'hide' ],
posOptions = this.options.position,
contentOptions = this.options.content,
width = this.tooltip.css('width'),
visible = this.tooltip[0].offsetWidth > 0,
animate = state || opts.target.length === 1,
sameTarget = !event || opts.target.length < 2 || cache.target[0] === event.target,
identicalState, allow, showEvent, delay, after;
// Detect state if valid one isn't provided
if((typeof state).search('boolean|number')) { state = !visible; }
// Check if the tooltip is in an identical state to the new would-be state
identicalState = !tooltip.is(':animated') && visible === state && sameTarget;
// Fire tooltip(show/hide) event and check if destroyed
allow = !identicalState ? !!this._trigger(type, [90]) : NULL;
// If the user didn't stop the method prematurely and we're showing the tooltip, focus it
if(allow !== FALSE && state) { this.focus(event); }
// If the state hasn't changed or the user stopped it, return early
if(!allow || identicalState) { return this; }
// Set ARIA hidden attribute
$.attr(tooltip[0], 'aria-hidden', !!!state);
// Execute state specific properties
if(state) {
// Store show origin coordinates
cache.origin = cloneEvent(this.mouse);
// Update tooltip content & title if it's a dynamic function
if($.isFunction(contentOptions.text)) { this._updateContent(contentOptions.text, FALSE); }
if($.isFunction(contentOptions.title)) { this._updateTitle(contentOptions.title, FALSE); }
// Cache mousemove events for positioning purposes (if not already tracking)
if(!trackingBound && posOptions.target === 'mouse' && posOptions.adjust.mouse) {
$(document).bind('mousemove.'+NAMESPACE, this._storeMouse);
trackingBound = TRUE;
}
// Update the tooltip position (set width first to prevent viewport/max-width issues)
if(!width) { tooltip.css('width', tooltip.outerWidth(FALSE)); }
this.reposition(event, arguments[2]);
if(!width) { tooltip.css('width', ''); }
// Hide other tooltips if tooltip is solo
if(!!opts.solo) {
(typeof opts.solo === 'string' ? $(opts.solo) : $(SELECTOR, opts.solo))
.not(tooltip).not(opts.target).qtip('hide', $.Event('tooltipsolo'));
}
}
else {
// Clear show timer if we're hiding
clearTimeout(this.timers.show);
// Remove cached origin on hide
delete cache.origin;
// Remove mouse tracking event if not needed (all tracking qTips are hidden)
if(trackingBound && !$(SELECTOR+'[tracking="true"]:visible', opts.solo).not(tooltip).length) {
$(document).unbind('mousemove.'+NAMESPACE);
trackingBound = FALSE;
}
// Blur the tooltip
this.blur(event);
}
// Define post-animation, state specific properties
after = $.proxy(function() {
if(state) {
// Prevent antialias from disappearing in IE by removing filter
if(BROWSER.ie) { tooltip[0].style.removeAttribute('filter'); }
// Remove overflow setting to prevent tip bugs
tooltip.css('overflow', '');
// Autofocus elements if enabled
if('string' === typeof opts.autofocus) {
$(this.options.show.autofocus, tooltip).focus();
}
// If set, hide tooltip when inactive for delay period
this.options.show.target.trigger('qtip-'+this.id+'-inactive');
}
else {
// Reset CSS states
tooltip.css({
display: '',
visibility: '',
opacity: '',
left: '',
top: ''
});
}
// tooltipvisible/tooltiphidden events
this._trigger(state ? 'visible' : 'hidden');
}, this);
// If no effect type is supplied, use a simple toggle
if(opts.effect === FALSE || animate === FALSE) {
tooltip[ type ]();
after();
}
// Use custom function if provided
else if($.isFunction(opts.effect)) {
tooltip.stop(1, 1);
opts.effect.call(tooltip, this);
tooltip.queue('fx', function(n) {
after(); n();
});
}
// Use basic fade function by default
else { tooltip.fadeTo(90, state ? 1 : 0, after); }
// If inactive hide method is set, active it
if(state) { opts.target.trigger('qtip-'+this.id+'-inactive'); }
return this;
};
PROTOTYPE.show = function(event) { return this.toggle(TRUE, event); };
PROTOTYPE.hide = function(event) { return this.toggle(FALSE, event); };