Add files via upload

This commit is contained in:
sienori 2017-09-25 00:06:58 +09:00 committed by GitHub
parent 7b49200253
commit 31382a84a8
22 changed files with 746 additions and 44 deletions

View file

@ -0,0 +1,29 @@
{
"extName": {
"message": "Simple Translate"
},
"extDescription": {
"message": "View translations easily as you browse the web."
},
"initialTextArea":{
"message": "Enter text"
},
"showLink":{
"message": "Translate this page"
},
"LangListLabel":{
"message":"Destination language"
},
"langList":{
"message":"<option value=\"is\">Icelandic</option><option value=\"ga\">Irish</option><option value=\"az\">Azerbaijani</option><option value=\"af\">Afrikaans</option><option value=\"am\">Amharic</option><option value=\"ar\">Arabic</option><option value=\"sq\">Albanian</option><option value=\"hy\">Armenian</option><option value=\"it\">Italian</option><option value=\"yi\">Yiddish</option><option value=\"ig\">Igbo</option><option value=\"id\">Indonesian</option><option value=\"cy\">Welsh</option><option value=\"uk\">Ukrainian</option><option value=\"uz\">Uzbek</option><option value=\"ur\">Urdu</option><option value=\"et\">Estonian</option><option value=\"eo\">Esperanto</option><option value=\"nl\">Dutch</option><option value=\"kk\">Kazakh</option><option value=\"ca\">Catalan</option><option value=\"gl\">Galician</option><option value=\"kn\">Kannada</option><option value=\"el\">Greek language</option><option value=\"ky\">Kirghiz</option><option value=\"gu\">Gujarati</option><option value=\"km\">Khmer</option><option value=\"ku\">Kurdish</option><option value=\"hr\">Croatian</option><option value=\"xh\">Xosa</option><option value=\"co\">Corsican</option><option value=\"sm\">Samoan</option><option value=\"jv\">Javanese</option><option value=\"ka\">Georgian</option><option value=\"sn\">Shona</option><option value=\"sd\">Sindhi</option><option value=\"si\">Sinhala</option><option value=\"sv\">Swedish</option><option value=\"zu\">Zulu</option><option value=\"gd\">Scottish Gaelic</option><option value=\"es\">Spanish</option><option value=\"sk\">Slovak</option><option value=\"sl\">Slovenian</option><option value=\"sw\">Swahili</option><option value=\"su\">Sundanese</option><option value=\"ceb\">Cebuano</option><option value=\"sr\">Serbian</option><option value=\"sx\">Sotho</option><option value=\"so\">Somali</option><option value=\"th\">Thai</option><option value=\"tl\">Tagalog</option><option value=\"tg\">Tajiki</option><option value=\"ta\">Tamil</option><option value=\"cs\">Czech</option><option value=\"ny\">Chewa</option><option value=\"te\">Telugu</option><option value=\"da\">Danish</option><option value=\"de\">German</option><option value=\"tr\">Turkish</option><option value=\"ne\">Nepali</option><option value=\"no\">Norwegian</option><option value=\"ht\">Haitian</option><option value=\"ha\">Hausa</option><option value=\"ps\">Pushto</option><option value=\"eu\">Basque</option><option value=\"haw\">Hawaiian</option><option value=\"hu\">Hungarian</option><option value=\"pa\">Punjabi</option><option value=\"hi\">Hindi</option><option value=\"fi\">Finnish</option><option value=\"fr\">French</option><option value=\"fy\">Frisian</option><option value=\"bg\">Bulgarian</option><option value=\"vi\">Vietnamese</option><option value=\"he\">Hebrew</option><option value=\"be\">Belarusian</option><option value=\"fa\">Persian</option><option value=\"bn\">Bengali</option><option value=\"pl\">Polish</option><option value=\"bs\">Bosnian</option><option value=\"pt\">Portuguese</option><option value=\"mi\">Maori</option><option value=\"mk\">Macedonian</option><option value=\"mr\">Marathi</option><option value=\"mg\">Malagasy</option><option value=\"ml\">Malayalam</option><option value=\"mt\">Maltese</option><option value=\"ms\">Malay</option><option value=\"my\">Myanmar</option><option value=\"mn\">Mongolian</option><option value=\"hmn\">Monk</option><option value=\"yo\">Yoruba</option><option value=\"lo\">Laotian</option><option value=\"la\">Latin</option><option value=\"lv\">Latvian</option><option value=\"lt\">Lithuanian</option><option value=\"ro\">Romanian</option><option value=\"lb\">Luxembourgish</option><option value=\"ru\">Russian</option><option value=\"en\">English</option><option value=\"ko\">Korean</option><option value=\"zh-CN\">Chinese (PRC)</option><option value=\"zh-TW\">Chinese (Taiwan)</option><option value=\"ja\">Japanese</option>"
},
"ifShowButtonLabel":{
"message": "Pop up a button when selecting text"
},
"ifCheckLangLabel":{
"message": "Do not display the button if the selected text is the same as the destination language"
},
"ifShowMenuLabel":{
"message": "Display context menu"
}
}

