PageSourceSearch

https://point.im/js/tooltip.js

js point.im collected 2026-10-03 22:43:00 UTC 4,751 bytes, 127 lines download raw bytes

1// Footnotes as Hovering Tooltips
2//
3// Original Scripts by Lukas Mathis and Osvaldas Valutis
4//     - http://ignorethecode.net/blog/2010/04/20/footnotes/
5//     - http://osvaldas.info/blog/elegant-css-and-jquery-tooltip- \
6//           responsive-mobile-friendly/
7// Modified by Syeong Gan
8//     - Uses Mathis's base code and Valutis's tooltip design
9//     - Searches for PHP Markdown Extra-style footnotes
10//     - Disabled link click-through for Android devices
11//
12// Requirements: jQuery
13
14$(document).ready(function() {
15    Footnotes.initTooltip();
16});
17
18var Footnotes = {
19    isIOS: function() {
20        var agent = navigator.userAgent.toLowerCase();
21        return(
22            agent.indexOf('iphone') >= 0 ||
23            agent.indexOf('ipad') >= 0 ||
24            agent.indexOf('ipod') >= 0
25        );
26    },
27    isAndroid: function() {
28        var agent = navigator.userAgent.toLowerCase();
29        return(agent.indexOf('android') >= 0);
30    },
31    initTooltip: function() {
32        var targets = $('[rel~=footnote]');
33        
34        // Load Tooltip CSS
35        //$('body').append('<style>' + cssTooltip + '</style>');
36        
37        targets.unbind('mouseover', Footnotes.addTooltip);
38        targets.unbind('mouseout', Footnotes.removeTooltip);
39        
40        targets.bind('mouseover', Footnotes.addTooltip);
41        targets.bind('mouseout', Footnotes.removeTooltip);
42    },
43    addTooltip: function () {
44        $('#tooltip').stop();
45        $('#tooltip').remove();
46        
47        // Find matching footnote text and remove extraneous tags
48        var target = $(this);
49        var id = target.attr('href').substr(1);
50        var fn = document.getElementById(id);
51        var tip = $(fn).html();
52        tip = tip.replace(/<p>(.+)<a href="#fnref.+<\/a><\/p>/, "$1");
53        if( !tip || tip == '' ) return false;
54        
55        // Create Tooltip
56        var tooltip = $('<div id="tooltip"></div>');
57        
58        // Check for mobile devices
59        if(Footnotes.isIOS()) {
60            tooltip.bind('click', Footnotes.removeTooltip);
61        } else if(Footnotes.isAndroid()) {
62            tooltip.bind('click', Footnotes.removeTooltip);
63            target.click(function(e) { e.preventDefault(); });
64        } else {
65            tooltip.bind('mouseover', Footnotes.hoverTooltip);
66            tooltip.bind('mouseout', Footnotes.removeTooltip);
67        }
68        
69        // Add Tooltip to page (hidden)
70        tooltip.css('opacity', 0)
71               .html(tip)
72               .appendTo('body');
73        
74        var positionTooltip = function() {
75            // Determine size of tooltip (max width of 340px)
76            if($(window).width() < 640)
77                tooltip.css('max-width', $(window).width() / 2);
78            else
79                tooltip.css('max-width', 340);
80            
81            // Set initial position of tooltip
82            var pos_left = target.offset().left + (target.outerWidth() / 2) - (tooltip.outerWidth() / 2),
83                pos_top  = target.offset().top - tooltip.outerHeight() - 30;
84            
85            // Check if the left side of the tooltip is off screen
86            if(pos_left < 0) {
87                pos_left = target.offset().left + (target.outerWidth() / 2) - 20;
88                tooltip.addClass('left');
89            } else
90                tooltip.removeClass('left');
91            
92            // Check if the right side of the tooltip is off screen
93            if(pos_left + tooltip.outerWidth() > $(window).width()) {
94                pos_left = target.offset().left - tooltip.outerWidth() + (target.outerWidth() / 2) + 20;
95                tooltip.addClass('right');
96            } else
97                tooltip.removeClass('right');
98            
99            // Check if the ltop of the tooltip is off screen
100            if(pos_top < 0) {
101                var pos_top = target.offset().top + target.outerHeight();
102                tooltip.addClass('top');
103            } else
104                tooltip.removeClass('top');
105            
106            tooltip.css({ left: pos_left, top: pos_top })
107                   .animate({ top: '+=10', opacity: 1 }, 100);
108        }
109        
110        // Show Tooltip (and reposition if window changes)
111        positionTooltip();
112        $(window).resize(positionTooltip());
113    },
114    removeTooltip: function() {
115        var tooltip = $('#tooltip');
116        
117        tooltip.animate({ top: '-=10', opacity: 0 }, 100, function() {
118                tooltip.remove();
119        });
120    },
121    hoverTooltip: function() {
122        var tooltip = $('#tooltip');
123        
124        tooltip.stop();
125        tooltip.css('opacity', 1);
126    }
127}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.