PageSourceSearch

https://docs.wpilib.org/en/latest/_static/js/hoverxref.js

js wpilib.org collected 2026-10-01 11:51:08 UTC 9,745 bytes, 264 lines download raw bytes

1var mathjax = true;
2var sphinxtabs = false;
3
4
5
6function reRenderTooltip (instance, helper) {
7    // Check if the content is the same as the default content until
8    // it's different. Once it's different, re renders its content
9    // to show it properly (this may involve calling external JS
10    // libraries like MathJax) and finally call tooltip.reposition().
11    if (helper.tooltip.textContent !== 'Loading...') {
12        // https://stackoverflow.com/questions/5200545/how-to-recall-or-restart-mathjax
13        if (mathjax) {
14            if (typeof MathJax !== 'undefined') {
15                reLoadMathJax(helper.tooltip.id);
16            } else {
17                console.debug('Not triggering MathJax because it is not defined');
18            };
19
20        };
21        instance.reposition();
22    } else {
23        setTimeout(reRenderTooltip, 100, instance, helper);
24    };
25}
26
27
28function reLoadMathJax(elementId) {
29    if (parseInt(MathJax.version[0]) >= 3) {
30        console.debug('Typesetting for Mathjax3');
31        MathJax.typeset();
32    } else {
33        console.debug('Typesetting for MathJax2');
34        MathJax.Hub.Queue((["Typeset", MathJax.Hub, elementId]));
35    }
36}
37
38
39function reLoadSphinxTabs() {
40    if (sphinxtabs) {
41        // https://github.com/djungelorm/sphinx-tabs
42        console.debug('Triggering Sphinx Tabs rendering');
43        (function(d, script) {
44            // HACK: please, improve this code to call the content of "tab.js" without creating a script element
45
46            // Get the URL from the current generated page since it's not always the same
47            var older_tabs_src = $('script[src$="sphinx_tabs/tabs.js"]');
48            if (older_tabs_src.length != 0) {
49                // sphinx-tabs < 2
50                older_tabs_src = older_tabs_src[0].older_tabs_src
51                script = d.createElement('script');
52                script.type = 'text/javascript';
53                script.onload = function(){
54                    // remote script has loaded
55                };
56                script.older_tabs_src = older_tabs_src;
57                d.getElementsByTagName('head')[0].appendChild(script);
58
59                // Once the script has been executed, we remove it from the DOM
60                script.parentNode.removeChild(script);
61            }
62            var newer_tabs_src = $('script[src$="_static/tabs.js"]');
63            if (newer_tabs_src.length != 0) {
64                // sphinx-tabs > 2
65                // Borrowed from
66                // https://github.com/executablebooks/sphinx-tabs/blob/0f3cbbe/sphinx_tabs/static/tabs.js#L8-L17
67                var allTabs = document.querySelectorAll('.sphinx-tabs-tab');
68                var tabLists = document.querySelectorAll('[role="tablist"]');
69                allTabs.forEach(tab => {
70                    tab.addEventListener("click", changeTabs);
71                });
72
73                tabLists.forEach(tabList => {
74                    tabList.addEventListener("keydown", keyTabs);
75                });
76            }
77
78        }(document));
79    };
80};
81
82function getEmbedURL(url) {
83    var params = {
84        'doctool': 'sphinx',
85        'doctoolversion': '8.2.3',
86        'url': url,
87    }
88    console.debug('Data: ' + JSON.stringify(params));
89    var url = '/_' + '/api/v3/embed/?' + $.param(params);
90    console.debug('URL: ' + url);
91    return url
92}
93
94function addTooltip(target) {
95    return target.tooltipster({
96        theme: ['tooltipster-shadow', 'tooltipster-shadow-custom'],
97        interactive: true,
98        maxWidth: 450,
99        animation: 'fade',
100        animationDuration: 0,
101        side: 'right',
102        content: 'Loading...',
103        contentAsHTML: true,
104
105        functionBefore: function(instance, helper) {
106            var $origin = $(helper.origin);
107            var href = $origin.prop('href');
108
109            // we set a variable so the data is only loaded once via Ajax, not every time the tooltip opens
110            if ($origin.data('loaded') !== true) {
111                var url = getEmbedURL(href);
112                $.ajax({
113                    url: url,
114                    headers: {'X-HoverXRef-Version': '1.4.2'},
115                }).done(
116                    function (data) {
117                        // call the 'content' method to update the content of our tooltip with the returned data.
118                        // note: this content update will trigger an update animation (see the updateAnimation option)
119                        instance.content(data['content']);
120
121                        // to remember that the data has been loaded
122                        $origin.data('loaded', true);
123                    }
124                );
125            }
126        },
127
128        functionReady: function(instance, helper) {
129            // most of Read the Docs Sphinx theme bases its style on "rst-content".
130            // We add that class to the tooltipser HTML tag here by default or a user-defined one.
131            helper.tooltip.classList.add('rst-content');
132            reLoadSphinxTabs();
133            setTimeout(
134                reRenderTooltip,
135                50,
136                instance,
137                helper
138            );
139        }
140    })
141}
142
143
144$(document).ready(function() {
145    // Remove ``title=`` attribute for intersphinx nodes that have hoverxref enabled.
146    // It doesn't make sense the browser shows the default tooltip (browser's built-in)
147    // and immediately after that our tooltip was shown.
148
149    // Support lazy-loading here by switching between on-page-load (calling .tooltipster directly)
150    // or delaying it until after a mouseenter or click event.
151    // On large pages (the use case for lazy-loaded tooltipster) this moves dom manipulation to
152    // on-interaction, which is known to be less performant on small pages (as per tooltipster docs),
153    // but on massive docs pages fixes an otherwise severe page load stall when tooltipster
154    // manipulates the html for every single tooltip at once.
155    
156    $('.hxr-hoverxref.external').each(function () { $(this).removeAttr('title') });
157    addTooltip(
158        $('.hxr-hoverxref.hxr-tooltip')
159    )
160    
161
162
163    var modalHtml = `
164  <div class="modal micromodal-slide rst-content" id="micromodal" aria-hidden="true">
165    <div class="modal__overlay" tabindex="-1" data-micromodal-close>
166      <div class="modal__container" role="dialog" aria-modal="true" aria-labelledby="micromodal-title">
167        <header class="modal__header">
168          <h1 class="modal__title" id="micromodal-title"></h1>
169          <button class="modal__close" aria-label="Close modal" data-micromodal-close></button>
170        </header>
171        <hr/>
172        <main class="modal__content" id="micromodal-content"></main>
173        <footer class="modal__footer">
174          <button class="modal__btn" data-micromodal-close aria-label="Close this dialog window">Close</button>
175        </footer>
176      </div>
177    </div>
178  </div>
179`
180    $('body').append(modalHtml);
181
182    
183    function onShow(modal, element) {
184        // This is a HACK to get some "smart" left position of the
185        // modal depending its size.
186        var container = $('#micromodal .modal__container')
187        var maxWidth = $('.wy-nav-content').innerWidth() - 150;
188        var contentLeft = $('.wy-nav-content').position().left;
189        if (container.width() >= maxWidth) {
190            var left = contentLeft - 150;
191        }
192        else {
193            var left = contentLeft + 150;
194        }
195        console.debug('Container left position: ' + left);
196        container.css('left', left);
197    }
198    
199
200    function showModal(element) {
201        var href = element.prop('href');
202        var url = getEmbedURL(href);
203        $.ajax({
204            url: url,
205            headers: {'X-HoverXRef-Version': '1.4.2'},
206        }).done(
207            function (data) {
208                var content = $('<div></div>');
209                content.html(data['content']);
210
211                var h1 = $('h1:first', content);
212                var title = h1.text()
213                if (title) {
214                    var link = $('a', h1).attr('href') || '#';
215
216                    // Remove permalink icon from the title
217                    var title = title.replace('¶', '').replace('', '');
218
219                    var a = $('<a></a>').attr('href', link).text('📝 ' + title);
220                }
221                else {
222                    var a = '📝 Note';
223                }
224                h1.replaceWith('');
225
226                $('#micromodal-title').html(a);
227                $('#micromodal-content').html(content);
228                MicroModal.show('micromodal', {
229                    
230                    onShow: onShow,
231                    
232                    openClass: 'is-open',
233                    disableScroll: false,
234                    disableFocus: true,
235                    awaitOpenAnimation: false,
236                    awaitCloseAnimation: false,
237                    debugMode: false
238                });
239                $('#micromodal .modal__container').scrollTop(0);
240                reLoadSphinxTabs();
241                if (mathjax) {
242                    if (typeof MathJax !== 'undefined') {
243                        reLoadMathJax('micromodal');
244                    } else {
245                        console.debug('Not triggering MathJax because it is not defined');
246                    };
247                };
248            }
249        );
250    };
251
252    var delay = 350, setTimeoutConst;
253    $('.hxr-hoverxref.hxr-modal').hover(function(event) {
254        var element = $(this);
255        console.debug('Event: ' + event + ' Element: ' + element);
256        event.preventDefault();
257
258        setTimeoutConst = setTimeout(function(){
259            showModal(element);
260        }, delay);
261    }, function(){
262        clearTimeout(setTimeoutConst);
263    });
264});

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.