jquery-qtip2-wrapper-rails 2.2.0 → 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2b86a3c00e5e478f9f6479cd67f2e3905dc7bb22
4
- data.tar.gz: 80c053ae476d81b6317ea63aeecb91131224bb73
3
+ metadata.gz: ee12a65df8fc37f10a0182cb139af5ebab0d1cf7
4
+ data.tar.gz: 318d8f219fd62dd2ed3a750d26c9d2be129ff777
5
5
  SHA512:
6
- metadata.gz: 01182abf5f96f91af606d55ada50df084e013e937b6c49352bc5d21b12211725a433f72dd5c8a397227831412d40d99503782309993a92d540f44357499c12b0
7
- data.tar.gz: 552eaaa47b5e7c4f21305b1ec67ab1f99cb852a33a57661ecb061e2dc4d665d78d10bcaff558d1e5c3baf5092a29259bf1e4af811f16bd151b7516fbcab63c07
6
+ metadata.gz: 0778e011829da73aff8bd884a7c4db9697dbb2d43447b283d1cb53fce3f31023da14e42e49b6322bad963e1142c1698599d4f2a624ac75efaa08909c215b57e6
7
+ data.tar.gz: 75efaa7bdf7bcce7741e30f004361f02fdc4b57d659b2560086a3c247b31bf0dfcced6ac1e046c43fc32b5a23f0a5fc711b4f01f31ce8b4967664c4600994ea3
@@ -2,7 +2,7 @@ module Jquery
2
2
  module Qtip2
3
3
  module Wrapper
4
4
  module Rails
5
- VERSION = "2.2.0"
5
+ VERSION = "2.2.1"
6
6
  end
7
7
  end
8
8
  end
@@ -1,14 +1,14 @@
1
1
  /*
2
- * qTip2 - Pretty powerful tooltips - v2.2.0
2
+ * qTip2 - Pretty powerful tooltips - v2.2.1
3
3
  * http://qtip2.com
4
4
  *
5
- * Copyright (c) 2013 Craig Michael Thompson
6
- * Released under the MIT, GPL licenses
5
+ * Copyright (c) 2014
6
+ * Released under the MIT licenses
7
7
  * http://jquery.org/license
8
8
  *
9
- * Date: Thu Nov 21 2013 08:34 GMT+0000
9
+ * Date: Sat Sep 6 2014 11:12 GMT+0100+0100
10
10
  * Plugins: tips modal viewport svg imagemap ie6
11
- * Styles: basic css3
11
+ * Styles: core basic css3
12
12
  */
13
13
  /*global window: false, jQuery: false, console: false, define: false */
14
14
 
@@ -27,7 +27,6 @@
27
27
  }
28
28
  (function($) {
29
29
  "use strict"; // Enable ECMAScript "strict" operation for this function. See more: http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/
30
-
31
30
  ;// Munge the primitives - Paul Irish tip
32
31
  var TRUE = true,
33
32
  FALSE = false,
@@ -79,222 +78,227 @@ BROWSER = {
79
78
  * Credit to James Padolsey for the original implemntation!
80
79
  */
81
80
  ie: (function(){
82
- var v = 3, div = document.createElement('div');
83
- while ((div.innerHTML = '<!--[if gt IE '+(++v)+']><i></i><![endif]-->')) {
84
- if(!div.getElementsByTagName('i')[0]) { break; }
85
- }
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
+ ) {}
86
86
  return v > 4 ? v : NaN;
87
87
  }()),
88
-
88
+
89
89
  /*
90
90
  * iOS version detection
91
91
  */
92
- iOS: parseFloat(
92
+ iOS: parseFloat(
93
93
  ('' + (/CPU.*OS ([0-9_]{1,5})|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent) || [0,''])[1])
94
94
  .replace('undefined', '3_2').replace('_', '.').replace('_', '')
95
95
  ) || FALSE
96
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;
97
252
 
98
- ;function QTip(target, options, id, attr) {
99
- // Elements and ID
100
- this.id = id;
101
- this.target = target;
102
- this.tooltip = NULL;
103
- this.elements = { target: target };
104
-
105
- // Internal constructs
106
- this._id = NAMESPACE + '-' + id;
107
- this.timers = { img: {} };
108
- this.options = options;
109
- this.plugins = {};
110
-
111
- // Cache object
112
- this.cache = {
113
- event: {},
114
- target: $(),
115
- disabled: FALSE,
116
- attr: attr,
117
- onTooltip: FALSE,
118
- lastClass: ''
119
- };
120
-
121
- // Set the initial flags
122
- this.rendered = this.destroyed = this.disabled = this.waiting =
123
- this.hiddenDuringWait = this.positioning = this.triggering = FALSE;
124
- }
125
- PROTOTYPE = QTip.prototype;
126
-
127
- PROTOTYPE._when = function(deferreds) {
128
- return $.when.apply($, deferreds);
129
- };
130
-
131
- PROTOTYPE.render = function(show) {
132
- if(this.rendered || this.destroyed) { return this; } // If tooltip has already been rendered, exit
133
-
134
- var self = this,
135
- options = this.options,
136
- cache = this.cache,
137
- elements = this.elements,
138
- text = options.content.text,
139
- title = options.content.title,
140
- button = options.content.button,
141
- posOptions = options.position,
142
- namespace = '.'+this._id+' ',
143
- deferreds = [],
144
- tooltip;
145
-
146
- // Add ARIA attributes to target
147
- $.attr(this.target[0], 'aria-describedby', this._id);
148
-
149
- // Create tooltip element
150
- this.tooltip = elements.tooltip = tooltip = $('<div/>', {
151
- 'id': this._id,
152
- 'class': [ NAMESPACE, CLASS_DEFAULT, options.style.classes, NAMESPACE + '-pos-' + options.position.my.abbrev() ].join(' '),
153
- 'width': options.style.width || '',
154
- 'height': options.style.height || '',
155
- 'tracking': posOptions.target === 'mouse' && posOptions.adjust.mouse,
156
-
157
- /* ARIA specific attributes */
158
- 'role': 'alert',
159
- 'aria-live': 'polite',
160
- 'aria-atomic': FALSE,
161
- 'aria-describedby': this._id + '-content',
162
- 'aria-hidden': TRUE
163
- })
164
- .toggleClass(CLASS_DISABLED, this.disabled)
165
- .attr(ATTR_ID, this.id)
166
- .data(NAMESPACE, this)
167
- .appendTo(posOptions.container)
168
- .append(
169
- // Create content element
170
- elements.content = $('<div />', {
171
- 'class': NAMESPACE + '-content',
172
- 'id': this._id + '-content',
173
- 'aria-atomic': TRUE
174
- })
175
- );
176
-
177
- // Set rendered flag and prevent redundant reposition calls for now
178
- this.rendered = -1;
179
- this.positioning = TRUE;
180
-
181
- // Create title...
182
- if(title) {
183
- this._createTitle();
184
-
185
- // Update title only if its not a callback (called in toggle if so)
186
- if(!$.isFunction(title)) {
187
- deferreds.push( this._updateTitle(title, FALSE) );
188
- }
189
- }
190
-
191
- // Create button
192
- if(button) { this._createButton(); }
193
-
194
- // Set proper rendered flag and update content if not a callback function (called in toggle)
195
- if(!$.isFunction(text)) {
196
- deferreds.push( this._updateContent(text, FALSE) );
197
- }
198
- this.rendered = TRUE;
199
-
200
- // Setup widget classes
201
- this._setWidget();
202
-
203
- // Initialize 'render' plugins
204
- $.each(PLUGINS, function(name) {
205
- var instance;
206
- if(this.initialize === 'render' && (instance = this(self))) {
207
- self.plugins[name] = instance;
208
- }
209
- });
210
-
211
- // Unassign initial events and assign proper events
212
- this._unassignEvents();
213
- this._assignEvents();
214
-
215
- // When deferreds have completed
216
- this._when(deferreds).then(function() {
217
- // tooltiprender event
218
- self._trigger('render');
219
-
220
- // Reset flags
221
- self.positioning = FALSE;
222
-
223
- // Show tooltip if not hidden during wait period
224
- if(!self.hiddenDuringWait && (options.show.ready || show)) {
225
- self.toggle(TRUE, cache.event, FALSE);
226
- }
227
- self.hiddenDuringWait = FALSE;
228
- });
229
-
230
- // Expose API
231
- QTIP.api[this.id] = this;
232
-
233
- return this;
234
- };
235
-
236
- PROTOTYPE.destroy = function(immediate) {
237
- // Set flag the signify destroy is taking place to plugins
238
- // and ensure it only gets destroyed once!
239
- if(this.destroyed) { return this.target; }
240
-
241
- function process() {
242
- if(this.destroyed) { return; }
243
- this.destroyed = TRUE;
244
-
245
- var target = this.target,
246
- title = target.attr(oldtitle);
247
-
248
- // Destroy tooltip if rendered
249
- if(this.rendered) {
250
- this.tooltip.stop(1,0).find('*').remove().end().remove();
251
- }
252
-
253
- // Destroy all plugins
254
- $.each(this.plugins, function(name) {
255
- this.destroy && this.destroy();
256
- });
257
-
258
- // Clear timers and remove bound events
259
- clearTimeout(this.timers.show);
260
- clearTimeout(this.timers.hide);
261
- this._unassignEvents();
262
-
263
- // Remove api object and ARIA attributes
264
- target.removeData(NAMESPACE)
265
- .removeAttr(ATTR_ID)
266
- .removeAttr(ATTR_HAS)
267
- .removeAttr('aria-describedby');
268
-
269
- // Reset old title attribute if removed
270
- if(this.options.suppress && title) {
271
- target.attr('title', title).removeAttr(oldtitle);
272
- }
273
-
274
- // Remove qTip events associated with this API
275
- this._unbind(target);
276
-
277
- // Remove ID from used id objects, and delete object references
278
- // for better garbage collection and leak protection
279
- this.options = this.elements = this.cache = this.timers =
280
- this.plugins = this.mouse = NULL;
281
-
282
- // Delete epoxsed API object
283
- delete QTIP.api[this.id];
284
- }
285
-
286
- // If an immediate destory is needed
287
- if((immediate !== TRUE || this.triggering === 'hide') && this.rendered) {
288
- this.tooltip.one('tooltiphidden', $.proxy(process, this));
289
- !this.triggering && this.hide();
290
- }
291
-
292
- // If we're not in the process of hiding... process
293
- else { process.call(this); }
294
-
295
- return this.target;
296
- };
297
-
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
+ }
290
+
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
+ };
298
302
  ;function invalidOpt(a) {
299
303
  return a === NULL || $.type(a) !== 'object';
300
304
  }
