您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Converts DOI links and plain text DOIs directly to Google Scholar links
// ==UserScript== // @name DOI to Google Scholar // @namespace https://violentmonkey.github.io/ // @version 1.6 // @description Converts DOI links and plain text DOIs directly to Google Scholar links // @author Bui Quoc Dung // @match *://*/* // @exclude *://scholar.google.com/* // @license AGPL-3.0-or-later // @grant none // ==/UserScript== (function () { 'use strict'; const SCHOLAR_URL = 'https://scholar.google.com/scholar?hl=en&as_sdt=0%2C5&q='; const DOI_REGEX = /(?:\b|^|\s)(10\.\d{4,}\/[^\s"'<>\]}]+)/gi; /** * Chuyển một DOI (URL hoặc plain text) thành link Google Scholar */ function convertDOIToScholarURL(doi) { const cleanDOI = doi.replace(/[.,;:]$/, ''); const doiPart = cleanDOI.startsWith('http') ? cleanDOI.split('doi.org/')[1] || cleanDOI : cleanDOI; return `${SCHOLAR_URL}${encodeURIComponent(doiPart)}`; } /** * Xử lý các liên kết DOI, thêm sự kiện click để mở trên Google Scholar trong tab mới */ function handleDOILinks() { const doiLinkSelectors = [ 'a[href*="doi.org/"]', 'a[href*="dx.doi.org/"]' ].join(','); document.querySelectorAll(doiLinkSelectors).forEach(link => { if (!link.dataset.scholarProcessed) { link.dataset.scholarProcessed = 'true'; link.addEventListener('click', e => { e.preventDefault(); window.open(convertDOIToScholarURL(link.href), '_blank'); }); } }); } /** * Tìm DOI trong text node và chuyển thành liên kết Google Scholar (mở tab mới) */ function convertPlainTextDOIsToLinks() { const walker = document.createTreeWalker( document.body, NodeFilter.SHOW_TEXT, null, false ); const nodesToProcess = []; const safeTestRegex = /(?:\b|^|\s)(10\.\d{4,}\/[^\s"'<>\]}]+)/i; while (walker.nextNode()) { const node = walker.currentNode; if (safeTestRegex.test(node.textContent)) { nodesToProcess.push(node); } } nodesToProcess.forEach(node => { const fragment = document.createDocumentFragment(); const text = node.textContent; let lastIndex = 0; let match; DOI_REGEX.lastIndex = 0; while ((match = DOI_REGEX.exec(text)) !== null) { if (match.index > lastIndex) { fragment.appendChild(document.createTextNode(text.substring(lastIndex, match.index))); } const link = document.createElement('a'); link.href = convertDOIToScholarURL(match[1]); link.target = '_blank'; // mở trong tab mới link.textContent = match[1]; link.style.color = '#1a0dab'; link.style.textDecoration = 'underline'; fragment.appendChild(link); lastIndex = match.index + match[0].length; } if (lastIndex < text.length) { fragment.appendChild(document.createTextNode(text.substring(lastIndex))); } node.replaceWith(fragment); }); } /** * Debounce để tránh xử lý quá nhiều khi DOM thay đổi liên tục */ function debounce(func, wait) { let timeout; return function executedFunction(...args) { clearTimeout(timeout); timeout = setTimeout(() => func(...args), wait); }; } /** * Xử lý cả liên kết và text chứa DOI */ function processDOIs() { handleDOILinks(); convertPlainTextDOIsToLinks(); } /** * Theo dõi các thay đổi động trên trang */ function observeDynamicChanges() { const debouncedProcess = debounce(processDOIs, 250); const observer = new MutationObserver(debouncedProcess); observer.observe(document.body, { childList: true, subtree: true }); } /** * Khởi chạy script */ function init() { processDOIs(); observeDynamicChanges(); } init(); })();