Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
431 additions
and
0 deletions.
There are no files selected for viewing
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
{ | ||
"manifest_version": 2, | ||
|
||
"name": "Goshen Web Translator", | ||
"description": "Translate entire webpages with a casmacat-moses backend", | ||
"version": "1.0", | ||
|
||
"browser_action": { | ||
"default_icon": "icon.png", | ||
"default_popup": "popup/popup.html" | ||
}, | ||
"permissions": [ | ||
"activeTab", | ||
"storage", | ||
"https://ajax.googleapis.com/" | ||
], | ||
"options_page" : "options/index.html", | ||
|
||
"content_scripts": [{ | ||
"matches": ["http://*/*", "https://*/*", "file:///*"], | ||
"css": ["onpage/onpage.css"], | ||
"js": [ | ||
"onpage/onpage.js", | ||
"onpage/goshen.js", | ||
"onpage/chromegoshen.js" | ||
], | ||
"all_frames": true | ||
}] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
(function(window) { | ||
|
||
var demo_url = "ec2-52-23-242-15.compute-1.amazonaws.com:8081"; | ||
|
||
var _goshen = window._goshen; | ||
|
||
on = function(event, cb) { | ||
window.addEventListener(event, cb); | ||
} | ||
|
||
off = function(event, cb) { | ||
window.removeEventListener(event, cb); | ||
} | ||
|
||
class ChromeGoshen { | ||
constructor() { | ||
this.G = new _goshen.Goshen(demo_url); | ||
console.info("Goshenjs engine loaded successfully.") | ||
} | ||
|
||
/** | ||
* Begin interactive dom node selection. | ||
*/ | ||
selectMode() { | ||
var self = this; | ||
var selection = []; | ||
var previousElement = null; | ||
|
||
var showSelection = function() { | ||
var olds = document.querySelectorAll('._goshen-selected'); | ||
for (var i = 0; i < olds.length; i++) { | ||
olds[i].classList.remove('_goshen-selected'); | ||
} | ||
for (var i = 0; i < selection.length; i++) { | ||
selection[i].classList.add('_goshen-selected'); | ||
} | ||
}; | ||
|
||
var setSelection = function(sel) { | ||
selection = sel; | ||
showSelection(); | ||
}; | ||
|
||
var validParents = [ | ||
"DIV", "ARTICLE", "BLOCKQUOTE", "MAIN", | ||
"SECTION", "UL", "OL", "DL" | ||
]; | ||
|
||
var validChildren = [ | ||
"P", "H1", "H2", "H3", "H4", "H5", "H6", "SPAN", "DL", | ||
"OL", "UL", "BLOCKQUOTE", "SECTION" | ||
]; | ||
|
||
var selectSiblings = function(el) { | ||
var firstChild = el; | ||
var parent = el.parentNode; | ||
while (parent && !~validParents.indexOf(parent.tagName)) { | ||
firstChild = parent; | ||
parent = firstChild.parentNode; | ||
} | ||
|
||
if (parent) { | ||
var kids = parent.childNodes, | ||
len = kids.length, | ||
result = [], | ||
i = 0; | ||
|
||
while (kids[i] !== firstChild) { i++; } | ||
|
||
for (; i < len; i++) { | ||
var kid = kids[i]; | ||
if (!!~validChildren.indexOf(kid.tagName)) { | ||
result.push(kid); | ||
} | ||
} | ||
return result; | ||
|
||
} else { return [el]; } | ||
}; | ||
|
||
var stop = function() { | ||
off("mouseover", mouseoverHandler); | ||
off("mousemove", moveHandler); | ||
off("keydown", keydownHandler); | ||
off("keyup", keyupHandler); | ||
off("click", clickHandler); | ||
self.performSelectTranslation(selection); | ||
}; | ||
|
||
var mouseoverHandler = function(ev) { | ||
previousElement = ev.target; | ||
|
||
if (ev.altKey) { | ||
setSelection([ev.target]); | ||
} else { | ||
setSelection(selectSiblings(ev.target)); | ||
} | ||
}; | ||
|
||
var clickHandler = function(ev) { | ||
stop(); | ||
}; | ||
|
||
var moveHandler = function(ev) { | ||
mouseoverHandler(ev); | ||
off("mousemove", moveHandler); | ||
}; | ||
|
||
var keydownHandler = function(ev) { | ||
if (ev.keyCode === 27) { | ||
stop(); | ||
} else if (ev.altKey && selection.length > 1) { | ||
setSelection([selection[0]]); | ||
} | ||
}; | ||
|
||
var keyupHandler = function(ev) { | ||
if (!ev.altKey && selection.length === 1) { | ||
setSelection(selectSiblings(selection[0])); | ||
} | ||
}; | ||
|
||
on("mouseover", mouseoverHandler); | ||
on("click", clickHandler); | ||
on("mousemove", moveHandler); | ||
on("keydown", keydownHandler); | ||
on("keyup", keyupHandler); | ||
} | ||
|
||
select(contextData) { | ||
var text; | ||
if (contextData === undefined) { | ||
text = window.getSelection().toString(); | ||
} else { | ||
text = contextData.selectionText; | ||
} | ||
if (text.trim().length > 0) { | ||
this.init(this.parse.string(text)); | ||
window.getSelection().removeAllRanges(); | ||
} else { | ||
selectMode(); | ||
} | ||
}; | ||
|
||
_chunkedTranslation(text) { | ||
// We need to find a way to split on sentences, or long things. | ||
var texts = text.split('.'); | ||
for (var i = 0; i < texts.length; i++) { | ||
texts[i] = this.G.translate(texts[i]); | ||
} | ||
return texts.join('.'); | ||
} | ||
|
||
performSelectTranslation(selection) { | ||
for (var i = 0; i < selection.length; i++) { | ||
selection[i].classList.add('_goshen-active'); | ||
selection[i].innerText = this._chunkedTranslation(selection[i].innerText); | ||
selection[i].classList.remove('_goshen-active'); | ||
selection[i].classList.remove('_goshen-selected'); | ||
} | ||
} | ||
}; | ||
|
||
_goshen._cg = new ChromeGoshen(); | ||
|
||
})(this); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
(function (root) { | ||
|
||
var _goshen = root._goshen; | ||
|
||
LANGUAGES = { | ||
English: 'en', | ||
en: 'en', | ||
German: 'de', | ||
de: 'de' | ||
} | ||
|
||
LOCALES = { | ||
English: 'en-US', | ||
en: 'en-US', | ||
German: 'de', | ||
de: 'de' | ||
} | ||
|
||
|
||
serialize = function(obj) { | ||
var str = []; | ||
for (var p in obj) { | ||
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); | ||
} | ||
return str.join("&"); | ||
}; | ||
|
||
|
||
class MosesGoshenAdapter { | ||
constructor(hostname, protocol, opts) { | ||
this.hostname = hostname; | ||
this.protocol = protocol || 'http'; | ||
} | ||
|
||
url(suffix) { | ||
suffix = suffix || ''; | ||
return `${this.protocol}://${this.hostname}/translate?${suffix}`; | ||
} | ||
|
||
translate(text, target, source, callback) { | ||
/* Translate a string `text`, using `opts` as corequisite options. | ||
Arguments: | ||
text (str): The text to translate. | ||
target (str): The language to translate to | ||
source (str): The language to translate from | ||
callback (function): The function to call on the translated text | ||
Returns: | ||
str: The translated text | ||
*/ | ||
|
||
var requestURL = this.url(serialize({ | ||
q: text, | ||
key: 'x', | ||
target: target || LANGUAGES.en, | ||
source: source || LANGUAGES.de | ||
})); | ||
|
||
if (!!root.Meteor && !!root.HTTP) { | ||
var response = HTTP.call('GET', requestURL, {}); | ||
var translated = response.data; | ||
if (callback) callback(text, translated); | ||
|
||
} else if (!!root.XMLHttpRequest) { | ||
var request = new XMLHttpRequest(); | ||
request.open('GET', requestURL, false); | ||
request.send(null); | ||
|
||
if (request.status === 200) { | ||
var translated = root.JSON.parse(request.responseText); | ||
if (callback) callback(text, translated); | ||
} | ||
} | ||
return translated.data.translations[0].translatedText | ||
} | ||
} | ||
|
||
|
||
_goshen.Goshen = class Goshen { | ||
constructor(hostname, protocol, type, opts) { | ||
/* Create a new Goshen object. | ||
Arguments: | ||
hostname (str): A protocol-less URI such as `255.255.0.0:3000` | ||
protocol (str: 'http'): An http protocol (either 'http' or 'https') | ||
type (class): The type of adapter to use by default. | ||
opts (dict): Options for configuration. | ||
The options configuration dictionary can contain | ||
*/ | ||
type = type || MosesGoshenAdapter; | ||
this.ga = new type(hostname, protocol, opts); | ||
} | ||
|
||
url(suffix) { | ||
return this.ga.url(suffix); | ||
} | ||
|
||
translate(text, target, source, callback) { | ||
/* Calls the local GoshenAdapter#translate. */ | ||
return this.ga.translate(text, target, source, callback); | ||
} | ||
|
||
|
||
}; | ||
})(this); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
._goshen-selected { | ||
background-color: rgba(100, 250, 250, 0.2); | ||
} | ||
|
||
._goshen-selected._goshen-active { | ||
background-color: rgba(250, 100, 250, 0.2); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// This is run inside the scope of a page, and so we have direct access to the | ||
// page's HTML from here. | ||
|
||
(function (window) { | ||
|
||
if (typeof window._goshen !== 'undefined') { | ||
console.warn("_goshen unable to initialize!"); | ||
return; | ||
} else { | ||
window._goshen = {}; | ||
} | ||
|
||
// We can now request the contents of window. | ||
|
||
window.addEventListener('keyup', function(ev) { | ||
// This is a bit heavy-handed, and we almost assuredly don't need to be | ||
// capturing every keyup event. But it's lightweight, and serves as a | ||
// decent proof of concept. | ||
if (ev.altKey && ev.keyCode == 84) { | ||
// They pressed Alt+T. Call _goshen's get-text function! | ||
window._goshen._cg.selectMode(); | ||
} | ||
}); | ||
|
||
})(this); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset="utf-8"> | ||
<title>Goshen Options</title> | ||
</head> | ||
<body> | ||
|
||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
<html> | ||
<head> | ||
<script src="../vendor/ustr.min.js"></script> | ||
<!-- <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> --> | ||
<script src="popup.js"></script> | ||
<link rel="stylesheet/less" type="text/css" href="style.less" /> | ||
<script src="../vendor/less.js"></script> | ||
</head> | ||
<body style="width: 400px"> | ||
<div class="container"> | ||
<h1>Goshen Translator</h1> | ||
<p> | ||
Goshen uses <code>python-mt-server</code> and <code>moses</code> to | ||
translate webpage text. For more information, see the repository | ||
on <a href="https://github.com/j6k4m8/en600.468-final/">GitHub</a>. | ||
</p> | ||
<hr> | ||
<div class="dropdown-container from-container"> | ||
<h2>Translate from:</h2> | ||
<select class="from-select"> | ||
<!-- <option value="English">English</option> --> | ||
<!-- <option value="French">French</option> --> | ||
<option value="German">German</option> | ||
</select> | ||
</div> | ||
<div class="dropdown-container to-container"> | ||
<h2>Translate to:</h2> | ||
<select class="to-select"> | ||
<option value="English">English</option> | ||
<!-- <option value="French">French</option> --> | ||
<!-- <option value="German">German</option> --> | ||
</select> | ||
</div> | ||
<hr> | ||
<p> | ||
To translate the webpage, press the <kbd>Alt</kbd>+<kbd>T</kbd> | ||
keychord and mouse over the element(s) that you want to queue for | ||
translation. Click to begin the translation — the selected | ||
elements will turn blue to indicate that they're queued. | ||
</p> | ||
<!-- <button type="button" style="float: right;" class="js-translate">Translate</button> --> | ||
</div> | ||
</body> | ||
</html> |
Empty file.
Oops, something went wrong.