Skip to content

Instantly share code, notes, and snippets.

@nthung2112
Last active November 19, 2024 15:50
Show Gist options
  • Save nthung2112/0ff608288900c8a10baa5f589b6192a2 to your computer and use it in GitHub Desktop.
Save nthung2112/0ff608288900c8a10baa5f589b6192a2 to your computer and use it in GitHub Desktop.
Translate Extension
javascript:(function()%7Bfunction%20getSelectedText()%20%7B%0A%20%20if%20(typeof%20window.getSelection%20!%3D%20'undefined')%20%7B%0A%20%20%20%20return%20window.getSelection().toString()%3B%0A%20%20%7D%20else%20if%20(typeof%20document.selection%20!%3D%20'undefined'%20%26%26%20document.selection.type%20%3D%3D%20'Text')%20%7B%0A%20%20%20%20return%20document.selection.createRange().text%3B%0A%20%20%7D%0A%20%20return%20''%3B%0A%7D%0A%0Afunction%20doSomethingWithSelectedText(event)%20%7B%0A%20%20event.stopPropagation()%3B%0A%20%20const%20selectedText%20%3D%20getSelectedText()%3B%0A%20%20if%20(selectedText)%20%7B%0A%20%20%20%20doTranslate(selectedText)%3B%0A%20%20%7D%0A%7D%0Adocument.onmouseup%20%3D%20doSomethingWithSelectedText%3B%0Adocument.onkeyup%20%3D%20doSomethingWithSelectedText%3B%0A%0Aasync%20function%20doTranslate(selectedText)%20%7B%0A%20%20const%20res%20%3D%20await%20fetch(%0A%20%20%20%20%60https%3A%2F%2Ftranslate.googleapis.com%2Ftranslate_a%2Fsingle%3Fclient%3Dgtx%26sl%3Den%26tl%3Dvi%26hl%3Den-US%26dt%3Dt%26dt%3Dbd%26dt%3Dmd%26dt%3Dss%26dt%3Dex%26dj%3D1%26source%3Dbubble%26q%3D%24%7BselectedText%7D%60%0A%20%20)%3B%0A%20%20const%20result%20%3D%20await%20res.json()%3B%0A%20%20console.log(result)%3B%0A%20%20if%20(selectedText.split('%20').length%20%3D%3D%3D%201)%20%7B%0A%20%20%20%20const%20response%20%3D%20await%20fetch(%0A%20%20%20%20%20%20%60https%3A%2F%2Fdictionary-api.eliaschen.dev%2Fapi%2Fdictionary%2Fen%2F%24%7BselectedText%7D%60%0A%20%20%20%20)%3B%0A%20%20%20%20const%20dResult%20%3D%20await%20response.json()%3B%0A%20%20%20%20showTranslation(selectedText%2C%20result%2C%20dResult)%3B%0A%20%20%20%20return%3B%0A%20%20%7D%0A%20%20showTranslation(selectedText%2C%20result%2C%20null)%3B%0A%7D%0A%0Afunction%20showTranslation(origin%2C%20ggResult%2C%20dictResult)%20%7B%0A%20%20renderDefaultLayout()%3B%0A%20%20const%20text%20%3D%20ggResult.sentences%5B0%5D.trans%3B%0A%20%20document.getElementById('ext-origin').textContent%20%3D%20origin%3B%0A%20%20document.getElementById('ext-body').innerHTML%20%3D%20%60%22%24%7Btext%7D%22%60%3B%0A%20%20if%20(ggResult.dict)%20%7B%0A%20%20%20%20const%20dictText%20%3D%20ggResult.dict%0A%20%20%20%20%20%20.map(%0A%20%20%20%20%20%20%20%20(item)%20%3D%3E%0A%20%20%20%20%20%20%20%20%20%20%60%3Cdiv%20style%3D%22display%3Aflex%3Bgap%3A10px%3Bmargin-bottom%3A5px%3B%22%3E%3Cem%20style%3D%22color%3A%23636363%3Bflex-basis%3A80px%22%3E%24%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20item.pos%0A%20%20%20%20%20%20%20%20%20%20%7D%3C%2Fem%3E%3Cspan%3E%24%7Bitem.terms.join('%2C%20')%7D%3C%2Fdiv%3E%60%0A%20%20%20%20%20%20)%0A%20%20%20%20%20%20.join('')%3B%0A%20%20%20%20document.getElementById('ext-dict').innerHTML%20%3D%20dictText%3B%0A%20%20%7D%0A%20%20if%20(dictResult%20%26%26%20!dictResult.error)%20%7B%0A%20%20%20%20const%20phoneticItem%20%3D%20dictResult.pronunciation.find((p)%20%3D%3E%20p.lang%20%3D%3D%3D%20'us')%3B%0A%20%20%20%20if%20(phoneticItem)%20%7B%0A%20%20%20%20%20%20document.getElementById('ext-phonetic').textContent%20%3D%20phoneticItem.pron%3B%0A%20%20%20%20%20%20document.getElementById('ext-sound').style.display%20%3D%20'block'%3B%0A%20%20%20%20%20%20document.getElementById(%0A%20%20%20%20%20%20%20%20'ext-sound-audio'%0A%20%20%20%20%20%20).innerHTML%20%3D%20%60%3Csource%20src%3D%22%24%7BphoneticItem.url%7D%22%20id%3D%22ext-sound-src%22%20type%3D%22audio%2Fmp3%22%3E%60%3B%0A%20%20%20%20%7D%0A%20%20%7D%0A%20%20document.getElementById('mypopover').showPopover()%3B%0A%7D%0Afunction%20renderDefaultLayout()%20%7B%0A%20%20const%20template%20%3D%20%60%0A%3Cdiv%0A%20%20id%3D%22mypopover%22%0A%20%20popover%0A%20%20style%3D%22%0A%20%20%20%20max-width%3A%20400px%3B%0A%20%20%20%20min-width%3A%20280px%3B%0A%20%20%20%20font-weight%3A%20400%3B%0A%20%20%20%20font-size%3A%2014px%3B%0A%20%20%20%20position%3A%20fixed%3B%0A%20%20%20%20inset%3A%20unset%3B%0A%20%20%20%20top%3A%2020px%3B%0A%20%20%20%20right%3A%2020px%3B%0A%20%20%20%20border%3A%201px%20dashed%3B%0A%20%20%20%20padding%3A%2010px%3B%0A%20%20%20%20font-family%3A%20-apple-system%2C%20BlinkMacSystemFont%2C%20Roboto%2C%20Helvetica%2C%20Arial%2C%20sans-serif%3B%0A%20%20%22%0A%3E%0A%20%20%3Cdiv%0A%20%20%20%20style%3D%22%0A%20%20%20%20%20%20display%3A%20flex%3B%0A%20%20%20%20%20%20justify-content%3A%20space-between%3B%0A%20%20%20%20%20%20align-items%3A%20center%3B%0A%20%20%20%20%20%20margin-bottom%3A%205px%3B%0A%20%20%20%20%20%20font-size%3A%2016px%3B%0A%20%20%20%20%22%0A%20%20%20%20id%3D%22ext-header%22%0A%20%20%3E%0A%20%20%20%20%3Cdiv%20id%3D%22ext-origin%22%3E%3C%2Fdiv%3E%0A%20%20%20%20%3Cdiv%20style%3D%22display%3A%20flex%3B%20align-items%3A%20end%3B%20gap%3A%204px%22%3E%0A%20%20%20%20%20%20%3Cdiv%20style%3D%22%22%20id%3D%22ext-phonetic%22%3E%3C%2Fdiv%3E%0A%20%20%20%20%20%20%3Cdiv%0A%20%20%20%20%20%20%20%20id%3D%22ext-sound%22%0A%20%20%20%20%20%20%20%20style%3D%22display%3A%20none%3B%20cursor%3A%20pointer%22%0A%20%20%20%20%20%20%20%20onclick%3D%22getElementById('ext-sound-audio').load()%3BgetElementById('ext-sound-audio').play()%22%0A%20%20%20%20%20%20%3E%0A%20%20%20%20%20%20%20%20%3Cspan%3E%26%23128264%3B%3C%2Fspan%3E%0A%20%20%20%20%20%20%20%20%3Caudio%20hidden%20id%3D%22ext-sound-audio%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3Csource%20src%3D%22%22%20id%3D%22ext-sound-src%22%20type%3D%22audio%2Fmp3%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2Faudio%3E%0A%20%20%20%20%20%20%3C%2Fdiv%3E%0A%20%20%20%20%3C%2Fdiv%3E%0A%20%20%3C%2Fdiv%3E%0A%20%20%3Cdiv%3E%0A%20%20%20%20%3Cdiv%20style%3D%22font-style%3A%20italic%3B%20margin-bottom%3A%205px%22%20id%3D%22ext-body%22%3E%3C%2Fdiv%3E%0A%20%20%20%20%3Cdiv%20style%3D%22%22%20id%3D%22ext-dict%22%3E%3C%2Fdiv%3E%0A%20%20%3C%2Fdiv%3E%0A%20%20%3Cdiv%20style%3D%22margin-top%3A%205px%22%20id%3D%22ext-footer%22%3E%3C%2Fdiv%3E%0A%3C%2Fdiv%3E%0A%60%3B%0A%20%20document.getElementById('ext-root').innerHTML%20%3D%20template%3B%0A%7D%0Aif%20(!document.getElementById('ext-root'))%20%7B%0A%20%20document.body.insertAdjacentHTML('beforeend'%2C%20%60%3Cdiv%20id%3D%22ext-root%22%3Ediv%3E%60)%3B%0A%7D%0ArenderDefaultLayout()%3B%7D)()%3B
function getSelectedText() {
if (typeof window.getSelection != 'undefined') {
return window.getSelection().toString();
} else if (typeof document.selection != 'undefined' && document.selection.type == 'Text') {
return document.selection.createRange().text;
}
return '';
}
function doSomethingWithSelectedText(event) {
event.stopPropagation();
const selectedText = getSelectedText();
if (selectedText) {
doTranslate(selectedText);
}
}
document.onmouseup = doSomethingWithSelectedText;
document.onkeyup = doSomethingWithSelectedText;
async function doTranslate(selectedText) {
const res = await fetch(
`https://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl=vi&hl=en-US&dt=t&dt=bd&dt=md&dt=ss&dt=ex&dj=1&source=bubble&q=${selectedText}`
);
const result = await res.json();
console.log(result);
if (selectedText.split(' ').length === 1) {
const response = await fetch(
`https://dictionary-api.eliaschen.dev/api/dictionary/en/${selectedText}`
);
const dResult = await response.json();
showTranslation(selectedText, result, dResult);
return;
}
showTranslation(selectedText, result, null);
}
function showTranslation(origin, ggResult, dictResult) {
renderDefaultLayout();
const text = ggResult.sentences[0].trans;
document.getElementById('ext-origin').textContent = origin;
document.getElementById('ext-body').innerHTML = `"${text}"`;
if (ggResult.dict) {
const dictText = ggResult.dict
.map(
(item) =>
`<div style="display:flex;gap:10px;margin-bottom:5px;"><em style="color:#636363;flex-basis:80px">${
item.pos
}</em><span>${item.terms.join(', ')}</div>`
)
.join('');
document.getElementById('ext-dict').innerHTML = dictText;
}
if (dictResult && !dictResult.error) {
const phoneticItem = dictResult.pronunciation.find((p) => p.lang === 'us');
if (phoneticItem) {
document.getElementById('ext-phonetic').textContent = phoneticItem.pron;
document.getElementById('ext-sound').style.display = 'block';
document.getElementById(
'ext-sound-audio'
).innerHTML = `<source src="${phoneticItem.url}" id="ext-sound-src" type="audio/mp3">`;
}
}
document.getElementById('mypopover').showPopover();
}
function renderDefaultLayout() {
const template = `
<div
id="mypopover"
popover
style="
max-width: 400px;
min-width: 280px;
font-weight: 400;
font-size: 14px;
position: fixed;
inset: unset;
top: 20px;
right: 20px;
border: 1px dashed;
padding: 10px;
font-family: -apple-system, BlinkMacSystemFont, Roboto, Helvetica, Arial, sans-serif;
"
>
<div
style="
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 5px;
font-size: 16px;
"
id="ext-header"
>
<div id="ext-origin"></div>
<div style="display: flex; align-items: end; gap: 4px">
<div style="" id="ext-phonetic"></div>
<div
id="ext-sound"
style="display: none; cursor: pointer"
onclick="getElementById('ext-sound-audio').load();getElementById('ext-sound-audio').play()"
>
<span>&#128264;</span>
<audio hidden id="ext-sound-audio">
<source src="" id="ext-sound-src" type="audio/mp3" />
</audio>
</div>
</div>
</div>
<div>
<div style="font-style: italic; margin-bottom: 5px" id="ext-body"></div>
<div style="" id="ext-dict"></div>
</div>
<div style="margin-top: 5px" id="ext-footer"></div>
</div>
`;
document.getElementById('ext-root').innerHTML = template;
}
if (!document.getElementById('ext-root')) {
document.body.insertAdjacentHTML('beforeend', `<div id="ext-root">div>`);
}
renderDefaultLayout();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment