diff --git a/public/_includes/_hero-home.jade b/public/_includes/_hero-home.jade
index c6efb3e28b..a653da5d4f 100644
--- a/public/_includes/_hero-home.jade
+++ b/public/_includes/_hero-home.jade
@@ -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")
diff --git a/public/_includes/_main-nav.jade b/public/_includes/_main-nav.jade
index 1b13d2b3ce..78496379fa 100644
--- a/public/_includes/_main-nav.jade
+++ b/public/_includes/_main-nav.jade
@@ -14,3 +14,7 @@ md-toolbar(class="main-nav background-regal l-pinned-top l-layer-5",scroll-y-off
li.l-left 新闻
li.l-left 关于中文版
li.l-right 立即开始!
+ 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") 隐藏原文
diff --git a/public/_includes/_scripts-include.jade b/public/_includes/_scripts-include.jade
index bbf241cd3e..5dd3407ed7 100644
--- a/public/_includes/_scripts-include.jade
+++ b/public/_includes/_scripts-include.jade
@@ -15,8 +15,8 @@ script(src="/resources/js/vendor/angular-material.min.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")
diff --git a/public/docs/ts/latest/tutorial/index.jade b/public/docs/ts/latest/tutorial/index.jade
index e08eb54a9f..991ec9a81e 100644
--- a/public/docs/ts/latest/tutorial/index.jade
+++ b/public/docs/ts/latest/tutorial/index.jade
@@ -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.
We’ll use built-in directives to show/hide elements and display lists of hero data.
@@ -25,7 +25,7 @@ include ../_util-fns
We’ll 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="英雄仪表盘的输出")
diff --git a/public/docs/ts/latest/tutorial/toh-pt1.jade b/public/docs/ts/latest/tutorial/toh-pt1.jade
index f713e6250b..567c6a6b2d 100644
--- a/public/docs/ts/latest/tutorial/toh-pt1.jade
+++ b/public/docs/ts/latest/tutorial/toh-pt1.jade
@@ -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".
diff --git a/public/resources/css/_translate.scss b/public/resources/css/_translate.scss
index fec7ab5ab4..2005a2d154 100644
--- a/public/resources/css/_translate.scss
+++ b/public/resources/css/_translate.scss
@@ -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 {
diff --git a/public/resources/js/controllers/app-controller.js b/public/resources/js/controllers/app-controller.js
index c8f4e15bdc..246b695bcb 100644
--- a/public/resources/js/controllers/app-controller.js
+++ b/public/resources/js/controllers/app-controller.js
@@ -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);
-} ]);
\ No newline at end of file
+
+ 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');
+ }
+ };
+}]);
diff --git a/public/resources/js/translate.js b/public/resources/js/translate.js
index 671c856f97..5e850fb97e 100644
--- a/public/resources/js/translate.js
+++ b/public/resources/js/translate.js
@@ -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 — , 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);