Tampermonkey/Greasemonkey Scripts

Install Tampermonkey, then create a new script and paste the code.

FFlogs XIVAnalysis Button

@match: https://www.fflogs.com/reports/*

Adds a button linking to XIVAnalysis based on the current fight parameter in FFLogs reports. Generated by AI so don't judge it too hard.

// ==UserScript==
// @name         FFLogs → XIVAnalysis Fight Button
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Adds a button linking to XIVAnalysis based on the current fight parameter in FFLogs reports.
// @author       Your Name
// @match        https://www.fflogs.com/reports/*
// @grant        none
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';

    // Returns the current "fight" parameter value (or null if not set)
    function getFightParam() {
        const urlParams = new URLSearchParams(window.location.search);
        return urlParams.get('fight');
    }

    // Returns the report id from the URL (assuming URL is /reports/{reportID}...)
    function getReportID() {
        const parts = window.location.pathname.split('/');
        const idx = parts.indexOf("reports");
        return (idx !== -1 && parts.length > idx + 1) ? parts[idx + 1] : null;
    }

    // Update or create the XIVAnalysis button based on the current URL.
    function updateButton() {
        const fight = getFightParam();
        const reportID = getReportID();

        // If there's no fight parameter or reportID, remove any existing button.
        if (!fight || !reportID) {
            const existing = document.getElementById('xivanalysis-button');
            if (existing) existing.remove();
            return;
        }

        // Build the new URL: https://xivanalysis.com/fflogs/{reportID}/{fight}
        const linkURL = `https://xivanalysis.com/fflogs/\${reportID}/\${fight}\`;

        // Check if our button already exists
        let button = document.getElementById('xivanalysis-button');
        if (!button) {
            // Create the button element (styled similar to FFLogs tabs)
            button = document.createElement('a');
            button.id = 'xivanalysis-button';
            button.className = 'big-tab view-type-tab';
            button.innerHTML = \`
                <span class="zmdi zmdi-search-in-file"></span>
                <span class="big-tab-text"><br>XIVAnalysis</span>
            \`;
            // Append the button to the tab container if available
            const container = document.getElementById('top-level-view-tabs');
            if (container) {
                container.appendChild(button);
            } else {
                // Otherwise, append to body (or choose a fallback container)
                document.body.appendChild(button);
            }
        }
        // Update the button's link URL
        button.href = linkURL;
    }

    // --- Listen for URL changes without full reloads ---
    // Override pushState/replaceState to dispatch a custom event
    (function(history) {
        const pushState = history.pushState;
        const replaceState = history.replaceState;
        history.pushState = function(state) {
            const ret = pushState.apply(history, arguments);
            window.dispatchEvent(new Event('locationchange'));
            return ret;
        };
        history.replaceState = function(state) {
            const ret = replaceState.apply(history, arguments);
            window.dispatchEvent(new Event('locationchange'));
            return ret;
        };
    })(window.history);

    // Also listen for popstate events (back/forward)
    window.addEventListener('popstate', () => {
        window.dispatchEvent(new Event('locationchange'));
    });

    // Run updateButton() whenever the URL changes
    window.addEventListener('locationchange', updateButton);

    // Initial run on page load
    updateButton();
})();