实现了显示/隐藏原文的功能

用jqLite重构了翻译逻辑
This commit is contained in:
Zhicheng Wang 2016-05-15 21:27:57 +08:00
parent 6a4799fe2d
commit 0ee5264d19
8 changed files with 66 additions and 32 deletions

View File

@ -5,6 +5,8 @@ header(class="background-sky")
.hero-cta
a(href="/docs/ts/latest/quickstart.html" class="md-raised button button-large button-plain" md-button) 开始吧!
h2 点击“译文”可显示/隐藏“原文”,点击“原文”可隐藏自身
.banner.banner-floaty
.banner-ng-annoucement
div(class="banner-text")

View File

@ -14,3 +14,7 @@ md-toolbar(class="main-nav background-regal l-pinned-top l-layer-5",scroll-y-off
li.l-left <a class="main-nav-button" href="/news.html" md-button>新闻</a>
li.l-left <a class="main-nav-button" href="/translate/cn/about.html" md-button>关于中文版</a>
li.l-right <a class="main-nav-button" href="/docs/ts/latest/quickstart.html" md-button>立即开始!</a>
li.l-right
a.main-nav-button.md-button(ng-click="appCtrl.toggleSource($event)", href)
span(ng-if="!appCtrl.sourceVisible") 显示原文
span(ng-if="appCtrl.sourceVisible") 隐藏原文

View File

@ -15,8 +15,8 @@ script(src="/resources/js/vendor/angular-material.min.js")
<!-- Angular.io Site JS -->
script(src="/resources/js/site.js")
script(src="/resources/js/translate.js")
script(src="/resources/js/site.js")
script(src="/resources/js/controllers/app-controller.js")
script(src="/resources/js/directives/cheatsheet.js")
script(src="/resources/js/directives/api-list.js")

View File

@ -15,7 +15,7 @@ include ../_util-fns
a list of heroes, editing a selected hero's detail, and navigating among different
views of heroic data.
当然,在这个教程中,我们只完成一小步。我们这次构建的应用会涉及很多特性:获得并显示英雄列表,编辑所选英雄的详情,并在英雄数据的多个视图之间建立导航。这些特性,在成熟的、数据驱动的应用中经常见到。
当然,在教程中,我们只完成一小步。我们这次构建的应用会涉及很多特性:获得并显示英雄列表,编辑所选英雄的详情,并在英雄数据的多个视图之间建立导航。这些特性,在成熟的、数据驱动的应用中经常见到。
The Tour of Heroes covers the core fundamentals of Angular.
Well use built-in directives to show/hide elements and display lists of hero data.
@ -25,7 +25,7 @@ include ../_util-fns
Well learn to select a hero from a master list and edit that hero in the details view. We'll
format data with pipes. We'll create a shared service to assemble our heroes. And we'll use routing to navigate among different views and their components.
《英雄指南》覆盖了Angular的核心原理。
《英雄指南》覆盖了Angular的核心原理。
我们将使用内建指令来显示/隐藏元素,并且显示英雄数据的列表。
我们将创建一个组件来显示英雄的详情,另一个组件则用来显示英雄列表。
我们将对只读数据使用单向数据绑定。我们将添加一些可编辑字段,并通过双向数据绑定更新模型。
@ -59,7 +59,7 @@ include ../_util-fns
Here's a visual idea of where we're going in this tour, beginning with the "Dashboard"
view and our most heroic heroes:
这个教程中还引入了一些可视化思想放一个“仪表盘Dashboard”视图来展示我们最勇敢的英雄。
教程中还引入了一些可视化思想放一个“仪表盘Dashboard”视图来展示我们最勇敢的英雄。
figure.image-display
img(src='/resources/images/devguide/toh/heroes-dashboard-1.png' alt="英雄仪表盘的输出")

View File

@ -60,7 +60,7 @@ code-example(format="" language="bash").
## 显示我们的英雄
We want to display Hero data in our app
我们要在我们的应用中显示英雄数据
我们要在应用中显示英雄数据
Let's add two properties to our `AppComponent`, a `title` property for the application name and a `hero` property
for a hero named "Windstorm".

View File

@ -1,9 +1,8 @@
.original-english {
display: none !important;
}
.original-english-debug {
border-bottom: 1px dashed red;
border-top: 1px dashed $regal;
&.hidden {
display: none !important;
}
}
.translated-cn {

View File

@ -8,7 +8,7 @@ angularIO.controller('AppCtrl', ['$mdDialog', '$timeout', '$http', '$sce', funct
vm.showDocsNav = false;
vm.showMainNav = false;
vm.showMenu = false;
vm.showMenu = false;
// TOGGLE MAIN NAV (TOP) ON MOBILE
vm.toggleDocsMenu = function () {
@ -25,7 +25,7 @@ angularIO.controller('AppCtrl', ['$mdDialog', '$timeout', '$http', '$sce', funct
vm.showMenu = !vm.showMenu;
};
vm.openFeedback = function() {
vm.openFeedback = function () {
var configuration = {
'productId': '410509',
'authuser': '1',
@ -36,7 +36,7 @@ angularIO.controller('AppCtrl', ['$mdDialog', '$timeout', '$http', '$sce', funct
// URL hash keeps track of which method the user wants to view in the API doc.
// Refer to _api.scss (.anchor-focused) and class.template.html (where ng-class is used) for details.
vm.isApiDocMemberFocused = function(memberName) {
vm.isApiDocMemberFocused = function (memberName) {
var apiDocFocusedMember = window.location.hash.replace('#!#', '').replace('-anchor', '');
return apiDocFocusedMember === memberName;
};
@ -62,4 +62,17 @@ angularIO.controller('AppCtrl', ['$mdDialog', '$timeout', '$http', '$sce', funct
// TRIGGER PRETTYPRINT AFTER DIGEST LOOP COMPLETE
$timeout(prettyPrint, 1);
} ]);
vm.sourceVisible = debugging;
vm.toggleSource = function ($event) {
$event.preventDefault();
vm.sourceVisible = !vm.sourceVisible;
var nodes = document.querySelectorAll('.original-english');
var $nodes = angular.element(nodes);
if (vm.sourceVisible) {
$nodes.removeClass('hidden');
} else {
$nodes.addClass('hidden');
}
};
}]);

View File

@ -1,24 +1,41 @@
(function () {
var debugging = location.hostname === 'localhost';
(function ($) {
var nodes = document.querySelectorAll('p, li, h1, h2, h3, h4, h5, h6, header, a, button, small');
_.each(nodes, function (node) {
if (isTranslationResult(node)) {
var prevNode = node.previousElementSibling;
if (prevNode && isPureEnglish(prevNode.innerText) && !prevNode.classList.contains('nav-list-item')) {
if (location.hostname === 'localhost') {
prevNode.classList.add('original-english-debug');
} else {
prevNode.classList.add('original-english');
var prevNode = node.previousElementSibling;
if (!prevNode) {
return;
}
if (isTranslationResult(node, prevNode)) {
var $prevNode = $(prevNode);
var $node = $(node);
if (isPureEnglish($prevNode.text()) && !$prevNode.hasClass('nav-list-item')) {
$node.attr('id', prevNode.id);
$node.addClass('translated');
$node.addClass('translated-cn');
if (!$node.attr('title')) {
$node.attr('title', '点击译文可显示/隐藏原文;点击原文可隐藏原文');
}
node.title = prevNode.innerText;
node.setAttribute('id', prevNode.id);
prevNode.removeAttribute('id');
node.classList.add('translated');
node.classList.add('translated-cn');
$prevNode.removeAttr('id');
$prevNode.addClass('original-english');
if (!debugging) {
$prevNode.addClass('hidden');
}
if (node.tagName !== 'A' && node.tagName !== 'BUTTON') {
$node.on('click', function () {
$prevNode.toggleClass('hidden');
});
$prevNode.on('click', function () {
$prevNode.addClass('hidden');
});
}
$node.after($prevNode);
}
}
});
function isPureEnglish(text) {
// accept &mdash; , quotes and façade too.
return /^[\1-\255—“”ç]*$/.test(text);
}
@ -41,7 +58,7 @@
attributesToString(node1) === attributesToString(node2);
}
function indexOf(node) {
function indexOfSameType(node) {
var i = 0;
var aNode = node.parentNode.firstChild;
while (aNode !== node) {
@ -54,8 +71,7 @@
return i;
}
function isTranslationResult(node) {
var prevNode = node.previousElementSibling;
return indexOf(node) % 2 === 1 && prevNode && isClonedNode(node, prevNode) && isPureEnglish(prevNode.innerText);
function isTranslationResult(node, prevNode) {
return indexOfSameType(node) % 2 === 1 && isClonedNode(node, prevNode) && isPureEnglish(prevNode.innerText);
}
})();
})(angular.element);