qTip2-3.0.2/000077500000000000000000000000001263162617100125205ustar00rootroot00000000000000qTip2-3.0.2/.eslintrc000066400000000000000000000035431263162617100143510ustar00rootroot00000000000000{ "env": { "node": true, "browser": true, "builtin": true }, "globals": { "jQuery": true, "$": true, "QTip": true, "TRUE": true, "FALSE": true, "NULL": true, "WIDTH": true, "HEIGHT": true, "TOP": true, "LEFT": true, "BOTTOM": true, "RIGHT": true, "X": true, "Y": true, "CENTER": true, "FLIP": true, "FLIPINVERT": true, "SHIFT": true, "QTIP": true, "PROTOTYPE": true, "CORNER": true, "CHECKS": true, "PLUGINS": true, "NAMESPACE": true, "ATTR_HAS": true, "ATTR_ID": true, "WIDGET": true, "SELECTOR": true, "INACTIVE_EVENTS": true, "CLASS_FIXED": true, "CLASS_DEFAULT": true, "CLASS_FOCUS": true, "CLASS_HOVER": true, "CLASS_DISABLED": true, "BROWSER": true, "replaceSuffix": true, "oldtitle": true, "trackingBound": true, "createWidgetClass": true, "sanitizeOptions": true, "cloneEvent": true }, "rules": { "block-scoped-var": 2, "camelcase": 2, "curly": [ 2, "all" ], "dot-notation": [ 2, { "allowKeywords": true } ], "eqeqeq": [ 2, "allow-null" ], "strict": [ 2, "never" ], "guard-for-in": 2, "new-cap": 2, "no-bitwise": 2, "no-caller": 2, "no-debugger": 2, "no-empty": 2, "no-eval": 2, "no-extend-native": 2, "no-extra-parens": 2, "no-irregular-whitespace": 2, "no-iterator": 2, "no-loop-func": 2, "no-multi-str": 2, "no-new": 2, "no-proto": 2, "no-script-url": 2, "no-sequences": 2, "no-shadow": 2, "no-undef": 2, "no-unused-vars": 2, "no-with": 2, "quotes": [ 2, "single" ], "semi": [ 0, "never" ], "valid-typeof": 2, "wrap-iife": [ 2, "inside" ] } }qTip2-3.0.2/.gitattributes000066400000000000000000000001341263162617100154110ustar00rootroot00000000000000# text files detection * text=auto # unix end of lines forcing for text files * text eol=lfqTip2-3.0.2/.gitignore000066400000000000000000000001031263162617100145020ustar00rootroot00000000000000*.diff *.patch *~ .DS_Store /npm-debug.log node_modules/ **/*.nfs* qTip2-3.0.2/.npmignore000066400000000000000000000000141263162617100145120ustar00rootroot00000000000000node_modulesqTip2-3.0.2/.travis.yml000066400000000000000000000002041263162617100146250ustar00rootroot00000000000000sudo: false language: node_js node_js: - "0.10" - "0.11" - "0.12" - "4" - "5" before_script: - npm install -g grunt-cli qTip2-3.0.2/Gruntfile.js000066400000000000000000000051011263162617100150120ustar00rootroot00000000000000/*global module:false*/ module.exports = function(grunt) { // Load external tasks grunt.loadTasks('grunt/tasks'); // Auto load grunt config/ tasks require('load-grunt-config')(grunt, { data: { // Package properties pkg: grunt.file.readJSON('package.json'), // So meta... meta: { banners: { full: '/*\n * <%= pkg.title || pkg.name %> - @@vVERSION\n' + ' * <%=pkg.homepage%>\n' + ' *\n' + ' * Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>\n' + ' * Released under the <%= _.pluck(pkg.licenses, "type").join(", ") %> licenses\n' + ' * http://jquery.org/license\n' + ' *\n' + ' * Date: <%= grunt.template.today("ddd mmm d yyyy hh:MM Zo", true) %>\n' + '@@BUILDPROPS */\n', minified:'/* <%= pkg.name %> @@vVERSION | Plugins: @@PLUGINS | Styles: @@STYLES | <%= pkg.homepage.replace("http://","") %> | '+ 'Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> | <%=grunt.template.today() %> */\n' } }, // Directories (dist changed in init()) dirs: { src: 'src', dist: 'dist', libs: 'libs', modules: 'node_modules' }, // Wrapper files for final built dist files wrappers: { js: { intro: '<%=dirs.src%>/core/intro.js', outro: '<%=dirs.src%>/core/outro.js' } }, // Core files in order core: { js: [ '<%=dirs.src%>/core/constants.js', '<%=dirs.src%>/core/class.js', '<%=dirs.src%>/core/options.js', '<%=dirs.src%>/core/content.js', '<%=dirs.src%>/core/position.js', '<%=dirs.src%>/core/toggle.js', '<%=dirs.src%>/core/focus.js', '<%=dirs.src%>/core/disable.js', '<%=dirs.src%>/core/button.js', '<%=dirs.src%>/core/style.js', '<%=dirs.src%>/core/events.js', '<%=dirs.src%>/core/jquery_methods.js', '<%=dirs.src%>/core/jquery_overrides.js', '<%=dirs.src%>/core/defaults.js' ], css: ['<%=dirs.src%>/core.css'] }, // Styles and plugins map styles: { basic: '<%=dirs.src%>/basic.css', css3: '<%=dirs.src%>/css3.css' }, plugins: { tips: { js: '<%=dirs.src%>/tips/tips.js', css: '<%=dirs.src%>/tips/tips.css' }, modal: { js: '<%=dirs.src%>/modal/modal.js', css: '<%=dirs.src%>/modal/modal.css' }, viewport: { js: '<%=dirs.src%>/position/viewport.js' }, svg: { js: [ '<%=dirs.src%>/position/polys.js', '<%=dirs.src%>/position/svg.js' ] }, imagemap: { js: [ '<%=dirs.src%>/position/polys.js', '<%=dirs.src%>/position/imagemap.js' ] }, ie6: { js: '<%=dirs.src%>/ie6/ie6.js', css: '<%=dirs.src%>/ie6/ie6.css' } } } }); }; qTip2-3.0.2/LICENSE000066400000000000000000000020521263162617100135240ustar00rootroot00000000000000Copyright (c) 2012 Craig Michael Thompson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. qTip2-3.0.2/README.md000066400000000000000000000073631263162617100140100ustar00rootroot00000000000000[![Build Status](https://travis-ci.org/qTip2/qTip2.svg)](https://travis-ci.org/qTip2/qTip2) [![devDependency Status](https://david-dm.org/qTip2/qTip2/dev-status.svg?theme=shields.io)](https://david-dm.org/qTip2/qTip2#info=devDependencies) [![Join the chat at https://gitter.im/qTip2/qTip2](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/qTip2/qTip2?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [qTip2][site] - Pretty powerful tooltips ================================ Introducing… qTip2. The second generation of the advanced qTip plugin for the ever popular jQuery framework. Building on 1.0's user friendly, yet feature rich base, qTip2 provides you with tonnes of features like [speech bubble tips][tips] and [imagemap support][imgmap], and best of all... **it's completely free under the MIT license!** More documentation and information is available at the [official site][site]. ## Browser support
8+       3+       6+       9+       2+, iOS 4+
## Getting qTip2 ### Stable releases Grab the latest releases of qTip2 from the [cdnjs][cdnjs] or [jsDelivr][jsdelivr] [CDN][wikipedia-cdn]s. You can also customize the [plugins][plugins] included using the [download page][download] of the [official site][site]. ### Nightly (and older) releases You can checkout the various releases of qTip2 (including the latest nightly builds) at the [release archive][archive]. ### Roll your own You can also build your own qTip2 script that includes select [plugins][plugins] and [styles][style] to reduce the overall file size and remove features you don't plan on using. Find more information about this [here][build] ## Documentation Take a look at the [documentation][docs] for extensive docs and guides. ## Release History See the official [Changelog][changelog] ## Questions or problems? If you have any questions, please feel free to post on the [support forums][forums], but before you do make sure to check out the [thorough documentation][docs] both here in the repo and on the [official site][site]. ## License Copyright (c) 2011-2016 Craig Michael Thompson. Licensed under the MIT license. *See [here][license] for more details.* ## Special thanks Big shout-out to ["Cowboy" Ben Alman][cowboy] for providing the [grunt][grunt] build system used by qTip2 [site]: http://qtip2.com/ [archive]: http://qtip2.com/v/ [docs]: http://qtip2.com/guides/ [download]: http://qtip2.com/download [changelog]: http://qtip2.com/changelog [build]: http://qtip2.com/guides#custom-build [style]: http://qtip2.com/demos#styling [plugins]: http://qtip2.com/plugins [tips]: http://qtip2.com/plugins#tips [imgmap]: http://qtip2.com/plugins#imagemap [forums]: http://craigsworks.com/projects/forums/forum-qtip2 [license]: http://jquery.org/license [cowboy]: http://github.com/cowboy [grunt]: http://github.com/gruntjs/grunt [wikipedia-cdn]: http://en.wikipedia.org/wiki/Content_delivery_network "Content Delivery Network" [cdnjs]: http://cdnjs.com/libraries/qtip2/ [jsdelivr]: http://www.jsdelivr.com/#!qtip2 qTip2-3.0.2/bower.json000066400000000000000000000013341263162617100145320ustar00rootroot00000000000000{ "name": "qtip2", "description": "Introducing... qTip2. The second generation of the advanced qTip plugin for the ever popular jQuery framework.", "version": "3.0.2", "homepage": "http://qtip2.com", "repository": { "type": "git", "url": "git://github.com/qTip2/qTip2.git" }, "author": "Craig Michael Thompson (http://craigsworks.com/)", "license": [ "MIT" ], "keywords": [ "tooltip", "tooltips", "jquery", "jquery-plugin", "qtip", "qtip2", "simpletip", "craig thompson", "craig michael thompson", "craigsworks", "craga89" ], "main": [ "./dist/jquery.qtip.js", "./dist/jquery.qtip.css" ], "dependencies": { "jquery": ">=1.6.0", "imagesloaded": ">=3.0.0" } }qTip2-3.0.2/dist/000077500000000000000000000000001263162617100134635ustar00rootroot00000000000000qTip2-3.0.2/dist/basic/000077500000000000000000000000001263162617100145445ustar00rootroot00000000000000qTip2-3.0.2/dist/basic/jquery.qtip.css000066400000000000000000000042701263162617100175540ustar00rootroot00000000000000/* * qTip2 - Pretty powerful tooltips - v3.0.2 * http://qtip2.com * * Copyright (c) 2015 * Released under the MIT licenses * http://jquery.org/license * * Date: Tue Dec 8 2015 07:16 GMT+0000 * Plugins: None * Styles: core */ .qtip{ position: absolute; left: -28000px; top: -28000px; display: none; max-width: 280px; min-width: 50px; font-size: 10.5px; line-height: 12px; direction: ltr; box-shadow: none; padding: 0; } .qtip-content{ position: relative; padding: 5px 9px; overflow: hidden; text-align: left; word-wrap: break-word; } .qtip-titlebar{ position: relative; padding: 5px 35px 5px 10px; overflow: hidden; border-width: 0 0 1px; font-weight: bold; } .qtip-titlebar + .qtip-content{ border-top-width: 0 !important; } /* Default close button class */ .qtip-close{ position: absolute; right: -9px; top: -9px; z-index: 11; /* Overlap .qtip-tip */ cursor: pointer; outline: medium none; border: 1px solid transparent; } .qtip-titlebar .qtip-close{ right: 4px; top: 50%; margin-top: -9px; } * html .qtip-titlebar .qtip-close{ top: 16px; } /* IE fix */ .qtip-titlebar .ui-icon, .qtip-icon .ui-icon{ display: block; text-indent: -1000em; direction: ltr; } .qtip-icon, .qtip-icon .ui-icon{ -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; text-decoration: none; } .qtip-icon .ui-icon{ width: 18px; height: 14px; line-height: 14px; text-align: center; text-indent: 0; font: normal bold 10px/13px Tahoma,sans-serif; color: inherit; background: transparent none no-repeat -100em -100em; } /* Applied to 'focused' tooltips e.g. most recently displayed/interacted with */ .qtip-focus{} /* Applied on hover of tooltips i.e. added/removed on mouseenter/mouseleave respectively */ .qtip-hover{} /* Default tooltip style */ .qtip-default{ border: 1px solid #F1D031; background-color: #FFFFA3; color: #555; } .qtip-default .qtip-titlebar{ background-color: #FFEF93; } .qtip-default .qtip-icon{ border-color: #CCC; background: #F1F1F1; color: #777; } .qtip-default .qtip-titlebar .qtip-close{ border-color: #AAA; color: #111; } qTip2-3.0.2/dist/basic/jquery.qtip.js000066400000000000000000001630021263162617100173770ustar00rootroot00000000000000/* * qTip2 - Pretty powerful tooltips - v3.0.2 * http://qtip2.com * * Copyright (c) 2015 * Released under the MIT licenses * http://jquery.org/license * * Date: Tue Dec 8 2015 07:16 GMT+0000 * Plugins: None * Styles: core */ /*global window: false, jQuery: false, console: false, define: false */ /* Cache window, document, undefined */ (function( window, document, undefined ) { // Uses AMD or browser globals to create a jQuery plugin. (function( factory ) { "use strict"; if(typeof define === 'function' && define.amd) { define(['jquery'], factory); } else if(jQuery && !jQuery.fn.qtip) { factory(jQuery); } } (function($) { "use strict"; // Enable ECMAScript "strict" operation for this function. See more: http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/ ;// Munge the primitives - Paul Irish tip var TRUE = true, FALSE = false, NULL = null, // Common variables X = 'x', Y = 'y', WIDTH = 'width', HEIGHT = 'height', // Positioning sides TOP = 'top', LEFT = 'left', BOTTOM = 'bottom', RIGHT = 'right', CENTER = 'center', // Position adjustment types FLIP = 'flip', FLIPINVERT = 'flipinvert', SHIFT = 'shift', // Shortcut vars QTIP, PROTOTYPE, CORNER, CHECKS, PLUGINS = {}, NAMESPACE = 'qtip', ATTR_HAS = 'data-hasqtip', ATTR_ID = 'data-qtip-id', WIDGET = ['ui-widget', 'ui-tooltip'], SELECTOR = '.'+NAMESPACE, INACTIVE_EVENTS = 'click dblclick mousedown mouseup mousemove mouseleave mouseenter'.split(' '), CLASS_FIXED = NAMESPACE+'-fixed', CLASS_DEFAULT = NAMESPACE + '-default', CLASS_FOCUS = NAMESPACE + '-focus', CLASS_HOVER = NAMESPACE + '-hover', CLASS_DISABLED = NAMESPACE+'-disabled', replaceSuffix = '_replacedByqTip', oldtitle = 'oldtitle', trackingBound, // Browser detection BROWSER = { /* * IE version detection * * Adapted from: http://ajaxian.com/archives/attack-of-the-ie-conditional-comment * Credit to James Padolsey for the original implemntation! */ ie: (function() { /* eslint-disable no-empty */ var v, i; for ( v = 4, i = document.createElement('div'); (i.innerHTML = '') && i.getElementsByTagName('i')[0]; v+=1 ) {} return v > 4 ? v : NaN; /* eslint-enable no-empty */ })(), /* * iOS version detection */ iOS: parseFloat( ('' + (/CPU.*OS ([0-9_]{1,5})|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent) || [0,''])[1]) .replace('undefined', '3_2').replace('_', '.').replace('_', '') ) || FALSE }; ;function QTip(target, options, id, attr) { // Elements and ID this.id = id; this.target = target; this.tooltip = NULL; this.elements = { target: target }; // Internal constructs this._id = NAMESPACE + '-' + id; this.timers = { img: {} }; this.options = options; this.plugins = {}; // Cache object this.cache = { event: {}, target: $(), disabled: FALSE, attr: attr, onTooltip: FALSE, lastClass: '' }; // Set the initial flags this.rendered = this.destroyed = this.disabled = this.waiting = this.hiddenDuringWait = this.positioning = this.triggering = FALSE; } PROTOTYPE = QTip.prototype; PROTOTYPE._when = function(deferreds) { return $.when.apply($, deferreds); }; PROTOTYPE.render = function(show) { if(this.rendered || this.destroyed) { return this; } // If tooltip has already been rendered, exit var self = this, options = this.options, cache = this.cache, elements = this.elements, text = options.content.text, title = options.content.title, button = options.content.button, posOptions = options.position, deferreds = []; // Add ARIA attributes to target $.attr(this.target[0], 'aria-describedby', this._id); // Create public position object that tracks current position corners cache.posClass = this._createPosClass( (this.position = { my: posOptions.my, at: posOptions.at }).my ); // Create tooltip element this.tooltip = elements.tooltip = $('
', { 'id': this._id, 'class': [ NAMESPACE, CLASS_DEFAULT, options.style.classes, cache.posClass ].join(' '), 'width': options.style.width || '', 'height': options.style.height || '', 'tracking': posOptions.target === 'mouse' && posOptions.adjust.mouse, /* ARIA specific attributes */ 'role': 'alert', 'aria-live': 'polite', 'aria-atomic': FALSE, 'aria-describedby': this._id + '-content', 'aria-hidden': TRUE }) .toggleClass(CLASS_DISABLED, this.disabled) .attr(ATTR_ID, this.id) .data(NAMESPACE, this) .appendTo(posOptions.container) .append( // Create content element elements.content = $('
', { 'class': NAMESPACE + '-content', 'id': this._id + '-content', 'aria-atomic': TRUE }) ); // Set rendered flag and prevent redundant reposition calls for now this.rendered = -1; this.positioning = TRUE; // Create title... if(title) { this._createTitle(); // Update title only if its not a callback (called in toggle if so) if(!$.isFunction(title)) { deferreds.push( this._updateTitle(title, FALSE) ); } } // Create button if(button) { this._createButton(); } // Set proper rendered flag and update content if not a callback function (called in toggle) if(!$.isFunction(text)) { deferreds.push( this._updateContent(text, FALSE) ); } this.rendered = TRUE; // Setup widget classes this._setWidget(); // Initialize 'render' plugins $.each(PLUGINS, function(name) { var instance; if(this.initialize === 'render' && (instance = this(self))) { self.plugins[name] = instance; } }); // Unassign initial events and assign proper events this._unassignEvents(); this._assignEvents(); // When deferreds have completed this._when(deferreds).then(function() { // tooltiprender event self._trigger('render'); // Reset flags self.positioning = FALSE; // Show tooltip if not hidden during wait period if(!self.hiddenDuringWait && (options.show.ready || show)) { self.toggle(TRUE, cache.event, FALSE); } self.hiddenDuringWait = FALSE; }); // Expose API QTIP.api[this.id] = this; return this; }; PROTOTYPE.destroy = function(immediate) { // Set flag the signify destroy is taking place to plugins // and ensure it only gets destroyed once! if(this.destroyed) { return this.target; } function process() { if(this.destroyed) { return; } this.destroyed = TRUE; var target = this.target, title = target.attr(oldtitle), timer; // Destroy tooltip if rendered if(this.rendered) { this.tooltip.stop(1,0).find('*').remove().end().remove(); } // Destroy all plugins $.each(this.plugins, function() { this.destroy && this.destroy(); }); // Clear timers for (timer in this.timers) { if (this.timers.hasOwnProperty(timer)) { clearTimeout(this.timers[timer]); } } // Remove api object and ARIA attributes target.removeData(NAMESPACE) .removeAttr(ATTR_ID) .removeAttr(ATTR_HAS) .removeAttr('aria-describedby'); // Reset old title attribute if removed if(this.options.suppress && title) { target.attr('title', title).removeAttr(oldtitle); } // Remove qTip events associated with this API this._unassignEvents(); // Remove ID from used id objects, and delete object references // for better garbage collection and leak protection this.options = this.elements = this.cache = this.timers = this.plugins = this.mouse = NULL; // Delete epoxsed API object delete QTIP.api[this.id]; } // If an immediate destroy is needed if((immediate !== TRUE || this.triggering === 'hide') && this.rendered) { this.tooltip.one('tooltiphidden', $.proxy(process, this)); !this.triggering && this.hide(); } // If we're not in the process of hiding... process else { process.call(this); } return this.target; }; ;function invalidOpt(a) { return a === NULL || $.type(a) !== 'object'; } function invalidContent(c) { return !($.isFunction(c) || c && c.attr) || c.length || $.type(c) === 'object' && (c.jquery || c.then); } // Option object sanitizer function sanitizeOptions(opts) { var content, text, ajax, once; if(invalidOpt(opts)) { return FALSE; } if(invalidOpt(opts.metadata)) { opts.metadata = { type: opts.metadata }; } if('content' in opts) { content = opts.content; if(invalidOpt(content) || content.jquery || content.done) { text = invalidContent(content) ? FALSE : content; content = opts.content = { text: text }; } else { text = content.text; } // DEPRECATED - Old content.ajax plugin functionality // Converts it into the proper Deferred syntax if('ajax' in content) { ajax = content.ajax; once = ajax && ajax.once !== FALSE; delete content.ajax; content.text = function(event, api) { var loading = text || $(this).attr(api.options.content.attr) || 'Loading...', deferred = $.ajax( $.extend({}, ajax, { context: api }) ) .then(ajax.success, NULL, ajax.error) .then(function(newContent) { if(newContent && once) { api.set('content.text', newContent); } return newContent; }, function(xhr, status, error) { if(api.destroyed || xhr.status === 0) { return; } api.set('content.text', status + ': ' + error); }); return !once ? (api.set('content.text', loading), deferred) : loading; }; } if('title' in content) { if($.isPlainObject(content.title)) { content.button = content.title.button; content.title = content.title.text; } if(invalidContent(content.title || FALSE)) { content.title = FALSE; } } } if('position' in opts && invalidOpt(opts.position)) { opts.position = { my: opts.position, at: opts.position }; } if('show' in opts && invalidOpt(opts.show)) { opts.show = opts.show.jquery ? { target: opts.show } : opts.show === TRUE ? { ready: TRUE } : { event: opts.show }; } if('hide' in opts && invalidOpt(opts.hide)) { opts.hide = opts.hide.jquery ? { target: opts.hide } : { event: opts.hide }; } if('style' in opts && invalidOpt(opts.style)) { opts.style = { classes: opts.style }; } // Sanitize plugin options $.each(PLUGINS, function() { this.sanitize && this.sanitize(opts); }); return opts; } // Setup builtin .set() option checks CHECKS = PROTOTYPE.checks = { builtin: { // Core checks '^id$': function(obj, o, v, prev) { var id = v === TRUE ? QTIP.nextid : v, newId = NAMESPACE + '-' + id; if(id !== FALSE && id.length > 0 && !$('#'+newId).length) { this._id = newId; if(this.rendered) { this.tooltip[0].id = this._id; this.elements.content[0].id = this._id + '-content'; this.elements.title[0].id = this._id + '-title'; } } else { obj[o] = prev; } }, '^prerender': function(obj, o, v) { v && !this.rendered && this.render(this.options.show.ready); }, // Content checks '^content.text$': function(obj, o, v) { this._updateContent(v); }, '^content.attr$': function(obj, o, v, prev) { if(this.options.content.text === this.target.attr(prev)) { this._updateContent( this.target.attr(v) ); } }, '^content.title$': function(obj, o, v) { // Remove title if content is null if(!v) { return this._removeTitle(); } // If title isn't already created, create it now and update v && !this.elements.title && this._createTitle(); this._updateTitle(v); }, '^content.button$': function(obj, o, v) { this._updateButton(v); }, '^content.title.(text|button)$': function(obj, o, v) { this.set('content.'+o, v); // Backwards title.text/button compat }, // Position checks '^position.(my|at)$': function(obj, o, v){ if('string' === typeof v) { this.position[o] = obj[o] = new CORNER(v, o === 'at'); } }, '^position.container$': function(obj, o, v){ this.rendered && this.tooltip.appendTo(v); }, // Show checks '^show.ready$': function(obj, o, v) { v && (!this.rendered && this.render(TRUE) || this.toggle(TRUE)); }, // Style checks '^style.classes$': function(obj, o, v, p) { this.rendered && this.tooltip.removeClass(p).addClass(v); }, '^style.(width|height)': function(obj, o, v) { this.rendered && this.tooltip.css(o, v); }, '^style.widget|content.title': function() { this.rendered && this._setWidget(); }, '^style.def': function(obj, o, v) { this.rendered && this.tooltip.toggleClass(CLASS_DEFAULT, !!v); }, // Events check '^events.(render|show|move|hide|focus|blur)$': function(obj, o, v) { this.rendered && this.tooltip[($.isFunction(v) ? '' : 'un') + 'bind']('tooltip'+o, v); }, // Properties which require event reassignment '^(show|hide|position).(event|target|fixed|inactive|leave|distance|viewport|adjust)': function() { if(!this.rendered) { return; } // Set tracking flag var posOptions = this.options.position; this.tooltip.attr('tracking', posOptions.target === 'mouse' && posOptions.adjust.mouse); // Reassign events this._unassignEvents(); this._assignEvents(); } } }; // Dot notation converter function convertNotation(options, notation) { var i = 0, obj, option = options, // Split notation into array levels = notation.split('.'); // Loop through while(option = option[ levels[i++] ]) { if(i < levels.length) { obj = option; } } return [obj || options, levels.pop()]; } PROTOTYPE.get = function(notation) { if(this.destroyed) { return this; } var o = convertNotation(this.options, notation.toLowerCase()), result = o[0][ o[1] ]; return result.precedance ? result.string() : result; }; function setCallback(notation, args) { var category, rule, match; for(category in this.checks) { if (!this.checks.hasOwnProperty(category)) { continue; } for(rule in this.checks[category]) { if (!this.checks[category].hasOwnProperty(rule)) { continue; } if(match = (new RegExp(rule, 'i')).exec(notation)) { args.push(match); if(category === 'builtin' || this.plugins[category]) { this.checks[category][rule].apply( this.plugins[category] || this, args ); } } } } } var rmove = /^position\.(my|at|adjust|target|container|viewport)|style|content|show\.ready/i, rrender = /^prerender|show\.ready/i; PROTOTYPE.set = function(option, value) { if(this.destroyed) { return this; } var rendered = this.rendered, reposition = FALSE, options = this.options, name; // Convert singular option/value pair into object form if('string' === typeof option) { name = option; option = {}; option[name] = value; } else { option = $.extend({}, option); } // Set all of the defined options to their new values $.each(option, function(notation, val) { if(rendered && rrender.test(notation)) { delete option[notation]; return; } // Set new obj value var obj = convertNotation(options, notation.toLowerCase()), previous; previous = obj[0][ obj[1] ]; obj[0][ obj[1] ] = val && val.nodeType ? $(val) : val; // Also check if we need to reposition reposition = rmove.test(notation) || reposition; // Set the new params for the callback option[notation] = [obj[0], obj[1], val, previous]; }); // Re-sanitize options sanitizeOptions(options); /* * Execute any valid callbacks for the set options * Also set positioning flag so we don't get loads of redundant repositioning calls. */ this.positioning = TRUE; $.each(option, $.proxy(setCallback, this)); this.positioning = FALSE; // Update position if needed if(this.rendered && this.tooltip[0].offsetWidth > 0 && reposition) { this.reposition( options.position.target === 'mouse' ? NULL : this.cache.event ); } return this; }; ;PROTOTYPE._update = function(content, element) { var self = this, cache = this.cache; // Make sure tooltip is rendered and content is defined. If not return if(!this.rendered || !content) { return FALSE; } // Use function to parse content if($.isFunction(content)) { content = content.call(this.elements.target, cache.event, this) || ''; } // Handle deferred content if($.isFunction(content.then)) { cache.waiting = TRUE; return content.then(function(c) { cache.waiting = FALSE; return self._update(c, element); }, NULL, function(e) { return self._update(e, element); }); } // If content is null... return false if(content === FALSE || !content && content !== '') { return FALSE; } // Append new content if its a DOM array and show it if hidden if(content.jquery && content.length > 0) { element.empty().append( content.css({ display: 'block', visibility: 'visible' }) ); } // Content is a regular string, insert the new content else { element.html(content); } // Wait for content to be loaded, and reposition return this._waitForContent(element).then(function(images) { if(self.rendered && self.tooltip[0].offsetWidth > 0) { self.reposition(cache.event, !images.length); } }); }; PROTOTYPE._waitForContent = function(element) { var cache = this.cache; // Set flag cache.waiting = TRUE; // If imagesLoaded is included, ensure images have loaded and return promise return ( $.fn.imagesLoaded ? element.imagesLoaded() : new $.Deferred().resolve([]) ) .done(function() { cache.waiting = FALSE; }) .promise(); }; PROTOTYPE._updateContent = function(content, reposition) { this._update(content, this.elements.content, reposition); }; PROTOTYPE._updateTitle = function(content, reposition) { if(this._update(content, this.elements.title, reposition) === FALSE) { this._removeTitle(FALSE); } }; PROTOTYPE._createTitle = function() { var elements = this.elements, id = this._id+'-title'; // Destroy previous title element, if present if(elements.titlebar) { this._removeTitle(); } // Create title bar and title elements elements.titlebar = $('
', { 'class': NAMESPACE + '-titlebar ' + (this.options.style.widget ? createWidgetClass('header') : '') }) .append( elements.title = $('
', { 'id': id, 'class': NAMESPACE + '-title', 'aria-atomic': TRUE }) ) .insertBefore(elements.content) // Button-specific events .delegate('.qtip-close', 'mousedown keydown mouseup keyup mouseout', function(event) { $(this).toggleClass('ui-state-active ui-state-focus', event.type.substr(-4) === 'down'); }) .delegate('.qtip-close', 'mouseover mouseout', function(event){ $(this).toggleClass('ui-state-hover', event.type === 'mouseover'); }); // Create button if enabled if(this.options.content.button) { this._createButton(); } }; PROTOTYPE._removeTitle = function(reposition) { var elements = this.elements; if(elements.title) { elements.titlebar.remove(); elements.titlebar = elements.title = elements.button = NULL; // Reposition if enabled if(reposition !== FALSE) { this.reposition(); } } }; ;PROTOTYPE._createPosClass = function(my) { return NAMESPACE + '-pos-' + (my || this.options.position.my).abbrev(); }; PROTOTYPE.reposition = function(event, effect) { if(!this.rendered || this.positioning || this.destroyed) { return this; } // Set positioning flag this.positioning = TRUE; var cache = this.cache, tooltip = this.tooltip, posOptions = this.options.position, target = posOptions.target, my = posOptions.my, at = posOptions.at, viewport = posOptions.viewport, container = posOptions.container, adjust = posOptions.adjust, method = adjust.method.split(' '), tooltipWidth = tooltip.outerWidth(FALSE), tooltipHeight = tooltip.outerHeight(FALSE), targetWidth = 0, targetHeight = 0, type = tooltip.css('position'), position = { left: 0, top: 0 }, visible = tooltip[0].offsetWidth > 0, isScroll = event && event.type === 'scroll', win = $(window), doc = container[0].ownerDocument, mouse = this.mouse, pluginCalculations, offset, adjusted, newClass; // Check if absolute position was passed if($.isArray(target) && target.length === 2) { // Force left top and set position at = { x: LEFT, y: TOP }; position = { left: target[0], top: target[1] }; } // Check if mouse was the target else if(target === 'mouse') { // Force left top to allow flipping at = { x: LEFT, y: TOP }; // Use the mouse origin that caused the show event, if distance hiding is enabled if((!adjust.mouse || this.options.hide.distance) && cache.origin && cache.origin.pageX) { event = cache.origin; } // Use cached event for resize/scroll events else if(!event || event && (event.type === 'resize' || event.type === 'scroll')) { event = cache.event; } // Otherwise, use the cached mouse coordinates if available else if(mouse && mouse.pageX) { event = mouse; } // Calculate body and container offset and take them into account below if(type !== 'static') { position = container.offset(); } if(doc.body.offsetWidth !== (window.innerWidth || doc.documentElement.clientWidth)) { offset = $(document.body).offset(); } // Use event coordinates for position position = { left: event.pageX - position.left + (offset && offset.left || 0), top: event.pageY - position.top + (offset && offset.top || 0) }; // Scroll events are a pain, some browsers if(adjust.mouse && isScroll && mouse) { position.left -= (mouse.scrollX || 0) - win.scrollLeft(); position.top -= (mouse.scrollY || 0) - win.scrollTop(); } } // Target wasn't mouse or absolute... else { // Check if event targetting is being used if(target === 'event') { if(event && event.target && event.type !== 'scroll' && event.type !== 'resize') { cache.target = $(event.target); } else if(!event.target) { cache.target = this.elements.target; } } else if(target !== 'event'){ cache.target = $(target.jquery ? target : this.elements.target); } target = cache.target; // Parse the target into a jQuery object and make sure there's an element present target = $(target).eq(0); if(target.length === 0) { return this; } // Check if window or document is the target else if(target[0] === document || target[0] === window) { targetWidth = BROWSER.iOS ? window.innerWidth : target.width(); targetHeight = BROWSER.iOS ? window.innerHeight : target.height(); if(target[0] === window) { position = { top: (viewport || target).scrollTop(), left: (viewport || target).scrollLeft() }; } } // Check if the target is an element else if(PLUGINS.imagemap && target.is('area')) { pluginCalculations = PLUGINS.imagemap(this, target, at, PLUGINS.viewport ? method : FALSE); } // Check if the target is an SVG element else if(PLUGINS.svg && target && target[0].ownerSVGElement) { pluginCalculations = PLUGINS.svg(this, target, at, PLUGINS.viewport ? method : FALSE); } // Otherwise use regular jQuery methods else { targetWidth = target.outerWidth(FALSE); targetHeight = target.outerHeight(FALSE); position = target.offset(); } // Parse returned plugin values into proper variables if(pluginCalculations) { targetWidth = pluginCalculations.width; targetHeight = pluginCalculations.height; offset = pluginCalculations.offset; position = pluginCalculations.position; } // Adjust position to take into account offset parents position = this.reposition.offset(target, position, container); // Adjust for position.fixed tooltips (and also iOS scroll bug in v3.2-4.0 & v4.3-4.3.2) if(BROWSER.iOS > 3.1 && BROWSER.iOS < 4.1 || BROWSER.iOS >= 4.3 && BROWSER.iOS < 4.33 || !BROWSER.iOS && type === 'fixed' ){ position.left -= win.scrollLeft(); position.top -= win.scrollTop(); } // Adjust position relative to target if(!pluginCalculations || pluginCalculations && pluginCalculations.adjustable !== FALSE) { position.left += at.x === RIGHT ? targetWidth : at.x === CENTER ? targetWidth / 2 : 0; position.top += at.y === BOTTOM ? targetHeight : at.y === CENTER ? targetHeight / 2 : 0; } } // Adjust position relative to tooltip position.left += adjust.x + (my.x === RIGHT ? -tooltipWidth : my.x === CENTER ? -tooltipWidth / 2 : 0); position.top += adjust.y + (my.y === BOTTOM ? -tooltipHeight : my.y === CENTER ? -tooltipHeight / 2 : 0); // Use viewport adjustment plugin if enabled if(PLUGINS.viewport) { adjusted = position.adjusted = PLUGINS.viewport( this, position, posOptions, targetWidth, targetHeight, tooltipWidth, tooltipHeight ); // Apply offsets supplied by positioning plugin (if used) if(offset && adjusted.left) { position.left += offset.left; } if(offset && adjusted.top) { position.top += offset.top; } // Apply any new 'my' position if(adjusted.my) { this.position.my = adjusted.my; } } // Viewport adjustment is disabled, set values to zero else { position.adjusted = { left: 0, top: 0 }; } // Set tooltip position class if it's changed if(cache.posClass !== (newClass = this._createPosClass(this.position.my))) { cache.posClass = newClass; tooltip.removeClass(cache.posClass).addClass(newClass); } // tooltipmove event if(!this._trigger('move', [position, viewport.elem || viewport], event)) { return this; } delete position.adjusted; // If effect is disabled, target it mouse, no animation is defined or positioning gives NaN out, set CSS directly if(effect === FALSE || !visible || isNaN(position.left) || isNaN(position.top) || target === 'mouse' || !$.isFunction(posOptions.effect)) { tooltip.css(position); } // Use custom function if provided else if($.isFunction(posOptions.effect)) { posOptions.effect.call(tooltip, this, $.extend({}, position)); tooltip.queue(function(next) { // Reset attributes to avoid cross-browser rendering bugs $(this).css({ opacity: '', height: '' }); if(BROWSER.ie) { this.style.removeAttribute('filter'); } next(); }); } // Set positioning flag this.positioning = FALSE; return this; }; // Custom (more correct for qTip!) offset calculator PROTOTYPE.reposition.offset = function(elem, pos, container) { if(!container[0]) { return pos; } var ownerDocument = $(elem[0].ownerDocument), quirks = !!BROWSER.ie && document.compatMode !== 'CSS1Compat', parent = container[0], scrolled, position, parentOffset, overflow; function scroll(e, i) { pos.left += i * e.scrollLeft(); pos.top += i * e.scrollTop(); } // Compensate for non-static containers offset do { if((position = $.css(parent, 'position')) !== 'static') { if(position === 'fixed') { parentOffset = parent.getBoundingClientRect(); scroll(ownerDocument, -1); } else { parentOffset = $(parent).position(); parentOffset.left += parseFloat($.css(parent, 'borderLeftWidth')) || 0; parentOffset.top += parseFloat($.css(parent, 'borderTopWidth')) || 0; } pos.left -= parentOffset.left + (parseFloat($.css(parent, 'marginLeft')) || 0); pos.top -= parentOffset.top + (parseFloat($.css(parent, 'marginTop')) || 0); // If this is the first parent element with an overflow of "scroll" or "auto", store it if(!scrolled && (overflow = $.css(parent, 'overflow')) !== 'hidden' && overflow !== 'visible') { scrolled = $(parent); } } } while(parent = parent.offsetParent); // Compensate for containers scroll if it also has an offsetParent (or in IE quirks mode) if(scrolled && (scrolled[0] !== ownerDocument[0] || quirks)) { scroll(scrolled, 1); } return pos; }; // Corner class var C = (CORNER = PROTOTYPE.reposition.Corner = function(corner, forceY) { corner = ('' + corner).replace(/([A-Z])/, ' $1').replace(/middle/gi, CENTER).toLowerCase(); this.x = (corner.match(/left|right/i) || corner.match(/center/) || ['inherit'])[0].toLowerCase(); this.y = (corner.match(/top|bottom|center/i) || ['inherit'])[0].toLowerCase(); this.forceY = !!forceY; var f = corner.charAt(0); this.precedance = f === 't' || f === 'b' ? Y : X; }).prototype; C.invert = function(z, center) { this[z] = this[z] === LEFT ? RIGHT : this[z] === RIGHT ? LEFT : center || this[z]; }; C.string = function(join) { var x = this.x, y = this.y; var result = x !== y ? x === 'center' || y !== 'center' && (this.precedance === Y || this.forceY) ? [y,x] : [x,y] : [x]; return join !== false ? result.join(' ') : result; }; C.abbrev = function() { var result = this.string(false); return result[0].charAt(0) + (result[1] && result[1].charAt(0) || ''); }; C.clone = function() { return new CORNER( this.string(), this.forceY ); }; ; PROTOTYPE.toggle = function(state, event) { var cache = this.cache, options = this.options, tooltip = this.tooltip; // Try to prevent flickering when tooltip overlaps show element if(event) { if((/over|enter/).test(event.type) && cache.event && (/out|leave/).test(cache.event.type) && options.show.target.add(event.target).length === options.show.target.length && tooltip.has(event.relatedTarget).length) { return this; } // Cache event cache.event = $.event.fix(event); } // If we're currently waiting and we've just hidden... stop it this.waiting && !state && (this.hiddenDuringWait = TRUE); // Render the tooltip if showing and it isn't already if(!this.rendered) { return state ? this.render(1) : this; } else if(this.destroyed || this.disabled) { return this; } var type = state ? 'show' : 'hide', opts = this.options[type], posOptions = this.options.position, contentOptions = this.options.content, width = this.tooltip.css('width'), visible = this.tooltip.is(':visible'), animate = state || opts.target.length === 1, sameTarget = !event || opts.target.length < 2 || cache.target[0] === event.target, identicalState, allow, after; // Detect state if valid one isn't provided if((typeof state).search('boolean|number')) { state = !visible; } // Check if the tooltip is in an identical state to the new would-be state identicalState = !tooltip.is(':animated') && visible === state && sameTarget; // Fire tooltip(show/hide) event and check if destroyed allow = !identicalState ? !!this._trigger(type, [90]) : NULL; // Check to make sure the tooltip wasn't destroyed in the callback if(this.destroyed) { return this; } // If the user didn't stop the method prematurely and we're showing the tooltip, focus it if(allow !== FALSE && state) { this.focus(event); } // If the state hasn't changed or the user stopped it, return early if(!allow || identicalState) { return this; } // Set ARIA hidden attribute $.attr(tooltip[0], 'aria-hidden', !!!state); // Execute state specific properties if(state) { // Store show origin coordinates this.mouse && (cache.origin = $.event.fix(this.mouse)); // Update tooltip content & title if it's a dynamic function if($.isFunction(contentOptions.text)) { this._updateContent(contentOptions.text, FALSE); } if($.isFunction(contentOptions.title)) { this._updateTitle(contentOptions.title, FALSE); } // Cache mousemove events for positioning purposes (if not already tracking) if(!trackingBound && posOptions.target === 'mouse' && posOptions.adjust.mouse) { $(document).bind('mousemove.'+NAMESPACE, this._storeMouse); trackingBound = TRUE; } // Update the tooltip position (set width first to prevent viewport/max-width issues) if(!width) { tooltip.css('width', tooltip.outerWidth(FALSE)); } this.reposition(event, arguments[2]); if(!width) { tooltip.css('width', ''); } // Hide other tooltips if tooltip is solo if(!!opts.solo) { (typeof opts.solo === 'string' ? $(opts.solo) : $(SELECTOR, opts.solo)) .not(tooltip).not(opts.target).qtip('hide', new $.Event('tooltipsolo')); } } else { // Clear show timer if we're hiding clearTimeout(this.timers.show); // Remove cached origin on hide delete cache.origin; // Remove mouse tracking event if not needed (all tracking qTips are hidden) if(trackingBound && !$(SELECTOR+'[tracking="true"]:visible', opts.solo).not(tooltip).length) { $(document).unbind('mousemove.'+NAMESPACE); trackingBound = FALSE; } // Blur the tooltip this.blur(event); } // Define post-animation, state specific properties after = $.proxy(function() { if(state) { // Prevent antialias from disappearing in IE by removing filter if(BROWSER.ie) { tooltip[0].style.removeAttribute('filter'); } // Remove overflow setting to prevent tip bugs tooltip.css('overflow', ''); // Autofocus elements if enabled if('string' === typeof opts.autofocus) { $(this.options.show.autofocus, tooltip).focus(); } // If set, hide tooltip when inactive for delay period this.options.show.target.trigger('qtip-'+this.id+'-inactive'); } else { // Reset CSS states tooltip.css({ display: '', visibility: '', opacity: '', left: '', top: '' }); } // tooltipvisible/tooltiphidden events this._trigger(state ? 'visible' : 'hidden'); }, this); // If no effect type is supplied, use a simple toggle if(opts.effect === FALSE || animate === FALSE) { tooltip[ type ](); after(); } // Use custom function if provided else if($.isFunction(opts.effect)) { tooltip.stop(1, 1); opts.effect.call(tooltip, this); tooltip.queue('fx', function(n) { after(); n(); }); } // Use basic fade function by default else { tooltip.fadeTo(90, state ? 1 : 0, after); } // If inactive hide method is set, active it if(state) { opts.target.trigger('qtip-'+this.id+'-inactive'); } return this; }; PROTOTYPE.show = function(event) { return this.toggle(TRUE, event); }; PROTOTYPE.hide = function(event) { return this.toggle(FALSE, event); }; ;PROTOTYPE.focus = function(event) { if(!this.rendered || this.destroyed) { return this; } var qtips = $(SELECTOR), tooltip = this.tooltip, curIndex = parseInt(tooltip[0].style.zIndex, 10), newIndex = QTIP.zindex + qtips.length; // Only update the z-index if it has changed and tooltip is not already focused if(!tooltip.hasClass(CLASS_FOCUS)) { // tooltipfocus event if(this._trigger('focus', [newIndex], event)) { // Only update z-index's if they've changed if(curIndex !== newIndex) { // Reduce our z-index's and keep them properly ordered qtips.each(function() { if(this.style.zIndex > curIndex) { this.style.zIndex = this.style.zIndex - 1; } }); // Fire blur event for focused tooltip qtips.filter('.' + CLASS_FOCUS).qtip('blur', event); } // Set the new z-index tooltip.addClass(CLASS_FOCUS)[0].style.zIndex = newIndex; } } return this; }; PROTOTYPE.blur = function(event) { if(!this.rendered || this.destroyed) { return this; } // Set focused status to FALSE this.tooltip.removeClass(CLASS_FOCUS); // tooltipblur event this._trigger('blur', [ this.tooltip.css('zIndex') ], event); return this; }; ;PROTOTYPE.disable = function(state) { if(this.destroyed) { return this; } // If 'toggle' is passed, toggle the current state if(state === 'toggle') { state = !(this.rendered ? this.tooltip.hasClass(CLASS_DISABLED) : this.disabled); } // Disable if no state passed else if('boolean' !== typeof state) { state = TRUE; } if(this.rendered) { this.tooltip.toggleClass(CLASS_DISABLED, state) .attr('aria-disabled', state); } this.disabled = !!state; return this; }; PROTOTYPE.enable = function() { return this.disable(FALSE); }; ;PROTOTYPE._createButton = function() { var self = this, elements = this.elements, tooltip = elements.tooltip, button = this.options.content.button, isString = typeof button === 'string', close = isString ? button : 'Close tooltip'; if(elements.button) { elements.button.remove(); } // Use custom button if one was supplied by user, else use default if(button.jquery) { elements.button = button; } else { elements.button = $('', { 'class': 'qtip-close ' + (this.options.style.widget ? '' : NAMESPACE+'-icon'), 'title': close, 'aria-label': close }) .prepend( $('', { 'class': 'ui-icon ui-icon-close', 'html': '×' }) ); } // Create button and setup attributes elements.button.appendTo(elements.titlebar || tooltip) .attr('role', 'button') .click(function(event) { if(!tooltip.hasClass(CLASS_DISABLED)) { self.hide(event); } return FALSE; }); }; PROTOTYPE._updateButton = function(button) { // Make sure tooltip is rendered and if not, return if(!this.rendered) { return FALSE; } var elem = this.elements.button; if(button) { this._createButton(); } else { elem.remove(); } }; ;// Widget class creator function createWidgetClass(cls) { return WIDGET.concat('').join(cls ? '-'+cls+' ' : ' '); } // Widget class setter method PROTOTYPE._setWidget = function() { var on = this.options.style.widget, elements = this.elements, tooltip = elements.tooltip, disabled = tooltip.hasClass(CLASS_DISABLED); tooltip.removeClass(CLASS_DISABLED); CLASS_DISABLED = on ? 'ui-state-disabled' : 'qtip-disabled'; tooltip.toggleClass(CLASS_DISABLED, disabled); tooltip.toggleClass('ui-helper-reset '+createWidgetClass(), on).toggleClass(CLASS_DEFAULT, this.options.style.def && !on); if(elements.content) { elements.content.toggleClass( createWidgetClass('content'), on); } if(elements.titlebar) { elements.titlebar.toggleClass( createWidgetClass('header'), on); } if(elements.button) { elements.button.toggleClass(NAMESPACE+'-icon', !on); } }; ;function delay(callback, duration) { // If tooltip has displayed, start hide timer if(duration > 0) { return setTimeout( $.proxy(callback, this), duration ); } else{ callback.call(this); } } function showMethod(event) { if(this.tooltip.hasClass(CLASS_DISABLED)) { return; } // Clear hide timers clearTimeout(this.timers.show); clearTimeout(this.timers.hide); // Start show timer this.timers.show = delay.call(this, function() { this.toggle(TRUE, event); }, this.options.show.delay ); } function hideMethod(event) { if(this.tooltip.hasClass(CLASS_DISABLED) || this.destroyed) { return; } // Check if new target was actually the tooltip element var relatedTarget = $(event.relatedTarget), ontoTooltip = relatedTarget.closest(SELECTOR)[0] === this.tooltip[0], ontoTarget = relatedTarget[0] === this.options.show.target[0]; // Clear timers and stop animation queue clearTimeout(this.timers.show); clearTimeout(this.timers.hide); // Prevent hiding if tooltip is fixed and event target is the tooltip. // Or if mouse positioning is enabled and cursor momentarily overlaps if(this !== relatedTarget[0] && (this.options.position.target === 'mouse' && ontoTooltip) || this.options.hide.fixed && ( (/mouse(out|leave|move)/).test(event.type) && (ontoTooltip || ontoTarget)) ) { /* eslint-disable no-empty */ try { event.preventDefault(); event.stopImmediatePropagation(); } catch(e) {} /* eslint-enable no-empty */ return; } // If tooltip has displayed, start hide timer this.timers.hide = delay.call(this, function() { this.toggle(FALSE, event); }, this.options.hide.delay, this ); } function inactiveMethod(event) { if(this.tooltip.hasClass(CLASS_DISABLED) || !this.options.hide.inactive) { return; } // Clear timer clearTimeout(this.timers.inactive); this.timers.inactive = delay.call(this, function(){ this.hide(event); }, this.options.hide.inactive ); } function repositionMethod(event) { if(this.rendered && this.tooltip[0].offsetWidth > 0) { this.reposition(event); } } // Store mouse coordinates PROTOTYPE._storeMouse = function(event) { (this.mouse = $.event.fix(event)).type = 'mousemove'; return this; }; // Bind events PROTOTYPE._bind = function(targets, events, method, suffix, context) { if(!targets || !method || !events.length) { return; } var ns = '.' + this._id + (suffix ? '-'+suffix : ''); $(targets).bind( (events.split ? events : events.join(ns + ' ')) + ns, $.proxy(method, context || this) ); return this; }; PROTOTYPE._unbind = function(targets, suffix) { targets && $(targets).unbind('.' + this._id + (suffix ? '-'+suffix : '')); return this; }; // Global delegation helper function delegate(selector, events, method) { $(document.body).delegate(selector, (events.split ? events : events.join('.'+NAMESPACE + ' ')) + '.'+NAMESPACE, function() { var api = QTIP.api[ $.attr(this, ATTR_ID) ]; api && !api.disabled && method.apply(api, arguments); } ); } // Event trigger PROTOTYPE._trigger = function(type, args, event) { var callback = new $.Event('tooltip'+type); callback.originalEvent = event && $.extend({}, event) || this.cache.event || NULL; this.triggering = type; this.tooltip.trigger(callback, [this].concat(args || [])); this.triggering = FALSE; return !callback.isDefaultPrevented(); }; PROTOTYPE._bindEvents = function(showEvents, hideEvents, showTargets, hideTargets, showCallback, hideCallback) { // Get tasrgets that lye within both var similarTargets = showTargets.filter( hideTargets ).add( hideTargets.filter(showTargets) ), toggleEvents = []; // If hide and show targets are the same... if(similarTargets.length) { // Filter identical show/hide events $.each(hideEvents, function(i, type) { var showIndex = $.inArray(type, showEvents); // Both events are identical, remove from both hide and show events // and append to toggleEvents showIndex > -1 && toggleEvents.push( showEvents.splice( showIndex, 1 )[0] ); }); // Toggle events are special case of identical show/hide events, which happen in sequence if(toggleEvents.length) { // Bind toggle events to the similar targets this._bind(similarTargets, toggleEvents, function(event) { var state = this.rendered ? this.tooltip[0].offsetWidth > 0 : false; (state ? hideCallback : showCallback).call(this, event); }); // Remove the similar targets from the regular show/hide bindings showTargets = showTargets.not(similarTargets); hideTargets = hideTargets.not(similarTargets); } } // Apply show/hide/toggle events this._bind(showTargets, showEvents, showCallback); this._bind(hideTargets, hideEvents, hideCallback); }; PROTOTYPE._assignInitialEvents = function(event) { var options = this.options, showTarget = options.show.target, hideTarget = options.hide.target, showEvents = options.show.event ? $.trim('' + options.show.event).split(' ') : [], hideEvents = options.hide.event ? $.trim('' + options.hide.event).split(' ') : []; // Catch remove/removeqtip events on target element to destroy redundant tooltips this._bind(this.elements.target, ['remove', 'removeqtip'], function() { this.destroy(true); }, 'destroy'); /* * Make sure hoverIntent functions properly by using mouseleave as a hide event if * mouseenter/mouseout is used for show.event, even if it isn't in the users options. */ if(/mouse(over|enter)/i.test(options.show.event) && !/mouse(out|leave)/i.test(options.hide.event)) { hideEvents.push('mouseleave'); } /* * Also make sure initial mouse targetting works correctly by caching mousemove coords * on show targets before the tooltip has rendered. Also set onTarget when triggered to * keep mouse tracking working. */ this._bind(showTarget, 'mousemove', function(moveEvent) { this._storeMouse(moveEvent); this.cache.onTarget = TRUE; }); // Define hoverIntent function function hoverIntent(hoverEvent) { // Only continue if tooltip isn't disabled if(this.disabled || this.destroyed) { return FALSE; } // Cache the event data this.cache.event = hoverEvent && $.event.fix(hoverEvent); this.cache.target = hoverEvent && $(hoverEvent.target); // Start the event sequence clearTimeout(this.timers.show); this.timers.show = delay.call(this, function() { this.render(typeof hoverEvent === 'object' || options.show.ready); }, options.prerender ? 0 : options.show.delay ); } // Filter and bind events this._bindEvents(showEvents, hideEvents, showTarget, hideTarget, hoverIntent, function() { if(!this.timers) { return FALSE; } clearTimeout(this.timers.show); }); // Prerendering is enabled, create tooltip now if(options.show.ready || options.prerender) { hoverIntent.call(this, event); } }; // Event assignment method PROTOTYPE._assignEvents = function() { var self = this, options = this.options, posOptions = options.position, tooltip = this.tooltip, showTarget = options.show.target, hideTarget = options.hide.target, containerTarget = posOptions.container, viewportTarget = posOptions.viewport, documentTarget = $(document), windowTarget = $(window), showEvents = options.show.event ? $.trim('' + options.show.event).split(' ') : [], hideEvents = options.hide.event ? $.trim('' + options.hide.event).split(' ') : []; // Assign passed event callbacks $.each(options.events, function(name, callback) { self._bind(tooltip, name === 'toggle' ? ['tooltipshow','tooltiphide'] : ['tooltip'+name], callback, null, tooltip); }); // Hide tooltips when leaving current window/frame (but not select/option elements) if(/mouse(out|leave)/i.test(options.hide.event) && options.hide.leave === 'window') { this._bind(documentTarget, ['mouseout', 'blur'], function(event) { if(!/select|option/.test(event.target.nodeName) && !event.relatedTarget) { this.hide(event); } }); } // Enable hide.fixed by adding appropriate class if(options.hide.fixed) { hideTarget = hideTarget.add( tooltip.addClass(CLASS_FIXED) ); } /* * Make sure hoverIntent functions properly by using mouseleave to clear show timer if * mouseenter/mouseout is used for show.event, even if it isn't in the users options. */ else if(/mouse(over|enter)/i.test(options.show.event)) { this._bind(hideTarget, 'mouseleave', function() { clearTimeout(this.timers.show); }); } // Hide tooltip on document mousedown if unfocus events are enabled if(('' + options.hide.event).indexOf('unfocus') > -1) { this._bind(containerTarget.closest('html'), ['mousedown', 'touchstart'], function(event) { var elem = $(event.target), enabled = this.rendered && !this.tooltip.hasClass(CLASS_DISABLED) && this.tooltip[0].offsetWidth > 0, isAncestor = elem.parents(SELECTOR).filter(this.tooltip[0]).length > 0; if(elem[0] !== this.target[0] && elem[0] !== this.tooltip[0] && !isAncestor && !this.target.has(elem[0]).length && enabled ) { this.hide(event); } }); } // Check if the tooltip hides when inactive if('number' === typeof options.hide.inactive) { // Bind inactive method to show target(s) as a custom event this._bind(showTarget, 'qtip-'+this.id+'-inactive', inactiveMethod, 'inactive'); // Define events which reset the 'inactive' event handler this._bind(hideTarget.add(tooltip), QTIP.inactiveEvents, inactiveMethod); } // Filter and bind events this._bindEvents(showEvents, hideEvents, showTarget, hideTarget, showMethod, hideMethod); // Mouse movement bindings this._bind(showTarget.add(tooltip), 'mousemove', function(event) { // Check if the tooltip hides when mouse is moved a certain distance if('number' === typeof options.hide.distance) { var origin = this.cache.origin || {}, limit = this.options.hide.distance, abs = Math.abs; // Check if the movement has gone beyond the limit, and hide it if so if(abs(event.pageX - origin.pageX) >= limit || abs(event.pageY - origin.pageY) >= limit) { this.hide(event); } } // Cache mousemove coords on show targets this._storeMouse(event); }); // Mouse positioning events if(posOptions.target === 'mouse') { // If mouse adjustment is on... if(posOptions.adjust.mouse) { // Apply a mouseleave event so we don't get problems with overlapping if(options.hide.event) { // Track if we're on the target or not this._bind(showTarget, ['mouseenter', 'mouseleave'], function(event) { if(!this.cache) {return FALSE; } this.cache.onTarget = event.type === 'mouseenter'; }); } // Update tooltip position on mousemove this._bind(documentTarget, 'mousemove', function(event) { // Update the tooltip position only if the tooltip is visible and adjustment is enabled if(this.rendered && this.cache.onTarget && !this.tooltip.hasClass(CLASS_DISABLED) && this.tooltip[0].offsetWidth > 0) { this.reposition(event); } }); } } // Adjust positions of the tooltip on window resize if enabled if(posOptions.adjust.resize || viewportTarget.length) { this._bind( $.event.special.resize ? viewportTarget : windowTarget, 'resize', repositionMethod ); } // Adjust tooltip position on scroll of the window or viewport element if present if(posOptions.adjust.scroll) { this._bind( windowTarget.add(posOptions.container), 'scroll', repositionMethod ); } }; // Un-assignment method PROTOTYPE._unassignEvents = function() { var options = this.options, showTargets = options.show.target, hideTargets = options.hide.target, targets = $.grep([ this.elements.target[0], this.rendered && this.tooltip[0], options.position.container[0], options.position.viewport[0], options.position.container.closest('html')[0], // unfocus window, document ], function(i) { return typeof i === 'object'; }); // Add show and hide targets if they're valid if(showTargets && showTargets.toArray) { targets = targets.concat(showTargets.toArray()); } if(hideTargets && hideTargets.toArray) { targets = targets.concat(hideTargets.toArray()); } // Unbind the events this._unbind(targets) ._unbind(targets, 'destroy') ._unbind(targets, 'inactive'); }; // Apply common event handlers using delegate (avoids excessive .bind calls!) $(function() { delegate(SELECTOR, ['mouseenter', 'mouseleave'], function(event) { var state = event.type === 'mouseenter', tooltip = $(event.currentTarget), target = $(event.relatedTarget || event.target), options = this.options; // On mouseenter... if(state) { // Focus the tooltip on mouseenter (z-index stacking) this.focus(event); // Clear hide timer on tooltip hover to prevent it from closing tooltip.hasClass(CLASS_FIXED) && !tooltip.hasClass(CLASS_DISABLED) && clearTimeout(this.timers.hide); } // On mouseleave... else { // When mouse tracking is enabled, hide when we leave the tooltip and not onto the show target (if a hide event is set) if(options.position.target === 'mouse' && options.position.adjust.mouse && options.hide.event && options.show.target && !target.closest(options.show.target[0]).length) { this.hide(event); } } // Add hover class tooltip.toggleClass(CLASS_HOVER, state); }); // Define events which reset the 'inactive' event handler delegate('['+ATTR_ID+']', INACTIVE_EVENTS, inactiveMethod); }); ;// Initialization method function init(elem, id, opts) { var obj, posOptions, attr, config, title, // Setup element references docBody = $(document.body), // Use document body instead of document element if needed newTarget = elem[0] === document ? docBody : elem, // Grab metadata from element if plugin is present metadata = elem.metadata ? elem.metadata(opts.metadata) : NULL, // If metadata type if HTML5, grab 'name' from the object instead, or use the regular data object otherwise metadata5 = opts.metadata.type === 'html5' && metadata ? metadata[opts.metadata.name] : NULL, // Grab data from metadata.name (or data-qtipopts as fallback) using .data() method, html5 = elem.data(opts.metadata.name || 'qtipopts'); // If we don't get an object returned attempt to parse it manualyl without parseJSON /* eslint-disable no-empty */ try { html5 = typeof html5 === 'string' ? $.parseJSON(html5) : html5; } catch(e) {} /* eslint-enable no-empty */ // Merge in and sanitize metadata config = $.extend(TRUE, {}, QTIP.defaults, opts, typeof html5 === 'object' ? sanitizeOptions(html5) : NULL, sanitizeOptions(metadata5 || metadata)); // Re-grab our positioning options now we've merged our metadata and set id to passed value posOptions = config.position; config.id = id; // Setup missing content if none is detected if('boolean' === typeof config.content.text) { attr = elem.attr(config.content.attr); // Grab from supplied attribute if available if(config.content.attr !== FALSE && attr) { config.content.text = attr; } // No valid content was found, abort render else { return FALSE; } } // Setup target options if(!posOptions.container.length) { posOptions.container = docBody; } if(posOptions.target === FALSE) { posOptions.target = newTarget; } if(config.show.target === FALSE) { config.show.target = newTarget; } if(config.show.solo === TRUE) { config.show.solo = posOptions.container.closest('body'); } if(config.hide.target === FALSE) { config.hide.target = newTarget; } if(config.position.viewport === TRUE) { config.position.viewport = posOptions.container; } // Ensure we only use a single container posOptions.container = posOptions.container.eq(0); // Convert position corner values into x and y strings posOptions.at = new CORNER(posOptions.at, TRUE); posOptions.my = new CORNER(posOptions.my); // Destroy previous tooltip if overwrite is enabled, or skip element if not if(elem.data(NAMESPACE)) { if(config.overwrite) { elem.qtip('destroy', true); } else if(config.overwrite === FALSE) { return FALSE; } } // Add has-qtip attribute elem.attr(ATTR_HAS, id); // Remove title attribute and store it if present if(config.suppress && (title = elem.attr('title'))) { // Final attr call fixes event delegatiom and IE default tooltip showing problem elem.removeAttr('title').attr(oldtitle, title).attr('title', ''); } // Initialize the tooltip and add API reference obj = new QTip(elem, config, id, !!attr); elem.data(NAMESPACE, obj); return obj; } // jQuery $.fn extension method QTIP = $.fn.qtip = function(options, notation, newValue) { var command = ('' + options).toLowerCase(), // Parse command returned = NULL, args = $.makeArray(arguments).slice(1), event = args[args.length - 1], opts = this[0] ? $.data(this[0], NAMESPACE) : NULL; // Check for API request if(!arguments.length && opts || command === 'api') { return opts; } // Execute API command if present else if('string' === typeof options) { this.each(function() { var api = $.data(this, NAMESPACE); if(!api) { return TRUE; } // Cache the event if possible if(event && event.timeStamp) { api.cache.event = event; } // Check for specific API commands if(notation && (command === 'option' || command === 'options')) { if(newValue !== undefined || $.isPlainObject(notation)) { api.set(notation, newValue); } else { returned = api.get(notation); return FALSE; } } // Execute API command else if(api[command]) { api[command].apply(api, args); } }); return returned !== NULL ? returned : this; } // No API commands. validate provided options and setup qTips else if('object' === typeof options || !arguments.length) { // Sanitize options first opts = sanitizeOptions($.extend(TRUE, {}, options)); return this.each(function(i) { var api, id; // Find next available ID, or use custom ID if provided id = $.isArray(opts.id) ? opts.id[i] : opts.id; id = !id || id === FALSE || id.length < 1 || QTIP.api[id] ? QTIP.nextid++ : id; // Initialize the qTip and re-grab newly sanitized options api = init($(this), id, opts); if(api === FALSE) { return TRUE; } else { QTIP.api[id] = api; } // Initialize plugins $.each(PLUGINS, function() { if(this.initialize === 'initialize') { this(api); } }); // Assign initial pre-render events api._assignInitialEvents(event); }); } }; // Expose class $.qtip = QTip; // Populated in render method QTIP.api = {}; ;$.each({ /* Allow other plugins to successfully retrieve the title of an element with a qTip applied */ attr: function(attr, val) { if(this.length) { var self = this[0], title = 'title', api = $.data(self, 'qtip'); if(attr === title && api && api.options && 'object' === typeof api && 'object' === typeof api.options && api.options.suppress) { if(arguments.length < 2) { return $.attr(self, oldtitle); } // If qTip is rendered and title was originally used as content, update it if(api && api.options.content.attr === title && api.cache.attr) { api.set('content.text', val); } // Use the regular attr method to set, then cache the result return this.attr(oldtitle, val); } } return $.fn['attr'+replaceSuffix].apply(this, arguments); }, /* Allow clone to correctly retrieve cached title attributes */ clone: function(keepData) { // Clone our element using the real clone method var elems = $.fn['clone'+replaceSuffix].apply(this, arguments); // Grab all elements with an oldtitle set, and change it to regular title attribute, if keepData is false if(!keepData) { elems.filter('['+oldtitle+']').attr('title', function() { return $.attr(this, oldtitle); }) .removeAttr(oldtitle); } return elems; } }, function(name, func) { if(!func || $.fn[name+replaceSuffix]) { return TRUE; } var old = $.fn[name+replaceSuffix] = $.fn[name]; $.fn[name] = function() { return func.apply(this, arguments) || old.apply(this, arguments); }; }); /* Fire off 'removeqtip' handler in $.cleanData if jQuery UI not present (it already does similar). * This snippet is taken directly from jQuery UI source code found here: * http://code.jquery.com/ui/jquery-ui-git.js */ if(!$.ui) { $['cleanData'+replaceSuffix] = $.cleanData; $.cleanData = function( elems ) { for(var i = 0, elem; (elem = $( elems[i] )).length; i++) { if(elem.attr(ATTR_HAS)) { /* eslint-disable no-empty */ try { elem.triggerHandler('removeqtip'); } catch( e ) {} /* eslint-enable no-empty */ } } $['cleanData'+replaceSuffix].apply(this, arguments); }; } ;// qTip version QTIP.version = '3.0.2'; // Base ID for all qTips QTIP.nextid = 0; // Inactive events array QTIP.inactiveEvents = INACTIVE_EVENTS; // Base z-index for all qTips QTIP.zindex = 15000; // Define configuration defaults QTIP.defaults = { prerender: FALSE, id: FALSE, overwrite: TRUE, suppress: TRUE, content: { text: TRUE, attr: 'title', title: FALSE, button: FALSE }, position: { my: 'top left', at: 'bottom right', target: FALSE, container: FALSE, viewport: FALSE, adjust: { x: 0, y: 0, mouse: TRUE, scroll: TRUE, resize: TRUE, method: 'flipinvert flipinvert' }, effect: function(api, pos) { $(this).animate(pos, { duration: 200, queue: FALSE }); } }, show: { target: FALSE, event: 'mouseenter', effect: TRUE, delay: 90, solo: FALSE, ready: FALSE, autofocus: FALSE }, hide: { target: FALSE, event: 'mouseleave', effect: TRUE, delay: 0, fixed: FALSE, inactive: FALSE, leave: 'window', distance: FALSE }, style: { classes: '', widget: FALSE, width: FALSE, height: FALSE, def: TRUE }, events: { render: NULL, move: NULL, show: NULL, hide: NULL, toggle: NULL, visible: NULL, hidden: NULL, focus: NULL, blur: NULL } }; ;})); }( window, document )); qTip2-3.0.2/dist/basic/jquery.qtip.min.map000066400000000000000000001077271263162617100203360ustar00rootroot00000000000000{"version":3,"sources":["jquery.qtip.js"],"names":["window","document","undefined","factory","define","amd","jQuery","fn","qtip","$","QTip","target","options","id","attr","this","tooltip","NULL","elements","_id","NAMESPACE","timers","img","plugins","cache","event","disabled","FALSE","onTooltip","lastClass","rendered","destroyed","waiting","hiddenDuringWait","positioning","triggering","invalidOpt","a","type","invalidContent","c","isFunction","length","jquery","then","sanitizeOptions","opts","content","text","ajax","once","metadata","done","api","loading","deferred","extend","context","success","error","newContent","set","xhr","status","isPlainObject","title","button","position","my","at","show","TRUE","ready","hide","style","classes","each","PLUGINS","sanitize","convertNotation","notation","obj","i","option","levels","split","pop","setCallback","args","category","rule","match","checks","hasOwnProperty","RegExp","exec","push","apply","createWidgetClass","cls","WIDGET","concat","join","delay","callback","duration","setTimeout","proxy","call","showMethod","hasClass","CLASS_DISABLED","clearTimeout","toggle","hideMethod","relatedTarget","ontoTooltip","closest","SELECTOR","ontoTarget","fixed","test","preventDefault","stopImmediatePropagation","e","inactiveMethod","inactive","repositionMethod","offsetWidth","reposition","delegate","selector","events","method","body","QTIP","ATTR_ID","arguments","init","elem","posOptions","config","docBody","newTarget","metadata5","name","html5","data","parseJSON","defaults","container","solo","viewport","eq","CORNER","overwrite","ATTR_HAS","suppress","removeAttr","oldtitle","PROTOTYPE","CHECKS","trackingBound","X","Y","TOP","LEFT","BOTTOM","RIGHT","CENTER","INACTIVE_EVENTS","CLASS_FIXED","CLASS_DEFAULT","CLASS_FOCUS","CLASS_HOVER","replaceSuffix","BROWSER","ie","v","createElement","innerHTML","getElementsByTagName","NaN","iOS","parseFloat","navigator","userAgent","replace","prototype","_when","deferreds","when","render","self","posClass","_createPosClass","class","width","height","tracking","adjust","mouse","role","aria-live","aria-atomic","aria-describedby","aria-hidden","toggleClass","appendTo","append","_createTitle","_updateTitle","_createButton","_updateContent","_setWidget","instance","initialize","_unassignEvents","_assignEvents","_trigger","destroy","immediate","process","timer","stop","find","remove","end","removeData","one","builtin","^id$","o","prev","nextid","newId","^prerender","^content.text$","^content.attr$","^content.title$","_removeTitle","^content.button$","_updateButton","^content.title.(text|button)$","^position.(my|at)$","^position.container$","^show.ready$","^style.classes$","p","removeClass","addClass","^style.(width|height)","css","^style.widget|content.title","^style.def","^events.(render|show|move|hide|focus|blur)$","^(show|hide|position).(event|target|fixed|inactive|leave|distance|viewport|adjust)","get","toLowerCase","result","precedance","string","rmove","rrender","value","val","previous","nodeType","_update","element","empty","display","visibility","html","_waitForContent","images","imagesLoaded","Deferred","resolve","promise","titlebar","widget","insertBefore","substr","abbrev","effect","pluginCalculations","offset","adjusted","newClass","tooltipWidth","outerWidth","tooltipHeight","outerHeight","targetWidth","targetHeight","left","top","visible","isScroll","win","doc","ownerDocument","isArray","x","y","distance","origin","pageX","innerWidth","documentElement","clientWidth","pageY","scrollX","scrollLeft","scrollY","scrollTop","innerHeight","imagemap","is","svg","ownerSVGElement","adjustable","isNaN","queue","next","opacity","removeAttribute","pos","scroll","scrolled","parentOffset","overflow","quirks","compatMode","parent","getBoundingClientRect","offsetParent","C","Corner","corner","forceY","f","charAt","invert","z","center","clone","state","add","has","fix","identicalState","allow","after","contentOptions","animate","sameTarget","search","focus","bind","_storeMouse","not","Event","unbind","blur","autofocus","trigger","n","fadeTo","qtips","curIndex","parseInt","zIndex","newIndex","zindex","filter","disable","enable","isString","close","aria-label","prepend","click","on","def","_bind","targets","suffix","ns","_unbind","originalEvent","isDefaultPrevented","_bindEvents","showEvents","hideEvents","showTargets","hideTargets","showCallback","hideCallback","similarTargets","toggleEvents","showIndex","inArray","splice","_assignInitialEvents","hoverIntent","hoverEvent","prerender","showTarget","hideTarget","trim","moveEvent","onTarget","containerTarget","viewportTarget","documentTarget","windowTarget","leave","nodeName","indexOf","enabled","isAncestor","parents","inactiveEvents","limit","abs","Math","resize","special","grep","toArray","currentTarget","newValue","command","returned","makeArray","slice","timeStamp","keepData","elems","func","old","ui","cleanData","triggerHandler","version","move","hidden"],"mappings":"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","file":"jquery.qtip.min.js"}qTip2-3.0.2/dist/jquery.qtip.css000066400000000000000000000306031263162617100164720ustar00rootroot00000000000000/* * qTip2 - Pretty powerful tooltips - v3.0.2 * http://qtip2.com * * Copyright (c) 2015 * Released under the MIT licenses * http://jquery.org/license * * Date: Tue Dec 8 2015 07:16 GMT+0000 * Plugins: tips modal viewport svg imagemap ie6 * Styles: core basic css3 */ .qtip{ position: absolute; left: -28000px; top: -28000px; display: none; max-width: 280px; min-width: 50px; font-size: 10.5px; line-height: 12px; direction: ltr; box-shadow: none; padding: 0; } .qtip-content{ position: relative; padding: 5px 9px; overflow: hidden; text-align: left; word-wrap: break-word; } .qtip-titlebar{ position: relative; padding: 5px 35px 5px 10px; overflow: hidden; border-width: 0 0 1px; font-weight: bold; } .qtip-titlebar + .qtip-content{ border-top-width: 0 !important; } /* Default close button class */ .qtip-close{ position: absolute; right: -9px; top: -9px; z-index: 11; /* Overlap .qtip-tip */ cursor: pointer; outline: medium none; border: 1px solid transparent; } .qtip-titlebar .qtip-close{ right: 4px; top: 50%; margin-top: -9px; } * html .qtip-titlebar .qtip-close{ top: 16px; } /* IE fix */ .qtip-titlebar .ui-icon, .qtip-icon .ui-icon{ display: block; text-indent: -1000em; direction: ltr; } .qtip-icon, .qtip-icon .ui-icon{ -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; text-decoration: none; } .qtip-icon .ui-icon{ width: 18px; height: 14px; line-height: 14px; text-align: center; text-indent: 0; font: normal bold 10px/13px Tahoma,sans-serif; color: inherit; background: transparent none no-repeat -100em -100em; } /* Applied to 'focused' tooltips e.g. most recently displayed/interacted with */ .qtip-focus{} /* Applied on hover of tooltips i.e. added/removed on mouseenter/mouseleave respectively */ .qtip-hover{} /* Default tooltip style */ .qtip-default{ border: 1px solid #F1D031; background-color: #FFFFA3; color: #555; } .qtip-default .qtip-titlebar{ background-color: #FFEF93; } .qtip-default .qtip-icon{ border-color: #CCC; background: #F1F1F1; color: #777; } .qtip-default .qtip-titlebar .qtip-close{ border-color: #AAA; color: #111; } /*! Light tooltip style */ .qtip-light{ background-color: white; border-color: #E2E2E2; color: #454545; } .qtip-light .qtip-titlebar{ background-color: #f1f1f1; } /*! Dark tooltip style */ .qtip-dark{ background-color: #505050; border-color: #303030; color: #f3f3f3; } .qtip-dark .qtip-titlebar{ background-color: #404040; } .qtip-dark .qtip-icon{ border-color: #444; } .qtip-dark .qtip-titlebar .ui-state-hover{ border-color: #303030; } /*! Cream tooltip style */ .qtip-cream{ background-color: #FBF7AA; border-color: #F9E98E; color: #A27D35; } .qtip-cream .qtip-titlebar{ background-color: #F0DE7D; } .qtip-cream .qtip-close .qtip-icon{ background-position: -82px 0; } /*! Red tooltip style */ .qtip-red{ background-color: #F78B83; border-color: #D95252; color: #912323; } .qtip-red .qtip-titlebar{ background-color: #F06D65; } .qtip-red .qtip-close .qtip-icon{ background-position: -102px 0; } .qtip-red .qtip-icon{ border-color: #D95252; } .qtip-red .qtip-titlebar .ui-state-hover{ border-color: #D95252; } /*! Green tooltip style */ .qtip-green{ background-color: #CAED9E; border-color: #90D93F; color: #3F6219; } .qtip-green .qtip-titlebar{ background-color: #B0DE78; } .qtip-green .qtip-close .qtip-icon{ background-position: -42px 0; } /*! Blue tooltip style */ .qtip-blue{ background-color: #E5F6FE; border-color: #ADD9ED; color: #5E99BD; } .qtip-blue .qtip-titlebar{ background-color: #D0E9F5; } .qtip-blue .qtip-close .qtip-icon{ background-position: -2px 0; } .qtip-shadow{ -webkit-box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15); -moz-box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15); box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15); } /* Add rounded corners to your tooltips in: FF3+, Chrome 2+, Opera 10.6+, IE9+, Safari 2+ */ .qtip-rounded, .qtip-tipsy, .qtip-bootstrap{ -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; } .qtip-rounded .qtip-titlebar{ -moz-border-radius: 4px 4px 0 0; -webkit-border-radius: 4px 4px 0 0; border-radius: 4px 4px 0 0; } /* Youtube tooltip style */ .qtip-youtube{ -moz-border-radius: 2px; -webkit-border-radius: 2px; border-radius: 2px; -webkit-box-shadow: 0 0 3px #333; -moz-box-shadow: 0 0 3px #333; box-shadow: 0 0 3px #333; color: white; border: 0 solid transparent; background: #4A4A4A; background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0,#4A4A4A),color-stop(100%,black)); background-image: -webkit-linear-gradient(top,#4A4A4A 0,black 100%); background-image: -moz-linear-gradient(top,#4A4A4A 0,black 100%); background-image: -ms-linear-gradient(top,#4A4A4A 0,black 100%); background-image: -o-linear-gradient(top,#4A4A4A 0,black 100%); } .qtip-youtube .qtip-titlebar{ background-color: #4A4A4A; background-color: rgba(0,0,0,0); } .qtip-youtube .qtip-content{ padding: .75em; font: 12px arial,sans-serif; filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#4a4a4a,EndColorStr=#000000); -ms-filter: "progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#4a4a4a,EndColorStr=#000000);"; } .qtip-youtube .qtip-icon{ border-color: #222; } .qtip-youtube .qtip-titlebar .ui-state-hover{ border-color: #303030; } /* jQuery TOOLS Tooltip style */ .qtip-jtools{ background: #232323; background: rgba(0, 0, 0, 0.7); background-image: -webkit-gradient(linear, left top, left bottom, from(#717171), to(#232323)); background-image: -moz-linear-gradient(top, #717171, #232323); background-image: -webkit-linear-gradient(top, #717171, #232323); background-image: -ms-linear-gradient(top, #717171, #232323); background-image: -o-linear-gradient(top, #717171, #232323); border: 2px solid #ddd; border: 2px solid rgba(241,241,241,1); -moz-border-radius: 2px; -webkit-border-radius: 2px; border-radius: 2px; -webkit-box-shadow: 0 0 12px #333; -moz-box-shadow: 0 0 12px #333; box-shadow: 0 0 12px #333; } /* IE Specific */ .qtip-jtools .qtip-titlebar{ background-color: transparent; filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A); -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A)"; } .qtip-jtools .qtip-content{ filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323); -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323)"; } .qtip-jtools .qtip-titlebar, .qtip-jtools .qtip-content{ background: transparent; color: white; border: 0 dashed transparent; } .qtip-jtools .qtip-icon{ border-color: #555; } .qtip-jtools .qtip-titlebar .ui-state-hover{ border-color: #333; } /* Cluetip style */ .qtip-cluetip{ -webkit-box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4); -moz-box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4); box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4); background-color: #D9D9C2; color: #111; border: 0 dashed transparent; } .qtip-cluetip .qtip-titlebar{ background-color: #87876A; color: white; border: 0 dashed transparent; } .qtip-cluetip .qtip-icon{ border-color: #808064; } .qtip-cluetip .qtip-titlebar .ui-state-hover{ border-color: #696952; color: #696952; } /* Tipsy style */ .qtip-tipsy{ background: black; background: rgba(0, 0, 0, .87); color: white; border: 0 solid transparent; font-size: 11px; font-family: 'Lucida Grande', sans-serif; font-weight: bold; line-height: 16px; text-shadow: 0 1px black; } .qtip-tipsy .qtip-titlebar{ padding: 6px 35px 0 10px; background-color: transparent; } .qtip-tipsy .qtip-content{ padding: 6px 10px; } .qtip-tipsy .qtip-icon{ border-color: #222; text-shadow: none; } .qtip-tipsy .qtip-titlebar .ui-state-hover{ border-color: #303030; } /* Tipped style */ .qtip-tipped{ border: 3px solid #959FA9; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; background-color: #F9F9F9; color: #454545; font-weight: normal; font-family: serif; } .qtip-tipped .qtip-titlebar{ border-bottom-width: 0; color: white; background: #3A79B8; background-image: -webkit-gradient(linear, left top, left bottom, from(#3A79B8), to(#2E629D)); background-image: -webkit-linear-gradient(top, #3A79B8, #2E629D); background-image: -moz-linear-gradient(top, #3A79B8, #2E629D); background-image: -ms-linear-gradient(top, #3A79B8, #2E629D); background-image: -o-linear-gradient(top, #3A79B8, #2E629D); filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D); -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D)"; } .qtip-tipped .qtip-icon{ border: 2px solid #285589; background: #285589; } .qtip-tipped .qtip-icon .ui-icon{ background-color: #FBFBFB; color: #555; } /** * Twitter Bootstrap style. * * Tested with IE 8, IE 9, Chrome 18, Firefox 9, Opera 11. * Does not work with IE 7. */ .qtip-bootstrap{ /** Taken from Bootstrap body */ font-size: 14px; line-height: 20px; color: #333333; /** Taken from Bootstrap .popover */ padding: 1px; background-color: #ffffff; border: 1px solid #ccc; border: 1px solid rgba(0, 0, 0, 0.2); -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); -webkit-background-clip: padding-box; -moz-background-clip: padding; background-clip: padding-box; } .qtip-bootstrap .qtip-titlebar{ /** Taken from Bootstrap .popover-title */ padding: 8px 14px; margin: 0; font-size: 14px; font-weight: normal; line-height: 18px; background-color: #f7f7f7; border-bottom: 1px solid #ebebeb; -webkit-border-radius: 5px 5px 0 0; -moz-border-radius: 5px 5px 0 0; border-radius: 5px 5px 0 0; } .qtip-bootstrap .qtip-titlebar .qtip-close{ /** * Overrides qTip2: * .qtip-titlebar .qtip-close{ * [...] * right: 4px; * top: 50%; * [...] * border-style: solid; * } */ right: 11px; top: 45%; border-style: none; } .qtip-bootstrap .qtip-content{ /** Taken from Bootstrap .popover-content */ padding: 9px 14px; } .qtip-bootstrap .qtip-icon{ /** * Overrides qTip2: * .qtip-default .qtip-icon { * border-color: #CCC; * background: #F1F1F1; * color: #777; * } */ background: transparent; } .qtip-bootstrap .qtip-icon .ui-icon{ /** * Overrides qTip2: * .qtip-icon .ui-icon{ * width: 18px; * height: 14px; * } */ width: auto; height: auto; /* Taken from Bootstrap .close */ float: right; font-size: 20px; font-weight: bold; line-height: 18px; color: #000000; text-shadow: 0 1px 0 #ffffff; opacity: 0.2; filter: alpha(opacity=20); } .qtip-bootstrap .qtip-icon .ui-icon:hover{ /* Taken from Bootstrap .close:hover */ color: #000000; text-decoration: none; cursor: pointer; opacity: 0.4; filter: alpha(opacity=40); } /* IE9 fix - removes all filters */ .qtip:not(.ie9haxors) div.qtip-content, .qtip:not(.ie9haxors) div.qtip-titlebar{ filter: none; -ms-filter: none; } .qtip .qtip-tip{ margin: 0 auto; overflow: hidden; z-index: 10; } /* Opera bug #357 - Incorrect tip position https://github.com/Craga89/qTip2/issues/367 */ x:-o-prefocus, .qtip .qtip-tip{ visibility: hidden; } .qtip .qtip-tip, .qtip .qtip-tip .qtip-vml, .qtip .qtip-tip canvas{ position: absolute; color: #123456; background: transparent; border: 0 dashed transparent; } .qtip .qtip-tip canvas{ top: 0; left: 0; } .qtip .qtip-tip .qtip-vml{ behavior: url(#default#VML); display: inline-block; visibility: visible; } #qtip-overlay{ position: fixed; left: 0; top: 0; width: 100%; height: 100%; } /* Applied to modals with show.modal.blur set to true */ #qtip-overlay.blurs{ cursor: pointer; } /* Change opacity of overlay here */ #qtip-overlay div{ position: absolute; left: 0; top: 0; width: 100%; height: 100%; background-color: black; opacity: 0.7; filter:alpha(opacity=70); -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)"; } .qtipmodal-ie6fix{ position: absolute !important; } qTip2-3.0.2/dist/jquery.qtip.js000066400000000000000000003104601263162617100163200ustar00rootroot00000000000000/* * qTip2 - Pretty powerful tooltips - v3.0.2 * http://qtip2.com * * Copyright (c) 2015 * Released under the MIT licenses * http://jquery.org/license * * Date: Tue Dec 8 2015 07:16 GMT+0000 * Plugins: tips modal viewport svg imagemap ie6 * Styles: core basic css3 */ /*global window: false, jQuery: false, console: false, define: false */ /* Cache window, document, undefined */ (function( window, document, undefined ) { // Uses AMD or browser globals to create a jQuery plugin. (function( factory ) { "use strict"; if(typeof define === 'function' && define.amd) { define(['jquery'], factory); } else if(jQuery && !jQuery.fn.qtip) { factory(jQuery); } } (function($) { "use strict"; // Enable ECMAScript "strict" operation for this function. See more: http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/ ;// Munge the primitives - Paul Irish tip var TRUE = true, FALSE = false, NULL = null, // Common variables X = 'x', Y = 'y', WIDTH = 'width', HEIGHT = 'height', // Positioning sides TOP = 'top', LEFT = 'left', BOTTOM = 'bottom', RIGHT = 'right', CENTER = 'center', // Position adjustment types FLIP = 'flip', FLIPINVERT = 'flipinvert', SHIFT = 'shift', // Shortcut vars QTIP, PROTOTYPE, CORNER, CHECKS, PLUGINS = {}, NAMESPACE = 'qtip', ATTR_HAS = 'data-hasqtip', ATTR_ID = 'data-qtip-id', WIDGET = ['ui-widget', 'ui-tooltip'], SELECTOR = '.'+NAMESPACE, INACTIVE_EVENTS = 'click dblclick mousedown mouseup mousemove mouseleave mouseenter'.split(' '), CLASS_FIXED = NAMESPACE+'-fixed', CLASS_DEFAULT = NAMESPACE + '-default', CLASS_FOCUS = NAMESPACE + '-focus', CLASS_HOVER = NAMESPACE + '-hover', CLASS_DISABLED = NAMESPACE+'-disabled', replaceSuffix = '_replacedByqTip', oldtitle = 'oldtitle', trackingBound, // Browser detection BROWSER = { /* * IE version detection * * Adapted from: http://ajaxian.com/archives/attack-of-the-ie-conditional-comment * Credit to James Padolsey for the original implemntation! */ ie: (function() { /* eslint-disable no-empty */ var v, i; for ( v = 4, i = document.createElement('div'); (i.innerHTML = '') && i.getElementsByTagName('i')[0]; v+=1 ) {} return v > 4 ? v : NaN; /* eslint-enable no-empty */ })(), /* * iOS version detection */ iOS: parseFloat( ('' + (/CPU.*OS ([0-9_]{1,5})|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent) || [0,''])[1]) .replace('undefined', '3_2').replace('_', '.').replace('_', '') ) || FALSE }; ;function QTip(target, options, id, attr) { // Elements and ID this.id = id; this.target = target; this.tooltip = NULL; this.elements = { target: target }; // Internal constructs this._id = NAMESPACE + '-' + id; this.timers = { img: {} }; this.options = options; this.plugins = {}; // Cache object this.cache = { event: {}, target: $(), disabled: FALSE, attr: attr, onTooltip: FALSE, lastClass: '' }; // Set the initial flags this.rendered = this.destroyed = this.disabled = this.waiting = this.hiddenDuringWait = this.positioning = this.triggering = FALSE; } PROTOTYPE = QTip.prototype; PROTOTYPE._when = function(deferreds) { return $.when.apply($, deferreds); }; PROTOTYPE.render = function(show) { if(this.rendered || this.destroyed) { return this; } // If tooltip has already been rendered, exit var self = this, options = this.options, cache = this.cache, elements = this.elements, text = options.content.text, title = options.content.title, button = options.content.button, posOptions = options.position, deferreds = []; // Add ARIA attributes to target $.attr(this.target[0], 'aria-describedby', this._id); // Create public position object that tracks current position corners cache.posClass = this._createPosClass( (this.position = { my: posOptions.my, at: posOptions.at }).my ); // Create tooltip element this.tooltip = elements.tooltip = $('
', { 'id': this._id, 'class': [ NAMESPACE, CLASS_DEFAULT, options.style.classes, cache.posClass ].join(' '), 'width': options.style.width || '', 'height': options.style.height || '', 'tracking': posOptions.target === 'mouse' && posOptions.adjust.mouse, /* ARIA specific attributes */ 'role': 'alert', 'aria-live': 'polite', 'aria-atomic': FALSE, 'aria-describedby': this._id + '-content', 'aria-hidden': TRUE }) .toggleClass(CLASS_DISABLED, this.disabled) .attr(ATTR_ID, this.id) .data(NAMESPACE, this) .appendTo(posOptions.container) .append( // Create content element elements.content = $('
', { 'class': NAMESPACE + '-content', 'id': this._id + '-content', 'aria-atomic': TRUE }) ); // Set rendered flag and prevent redundant reposition calls for now this.rendered = -1; this.positioning = TRUE; // Create title... if(title) { this._createTitle(); // Update title only if its not a callback (called in toggle if so) if(!$.isFunction(title)) { deferreds.push( this._updateTitle(title, FALSE) ); } } // Create button if(button) { this._createButton(); } // Set proper rendered flag and update content if not a callback function (called in toggle) if(!$.isFunction(text)) { deferreds.push( this._updateContent(text, FALSE) ); } this.rendered = TRUE; // Setup widget classes this._setWidget(); // Initialize 'render' plugins $.each(PLUGINS, function(name) { var instance; if(this.initialize === 'render' && (instance = this(self))) { self.plugins[name] = instance; } }); // Unassign initial events and assign proper events this._unassignEvents(); this._assignEvents(); // When deferreds have completed this._when(deferreds).then(function() { // tooltiprender event self._trigger('render'); // Reset flags self.positioning = FALSE; // Show tooltip if not hidden during wait period if(!self.hiddenDuringWait && (options.show.ready || show)) { self.toggle(TRUE, cache.event, FALSE); } self.hiddenDuringWait = FALSE; }); // Expose API QTIP.api[this.id] = this; return this; }; PROTOTYPE.destroy = function(immediate) { // Set flag the signify destroy is taking place to plugins // and ensure it only gets destroyed once! if(this.destroyed) { return this.target; } function process() { if(this.destroyed) { return; } this.destroyed = TRUE; var target = this.target, title = target.attr(oldtitle), timer; // Destroy tooltip if rendered if(this.rendered) { this.tooltip.stop(1,0).find('*').remove().end().remove(); } // Destroy all plugins $.each(this.plugins, function() { this.destroy && this.destroy(); }); // Clear timers for (timer in this.timers) { if (this.timers.hasOwnProperty(timer)) { clearTimeout(this.timers[timer]); } } // Remove api object and ARIA attributes target.removeData(NAMESPACE) .removeAttr(ATTR_ID) .removeAttr(ATTR_HAS) .removeAttr('aria-describedby'); // Reset old title attribute if removed if(this.options.suppress && title) { target.attr('title', title).removeAttr(oldtitle); } // Remove qTip events associated with this API this._unassignEvents(); // Remove ID from used id objects, and delete object references // for better garbage collection and leak protection this.options = this.elements = this.cache = this.timers = this.plugins = this.mouse = NULL; // Delete epoxsed API object delete QTIP.api[this.id]; } // If an immediate destroy is needed if((immediate !== TRUE || this.triggering === 'hide') && this.rendered) { this.tooltip.one('tooltiphidden', $.proxy(process, this)); !this.triggering && this.hide(); } // If we're not in the process of hiding... process else { process.call(this); } return this.target; }; ;function invalidOpt(a) { return a === NULL || $.type(a) !== 'object'; } function invalidContent(c) { return !($.isFunction(c) || c && c.attr) || c.length || $.type(c) === 'object' && (c.jquery || c.then); } // Option object sanitizer function sanitizeOptions(opts) { var content, text, ajax, once; if(invalidOpt(opts)) { return FALSE; } if(invalidOpt(opts.metadata)) { opts.metadata = { type: opts.metadata }; } if('content' in opts) { content = opts.content; if(invalidOpt(content) || content.jquery || content.done) { text = invalidContent(content) ? FALSE : content; content = opts.content = { text: text }; } else { text = content.text; } // DEPRECATED - Old content.ajax plugin functionality // Converts it into the proper Deferred syntax if('ajax' in content) { ajax = content.ajax; once = ajax && ajax.once !== FALSE; delete content.ajax; content.text = function(event, api) { var loading = text || $(this).attr(api.options.content.attr) || 'Loading...', deferred = $.ajax( $.extend({}, ajax, { context: api }) ) .then(ajax.success, NULL, ajax.error) .then(function(newContent) { if(newContent && once) { api.set('content.text', newContent); } return newContent; }, function(xhr, status, error) { if(api.destroyed || xhr.status === 0) { return; } api.set('content.text', status + ': ' + error); }); return !once ? (api.set('content.text', loading), deferred) : loading; }; } if('title' in content) { if($.isPlainObject(content.title)) { content.button = content.title.button; content.title = content.title.text; } if(invalidContent(content.title || FALSE)) { content.title = FALSE; } } } if('position' in opts && invalidOpt(opts.position)) { opts.position = { my: opts.position, at: opts.position }; } if('show' in opts && invalidOpt(opts.show)) { opts.show = opts.show.jquery ? { target: opts.show } : opts.show === TRUE ? { ready: TRUE } : { event: opts.show }; } if('hide' in opts && invalidOpt(opts.hide)) { opts.hide = opts.hide.jquery ? { target: opts.hide } : { event: opts.hide }; } if('style' in opts && invalidOpt(opts.style)) { opts.style = { classes: opts.style }; } // Sanitize plugin options $.each(PLUGINS, function() { this.sanitize && this.sanitize(opts); }); return opts; } // Setup builtin .set() option checks CHECKS = PROTOTYPE.checks = { builtin: { // Core checks '^id$': function(obj, o, v, prev) { var id = v === TRUE ? QTIP.nextid : v, newId = NAMESPACE + '-' + id; if(id !== FALSE && id.length > 0 && !$('#'+newId).length) { this._id = newId; if(this.rendered) { this.tooltip[0].id = this._id; this.elements.content[0].id = this._id + '-content'; this.elements.title[0].id = this._id + '-title'; } } else { obj[o] = prev; } }, '^prerender': function(obj, o, v) { v && !this.rendered && this.render(this.options.show.ready); }, // Content checks '^content.text$': function(obj, o, v) { this._updateContent(v); }, '^content.attr$': function(obj, o, v, prev) { if(this.options.content.text === this.target.attr(prev)) { this._updateContent( this.target.attr(v) ); } }, '^content.title$': function(obj, o, v) { // Remove title if content is null if(!v) { return this._removeTitle(); } // If title isn't already created, create it now and update v && !this.elements.title && this._createTitle(); this._updateTitle(v); }, '^content.button$': function(obj, o, v) { this._updateButton(v); }, '^content.title.(text|button)$': function(obj, o, v) { this.set('content.'+o, v); // Backwards title.text/button compat }, // Position checks '^position.(my|at)$': function(obj, o, v){ if('string' === typeof v) { this.position[o] = obj[o] = new CORNER(v, o === 'at'); } }, '^position.container$': function(obj, o, v){ this.rendered && this.tooltip.appendTo(v); }, // Show checks '^show.ready$': function(obj, o, v) { v && (!this.rendered && this.render(TRUE) || this.toggle(TRUE)); }, // Style checks '^style.classes$': function(obj, o, v, p) { this.rendered && this.tooltip.removeClass(p).addClass(v); }, '^style.(width|height)': function(obj, o, v) { this.rendered && this.tooltip.css(o, v); }, '^style.widget|content.title': function() { this.rendered && this._setWidget(); }, '^style.def': function(obj, o, v) { this.rendered && this.tooltip.toggleClass(CLASS_DEFAULT, !!v); }, // Events check '^events.(render|show|move|hide|focus|blur)$': function(obj, o, v) { this.rendered && this.tooltip[($.isFunction(v) ? '' : 'un') + 'bind']('tooltip'+o, v); }, // Properties which require event reassignment '^(show|hide|position).(event|target|fixed|inactive|leave|distance|viewport|adjust)': function() { if(!this.rendered) { return; } // Set tracking flag var posOptions = this.options.position; this.tooltip.attr('tracking', posOptions.target === 'mouse' && posOptions.adjust.mouse); // Reassign events this._unassignEvents(); this._assignEvents(); } } }; // Dot notation converter function convertNotation(options, notation) { var i = 0, obj, option = options, // Split notation into array levels = notation.split('.'); // Loop through while(option = option[ levels[i++] ]) { if(i < levels.length) { obj = option; } } return [obj || options, levels.pop()]; } PROTOTYPE.get = function(notation) { if(this.destroyed) { return this; } var o = convertNotation(this.options, notation.toLowerCase()), result = o[0][ o[1] ]; return result.precedance ? result.string() : result; }; function setCallback(notation, args) { var category, rule, match; for(category in this.checks) { if (!this.checks.hasOwnProperty(category)) { continue; } for(rule in this.checks[category]) { if (!this.checks[category].hasOwnProperty(rule)) { continue; } if(match = (new RegExp(rule, 'i')).exec(notation)) { args.push(match); if(category === 'builtin' || this.plugins[category]) { this.checks[category][rule].apply( this.plugins[category] || this, args ); } } } } } var rmove = /^position\.(my|at|adjust|target|container|viewport)|style|content|show\.ready/i, rrender = /^prerender|show\.ready/i; PROTOTYPE.set = function(option, value) { if(this.destroyed) { return this; } var rendered = this.rendered, reposition = FALSE, options = this.options, name; // Convert singular option/value pair into object form if('string' === typeof option) { name = option; option = {}; option[name] = value; } else { option = $.extend({}, option); } // Set all of the defined options to their new values $.each(option, function(notation, val) { if(rendered && rrender.test(notation)) { delete option[notation]; return; } // Set new obj value var obj = convertNotation(options, notation.toLowerCase()), previous; previous = obj[0][ obj[1] ]; obj[0][ obj[1] ] = val && val.nodeType ? $(val) : val; // Also check if we need to reposition reposition = rmove.test(notation) || reposition; // Set the new params for the callback option[notation] = [obj[0], obj[1], val, previous]; }); // Re-sanitize options sanitizeOptions(options); /* * Execute any valid callbacks for the set options * Also set positioning flag so we don't get loads of redundant repositioning calls. */ this.positioning = TRUE; $.each(option, $.proxy(setCallback, this)); this.positioning = FALSE; // Update position if needed if(this.rendered && this.tooltip[0].offsetWidth > 0 && reposition) { this.reposition( options.position.target === 'mouse' ? NULL : this.cache.event ); } return this; }; ;PROTOTYPE._update = function(content, element) { var self = this, cache = this.cache; // Make sure tooltip is rendered and content is defined. If not return if(!this.rendered || !content) { return FALSE; } // Use function to parse content if($.isFunction(content)) { content = content.call(this.elements.target, cache.event, this) || ''; } // Handle deferred content if($.isFunction(content.then)) { cache.waiting = TRUE; return content.then(function(c) { cache.waiting = FALSE; return self._update(c, element); }, NULL, function(e) { return self._update(e, element); }); } // If content is null... return false if(content === FALSE || !content && content !== '') { return FALSE; } // Append new content if its a DOM array and show it if hidden if(content.jquery && content.length > 0) { element.empty().append( content.css({ display: 'block', visibility: 'visible' }) ); } // Content is a regular string, insert the new content else { element.html(content); } // Wait for content to be loaded, and reposition return this._waitForContent(element).then(function(images) { if(self.rendered && self.tooltip[0].offsetWidth > 0) { self.reposition(cache.event, !images.length); } }); }; PROTOTYPE._waitForContent = function(element) { var cache = this.cache; // Set flag cache.waiting = TRUE; // If imagesLoaded is included, ensure images have loaded and return promise return ( $.fn.imagesLoaded ? element.imagesLoaded() : new $.Deferred().resolve([]) ) .done(function() { cache.waiting = FALSE; }) .promise(); }; PROTOTYPE._updateContent = function(content, reposition) { this._update(content, this.elements.content, reposition); }; PROTOTYPE._updateTitle = function(content, reposition) { if(this._update(content, this.elements.title, reposition) === FALSE) { this._removeTitle(FALSE); } }; PROTOTYPE._createTitle = function() { var elements = this.elements, id = this._id+'-title'; // Destroy previous title element, if present if(elements.titlebar) { this._removeTitle(); } // Create title bar and title elements elements.titlebar = $('
', { 'class': NAMESPACE + '-titlebar ' + (this.options.style.widget ? createWidgetClass('header') : '') }) .append( elements.title = $('
', { 'id': id, 'class': NAMESPACE + '-title', 'aria-atomic': TRUE }) ) .insertBefore(elements.content) // Button-specific events .delegate('.qtip-close', 'mousedown keydown mouseup keyup mouseout', function(event) { $(this).toggleClass('ui-state-active ui-state-focus', event.type.substr(-4) === 'down'); }) .delegate('.qtip-close', 'mouseover mouseout', function(event){ $(this).toggleClass('ui-state-hover', event.type === 'mouseover'); }); // Create button if enabled if(this.options.content.button) { this._createButton(); } }; PROTOTYPE._removeTitle = function(reposition) { var elements = this.elements; if(elements.title) { elements.titlebar.remove(); elements.titlebar = elements.title = elements.button = NULL; // Reposition if enabled if(reposition !== FALSE) { this.reposition(); } } }; ;PROTOTYPE._createPosClass = function(my) { return NAMESPACE + '-pos-' + (my || this.options.position.my).abbrev(); }; PROTOTYPE.reposition = function(event, effect) { if(!this.rendered || this.positioning || this.destroyed) { return this; } // Set positioning flag this.positioning = TRUE; var cache = this.cache, tooltip = this.tooltip, posOptions = this.options.position, target = posOptions.target, my = posOptions.my, at = posOptions.at, viewport = posOptions.viewport, container = posOptions.container, adjust = posOptions.adjust, method = adjust.method.split(' '), tooltipWidth = tooltip.outerWidth(FALSE), tooltipHeight = tooltip.outerHeight(FALSE), targetWidth = 0, targetHeight = 0, type = tooltip.css('position'), position = { left: 0, top: 0 }, visible = tooltip[0].offsetWidth > 0, isScroll = event && event.type === 'scroll', win = $(window), doc = container[0].ownerDocument, mouse = this.mouse, pluginCalculations, offset, adjusted, newClass; // Check if absolute position was passed if($.isArray(target) && target.length === 2) { // Force left top and set position at = { x: LEFT, y: TOP }; position = { left: target[0], top: target[1] }; } // Check if mouse was the target else if(target === 'mouse') { // Force left top to allow flipping at = { x: LEFT, y: TOP }; // Use the mouse origin that caused the show event, if distance hiding is enabled if((!adjust.mouse || this.options.hide.distance) && cache.origin && cache.origin.pageX) { event = cache.origin; } // Use cached event for resize/scroll events else if(!event || event && (event.type === 'resize' || event.type === 'scroll')) { event = cache.event; } // Otherwise, use the cached mouse coordinates if available else if(mouse && mouse.pageX) { event = mouse; } // Calculate body and container offset and take them into account below if(type !== 'static') { position = container.offset(); } if(doc.body.offsetWidth !== (window.innerWidth || doc.documentElement.clientWidth)) { offset = $(document.body).offset(); } // Use event coordinates for position position = { left: event.pageX - position.left + (offset && offset.left || 0), top: event.pageY - position.top + (offset && offset.top || 0) }; // Scroll events are a pain, some browsers if(adjust.mouse && isScroll && mouse) { position.left -= (mouse.scrollX || 0) - win.scrollLeft(); position.top -= (mouse.scrollY || 0) - win.scrollTop(); } } // Target wasn't mouse or absolute... else { // Check if event targetting is being used if(target === 'event') { if(event && event.target && event.type !== 'scroll' && event.type !== 'resize') { cache.target = $(event.target); } else if(!event.target) { cache.target = this.elements.target; } } else if(target !== 'event'){ cache.target = $(target.jquery ? target : this.elements.target); } target = cache.target; // Parse the target into a jQuery object and make sure there's an element present target = $(target).eq(0); if(target.length === 0) { return this; } // Check if window or document is the target else if(target[0] === document || target[0] === window) { targetWidth = BROWSER.iOS ? window.innerWidth : target.width(); targetHeight = BROWSER.iOS ? window.innerHeight : target.height(); if(target[0] === window) { position = { top: (viewport || target).scrollTop(), left: (viewport || target).scrollLeft() }; } } // Check if the target is an element else if(PLUGINS.imagemap && target.is('area')) { pluginCalculations = PLUGINS.imagemap(this, target, at, PLUGINS.viewport ? method : FALSE); } // Check if the target is an SVG element else if(PLUGINS.svg && target && target[0].ownerSVGElement) { pluginCalculations = PLUGINS.svg(this, target, at, PLUGINS.viewport ? method : FALSE); } // Otherwise use regular jQuery methods else { targetWidth = target.outerWidth(FALSE); targetHeight = target.outerHeight(FALSE); position = target.offset(); } // Parse returned plugin values into proper variables if(pluginCalculations) { targetWidth = pluginCalculations.width; targetHeight = pluginCalculations.height; offset = pluginCalculations.offset; position = pluginCalculations.position; } // Adjust position to take into account offset parents position = this.reposition.offset(target, position, container); // Adjust for position.fixed tooltips (and also iOS scroll bug in v3.2-4.0 & v4.3-4.3.2) if(BROWSER.iOS > 3.1 && BROWSER.iOS < 4.1 || BROWSER.iOS >= 4.3 && BROWSER.iOS < 4.33 || !BROWSER.iOS && type === 'fixed' ){ position.left -= win.scrollLeft(); position.top -= win.scrollTop(); } // Adjust position relative to target if(!pluginCalculations || pluginCalculations && pluginCalculations.adjustable !== FALSE) { position.left += at.x === RIGHT ? targetWidth : at.x === CENTER ? targetWidth / 2 : 0; position.top += at.y === BOTTOM ? targetHeight : at.y === CENTER ? targetHeight / 2 : 0; } } // Adjust position relative to tooltip position.left += adjust.x + (my.x === RIGHT ? -tooltipWidth : my.x === CENTER ? -tooltipWidth / 2 : 0); position.top += adjust.y + (my.y === BOTTOM ? -tooltipHeight : my.y === CENTER ? -tooltipHeight / 2 : 0); // Use viewport adjustment plugin if enabled if(PLUGINS.viewport) { adjusted = position.adjusted = PLUGINS.viewport( this, position, posOptions, targetWidth, targetHeight, tooltipWidth, tooltipHeight ); // Apply offsets supplied by positioning plugin (if used) if(offset && adjusted.left) { position.left += offset.left; } if(offset && adjusted.top) { position.top += offset.top; } // Apply any new 'my' position if(adjusted.my) { this.position.my = adjusted.my; } } // Viewport adjustment is disabled, set values to zero else { position.adjusted = { left: 0, top: 0 }; } // Set tooltip position class if it's changed if(cache.posClass !== (newClass = this._createPosClass(this.position.my))) { cache.posClass = newClass; tooltip.removeClass(cache.posClass).addClass(newClass); } // tooltipmove event if(!this._trigger('move', [position, viewport.elem || viewport], event)) { return this; } delete position.adjusted; // If effect is disabled, target it mouse, no animation is defined or positioning gives NaN out, set CSS directly if(effect === FALSE || !visible || isNaN(position.left) || isNaN(position.top) || target === 'mouse' || !$.isFunction(posOptions.effect)) { tooltip.css(position); } // Use custom function if provided else if($.isFunction(posOptions.effect)) { posOptions.effect.call(tooltip, this, $.extend({}, position)); tooltip.queue(function(next) { // Reset attributes to avoid cross-browser rendering bugs $(this).css({ opacity: '', height: '' }); if(BROWSER.ie) { this.style.removeAttribute('filter'); } next(); }); } // Set positioning flag this.positioning = FALSE; return this; }; // Custom (more correct for qTip!) offset calculator PROTOTYPE.reposition.offset = function(elem, pos, container) { if(!container[0]) { return pos; } var ownerDocument = $(elem[0].ownerDocument), quirks = !!BROWSER.ie && document.compatMode !== 'CSS1Compat', parent = container[0], scrolled, position, parentOffset, overflow; function scroll(e, i) { pos.left += i * e.scrollLeft(); pos.top += i * e.scrollTop(); } // Compensate for non-static containers offset do { if((position = $.css(parent, 'position')) !== 'static') { if(position === 'fixed') { parentOffset = parent.getBoundingClientRect(); scroll(ownerDocument, -1); } else { parentOffset = $(parent).position(); parentOffset.left += parseFloat($.css(parent, 'borderLeftWidth')) || 0; parentOffset.top += parseFloat($.css(parent, 'borderTopWidth')) || 0; } pos.left -= parentOffset.left + (parseFloat($.css(parent, 'marginLeft')) || 0); pos.top -= parentOffset.top + (parseFloat($.css(parent, 'marginTop')) || 0); // If this is the first parent element with an overflow of "scroll" or "auto", store it if(!scrolled && (overflow = $.css(parent, 'overflow')) !== 'hidden' && overflow !== 'visible') { scrolled = $(parent); } } } while(parent = parent.offsetParent); // Compensate for containers scroll if it also has an offsetParent (or in IE quirks mode) if(scrolled && (scrolled[0] !== ownerDocument[0] || quirks)) { scroll(scrolled, 1); } return pos; }; // Corner class var C = (CORNER = PROTOTYPE.reposition.Corner = function(corner, forceY) { corner = ('' + corner).replace(/([A-Z])/, ' $1').replace(/middle/gi, CENTER).toLowerCase(); this.x = (corner.match(/left|right/i) || corner.match(/center/) || ['inherit'])[0].toLowerCase(); this.y = (corner.match(/top|bottom|center/i) || ['inherit'])[0].toLowerCase(); this.forceY = !!forceY; var f = corner.charAt(0); this.precedance = f === 't' || f === 'b' ? Y : X; }).prototype; C.invert = function(z, center) { this[z] = this[z] === LEFT ? RIGHT : this[z] === RIGHT ? LEFT : center || this[z]; }; C.string = function(join) { var x = this.x, y = this.y; var result = x !== y ? x === 'center' || y !== 'center' && (this.precedance === Y || this.forceY) ? [y,x] : [x,y] : [x]; return join !== false ? result.join(' ') : result; }; C.abbrev = function() { var result = this.string(false); return result[0].charAt(0) + (result[1] && result[1].charAt(0) || ''); }; C.clone = function() { return new CORNER( this.string(), this.forceY ); }; ; PROTOTYPE.toggle = function(state, event) { var cache = this.cache, options = this.options, tooltip = this.tooltip; // Try to prevent flickering when tooltip overlaps show element if(event) { if((/over|enter/).test(event.type) && cache.event && (/out|leave/).test(cache.event.type) && options.show.target.add(event.target).length === options.show.target.length && tooltip.has(event.relatedTarget).length) { return this; } // Cache event cache.event = $.event.fix(event); } // If we're currently waiting and we've just hidden... stop it this.waiting && !state && (this.hiddenDuringWait = TRUE); // Render the tooltip if showing and it isn't already if(!this.rendered) { return state ? this.render(1) : this; } else if(this.destroyed || this.disabled) { return this; } var type = state ? 'show' : 'hide', opts = this.options[type], posOptions = this.options.position, contentOptions = this.options.content, width = this.tooltip.css('width'), visible = this.tooltip.is(':visible'), animate = state || opts.target.length === 1, sameTarget = !event || opts.target.length < 2 || cache.target[0] === event.target, identicalState, allow, after; // Detect state if valid one isn't provided if((typeof state).search('boolean|number')) { state = !visible; } // Check if the tooltip is in an identical state to the new would-be state identicalState = !tooltip.is(':animated') && visible === state && sameTarget; // Fire tooltip(show/hide) event and check if destroyed allow = !identicalState ? !!this._trigger(type, [90]) : NULL; // Check to make sure the tooltip wasn't destroyed in the callback if(this.destroyed) { return this; } // If the user didn't stop the method prematurely and we're showing the tooltip, focus it if(allow !== FALSE && state) { this.focus(event); } // If the state hasn't changed or the user stopped it, return early if(!allow || identicalState) { return this; } // Set ARIA hidden attribute $.attr(tooltip[0], 'aria-hidden', !!!state); // Execute state specific properties if(state) { // Store show origin coordinates this.mouse && (cache.origin = $.event.fix(this.mouse)); // Update tooltip content & title if it's a dynamic function if($.isFunction(contentOptions.text)) { this._updateContent(contentOptions.text, FALSE); } if($.isFunction(contentOptions.title)) { this._updateTitle(contentOptions.title, FALSE); } // Cache mousemove events for positioning purposes (if not already tracking) if(!trackingBound && posOptions.target === 'mouse' && posOptions.adjust.mouse) { $(document).bind('mousemove.'+NAMESPACE, this._storeMouse); trackingBound = TRUE; } // Update the tooltip position (set width first to prevent viewport/max-width issues) if(!width) { tooltip.css('width', tooltip.outerWidth(FALSE)); } this.reposition(event, arguments[2]); if(!width) { tooltip.css('width', ''); } // Hide other tooltips if tooltip is solo if(!!opts.solo) { (typeof opts.solo === 'string' ? $(opts.solo) : $(SELECTOR, opts.solo)) .not(tooltip).not(opts.target).qtip('hide', new $.Event('tooltipsolo')); } } else { // Clear show timer if we're hiding clearTimeout(this.timers.show); // Remove cached origin on hide delete cache.origin; // Remove mouse tracking event if not needed (all tracking qTips are hidden) if(trackingBound && !$(SELECTOR+'[tracking="true"]:visible', opts.solo).not(tooltip).length) { $(document).unbind('mousemove.'+NAMESPACE); trackingBound = FALSE; } // Blur the tooltip this.blur(event); } // Define post-animation, state specific properties after = $.proxy(function() { if(state) { // Prevent antialias from disappearing in IE by removing filter if(BROWSER.ie) { tooltip[0].style.removeAttribute('filter'); } // Remove overflow setting to prevent tip bugs tooltip.css('overflow', ''); // Autofocus elements if enabled if('string' === typeof opts.autofocus) { $(this.options.show.autofocus, tooltip).focus(); } // If set, hide tooltip when inactive for delay period this.options.show.target.trigger('qtip-'+this.id+'-inactive'); } else { // Reset CSS states tooltip.css({ display: '', visibility: '', opacity: '', left: '', top: '' }); } // tooltipvisible/tooltiphidden events this._trigger(state ? 'visible' : 'hidden'); }, this); // If no effect type is supplied, use a simple toggle if(opts.effect === FALSE || animate === FALSE) { tooltip[ type ](); after(); } // Use custom function if provided else if($.isFunction(opts.effect)) { tooltip.stop(1, 1); opts.effect.call(tooltip, this); tooltip.queue('fx', function(n) { after(); n(); }); } // Use basic fade function by default else { tooltip.fadeTo(90, state ? 1 : 0, after); } // If inactive hide method is set, active it if(state) { opts.target.trigger('qtip-'+this.id+'-inactive'); } return this; }; PROTOTYPE.show = function(event) { return this.toggle(TRUE, event); }; PROTOTYPE.hide = function(event) { return this.toggle(FALSE, event); }; ;PROTOTYPE.focus = function(event) { if(!this.rendered || this.destroyed) { return this; } var qtips = $(SELECTOR), tooltip = this.tooltip, curIndex = parseInt(tooltip[0].style.zIndex, 10), newIndex = QTIP.zindex + qtips.length; // Only update the z-index if it has changed and tooltip is not already focused if(!tooltip.hasClass(CLASS_FOCUS)) { // tooltipfocus event if(this._trigger('focus', [newIndex], event)) { // Only update z-index's if they've changed if(curIndex !== newIndex) { // Reduce our z-index's and keep them properly ordered qtips.each(function() { if(this.style.zIndex > curIndex) { this.style.zIndex = this.style.zIndex - 1; } }); // Fire blur event for focused tooltip qtips.filter('.' + CLASS_FOCUS).qtip('blur', event); } // Set the new z-index tooltip.addClass(CLASS_FOCUS)[0].style.zIndex = newIndex; } } return this; }; PROTOTYPE.blur = function(event) { if(!this.rendered || this.destroyed) { return this; } // Set focused status to FALSE this.tooltip.removeClass(CLASS_FOCUS); // tooltipblur event this._trigger('blur', [ this.tooltip.css('zIndex') ], event); return this; }; ;PROTOTYPE.disable = function(state) { if(this.destroyed) { return this; } // If 'toggle' is passed, toggle the current state if(state === 'toggle') { state = !(this.rendered ? this.tooltip.hasClass(CLASS_DISABLED) : this.disabled); } // Disable if no state passed else if('boolean' !== typeof state) { state = TRUE; } if(this.rendered) { this.tooltip.toggleClass(CLASS_DISABLED, state) .attr('aria-disabled', state); } this.disabled = !!state; return this; }; PROTOTYPE.enable = function() { return this.disable(FALSE); }; ;PROTOTYPE._createButton = function() { var self = this, elements = this.elements, tooltip = elements.tooltip, button = this.options.content.button, isString = typeof button === 'string', close = isString ? button : 'Close tooltip'; if(elements.button) { elements.button.remove(); } // Use custom button if one was supplied by user, else use default if(button.jquery) { elements.button = button; } else { elements.button = $('', { 'class': 'qtip-close ' + (this.options.style.widget ? '' : NAMESPACE+'-icon'), 'title': close, 'aria-label': close }) .prepend( $('', { 'class': 'ui-icon ui-icon-close', 'html': '×' }) ); } // Create button and setup attributes elements.button.appendTo(elements.titlebar || tooltip) .attr('role', 'button') .click(function(event) { if(!tooltip.hasClass(CLASS_DISABLED)) { self.hide(event); } return FALSE; }); }; PROTOTYPE._updateButton = function(button) { // Make sure tooltip is rendered and if not, return if(!this.rendered) { return FALSE; } var elem = this.elements.button; if(button) { this._createButton(); } else { elem.remove(); } }; ;// Widget class creator function createWidgetClass(cls) { return WIDGET.concat('').join(cls ? '-'+cls+' ' : ' '); } // Widget class setter method PROTOTYPE._setWidget = function() { var on = this.options.style.widget, elements = this.elements, tooltip = elements.tooltip, disabled = tooltip.hasClass(CLASS_DISABLED); tooltip.removeClass(CLASS_DISABLED); CLASS_DISABLED = on ? 'ui-state-disabled' : 'qtip-disabled'; tooltip.toggleClass(CLASS_DISABLED, disabled); tooltip.toggleClass('ui-helper-reset '+createWidgetClass(), on).toggleClass(CLASS_DEFAULT, this.options.style.def && !on); if(elements.content) { elements.content.toggleClass( createWidgetClass('content'), on); } if(elements.titlebar) { elements.titlebar.toggleClass( createWidgetClass('header'), on); } if(elements.button) { elements.button.toggleClass(NAMESPACE+'-icon', !on); } }; ;function delay(callback, duration) { // If tooltip has displayed, start hide timer if(duration > 0) { return setTimeout( $.proxy(callback, this), duration ); } else{ callback.call(this); } } function showMethod(event) { if(this.tooltip.hasClass(CLASS_DISABLED)) { return; } // Clear hide timers clearTimeout(this.timers.show); clearTimeout(this.timers.hide); // Start show timer this.timers.show = delay.call(this, function() { this.toggle(TRUE, event); }, this.options.show.delay ); } function hideMethod(event) { if(this.tooltip.hasClass(CLASS_DISABLED) || this.destroyed) { return; } // Check if new target was actually the tooltip element var relatedTarget = $(event.relatedTarget), ontoTooltip = relatedTarget.closest(SELECTOR)[0] === this.tooltip[0], ontoTarget = relatedTarget[0] === this.options.show.target[0]; // Clear timers and stop animation queue clearTimeout(this.timers.show); clearTimeout(this.timers.hide); // Prevent hiding if tooltip is fixed and event target is the tooltip. // Or if mouse positioning is enabled and cursor momentarily overlaps if(this !== relatedTarget[0] && (this.options.position.target === 'mouse' && ontoTooltip) || this.options.hide.fixed && ( (/mouse(out|leave|move)/).test(event.type) && (ontoTooltip || ontoTarget)) ) { /* eslint-disable no-empty */ try { event.preventDefault(); event.stopImmediatePropagation(); } catch(e) {} /* eslint-enable no-empty */ return; } // If tooltip has displayed, start hide timer this.timers.hide = delay.call(this, function() { this.toggle(FALSE, event); }, this.options.hide.delay, this ); } function inactiveMethod(event) { if(this.tooltip.hasClass(CLASS_DISABLED) || !this.options.hide.inactive) { return; } // Clear timer clearTimeout(this.timers.inactive); this.timers.inactive = delay.call(this, function(){ this.hide(event); }, this.options.hide.inactive ); } function repositionMethod(event) { if(this.rendered && this.tooltip[0].offsetWidth > 0) { this.reposition(event); } } // Store mouse coordinates PROTOTYPE._storeMouse = function(event) { (this.mouse = $.event.fix(event)).type = 'mousemove'; return this; }; // Bind events PROTOTYPE._bind = function(targets, events, method, suffix, context) { if(!targets || !method || !events.length) { return; } var ns = '.' + this._id + (suffix ? '-'+suffix : ''); $(targets).bind( (events.split ? events : events.join(ns + ' ')) + ns, $.proxy(method, context || this) ); return this; }; PROTOTYPE._unbind = function(targets, suffix) { targets && $(targets).unbind('.' + this._id + (suffix ? '-'+suffix : '')); return this; }; // Global delegation helper function delegate(selector, events, method) { $(document.body).delegate(selector, (events.split ? events : events.join('.'+NAMESPACE + ' ')) + '.'+NAMESPACE, function() { var api = QTIP.api[ $.attr(this, ATTR_ID) ]; api && !api.disabled && method.apply(api, arguments); } ); } // Event trigger PROTOTYPE._trigger = function(type, args, event) { var callback = new $.Event('tooltip'+type); callback.originalEvent = event && $.extend({}, event) || this.cache.event || NULL; this.triggering = type; this.tooltip.trigger(callback, [this].concat(args || [])); this.triggering = FALSE; return !callback.isDefaultPrevented(); }; PROTOTYPE._bindEvents = function(showEvents, hideEvents, showTargets, hideTargets, showCallback, hideCallback) { // Get tasrgets that lye within both var similarTargets = showTargets.filter( hideTargets ).add( hideTargets.filter(showTargets) ), toggleEvents = []; // If hide and show targets are the same... if(similarTargets.length) { // Filter identical show/hide events $.each(hideEvents, function(i, type) { var showIndex = $.inArray(type, showEvents); // Both events are identical, remove from both hide and show events // and append to toggleEvents showIndex > -1 && toggleEvents.push( showEvents.splice( showIndex, 1 )[0] ); }); // Toggle events are special case of identical show/hide events, which happen in sequence if(toggleEvents.length) { // Bind toggle events to the similar targets this._bind(similarTargets, toggleEvents, function(event) { var state = this.rendered ? this.tooltip[0].offsetWidth > 0 : false; (state ? hideCallback : showCallback).call(this, event); }); // Remove the similar targets from the regular show/hide bindings showTargets = showTargets.not(similarTargets); hideTargets = hideTargets.not(similarTargets); } } // Apply show/hide/toggle events this._bind(showTargets, showEvents, showCallback); this._bind(hideTargets, hideEvents, hideCallback); }; PROTOTYPE._assignInitialEvents = function(event) { var options = this.options, showTarget = options.show.target, hideTarget = options.hide.target, showEvents = options.show.event ? $.trim('' + options.show.event).split(' ') : [], hideEvents = options.hide.event ? $.trim('' + options.hide.event).split(' ') : []; // Catch remove/removeqtip events on target element to destroy redundant tooltips this._bind(this.elements.target, ['remove', 'removeqtip'], function() { this.destroy(true); }, 'destroy'); /* * Make sure hoverIntent functions properly by using mouseleave as a hide event if * mouseenter/mouseout is used for show.event, even if it isn't in the users options. */ if(/mouse(over|enter)/i.test(options.show.event) && !/mouse(out|leave)/i.test(options.hide.event)) { hideEvents.push('mouseleave'); } /* * Also make sure initial mouse targetting works correctly by caching mousemove coords * on show targets before the tooltip has rendered. Also set onTarget when triggered to * keep mouse tracking working. */ this._bind(showTarget, 'mousemove', function(moveEvent) { this._storeMouse(moveEvent); this.cache.onTarget = TRUE; }); // Define hoverIntent function function hoverIntent(hoverEvent) { // Only continue if tooltip isn't disabled if(this.disabled || this.destroyed) { return FALSE; } // Cache the event data this.cache.event = hoverEvent && $.event.fix(hoverEvent); this.cache.target = hoverEvent && $(hoverEvent.target); // Start the event sequence clearTimeout(this.timers.show); this.timers.show = delay.call(this, function() { this.render(typeof hoverEvent === 'object' || options.show.ready); }, options.prerender ? 0 : options.show.delay ); } // Filter and bind events this._bindEvents(showEvents, hideEvents, showTarget, hideTarget, hoverIntent, function() { if(!this.timers) { return FALSE; } clearTimeout(this.timers.show); }); // Prerendering is enabled, create tooltip now if(options.show.ready || options.prerender) { hoverIntent.call(this, event); } }; // Event assignment method PROTOTYPE._assignEvents = function() { var self = this, options = this.options, posOptions = options.position, tooltip = this.tooltip, showTarget = options.show.target, hideTarget = options.hide.target, containerTarget = posOptions.container, viewportTarget = posOptions.viewport, documentTarget = $(document), windowTarget = $(window), showEvents = options.show.event ? $.trim('' + options.show.event).split(' ') : [], hideEvents = options.hide.event ? $.trim('' + options.hide.event).split(' ') : []; // Assign passed event callbacks $.each(options.events, function(name, callback) { self._bind(tooltip, name === 'toggle' ? ['tooltipshow','tooltiphide'] : ['tooltip'+name], callback, null, tooltip); }); // Hide tooltips when leaving current window/frame (but not select/option elements) if(/mouse(out|leave)/i.test(options.hide.event) && options.hide.leave === 'window') { this._bind(documentTarget, ['mouseout', 'blur'], function(event) { if(!/select|option/.test(event.target.nodeName) && !event.relatedTarget) { this.hide(event); } }); } // Enable hide.fixed by adding appropriate class if(options.hide.fixed) { hideTarget = hideTarget.add( tooltip.addClass(CLASS_FIXED) ); } /* * Make sure hoverIntent functions properly by using mouseleave to clear show timer if * mouseenter/mouseout is used for show.event, even if it isn't in the users options. */ else if(/mouse(over|enter)/i.test(options.show.event)) { this._bind(hideTarget, 'mouseleave', function() { clearTimeout(this.timers.show); }); } // Hide tooltip on document mousedown if unfocus events are enabled if(('' + options.hide.event).indexOf('unfocus') > -1) { this._bind(containerTarget.closest('html'), ['mousedown', 'touchstart'], function(event) { var elem = $(event.target), enabled = this.rendered && !this.tooltip.hasClass(CLASS_DISABLED) && this.tooltip[0].offsetWidth > 0, isAncestor = elem.parents(SELECTOR).filter(this.tooltip[0]).length > 0; if(elem[0] !== this.target[0] && elem[0] !== this.tooltip[0] && !isAncestor && !this.target.has(elem[0]).length && enabled ) { this.hide(event); } }); } // Check if the tooltip hides when inactive if('number' === typeof options.hide.inactive) { // Bind inactive method to show target(s) as a custom event this._bind(showTarget, 'qtip-'+this.id+'-inactive', inactiveMethod, 'inactive'); // Define events which reset the 'inactive' event handler this._bind(hideTarget.add(tooltip), QTIP.inactiveEvents, inactiveMethod); } // Filter and bind events this._bindEvents(showEvents, hideEvents, showTarget, hideTarget, showMethod, hideMethod); // Mouse movement bindings this._bind(showTarget.add(tooltip), 'mousemove', function(event) { // Check if the tooltip hides when mouse is moved a certain distance if('number' === typeof options.hide.distance) { var origin = this.cache.origin || {}, limit = this.options.hide.distance, abs = Math.abs; // Check if the movement has gone beyond the limit, and hide it if so if(abs(event.pageX - origin.pageX) >= limit || abs(event.pageY - origin.pageY) >= limit) { this.hide(event); } } // Cache mousemove coords on show targets this._storeMouse(event); }); // Mouse positioning events if(posOptions.target === 'mouse') { // If mouse adjustment is on... if(posOptions.adjust.mouse) { // Apply a mouseleave event so we don't get problems with overlapping if(options.hide.event) { // Track if we're on the target or not this._bind(showTarget, ['mouseenter', 'mouseleave'], function(event) { if(!this.cache) {return FALSE; } this.cache.onTarget = event.type === 'mouseenter'; }); } // Update tooltip position on mousemove this._bind(documentTarget, 'mousemove', function(event) { // Update the tooltip position only if the tooltip is visible and adjustment is enabled if(this.rendered && this.cache.onTarget && !this.tooltip.hasClass(CLASS_DISABLED) && this.tooltip[0].offsetWidth > 0) { this.reposition(event); } }); } } // Adjust positions of the tooltip on window resize if enabled if(posOptions.adjust.resize || viewportTarget.length) { this._bind( $.event.special.resize ? viewportTarget : windowTarget, 'resize', repositionMethod ); } // Adjust tooltip position on scroll of the window or viewport element if present if(posOptions.adjust.scroll) { this._bind( windowTarget.add(posOptions.container), 'scroll', repositionMethod ); } }; // Un-assignment method PROTOTYPE._unassignEvents = function() { var options = this.options, showTargets = options.show.target, hideTargets = options.hide.target, targets = $.grep([ this.elements.target[0], this.rendered && this.tooltip[0], options.position.container[0], options.position.viewport[0], options.position.container.closest('html')[0], // unfocus window, document ], function(i) { return typeof i === 'object'; }); // Add show and hide targets if they're valid if(showTargets && showTargets.toArray) { targets = targets.concat(showTargets.toArray()); } if(hideTargets && hideTargets.toArray) { targets = targets.concat(hideTargets.toArray()); } // Unbind the events this._unbind(targets) ._unbind(targets, 'destroy') ._unbind(targets, 'inactive'); }; // Apply common event handlers using delegate (avoids excessive .bind calls!) $(function() { delegate(SELECTOR, ['mouseenter', 'mouseleave'], function(event) { var state = event.type === 'mouseenter', tooltip = $(event.currentTarget), target = $(event.relatedTarget || event.target), options = this.options; // On mouseenter... if(state) { // Focus the tooltip on mouseenter (z-index stacking) this.focus(event); // Clear hide timer on tooltip hover to prevent it from closing tooltip.hasClass(CLASS_FIXED) && !tooltip.hasClass(CLASS_DISABLED) && clearTimeout(this.timers.hide); } // On mouseleave... else { // When mouse tracking is enabled, hide when we leave the tooltip and not onto the show target (if a hide event is set) if(options.position.target === 'mouse' && options.position.adjust.mouse && options.hide.event && options.show.target && !target.closest(options.show.target[0]).length) { this.hide(event); } } // Add hover class tooltip.toggleClass(CLASS_HOVER, state); }); // Define events which reset the 'inactive' event handler delegate('['+ATTR_ID+']', INACTIVE_EVENTS, inactiveMethod); }); ;// Initialization method function init(elem, id, opts) { var obj, posOptions, attr, config, title, // Setup element references docBody = $(document.body), // Use document body instead of document element if needed newTarget = elem[0] === document ? docBody : elem, // Grab metadata from element if plugin is present metadata = elem.metadata ? elem.metadata(opts.metadata) : NULL, // If metadata type if HTML5, grab 'name' from the object instead, or use the regular data object otherwise metadata5 = opts.metadata.type === 'html5' && metadata ? metadata[opts.metadata.name] : NULL, // Grab data from metadata.name (or data-qtipopts as fallback) using .data() method, html5 = elem.data(opts.metadata.name || 'qtipopts'); // If we don't get an object returned attempt to parse it manualyl without parseJSON /* eslint-disable no-empty */ try { html5 = typeof html5 === 'string' ? $.parseJSON(html5) : html5; } catch(e) {} /* eslint-enable no-empty */ // Merge in and sanitize metadata config = $.extend(TRUE, {}, QTIP.defaults, opts, typeof html5 === 'object' ? sanitizeOptions(html5) : NULL, sanitizeOptions(metadata5 || metadata)); // Re-grab our positioning options now we've merged our metadata and set id to passed value posOptions = config.position; config.id = id; // Setup missing content if none is detected if('boolean' === typeof config.content.text) { attr = elem.attr(config.content.attr); // Grab from supplied attribute if available if(config.content.attr !== FALSE && attr) { config.content.text = attr; } // No valid content was found, abort render else { return FALSE; } } // Setup target options if(!posOptions.container.length) { posOptions.container = docBody; } if(posOptions.target === FALSE) { posOptions.target = newTarget; } if(config.show.target === FALSE) { config.show.target = newTarget; } if(config.show.solo === TRUE) { config.show.solo = posOptions.container.closest('body'); } if(config.hide.target === FALSE) { config.hide.target = newTarget; } if(config.position.viewport === TRUE) { config.position.viewport = posOptions.container; } // Ensure we only use a single container posOptions.container = posOptions.container.eq(0); // Convert position corner values into x and y strings posOptions.at = new CORNER(posOptions.at, TRUE); posOptions.my = new CORNER(posOptions.my); // Destroy previous tooltip if overwrite is enabled, or skip element if not if(elem.data(NAMESPACE)) { if(config.overwrite) { elem.qtip('destroy', true); } else if(config.overwrite === FALSE) { return FALSE; } } // Add has-qtip attribute elem.attr(ATTR_HAS, id); // Remove title attribute and store it if present if(config.suppress && (title = elem.attr('title'))) { // Final attr call fixes event delegatiom and IE default tooltip showing problem elem.removeAttr('title').attr(oldtitle, title).attr('title', ''); } // Initialize the tooltip and add API reference obj = new QTip(elem, config, id, !!attr); elem.data(NAMESPACE, obj); return obj; } // jQuery $.fn extension method QTIP = $.fn.qtip = function(options, notation, newValue) { var command = ('' + options).toLowerCase(), // Parse command returned = NULL, args = $.makeArray(arguments).slice(1), event = args[args.length - 1], opts = this[0] ? $.data(this[0], NAMESPACE) : NULL; // Check for API request if(!arguments.length && opts || command === 'api') { return opts; } // Execute API command if present else if('string' === typeof options) { this.each(function() { var api = $.data(this, NAMESPACE); if(!api) { return TRUE; } // Cache the event if possible if(event && event.timeStamp) { api.cache.event = event; } // Check for specific API commands if(notation && (command === 'option' || command === 'options')) { if(newValue !== undefined || $.isPlainObject(notation)) { api.set(notation, newValue); } else { returned = api.get(notation); return FALSE; } } // Execute API command else if(api[command]) { api[command].apply(api, args); } }); return returned !== NULL ? returned : this; } // No API commands. validate provided options and setup qTips else if('object' === typeof options || !arguments.length) { // Sanitize options first opts = sanitizeOptions($.extend(TRUE, {}, options)); return this.each(function(i) { var api, id; // Find next available ID, or use custom ID if provided id = $.isArray(opts.id) ? opts.id[i] : opts.id; id = !id || id === FALSE || id.length < 1 || QTIP.api[id] ? QTIP.nextid++ : id; // Initialize the qTip and re-grab newly sanitized options api = init($(this), id, opts); if(api === FALSE) { return TRUE; } else { QTIP.api[id] = api; } // Initialize plugins $.each(PLUGINS, function() { if(this.initialize === 'initialize') { this(api); } }); // Assign initial pre-render events api._assignInitialEvents(event); }); } }; // Expose class $.qtip = QTip; // Populated in render method QTIP.api = {}; ;$.each({ /* Allow other plugins to successfully retrieve the title of an element with a qTip applied */ attr: function(attr, val) { if(this.length) { var self = this[0], title = 'title', api = $.data(self, 'qtip'); if(attr === title && api && api.options && 'object' === typeof api && 'object' === typeof api.options && api.options.suppress) { if(arguments.length < 2) { return $.attr(self, oldtitle); } // If qTip is rendered and title was originally used as content, update it if(api && api.options.content.attr === title && api.cache.attr) { api.set('content.text', val); } // Use the regular attr method to set, then cache the result return this.attr(oldtitle, val); } } return $.fn['attr'+replaceSuffix].apply(this, arguments); }, /* Allow clone to correctly retrieve cached title attributes */ clone: function(keepData) { // Clone our element using the real clone method var elems = $.fn['clone'+replaceSuffix].apply(this, arguments); // Grab all elements with an oldtitle set, and change it to regular title attribute, if keepData is false if(!keepData) { elems.filter('['+oldtitle+']').attr('title', function() { return $.attr(this, oldtitle); }) .removeAttr(oldtitle); } return elems; } }, function(name, func) { if(!func || $.fn[name+replaceSuffix]) { return TRUE; } var old = $.fn[name+replaceSuffix] = $.fn[name]; $.fn[name] = function() { return func.apply(this, arguments) || old.apply(this, arguments); }; }); /* Fire off 'removeqtip' handler in $.cleanData if jQuery UI not present (it already does similar). * This snippet is taken directly from jQuery UI source code found here: * http://code.jquery.com/ui/jquery-ui-git.js */ if(!$.ui) { $['cleanData'+replaceSuffix] = $.cleanData; $.cleanData = function( elems ) { for(var i = 0, elem; (elem = $( elems[i] )).length; i++) { if(elem.attr(ATTR_HAS)) { /* eslint-disable no-empty */ try { elem.triggerHandler('removeqtip'); } catch( e ) {} /* eslint-enable no-empty */ } } $['cleanData'+replaceSuffix].apply(this, arguments); }; } ;// qTip version QTIP.version = '3.0.2'; // Base ID for all qTips QTIP.nextid = 0; // Inactive events array QTIP.inactiveEvents = INACTIVE_EVENTS; // Base z-index for all qTips QTIP.zindex = 15000; // Define configuration defaults QTIP.defaults = { prerender: FALSE, id: FALSE, overwrite: TRUE, suppress: TRUE, content: { text: TRUE, attr: 'title', title: FALSE, button: FALSE }, position: { my: 'top left', at: 'bottom right', target: FALSE, container: FALSE, viewport: FALSE, adjust: { x: 0, y: 0, mouse: TRUE, scroll: TRUE, resize: TRUE, method: 'flipinvert flipinvert' }, effect: function(api, pos) { $(this).animate(pos, { duration: 200, queue: FALSE }); } }, show: { target: FALSE, event: 'mouseenter', effect: TRUE, delay: 90, solo: FALSE, ready: FALSE, autofocus: FALSE }, hide: { target: FALSE, event: 'mouseleave', effect: TRUE, delay: 0, fixed: FALSE, inactive: FALSE, leave: 'window', distance: FALSE }, style: { classes: '', widget: FALSE, width: FALSE, height: FALSE, def: TRUE }, events: { render: NULL, move: NULL, show: NULL, hide: NULL, toggle: NULL, visible: NULL, hidden: NULL, focus: NULL, blur: NULL } }; ;var TIP, createVML, SCALE, PIXEL_RATIO, BACKING_STORE_RATIO, // Common CSS strings MARGIN = 'margin', BORDER = 'border', COLOR = 'color', BG_COLOR = 'background-color', TRANSPARENT = 'transparent', IMPORTANT = ' !important', // Check if the browser supports elements HASCANVAS = !!document.createElement('canvas').getContext, // Invalid colour values used in parseColours() INVALID = /rgba?\(0, 0, 0(, 0)?\)|transparent|#123456/i; // Camel-case method, taken from jQuery source // http://code.jquery.com/jquery-1.8.0.js function camel(s) { return s.charAt(0).toUpperCase() + s.slice(1); } /* * Modified from Modernizr's testPropsAll() * http://modernizr.com/downloads/modernizr-latest.js */ var cssProps = {}, cssPrefixes = ['Webkit', 'O', 'Moz', 'ms']; function vendorCss(elem, prop) { var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1), props = (prop + ' ' + cssPrefixes.join(ucProp + ' ') + ucProp).split(' '), cur, val, i = 0; // If the property has already been mapped... if(cssProps[prop]) { return elem.css(cssProps[prop]); } while(cur = props[i++]) { if((val = elem.css(cur)) !== undefined) { cssProps[prop] = cur; return val; } } } // Parse a given elements CSS property into an int function intCss(elem, prop) { return Math.ceil(parseFloat(vendorCss(elem, prop))); } // VML creation (for IE only) if(!HASCANVAS) { createVML = function(tag, props, style) { return ''; }; } // Canvas only definitions else { PIXEL_RATIO = window.devicePixelRatio || 1; BACKING_STORE_RATIO = (function() { var context = document.createElement('canvas').getContext('2d'); return context.backingStorePixelRatio || context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || 1; })(); SCALE = PIXEL_RATIO / BACKING_STORE_RATIO; } function Tip(qtip, options) { this._ns = 'tip'; this.options = options; this.offset = options.offset; this.size = [ options.width, options.height ]; // Initialize this.qtip = qtip; this.init(qtip); } $.extend(Tip.prototype, { init: function(qtip) { var context, tip; // Create tip element and prepend to the tooltip tip = this.element = qtip.elements.tip = $('
', { 'class': NAMESPACE+'-tip' }).prependTo(qtip.tooltip); // Create tip drawing element(s) if(HASCANVAS) { // save() as soon as we create the canvas element so FF2 doesn't bork on our first restore()! context = $('').appendTo(this.element)[0].getContext('2d'); // Setup constant parameters context.lineJoin = 'miter'; context.miterLimit = 100000; context.save(); } else { context = createVML('shape', 'coordorigin="0,0"', 'position:absolute;'); this.element.html(context + context); // Prevent mousing down on the tip since it causes problems with .live() handling in IE due to VML qtip._bind( $('*', tip).add(tip), ['click', 'mousedown'], function(event) { event.stopPropagation(); }, this._ns); } // Bind update events qtip._bind(qtip.tooltip, 'tooltipmove', this.reposition, this._ns, this); // Create it this.create(); }, _swapDimensions: function() { this.size[0] = this.options.height; this.size[1] = this.options.width; }, _resetDimensions: function() { this.size[0] = this.options.width; this.size[1] = this.options.height; }, _useTitle: function(corner) { var titlebar = this.qtip.elements.titlebar; return titlebar && ( corner.y === TOP || corner.y === CENTER && this.element.position().top + this.size[1] / 2 + this.options.offset < titlebar.outerHeight(TRUE) ); }, _parseCorner: function(corner) { var my = this.qtip.options.position.my; // Detect corner and mimic properties if(corner === FALSE || my === FALSE) { corner = FALSE; } else if(corner === TRUE) { corner = new CORNER( my.string() ); } else if(!corner.string) { corner = new CORNER(corner); corner.fixed = TRUE; } return corner; }, _parseWidth: function(corner, side, use) { var elements = this.qtip.elements, prop = BORDER + camel(side) + 'Width'; return (use ? intCss(use, prop) : intCss(elements.content, prop) || intCss(this._useTitle(corner) && elements.titlebar || elements.content, prop) || intCss(elements.tooltip, prop) ) || 0; }, _parseRadius: function(corner) { var elements = this.qtip.elements, prop = BORDER + camel(corner.y) + camel(corner.x) + 'Radius'; return BROWSER.ie < 9 ? 0 : intCss(this._useTitle(corner) && elements.titlebar || elements.content, prop) || intCss(elements.tooltip, prop) || 0; }, _invalidColour: function(elem, prop, compare) { var val = elem.css(prop); return !val || compare && val === elem.css(compare) || INVALID.test(val) ? FALSE : val; }, _parseColours: function(corner) { var elements = this.qtip.elements, tip = this.element.css('cssText', ''), borderSide = BORDER + camel(corner[ corner.precedance ]) + camel(COLOR), colorElem = this._useTitle(corner) && elements.titlebar || elements.content, css = this._invalidColour, color = []; // Attempt to detect the background colour from various elements, left-to-right precedance color[0] = css(tip, BG_COLOR) || css(colorElem, BG_COLOR) || css(elements.content, BG_COLOR) || css(elements.tooltip, BG_COLOR) || tip.css(BG_COLOR); // Attempt to detect the correct border side colour from various elements, left-to-right precedance color[1] = css(tip, borderSide, COLOR) || css(colorElem, borderSide, COLOR) || css(elements.content, borderSide, COLOR) || css(elements.tooltip, borderSide, COLOR) || elements.tooltip.css(borderSide); // Reset background and border colours $('*', tip).add(tip).css('cssText', BG_COLOR+':'+TRANSPARENT+IMPORTANT+';'+BORDER+':0'+IMPORTANT+';'); return color; }, _calculateSize: function(corner) { var y = corner.precedance === Y, width = this.options.width, height = this.options.height, isCenter = corner.abbrev() === 'c', base = (y ? width: height) * (isCenter ? 0.5 : 1), pow = Math.pow, round = Math.round, bigHyp, ratio, result, smallHyp = Math.sqrt( pow(base, 2) + pow(height, 2) ), hyp = [ this.border / base * smallHyp, this.border / height * smallHyp ]; hyp[2] = Math.sqrt( pow(hyp[0], 2) - pow(this.border, 2) ); hyp[3] = Math.sqrt( pow(hyp[1], 2) - pow(this.border, 2) ); bigHyp = smallHyp + hyp[2] + hyp[3] + (isCenter ? 0 : hyp[0]); ratio = bigHyp / smallHyp; result = [ round(ratio * width), round(ratio * height) ]; return y ? result : result.reverse(); }, // Tip coordinates calculator _calculateTip: function(corner, size, scale) { scale = scale || 1; size = size || this.size; var width = size[0] * scale, height = size[1] * scale, width2 = Math.ceil(width / 2), height2 = Math.ceil(height / 2), // Define tip coordinates in terms of height and width values tips = { br: [0,0, width,height, width,0], bl: [0,0, width,0, 0,height], tr: [0,height, width,0, width,height], tl: [0,0, 0,height, width,height], tc: [0,height, width2,0, width,height], bc: [0,0, width,0, width2,height], rc: [0,0, width,height2, 0,height], lc: [width,0, width,height, 0,height2] }; // Set common side shapes tips.lt = tips.br; tips.rt = tips.bl; tips.lb = tips.tr; tips.rb = tips.tl; return tips[ corner.abbrev() ]; }, // Tip coordinates drawer (canvas) _drawCoords: function(context, coords) { context.beginPath(); context.moveTo(coords[0], coords[1]); context.lineTo(coords[2], coords[3]); context.lineTo(coords[4], coords[5]); context.closePath(); }, create: function() { // Determine tip corner var c = this.corner = (HASCANVAS || BROWSER.ie) && this._parseCorner(this.options.corner); // If we have a tip corner... this.enabled = !!this.corner && this.corner.abbrev() !== 'c'; if(this.enabled) { // Cache it this.qtip.cache.corner = c.clone(); // Create it this.update(); } // Toggle tip element this.element.toggle(this.enabled); return this.corner; }, update: function(corner, position) { if(!this.enabled) { return this; } var elements = this.qtip.elements, tip = this.element, inner = tip.children(), options = this.options, curSize = this.size, mimic = options.mimic, round = Math.round, color, precedance, context, coords, bigCoords, translate, newSize, border; // Re-determine tip if not already set if(!corner) { corner = this.qtip.cache.corner || this.corner; } // Use corner property if we detect an invalid mimic value if(mimic === FALSE) { mimic = corner; } // Otherwise inherit mimic properties from the corner object as necessary else { mimic = new CORNER(mimic); mimic.precedance = corner.precedance; if(mimic.x === 'inherit') { mimic.x = corner.x; } else if(mimic.y === 'inherit') { mimic.y = corner.y; } else if(mimic.x === mimic.y) { mimic[ corner.precedance ] = corner[ corner.precedance ]; } } precedance = mimic.precedance; // Ensure the tip width.height are relative to the tip position if(corner.precedance === X) { this._swapDimensions(); } else { this._resetDimensions(); } // Update our colours color = this.color = this._parseColours(corner); // Detect border width, taking into account colours if(color[1] !== TRANSPARENT) { // Grab border width border = this.border = this._parseWidth(corner, corner[corner.precedance]); // If border width isn't zero, use border color as fill if it's not invalid (1.0 style tips) if(options.border && border < 1 && !INVALID.test(color[1])) { color[0] = color[1]; } // Set border width (use detected border width if options.border is true) this.border = border = options.border !== TRUE ? options.border : border; } // Border colour was invalid, set border to zero else { this.border = border = 0; } // Determine tip size newSize = this.size = this._calculateSize(corner); tip.css({ width: newSize[0], height: newSize[1], lineHeight: newSize[1]+'px' }); // Calculate tip translation if(corner.precedance === Y) { translate = [ round(mimic.x === LEFT ? border : mimic.x === RIGHT ? newSize[0] - curSize[0] - border : (newSize[0] - curSize[0]) / 2), round(mimic.y === TOP ? newSize[1] - curSize[1] : 0) ]; } else { translate = [ round(mimic.x === LEFT ? newSize[0] - curSize[0] : 0), round(mimic.y === TOP ? border : mimic.y === BOTTOM ? newSize[1] - curSize[1] - border : (newSize[1] - curSize[1]) / 2) ]; } // Canvas drawing implementation if(HASCANVAS) { // Grab canvas context and clear/save it context = inner[0].getContext('2d'); context.restore(); context.save(); context.clearRect(0,0,6000,6000); // Calculate coordinates coords = this._calculateTip(mimic, curSize, SCALE); bigCoords = this._calculateTip(mimic, this.size, SCALE); // Set the canvas size using calculated size inner.attr(WIDTH, newSize[0] * SCALE).attr(HEIGHT, newSize[1] * SCALE); inner.css(WIDTH, newSize[0]).css(HEIGHT, newSize[1]); // Draw the outer-stroke tip this._drawCoords(context, bigCoords); context.fillStyle = color[1]; context.fill(); // Draw the actual tip context.translate(translate[0] * SCALE, translate[1] * SCALE); this._drawCoords(context, coords); context.fillStyle = color[0]; context.fill(); } // VML (IE Proprietary implementation) else { // Calculate coordinates coords = this._calculateTip(mimic); // Setup coordinates string coords = 'm' + coords[0] + ',' + coords[1] + ' l' + coords[2] + ',' + coords[3] + ' ' + coords[4] + ',' + coords[5] + ' xe'; // Setup VML-specific offset for pixel-perfection translate[2] = border && /^(r|b)/i.test(corner.string()) ? BROWSER.ie === 8 ? 2 : 1 : 0; // Set initial CSS inner.css({ coordsize: newSize[0]+border + ' ' + newSize[1]+border, antialias: ''+(mimic.string().indexOf(CENTER) > -1), left: translate[0] - translate[2] * Number(precedance === X), top: translate[1] - translate[2] * Number(precedance === Y), width: newSize[0] + border, height: newSize[1] + border }) .each(function(i) { var $this = $(this); // Set shape specific attributes $this[ $this.prop ? 'prop' : 'attr' ]({ coordsize: newSize[0]+border + ' ' + newSize[1]+border, path: coords, fillcolor: color[0], filled: !!i, stroked: !i }) .toggle(!!(border || i)); // Check if border is enabled and add stroke element !i && $this.html( createVML( 'stroke', 'weight="'+border*2+'px" color="'+color[1]+'" miterlimit="1000" joinstyle="miter"' ) ); }); } // Opera bug #357 - Incorrect tip position // https://github.com/Craga89/qTip2/issues/367 window.opera && setTimeout(function() { elements.tip.css({ display: 'inline-block', visibility: 'visible' }); }, 1); // Position if needed if(position !== FALSE) { this.calculate(corner, newSize); } }, calculate: function(corner, size) { if(!this.enabled) { return FALSE; } var self = this, elements = this.qtip.elements, tip = this.element, userOffset = this.options.offset, position = {}, precedance, corners; // Inherit corner if not provided corner = corner || this.corner; precedance = corner.precedance; // Determine which tip dimension to use for adjustment size = size || this._calculateSize(corner); // Setup corners and offset array corners = [ corner.x, corner.y ]; if(precedance === X) { corners.reverse(); } // Calculate tip position $.each(corners, function(i, side) { var b, bc, br; if(side === CENTER) { b = precedance === Y ? LEFT : TOP; position[ b ] = '50%'; position[MARGIN+'-' + b] = -Math.round(size[ precedance === Y ? 0 : 1 ] / 2) + userOffset; } else { b = self._parseWidth(corner, side, elements.tooltip); bc = self._parseWidth(corner, side, elements.content); br = self._parseRadius(corner); position[ side ] = Math.max(-self.border, i ? bc : userOffset + (br > b ? br : -b)); } }); // Adjust for tip size position[ corner[precedance] ] -= size[ precedance === X ? 0 : 1 ]; // Set and return new position tip.css({ margin: '', top: '', bottom: '', left: '', right: '' }).css(position); return position; }, reposition: function(event, api, pos) { if(!this.enabled) { return; } var cache = api.cache, newCorner = this.corner.clone(), adjust = pos.adjusted, method = api.options.position.adjust.method.split(' '), horizontal = method[0], vertical = method[1] || method[0], shift = { left: FALSE, top: FALSE, x: 0, y: 0 }, offset, css = {}, props; function shiftflip(direction, precedance, popposite, side, opposite) { // Horizontal - Shift or flip method if(direction === SHIFT && newCorner.precedance === precedance && adjust[side] && newCorner[popposite] !== CENTER) { newCorner.precedance = newCorner.precedance === X ? Y : X; } else if(direction !== SHIFT && adjust[side]){ newCorner[precedance] = newCorner[precedance] === CENTER ? adjust[side] > 0 ? side : opposite : newCorner[precedance] === side ? opposite : side; } } function shiftonly(xy, side, opposite) { if(newCorner[xy] === CENTER) { css[MARGIN+'-'+side] = shift[xy] = offset[MARGIN+'-'+side] - adjust[side]; } else { props = offset[opposite] !== undefined ? [ adjust[side], -offset[side] ] : [ -adjust[side], offset[side] ]; if( (shift[xy] = Math.max(props[0], props[1])) > props[0] ) { pos[side] -= adjust[side]; shift[side] = FALSE; } css[ offset[opposite] !== undefined ? opposite : side ] = shift[xy]; } } // If our tip position isn't fixed e.g. doesn't adjust with viewport... if(this.corner.fixed !== TRUE) { // Perform shift/flip adjustments shiftflip(horizontal, X, Y, LEFT, RIGHT); shiftflip(vertical, Y, X, TOP, BOTTOM); // Update and redraw the tip if needed (check cached details of last drawn tip) if(newCorner.string() !== cache.corner.string() || cache.cornerTop !== adjust.top || cache.cornerLeft !== adjust.left) { this.update(newCorner, FALSE); } } // Setup tip offset properties offset = this.calculate(newCorner); // Readjust offset object to make it left/top if(offset.right !== undefined) { offset.left = -offset.right; } if(offset.bottom !== undefined) { offset.top = -offset.bottom; } offset.user = this.offset; // Perform shift adjustments shift.left = horizontal === SHIFT && !!adjust.left; if(shift.left) { shiftonly(X, LEFT, RIGHT); } shift.top = vertical === SHIFT && !!adjust.top; if(shift.top) { shiftonly(Y, TOP, BOTTOM); } /* * If the tip is adjusted in both dimensions, or in a * direction that would cause it to be anywhere but the * outer border, hide it! */ this.element.css(css).toggle( !(shift.x && shift.y || newCorner.x === CENTER && shift.y || newCorner.y === CENTER && shift.x) ); // Adjust position to accomodate tip dimensions pos.left -= offset.left.charAt ? offset.user : horizontal !== SHIFT || shift.top || !shift.left && !shift.top ? offset.left + this.border : 0; pos.top -= offset.top.charAt ? offset.user : vertical !== SHIFT || shift.left || !shift.left && !shift.top ? offset.top + this.border : 0; // Cache details cache.cornerLeft = adjust.left; cache.cornerTop = adjust.top; cache.corner = newCorner.clone(); }, destroy: function() { // Unbind events this.qtip._unbind(this.qtip.tooltip, this._ns); // Remove the tip element(s) if(this.qtip.elements.tip) { this.qtip.elements.tip.find('*') .remove().end().remove(); } } }); TIP = PLUGINS.tip = function(api) { return new Tip(api, api.options.style.tip); }; // Initialize tip on render TIP.initialize = 'render'; // Setup plugin sanitization options TIP.sanitize = function(options) { if(options.style && 'tip' in options.style) { var opts = options.style.tip; if(typeof opts !== 'object') { opts = options.style.tip = { corner: opts }; } if(!(/string|boolean/i).test(typeof opts.corner)) { opts.corner = TRUE; } } }; // Add new option checks for the plugin CHECKS.tip = { '^position.my|style.tip.(corner|mimic|border)$': function() { // Make sure a tip can be drawn this.create(); // Reposition the tooltip this.qtip.reposition(); }, '^style.tip.(height|width)$': function(obj) { // Re-set dimensions and redraw the tip this.size = [ obj.width, obj.height ]; this.update(); // Reposition the tooltip this.qtip.reposition(); }, '^content.title|style.(classes|widget)$': function() { this.update(); } }; // Extend original qTip defaults $.extend(TRUE, QTIP.defaults, { style: { tip: { corner: TRUE, mimic: FALSE, width: 6, height: 6, border: TRUE, offset: 0 } } }); ;var MODAL, OVERLAY, MODALCLASS = 'qtip-modal', MODALSELECTOR = '.'+MODALCLASS; OVERLAY = function() { var self = this, focusableElems = {}, current, prevState, elem; // Modified code from jQuery UI 1.10.0 source // http://code.jquery.com/ui/1.10.0/jquery-ui.js function focusable(element) { // Use the defined focusable checker when possible if($.expr[':'].focusable) { return $.expr[':'].focusable; } var isTabIndexNotNaN = !isNaN($.attr(element, 'tabindex')), nodeName = element.nodeName && element.nodeName.toLowerCase(), map, mapName, img; if('area' === nodeName) { map = element.parentNode; mapName = map.name; if(!element.href || !mapName || map.nodeName.toLowerCase() !== 'map') { return false; } img = $('img[usemap=#' + mapName + ']')[0]; return !!img && img.is(':visible'); } return /input|select|textarea|button|object/.test( nodeName ) ? !element.disabled : 'a' === nodeName ? element.href || isTabIndexNotNaN : isTabIndexNotNaN ; } // Focus inputs using cached focusable elements (see update()) function focusInputs(blurElems) { // Blurring body element in IE causes window.open windows to unfocus! if(focusableElems.length < 1 && blurElems.length) { blurElems.not('body').blur(); } // Focus the inputs else { focusableElems.first().focus(); } } // Steal focus from elements outside tooltip function stealFocus(event) { if(!elem.is(':visible')) { return; } var target = $(event.target), tooltip = current.tooltip, container = target.closest(SELECTOR), targetOnTop; // Determine if input container target is above this targetOnTop = container.length < 1 ? FALSE : parseInt(container[0].style.zIndex, 10) > parseInt(tooltip[0].style.zIndex, 10); // If we're showing a modal, but focus has landed on an input below // this modal, divert focus to the first visible input in this modal // or if we can't find one... the tooltip itself if(!targetOnTop && target.closest(SELECTOR)[0] !== tooltip[0]) { focusInputs(target); } } $.extend(self, { init: function() { // Create document overlay elem = self.elem = $('
', { id: 'qtip-overlay', html: '
', mousedown: function() { return FALSE; } }) .hide(); // Make sure we can't focus anything outside the tooltip $(document.body).bind('focusin'+MODALSELECTOR, stealFocus); // Apply keyboard "Escape key" close handler $(document).bind('keydown'+MODALSELECTOR, function(event) { if(current && current.options.show.modal.escape && event.keyCode === 27) { current.hide(event); } }); // Apply click handler for blur option elem.bind('click'+MODALSELECTOR, function(event) { if(current && current.options.show.modal.blur) { current.hide(event); } }); return self; }, update: function(api) { // Update current API reference current = api; // Update focusable elements if enabled if(api.options.show.modal.stealfocus !== FALSE) { focusableElems = api.tooltip.find('*').filter(function() { return focusable(this); }); } else { focusableElems = []; } }, toggle: function(api, state, duration) { var tooltip = api.tooltip, options = api.options.show.modal, effect = options.effect, type = state ? 'show': 'hide', visible = elem.is(':visible'), visibleModals = $(MODALSELECTOR).filter(':visible:not(:animated)').not(tooltip); // Set active tooltip API reference self.update(api); // If the modal can steal the focus... // Blur the current item and focus anything in the modal we an if(state && options.stealfocus !== FALSE) { focusInputs( $(':focus') ); } // Toggle backdrop cursor style on show elem.toggleClass('blurs', options.blur); // Append to body on show if(state) { elem.appendTo(document.body); } // Prevent modal from conflicting with show.solo, and don't hide backdrop is other modals are visible if(elem.is(':animated') && visible === state && prevState !== FALSE || !state && visibleModals.length) { return self; } // Stop all animations elem.stop(TRUE, FALSE); // Use custom function if provided if($.isFunction(effect)) { effect.call(elem, state); } // If no effect type is supplied, use a simple toggle else if(effect === FALSE) { elem[ type ](); } // Use basic fade function else { elem.fadeTo( parseInt(duration, 10) || 90, state ? 1 : 0, function() { if(!state) { elem.hide(); } }); } // Reset position and detach from body on hide if(!state) { elem.queue(function(next) { elem.css({ left: '', top: '' }); if(!$(MODALSELECTOR).length) { elem.detach(); } next(); }); } // Cache the state prevState = state; // If the tooltip is destroyed, set reference to null if(current.destroyed) { current = NULL; } return self; } }); self.init(); }; OVERLAY = new OVERLAY(); function Modal(api, options) { this.options = options; this._ns = '-modal'; this.qtip = api; this.init(api); } $.extend(Modal.prototype, { init: function(qtip) { var tooltip = qtip.tooltip; // If modal is disabled... return if(!this.options.on) { return this; } // Set overlay reference qtip.elements.overlay = OVERLAY.elem; // Add unique attribute so we can grab modal tooltips easily via a SELECTOR, and set z-index tooltip.addClass(MODALCLASS).css('z-index', QTIP.modal_zindex + $(MODALSELECTOR).length); // Apply our show/hide/focus modal events qtip._bind(tooltip, ['tooltipshow', 'tooltiphide'], function(event, api, duration) { var oEvent = event.originalEvent; // Make sure mouseout doesn't trigger a hide when showing the modal and mousing onto backdrop if(event.target === tooltip[0]) { if(oEvent && event.type === 'tooltiphide' && /mouse(leave|enter)/.test(oEvent.type) && $(oEvent.relatedTarget).closest(OVERLAY.elem[0]).length) { /* eslint-disable no-empty */ try { event.preventDefault(); } catch(e) {} /* eslint-enable no-empty */ } else if(!oEvent || oEvent && oEvent.type !== 'tooltipsolo') { this.toggle(event, event.type === 'tooltipshow', duration); } } }, this._ns, this); // Adjust modal z-index on tooltip focus qtip._bind(tooltip, 'tooltipfocus', function(event, api) { // If focus was cancelled before it reached us, don't do anything if(event.isDefaultPrevented() || event.target !== tooltip[0]) { return; } var qtips = $(MODALSELECTOR), // Keep the modal's lower than other, regular qtips newIndex = QTIP.modal_zindex + qtips.length, curIndex = parseInt(tooltip[0].style.zIndex, 10); // Set overlay z-index OVERLAY.elem[0].style.zIndex = newIndex - 1; // Reduce modal z-index's and keep them properly ordered qtips.each(function() { if(this.style.zIndex > curIndex) { this.style.zIndex -= 1; } }); // Fire blur event for focused tooltip qtips.filter('.' + CLASS_FOCUS).qtip('blur', event.originalEvent); // Set the new z-index tooltip.addClass(CLASS_FOCUS)[0].style.zIndex = newIndex; // Set current OVERLAY.update(api); // Prevent default handling /* eslint-disable no-empty */ try { event.preventDefault(); } catch(e) {} /* eslint-enable no-empty */ }, this._ns, this); // Focus any other visible modals when this one hides qtip._bind(tooltip, 'tooltiphide', function(event) { if(event.target === tooltip[0]) { $(MODALSELECTOR).filter(':visible').not(tooltip).last().qtip('focus', event); } }, this._ns, this); }, toggle: function(event, state, duration) { // Make sure default event hasn't been prevented if(event && event.isDefaultPrevented()) { return this; } // Toggle it OVERLAY.toggle(this.qtip, !!state, duration); }, destroy: function() { // Remove modal class this.qtip.tooltip.removeClass(MODALCLASS); // Remove bound events this.qtip._unbind(this.qtip.tooltip, this._ns); // Delete element reference OVERLAY.toggle(this.qtip, FALSE); delete this.qtip.elements.overlay; } }); MODAL = PLUGINS.modal = function(api) { return new Modal(api, api.options.show.modal); }; // Setup sanitiztion rules MODAL.sanitize = function(opts) { if(opts.show) { if(typeof opts.show.modal !== 'object') { opts.show.modal = { on: !!opts.show.modal }; } else if(typeof opts.show.modal.on === 'undefined') { opts.show.modal.on = TRUE; } } }; // Base z-index for all modal tooltips (use qTip core z-index as a base) /* eslint-disable camelcase */ QTIP.modal_zindex = QTIP.zindex - 200; /* eslint-enable camelcase */ // Plugin needs to be initialized on render MODAL.initialize = 'render'; // Setup option set checks CHECKS.modal = { '^show.modal.(on|blur)$': function() { // Initialise this.destroy(); this.init(); // Show the modal if not visible already and tooltip is visible this.qtip.elems.overlay.toggle( this.qtip.tooltip[0].offsetWidth > 0 ); } }; // Extend original api defaults $.extend(TRUE, QTIP.defaults, { show: { modal: { on: FALSE, effect: TRUE, blur: TRUE, stealfocus: TRUE, escape: TRUE } } }); ;PLUGINS.viewport = function(api, position, posOptions, targetWidth, targetHeight, elemWidth, elemHeight) { var target = posOptions.target, tooltip = api.elements.tooltip, my = posOptions.my, at = posOptions.at, adjust = posOptions.adjust, method = adjust.method.split(' '), methodX = method[0], methodY = method[1] || method[0], viewport = posOptions.viewport, container = posOptions.container, adjusted = { left: 0, top: 0 }, fixed, newMy, containerOffset, containerStatic, viewportWidth, viewportHeight, viewportScroll, viewportOffset; // If viewport is not a jQuery element, or it's the window/document, or no adjustment method is used... return if(!viewport.jquery || target[0] === window || target[0] === document.body || adjust.method === 'none') { return adjusted; } // Cach container details containerOffset = container.offset() || adjusted; containerStatic = container.css('position') === 'static'; // Cache our viewport details fixed = tooltip.css('position') === 'fixed'; viewportWidth = viewport[0] === window ? viewport.width() : viewport.outerWidth(FALSE); viewportHeight = viewport[0] === window ? viewport.height() : viewport.outerHeight(FALSE); viewportScroll = { left: fixed ? 0 : viewport.scrollLeft(), top: fixed ? 0 : viewport.scrollTop() }; viewportOffset = viewport.offset() || adjusted; // Generic calculation method function calculate(side, otherSide, type, adjustment, side1, side2, lengthName, targetLength, elemLength) { var initialPos = position[side1], mySide = my[side], atSide = at[side], isShift = type === SHIFT, myLength = mySide === side1 ? elemLength : mySide === side2 ? -elemLength : -elemLength / 2, atLength = atSide === side1 ? targetLength : atSide === side2 ? -targetLength : -targetLength / 2, sideOffset = viewportScroll[side1] + viewportOffset[side1] - (containerStatic ? 0 : containerOffset[side1]), overflow1 = sideOffset - initialPos, overflow2 = initialPos + elemLength - (lengthName === WIDTH ? viewportWidth : viewportHeight) - sideOffset, offset = myLength - (my.precedance === side || mySide === my[otherSide] ? atLength : 0) - (atSide === CENTER ? targetLength / 2 : 0); // shift if(isShift) { offset = (mySide === side1 ? 1 : -1) * myLength; // Adjust position but keep it within viewport dimensions position[side1] += overflow1 > 0 ? overflow1 : overflow2 > 0 ? -overflow2 : 0; position[side1] = Math.max( -containerOffset[side1] + viewportOffset[side1], initialPos - offset, Math.min( Math.max( -containerOffset[side1] + viewportOffset[side1] + (lengthName === WIDTH ? viewportWidth : viewportHeight), initialPos + offset ), position[side1], // Make sure we don't adjust complete off the element when using 'center' mySide === 'center' ? initialPos - myLength : 1E9 ) ); } // flip/flipinvert else { // Update adjustment amount depending on if using flipinvert or flip adjustment *= type === FLIPINVERT ? 2 : 0; // Check for overflow on the left/top if(overflow1 > 0 && (mySide !== side1 || overflow2 > 0)) { position[side1] -= offset + adjustment; newMy.invert(side, side1); } // Check for overflow on the bottom/right else if(overflow2 > 0 && (mySide !== side2 || overflow1 > 0) ) { position[side1] -= (mySide === CENTER ? -offset : offset) + adjustment; newMy.invert(side, side2); } // Make sure we haven't made things worse with the adjustment and reset if so if(position[side1] < viewportScroll[side1] && -position[side1] > overflow2) { position[side1] = initialPos; newMy = my.clone(); } } return position[side1] - initialPos; } // Set newMy if using flip or flipinvert methods if(methodX !== 'shift' || methodY !== 'shift') { newMy = my.clone(); } // Adjust position based onviewport and adjustment options adjusted = { left: methodX !== 'none' ? calculate( X, Y, methodX, adjust.x, LEFT, RIGHT, WIDTH, targetWidth, elemWidth ) : 0, top: methodY !== 'none' ? calculate( Y, X, methodY, adjust.y, TOP, BOTTOM, HEIGHT, targetHeight, elemHeight ) : 0, my: newMy }; return adjusted; }; ;PLUGINS.polys = { // POLY area coordinate calculator // Special thanks to Ed Cradock for helping out with this. // Uses a binary search algorithm to find suitable coordinates. polygon: function(baseCoords, corner) { var result = { width: 0, height: 0, position: { top: 1e10, right: 0, bottom: 0, left: 1e10 }, adjustable: FALSE }, i = 0, next, coords = [], compareX = 1, compareY = 1, realX = 0, realY = 0, newWidth, newHeight; // First pass, sanitize coords and determine outer edges i = baseCoords.length; while(i--) { next = [ parseInt(baseCoords[--i], 10), parseInt(baseCoords[i+1], 10) ]; if(next[0] > result.position.right){ result.position.right = next[0]; } if(next[0] < result.position.left){ result.position.left = next[0]; } if(next[1] > result.position.bottom){ result.position.bottom = next[1]; } if(next[1] < result.position.top){ result.position.top = next[1]; } coords.push(next); } // Calculate height and width from outer edges newWidth = result.width = Math.abs(result.position.right - result.position.left); newHeight = result.height = Math.abs(result.position.bottom - result.position.top); // If it's the center corner... if(corner.abbrev() === 'c') { result.position = { left: result.position.left + result.width / 2, top: result.position.top + result.height / 2 }; } else { // Second pass, use a binary search algorithm to locate most suitable coordinate while(newWidth > 0 && newHeight > 0 && compareX > 0 && compareY > 0) { newWidth = Math.floor(newWidth / 2); newHeight = Math.floor(newHeight / 2); if(corner.x === LEFT){ compareX = newWidth; } else if(corner.x === RIGHT){ compareX = result.width - newWidth; } else{ compareX += Math.floor(newWidth / 2); } if(corner.y === TOP){ compareY = newHeight; } else if(corner.y === BOTTOM){ compareY = result.height - newHeight; } else{ compareY += Math.floor(newHeight / 2); } i = coords.length; while(i--) { if(coords.length < 2){ break; } realX = coords[i][0] - result.position.left; realY = coords[i][1] - result.position.top; if( corner.x === LEFT && realX >= compareX || corner.x === RIGHT && realX <= compareX || corner.x === CENTER && (realX < compareX || realX > result.width - compareX) || corner.y === TOP && realY >= compareY || corner.y === BOTTOM && realY <= compareY || corner.y === CENTER && (realY < compareY || realY > result.height - compareY)) { coords.splice(i, 1); } } } result.position = { left: coords[0][0], top: coords[0][1] }; } return result; }, rect: function(ax, ay, bx, by) { return { width: Math.abs(bx - ax), height: Math.abs(by - ay), position: { left: Math.min(ax, bx), top: Math.min(ay, by) } }; }, _angles: { tc: 3 / 2, tr: 7 / 4, tl: 5 / 4, bc: 1 / 2, br: 1 / 4, bl: 3 / 4, rc: 2, lc: 1, c: 0 }, ellipse: function(cx, cy, rx, ry, corner) { var c = PLUGINS.polys._angles[ corner.abbrev() ], rxc = c === 0 ? 0 : rx * Math.cos( c * Math.PI ), rys = ry * Math.sin( c * Math.PI ); return { width: rx * 2 - Math.abs(rxc), height: ry * 2 - Math.abs(rys), position: { left: cx + rxc, top: cy + rys }, adjustable: FALSE }; }, circle: function(cx, cy, r, corner) { return PLUGINS.polys.ellipse(cx, cy, r, r, corner); } }; ;PLUGINS.svg = function(api, svg, corner) { var elem = svg[0], root = $(elem.ownerSVGElement), ownerDocument = elem.ownerDocument, strokeWidth2 = (parseInt(svg.css('stroke-width'), 10) || 0) / 2, frameOffset, mtx, transformed, len, next, i, points, result, position; // Ascend the parentNode chain until we find an element with getBBox() while(!elem.getBBox) { elem = elem.parentNode; } if(!elem.getBBox || !elem.parentNode) { return FALSE; } // Determine which shape calculation to use switch(elem.nodeName) { case 'ellipse': case 'circle': result = PLUGINS.polys.ellipse( elem.cx.baseVal.value, elem.cy.baseVal.value, (elem.rx || elem.r).baseVal.value + strokeWidth2, (elem.ry || elem.r).baseVal.value + strokeWidth2, corner ); break; case 'line': case 'polygon': case 'polyline': // Determine points object (line has none, so mimic using array) points = elem.points || [ { x: elem.x1.baseVal.value, y: elem.y1.baseVal.value }, { x: elem.x2.baseVal.value, y: elem.y2.baseVal.value } ]; for(result = [], i = -1, len = points.numberOfItems || points.length; ++i < len;) { next = points.getItem ? points.getItem(i) : points[i]; result.push.apply(result, [next.x, next.y]); } result = PLUGINS.polys.polygon(result, corner); break; // Unknown shape or rectangle? Use bounding box default: result = elem.getBBox(); result = { width: result.width, height: result.height, position: { left: result.x, top: result.y } }; break; } // Shortcut assignments position = result.position; root = root[0]; // Convert position into a pixel value if(root.createSVGPoint) { mtx = elem.getScreenCTM(); points = root.createSVGPoint(); points.x = position.left; points.y = position.top; transformed = points.matrixTransform( mtx ); position.left = transformed.x; position.top = transformed.y; } // Check the element is not in a child document, and if so, adjust for frame elements offset if(ownerDocument !== document && api.position.target !== 'mouse') { frameOffset = $((ownerDocument.defaultView || ownerDocument.parentWindow).frameElement).offset(); if(frameOffset) { position.left += frameOffset.left; position.top += frameOffset.top; } } // Adjust by scroll offset of owner document ownerDocument = $(ownerDocument); position.left += ownerDocument.scrollLeft(); position.top += ownerDocument.scrollTop(); return result; }; ;PLUGINS.imagemap = function(api, area, corner) { if(!area.jquery) { area = $(area); } var shape = (area.attr('shape') || 'rect').toLowerCase().replace('poly', 'polygon'), image = $('img[usemap="#'+area.parent('map').attr('name')+'"]'), coordsString = $.trim(area.attr('coords')), coordsArray = coordsString.replace(/,$/, '').split(','), imageOffset, coords, i, result, len; // If we can't find the image using the map... if(!image.length) { return FALSE; } // Pass coordinates string if polygon if(shape === 'polygon') { result = PLUGINS.polys.polygon(coordsArray, corner); } // Otherwise parse the coordinates and pass them as arguments else if(PLUGINS.polys[shape]) { for(i = -1, len = coordsArray.length, coords = []; ++i < len;) { coords.push( parseInt(coordsArray[i], 10) ); } result = PLUGINS.polys[shape].apply( this, coords.concat(corner) ); } // If no shapre calculation method was found, return false else { return FALSE; } // Make sure we account for padding and borders on the image imageOffset = image.offset(); imageOffset.left += Math.ceil((image.outerWidth(FALSE) - image.width()) / 2); imageOffset.top += Math.ceil((image.outerHeight(FALSE) - image.height()) / 2); // Add image position to offset coordinates result.position.left += imageOffset.left; result.position.top += imageOffset.top; return result; }; ;var IE6, /* * BGIFrame adaption (http://plugins.jquery.com/project/bgiframe) * Special thanks to Brandon Aaron */ BGIFRAME = ''; function Ie6(api) { this._ns = 'ie6'; this.qtip = api; this.init(api); } $.extend(Ie6.prototype, { _scroll : function() { var overlay = this.qtip.elements.overlay; overlay && (overlay[0].style.top = $(window).scrollTop() + 'px'); }, init: function(qtip) { var tooltip = qtip.tooltip; // Create the BGIFrame element if needed if($('select, object').length < 1) { this.bgiframe = qtip.elements.bgiframe = $(BGIFRAME).appendTo(tooltip); // Update BGIFrame on tooltip move qtip._bind(tooltip, 'tooltipmove', this.adjustBGIFrame, this._ns, this); } // redraw() container for width/height calculations this.redrawContainer = $('
', { id: NAMESPACE+'-rcontainer' }) .appendTo(document.body); // Fixup modal plugin if present too if( qtip.elements.overlay && qtip.elements.overlay.addClass('qtipmodal-ie6fix') ) { qtip._bind(window, ['scroll', 'resize'], this._scroll, this._ns, this); qtip._bind(tooltip, ['tooltipshow'], this._scroll, this._ns, this); } // Set dimensions this.redraw(); }, adjustBGIFrame: function() { var tooltip = this.qtip.tooltip, dimensions = { height: tooltip.outerHeight(FALSE), width: tooltip.outerWidth(FALSE) }, plugin = this.qtip.plugins.tip, tip = this.qtip.elements.tip, tipAdjust, offset; // Adjust border offset offset = parseInt(tooltip.css('borderLeftWidth'), 10) || 0; offset = { left: -offset, top: -offset }; // Adjust for tips plugin if(plugin && tip) { tipAdjust = plugin.corner.precedance === 'x' ? [WIDTH, LEFT] : [HEIGHT, TOP]; offset[ tipAdjust[1] ] -= tip[ tipAdjust[0] ](); } // Update bgiframe this.bgiframe.css(offset).css(dimensions); }, // Max/min width simulator function redraw: function() { if(this.qtip.rendered < 1 || this.drawing) { return this; } var tooltip = this.qtip.tooltip, style = this.qtip.options.style, container = this.qtip.options.position.container, perc, width, max, min; // Set drawing flag this.qtip.drawing = 1; // If tooltip has a set height/width, just set it... like a boss! if(style.height) { tooltip.css(HEIGHT, style.height); } if(style.width) { tooltip.css(WIDTH, style.width); } // Simulate max/min width if not set width present... else { // Reset width and add fluid class tooltip.css(WIDTH, '').appendTo(this.redrawContainer); // Grab our tooltip width (add 1 if odd so we don't get wrapping problems.. huzzah!) width = tooltip.width(); if(width % 2 < 1) { width += 1; } // Grab our max/min properties max = tooltip.css('maxWidth') || ''; min = tooltip.css('minWidth') || ''; // Parse into proper pixel values perc = (max + min).indexOf('%') > -1 ? container.width() / 100 : 0; max = (max.indexOf('%') > -1 ? perc : 1 * parseInt(max, 10)) || width; min = (min.indexOf('%') > -1 ? perc : 1 * parseInt(min, 10)) || 0; // Determine new dimension size based on max/min/current values width = max + min ? Math.min(Math.max(width, min), max) : width; // Set the newly calculated width and remvoe fluid class tooltip.css(WIDTH, Math.round(width)).appendTo(container); } // Set drawing flag this.drawing = 0; return this; }, destroy: function() { // Remove iframe this.bgiframe && this.bgiframe.remove(); // Remove bound events this.qtip._unbind([window, this.qtip.tooltip], this._ns); } }); IE6 = PLUGINS.ie6 = function(api) { // Proceed only if the browser is IE6 return BROWSER.ie === 6 ? new Ie6(api) : FALSE; }; IE6.initialize = 'render'; CHECKS.ie6 = { '^content|style$': function() { this.redraw(); } }; ;})); }( window, document )); qTip2-3.0.2/dist/jquery.qtip.min.map000066400000000000000000002007211263162617100172410ustar00rootroot00000000000000{"version":3,"sources":["jquery.qtip.js"],"names":["window","document","undefined","factory","define","amd","jQuery","fn","qtip","$","QTip","target","options","id","attr","this","tooltip","NULL","elements","_id","NAMESPACE","timers","img","plugins","cache","event","disabled","FALSE","onTooltip","lastClass","rendered","destroyed","waiting","hiddenDuringWait","positioning","triggering","invalidOpt","a","type","invalidContent","c","isFunction","length","jquery","then","sanitizeOptions","opts","content","text","ajax","once","metadata","done","api","loading","deferred","extend","context","success","error","newContent","set","xhr","status","isPlainObject","title","button","position","my","at","show","TRUE","ready","hide","style","classes","each","PLUGINS","sanitize","convertNotation","notation","obj","i","option","levels","split","pop","setCallback","args","category","rule","match","checks","hasOwnProperty","RegExp","exec","push","apply","createWidgetClass","cls","WIDGET","concat","join","delay","callback","duration","setTimeout","proxy","call","showMethod","hasClass","CLASS_DISABLED","clearTimeout","toggle","hideMethod","relatedTarget","ontoTooltip","closest","SELECTOR","ontoTarget","fixed","test","preventDefault","stopImmediatePropagation","e","inactiveMethod","inactive","repositionMethod","offsetWidth","reposition","delegate","selector","events","method","body","QTIP","ATTR_ID","arguments","init","elem","posOptions","config","docBody","newTarget","metadata5","name","html5","data","parseJSON","defaults","container","solo","viewport","eq","CORNER","overwrite","ATTR_HAS","suppress","removeAttr","oldtitle","camel","s","charAt","toUpperCase","slice","vendorCss","prop","cur","val","ucProp","props","cssPrefixes","cssProps","css","intCss","Math","ceil","parseFloat","Tip","_ns","offset","size","width","height","Modal","Ie6","PROTOTYPE","CHECKS","trackingBound","X","Y","WIDTH","HEIGHT","TOP","LEFT","BOTTOM","RIGHT","CENTER","FLIPINVERT","SHIFT","INACTIVE_EVENTS","CLASS_FIXED","CLASS_DEFAULT","CLASS_FOCUS","CLASS_HOVER","replaceSuffix","BROWSER","ie","v","createElement","innerHTML","getElementsByTagName","NaN","iOS","navigator","userAgent","replace","prototype","_when","deferreds","when","render","self","posClass","_createPosClass","class","tracking","adjust","mouse","role","aria-live","aria-atomic","aria-describedby","aria-hidden","toggleClass","appendTo","append","_createTitle","_updateTitle","_createButton","_updateContent","_setWidget","instance","initialize","_unassignEvents","_assignEvents","_trigger","destroy","immediate","process","timer","stop","find","remove","end","removeData","one","builtin","^id$","o","prev","nextid","newId","^prerender","^content.text$","^content.attr$","^content.title$","_removeTitle","^content.button$","_updateButton","^content.title.(text|button)$","^position.(my|at)$","^position.container$","^show.ready$","^style.classes$","p","removeClass","addClass","^style.(width|height)","^style.widget|content.title","^style.def","^events.(render|show|move|hide|focus|blur)$","^(show|hide|position).(event|target|fixed|inactive|leave|distance|viewport|adjust)","get","toLowerCase","result","precedance","string","rmove","rrender","value","previous","nodeType","_update","element","empty","display","visibility","html","_waitForContent","images","imagesLoaded","Deferred","resolve","promise","titlebar","widget","insertBefore","substr","abbrev","effect","pluginCalculations","adjusted","newClass","tooltipWidth","outerWidth","tooltipHeight","outerHeight","targetWidth","targetHeight","left","top","visible","isScroll","win","doc","ownerDocument","isArray","x","y","distance","origin","pageX","innerWidth","documentElement","clientWidth","pageY","scrollX","scrollLeft","scrollY","scrollTop","innerHeight","imagemap","is","svg","ownerSVGElement","adjustable","isNaN","queue","next","opacity","removeAttribute","pos","scroll","scrolled","parentOffset","overflow","quirks","compatMode","parent","getBoundingClientRect","offsetParent","C","Corner","corner","forceY","f","invert","z","center","clone","state","add","has","fix","identicalState","allow","after","contentOptions","animate","sameTarget","search","focus","bind","_storeMouse","not","Event","unbind","blur","autofocus","trigger","n","fadeTo","qtips","curIndex","parseInt","zIndex","newIndex","zindex","filter","disable","enable","isString","close","aria-label","prepend","click","on","def","_bind","targets","suffix","ns","_unbind","originalEvent","isDefaultPrevented","_bindEvents","showEvents","hideEvents","showTargets","hideTargets","showCallback","hideCallback","similarTargets","toggleEvents","showIndex","inArray","splice","_assignInitialEvents","hoverIntent","hoverEvent","prerender","showTarget","hideTarget","trim","moveEvent","onTarget","containerTarget","viewportTarget","documentTarget","windowTarget","leave","nodeName","indexOf","enabled","isAncestor","parents","inactiveEvents","limit","abs","resize","special","grep","toArray","currentTarget","newValue","command","returned","makeArray","timeStamp","keepData","elems","func","old","ui","cleanData","triggerHandler","version","move","hidden","TIP","createVML","SCALE","PIXEL_RATIO","BACKING_STORE_RATIO","MARGIN","BORDER","COLOR","BG_COLOR","TRANSPARENT","IMPORTANT","HASCANVAS","getContext","INVALID","devicePixelRatio","backingStorePixelRatio","webkitBackingStorePixelRatio","mozBackingStorePixelRatio","msBackingStorePixelRatio","oBackingStorePixelRatio","tag","tip","prependTo","lineJoin","miterLimit","save","stopPropagation","create","_swapDimensions","_resetDimensions","_useTitle","_parseCorner","_parseWidth","side","use","_parseRadius","_invalidColour","compare","_parseColours","borderSide","colorElem","color","_calculateSize","bigHyp","ratio","isCenter","base","pow","round","smallHyp","sqrt","hyp","border","reverse","_calculateTip","scale","width2","height2","tips","br","bl","tr","tl","tc","bc","rc","lc","lt","rt","lb","rb","_drawCoords","coords","beginPath","moveTo","lineTo","closePath","update","bigCoords","translate","newSize","inner","children","curSize","mimic","lineHeight","restore","clearRect","fillStyle","fill","coordsize","antialias","Number","$this","path","fillcolor","filled","stroked","opera","calculate","corners","userOffset","b","max","margin","bottom","right","shiftflip","direction","popposite","opposite","newCorner","shiftonly","xy","shift","horizontal","vertical","cornerTop","cornerLeft","user","^position.my|style.tip.(corner|mimic|border)$","^style.tip.(height|width)$","^content.title|style.(classes|widget)$","MODAL","OVERLAY","MODALCLASS","MODALSELECTOR","focusable","expr","map","mapName","isTabIndexNotNaN","parentNode","href","focusInputs","blurElems","focusableElems","first","stealFocus","targetOnTop","current","prevState","mousedown","modal","escape","keyCode","stealfocus","visibleModals","detach","overlay","modal_zindex","oEvent","last","^show.modal.(on|blur)$","elemWidth","elemHeight","otherSide","adjustment","side1","side2","lengthName","targetLength","elemLength","initialPos","mySide","atSide","isShift","myLength","atLength","sideOffset","viewportScroll","viewportOffset","containerStatic","containerOffset","overflow1","overflow2","viewportWidth","viewportHeight","min","newMy","methodX","methodY","polys","polygon","baseCoords","newWidth","newHeight","compareX","compareY","realX","realY","floor","rect","ax","ay","bx","by","_angles","ellipse","cx","cy","rx","ry","rxc","cos","PI","rys","sin","circle","r","frameOffset","mtx","transformed","len","points","root","strokeWidth2","getBBox","baseVal","x1","y1","x2","y2","numberOfItems","getItem","createSVGPoint","getScreenCTM","matrixTransform","defaultView","parentWindow","frameElement","area","imageOffset","shape","image","coordsString","coordsArray","IE6","BGIFRAME","_scroll","bgiframe","adjustBGIFrame","redrawContainer","redraw","tipAdjust","dimensions","plugin","drawing","perc","ie6","^content|style$"],"mappings":"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","file":"jquery.qtip.min.js"}qTip2-3.0.2/generate-bower.json.js000066400000000000000000000007521263162617100167400ustar00rootroot00000000000000var fs = require('fs'); var pkg = require('./package.json'); var bower = { name: pkg.name, description: pkg.description, version: pkg.version, homepage: pkg.homepage, repository: pkg.repository, author: pkg.author, license: pkg.licenses.map(function (license) { return license.type; }), keywords: pkg.keywords, main: [ './dist/jquery.qtip.js', './dist/jquery.qtip.css' ], dependencies: pkg.dependencies }; fs.writeFile('bower.json', JSON.stringify(bower, null, '\t')); qTip2-3.0.2/grunt/000077500000000000000000000000001263162617100136575ustar00rootroot00000000000000qTip2-3.0.2/grunt/aliases.js000066400000000000000000000012131263162617100156330ustar00rootroot00000000000000var BASIC = 'BASIC'; var defaultTasks = [ 'concat', 'uglify', 'cssmin', 'replace' ]; function alias(type) { var start = type === BASIC ? 1 : 0; return [type === BASIC ? 'init:basic' : 'init'].concat( Array.prototype.slice.call(arguments, start) ).concat( defaultTasks ); } // Task aliases module.exports = { default: alias('clean'), basic: alias(BASIC, 'clean'), css: alias('clean', 'concat:css', 'cssmin', 'replace'), all: alias('clean').concat( alias(BASIC) ), lint: [ 'eslint', 'csslint' ], 'watch_js': [ 'eslint', 'init', 'concat', 'uglify', 'replace' ], 'watch_css': [ 'csslint', 'init', 'concat', 'cssmin', 'replace' ] }; qTip2-3.0.2/grunt/clean.js000066400000000000000000000000531263162617100152750ustar00rootroot00000000000000module.exports = ['<%=dirs.dist%>/**/*.*'];qTip2-3.0.2/grunt/concat.js000066400000000000000000000004641263162617100154700ustar00rootroot00000000000000module.exports = { options: { stripBanners: true, separator: ';', banner: '<%=meta.banners.full%>' }, js: { // See "init" task for src dest: '<%=dirs.dist%>/jquery.qtip.js' }, css: { // See "init" task for src options: { separator: '\n\n' }, dest: '<%=dirs.dist%>/jquery.qtip.css' } }; qTip2-3.0.2/grunt/csslint.js000066400000000000000000000002141263162617100156710ustar00rootroot00000000000000module.exports = { options: { 'empty-rules': false, important: false, ids: false }, css: { src: ['<%=dirs.src%>/**/*.css'] } }; qTip2-3.0.2/grunt/cssmin.js000066400000000000000000000003321263162617100155070ustar00rootroot00000000000000module.exports = { options: { keepSpecialComments: 0, banner: '<%=meta.banners.minified%>', report: 'min' }, js: { files: { '<%=dirs.dist%>/jquery.qtip.min.css': '<%=dirs.dist%>/jquery.qtip.css' } } };qTip2-3.0.2/grunt/eslint.js000066400000000000000000000003021263162617100155060ustar00rootroot00000000000000module.exports = { js: { src: [ 'Gruntfile.js', '<%=dirs.src%>/*/*.js', // Ignore intro/outro files '!<%=dirs.src%>/core/intro.js', '!<%=dirs.src%>/core/outro.js' ] } }; qTip2-3.0.2/grunt/replace.js000066400000000000000000000003311263162617100156250ustar00rootroot00000000000000module.exports = { js: { options: { patterns: [] // Replacements are set up in `init` task }, files: [{ expand: true, flatten: true, src: ['<%=dirs.dist%>/**/*'], dest: '<%=dirs.dist%>/' }] } }; qTip2-3.0.2/grunt/tasks/000077500000000000000000000000001263162617100150045ustar00rootroot00000000000000qTip2-3.0.2/grunt/tasks/init.js000066400000000000000000000070121263162617100163050ustar00rootroot00000000000000module.exports = function(grunt) { grunt.registerTask('init', 'Initialise build configuration.', function(basic) { // Grab command - line options, using valid defaults if not given var done = this.async(), stable = grunt.option('stable') === true, plugins = (grunt.option('plugins') || Object.keys( grunt.config('plugins')).join(' ')).replace(/ /g, ' ').split(' '), styles = (grunt.option('styles') || Object.keys( grunt.config('styles')).join(' ')).replace(/ /g, ' ').split(' '), valid; // Setup JS/CSS arrays var js = grunt.config('core.js'), css = grunt.config('core.css'), dist = grunt.option('dist') || 'dist'; // Add intro file js.unshift(grunt.config('wrappers.js.intro')); // If basic... go into dist/basic if(basic) { dist += '/basic'; } // Parse 'dist' option (decides which directory to build into) grunt.config('dirs.dist', dist); // Parse 'styles' option (decides which stylesheets are included) if(!basic && grunt.option('styles') !== 0) { styles.forEach(function(style, i) { if(valid = grunt.config('styles.' + style)) { css.push(valid); } else { styles[i] = style + '*'.red; } }); styles.unshift('core'); } else { styles = ['core']; } // Parse 'plugins' option (decides which plugins are included) if(!basic && grunt.option('plugins') !== 0) { plugins.forEach(function(plugin, i) { if(valid = grunt.config('plugins.' + plugin)) { if(valid.js) { js.push(valid.js); } if(valid.css) { css.push(valid.css); } } else { plugins[i] = plugin + '*'.red; } }); } else { plugins = ['None']; } // Add outro file js.push(grunt.config('wrappers.js.outro')); // Update concatenation config grunt.config('concat.js.src', js); grunt.config('concat.css.src', css); // Setup in - file text replacements (version, date etc) grunt.util.spawn({ cmd: 'git', args: ['describe', '--tags'] }, function(err, data) { // Ensure it succeed if(data.code > 1) { grunt.log.write('Uhoh... couldn\'t grab Git repository description. Somethings up!'); return done(); } // Determine version var version = stable ? grunt.config('pkg.version') : grunt.config('pkg.version', data.stdout.substr(0,10) ); // Set version type config grunt.config('pkg.type', stable ? 'stable' : 'nightly'); // Setup styles and plugins replacements arrays var strStyles = styles.length ? styles.join(' ') : ''; var strPlugins = plugins.length ? plugins.join(' ') : ''; // Setup build properties var buildprops = (plugins.length ? ' * Plugins: ' + strPlugins + '\n' : '') + (styles.length ? ' * Styles: ' + strStyles + '\n' : ''); // Setup minification build properties var minbuildprops = plugins[0] !== 'None' || styles[0] !== 'None' ? '(includes: ' + (plugins[0] !== 'None' ? strPlugins : '') + (styles[0] !== 'None' ? ' / ' + strStyles : '') + ') ' : ''; // Set replacement variables grunt.config('replace.js.options.patterns', [{ json: { 'BUILDPROPS': buildprops, 'MINBUILDPROPS': minbuildprops, 'VERSION': stable ? version : version.substr(1), 'vVERSION': stable ? 'v' + version : version, 'DATE': grunt.template.today('dd - mm - yyyy'), 'STYLES': strStyles, 'PLUGINS': strPlugins } }]); // Output current build properties grunt.log.write('\nBuilding ' + 'qTip2'.green + ' ' + version + ' with ' + 'plugins ' + plugins.join(' ').green + ' and ' + 'styles ' +styles.join(' ').green + '\n' ); // Async task done done(version); }); }); };qTip2-3.0.2/grunt/uglify.js000066400000000000000000000004751263162617100155220ustar00rootroot00000000000000module.exports = { options: { preserveComments: false, report: 'min', banner: '<%=meta.banners.minified%>', sourceMap: true, sourceMapName: function(name) { return name.replace('.js', '.map'); } }, js: { files: { '<%=dirs.dist%>/jquery.qtip.min.js': ['<%=dirs.dist%>/jquery.qtip.js'] } } }; qTip2-3.0.2/grunt/watch.js000066400000000000000000000002511263162617100153210ustar00rootroot00000000000000module.exports = { options: { livereload: true }, js: { files: 'src/**/*js', tasks: 'watch_js' }, css: { files: 'src/**/*.css', tasks: 'watch_css' } };qTip2-3.0.2/package.json000066400000000000000000000035611263162617100150130ustar00rootroot00000000000000{ "name": "qtip2", "title": "qTip2 - Pretty powerful tooltips", "description": "Introducing... qTip2. The second generation of the advanced qTip plugin for the ever popular jQuery framework.", "version": "3.0.2", "homepage": "http://qtip2.com", "author": "Craig Michael Thompson (http://craigsworks.com/)", "main": "dist/jquery.qtip.js", "scripts": { "build": "npm install && grunt", "build:all": "grunt all", "build:stable": "grunt all --stable && npm run build:bower", "build:bower": "node generate-bower.json", "start": "grunt", "test": "grunt lint", "preversion": "npm test", "version": "npm run build:stable && npm run version:add", "version:add": "git add dist bower.json", "postversion": "git push --follow-tags && npm publish", "recompile": "npm run build:all && git commit dist -m \"Recompile distributable files\"; git push" }, "repository": { "type": "git", "url": "git://github.com/qTip2/qTip2.git" }, "keywords": [ "tooltip", "tooltips", "jquery", "jquery-plugin", "qtip", "qtip2", "simpletip", "craig thompson", "craig michael thompson", "craigsworks", "craga89" ], "bugs": { "url": "https://github.com/qTip2/qTip2/issues" }, "licenses": [ { "type": "MIT", "url": "https://github.com/qTip2/qTip2/blob/master/LICENSE-MIT" } ], "dependencies": { "jquery": ">=1.6.0", "imagesloaded": ">=3.0.0" }, "devDependencies": { "grunt": "~0.4.5", "grunt-cli": "~0.1.13", "grunt-contrib-clean": "~0.7.0", "grunt-contrib-concat": "~0.5.1", "grunt-contrib-csslint": "~0.5.0", "grunt-contrib-cssmin": "~0.14.0", "grunt-contrib-uglify": "~0.11.0", "grunt-contrib-watch": "~0.6.1", "grunt-eslint": "^17.3.1", "grunt-replace": "~0.11.0", "load-grunt-config": "~0.19.1" } } qTip2-3.0.2/src/000077500000000000000000000000001263162617100133075ustar00rootroot00000000000000qTip2-3.0.2/src/basic.css000066400000000000000000000030421263162617100151010ustar00rootroot00000000000000/*! Light tooltip style */ .qtip-light{ background-color: white; border-color: #E2E2E2; color: #454545; } .qtip-light .qtip-titlebar{ background-color: #f1f1f1; } /*! Dark tooltip style */ .qtip-dark{ background-color: #505050; border-color: #303030; color: #f3f3f3; } .qtip-dark .qtip-titlebar{ background-color: #404040; } .qtip-dark .qtip-icon{ border-color: #444; } .qtip-dark .qtip-titlebar .ui-state-hover{ border-color: #303030; } /*! Cream tooltip style */ .qtip-cream{ background-color: #FBF7AA; border-color: #F9E98E; color: #A27D35; } .qtip-cream .qtip-titlebar{ background-color: #F0DE7D; } .qtip-cream .qtip-close .qtip-icon{ background-position: -82px 0; } /*! Red tooltip style */ .qtip-red{ background-color: #F78B83; border-color: #D95252; color: #912323; } .qtip-red .qtip-titlebar{ background-color: #F06D65; } .qtip-red .qtip-close .qtip-icon{ background-position: -102px 0; } .qtip-red .qtip-icon{ border-color: #D95252; } .qtip-red .qtip-titlebar .ui-state-hover{ border-color: #D95252; } /*! Green tooltip style */ .qtip-green{ background-color: #CAED9E; border-color: #90D93F; color: #3F6219; } .qtip-green .qtip-titlebar{ background-color: #B0DE78; } .qtip-green .qtip-close .qtip-icon{ background-position: -42px 0; } /*! Blue tooltip style */ .qtip-blue{ background-color: #E5F6FE; border-color: #ADD9ED; color: #5E99BD; } .qtip-blue .qtip-titlebar{ background-color: #D0E9F5; } .qtip-blue .qtip-close .qtip-icon{ background-position: -2px 0; } qTip2-3.0.2/src/core.css000066400000000000000000000037131263162617100147550ustar00rootroot00000000000000.qtip{ position: absolute; left: -28000px; top: -28000px; display: none; max-width: 280px; min-width: 50px; font-size: 10.5px; line-height: 12px; direction: ltr; box-shadow: none; padding: 0; } .qtip-content{ position: relative; padding: 5px 9px; overflow: hidden; text-align: left; word-wrap: break-word; } .qtip-titlebar{ position: relative; padding: 5px 35px 5px 10px; overflow: hidden; border-width: 0 0 1px; font-weight: bold; } .qtip-titlebar + .qtip-content{ border-top-width: 0 !important; } /* Default close button class */ .qtip-close{ position: absolute; right: -9px; top: -9px; z-index: 11; /* Overlap .qtip-tip */ cursor: pointer; outline: medium none; border: 1px solid transparent; } .qtip-titlebar .qtip-close{ right: 4px; top: 50%; margin-top: -9px; } * html .qtip-titlebar .qtip-close{ top: 16px; } /* IE fix */ .qtip-titlebar .ui-icon, .qtip-icon .ui-icon{ display: block; text-indent: -1000em; direction: ltr; } .qtip-icon, .qtip-icon .ui-icon{ -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; text-decoration: none; } .qtip-icon .ui-icon{ width: 18px; height: 14px; line-height: 14px; text-align: center; text-indent: 0; font: normal bold 10px/13px Tahoma,sans-serif; color: inherit; background: transparent none no-repeat -100em -100em; } /* Applied to 'focused' tooltips e.g. most recently displayed/interacted with */ .qtip-focus{} /* Applied on hover of tooltips i.e. added/removed on mouseenter/mouseleave respectively */ .qtip-hover{} /* Default tooltip style */ .qtip-default{ border: 1px solid #F1D031; background-color: #FFFFA3; color: #555; } .qtip-default .qtip-titlebar{ background-color: #FFEF93; } .qtip-default .qtip-icon{ border-color: #CCC; background: #F1F1F1; color: #777; } .qtip-default .qtip-titlebar .qtip-close{ border-color: #AAA; color: #111; } qTip2-3.0.2/src/core/000077500000000000000000000000001263162617100142375ustar00rootroot00000000000000qTip2-3.0.2/src/core/button.js000066400000000000000000000022171263162617100161120ustar00rootroot00000000000000PROTOTYPE._createButton = function() { var self = this, elements = this.elements, tooltip = elements.tooltip, button = this.options.content.button, isString = typeof button === 'string', close = isString ? button : 'Close tooltip'; if(elements.button) { elements.button.remove(); } // Use custom button if one was supplied by user, else use default if(button.jquery) { elements.button = button; } else { elements.button = $('', { 'class': 'qtip-close ' + (this.options.style.widget ? '' : NAMESPACE+'-icon'), 'title': close, 'aria-label': close }) .prepend( $('', { 'class': 'ui-icon ui-icon-close', 'html': '×' }) ); } // Create button and setup attributes elements.button.appendTo(elements.titlebar || tooltip) .attr('role', 'button') .click(function(event) { if(!tooltip.hasClass(CLASS_DISABLED)) { self.hide(event); } return FALSE; }); }; PROTOTYPE._updateButton = function(button) { // Make sure tooltip is rendered and if not, return if(!this.rendered) { return FALSE; } var elem = this.elements.button; if(button) { this._createButton(); } else { elem.remove(); } }; qTip2-3.0.2/src/core/class.js000066400000000000000000000122021263162617100156770ustar00rootroot00000000000000/* * Core plugin implementation */ function QTip(target, options, id, attr) { // Elements and ID this.id = id; this.target = target; this.tooltip = NULL; this.elements = { target: target }; // Internal constructs this._id = NAMESPACE + '-' + id; this.timers = { img: {} }; this.options = options; this.plugins = {}; // Cache object this.cache = { event: {}, target: $(), disabled: FALSE, attr: attr, onTooltip: FALSE, lastClass: '' }; // Set the initial flags this.rendered = this.destroyed = this.disabled = this.waiting = this.hiddenDuringWait = this.positioning = this.triggering = FALSE; } PROTOTYPE = QTip.prototype; PROTOTYPE._when = function(deferreds) { return $.when.apply($, deferreds); }; PROTOTYPE.render = function(show) { if(this.rendered || this.destroyed) { return this; } // If tooltip has already been rendered, exit var self = this, options = this.options, cache = this.cache, elements = this.elements, text = options.content.text, title = options.content.title, button = options.content.button, posOptions = options.position, deferreds = []; // Add ARIA attributes to target $.attr(this.target[0], 'aria-describedby', this._id); // Create public position object that tracks current position corners cache.posClass = this._createPosClass( (this.position = { my: posOptions.my, at: posOptions.at }).my ); // Create tooltip element this.tooltip = elements.tooltip = $('
', { 'id': this._id, 'class': [ NAMESPACE, CLASS_DEFAULT, options.style.classes, cache.posClass ].join(' '), 'width': options.style.width || '', 'height': options.style.height || '', 'tracking': posOptions.target === 'mouse' && posOptions.adjust.mouse, /* ARIA specific attributes */ 'role': 'alert', 'aria-live': 'polite', 'aria-atomic': FALSE, 'aria-describedby': this._id + '-content', 'aria-hidden': TRUE }) .toggleClass(CLASS_DISABLED, this.disabled) .attr(ATTR_ID, this.id) .data(NAMESPACE, this) .appendTo(posOptions.container) .append( // Create content element elements.content = $('
', { 'class': NAMESPACE + '-content', 'id': this._id + '-content', 'aria-atomic': TRUE }) ); // Set rendered flag and prevent redundant reposition calls for now this.rendered = -1; this.positioning = TRUE; // Create title... if(title) { this._createTitle(); // Update title only if its not a callback (called in toggle if so) if(!$.isFunction(title)) { deferreds.push( this._updateTitle(title, FALSE) ); } } // Create button if(button) { this._createButton(); } // Set proper rendered flag and update content if not a callback function (called in toggle) if(!$.isFunction(text)) { deferreds.push( this._updateContent(text, FALSE) ); } this.rendered = TRUE; // Setup widget classes this._setWidget(); // Initialize 'render' plugins $.each(PLUGINS, function(name) { var instance; if(this.initialize === 'render' && (instance = this(self))) { self.plugins[name] = instance; } }); // Unassign initial events and assign proper events this._unassignEvents(); this._assignEvents(); // When deferreds have completed this._when(deferreds).then(function() { // tooltiprender event self._trigger('render'); // Reset flags self.positioning = FALSE; // Show tooltip if not hidden during wait period if(!self.hiddenDuringWait && (options.show.ready || show)) { self.toggle(TRUE, cache.event, FALSE); } self.hiddenDuringWait = FALSE; }); // Expose API QTIP.api[this.id] = this; return this; }; PROTOTYPE.destroy = function(immediate) { // Set flag the signify destroy is taking place to plugins // and ensure it only gets destroyed once! if(this.destroyed) { return this.target; } function process() { if(this.destroyed) { return; } this.destroyed = TRUE; var target = this.target, title = target.attr(oldtitle), timer; // Destroy tooltip if rendered if(this.rendered) { this.tooltip.stop(1,0).find('*').remove().end().remove(); } // Destroy all plugins $.each(this.plugins, function() { this.destroy && this.destroy(); }); // Clear timers for (timer in this.timers) { if (this.timers.hasOwnProperty(timer)) { clearTimeout(this.timers[timer]); } } // Remove api object and ARIA attributes target.removeData(NAMESPACE) .removeAttr(ATTR_ID) .removeAttr(ATTR_HAS) .removeAttr('aria-describedby'); // Reset old title attribute if removed if(this.options.suppress && title) { target.attr('title', title).removeAttr(oldtitle); } // Remove qTip events associated with this API this._unassignEvents(); // Remove ID from used id objects, and delete object references // for better garbage collection and leak protection this.options = this.elements = this.cache = this.timers = this.plugins = this.mouse = NULL; // Delete epoxsed API object delete QTIP.api[this.id]; } // If an immediate destroy is needed if((immediate !== TRUE || this.triggering === 'hide') && this.rendered) { this.tooltip.one('tooltiphidden', $.proxy(process, this)); !this.triggering && this.hide(); } // If we're not in the process of hiding... process else { process.call(this); } return this.target; }; qTip2-3.0.2/src/core/constants.js000066400000000000000000000032521263162617100166130ustar00rootroot00000000000000/* eslint-disable no-unused-vars */ // Munge the primitives - Paul Irish tip var TRUE = true, FALSE = false, NULL = null, // Common variables X = 'x', Y = 'y', WIDTH = 'width', HEIGHT = 'height', // Positioning sides TOP = 'top', LEFT = 'left', BOTTOM = 'bottom', RIGHT = 'right', CENTER = 'center', // Position adjustment types FLIP = 'flip', FLIPINVERT = 'flipinvert', SHIFT = 'shift', // Shortcut vars QTIP, PROTOTYPE, CORNER, CHECKS, PLUGINS = {}, NAMESPACE = 'qtip', ATTR_HAS = 'data-hasqtip', ATTR_ID = 'data-qtip-id', WIDGET = ['ui-widget', 'ui-tooltip'], SELECTOR = '.'+NAMESPACE, INACTIVE_EVENTS = 'click dblclick mousedown mouseup mousemove mouseleave mouseenter'.split(' '), CLASS_FIXED = NAMESPACE+'-fixed', CLASS_DEFAULT = NAMESPACE + '-default', CLASS_FOCUS = NAMESPACE + '-focus', CLASS_HOVER = NAMESPACE + '-hover', CLASS_DISABLED = NAMESPACE+'-disabled', replaceSuffix = '_replacedByqTip', oldtitle = 'oldtitle', trackingBound, // Browser detection BROWSER = { /* * IE version detection * * Adapted from: http://ajaxian.com/archives/attack-of-the-ie-conditional-comment * Credit to James Padolsey for the original implemntation! */ ie: (function() { /* eslint-disable no-empty */ var v, i; for ( v = 4, i = document.createElement('div'); (i.innerHTML = '') && i.getElementsByTagName('i')[0]; v+=1 ) {} return v > 4 ? v : NaN; /* eslint-enable no-empty */ })(), /* * iOS version detection */ iOS: parseFloat( ('' + (/CPU.*OS ([0-9_]{1,5})|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent) || [0,''])[1]) .replace('undefined', '3_2').replace('_', '.').replace('_', '') ) || FALSE }; qTip2-3.0.2/src/core/content.js000066400000000000000000000060571263162617100162570ustar00rootroot00000000000000PROTOTYPE._update = function(content, element) { var self = this, cache = this.cache; // Make sure tooltip is rendered and content is defined. If not return if(!this.rendered || !content) { return FALSE; } // Use function to parse content if($.isFunction(content)) { content = content.call(this.elements.target, cache.event, this) || ''; } // Handle deferred content if($.isFunction(content.then)) { cache.waiting = TRUE; return content.then(function(c) { cache.waiting = FALSE; return self._update(c, element); }, NULL, function(e) { return self._update(e, element); }); } // If content is null... return false if(content === FALSE || !content && content !== '') { return FALSE; } // Append new content if its a DOM array and show it if hidden if(content.jquery && content.length > 0) { element.empty().append( content.css({ display: 'block', visibility: 'visible' }) ); } // Content is a regular string, insert the new content else { element.html(content); } // Wait for content to be loaded, and reposition return this._waitForContent(element).then(function(images) { if(self.rendered && self.tooltip[0].offsetWidth > 0) { self.reposition(cache.event, !images.length); } }); }; PROTOTYPE._waitForContent = function(element) { var cache = this.cache; // Set flag cache.waiting = TRUE; // If imagesLoaded is included, ensure images have loaded and return promise return ( $.fn.imagesLoaded ? element.imagesLoaded() : new $.Deferred().resolve([]) ) .done(function() { cache.waiting = FALSE; }) .promise(); }; PROTOTYPE._updateContent = function(content, reposition) { this._update(content, this.elements.content, reposition); }; PROTOTYPE._updateTitle = function(content, reposition) { if(this._update(content, this.elements.title, reposition) === FALSE) { this._removeTitle(FALSE); } }; PROTOTYPE._createTitle = function() { var elements = this.elements, id = this._id+'-title'; // Destroy previous title element, if present if(elements.titlebar) { this._removeTitle(); } // Create title bar and title elements elements.titlebar = $('
', { 'class': NAMESPACE + '-titlebar ' + (this.options.style.widget ? createWidgetClass('header') : '') }) .append( elements.title = $('
', { 'id': id, 'class': NAMESPACE + '-title', 'aria-atomic': TRUE }) ) .insertBefore(elements.content) // Button-specific events .delegate('.qtip-close', 'mousedown keydown mouseup keyup mouseout', function(event) { $(this).toggleClass('ui-state-active ui-state-focus', event.type.substr(-4) === 'down'); }) .delegate('.qtip-close', 'mouseover mouseout', function(event){ $(this).toggleClass('ui-state-hover', event.type === 'mouseover'); }); // Create button if enabled if(this.options.content.button) { this._createButton(); } }; PROTOTYPE._removeTitle = function(reposition) { var elements = this.elements; if(elements.title) { elements.titlebar.remove(); elements.titlebar = elements.title = elements.button = NULL; // Reposition if enabled if(reposition !== FALSE) { this.reposition(); } } }; qTip2-3.0.2/src/core/defaults.js000066400000000000000000000023571263162617100164130ustar00rootroot00000000000000// qTip version QTIP.version = '@@VERSION'; // Base ID for all qTips QTIP.nextid = 0; // Inactive events array QTIP.inactiveEvents = INACTIVE_EVENTS; // Base z-index for all qTips QTIP.zindex = 15000; // Define configuration defaults QTIP.defaults = { prerender: FALSE, id: FALSE, overwrite: TRUE, suppress: TRUE, content: { text: TRUE, attr: 'title', title: FALSE, button: FALSE }, position: { my: 'top left', at: 'bottom right', target: FALSE, container: FALSE, viewport: FALSE, adjust: { x: 0, y: 0, mouse: TRUE, scroll: TRUE, resize: TRUE, method: 'flipinvert flipinvert' }, effect: function(api, pos) { $(this).animate(pos, { duration: 200, queue: FALSE }); } }, show: { target: FALSE, event: 'mouseenter', effect: TRUE, delay: 90, solo: FALSE, ready: FALSE, autofocus: FALSE }, hide: { target: FALSE, event: 'mouseleave', effect: TRUE, delay: 0, fixed: FALSE, inactive: FALSE, leave: 'window', distance: FALSE }, style: { classes: '', widget: FALSE, width: FALSE, height: FALSE, def: TRUE }, events: { render: NULL, move: NULL, show: NULL, hide: NULL, toggle: NULL, visible: NULL, hidden: NULL, focus: NULL, blur: NULL } }; qTip2-3.0.2/src/core/disable.js000066400000000000000000000010451263162617100162000ustar00rootroot00000000000000PROTOTYPE.disable = function(state) { if(this.destroyed) { return this; } // If 'toggle' is passed, toggle the current state if(state === 'toggle') { state = !(this.rendered ? this.tooltip.hasClass(CLASS_DISABLED) : this.disabled); } // Disable if no state passed else if('boolean' !== typeof state) { state = TRUE; } if(this.rendered) { this.tooltip.toggleClass(CLASS_DISABLED, state) .attr('aria-disabled', state); } this.disabled = !!state; return this; }; PROTOTYPE.enable = function() { return this.disable(FALSE); }; qTip2-3.0.2/src/core/events.js000066400000000000000000000320111263162617100160760ustar00rootroot00000000000000function delay(callback, duration) { // If tooltip has displayed, start hide timer if(duration > 0) { return setTimeout( $.proxy(callback, this), duration ); } else{ callback.call(this); } } function showMethod(event) { if(this.tooltip.hasClass(CLASS_DISABLED)) { return; } // Clear hide timers clearTimeout(this.timers.show); clearTimeout(this.timers.hide); // Start show timer this.timers.show = delay.call(this, function() { this.toggle(TRUE, event); }, this.options.show.delay ); } function hideMethod(event) { if(this.tooltip.hasClass(CLASS_DISABLED) || this.destroyed) { return; } // Check if new target was actually the tooltip element var relatedTarget = $(event.relatedTarget), ontoTooltip = relatedTarget.closest(SELECTOR)[0] === this.tooltip[0], ontoTarget = relatedTarget[0] === this.options.show.target[0]; // Clear timers and stop animation queue clearTimeout(this.timers.show); clearTimeout(this.timers.hide); // Prevent hiding if tooltip is fixed and event target is the tooltip. // Or if mouse positioning is enabled and cursor momentarily overlaps if(this !== relatedTarget[0] && (this.options.position.target === 'mouse' && ontoTooltip) || this.options.hide.fixed && ( (/mouse(out|leave|move)/).test(event.type) && (ontoTooltip || ontoTarget)) ) { /* eslint-disable no-empty */ try { event.preventDefault(); event.stopImmediatePropagation(); } catch(e) {} /* eslint-enable no-empty */ return; } // If tooltip has displayed, start hide timer this.timers.hide = delay.call(this, function() { this.toggle(FALSE, event); }, this.options.hide.delay, this ); } function inactiveMethod(event) { if(this.tooltip.hasClass(CLASS_DISABLED) || !this.options.hide.inactive) { return; } // Clear timer clearTimeout(this.timers.inactive); this.timers.inactive = delay.call(this, function(){ this.hide(event); }, this.options.hide.inactive ); } function repositionMethod(event) { if(this.rendered && this.tooltip[0].offsetWidth > 0) { this.reposition(event); } } // Store mouse coordinates PROTOTYPE._storeMouse = function(event) { (this.mouse = $.event.fix(event)).type = 'mousemove'; return this; }; // Bind events PROTOTYPE._bind = function(targets, events, method, suffix, context) { if(!targets || !method || !events.length) { return; } var ns = '.' + this._id + (suffix ? '-'+suffix : ''); $(targets).bind( (events.split ? events : events.join(ns + ' ')) + ns, $.proxy(method, context || this) ); return this; }; PROTOTYPE._unbind = function(targets, suffix) { targets && $(targets).unbind('.' + this._id + (suffix ? '-'+suffix : '')); return this; }; // Global delegation helper function delegate(selector, events, method) { $(document.body).delegate(selector, (events.split ? events : events.join('.'+NAMESPACE + ' ')) + '.'+NAMESPACE, function() { var api = QTIP.api[ $.attr(this, ATTR_ID) ]; api && !api.disabled && method.apply(api, arguments); } ); } // Event trigger PROTOTYPE._trigger = function(type, args, event) { var callback = new $.Event('tooltip'+type); callback.originalEvent = event && $.extend({}, event) || this.cache.event || NULL; this.triggering = type; this.tooltip.trigger(callback, [this].concat(args || [])); this.triggering = FALSE; return !callback.isDefaultPrevented(); }; PROTOTYPE._bindEvents = function(showEvents, hideEvents, showTargets, hideTargets, showCallback, hideCallback) { // Get tasrgets that lye within both var similarTargets = showTargets.filter( hideTargets ).add( hideTargets.filter(showTargets) ), toggleEvents = []; // If hide and show targets are the same... if(similarTargets.length) { // Filter identical show/hide events $.each(hideEvents, function(i, type) { var showIndex = $.inArray(type, showEvents); // Both events are identical, remove from both hide and show events // and append to toggleEvents showIndex > -1 && toggleEvents.push( showEvents.splice( showIndex, 1 )[0] ); }); // Toggle events are special case of identical show/hide events, which happen in sequence if(toggleEvents.length) { // Bind toggle events to the similar targets this._bind(similarTargets, toggleEvents, function(event) { var state = this.rendered ? this.tooltip[0].offsetWidth > 0 : false; (state ? hideCallback : showCallback).call(this, event); }); // Remove the similar targets from the regular show/hide bindings showTargets = showTargets.not(similarTargets); hideTargets = hideTargets.not(similarTargets); } } // Apply show/hide/toggle events this._bind(showTargets, showEvents, showCallback); this._bind(hideTargets, hideEvents, hideCallback); }; PROTOTYPE._assignInitialEvents = function(event) { var options = this.options, showTarget = options.show.target, hideTarget = options.hide.target, showEvents = options.show.event ? $.trim('' + options.show.event).split(' ') : [], hideEvents = options.hide.event ? $.trim('' + options.hide.event).split(' ') : []; // Catch remove/removeqtip events on target element to destroy redundant tooltips this._bind(this.elements.target, ['remove', 'removeqtip'], function() { this.destroy(true); }, 'destroy'); /* * Make sure hoverIntent functions properly by using mouseleave as a hide event if * mouseenter/mouseout is used for show.event, even if it isn't in the users options. */ if(/mouse(over|enter)/i.test(options.show.event) && !/mouse(out|leave)/i.test(options.hide.event)) { hideEvents.push('mouseleave'); } /* * Also make sure initial mouse targetting works correctly by caching mousemove coords * on show targets before the tooltip has rendered. Also set onTarget when triggered to * keep mouse tracking working. */ this._bind(showTarget, 'mousemove', function(moveEvent) { this._storeMouse(moveEvent); this.cache.onTarget = TRUE; }); // Define hoverIntent function function hoverIntent(hoverEvent) { // Only continue if tooltip isn't disabled if(this.disabled || this.destroyed) { return FALSE; } // Cache the event data this.cache.event = hoverEvent && $.event.fix(hoverEvent); this.cache.target = hoverEvent && $(hoverEvent.target); // Start the event sequence clearTimeout(this.timers.show); this.timers.show = delay.call(this, function() { this.render(typeof hoverEvent === 'object' || options.show.ready); }, options.prerender ? 0 : options.show.delay ); } // Filter and bind events this._bindEvents(showEvents, hideEvents, showTarget, hideTarget, hoverIntent, function() { if(!this.timers) { return FALSE; } clearTimeout(this.timers.show); }); // Prerendering is enabled, create tooltip now if(options.show.ready || options.prerender) { hoverIntent.call(this, event); } }; // Event assignment method PROTOTYPE._assignEvents = function() { var self = this, options = this.options, posOptions = options.position, tooltip = this.tooltip, showTarget = options.show.target, hideTarget = options.hide.target, containerTarget = posOptions.container, viewportTarget = posOptions.viewport, documentTarget = $(document), windowTarget = $(window), showEvents = options.show.event ? $.trim('' + options.show.event).split(' ') : [], hideEvents = options.hide.event ? $.trim('' + options.hide.event).split(' ') : []; // Assign passed event callbacks $.each(options.events, function(name, callback) { self._bind(tooltip, name === 'toggle' ? ['tooltipshow','tooltiphide'] : ['tooltip'+name], callback, null, tooltip); }); // Hide tooltips when leaving current window/frame (but not select/option elements) if(/mouse(out|leave)/i.test(options.hide.event) && options.hide.leave === 'window') { this._bind(documentTarget, ['mouseout', 'blur'], function(event) { if(!/select|option/.test(event.target.nodeName) && !event.relatedTarget) { this.hide(event); } }); } // Enable hide.fixed by adding appropriate class if(options.hide.fixed) { hideTarget = hideTarget.add( tooltip.addClass(CLASS_FIXED) ); } /* * Make sure hoverIntent functions properly by using mouseleave to clear show timer if * mouseenter/mouseout is used for show.event, even if it isn't in the users options. */ else if(/mouse(over|enter)/i.test(options.show.event)) { this._bind(hideTarget, 'mouseleave', function() { clearTimeout(this.timers.show); }); } // Hide tooltip on document mousedown if unfocus events are enabled if(('' + options.hide.event).indexOf('unfocus') > -1) { this._bind(containerTarget.closest('html'), ['mousedown', 'touchstart'], function(event) { var elem = $(event.target), enabled = this.rendered && !this.tooltip.hasClass(CLASS_DISABLED) && this.tooltip[0].offsetWidth > 0, isAncestor = elem.parents(SELECTOR).filter(this.tooltip[0]).length > 0; if(elem[0] !== this.target[0] && elem[0] !== this.tooltip[0] && !isAncestor && !this.target.has(elem[0]).length && enabled ) { this.hide(event); } }); } // Check if the tooltip hides when inactive if('number' === typeof options.hide.inactive) { // Bind inactive method to show target(s) as a custom event this._bind(showTarget, 'qtip-'+this.id+'-inactive', inactiveMethod, 'inactive'); // Define events which reset the 'inactive' event handler this._bind(hideTarget.add(tooltip), QTIP.inactiveEvents, inactiveMethod); } // Filter and bind events this._bindEvents(showEvents, hideEvents, showTarget, hideTarget, showMethod, hideMethod); // Mouse movement bindings this._bind(showTarget.add(tooltip), 'mousemove', function(event) { // Check if the tooltip hides when mouse is moved a certain distance if('number' === typeof options.hide.distance) { var origin = this.cache.origin || {}, limit = this.options.hide.distance, abs = Math.abs; // Check if the movement has gone beyond the limit, and hide it if so if(abs(event.pageX - origin.pageX) >= limit || abs(event.pageY - origin.pageY) >= limit) { this.hide(event); } } // Cache mousemove coords on show targets this._storeMouse(event); }); // Mouse positioning events if(posOptions.target === 'mouse') { // If mouse adjustment is on... if(posOptions.adjust.mouse) { // Apply a mouseleave event so we don't get problems with overlapping if(options.hide.event) { // Track if we're on the target or not this._bind(showTarget, ['mouseenter', 'mouseleave'], function(event) { if(!this.cache) {return FALSE; } this.cache.onTarget = event.type === 'mouseenter'; }); } // Update tooltip position on mousemove this._bind(documentTarget, 'mousemove', function(event) { // Update the tooltip position only if the tooltip is visible and adjustment is enabled if(this.rendered && this.cache.onTarget && !this.tooltip.hasClass(CLASS_DISABLED) && this.tooltip[0].offsetWidth > 0) { this.reposition(event); } }); } } // Adjust positions of the tooltip on window resize if enabled if(posOptions.adjust.resize || viewportTarget.length) { this._bind( $.event.special.resize ? viewportTarget : windowTarget, 'resize', repositionMethod ); } // Adjust tooltip position on scroll of the window or viewport element if present if(posOptions.adjust.scroll) { this._bind( windowTarget.add(posOptions.container), 'scroll', repositionMethod ); } }; // Un-assignment method PROTOTYPE._unassignEvents = function() { var options = this.options, showTargets = options.show.target, hideTargets = options.hide.target, targets = $.grep([ this.elements.target[0], this.rendered && this.tooltip[0], options.position.container[0], options.position.viewport[0], options.position.container.closest('html')[0], // unfocus window, document ], function(i) { return typeof i === 'object'; }); // Add show and hide targets if they're valid if(showTargets && showTargets.toArray) { targets = targets.concat(showTargets.toArray()); } if(hideTargets && hideTargets.toArray) { targets = targets.concat(hideTargets.toArray()); } // Unbind the events this._unbind(targets) ._unbind(targets, 'destroy') ._unbind(targets, 'inactive'); }; // Apply common event handlers using delegate (avoids excessive .bind calls!) $(function() { delegate(SELECTOR, ['mouseenter', 'mouseleave'], function(event) { var state = event.type === 'mouseenter', tooltip = $(event.currentTarget), target = $(event.relatedTarget || event.target), options = this.options; // On mouseenter... if(state) { // Focus the tooltip on mouseenter (z-index stacking) this.focus(event); // Clear hide timer on tooltip hover to prevent it from closing tooltip.hasClass(CLASS_FIXED) && !tooltip.hasClass(CLASS_DISABLED) && clearTimeout(this.timers.hide); } // On mouseleave... else { // When mouse tracking is enabled, hide when we leave the tooltip and not onto the show target (if a hide event is set) if(options.position.target === 'mouse' && options.position.adjust.mouse && options.hide.event && options.show.target && !target.closest(options.show.target[0]).length) { this.hide(event); } } // Add hover class tooltip.toggleClass(CLASS_HOVER, state); }); // Define events which reset the 'inactive' event handler delegate('['+ATTR_ID+']', INACTIVE_EVENTS, inactiveMethod); }); qTip2-3.0.2/src/core/focus.js000066400000000000000000000022431263162617100157150ustar00rootroot00000000000000PROTOTYPE.focus = function(event) { if(!this.rendered || this.destroyed) { return this; } var qtips = $(SELECTOR), tooltip = this.tooltip, curIndex = parseInt(tooltip[0].style.zIndex, 10), newIndex = QTIP.zindex + qtips.length; // Only update the z-index if it has changed and tooltip is not already focused if(!tooltip.hasClass(CLASS_FOCUS)) { // tooltipfocus event if(this._trigger('focus', [newIndex], event)) { // Only update z-index's if they've changed if(curIndex !== newIndex) { // Reduce our z-index's and keep them properly ordered qtips.each(function() { if(this.style.zIndex > curIndex) { this.style.zIndex = this.style.zIndex - 1; } }); // Fire blur event for focused tooltip qtips.filter('.' + CLASS_FOCUS).qtip('blur', event); } // Set the new z-index tooltip.addClass(CLASS_FOCUS)[0].style.zIndex = newIndex; } } return this; }; PROTOTYPE.blur = function(event) { if(!this.rendered || this.destroyed) { return this; } // Set focused status to FALSE this.tooltip.removeClass(CLASS_FOCUS); // tooltipblur event this._trigger('blur', [ this.tooltip.css('zIndex') ], event); return this; }; qTip2-3.0.2/src/core/intro.js000066400000000000000000000012701263162617100157300ustar00rootroot00000000000000/*jslint browser: true, onevar: true, undef: true, nomen: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: true */ /*global window: false, jQuery: false, console: false, define: false */ /* Cache window, document, undefined */ (function( window, document, undefined ) { // Uses AMD or browser globals to create a jQuery plugin. (function( factory ) { "use strict"; if(typeof define === 'function' && define.amd) { define(['jquery'], factory); } else if(jQuery && !jQuery.fn.qtip) { factory(jQuery); } } (function($) { "use strict"; // Enable ECMAScript "strict" operation for this function. See more: http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/ qTip2-3.0.2/src/core/jquery_methods.js000066400000000000000000000117041263162617100176420ustar00rootroot00000000000000// Initialization method function init(elem, id, opts) { var obj, posOptions, attr, config, title, // Setup element references docBody = $(document.body), // Use document body instead of document element if needed newTarget = elem[0] === document ? docBody : elem, // Grab metadata from element if plugin is present metadata = elem.metadata ? elem.metadata(opts.metadata) : NULL, // If metadata type if HTML5, grab 'name' from the object instead, or use the regular data object otherwise metadata5 = opts.metadata.type === 'html5' && metadata ? metadata[opts.metadata.name] : NULL, // Grab data from metadata.name (or data-qtipopts as fallback) using .data() method, html5 = elem.data(opts.metadata.name || 'qtipopts'); // If we don't get an object returned attempt to parse it manualyl without parseJSON /* eslint-disable no-empty */ try { html5 = typeof html5 === 'string' ? $.parseJSON(html5) : html5; } catch(e) {} /* eslint-enable no-empty */ // Merge in and sanitize metadata config = $.extend(TRUE, {}, QTIP.defaults, opts, typeof html5 === 'object' ? sanitizeOptions(html5) : NULL, sanitizeOptions(metadata5 || metadata)); // Re-grab our positioning options now we've merged our metadata and set id to passed value posOptions = config.position; config.id = id; // Setup missing content if none is detected if('boolean' === typeof config.content.text) { attr = elem.attr(config.content.attr); // Grab from supplied attribute if available if(config.content.attr !== FALSE && attr) { config.content.text = attr; } // No valid content was found, abort render else { return FALSE; } } // Setup target options if(!posOptions.container.length) { posOptions.container = docBody; } if(posOptions.target === FALSE) { posOptions.target = newTarget; } if(config.show.target === FALSE) { config.show.target = newTarget; } if(config.show.solo === TRUE) { config.show.solo = posOptions.container.closest('body'); } if(config.hide.target === FALSE) { config.hide.target = newTarget; } if(config.position.viewport === TRUE) { config.position.viewport = posOptions.container; } // Ensure we only use a single container posOptions.container = posOptions.container.eq(0); // Convert position corner values into x and y strings posOptions.at = new CORNER(posOptions.at, TRUE); posOptions.my = new CORNER(posOptions.my); // Destroy previous tooltip if overwrite is enabled, or skip element if not if(elem.data(NAMESPACE)) { if(config.overwrite) { elem.qtip('destroy', true); } else if(config.overwrite === FALSE) { return FALSE; } } // Add has-qtip attribute elem.attr(ATTR_HAS, id); // Remove title attribute and store it if present if(config.suppress && (title = elem.attr('title'))) { // Final attr call fixes event delegatiom and IE default tooltip showing problem elem.removeAttr('title').attr(oldtitle, title).attr('title', ''); } // Initialize the tooltip and add API reference obj = new QTip(elem, config, id, !!attr); elem.data(NAMESPACE, obj); return obj; } // jQuery $.fn extension method QTIP = $.fn.qtip = function(options, notation, newValue) { var command = ('' + options).toLowerCase(), // Parse command returned = NULL, args = $.makeArray(arguments).slice(1), event = args[args.length - 1], opts = this[0] ? $.data(this[0], NAMESPACE) : NULL; // Check for API request if(!arguments.length && opts || command === 'api') { return opts; } // Execute API command if present else if('string' === typeof options) { this.each(function() { var api = $.data(this, NAMESPACE); if(!api) { return TRUE; } // Cache the event if possible if(event && event.timeStamp) { api.cache.event = event; } // Check for specific API commands if(notation && (command === 'option' || command === 'options')) { if(newValue !== undefined || $.isPlainObject(notation)) { api.set(notation, newValue); } else { returned = api.get(notation); return FALSE; } } // Execute API command else if(api[command]) { api[command].apply(api, args); } }); return returned !== NULL ? returned : this; } // No API commands. validate provided options and setup qTips else if('object' === typeof options || !arguments.length) { // Sanitize options first opts = sanitizeOptions($.extend(TRUE, {}, options)); return this.each(function(i) { var api, id; // Find next available ID, or use custom ID if provided id = $.isArray(opts.id) ? opts.id[i] : opts.id; id = !id || id === FALSE || id.length < 1 || QTIP.api[id] ? QTIP.nextid++ : id; // Initialize the qTip and re-grab newly sanitized options api = init($(this), id, opts); if(api === FALSE) { return TRUE; } else { QTIP.api[id] = api; } // Initialize plugins $.each(PLUGINS, function() { if(this.initialize === 'initialize') { this(api); } }); // Assign initial pre-render events api._assignInitialEvents(event); }); } }; // Expose class $.qtip = QTip; // Populated in render method QTIP.api = {}; qTip2-3.0.2/src/core/jquery_overrides.js000066400000000000000000000042111263162617100201740ustar00rootroot00000000000000 /* * jQuery-specific $.fn overrides */ $.each({ /* Allow other plugins to successfully retrieve the title of an element with a qTip applied */ attr: function(attr, val) { if(this.length) { var self = this[0], title = 'title', api = $.data(self, 'qtip'); if(attr === title && api && api.options && 'object' === typeof api && 'object' === typeof api.options && api.options.suppress) { if(arguments.length < 2) { return $.attr(self, oldtitle); } // If qTip is rendered and title was originally used as content, update it if(api && api.options.content.attr === title && api.cache.attr) { api.set('content.text', val); } // Use the regular attr method to set, then cache the result return this.attr(oldtitle, val); } } return $.fn['attr'+replaceSuffix].apply(this, arguments); }, /* Allow clone to correctly retrieve cached title attributes */ clone: function(keepData) { // Clone our element using the real clone method var elems = $.fn['clone'+replaceSuffix].apply(this, arguments); // Grab all elements with an oldtitle set, and change it to regular title attribute, if keepData is false if(!keepData) { elems.filter('['+oldtitle+']').attr('title', function() { return $.attr(this, oldtitle); }) .removeAttr(oldtitle); } return elems; } }, function(name, func) { if(!func || $.fn[name+replaceSuffix]) { return TRUE; } var old = $.fn[name+replaceSuffix] = $.fn[name]; $.fn[name] = function() { return func.apply(this, arguments) || old.apply(this, arguments); }; }); /* Fire off 'removeqtip' handler in $.cleanData if jQuery UI not present (it already does similar). * This snippet is taken directly from jQuery UI source code found here: * http://code.jquery.com/ui/jquery-ui-git.js */ if(!$.ui) { $['cleanData'+replaceSuffix] = $.cleanData; $.cleanData = function( elems ) { for(var i = 0, elem; (elem = $( elems[i] )).length; i++) { if(elem.attr(ATTR_HAS)) { /* eslint-disable no-empty */ try { elem.triggerHandler('removeqtip'); } catch( e ) {} /* eslint-enable no-empty */ } } $['cleanData'+replaceSuffix].apply(this, arguments); }; } qTip2-3.0.2/src/core/options.js000066400000000000000000000171561263162617100163020ustar00rootroot00000000000000function invalidOpt(a) { return a === NULL || $.type(a) !== 'object'; } function invalidContent(c) { return !($.isFunction(c) || c && c.attr) || c.length || $.type(c) === 'object' && (c.jquery || c.then); } // Option object sanitizer function sanitizeOptions(opts) { var content, text, ajax, once; if(invalidOpt(opts)) { return FALSE; } if(invalidOpt(opts.metadata)) { opts.metadata = { type: opts.metadata }; } if('content' in opts) { content = opts.content; if(invalidOpt(content) || content.jquery || content.done) { text = invalidContent(content) ? FALSE : content; content = opts.content = { text: text }; } else { text = content.text; } // DEPRECATED - Old content.ajax plugin functionality // Converts it into the proper Deferred syntax if('ajax' in content) { ajax = content.ajax; once = ajax && ajax.once !== FALSE; delete content.ajax; content.text = function(event, api) { var loading = text || $(this).attr(api.options.content.attr) || 'Loading...', deferred = $.ajax( $.extend({}, ajax, { context: api }) ) .then(ajax.success, NULL, ajax.error) .then(function(newContent) { if(newContent && once) { api.set('content.text', newContent); } return newContent; }, function(xhr, status, error) { if(api.destroyed || xhr.status === 0) { return; } api.set('content.text', status + ': ' + error); }); return !once ? (api.set('content.text', loading), deferred) : loading; }; } if('title' in content) { if($.isPlainObject(content.title)) { content.button = content.title.button; content.title = content.title.text; } if(invalidContent(content.title || FALSE)) { content.title = FALSE; } } } if('position' in opts && invalidOpt(opts.position)) { opts.position = { my: opts.position, at: opts.position }; } if('show' in opts && invalidOpt(opts.show)) { opts.show = opts.show.jquery ? { target: opts.show } : opts.show === TRUE ? { ready: TRUE } : { event: opts.show }; } if('hide' in opts && invalidOpt(opts.hide)) { opts.hide = opts.hide.jquery ? { target: opts.hide } : { event: opts.hide }; } if('style' in opts && invalidOpt(opts.style)) { opts.style = { classes: opts.style }; } // Sanitize plugin options $.each(PLUGINS, function() { this.sanitize && this.sanitize(opts); }); return opts; } // Setup builtin .set() option checks CHECKS = PROTOTYPE.checks = { builtin: { // Core checks '^id$': function(obj, o, v, prev) { var id = v === TRUE ? QTIP.nextid : v, newId = NAMESPACE + '-' + id; if(id !== FALSE && id.length > 0 && !$('#'+newId).length) { this._id = newId; if(this.rendered) { this.tooltip[0].id = this._id; this.elements.content[0].id = this._id + '-content'; this.elements.title[0].id = this._id + '-title'; } } else { obj[o] = prev; } }, '^prerender': function(obj, o, v) { v && !this.rendered && this.render(this.options.show.ready); }, // Content checks '^content.text$': function(obj, o, v) { this._updateContent(v); }, '^content.attr$': function(obj, o, v, prev) { if(this.options.content.text === this.target.attr(prev)) { this._updateContent( this.target.attr(v) ); } }, '^content.title$': function(obj, o, v) { // Remove title if content is null if(!v) { return this._removeTitle(); } // If title isn't already created, create it now and update v && !this.elements.title && this._createTitle(); this._updateTitle(v); }, '^content.button$': function(obj, o, v) { this._updateButton(v); }, '^content.title.(text|button)$': function(obj, o, v) { this.set('content.'+o, v); // Backwards title.text/button compat }, // Position checks '^position.(my|at)$': function(obj, o, v){ if('string' === typeof v) { this.position[o] = obj[o] = new CORNER(v, o === 'at'); } }, '^position.container$': function(obj, o, v){ this.rendered && this.tooltip.appendTo(v); }, // Show checks '^show.ready$': function(obj, o, v) { v && (!this.rendered && this.render(TRUE) || this.toggle(TRUE)); }, // Style checks '^style.classes$': function(obj, o, v, p) { this.rendered && this.tooltip.removeClass(p).addClass(v); }, '^style.(width|height)': function(obj, o, v) { this.rendered && this.tooltip.css(o, v); }, '^style.widget|content.title': function() { this.rendered && this._setWidget(); }, '^style.def': function(obj, o, v) { this.rendered && this.tooltip.toggleClass(CLASS_DEFAULT, !!v); }, // Events check '^events.(render|show|move|hide|focus|blur)$': function(obj, o, v) { this.rendered && this.tooltip[($.isFunction(v) ? '' : 'un') + 'bind']('tooltip'+o, v); }, // Properties which require event reassignment '^(show|hide|position).(event|target|fixed|inactive|leave|distance|viewport|adjust)': function() { if(!this.rendered) { return; } // Set tracking flag var posOptions = this.options.position; this.tooltip.attr('tracking', posOptions.target === 'mouse' && posOptions.adjust.mouse); // Reassign events this._unassignEvents(); this._assignEvents(); } } }; // Dot notation converter function convertNotation(options, notation) { var i = 0, obj, option = options, // Split notation into array levels = notation.split('.'); // Loop through while(option = option[ levels[i++] ]) { if(i < levels.length) { obj = option; } } return [obj || options, levels.pop()]; } PROTOTYPE.get = function(notation) { if(this.destroyed) { return this; } var o = convertNotation(this.options, notation.toLowerCase()), result = o[0][ o[1] ]; return result.precedance ? result.string() : result; }; function setCallback(notation, args) { var category, rule, match; for(category in this.checks) { if (!this.checks.hasOwnProperty(category)) { continue; } for(rule in this.checks[category]) { if (!this.checks[category].hasOwnProperty(rule)) { continue; } if(match = (new RegExp(rule, 'i')).exec(notation)) { args.push(match); if(category === 'builtin' || this.plugins[category]) { this.checks[category][rule].apply( this.plugins[category] || this, args ); } } } } } var rmove = /^position\.(my|at|adjust|target|container|viewport)|style|content|show\.ready/i, rrender = /^prerender|show\.ready/i; PROTOTYPE.set = function(option, value) { if(this.destroyed) { return this; } var rendered = this.rendered, reposition = FALSE, options = this.options, name; // Convert singular option/value pair into object form if('string' === typeof option) { name = option; option = {}; option[name] = value; } else { option = $.extend({}, option); } // Set all of the defined options to their new values $.each(option, function(notation, val) { if(rendered && rrender.test(notation)) { delete option[notation]; return; } // Set new obj value var obj = convertNotation(options, notation.toLowerCase()), previous; previous = obj[0][ obj[1] ]; obj[0][ obj[1] ] = val && val.nodeType ? $(val) : val; // Also check if we need to reposition reposition = rmove.test(notation) || reposition; // Set the new params for the callback option[notation] = [obj[0], obj[1], val, previous]; }); // Re-sanitize options sanitizeOptions(options); /* * Execute any valid callbacks for the set options * Also set positioning flag so we don't get loads of redundant repositioning calls. */ this.positioning = TRUE; $.each(option, $.proxy(setCallback, this)); this.positioning = FALSE; // Update position if needed if(this.rendered && this.tooltip[0].offsetWidth > 0 && reposition) { this.reposition( options.position.target === 'mouse' ? NULL : this.cache.event ); } return this; }; qTip2-3.0.2/src/core/outro.js000066400000000000000000000000351263162617100157430ustar00rootroot00000000000000})); }( window, document )); qTip2-3.0.2/src/core/position.js000066400000000000000000000225651263162617100164530ustar00rootroot00000000000000PROTOTYPE._createPosClass = function(my) { return NAMESPACE + '-pos-' + (my || this.options.position.my).abbrev(); }; PROTOTYPE.reposition = function(event, effect) { if(!this.rendered || this.positioning || this.destroyed) { return this; } // Set positioning flag this.positioning = TRUE; var cache = this.cache, tooltip = this.tooltip, posOptions = this.options.position, target = posOptions.target, my = posOptions.my, at = posOptions.at, viewport = posOptions.viewport, container = posOptions.container, adjust = posOptions.adjust, method = adjust.method.split(' '), tooltipWidth = tooltip.outerWidth(FALSE), tooltipHeight = tooltip.outerHeight(FALSE), targetWidth = 0, targetHeight = 0, type = tooltip.css('position'), position = { left: 0, top: 0 }, visible = tooltip[0].offsetWidth > 0, isScroll = event && event.type === 'scroll', win = $(window), doc = container[0].ownerDocument, mouse = this.mouse, pluginCalculations, offset, adjusted, newClass; // Check if absolute position was passed if($.isArray(target) && target.length === 2) { // Force left top and set position at = { x: LEFT, y: TOP }; position = { left: target[0], top: target[1] }; } // Check if mouse was the target else if(target === 'mouse') { // Force left top to allow flipping at = { x: LEFT, y: TOP }; // Use the mouse origin that caused the show event, if distance hiding is enabled if((!adjust.mouse || this.options.hide.distance) && cache.origin && cache.origin.pageX) { event = cache.origin; } // Use cached event for resize/scroll events else if(!event || event && (event.type === 'resize' || event.type === 'scroll')) { event = cache.event; } // Otherwise, use the cached mouse coordinates if available else if(mouse && mouse.pageX) { event = mouse; } // Calculate body and container offset and take them into account below if(type !== 'static') { position = container.offset(); } if(doc.body.offsetWidth !== (window.innerWidth || doc.documentElement.clientWidth)) { offset = $(document.body).offset(); } // Use event coordinates for position position = { left: event.pageX - position.left + (offset && offset.left || 0), top: event.pageY - position.top + (offset && offset.top || 0) }; // Scroll events are a pain, some browsers if(adjust.mouse && isScroll && mouse) { position.left -= (mouse.scrollX || 0) - win.scrollLeft(); position.top -= (mouse.scrollY || 0) - win.scrollTop(); } } // Target wasn't mouse or absolute... else { // Check if event targetting is being used if(target === 'event') { if(event && event.target && event.type !== 'scroll' && event.type !== 'resize') { cache.target = $(event.target); } else if(!event.target) { cache.target = this.elements.target; } } else if(target !== 'event'){ cache.target = $(target.jquery ? target : this.elements.target); } target = cache.target; // Parse the target into a jQuery object and make sure there's an element present target = $(target).eq(0); if(target.length === 0) { return this; } // Check if window or document is the target else if(target[0] === document || target[0] === window) { targetWidth = BROWSER.iOS ? window.innerWidth : target.width(); targetHeight = BROWSER.iOS ? window.innerHeight : target.height(); if(target[0] === window) { position = { top: (viewport || target).scrollTop(), left: (viewport || target).scrollLeft() }; } } // Check if the target is an element else if(PLUGINS.imagemap && target.is('area')) { pluginCalculations = PLUGINS.imagemap(this, target, at, PLUGINS.viewport ? method : FALSE); } // Check if the target is an SVG element else if(PLUGINS.svg && target && target[0].ownerSVGElement) { pluginCalculations = PLUGINS.svg(this, target, at, PLUGINS.viewport ? method : FALSE); } // Otherwise use regular jQuery methods else { targetWidth = target.outerWidth(FALSE); targetHeight = target.outerHeight(FALSE); position = target.offset(); } // Parse returned plugin values into proper variables if(pluginCalculations) { targetWidth = pluginCalculations.width; targetHeight = pluginCalculations.height; offset = pluginCalculations.offset; position = pluginCalculations.position; } // Adjust position to take into account offset parents position = this.reposition.offset(target, position, container); // Adjust for position.fixed tooltips (and also iOS scroll bug in v3.2-4.0 & v4.3-4.3.2) if(BROWSER.iOS > 3.1 && BROWSER.iOS < 4.1 || BROWSER.iOS >= 4.3 && BROWSER.iOS < 4.33 || !BROWSER.iOS && type === 'fixed' ){ position.left -= win.scrollLeft(); position.top -= win.scrollTop(); } // Adjust position relative to target if(!pluginCalculations || pluginCalculations && pluginCalculations.adjustable !== FALSE) { position.left += at.x === RIGHT ? targetWidth : at.x === CENTER ? targetWidth / 2 : 0; position.top += at.y === BOTTOM ? targetHeight : at.y === CENTER ? targetHeight / 2 : 0; } } // Adjust position relative to tooltip position.left += adjust.x + (my.x === RIGHT ? -tooltipWidth : my.x === CENTER ? -tooltipWidth / 2 : 0); position.top += adjust.y + (my.y === BOTTOM ? -tooltipHeight : my.y === CENTER ? -tooltipHeight / 2 : 0); // Use viewport adjustment plugin if enabled if(PLUGINS.viewport) { adjusted = position.adjusted = PLUGINS.viewport( this, position, posOptions, targetWidth, targetHeight, tooltipWidth, tooltipHeight ); // Apply offsets supplied by positioning plugin (if used) if(offset && adjusted.left) { position.left += offset.left; } if(offset && adjusted.top) { position.top += offset.top; } // Apply any new 'my' position if(adjusted.my) { this.position.my = adjusted.my; } } // Viewport adjustment is disabled, set values to zero else { position.adjusted = { left: 0, top: 0 }; } // Set tooltip position class if it's changed if(cache.posClass !== (newClass = this._createPosClass(this.position.my))) { cache.posClass = newClass; tooltip.removeClass(cache.posClass).addClass(newClass); } // tooltipmove event if(!this._trigger('move', [position, viewport.elem || viewport], event)) { return this; } delete position.adjusted; // If effect is disabled, target it mouse, no animation is defined or positioning gives NaN out, set CSS directly if(effect === FALSE || !visible || isNaN(position.left) || isNaN(position.top) || target === 'mouse' || !$.isFunction(posOptions.effect)) { tooltip.css(position); } // Use custom function if provided else if($.isFunction(posOptions.effect)) { posOptions.effect.call(tooltip, this, $.extend({}, position)); tooltip.queue(function(next) { // Reset attributes to avoid cross-browser rendering bugs $(this).css({ opacity: '', height: '' }); if(BROWSER.ie) { this.style.removeAttribute('filter'); } next(); }); } // Set positioning flag this.positioning = FALSE; return this; }; // Custom (more correct for qTip!) offset calculator PROTOTYPE.reposition.offset = function(elem, pos, container) { if(!container[0]) { return pos; } var ownerDocument = $(elem[0].ownerDocument), quirks = !!BROWSER.ie && document.compatMode !== 'CSS1Compat', parent = container[0], scrolled, position, parentOffset, overflow; function scroll(e, i) { pos.left += i * e.scrollLeft(); pos.top += i * e.scrollTop(); } // Compensate for non-static containers offset do { if((position = $.css(parent, 'position')) !== 'static') { if(position === 'fixed') { parentOffset = parent.getBoundingClientRect(); scroll(ownerDocument, -1); } else { parentOffset = $(parent).position(); parentOffset.left += parseFloat($.css(parent, 'borderLeftWidth')) || 0; parentOffset.top += parseFloat($.css(parent, 'borderTopWidth')) || 0; } pos.left -= parentOffset.left + (parseFloat($.css(parent, 'marginLeft')) || 0); pos.top -= parentOffset.top + (parseFloat($.css(parent, 'marginTop')) || 0); // If this is the first parent element with an overflow of "scroll" or "auto", store it if(!scrolled && (overflow = $.css(parent, 'overflow')) !== 'hidden' && overflow !== 'visible') { scrolled = $(parent); } } } while(parent = parent.offsetParent); // Compensate for containers scroll if it also has an offsetParent (or in IE quirks mode) if(scrolled && (scrolled[0] !== ownerDocument[0] || quirks)) { scroll(scrolled, 1); } return pos; }; // Corner class var C = (CORNER = PROTOTYPE.reposition.Corner = function(corner, forceY) { corner = ('' + corner).replace(/([A-Z])/, ' $1').replace(/middle/gi, CENTER).toLowerCase(); this.x = (corner.match(/left|right/i) || corner.match(/center/) || ['inherit'])[0].toLowerCase(); this.y = (corner.match(/top|bottom|center/i) || ['inherit'])[0].toLowerCase(); this.forceY = !!forceY; var f = corner.charAt(0); this.precedance = f === 't' || f === 'b' ? Y : X; }).prototype; C.invert = function(z, center) { this[z] = this[z] === LEFT ? RIGHT : this[z] === RIGHT ? LEFT : center || this[z]; }; C.string = function(join) { var x = this.x, y = this.y; var result = x !== y ? x === 'center' || y !== 'center' && (this.precedance === Y || this.forceY) ? [y,x] : [x,y] : [x]; return join !== false ? result.join(' ') : result; }; C.abbrev = function() { var result = this.string(false); return result[0].charAt(0) + (result[1] && result[1].charAt(0) || ''); }; C.clone = function() { return new CORNER( this.string(), this.forceY ); }; qTip2-3.0.2/src/core/style.js000066400000000000000000000015521263162617100157400ustar00rootroot00000000000000// Widget class creator function createWidgetClass(cls) { return WIDGET.concat('').join(cls ? '-'+cls+' ' : ' '); } // Widget class setter method PROTOTYPE._setWidget = function() { var on = this.options.style.widget, elements = this.elements, tooltip = elements.tooltip, disabled = tooltip.hasClass(CLASS_DISABLED); tooltip.removeClass(CLASS_DISABLED); CLASS_DISABLED = on ? 'ui-state-disabled' : 'qtip-disabled'; tooltip.toggleClass(CLASS_DISABLED, disabled); tooltip.toggleClass('ui-helper-reset '+createWidgetClass(), on).toggleClass(CLASS_DEFAULT, this.options.style.def && !on); if(elements.content) { elements.content.toggleClass( createWidgetClass('content'), on); } if(elements.titlebar) { elements.titlebar.toggleClass( createWidgetClass('header'), on); } if(elements.button) { elements.button.toggleClass(NAMESPACE+'-icon', !on); } }; qTip2-3.0.2/src/core/toggle.js000066400000000000000000000117531263162617100160650ustar00rootroot00000000000000 PROTOTYPE.toggle = function(state, event) { var cache = this.cache, options = this.options, tooltip = this.tooltip; // Try to prevent flickering when tooltip overlaps show element if(event) { if((/over|enter/).test(event.type) && cache.event && (/out|leave/).test(cache.event.type) && options.show.target.add(event.target).length === options.show.target.length && tooltip.has(event.relatedTarget).length) { return this; } // Cache event cache.event = $.event.fix(event); } // If we're currently waiting and we've just hidden... stop it this.waiting && !state && (this.hiddenDuringWait = TRUE); // Render the tooltip if showing and it isn't already if(!this.rendered) { return state ? this.render(1) : this; } else if(this.destroyed || this.disabled) { return this; } var type = state ? 'show' : 'hide', opts = this.options[type], posOptions = this.options.position, contentOptions = this.options.content, width = this.tooltip.css('width'), visible = this.tooltip.is(':visible'), animate = state || opts.target.length === 1, sameTarget = !event || opts.target.length < 2 || cache.target[0] === event.target, identicalState, allow, after; // Detect state if valid one isn't provided if((typeof state).search('boolean|number')) { state = !visible; } // Check if the tooltip is in an identical state to the new would-be state identicalState = !tooltip.is(':animated') && visible === state && sameTarget; // Fire tooltip(show/hide) event and check if destroyed allow = !identicalState ? !!this._trigger(type, [90]) : NULL; // Check to make sure the tooltip wasn't destroyed in the callback if(this.destroyed) { return this; } // If the user didn't stop the method prematurely and we're showing the tooltip, focus it if(allow !== FALSE && state) { this.focus(event); } // If the state hasn't changed or the user stopped it, return early if(!allow || identicalState) { return this; } // Set ARIA hidden attribute $.attr(tooltip[0], 'aria-hidden', !!!state); // Execute state specific properties if(state) { // Store show origin coordinates this.mouse && (cache.origin = $.event.fix(this.mouse)); // Update tooltip content & title if it's a dynamic function if($.isFunction(contentOptions.text)) { this._updateContent(contentOptions.text, FALSE); } if($.isFunction(contentOptions.title)) { this._updateTitle(contentOptions.title, FALSE); } // Cache mousemove events for positioning purposes (if not already tracking) if(!trackingBound && posOptions.target === 'mouse' && posOptions.adjust.mouse) { $(document).bind('mousemove.'+NAMESPACE, this._storeMouse); trackingBound = TRUE; } // Update the tooltip position (set width first to prevent viewport/max-width issues) if(!width) { tooltip.css('width', tooltip.outerWidth(FALSE)); } this.reposition(event, arguments[2]); if(!width) { tooltip.css('width', ''); } // Hide other tooltips if tooltip is solo if(!!opts.solo) { (typeof opts.solo === 'string' ? $(opts.solo) : $(SELECTOR, opts.solo)) .not(tooltip).not(opts.target).qtip('hide', new $.Event('tooltipsolo')); } } else { // Clear show timer if we're hiding clearTimeout(this.timers.show); // Remove cached origin on hide delete cache.origin; // Remove mouse tracking event if not needed (all tracking qTips are hidden) if(trackingBound && !$(SELECTOR+'[tracking="true"]:visible', opts.solo).not(tooltip).length) { $(document).unbind('mousemove.'+NAMESPACE); trackingBound = FALSE; } // Blur the tooltip this.blur(event); } // Define post-animation, state specific properties after = $.proxy(function() { if(state) { // Prevent antialias from disappearing in IE by removing filter if(BROWSER.ie) { tooltip[0].style.removeAttribute('filter'); } // Remove overflow setting to prevent tip bugs tooltip.css('overflow', ''); // Autofocus elements if enabled if('string' === typeof opts.autofocus) { $(this.options.show.autofocus, tooltip).focus(); } // If set, hide tooltip when inactive for delay period this.options.show.target.trigger('qtip-'+this.id+'-inactive'); } else { // Reset CSS states tooltip.css({ display: '', visibility: '', opacity: '', left: '', top: '' }); } // tooltipvisible/tooltiphidden events this._trigger(state ? 'visible' : 'hidden'); }, this); // If no effect type is supplied, use a simple toggle if(opts.effect === FALSE || animate === FALSE) { tooltip[ type ](); after(); } // Use custom function if provided else if($.isFunction(opts.effect)) { tooltip.stop(1, 1); opts.effect.call(tooltip, this); tooltip.queue('fx', function(n) { after(); n(); }); } // Use basic fade function by default else { tooltip.fadeTo(90, state ? 1 : 0, after); } // If inactive hide method is set, active it if(state) { opts.target.trigger('qtip-'+this.id+'-inactive'); } return this; }; PROTOTYPE.show = function(event) { return this.toggle(TRUE, event); }; PROTOTYPE.hide = function(event) { return this.toggle(FALSE, event); }; qTip2-3.0.2/src/css3.css000066400000000000000000000172461263162617100147060ustar00rootroot00000000000000/* Add shadows to your tooltips in: FF3+, Chrome 2+, Opera 10.6+, IE9+, Safari 2+ */ .qtip-shadow{ -webkit-box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15); -moz-box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15); box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15); } /* Add rounded corners to your tooltips in: FF3+, Chrome 2+, Opera 10.6+, IE9+, Safari 2+ */ .qtip-rounded, .qtip-tipsy, .qtip-bootstrap{ -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; } .qtip-rounded .qtip-titlebar{ -moz-border-radius: 4px 4px 0 0; -webkit-border-radius: 4px 4px 0 0; border-radius: 4px 4px 0 0; } /* Youtube tooltip style */ .qtip-youtube{ -moz-border-radius: 2px; -webkit-border-radius: 2px; border-radius: 2px; -webkit-box-shadow: 0 0 3px #333; -moz-box-shadow: 0 0 3px #333; box-shadow: 0 0 3px #333; color: white; border: 0 solid transparent; background: #4A4A4A; background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0,#4A4A4A),color-stop(100%,black)); background-image: -webkit-linear-gradient(top,#4A4A4A 0,black 100%); background-image: -moz-linear-gradient(top,#4A4A4A 0,black 100%); background-image: -ms-linear-gradient(top,#4A4A4A 0,black 100%); background-image: -o-linear-gradient(top,#4A4A4A 0,black 100%); } .qtip-youtube .qtip-titlebar{ background-color: #4A4A4A; background-color: rgba(0,0,0,0); } .qtip-youtube .qtip-content{ padding: .75em; font: 12px arial,sans-serif; filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#4a4a4a,EndColorStr=#000000); -ms-filter: "progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#4a4a4a,EndColorStr=#000000);"; } .qtip-youtube .qtip-icon{ border-color: #222; } .qtip-youtube .qtip-titlebar .ui-state-hover{ border-color: #303030; } /* jQuery TOOLS Tooltip style */ .qtip-jtools{ background: #232323; background: rgba(0, 0, 0, 0.7); background-image: -webkit-gradient(linear, left top, left bottom, from(#717171), to(#232323)); background-image: -moz-linear-gradient(top, #717171, #232323); background-image: -webkit-linear-gradient(top, #717171, #232323); background-image: -ms-linear-gradient(top, #717171, #232323); background-image: -o-linear-gradient(top, #717171, #232323); border: 2px solid #ddd; border: 2px solid rgba(241,241,241,1); -moz-border-radius: 2px; -webkit-border-radius: 2px; border-radius: 2px; -webkit-box-shadow: 0 0 12px #333; -moz-box-shadow: 0 0 12px #333; box-shadow: 0 0 12px #333; } /* IE Specific */ .qtip-jtools .qtip-titlebar{ background-color: transparent; filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A); -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A)"; } .qtip-jtools .qtip-content{ filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323); -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323)"; } .qtip-jtools .qtip-titlebar, .qtip-jtools .qtip-content{ background: transparent; color: white; border: 0 dashed transparent; } .qtip-jtools .qtip-icon{ border-color: #555; } .qtip-jtools .qtip-titlebar .ui-state-hover{ border-color: #333; } /* Cluetip style */ .qtip-cluetip{ -webkit-box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4); -moz-box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4); box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4); background-color: #D9D9C2; color: #111; border: 0 dashed transparent; } .qtip-cluetip .qtip-titlebar{ background-color: #87876A; color: white; border: 0 dashed transparent; } .qtip-cluetip .qtip-icon{ border-color: #808064; } .qtip-cluetip .qtip-titlebar .ui-state-hover{ border-color: #696952; color: #696952; } /* Tipsy style */ .qtip-tipsy{ background: black; background: rgba(0, 0, 0, .87); color: white; border: 0 solid transparent; font-size: 11px; font-family: 'Lucida Grande', sans-serif; font-weight: bold; line-height: 16px; text-shadow: 0 1px black; } .qtip-tipsy .qtip-titlebar{ padding: 6px 35px 0 10px; background-color: transparent; } .qtip-tipsy .qtip-content{ padding: 6px 10px; } .qtip-tipsy .qtip-icon{ border-color: #222; text-shadow: none; } .qtip-tipsy .qtip-titlebar .ui-state-hover{ border-color: #303030; } /* Tipped style */ .qtip-tipped{ border: 3px solid #959FA9; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; background-color: #F9F9F9; color: #454545; font-weight: normal; font-family: serif; } .qtip-tipped .qtip-titlebar{ border-bottom-width: 0; color: white; background: #3A79B8; background-image: -webkit-gradient(linear, left top, left bottom, from(#3A79B8), to(#2E629D)); background-image: -webkit-linear-gradient(top, #3A79B8, #2E629D); background-image: -moz-linear-gradient(top, #3A79B8, #2E629D); background-image: -ms-linear-gradient(top, #3A79B8, #2E629D); background-image: -o-linear-gradient(top, #3A79B8, #2E629D); filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D); -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D)"; } .qtip-tipped .qtip-icon{ border: 2px solid #285589; background: #285589; } .qtip-tipped .qtip-icon .ui-icon{ background-color: #FBFBFB; color: #555; } /** * Twitter Bootstrap style. * * Tested with IE 8, IE 9, Chrome 18, Firefox 9, Opera 11. * Does not work with IE 7. */ .qtip-bootstrap{ /** Taken from Bootstrap body */ font-size: 14px; line-height: 20px; color: #333333; /** Taken from Bootstrap .popover */ padding: 1px; background-color: #ffffff; border: 1px solid #ccc; border: 1px solid rgba(0, 0, 0, 0.2); -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); -webkit-background-clip: padding-box; -moz-background-clip: padding; background-clip: padding-box; } .qtip-bootstrap .qtip-titlebar{ /** Taken from Bootstrap .popover-title */ padding: 8px 14px; margin: 0; font-size: 14px; font-weight: normal; line-height: 18px; background-color: #f7f7f7; border-bottom: 1px solid #ebebeb; -webkit-border-radius: 5px 5px 0 0; -moz-border-radius: 5px 5px 0 0; border-radius: 5px 5px 0 0; } .qtip-bootstrap .qtip-titlebar .qtip-close{ /** * Overrides qTip2: * .qtip-titlebar .qtip-close{ * [...] * right: 4px; * top: 50%; * [...] * border-style: solid; * } */ right: 11px; top: 45%; border-style: none; } .qtip-bootstrap .qtip-content{ /** Taken from Bootstrap .popover-content */ padding: 9px 14px; } .qtip-bootstrap .qtip-icon{ /** * Overrides qTip2: * .qtip-default .qtip-icon { * border-color: #CCC; * background: #F1F1F1; * color: #777; * } */ background: transparent; } .qtip-bootstrap .qtip-icon .ui-icon{ /** * Overrides qTip2: * .qtip-icon .ui-icon{ * width: 18px; * height: 14px; * } */ width: auto; height: auto; /* Taken from Bootstrap .close */ float: right; font-size: 20px; font-weight: bold; line-height: 18px; color: #000000; text-shadow: 0 1px 0 #ffffff; opacity: 0.2; filter: alpha(opacity=20); } .qtip-bootstrap .qtip-icon .ui-icon:hover{ /* Taken from Bootstrap .close:hover */ color: #000000; text-decoration: none; cursor: pointer; opacity: 0.4; filter: alpha(opacity=40); } /* IE9 fix - removes all filters */ .qtip:not(.ie9haxors) div.qtip-content, .qtip:not(.ie9haxors) div.qtip-titlebar{ filter: none; -ms-filter: none; } qTip2-3.0.2/src/ie6/000077500000000000000000000000001263162617100137725ustar00rootroot00000000000000qTip2-3.0.2/src/ie6/ie6.css000066400000000000000000000001201263162617100151600ustar00rootroot00000000000000/* IE6 Modal plugin fix */ .qtipmodal-ie6fix{ position: absolute !important; } qTip2-3.0.2/src/ie6/ie6.js000066400000000000000000000076411263162617100150230ustar00rootroot00000000000000var IE6, /* * BGIFrame adaption (http://plugins.jquery.com/project/bgiframe) * Special thanks to Brandon Aaron */ BGIFRAME = ''; function Ie6(api) { this._ns = 'ie6'; this.qtip = api; this.init(api); } $.extend(Ie6.prototype, { _scroll : function() { var overlay = this.qtip.elements.overlay; overlay && (overlay[0].style.top = $(window).scrollTop() + 'px'); }, init: function(qtip) { var tooltip = qtip.tooltip; // Create the BGIFrame element if needed if($('select, object').length < 1) { this.bgiframe = qtip.elements.bgiframe = $(BGIFRAME).appendTo(tooltip); // Update BGIFrame on tooltip move qtip._bind(tooltip, 'tooltipmove', this.adjustBGIFrame, this._ns, this); } // redraw() container for width/height calculations this.redrawContainer = $('
', { id: NAMESPACE+'-rcontainer' }) .appendTo(document.body); // Fixup modal plugin if present too if( qtip.elements.overlay && qtip.elements.overlay.addClass('qtipmodal-ie6fix') ) { qtip._bind(window, ['scroll', 'resize'], this._scroll, this._ns, this); qtip._bind(tooltip, ['tooltipshow'], this._scroll, this._ns, this); } // Set dimensions this.redraw(); }, adjustBGIFrame: function() { var tooltip = this.qtip.tooltip, dimensions = { height: tooltip.outerHeight(FALSE), width: tooltip.outerWidth(FALSE) }, plugin = this.qtip.plugins.tip, tip = this.qtip.elements.tip, tipAdjust, offset; // Adjust border offset offset = parseInt(tooltip.css('borderLeftWidth'), 10) || 0; offset = { left: -offset, top: -offset }; // Adjust for tips plugin if(plugin && tip) { tipAdjust = plugin.corner.precedance === 'x' ? [WIDTH, LEFT] : [HEIGHT, TOP]; offset[ tipAdjust[1] ] -= tip[ tipAdjust[0] ](); } // Update bgiframe this.bgiframe.css(offset).css(dimensions); }, // Max/min width simulator function redraw: function() { if(this.qtip.rendered < 1 || this.drawing) { return this; } var tooltip = this.qtip.tooltip, style = this.qtip.options.style, container = this.qtip.options.position.container, perc, width, max, min; // Set drawing flag this.qtip.drawing = 1; // If tooltip has a set height/width, just set it... like a boss! if(style.height) { tooltip.css(HEIGHT, style.height); } if(style.width) { tooltip.css(WIDTH, style.width); } // Simulate max/min width if not set width present... else { // Reset width and add fluid class tooltip.css(WIDTH, '').appendTo(this.redrawContainer); // Grab our tooltip width (add 1 if odd so we don't get wrapping problems.. huzzah!) width = tooltip.width(); if(width % 2 < 1) { width += 1; } // Grab our max/min properties max = tooltip.css('maxWidth') || ''; min = tooltip.css('minWidth') || ''; // Parse into proper pixel values perc = (max + min).indexOf('%') > -1 ? container.width() / 100 : 0; max = (max.indexOf('%') > -1 ? perc : 1 * parseInt(max, 10)) || width; min = (min.indexOf('%') > -1 ? perc : 1 * parseInt(min, 10)) || 0; // Determine new dimension size based on max/min/current values width = max + min ? Math.min(Math.max(width, min), max) : width; // Set the newly calculated width and remvoe fluid class tooltip.css(WIDTH, Math.round(width)).appendTo(container); } // Set drawing flag this.drawing = 0; return this; }, destroy: function() { // Remove iframe this.bgiframe && this.bgiframe.remove(); // Remove bound events this.qtip._unbind([window, this.qtip.tooltip], this._ns); } }); IE6 = PLUGINS.ie6 = function(api) { // Proceed only if the browser is IE6 return BROWSER.ie === 6 ? new Ie6(api) : FALSE; }; IE6.initialize = 'render'; CHECKS.ie6 = { '^content|style$': function() { this.redraw(); } }; qTip2-3.0.2/src/modal/000077500000000000000000000000001263162617100144035ustar00rootroot00000000000000qTip2-3.0.2/src/modal/modal.css000066400000000000000000000007311263162617100162120ustar00rootroot00000000000000/* Modal plugin */ #qtip-overlay{ position: fixed; left: 0; top: 0; width: 100%; height: 100%; } /* Applied to modals with show.modal.blur set to true */ #qtip-overlay.blurs{ cursor: pointer; } /* Change opacity of overlay here */ #qtip-overlay div{ position: absolute; left: 0; top: 0; width: 100%; height: 100%; background-color: black; opacity: 0.7; filter:alpha(opacity=70); -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)"; } qTip2-3.0.2/src/modal/modal.js000066400000000000000000000217601263162617100160430ustar00rootroot00000000000000var MODAL, OVERLAY, MODALCLASS = 'qtip-modal', MODALSELECTOR = '.'+MODALCLASS; OVERLAY = function() { var self = this, focusableElems = {}, current, prevState, elem; // Modified code from jQuery UI 1.10.0 source // http://code.jquery.com/ui/1.10.0/jquery-ui.js function focusable(element) { // Use the defined focusable checker when possible if($.expr[':'].focusable) { return $.expr[':'].focusable; } var isTabIndexNotNaN = !isNaN($.attr(element, 'tabindex')), nodeName = element.nodeName && element.nodeName.toLowerCase(), map, mapName, img; if('area' === nodeName) { map = element.parentNode; mapName = map.name; if(!element.href || !mapName || map.nodeName.toLowerCase() !== 'map') { return false; } img = $('img[usemap=#' + mapName + ']')[0]; return !!img && img.is(':visible'); } return /input|select|textarea|button|object/.test( nodeName ) ? !element.disabled : 'a' === nodeName ? element.href || isTabIndexNotNaN : isTabIndexNotNaN ; } // Focus inputs using cached focusable elements (see update()) function focusInputs(blurElems) { // Blurring body element in IE causes window.open windows to unfocus! if(focusableElems.length < 1 && blurElems.length) { blurElems.not('body').blur(); } // Focus the inputs else { focusableElems.first().focus(); } } // Steal focus from elements outside tooltip function stealFocus(event) { if(!elem.is(':visible')) { return; } var target = $(event.target), tooltip = current.tooltip, container = target.closest(SELECTOR), targetOnTop; // Determine if input container target is above this targetOnTop = container.length < 1 ? FALSE : parseInt(container[0].style.zIndex, 10) > parseInt(tooltip[0].style.zIndex, 10); // If we're showing a modal, but focus has landed on an input below // this modal, divert focus to the first visible input in this modal // or if we can't find one... the tooltip itself if(!targetOnTop && target.closest(SELECTOR)[0] !== tooltip[0]) { focusInputs(target); } } $.extend(self, { init: function() { // Create document overlay elem = self.elem = $('
', { id: 'qtip-overlay', html: '
', mousedown: function() { return FALSE; } }) .hide(); // Make sure we can't focus anything outside the tooltip $(document.body).bind('focusin'+MODALSELECTOR, stealFocus); // Apply keyboard "Escape key" close handler $(document).bind('keydown'+MODALSELECTOR, function(event) { if(current && current.options.show.modal.escape && event.keyCode === 27) { current.hide(event); } }); // Apply click handler for blur option elem.bind('click'+MODALSELECTOR, function(event) { if(current && current.options.show.modal.blur) { current.hide(event); } }); return self; }, update: function(api) { // Update current API reference current = api; // Update focusable elements if enabled if(api.options.show.modal.stealfocus !== FALSE) { focusableElems = api.tooltip.find('*').filter(function() { return focusable(this); }); } else { focusableElems = []; } }, toggle: function(api, state, duration) { var tooltip = api.tooltip, options = api.options.show.modal, effect = options.effect, type = state ? 'show': 'hide', visible = elem.is(':visible'), visibleModals = $(MODALSELECTOR).filter(':visible:not(:animated)').not(tooltip); // Set active tooltip API reference self.update(api); // If the modal can steal the focus... // Blur the current item and focus anything in the modal we an if(state && options.stealfocus !== FALSE) { focusInputs( $(':focus') ); } // Toggle backdrop cursor style on show elem.toggleClass('blurs', options.blur); // Append to body on show if(state) { elem.appendTo(document.body); } // Prevent modal from conflicting with show.solo, and don't hide backdrop is other modals are visible if(elem.is(':animated') && visible === state && prevState !== FALSE || !state && visibleModals.length) { return self; } // Stop all animations elem.stop(TRUE, FALSE); // Use custom function if provided if($.isFunction(effect)) { effect.call(elem, state); } // If no effect type is supplied, use a simple toggle else if(effect === FALSE) { elem[ type ](); } // Use basic fade function else { elem.fadeTo( parseInt(duration, 10) || 90, state ? 1 : 0, function() { if(!state) { elem.hide(); } }); } // Reset position and detach from body on hide if(!state) { elem.queue(function(next) { elem.css({ left: '', top: '' }); if(!$(MODALSELECTOR).length) { elem.detach(); } next(); }); } // Cache the state prevState = state; // If the tooltip is destroyed, set reference to null if(current.destroyed) { current = NULL; } return self; } }); self.init(); }; OVERLAY = new OVERLAY(); function Modal(api, options) { this.options = options; this._ns = '-modal'; this.qtip = api; this.init(api); } $.extend(Modal.prototype, { init: function(qtip) { var tooltip = qtip.tooltip; // If modal is disabled... return if(!this.options.on) { return this; } // Set overlay reference qtip.elements.overlay = OVERLAY.elem; // Add unique attribute so we can grab modal tooltips easily via a SELECTOR, and set z-index tooltip.addClass(MODALCLASS).css('z-index', QTIP.modal_zindex + $(MODALSELECTOR).length); // Apply our show/hide/focus modal events qtip._bind(tooltip, ['tooltipshow', 'tooltiphide'], function(event, api, duration) { var oEvent = event.originalEvent; // Make sure mouseout doesn't trigger a hide when showing the modal and mousing onto backdrop if(event.target === tooltip[0]) { if(oEvent && event.type === 'tooltiphide' && /mouse(leave|enter)/.test(oEvent.type) && $(oEvent.relatedTarget).closest(OVERLAY.elem[0]).length) { /* eslint-disable no-empty */ try { event.preventDefault(); } catch(e) {} /* eslint-enable no-empty */ } else if(!oEvent || oEvent && oEvent.type !== 'tooltipsolo') { this.toggle(event, event.type === 'tooltipshow', duration); } } }, this._ns, this); // Adjust modal z-index on tooltip focus qtip._bind(tooltip, 'tooltipfocus', function(event, api) { // If focus was cancelled before it reached us, don't do anything if(event.isDefaultPrevented() || event.target !== tooltip[0]) { return; } var qtips = $(MODALSELECTOR), // Keep the modal's lower than other, regular qtips newIndex = QTIP.modal_zindex + qtips.length, curIndex = parseInt(tooltip[0].style.zIndex, 10); // Set overlay z-index OVERLAY.elem[0].style.zIndex = newIndex - 1; // Reduce modal z-index's and keep them properly ordered qtips.each(function() { if(this.style.zIndex > curIndex) { this.style.zIndex -= 1; } }); // Fire blur event for focused tooltip qtips.filter('.' + CLASS_FOCUS).qtip('blur', event.originalEvent); // Set the new z-index tooltip.addClass(CLASS_FOCUS)[0].style.zIndex = newIndex; // Set current OVERLAY.update(api); // Prevent default handling /* eslint-disable no-empty */ try { event.preventDefault(); } catch(e) {} /* eslint-enable no-empty */ }, this._ns, this); // Focus any other visible modals when this one hides qtip._bind(tooltip, 'tooltiphide', function(event) { if(event.target === tooltip[0]) { $(MODALSELECTOR).filter(':visible').not(tooltip).last().qtip('focus', event); } }, this._ns, this); }, toggle: function(event, state, duration) { // Make sure default event hasn't been prevented if(event && event.isDefaultPrevented()) { return this; } // Toggle it OVERLAY.toggle(this.qtip, !!state, duration); }, destroy: function() { // Remove modal class this.qtip.tooltip.removeClass(MODALCLASS); // Remove bound events this.qtip._unbind(this.qtip.tooltip, this._ns); // Delete element reference OVERLAY.toggle(this.qtip, FALSE); delete this.qtip.elements.overlay; } }); MODAL = PLUGINS.modal = function(api) { return new Modal(api, api.options.show.modal); }; // Setup sanitiztion rules MODAL.sanitize = function(opts) { if(opts.show) { if(typeof opts.show.modal !== 'object') { opts.show.modal = { on: !!opts.show.modal }; } else if(typeof opts.show.modal.on === 'undefined') { opts.show.modal.on = TRUE; } } }; // Base z-index for all modal tooltips (use qTip core z-index as a base) /* eslint-disable camelcase */ QTIP.modal_zindex = QTIP.zindex - 200; /* eslint-enable camelcase */ // Plugin needs to be initialized on render MODAL.initialize = 'render'; // Setup option set checks CHECKS.modal = { '^show.modal.(on|blur)$': function() { // Initialise this.destroy(); this.init(); // Show the modal if not visible already and tooltip is visible this.qtip.elems.overlay.toggle( this.qtip.tooltip[0].offsetWidth > 0 ); } }; // Extend original api defaults $.extend(TRUE, QTIP.defaults, { show: { modal: { on: FALSE, effect: TRUE, blur: TRUE, stealfocus: TRUE, escape: TRUE } } }); qTip2-3.0.2/src/position/000077500000000000000000000000001263162617100151535ustar00rootroot00000000000000qTip2-3.0.2/src/position/imagemap.js000066400000000000000000000025431263162617100172750ustar00rootroot00000000000000PLUGINS.imagemap = function(api, area, corner) { if(!area.jquery) { area = $(area); } var shape = (area.attr('shape') || 'rect').toLowerCase().replace('poly', 'polygon'), image = $('img[usemap="#'+area.parent('map').attr('name')+'"]'), coordsString = $.trim(area.attr('coords')), coordsArray = coordsString.replace(/,$/, '').split(','), imageOffset, coords, i, result, len; // If we can't find the image using the map... if(!image.length) { return FALSE; } // Pass coordinates string if polygon if(shape === 'polygon') { result = PLUGINS.polys.polygon(coordsArray, corner); } // Otherwise parse the coordinates and pass them as arguments else if(PLUGINS.polys[shape]) { for(i = -1, len = coordsArray.length, coords = []; ++i < len;) { coords.push( parseInt(coordsArray[i], 10) ); } result = PLUGINS.polys[shape].apply( this, coords.concat(corner) ); } // If no shapre calculation method was found, return false else { return FALSE; } // Make sure we account for padding and borders on the image imageOffset = image.offset(); imageOffset.left += Math.ceil((image.outerWidth(FALSE) - image.width()) / 2); imageOffset.top += Math.ceil((image.outerHeight(FALSE) - image.height()) / 2); // Add image position to offset coordinates result.position.left += imageOffset.left; result.position.top += imageOffset.top; return result; }; qTip2-3.0.2/src/position/polys.js000066400000000000000000000065551263162617100166720ustar00rootroot00000000000000PLUGINS.polys = { // POLY area coordinate calculator // Special thanks to Ed Cradock for helping out with this. // Uses a binary search algorithm to find suitable coordinates. polygon: function(baseCoords, corner) { var result = { width: 0, height: 0, position: { top: 1e10, right: 0, bottom: 0, left: 1e10 }, adjustable: FALSE }, i = 0, next, coords = [], compareX = 1, compareY = 1, realX = 0, realY = 0, newWidth, newHeight; // First pass, sanitize coords and determine outer edges i = baseCoords.length; while(i--) { next = [ parseInt(baseCoords[--i], 10), parseInt(baseCoords[i+1], 10) ]; if(next[0] > result.position.right){ result.position.right = next[0]; } if(next[0] < result.position.left){ result.position.left = next[0]; } if(next[1] > result.position.bottom){ result.position.bottom = next[1]; } if(next[1] < result.position.top){ result.position.top = next[1]; } coords.push(next); } // Calculate height and width from outer edges newWidth = result.width = Math.abs(result.position.right - result.position.left); newHeight = result.height = Math.abs(result.position.bottom - result.position.top); // If it's the center corner... if(corner.abbrev() === 'c') { result.position = { left: result.position.left + result.width / 2, top: result.position.top + result.height / 2 }; } else { // Second pass, use a binary search algorithm to locate most suitable coordinate while(newWidth > 0 && newHeight > 0 && compareX > 0 && compareY > 0) { newWidth = Math.floor(newWidth / 2); newHeight = Math.floor(newHeight / 2); if(corner.x === LEFT){ compareX = newWidth; } else if(corner.x === RIGHT){ compareX = result.width - newWidth; } else{ compareX += Math.floor(newWidth / 2); } if(corner.y === TOP){ compareY = newHeight; } else if(corner.y === BOTTOM){ compareY = result.height - newHeight; } else{ compareY += Math.floor(newHeight / 2); } i = coords.length; while(i--) { if(coords.length < 2){ break; } realX = coords[i][0] - result.position.left; realY = coords[i][1] - result.position.top; if( corner.x === LEFT && realX >= compareX || corner.x === RIGHT && realX <= compareX || corner.x === CENTER && (realX < compareX || realX > result.width - compareX) || corner.y === TOP && realY >= compareY || corner.y === BOTTOM && realY <= compareY || corner.y === CENTER && (realY < compareY || realY > result.height - compareY)) { coords.splice(i, 1); } } } result.position = { left: coords[0][0], top: coords[0][1] }; } return result; }, rect: function(ax, ay, bx, by) { return { width: Math.abs(bx - ax), height: Math.abs(by - ay), position: { left: Math.min(ax, bx), top: Math.min(ay, by) } }; }, _angles: { tc: 3 / 2, tr: 7 / 4, tl: 5 / 4, bc: 1 / 2, br: 1 / 4, bl: 3 / 4, rc: 2, lc: 1, c: 0 }, ellipse: function(cx, cy, rx, ry, corner) { var c = PLUGINS.polys._angles[ corner.abbrev() ], rxc = c === 0 ? 0 : rx * Math.cos( c * Math.PI ), rys = ry * Math.sin( c * Math.PI ); return { width: rx * 2 - Math.abs(rxc), height: ry * 2 - Math.abs(rys), position: { left: cx + rxc, top: cy + rys }, adjustable: FALSE }; }, circle: function(cx, cy, r, corner) { return PLUGINS.polys.ellipse(cx, cy, r, r, corner); } }; qTip2-3.0.2/src/position/svg.js000066400000000000000000000046741263162617100163230ustar00rootroot00000000000000PLUGINS.svg = function(api, svg, corner) { var elem = svg[0], root = $(elem.ownerSVGElement), ownerDocument = elem.ownerDocument, strokeWidth2 = (parseInt(svg.css('stroke-width'), 10) || 0) / 2, frameOffset, mtx, transformed, len, next, i, points, result, position; // Ascend the parentNode chain until we find an element with getBBox() while(!elem.getBBox) { elem = elem.parentNode; } if(!elem.getBBox || !elem.parentNode) { return FALSE; } // Determine which shape calculation to use switch(elem.nodeName) { case 'ellipse': case 'circle': result = PLUGINS.polys.ellipse( elem.cx.baseVal.value, elem.cy.baseVal.value, (elem.rx || elem.r).baseVal.value + strokeWidth2, (elem.ry || elem.r).baseVal.value + strokeWidth2, corner ); break; case 'line': case 'polygon': case 'polyline': // Determine points object (line has none, so mimic using array) points = elem.points || [ { x: elem.x1.baseVal.value, y: elem.y1.baseVal.value }, { x: elem.x2.baseVal.value, y: elem.y2.baseVal.value } ]; for(result = [], i = -1, len = points.numberOfItems || points.length; ++i < len;) { next = points.getItem ? points.getItem(i) : points[i]; result.push.apply(result, [next.x, next.y]); } result = PLUGINS.polys.polygon(result, corner); break; // Unknown shape or rectangle? Use bounding box default: result = elem.getBBox(); result = { width: result.width, height: result.height, position: { left: result.x, top: result.y } }; break; } // Shortcut assignments position = result.position; root = root[0]; // Convert position into a pixel value if(root.createSVGPoint) { mtx = elem.getScreenCTM(); points = root.createSVGPoint(); points.x = position.left; points.y = position.top; transformed = points.matrixTransform( mtx ); position.left = transformed.x; position.top = transformed.y; } // Check the element is not in a child document, and if so, adjust for frame elements offset if(ownerDocument !== document && api.position.target !== 'mouse') { frameOffset = $((ownerDocument.defaultView || ownerDocument.parentWindow).frameElement).offset(); if(frameOffset) { position.left += frameOffset.left; position.top += frameOffset.top; } } // Adjust by scroll offset of owner document ownerDocument = $(ownerDocument); position.left += ownerDocument.scrollLeft(); position.top += ownerDocument.scrollTop(); return result; }; qTip2-3.0.2/src/position/viewport.js000066400000000000000000000101251263162617100173670ustar00rootroot00000000000000PLUGINS.viewport = function(api, position, posOptions, targetWidth, targetHeight, elemWidth, elemHeight) { var target = posOptions.target, tooltip = api.elements.tooltip, my = posOptions.my, at = posOptions.at, adjust = posOptions.adjust, method = adjust.method.split(' '), methodX = method[0], methodY = method[1] || method[0], viewport = posOptions.viewport, container = posOptions.container, adjusted = { left: 0, top: 0 }, fixed, newMy, containerOffset, containerStatic, viewportWidth, viewportHeight, viewportScroll, viewportOffset; // If viewport is not a jQuery element, or it's the window/document, or no adjustment method is used... return if(!viewport.jquery || target[0] === window || target[0] === document.body || adjust.method === 'none') { return adjusted; } // Cach container details containerOffset = container.offset() || adjusted; containerStatic = container.css('position') === 'static'; // Cache our viewport details fixed = tooltip.css('position') === 'fixed'; viewportWidth = viewport[0] === window ? viewport.width() : viewport.outerWidth(FALSE); viewportHeight = viewport[0] === window ? viewport.height() : viewport.outerHeight(FALSE); viewportScroll = { left: fixed ? 0 : viewport.scrollLeft(), top: fixed ? 0 : viewport.scrollTop() }; viewportOffset = viewport.offset() || adjusted; // Generic calculation method function calculate(side, otherSide, type, adjustment, side1, side2, lengthName, targetLength, elemLength) { var initialPos = position[side1], mySide = my[side], atSide = at[side], isShift = type === SHIFT, myLength = mySide === side1 ? elemLength : mySide === side2 ? -elemLength : -elemLength / 2, atLength = atSide === side1 ? targetLength : atSide === side2 ? -targetLength : -targetLength / 2, sideOffset = viewportScroll[side1] + viewportOffset[side1] - (containerStatic ? 0 : containerOffset[side1]), overflow1 = sideOffset - initialPos, overflow2 = initialPos + elemLength - (lengthName === WIDTH ? viewportWidth : viewportHeight) - sideOffset, offset = myLength - (my.precedance === side || mySide === my[otherSide] ? atLength : 0) - (atSide === CENTER ? targetLength / 2 : 0); // shift if(isShift) { offset = (mySide === side1 ? 1 : -1) * myLength; // Adjust position but keep it within viewport dimensions position[side1] += overflow1 > 0 ? overflow1 : overflow2 > 0 ? -overflow2 : 0; position[side1] = Math.max( -containerOffset[side1] + viewportOffset[side1], initialPos - offset, Math.min( Math.max( -containerOffset[side1] + viewportOffset[side1] + (lengthName === WIDTH ? viewportWidth : viewportHeight), initialPos + offset ), position[side1], // Make sure we don't adjust complete off the element when using 'center' mySide === 'center' ? initialPos - myLength : 1E9 ) ); } // flip/flipinvert else { // Update adjustment amount depending on if using flipinvert or flip adjustment *= type === FLIPINVERT ? 2 : 0; // Check for overflow on the left/top if(overflow1 > 0 && (mySide !== side1 || overflow2 > 0)) { position[side1] -= offset + adjustment; newMy.invert(side, side1); } // Check for overflow on the bottom/right else if(overflow2 > 0 && (mySide !== side2 || overflow1 > 0) ) { position[side1] -= (mySide === CENTER ? -offset : offset) + adjustment; newMy.invert(side, side2); } // Make sure we haven't made things worse with the adjustment and reset if so if(position[side1] < viewportScroll[side1] && -position[side1] > overflow2) { position[side1] = initialPos; newMy = my.clone(); } } return position[side1] - initialPos; } // Set newMy if using flip or flipinvert methods if(methodX !== 'shift' || methodY !== 'shift') { newMy = my.clone(); } // Adjust position based onviewport and adjustment options adjusted = { left: methodX !== 'none' ? calculate( X, Y, methodX, adjust.x, LEFT, RIGHT, WIDTH, targetWidth, elemWidth ) : 0, top: methodY !== 'none' ? calculate( Y, X, methodY, adjust.y, TOP, BOTTOM, HEIGHT, targetHeight, elemHeight ) : 0, my: newMy }; return adjusted; }; qTip2-3.0.2/src/tips/000077500000000000000000000000001263162617100142665ustar00rootroot00000000000000qTip2-3.0.2/src/tips/tips.css000066400000000000000000000010721263162617100157570ustar00rootroot00000000000000/* Tips plugin */ .qtip .qtip-tip{ margin: 0 auto; overflow: hidden; z-index: 10; } /* Opera bug #357 - Incorrect tip position https://github.com/Craga89/qTip2/issues/367 */ x:-o-prefocus, .qtip .qtip-tip{ visibility: hidden; } .qtip .qtip-tip, .qtip .qtip-tip .qtip-vml, .qtip .qtip-tip canvas{ position: absolute; color: #123456; background: transparent; border: 0 dashed transparent; } .qtip .qtip-tip canvas{ top: 0; left: 0; } .qtip .qtip-tip .qtip-vml{ behavior: url(#default#VML); display: inline-block; visibility: visible; } qTip2-3.0.2/src/tips/tips.js000066400000000000000000000452121263162617100156070ustar00rootroot00000000000000var TIP, createVML, SCALE, PIXEL_RATIO, BACKING_STORE_RATIO, // Common CSS strings MARGIN = 'margin', BORDER = 'border', COLOR = 'color', BG_COLOR = 'background-color', TRANSPARENT = 'transparent', IMPORTANT = ' !important', // Check if the browser supports elements HASCANVAS = !!document.createElement('canvas').getContext, // Invalid colour values used in parseColours() INVALID = /rgba?\(0, 0, 0(, 0)?\)|transparent|#123456/i; // Camel-case method, taken from jQuery source // http://code.jquery.com/jquery-1.8.0.js function camel(s) { return s.charAt(0).toUpperCase() + s.slice(1); } /* * Modified from Modernizr's testPropsAll() * http://modernizr.com/downloads/modernizr-latest.js */ var cssProps = {}, cssPrefixes = ['Webkit', 'O', 'Moz', 'ms']; function vendorCss(elem, prop) { var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1), props = (prop + ' ' + cssPrefixes.join(ucProp + ' ') + ucProp).split(' '), cur, val, i = 0; // If the property has already been mapped... if(cssProps[prop]) { return elem.css(cssProps[prop]); } while(cur = props[i++]) { if((val = elem.css(cur)) !== undefined) { cssProps[prop] = cur; return val; } } } // Parse a given elements CSS property into an int function intCss(elem, prop) { return Math.ceil(parseFloat(vendorCss(elem, prop))); } // VML creation (for IE only) if(!HASCANVAS) { createVML = function(tag, props, style) { return ''; }; } // Canvas only definitions else { PIXEL_RATIO = window.devicePixelRatio || 1; BACKING_STORE_RATIO = (function() { var context = document.createElement('canvas').getContext('2d'); return context.backingStorePixelRatio || context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || 1; })(); SCALE = PIXEL_RATIO / BACKING_STORE_RATIO; } function Tip(qtip, options) { this._ns = 'tip'; this.options = options; this.offset = options.offset; this.size = [ options.width, options.height ]; // Initialize this.qtip = qtip; this.init(qtip); } $.extend(Tip.prototype, { init: function(qtip) { var context, tip; // Create tip element and prepend to the tooltip tip = this.element = qtip.elements.tip = $('
', { 'class': NAMESPACE+'-tip' }).prependTo(qtip.tooltip); // Create tip drawing element(s) if(HASCANVAS) { // save() as soon as we create the canvas element so FF2 doesn't bork on our first restore()! context = $('').appendTo(this.element)[0].getContext('2d'); // Setup constant parameters context.lineJoin = 'miter'; context.miterLimit = 100000; context.save(); } else { context = createVML('shape', 'coordorigin="0,0"', 'position:absolute;'); this.element.html(context + context); // Prevent mousing down on the tip since it causes problems with .live() handling in IE due to VML qtip._bind( $('*', tip).add(tip), ['click', 'mousedown'], function(event) { event.stopPropagation(); }, this._ns); } // Bind update events qtip._bind(qtip.tooltip, 'tooltipmove', this.reposition, this._ns, this); // Create it this.create(); }, _swapDimensions: function() { this.size[0] = this.options.height; this.size[1] = this.options.width; }, _resetDimensions: function() { this.size[0] = this.options.width; this.size[1] = this.options.height; }, _useTitle: function(corner) { var titlebar = this.qtip.elements.titlebar; return titlebar && ( corner.y === TOP || corner.y === CENTER && this.element.position().top + this.size[1] / 2 + this.options.offset < titlebar.outerHeight(TRUE) ); }, _parseCorner: function(corner) { var my = this.qtip.options.position.my; // Detect corner and mimic properties if(corner === FALSE || my === FALSE) { corner = FALSE; } else if(corner === TRUE) { corner = new CORNER( my.string() ); } else if(!corner.string) { corner = new CORNER(corner); corner.fixed = TRUE; } return corner; }, _parseWidth: function(corner, side, use) { var elements = this.qtip.elements, prop = BORDER + camel(side) + 'Width'; return (use ? intCss(use, prop) : intCss(elements.content, prop) || intCss(this._useTitle(corner) && elements.titlebar || elements.content, prop) || intCss(elements.tooltip, prop) ) || 0; }, _parseRadius: function(corner) { var elements = this.qtip.elements, prop = BORDER + camel(corner.y) + camel(corner.x) + 'Radius'; return BROWSER.ie < 9 ? 0 : intCss(this._useTitle(corner) && elements.titlebar || elements.content, prop) || intCss(elements.tooltip, prop) || 0; }, _invalidColour: function(elem, prop, compare) { var val = elem.css(prop); return !val || compare && val === elem.css(compare) || INVALID.test(val) ? FALSE : val; }, _parseColours: function(corner) { var elements = this.qtip.elements, tip = this.element.css('cssText', ''), borderSide = BORDER + camel(corner[ corner.precedance ]) + camel(COLOR), colorElem = this._useTitle(corner) && elements.titlebar || elements.content, css = this._invalidColour, color = []; // Attempt to detect the background colour from various elements, left-to-right precedance color[0] = css(tip, BG_COLOR) || css(colorElem, BG_COLOR) || css(elements.content, BG_COLOR) || css(elements.tooltip, BG_COLOR) || tip.css(BG_COLOR); // Attempt to detect the correct border side colour from various elements, left-to-right precedance color[1] = css(tip, borderSide, COLOR) || css(colorElem, borderSide, COLOR) || css(elements.content, borderSide, COLOR) || css(elements.tooltip, borderSide, COLOR) || elements.tooltip.css(borderSide); // Reset background and border colours $('*', tip).add(tip).css('cssText', BG_COLOR+':'+TRANSPARENT+IMPORTANT+';'+BORDER+':0'+IMPORTANT+';'); return color; }, _calculateSize: function(corner) { var y = corner.precedance === Y, width = this.options.width, height = this.options.height, isCenter = corner.abbrev() === 'c', base = (y ? width: height) * (isCenter ? 0.5 : 1), pow = Math.pow, round = Math.round, bigHyp, ratio, result, smallHyp = Math.sqrt( pow(base, 2) + pow(height, 2) ), hyp = [ this.border / base * smallHyp, this.border / height * smallHyp ]; hyp[2] = Math.sqrt( pow(hyp[0], 2) - pow(this.border, 2) ); hyp[3] = Math.sqrt( pow(hyp[1], 2) - pow(this.border, 2) ); bigHyp = smallHyp + hyp[2] + hyp[3] + (isCenter ? 0 : hyp[0]); ratio = bigHyp / smallHyp; result = [ round(ratio * width), round(ratio * height) ]; return y ? result : result.reverse(); }, // Tip coordinates calculator _calculateTip: function(corner, size, scale) { scale = scale || 1; size = size || this.size; var width = size[0] * scale, height = size[1] * scale, width2 = Math.ceil(width / 2), height2 = Math.ceil(height / 2), // Define tip coordinates in terms of height and width values tips = { br: [0,0, width,height, width,0], bl: [0,0, width,0, 0,height], tr: [0,height, width,0, width,height], tl: [0,0, 0,height, width,height], tc: [0,height, width2,0, width,height], bc: [0,0, width,0, width2,height], rc: [0,0, width,height2, 0,height], lc: [width,0, width,height, 0,height2] }; // Set common side shapes tips.lt = tips.br; tips.rt = tips.bl; tips.lb = tips.tr; tips.rb = tips.tl; return tips[ corner.abbrev() ]; }, // Tip coordinates drawer (canvas) _drawCoords: function(context, coords) { context.beginPath(); context.moveTo(coords[0], coords[1]); context.lineTo(coords[2], coords[3]); context.lineTo(coords[4], coords[5]); context.closePath(); }, create: function() { // Determine tip corner var c = this.corner = (HASCANVAS || BROWSER.ie) && this._parseCorner(this.options.corner); // If we have a tip corner... this.enabled = !!this.corner && this.corner.abbrev() !== 'c'; if(this.enabled) { // Cache it this.qtip.cache.corner = c.clone(); // Create it this.update(); } // Toggle tip element this.element.toggle(this.enabled); return this.corner; }, update: function(corner, position) { if(!this.enabled) { return this; } var elements = this.qtip.elements, tip = this.element, inner = tip.children(), options = this.options, curSize = this.size, mimic = options.mimic, round = Math.round, color, precedance, context, coords, bigCoords, translate, newSize, border; // Re-determine tip if not already set if(!corner) { corner = this.qtip.cache.corner || this.corner; } // Use corner property if we detect an invalid mimic value if(mimic === FALSE) { mimic = corner; } // Otherwise inherit mimic properties from the corner object as necessary else { mimic = new CORNER(mimic); mimic.precedance = corner.precedance; if(mimic.x === 'inherit') { mimic.x = corner.x; } else if(mimic.y === 'inherit') { mimic.y = corner.y; } else if(mimic.x === mimic.y) { mimic[ corner.precedance ] = corner[ corner.precedance ]; } } precedance = mimic.precedance; // Ensure the tip width.height are relative to the tip position if(corner.precedance === X) { this._swapDimensions(); } else { this._resetDimensions(); } // Update our colours color = this.color = this._parseColours(corner); // Detect border width, taking into account colours if(color[1] !== TRANSPARENT) { // Grab border width border = this.border = this._parseWidth(corner, corner[corner.precedance]); // If border width isn't zero, use border color as fill if it's not invalid (1.0 style tips) if(options.border && border < 1 && !INVALID.test(color[1])) { color[0] = color[1]; } // Set border width (use detected border width if options.border is true) this.border = border = options.border !== TRUE ? options.border : border; } // Border colour was invalid, set border to zero else { this.border = border = 0; } // Determine tip size newSize = this.size = this._calculateSize(corner); tip.css({ width: newSize[0], height: newSize[1], lineHeight: newSize[1]+'px' }); // Calculate tip translation if(corner.precedance === Y) { translate = [ round(mimic.x === LEFT ? border : mimic.x === RIGHT ? newSize[0] - curSize[0] - border : (newSize[0] - curSize[0]) / 2), round(mimic.y === TOP ? newSize[1] - curSize[1] : 0) ]; } else { translate = [ round(mimic.x === LEFT ? newSize[0] - curSize[0] : 0), round(mimic.y === TOP ? border : mimic.y === BOTTOM ? newSize[1] - curSize[1] - border : (newSize[1] - curSize[1]) / 2) ]; } // Canvas drawing implementation if(HASCANVAS) { // Grab canvas context and clear/save it context = inner[0].getContext('2d'); context.restore(); context.save(); context.clearRect(0,0,6000,6000); // Calculate coordinates coords = this._calculateTip(mimic, curSize, SCALE); bigCoords = this._calculateTip(mimic, this.size, SCALE); // Set the canvas size using calculated size inner.attr(WIDTH, newSize[0] * SCALE).attr(HEIGHT, newSize[1] * SCALE); inner.css(WIDTH, newSize[0]).css(HEIGHT, newSize[1]); // Draw the outer-stroke tip this._drawCoords(context, bigCoords); context.fillStyle = color[1]; context.fill(); // Draw the actual tip context.translate(translate[0] * SCALE, translate[1] * SCALE); this._drawCoords(context, coords); context.fillStyle = color[0]; context.fill(); } // VML (IE Proprietary implementation) else { // Calculate coordinates coords = this._calculateTip(mimic); // Setup coordinates string coords = 'm' + coords[0] + ',' + coords[1] + ' l' + coords[2] + ',' + coords[3] + ' ' + coords[4] + ',' + coords[5] + ' xe'; // Setup VML-specific offset for pixel-perfection translate[2] = border && /^(r|b)/i.test(corner.string()) ? BROWSER.ie === 8 ? 2 : 1 : 0; // Set initial CSS inner.css({ coordsize: newSize[0]+border + ' ' + newSize[1]+border, antialias: ''+(mimic.string().indexOf(CENTER) > -1), left: translate[0] - translate[2] * Number(precedance === X), top: translate[1] - translate[2] * Number(precedance === Y), width: newSize[0] + border, height: newSize[1] + border }) .each(function(i) { var $this = $(this); // Set shape specific attributes $this[ $this.prop ? 'prop' : 'attr' ]({ coordsize: newSize[0]+border + ' ' + newSize[1]+border, path: coords, fillcolor: color[0], filled: !!i, stroked: !i }) .toggle(!!(border || i)); // Check if border is enabled and add stroke element !i && $this.html( createVML( 'stroke', 'weight="'+border*2+'px" color="'+color[1]+'" miterlimit="1000" joinstyle="miter"' ) ); }); } // Opera bug #357 - Incorrect tip position // https://github.com/Craga89/qTip2/issues/367 window.opera && setTimeout(function() { elements.tip.css({ display: 'inline-block', visibility: 'visible' }); }, 1); // Position if needed if(position !== FALSE) { this.calculate(corner, newSize); } }, calculate: function(corner, size) { if(!this.enabled) { return FALSE; } var self = this, elements = this.qtip.elements, tip = this.element, userOffset = this.options.offset, position = {}, precedance, corners; // Inherit corner if not provided corner = corner || this.corner; precedance = corner.precedance; // Determine which tip dimension to use for adjustment size = size || this._calculateSize(corner); // Setup corners and offset array corners = [ corner.x, corner.y ]; if(precedance === X) { corners.reverse(); } // Calculate tip position $.each(corners, function(i, side) { var b, bc, br; if(side === CENTER) { b = precedance === Y ? LEFT : TOP; position[ b ] = '50%'; position[MARGIN+'-' + b] = -Math.round(size[ precedance === Y ? 0 : 1 ] / 2) + userOffset; } else { b = self._parseWidth(corner, side, elements.tooltip); bc = self._parseWidth(corner, side, elements.content); br = self._parseRadius(corner); position[ side ] = Math.max(-self.border, i ? bc : userOffset + (br > b ? br : -b)); } }); // Adjust for tip size position[ corner[precedance] ] -= size[ precedance === X ? 0 : 1 ]; // Set and return new position tip.css({ margin: '', top: '', bottom: '', left: '', right: '' }).css(position); return position; }, reposition: function(event, api, pos) { if(!this.enabled) { return; } var cache = api.cache, newCorner = this.corner.clone(), adjust = pos.adjusted, method = api.options.position.adjust.method.split(' '), horizontal = method[0], vertical = method[1] || method[0], shift = { left: FALSE, top: FALSE, x: 0, y: 0 }, offset, css = {}, props; function shiftflip(direction, precedance, popposite, side, opposite) { // Horizontal - Shift or flip method if(direction === SHIFT && newCorner.precedance === precedance && adjust[side] && newCorner[popposite] !== CENTER) { newCorner.precedance = newCorner.precedance === X ? Y : X; } else if(direction !== SHIFT && adjust[side]){ newCorner[precedance] = newCorner[precedance] === CENTER ? adjust[side] > 0 ? side : opposite : newCorner[precedance] === side ? opposite : side; } } function shiftonly(xy, side, opposite) { if(newCorner[xy] === CENTER) { css[MARGIN+'-'+side] = shift[xy] = offset[MARGIN+'-'+side] - adjust[side]; } else { props = offset[opposite] !== undefined ? [ adjust[side], -offset[side] ] : [ -adjust[side], offset[side] ]; if( (shift[xy] = Math.max(props[0], props[1])) > props[0] ) { pos[side] -= adjust[side]; shift[side] = FALSE; } css[ offset[opposite] !== undefined ? opposite : side ] = shift[xy]; } } // If our tip position isn't fixed e.g. doesn't adjust with viewport... if(this.corner.fixed !== TRUE) { // Perform shift/flip adjustments shiftflip(horizontal, X, Y, LEFT, RIGHT); shiftflip(vertical, Y, X, TOP, BOTTOM); // Update and redraw the tip if needed (check cached details of last drawn tip) if(newCorner.string() !== cache.corner.string() || cache.cornerTop !== adjust.top || cache.cornerLeft !== adjust.left) { this.update(newCorner, FALSE); } } // Setup tip offset properties offset = this.calculate(newCorner); // Readjust offset object to make it left/top if(offset.right !== undefined) { offset.left = -offset.right; } if(offset.bottom !== undefined) { offset.top = -offset.bottom; } offset.user = this.offset; // Perform shift adjustments shift.left = horizontal === SHIFT && !!adjust.left; if(shift.left) { shiftonly(X, LEFT, RIGHT); } shift.top = vertical === SHIFT && !!adjust.top; if(shift.top) { shiftonly(Y, TOP, BOTTOM); } /* * If the tip is adjusted in both dimensions, or in a * direction that would cause it to be anywhere but the * outer border, hide it! */ this.element.css(css).toggle( !(shift.x && shift.y || newCorner.x === CENTER && shift.y || newCorner.y === CENTER && shift.x) ); // Adjust position to accomodate tip dimensions pos.left -= offset.left.charAt ? offset.user : horizontal !== SHIFT || shift.top || !shift.left && !shift.top ? offset.left + this.border : 0; pos.top -= offset.top.charAt ? offset.user : vertical !== SHIFT || shift.left || !shift.left && !shift.top ? offset.top + this.border : 0; // Cache details cache.cornerLeft = adjust.left; cache.cornerTop = adjust.top; cache.corner = newCorner.clone(); }, destroy: function() { // Unbind events this.qtip._unbind(this.qtip.tooltip, this._ns); // Remove the tip element(s) if(this.qtip.elements.tip) { this.qtip.elements.tip.find('*') .remove().end().remove(); } } }); TIP = PLUGINS.tip = function(api) { return new Tip(api, api.options.style.tip); }; // Initialize tip on render TIP.initialize = 'render'; // Setup plugin sanitization options TIP.sanitize = function(options) { if(options.style && 'tip' in options.style) { var opts = options.style.tip; if(typeof opts !== 'object') { opts = options.style.tip = { corner: opts }; } if(!(/string|boolean/i).test(typeof opts.corner)) { opts.corner = TRUE; } } }; // Add new option checks for the plugin CHECKS.tip = { '^position.my|style.tip.(corner|mimic|border)$': function() { // Make sure a tip can be drawn this.create(); // Reposition the tooltip this.qtip.reposition(); }, '^style.tip.(height|width)$': function(obj) { // Re-set dimensions and redraw the tip this.size = [ obj.width, obj.height ]; this.update(); // Reposition the tooltip this.qtip.reposition(); }, '^content.title|style.(classes|widget)$': function() { this.update(); } }; // Extend original qTip defaults $.extend(TRUE, QTIP.defaults, { style: { tip: { corner: TRUE, mimic: FALSE, width: 6, height: 6, border: TRUE, offset: 0 } } });