Greasy Fork

Jump to ArXiv

Add a button to jump from alphaxiv.org to arxiv.org

当前为 2025-06-02 提交的版本,查看 最新版本

// ==UserScript==
// @name         Jump to ArXiv
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Add a button to jump from alphaxiv.org to arxiv.org
// @author       You
// @match        https://www.alphaxiv.org/abs/*
// @grant        none
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    function addArxivButton() {
        // 使用更精确的选择器查找目标div容器
        // 优先使用最具体的选择器,然后使用备用选择器
        let targetDiv = document.querySelector('[data-sentry-component="RightSection"] .flex.items-center.space-x-2');

        // 备用选择器1:通过包含下载按钮的div来定位
        if (!targetDiv) {
            const downloadButton = document.querySelector('button[aria-label="Download from arXiv"]');
            if (downloadButton) {
                targetDiv = downloadButton.closest('.flex.items-center.space-x-2');
            }
        }

        // 备用选择器2:通过包含thumbs-up的按钮来定位
        if (!targetDiv) {
            const thumbsUpButton = document.querySelector('svg.lucide-thumbs-up');
            if (thumbsUpButton) {
                targetDiv = thumbsUpButton.closest('.flex.items-center.space-x-2');
            }
        }

        // 备用选择器3:通过包含bookmark的div来定位
        if (!targetDiv) {
            const bookmarkDiv = document.querySelector('[data-sentry-component="PaperFeedBookmarks"]');
            if (bookmarkDiv) {
                targetDiv = bookmarkDiv.closest('.flex.items-center.space-x-2');
            }
        }

        // 备用选择器4:最后的通用选择器
        if (!targetDiv) {
            targetDiv = document.querySelector('.flex.items-center.space-x-2');
        }

        if (!targetDiv) {
            console.log('Target div not found, retrying...');
            return false;
        }

        // 检查是否已经添加了按钮
        if (targetDiv.querySelector('.arxiv-jump-button')) {
            return true;
        }

        // 获取当前URL中的论文ID
        const currentUrl = window.location.href;
        const match = currentUrl.match(/\/abs\/(.+)$/);

        if (!match) {
            console.log('Paper ID not found in URL');
            return true;
        }

        const paperId = match[1];
        const arxivUrl = `https://www.arxiv.org/abs/${paperId}`;

        // 创建ArXiv跳转按钮
        const arxivButton = document.createElement('button');
        arxivButton.className = 'arxiv-jump-button inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm ring-offset-white transition-all duration-200 outline-hidden focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50 dark:ring-offset-neutral-950 hover:bg-[#9a20360a] hover:text-custom-red dark:text-white dark:hover:bg-custom-red/25 enabled:active:ring-2 enabled:active:ring-[#9a20360a] size-10 rounded-full! h-8 w-8';
        arxivButton.setAttribute('aria-label', 'Jump to ArXiv');
        arxivButton.setAttribute('title', 'Jump to ArXiv');

        // 添加ArXiv图标 (使用外部链接图标)
        arxivButton.innerHTML = `
            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-external-link size-4" aria-hidden="true">
                <path d="M15 3h6v6"></path>
                <path d="M10 14 21 3"></path>
                <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path>
            </svg>
        `;

        // 添加点击事件
        arxivButton.addEventListener('click', function(e) {
            e.preventDefault();
            window.open(arxivUrl, '_blank');
        });

        // 在div的第一个位置插入按钮
        targetDiv.insertBefore(arxivButton, targetDiv.firstChild);

        console.log('ArXiv jump button added successfully');
        return true;
    }

    // 页面加载完成后尝试添加按钮
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', function() {
            setTimeout(addArxivButton, 100);
        });
    } else {
        // 如果页面已经加载完成,立即尝试添加
        setTimeout(addArxivButton, 100);
    }

    // 使用MutationObserver监听DOM变化,以防按钮容器是动态加载的
    const observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
                // 延迟执行,确保DOM完全更新
                setTimeout(function() {
                    if (addArxivButton()) {
                        observer.disconnect(); // 成功添加按钮后停止观察
                    }
                }, 100);
            }
        });
    });

    // 开始观察DOM变化
    observer.observe(document.body, {
        childList: true,
        subtree: true
    });

    // 5秒后停止观察(防止无限观察)
    setTimeout(function() {
        observer.disconnect();
    }, 5000);

})();