Changeset bde104 in indico
- Timestamp:
- 04/13/12 10:13:39 (14 months ago)
- Branches:
- master, hello-world-walkthrough, ipv6, v0.98-series, v0.98.2, v0.98.3, v0.99, 051b2622c51afb171a1dedb46a0df4fbb0cbd02e, 0da0c1403bae8e51d8229f460181c71b9e6dda72
- Children:
- 1af5639
- Parents:
- 2108190
- git-author:
- Pedro Ferreira <jose.pedro.ferreira@…> (04/05/12 11:46:00)
- git-committer:
- Pedro Ferreira <jose.pedro.ferreira@…> (04/13/12 10:13:39)
- Location:
- indico/htdocs
- Files:
-
- 2 edited
-
css/jquery.qtip.css (modified) (5 diffs)
-
js/jquery/jquery.qtip.js (modified) (70 diffs)
Legend:
- Unmodified
- Added
- Removed
-
indico/htdocs/css/jquery.qtip.css
r683050 rbde104 10 10 * http://en.wikipedia.org/wiki/GNU_General_Public_License 11 11 * 12 * Date: Fri Nov 4 13:47:48.0000000000 201112 * Date: Mon Apr 2 13:46:17.0000000000 2012 13 13 */ 14 14 … … 25 25 font-size: 10.5px; 26 26 line-height: 12px; 27 28 z-index: 15000;29 27 } 30 28 … … 41 39 padding: 5px 9px; 42 40 overflow: hidden; 43 44 border-width: 1px; 45 border-style: solid; 46 41 42 border: 1px solid #000001; 43 47 44 text-align: left; 48 45 word-wrap: break-word; … … 55 52 padding: 5px 35px 5px 10px; 56 53 overflow: hidden; 57 54 55 border: 1px solid #000001; 58 56 border-width: 1px 1px 0; 59 border-style: solid;60 57 61 58 font-weight: bold; … … 558 555 -ms-filter: none; 559 556 } 557 -
indico/htdocs/js/jquery/jquery.qtip.js
r683050 rbde104 10 10 * http://en.wikipedia.org/wiki/GNU_General_Public_License 11 11 * 12 * Date: Fri Nov 4 13:47:48.0000000000 201112 * Date: Mon Apr 2 13:46:17.0000000000 2012 13 13 */ 14 14 15 15 /*jslint browser: true, onevar: true, undef: true, nomen: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: true */ 16 /*global window: false, jQuery: false, console: false */ 17 18 19 (function($, window, undefined) { 16 /*global window: false, jQuery: false, console: false, define: false */ 17 18 // Uses AMD or browser globals to create a jQuery plugin. 19 (function(factory) { 20 if(typeof define === 'function' && define.amd) { 21 define(['jquery'], factory); 22 } 23 else { 24 factory(jQuery); 25 } 26 } 27 (function($) { 20 28 21 29 "use strict"; // Enable ECMAScript "strict" operation for this function. See more: http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/ … … 25 33 FALSE = false, 26 34 NULL = null, 35 undefined, 27 36 28 37 // Shortcut vars … … 69 78 if(!opts || 'object' !== typeof opts) { return FALSE; } 70 79 71 if( 'object' !== typeof opts.metadata) {80 if(opts.metadata === NULL || 'object' !== typeof opts.metadata) { 72 81 opts.metadata = { 73 82 type: opts.metadata … … 76 85 77 86 if('content' in opts) { 78 if( 'object' !== typeof opts.content || opts.content.jquery) {87 if(opts.content === NULL || 'object' !== typeof opts.content || opts.content.jquery) { 79 88 opts.content = { 80 89 text: opts.content … … 88 97 89 98 if('title' in opts.content) { 90 if( 'object' !== typeof opts.content.title) {99 if(opts.content.title === NULL || 'object' !== typeof opts.content.title) { 91 100 opts.content.title = { 92 101 text: opts.content.title … … 102 111 103 112 if('position' in opts) { 104 if( 'object' !== typeof opts.position) {113 if(opts.position === NULL || 'object' !== typeof opts.position) { 105 114 opts.position = { 106 115 my: opts.position, … … 111 120 112 121 if('show' in opts) { 113 if( 'object' !== typeof opts.show) {122 if(opts.show === NULL || 'object' !== typeof opts.show) { 114 123 if(opts.show.jquery) { 115 124 opts.show = { target: opts.show }; … … 122 131 123 132 if('hide' in opts) { 124 if( 'object' !== typeof opts.hide) {133 if(opts.hide === NULL || 'object' !== typeof opts.hide) { 125 134 if(opts.hide.jquery) { 126 135 opts.hide = { target: opts.hide }; … … 133 142 134 143 if('style' in opts) { 135 if( 'object' !== typeof opts.style) {144 if(opts.style === NULL || 'object' !== typeof opts.style) { 136 145 opts.style = { 137 146 classes: opts.style … … 175 184 target: $(), 176 185 disabled: FALSE, 177 attr: attr 186 attr: attr, 187 onTarget: FALSE 178 188 }; 179 189 … … 199 209 var on = options.style.widget; 200 210 201 tooltip.toggleClass(widget, on).toggleClass(defaultClass, !on);211 tooltip.toggleClass(widget, on).toggleClass(defaultClass, options.style.def && !on); 202 212 elements.content.toggleClass(widget+'-content', on); 203 213 … … 325 335 } 326 336 327 // Remove title if callback returns false 328 if(content === FALSE ) { return removeTitle(FALSE); }337 // Remove title if callback returns false or null/undefined (but not '') 338 if(content === FALSE || (!content && content !== '')) { return removeTitle(FALSE); } 329 339 330 340 // Append new content if its a DOM array and show it if hidden … … 387 397 388 398 // Find all content images without dimensions, and if no images were found, continue 389 if((images = elem.find('img :not([height]):not([width])')).length === 0) { return imageLoad(); }399 if((images = elem.find('img[src]:not([height]):not([width])')).length === 0) { return imageLoad(); } 390 400 391 401 // Apply timer to each image to poll for dimensions … … 394 404 if(srcs[elem.src] !== undefined) { return; } 395 405 396 // Keep track of how many times we poll for image dimensions.397 // If it doesn't return in a reasonable amount of time, it's better398 // to display the tooltip, rather than hold up the queue.399 var iterations = 0, maxIterations = 3;406 // Keep track of how many times we poll for image dimensions. 407 // If it doesn't return in a reasonable amount of time, it's better 408 // to display the tooltip, rather than hold up the queue. 409 var iterations = 0, maxIterations = 3; 400 410 401 411 (function timer(){ … … 403 413 if(elem.height || elem.width || (iterations > maxIterations)) { return imageLoad(elem); } 404 414 405 iterations += 1; 406 407 // Restart timer 415 // Increase iterations and restart timer 416 iterations += 1; 408 417 self.timers.img[elem.src] = setTimeout(timer, 700); 409 418 }()); … … 530 539 // Hide tooltips when leaving current window/frame (but not select/option elements) 531 540 if(options.hide.leave === 'window') { 532 targets.window.bind('mouseout' +namespace, function(event) {541 targets.window.bind('mouseout'+namespace+' blur'+namespace, function(event) { 533 542 if(/select|option/.test(event.target) && !event.relatedTarget) { self.hide(event); } 534 543 }); … … 548 557 // Hide tooltip on document mousedown if unfocus events are enabled 549 558 if(('' + options.hide.event).indexOf('unfocus') > -1) { 550 targets.body.bind('mousedown'+namespace, function(event) { 551 var $target = $(event.target), 552 enabled = !tooltip.hasClass(disabled) && tooltip.is(':visible'); 553 554 if($target[0] !== tooltip[0] && $target.parents(selector).length === 0 && $target.add(target).length > 1 && !$target.attr('disabled')) { 559 posOptions.container.closest('html').bind('mousedown'+namespace, function(event) { 560 var elem = $(event.target), 561 enabled = !tooltip.hasClass(disabled) && tooltip.is(':visible'), 562 isAncestor = elem.parents(selector).filter(tooltip[0]).length > 0; 563 564 if(elem[0] !== target[0] && elem[0] !== tooltip[0] && !isAncestor && 565 !target.has(elem[0]).length && !elem.attr('disabled') 566 ) { 555 567 self.hide(event); 556 568 } … … 621 633 // Apply a mouseleave event so we don't get problems with overlapping 622 634 if(options.hide.event) { 635 // Hide when we leave the tooltip and not onto the show target 623 636 tooltip.bind('mouseleave'+namespace, function(event) { 624 637 if((event.relatedTarget || event.target) !== targets.show[0]) { self.hide(event); } 625 638 }); 639 640 // Track if we're on the target or not 641 elements.target.bind('mouseenter'+namespace+' mouseleave'+namespace, function(event) { 642 cache.onTarget = event.type === 'mouseenter'; 643 }); 626 644 } 627 645 … … 629 647 targets.document.bind('mousemove'+namespace, function(event) { 630 648 // Update the tooltip position only if the tooltip is visible and adjustment is enabled 631 if( !tooltip.hasClass(disabled) && tooltip.is(':visible')) {649 if(cache.onTarget && !tooltip.hasClass(disabled) && tooltip.is(':visible')) { 632 650 self.reposition(event || MOUSE); 633 651 } … … 753 771 tooltip = elements.tooltip = $('<div/>', { 754 772 'id': tooltipID, 755 'class': uitooltip + ' qtip ui-helper-reset ' + defaultClass + ' ' + options.style.classes + ' '+ uitooltip + '-pos-' + options.position.my.abbrev iation(),773 'class': uitooltip + ' qtip ui-helper-reset ' + defaultClass + ' ' + options.style.classes + ' '+ uitooltip + '-pos-' + options.position.my.abbrev(), 756 774 'width': options.style.width || '', 757 775 'height': options.style.height || '', … … 829 847 // Show tooltip if needed 830 848 if(options.show.ready || show) { 831 self.toggle(TRUE, cache.event );849 self.toggle(TRUE, cache.event, FALSE); 832 850 } 833 851 … … 937 955 opts = options[type], 938 956 visible = tooltip.is(':visible'), 939 sameTarget = !event || options[type].target.length < 2 || cache.target[0] === event.target, 957 sameTarget = !event || opts.target.length < 2 || cache.target[0] === event.target, 958 eventAsTarget = event && opts.target.add(event.target).length !== opts.target.length, 940 959 posOptions = options.position, 941 960 contentOptions = options.content, … … 952 971 if(event) { 953 972 if((/over|enter/).test(event.type) && (/out|leave/).test(cache.event.type) && 954 event.target === options.show.target[0] && tooltip.has(event.relatedTarget).length) { 973 options.show.target.add(event.target).length === options.show.target.length && 974 tooltip.has(event.relatedTarget).length) { 955 975 return self; 956 976 } … … 990 1010 991 1011 // Update the tooltip position 992 self.reposition(event );1012 self.reposition(event, arguments[2]); 993 1013 994 1014 // Hide other tooltips if tooltip is solo, using it as the context … … 1025 1045 $(opts.autofocus, tooltip).focus(); 1026 1046 } 1027 1028 // Call API method1029 callback = $.Event('tooltipvisible');1030 callback.originalEvent = event ? cache.event : NULL;1031 tooltip.trigger(callback, [self]);1032 1047 1033 1048 // If set, hide tooltip when inactive for delay period … … 1044 1059 }); 1045 1060 } 1046 } 1047 1048 // Clear animation queue if same target 1049 if(sameTarget) { tooltip.stop(0, 1); } 1061 1062 // Call API method 1063 callback = $.Event('tooltip'+(state ? 'visible' : 'hidden')); 1064 callback.originalEvent = event ? cache.event : NULL; 1065 tooltip.trigger(callback, [self]); 1066 } 1067 1068 // Clear/stop animation 1069 tooltip.stop(eventAsTarget, !eventAsTarget); 1050 1070 1051 1071 // If no effect type is supplied, use a simple toggle … … 1151 1171 viewport = posOptions.viewport, 1152 1172 position = { left: 0, top: 0 }, 1173 container = posOptions.container, 1153 1174 flipoffset = FALSE, 1154 1175 tip = self.plugins.tip, … … 1162 1183 left: function(posLeft) { 1163 1184 var isShift = readjust.horizontal === 'shift', 1164 viewportScroll = viewport.offset.left + viewport.scrollLeft,1185 viewportScroll = -container.offset.left + viewport.offset.left + viewport.scrollLeft, 1165 1186 myWidth = my.x === 'left' ? elemWidth : my.x === 'right' ? -elemWidth : -elemWidth / 2, 1166 1187 atWidth = at.x === 'left' ? targetWidth : at.x === 'right' ? -targetWidth : -targetWidth / 2, … … 1169 1190 overflowLeft = viewportScroll - posLeft + tipAdjust, 1170 1191 overflowRight = posLeft + elemWidth - viewport.width - viewportScroll + tipAdjust, 1171 offset = myWidth - (my.precedance === 'x' || my.x === my.y ? atWidth : 0) ,1192 offset = myWidth - (my.precedance === 'x' || my.x === my.y ? atWidth : 0) - (at.x === 'center' ? targetWidth / 2 : 0), 1172 1193 isCenter = my.x === 'center'; 1173 1194 … … 1180 1201 position.left += overflowLeft > 0 ? overflowLeft : overflowRight > 0 ? -overflowRight : 0; 1181 1202 position.left = Math.max( 1182 viewport.offset.left + (tipAdjust && tip.corner.x === 'center' ? tip.offset : 0),1203 -container.offset.left + viewport.offset.left + (tipAdjust && tip.corner.x === 'center' ? tip.offset : 0), 1183 1204 posLeft - offset, 1184 1205 Math.min( 1185 Math.max( viewport.offset.left + viewport.width, posLeft + offset),1206 Math.max(-container.offset.left + viewport.offset.left + viewport.width, posLeft + offset), 1186 1207 position.left 1187 1208 ) … … 1207 1228 top: function(posTop) { 1208 1229 var isShift = readjust.vertical === 'shift', 1209 viewportScroll = viewport.offset.top + viewport.scrollTop,1230 viewportScroll = -container.offset.top + viewport.offset.top + viewport.scrollTop, 1210 1231 myHeight = my.y === 'top' ? elemHeight : my.y === 'bottom' ? -elemHeight : -elemHeight / 2, 1211 1232 atHeight = at.y === 'top' ? targetHeight : at.y === 'bottom' ? -targetHeight : -targetHeight / 2, … … 1214 1235 overflowTop = viewportScroll - posTop + tipAdjust, 1215 1236 overflowBottom = posTop + elemHeight - viewport.height - viewportScroll + tipAdjust, 1216 offset = myHeight - (my.precedance === 'y' || my.x === my.y ? atHeight : 0) ,1237 offset = myHeight - (my.precedance === 'y' || my.x === my.y ? atHeight : 0) - (at.y === 'center' ? targetHeight / 2 : 0), 1217 1238 isCenter = my.y === 'center'; 1218 1239 … … 1225 1246 position.top += overflowTop > 0 ? overflowTop : overflowBottom > 0 ? -overflowBottom : 0; 1226 1247 position.top = Math.max( 1227 viewport.offset.top + (tipAdjust && tip.corner.x === 'center' ? tip.offset : 0),1248 -container.offset.top + viewport.offset.top + (tipAdjust && tip.corner.x === 'center' ? tip.offset : 0), 1228 1249 posTop - offset, 1229 1250 Math.min( 1230 Math.max( viewport.offset.top + viewport.height, posTop + offset),1251 Math.max(-container.offset.top + viewport.offset.top + viewport.height, posTop + offset), 1231 1252 position.top 1232 1253 ) … … 1269 1290 event && event.pageX && event.type === 'mousemove' ? event : 1270 1291 MOUSE && MOUSE.pageX && (adjust.mouse || !event || !event.pageX) ? { pageX: MOUSE.pageX, pageY: MOUSE.pageY } : 1271 !adjust.mouse && cache.origin && cache.origin.pageX ? cache.origin :1292 !adjust.mouse && cache.origin && cache.origin.pageX && options.show.distance ? cache.origin : 1272 1293 event) || event || cache.event || MOUSE || {}; 1273 1294 … … 1287 1308 } 1288 1309 } 1289 else { cache.target = $(target); } 1310 else { 1311 target = cache.target = $(target.jquery ? target : elements.target); 1312 } 1290 1313 1291 1314 // Parse the target into a jQuery object and make sure there's an element present … … 1300 1323 if(target[0] === window) { 1301 1324 position = { 1302 top: !fixed || PLUGINS.iOS ? (viewport || target).scrollTop() : 0,1303 left: !fixed || PLUGINS.iOS ? (viewport || target).scrollLeft() : 01325 top: (viewport || target).scrollTop(), 1326 left: (viewport || target).scrollLeft() 1304 1327 }; 1305 1328 } … … 1318 1341 targetHeight = target.outerHeight(); 1319 1342 1320 position = PLUGINS.offset(target, posOptions.container);1343 position = PLUGINS.offset(target, container); 1321 1344 } 1322 1345 … … 1356 1379 offset: viewport.offset() || { left: 0, top: 0 } 1357 1380 }; 1381 container = { 1382 elem: container, 1383 scrollLeft: container.scrollLeft(), 1384 scrollTop: container.scrollTop(), 1385 offset: container.offset() || { left: 0, top: 0 } 1386 }; 1358 1387 1359 1388 // Adjust position based onviewport and adjustment options … … 1365 1394 // Set tooltip position class 1366 1395 if(position.adjusted.left + position.adjusted.top) { 1367 tooltip.attr('class', function(i, val) { 1368 return val.replace(/ui-tooltip-pos-\w+/i, uitooltip + '-pos-' + my.abbreviation()); 1369 }); 1396 tooltip.attr('class', tooltip[0].className.replace(/ui-tooltip-pos-\w+/i, uitooltip + '-pos-' + my.abbrev())); 1370 1397 } 1371 1398 … … 1481 1508 // Destroy tooltip and any associated plugins if rendered 1482 1509 if(self.rendered) { 1483 tooltip. remove();1510 tooltip.stop(1,0).remove(); 1484 1511 1485 1512 $.each(self.plugins, function() { … … 1568 1595 1569 1596 // Setup target options 1570 if( posOptions.container === FALSE) { posOptions.container = docBody; }1597 if(!posOptions.container.length) { posOptions.container = docBody; } 1571 1598 if(posOptions.target === FALSE) { posOptions.target = newTarget; } 1572 1599 if(config.show.target === FALSE) { config.show.target = newTarget; } 1573 if(config.show.solo === TRUE) { config.show.solo = docBody; }1600 if(config.show.solo === TRUE) { config.show.solo = posOptions.container.closest('body'); } 1574 1601 if(config.hide.target === FALSE) { config.hide.target = newTarget; } 1575 1602 if(config.position.viewport === TRUE) { config.position.viewport = posOptions.container; } 1603 1604 // Ensure we only use a single container 1605 posOptions.container = posOptions.container.eq(0); 1576 1606 1577 1607 // Convert position corner values into x and y strings … … 1598 1628 $.data(this, 'qtip', obj); 1599 1629 1600 // Catch remove events on target element to destroy redundant tooltip1601 elem.bind('remove.qtip-'+id , function(){ obj.destroy(); });1630 // Catch remove/removeqtip events on target element to destroy redundant tooltip 1631 elem.bind('remove.qtip-'+id+' removeqtip.qtip-'+id, function(){ obj.destroy(); }); 1602 1632 1603 1633 return obj; … … 1609 1639 var command = ('' + options).toLowerCase(), // Parse command 1610 1640 returned = NULL, 1611 args = command === 'disable' ? [TRUE] :$.makeArray(arguments).slice(1),1641 args = $.makeArray(arguments).slice(1), 1612 1642 event = args[args.length - 1], 1613 1643 opts = this[0] ? $.data(this[0], 'qtip') : NULL; … … 1700 1730 * Also make sure initial mouse targetting works correctly by caching mousemove coords 1701 1731 * on show targets before the tooltip has rendered. 1732 * 1733 * Also set onTarget when triggered to keep mouse tracking working 1702 1734 */ 1703 1735 targets.show.bind('mousemove'+namespace, function(event) { 1704 1736 MOUSE = { pageX: event.pageX, pageY: event.pageY, type: 'mousemove' }; 1737 api.cache.onTarget = TRUE; 1705 1738 }); 1706 1739 … … 1749 1782 this.y = (corner.match(/top|bottom|center/i) || ['inherit'])[0].toLowerCase(); 1750 1783 1751 this.precedance = (corner.charAt(0).search(/^(t|b)/) > -1) ? 'y' : 'x'; 1784 var f = corner.charAt(0); this.precedance = (f === 't' || f === 'b' ? 'y' : 'x'); 1785 1752 1786 this.string = function() { return this.precedance === 'y' ? this.y+this.x : this.x+this.y; }; 1753 this.abbrev iation= function() {1787 this.abbrev = function() { 1754 1788 var x = this.x.substr(0,1), y = this.y.substr(0,1); 1755 1789 return x === y ? x : (x === 'c' || (x !== 'c' && y !== 'c')) ? y + x : x + y; 1756 1790 }; 1791 1792 this.clone = function() { 1793 return { x: this.x, y: this.y, precedance: this.precedance, string: this.string, abbrev: this.abbrev, clone: this.clone }; 1794 }; 1757 1795 }, 1758 1796 … … 1760 1798 offset: function(elem, container) { 1761 1799 var pos = elem.offset(), 1762 parent = container, 1763 deep = 0, 1764 docBody = document.body, 1800 docBody = elem.closest('body')[0], 1801 parent = container, scrolled, 1765 1802 coffset, overflow; 1766 1803 … … 1774 1811 do { 1775 1812 if(parent.css('position') !== 'static') { 1776 coffset = parent[0] === docBody ? 1777 { left: parseInt(parent.css('left'), 10) || 0, top: parseInt(parent.css('top'), 10) || 0 } : 1778 parent.position(); 1779 1813 coffset = parent.position(); 1814 1815 // Account for element positioning, borders and margins 1780 1816 pos.left -= coffset.left + (parseInt(parent.css('borderLeftWidth'), 10) || 0) + (parseInt(parent.css('marginLeft'), 10) || 0); 1781 pos.top -= coffset.top + (parseInt(parent.css('borderTopWidth'), 10) || 0); 1782 1783 overflow = parent.css('overflow'); 1784 if(overflow === 'scroll' || overflow === 'auto') { deep++; } 1785 } 1786 1787 if(parent[0] === docBody) { break; } 1788 } 1789 while(parent = parent.offsetParent()); 1817 pos.top -= coffset.top + (parseInt(parent.css('borderTopWidth'), 10) || 0) + (parseInt(parent.css('marginTop'), 10) || 0); 1818 1819 // If this is the first parent element with an overflow of "scroll" or "auto", store it 1820 if(!scrolled && (overflow = parent.css('overflow')) !== 'hidden' && overflow !== 'visible') { scrolled = parent; } 1821 } 1822 } 1823 while((parent = $(parent[0].offsetParent)).length); 1790 1824 1791 1825 // Compensate for containers scroll if it also has an offsetParent 1792 if( container[0] !== docBody && deep) { scroll( container, 1 ); }1826 if(scrolled && scrolled[0] !== docBody) { scroll( scrolled, 1 ); } 1793 1827 } 1794 1828 … … 1850 1884 1851 1885 return elems; 1852 },1853 1854 /*1855 * Taken directly from jQuery 1.8.2 widget source code1856 * Trigger 'remove' event on all elements on removal1857 */1858 remove: $.ui ? NULL : function( selector, keepData ) {1859 if($.ui) { return; } // We don't need to do this if jQuery UI is present!1860 1861 $(this).each(function() {1862 if (!keepData) {1863 if (!selector || $.filter( selector, [ this ] ).length) {1864 $('*', this).add(this).each(function() {1865 $(this).triggerHandler('remove');1866 });1867 }1868 }1869 });1870 1886 } 1871 1887 } … … 1881 1897 }; 1882 1898 }); 1899 1900 /* Fire off 'removeqtip' handler in $.cleanData if jQuery UI not present (it already does similar). 1901 * This snippet is taken directly from jQuery UI source code found here: 1902 * http://code.jquery.com/ui/jquery-ui-git.js 1903 */ 1904 if(!$.ui) { 1905 $['cleanData'+replaceSuffix] = $.cleanData; 1906 $.cleanData = function( elems ) { 1907 for(var i = 0, elem; (elem = elems[i]) !== undefined; i++) { 1908 try { $( elem ).triggerHandler('removeqtip'); } 1909 catch( e ) {} 1910 } 1911 $['cleanData'+replaceSuffix]( elems ); 1912 }; 1913 } 1883 1914 1884 1915 // Set global qTip properties … … 1944 1975 widget: FALSE, 1945 1976 width: FALSE, 1946 height: FALSE 1977 height: FALSE, 1978 def: TRUE 1947 1979 }, 1948 1980 events: { … … 1953 1985 toggle: NULL, 1954 1986 visible: NULL, 1987 hidden: NULL, 1955 1988 focus: NULL, 1956 1989 blur: NULL … … 1965 1998 namespace = '.qtip-ajax', 1966 1999 rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, 1967 first = TRUE; 2000 first = TRUE, 2001 destroyed = FALSE, 2002 xhr; 1968 2003 1969 2004 api.checks.ajax = { … … 2005 2040 // Make sure default event hasn't been prevented 2006 2041 else if(event && event.isDefaultPrevented()) { return self; } 2042 2043 // Cancel old request 2044 if(xhr && xhr.abort) { xhr.abort(); } 2007 2045 2008 2046 // Check if user delcared a content selector like in .load() … … 2014 2052 // Define common after callback for both success/error handlers 2015 2053 function after() { 2054 if(destroyed) { return; } 2055 2016 2056 // Re-display tip if loading and first time, and reset first flag 2017 2057 if(hideFirst) { api.show(event.originalEvent); first = FALSE; } … … 2023 2063 // Define success handler 2024 2064 function successHandler(content) { 2065 if(destroyed) { return; } 2066 2025 2067 if(selector) { 2026 2068 // Create a dummy div to hold the results and grab the selector element … … 2039 2081 2040 2082 // Error handler 2041 function errorHandler(xh , status, error) {2042 if ( xh.status === 0) { return; }2083 function errorHandler(xhr, status, error) { 2084 if (destroyed || xhr.status === 0) { return; } 2043 2085 api.set('content.text', status + ': ' + error); 2044 2086 } 2045 2087 2046 2088 // Setup $.ajax option object and process the request 2047 $.ajax( $.extend({ success: successHandler, error: errorHandler, context: api }, opts, { url: url, complete: after }) ); 2089 xhr = $.ajax( $.extend({ success: successHandler, error: errorHandler, context: api }, opts, { url: url, complete: after }) ); 2090 }, 2091 2092 destroy: function() { 2093 // Cancel ajax request if possible 2094 if(xhr && xhr.abort) { xhr.abort(); } 2095 2096 // Set destroyed flag 2097 destroyed = TRUE; 2048 2098 } 2049 2099 }); … … 2114 2164 elems = qTip.elements, 2115 2165 tooltip = elems.tooltip, 2116 cache = { 2117 top: 0, 2118 left: 0, 2119 corner: '' 2120 }, 2166 cache = { top: 0, left: 0 }, 2121 2167 size = { 2122 2168 width: opts.width, … … 2167 2213 if(!elems.tip) { return; } 2168 2214 2169 var newCorner = $.extend({}, self.corner),2215 var newCorner = self.corner.clone(), 2170 2216 adjust = pos.adjusted, 2171 2217 method = qTip.options.position.adjust.method.split(' '), … … 2194 2240 2195 2241 // Update and redraw the tip if needed (check cached details of last drawn tip) 2196 if(newCorner.string() !== cache.corner && (cache.top !== adjust.top || cache.left !== adjust.left)) {2242 if(newCorner.string() !== cache.corner.string() && (cache.top !== adjust.top || cache.left !== adjust.left)) { 2197 2243 self.update(newCorner, FALSE); 2198 2244 } … … 2254 2300 // Cache details 2255 2301 cache.left = adjust.left; cache.top = adjust.top; 2256 cache.corner = newCorner. string();2302 cache.corner = newCorner.clone(); 2257 2303 } 2258 2304 … … 2351 2397 } 2352 2398 2399 // Cache it 2400 cache.corner = new PLUGINS.Corner( self.corner.string() ); 2401 2353 2402 return self.corner.string() !== 'centercenter'; 2354 2403 }, … … 2422 2471 vml = '<vml:shape coordorigin="0,0" style="display:inline-block; position:absolute; behavior:url(#default#VML);"></vml:shape>'; 2423 2472 elems.tip.html(vml + vml); 2473 2474 // Prevent mousing down on the tip since it causes problems with .live() handling in IE due to VML 2475 $('*', elems.tip).bind('click mousedown', function(event) { event.stopPropagation(); }); 2424 2476 } 2425 2477 }, … … 2438 2490 2439 2491 // Re-determine tip if not already set 2440 if(!corner) { corner = self.corner; }2492 if(!corner) { corner = cache.corner || self.corner; } 2441 2493 2442 2494 // Use corner property if we detect an invalid mimic value … … 2624 2676 } 2625 2677 }); 2626 2678 2627 2679 self.init(); 2628 2680 } … … 2714 2766 2715 2767 // Make sure mouseout doesn't trigger a hide when showing the modal and mousing onto backdrop 2716 if(oEvent && event.type === 'tooltiphide' && /mouse(leave|enter)/.test(oEvent.type) && $(oEvent.relatedTarget).closest(overlay[0]).length) { 2717 try { event.preventDefault(); } catch(e) {} 2718 } 2719 else if(!oEvent || (oEvent && !oEvent.solo)) { 2720 self[ event.type.replace('tooltip', '') ](event, duration); 2768 if(event.target === tooltip[0]) { 2769 if(oEvent && event.type === 'tooltiphide' && /mouse(leave|enter)/.test(oEvent.type) && $(oEvent.relatedTarget).closest(overlay[0]).length) { 2770 try { event.preventDefault(); } catch(e) {} 2771 } 2772 else if(!oEvent || (oEvent && !oEvent.solo)) { 2773 self[ event.type.replace('tooltip', '') ](event, duration); 2774 } 2721 2775 } 2722 2776 }) … … 2725 2779 .bind('tooltipfocus'+globalNamespace, function(event) { 2726 2780 // If focus was cancelled before it reearch us, don't do anything 2727 if(event.isDefaultPrevented() ) { return; }2781 if(event.isDefaultPrevented() || event.target !== tooltip[0]) { return; } 2728 2782 2729 2783 var qtips = $(selector).filter('['+attr+']'), … … 2755 2809 // Focus any other visible modals when this one hides 2756 2810 .bind('tooltiphide'+globalNamespace, function(event) { 2757 $('[' + attr + ']').filter(':visible').not(tooltip).last().qtip('focus', event); 2811 if(event.target === tooltip[0]) { 2812 $('[' + attr + ']').filter(':visible').not(tooltip).last().qtip('focus', event); 2813 } 2758 2814 }); 2759 2815 … … 2796 2852 2797 2853 // Update position on window resize or scroll 2798 $(window).unbind(globalNamespace).bind('resize'+globalNamespace, function() {2854 function resize() { 2799 2855 overlay.css({ 2800 2856 height: $(window).height(), 2801 2857 width: $(window).width() 2802 2858 }); 2803 }) 2804 .triggerHandler('resize'); 2859 } 2860 $(window).unbind(globalNamespace).bind('resize'+globalNamespace, resize); 2861 resize(); // Fire it initially too 2805 2862 2806 2863 return overlay; … … 2934 2991 2935 2992 // Base z-index for all modal tooltips (use qTip core z-index as a base) 2936 PLUGINS.modal.zindex = QTIP.zindex -= 200;2993 PLUGINS.modal.zindex = QTIP.zindex + 1000; 2937 2994 2938 2995 // Extend original api defaults … … 2949 3006 2950 3007 2951 } (jQuery, window));3008 }));
Note: See TracChangeset
for help on using the changeset viewer.
