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

用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 .hero-cta
a(href="/docs/ts/latest/quickstart.html" class="md-raised button button-large button-plain" md-button) 开始吧! a(href="/docs/ts/latest/quickstart.html" class="md-raised button button-large button-plain" md-button) 开始吧!
h2 点击“译文”可显示/隐藏“原文”,点击“原文”可隐藏自身
.banner.banner-floaty .banner.banner-floaty
.banner-ng-annoucement .banner-ng-annoucement
div(class="banner-text") 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="/news.html" md-button>新闻</a>
li.l-left <a class="main-nav-button" href="/translate/cn/about.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 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 --> <!-- Angular.io Site JS -->
script(src="/resources/js/site.js")
script(src="/resources/js/translate.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/controllers/app-controller.js")
script(src="/resources/js/directives/cheatsheet.js") script(src="/resources/js/directives/cheatsheet.js")
script(src="/resources/js/directives/api-list.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 a list of heroes, editing a selected hero's detail, and navigating among different
views of heroic data. views of heroic data.
当然,在这个教程中,我们只完成一小步。我们这次构建的应用会涉及很多特性:获得并显示英雄列表,编辑所选英雄的详情,并在英雄数据的多个视图之间建立导航。这些特性,在成熟的、数据驱动的应用中经常见到。 当然,在教程中,我们只完成一小步。我们这次构建的应用会涉及很多特性:获得并显示英雄列表,编辑所选英雄的详情,并在英雄数据的多个视图之间建立导航。这些特性,在成熟的、数据驱动的应用中经常见到。
The Tour of Heroes covers the core fundamentals of Angular. 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. 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 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. 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" Here's a visual idea of where we're going in this tour, beginning with the "Dashboard"
view and our most heroic heroes: view and our most heroic heroes:
这个教程中还引入了一些可视化思想放一个“仪表盘Dashboard”视图来展示我们最勇敢的英雄。 教程中还引入了一些可视化思想放一个“仪表盘Dashboard”视图来展示我们最勇敢的英雄。
figure.image-display figure.image-display
img(src='/resources/images/devguide/toh/heroes-dashboard-1.png' alt="英雄仪表盘的输出") 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 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 Let's add two properties to our `AppComponent`, a `title` property for the application name and a `hero` property
for a hero named "Windstorm". for a hero named "Windstorm".

View File

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

View File

@ -62,4 +62,17 @@ angularIO.controller('AppCtrl', ['$mdDialog', '$timeout', '$http', '$sce', funct
// TRIGGER PRETTYPRINT AFTER DIGEST LOOP COMPLETE // TRIGGER PRETTYPRINT AFTER DIGEST LOOP COMPLETE
$timeout(prettyPrint, 1); $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'); var nodes = document.querySelectorAll('p, li, h1, h2, h3, h4, h5, h6, header, a, button, small');
_.each(nodes, function (node) { _.each(nodes, function (node) {
if (isTranslationResult(node)) {
var prevNode = node.previousElementSibling; var prevNode = node.previousElementSibling;
if (prevNode && isPureEnglish(prevNode.innerText) && !prevNode.classList.contains('nav-list-item')) { if (!prevNode) {
if (location.hostname === 'localhost') { return;
prevNode.classList.add('original-english-debug');
} else {
prevNode.classList.add('original-english');
} }
node.title = prevNode.innerText; if (isTranslationResult(node, prevNode)) {
node.setAttribute('id', prevNode.id); var $prevNode = $(prevNode);
prevNode.removeAttribute('id'); var $node = $(node);
node.classList.add('translated'); if (isPureEnglish($prevNode.text()) && !$prevNode.hasClass('nav-list-item')) {
node.classList.add('translated-cn'); $node.attr('id', prevNode.id);
$node.addClass('translated');
$node.addClass('translated-cn');
if (!$node.attr('title')) {
$node.attr('title', '点击译文可显示/隐藏原文;点击原文可隐藏原文');
}
$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) { function isPureEnglish(text) {
// accept &mdash; , quotes and façade too.
return /^[\1-\255—“”ç]*$/.test(text); return /^[\1-\255—“”ç]*$/.test(text);
} }
@ -41,7 +58,7 @@
attributesToString(node1) === attributesToString(node2); attributesToString(node1) === attributesToString(node2);
} }
function indexOf(node) { function indexOfSameType(node) {
var i = 0; var i = 0;
var aNode = node.parentNode.firstChild; var aNode = node.parentNode.firstChild;
while (aNode !== node) { while (aNode !== node) {
@ -54,8 +71,7 @@
return i; return i;
} }
function isTranslationResult(node) { function isTranslationResult(node, prevNode) {
var prevNode = node.previousElementSibling; return indexOfSameType(node) % 2 === 1 && isClonedNode(node, prevNode) && isPureEnglish(prevNode.innerText);
return indexOf(node) % 2 === 1 && prevNode && isClonedNode(node, prevNode) && isPureEnglish(prevNode.innerText);
} }
})(); })(angular.element);