User:Nitwad/infoboxTooltips.js

From Cobalt Core Wiki
Jump to navigation Jump to search

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
// load dependencies first
CobaltCoreWikiModuleLoader.load([
    'MediaWiki:Tippy.js',
    'MediaWiki:Tippy.css',
    'MediaWiki:InfoboxTransclusions.js',
]).then( function() {
    function getPageContent(pageTitle) {
        return new Promise(function(resolve, reject) {
            fetch("https://cobaltcore.wiki.gg/api.php?action=parse&format=json&page=" + pageTitle + "&prop=text", {
                method:'POST',
                headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/x-www-form-urlencoded',
                }
            }).then( function(response) {
                if (response.status !== 200) {
                    reject("response status is " + response.status);
                    return;
                }
                
                response.json().then( function(responseJson) {
                    if ( !responseJson.hasOwnProperty('parse') ) {
                        reject('response is missing "parse" property');
                        return;
                    }
                    
                    if ( !responseJson.parse.hasOwnProperty('text') ) {
                        reject('response.parse is missing "text" property');
                        return;
                    }
                    
                    if ( !responseJson.parse.text.hasOwnProperty('*') ) {
                        reject('response.parse.text is missing "*" property');
                        return;
                    }
                    
                    resolve(responseJson.parse.text['*']);
                    return;
                } );
            } );
        });
    }
    
    var infoboxJsCssInjected = false;
    
    function injectInfoboxJsCss() {
        if (infoboxJsCssInjected) {
            return;
        }
        
        mw.loader.load([
            'ext.PortableInfobox.styles',
            'mediawiki.page.gallery.styles',
        ]);
        
        (function(window, $) {
            $(document.body).on('click', '.tippy-content .portable-infobox .pi-media-collection ul.pi-media-collection-tabs li:not(.current)', function() {
                var $target = $(this);
                var tabId = $target.attr('data-pi-tab');
                var $collection = $target.closest('.pi-media-collection');
                var $currentTab = $collection.find('ul.pi-media-collection-tabs li.current');
                var $currentTabContent = $collection.find('.pi-media-collection-tab-content.current');
    
                $currentTab.removeClass('current');
                $currentTabContent.removeClass('current');
    
                $target.addClass('current');
                $collection.find('#' + tabId).addClass('current');
            });
        })(window, jQuery);
        
        infoboxJsCssInjected = true;
    }
    
    var tippyShowDelay = 500;
    var tippyContentsByPageTitle = {};
    
    function getTippyContent(pageTitle, infoboxType) {
        if (!infoboxType) {
            infoboxType = '';
        }
    
        return new Promise(function(resolve, reject) {
            if ( tippyContentsByPageTitle.hasOwnProperty(pageTitle) ) {
                resolve(tippyContentsByPageTitle[pageTitle]);
                return;
            }
            
            getPageContent(pageTitle).then(
                // resolve
                function(html) {
                    const domParser = new DOMParser();
                    const htmlDoc = domParser.parseFromString(html, 'text/html');
                    const infoboxEl = htmlDoc.querySelector('.portable-infobox.pi-type-'+infoboxType);
                    
                    if ( !infoboxEl ) {
                        reject(null);
                        return;
                    }
                    
                    var tippyContent = infoboxEl.outerHTML + '<div style="clear:both;"></div>';
                    tippyContentsByPageTitle[pageTitle] = tippyContent;
                    
                    resolve(tippyContent);
                    return;
                },
                
                // reject
                function(error) {
                    reject(error);
                    return;
                }
            );
        });
    }
    
    var currentlyHoveredTippyEl = null;
     
    tippy.setDefaultProps({
        theme: 'light',
        allowHTML: true,
        animation: 'scale',
        delay: [tippyShowDelay, 0],
        duration: [200, 0],
        hideOnClick: false,
        offset: [0, 12],
        placement: 'right',
        interactive: true,
        interactiveDebounce: 75,
        overrides: ['triggerTarget'],
        // content: function (reference) { return reference.getAttribute('title') },
        // content: null,
        onShow: function(instance) {
            tippy.hideAll({duration: 0});
        },
        onTrigger: function(instance, event) {
            if ( typeof cobaltCoreWikiInfoboxTransclusions === 'undefined' ) {
                return;
            }

            instance.disable();
            var desiredInstance = instance;

            var waitForTippyShowDelay = new Promise(resolve => setTimeout(resolve, tippyShowDelay));
            
            const el = instance.reference;
            var linkEl = el;

            if ( el.classList.contains('icon-link') ) {
                linkEl = instance.props.triggerTarget[0];
            }
    
            currentlyHoveredTippyEl = el;
            const href = linkEl.getAttribute('href');
            const baseUrl = window.location.protocol + '//' + window.location.host;
            const urlInstance = new URL(href, baseUrl);
            const pathname = urlInstance.pathname;
            const lastSlashIndex = pathname.lastIndexOf('/');
            const pageTitle = pathname.substring(lastSlashIndex + 1);

            let infoboxType;

            if ( cobaltCoreWikiInfoboxTransclusions.hasOwnProperty(pageTitle) ) {
                infoboxType = cobaltCoreWikiInfoboxTransclusions[pageTitle];
            } else {
                const pageTitleWithoutUnderscores = pageTitle.replace(/_/g, ' ');

                if ( cobaltCoreWikiInfoboxTransclusions.hasOwnProperty(pageTitleWithoutUnderscores) ) {
                    infoboxType = cobaltCoreWikiInfoboxTransclusions[pageTitleWithoutUnderscores];
                }
            }

            if (!infoboxType) {
                return;
            }

            let iconLinkParentEl = el.closest('.icon-link');
            let iconLinkChildLinkEls;

            if (iconLinkParentEl) {
                iconLinkChildLinkEls = iconLinkParentEl.querySelectorAll('a');

                if (!iconLinkParentEl._tippy) {
                    var triggerTargets = [];
                    for (var i = 0; i < iconLinkChildLinkEls.length; i++) {
                        triggerTargets.push(iconLinkChildLinkEls[i]);
                    }

                    desiredInstance = tippy(iconLinkParentEl, {
                        triggerTarget: triggerTargets,
                        content: 'hello',
                    });
                    // console.log('desiredInstance changed');
                } else {
                    desiredInstance = iconLinkParentEl._tippy;
                    // console.log('desiredInstance changed');
                }
            }
            
            getTippyContent(pageTitle, infoboxType).then(
                // resolve
                function(tippyContent) {
                    injectInfoboxJsCss();
                    desiredInstance.setContent(tippyContent);
                    linkEl.removeAttribute('title');
    
                    if (iconLinkChildLinkEls && iconLinkChildLinkEls.length) {
                        for (var i = 0; i < iconLinkChildLinkEls.length; i++) {
                            iconLinkChildLinkEls[i].removeAttribute('title');
                        }
                    }
    
                    desiredInstance.enable();

                    if ( el == currentlyHoveredTippyEl ) {
                        waitForTippyShowDelay.then( function() {
                            desiredInstance.show();
                        } );
                    }
                    
                    mw.loader.using( [ 'ext.PortableInfobox.scripts' ], function ( require ) {
                        var x = require('ext.PortableInfobox.scripts');
                        // console.log(x);
                    } );
                },
                
                // reject
                function(error) {
                    console.log('getTippyContent reject');
                    console.log('error =', error);
                }
            );
        },
        onUntrigger: function(instance, event) {
            console.log('onUntrigger');
            const el = instance.reference;
            if (el == currentlyHoveredTippyEl) {
                currentlyHoveredTippyEl = null;
            }
        }
    });
    
    tippy.delegate(document.getElementById('content'), {
        target: '#content a[href][title]',
        appendTo: document.body,
    });
    
    // tippy.delegate(document.getElementById('content'), {
    //     target: '#content .icon-link.artifact',
    //     appendTo: document.body,
    // });
} );