2016-06-19 04:46:50 -04:00
|
|
|
|
// TODO: refactor me!
|
|
|
|
|
var sourceVisible = localStorage.getItem('source-visible') === 'true';
|
|
|
|
|
|
|
|
|
|
(function ($) {
|
|
|
|
|
addOriginalToggler();
|
|
|
|
|
addSpacingBetweenCnAndEn();
|
|
|
|
|
|
|
|
|
|
function addOriginalToggler() {
|
|
|
|
|
var nodes = document.querySelectorAll('p, li, h1, h2, h3, h4, h5, h6, header, a, button, small');
|
|
|
|
|
_.each(nodes, function (node) {
|
|
|
|
|
var $node = $(node);
|
|
|
|
|
|
|
|
|
|
if (isLink(node) || isButton(node)) {
|
|
|
|
|
$node.on('click', function (event) {
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (/^http?s:\/\//.test($node.attr('href')) && !$node.attr('target')) {
|
|
|
|
|
$node.attr('target', '_blank');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var prevNode = node.previousElementSibling;
|
|
|
|
|
var $prevNode = $(prevNode);
|
|
|
|
|
|
|
|
|
|
if (!prevNode) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isTranslationResult(node, prevNode)) {
|
|
|
|
|
if ($prevNode.hasClass('nav-list-item')) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (isPureEnglish($node.text()) && $node.text() !== $prevNode.text()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isPureEnglish($prevNode.text())) {
|
|
|
|
|
$node.attr('id', prevNode.id);
|
|
|
|
|
$node.addClass('translated');
|
|
|
|
|
$node.addClass('translated-cn');
|
|
|
|
|
$prevNode.removeAttr('id');
|
|
|
|
|
$prevNode.addClass('original-english');
|
|
|
|
|
if (!sourceVisible) {
|
|
|
|
|
$prevNode.addClass('hidden');
|
|
|
|
|
}
|
|
|
|
|
if (!isLink(node) && !isButton(node)) {
|
2016-07-05 07:53:58 -04:00
|
|
|
|
var isDragging = false;
|
|
|
|
|
$node.on('mousedown', function(){
|
|
|
|
|
$(window).on('mousemove', function(){
|
|
|
|
|
isDragging = true;
|
|
|
|
|
$(window).unbind('mousemove');
|
2016-07-16 06:29:42 -04:00
|
|
|
|
});
|
2016-06-19 04:46:50 -04:00
|
|
|
|
});
|
2016-07-05 07:53:58 -04:00
|
|
|
|
$prevNode.on('mousedown', function(){
|
|
|
|
|
$(window).on('mousemove', function(){
|
|
|
|
|
isDragging = true;
|
|
|
|
|
$(window).unbind('mousemove');
|
2016-07-16 06:29:42 -04:00
|
|
|
|
});
|
2016-07-05 07:53:58 -04:00
|
|
|
|
});
|
|
|
|
|
$node.on('mouseup', function () {
|
|
|
|
|
var wasDragging = isDragging;
|
|
|
|
|
isDragging = false;
|
|
|
|
|
$(window).unbind('mousemove');
|
|
|
|
|
if(!wasDragging){
|
|
|
|
|
$prevNode.toggleClass('hidden');
|
2016-07-16 06:29:42 -04:00
|
|
|
|
}
|
2016-07-05 07:53:58 -04:00
|
|
|
|
});
|
|
|
|
|
$prevNode.on('mouseup', function () {
|
|
|
|
|
var wasDragging = isDragging;
|
|
|
|
|
isDragging = false;
|
|
|
|
|
$(window).unbind('mousemove');
|
|
|
|
|
if(!wasDragging){
|
|
|
|
|
$prevNode.addClass('hidden');
|
2016-07-16 06:29:42 -04:00
|
|
|
|
}
|
2016-06-19 04:46:50 -04:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
$node.after($prevNode);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
2016-07-16 06:29:42 -04:00
|
|
|
|
|
2016-06-19 04:46:50 -04:00
|
|
|
|
function addSpacingBetweenCnAndEn($node) {
|
|
|
|
|
var nodes = document.querySelectorAll('.translated-cn');
|
|
|
|
|
_.each(nodes, function (node) {
|
|
|
|
|
var text = node.innerHTML;
|
2016-06-19 07:31:02 -04:00
|
|
|
|
text = text.replace(/([\x20-\xff]+)/g, function (word) {
|
|
|
|
|
if (!word.replace(/\s/, '')) {
|
|
|
|
|
return '';
|
|
|
|
|
} else if (/<[^>]*>/.test(word)) {
|
2016-06-19 07:45:07 -04:00
|
|
|
|
return ' ' + word + ' ';
|
2016-06-19 07:31:02 -04:00
|
|
|
|
} else {
|
2016-06-19 07:45:07 -04:00
|
|
|
|
return ' ' + word + ' ';
|
2016-06-19 07:31:02 -04:00
|
|
|
|
}
|
|
|
|
|
});
|
2016-06-19 04:46:50 -04:00
|
|
|
|
node.innerHTML = text;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function isLink(node) {
|
|
|
|
|
return node.tagName.toUpperCase() === 'A';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function isButton(node) {
|
|
|
|
|
return node.tagName.toUpperCase() === 'BUTTON';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function isPureEnglish(text) {
|
|
|
|
|
// accept — , quotes, ® and façade too.
|
2016-07-16 06:29:42 -04:00
|
|
|
|
text = text.replace('在线例子', '');
|
2016-11-22 13:41:11 -05:00
|
|
|
|
return /^[\1-\255—’“”ç®…à\u200B]*$/.test(text);
|
2016-06-19 04:46:50 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function attributesToString(node) {
|
|
|
|
|
return _.chain(node.attributes)
|
|
|
|
|
.map(function (value) {
|
|
|
|
|
if (value.name === 'id') {
|
|
|
|
|
return '';
|
|
|
|
|
} else {
|
|
|
|
|
return value.name + '=' + value.value;
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.sortBy()
|
|
|
|
|
.value()
|
|
|
|
|
.join(';');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function isClonedNode(node1, node2) {
|
|
|
|
|
return node1.tagName === node2.tagName &&
|
|
|
|
|
attributesToString(node1) === attributesToString(node2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function indexOfSameType(node) {
|
|
|
|
|
var i = 0;
|
|
|
|
|
var aNode = node.parentNode.firstChild;
|
|
|
|
|
while (aNode !== node) {
|
|
|
|
|
++i;
|
|
|
|
|
if (aNode.tagName !== node.tagName) {
|
|
|
|
|
i = 0;
|
|
|
|
|
}
|
|
|
|
|
aNode = aNode.nextElementSibling;
|
|
|
|
|
}
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function isTranslationResult(node, prevNode) {
|
|
|
|
|
return indexOfSameType(node) % 2 === 1 && isClonedNode(node, prevNode) && isPureEnglish(prevNode.innerText);
|
|
|
|
|
}
|
|
|
|
|
})(angular.element);
|