您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Use the VajehYab.com website as a dictionary. Just double-click or select any text, and the results will appear as a smooth and light pop-up. It is a translator that you can enable/disable by using Ctrl + Alt + Q.
// ==UserScript== // @name Vajehyab Assistan // @name:fa دستیار واژهیاب // @version 0.11 // @author Amir // @description Use the VajehYab.com website as a dictionary. Just double-click or select any text, and the results will appear as a smooth and light pop-up. It is a translator that you can enable/disable by using Ctrl + Alt + Q. // @description:fa کلمه انتخاب شده را در سایت واژهیاب جستجو و نمایش میدهد // @namespace amm1rr // @match https://twitter.com/* // @include * // @homepage https://github.com/Amm1rr/Vajehyab-Assistant // @icon https://vajehyab.com/assets/icons/180.png // @source https://github.com/Amm1rr/Vajehyab-Assistant // @supportURL https://github.com/Amm1rr/Vajehyab-Assistant/issues // @require https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js // @require https://code.jquery.com/jquery-3.6.0.slim.min.js // @resource https://github.com/Amm1rr/Vajehyab-Assistant/raw/main/ref/style-minimal.min.css // @grant GM_xmlhttpRequest // @grant GM_getResourceText // @connect vajehyab.com // @license MIT // ==/UserScript== // window.getSelection().toString() // window.document.body.addEventListener("mouseup", translate, false); window.document.body.addEventListener("click", translate, false); window.document.body.addEventListener("keyup", toggleVajehyab, false); var toggle = true; // Ctrl + Alt + Q => Toggle Enable\Disable Vajehyab Assistant function toggleVajehyab(e) { if (e.which == 81 && e.altKey && e.ctrlKey) { if (toggle) { window.document.body.removeEventListener("click", translate, false); toggle = false; } else { window.document.body.addEventListener("click", translate, false); toggle = true; } } } function translate(e) { // remove previous .vajehPopup if exists PopupsRemover(); // console.log("translate start"); var selectObj = document.getSelection(); // if #text node if (selectObj.anchorNode && selectObj.anchorNode.nodeType == 3) { //GM_log(selectObj.anchorNode.nodeType.toString()); var word = selectObj.toString(); if (word == "") { return; } // linebreak wordwrap, optimize for pdf.js word = word.replace("-\n", ""); // multiline selection, optimize for pdf.js word = word.replace("\n", " "); //console.log("word:", word); var ts = new Date().getTime(); //console.log("time: ", ts); var mx = e.clientX; var my = e.clientY; GetTranslate(word, ts); } function PopupsRemover() { // remove previous .vajehPopup if exists var previous = document.querySelector(".vajehPopup"); while (previous) { document.body.removeChild(previous); previous = document.querySelector(".vajehPopup"); } previous = document.querySelector("#vajehiframe"); while (previous) { document.body.removeChild(previous); previous = document.querySelector("#vajehiframe"); } } // function calculatePosition(x, y, popup) { // const pos = {}; // const margin = 5; // const anchor = 10; // const outerWidth = $(popup).outerWidth(); // const outerHeight = $(popup).outerHeight(); // // show popup to the right of the word if it fits into window this way // if (x + anchor + outerWidth + margin < $(window).width()) { // pos.x = x + anchor; // } // // show popup to the left of the word if it fits into window this way // else if (x - anchor - outerWidth - margin > 0) { // pos.x = x - anchor - outerWidth; // } // // show popup at the very left if it is not wider than window // else if (outerWidth + margin * 2 < $(window).width()) { // pos.x = margin; // } // // resize popup width to fit into window and position it the very left of the window // else { // const non_content_x = outerWidth - $(popup).width(); // $(popup).width($(window).width() - margin * 2 - non_content_x); // pos.x = margin; // } // // show popup above the word if it fits into window this way // if (y - anchor - outerHeight - margin > 0) { // pos.y = y - anchor - outerHeight; // } // // show popup below the word if it fits into window this way // else if (y + anchor + outerHeight + margin < $(window).height()) { // pos.y = y + anchor; // } // // show popup at the very top of the window // else { // pos.y = margin; // } // return pos; // } function calculatePosition(x, y, popup) { const pos = {}; const margin = 5; const anchor = 10; const outerWidth = $(popup).outerWidth(); const outerHeight = $(popup).outerHeight(); // show popup to the right of the word if it fits into window this way if (x + anchor + outerWidth + margin < $(window).width()) { pos.x = x + anchor; } // show popup to the left of the word if it fits into window this way else if (x - anchor - outerWidth - margin > 0) { pos.x = x - anchor - outerWidth; } // show popup at the very left if it is not wider than window else if (outerWidth + margin * 2 < $(window).width()) { pos.x = margin; } // resize popup width to fit into window and position it the very left of the window else { const non_content_x = outerWidth - $(popup).width(); $(popup).width($(window).width() - margin * 2 - non_content_x); pos.x = margin; } // show popup above the word if it fits into window this way if (y - anchor - outerHeight - margin > 0) { pos.y = y - anchor - outerHeight; } // show popup below the word if it fits into window this way else if (y + anchor + outerHeight + margin < $(window).height()) { pos.y = y + anchor; } // show popup at the very top of the window else { pos.y = margin; } const scrollBarWidth = $(window).width() - $(document).width(); if (scrollBarWidth > 0) { margin += scrollBarWidth; } if (window.orientation === "landscape") { const temp = pos.x; pos.x = pos.y; pos.y = temp; } if (pos.x === x + anchor) { const scrollBarLeft = $(window).scrollLeft(); if (scrollBarLeft > x) { pos.x -= scrollBarLeft; } } return pos; } function getParameter(jsonData, parameter, wrd) { let jsdata = JSON.parse(jsonData); let data; try { data = jsdata.props.pageProps.fallback[wrd + ":"].data; } catch (error) { return undefined; } if (typeof data === "undefined") { return undefined; } switch (parameter) { case "Query": return data.Query ? data.Query : undefined; case "Id": return data.Id ? data.Id : undefined; case "Exact": { const exact = []; if (data.WordBox) { // console.log(data.WordBox); let nullCount = 0; let totalCount = 0; for (const dictionaryName in data.WordBox) { totalCount++; if (data.WordBox.hasOwnProperty(dictionaryName)) { const dictionary = data.WordBox[dictionaryName]; if (dictionary && dictionary.dictionary) { const dicname = dictionary.dictionary; // console.log(`Title for ${dictionaryName}: ${dicname}`); const dataobjEntry = { dictionary: dicname, dictionary_id: dictionary.dictionary_id, id: dictionary.id, score: dictionary.score, slug: dictionary.slug, summary: dictionary.description, title: dictionary.title, }; // Add dataobjEntry to eact array exact.push(dataobjEntry); } else { //// Count null dictionary.id values // if (dictionary.id === null) { nullCount++; // } // Check if more than half of dictionary.id values are null } // switch (dictionaryName) { // // case "Query": // case "Amid": // exact.push(); // // case "Motaradef": // // case "Sereh": // // case "En2fa": // // case "Fa2en": // } } } if (nullCount > totalCount / 2) { if (data.Exact) { for (const doc of data.Exact.Docs) { exact.push(doc); } } if (exact.length == 0) { const similar = []; if (data.Similar) { for (const doc of data.Similar.Docs) { exact.push(doc); } } } } return exact; } else { if (data.Exact) { for (const doc of data.Exact.Docs) { exact.push(doc); } } if (exact.length == 0) { const similar = []; if (data.Similar) { for (const doc of data.Similar.Docs) { exact.push(doc); } } } return exact; } } case "Similar": return data.Similar ? data.Similar : undefined; case "Text": return data.Text ? data.Text : undefined; case "Prefix": return data.Prefix ? data.Prefix : undefined; case "Mlt": return data.Mlt ? data.Mlt : undefined; case "Spell": return data.Spell ? data.Spell : undefined; case "Random": return data.Random ? data.Random : undefined; case "WordBox": return data.WordBox ? data.WordBox : undefined; default: return undefined; } } function popup(mx, my, result, wrd) { PopupsRemover(); /* HTML Parse */ const parser = new DOMParser(); const page = parser.parseFromString(result, "text/html"); const jsontag = page.querySelector("#__NEXT_DATA__"); const json = jsontag.innerHTML; const res = getParameter(json, "Exact", wrd); if ( typeof res === "undefined" || !Array.isArray(res) || res.length < 1 || typeof res[0] === "undefined" || res[0].length < 2 ) { console.log("یافت نشد"); return; } // // Move amid's dictionary first. // res.sort((a, b) => { // if (a.dictionary === "amid") return -1; // if (b.dictionary === "amid") return 1; // return a.dictionary.localeCompare(b.dictionary); // }); // Mapping of English dictionary names to Persian Names const dictionaryNames = { amid: "امید", dehkhoda: "دهخدا", moein: "معین", isfahani: "اصفهانی", mazani: "مازنی", fa2en: "انگلیسی", motaradef: "مترادف", fa2tr: "ترکی", fa2ar: "عربی", en2fa: "EN", ar2fa: "AR", sereh: "سِرِه", wiki: "ویکی", }; // console.log(res); // console.log(res[0].title); /* HTML Parse */ var iframe = document.createElement("iframe"); iframe.src = "about:blank"; iframe.id = "vajehiframe"; // main window // first insert into dom then there is offsetHeight!IMPORTANT! // document.body.appendChild(vajehWindow); document.body.appendChild(iframe); var direc = "rtl"; var html = "<html><head><title>واژهیاب فارسی</title>" + ' </head><body style="padding-bottom: 0px; direction:rtl; padding-right:15px;">'; for (let i = 0; i < res.length; i++) { const persianDictionary = dictionaryNames[res[i].dictionary] || res[i].dictionary; if (persianDictionary == "انگلیسی" || persianDictionary == "ترکی") { direc = "ltr"; } else { direc = "rtl"; } html += "<header><div style='float:right;color:rgb(158, 63, 26);'>" + res[i].title + "</div><div style='float:left;font-size:12px;color:green;'>" + persianDictionary + "</div></header><br><hr>"; html += "<div style='direction:" + direc + "; font-size:14px;'>" + res[i].summary + "</div><br>"; } html += "</body></html>"; iframe.srcdoc = html; let vajehWindow = iframe; vajehWindow.style.color = "blue"; vajehWindow.style.textAlign = "right"; vajehWindow.style.display = "block"; vajehWindow.style.position = "fixed"; vajehWindow.style.background = "lightblue"; vajehWindow.style.borderRadius = "5px"; vajehWindow.style.boxShadow = "0 0 5px 0"; vajehWindow.style.opacity = "0.9"; vajehWindow.style.width = "20%"; vajehWindow.style.overflowWrap = "break-word"; vajehWindow.style.left = mx - 40 + "px"; // vajehWindow.style.dir = "rtl"; var cssstyle = { "overflow-y": "scroll", height: "40%", }; Object.assign(vajehWindow.style, cssstyle); var pos = calculatePosition(mx, my, vajehWindow); if (pos.x >= window.innerWidth || 500 >= window.innerWidth) { vajehWindow.style.left = "20px"; vajehWindow.style.width = window.innerWidth - 55 + "px"; vajehWindow.style.height = "25%"; } else if (1000 >= window.innerWidth) { vajehWindow.style.width = "30%"; vajehWindow.style.height = "25%"; } else { vajehWindow.style.left = pos.x; } if (pos.y + vajehWindow.offsetHeight + 10 >= window.innerHeight) { vajehWindow.style.bottom = "10px"; } else { vajehWindow.style.top = pos.y + 10 + "px"; } if (my + vajehWindow.offsetHeight + 10 >= window.innerHeight) { //vajehWindow.style.bottom = "10px"; //console.log("Height bottom"); } else { vajehWindow.style.top = my + 15 + "px"; //console.log("Height top"); } if (pos.x + vajehWindow.offsetWidth + 55 >= window.innerWidth) { vajehWindow.style.left = window.innerWidth - vajehWindow.offsetWidth - 20 + "px"; } vajehWindow.style.padding = "5px"; vajehWindow.style.zIndex = "999999"; } function GetTranslate(wrd, ts) { // var reqUrl = `https://www.vajehyab.com/?q=${word}&d=en&_=1617191412351&ts=${ts}`; // var reqUrl = `https://www.vajehyab.com/?q=${word}&d=en`; let trimWord = wrd.trim(); let reqUrl = `https://vajehyab.com/?q=${trimWord}`; //console.log("request url: ", reqUrl); let ret = GM.xmlHttpRequest({ method: "GET", url: reqUrl, headers: { Accept: "application/json" }, // can be omitted... onreadystatechange: function (res) { //console.log("Request state changed to: " + res.readyState); }, onload: function (res) { let retContent = res.response; // console.log(retContent); // const parser = new DOMParser(); // retContent = parser.parseFromString(retContent, 'text/html'); popup(mx, my, retContent, trimWord); }, onerror: function (res) { console.log("error"); }, }); } }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址