View file

@ -0,0 +1,29 @@
{
"extName": {
"message": "Simple Translate"
},
"extDescription": {
"message": "シンプルな翻訳を表示するツールです。"
},
"initialTextArea":{
"message": "テキストを入力"
},
"showLink":{
"message": "このページを翻訳"
},
"LangListLabel":{
"message":"翻訳先の言語"
},
"langList":{
"message":"<option value=\"en\">英語</option><option value=\"ko\">韓国語</option><option value=\"zh-CN\">中国語(簡体)</option><option value=\"zh-TW\">中国語(繁体)</option><option value=\"ja\">日本語</option><option value=\"is\">アイスランド語</option><option value=\"ga\">アイルランド語</option><option value=\"az\">アゼルバイジャン語</option><option value=\"af\">アフリカーンス語</option><option value=\"am\">アムハラ語</option><option value=\"ar\">アラビア語</option><option value=\"sq\">アルバニア語</option><option value=\"hy\">アルメニア語</option><option value=\"it\">イタリア語</option><option value=\"yi\">イディッシュ語</option><option value=\"ig\">イボ語</option><option value=\"id\">インドネシア語</option><option value=\"cy\">ウェールズ語</option><option value=\"uk\">ウクライナ語</option><option value=\"uz\">ウズベク語</option><option value=\"ur\">ウルドゥ語</option><option value=\"et\">エストニア語</option><option value=\"eo\">エスペラント語</option><option value=\"nl\">オランダ語</option><option value=\"kk\">カザフ語</option><option value=\"ca\">カタルーニャ語</option><option value=\"gl\">ガリシア語</option><option value=\"kn\">カンナダ語</option><option value=\"el\">ギリシャ語</option><option value=\"ky\">キルギス語</option><option value=\"gu\">グジャラト語</option><option value=\"km\">クメール語</option><option value=\"ku\">クルド語</option><option value=\"hr\">クロアチア語</option><option value=\"xh\">コーサ語</option><option value=\"co\">コルシカ語</option><option value=\"sm\">サモア語</option><option value=\"jw\">ジャワ語</option><option value=\"ka\">ジョージア(グルジア)語</option><option value=\"sn\">ショナ語</option><option value=\"sd\">シンド語</option><option value=\"si\">シンハラ語</option><option value=\"sv\">スウェーデン語</option><option value=\"zu\">ズールー語</option><option value=\"gd\">スコットランド ゲール語</option><option value=\"es\">スペイン語</option><option value=\"sk\">スロバキア語</option><option value=\"sl\">スロベニア語</option><option value=\"sw\">スワヒリ語</option><option value=\"su\">スンダ語</option><option value=\"ceb\">セブアノ語</option><option value=\"sr\">セルビア語</option><option value=\"st\">ソト語</option><option value=\"so\">ソマリ語</option><option value=\"th\">タイ語</option><option value=\"tl\">タガログ語</option><option value=\"tg\">タジク語</option><option value=\"ta\">タミル語</option><option value=\"cs\">チェコ語</option><option value=\"ny\">チェワ語</option><option value=\"te\">テルグ語</option><option value=\"da\">デンマーク語</option><option value=\"de\">ドイツ語</option><option value=\"tr\">トルコ語</option><option value=\"ne\">ネパール語</option><option value=\"no\">ノルウェー語</option><option value=\"ht\">ハイチ語</option><option value=\"ha\">ハウサ語</option><option value=\"ps\">パシュト語</option><option value=\"eu\">バスク語</option><option value=\"haw\">ハワイ語</option><option value=\"hu\">ハンガリー語</option><option value=\"pa\">パンジャブ語</option><option value=\"hi\">ヒンディー語</option><option value=\"fi\">フィンランド語</option><option value=\"fr\">フランス語</option><option value=\"fy\">フリジア語</option><option value=\"bg\">ブルガリア語</option><option value=\"vi\">ベトナム語</option><option value=\"iw\">ヘブライ語</option><option value=\"be\">ベラルーシ語</option><option value=\"fa\">ペルシャ語</option><option value=\"bn\">ベンガル語</option><option value=\"pl\">ポーランド語</option><option value=\"bs\">ボスニア語</option><option value=\"pt\">ポルトガル語</option><option value=\"mi\">マオリ語</option><option value=\"mk\">マケドニア語</option><option value=\"mr\">マラーティー語</option><option value=\"mg\">マラガシ語</option><option value=\"ml\">マラヤーラム語</option><option value=\"mt\">マルタ語</option><option value=\"ms\">マレー語</option><option value=\"my\">ミャンマー語</option><option value=\"mn\">モンゴル語</option><option value=\"hmn\">モン語</option><option value=\"yo\">ヨルバ語</option><option value=\"lo\">ラオ語</option><option value=\"la\">ラテン語</option><option value=\"lv\">ラトビア語</option><option value=\"lt\">リトアニア語</option><option value=\"ro\">ルーマニア語</option><option value=\"lb\">ルクセンブルク語</option><option value=\"ru\">ロシア語</option>"
},
"ifShowButtonLabel":{
"message": "テキスト選択時にボタンを表示する"
},
"ifCheckLangLabel":{
"message": "選択したテキストが翻訳先言語と同じ場合はボタンを表示しない"
},
"ifShowMenuLabel":{
"message": "コンテキストメニューを表示する"
}
}

