jquery-qtip2-rails 0.0.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.
@@ -0,0 +1,2 @@
1
+
2
+ }));
@@ -0,0 +1,43 @@
1
+ PLUGINS.svg = function(svg, corner)
2
+ {
3
+ var doc = $(document),
4
+ elem = svg[0],
5
+ result = {
6
+ width: 0, height: 0,
7
+ offset: { top: 1e10, left: 1e10 }
8
+ },
9
+ box, mtx, root, point, tPoint;
10
+
11
+ if (elem.getBBox && elem.parentNode) {
12
+ box = elem.getBBox();
13
+ mtx = elem.getScreenCTM();
14
+ root = elem.farthestViewportElement || elem;
15
+
16
+ // Return if no method is found
17
+ if(!root.createSVGPoint) { return result; }
18
+
19
+ // Create our point var
20
+ point = root.createSVGPoint();
21
+
22
+ // Adjust top and left
23
+ point.x = box.x;
24
+ point.y = box.y;
25
+ tPoint = point.matrixTransform(mtx);
26
+ result.offset.left = tPoint.x;
27
+ result.offset.top = tPoint.y;
28
+
29
+ // Adjust width and height
30
+ point.x += box.width;
31
+ point.y += box.height;
32
+ tPoint = point.matrixTransform(mtx);
33
+ result.width = tPoint.x - result.offset.left;
34
+ result.height = tPoint.y - result.offset.top;
35
+
36
+ // Adjust by scroll offset
37
+ result.offset.left += doc.scrollLeft();
38
+ result.offset.top += doc.scrollTop();
39
+ }
40
+
41
+ return result;
42
+ };
43
+
@@ -0,0 +1,610 @@
1
+ // Tip coordinates calculator
2
+ function calculateTip(corner, width, height)
3
+ {
4
+ var width2 = Math.ceil(width / 2), height2 = Math.ceil(height / 2),
5
+
6
+ // Define tip coordinates in terms of height and width values
7
+ tips = {
8
+ bottomright: [[0,0], [width,height], [width,0]],
9
+ bottomleft: [[0,0], [width,0], [0,height]],
10
+ topright: [[0,height], [width,0], [width,height]],
11
+ topleft: [[0,0], [0,height], [width,height]],
12
+ topcenter: [[0,height], [width2,0], [width,height]],
13
+ bottomcenter: [[0,0], [width,0], [width2,height]],
14
+ rightcenter: [[0,0], [width,height2], [0,height]],
15
+ leftcenter: [[width,0], [width,height], [0,height2]]
16
+ };
17
+
18
+ // Set common side shapes
19
+ tips.lefttop = tips.bottomright; tips.righttop = tips.bottomleft;
20
+ tips.leftbottom = tips.topright; tips.rightbottom = tips.topleft;
21
+
22
+ return tips[ corner.string() ];
23
+ }
24
+
25
+
26
+ function Tip(qTip, command)
27
+ {
28
+ var self = this,
29
+ opts = qTip.options.style.tip,
30
+ elems = qTip.elements,
31
+ tooltip = elems.tooltip,
32
+ cache = { top: 0, left: 0 },
33
+ size = {
34
+ width: opts.width,
35
+ height: opts.height
36
+ },
37
+ color = { },
38
+ border = opts.border || 0,
39
+ namespace = '.qtip-tip',
40
+ hasCanvas = !!($('<canvas />')[0] || {}).getContext;
41
+
42
+ self.corner = NULL;
43
+ self.mimic = NULL;
44
+ self.border = border;
45
+ self.offset = opts.offset;
46
+ self.size = size;
47
+
48
+ // Add new option checks for the plugin
49
+ qTip.checks.tip = {
50
+ '^position.my|style.tip.(corner|mimic|border)$': function() {
51
+ // Make sure a tip can be drawn
52
+ if(!self.init()) {
53
+ self.destroy();
54
+ }
55
+
56
+ // Reposition the tooltip
57
+ qTip.reposition();
58
+ },
59
+ '^style.tip.(height|width)$': function() {
60
+ // Re-set dimensions and redraw the tip
61
+ size = {
62
+ width: opts.width,
63
+ height: opts.height
64
+ };
65
+ self.create();
66
+ self.update();
67
+
68
+ // Reposition the tooltip
69
+ qTip.reposition();
70
+ },
71
+ '^content.title.text|style.(classes|widget)$': function() {
72
+ if(elems.tip && elems.tip.length) {
73
+ self.update();
74
+ }
75
+ }
76
+ };
77
+
78
+ function swapDimensions() {
79
+ var temp = size.width;
80
+ size.width = size.height;
81
+ size.height = temp;
82
+ }
83
+
84
+ function resetDimensions() {
85
+ size.width = opts.width;
86
+ size.height = opts.height;
87
+ }
88
+
89
+ function reposition(event, api, pos, viewport) {
90
+ if(!elems.tip) { return; }
91
+
92
+ var newCorner = self.corner.clone(),
93
+ adjust = pos.adjusted,
94
+ method = qTip.options.position.adjust.method.split(' '),
95
+ horizontal = method[0],
96
+ vertical = method[1] || method[0],
97
+ shift = { left: FALSE, top: FALSE, x: 0, y: 0 },
98
+ offset, css = {}, props;
99
+
100
+ // Make sure our tip position isn't fixed e.g. doesn't adjust with viewport
101
+ if(self.corner.fixed !== TRUE) {
102
+ // Horizontal - Shift or flip method
103
+ if(horizontal === 'shift' && newCorner.precedance === 'x' && adjust.left && newCorner.y !== 'center') {
104
+ newCorner.precedance = newCorner.precedance === 'x' ? 'y' : 'x';
105
+ }
106
+ else if(horizontal !== 'shift' && adjust.left){
107
+ newCorner.x = newCorner.x === 'center' ? (adjust.left > 0 ? 'left' : 'right') : (newCorner.x === 'left' ? 'right' : 'left');
108
+ }
109
+
110
+ // Vertical - Shift or flip method
111
+ if(vertical === 'shift' && newCorner.precedance === 'y' && adjust.top && newCorner.x !== 'center') {
112
+ newCorner.precedance = newCorner.precedance === 'y' ? 'x' : 'y';
113
+ }
114
+ else if(vertical !== 'shift' && adjust.top) {
115
+ newCorner.y = newCorner.y === 'center' ? (adjust.top > 0 ? 'top' : 'bottom') : (newCorner.y === 'top' ? 'bottom' : 'top');
116
+ }
117
+
118
+ // Update and redraw the tip if needed (check cached details of last drawn tip)
119
+ if(newCorner.string() !== cache.corner.string() && (cache.top !== adjust.top || cache.left !== adjust.left)) {
120
+ self.update(newCorner, FALSE);
121
+ }
122
+ }
123
+
124
+ // Setup tip offset properties
125
+ offset = self.position(newCorner, adjust);
126
+ if(offset.right !== undefined) { offset.left = -offset.right; }
127
+ if(offset.bottom !== undefined) { offset.top = -offset.bottom; }
128
+ offset.user = Math.max(0, opts.offset);
129
+
130
+ // Viewport "shift" specific adjustments
131
+ if(shift.left = (horizontal === 'shift' && !!adjust.left)) {
132
+ if(newCorner.x === 'center') {
133
+ css['margin-left'] = shift.x = offset['margin-left'] - adjust.left;
134
+ }
135
+ else {
136
+ props = offset.right !== undefined ?
137
+ [ adjust.left, -offset.left ] : [ -adjust.left, offset.left ];
138
+
139
+ if( (shift.x = Math.max(props[0], props[1])) > props[0] ) {
140
+ pos.left -= adjust.left;
141
+ shift.left = FALSE;
142
+ }
143
+
144
+ css[ offset.right !== undefined ? 'right' : 'left' ] = shift.x;
145
+ }
146
+ }
147
+ if(shift.top = (vertical === 'shift' && !!adjust.top)) {
148
+ if(newCorner.y === 'center') {
149
+ css['margin-top'] = shift.y = offset['margin-top'] - adjust.top;
150
+ }
151
+ else {
152
+ props = offset.bottom !== undefined ?
153
+ [ adjust.top, -offset.top ] : [ -adjust.top, offset.top ];
154
+
155
+ if( (shift.y = Math.max(props[0], props[1])) > props[0] ) {
156
+ pos.top -= adjust.top;
157
+ shift.top = FALSE;
158
+ }
159
+
160
+ css[ offset.bottom !== undefined ? 'bottom' : 'top' ] = shift.y;
161
+ }
162
+ }
163
+
164
+ /*
165
+ * If the tip is adjusted in both dimensions, or in a
166
+ * direction that would cause it to be anywhere but the
167
+ * outer border, hide it!
168
+ */
169
+ elems.tip.css(css).toggle(
170
+ !((shift.x && shift.y) || (newCorner.x === 'center' && shift.y) || (newCorner.y === 'center' && shift.x))
171
+ );
172
+
173
+ // Adjust position to accomodate tip dimensions
174
+ pos.left -= offset.left.charAt ? offset.user : horizontal !== 'shift' || shift.top || !shift.left && !shift.top ? offset.left : 0;
175
+ pos.top -= offset.top.charAt ? offset.user : vertical !== 'shift' || shift.left || !shift.left && !shift.top ? offset.top : 0;
176
+
177
+ // Cache details
178
+ cache.left = adjust.left; cache.top = adjust.top;
179
+ cache.corner = newCorner.clone();
180
+ }
181
+
182
+ /* border width calculator */
183
+ function borderWidth(corner, side, backup) {
184
+ side = !side ? corner[corner.precedance] : side;
185
+
186
+ var isFluid = tooltip.hasClass(fluidClass),
187
+ isTitleTop = elems.titlebar && corner.y === 'top',
188
+ elem = isTitleTop ? elems.titlebar : elems.content,
189
+ css = 'border-' + side + '-width',
190
+ val;
191
+
192
+ // Grab the border-width value (add fluid class if needed)
193
+ tooltip.addClass(fluidClass);
194
+ val = parseInt(elem.css(css), 10);
195
+ val = (backup ? val || parseInt(tooltip.css(css), 10) : val) || 0;
196
+ tooltip.toggleClass(fluidClass, isFluid);
197
+
198
+ return val;
199
+ }
200
+
201
+ function borderRadius(corner) {
202
+ var isTitleTop = elems.titlebar && corner.y === 'top',
203
+ elem = isTitleTop ? elems.titlebar : elems.content,
204
+ moz = $.browser.mozilla,
205
+ prefix = moz ? '-moz-' : $.browser.webkit ? '-webkit-' : '',
206
+ side = corner.y + (moz ? '' : '-') + corner.x,
207
+ css = prefix + (moz ? 'border-radius-' + side : 'border-' + side + '-radius');
208
+
209
+ return parseInt(elem.css(css), 10) || parseInt(tooltip.css(css), 10) || 0;
210
+ }
211
+
212
+ function calculateSize(corner) {
213
+ var y = corner.precedance === 'y',
214
+ width = size [ y ? 'width' : 'height' ],
215
+ height = size [ y ? 'height' : 'width' ],
216
+ isCenter = corner.string().indexOf('center') > -1,
217
+ base = width * (isCenter ? 0.5 : 1),
218
+ pow = Math.pow,
219
+ round = Math.round,
220
+ bigHyp, ratio, result,
221
+
222
+ smallHyp = Math.sqrt( pow(base, 2) + pow(height, 2) ),
223
+
224
+ hyp = [
225
+ (border / base) * smallHyp, (border / height) * smallHyp
226
+ ];
227
+ hyp[2] = Math.sqrt( pow(hyp[0], 2) - pow(border, 2) );
228
+ hyp[3] = Math.sqrt( pow(hyp[1], 2) - pow(border, 2) );
229
+
230
+ bigHyp = smallHyp + hyp[2] + hyp[3] + (isCenter ? 0 : hyp[0]);
231
+ ratio = bigHyp / smallHyp;
232
+
233
+ result = [ round(ratio * height), round(ratio * width) ];
234
+ return { height: result[ y ? 0 : 1 ], width: result[ y ? 1 : 0 ] };
235
+ }
236
+
237
+ $.extend(self, {
238
+ init: function()
239
+ {
240
+ var enabled = self.detectCorner() && (hasCanvas || $.browser.msie);
241
+
242
+ // Determine tip corner and type
243
+ if(enabled) {
244
+ // Create a new tip and draw it
245
+ self.create();
246
+ self.update();
247
+
248
+ // Bind update events
249
+ tooltip.unbind(namespace).bind('tooltipmove'+namespace, reposition);
250
+ }
251
+
252
+ return enabled;
253
+ },
254
+
255
+ detectCorner: function()
256
+ {
257
+ var corner = opts.corner,
258
+ posOptions = qTip.options.position,
259
+ at = posOptions.at,
260
+ my = posOptions.my.string ? posOptions.my.string() : posOptions.my;
261
+
262
+ // Detect corner and mimic properties
263
+ if(corner === FALSE || (my === FALSE && at === FALSE)) {
264
+ return FALSE;
265
+ }
266
+ else {
267
+ if(corner === TRUE) {
268
+ self.corner = new PLUGINS.Corner(my);
269
+ }
270
+ else if(!corner.string) {
271
+ self.corner = new PLUGINS.Corner(corner);
272
+ self.corner.fixed = TRUE;
273
+ }
274
+ }
275
+
276
+ // Cache it
277
+ cache.corner = new PLUGINS.Corner( self.corner.string() );
278
+
279
+ return self.corner.string() !== 'centercenter';
280
+ },
281
+
282
+ detectColours: function(actual) {
283
+ var i, fill, border,
284
+ tip = elems.tip.css('cssText', ''),
285
+ corner = actual || self.corner,
286
+ precedance = corner[ corner.precedance ],
287
+
288
+ borderSide = 'border-' + precedance + '-color',
289
+ borderSideCamel = 'border' + precedance.charAt(0) + precedance.substr(1) + 'Color',
290
+
291
+ invalid = /rgba?\(0, 0, 0(, 0)?\)|transparent|#123456/i,
292
+ backgroundColor = 'background-color',
293
+ transparent = 'transparent',
294
+ important = ' !important',
295
+
296
+ bodyBorder = $(document.body).css('color'),
297
+ contentColour = qTip.elements.content.css('color'),
298
+
299
+ useTitle = elems.titlebar && (corner.y === 'top' || (corner.y === 'center' && tip.position().top + (size.height / 2) + opts.offset < elems.titlebar.outerHeight(1))),
300
+ colorElem = useTitle ? elems.titlebar : elems.content;
301
+
302
+ // Apply the fluid class so we can see our CSS values properly
303
+ tooltip.addClass(fluidClass);
304
+
305
+ // Detect tip colours from CSS styles
306
+ color.fill = fill = tip.css(backgroundColor);
307
+ color.border = border = tip[0].style[ borderSideCamel ] || tip.css(borderSide) || tooltip.css(borderSide);
308
+
309
+ // Make sure colours are valid
310
+ if(!fill || invalid.test(fill)) {
311
+ color.fill = colorElem.css(backgroundColor) || transparent;
312
+ if(invalid.test(color.fill)) {
313
+ color.fill = tooltip.css(backgroundColor) || fill;
314
+ }
315
+ }
316
+ if(!border || invalid.test(border) || border === bodyBorder) {
317
+ color.border = colorElem.css(borderSide) || transparent;
318
+ if(invalid.test(color.border)) {
319
+ color.border = border;
320
+ }
321
+ }
322
+
323
+ // Reset background and border colours
324
+ $('*', tip).add(tip).css('cssText', backgroundColor+':'+transparent+important+';border:0'+important+';');
325
+
326
+ // Remove fluid class
327
+ tooltip.removeClass(fluidClass);
328
+ },
329
+
330
+ create: function()
331
+ {
332
+ var width = size.width,
333
+ height = size.height,
334
+ vml;
335
+
336
+ // Remove previous tip element if present
337
+ if(elems.tip) { elems.tip.remove(); }
338
+
339
+ // Create tip element and prepend to the tooltip
340
+ elems.tip = $('<div />', { 'class': 'ui-tooltip-tip' }).css({ width: width, height: height }).prependTo(tooltip);
341
+
342
+ // Create tip drawing element(s)
343
+ if(hasCanvas) {
344
+ // save() as soon as we create the canvas element so FF2 doesn't bork on our first restore()!
345
+ $('<canvas />').appendTo(elems.tip)[0].getContext('2d').save();
346
+ }
347
+ else {
348
+ vml = '<vml:shape coordorigin="0,0" style="display:inline-block; position:absolute; behavior:url(#default#VML);"></vml:shape>';
349
+ elems.tip.html(vml + vml);
350
+
351
+ // Prevent mousing down on the tip since it causes problems with .live() handling in IE due to VML
352
+ $('*', elems.tip).bind('click mousedown', function(event) { event.stopPropagation(); });
353
+ }
354
+ },
355
+
356
+ update: function(corner, position)
357
+ {
358
+ var tip = elems.tip,
359
+ inner = tip.children(),
360
+ width = size.width,
361
+ height = size.height,
362
+ regular = 'px solid ',
363
+ transparent = 'px dashed transparent', // Dashed IE6 border-transparency hack. Awesome!
364
+ mimic = opts.mimic,
365
+ round = Math.round,
366
+ precedance, context, coords, translate, newSize;
367
+
368
+ // Re-determine tip if not already set
369
+ if(!corner) { corner = cache.corner || self.corner; }
370
+
371
+ // Use corner property if we detect an invalid mimic value
372
+ if(mimic === FALSE) { mimic = corner; }
373
+
374
+ // Otherwise inherit mimic properties from the corner object as necessary
375
+ else {
376
+ mimic = new PLUGINS.Corner(mimic);
377
+ mimic.precedance = corner.precedance;
378
+
379
+ if(mimic.x === 'inherit') { mimic.x = corner.x; }
380
+ else if(mimic.y === 'inherit') { mimic.y = corner.y; }
381
+ else if(mimic.x === mimic.y) {
382
+ mimic[ corner.precedance ] = corner[ corner.precedance ];
383
+ }
384
+ }
385
+ precedance = mimic.precedance;
386
+
387
+ // Ensure the tip width.height are relative to the tip position
388
+ if(corner.precedance === 'x') { swapDimensions(); }
389
+ else { resetDimensions(); }
390
+
391
+ // Set the tip dimensions
392
+ elems.tip.css({
393
+ width: (width = size.width),
394
+ height: (height = size.height)
395
+ });
396
+
397
+ // Update our colours
398
+ self.detectColours(corner);
399
+
400
+ // Detect border width, taking into account colours
401
+ if(color.border !== 'transparent' && color.border !== '#123456') {
402
+ // Grab border width
403
+ border = borderWidth(corner, NULL, TRUE);
404
+
405
+ // If border width isn't zero, use border color as fill (1.0 style tips)
406
+ if(opts.border === 0 && border > 0) { color.fill = color.border; }
407
+
408
+ // Set border width (use detected border width if opts.border is true)
409
+ self.border = border = opts.border !== TRUE ? opts.border : border;
410
+ }
411
+
412
+ // Border colour was invalid, set border to zero
413
+ else { self.border = border = 0; }
414
+
415
+ // Calculate coordinates
416
+ coords = calculateTip(mimic, width , height);
417
+
418
+ // Determine tip size
419
+ self.size = newSize = calculateSize(corner);
420
+ tip.css(newSize);
421
+
422
+ // Calculate tip translation
423
+ if(corner.precedance === 'y') {
424
+ translate = [
425
+ round(mimic.x === 'left' ? border : mimic.x === 'right' ? newSize.width - width - border : (newSize.width - width) / 2),
426
+ round(mimic.y === 'top' ? newSize.height - height : 0)
427
+ ];
428
+ }
429
+ else {
430
+ translate = [
431
+ round(mimic.x === 'left' ? newSize.width - width : 0),
432
+ round(mimic.y === 'top' ? border : mimic.y === 'bottom' ? newSize.height - height - border : (newSize.height - height) / 2)
433
+ ];
434
+ }
435
+
436
+ // Canvas drawing implementation
437
+ if(hasCanvas) {
438
+ // Set the canvas size using calculated size
439
+ inner.attr(newSize);
440
+
441
+ // Grab canvas context and clear/save it
442
+ context = inner[0].getContext('2d');
443
+ context.restore(); context.save();
444
+ context.clearRect(0,0,3000,3000);
445
+
446
+ // Translate origin
447
+ context.translate(translate[0], translate[1]);
448
+
449
+ // Draw the tip
450
+ context.beginPath();
451
+ context.moveTo(coords[0][0], coords[0][1]);
452
+ context.lineTo(coords[1][0], coords[1][1]);
453
+ context.lineTo(coords[2][0], coords[2][1]);
454
+ context.closePath();
455
+ context.fillStyle = color.fill;
456
+ context.strokeStyle = color.border;
457
+ context.lineWidth = border * 2;
458
+ context.lineJoin = 'miter';
459
+ context.miterLimit = 100;
460
+ if(border) { context.stroke(); }
461
+ context.fill();
462
+ }
463
+
464
+ // VML (IE Proprietary implementation)
465
+ else {
466
+ // Setup coordinates string
467
+ coords = 'm' + coords[0][0] + ',' + coords[0][1] + ' l' + coords[1][0] +
468
+ ',' + coords[1][1] + ' ' + coords[2][0] + ',' + coords[2][1] + ' xe';
469
+
470
+ // Setup VML-specific offset for pixel-perfection
471
+ translate[2] = border && /^(r|b)/i.test(corner.string()) ?
472
+ parseFloat($.browser.version, 10) === 8 ? 2 : 1 : 0;
473
+
474
+ // Set initial CSS
475
+ inner.css({
476
+ antialias: ''+(mimic.string().indexOf('center') > -1),
477
+ left: translate[0] - (translate[2] * Number(precedance === 'x')),
478
+ top: translate[1] - (translate[2] * Number(precedance === 'y')),
479
+ width: width + border,
480
+ height: height + border
481
+ })
482
+ .each(function(i) {
483
+ var $this = $(this);
484
+
485
+ // Set shape specific attributes
486
+ $this[ $this.prop ? 'prop' : 'attr' ]({
487
+ coordsize: (width+border) + ' ' + (height+border),
488
+ path: coords,
489
+ fillcolor: color.fill,
490
+ filled: !!i,
491
+ stroked: !!!i
492
+ })
493
+ .css({ display: border || i ? 'block' : 'none' });
494
+
495
+ // Check if border is enabled and add stroke element
496
+ if(!i && $this.html() === '') {
497
+ $this.html(
498
+ '<vml:stroke weight="'+(border*2)+'px" color="'+color.border+'" miterlimit="1000" joinstyle="miter" ' +
499
+ ' style="behavior:url(#default#VML); display:inline-block;" />'
500
+ );
501
+ }
502
+ });
503
+ }
504
+
505
+ // Position if needed
506
+ if(position !== FALSE) { self.position(corner); }
507
+ },
508
+
509
+ // Tip positioning method
510
+ position: function(corner)
511
+ {
512
+ var tip = elems.tip,
513
+ position = {},
514
+ userOffset = Math.max(0, opts.offset),
515
+ precedance, dimensions, corners;
516
+
517
+ // Return if tips are disabled or tip is not yet rendered
518
+ if(opts.corner === FALSE || !tip) { return FALSE; }
519
+
520
+ // Inherit corner if not provided
521
+ corner = corner || self.corner;
522
+ precedance = corner.precedance;
523
+
524
+ // Determine which tip dimension to use for adjustment
525
+ dimensions = calculateSize(corner);
526
+
527
+ // Setup corners and offset array
528
+ corners = [ corner.x, corner.y ];
529
+ if(precedance === 'x') { corners.reverse(); }
530
+
531
+ // Calculate tip position
532
+ $.each(corners, function(i, side) {
533
+ var b, br;
534
+
535
+ if(side === 'center') {
536
+ b = precedance === 'y' ? 'left' : 'top';
537
+ position[ b ] = '50%';
538
+ position['margin-' + b] = -Math.round(dimensions[ precedance === 'y' ? 'width' : 'height' ] / 2) + userOffset;
539
+ }
540
+ else {
541
+ b = borderWidth(corner, side, TRUE);
542
+ br = borderRadius(corner);
543
+
544
+ position[ side ] = i ?
545
+ border ? borderWidth(corner, side) : 0 :
546
+ userOffset + (br > b ? br : 0);
547
+ }
548
+ });
549
+
550
+ // Adjust for tip dimensions
551
+ position[ corner[precedance] ] -= dimensions[ precedance === 'x' ? 'width' : 'height' ];
552
+
553
+ // Set and return new position
554
+ tip.css({ top: '', bottom: '', left: '', right: '', margin: '' }).css(position);
555
+ return position;
556
+ },
557
+
558
+ destroy: function()
559
+ {
560
+ // Remove the tip element
561
+ if(elems.tip) { elems.tip.remove(); }
562
+ elems.tip = false;
563
+
564
+ // Unbind events
565
+ tooltip.unbind(namespace);
566
+ }
567
+ });
568
+
569
+ self.init();
570
+ }
571
+
572
+ PLUGINS.tip = function(api)
573
+ {
574
+ var self = api.plugins.tip;
575
+
576
+ return 'object' === typeof self ? self : (api.plugins.tip = new Tip(api));
577
+ };
578
+
579
+ // Initialize tip on render
580
+ PLUGINS.tip.initialize = 'render';
581
+
582
+ // Setup plugin sanitization options
583
+ PLUGINS.tip.sanitize = function(options)
584
+ {
585
+ var style = options.style, opts;
586
+ if(style && 'tip' in style) {
587
+ opts = options.style.tip;
588
+ if(typeof opts !== 'object'){ options.style.tip = { corner: opts }; }
589
+ if(!(/string|boolean/i).test(typeof opts.corner)) { opts.corner = TRUE; }
590
+ if(typeof opts.width !== 'number'){ delete opts.width; }
591
+ if(typeof opts.height !== 'number'){ delete opts.height; }
592
+ if(typeof opts.border !== 'number' && opts.border !== TRUE){ delete opts.border; }
593
+ if(typeof opts.offset !== 'number'){ delete opts.offset; }
594
+ }
595
+ };
596
+
597
+ // Extend original qTip defaults
598
+ $.extend(TRUE, QTIP.defaults, {
599
+ style: {
600
+ tip: {
601
+ corner: TRUE,
602
+ mimic: FALSE,
603
+ width: 6,
604
+ height: 6,
605
+ border: TRUE,
606
+ offset: 0
607
+ }
608
+ }
609
+ });
610
+