Google翻訳をしたい時に、毎回ブラウザを開いて検索するのが面倒だったので、
翻訳したい英文テキストを選択して、右クリックからすぐにGoogle翻訳できるようにしてみた。
右クリックで使用するのは、以前にも使った「クイックアクション」の機能。
Google翻訳.workflow
(ワークフローが受け取る現在の項目:テキスト)
【Apple Script を実行】
property repeatCount : 20
property delayTime : 0.5
on run argv
set text1 to ""
if (count of argv) > 0 then
set text1 to item 1 of argv as text
else
return
end if
tell application "Safari"
activate
tell window 1
set home_url to "https://translate.google.co.jp/?hl=ja"
open location my home_url
set bounds to {50, 50, 1000, 1000}
my isLoaded({url_:home_url})
set text2 to my escape({text_:text1})
set xpath to my getXPathBySelector({sel_:"textarea[id=\"source\"]"})
my inputByXPath({xpath_:xpath, val_:text2})
end tell
end tell
end run
on isLoaded(args)
set {url_:aURL} to args & {url_:""}
tell application "Safari"
repeat my repeatCount times
if (URL of document 1 as text) contains aURL then
repeat my repeatCount times
if (do JavaScript "document.readyState" in document 1) is "complete" then
return true
end if
delay my delayTime
end repeat
return false
end if
delay my delayTime
end repeat
return false
end tell
end isLoaded
on escape(args)
set {text_:aText} to ¬
args & {text_:""}
set text1 to aText
set text1 to my replace({text_:text1, find_:"'", replace_:"\\'"})
set text1 to my replace({text_:text1, find_:"
", replace_:" "}) --\r\n
set text1 to my replace({text_:text1, find_:"
", replace_:" "}) --\r
set text1 to my replace({text_:text1, find_:"
", replace_:" "}) --\n
return text1
end escape
on replace(args)
set {text_:aText, find_:aFind, replace_:theReplace} to ¬
args & {text_:"", find_:"", replace_:""}
set temp to AppleScript's text item delimiters
set AppleScript's text item delimiters to aFind
set theList to every text item of aText
set AppleScript's text item delimiters to theReplace
set aText to theList as string
set AppleScript's text item delimiters to temp
return aText
end replace
on getXPathBySelector(args)
set {debug_:aDebug, sel_:aSel, text_:aText, index_:aIndex, xpath_:aXPath, scroll_flg_:aScrollFlg} to ¬
args & {debug_:false, sel_:"", text_:"", index_:-1, xpath_:"", scroll_flg_:false}
tell application "Safari"
set cnt_max to 20
set cnt_current to 0
if aScrollFlg then
do JavaScript "window.scroll(0, 0);" in document 1
end if
repeat cnt_max times
set cnt_current to cnt_current + 1
if aScrollFlg then
do JavaScript "
var element = document.documentElement;
var bottom = element.scrollHeight - element.clientHeight;
var scrollY = 0;
scrollY = (bottom / " & cnt_max & ") * " & cnt_current & ";
window.scroll(0, scrollY);
" in document 1
end if
if aScrollFlg then
delay 0.1
end if
set val to do JavaScript "
var val = '';
" & my getTopElement({xpath_:aXPath}) & "
var lists = ele.querySelectorAll(':scope " & aSel & "');
for ( var i = 0; i < lists.length; i++ ) {
var ele = lists[i];
if((" & aIndex & " == -1) && ('" & aText & "' == '')){
val = getXpath(ele);
break;
}
if(" & aIndex & " > -1){
if(" & aIndex & " == i){
val = getXpath(ele);
break;
}
}
if('" & aText & "' != ''){
if(ele.innerHTML.indexOf( '" & aText & "') > -1){
val = getXpath(ele);
break;
}
}
}
" & my getJsFuncXPath() & "
res = val;
" in document 1
if val is not "" then
return val
end if
delay 0.1
end repeat
return ""
end tell
end getXPathBySelector
on inputByXPath(args)
set {val_:aVal, xpath_:aXPath} to ¬
args & {val_:"", xpath_:""}
tell application "Safari"
do JavaScript "
" & my getTopElement({xpath_:aXPath}) & "
ele.value = '" & aVal & "';
" in document 1
end tell
end inputByXPath
on getTopElement(args)
set {xpath_:aXPath} to args & {xpath_:""}
if aXPath is "" then
set top_element to "var ele = document;"
else
set top_element to "
var xpaths = document.evaluate('" & aXPath & "', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null );
var ele = xpaths.snapshotItem(0);"
end if
return top_element
end getTopElement
on getJsFuncXPath()
return "
function getXpath(element) {
if(element && element.parentNode) {
var xpath = getXpath(element.parentNode) + '/' + element.tagName;
var s = [];
for(var i = 0; i < element.parentNode.childNodes.length; i++) {
var e = element.parentNode.childNodes[i];
if(e.tagName == element.tagName) {
s.push(e);
}
}
if(1 < s.length) {
for(var i = 0; i < s.length; i++) {
if(s[i] === element) {
xpath += '[' + (i+1) + ']';
break;
}
}
}
return xpath.toLowerCase();
} else {
return '';
}
}
"
end getJsFuncXPath
ブラウザの拡張機能でも翻訳が付けられますが、今回のはテキストならメモ帳など、どこからでも使えるということで。
参考サイト
システム環境設定 > キーボード > ショートカット