View file

@ -0,0 +1,115 @@
getSetting();
browser.storage.onChanged.addListener(getSetting)
//設定の読み出し
function getSetting() {
browser.storage.sync.get(["targetLang", "ifShowButton", "ifCheckLang", "ifShowMenu"], function (value) {
if (value.targetLang == undefined) initialSetting(); //初回起動時
targetLang = value.targetLang;
ifShowButton = value.ifShowButton;
ifCheckLang = value.ifCheckLang;
ifShowMenu = value.ifShowMenu;
if (ifShowMenu) menuCreate();
else menuRemove();
});
}
//設定の初期化 動く?
function initialSetting() {
switch (browser.i18n.getUILanguage()) { //一部の言語はブラウザの設定に合わせる
case "ja":
case "zh-CN":
case "zh-TW":
case "ko":
targetLang = browser.i18n.getUILanguage();
break;
default:
targetLang = "en";
break;
}
browser.storage.sync.set({
'targetLang': targetLang,
'ifShowButton': true,
'ifCheckLang': true,
'ifShowMenu': true
}, function () {
getSetting();
});
}
//メニューを表示
function menuCreate() {
browser.contextMenus.create({
id: "translateText",
title: "選択したテキストを翻訳",
contexts: ["selection"],
});
browser.contextMenus.create({
id: "translatePage",
title: "ページ全体を翻訳",
contexts: ["all"],
});
browser.contextMenus.create({
id: "translateLink",
title: "選択したリンクを翻訳",
contexts: ["link"],
});
}
//メニューを削除
function menuRemove() {
browser.contextMenus.removeAll();
}
//メニュークリック時
browser.contextMenus.onClicked.addListener(function (info, tab) {
switch (info.menuItemId) {
case "translateText":
translateTextMenu(info, tab);
break;
case "translatePage":
translatePageMenu(info, tab);
break;
case "translateLink":
translateLinkMenu(info, tab);
break;
}
});
//テキストを翻訳
function translateTextMenu(info, tab) {
browser.tabs.sendMessage(
tab.id, {
message: "showPanelFromMenu"
}
)
}
//ページ全体を翻訳
function translatePageMenu(info, tab) {
browser.tabs.create({
'url': "https://translate.google.co.jp/translate?hl=" + targetLang + "&sl=auto&u=" + encodeURIComponent(info.pageUrl),
'active': true,
'index': tab.index + 1
});
}
//リンクを翻訳
function translateLinkMenu(info, tab) {
browser.tabs.create({
'url': "https://translate.google.co.jp/translate?hl=" + targetLang + "&sl=auto&u=" + encodeURIComponent(info.linkUrl),
'active': true,
'index': tab.index + 1
});
}
//スクリプトからのメッセージに返信
browser.runtime.onMessage.addListener(function (request) {
switch (request.message) {
case "getSetting":
break;
}
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Binary file not shown.

View file

@ -1,20 +1,58 @@
{
"manifest_version": 2,
"name": "Simple Translate",
"version": "1.0",
"description": "Adds a red border to all webpages matching mozilla.org.",
"name": "__MSG_extName__",
"description": "__MSG_extDescription__",
"default_locale": "en",
"applications": {
"gecko": {
"id": "addon@example.com",
"update_url": "https://example.com/updates.json"
}
},
"permissions": ["<all_urls>", "storage", "contextMenus"],
"options_ui": {
"page": "options/options.html"
},
"icons": {
"48": "icons/border-48.png"
"512": "icons/512.png",
"128": "icons/128.png",
"64": "icons/64.png",
"48": "icons/48.png",
"32": "icons/32.png"
},
"background": {
"scripts": ["background.js"]
},
"browser_action": {
"default_icon": {
"512": "icons/512.png",
"128": "icons/128.png",
"64": "icons/64.png",
"48": "icons/48.png",
"38": "icons/38.png",
"32": "icons/32.png",
"19": "icons/19.png",
"16": "icons/16.png"
},
"default_popup": "popup/popup.html"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"matches": ["http://*/*", "https://*/*", "<all_urls>"],
"css": ["simple-translate.css"],
"js": ["simple-translate.js"]
}
]
}

View file

@ -0,0 +1,28 @@
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<p>
<label id=targetLangLabel>翻訳先の言語:</label>
<select id="targetLang"></select>
</p>
<p>
<input type="checkbox" name="ifShowButton" value="1">
<label id=ifShowButtonLabel>テキスト選択時にボタンを表示する</label>
</p>
<p>
<input type="checkbox" name="ifCheckLang" value="1">
<label id=ifCheckLangLabel>選択したテキストが翻訳先言語と同じ時はボタンを表示しない</label>
</p>
<p>
<input type="checkbox" name="ifShowMenu" value="1">
<label id=ifShowMenuLabel>コンテキストメニューを表示する</label>
</p>
<script type="text/javascript" src="options.js"></script>
</body>
</html>

View file

@ -0,0 +1,32 @@
var targetLang = document.getElementById("targetLang");
var ifShowButton = document.getElementsByName("ifShowButton").item(0);
var ifCheckLang = document.getElementsByName("ifCheckLang").item(0);
var ifShowMenu = document.getElementsByName("ifShowMenu").item(0);
targetLang.innerHTML=browser.i18n.getMessage("langList");
document.getElementById("targetLangLabel").innerHTML=browser.i18n.getMessage("langListLabel");
document.getElementById("ifShowButtonLabel").innerHTML=browser.i18n.getMessage("ifShowButtonLabel");
document.getElementById("ifCheckLangLabel").innerHTML=browser.i18n.getMessage("ifCheckLangLabel");
document.getElementById("ifShowMenuLabel").innerHTML=browser.i18n.getMessage("ifShowMenuLabel");
//設定を読み込んで反映
browser.storage.sync.get(["targetLang", "ifShowButton", "ifCheckLang", "ifShowMenu"], function (value) {
targetLang.value = value.targetLang;
ifShowButton.checked=value.ifShowButton;
ifCheckLang.checked=value.ifCheckLang;
ifShowMenu.checked=value.ifShowMenu;
});
function save() {
browser.storage.sync.set({
'targetLang': targetLang.value,
'ifShowButton': ifShowButton.checked,
'ifCheckLang': ifCheckLang.checked,
'ifShowMenu': ifShowMenu.checked
}, function () {});
}
targetLang.addEventListener("change", save);
ifShowButton.addEventListener("change", save);
ifCheckLang.addEventListener("change", save);
ifShowMenu.addEventListener("change", save);

View file

@ -1,6 +1,70 @@
#button {
width: 20px;
height: 20px;
background-color: steelblue;
body {
font-family: 'Hiragino Kaku Gothic Pro', 'ヒラギノ角ゴ Pro W3', 'Meiryo', 'メイリオ', 'Osaka', 'MS PGothic', 'arial', 'helvetica', 'sans-serif';
text-align: left;
font-size: 13px;
height: auto;
width: 300px;
padding: 5px 20px 0px;
overflow: hidden;
}
#main{
margin: 10px 0px;
}
hr {
size: 1;
color: #eee;
}
p {}
textarea {
font-family: 'Hiragino Kaku Gothic Pro', 'ヒラギノ角ゴ Pro W3', 'Meiryo', 'メイリオ', 'Osaka', 'MS PGothic', 'arial', 'helvetica', 'sans-serif';
text-align: left;
font-size: 13px;
resize: none;
overflow: auto;
max-height: 250px;
height: 30px;
width: 277px;
padding-top: 10px;
padding-bottom: 0px;
padding-left: 10px;
padding-right: 10px;
}
#link a {
font-style: normal;
text-decoration: none;
color: #4268da;
}
#distination {
color: #aaa;
max-height: 250px;
overflow-y: auto;
}
#target {
max-height: 250px;
overflow-y: auto;
word-wrap: break-word;
}
#link {
margin-top: 3px;
}
#langList {
font-family: 'Hiragino Kaku Gothic Pro', 'ヒラギノ角ゴ Pro W3', 'Meiryo', 'メイリオ', 'Osaka', 'MS PGothic', 'arial', 'helvetica', 'sans-serif';
text-align: left;
font-size: 13px;
float: right;
margin-bottom: 20px;
max-width: 140px;
}
::-moz-selection {
background: #ebebeb;
}

