qtip2-jquery-rails 2.1.108 → 2.2.100
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
-
|