// ==UserScript== // @name Ovearleaf-BibTex // @namespace com.jw23.overleaf // @version 0.1.1 // @description the script will make you search bibtex easily in overleaf // @author jw23 // @match https://www.overleaf.com/project/* // @require https://cdn.jsdelivr.net/npm/@floating-ui/core@1.6.8 // @require https://cdn.jsdelivr.net/npm/@floating-ui/dom@1.6.12 // @require https://cdn.jsdelivr.net/npm/simple-notify@1.0.6/dist/simple-notify.min.js // @resource notifycss https://cdn.jsdelivr.net/npm/simple-notify/dist/simple-notify.css // @grant GM_setClipboard // @grant GM_xmlhttpRequest // @grant GM_getResourceText // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // @license MIT // @downloadURL none // ==/UserScript== /* ==UserConfig== configure: origin: title: Orgin description: choose google scholar or its mirror type: select bind: $origins ==/UserConfig== */ // configure the origin const origins = ["https://scholar.google.com.hk", "https://scholar.lanfanshu.cn", "https://xs.vygc.top"] let oldOrigins = GM_getValue("origins", []); const mergedArray = [...new Set([...origins, ...oldOrigins])]; GM_setValue("origins", mergedArray) // If you are not using scriptable cat, just change the https://scholar.google.com.hk let currentOrigin = () => { return GM_getValue("configure.origin", "https://scholar.google.com.hk") } let scholarIcon = ``; let showBox = false; let scholarURL = query => `${currentOrigin()}/scholar?hl=zh-CN&as_sdt=0%2C5&q=${query}&oq=a`; let scholarRefPageURL = id => `${currentOrigin()}/scholar?q=info:${id}:scholar.google.com/&output=cite&scirp=1&hl=zh-CN`; (function () { 'use strict'; GM_addStyle(GM_getResourceText('notifycss')) injectScript() setInterval(() => { if (!document.getElementById('toggleIcon')) { injectScript() } }, 2000) })(); function injectScript() { // query element by className waitUtil('div.ol-cm-toolbar-button-group.ol-cm-toolbar-end', el => { let iconBox = createToggleIcon(); el.appendChild(iconBox); let popupBox = createBox(); let oldPopup = document.querySelector("#popup"); // toggle the search box with the icon. if (oldPopup) { popupBox = oldPopup; } document.body.appendChild(popupBox) popupBox.addEventListener('keydown', env => { if (env.key === 'Enter') { queryArticle() } }) FloatingUIDOM.autoUpdate(iconBox, popupBox, () => { FloatingUIDOM.computePosition(iconBox, popupBox, { middleware: [FloatingUICore.shift(), FloatingUICore.flip(), FloatingUICore.offset(6)], }).then(({ x, y }) => { Object.assign(popupBox.style, { top: `${y}px`, left: `${x}px` }) }) }) iconBox.onclick = (ev) => { if (showBox) { showBox = false; popupBox.style.display = 'none'; } else { showBox = true; popupBox.style.display = 'block'; } } let searchIcon = document.getElementById('search-word'); let content = document.getElementById("search-content"); content.onclick = (env) => { if (env.target.className == 'scholar-data') { let id = env.target.getAttribute("data-cid"); getBibTex(id).then(bib => { new Notify({ status: 'success', title: 'Copy successfully', text: 'Bib has been copied to clipboard', effect: 'slide', type: 'filled' }) GM_setClipboard(bib); }).catch(_ => { new Notify({ status: 'error', title: "Copy failed", text: "Failed to get bib tex", effect: "slide", type: "filled" }) }) } } searchIcon.onclick = () => { queryArticle() } }) } function queryArticle() { let content = document.getElementById("search-content"); content.innerHTML = "Loading......" let word = document.querySelector('input.search-input').value; getArticleIDList(word).then(async lists => { let searchText = ""; lists.forEach((article) => { let articleId = article.id; searchText += scholarContent(`${article.title}@${article.author}`, articleId) }) return searchText }).then(text => { content.innerHTML = text; }); } function waitUtil(el, callback, timeout = 6000) { let query = setInterval(() => { let target = document.querySelector(el) if (target) { // 如果找到了目标元素,则清除查询任务 clearInterval(query) callback(target) } }) // 超时则清除查询任务 setTimeout(() => { clearInterval(query) }, timeout) } function createToggleIcon() { let iconBox = document.createElement('div'); iconBox.className = 'ol-cm-toolbar-button'; iconBox.style.display = 'flex'; iconBox.style.justifyContent = 'center'; iconBox.style.alignItems = 'center'; iconBox.id = "toggleIcon" iconBox.innerHTML = scholarIcon; return iconBox; } // create box to show search box and result box function createBox() { let box = document.createElement('div'); box.id = "popup" box.style = 'width:265px;background:#eef;padding:5px;border:1px solid #ccc;border-radius:5px;position: absolute;display:none;top:0px;left:0px'; box.innerHTML = `