View file

@ -4,11 +4,23 @@
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="popup.css">
<link rel="stylesheet" type="text/css" href="popup.css">
</head>
<body>
<div id=button></div>
<div id=main>
<form>
<textarea id=textarea spellcheck=false></textarea>
</form>
<hr>
<div id=target>
<p></p>
</div>
</div>
<select id="langList"></select>
<div id=link></div>
<script src="popup.js"></script>
</body>
</html>

View file

@ -0,0 +1,138 @@
let target = document.getElementById("target");
let langList = document.getElementById("langList");
let textarea = document.getElementById("textarea");
const initialText = browser.i18n.getMessage("initialTextArea");
langList.innerHTML = browser.i18n.getMessage("langList");
textarea.innerText = initialText;
let targetLang;
let sourceWord = "";
browser.storage.onChanged.addListener(getTargetLang);
getTargetLang(); //翻訳先言語初期化
//設定を読み出し
function getTargetLang() {
browser.storage.sync.get("targetLang", function (value) {
targetLang = value.targetLang;
langList.value = targetLang; //リスト初期値をセット
langList.addEventListener("change", changeLang);
});
}
//翻訳先言語変更時に更新
function changeLang() {
targetLang = langList.value;
if (sourceWord !== "") {
removeResult();
splitLine();
}
if (url !== "") showLink();
}
//アクティブなタブを取得して渡す
browser.tabs.query({
currentWindow: true,
active: true
}).then(function (tabs) {
getSelectionWord(tabs);
});
//アクティブタブから選択文字列とurlを取得
function getSelectionWord(tabs) {
for (let tab of tabs) {
browser.tabs.sendMessage(
tab.id, {
message: "fromPopup"
}
).then(response => {
sourceWord = response.word;
url = response.url;
refleshSource();
showLink();
});
}
}
//ページ翻訳へのリンクを表示
function showLink() {
document.getElementById("link").innerHTML = "<a href=https://translate.google.co.jp/translate?hl=" + targetLang + "&sl=auto&u=" + encodeURIComponent(url) + ">" + browser.i18n.getMessage('showLink') + "</a>";
}
//翻訳元テキストを表示
function refleshSource() {
if (sourceWord !== "") {
textarea.innerHTML = sourceWord;
translate();
resize();
}
}
textarea.addEventListener("keydown", resize);
//テキストボックスをリサイズ
function resize() {
setTimeout(function () {
textarea.style.height = "0px";
textarea.style.height = parseInt(textarea.scrollHeight) + "px";
}, 0);
}
//テキストエリアクリック時の処理
textarea.addEventListener("click", textAreaClick, {
once: true
});
function textAreaClick() {
if (textarea.value == initialText) {
textarea.value = "";
} else {
textarea.select();
}
}
textarea.addEventListener("keyup", inputText);
//文字入力時の処理
function inputText() {
sourceWord = textarea.value;
translate();
}
//改行で分割してgetRequestに渡す
function translate() {
let promises = [];
sourceLine = sourceWord.split("\n");
for (i = 0; i < sourceLine.length; i++) {
promises.push(getRequest(sourceLine[i]));
}
Promise.all(promises)
.then(function (results) {
showResult(results); //翻訳結果が帰ってきたらshowResult
});
}
//翻訳リクエストを送信,取得して返す
function getRequest(word) {
return new Promise(function (resolve, reject) {
let xhr = new XMLHttpRequest();
xhr.responseType = 'json';
let url = "https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=" + targetLang + "&dt=t&q=" + encodeURIComponent(word);
xhr.open("GET", url);
xhr.send();
xhr.onload = function () {
resolve(xhr);
};
})
}
//翻訳結果を表示
function showResult(results) {
target.innerText = "";
let resultText = "";
for (let j = 0; j < results.length; j++) {
for (let i = 0; i < results[j].response[0].length; i++) {
resultText += results[j].response[0][i][0];
}
resultText += "\n"; //
}
target.innerText = resultText;
}

