jquery-qtip2-wrapper-rails 2.2.0 → 2.2.1

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 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 ));