OptiTranslate for iOS
当前为
// ==UserScript==
// @name OptiTranslate
// @namespace com.vonkleist.optitranslate
// @version 3.3
// @description OptiTranslate for iOS
// @author VonKleistL
// @match *://*/*
// @run-at document-end
// @grant none
// @license MIT
// ==/UserScript==
(function() {
'use strict';
const TARGET_LANG = 'en';
if (window.location.hostname.match(/(translate|googleusercontent|yandex)/)) return;
const pageLang = document.documentElement.lang || navigator.language;
if (pageLang && pageLang.toLowerCase().startsWith(TARGET_LANG)) return;
if (document.body.innerText.length < 50) return;
// --- HOST ---
const host = document.createElement('div');
host.id = 'opti-translate-host';
document.documentElement.appendChild(host);
const shadow = host.attachShadow({mode: 'open'});
// --- STYLES ---
const style = document.createElement('style');
style.textContent = `
:host {
all: initial;
z-index: 2147483647;
position: fixed;
bottom: 30px;
right: 20px;
font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", sans-serif;
pointer-events: none;
}
.opti-panel {
background: rgba(20, 20, 20, 0.95);
backdrop-filter: blur(25px);
-webkit-backdrop-filter: blur(25px);
border: 1px solid rgba(255, 255, 255, 0.15);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
border-radius: 24px;
padding: 8px;
display: flex;
gap: 8px;
transform: translateY(120%);
opacity: 0;
transition: transform 0.4s cubic-bezier(0.2, 1, 0.2, 1), opacity 0.3s;
pointer-events: auto;
}
.opti-panel.visible {
transform: translateY(0);
opacity: 1;
}
.opti-btn {
border: none;
padding: 0 16px;
height: 40px;
border-radius: 18px;
color: #fff;
font-size: 14px;
font-weight: 700;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
#btn-google {
background: #4285F4;
box-shadow: 0 2px 10px rgba(66, 133, 244, 0.3);
}
#btn-yandex {
background: #FC3F1D;
box-shadow: 0 2px 10px rgba(252, 63, 29, 0.3);
}
.opti-close {
width: 40px;
height: 40px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.1);
border: none;
color: rgba(255, 255, 255, 0.5);
font-size: 20px;
display: flex;
align-items: center;
justify-content: center;
}
`;
shadow.appendChild(style);
// --- BODY ---
const panel = document.createElement('div');
panel.className = 'opti-panel';
panel.innerHTML = `
<button class="opti-btn" id="btn-google">Google</button>
<button class="opti-btn" id="btn-yandex">Yandex</button>
<button class="opti-close" id="do-close">×</button>
`;
shadow.appendChild(panel);
// --- LOGIC ---
function forceOpen(url) {
const a = document.createElement('a');
a.href = url;
a.target = '_blank';
a.rel = 'noopener noreferrer';
a.style.display = 'none';
document.body.appendChild(a);
a.click();
setTimeout(() => a.remove(), 100);
closePanel();
}
shadow.getElementById('btn-google').onclick = (e) => {
e.preventDefault();
const url = encodeURIComponent(window.location.href);
// CHANGED: Removed /m, reverted to /translate with explicit webapp client
forceOpen(`https://translate.google.com/translate?sl=auto&tl=${TARGET_LANG}&u=${url}&client=webapp`);
};
shadow.getElementById('btn-yandex').onclick = (e) => {
e.preventDefault();
const url = encodeURIComponent(window.location.href);
forceOpen(`https://translate.yandex.com/translate?url=${url}&lang=auto-en`);
};
shadow.getElementById('do-close').onclick = () => closePanel();
function closePanel() {
panel.classList.remove('visible');
setTimeout(() => host.remove(), 500);
}
setTimeout(() => panel.classList.add('visible'), 500);
})();