qtip2-jquery-rails 2.1.108 → 2.2.100
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +1 -1
- data/lib/qtip2-jquery-rails/version.rb +2 -2
- data/spec/features/asset_pipeline_spec.rb +3 -3
- data/vendor/assets/javascripts/jquery.qtip.js +1259 -1208
- data/vendor/assets/stylesheets/jquery.qtip.css +25 -31
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 154e6b873880e9dcc0f57d5cccc9c84c9232df46
|
4
|
+
data.tar.gz: 0e9c3f4ae90e73467414b7744b62c8b10923f0cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 86afbc1f08bd7d0530fe3378985e78997b7e44db7b021cdc5bd3719a72067c19d7ab43621289d8fef4f98ecc38449d3f8d4d3efa4a016d250e17759bb2d10e42
|
7
|
+
data.tar.gz: 6474c81e62c4a2c91bee046ff103af992e63a0335740a26833526ffff960d39fc7c59dcb26e067cc86985e2dee4037a13347386b823f462dd4109d7585ae6684
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -10,8 +10,8 @@ module Qtip2Jquery
|
|
10
10
|
# "2.1.101" is qtip2 v2.1.1 + gem release 1
|
11
11
|
# "2.1.110" is qtip2 v2.1.1 + gem release 10
|
12
12
|
MAJOR = 2
|
13
|
-
MINOR =
|
14
|
-
PATCH =
|
13
|
+
MINOR = 2
|
14
|
+
PATCH = 100
|
15
15
|
BUILD = nil
|
16
16
|
VERSION = [MAJOR, MINOR, PATCH, BUILD].compact.join('.')
|
17
17
|
end
|
@@ -7,11 +7,11 @@ feature 'Asset pipeline' do
|
|
7
7
|
# save_and_open_page # for debugging (opens page in browser)
|
8
8
|
|
9
9
|
expect(page).to have_text(<<-EOF
|
10
|
-
* qTip2 - Pretty powerful tooltips - v2.
|
10
|
+
* qTip2 - Pretty powerful tooltips - v2.2.1
|
11
11
|
* http://qtip2.com
|
12
12
|
*
|
13
|
-
* Copyright (c)
|
14
|
-
* Released under the MIT
|
13
|
+
* Copyright (c) 2014
|
14
|
+
* Released under the MIT licenses
|
15
15
|
* http://jquery.org/license
|
16
16
|
EOF
|
17
17
|
)
|
@@ -1,14 +1,14 @@
|
|
1
1
|
/*
|
2
|
-
* qTip2 - Pretty powerful tooltips - v2.
|
2
|
+
* qTip2 - Pretty powerful tooltips - v2.2.1
|
3
3
|
* http://qtip2.com
|
4
4
|
*
|
5
|
-
* Copyright (c)
|
6
|
-
* Released under the MIT
|
5
|
+
* Copyright (c) 2014
|
6
|
+
* Released under the MIT licenses
|
7
7
|
* http://jquery.org/license
|
8
8
|
*
|
9
|
-
* Date:
|
10
|
-
* Plugins: tips
|
11
|
-
* Styles: basic css3
|
9
|
+
* Date: Sat Sep 6 2014 06:25 EDT-0400
|
10
|
+
* Plugins: tips viewport imagemap svg modal ie6
|
11
|
+
* Styles: core basic css3
|
12
12
|
*/
|
13
13
|
/*global window: false, jQuery: false, console: false, define: false */
|
14
14
|
|
@@ -19,16 +19,14 @@
|
|
19
19
|
(function( factory ) {
|
20
20
|
"use strict";
|
21
21
|
if(typeof define === 'function' && define.amd) {
|
22
|
-
define(['jquery'
|
22
|
+
define(['jquery'], factory);
|
23
23
|
}
|
24
24
|
else if(jQuery && !jQuery.fn.qtip) {
|
25
25
|
factory(jQuery);
|
26
26
|
}
|
27
27
|
}
|
28
28
|
(function($) {
|
29
|
-
|
30
|
-
//"use strict"; // (Dis)able ECMAScript "strict" operation for this function. See more: http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/
|
31
|
-
|
29
|
+
"use strict"; // Enable ECMAScript "strict" operation for this function. See more: http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/
|
32
30
|
;// Munge the primitives - Paul Irish tip
|
33
31
|
var TRUE = true,
|
34
32
|
FALSE = false,
|
@@ -69,7 +67,7 @@ CLASS_DISABLED = NAMESPACE+'-disabled',
|
|
69
67
|
|
70
68
|
replaceSuffix = '_replacedByqTip',
|
71
69
|
oldtitle = 'oldtitle',
|
72
|
-
trackingBound
|
70
|
+
trackingBound,
|
73
71
|
|
74
72
|
// Browser detection
|
75
73
|
BROWSER = {
|
@@ -80,222 +78,227 @@ BROWSER = {
|
|
80
78
|
* Credit to James Padolsey for the original implemntation!
|
81
79
|
*/
|
82
80
|
ie: (function(){
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
81
|
+
for (
|
82
|
+
var v = 4, i = document.createElement("div");
|
83
|
+
(i.innerHTML = "<!--[if gt IE " + v + "]><i></i><![endif]-->") && i.getElementsByTagName("i")[0];
|
84
|
+
v+=1
|
85
|
+
) {}
|
87
86
|
return v > 4 ? v : NaN;
|
88
87
|
}()),
|
89
|
-
|
88
|
+
|
90
89
|
/*
|
91
90
|
* iOS version detection
|
92
91
|
*/
|
93
|
-
iOS: parseFloat(
|
92
|
+
iOS: parseFloat(
|
94
93
|
('' + (/CPU.*OS ([0-9_]{1,5})|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent) || [0,''])[1])
|
95
94
|
.replace('undefined', '3_2').replace('_', '.').replace('_', '')
|
96
95
|
) || FALSE
|
97
96
|
};
|
97
|
+
;function QTip(target, options, id, attr) {
|
98
|
+
// Elements and ID
|
99
|
+
this.id = id;
|
100
|
+
this.target = target;
|
101
|
+
this.tooltip = NULL;
|
102
|
+
this.elements = { target: target };
|
103
|
+
|
104
|
+
// Internal constructs
|
105
|
+
this._id = NAMESPACE + '-' + id;
|
106
|
+
this.timers = { img: {} };
|
107
|
+
this.options = options;
|
108
|
+
this.plugins = {};
|
109
|
+
|
110
|
+
// Cache object
|
111
|
+
this.cache = {
|
112
|
+
event: {},
|
113
|
+
target: $(),
|
114
|
+
disabled: FALSE,
|
115
|
+
attr: attr,
|
116
|
+
onTooltip: FALSE,
|
117
|
+
lastClass: ''
|
118
|
+
};
|
119
|
+
|
120
|
+
// Set the initial flags
|
121
|
+
this.rendered = this.destroyed = this.disabled = this.waiting =
|
122
|
+
this.hiddenDuringWait = this.positioning = this.triggering = FALSE;
|
123
|
+
}
|
124
|
+
PROTOTYPE = QTip.prototype;
|
125
|
+
|
126
|
+
PROTOTYPE._when = function(deferreds) {
|
127
|
+
return $.when.apply($, deferreds);
|
128
|
+
};
|
129
|
+
|
130
|
+
PROTOTYPE.render = function(show) {
|
131
|
+
if(this.rendered || this.destroyed) { return this; } // If tooltip has already been rendered, exit
|
132
|
+
|
133
|
+
var self = this,
|
134
|
+
options = this.options,
|
135
|
+
cache = this.cache,
|
136
|
+
elements = this.elements,
|
137
|
+
text = options.content.text,
|
138
|
+
title = options.content.title,
|
139
|
+
button = options.content.button,
|
140
|
+
posOptions = options.position,
|
141
|
+
namespace = '.'+this._id+' ',
|
142
|
+
deferreds = [],
|
143
|
+
tooltip;
|
144
|
+
|
145
|
+
// Add ARIA attributes to target
|
146
|
+
$.attr(this.target[0], 'aria-describedby', this._id);
|
147
|
+
|
148
|
+
// Create public position object that tracks current position corners
|
149
|
+
cache.posClass = this._createPosClass(
|
150
|
+
(this.position = { my: posOptions.my, at: posOptions.at }).my
|
151
|
+
);
|
152
|
+
|
153
|
+
// Create tooltip element
|
154
|
+
this.tooltip = elements.tooltip = tooltip = $('<div/>', {
|
155
|
+
'id': this._id,
|
156
|
+
'class': [ NAMESPACE, CLASS_DEFAULT, options.style.classes, cache.posClass ].join(' '),
|
157
|
+
'width': options.style.width || '',
|
158
|
+
'height': options.style.height || '',
|
159
|
+
'tracking': posOptions.target === 'mouse' && posOptions.adjust.mouse,
|
160
|
+
|
161
|
+
/* ARIA specific attributes */
|
162
|
+
'role': 'alert',
|
163
|
+
'aria-live': 'polite',
|
164
|
+
'aria-atomic': FALSE,
|
165
|
+
'aria-describedby': this._id + '-content',
|
166
|
+
'aria-hidden': TRUE
|
167
|
+
})
|
168
|
+
.toggleClass(CLASS_DISABLED, this.disabled)
|
169
|
+
.attr(ATTR_ID, this.id)
|
170
|
+
.data(NAMESPACE, this)
|
171
|
+
.appendTo(posOptions.container)
|
172
|
+
.append(
|
173
|
+
// Create content element
|
174
|
+
elements.content = $('<div />', {
|
175
|
+
'class': NAMESPACE + '-content',
|
176
|
+
'id': this._id + '-content',
|
177
|
+
'aria-atomic': TRUE
|
178
|
+
})
|
179
|
+
);
|
180
|
+
|
181
|
+
// Set rendered flag and prevent redundant reposition calls for now
|
182
|
+
this.rendered = -1;
|
183
|
+
this.positioning = TRUE;
|
184
|
+
|
185
|
+
// Create title...
|
186
|
+
if(title) {
|
187
|
+
this._createTitle();
|
188
|
+
|
189
|
+
// Update title only if its not a callback (called in toggle if so)
|
190
|
+
if(!$.isFunction(title)) {
|
191
|
+
deferreds.push( this._updateTitle(title, FALSE) );
|
192
|
+
}
|
193
|
+
}
|
194
|
+
|
195
|
+
// Create button
|
196
|
+
if(button) { this._createButton(); }
|
197
|
+
|
198
|
+
// Set proper rendered flag and update content if not a callback function (called in toggle)
|
199
|
+
if(!$.isFunction(text)) {
|
200
|
+
deferreds.push( this._updateContent(text, FALSE) );
|
201
|
+
}
|
202
|
+
this.rendered = TRUE;
|
203
|
+
|
204
|
+
// Setup widget classes
|
205
|
+
this._setWidget();
|
206
|
+
|
207
|
+
// Initialize 'render' plugins
|
208
|
+
$.each(PLUGINS, function(name) {
|
209
|
+
var instance;
|
210
|
+
if(this.initialize === 'render' && (instance = this(self))) {
|
211
|
+
self.plugins[name] = instance;
|
212
|
+
}
|
213
|
+
});
|
214
|
+
|
215
|
+
// Unassign initial events and assign proper events
|
216
|
+
this._unassignEvents();
|
217
|
+
this._assignEvents();
|
218
|
+
|
219
|
+
// When deferreds have completed
|
220
|
+
this._when(deferreds).then(function() {
|
221
|
+
// tooltiprender event
|
222
|
+
self._trigger('render');
|
223
|
+
|
224
|
+
// Reset flags
|
225
|
+
self.positioning = FALSE;
|
226
|
+
|
227
|
+
// Show tooltip if not hidden during wait period
|
228
|
+
if(!self.hiddenDuringWait && (options.show.ready || show)) {
|
229
|
+
self.toggle(TRUE, cache.event, FALSE);
|
230
|
+
}
|
231
|
+
self.hiddenDuringWait = FALSE;
|
232
|
+
});
|
233
|
+
|
234
|
+
// Expose API
|
235
|
+
QTIP.api[this.id] = this;
|
236
|
+
|
237
|
+
return this;
|
238
|
+
};
|
239
|
+
|
240
|
+
PROTOTYPE.destroy = function(immediate) {
|
241
|
+
// Set flag the signify destroy is taking place to plugins
|
242
|
+
// and ensure it only gets destroyed once!
|
243
|
+
if(this.destroyed) { return this.target; }
|
244
|
+
|
245
|
+
function process() {
|
246
|
+
if(this.destroyed) { return; }
|
247
|
+
this.destroyed = TRUE;
|
248
|
+
|
249
|
+
var target = this.target,
|
250
|
+
title = target.attr(oldtitle),
|
251
|
+
timer;
|
252
|
+
|
253
|
+
// Destroy tooltip if rendered
|
254
|
+
if(this.rendered) {
|
255
|
+
this.tooltip.stop(1,0).find('*').remove().end().remove();
|
256
|
+
}
|
257
|
+
|
258
|
+
// Destroy all plugins
|
259
|
+
$.each(this.plugins, function(name) {
|
260
|
+
this.destroy && this.destroy();
|
261
|
+
});
|
262
|
+
|
263
|
+
// Clear timers
|
264
|
+
for(timer in this.timers) {
|
265
|
+
clearTimeout(this.timers[timer]);
|
266
|
+
}
|
267
|
+
|
268
|
+
// Remove api object and ARIA attributes
|
269
|
+
target.removeData(NAMESPACE)
|
270
|
+
.removeAttr(ATTR_ID)
|
271
|
+
.removeAttr(ATTR_HAS)
|
272
|
+
.removeAttr('aria-describedby');
|
273
|
+
|
274
|
+
// Reset old title attribute if removed
|
275
|
+
if(this.options.suppress && title) {
|
276
|
+
target.attr('title', title).removeAttr(oldtitle);
|
277
|
+
}
|
278
|
+
|
279
|
+
// Remove qTip events associated with this API
|
280
|
+
this._unassignEvents();
|
281
|
+
|
282
|
+
// Remove ID from used id objects, and delete object references
|
283
|
+
// for better garbage collection and leak protection
|
284
|
+
this.options = this.elements = this.cache = this.timers =
|
285
|
+
this.plugins = this.mouse = NULL;
|
286
|
+
|
287
|
+
// Delete epoxsed API object
|
288
|
+
delete QTIP.api[this.id];
|
289
|
+
}
|
98
290
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
this.
|
109
|
-
|
110
|
-
this.plugins = {};
|
111
|
-
|
112
|
-
// Cache object
|
113
|
-
this.cache = cache = {
|
114
|
-
event: {},
|
115
|
-
target: $(),
|
116
|
-
disabled: FALSE,
|
117
|
-
attr: attr,
|
118
|
-
onTooltip: FALSE,
|
119
|
-
lastClass: ''
|
120
|
-
};
|
121
|
-
|
122
|
-
// Set the initial flags
|
123
|
-
this.rendered = this.destroyed = this.disabled = this.waiting =
|
124
|
-
this.hiddenDuringWait = this.positioning = this.triggering = FALSE;
|
125
|
-
}
|
126
|
-
PROTOTYPE = QTip.prototype;
|
127
|
-
|
128
|
-
PROTOTYPE.render = function(show) {
|
129
|
-
if(this.rendered || this.destroyed) { return this; } // If tooltip has already been rendered, exit
|
130
|
-
|
131
|
-
var self = this,
|
132
|
-
options = this.options,
|
133
|
-
cache = this.cache,
|
134
|
-
elements = this.elements,
|
135
|
-
text = options.content.text,
|
136
|
-
title = options.content.title,
|
137
|
-
button = options.content.button,
|
138
|
-
posOptions = options.position,
|
139
|
-
namespace = '.'+this._id+' ',
|
140
|
-
deferreds = [];
|
141
|
-
|
142
|
-
// Add ARIA attributes to target
|
143
|
-
$.attr(this.target[0], 'aria-describedby', this._id);
|
144
|
-
|
145
|
-
// Create tooltip element
|
146
|
-
this.tooltip = elements.tooltip = tooltip = $('<div/>', {
|
147
|
-
'id': this._id,
|
148
|
-
'class': [ NAMESPACE, CLASS_DEFAULT, options.style.classes, NAMESPACE + '-pos-' + options.position.my.abbrev() ].join(' '),
|
149
|
-
'width': options.style.width || '',
|
150
|
-
'height': options.style.height || '',
|
151
|
-
'tracking': posOptions.target === 'mouse' && posOptions.adjust.mouse,
|
152
|
-
|
153
|
-
/* ARIA specific attributes */
|
154
|
-
'role': 'alert',
|
155
|
-
'aria-live': 'polite',
|
156
|
-
'aria-atomic': FALSE,
|
157
|
-
'aria-describedby': this._id + '-content',
|
158
|
-
'aria-hidden': TRUE
|
159
|
-
})
|
160
|
-
.toggleClass(CLASS_DISABLED, this.disabled)
|
161
|
-
.attr(ATTR_ID, this.id)
|
162
|
-
.data(NAMESPACE, this)
|
163
|
-
.appendTo(posOptions.container)
|
164
|
-
.append(
|
165
|
-
// Create content element
|
166
|
-
elements.content = $('<div />', {
|
167
|
-
'class': NAMESPACE + '-content',
|
168
|
-
'id': this._id + '-content',
|
169
|
-
'aria-atomic': TRUE
|
170
|
-
})
|
171
|
-
);
|
172
|
-
|
173
|
-
// Set rendered flag and prevent redundant reposition calls for now
|
174
|
-
this.rendered = -1;
|
175
|
-
this.positioning = TRUE;
|
176
|
-
|
177
|
-
// Create title...
|
178
|
-
if(title) {
|
179
|
-
this._createTitle();
|
180
|
-
|
181
|
-
// Update title only if its not a callback (called in toggle if so)
|
182
|
-
if(!$.isFunction(title)) {
|
183
|
-
deferreds.push( this._updateTitle(title, FALSE) );
|
184
|
-
}
|
185
|
-
}
|
186
|
-
|
187
|
-
// Create button
|
188
|
-
if(button) { this._createButton(); }
|
189
|
-
|
190
|
-
// Set proper rendered flag and update content if not a callback function (called in toggle)
|
191
|
-
if(!$.isFunction(text)) {
|
192
|
-
deferreds.push( this._updateContent(text, FALSE) );
|
193
|
-
}
|
194
|
-
this.rendered = TRUE;
|
195
|
-
|
196
|
-
// Setup widget classes
|
197
|
-
this._setWidget();
|
198
|
-
|
199
|
-
// Assign passed event callbacks (before plugins!)
|
200
|
-
$.each(options.events, function(name, callback) {
|
201
|
-
$.isFunction(callback) && tooltip.bind(
|
202
|
-
(name === 'toggle' ? ['tooltipshow','tooltiphide'] : ['tooltip'+name])
|
203
|
-
.join(namespace)+namespace, callback
|
204
|
-
);
|
205
|
-
});
|
206
|
-
|
207
|
-
// Initialize 'render' plugins
|
208
|
-
$.each(PLUGINS, function(name) {
|
209
|
-
var instance;
|
210
|
-
if(this.initialize === 'render' && (instance = this(self))) {
|
211
|
-
self.plugins[name] = instance;
|
212
|
-
}
|
213
|
-
});
|
214
|
-
|
215
|
-
// Assign events
|
216
|
-
this._assignEvents();
|
217
|
-
|
218
|
-
// When deferreds have completed
|
219
|
-
$.when.apply($, deferreds).then(function() {
|
220
|
-
// tooltiprender event
|
221
|
-
self._trigger('render');
|
222
|
-
|
223
|
-
// Reset flags
|
224
|
-
self.positioning = FALSE;
|
225
|
-
|
226
|
-
// Show tooltip if not hidden during wait period
|
227
|
-
if(!self.hiddenDuringWait && (options.show.ready || show)) {
|
228
|
-
self.toggle(TRUE, cache.event, FALSE);
|
229
|
-
}
|
230
|
-
self.hiddenDuringWait = FALSE;
|
231
|
-
});
|
232
|
-
|
233
|
-
// Expose API
|
234
|
-
QTIP.api[this.id] = this;
|
235
|
-
|
236
|
-
return this;
|
237
|
-
};
|
238
|
-
|
239
|
-
PROTOTYPE.destroy = function(immediate) {
|
240
|
-
// Set flag the signify destroy is taking place to plugins
|
241
|
-
// and ensure it only gets destroyed once!
|
242
|
-
if(this.destroyed) { return this.target; }
|
243
|
-
|
244
|
-
function process() {
|
245
|
-
if(this.destroyed) { return; }
|
246
|
-
this.destroyed = TRUE;
|
247
|
-
|
248
|
-
var target = this.target,
|
249
|
-
title = target.attr(oldtitle);
|
250
|
-
|
251
|
-
// Destroy tooltip if rendered
|
252
|
-
if(this.rendered) {
|
253
|
-
this.tooltip.stop(1,0).find('*').remove().end().remove();
|
254
|
-
}
|
255
|
-
|
256
|
-
// Destroy all plugins
|
257
|
-
$.each(this.plugins, function(name) {
|
258
|
-
this.destroy && this.destroy();
|
259
|
-
});
|
260
|
-
|
261
|
-
// Clear timers and remove bound events
|
262
|
-
clearTimeout(this.timers.show);
|
263
|
-
clearTimeout(this.timers.hide);
|
264
|
-
this._unassignEvents();
|
265
|
-
|
266
|
-
// Remove api object and ARIA attributes
|
267
|
-
target.removeData(NAMESPACE).removeAttr(ATTR_ID)
|
268
|
-
.removeAttr('aria-describedby');
|
269
|
-
|
270
|
-
// Reset old title attribute if removed
|
271
|
-
if(this.options.suppress && title) {
|
272
|
-
target.attr('title', title).removeAttr(oldtitle);
|
273
|
-
}
|
274
|
-
|
275
|
-
// Remove qTip events associated with this API
|
276
|
-
this._unbind(target);
|
277
|
-
|
278
|
-
// Remove ID from used id objects, and delete object references
|
279
|
-
// for better garbage collection and leak protection
|
280
|
-
this.options = this.elements = this.cache = this.timers =
|
281
|
-
this.plugins = this.mouse = NULL;
|
282
|
-
|
283
|
-
// Delete epoxsed API object
|
284
|
-
delete QTIP.api[this.id];
|
285
|
-
}
|
286
|
-
|
287
|
-
// If an immediate destory is needed
|
288
|
-
if(immediate !== TRUE && this.rendered) {
|
289
|
-
tooltip.one('tooltiphidden', $.proxy(process, this));
|
290
|
-
!this.triggering && this.hide();
|
291
|
-
}
|
292
|
-
|
293
|
-
// If we're not in the process of hiding... process
|
294
|
-
else { process.call(this); }
|
295
|
-
|
296
|
-
return this.target;
|
297
|
-
};
|
298
|
-
|
291
|
+
// If an immediate destory is needed
|
292
|
+
if((immediate !== TRUE || this.triggering === 'hide') && this.rendered) {
|
293
|
+
this.tooltip.one('tooltiphidden', $.proxy(process, this));
|
294
|
+
!this.triggering && this.hide();
|
295
|
+
}
|
296
|
+
|
297
|
+
// If we're not in the process of hiding... process
|
298
|
+
else { process.call(this); }
|
299
|
+
|
300
|
+
return this.target;
|
301
|
+
};
|
299
302
|
;function invalidOpt(a) {
|
300
303
|
return a === NULL || $.type(a) !== 'object';
|
301
304
|
}
|
@@ -352,7 +355,7 @@ function sanitizeOptions(opts) {
|
|
352
355
|
}
|
353
356
|
|
354
357
|
if('title' in content) {
|
355
|
-
if(
|
358
|
+
if($.isPlainObject(content.title)) {
|
356
359
|
content.button = content.title.button;
|
357
360
|
content.title = content.title.text;
|
358
361
|
}
|
@@ -368,7 +371,7 @@ function sanitizeOptions(opts) {
|
|
368
371
|
}
|
369
372
|
|
370
373
|
if('show' in opts && invalidOpt(opts.show)) {
|
371
|
-
opts.show = opts.show.jquery ? { target: opts.show } :
|
374
|
+
opts.show = opts.show.jquery ? { target: opts.show } :
|
372
375
|
opts.show === TRUE ? { ready: TRUE } : { event: opts.show };
|
373
376
|
}
|
374
377
|
|
@@ -433,14 +436,14 @@ CHECKS = PROTOTYPE.checks = {
|
|
433
436
|
},
|
434
437
|
'^content.title.(text|button)$': function(obj, o, v) {
|
435
438
|
this.set('content.'+o, v); // Backwards title.text/button compat
|
436
|
-
},
|
439
|
+
},
|
437
440
|
|
438
441
|
// Position checks
|
439
442
|
'^position.(my|at)$': function(obj, o, v){
|
440
|
-
'string' === typeof v && (obj[o] = new CORNER(v, o === 'at'));
|
443
|
+
'string' === typeof v && (this.position[o] = obj[o] = new CORNER(v, o === 'at'));
|
441
444
|
},
|
442
445
|
'^position.container$': function(obj, o, v){
|
443
|
-
this.tooltip.appendTo(v);
|
446
|
+
this.rendered && this.tooltip.appendTo(v);
|
444
447
|
},
|
445
448
|
|
446
449
|
// Show checks
|
@@ -450,29 +453,30 @@ CHECKS = PROTOTYPE.checks = {
|
|
450
453
|
|
451
454
|
// Style checks
|
452
455
|
'^style.classes$': function(obj, o, v, p) {
|
453
|
-
this.tooltip.removeClass(p).addClass(v);
|
456
|
+
this.rendered && this.tooltip.removeClass(p).addClass(v);
|
454
457
|
},
|
455
|
-
'^style.width|height': function(obj, o, v) {
|
456
|
-
this.tooltip.css(o, v);
|
458
|
+
'^style.(width|height)': function(obj, o, v) {
|
459
|
+
this.rendered && this.tooltip.css(o, v);
|
457
460
|
},
|
458
461
|
'^style.widget|content.title': function() {
|
459
|
-
this._setWidget();
|
462
|
+
this.rendered && this._setWidget();
|
460
463
|
},
|
461
464
|
'^style.def': function(obj, o, v) {
|
462
|
-
this.tooltip.toggleClass(CLASS_DEFAULT, !!v);
|
465
|
+
this.rendered && this.tooltip.toggleClass(CLASS_DEFAULT, !!v);
|
463
466
|
},
|
464
467
|
|
465
468
|
// Events check
|
466
469
|
'^events.(render|show|move|hide|focus|blur)$': function(obj, o, v) {
|
467
|
-
tooltip[($.isFunction(v) ? '' : 'un') + 'bind']('tooltip'+o, v);
|
470
|
+
this.rendered && this.tooltip[($.isFunction(v) ? '' : 'un') + 'bind']('tooltip'+o, v);
|
468
471
|
},
|
469
472
|
|
470
473
|
// Properties which require event reassignment
|
471
474
|
'^(show|hide|position).(event|target|fixed|inactive|leave|distance|viewport|adjust)': function() {
|
472
|
-
|
475
|
+
if(!this.rendered) { return; }
|
473
476
|
|
474
477
|
// Set tracking flag
|
475
|
-
|
478
|
+
var posOptions = this.options.position;
|
479
|
+
this.tooltip.attr('tracking', posOptions.target === 'mouse' && posOptions.adjust.mouse);
|
476
480
|
|
477
481
|
// Reassign events
|
478
482
|
this._unassignEvents();
|
@@ -543,7 +547,7 @@ PROTOTYPE.set = function(option, value) {
|
|
543
547
|
|
544
548
|
// Set all of the defined options to their new values
|
545
549
|
$.each(option, function(notation, value) {
|
546
|
-
if(
|
550
|
+
if(rendered && rrender.test(notation)) {
|
547
551
|
delete option[notation]; return;
|
548
552
|
}
|
549
553
|
|
@@ -577,7 +581,6 @@ PROTOTYPE.set = function(option, value) {
|
|
577
581
|
|
578
582
|
return this;
|
579
583
|
};
|
580
|
-
|
581
584
|
;PROTOTYPE._update = function(content, element, reposition) {
|
582
585
|
var self = this,
|
583
586
|
cache = this.cache;
|
@@ -606,24 +609,31 @@ PROTOTYPE.set = function(option, value) {
|
|
606
609
|
|
607
610
|
// Append new content if its a DOM array and show it if hidden
|
608
611
|
if(content.jquery && content.length > 0) {
|
609
|
-
element.
|
612
|
+
element.empty().append(
|
613
|
+
content.css({ display: 'block', visibility: 'visible' })
|
614
|
+
);
|
610
615
|
}
|
611
616
|
|
612
617
|
// Content is a regular string, insert the new content
|
613
618
|
else { element.html(content); }
|
614
619
|
|
615
|
-
//
|
616
|
-
|
620
|
+
// Wait for content to be loaded, and reposition
|
621
|
+
return this._waitForContent(element).then(function(images) {
|
622
|
+
if(self.rendered && self.tooltip[0].offsetWidth > 0) {
|
623
|
+
self.reposition(cache.event, !images.length);
|
624
|
+
}
|
625
|
+
});
|
626
|
+
};
|
617
627
|
|
618
|
-
|
619
|
-
|
620
|
-
cache.waiting = FALSE;
|
628
|
+
PROTOTYPE._waitForContent = function(element) {
|
629
|
+
var cache = this.cache;
|
621
630
|
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
631
|
+
// Set flag
|
632
|
+
cache.waiting = TRUE;
|
633
|
+
|
634
|
+
// If imagesLoaded is included, ensure images have loaded and return promise
|
635
|
+
return ( $.fn.imagesLoaded ? element.imagesLoaded() : $.Deferred().resolve([]) )
|
636
|
+
.done(function() { cache.waiting = FALSE; })
|
627
637
|
.promise();
|
628
638
|
};
|
629
639
|
|
@@ -682,8 +692,11 @@ PROTOTYPE._removeTitle = function(reposition)
|
|
682
692
|
if(reposition !== FALSE) { this.reposition(); }
|
683
693
|
}
|
684
694
|
};
|
695
|
+
;PROTOTYPE._createPosClass = function(my) {
|
696
|
+
return NAMESPACE + '-pos-' + (my || this.options.position.my).abbrev();
|
697
|
+
};
|
685
698
|
|
686
|
-
|
699
|
+
PROTOTYPE.reposition = function(event, effect) {
|
687
700
|
if(!this.rendered || this.positioning || this.destroyed) { return this; }
|
688
701
|
|
689
702
|
// Set positioning flag
|
@@ -699,8 +712,8 @@ PROTOTYPE._removeTitle = function(reposition)
|
|
699
712
|
container = posOptions.container,
|
700
713
|
adjust = posOptions.adjust,
|
701
714
|
method = adjust.method.split(' '),
|
702
|
-
|
703
|
-
|
715
|
+
tooltipWidth = tooltip.outerWidth(FALSE),
|
716
|
+
tooltipHeight = tooltip.outerHeight(FALSE),
|
704
717
|
targetWidth = 0,
|
705
718
|
targetHeight = 0,
|
706
719
|
type = tooltip.css('position'),
|
@@ -710,7 +723,7 @@ PROTOTYPE._removeTitle = function(reposition)
|
|
710
723
|
win = $(window),
|
711
724
|
doc = container[0].ownerDocument,
|
712
725
|
mouse = this.mouse,
|
713
|
-
pluginCalculations, offset;
|
726
|
+
pluginCalculations, offset, adjusted, newClass;
|
714
727
|
|
715
728
|
// Check if absolute position was passed
|
716
729
|
if($.isArray(target) && target.length === 2) {
|
@@ -720,20 +733,30 @@ PROTOTYPE._removeTitle = function(reposition)
|
|
720
733
|
}
|
721
734
|
|
722
735
|
// Check if mouse was the target
|
723
|
-
else if(target === 'mouse'
|
736
|
+
else if(target === 'mouse') {
|
724
737
|
// Force left top to allow flipping
|
725
738
|
at = { x: LEFT, y: TOP };
|
726
739
|
|
727
|
-
// Use
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
740
|
+
// Use the mouse origin that caused the show event, if distance hiding is enabled
|
741
|
+
if((!adjust.mouse || this.options.hide.distance) && cache.origin && cache.origin.pageX) {
|
742
|
+
event = cache.origin;
|
743
|
+
}
|
744
|
+
|
745
|
+
// Use cached event for resize/scroll events
|
746
|
+
else if(!event || (event && (event.type === 'resize' || event.type === 'scroll'))) {
|
747
|
+
event = cache.event;
|
748
|
+
}
|
749
|
+
|
750
|
+
// Otherwise, use the cached mouse coordinates if available
|
751
|
+
else if(mouse && mouse.pageX) {
|
752
|
+
event = mouse;
|
753
|
+
}
|
733
754
|
|
734
755
|
// Calculate body and container offset and take them into account below
|
735
756
|
if(type !== 'static') { position = container.offset(); }
|
736
|
-
if(doc.body.offsetWidth !== (window.innerWidth || doc.documentElement.clientWidth)) {
|
757
|
+
if(doc.body.offsetWidth !== (window.innerWidth || doc.documentElement.clientWidth)) {
|
758
|
+
offset = $(document.body).offset();
|
759
|
+
}
|
737
760
|
|
738
761
|
// Use event coordinates for position
|
739
762
|
position = {
|
@@ -742,20 +765,25 @@ PROTOTYPE._removeTitle = function(reposition)
|
|
742
765
|
};
|
743
766
|
|
744
767
|
// Scroll events are a pain, some browsers
|
745
|
-
if(adjust.mouse && isScroll) {
|
746
|
-
position.left -= mouse.scrollX - win.scrollLeft();
|
747
|
-
position.top -= mouse.scrollY - win.scrollTop();
|
768
|
+
if(adjust.mouse && isScroll && mouse) {
|
769
|
+
position.left -= (mouse.scrollX || 0) - win.scrollLeft();
|
770
|
+
position.top -= (mouse.scrollY || 0) - win.scrollTop();
|
748
771
|
}
|
749
772
|
}
|
750
773
|
|
751
774
|
// Target wasn't mouse or absolute...
|
752
775
|
else {
|
753
776
|
// Check if event targetting is being used
|
754
|
-
if(target === 'event'
|
755
|
-
|
777
|
+
if(target === 'event') {
|
778
|
+
if(event && event.target && event.type !== 'scroll' && event.type !== 'resize') {
|
779
|
+
cache.target = $(event.target);
|
780
|
+
}
|
781
|
+
else if(!event.target) {
|
782
|
+
cache.target = this.elements.target;
|
783
|
+
}
|
756
784
|
}
|
757
785
|
else if(target !== 'event'){
|
758
|
-
cache.target = $(target.jquery ? target : elements.target);
|
786
|
+
cache.target = $(target.jquery ? target : this.elements.target);
|
759
787
|
}
|
760
788
|
target = cache.target;
|
761
789
|
|
@@ -782,7 +810,7 @@ PROTOTYPE._removeTitle = function(reposition)
|
|
782
810
|
}
|
783
811
|
|
784
812
|
// Check if the target is an SVG element
|
785
|
-
else if(PLUGINS.svg && target[0].ownerSVGElement) {
|
813
|
+
else if(PLUGINS.svg && target && target[0].ownerSVGElement) {
|
786
814
|
pluginCalculations = PLUGINS.svg(this, target, at, PLUGINS.viewport ? method : FALSE);
|
787
815
|
}
|
788
816
|
|
@@ -805,8 +833,8 @@ PROTOTYPE._removeTitle = function(reposition)
|
|
805
833
|
position = this.reposition.offset(target, position, container);
|
806
834
|
|
807
835
|
// Adjust for position.fixed tooltips (and also iOS scroll bug in v3.2-4.0 & v4.3-4.3.2)
|
808
|
-
if((BROWSER.iOS > 3.1 && BROWSER.iOS < 4.1) ||
|
809
|
-
(BROWSER.iOS >= 4.3 && BROWSER.iOS < 4.33) ||
|
836
|
+
if((BROWSER.iOS > 3.1 && BROWSER.iOS < 4.1) ||
|
837
|
+
(BROWSER.iOS >= 4.3 && BROWSER.iOS < 4.33) ||
|
810
838
|
(!BROWSER.iOS && type === 'fixed')
|
811
839
|
){
|
812
840
|
position.left -= win.scrollLeft();
|
@@ -821,23 +849,31 @@ PROTOTYPE._removeTitle = function(reposition)
|
|
821
849
|
}
|
822
850
|
|
823
851
|
// Adjust position relative to tooltip
|
824
|
-
position.left += adjust.x + (my.x === RIGHT ? -
|
825
|
-
position.top += adjust.y + (my.y === BOTTOM ? -
|
852
|
+
position.left += adjust.x + (my.x === RIGHT ? -tooltipWidth : my.x === CENTER ? -tooltipWidth / 2 : 0);
|
853
|
+
position.top += adjust.y + (my.y === BOTTOM ? -tooltipHeight : my.y === CENTER ? -tooltipHeight / 2 : 0);
|
826
854
|
|
827
855
|
// Use viewport adjustment plugin if enabled
|
828
856
|
if(PLUGINS.viewport) {
|
829
|
-
position.adjusted = PLUGINS.viewport(
|
830
|
-
this, position, posOptions, targetWidth, targetHeight,
|
857
|
+
adjusted = position.adjusted = PLUGINS.viewport(
|
858
|
+
this, position, posOptions, targetWidth, targetHeight, tooltipWidth, tooltipHeight
|
831
859
|
);
|
832
860
|
|
833
861
|
// Apply offsets supplied by positioning plugin (if used)
|
834
|
-
if(offset &&
|
835
|
-
if(offset &&
|
862
|
+
if(offset && adjusted.left) { position.left += offset.left; }
|
863
|
+
if(offset && adjusted.top) { position.top += offset.top; }
|
864
|
+
|
865
|
+
// Apply any new 'my' position
|
866
|
+
if(adjusted.my) { this.position.my = adjusted.my; }
|
836
867
|
}
|
837
868
|
|
838
869
|
// Viewport adjustment is disabled, set values to zero
|
839
870
|
else { position.adjusted = { left: 0, top: 0 }; }
|
840
871
|
|
872
|
+
// Set tooltip position class if it's changed
|
873
|
+
if(cache.posClass !== (newClass = this._createPosClass(this.position.my))) {
|
874
|
+
tooltip.removeClass(cache.posClass).addClass( (cache.posClass = newClass) );
|
875
|
+
}
|
876
|
+
|
841
877
|
// tooltipmove event
|
842
878
|
if(!this._trigger('move', [position, viewport.elem || viewport], event)) { return this; }
|
843
879
|
delete position.adjusted;
|
@@ -921,22 +957,31 @@ var C = (CORNER = PROTOTYPE.reposition.Corner = function(corner, forceY) {
|
|
921
957
|
}).prototype;
|
922
958
|
|
923
959
|
C.invert = function(z, center) {
|
924
|
-
this[z] = this[z] === LEFT ? RIGHT : this[z] === RIGHT ? LEFT : center || this[z];
|
960
|
+
this[z] = this[z] === LEFT ? RIGHT : this[z] === RIGHT ? LEFT : center || this[z];
|
925
961
|
};
|
926
962
|
|
927
|
-
C.string = function() {
|
963
|
+
C.string = function(join) {
|
928
964
|
var x = this.x, y = this.y;
|
929
|
-
|
965
|
+
|
966
|
+
var result = x !== y ?
|
967
|
+
(x === 'center' || y !== 'center' && (this.precedance === Y || this.forceY) ?
|
968
|
+
[y,x] : [x,y]
|
969
|
+
) :
|
970
|
+
[x];
|
971
|
+
|
972
|
+
return join !== false ? result.join(' ') : result;
|
930
973
|
};
|
931
974
|
|
932
975
|
C.abbrev = function() {
|
933
|
-
var result = this.string()
|
976
|
+
var result = this.string(false);
|
934
977
|
return result[0].charAt(0) + (result[1] && result[1].charAt(0) || '');
|
935
978
|
};
|
936
979
|
|
937
980
|
C.clone = function() {
|
938
981
|
return new CORNER( this.string(), this.forceY );
|
939
|
-
}
|
982
|
+
};
|
983
|
+
|
984
|
+
;
|
940
985
|
PROTOTYPE.toggle = function(state, event) {
|
941
986
|
var cache = this.cache,
|
942
987
|
options = this.options,
|
@@ -944,16 +989,16 @@ PROTOTYPE.toggle = function(state, event) {
|
|
944
989
|
|
945
990
|
// Try to prevent flickering when tooltip overlaps show element
|
946
991
|
if(event) {
|
947
|
-
if((/over|enter/).test(event.type) && (/out|leave/).test(cache.event.type) &&
|
992
|
+
if((/over|enter/).test(event.type) && cache.event && (/out|leave/).test(cache.event.type) &&
|
948
993
|
options.show.target.add(event.target).length === options.show.target.length &&
|
949
994
|
tooltip.has(event.relatedTarget).length) {
|
950
995
|
return this;
|
951
996
|
}
|
952
997
|
|
953
998
|
// Cache event
|
954
|
-
cache.event = $.
|
999
|
+
cache.event = $.event.fix(event);
|
955
1000
|
}
|
956
|
-
|
1001
|
+
|
957
1002
|
// If we're currently waiting and we've just hidden... stop it
|
958
1003
|
this.waiting && !state && (this.hiddenDuringWait = TRUE);
|
959
1004
|
|
@@ -967,10 +1012,10 @@ PROTOTYPE.toggle = function(state, event) {
|
|
967
1012
|
posOptions = this.options.position,
|
968
1013
|
contentOptions = this.options.content,
|
969
1014
|
width = this.tooltip.css('width'),
|
970
|
-
visible = this.tooltip
|
1015
|
+
visible = this.tooltip.is(':visible'),
|
971
1016
|
animate = state || opts.target.length === 1,
|
972
1017
|
sameTarget = !event || opts.target.length < 2 || cache.target[0] === event.target,
|
973
|
-
identicalState, allow, showEvent, delay;
|
1018
|
+
identicalState, allow, showEvent, delay, after;
|
974
1019
|
|
975
1020
|
// Detect state if valid one isn't provided
|
976
1021
|
if((typeof state).search('boolean|number')) { state = !visible; }
|
@@ -981,6 +1026,9 @@ PROTOTYPE.toggle = function(state, event) {
|
|
981
1026
|
// Fire tooltip(show/hide) event and check if destroyed
|
982
1027
|
allow = !identicalState ? !!this._trigger(type, [90]) : NULL;
|
983
1028
|
|
1029
|
+
// Check to make sure the tooltip wasn't destroyed in the callback
|
1030
|
+
if(this.destroyed) { return this; }
|
1031
|
+
|
984
1032
|
// If the user didn't stop the method prematurely and we're showing the tooltip, focus it
|
985
1033
|
if(allow !== FALSE && state) { this.focus(event); }
|
986
1034
|
|
@@ -993,7 +1041,7 @@ PROTOTYPE.toggle = function(state, event) {
|
|
993
1041
|
// Execute state specific properties
|
994
1042
|
if(state) {
|
995
1043
|
// Store show origin coordinates
|
996
|
-
cache.origin = $.
|
1044
|
+
this.mouse && (cache.origin = $.event.fix(this.mouse));
|
997
1045
|
|
998
1046
|
// Update tooltip content & title if it's a dynamic function
|
999
1047
|
if($.isFunction(contentOptions.text)) { this._updateContent(contentOptions.text, FALSE); }
|
@@ -1092,7 +1140,6 @@ PROTOTYPE.toggle = function(state, event) {
|
|
1092
1140
|
PROTOTYPE.show = function(event) { return this.toggle(TRUE, event); };
|
1093
1141
|
|
1094
1142
|
PROTOTYPE.hide = function(event) { return this.toggle(FALSE, event); };
|
1095
|
-
|
1096
1143
|
;PROTOTYPE.focus = function(event) {
|
1097
1144
|
if(!this.rendered || this.destroyed) { return this; }
|
1098
1145
|
|
@@ -1138,12 +1185,17 @@ PROTOTYPE.blur = function(event) {
|
|
1138
1185
|
|
1139
1186
|
return this;
|
1140
1187
|
};
|
1141
|
-
|
1142
1188
|
;PROTOTYPE.disable = function(state) {
|
1143
1189
|
if(this.destroyed) { return this; }
|
1144
1190
|
|
1145
|
-
|
1146
|
-
|
1191
|
+
// If 'toggle' is passed, toggle the current state
|
1192
|
+
if(state === 'toggle') {
|
1193
|
+
state = !(this.rendered ? this.tooltip.hasClass(CLASS_DISABLED) : this.disabled);
|
1194
|
+
}
|
1195
|
+
|
1196
|
+
// Disable if no state passed
|
1197
|
+
else if('boolean' !== typeof state) {
|
1198
|
+
state = TRUE;
|
1147
1199
|
}
|
1148
1200
|
|
1149
1201
|
if(this.rendered) {
|
@@ -1157,7 +1209,6 @@ PROTOTYPE.blur = function(event) {
|
|
1157
1209
|
};
|
1158
1210
|
|
1159
1211
|
PROTOTYPE.enable = function() { return this.disable(FALSE); };
|
1160
|
-
|
1161
1212
|
;PROTOTYPE._createButton = function()
|
1162
1213
|
{
|
1163
1214
|
var self = this,
|
@@ -1205,7 +1256,6 @@ PROTOTYPE._updateButton = function(button)
|
|
1205
1256
|
if(button) { this._createButton(); }
|
1206
1257
|
else { elem.remove(); }
|
1207
1258
|
};
|
1208
|
-
|
1209
1259
|
;// Widget class creator
|
1210
1260
|
function createWidgetClass(cls) {
|
1211
1261
|
return WIDGET.concat('').join(cls ? '-'+cls+' ' : ' ');
|
@@ -1224,7 +1274,7 @@ PROTOTYPE._setWidget = function()
|
|
1224
1274
|
tooltip.toggleClass(CLASS_DISABLED, disabled);
|
1225
1275
|
|
1226
1276
|
tooltip.toggleClass('ui-helper-reset '+createWidgetClass(), on).toggleClass(CLASS_DEFAULT, this.options.style.def && !on);
|
1227
|
-
|
1277
|
+
|
1228
1278
|
if(elements.content) {
|
1229
1279
|
elements.content.toggleClass( createWidgetClass('content'), on);
|
1230
1280
|
}
|
@@ -1234,23 +1284,33 @@ PROTOTYPE._setWidget = function()
|
|
1234
1284
|
if(elements.button) {
|
1235
1285
|
elements.button.toggleClass(NAMESPACE+'-icon', !on);
|
1236
1286
|
}
|
1237
|
-
}
|
1238
|
-
|
1287
|
+
};
|
1288
|
+
;function delay(callback, duration) {
|
1289
|
+
// If tooltip has displayed, start hide timer
|
1290
|
+
if(duration > 0) {
|
1291
|
+
return setTimeout(
|
1292
|
+
$.proxy(callback, this), duration
|
1293
|
+
);
|
1294
|
+
}
|
1295
|
+
else{ callback.call(this); }
|
1296
|
+
}
|
1297
|
+
|
1298
|
+
function showMethod(event) {
|
1299
|
+
if(this.tooltip.hasClass(CLASS_DISABLED)) { return; }
|
1239
1300
|
|
1240
1301
|
// Clear hide timers
|
1241
1302
|
clearTimeout(this.timers.show);
|
1242
1303
|
clearTimeout(this.timers.hide);
|
1243
1304
|
|
1244
1305
|
// Start show timer
|
1245
|
-
|
1246
|
-
|
1247
|
-
this.
|
1248
|
-
|
1249
|
-
else{ callback(); }
|
1306
|
+
this.timers.show = delay.call(this,
|
1307
|
+
function() { this.toggle(TRUE, event); },
|
1308
|
+
this.options.show.delay
|
1309
|
+
);
|
1250
1310
|
}
|
1251
1311
|
|
1252
1312
|
function hideMethod(event) {
|
1253
|
-
if(this.tooltip.hasClass(CLASS_DISABLED)) { return
|
1313
|
+
if(this.tooltip.hasClass(CLASS_DISABLED) || this.destroyed) { return; }
|
1254
1314
|
|
1255
1315
|
// Check if new target was actually the tooltip element
|
1256
1316
|
var relatedTarget = $(event.relatedTarget),
|
@@ -1263,8 +1323,8 @@ function hideMethod(event) {
|
|
1263
1323
|
|
1264
1324
|
// Prevent hiding if tooltip is fixed and event target is the tooltip.
|
1265
1325
|
// Or if mouse positioning is enabled and cursor momentarily overlaps
|
1266
|
-
if(this !== relatedTarget[0] &&
|
1267
|
-
(this.options.position.target === 'mouse' && ontoTooltip) ||
|
1326
|
+
if(this !== relatedTarget[0] &&
|
1327
|
+
(this.options.position.target === 'mouse' && ontoTooltip) ||
|
1268
1328
|
(this.options.hide.fixed && (
|
1269
1329
|
(/mouse(out|leave|move)/).test(event.type) && (ontoTooltip || ontoTarget))
|
1270
1330
|
))
|
@@ -1278,20 +1338,22 @@ function hideMethod(event) {
|
|
1278
1338
|
}
|
1279
1339
|
|
1280
1340
|
// If tooltip has displayed, start hide timer
|
1281
|
-
|
1282
|
-
|
1283
|
-
this.
|
1284
|
-
|
1285
|
-
|
1341
|
+
this.timers.hide = delay.call(this,
|
1342
|
+
function() { this.toggle(FALSE, event); },
|
1343
|
+
this.options.hide.delay,
|
1344
|
+
this
|
1345
|
+
);
|
1286
1346
|
}
|
1287
1347
|
|
1288
1348
|
function inactiveMethod(event) {
|
1289
|
-
if(this.tooltip.hasClass(CLASS_DISABLED) || !this.options.hide.inactive) { return
|
1349
|
+
if(this.tooltip.hasClass(CLASS_DISABLED) || !this.options.hide.inactive) { return; }
|
1290
1350
|
|
1291
1351
|
// Clear timer
|
1292
1352
|
clearTimeout(this.timers.inactive);
|
1293
|
-
|
1294
|
-
|
1353
|
+
|
1354
|
+
this.timers.inactive = delay.call(this,
|
1355
|
+
function(){ this.hide(event); },
|
1356
|
+
this.options.hide.inactive
|
1295
1357
|
);
|
1296
1358
|
}
|
1297
1359
|
|
@@ -1301,87 +1363,144 @@ function repositionMethod(event) {
|
|
1301
1363
|
|
1302
1364
|
// Store mouse coordinates
|
1303
1365
|
PROTOTYPE._storeMouse = function(event) {
|
1304
|
-
this.mouse =
|
1305
|
-
|
1306
|
-
pageY: event.pageY,
|
1307
|
-
type: 'mousemove',
|
1308
|
-
scrollX: window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft,
|
1309
|
-
scrollY: window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop
|
1310
|
-
};
|
1366
|
+
(this.mouse = $.event.fix(event)).type = 'mousemove';
|
1367
|
+
return this;
|
1311
1368
|
};
|
1312
1369
|
|
1313
1370
|
// Bind events
|
1314
1371
|
PROTOTYPE._bind = function(targets, events, method, suffix, context) {
|
1372
|
+
if(!targets || !method || !events.length) { return; }
|
1315
1373
|
var ns = '.' + this._id + (suffix ? '-'+suffix : '');
|
1316
|
-
|
1374
|
+
$(targets).bind(
|
1317
1375
|
(events.split ? events : events.join(ns + ' ')) + ns,
|
1318
1376
|
$.proxy(method, context || this)
|
1319
1377
|
);
|
1378
|
+
return this;
|
1320
1379
|
};
|
1321
1380
|
PROTOTYPE._unbind = function(targets, suffix) {
|
1322
|
-
$(targets).unbind('.' + this._id + (suffix ? '-'+suffix : ''));
|
1381
|
+
targets && $(targets).unbind('.' + this._id + (suffix ? '-'+suffix : ''));
|
1382
|
+
return this;
|
1323
1383
|
};
|
1324
1384
|
|
1325
|
-
//
|
1326
|
-
|
1327
|
-
function delegate(selector, events, method) {
|
1385
|
+
// Global delegation helper
|
1386
|
+
function delegate(selector, events, method) {
|
1328
1387
|
$(document.body).delegate(selector,
|
1329
|
-
(events.split ? events : events.join(
|
1388
|
+
(events.split ? events : events.join('.'+NAMESPACE + ' ')) + '.'+NAMESPACE,
|
1330
1389
|
function() {
|
1331
1390
|
var api = QTIP.api[ $.attr(this, ATTR_ID) ];
|
1332
1391
|
api && !api.disabled && method.apply(api, arguments);
|
1333
1392
|
}
|
1334
1393
|
);
|
1335
1394
|
}
|
1395
|
+
// Event trigger
|
1396
|
+
PROTOTYPE._trigger = function(type, args, event) {
|
1397
|
+
var callback = $.Event('tooltip'+type);
|
1398
|
+
callback.originalEvent = (event && $.extend({}, event)) || this.cache.event || NULL;
|
1336
1399
|
|
1337
|
-
|
1338
|
-
|
1339
|
-
|
1340
|
-
tooltip = $(event.currentTarget),
|
1341
|
-
target = $(event.relatedTarget || event.target),
|
1342
|
-
options = this.options;
|
1400
|
+
this.triggering = type;
|
1401
|
+
this.tooltip.trigger(callback, [this].concat(args || []));
|
1402
|
+
this.triggering = FALSE;
|
1343
1403
|
|
1344
|
-
|
1345
|
-
|
1346
|
-
// Focus the tooltip on mouseenter (z-index stacking)
|
1347
|
-
this.focus(event);
|
1404
|
+
return !callback.isDefaultPrevented();
|
1405
|
+
};
|
1348
1406
|
|
1349
|
-
|
1350
|
-
|
1351
|
-
|
1407
|
+
PROTOTYPE._bindEvents = function(showEvents, hideEvents, showTargets, hideTargets, showMethod, hideMethod) {
|
1408
|
+
// Get tasrgets that lye within both
|
1409
|
+
var similarTargets = showTargets.filter( hideTargets ).add( hideTargets.filter(showTargets) ),
|
1410
|
+
toggleEvents = [];
|
1352
1411
|
|
1353
|
-
|
1354
|
-
|
1355
|
-
|
1356
|
-
|
1357
|
-
|
1358
|
-
|
1359
|
-
|
1412
|
+
// If hide and show targets are the same...
|
1413
|
+
if(similarTargets.length) {
|
1414
|
+
|
1415
|
+
// Filter identical show/hide events
|
1416
|
+
$.each(hideEvents, function(i, type) {
|
1417
|
+
var showIndex = $.inArray(type, showEvents);
|
1418
|
+
|
1419
|
+
// Both events are identical, remove from both hide and show events
|
1420
|
+
// and append to toggleEvents
|
1421
|
+
showIndex > -1 && toggleEvents.push( showEvents.splice( showIndex, 1 )[0] );
|
1422
|
+
});
|
1423
|
+
|
1424
|
+
// Toggle events are special case of identical show/hide events, which happen in sequence
|
1425
|
+
if(toggleEvents.length) {
|
1426
|
+
// Bind toggle events to the similar targets
|
1427
|
+
this._bind(similarTargets, toggleEvents, function(event) {
|
1428
|
+
var state = this.rendered ? this.tooltip[0].offsetWidth > 0 : false;
|
1429
|
+
(state ? hideMethod : showMethod).call(this, event);
|
1430
|
+
});
|
1431
|
+
|
1432
|
+
// Remove the similar targets from the regular show/hide bindings
|
1433
|
+
showTargets = showTargets.not(similarTargets);
|
1434
|
+
hideTargets = hideTargets.not(similarTargets);
|
1360
1435
|
}
|
1436
|
+
}
|
1361
1437
|
|
1362
|
-
|
1363
|
-
|
1438
|
+
// Apply show/hide/toggle events
|
1439
|
+
this._bind(showTargets, showEvents, showMethod);
|
1440
|
+
this._bind(hideTargets, hideEvents, hideMethod);
|
1441
|
+
};
|
1442
|
+
|
1443
|
+
PROTOTYPE._assignInitialEvents = function(event) {
|
1444
|
+
var options = this.options,
|
1445
|
+
showTarget = options.show.target,
|
1446
|
+
hideTarget = options.hide.target,
|
1447
|
+
showEvents = options.show.event ? $.trim('' + options.show.event).split(' ') : [],
|
1448
|
+
hideEvents = options.hide.event ? $.trim('' + options.hide.event).split(' ') : [];
|
1449
|
+
|
1450
|
+
// Catch remove/removeqtip events on target element to destroy redundant tooltips
|
1451
|
+
this._bind(this.elements.target, ['remove', 'removeqtip'], function(event) {
|
1452
|
+
this.destroy(true);
|
1453
|
+
}, 'destroy');
|
1454
|
+
|
1455
|
+
/*
|
1456
|
+
* Make sure hoverIntent functions properly by using mouseleave as a hide event if
|
1457
|
+
* mouseenter/mouseout is used for show.event, even if it isn't in the users options.
|
1458
|
+
*/
|
1459
|
+
if(/mouse(over|enter)/i.test(options.show.event) && !/mouse(out|leave)/i.test(options.hide.event)) {
|
1460
|
+
hideEvents.push('mouseleave');
|
1461
|
+
}
|
1462
|
+
|
1463
|
+
/*
|
1464
|
+
* Also make sure initial mouse targetting works correctly by caching mousemove coords
|
1465
|
+
* on show targets before the tooltip has rendered. Also set onTarget when triggered to
|
1466
|
+
* keep mouse tracking working.
|
1467
|
+
*/
|
1468
|
+
this._bind(showTarget, 'mousemove', function(event) {
|
1469
|
+
this._storeMouse(event);
|
1470
|
+
this.cache.onTarget = TRUE;
|
1364
1471
|
});
|
1365
1472
|
|
1366
|
-
// Define
|
1367
|
-
|
1368
|
-
|
1473
|
+
// Define hoverIntent function
|
1474
|
+
function hoverIntent(event) {
|
1475
|
+
// Only continue if tooltip isn't disabled
|
1476
|
+
if(this.disabled || this.destroyed) { return FALSE; }
|
1369
1477
|
|
1370
|
-
//
|
1371
|
-
|
1372
|
-
|
1373
|
-
callback.originalEvent = (event && $.extend({}, event)) || this.cache.event || NULL;
|
1478
|
+
// Cache the event data
|
1479
|
+
this.cache.event = event && $.event.fix(event);
|
1480
|
+
this.cache.target = event && $(event.target);
|
1374
1481
|
|
1375
|
-
|
1376
|
-
|
1377
|
-
|
1482
|
+
// Start the event sequence
|
1483
|
+
clearTimeout(this.timers.show);
|
1484
|
+
this.timers.show = delay.call(this,
|
1485
|
+
function() { this.render(typeof event === 'object' || options.show.ready); },
|
1486
|
+
options.prerender ? 0 : options.show.delay
|
1487
|
+
);
|
1488
|
+
}
|
1378
1489
|
|
1379
|
-
|
1490
|
+
// Filter and bind events
|
1491
|
+
this._bindEvents(showEvents, hideEvents, showTarget, hideTarget, hoverIntent, function() {
|
1492
|
+
if(!this.timers) { return FALSE; }
|
1493
|
+
clearTimeout(this.timers.show);
|
1494
|
+
});
|
1495
|
+
|
1496
|
+
// Prerendering is enabled, create tooltip now
|
1497
|
+
if(options.show.ready || options.prerender) { hoverIntent.call(this, event); }
|
1380
1498
|
};
|
1381
1499
|
|
1382
1500
|
// Event assignment method
|
1383
1501
|
PROTOTYPE._assignEvents = function() {
|
1384
|
-
var
|
1502
|
+
var self = this,
|
1503
|
+
options = this.options,
|
1385
1504
|
posOptions = options.position,
|
1386
1505
|
|
1387
1506
|
tooltip = this.tooltip,
|
@@ -1394,8 +1513,13 @@ PROTOTYPE._assignEvents = function() {
|
|
1394
1513
|
windowTarget = $(window),
|
1395
1514
|
|
1396
1515
|
showEvents = options.show.event ? $.trim('' + options.show.event).split(' ') : [],
|
1397
|
-
hideEvents = options.hide.event ? $.trim('' + options.hide.event).split(' ') : []
|
1398
|
-
|
1516
|
+
hideEvents = options.hide.event ? $.trim('' + options.hide.event).split(' ') : [];
|
1517
|
+
|
1518
|
+
|
1519
|
+
// Assign passed event callbacks
|
1520
|
+
$.each(options.events, function(name, callback) {
|
1521
|
+
self._bind(tooltip, name === 'toggle' ? ['tooltipshow','tooltiphide'] : ['tooltip'+name], callback, null, tooltip);
|
1522
|
+
});
|
1399
1523
|
|
1400
1524
|
// Hide tooltips when leaving current window/frame (but not select/option elements)
|
1401
1525
|
if(/mouse(out|leave)/i.test(options.hide.event) && options.hide.leave === 'window') {
|
@@ -1439,31 +1563,14 @@ PROTOTYPE._assignEvents = function() {
|
|
1439
1563
|
// Check if the tooltip hides when inactive
|
1440
1564
|
if('number' === typeof options.hide.inactive) {
|
1441
1565
|
// Bind inactive method to show target(s) as a custom event
|
1442
|
-
this._bind(showTarget, 'qtip-'+this.id+'-inactive', inactiveMethod);
|
1566
|
+
this._bind(showTarget, 'qtip-'+this.id+'-inactive', inactiveMethod, 'inactive');
|
1443
1567
|
|
1444
1568
|
// Define events which reset the 'inactive' event handler
|
1445
|
-
this._bind(hideTarget.add(tooltip), QTIP.inactiveEvents, inactiveMethod
|
1569
|
+
this._bind(hideTarget.add(tooltip), QTIP.inactiveEvents, inactiveMethod);
|
1446
1570
|
}
|
1447
1571
|
|
1448
|
-
//
|
1449
|
-
hideEvents
|
1450
|
-
var showIndex = $.inArray(type, showEvents);
|
1451
|
-
|
1452
|
-
// Both events and targets are identical, apply events using a toggle
|
1453
|
-
if((showIndex > -1 && hideTarget.add(showTarget).length === hideTarget.length)) {
|
1454
|
-
toggleEvents.push( showEvents.splice( showIndex, 1 )[0] ); return;
|
1455
|
-
}
|
1456
|
-
|
1457
|
-
return type;
|
1458
|
-
});
|
1459
|
-
|
1460
|
-
// Apply show/hide/toggle events
|
1461
|
-
this._bind(showTarget, showEvents, showMethod);
|
1462
|
-
this._bind(hideTarget, hideEvents, hideMethod);
|
1463
|
-
this._bind(showTarget, toggleEvents, function(event) {
|
1464
|
-
(this.tooltip[0].offsetWidth > 0 ? hideMethod : showMethod).call(this, event);
|
1465
|
-
});
|
1466
|
-
|
1572
|
+
// Filter and bind events
|
1573
|
+
this._bindEvents(showEvents, hideEvents, showTarget, hideTarget, showMethod, hideMethod);
|
1467
1574
|
|
1468
1575
|
// Mouse movement bindings
|
1469
1576
|
this._bind(showTarget.add(tooltip), 'mousemove', function(event) {
|
@@ -1491,6 +1598,7 @@ PROTOTYPE._assignEvents = function() {
|
|
1491
1598
|
if(options.hide.event) {
|
1492
1599
|
// Track if we're on the target or not
|
1493
1600
|
this._bind(showTarget, ['mouseenter', 'mouseleave'], function(event) {
|
1601
|
+
if(!this.cache) {return FALSE; }
|
1494
1602
|
this.cache.onTarget = event.type === 'mouseenter';
|
1495
1603
|
});
|
1496
1604
|
}
|
@@ -1518,31 +1626,70 @@ PROTOTYPE._assignEvents = function() {
|
|
1518
1626
|
|
1519
1627
|
// Un-assignment method
|
1520
1628
|
PROTOTYPE._unassignEvents = function() {
|
1521
|
-
var
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
|
1529
|
-
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
if(this.rendered) {
|
1534
|
-
this._unbind($([]).pushStack( $.grep(targets, function(i) {
|
1629
|
+
var options = this.options,
|
1630
|
+
showTargets = options.show.target,
|
1631
|
+
hideTargets = options.hide.target,
|
1632
|
+
targets = $.grep([
|
1633
|
+
this.elements.target[0],
|
1634
|
+
this.rendered && this.tooltip[0],
|
1635
|
+
options.position.container[0],
|
1636
|
+
options.position.viewport[0],
|
1637
|
+
options.position.container.closest('html')[0], // unfocus
|
1638
|
+
window,
|
1639
|
+
document
|
1640
|
+
], function(i) {
|
1535
1641
|
return typeof i === 'object';
|
1536
|
-
})
|
1642
|
+
});
|
1643
|
+
|
1644
|
+
// Add show and hide targets if they're valid
|
1645
|
+
if(showTargets && showTargets.toArray) {
|
1646
|
+
targets = targets.concat(showTargets.toArray());
|
1647
|
+
}
|
1648
|
+
if(hideTargets && hideTargets.toArray) {
|
1649
|
+
targets = targets.concat(hideTargets.toArray());
|
1537
1650
|
}
|
1538
1651
|
|
1539
|
-
//
|
1540
|
-
|
1652
|
+
// Unbind the events
|
1653
|
+
this._unbind(targets)
|
1654
|
+
._unbind(targets, 'destroy')
|
1655
|
+
._unbind(targets, 'inactive');
|
1541
1656
|
};
|
1542
1657
|
|
1658
|
+
// Apply common event handlers using delegate (avoids excessive .bind calls!)
|
1659
|
+
$(function() {
|
1660
|
+
delegate(SELECTOR, ['mouseenter', 'mouseleave'], function(event) {
|
1661
|
+
var state = event.type === 'mouseenter',
|
1662
|
+
tooltip = $(event.currentTarget),
|
1663
|
+
target = $(event.relatedTarget || event.target),
|
1664
|
+
options = this.options;
|
1665
|
+
|
1666
|
+
// On mouseenter...
|
1667
|
+
if(state) {
|
1668
|
+
// Focus the tooltip on mouseenter (z-index stacking)
|
1669
|
+
this.focus(event);
|
1670
|
+
|
1671
|
+
// Clear hide timer on tooltip hover to prevent it from closing
|
1672
|
+
tooltip.hasClass(CLASS_FIXED) && !tooltip.hasClass(CLASS_DISABLED) && clearTimeout(this.timers.hide);
|
1673
|
+
}
|
1674
|
+
|
1675
|
+
// On mouseleave...
|
1676
|
+
else {
|
1677
|
+
// When mouse tracking is enabled, hide when we leave the tooltip and not onto the show target (if a hide event is set)
|
1678
|
+
if(options.position.target === 'mouse' && options.position.adjust.mouse &&
|
1679
|
+
options.hide.event && options.show.target && !target.closest(options.show.target[0]).length) {
|
1680
|
+
this.hide(event);
|
1681
|
+
}
|
1682
|
+
}
|
1683
|
+
|
1684
|
+
// Add hover class
|
1685
|
+
tooltip.toggleClass(CLASS_HOVER, state);
|
1686
|
+
});
|
1687
|
+
|
1688
|
+
// Define events which reset the 'inactive' event handler
|
1689
|
+
delegate('['+ATTR_ID+']', INACTIVE_EVENTS, inactiveMethod);
|
1690
|
+
});
|
1543
1691
|
;// Initialization method
|
1544
|
-
function init(elem, id, opts)
|
1545
|
-
{
|
1692
|
+
function init(elem, id, opts) {
|
1546
1693
|
var obj, posOptions, attr, config, title,
|
1547
1694
|
|
1548
1695
|
// Setup element references
|
@@ -1601,7 +1748,7 @@ function init(elem, id, opts)
|
|
1601
1748
|
// Destroy previous tooltip if overwrite is enabled, or skip element if not
|
1602
1749
|
if(elem.data(NAMESPACE)) {
|
1603
1750
|
if(config.overwrite) {
|
1604
|
-
elem.qtip('destroy');
|
1751
|
+
elem.qtip('destroy', true);
|
1605
1752
|
}
|
1606
1753
|
else if(config.overwrite === FALSE) {
|
1607
1754
|
return FALSE;
|
@@ -1621,11 +1768,6 @@ function init(elem, id, opts)
|
|
1621
1768
|
obj = new QTip(elem, config, id, !!attr);
|
1622
1769
|
elem.data(NAMESPACE, obj);
|
1623
1770
|
|
1624
|
-
// Catch remove/removeqtip events on target element to destroy redundant tooltip
|
1625
|
-
elem.one('remove.qtip-'+id+' removeqtip.qtip-'+id, function() {
|
1626
|
-
var api; if((api = $(this).data(NAMESPACE))) { api.destroy(); }
|
1627
|
-
});
|
1628
|
-
|
1629
1771
|
return obj;
|
1630
1772
|
}
|
1631
1773
|
|
@@ -1644,10 +1786,8 @@ QTIP = $.fn.qtip = function(options, notation, newValue)
|
|
1644
1786
|
}
|
1645
1787
|
|
1646
1788
|
// Execute API command if present
|
1647
|
-
else if('string' === typeof options)
|
1648
|
-
|
1649
|
-
this.each(function()
|
1650
|
-
{
|
1789
|
+
else if('string' === typeof options) {
|
1790
|
+
this.each(function() {
|
1651
1791
|
var api = $.data(this, NAMESPACE);
|
1652
1792
|
if(!api) { return TRUE; }
|
1653
1793
|
|
@@ -1675,101 +1815,36 @@ QTIP = $.fn.qtip = function(options, notation, newValue)
|
|
1675
1815
|
}
|
1676
1816
|
|
1677
1817
|
// No API commands. validate provided options and setup qTips
|
1678
|
-
else if('object' === typeof options || !arguments.length)
|
1679
|
-
|
1818
|
+
else if('object' === typeof options || !arguments.length) {
|
1819
|
+
// Sanitize options first
|
1680
1820
|
opts = sanitizeOptions($.extend(TRUE, {}, options));
|
1681
1821
|
|
1682
|
-
|
1683
|
-
|
1684
|
-
}
|
1685
|
-
};
|
1686
|
-
|
1687
|
-
// $.fn.qtip Bind method
|
1688
|
-
QTIP.bind = function(opts, event)
|
1689
|
-
{
|
1690
|
-
return this.each(function(i) {
|
1691
|
-
var options, targets, events, namespace, api, id;
|
1822
|
+
return this.each(function(i) {
|
1823
|
+
var api, id;
|
1692
1824
|
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1825
|
+
// Find next available ID, or use custom ID if provided
|
1826
|
+
id = $.isArray(opts.id) ? opts.id[i] : opts.id;
|
1827
|
+
id = !id || id === FALSE || id.length < 1 || QTIP.api[id] ? QTIP.nextid++ : id;
|
1696
1828
|
|
1697
|
-
|
1698
|
-
|
1829
|
+
// Initialize the qTip and re-grab newly sanitized options
|
1830
|
+
api = init($(this), id, opts);
|
1831
|
+
if(api === FALSE) { return TRUE; }
|
1832
|
+
else { QTIP.api[id] = api; }
|
1699
1833
|
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1704
|
-
options = api.options;
|
1834
|
+
// Initialize plugins
|
1835
|
+
$.each(PLUGINS, function() {
|
1836
|
+
if(this.initialize === 'initialize') { this(api); }
|
1837
|
+
});
|
1705
1838
|
|
1706
|
-
|
1707
|
-
|
1708
|
-
if(this.initialize === 'initialize') { this(api); }
|
1839
|
+
// Assign initial pre-render events
|
1840
|
+
api._assignInitialEvents(event);
|
1709
1841
|
});
|
1710
|
-
|
1711
|
-
// Determine hide and show targets
|
1712
|
-
targets = { show: options.show.target, hide: options.hide.target };
|
1713
|
-
events = {
|
1714
|
-
show: $.trim('' + options.show.event).replace(/ /g, namespace+' ') + namespace,
|
1715
|
-
hide: $.trim('' + options.hide.event).replace(/ /g, namespace+' ') + namespace
|
1716
|
-
};
|
1717
|
-
|
1718
|
-
/*
|
1719
|
-
* Make sure hoverIntent functions properly by using mouseleave as a hide event if
|
1720
|
-
* mouseenter/mouseout is used for show.event, even if it isn't in the users options.
|
1721
|
-
*/
|
1722
|
-
if(/mouse(over|enter)/i.test(events.show) && !/mouse(out|leave)/i.test(events.hide)) {
|
1723
|
-
events.hide += ' mouseleave' + namespace;
|
1724
|
-
}
|
1725
|
-
|
1726
|
-
/*
|
1727
|
-
* Also make sure initial mouse targetting works correctly by caching mousemove coords
|
1728
|
-
* on show targets before the tooltip has rendered.
|
1729
|
-
*
|
1730
|
-
* Also set onTarget when triggered to keep mouse tracking working
|
1731
|
-
*/
|
1732
|
-
targets.show.bind('mousemove'+namespace, function(event) {
|
1733
|
-
api._storeMouse(event);
|
1734
|
-
api.cache.onTarget = TRUE;
|
1735
|
-
});
|
1736
|
-
|
1737
|
-
// Define hoverIntent function
|
1738
|
-
function hoverIntent(event) {
|
1739
|
-
function render() {
|
1740
|
-
// Cache mouse coords,render and render the tooltip
|
1741
|
-
api.render(typeof event === 'object' || options.show.ready);
|
1742
|
-
|
1743
|
-
// Unbind show and hide events
|
1744
|
-
targets.show.add(targets.hide).unbind(namespace);
|
1745
|
-
}
|
1746
|
-
|
1747
|
-
// Only continue if tooltip isn't disabled
|
1748
|
-
if(api.disabled) { return FALSE; }
|
1749
|
-
|
1750
|
-
// Cache the event data
|
1751
|
-
api.cache.event = $.extend({}, event);
|
1752
|
-
api.cache.target = event ? $(event.target) : [undefined];
|
1753
|
-
|
1754
|
-
// Start the event sequence
|
1755
|
-
if(options.show.delay > 0) {
|
1756
|
-
clearTimeout(api.timers.show);
|
1757
|
-
api.timers.show = setTimeout(render, options.show.delay);
|
1758
|
-
if(events.show !== events.hide) {
|
1759
|
-
targets.hide.bind(events.hide, function() { clearTimeout(api.timers.show); });
|
1760
|
-
}
|
1761
|
-
}
|
1762
|
-
else { render(); }
|
1763
|
-
}
|
1764
|
-
|
1765
|
-
// Bind show events to target
|
1766
|
-
targets.show.bind(events.show, hoverIntent);
|
1767
|
-
|
1768
|
-
// Prerendering is enabled, create tooltip now
|
1769
|
-
if(options.show.ready || options.prerender) { hoverIntent(event); }
|
1770
|
-
});
|
1842
|
+
}
|
1771
1843
|
};
|
1772
1844
|
|
1845
|
+
// Expose class
|
1846
|
+
$.qtip = QTip;
|
1847
|
+
|
1773
1848
|
// Populated in render method
|
1774
1849
|
QTIP.api = {};
|
1775
1850
|
;$.each({
|
@@ -1833,16 +1908,15 @@ if(!$.ui) {
|
|
1833
1908
|
$.cleanData = function( elems ) {
|
1834
1909
|
for(var i = 0, elem; (elem = $( elems[i] )).length; i++) {
|
1835
1910
|
if(elem.attr(ATTR_HAS)) {
|
1836
|
-
try { elem.triggerHandler('removeqtip'); }
|
1911
|
+
try { elem.triggerHandler('removeqtip'); }
|
1837
1912
|
catch( e ) {}
|
1838
1913
|
}
|
1839
1914
|
}
|
1840
1915
|
$['cleanData'+replaceSuffix].apply(this, arguments);
|
1841
1916
|
};
|
1842
1917
|
}
|
1843
|
-
|
1844
1918
|
;// qTip version
|
1845
|
-
QTIP.version = '2.
|
1919
|
+
QTIP.version = '2.2.1';
|
1846
1920
|
|
1847
1921
|
// Base ID for all qTips
|
1848
1922
|
QTIP.nextid = 0;
|
@@ -1923,7 +1997,6 @@ QTIP.defaults = {
|
|
1923
1997
|
blur: NULL
|
1924
1998
|
}
|
1925
1999
|
};
|
1926
|
-
|
1927
2000
|
;var TIP,
|
1928
2001
|
|
1929
2002
|
// .bind()/.on() namespace
|
@@ -1969,18 +2042,28 @@ function vendorCss(elem, prop) {
|
|
1969
2042
|
|
1970
2043
|
// Parse a given elements CSS property into an int
|
1971
2044
|
function intCss(elem, prop) {
|
1972
|
-
return
|
2045
|
+
return Math.ceil(parseFloat(vendorCss(elem, prop)));
|
1973
2046
|
}
|
1974
2047
|
|
1975
2048
|
|
1976
2049
|
// VML creation (for IE only)
|
1977
2050
|
if(!HASCANVAS) {
|
1978
|
-
createVML = function(tag, props, style) {
|
2051
|
+
var createVML = function(tag, props, style) {
|
1979
2052
|
return '<qtipvml:'+tag+' xmlns="urn:schemas-microsoft.com:vml" class="qtip-vml" '+(props||'')+
|
1980
2053
|
' style="behavior: url(#default#VML); '+(style||'')+ '" />';
|
1981
2054
|
};
|
1982
2055
|
}
|
1983
2056
|
|
2057
|
+
// Canvas only definitions
|
2058
|
+
else {
|
2059
|
+
var PIXEL_RATIO = window.devicePixelRatio || 1,
|
2060
|
+
BACKING_STORE_RATIO = (function() {
|
2061
|
+
var context = document.createElement('canvas').getContext('2d');
|
2062
|
+
return context.backingStorePixelRatio || context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio ||
|
2063
|
+
context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || 1;
|
2064
|
+
}()),
|
2065
|
+
SCALE = PIXEL_RATIO / BACKING_STORE_RATIO;
|
2066
|
+
}
|
1984
2067
|
|
1985
2068
|
|
1986
2069
|
function Tip(qtip, options) {
|
@@ -2007,7 +2090,7 @@ $.extend(Tip.prototype, {
|
|
2007
2090
|
|
2008
2091
|
// Setup constant parameters
|
2009
2092
|
context.lineJoin = 'miter';
|
2010
|
-
context.miterLimit =
|
2093
|
+
context.miterLimit = 100000;
|
2011
2094
|
context.save();
|
2012
2095
|
}
|
2013
2096
|
else {
|
@@ -2066,7 +2149,7 @@ $.extend(Tip.prototype, {
|
|
2066
2149
|
return (use ? intCss(use, prop) : (
|
2067
2150
|
intCss(elements.content, prop) ||
|
2068
2151
|
intCss(this._useTitle(corner) && elements.titlebar || elements.content, prop) ||
|
2069
|
-
intCss(tooltip, prop)
|
2152
|
+
intCss(elements.tooltip, prop)
|
2070
2153
|
)) || 0;
|
2071
2154
|
},
|
2072
2155
|
|
@@ -2075,7 +2158,7 @@ $.extend(Tip.prototype, {
|
|
2075
2158
|
prop = BORDER + camel(corner.y) + camel(corner.x) + 'Radius';
|
2076
2159
|
|
2077
2160
|
return BROWSER.ie < 9 ? 0 :
|
2078
|
-
intCss(this._useTitle(corner) && elements.titlebar || elements.content, prop) ||
|
2161
|
+
intCss(this._useTitle(corner) && elements.titlebar || elements.content, prop) ||
|
2079
2162
|
intCss(elements.tooltip, prop) || 0;
|
2080
2163
|
},
|
2081
2164
|
|
@@ -2092,12 +2175,12 @@ $.extend(Tip.prototype, {
|
|
2092
2175
|
css = this._invalidColour, color = [];
|
2093
2176
|
|
2094
2177
|
// Attempt to detect the background colour from various elements, left-to-right precedance
|
2095
|
-
color[0] = css(tip, BG_COLOR) || css(colorElem, BG_COLOR) || css(elements.content, BG_COLOR) ||
|
2096
|
-
css(tooltip, BG_COLOR) || tip.css(BG_COLOR);
|
2178
|
+
color[0] = css(tip, BG_COLOR) || css(colorElem, BG_COLOR) || css(elements.content, BG_COLOR) ||
|
2179
|
+
css(elements.tooltip, BG_COLOR) || tip.css(BG_COLOR);
|
2097
2180
|
|
2098
2181
|
// Attempt to detect the correct border side colour from various elements, left-to-right precedance
|
2099
|
-
color[1] = css(tip, borderSide, COLOR) || css(colorElem, borderSide, COLOR) ||
|
2100
|
-
css(elements.content, borderSide, COLOR) || css(tooltip, borderSide, COLOR) || tooltip.css(borderSide);
|
2182
|
+
color[1] = css(tip, borderSide, COLOR) || css(colorElem, borderSide, COLOR) ||
|
2183
|
+
css(elements.content, borderSide, COLOR) || css(elements.tooltip, borderSide, COLOR) || elements.tooltip.css(borderSide);
|
2101
2184
|
|
2102
2185
|
// Reset background and border colours
|
2103
2186
|
$('*', tip).add(tip).css('cssText', BG_COLOR+':'+TRANSPARENT+IMPORTANT+';'+BORDER+':0'+IMPORTANT+';');
|
@@ -2107,10 +2190,10 @@ $.extend(Tip.prototype, {
|
|
2107
2190
|
|
2108
2191
|
_calculateSize: function(corner) {
|
2109
2192
|
var y = corner.precedance === Y,
|
2110
|
-
width = this.options[
|
2111
|
-
height = this.options[
|
2193
|
+
width = this.options['width'],
|
2194
|
+
height = this.options['height'],
|
2112
2195
|
isCenter = corner.abbrev() === 'c',
|
2113
|
-
base = width * (isCenter ? 0.5 : 1),
|
2196
|
+
base = (y ? width: height) * (isCenter ? 0.5 : 1),
|
2114
2197
|
pow = Math.pow,
|
2115
2198
|
round = Math.round,
|
2116
2199
|
bigHyp, ratio, result,
|
@@ -2125,13 +2208,16 @@ $.extend(Tip.prototype, {
|
|
2125
2208
|
ratio = bigHyp / smallHyp;
|
2126
2209
|
|
2127
2210
|
result = [ round(ratio * width), round(ratio * height) ];
|
2128
|
-
|
2129
2211
|
return y ? result : result.reverse();
|
2130
2212
|
},
|
2131
2213
|
|
2132
2214
|
// Tip coordinates calculator
|
2133
|
-
_calculateTip: function(corner) {
|
2134
|
-
|
2215
|
+
_calculateTip: function(corner, size, scale) {
|
2216
|
+
scale = scale || 1;
|
2217
|
+
size = size || this.size;
|
2218
|
+
|
2219
|
+
var width = size[0] * scale,
|
2220
|
+
height = size[1] * scale,
|
2135
2221
|
width2 = Math.ceil(width / 2), height2 = Math.ceil(height / 2),
|
2136
2222
|
|
2137
2223
|
// Define tip coordinates in terms of height and width values
|
@@ -2153,10 +2239,19 @@ $.extend(Tip.prototype, {
|
|
2153
2239
|
return tips[ corner.abbrev() ];
|
2154
2240
|
},
|
2155
2241
|
|
2242
|
+
// Tip coordinates drawer (canvas)
|
2243
|
+
_drawCoords: function(context, coords) {
|
2244
|
+
context.beginPath();
|
2245
|
+
context.moveTo(coords[0], coords[1]);
|
2246
|
+
context.lineTo(coords[2], coords[3]);
|
2247
|
+
context.lineTo(coords[4], coords[5]);
|
2248
|
+
context.closePath();
|
2249
|
+
},
|
2250
|
+
|
2156
2251
|
create: function() {
|
2157
2252
|
// Determine tip corner
|
2158
2253
|
var c = this.corner = (HASCANVAS || BROWSER.ie) && this._parseCorner(this.options.corner);
|
2159
|
-
|
2254
|
+
|
2160
2255
|
// If we have a tip corner...
|
2161
2256
|
if( (this.enabled = !!this.corner && this.corner.abbrev() !== 'c') ) {
|
2162
2257
|
// Cache it
|
@@ -2179,11 +2274,11 @@ $.extend(Tip.prototype, {
|
|
2179
2274
|
tip = this.element,
|
2180
2275
|
inner = tip.children(),
|
2181
2276
|
options = this.options,
|
2182
|
-
|
2277
|
+
curSize = this.size,
|
2183
2278
|
mimic = options.mimic,
|
2184
2279
|
round = Math.round,
|
2185
2280
|
color, precedance, context,
|
2186
|
-
coords, translate, newSize, border;
|
2281
|
+
coords, bigCoords, translate, newSize, border, BACKING_STORE_RATIO;
|
2187
2282
|
|
2188
2283
|
// Re-determine tip if not already set
|
2189
2284
|
if(!corner) { corner = this.qtip.cache.corner || this.corner; }
|
@@ -2216,8 +2311,8 @@ $.extend(Tip.prototype, {
|
|
2216
2311
|
// Grab border width
|
2217
2312
|
border = this.border = this._parseWidth(corner, corner[corner.precedance]);
|
2218
2313
|
|
2219
|
-
// If border width isn't zero, use border color as fill (1.0 style tips)
|
2220
|
-
if(options.border && border < 1) { color[0] = color[1]; }
|
2314
|
+
// If border width isn't zero, use border color as fill if it's not invalid (1.0 style tips)
|
2315
|
+
if(options.border && border < 1 && !INVALID.test(color[1])) { color[0] = color[1]; }
|
2221
2316
|
|
2222
2317
|
// Set border width (use detected border width if options.border is true)
|
2223
2318
|
this.border = border = options.border !== TRUE ? options.border : border;
|
@@ -2226,9 +2321,6 @@ $.extend(Tip.prototype, {
|
|
2226
2321
|
// Border colour was invalid, set border to zero
|
2227
2322
|
else { this.border = border = 0; }
|
2228
2323
|
|
2229
|
-
// Calculate coordinates
|
2230
|
-
coords = this._calculateTip(mimic);
|
2231
|
-
|
2232
2324
|
// Determine tip size
|
2233
2325
|
newSize = this.size = this._calculateSize(corner);
|
2234
2326
|
tip.css({
|
@@ -2240,79 +2332,72 @@ $.extend(Tip.prototype, {
|
|
2240
2332
|
// Calculate tip translation
|
2241
2333
|
if(corner.precedance === Y) {
|
2242
2334
|
translate = [
|
2243
|
-
round(mimic.x === LEFT ? border : mimic.x === RIGHT ? newSize[0] -
|
2244
|
-
round(mimic.y === TOP ? newSize[1] -
|
2335
|
+
round(mimic.x === LEFT ? border : mimic.x === RIGHT ? newSize[0] - curSize[0] - border : (newSize[0] - curSize[0]) / 2),
|
2336
|
+
round(mimic.y === TOP ? newSize[1] - curSize[1] : 0)
|
2245
2337
|
];
|
2246
2338
|
}
|
2247
2339
|
else {
|
2248
2340
|
translate = [
|
2249
|
-
round(mimic.x === LEFT ? newSize[0] -
|
2250
|
-
round(mimic.y === TOP ? border : mimic.y === BOTTOM ? newSize[1] -
|
2341
|
+
round(mimic.x === LEFT ? newSize[0] - curSize[0] : 0),
|
2342
|
+
round(mimic.y === TOP ? border : mimic.y === BOTTOM ? newSize[1] - curSize[1] - border : (newSize[1] - curSize[1]) / 2)
|
2251
2343
|
];
|
2252
2344
|
}
|
2253
2345
|
|
2254
2346
|
// Canvas drawing implementation
|
2255
2347
|
if(HASCANVAS) {
|
2256
|
-
// Set the canvas size using calculated size
|
2257
|
-
inner.attr(WIDTH, newSize[0]).attr(HEIGHT, newSize[1]);
|
2258
|
-
|
2259
2348
|
// Grab canvas context and clear/save it
|
2260
2349
|
context = inner[0].getContext('2d');
|
2261
2350
|
context.restore(); context.save();
|
2262
|
-
context.clearRect(0,0,
|
2351
|
+
context.clearRect(0,0,6000,6000);
|
2352
|
+
|
2353
|
+
// Calculate coordinates
|
2354
|
+
coords = this._calculateTip(mimic, curSize, SCALE);
|
2355
|
+
bigCoords = this._calculateTip(mimic, this.size, SCALE);
|
2356
|
+
|
2357
|
+
// Set the canvas size using calculated size
|
2358
|
+
inner.attr(WIDTH, newSize[0] * SCALE).attr(HEIGHT, newSize[1] * SCALE);
|
2359
|
+
inner.css(WIDTH, newSize[0]).css(HEIGHT, newSize[1]);
|
2360
|
+
|
2361
|
+
// Draw the outer-stroke tip
|
2362
|
+
this._drawCoords(context, bigCoords);
|
2363
|
+
context.fillStyle = color[1];
|
2364
|
+
context.fill();
|
2263
2365
|
|
2264
|
-
//
|
2366
|
+
// Draw the actual tip
|
2367
|
+
context.translate(translate[0] * SCALE, translate[1] * SCALE);
|
2368
|
+
this._drawCoords(context, coords);
|
2265
2369
|
context.fillStyle = color[0];
|
2266
|
-
context.strokeStyle = color[1];
|
2267
|
-
context.lineWidth = border * 2;
|
2268
|
-
|
2269
|
-
// Draw the tip
|
2270
|
-
context.translate(translate[0], translate[1]);
|
2271
|
-
context.beginPath();
|
2272
|
-
context.moveTo(coords[0], coords[1]);
|
2273
|
-
context.lineTo(coords[2], coords[3]);
|
2274
|
-
context.lineTo(coords[4], coords[5]);
|
2275
|
-
context.closePath();
|
2276
|
-
|
2277
|
-
// Apply fill and border
|
2278
|
-
if(border) {
|
2279
|
-
// Make sure transparent borders are supported by doing a stroke
|
2280
|
-
// of the background colour before the stroke colour
|
2281
|
-
if(tooltip.css('background-clip') === 'border-box') {
|
2282
|
-
context.strokeStyle = color[0];
|
2283
|
-
context.stroke();
|
2284
|
-
}
|
2285
|
-
context.strokeStyle = color[1];
|
2286
|
-
context.stroke();
|
2287
|
-
}
|
2288
2370
|
context.fill();
|
2289
2371
|
}
|
2290
2372
|
|
2291
2373
|
// VML (IE Proprietary implementation)
|
2292
2374
|
else {
|
2375
|
+
// Calculate coordinates
|
2376
|
+
coords = this._calculateTip(mimic);
|
2377
|
+
|
2293
2378
|
// Setup coordinates string
|
2294
2379
|
coords = 'm' + coords[0] + ',' + coords[1] + ' l' + coords[2] +
|
2295
2380
|
',' + coords[3] + ' ' + coords[4] + ',' + coords[5] + ' xe';
|
2296
2381
|
|
2297
2382
|
// Setup VML-specific offset for pixel-perfection
|
2298
|
-
translate[2] = border && /^(r|b)/i.test(corner.string()) ?
|
2383
|
+
translate[2] = border && /^(r|b)/i.test(corner.string()) ?
|
2299
2384
|
BROWSER.ie === 8 ? 2 : 1 : 0;
|
2300
2385
|
|
2301
2386
|
// Set initial CSS
|
2302
2387
|
inner.css({
|
2303
|
-
coordsize: (
|
2388
|
+
coordsize: (newSize[0]+border) + ' ' + (newSize[1]+border),
|
2304
2389
|
antialias: ''+(mimic.string().indexOf(CENTER) > -1),
|
2305
2390
|
left: translate[0] - (translate[2] * Number(precedance === X)),
|
2306
2391
|
top: translate[1] - (translate[2] * Number(precedance === Y)),
|
2307
|
-
width:
|
2308
|
-
height:
|
2392
|
+
width: newSize[0] + border,
|
2393
|
+
height: newSize[1] + border
|
2309
2394
|
})
|
2310
2395
|
.each(function(i) {
|
2311
2396
|
var $this = $(this);
|
2312
2397
|
|
2313
2398
|
// Set shape specific attributes
|
2314
2399
|
$this[ $this.prop ? 'prop' : 'attr' ]({
|
2315
|
-
coordsize: (
|
2400
|
+
coordsize: (newSize[0]+border) + ' ' + (newSize[1]+border),
|
2316
2401
|
path: coords,
|
2317
2402
|
fillcolor: color[0],
|
2318
2403
|
filled: !!i,
|
@@ -2327,27 +2412,36 @@ $.extend(Tip.prototype, {
|
|
2327
2412
|
});
|
2328
2413
|
}
|
2329
2414
|
|
2415
|
+
// Opera bug #357 - Incorrect tip position
|
2416
|
+
// https://github.com/Craga89/qTip2/issues/367
|
2417
|
+
window.opera && setTimeout(function() {
|
2418
|
+
elements.tip.css({
|
2419
|
+
display: 'inline-block',
|
2420
|
+
visibility: 'visible'
|
2421
|
+
});
|
2422
|
+
}, 1);
|
2423
|
+
|
2330
2424
|
// Position if needed
|
2331
|
-
if(position !== FALSE) { this.calculate(corner); }
|
2425
|
+
if(position !== FALSE) { this.calculate(corner, newSize); }
|
2332
2426
|
},
|
2333
2427
|
|
2334
|
-
calculate: function(corner) {
|
2428
|
+
calculate: function(corner, size) {
|
2335
2429
|
if(!this.enabled) { return FALSE; }
|
2336
2430
|
|
2337
2431
|
var self = this,
|
2338
2432
|
elements = this.qtip.elements,
|
2339
2433
|
tip = this.element,
|
2340
2434
|
userOffset = this.options.offset,
|
2341
|
-
isWidget =
|
2435
|
+
isWidget = elements.tooltip.hasClass('ui-widget'),
|
2342
2436
|
position = { },
|
2343
|
-
precedance,
|
2437
|
+
precedance, corners;
|
2344
2438
|
|
2345
2439
|
// Inherit corner if not provided
|
2346
2440
|
corner = corner || this.corner;
|
2347
2441
|
precedance = corner.precedance;
|
2348
2442
|
|
2349
2443
|
// Determine which tip dimension to use for adjustment
|
2350
|
-
size = this._calculateSize(corner);
|
2444
|
+
size = size || this._calculateSize(corner);
|
2351
2445
|
|
2352
2446
|
// Setup corners and offset array
|
2353
2447
|
corners = [ corner.x, corner.y ];
|
@@ -2391,71 +2485,57 @@ $.extend(Tip.prototype, {
|
|
2391
2485
|
shift = { left: FALSE, top: FALSE, x: 0, y: 0 },
|
2392
2486
|
offset, css = {}, props;
|
2393
2487
|
|
2394
|
-
|
2395
|
-
if(this.corner.fixed !== TRUE) {
|
2488
|
+
function shiftflip(direction, precedance, popposite, side, opposite) {
|
2396
2489
|
// Horizontal - Shift or flip method
|
2397
|
-
if(
|
2490
|
+
if(direction === SHIFT && newCorner.precedance === precedance && adjust[side] && newCorner[popposite] !== CENTER) {
|
2398
2491
|
newCorner.precedance = newCorner.precedance === X ? Y : X;
|
2399
2492
|
}
|
2400
|
-
else if(
|
2401
|
-
newCorner
|
2493
|
+
else if(direction !== SHIFT && adjust[side]){
|
2494
|
+
newCorner[precedance] = newCorner[precedance] === CENTER ?
|
2495
|
+
(adjust[side] > 0 ? side : opposite) : (newCorner[precedance] === side ? opposite : side);
|
2402
2496
|
}
|
2497
|
+
}
|
2403
2498
|
|
2404
|
-
|
2405
|
-
if(
|
2406
|
-
|
2499
|
+
function shiftonly(xy, side, opposite) {
|
2500
|
+
if(newCorner[xy] === CENTER) {
|
2501
|
+
css[MARGIN+'-'+side] = shift[xy] = offset[MARGIN+'-'+side] - adjust[side];
|
2407
2502
|
}
|
2408
|
-
else
|
2409
|
-
|
2503
|
+
else {
|
2504
|
+
props = offset[opposite] !== undefined ?
|
2505
|
+
[ adjust[side], -offset[side] ] : [ -adjust[side], offset[side] ];
|
2506
|
+
|
2507
|
+
if( (shift[xy] = Math.max(props[0], props[1])) > props[0] ) {
|
2508
|
+
pos[side] -= adjust[side];
|
2509
|
+
shift[side] = FALSE;
|
2510
|
+
}
|
2511
|
+
|
2512
|
+
css[ offset[opposite] !== undefined ? opposite : side ] = shift[xy];
|
2410
2513
|
}
|
2514
|
+
}
|
2515
|
+
|
2516
|
+
// If our tip position isn't fixed e.g. doesn't adjust with viewport...
|
2517
|
+
if(this.corner.fixed !== TRUE) {
|
2518
|
+
// Perform shift/flip adjustments
|
2519
|
+
shiftflip(horizontal, X, Y, LEFT, RIGHT);
|
2520
|
+
shiftflip(vertical, Y, X, TOP, BOTTOM);
|
2411
2521
|
|
2412
2522
|
// Update and redraw the tip if needed (check cached details of last drawn tip)
|
2413
|
-
if(newCorner.string() !== cache.corner.string()
|
2523
|
+
if(newCorner.string() !== cache.corner.string() || cache.cornerTop !== adjust.top || cache.cornerLeft !== adjust.left) {
|
2414
2524
|
this.update(newCorner, FALSE);
|
2415
2525
|
}
|
2416
2526
|
}
|
2417
2527
|
|
2418
2528
|
// Setup tip offset properties
|
2419
|
-
offset = this.calculate(newCorner
|
2529
|
+
offset = this.calculate(newCorner);
|
2420
2530
|
|
2421
2531
|
// Readjust offset object to make it left/top
|
2422
2532
|
if(offset.right !== undefined) { offset.left = -offset.right; }
|
2423
2533
|
if(offset.bottom !== undefined) { offset.top = -offset.bottom; }
|
2424
2534
|
offset.user = this.offset;
|
2425
2535
|
|
2426
|
-
//
|
2427
|
-
if(shift.left = (horizontal === SHIFT && !!adjust.left)) {
|
2428
|
-
|
2429
|
-
css[MARGIN+'-left'] = shift.x = offset[MARGIN+'-left'] - adjust.left;
|
2430
|
-
}
|
2431
|
-
else {
|
2432
|
-
props = offset.right !== undefined ?
|
2433
|
-
[ adjust.left, -offset.left ] : [ -adjust.left, offset.left ];
|
2434
|
-
|
2435
|
-
if( (shift.x = Math.max(props[0], props[1])) > props[0] ) {
|
2436
|
-
pos.left -= adjust.left;
|
2437
|
-
shift.left = FALSE;
|
2438
|
-
}
|
2439
|
-
|
2440
|
-
css[ offset.right !== undefined ? RIGHT : LEFT ] = shift.x;
|
2441
|
-
}
|
2442
|
-
}
|
2443
|
-
if(shift.top = (vertical === SHIFT && !!adjust.top)) {
|
2444
|
-
if(newCorner.y === CENTER) {
|
2445
|
-
css[MARGIN+'-top'] = shift.y = offset[MARGIN+'-top'] - adjust.top;
|
2446
|
-
}
|
2447
|
-
else {
|
2448
|
-
props = offset.bottom !== undefined ?
|
2449
|
-
[ adjust.top, -offset.top ] : [ -adjust.top, offset.top ];
|
2450
|
-
|
2451
|
-
if( (shift.y = Math.max(props[0], props[1])) > props[0] ) {
|
2452
|
-
pos.top -= adjust.top;
|
2453
|
-
shift.top = FALSE;
|
2454
|
-
}
|
2455
|
-
|
2456
|
-
css[ offset.bottom !== undefined ? BOTTOM : TOP ] = shift.y;
|
2457
|
-
}
|
2458
|
-
}
|
2536
|
+
// Perform shift adjustments
|
2537
|
+
if(shift.left = (horizontal === SHIFT && !!adjust.left)) { shiftonly(X, LEFT, RIGHT); }
|
2538
|
+
if(shift.top = (vertical === SHIFT && !!adjust.top)) { shiftonly(Y, TOP, BOTTOM); }
|
2459
2539
|
|
2460
2540
|
/*
|
2461
2541
|
* If the tip is adjusted in both dimensions, or in a
|
@@ -2467,8 +2547,10 @@ $.extend(Tip.prototype, {
|
|
2467
2547
|
);
|
2468
2548
|
|
2469
2549
|
// Adjust position to accomodate tip dimensions
|
2470
|
-
pos.left -= offset.left.charAt ? offset.user :
|
2471
|
-
|
2550
|
+
pos.left -= offset.left.charAt ? offset.user :
|
2551
|
+
horizontal !== SHIFT || shift.top || !shift.left && !shift.top ? offset.left + this.border : 0;
|
2552
|
+
pos.top -= offset.top.charAt ? offset.user :
|
2553
|
+
vertical !== SHIFT || shift.left || !shift.left && !shift.top ? offset.top + this.border : 0;
|
2472
2554
|
|
2473
2555
|
// Cache details
|
2474
2556
|
cache.cornerLeft = adjust.left; cache.cornerTop = adjust.top;
|
@@ -2497,7 +2579,7 @@ TIP.initialize = 'render';
|
|
2497
2579
|
// Setup plugin sanitization options
|
2498
2580
|
TIP.sanitize = function(options) {
|
2499
2581
|
if(options.style && 'tip' in options.style) {
|
2500
|
-
opts = options.style.tip;
|
2582
|
+
var opts = options.style.tip;
|
2501
2583
|
if(typeof opts !== 'object') { opts = options.style.tip = { corner: opts }; }
|
2502
2584
|
if(!(/string|boolean/i).test(typeof opts.corner)) { opts.corner = TRUE; }
|
2503
2585
|
}
|
@@ -2508,13 +2590,13 @@ CHECKS.tip = {
|
|
2508
2590
|
'^position.my|style.tip.(corner|mimic|border)$': function() {
|
2509
2591
|
// Make sure a tip can be drawn
|
2510
2592
|
this.create();
|
2511
|
-
|
2593
|
+
|
2512
2594
|
// Reposition the tooltip
|
2513
2595
|
this.qtip.reposition();
|
2514
2596
|
},
|
2515
2597
|
'^style.tip.(height|width)$': function(obj) {
|
2516
2598
|
// Re-set dimensions and redraw the tip
|
2517
|
-
this.size =
|
2599
|
+
this.size = [ obj.width, obj.height ];
|
2518
2600
|
this.update();
|
2519
2601
|
|
2520
2602
|
// Reposition the tooltip
|
@@ -2538,727 +2620,697 @@ $.extend(TRUE, QTIP.defaults, {
|
|
2538
2620
|
}
|
2539
2621
|
}
|
2540
2622
|
});
|
2541
|
-
|
2542
|
-
;var MODAL, OVERLAY,
|
2543
|
-
MODALCLASS = 'qtip-modal',
|
2544
|
-
MODALSELECTOR = '.'+MODALCLASS;
|
2545
|
-
|
2546
|
-
OVERLAY = function()
|
2623
|
+
;PLUGINS.viewport = function(api, position, posOptions, targetWidth, targetHeight, elemWidth, elemHeight)
|
2547
2624
|
{
|
2548
|
-
var
|
2549
|
-
|
2550
|
-
|
2551
|
-
|
2552
|
-
|
2553
|
-
|
2554
|
-
|
2555
|
-
|
2556
|
-
|
2557
|
-
|
2558
|
-
|
2559
|
-
|
2560
|
-
|
2561
|
-
|
2625
|
+
var target = posOptions.target,
|
2626
|
+
tooltip = api.elements.tooltip,
|
2627
|
+
my = posOptions.my,
|
2628
|
+
at = posOptions.at,
|
2629
|
+
adjust = posOptions.adjust,
|
2630
|
+
method = adjust.method.split(' '),
|
2631
|
+
methodX = method[0],
|
2632
|
+
methodY = method[1] || method[0],
|
2633
|
+
viewport = posOptions.viewport,
|
2634
|
+
container = posOptions.container,
|
2635
|
+
cache = api.cache,
|
2636
|
+
adjusted = { left: 0, top: 0 },
|
2637
|
+
fixed, newMy, containerOffset, containerStatic,
|
2638
|
+
viewportWidth, viewportHeight, viewportScroll, viewportOffset;
|
2562
2639
|
|
2563
|
-
|
2564
|
-
|
2565
|
-
|
2566
|
-
if(!element.href || !mapName || map.nodeName.toLowerCase() !== 'map') {
|
2567
|
-
return false;
|
2568
|
-
}
|
2569
|
-
img = $('img[usemap=#' + mapName + ']')[0];
|
2570
|
-
return !!img && img.is(':visible');
|
2571
|
-
}
|
2572
|
-
return (/input|select|textarea|button|object/.test( nodeName ) ?
|
2573
|
-
!element.disabled :
|
2574
|
-
'a' === nodeName ?
|
2575
|
-
element.href || isTabIndexNotNaN :
|
2576
|
-
isTabIndexNotNaN
|
2577
|
-
);
|
2640
|
+
// If viewport is not a jQuery element, or it's the window/document, or no adjustment method is used... return
|
2641
|
+
if(!viewport.jquery || target[0] === window || target[0] === document.body || adjust.method === 'none') {
|
2642
|
+
return adjusted;
|
2578
2643
|
}
|
2579
2644
|
|
2580
|
-
//
|
2581
|
-
|
2582
|
-
|
2583
|
-
if(focusableElems.length < 1 && blurElems.length) { blurElems.not('body').blur(); }
|
2645
|
+
// Cach container details
|
2646
|
+
containerOffset = container.offset() || adjusted;
|
2647
|
+
containerStatic = container.css('position') === 'static';
|
2584
2648
|
|
2585
|
-
|
2586
|
-
|
2587
|
-
|
2649
|
+
// Cache our viewport details
|
2650
|
+
fixed = tooltip.css('position') === 'fixed';
|
2651
|
+
viewportWidth = viewport[0] === window ? viewport.width() : viewport.outerWidth(FALSE);
|
2652
|
+
viewportHeight = viewport[0] === window ? viewport.height() : viewport.outerHeight(FALSE);
|
2653
|
+
viewportScroll = { left: fixed ? 0 : viewport.scrollLeft(), top: fixed ? 0 : viewport.scrollTop() };
|
2654
|
+
viewportOffset = viewport.offset() || adjusted;
|
2588
2655
|
|
2589
|
-
//
|
2590
|
-
function
|
2591
|
-
|
2656
|
+
// Generic calculation method
|
2657
|
+
function calculate(side, otherSide, type, adjust, side1, side2, lengthName, targetLength, elemLength) {
|
2658
|
+
var initialPos = position[side1],
|
2659
|
+
mySide = my[side],
|
2660
|
+
atSide = at[side],
|
2661
|
+
isShift = type === SHIFT,
|
2662
|
+
myLength = mySide === side1 ? elemLength : mySide === side2 ? -elemLength : -elemLength / 2,
|
2663
|
+
atLength = atSide === side1 ? targetLength : atSide === side2 ? -targetLength : -targetLength / 2,
|
2664
|
+
sideOffset = viewportScroll[side1] + viewportOffset[side1] - (containerStatic ? 0 : containerOffset[side1]),
|
2665
|
+
overflow1 = sideOffset - initialPos,
|
2666
|
+
overflow2 = initialPos + elemLength - (lengthName === WIDTH ? viewportWidth : viewportHeight) - sideOffset,
|
2667
|
+
offset = myLength - (my.precedance === side || mySide === my[otherSide] ? atLength : 0) - (atSide === CENTER ? targetLength / 2 : 0);
|
2592
2668
|
|
2593
|
-
|
2594
|
-
|
2595
|
-
|
2596
|
-
targetOnTop;
|
2669
|
+
// shift
|
2670
|
+
if(isShift) {
|
2671
|
+
offset = (mySide === side1 ? 1 : -1) * myLength;
|
2597
2672
|
|
2598
|
-
|
2599
|
-
|
2600
|
-
|
2673
|
+
// Adjust position but keep it within viewport dimensions
|
2674
|
+
position[side1] += overflow1 > 0 ? overflow1 : overflow2 > 0 ? -overflow2 : 0;
|
2675
|
+
position[side1] = Math.max(
|
2676
|
+
-containerOffset[side1] + viewportOffset[side1],
|
2677
|
+
initialPos - offset,
|
2678
|
+
Math.min(
|
2679
|
+
Math.max(
|
2680
|
+
-containerOffset[side1] + viewportOffset[side1] + (lengthName === WIDTH ? viewportWidth : viewportHeight),
|
2681
|
+
initialPos + offset
|
2682
|
+
),
|
2683
|
+
position[side1],
|
2684
|
+
|
2685
|
+
// Make sure we don't adjust complete off the element when using 'center'
|
2686
|
+
mySide === 'center' ? initialPos - myLength : 1E9
|
2687
|
+
)
|
2688
|
+
);
|
2601
2689
|
|
2602
|
-
// If we're showing a modal, but focus has landed on an input below
|
2603
|
-
// this modal, divert focus to the first visible input in this modal
|
2604
|
-
// or if we can't find one... the tooltip itself
|
2605
|
-
if(!targetOnTop && target.closest(SELECTOR)[0] !== tooltip[0]) {
|
2606
|
-
focusInputs(target);
|
2607
2690
|
}
|
2608
2691
|
|
2609
|
-
//
|
2610
|
-
|
2611
|
-
|
2612
|
-
|
2613
|
-
$.extend(self, {
|
2614
|
-
init: function() {
|
2615
|
-
// Create document overlay
|
2616
|
-
elem = self.elem = $('<div />', {
|
2617
|
-
id: 'qtip-overlay',
|
2618
|
-
html: '<div></div>',
|
2619
|
-
mousedown: function() { return FALSE; }
|
2620
|
-
})
|
2621
|
-
.hide();
|
2692
|
+
// flip/flipinvert
|
2693
|
+
else {
|
2694
|
+
// Update adjustment amount depending on if using flipinvert or flip
|
2695
|
+
adjust *= (type === FLIPINVERT ? 2 : 0);
|
2622
2696
|
|
2623
|
-
//
|
2624
|
-
|
2625
|
-
|
2626
|
-
|
2627
|
-
height: win.height(),
|
2628
|
-
width: win.width()
|
2629
|
-
});
|
2697
|
+
// Check for overflow on the left/top
|
2698
|
+
if(overflow1 > 0 && (mySide !== side1 || overflow2 > 0)) {
|
2699
|
+
position[side1] -= offset + adjust;
|
2700
|
+
newMy.invert(side, side1);
|
2630
2701
|
}
|
2631
|
-
$(window).bind('resize'+MODALSELECTOR, resize);
|
2632
|
-
resize(); // Fire it initially too
|
2633
2702
|
|
2634
|
-
//
|
2635
|
-
|
2703
|
+
// Check for overflow on the bottom/right
|
2704
|
+
else if(overflow2 > 0 && (mySide !== side2 || overflow1 > 0) ) {
|
2705
|
+
position[side1] -= (mySide === CENTER ? -offset : offset) + adjust;
|
2706
|
+
newMy.invert(side, side2);
|
2707
|
+
}
|
2636
2708
|
|
2637
|
-
//
|
2638
|
-
|
2639
|
-
|
2640
|
-
|
2641
|
-
|
2642
|
-
});
|
2709
|
+
// Make sure we haven't made things worse with the adjustment and reset if so
|
2710
|
+
if(position[side1] < viewportScroll && -position[side1] > overflow2) {
|
2711
|
+
position[side1] = initialPos; newMy = my.clone();
|
2712
|
+
}
|
2713
|
+
}
|
2643
2714
|
|
2644
|
-
|
2645
|
-
|
2646
|
-
if(current && current.options.show.modal.blur) {
|
2647
|
-
current.hide(event);
|
2648
|
-
}
|
2649
|
-
});
|
2715
|
+
return position[side1] - initialPos;
|
2716
|
+
}
|
2650
2717
|
|
2651
|
-
|
2652
|
-
|
2718
|
+
// Set newMy if using flip or flipinvert methods
|
2719
|
+
if(methodX !== 'shift' || methodY !== 'shift') { newMy = my.clone(); }
|
2653
2720
|
|
2654
|
-
|
2655
|
-
|
2656
|
-
|
2721
|
+
// Adjust position based onviewport and adjustment options
|
2722
|
+
adjusted = {
|
2723
|
+
left: methodX !== 'none' ? calculate( X, Y, methodX, adjust.x, LEFT, RIGHT, WIDTH, targetWidth, elemWidth ) : 0,
|
2724
|
+
top: methodY !== 'none' ? calculate( Y, X, methodY, adjust.y, TOP, BOTTOM, HEIGHT, targetHeight, elemHeight ) : 0,
|
2725
|
+
my: newMy
|
2726
|
+
};
|
2657
2727
|
|
2658
|
-
|
2659
|
-
|
2660
|
-
|
2661
|
-
|
2662
|
-
|
2663
|
-
|
2664
|
-
|
2728
|
+
return adjusted;
|
2729
|
+
};
|
2730
|
+
;PLUGINS.polys = {
|
2731
|
+
// POLY area coordinate calculator
|
2732
|
+
// Special thanks to Ed Cradock for helping out with this.
|
2733
|
+
// Uses a binary search algorithm to find suitable coordinates.
|
2734
|
+
polygon: function(baseCoords, corner) {
|
2735
|
+
var result = {
|
2736
|
+
width: 0, height: 0,
|
2737
|
+
position: {
|
2738
|
+
top: 1e10, right: 0,
|
2739
|
+
bottom: 0, left: 1e10
|
2740
|
+
},
|
2741
|
+
adjustable: FALSE
|
2665
2742
|
},
|
2743
|
+
i = 0, next,
|
2744
|
+
coords = [],
|
2745
|
+
compareX = 1, compareY = 1,
|
2746
|
+
realX = 0, realY = 0,
|
2747
|
+
newWidth, newHeight;
|
2666
2748
|
|
2667
|
-
|
2668
|
-
|
2669
|
-
|
2670
|
-
options = api.options.show.modal,
|
2671
|
-
effect = options.effect,
|
2672
|
-
type = state ? 'show': 'hide',
|
2673
|
-
visible = elem.is(':visible'),
|
2674
|
-
visibleModals = $(MODALSELECTOR).filter(':visible:not(:animated)').not(tooltip),
|
2675
|
-
zindex;
|
2676
|
-
|
2677
|
-
// Set active tooltip API reference
|
2678
|
-
self.update(api);
|
2749
|
+
// First pass, sanitize coords and determine outer edges
|
2750
|
+
i = baseCoords.length; while(i--) {
|
2751
|
+
next = [ parseInt(baseCoords[--i], 10), parseInt(baseCoords[i+1], 10) ];
|
2679
2752
|
|
2680
|
-
|
2681
|
-
|
2682
|
-
if(
|
2683
|
-
|
2684
|
-
}
|
2753
|
+
if(next[0] > result.position.right){ result.position.right = next[0]; }
|
2754
|
+
if(next[0] < result.position.left){ result.position.left = next[0]; }
|
2755
|
+
if(next[1] > result.position.bottom){ result.position.bottom = next[1]; }
|
2756
|
+
if(next[1] < result.position.top){ result.position.top = next[1]; }
|
2685
2757
|
|
2686
|
-
|
2687
|
-
|
2758
|
+
coords.push(next);
|
2759
|
+
}
|
2688
2760
|
|
2689
|
-
|
2690
|
-
|
2691
|
-
|
2692
|
-
.appendTo(document.body);
|
2693
|
-
}
|
2761
|
+
// Calculate height and width from outer edges
|
2762
|
+
newWidth = result.width = Math.abs(result.position.right - result.position.left);
|
2763
|
+
newHeight = result.height = Math.abs(result.position.bottom - result.position.top);
|
2694
2764
|
|
2695
|
-
|
2696
|
-
|
2697
|
-
|
2698
|
-
|
2765
|
+
// If it's the center corner...
|
2766
|
+
if(corner.abbrev() === 'c') {
|
2767
|
+
result.position = {
|
2768
|
+
left: result.position.left + (result.width / 2),
|
2769
|
+
top: result.position.top + (result.height / 2)
|
2770
|
+
};
|
2771
|
+
}
|
2772
|
+
else {
|
2773
|
+
// Second pass, use a binary search algorithm to locate most suitable coordinate
|
2774
|
+
while(newWidth > 0 && newHeight > 0 && compareX > 0 && compareY > 0)
|
2775
|
+
{
|
2776
|
+
newWidth = Math.floor(newWidth / 2);
|
2777
|
+
newHeight = Math.floor(newHeight / 2);
|
2699
2778
|
|
2700
|
-
|
2701
|
-
|
2779
|
+
if(corner.x === LEFT){ compareX = newWidth; }
|
2780
|
+
else if(corner.x === RIGHT){ compareX = result.width - newWidth; }
|
2781
|
+
else{ compareX += Math.floor(newWidth / 2); }
|
2702
2782
|
|
2703
|
-
|
2704
|
-
|
2705
|
-
|
2706
|
-
}
|
2783
|
+
if(corner.y === TOP){ compareY = newHeight; }
|
2784
|
+
else if(corner.y === BOTTOM){ compareY = result.height - newHeight; }
|
2785
|
+
else{ compareY += Math.floor(newHeight / 2); }
|
2707
2786
|
|
2708
|
-
|
2709
|
-
|
2710
|
-
|
2711
|
-
}
|
2787
|
+
i = coords.length; while(i--)
|
2788
|
+
{
|
2789
|
+
if(coords.length < 2){ break; }
|
2712
2790
|
|
2713
|
-
|
2714
|
-
|
2715
|
-
elem.fadeTo( parseInt(duration, 10) || 90, state ? 1 : 0, function() {
|
2716
|
-
if(!state) { elem.hide(); }
|
2717
|
-
});
|
2718
|
-
}
|
2791
|
+
realX = coords[i][0] - result.position.left;
|
2792
|
+
realY = coords[i][1] - result.position.top;
|
2719
2793
|
|
2720
|
-
|
2721
|
-
|
2722
|
-
|
2723
|
-
|
2724
|
-
|
2725
|
-
|
2726
|
-
|
2794
|
+
if((corner.x === LEFT && realX >= compareX) ||
|
2795
|
+
(corner.x === RIGHT && realX <= compareX) ||
|
2796
|
+
(corner.x === CENTER && (realX < compareX || realX > (result.width - compareX))) ||
|
2797
|
+
(corner.y === TOP && realY >= compareY) ||
|
2798
|
+
(corner.y === BOTTOM && realY <= compareY) ||
|
2799
|
+
(corner.y === CENTER && (realY < compareY || realY > (result.height - compareY)))) {
|
2800
|
+
coords.splice(i, 1);
|
2801
|
+
}
|
2802
|
+
}
|
2727
2803
|
}
|
2804
|
+
result.position = { left: coords[0][0], top: coords[0][1] };
|
2805
|
+
}
|
2728
2806
|
|
2729
|
-
|
2730
|
-
|
2807
|
+
return result;
|
2808
|
+
},
|
2731
2809
|
|
2732
|
-
|
2733
|
-
|
2810
|
+
rect: function(ax, ay, bx, by) {
|
2811
|
+
return {
|
2812
|
+
width: Math.abs(bx - ax),
|
2813
|
+
height: Math.abs(by - ay),
|
2814
|
+
position: {
|
2815
|
+
left: Math.min(ax, bx),
|
2816
|
+
top: Math.min(ay, by)
|
2817
|
+
}
|
2818
|
+
};
|
2819
|
+
},
|
2734
2820
|
|
2735
|
-
|
2736
|
-
|
2737
|
-
|
2821
|
+
_angles: {
|
2822
|
+
tc: 3 / 2, tr: 7 / 4, tl: 5 / 4,
|
2823
|
+
bc: 1 / 2, br: 1 / 4, bl: 3 / 4,
|
2824
|
+
rc: 2, lc: 1, c: 0
|
2825
|
+
},
|
2826
|
+
ellipse: function(cx, cy, rx, ry, corner) {
|
2827
|
+
var c = PLUGINS.polys._angles[ corner.abbrev() ],
|
2828
|
+
rxc = c === 0 ? 0 : rx * Math.cos( c * Math.PI ),
|
2829
|
+
rys = ry * Math.sin( c * Math.PI );
|
2738
2830
|
|
2739
|
-
|
2831
|
+
return {
|
2832
|
+
width: (rx * 2) - Math.abs(rxc),
|
2833
|
+
height: (ry * 2) - Math.abs(rys),
|
2834
|
+
position: {
|
2835
|
+
left: cx + rxc,
|
2836
|
+
top: cy + rys
|
2837
|
+
},
|
2838
|
+
adjustable: FALSE
|
2839
|
+
};
|
2840
|
+
},
|
2841
|
+
circle: function(cx, cy, r, corner) {
|
2842
|
+
return PLUGINS.polys.ellipse(cx, cy, r, r, corner);
|
2843
|
+
}
|
2740
2844
|
};
|
2741
|
-
|
2845
|
+
;PLUGINS.imagemap = function(api, area, corner, adjustMethod)
|
2846
|
+
{
|
2847
|
+
if(!area.jquery) { area = $(area); }
|
2742
2848
|
|
2743
|
-
|
2744
|
-
|
2745
|
-
|
2849
|
+
var shape = (area.attr('shape') || 'rect').toLowerCase().replace('poly', 'polygon'),
|
2850
|
+
image = $('img[usemap="#'+area.parent('map').attr('name')+'"]'),
|
2851
|
+
coordsString = $.trim(area.attr('coords')),
|
2852
|
+
coordsArray = coordsString.replace(/,$/, '').split(','),
|
2853
|
+
imageOffset, coords, i, next, result, len;
|
2746
2854
|
|
2747
|
-
|
2748
|
-
}
|
2855
|
+
// If we can't find the image using the map...
|
2856
|
+
if(!image.length) { return FALSE; }
|
2749
2857
|
|
2750
|
-
|
2751
|
-
|
2752
|
-
|
2858
|
+
// Pass coordinates string if polygon
|
2859
|
+
if(shape === 'polygon') {
|
2860
|
+
result = PLUGINS.polys.polygon(coordsArray, corner);
|
2861
|
+
}
|
2753
2862
|
|
2754
|
-
|
2755
|
-
|
2863
|
+
// Otherwise parse the coordinates and pass them as arguments
|
2864
|
+
else if(PLUGINS.polys[shape]) {
|
2865
|
+
for(i = -1, len = coordsArray.length, coords = []; ++i < len;) {
|
2866
|
+
coords.push( parseInt(coordsArray[i], 10) );
|
2867
|
+
}
|
2756
2868
|
|
2757
|
-
|
2758
|
-
|
2869
|
+
result = PLUGINS.polys[shape].apply(
|
2870
|
+
this, coords.concat(corner)
|
2871
|
+
);
|
2872
|
+
}
|
2759
2873
|
|
2760
|
-
|
2761
|
-
|
2762
|
-
|
2763
|
-
// Apply our show/hide/focus modal events
|
2764
|
-
qtip._bind(tooltip, ['tooltipshow', 'tooltiphide'], function(event, api, duration) {
|
2765
|
-
var oEvent = event.originalEvent;
|
2874
|
+
// If no shapre calculation method was found, return false
|
2875
|
+
else { return FALSE; }
|
2766
2876
|
|
2767
|
-
|
2768
|
-
|
2769
|
-
|
2770
|
-
|
2771
|
-
}
|
2772
|
-
else if(!oEvent || (oEvent && !oEvent.solo)) {
|
2773
|
-
this.toggle(event, event.type === 'tooltipshow', duration);
|
2774
|
-
}
|
2775
|
-
}
|
2776
|
-
}, this._ns, this);
|
2877
|
+
// Make sure we account for padding and borders on the image
|
2878
|
+
imageOffset = image.offset();
|
2879
|
+
imageOffset.left += Math.ceil((image.outerWidth(FALSE) - image.width()) / 2);
|
2880
|
+
imageOffset.top += Math.ceil((image.outerHeight(FALSE) - image.height()) / 2);
|
2777
2881
|
|
2778
|
-
|
2779
|
-
|
2780
|
-
|
2781
|
-
if(event.isDefaultPrevented() || event.target !== tooltip[0]) { return; }
|
2882
|
+
// Add image position to offset coordinates
|
2883
|
+
result.position.left += imageOffset.left;
|
2884
|
+
result.position.top += imageOffset.top;
|
2782
2885
|
|
2783
|
-
|
2886
|
+
return result;
|
2887
|
+
};
|
2888
|
+
;PLUGINS.svg = function(api, svg, corner)
|
2889
|
+
{
|
2890
|
+
var doc = $(document),
|
2891
|
+
elem = svg[0],
|
2892
|
+
root = $(elem.ownerSVGElement),
|
2893
|
+
ownerDocument = elem.ownerDocument,
|
2894
|
+
strokeWidth2 = (parseInt(svg.css('stroke-width'), 10) || 0) / 2,
|
2895
|
+
frameOffset, mtx, transformed, viewBox,
|
2896
|
+
len, next, i, points,
|
2897
|
+
result, position, dimensions;
|
2784
2898
|
|
2785
|
-
|
2786
|
-
|
2787
|
-
|
2899
|
+
// Ascend the parentNode chain until we find an element with getBBox()
|
2900
|
+
while(!elem.getBBox) { elem = elem.parentNode; }
|
2901
|
+
if(!elem.getBBox || !elem.parentNode) { return FALSE; }
|
2788
2902
|
|
2789
|
-
|
2790
|
-
|
2903
|
+
// Determine which shape calculation to use
|
2904
|
+
switch(elem.nodeName) {
|
2905
|
+
case 'ellipse':
|
2906
|
+
case 'circle':
|
2907
|
+
result = PLUGINS.polys.ellipse(
|
2908
|
+
elem.cx.baseVal.value,
|
2909
|
+
elem.cy.baseVal.value,
|
2910
|
+
(elem.rx || elem.r).baseVal.value + strokeWidth2,
|
2911
|
+
(elem.ry || elem.r).baseVal.value + strokeWidth2,
|
2912
|
+
corner
|
2913
|
+
);
|
2914
|
+
break;
|
2791
2915
|
|
2792
|
-
|
2793
|
-
|
2794
|
-
|
2795
|
-
|
2916
|
+
case 'line':
|
2917
|
+
case 'polygon':
|
2918
|
+
case 'polyline':
|
2919
|
+
// Determine points object (line has none, so mimic using array)
|
2920
|
+
points = elem.points || [
|
2921
|
+
{ x: elem.x1.baseVal.value, y: elem.y1.baseVal.value },
|
2922
|
+
{ x: elem.x2.baseVal.value, y: elem.y2.baseVal.value }
|
2923
|
+
];
|
2924
|
+
|
2925
|
+
for(result = [], i = -1, len = points.numberOfItems || points.length; ++i < len;) {
|
2926
|
+
next = points.getItem ? points.getItem(i) : points[i];
|
2927
|
+
result.push.apply(result, [next.x, next.y]);
|
2928
|
+
}
|
2929
|
+
|
2930
|
+
result = PLUGINS.polys.polygon(result, corner);
|
2931
|
+
break;
|
2932
|
+
|
2933
|
+
// Unknown shape or rectangle? Use bounding box
|
2934
|
+
default:
|
2935
|
+
result = elem.getBBox();
|
2936
|
+
result = {
|
2937
|
+
width: result.width,
|
2938
|
+
height: result.height,
|
2939
|
+
position: {
|
2940
|
+
left: result.x,
|
2941
|
+
top: result.y
|
2796
2942
|
}
|
2797
|
-
}
|
2943
|
+
};
|
2944
|
+
break;
|
2945
|
+
}
|
2798
2946
|
|
2799
|
-
|
2800
|
-
|
2947
|
+
// Shortcut assignments
|
2948
|
+
position = result.position;
|
2949
|
+
root = root[0];
|
2801
2950
|
|
2802
|
-
|
2803
|
-
|
2951
|
+
// Convert position into a pixel value
|
2952
|
+
if(root.createSVGPoint) {
|
2953
|
+
mtx = elem.getScreenCTM();
|
2954
|
+
points = root.createSVGPoint();
|
2804
2955
|
|
2805
|
-
|
2806
|
-
|
2956
|
+
points.x = position.left;
|
2957
|
+
points.y = position.top;
|
2958
|
+
transformed = points.matrixTransform( mtx );
|
2959
|
+
position.left = transformed.x;
|
2960
|
+
position.top = transformed.y;
|
2961
|
+
}
|
2807
2962
|
|
2808
|
-
|
2809
|
-
|
2810
|
-
|
2963
|
+
// Check the element is not in a child document, and if so, adjust for frame elements offset
|
2964
|
+
if(ownerDocument !== document && api.position.target !== 'mouse') {
|
2965
|
+
frameOffset = $((ownerDocument.defaultView || ownerDocument.parentWindow).frameElement).offset();
|
2966
|
+
if(frameOffset) {
|
2967
|
+
position.left += frameOffset.left;
|
2968
|
+
position.top += frameOffset.top;
|
2969
|
+
}
|
2970
|
+
}
|
2811
2971
|
|
2812
|
-
|
2813
|
-
|
2814
|
-
|
2815
|
-
|
2816
|
-
}
|
2817
|
-
}, this._ns, this);
|
2818
|
-
},
|
2972
|
+
// Adjust by scroll offset of owner document
|
2973
|
+
ownerDocument = $(ownerDocument);
|
2974
|
+
position.left += ownerDocument.scrollLeft();
|
2975
|
+
position.top += ownerDocument.scrollTop();
|
2819
2976
|
|
2820
|
-
|
2821
|
-
|
2822
|
-
|
2977
|
+
return result;
|
2978
|
+
};
|
2979
|
+
;var MODAL, OVERLAY,
|
2980
|
+
MODALCLASS = 'qtip-modal',
|
2981
|
+
MODALSELECTOR = '.'+MODALCLASS;
|
2823
2982
|
|
2824
|
-
|
2825
|
-
|
2826
|
-
|
2983
|
+
OVERLAY = function()
|
2984
|
+
{
|
2985
|
+
var self = this,
|
2986
|
+
focusableElems = {},
|
2987
|
+
current, onLast,
|
2988
|
+
prevState, elem;
|
2827
2989
|
|
2828
|
-
|
2829
|
-
|
2830
|
-
|
2990
|
+
// Modified code from jQuery UI 1.10.0 source
|
2991
|
+
// http://code.jquery.com/ui/1.10.0/jquery-ui.js
|
2992
|
+
function focusable(element) {
|
2993
|
+
// Use the defined focusable checker when possible
|
2994
|
+
if($.expr[':'].focusable) { return $.expr[':'].focusable; }
|
2831
2995
|
|
2832
|
-
|
2833
|
-
|
2996
|
+
var isTabIndexNotNaN = !isNaN($.attr(element, 'tabindex')),
|
2997
|
+
nodeName = element.nodeName && element.nodeName.toLowerCase(),
|
2998
|
+
map, mapName, img;
|
2834
2999
|
|
2835
|
-
|
2836
|
-
|
2837
|
-
|
3000
|
+
if('area' === nodeName) {
|
3001
|
+
map = element.parentNode;
|
3002
|
+
mapName = map.name;
|
3003
|
+
if(!element.href || !mapName || map.nodeName.toLowerCase() !== 'map') {
|
3004
|
+
return false;
|
3005
|
+
}
|
3006
|
+
img = $('img[usemap=#' + mapName + ']')[0];
|
3007
|
+
return !!img && img.is(':visible');
|
3008
|
+
}
|
3009
|
+
return (/input|select|textarea|button|object/.test( nodeName ) ?
|
3010
|
+
!element.disabled :
|
3011
|
+
'a' === nodeName ?
|
3012
|
+
element.href || isTabIndexNotNaN :
|
3013
|
+
isTabIndexNotNaN
|
3014
|
+
);
|
2838
3015
|
}
|
2839
|
-
});
|
2840
|
-
|
2841
3016
|
|
2842
|
-
|
2843
|
-
|
2844
|
-
|
3017
|
+
// Focus inputs using cached focusable elements (see update())
|
3018
|
+
function focusInputs(blurElems) {
|
3019
|
+
// Blurring body element in IE causes window.open windows to unfocus!
|
3020
|
+
if(focusableElems.length < 1 && blurElems.length) { blurElems.not('body').blur(); }
|
2845
3021
|
|
2846
|
-
//
|
2847
|
-
|
2848
|
-
if(opts.show) {
|
2849
|
-
if(typeof opts.show.modal !== 'object') { opts.show.modal = { on: !!opts.show.modal }; }
|
2850
|
-
else if(typeof opts.show.modal.on === 'undefined') { opts.show.modal.on = TRUE; }
|
3022
|
+
// Focus the inputs
|
3023
|
+
else { focusableElems.first().focus(); }
|
2851
3024
|
}
|
2852
|
-
};
|
2853
3025
|
|
2854
|
-
//
|
2855
|
-
|
3026
|
+
// Steal focus from elements outside tooltip
|
3027
|
+
function stealFocus(event) {
|
3028
|
+
if(!elem.is(':visible')) { return; }
|
2856
3029
|
|
2857
|
-
|
2858
|
-
|
3030
|
+
var target = $(event.target),
|
3031
|
+
tooltip = current.tooltip,
|
3032
|
+
container = target.closest(SELECTOR),
|
3033
|
+
targetOnTop;
|
2859
3034
|
|
2860
|
-
//
|
2861
|
-
|
2862
|
-
|
2863
|
-
// Initialise
|
2864
|
-
this.destroy();
|
2865
|
-
this.init();
|
2866
|
-
|
2867
|
-
// Show the modal if not visible already and tooltip is visible
|
2868
|
-
this.qtip.elems.overlay.toggle(
|
2869
|
-
this.qtip.tooltip[0].offsetWidth > 0
|
2870
|
-
);
|
2871
|
-
}
|
2872
|
-
};
|
3035
|
+
// Determine if input container target is above this
|
3036
|
+
targetOnTop = container.length < 1 ? FALSE :
|
3037
|
+
(parseInt(container[0].style.zIndex, 10) > parseInt(tooltip[0].style.zIndex, 10));
|
2873
3038
|
|
2874
|
-
//
|
2875
|
-
|
2876
|
-
|
2877
|
-
|
2878
|
-
|
2879
|
-
effect: TRUE,
|
2880
|
-
blur: TRUE,
|
2881
|
-
stealfocus: TRUE,
|
2882
|
-
escape: TRUE
|
3039
|
+
// If we're showing a modal, but focus has landed on an input below
|
3040
|
+
// this modal, divert focus to the first visible input in this modal
|
3041
|
+
// or if we can't find one... the tooltip itself
|
3042
|
+
if(!targetOnTop && target.closest(SELECTOR)[0] !== tooltip[0]) {
|
3043
|
+
focusInputs(target);
|
2883
3044
|
}
|
2884
|
-
}
|
2885
|
-
});
|
2886
|
-
;PLUGINS.viewport = function(api, position, posOptions, targetWidth, targetHeight, elemWidth, elemHeight)
|
2887
|
-
{
|
2888
|
-
var target = posOptions.target,
|
2889
|
-
tooltip = api.elements.tooltip,
|
2890
|
-
my = posOptions.my,
|
2891
|
-
at = posOptions.at,
|
2892
|
-
adjust = posOptions.adjust,
|
2893
|
-
method = adjust.method.split(' '),
|
2894
|
-
methodX = method[0],
|
2895
|
-
methodY = method[1] || method[0],
|
2896
|
-
viewport = posOptions.viewport,
|
2897
|
-
container = posOptions.container,
|
2898
|
-
cache = api.cache,
|
2899
|
-
tip = api.plugins.tip,
|
2900
|
-
adjusted = { left: 0, top: 0 },
|
2901
|
-
fixed, newMy, newClass;
|
2902
3045
|
|
2903
|
-
|
2904
|
-
|
2905
|
-
return adjusted;
|
3046
|
+
// Detect when we leave the last focusable element...
|
3047
|
+
onLast = event.target === focusableElems[focusableElems.length - 1];
|
2906
3048
|
}
|
2907
3049
|
|
2908
|
-
|
2909
|
-
|
2910
|
-
|
2911
|
-
|
2912
|
-
|
2913
|
-
|
2914
|
-
|
2915
|
-
|
2916
|
-
|
2917
|
-
};
|
2918
|
-
container = {
|
2919
|
-
elem: container,
|
2920
|
-
scrollLeft: container.scrollLeft(),
|
2921
|
-
scrollTop: container.scrollTop(),
|
2922
|
-
offset: container.offset() || { left: 0, top: 0 }
|
2923
|
-
};
|
3050
|
+
$.extend(self, {
|
3051
|
+
init: function() {
|
3052
|
+
// Create document overlay
|
3053
|
+
elem = self.elem = $('<div />', {
|
3054
|
+
id: 'qtip-overlay',
|
3055
|
+
html: '<div></div>',
|
3056
|
+
mousedown: function() { return FALSE; }
|
3057
|
+
})
|
3058
|
+
.hide();
|
2924
3059
|
|
2925
|
-
|
2926
|
-
|
2927
|
-
var initialPos = position[side1],
|
2928
|
-
mySide = my[side], atSide = at[side],
|
2929
|
-
isShift = type === SHIFT,
|
2930
|
-
viewportScroll = -container.offset[side1] + viewport.offset[side1] + viewport['scroll'+side1],
|
2931
|
-
myLength = mySide === side1 ? elemLength : mySide === side2 ? -elemLength : -elemLength / 2,
|
2932
|
-
atLength = atSide === side1 ? targetLength : atSide === side2 ? -targetLength : -targetLength / 2,
|
2933
|
-
tipLength = tip && tip.size ? tip.size[lengthName] || 0 : 0,
|
2934
|
-
tipAdjust = tip && tip.corner && tip.corner.precedance === side && !isShift ? tipLength : 0,
|
2935
|
-
overflow1 = viewportScroll - initialPos + tipAdjust,
|
2936
|
-
overflow2 = initialPos + elemLength - viewport[lengthName] - viewportScroll + tipAdjust,
|
2937
|
-
offset = myLength - (my.precedance === side || mySide === my[otherSide] ? atLength : 0) - (atSide === CENTER ? targetLength / 2 : 0);
|
3060
|
+
// Make sure we can't focus anything outside the tooltip
|
3061
|
+
$(document.body).bind('focusin'+MODALSELECTOR, stealFocus);
|
2938
3062
|
|
2939
|
-
|
2940
|
-
|
2941
|
-
|
2942
|
-
|
3063
|
+
// Apply keyboard "Escape key" close handler
|
3064
|
+
$(document).bind('keydown'+MODALSELECTOR, function(event) {
|
3065
|
+
if(current && current.options.show.modal.escape && event.keyCode === 27) {
|
3066
|
+
current.hide(event);
|
3067
|
+
}
|
3068
|
+
});
|
2943
3069
|
|
2944
|
-
//
|
2945
|
-
|
2946
|
-
|
2947
|
-
|
2948
|
-
|
2949
|
-
|
2950
|
-
Math.max(-container.offset[side1] + viewport.offset[side1] + viewport[lengthName], initialPos + offset),
|
2951
|
-
position[side1]
|
2952
|
-
)
|
2953
|
-
);
|
2954
|
-
}
|
3070
|
+
// Apply click handler for blur option
|
3071
|
+
elem.bind('click'+MODALSELECTOR, function(event) {
|
3072
|
+
if(current && current.options.show.modal.blur) {
|
3073
|
+
current.hide(event);
|
3074
|
+
}
|
3075
|
+
});
|
2955
3076
|
|
2956
|
-
|
2957
|
-
|
2958
|
-
// Update adjustment amount depending on if using flipinvert or flip
|
2959
|
-
adjust *= (type === FLIPINVERT ? 2 : 0);
|
3077
|
+
return self;
|
3078
|
+
},
|
2960
3079
|
|
2961
|
-
|
2962
|
-
|
2963
|
-
|
2964
|
-
|
3080
|
+
update: function(api) {
|
3081
|
+
// Update current API reference
|
3082
|
+
current = api;
|
3083
|
+
|
3084
|
+
// Update focusable elements if enabled
|
3085
|
+
if(api.options.show.modal.stealfocus !== FALSE) {
|
3086
|
+
focusableElems = api.tooltip.find('*').filter(function() {
|
3087
|
+
return focusable(this);
|
3088
|
+
});
|
2965
3089
|
}
|
3090
|
+
else { focusableElems = []; }
|
3091
|
+
},
|
2966
3092
|
|
2967
|
-
|
2968
|
-
|
2969
|
-
|
2970
|
-
|
3093
|
+
toggle: function(api, state, duration) {
|
3094
|
+
var docBody = $(document.body),
|
3095
|
+
tooltip = api.tooltip,
|
3096
|
+
options = api.options.show.modal,
|
3097
|
+
effect = options.effect,
|
3098
|
+
type = state ? 'show': 'hide',
|
3099
|
+
visible = elem.is(':visible'),
|
3100
|
+
visibleModals = $(MODALSELECTOR).filter(':visible:not(:animated)').not(tooltip),
|
3101
|
+
zindex;
|
3102
|
+
|
3103
|
+
// Set active tooltip API reference
|
3104
|
+
self.update(api);
|
3105
|
+
|
3106
|
+
// If the modal can steal the focus...
|
3107
|
+
// Blur the current item and focus anything in the modal we an
|
3108
|
+
if(state && options.stealfocus !== FALSE) {
|
3109
|
+
focusInputs( $(':focus') );
|
2971
3110
|
}
|
2972
3111
|
|
2973
|
-
//
|
2974
|
-
|
2975
|
-
|
3112
|
+
// Toggle backdrop cursor style on show
|
3113
|
+
elem.toggleClass('blurs', options.blur);
|
3114
|
+
|
3115
|
+
// Append to body on show
|
3116
|
+
if(state) {
|
3117
|
+
elem.appendTo(document.body);
|
2976
3118
|
}
|
2977
|
-
}
|
2978
3119
|
|
2979
|
-
|
2980
|
-
|
3120
|
+
// Prevent modal from conflicting with show.solo, and don't hide backdrop is other modals are visible
|
3121
|
+
if((elem.is(':animated') && visible === state && prevState !== FALSE) || (!state && visibleModals.length)) {
|
3122
|
+
return self;
|
3123
|
+
}
|
2981
3124
|
|
2982
|
-
|
2983
|
-
|
3125
|
+
// Stop all animations
|
3126
|
+
elem.stop(TRUE, FALSE);
|
2984
3127
|
|
2985
|
-
|
2986
|
-
|
2987
|
-
|
2988
|
-
|
2989
|
-
};
|
3128
|
+
// Use custom function if provided
|
3129
|
+
if($.isFunction(effect)) {
|
3130
|
+
effect.call(elem, state);
|
3131
|
+
}
|
2990
3132
|
|
2991
|
-
|
2992
|
-
|
2993
|
-
|
2994
|
-
|
3133
|
+
// If no effect type is supplied, use a simple toggle
|
3134
|
+
else if(effect === FALSE) {
|
3135
|
+
elem[ type ]();
|
3136
|
+
}
|
2995
3137
|
|
2996
|
-
|
2997
|
-
|
2998
|
-
|
2999
|
-
|
3000
|
-
|
3001
|
-
|
3002
|
-
var result = {
|
3003
|
-
width: 0, height: 0,
|
3004
|
-
position: {
|
3005
|
-
top: 1e10, right: 0,
|
3006
|
-
bottom: 0, left: 1e10
|
3007
|
-
},
|
3008
|
-
adjustable: FALSE
|
3009
|
-
},
|
3010
|
-
i = 0, next,
|
3011
|
-
coords = [],
|
3012
|
-
compareX = 1, compareY = 1,
|
3013
|
-
realX = 0, realY = 0,
|
3014
|
-
newWidth, newHeight;
|
3138
|
+
// Use basic fade function
|
3139
|
+
else {
|
3140
|
+
elem.fadeTo( parseInt(duration, 10) || 90, state ? 1 : 0, function() {
|
3141
|
+
if(!state) { elem.hide(); }
|
3142
|
+
});
|
3143
|
+
}
|
3015
3144
|
|
3016
|
-
|
3017
|
-
|
3018
|
-
|
3145
|
+
// Reset position and detach from body on hide
|
3146
|
+
if(!state) {
|
3147
|
+
elem.queue(function(next) {
|
3148
|
+
elem.css({ left: '', top: '' });
|
3149
|
+
if(!$(MODALSELECTOR).length) { elem.detach(); }
|
3150
|
+
next();
|
3151
|
+
});
|
3152
|
+
}
|
3019
3153
|
|
3020
|
-
|
3021
|
-
|
3022
|
-
if(next[1] > result.position.bottom){ result.position.bottom = next[1]; }
|
3023
|
-
if(next[1] < result.position.top){ result.position.top = next[1]; }
|
3154
|
+
// Cache the state
|
3155
|
+
prevState = state;
|
3024
3156
|
|
3025
|
-
|
3157
|
+
// If the tooltip is destroyed, set reference to null
|
3158
|
+
if(current.destroyed) { current = NULL; }
|
3159
|
+
|
3160
|
+
return self;
|
3026
3161
|
}
|
3162
|
+
});
|
3027
3163
|
|
3028
|
-
|
3029
|
-
|
3030
|
-
|
3164
|
+
self.init();
|
3165
|
+
};
|
3166
|
+
OVERLAY = new OVERLAY();
|
3031
3167
|
|
3032
|
-
|
3033
|
-
|
3034
|
-
|
3035
|
-
left: result.position.left + (result.width / 2),
|
3036
|
-
top: result.position.top + (result.height / 2)
|
3037
|
-
};
|
3038
|
-
}
|
3039
|
-
else {
|
3040
|
-
// Second pass, use a binary search algorithm to locate most suitable coordinate
|
3041
|
-
while(newWidth > 0 && newHeight > 0 && compareX > 0 && compareY > 0)
|
3042
|
-
{
|
3043
|
-
newWidth = Math.floor(newWidth / 2);
|
3044
|
-
newHeight = Math.floor(newHeight / 2);
|
3168
|
+
function Modal(api, options) {
|
3169
|
+
this.options = options;
|
3170
|
+
this._ns = '-modal';
|
3045
3171
|
|
3046
|
-
|
3047
|
-
|
3048
|
-
else{ compareX += Math.floor(newWidth / 2); }
|
3172
|
+
this.init( (this.qtip = api) );
|
3173
|
+
}
|
3049
3174
|
|
3050
|
-
|
3051
|
-
|
3052
|
-
|
3175
|
+
$.extend(Modal.prototype, {
|
3176
|
+
init: function(qtip) {
|
3177
|
+
var tooltip = qtip.tooltip;
|
3053
3178
|
|
3054
|
-
|
3055
|
-
|
3056
|
-
if(coords.length < 2){ break; }
|
3179
|
+
// If modal is disabled... return
|
3180
|
+
if(!this.options.on) { return this; }
|
3057
3181
|
|
3058
|
-
|
3059
|
-
|
3182
|
+
// Set overlay reference
|
3183
|
+
qtip.elements.overlay = OVERLAY.elem;
|
3060
3184
|
|
3061
|
-
|
3062
|
-
|
3063
|
-
(corner.x === CENTER && (realX < compareX || realX > (result.width - compareX))) ||
|
3064
|
-
(corner.y === TOP && realY >= compareY) ||
|
3065
|
-
(corner.y === BOTTOM && realY <= compareY) ||
|
3066
|
-
(corner.y === CENTER && (realY < compareY || realY > (result.height - compareY)))) {
|
3067
|
-
coords.splice(i, 1);
|
3068
|
-
}
|
3069
|
-
}
|
3070
|
-
}
|
3071
|
-
result.position = { left: coords[0][0], top: coords[0][1] };
|
3072
|
-
}
|
3185
|
+
// Add unique attribute so we can grab modal tooltips easily via a SELECTOR, and set z-index
|
3186
|
+
tooltip.addClass(MODALCLASS).css('z-index', QTIP.modal_zindex + $(MODALSELECTOR).length);
|
3073
3187
|
|
3074
|
-
|
3075
|
-
|
3188
|
+
// Apply our show/hide/focus modal events
|
3189
|
+
qtip._bind(tooltip, ['tooltipshow', 'tooltiphide'], function(event, api, duration) {
|
3190
|
+
var oEvent = event.originalEvent;
|
3076
3191
|
|
3077
|
-
|
3078
|
-
|
3079
|
-
|
3080
|
-
|
3081
|
-
|
3082
|
-
|
3083
|
-
|
3192
|
+
// Make sure mouseout doesn't trigger a hide when showing the modal and mousing onto backdrop
|
3193
|
+
if(event.target === tooltip[0]) {
|
3194
|
+
if(oEvent && event.type === 'tooltiphide' && /mouse(leave|enter)/.test(oEvent.type) && $(oEvent.relatedTarget).closest(OVERLAY.elem[0]).length) {
|
3195
|
+
try { event.preventDefault(); } catch(e) {}
|
3196
|
+
}
|
3197
|
+
else if(!oEvent || (oEvent && oEvent.type !== 'tooltipsolo')) {
|
3198
|
+
this.toggle(event, event.type === 'tooltipshow', duration);
|
3199
|
+
}
|
3084
3200
|
}
|
3085
|
-
};
|
3086
|
-
},
|
3201
|
+
}, this._ns, this);
|
3087
3202
|
|
3088
|
-
|
3089
|
-
|
3090
|
-
|
3091
|
-
|
3092
|
-
},
|
3093
|
-
ellipse: function(cx, cy, rx, ry, corner) {
|
3094
|
-
var c = PLUGINS.polys._angles[ corner.abbrev() ],
|
3095
|
-
rxc = rx * Math.cos( c * Math.PI ),
|
3096
|
-
rys = ry * Math.sin( c * Math.PI );
|
3203
|
+
// Adjust modal z-index on tooltip focus
|
3204
|
+
qtip._bind(tooltip, 'tooltipfocus', function(event, api) {
|
3205
|
+
// If focus was cancelled before it reached us, don't do anything
|
3206
|
+
if(event.isDefaultPrevented() || event.target !== tooltip[0]) { return; }
|
3097
3207
|
|
3098
|
-
|
3099
|
-
width: (rx * 2) - Math.abs(rxc),
|
3100
|
-
height: (ry * 2) - Math.abs(rys),
|
3101
|
-
position: {
|
3102
|
-
left: cx + rxc,
|
3103
|
-
top: cy + rys
|
3104
|
-
},
|
3105
|
-
adjustable: FALSE
|
3106
|
-
};
|
3107
|
-
},
|
3108
|
-
circle: function(cx, cy, r, corner) {
|
3109
|
-
return PLUGINS.polys.ellipse(cx, cy, r, r, corner);
|
3110
|
-
}
|
3111
|
-
};;PLUGINS.svg = function(api, svg, corner, adjustMethod)
|
3112
|
-
{
|
3113
|
-
var doc = $(document),
|
3114
|
-
elem = svg[0],
|
3115
|
-
result = {},
|
3116
|
-
name, box, position, dimensions;
|
3208
|
+
var qtips = $(MODALSELECTOR),
|
3117
3209
|
|
3118
|
-
|
3119
|
-
|
3120
|
-
|
3210
|
+
// Keep the modal's lower than other, regular qtips
|
3211
|
+
newIndex = QTIP.modal_zindex + qtips.length,
|
3212
|
+
curIndex = parseInt(tooltip[0].style.zIndex, 10);
|
3121
3213
|
|
3122
|
-
|
3123
|
-
|
3124
|
-
case 'rect':
|
3125
|
-
position = PLUGINS.svg.toPixel(elem, elem.x.baseVal.value, elem.y.baseVal.value);
|
3126
|
-
dimensions = PLUGINS.svg.toPixel(elem,
|
3127
|
-
elem.x.baseVal.value + elem.width.baseVal.value,
|
3128
|
-
elem.y.baseVal.value + elem.height.baseVal.value
|
3129
|
-
);
|
3214
|
+
// Set overlay z-index
|
3215
|
+
OVERLAY.elem[0].style.zIndex = newIndex - 1;
|
3130
3216
|
|
3131
|
-
|
3132
|
-
|
3133
|
-
|
3134
|
-
|
3135
|
-
|
3136
|
-
|
3217
|
+
// Reduce modal z-index's and keep them properly ordered
|
3218
|
+
qtips.each(function() {
|
3219
|
+
if(this.style.zIndex > curIndex) {
|
3220
|
+
this.style.zIndex -= 1;
|
3221
|
+
}
|
3222
|
+
});
|
3137
3223
|
|
3138
|
-
|
3139
|
-
|
3140
|
-
position = PLUGINS.svg.toPixel(elem,
|
3141
|
-
elem.cx.baseVal.value,
|
3142
|
-
elem.cy.baseVal.value
|
3143
|
-
);
|
3224
|
+
// Fire blur event for focused tooltip
|
3225
|
+
qtips.filter('.' + CLASS_FOCUS).qtip('blur', event.originalEvent);
|
3144
3226
|
|
3145
|
-
|
3146
|
-
|
3147
|
-
(elem.rx || elem.r).baseVal.value,
|
3148
|
-
(elem.ry || elem.r).baseVal.value,
|
3149
|
-
corner
|
3150
|
-
);
|
3151
|
-
break;
|
3227
|
+
// Set the new z-index
|
3228
|
+
tooltip.addClass(CLASS_FOCUS)[0].style.zIndex = newIndex;
|
3152
3229
|
|
3153
|
-
|
3154
|
-
|
3155
|
-
case 'polyline':
|
3156
|
-
points = elem.points || [
|
3157
|
-
{ x: elem.x1.baseVal.value, y: elem.y1.baseVal.value },
|
3158
|
-
{ x: elem.x2.baseVal.value, y: elem.y2.baseVal.value }
|
3159
|
-
];
|
3230
|
+
// Set current
|
3231
|
+
OVERLAY.update(api);
|
3160
3232
|
|
3161
|
-
|
3162
|
-
|
3163
|
-
|
3164
|
-
}
|
3233
|
+
// Prevent default handling
|
3234
|
+
try { event.preventDefault(); } catch(e) {}
|
3235
|
+
}, this._ns, this);
|
3165
3236
|
|
3166
|
-
|
3167
|
-
|
3237
|
+
// Focus any other visible modals when this one hides
|
3238
|
+
qtip._bind(tooltip, 'tooltiphide', function(event) {
|
3239
|
+
if(event.target === tooltip[0]) {
|
3240
|
+
$(MODALSELECTOR).filter(':visible').not(tooltip).last().qtip('focus', event);
|
3241
|
+
}
|
3242
|
+
}, this._ns, this);
|
3243
|
+
},
|
3168
3244
|
|
3169
|
-
|
3170
|
-
default
|
3171
|
-
|
3172
|
-
mtx = elem.getScreenCTM();
|
3173
|
-
root = elem.farthestViewportElement || elem;
|
3245
|
+
toggle: function(event, state, duration) {
|
3246
|
+
// Make sure default event hasn't been prevented
|
3247
|
+
if(event && event.isDefaultPrevented()) { return this; }
|
3174
3248
|
|
3175
|
-
|
3176
|
-
|
3249
|
+
// Toggle it
|
3250
|
+
OVERLAY.toggle(this.qtip, !!state, duration);
|
3251
|
+
},
|
3177
3252
|
|
3178
|
-
|
3179
|
-
|
3253
|
+
destroy: function() {
|
3254
|
+
// Remove modal class
|
3255
|
+
this.qtip.tooltip.removeClass(MODALCLASS);
|
3180
3256
|
|
3181
|
-
|
3182
|
-
|
3183
|
-
point.y = box.y;
|
3184
|
-
tPoint = point.matrixTransform(mtx);
|
3185
|
-
result.position = {
|
3186
|
-
left: tPoint.x, top: tPoint.y
|
3187
|
-
};
|
3257
|
+
// Remove bound events
|
3258
|
+
this.qtip._unbind(this.qtip.tooltip, this._ns);
|
3188
3259
|
|
3189
|
-
|
3190
|
-
|
3191
|
-
|
3192
|
-
tPoint = point.matrixTransform(mtx);
|
3193
|
-
result.width = tPoint.x - result.position.left;
|
3194
|
-
result.height = tPoint.y - result.position.top;
|
3195
|
-
break;
|
3260
|
+
// Delete element reference
|
3261
|
+
OVERLAY.toggle(this.qtip, FALSE);
|
3262
|
+
delete this.qtip.elements.overlay;
|
3196
3263
|
}
|
3264
|
+
});
|
3197
3265
|
|
3198
|
-
// Adjust by scroll offset
|
3199
|
-
result.position.left += doc.scrollLeft();
|
3200
|
-
result.position.top += doc.scrollTop();
|
3201
3266
|
|
3202
|
-
|
3267
|
+
MODAL = PLUGINS.modal = function(api) {
|
3268
|
+
return new Modal(api, api.options.show.modal);
|
3203
3269
|
};
|
3204
3270
|
|
3205
|
-
|
3206
|
-
|
3207
|
-
|
3208
|
-
|
3209
|
-
|
3210
|
-
|
3211
|
-
|
3212
|
-
point = root.createSVGPoint();
|
3271
|
+
// Setup sanitiztion rules
|
3272
|
+
MODAL.sanitize = function(opts) {
|
3273
|
+
if(opts.show) {
|
3274
|
+
if(typeof opts.show.modal !== 'object') { opts.show.modal = { on: !!opts.show.modal }; }
|
3275
|
+
else if(typeof opts.show.modal.on === 'undefined') { opts.show.modal.on = TRUE; }
|
3276
|
+
}
|
3277
|
+
};
|
3213
3278
|
|
3214
|
-
|
3215
|
-
|
3216
|
-
return [ result.x, result.y ];
|
3217
|
-
};;PLUGINS.imagemap = function(api, area, corner, adjustMethod)
|
3218
|
-
{
|
3219
|
-
if(!area.jquery) { area = $(area); }
|
3279
|
+
// Base z-index for all modal tooltips (use qTip core z-index as a base)
|
3280
|
+
QTIP.modal_zindex = QTIP.zindex - 200;
|
3220
3281
|
|
3221
|
-
|
3222
|
-
|
3223
|
-
coordsString = area.attr('coords'),
|
3224
|
-
coordsArray = coordsString.split(','),
|
3225
|
-
imageOffset, coords, i, next;
|
3282
|
+
// Plugin needs to be initialized on render
|
3283
|
+
MODAL.initialize = 'render';
|
3226
3284
|
|
3227
|
-
|
3228
|
-
|
3285
|
+
// Setup option set checks
|
3286
|
+
CHECKS.modal = {
|
3287
|
+
'^show.modal.(on|blur)$': function() {
|
3288
|
+
// Initialise
|
3289
|
+
this.destroy();
|
3290
|
+
this.init();
|
3229
3291
|
|
3230
|
-
|
3231
|
-
|
3232
|
-
|
3292
|
+
// Show the modal if not visible already and tooltip is visible
|
3293
|
+
this.qtip.elems.overlay.toggle(
|
3294
|
+
this.qtip.tooltip[0].offsetWidth > 0
|
3295
|
+
);
|
3233
3296
|
}
|
3297
|
+
};
|
3234
3298
|
|
3235
|
-
|
3236
|
-
|
3237
|
-
|
3238
|
-
|
3299
|
+
// Extend original api defaults
|
3300
|
+
$.extend(TRUE, QTIP.defaults, {
|
3301
|
+
show: {
|
3302
|
+
modal: {
|
3303
|
+
on: FALSE,
|
3304
|
+
effect: TRUE,
|
3305
|
+
blur: TRUE,
|
3306
|
+
stealfocus: TRUE,
|
3307
|
+
escape: TRUE
|
3239
3308
|
}
|
3240
|
-
|
3241
|
-
result = PLUGINS.polys[shape].apply(
|
3242
|
-
this, coords.concat(corner)
|
3243
|
-
);
|
3244
3309
|
}
|
3310
|
+
});
|
3311
|
+
;var IE6,
|
3245
3312
|
|
3246
|
-
|
3247
|
-
else { return FALSE; }
|
3248
|
-
|
3249
|
-
// Make sure we account for padding and borders on the image
|
3250
|
-
imageOffset = image.offset();
|
3251
|
-
imageOffset.left += Math.ceil((image.outerWidth(FALSE) - image.width()) / 2);
|
3252
|
-
imageOffset.top += Math.ceil((image.outerHeight(FALSE) - image.height()) / 2);
|
3253
|
-
|
3254
|
-
// Add image position to offset coordinates
|
3255
|
-
result.position.left += imageOffset.left;
|
3256
|
-
result.position.top += imageOffset.top;
|
3257
|
-
|
3258
|
-
return result;
|
3259
|
-
};;var IE6,
|
3260
|
-
|
3261
|
-
/*
|
3313
|
+
/*
|
3262
3314
|
* BGIFrame adaption (http://plugins.jquery.com/project/bgiframe)
|
3263
3315
|
* Special thanks to Brandon Aaron
|
3264
3316
|
*/
|
@@ -3329,7 +3381,7 @@ $.extend(Ie6.prototype, {
|
|
3329
3381
|
|
3330
3382
|
// Max/min width simulator function
|
3331
3383
|
redraw: function() {
|
3332
|
-
if(this.qtip.rendered < 1 || this.drawing) { return
|
3384
|
+
if(this.qtip.rendered < 1 || this.drawing) { return this; }
|
3333
3385
|
|
3334
3386
|
var tooltip = this.qtip.tooltip,
|
3335
3387
|
style = this.qtip.options.style,
|
@@ -3358,7 +3410,7 @@ $.extend(Ie6.prototype, {
|
|
3358
3410
|
|
3359
3411
|
// Parse into proper pixel values
|
3360
3412
|
perc = (max + min).indexOf('%') > -1 ? container.width() / 100 : 0;
|
3361
|
-
|
3413
|
+
max = ((max.indexOf('%') > -1 ? perc : 1) * parseInt(max, 10)) || width;
|
3362
3414
|
min = ((min.indexOf('%') > -1 ? perc : 1) * parseInt(min, 10)) || 0;
|
3363
3415
|
|
3364
3416
|
// Determine new dimension size based on max/min/current values
|
@@ -3371,7 +3423,7 @@ $.extend(Ie6.prototype, {
|
|
3371
3423
|
// Set drawing flag
|
3372
3424
|
this.drawing = 0;
|
3373
3425
|
|
3374
|
-
return
|
3426
|
+
return this;
|
3375
3427
|
},
|
3376
3428
|
|
3377
3429
|
destroy: function() {
|
@@ -3391,10 +3443,9 @@ IE6 = PLUGINS.ie6 = function(api) {
|
|
3391
3443
|
IE6.initialize = 'render';
|
3392
3444
|
|
3393
3445
|
CHECKS.ie6 = {
|
3394
|
-
'^content|style$': function() {
|
3446
|
+
'^content|style$': function() {
|
3395
3447
|
this.redraw();
|
3396
3448
|
}
|
3397
|
-
}
|
3449
|
+
};
|
3450
|
+
;}));
|
3398
3451
|
}( window, document ));
|
3399
|
-
|
3400
|
-
|