@@ -351,7 +355,7 @@ function sanitizeOptions(opts) {
351
355
  }
352
356
 
353
357
  if('title' in content) {
354
- if(!invalidOpt(content.title)) {
358
+ if($.isPlainObject(content.title)) {
355
359
  content.button = content.title.button;
356
360
  content.title = content.title.text;
357
361
  }
@@ -367,7 +371,7 @@ function sanitizeOptions(opts) {
367
371
  }
368
372
 
369
373
  if('show' in opts && invalidOpt(opts.show)) {
370
- opts.show = opts.show.jquery ? { target: opts.show } :
374
+ opts.show = opts.show.jquery ? { target: opts.show } :
371
375
  opts.show === TRUE ? { ready: TRUE } : { event: opts.show };
372
376
  }
373
377
 
@@ -432,11 +436,11 @@ CHECKS = PROTOTYPE.checks = {
432
436
  },
433
437
  '^content.title.(text|button)$': function(obj, o, v) {
434
438
  this.set('content.'+o, v); // Backwards title.text/button compat
435
- },
439
+ },
436
440
 
437
441
  // Position checks
438
442
  '^position.(my|at)$': function(obj, o, v){
439
- 'string' === typeof v && (obj[o] = new CORNER(v, o === 'at'));
443
+ 'string' === typeof v && (this.position[o] = obj[o] = new CORNER(v, o === 'at'));
440
444
  },
441
445
  '^position.container$': function(obj, o, v){
442
446
  this.rendered && this.tooltip.appendTo(v);
@@ -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;
@@ -616,7 +619,7 @@ PROTOTYPE.set = function(option, value) {
616
619
 
617
620
  // Wait for content to be loaded, and reposition
618
621
  return this._waitForContent(element).then(function(images) {
619
- if(images.images && images.images.length && self.rendered && self.tooltip[0].offsetWidth > 0) {
622
+ if(self.rendered && self.tooltip[0].offsetWidth > 0) {
620
623
  self.reposition(cache.event, !images.length);
621
624
  }
622
625
  });
@@ -624,7 +627,7 @@ PROTOTYPE.set = function(option, value) {
624
627
 
625
628
  PROTOTYPE._waitForContent = function(element) {
626
629
  var cache = this.cache;
627
-
630
+
628
631
  // Set flag
629
632
  cache.waiting = TRUE;
630
633
 
@@ -689,8 +692,11 @@ PROTOTYPE._removeTitle = function(reposition)
689
692
  if(reposition !== FALSE) { this.reposition(); }
690
693
  }
691
694
  };
695
+ ;PROTOTYPE._createPosClass = function(my) {
696
+ return NAMESPACE + '-pos-' + (my || this.options.position.my).abbrev();
697
+ };
692
698
 
693
- ;PROTOTYPE.reposition = function(event, effect) {
699
+ PROTOTYPE.reposition = function(event, effect) {
694
700
  if(!this.rendered || this.positioning || this.destroyed) { return this; }
695
701
 
696
702
  // Set positioning flag
@@ -717,7 +723,7 @@ PROTOTYPE._removeTitle = function(reposition)
717
723
  win = $(window),
718
724
  doc = container[0].ownerDocument,
719
725
  mouse = this.mouse,
720
- pluginCalculations, offset;
726
+ pluginCalculations, offset, adjusted, newClass;
721
727
 
722
728
  // Check if absolute position was passed
723
729
  if($.isArray(target) && target.length === 2) {
@@ -731,22 +737,19 @@ PROTOTYPE._removeTitle = function(reposition)
731
737
  // Force left top to allow flipping
732
738
  at = { x: LEFT, y: TOP };
733
739
 
734
- // Use the cached mouse coordinates if available, or passed event has no coordinates
735
- if(mouse && mouse.pageX && (adjust.mouse || !event || !event.pageX) ) {
736
- event = mouse;
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;
737
743
  }
738
-
739
- // If the passed event has no coordinates (such as a scroll event)
740
- else if(!event || !event.pageX) {
741
- // Use the mouse origin that caused the show event, if distance hiding is enabled
742
- if((!adjust.mouse || this.options.show.distance) && cache.origin && cache.origin.pageX) {
743
- event = cache.origin;
744
- }
745
744
 
746
- // Use cached event for resize/scroll events
747
- else if(!event || (event && (event.type === 'resize' || event.type === 'scroll'))) {
748
- event = cache.event;
749
- }
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;
750
753
  }
751
754
 
752
755
  // Calculate body and container offset and take them into account below
@@ -830,8 +833,8 @@ PROTOTYPE._removeTitle = function(reposition)
830
833
  position = this.reposition.offset(target, position, container);
831
834
 
832
835
  // Adjust for position.fixed tooltips (and also iOS scroll bug in v3.2-4.0 & v4.3-4.3.2)
833
- if((BROWSER.iOS > 3.1 && BROWSER.iOS < 4.1) ||
834
- (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) ||
835
838
  (!BROWSER.iOS && type === 'fixed')
836
839
  ){
837
840
  position.left -= win.scrollLeft();
@@ -851,18 +854,26 @@ PROTOTYPE._removeTitle = function(reposition)
851
854
 
852
855
  // Use viewport adjustment plugin if enabled
853
856
  if(PLUGINS.viewport) {
854
- position.adjusted = PLUGINS.viewport(
857
+ adjusted = position.adjusted = PLUGINS.viewport(
855
858
  this, position, posOptions, targetWidth, targetHeight, tooltipWidth, tooltipHeight
856
859
  );
857
860
 
858
861
  // Apply offsets supplied by positioning plugin (if used)
859
- if(offset && position.adjusted.left) { position.left += offset.left; }
860
- if(offset && position.adjusted.top) { position.top += offset.top; }
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; }
861
867
  }
862
868
 
863
869
  // Viewport adjustment is disabled, set values to zero
864
870
  else { position.adjusted = { left: 0, top: 0 }; }
865
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
+
866
877
  // tooltipmove event
867
878
  if(!this._trigger('move', [position, viewport.elem || viewport], event)) { return this; }
868
879
  delete position.adjusted;
@@ -946,22 +957,31 @@ var C = (CORNER = PROTOTYPE.reposition.Corner = function(corner, forceY) {
946
957
  }).prototype;
947
958
 
948
959
  C.invert = function(z, center) {
949
- 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];
950
961
  };
951
962
 
952
- C.string = function() {
963
+ C.string = function(join) {
953
964
  var x = this.x, y = this.y;
954
- return x === y ? x : this.precedance === Y || (this.forceY && y !== 'center') ? y+' '+x : x+' '+y;
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;
955
973
  };
956
974
 
957
975
  C.abbrev = function() {
958
- var result = this.string().split(' ');
976
+ var result = this.string(false);
959
977
  return result[0].charAt(0) + (result[1] && result[1].charAt(0) || '');
960
978
  };
961
979
 
962
980
  C.clone = function() {
963
981
  return new CORNER( this.string(), this.forceY );
964
- };;
982
+ };
983
+
984
+ ;
965
985
  PROTOTYPE.toggle = function(state, event) {
966
986
  var cache = this.cache,
967
987
  options = this.options,
@@ -969,16 +989,16 @@ PROTOTYPE.toggle = function(state, event) {
969
989
 
970
990
  // Try to prevent flickering when tooltip overlaps show element
971
991
  if(event) {
972
- 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) &&
973
993
  options.show.target.add(event.target).length === options.show.target.length &&
974
994
  tooltip.has(event.relatedTarget).length) {
975
995
  return this;
976
996
  }
977
997
 
978
998
  // Cache event
979
- cache.event = cloneEvent(event);
999
+ cache.event = $.event.fix(event);
980
1000
  }
981
-
1001
+
982
1002
  // If we're currently waiting and we've just hidden... stop it
983
1003
  this.waiting && !state && (this.hiddenDuringWait = TRUE);
984
1004
 
@@ -1021,7 +1041,7 @@ PROTOTYPE.toggle = function(state, event) {
1021
1041
  // Execute state specific properties
1022
1042
  if(state) {
1023
1043
  // Store show origin coordinates
1024
- cache.origin = cloneEvent(this.mouse);
1044
+ this.mouse && (cache.origin = $.event.fix(this.mouse));
1025
1045
 
1026
1046
  // Update tooltip content & title if it's a dynamic function
1027
1047
  if($.isFunction(contentOptions.text)) { this._updateContent(contentOptions.text, FALSE); }
@@ -1120,7 +1140,6 @@ PROTOTYPE.toggle = function(state, event) {
1120
1140
  PROTOTYPE.show = function(event) { return this.toggle(TRUE, event); };
1121
1141
 
1122
1142
  PROTOTYPE.hide = function(event) { return this.toggle(FALSE, event); };
1123
-
1124
1143
  ;PROTOTYPE.focus = function(event) {
1125
1144
  if(!this.rendered || this.destroyed) { return this; }
1126
1145
 
@@ -1166,7 +1185,6 @@ PROTOTYPE.blur = function(event) {
1166
1185
 
1167
1186
  return this;
1168
1187
  };
1169
-
1170
1188
  ;PROTOTYPE.disable = function(state) {
1171
1189
  if(this.destroyed) { return this; }
1172
1190
 
@@ -1191,7 +1209,6 @@ PROTOTYPE.blur = function(event) {
1191
1209
  };
1192
1210
 
1193
1211
  PROTOTYPE.enable = function() { return this.disable(FALSE); };
1194
-
1195
1212
  ;PROTOTYPE._createButton = function()
1196
1213
  {
1197
1214
  var self = this,
@@ -1239,7 +1256,6 @@ PROTOTYPE._updateButton = function(button)
1239
1256
  if(button) { this._createButton(); }
1240
1257
  else { elem.remove(); }
1241
1258
  };
1242
-
1243
1259
  ;// Widget class creator
1244
1260
  function createWidgetClass(cls) {
1245
1261
  return WIDGET.concat('').join(cls ? '-'+cls+' ' : ' ');
@@ -1258,7 +1274,7 @@ PROTOTYPE._setWidget = function()
1258
1274
  tooltip.toggleClass(CLASS_DISABLED, disabled);
1259
1275
 
1260
1276
  tooltip.toggleClass('ui-helper-reset '+createWidgetClass(), on).toggleClass(CLASS_DEFAULT, this.options.style.def && !on);
1261
-
1277
+
1262
1278
  if(elements.content) {
1263
1279
  elements.content.toggleClass( createWidgetClass('content'), on);
1264
1280
  }
@@ -1268,19 +1284,8 @@ PROTOTYPE._setWidget = function()
1268
1284
  if(elements.button) {
1269
1285
  elements.button.toggleClass(NAMESPACE+'-icon', !on);
1270
1286
  }
1271
- };;function cloneEvent(event) {
1272
- return event && {
1273
- type: event.type,
1274
- pageX: event.pageX,
1275
- pageY: event.pageY,
1276
- target: event.target,
1277
- relatedTarget: event.relatedTarget,
1278
- scrollX: event.scrollX || window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft,
1279
- scrollY: event.scrollY || window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop
1280
- } || {};
1281
- }
1282
-
1283
- function delay(callback, duration) {
1287
+ };
1288
+ ;function delay(callback, duration) {
1284
1289
  // If tooltip has displayed, start hide timer
1285
1290
  if(duration > 0) {
1286
1291
  return setTimeout(
@@ -1291,7 +1296,7 @@ function delay(callback, duration) {
1291
1296
  }
1292
1297
 
1293
1298
  function showMethod(event) {
1294
- if(this.tooltip.hasClass(CLASS_DISABLED)) { return FALSE; }
1299
+ if(this.tooltip.hasClass(CLASS_DISABLED)) { return; }
1295
1300
 
1296
1301
  // Clear hide timers
1297
1302
  clearTimeout(this.timers.show);
@@ -1305,7 +1310,7 @@ function showMethod(event) {
1305
1310
  }
1306
1311
 
1307
1312
  function hideMethod(event) {
1308
- if(this.tooltip.hasClass(CLASS_DISABLED)) { return FALSE; }
1313
+ if(this.tooltip.hasClass(CLASS_DISABLED) || this.destroyed) { return; }
1309
1314
 
1310
1315
  // Check if new target was actually the tooltip element
1311
1316
  var relatedTarget = $(event.relatedTarget),
@@ -1318,8 +1323,8 @@ function hideMethod(event) {
1318
1323
 
1319
1324
  // Prevent hiding if tooltip is fixed and event target is the tooltip.
1320
1325
  // Or if mouse positioning is enabled and cursor momentarily overlaps
1321
- if(this !== relatedTarget[0] &&
1322
- (this.options.position.target === 'mouse' && ontoTooltip) ||
1326
+ if(this !== relatedTarget[0] &&
1327
+ (this.options.position.target === 'mouse' && ontoTooltip) ||
1323
1328
  (this.options.hide.fixed && (
1324
1329
  (/mouse(out|leave|move)/).test(event.type) && (ontoTooltip || ontoTarget))
1325
1330
  ))
@@ -1341,7 +1346,7 @@ function hideMethod(event) {
1341
1346
  }
1342
1347
 
1343
1348
  function inactiveMethod(event) {
1344
- if(this.tooltip.hasClass(CLASS_DISABLED) || !this.options.hide.inactive) { return FALSE; }
1349
+ if(this.tooltip.hasClass(CLASS_DISABLED) || !this.options.hide.inactive) { return; }
1345
1350
 
1346
1351
  // Clear timer
1347
1352
  clearTimeout(this.timers.inactive);
@@ -1358,66 +1363,35 @@ function repositionMethod(event) {
1358
1363
 
1359
1364
  // Store mouse coordinates
1360
1365
  PROTOTYPE._storeMouse = function(event) {
1361
- (this.mouse = cloneEvent(event)).type = 'mousemove';
1366
+ (this.mouse = $.event.fix(event)).type = 'mousemove';
1367
+ return this;
1362
1368
  };
1363
1369
 
1364
1370
  // Bind events
1365
1371
  PROTOTYPE._bind = function(targets, events, method, suffix, context) {
1372
+ if(!targets || !method || !events.length) { return; }
1366
1373
  var ns = '.' + this._id + (suffix ? '-'+suffix : '');
1367
- events.length && $(targets).bind(
1374
+ $(targets).bind(
1368
1375
  (events.split ? events : events.join(ns + ' ')) + ns,
1369
1376
  $.proxy(method, context || this)
1370
1377
  );
1378
+ return this;
1371
1379
  };
1372
1380
  PROTOTYPE._unbind = function(targets, suffix) {
1373
- $(targets).unbind('.' + this._id + (suffix ? '-'+suffix : ''));
1381
+ targets && $(targets).unbind('.' + this._id + (suffix ? '-'+suffix : ''));
1382
+ return this;
1374
1383
  };
1375
1384
 
1376
- // Apply common event handlers using delegate (avoids excessive .bind calls!)
1377
- var ns = '.'+NAMESPACE;
1378
- function delegate(selector, events, method) {
1385
+ // Global delegation helper
1386
+ function delegate(selector, events, method) {
1379
1387
  $(document.body).delegate(selector,
1380
- (events.split ? events : events.join(ns + ' ')) + ns,
1388
+ (events.split ? events : events.join('.'+NAMESPACE + ' ')) + '.'+NAMESPACE,
1381
1389
  function() {
1382
1390
  var api = QTIP.api[ $.attr(this, ATTR_ID) ];
1383
1391
  api && !api.disabled && method.apply(api, arguments);
1384
1392
  }
1385
1393
  );
1386
1394
  }
1387
-
1388
- $(function() {
1389
- delegate(SELECTOR, ['mouseenter', 'mouseleave'], function(event) {
1390
- var state = event.type === 'mouseenter',
1391
- tooltip = $(event.currentTarget),
1392
- target = $(event.relatedTarget || event.target),
1393
- options = this.options;
1394
-
1395
- // On mouseenter...
1396
- if(state) {
1397
- // Focus the tooltip on mouseenter (z-index stacking)
1398
- this.focus(event);
1399
-
1400
- // Clear hide timer on tooltip hover to prevent it from closing
1401
- tooltip.hasClass(CLASS_FIXED) && !tooltip.hasClass(CLASS_DISABLED) && clearTimeout(this.timers.hide);
1402
- }
1403
-
1404
- // On mouseleave...
1405
- else {
1406
- // Hide when we leave the tooltip and not onto the show target (if a hide event is set)
1407
- if(options.position.target === 'mouse' && options.hide.event &&
1408
- options.show.target && !target.closest(options.show.target[0]).length) {
1409
- this.hide(event);
1410
- }
1411
- }
1412
-
1413
- // Add hover class
1414
- tooltip.toggleClass(CLASS_HOVER, state);
1415
- });
1416
-
1417
- // Define events which reset the 'inactive' event handler
1418
- delegate('['+ATTR_ID+']', INACTIVE_EVENTS, inactiveMethod);
1419
- });
1420
-
1421
1395
  // Event trigger
1422
1396
  PROTOTYPE._trigger = function(type, args, event) {
1423
1397
  var callback = $.Event('tooltip'+type);
@@ -1430,35 +1404,40 @@ PROTOTYPE._trigger = function(type, args, event) {
1430
1404
  return !callback.isDefaultPrevented();
1431
1405
  };
1432
1406
 
1433
- PROTOTYPE._bindEvents = function(showEvents, hideEvents, showTarget, hideTarget, showMethod, hideMethod) {
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 = [];
1411
+
1434
1412
  // If hide and show targets are the same...
1435
- if(hideTarget.add(showTarget).length === hideTarget.length) {
1436
- var toggleEvents = [];
1413
+ if(similarTargets.length) {
1437
1414
 
1438
1415
  // Filter identical show/hide events
1439
- hideEvents = $.map(hideEvents, function(type) {
1416
+ $.each(hideEvents, function(i, type) {
1440
1417
  var showIndex = $.inArray(type, showEvents);
1441
1418
 
1442
1419
  // Both events are identical, remove from both hide and show events
1443
1420
  // and append to toggleEvents
1444
- if(showIndex > -1) {
1445
- toggleEvents.push( showEvents.splice( showIndex, 1 )[0] );
1446
- return;
1447
- }
1448
-
1449
- return type;
1421
+ showIndex > -1 && toggleEvents.push( showEvents.splice( showIndex, 1 )[0] );
1450
1422
  });
1451
1423
 
1452
1424
  // Toggle events are special case of identical show/hide events, which happen in sequence
1453
- toggleEvents.length && this._bind(showTarget, toggleEvents, function(event) {
1454
- var state = this.rendered ? this.tooltip[0].offsetWidth > 0 : false;
1455
- (state ? hideMethod : showMethod).call(this, event);
1456
- });
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);
1435
+ }
1457
1436
  }
1458
1437
 
1459
1438
  // Apply show/hide/toggle events
1460
- this._bind(showTarget, showEvents, showMethod);
1461
- this._bind(hideTarget, hideEvents, hideMethod);
1439
+ this._bind(showTargets, showEvents, showMethod);
1440
+ this._bind(hideTargets, hideEvents, hideMethod);
1462
1441
  };
1463
1442
 
1464
1443
  PROTOTYPE._assignInitialEvents = function(event) {
@@ -1468,6 +1447,11 @@ PROTOTYPE._assignInitialEvents = function(event) {
1468
1447
  showEvents = options.show.event ? $.trim('' + options.show.event).split(' ') : [],
1469
1448
  hideEvents = options.hide.event ? $.trim('' + options.hide.event).split(' ') : [];
1470
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
+
1471
1455
  /*
1472
1456
  * Make sure hoverIntent functions properly by using mouseleave as a hide event if
1473
1457
  * mouseenter/mouseout is used for show.event, even if it isn't in the users options.
@@ -1492,19 +1476,20 @@ PROTOTYPE._assignInitialEvents = function(event) {
1492
1476
  if(this.disabled || this.destroyed) { return FALSE; }
1493
1477
 
1494
1478
  // Cache the event data
1495
- this.cache.event = cloneEvent(event);
1496
- this.cache.target = event ? $(event.target) : [undefined];
1479
+ this.cache.event = event && $.event.fix(event);
1480
+ this.cache.target = event && $(event.target);
1497
1481
 
1498
1482
  // Start the event sequence
1499
1483
  clearTimeout(this.timers.show);
1500
1484
  this.timers.show = delay.call(this,
1501
1485
  function() { this.render(typeof event === 'object' || options.show.ready); },
1502
- options.show.delay
1486
+ options.prerender ? 0 : options.show.delay
1503
1487
  );
1504
1488
  }
1505
1489
 
1506
1490
  // Filter and bind events
1507
1491
  this._bindEvents(showEvents, hideEvents, showTarget, hideTarget, hoverIntent, function() {
1492
+ if(!this.timers) { return FALSE; }
1508
1493
  clearTimeout(this.timers.show);
1509
1494
  });
1510
1495
 
@@ -1578,10 +1563,10 @@ PROTOTYPE._assignEvents = function() {
1578
1563
  // Check if the tooltip hides when inactive
1579
1564
  if('number' === typeof options.hide.inactive) {
1580
1565
  // Bind inactive method to show target(s) as a custom event
1581
- this._bind(showTarget, 'qtip-'+this.id+'-inactive', inactiveMethod);
1566
+ this._bind(showTarget, 'qtip-'+this.id+'-inactive', inactiveMethod, 'inactive');
1582
1567
 
1583
1568
  // Define events which reset the 'inactive' event handler
1584
- this._bind(hideTarget.add(tooltip), QTIP.inactiveEvents, inactiveMethod, '-inactive');
1569
+ this._bind(hideTarget.add(tooltip), QTIP.inactiveEvents, inactiveMethod);
1585
1570
  }
1586
1571
 
1587
1572
  // Filter and bind events
@@ -1613,6 +1598,7 @@ PROTOTYPE._assignEvents = function() {
1613
1598
  if(options.hide.event) {
1614
1599
  // Track if we're on the target or not
1615
1600
  this._bind(showTarget, ['mouseenter', 'mouseleave'], function(event) {
1601
+ if(!this.cache) {return FALSE; }
1616
1602
  this.cache.onTarget = event.type === 'mouseenter';
1617
1603
  });
1618
1604
  }
@@ -1640,22 +1626,68 @@ PROTOTYPE._assignEvents = function() {
1640
1626
 
1641
1627
  // Un-assignment method
1642
1628
  PROTOTYPE._unassignEvents = function() {
1643
- var targets = [
1644
- this.options.show.target[0],
1645
- this.options.hide.target[0],
1646
- this.rendered && this.tooltip[0],
1647
- this.options.position.container[0],
1648
- this.options.position.viewport[0],
1649
- this.options.position.container.closest('html')[0], // unfocus
1650
- window,
1651
- document
1652
- ];
1653
-
1654
- this._unbind($([]).pushStack( $.grep(targets, function(i) {
1655
- return typeof i === 'object';
1656
- })));
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) {
1641
+ return typeof i === 'object';
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());
1650
+ }
1651
+
1652
+ // Unbind the events
1653
+ this._unbind(targets)
1654
+ ._unbind(targets, 'destroy')
1655
+ ._unbind(targets, 'inactive');
1657
1656
  };
1658
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
+ });
1659
1691
  ;// Initialization method
1660
1692
  function init(elem, id, opts) {
1661
1693
  var obj, posOptions, attr, config, title,
@@ -1736,11 +1768,6 @@ function init(elem, id, opts) {
1736
1768
  obj = new QTip(elem, config, id, !!attr);
1737
1769
  elem.data(NAMESPACE, obj);
1738
1770
 
1739
- // Catch remove/removeqtip events on target element to destroy redundant tooltip
1740
- elem.one('remove.qtip-'+id+' removeqtip.qtip-'+id, function() {
1741
- var api; if((api = $(this).data(NAMESPACE))) { api.destroy(true); }
1742
- });
1743
-
1744
1771
  return obj;
1745
1772
  }
1746
1773
 
@@ -1881,16 +1908,15 @@ if(!$.ui) {
1881
1908
  $.cleanData = function( elems ) {
1882
1909
  for(var i = 0, elem; (elem = $( elems[i] )).length; i++) {
1883
1910
  if(elem.attr(ATTR_HAS)) {
1884
- try { elem.triggerHandler('removeqtip'); }
1911
+ try { elem.triggerHandler('removeqtip'); }
1885
1912
  catch( e ) {}
1886
1913
  }
1887
1914
  }
1888
1915
  $['cleanData'+replaceSuffix].apply(this, arguments);
1889
1916
  };
1890
1917
  }
1891
-
1892
1918
  ;// qTip version
1893
- QTIP.version = '2.2.0';
1919
+ QTIP.version = '2.2.1';
1894
1920
 
1895
1921
  // Base ID for all qTips
1896
1922
  QTIP.nextid = 0;
@@ -1971,8 +1997,7 @@ QTIP.defaults = {
1971
1997
  blur: NULL
1972
1998
  }
1973
1999
  };
1974
-
1975
- ;var TIP,
2000
+ ;var TIP,
1976
2001
 
1977
2002
  // .bind()/.on() namespace
1978
2003
  TIPNS = '.qtip-tip',
@@ -2034,7 +2059,7 @@ else {
2034
2059
  var PIXEL_RATIO = window.devicePixelRatio || 1,
2035
2060
  BACKING_STORE_RATIO = (function() {
2036
2061
  var context = document.createElement('canvas').getContext('2d');
2037
- return context.backingStorePixelRatio || context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio ||
2062
+ return context.backingStorePixelRatio || context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio ||
2038
2063
  context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || 1;
2039
2064
  }()),
2040
2065
  SCALE = PIXEL_RATIO / BACKING_STORE_RATIO;
@@ -2133,7 +2158,7 @@ $.extend(Tip.prototype, {
2133
2158
  prop = BORDER + camel(corner.y) + camel(corner.x) + 'Radius';
2134
2159
 
2135
2160
  return BROWSER.ie < 9 ? 0 :
2136
- intCss(this._useTitle(corner) && elements.titlebar || elements.content, prop) ||
2161
+ intCss(this._useTitle(corner) && elements.titlebar || elements.content, prop) ||
2137
2162
  intCss(elements.tooltip, prop) || 0;
2138
2163
  },
2139
2164
 
@@ -2150,11 +2175,11 @@ $.extend(Tip.prototype, {
2150
2175
  css = this._invalidColour, color = [];
2151
2176
 
2152
2177
  // Attempt to detect the background colour from various elements, left-to-right precedance
2153
- color[0] = css(tip, BG_COLOR) || css(colorElem, BG_COLOR) || css(elements.content, BG_COLOR) ||
2178
+ color[0] = css(tip, BG_COLOR) || css(colorElem, BG_COLOR) || css(elements.content, BG_COLOR) ||
2154
2179
  css(elements.tooltip, BG_COLOR) || tip.css(BG_COLOR);
2155
2180
 
2156
2181
  // Attempt to detect the correct border side colour from various elements, left-to-right precedance
2157
- color[1] = css(tip, borderSide, COLOR) || css(colorElem, borderSide, COLOR) ||
2182
+ color[1] = css(tip, borderSide, COLOR) || css(colorElem, borderSide, COLOR) ||
2158
2183
  css(elements.content, borderSide, COLOR) || css(elements.tooltip, borderSide, COLOR) || elements.tooltip.css(borderSide);
2159
2184
 
2160
2185
  // Reset background and border colours
@@ -2226,7 +2251,7 @@ $.extend(Tip.prototype, {
2226
2251
  create: function() {
2227
2252
  // Determine tip corner
2228
2253
  var c = this.corner = (HASCANVAS || BROWSER.ie) && this._parseCorner(this.options.corner);
2229
-
2254
+
2230
2255
  // If we have a tip corner...
2231
2256
  if( (this.enabled = !!this.corner && this.corner.abbrev() !== 'c') ) {
2232
2257
  // Cache it
@@ -2324,7 +2349,7 @@ $.extend(Tip.prototype, {
2324
2349
  context = inner[0].getContext('2d');
2325
2350
  context.restore(); context.save();
2326
2351
  context.clearRect(0,0,6000,6000);
2327
-
2352
+
2328
2353
  // Calculate coordinates
2329
2354
  coords = this._calculateTip(mimic, curSize, SCALE);
2330
2355
  bigCoords = this._calculateTip(mimic, this.size, SCALE);
@@ -2466,7 +2491,7 @@ $.extend(Tip.prototype, {
2466
2491
  newCorner.precedance = newCorner.precedance === X ? Y : X;
2467
2492
  }
2468
2493
  else if(direction !== SHIFT && adjust[side]){
2469
- newCorner[precedance] = newCorner[precedance] === CENTER ?
2494
+ newCorner[precedance] = newCorner[precedance] === CENTER ?
2470
2495
  (adjust[side] > 0 ? side : opposite) : (newCorner[precedance] === side ? opposite : side);
2471
2496
  }
2472
2497
  }
@@ -2483,7 +2508,7 @@ $.extend(Tip.prototype, {
2483
2508
  pos[side] -= adjust[side];
2484
2509
  shift[side] = FALSE;
2485
2510
  }
2486
-
2511
+
2487
2512
  css[ offset[opposite] !== undefined ? opposite : side ] = shift[xy];
2488
2513
  }
2489
2514
  }
@@ -2495,7 +2520,7 @@ $.extend(Tip.prototype, {
2495
2520
  shiftflip(vertical, Y, X, TOP, BOTTOM);
2496
2521
 
2497
2522
  // Update and redraw the tip if needed (check cached details of last drawn tip)
2498
- if(newCorner.string() !== cache.corner.string() && (cache.cornerTop !== adjust.top || cache.cornerLeft !== adjust.left)) {
2523
+ if(newCorner.string() !== cache.corner.string() || cache.cornerTop !== adjust.top || cache.cornerLeft !== adjust.left) {
2499
2524
  this.update(newCorner, FALSE);
2500
2525
  }
2501
2526
  }
@@ -2522,9 +2547,9 @@ $.extend(Tip.prototype, {
2522
2547
  );
2523
2548
 
2524
2549
  // Adjust position to accomodate tip dimensions
2525
- pos.left -= offset.left.charAt ? offset.user :
2550
+ pos.left -= offset.left.charAt ? offset.user :
2526
2551
  horizontal !== SHIFT || shift.top || !shift.left && !shift.top ? offset.left + this.border : 0;
2527
- pos.top -= offset.top.charAt ? offset.user :
2552
+ pos.top -= offset.top.charAt ? offset.user :
2528
2553
  vertical !== SHIFT || shift.left || !shift.left && !shift.top ? offset.top + this.border : 0;
2529
2554
 
2530
2555
  // Cache details
@@ -2565,7 +2590,7 @@ CHECKS.tip = {
2565
2590
  '^position.my|style.tip.(corner|mimic|border)$': function() {
2566
2591
  // Make sure a tip can be drawn
2567
2592
  this.create();
2568
-
2593
+
2569
2594
  // Reposition the tooltip
2570
2595
  this.qtip.reposition();
2571
2596
  },
@@ -2595,7 +2620,6 @@ $.extend(TRUE, QTIP.defaults, {
2595
2620
  }
2596
2621
  }
2597
2622
  });
2598
-
2599
2623
  ;var MODAL, OVERLAY,
2600
2624
  MODALCLASS = 'qtip-modal',
2601
2625
  MODALSELECTOR = '.'+MODALCLASS;
@@ -2628,8 +2652,8 @@ OVERLAY = function()
2628
2652
  }
2629
2653
  return (/input|select|textarea|button|object/.test( nodeName ) ?
2630
2654
  !element.disabled :
2631
- 'a' === nodeName ?
2632
- element.href || isTabIndexNotNaN :
2655
+ 'a' === nodeName ?
2656
+ element.href || isTabIndexNotNaN :
2633
2657
  isTabIndexNotNaN
2634
2658
  );
2635
2659
  }
@@ -2779,7 +2803,7 @@ OVERLAY = function()
2779
2803
 
2780
2804
  return self;
2781
2805
  }
2782
- });
2806
+ });
2783
2807
 
2784
2808
  self.init();
2785
2809
  };
@@ -2804,7 +2828,7 @@ $.extend(Modal.prototype, {
2804
2828
 
2805
2829
  // Add unique attribute so we can grab modal tooltips easily via a SELECTOR, and set z-index
2806
2830
  tooltip.addClass(MODALCLASS).css('z-index', QTIP.modal_zindex + $(MODALSELECTOR).length);
2807
-
2831
+
2808
2832
  // Apply our show/hide/focus modal events
2809
2833
  qtip._bind(tooltip, ['tooltipshow', 'tooltiphide'], function(event, api, duration) {
2810
2834
  var oEvent = event.originalEvent;
@@ -2890,7 +2914,7 @@ MODAL = PLUGINS.modal = function(api) {
2890
2914
 
2891
2915
  // Setup sanitiztion rules
2892
2916
  MODAL.sanitize = function(opts) {
2893
- if(opts.show) {
2917
+ if(opts.show) {
2894
2918
  if(typeof opts.show.modal !== 'object') { opts.show.modal = { on: !!opts.show.modal }; }
2895
2919
  else if(typeof opts.show.modal.on === 'undefined') { opts.show.modal.on = TRUE; }
2896
2920
  }
@@ -2908,7 +2932,7 @@ CHECKS.modal = {
2908
2932
  // Initialise
2909
2933
  this.destroy();
2910
2934
  this.init();
2911
-
2935
+
2912
2936
  // Show the modal if not visible already and tooltip is visible
2913
2937
  this.qtip.elems.overlay.toggle(
2914
2938
  this.qtip.tooltip[0].offsetWidth > 0
@@ -2942,7 +2966,7 @@ $.extend(TRUE, QTIP.defaults, {
2942
2966
  container = posOptions.container,
2943
2967
  cache = api.cache,
2944
2968
  adjusted = { left: 0, top: 0 },
2945
- fixed, newMy, newClass, containerOffset, containerStatic,
2969
+ fixed, newMy, containerOffset, containerStatic,
2946
2970
  viewportWidth, viewportHeight, viewportScroll, viewportOffset;
2947
2971
 
2948
2972
  // If viewport is not a jQuery element, or it's the window/document, or no adjustment method is used... return
@@ -3029,14 +3053,10 @@ $.extend(TRUE, QTIP.defaults, {
3029
3053
  // Adjust position based onviewport and adjustment options
3030
3054
  adjusted = {
3031
3055
  left: methodX !== 'none' ? calculate( X, Y, methodX, adjust.x, LEFT, RIGHT, WIDTH, targetWidth, elemWidth ) : 0,
3032
- top: methodY !== 'none' ? calculate( Y, X, methodY, adjust.y, TOP, BOTTOM, HEIGHT, targetHeight, elemHeight ) : 0
3056
+ top: methodY !== 'none' ? calculate( Y, X, methodY, adjust.y, TOP, BOTTOM, HEIGHT, targetHeight, elemHeight ) : 0,
3057
+ my: newMy
3033
3058
  };
3034
3059
 
3035
- // Set tooltip position class if it's changed
3036
- if(newMy && cache.lastClass !== (newClass = NAMESPACE + '-pos-' + newMy.abbrev())) {
3037
- tooltip.removeClass(api.cache.lastClass).addClass( (api.cache.lastClass = newClass) );
3038
- }
3039
-
3040
3060
  return adjusted;
3041
3061
  };
3042
3062
  ;PLUGINS.polys = {
@@ -3131,8 +3151,8 @@ $.extend(TRUE, QTIP.defaults, {
3131
3151
  },
3132
3152
 
3133
3153
  _angles: {
3134
- tc: 3 / 2, tr: 7 / 4, tl: 5 / 4,
3135
- bc: 1 / 2, br: 1 / 4, bl: 3 / 4,
3154
+ tc: 3 / 2, tr: 7 / 4, tl: 5 / 4,
3155
+ bc: 1 / 2, br: 1 / 4, bl: 3 / 4,
3136
3156
  rc: 2, lc: 1, c: 0
3137
3157
  },
3138
3158
  ellipse: function(cx, cy, rx, ry, corner) {
@@ -3153,15 +3173,15 @@ $.extend(TRUE, QTIP.defaults, {
3153
3173
  circle: function(cx, cy, r, corner) {
3154
3174
  return PLUGINS.polys.ellipse(cx, cy, r, r, corner);
3155
3175
  }
3156
- };;PLUGINS.svg = function(api, svg, corner)
3176
+ };
3177
+ ;PLUGINS.svg = function(api, svg, corner)
3157
3178
  {
3158
3179
  var doc = $(document),
3159
3180
  elem = svg[0],
3160
3181
  root = $(elem.ownerSVGElement),
3161
- xScale = 1, yScale = 1,
3162
- complex = true,
3163
- rootWidth, rootHeight,
3164
- mtx, transformed, viewBox,
3182
+ ownerDocument = elem.ownerDocument,
3183
+ strokeWidth2 = (parseInt(svg.css('stroke-width'), 10) || 0) / 2,
3184
+ frameOffset, mtx, transformed, viewBox,
3165
3185
  len, next, i, points,
3166
3186
  result, position, dimensions;
3167
3187
 
@@ -3169,17 +3189,6 @@ $.extend(TRUE, QTIP.defaults, {
3169
3189
  while(!elem.getBBox) { elem = elem.parentNode; }
3170
3190
  if(!elem.getBBox || !elem.parentNode) { return FALSE; }
3171
3191
 
3172
- // Determine dimensions where possible
3173
- rootWidth = root.attr('width') || root.width() || parseInt(root.css('width'), 10);
3174
- rootHeight = root.attr('height') || root.height() || parseInt(root.css('height'), 10);
3175
-
3176
- // Add stroke characteristics to scaling
3177
- var strokeWidth2 = (parseInt(svg.css('stroke-width'), 10) || 0) / 2;
3178
- if(strokeWidth2) {
3179
- xScale += strokeWidth2 / rootWidth;
3180
- yScale += strokeWidth2 / rootHeight;
3181
- }
3182
-
3183
3192
  // Determine which shape calculation to use
3184
3193
  switch(elem.nodeName) {
3185
3194
  case 'ellipse':
@@ -3197,7 +3206,7 @@ $.extend(TRUE, QTIP.defaults, {
3197
3206
  case 'polygon':
3198
3207
  case 'polyline':
3199
3208
  // Determine points object (line has none, so mimic using array)
3200
- points = elem.points || [
3209
+ points = elem.points || [
3201
3210
  { x: elem.x1.baseVal.value, y: elem.y1.baseVal.value },
3202
3211
  { x: elem.x2.baseVal.value, y: elem.y2.baseVal.value }
3203
3212
  ];
@@ -3212,15 +3221,15 @@ $.extend(TRUE, QTIP.defaults, {
3212
3221
 
3213
3222
  // Unknown shape or rectangle? Use bounding box
3214
3223
  default:
3215
- result = elem.getBoundingClientRect();
3224
+ result = elem.getBBox();
3216
3225
  result = {
3217
- width: result.width, height: result.height,
3226
+ width: result.width,
3227
+ height: result.height,
3218
3228
  position: {
3219
- left: result.left,
3220
- top: result.top
3229
+ left: result.x,
3230
+ top: result.y
3221
3231
  }
3222
3232
  };
3223
- complex = false;
3224
3233
  break;
3225
3234
  }
3226
3235
 
@@ -3228,37 +3237,39 @@ $.extend(TRUE, QTIP.defaults, {
3228
3237
  position = result.position;
3229
3238
  root = root[0];
3230
3239
 
3231
- // If the shape was complex (i.e. not using bounding box calculations)
3232
- if(complex) {
3233
- // Convert position into a pixel value
3234
- if(root.createSVGPoint) {
3235
- mtx = elem.getScreenCTM();
3236
- points = root.createSVGPoint();
3240
+ // Convert position into a pixel value
3241
+ if(root.createSVGPoint) {
3242
+ mtx = elem.getScreenCTM();
3243
+ points = root.createSVGPoint();
3237
3244
 
3238
- points.x = position.left;
3239
- points.y = position.top;
3240
- transformed = points.matrixTransform( mtx );
3241
- position.left = transformed.x;
3242
- position.top = transformed.y;
3243
- }
3245
+ points.x = position.left;
3246
+ points.y = position.top;
3247
+ transformed = points.matrixTransform( mtx );
3248
+ position.left = transformed.x;
3249
+ position.top = transformed.y;
3250
+ }
3244
3251
 
3245
- // Calculate viewBox characteristics
3246
- if(root.viewBox && (viewBox = root.viewBox.baseVal) && viewBox.width && viewBox.height) {
3247
- xScale *= rootWidth / viewBox.width;
3248
- yScale *= rootHeight / viewBox.height;
3252
+ // Check the element is not in a child document, and if so, adjust for frame elements offset
3253
+ if(ownerDocument !== document && api.position.target !== 'mouse') {
3254
+ frameOffset = $((ownerDocument.defaultView || ownerDocument.parentWindow).frameElement).offset();
3255
+ if(frameOffset) {
3256
+ position.left += frameOffset.left;
3257
+ position.top += frameOffset.top;
3249
3258
  }
3250
3259
  }
3251
3260
 
3252
- // Adjust by scroll offset
3253
- position.left += doc.scrollLeft();
3254
- position.top += doc.scrollTop();
3261
+ // Adjust by scroll offset of owner document
3262
+ ownerDocument = $(ownerDocument);
3263
+ position.left += ownerDocument.scrollLeft();
3264
+ position.top += ownerDocument.scrollTop();
3255
3265
 
3256
3266
  return result;
3257
- };;PLUGINS.imagemap = function(api, area, corner, adjustMethod)
3267
+ };
3268
+ ;PLUGINS.imagemap = function(api, area, corner, adjustMethod)
3258
3269
  {
3259
3270
  if(!area.jquery) { area = $(area); }
3260
3271
 
3261
- var shape = area.attr('shape').toLowerCase().replace('poly', 'polygon'),
3272
+ var shape = (area.attr('shape') || 'rect').toLowerCase().replace('poly', 'polygon'),
3262
3273
  image = $('img[usemap="#'+area.parent('map').attr('name')+'"]'),
3263
3274
  coordsString = $.trim(area.attr('coords')),
3264
3275
  coordsArray = coordsString.replace(/,$/, '').split(','),
@@ -3296,9 +3307,10 @@ $.extend(TRUE, QTIP.defaults, {
3296
3307
  result.position.top += imageOffset.top;
3297
3308
 
3298
3309
  return result;
3299
- };;var IE6,
3310
+ };
3311
+ ;var IE6,
3300
3312
 
3301
- /*
3313
+ /*
3302
3314
  * BGIFrame adaption (http://plugins.jquery.com/project/bgiframe)
3303
3315
  * Special thanks to Brandon Aaron
3304
3316
  */
@@ -3431,10 +3443,9 @@ IE6 = PLUGINS.ie6 = function(api) {
3431
3443
  IE6.initialize = 'render';
3432
3444
 
3433
3445
  CHECKS.ie6 = {
3434
- '^content|style$': function() {
3446
+ '^content|style$': function() {
3435
3447
  this.redraw();
3436
3448
  }
3437
- };;}));
3438
- }( window, document ));
3439
-
3440
-
3449
+ };
3450
+ ;}));
3451
+ }( window, document ));