View file

@ -0,0 +1,78 @@
#simple-translate-button {
background-color: #fff;
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0 0 1px rgba(0, 0, 0, 0.08);
border-radius: 3px;
background-image: url("icons/16.png");
background-repeat: no-repeat;
background-position: center;
height: 22px;
width: 22px;
position: fixed;
z-index: 151;
left: 0px;
top: 0px;
display: none;
cursor: pointer;
animation-duration: 200ms;
animation-name: showButton;
}
#simple-translate-panel {
background-color: #fff;
font-family: 'Hiragino Kaku Gothic Pro', 'ヒラギノ角ゴ Pro W3', Meiryo, メイリオ, Osaka, 'MS PGothic', arial, helvetica, sans-serif;
text-align: left;
font-size: 13px;
/*opacity: 0;*/
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0 0 1px rgba(0, 0, 0, 0.08);
border-radius: 3px;
min-height: 20px;
max-height: 200px;
line-height: 150%;
height: auto;
min-width: 10px;
max-width: 300px;
width:300px;/*消すかも*/
position: fixed;
padding: 10px 18px;
z-index: 150;
left: 0px;
top: 0px;
display: none;
overflow-y: auto;
/*
transition-property: height, width, opacity;
transition-timing-function: ease-out;
transition-duration: 400ms;*/
}
#simple-translate-panel p {
display: inline-block;
margin: 0;
transition-duration: 200ms;
animation-name: fadein;
}
@keyframes showButton {
0% {
transform: scale3d(1, 1, 1);
}
50% {
transform: scale3d(1.1, 1.1, 1.1);
}
100% {
transform: scale3d(1, 1, 1);
}
}
@keyframes fadein {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#simple-translate-panel p::-moz-selection {
background: #ebebeb;
}

