xd2shuffle

ARS to USD converter for shuffle.com (text + numbers) - NO SPACE FIX

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

You will need to install an extension such as Tampermonkey to install this script.

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

Advertisement:

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

Advertisement:

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         xd2shuffle
// @namespace    http://tampermonkey.net/
// @version      7.7.7.9
// @description  ARS to USD converter for shuffle.com (text + numbers) - NO SPACE FIX
// @author       fusi | @loficat on tg | codedfusi on github | Modified by user
// @match        *://*.shuffle.com/*
// @grant        none
// @run-at       document-start
// @license      MIT
// ==/UserScript==

(function () {
    // ==========================================
    // SET THE EXCHANGE RATE HERE
    // Example: 1 USD = 1400 ARS
    // ==========================================
    const USD_RATE = 1400;  // <-- CHANGE THIS NUMBER to the current rate

    // Store modified nodes to avoid double processing
    const processedTextNodes = new WeakSet();
    const processedImages = new WeakSet();

    // Helper: Convert ARS number string to USD formatted string (NO SPACE AFTER $)
    function convertARStextToUSD(text) {
        // Match numbers that could be ARS amounts (including commas and decimals)
        const arsNumberPattern = /(\b[\d,]+(?:\.\d+)?\b)|(\b[\d.]+(?:,\d+)?\b)/g;

        return text.replace(arsNumberPattern, (match) => {
            // Clean the match: remove commas (for US style) or dots (for EU style)
            let cleanNumber = match.replace(/,/g, '');
            // For EU style like 1.234,56 -> replace dot with empty and comma with dot
            if (cleanNumber.includes('.') && cleanNumber.includes(',')) {
                cleanNumber = cleanNumber.replace(/\./g, '').replace(/,/, '.');
            } else if (cleanNumber.includes(',')) {
                // If only commas, treat as decimal separator (EU)
                cleanNumber = cleanNumber.replace(/,/, '.');
            }

            const arsValue = parseFloat(cleanNumber);
            if (isNaN(arsValue)) return match;

            const usdValue = arsValue / USD_RATE;
            // Format USD with 2 decimal places, using US notation
            // toLocaleString can add spaces? No, but we'll force no space by joining directly.
            // Use toFixed to avoid any automatic spacing issues.
            let formattedUsd = usdValue.toFixed(2);
            // Add commas for thousands separators manually (simple version)
            // This adds commas but ensures NO SPACE.
            let parts = formattedUsd.split('.');
            parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
            return parts.join('.');
        });
    }

    function processTextNode(node) {
        if (node.nodeType === 3 && node.nodeValue && !processedTextNodes.has(node)) {
            let original = node.nodeValue;
            let modified = false;
            let newValue = original;

            // Replace ARS symbol with $ - ensure no space is added
            if (newValue.includes("ARS")) {
                // Replace ARS with $, and also remove any space that might be between the $ and the number
                newValue = newValue.replace(/ARS\s*/g, "$");
                modified = true;
            }

            // Convert ARS numbers to USD (if text contains numbers)
            if (/\d/.test(newValue)) {
                // Temporarily protect the $ so it doesn't get a space added
                let protectedValue = newValue;
                const converted = convertARStextToUSD(protectedValue);
                if (converted !== protectedValue) {
                    // Now, ensure that if a $ is present, there is NO space after it
                    // This regex looks for $ followed by any whitespace and then a number
                    let finalConversion = converted.replace(/\$\s+(\d)/g, '$$$1');
                    newValue = finalConversion;
                    modified = true;
                }
            }

            // Final cleanup: ensure no space after any $ sign
            newValue = newValue.replace(/\$\s+/g, '$');

            if (modified) {
                node.nodeValue = newValue;
                processedTextNodes.add(node);
            }
        }
    }

    function processImageElement(el) {
        if (el.nodeType === 1 && el.hasAttribute("src") && !processedImages.has(el)) {
            const src = el.getAttribute("src");
            if (src && src.includes("/icons/fiat/ARS.svg")) {
                el.setAttribute("src", src.replace("/icons/fiat/ARS.svg", "/icons/fiat/USD.svg"));
                processedImages.add(el);
            }
        }
    }

    function walkAndProcess(root) {
        if (!root) return;

        // Process text nodes
        const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null, false);
        let node;
        while ((node = walker.nextNode())) {
            processTextNode(node);
        }

        // Process image elements
        const images = root.querySelectorAll('img[src*="/icons/fiat/ARS.svg"]');
        images.forEach(img => processImageElement(img));
    }

    // MutationObserver callback to handle dynamically added content
    function onMutation(mutations) {
        for (const mutation of mutations) {
            if (mutation.type === 'childList') {
                for (const addedNode of mutation.addedNodes) {
                    if (addedNode.nodeType === 1) {
                        walkAndProcess(addedNode);
                    } else if (addedNode.nodeType === 3) {
                        processTextNode(addedNode);
                    }
                }
            }
        }
    }

    // Start the script once the DOM is ready
    document.addEventListener("DOMContentLoaded", () => {
        walkAndProcess(document.body);

        const observer = new MutationObserver(onMutation);
        observer.observe(document.body, {
            childList: true,
            subtree: true
        });
    });
})();