View file

@ -1,41 +1,180 @@
var style = document.createElement("style");
style.setAttribute("type", "text/css");
style.innerHTML = "" +
"#simple-translate-button {" +
"background-color :rgba(87, 199, 232, 0.6);" +
"height :20px;" +
"width :20px;" +
"position :fixed;" +
"z-index: 150;" +
"left :0px;" +
"top :0px;" +
"display :none;" +
"cursor :pointer;" +
"}";
document.getElementsByTagName("head")[0].appendChild(style); //headに上記スタイルを追記
document.body.insertAdjacentHTML("beforeend", "<div id='simple-translate-button'></div>"); //body末尾にボタン配置
document.body.insertAdjacentHTML("beforeend", "<div id='simple-translate-button'></div><div id='simple-translate-panel'><p>...</p></div><div id='simple-translate-popup'></div>"); //body末尾にボタン配置
var button = document.getElementById("simple-translate-button");
var panel = document.getElementById("simple-translate-panel");
var popup = document.getElementById("simple-translate-popup");
var selectionWord;
var clickPosition;
function showPanel() {
console.log(selectionWord);
}
function popupButton(e) {
button.style.display = 'block';
button.style.left = e.clientX + 20 + 'px';
button.style.top = e.clientY + 0 + 'px';
var targetLang;
var ifShowButton;
var ifCheckLang;
//設定を読み出し
getSetting();
browser.storage.onChanged.addListener(getSetting);
function getSetting() {
browser.storage.sync.get(["targetLang", "ifShowButton", "ifCheckLang"], function (value) {
targetLang = value.targetLang;
ifShowButton = value.ifShowButton;
ifCheckLang = value.ifCheckLang;
});
}
window.addEventListener("mouseup", Select, false);
//テキスト選択時の処理
function Select(e) {
button.style.display = 'none'; //マウスクリックでボタンを非表示に
hidePanel(e);
setTimeout(function () { //誤動作防止の為ディレイを設ける
selectionWord = String(window.getSelection());
if (selectionWord.length !== 0 && e.button == 0) { //選択範囲が存在かつ左クリックのとき
popupButton(e);
if ((selectionWord.length !== 0) && (e.button == 0) && (e.target.id !== "simple-translate-panel") && (e.target.parentElement.id !== "simple-translate-panel")) { //選択範囲が存在かつ左クリックかつパネル以外のとき
if (ifCheckLang) {
checkLang().then(function (results) {
if (results) popupButton(e);
});
} else {
popupButton(e);
}
}
}, 100);
}, 200);
}
//選択テキストの言語をチェックして返す
function checkLang() {
return new Promise(function (resolve, reject) {
getRequest(selectionWord.substr(0, 100)) //先頭100文字を抽出
.then(function (results) {
let lang = results.response[2];
let percentage = results.response[6];
//console.log(lang, percentage, lang!=targetLang && percentage>0);
resolve(lang != targetLang && percentage > 0); //真偽値を返す
});
})
}
//ボタンを表示
function popupButton(e) {
button.style.left = e.clientX + 10 + 'px';
button.style.top = e.clientY + 5 + 'px';
if (ifShowButton) {
button.style.display = 'block';
}
}
button.addEventListener("click", function (e) {
translate();
showPanel(e);
}, false);
//改行で分割してgetRequestに渡す
function translate() {
promises = [];
sourceLine = selectionWord.split("\n");
for (i = 0; i < sourceLine.length; i++) {
promises.push(getRequest(sourceLine[i]));
}
Promise.all(promises)
.then(function (results) {
showResult(results); //翻訳結果が帰ってきたらshowResult
});
}
//翻訳リクエストを送信,取得して返す
function getRequest(word) {
return new Promise(function (resolve, reject) {
let xhr = new XMLHttpRequest();
xhr.responseType = 'json';
let url = "https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=" + targetLang + "&dt=t&q=" + encodeURIComponent(word);
xhr.open("GET", url);
xhr.send();
xhr.onload = function () {
resolve(xhr);
};
})
}
//翻訳結果を表示
function showResult(results) {
panel.innerText = "";
let resultText = "";
for (let j = 0; j < results.length; j++) {
for (let i = 0; i < results[j].response[0].length; i++) {
resultText += results[j].response[0][i][0];
}
resultText += "\n"; //
}
panel.innerHTML = "<p></p>"
panel.getElementsByTagName("p")[0].innerText = resultText;
panelPosition(clickPosition);
}
//パネル表示
function showPanel(e) {
clickPosition = e;
panel.style.display = 'block';
panelPosition(e);
}
//パネル非表示
function hidePanel(e) {
button.style.display = 'none'; //ボタンを非表示
if ((e.target.id !== "simple-translate-panel") && (e.target.parentElement.id !== "simple-translate-panel")) { //パネル以外の場所をクリックでパネルを非表示
panel.style.display = 'none';
panel.innerHTML = "<p>...</p>";
}
}
//パネルがウィンドウ外にはみ出る時に位置を調整
function panelPosition(e) {
var p = new Object();
panel.style.width = '300px';
var panelHeight = panel.clientHeight;
var panelWidth = parseInt(window.getComputedStyle(panel.getElementsByTagName("p")[0], null).width);
//一旦パネルの横幅を300にしてpの横幅を取得
if (e.clientX + panelWidth > window.innerWidth - 80) {
p.x = window.innerWidth - panelWidth - 80;
} else {
p.x = e.clientX + 10;
}
if (e.clientY + panelHeight > window.innerHeight - 30) {
p.y = window.innerHeight - panelHeight - 30;
} else {
p.y = e.clientY + 10;
}
panel.style.width = 'auto'; //panelWidth + 'px';
panel.style.top = p.y + 'px';
panel.style.left = p.x + 'px';
}
//スクリプトからのメッセージに返信
browser.runtime.onMessage.addListener(function (request) {
switch (request.message) {
case "fromPopup":
return sendToPopup();
break;
case "showPanelFromMenu":
showPanelFromMenu();
break;
}
});
//popupにテキストとurlを返す
function sendToPopup() {
return Promise.resolve({
word: String(window.getSelection()),
url: window.location.href
});
}
//コンテキストメニュークリックでパネルを表示
function showPanelFromMenu() {
button.style.display = "none";
translate();
let event = new Object();
event.clientX = parseInt(button.style.left);
event.clientY = parseInt(button.style.top);
showPanel(event);
}
window.addEventListener("mouseup", Select, false);
button.addEventListener("click", showPanel, false);