
English: 
Thank you guys so much.
This is really awesome
to be on the stage today.
Over the past year,
I've spent a lot
of time talking
about web components,
really teaching developers
the basics of the standards
and teaching folks how to
focus on building elements.
And we're now at
this place where
we have this burgeoning
ecosystem of elements
that are out there.
There's a lot of developers
out in the open source world
who are creating
elements but also got
element sets that have been
created by the Polymer team.
We've got the core and
the paper elements.
And so we're at
this point where we
have this flourishing
ecosystem and I
think it's time for
us to start to think
about the next challenge, which
is how do we leverage that
ecosystem to actually
build real applications.
And I'm particularly
interested in figuring out
how to build compelling
experiences on mobile.
The mobile web has a
ton of opportunity,
but it's one of those areas
where for web developers,
it's always been a
challenge to create
a real compelling experience
on a mobile device.
And so when I was preparing for
this talk, what I wanted to do

Chinese: 
谢谢大家
也很荣幸今天能站在这里
过去的几年  我花了大量的时间
来谈论Web组件
传授给开发者们什么是基本的开发标准
以及教大家如何专注于构建elements
此时此刻
我们有一个正在蓬勃发展的elements生态圈
在开源社区也有很多的开发者
他(她)们在创作elements的同时
也享受着由Polymer团队开发的element集合所带来的便利
我们有core和paper elements
所以说 在这一点上
我们正处在日渐兴旺的生态系统之中 
我想是时候让我们开始思考
我们的下一个挑战 那就是
如何利用这个生态系统开发出实际的应用
并且我对如何在移动应用上创造出让人爱不释手的体验
非常的感兴趣
移动互联网拥有着大量的机遇
而对于Web开发者来说 
如何在移动端上创造出真正让人爱不释手的体验
一直都是一个挑战
所以 当我准备这个演讲的时候 我要做的

English: 
was just like pop my phone out
and look at the applications
that I use all
the time, things I
consider sort of
successful experiences.
And I wanted to go through them
and just sort of catalog what
I see as the kind of common
UI and UX expectations
in a successful app.
So what I've got
here is Twitter,
I've got Pocket Cast for
listening to podcasts,
and I've got RDO.
And one thing that struck
me as I was doing this
is if I just take
these applications
and I put them side by side,
even though each of them
kind of feels unique when I'm
looking at it in isolation,
when they're all
lined up like that,
it feels like they're just
like a ton of commonalities
in their interfaces.
And so using Twitter
as an example here,
I want to just catalog some
of those common UI patterns
that I see.
So up at the top,
we have a toolbar.
Pretty familiar.
And oftentimes, if
you've got a toolbar,
you're going to fill it
up with some icon buttons.
And below that,
you've got some tabs
for switching between content.
You've got a primary
content area,
and oftentimes,
you're going to have

Chinese: 
仅仅是掏出我的手（爪）机 翻看那些
我也一直在使用的  那些我认为
带来耳目一新的用户体验的应用
我想在它们的身上
找到作为一个成功的应用程序
该有的UI和UX的影子
在这里我有Twitter
有Pocket Cast用来听播客
还有RDO
使我感到吃惊的是
当我把这些应用拿出来玩的时候
尽管我知道把每一个应用孤立开来看时
会给人与众不同的感觉
但当我把它们一字排开
仿佛感觉他们的界面
都是如出一辙的
在此拿Twitter为例 
我想要做的仅仅是把这些常用的UI编录到一起
比如在顶端  会有一个工具栏
非常眼熟吧
而且一般的话  如果你建了个工具栏
你将会用一些图标按钮对其进行填充
往下一点儿  是一些选项卡
目的是用来进行内容间的切换
这里是主要内容区域
而且一般情况下

English: 
like an infinite list of
contents inside of there,
or you might just be
lazy loading more content
as the user is
scrolling down the page.
And down at the bottom,
you've got a secondary toolbar
for doing additional
actions of some kind.
Now, if we take
a step back again
and we line these apps
up again, like when
I was looking at
Twitter a moment ago,
it felt like a very
unique experience.
It felt kind of
aligned with its brand
and it had kind of its
own thing going on.
But again, I line
these guys up and I
can see that they all
kind of have those same UI
patterns going on.
They're all kind of doing
the exact same thing.
And the reason they
all look the same
is because they're all
built using an SDK.
So these are examples
coming from Android,
but the same is true if
you're working in iOS.
If you're building on
one of those platforms,
you already have this SDK
that's available to you,
grab a bunch of
components out of it.
Maybe you kind of tweak
them a little bit,
color them differently.
But in general,
you're using stuff
that's already available to
compose your application.
Now, on the web, we've kind of
never really had this thing.

Chinese: 
都会有无数的内容列表在里面
或者你仅仅是想在用户向下翻页时
延迟加载更多的内容
最后在底部  会有一个次级工具栏
用来做一些额外的操作
现在  如果我们往回倒退一点
回到把它们拿出来一起看的时候
也就是刚才打量Twitter的时候
你会感觉非常奇特
这些应用有自身的品牌特点
也有自身的交互体验
但当我把这些应用再次并排放在一起的时候
我发现它们都有着相似的UI模式
做着同样的工作
而它们之所以看起来很像
那就是它们都是用一个SDK开发的
所有的这些都是来自Android平台的例子
而这些例子在iOS平台上也是这么回事
如果你在其中任意的一个平台开发应用的话
SDK都是现成的
其中的组件一抓一大把
也许你只是稍作调整  改变一下它们的颜色而已
但是总体上说 开发应用的原件
都是预先准备好的
而现在  在Web开发方面  我们从未拥有过任何此类的东西

English: 
We've never had app
building primitives.
We've never had
a mobile web SDK,
and I think it's time
for that to change.
And I really think
that the way that we're
going about doing this is using
Polymer and Web Components.
So my goal today is to teach
you how to build mobile web
applications using
these new technologies.
And I basically split
this up into four parts.
[? The very ?] part, I'm
going to show you just
how you can structure the
UI for your application,
then we're going to look at
how you can transition from one
state of your
application to the next.
After that, we're
going to look at ways
to make sure your application
is performant, because that's
really crucial for a
mobile application.
And lastly, we're
going to look at ways
you can make sure your
application runs offline
because if your mobile
app doesn't run offline,
then you really don't
have a mobile app.
People are oftentimes
on their mobile devices
when they're in low connectivity
to no connectivity situations.
So it's got to
run offline for it
to be a real, compelling
mobile app experience.
Let's start with structure
and just think about ways
that we can compose the
UI for our application.

Chinese: 
更没有用于应用开发的原型
我们也从来没有一个移动端web的SDK
我想是时候要改变一下这种现状
并且我觉得真正能够胜任这种改变的
应该就是使用Polymer和Web组件了
所以我今天的目的就是要教大家
如何利用这些新技术去开发移动端的web应用
大体上我把内容分成了四个部分
第一部分  我将向你们展示
怎样为你的应用构建UI
接下来我们将要看看
如何从应用的一个状态过渡到另外一个状态
此后  我们将专注于
如何优化应用的性能
因为对于移动应用来说这非常重要
最后的最后 让我们谈谈
如何确保你的应用在不联网的情况下也可使用
因为如果你的移动应用不能做到脱机可用的话
那根本就算不上是移动应用
人们经常在没有网或者是网络不好的情况下
使用移动设备
所以说能够离线使用
是创造一个给人以流连忘返用户体验的前提
我们先从Structure讲起
想一想我们为应用布置UI的方式

English: 
And really, that's the
key word here-- compose.
What I want to do is I'm going
to take as many preexisting
elements from the Polymer
core sets to the paper sets
and I want to bolt them together
to build my application.
So this is the app
that we're going
to be working from today, just
a really simple contacts app
that I threw together.
And I'm trying to utilize
a lot of the same patterns
that I was showing in the
previous successful apps
that I had before.
So you've got the toolbar at
the top with some icon buttons.
You start scrolling
around, you're
going to get this sort of
infinite list of content
inside of there.
You've got a drawer panel that
you can pop out for your menu.
Clicking on any
one of the contacts
is going to do kind of
like an animated transition
to show you that
person's contact details.
I get it's really nice, cool
condensing header effect
as I scroll around.
And also, I've got a little
floating action button
down there in the corner.
I can click that, pop
open another screen.
These are all
animated transitions
that I'm using here.
Now, if you've seen
me talk before,
you've probably seen me start
off by using this element.
Anytime I'm building
an application,
it seems like I'm
always starting off

Chinese: 
是的  关键就在这  compose
我将要做的就是从Polymer的core elements以及paper elements集合中
获取一些先前已有的element
用它们联合来开发我的应用
这就是今天我们将要开发的应用
只是一个简单的联系人通讯录应用
把那些element联合在了一起
并且我会尽量采用不少和先前  我所讲过的
那些成功应用相同的样式
你看工具栏上有图标按钮
你开始上下滑动
为了查看这些无数列表里面的内容
这有一个抽屉面板  你可以弹出菜单
点击其中任意一个联系人
会有一个过场动画
向你展示详细的联系人信息
随着我来回滚动
会有非常棒的头部收起和展开的效果
并且这还有一个浮动的动作按钮
在右下角
点击这个按钮  弹出并打开另一个界面
这些就是我所使用的全部过场动画效果
如果你之前听过我的演讲的话
你可能已经见过我在开发应用的过程中
都会用这个element作为开始
你也可能会感觉

Chinese: 
我经常会以core toolbar element作为开始
虽然说它只是一个非常基本的容器
但规定它的子element使用Flexbox式布局
这也是你打造一个页面
所踏出的第一步
而且因为composition才是今天真正的主角
所以我想要做的第一件事就是
把一些我想要的额外的element放在这里面
为我的工具栏来构造UI
所以我把一个paper icon button放在那
赋予它图标的属性
用来实现hamburger菜单按钮的效果
方便等会我滑动屏幕唤出菜单
这里还有一个div属性
来显示应用的标题
而core toolbar蛮赞的一点在于
它使用Flexbox式布局
我们可以好好利用一下
在Polymer中称这些东西为布局属性
而我可以做到的就是
告诉我的工具栏标题
我希望它能尽可能地
填充满工具栏里面的空间
这是个易用的技巧
因为它意味着
我可以把控制按钮固定在另外一边
我想要做的其实是添加一个背景菜单
这样我才能有类似于设置以及反馈啊之类的东西

English: 
with this core
toolbar element, which
is just a really
simple container.
It lays out its
children using Flexbox
and it's a really
good place to get
started with one
of your screens.
And because
composition is really
the name of the game,
what I want to do first
is I want to just throw
some additional elements
inside of here, and I
just want to compose
the UI for my toolbar.
So I've dropped a paper
icon button inside of there.
I've configured it
with an icon attribute
to give me the hamburger
menu from that application,
and so I'm going to
slide out my menu later.
I've also dropped a
div inside of here
for the title of my application.
Now, one of the cool things
about the core toolbar
is that since it uses
Flexbox, I can kind of
take advantage of
that a little bit.
There's things called layout
attributes in Polymer,
and what I can do
is I can actually
tell the title of
my toolbar that I
want it to flex to take
up as much space is
it can inside of the toolbar.
This is a really
handy trick to know
because it means that
I can then pin controls
to the other side of my toolbar.
What I want to do
here is actually
add a little context
menu so I can
have things like
settings and feedback.

Chinese: 
为了实现那个  我将要用另外一个element
它叫做paper-menu-button
它本身非常的有趣  因为它
真的没有做任何事情
它是无用的
如果你只是把paper-menu-button标签
放在页面上  真的是什么都没有
它仅仅是在你开始compose它里面的
其他elements时才发挥其作用
就看你怎么去使用它了  
所以我现在在那里
创建了另一个paper icon button
用来让用户点击
然后我把paper drop down放在
paper icon button下面
在这里实现一个小矩形动画
所以  当菜单展开的时候
它仿佛就像从角落里走出来一样
朝向页面的中心展开
其中的halign属性
是为了标明动画该从哪个方向开始
所以在这里  我们定义的动画方向
是从页面的右边缘延伸至屏幕中央
最后  我在这里面放一个core menu
实现一些类似于Feekback接收用户反馈之类的
这样的实际菜单项
这时候你会惊喜地发现
每一个我放在paper menu button里面的element

English: 
So to do that, I'm going to
use another element called
paper-menu-button, and
paper-menu-button's
pretty interesting because
by itself, it really
doesn't do anything.
It's kind of useless.
If you just put a
paper-menu-button tag
on the page, you
get really nothing.
It only really
comes into its own
when you start composing
other elements inside of it.
That's really how you
unlock the potential of it.
So I've got another
paper icon button
that I've thrown inside
of here, and that's
going to give the user
something to click on.
Then I'm going to throw
in a paper drop down,
and that's going to give me
this little animated rectangle
thing up there.
So when the menu
expands, it's going
to kind of like come
out from the corner,
expand towards the
center of the site.
The halign attribute
that I've thrown
on there is going to
indicate which direction it
should animate from.
So here, we're
telling it to animate
from the right edge towards
the center of the screen.
Lastly, I'm going to throw
a core menu inside of here,
and that's going to give me the
actual menu items that users
are going to select for
my sending them feedback.
Now, the cool thing
here is that each
of those elements that I threw
inside of my paper menu button

English: 
is useful on its own.
I can use core menu elsewhere
my site if I need a menu.
What's awesome,
though, is when I
start to compose
these things together,
I get different interesting
complex behaviors.
And it's also
important to point out
that I didn't write any CSS or
JavaScript to make this happen.
I just nipped together
these-- oh, yay.
Thank you, [? Demetri ?].
These elements just know
how to work together
because they're app building
primitives, which is awesome.
And once I'm happy with
the look of my toolbar,
then you take all of this markup
and I could throw it inside
of another element
called core-header-panel.
And the core-header-panel is
just a really simple container.
It's got a header section
up at the top, which
will hold the toolbar,
content area down below.
And the cool thing about
the core header panel
is it only really cares about
managing the scroll behavior
from my application.
If I put a toolbar
inside of it, it's
going to make sure
that that toolbar stays
sticky up there at the
top of the document

Chinese: 
其自身都是有用的了
通过使用core menu我可以在页面的其它地方创建菜单  如果我需要一个菜单的情况下
这简直棒极了
当我开始把这些东西组合在一起的时候
我获得了很多不同又十分有趣的交互效果
而且还有重要的一点要指出
我没有写任何的CSS或JavaScript代码  来实现这一效果
我仅仅是把这些捏合到一起 oh yay
谢谢
这些element知道如何一起工作
因为它们是应用开发的原型 酷极了
一旦我对我自己工具栏的外观满意了
那么接下来我们把所有的标记
放进另一个叫core-header-panel的element里
core-header-panel仅仅是一个包含标题区和内容区的简单容器
标题区默认保持在页面的顶部
内容则在其下方
拿core-header-panel很赞的地方来说
它仅仅只专注于管理
应用的滚动行为
如果我把工具栏放在core-header-panel里面
它会确保工具栏
一直都固定在文档的顶部

English: 
and all my other content is just
going to move underneath it.
Again, no CSS or JavaScript
to make this happen.
These are just
smarter primitives.
They know how to work
together like that.
Now, when someone's actually
looking at one of my contacts,
I want to have this cool, big
shot of Addy Osmani's face
basically, and I want it to
do this cool animating effect.
So as the person
is scrolling down,
it kind of collapses,
and it's sort
of crossfading with
the background image.
And to do that, I'm using a
cousin of the core-header-panel
called the
core-scroll-header-panel.
It's basically the
same component,
but it adds this nice
condenses attribute,
and it gives me that
kind of cool effect.
Now, once I have the different
screens for my mobile site laid
out in a way that I like
them, I can drop all of this
into another element
called core-drawer-panel,
and that's going to
give me a responsive
scaffold for desktop and mobile.
And the way this
element works, it's
basically got a drawer area.
Any content that I
place inside of there
is going to end
up in my sidebar.
It's got a main area.
Any content that I
place inside of there
ends up in the
primary content area.

Chinese: 
而且其他的内容只在它的底下移动
再一次  没有写任何CSS及JavaScript的代码
因为这都是高级些的原型
它们知道如何像刚才那样一起工作
现在  假设有人在点开我其中的一个联系人
我想要有像这个一样酷酷的Addy Osmani的头像封面效果
这是我想要实现的漂亮动画效果
随着联系人向下滚动
页面开始渐渐展开
与此同时  伴随着背景图片的淡入淡出
为了实现这个  我使用了一个core-header-panel的表亲类
叫作core-scroll-header-panel
它们基本上是相同的组件
但是core-scroll-header-panel增添了很棒的condenses属性
所以才有刚刚这种酷炫的效果
现在呢 我已经搞定了几页还不错的页面
接下来我要把所有的这些统统放进
另一个叫core-drawer-panel的element里面
目的是为移动端和桌面端
构建响应式框架
而且这个element生效的方式  一般是有个抽屉区
所有放在里面的内容
都在侧边栏中
这是主内容区
所有放在主内容区里的内容
都以次级内容去作为结尾

English: 
And the cool thing
is, this element
is responsive by default.
So if I'm on my desktop and
I just start dragging it out,
you'll see the drawer
panel opens there.
I can open and close it.
I drag this thing out, and
when I hit a certain size,
the toolbar just
pops out for me.
This is really nice.
Again, I'm not writing any
breakpoints or media queries
to make this happen.
The element's just responsive by
default, which is really nice.
Now, at this point, I've built
the skeleton of an application.
I've kind of shown you
how to put the shell
around everything, but
what we're still missing
is the lifeblood
of our application.
We're missing the content.
And when I'm showing
these apps earlier,
I mentioned that oftentimes
what they're going to do
is they're going to do
like an infinite list,
or of a lazy load of
content so the user can
keep scrolling through
all of their tweets,
or all of their albums,
and things like that,
and we can achieve the same
thing in our application using
an element called core-list.
And core-list is one
of my favorite elements
because I feel like it's
sort of the thing that
knits all the scaffolding
and the content
together in this way
that I really love.
The core-list is basically
a virtualized infinite list.

Chinese: 
注意看这个element自响应式的
如果我在桌面上开始向外拖拽
你会看到这边抽屉面板已经打开
我可以随意地开开关关
继续拖拽  一旦到达预设的大小
工具栏会自动弹出
非常的棒
再一次  我没有写任何断点或者是CSS media queries
就让此得以实现
element默认就是响应式的  非常棒棒哒
现在 我已经把应用的骨架搭好了
也已经向你们展示了怎么放上外壳
但是我们的应用
显然还缺少最核心的东西
那就是我们还没有内容呢
并且之前在我展示这些应用的时候
我一直在说  这些应用要做的事情是
展示一条长长的列表
亦或是延迟加载 所以用户才能让他们的推文
也可以是相册或者其他之类的东西
一直从头到尾  来回滚动
我们可以通过一个叫core-list的element
在我们的应用上实现相同的效果
core-list也是我最喜爱的element之一
因为从某种程度上说我觉得
core-list把所有的框架和内容
都用我喜欢的方式整到了一起
core-list是一个虚拟化的infinite list

English: 
You connect it to
a data provider
and then it stamps
out a template
for every single instance in
that data provider's array.
So here, I'm saying
list.data equals some array.
I've got objects
inside of that array.
Each of those
objects has a name.
And inside my core-list,
I have a template element
and I'm just binding to
each of those instances
as they come in.
It gives me this really,
really performant infinite list
so I can go through
all of my contacts.
Now, as I was building
my application,
I kind of came
across this thing--
which I'm going to
share with you as a tip
if you want to go out and
start using core-list yourself.
One of things that
core-list does
is it recycles its children.
That's actually how
it's so performant.
It makes a fixed set of
children and as they're moving,
it's pulling them back
around the other way.
So if you have image tags
inside of your core-list,
you can end up in a situation
where you're basically
racing the network and you're
having stale images fly
past the screen, and
then they catch up
and change, which
sort of looks weird.
So I found that there's an
element called core-image

Chinese: 
当你把它和data provider连接起来  然后它会为在data provider数组里面的
每一个single instance压制出一个template
所以在这里list.data就等同于一些array数组
array数组里面有一些对象
每一个对象对应着一个名字
并且在core-list里面  有一个template element
我只是将其绑定起来
就可以得到性能不错的长列表
这样就能遍历所有联系人了
在我开发应用的过程中
我遇到了这样一件事
在此作为一条经验和你们分享
如果你开始使用core-list的话
需要注意的是core-list会回收其子元素
这也是它为何性能出众的原因
在子元素移动过程中  core-list会使其固定
然后再用其他的方式把它们打回原形
所以如果在core-list里有图像标签的话
只要网络慢一点
你就会看到
图片更新跟不上你的速度
看起来怪怪的
但这有一个叫做core-image的element

Chinese: 
用它就可以防止应用加载过期的图片
这非常的简单
你只需把它嵌套在这里
给它一个预加载属性
这样它就会告诉应用说
如果我正在加载图像
我是不会去显示之前这的过期图像的
我只会显示一些背景颜色
所以我们才能得以
有这样炫酷的联系人列表
我们在和网速比谁快
你可以看见这些图片一直在加载
但是你看不见过期的图像  这非常的棒
在开发过程中我还发现一件重要的事儿
一定要将core-list的scrollTarget
设置到core-header-panel-scroller上
我知道这理解上可能会有点困难
但是我希望大家能记住到一点
如果你开始使用这个
内部流程基本是这个样子
core-list这个element
会监听由core-header-panel发出的scroll事件
它们俩可以愉快的玩耍在一起
现在  你可以通过两种方式实现这个
你要么在JavaScript里指定scroll target

English: 
which you can use to
prevent stale images
in your application.
It's pretty easy.
You just drop it in here.
You give it a preload
attribute, and what
that does is it says, hey,
if I'm loading an image,
I'm not going to display
the stale image that
perhaps was inside
of here before.
I'm just going to display
a little background color.
And so what we can do
now is we can actually
have this cool contacts list.
We can sort of
race the networking
and you can see the
images loading in,
but what you're not seeing is
stale images, which is good.
The other thing that I
discovered as I was doing this
is that it's really important to
make sure to set your core-list
scroll target to your
core-header-panel-scroller.
I know that this is a
little bit of a rough edge,
but I wanted to make
you guys aware of it
if you're going to go out and
start hacking on these things
today.
Basically what
happens when you do
this is you're
telling the core-list
to listen to the scroll events
that the core header panel is
firing and that way, the two
can work together in harmony.
Now, there's two ways that
you can go about doing this.
You can either set the
scroll target in JavaScript.

English: 
You could say list.scrollTarget
equals hPanel.scroller,
or you can do this with bindings
if you want to be really fancy
and impress your friends.
You could just say scrollTarget
equals hPanel.scroller.
Now, this is one of those
things which, again,
I think it's a little
bit of a rough edge.
Perhaps we might be able to
clean this up in the future
so that you don't have
to wire this up yourself,
but I wanted to
make you aware of it
because it was like the
first thing I wanted to do
was put one of those
lists inside of one
of those fancy
headers, and I needed
to set up this linkage
to make it all work.
Now, through the beauty of
composition, I've taken my list
and I've thrown it
inside of my scaffold,
and I have this really,
really cool application now.
Now, I want to give
you a quick recap
of what we have inside of here.
So up at the top, I've
got a core toolbar.
After that, a paper-icon-button,
a paper-menu-button
for my contacts menu.
I've got a
core-header-panel, which
is controlling the scroll
behavior for my home page.
I've got a
core-drawer-panel, which
gives me that
responsive scaffolding
so it works on
desktop and mobile,
and I've got a core list for
my infinite content provider.
Now, one thing
that's really cool

Chinese: 
像这样list.scrollTarget=hPanel.scroller
要么你也可以通过数据绑定这种神奇的方式
来惊艳你的朋友
即scrollTarget=hPanel.scroller
再一次  
现在听起来可能会有些晦涩难懂
在未来  我们可能会让它变得更加简洁
这样就不用手动去把它们链接到一起了
但请大家注意
因为我们要做的第一件事
就是把这些list中的某个
放入某个header中  再设置个链接
好把它们都连接起来  这样才能生效
至此  成功运用composition的魅力
我们得以把list放入了scaffold里
打造出这样一个炫酷的应用
现在  让我们简单概括一下这都有什么
在顶端  有个core-toolbar
其次有paper-icon-button和paper-menu-button
在联系人菜单里
这有一个core-header-panel
控制主页的滚动行为
还有core-drawer-panel
构建响应式布局
所以才能在桌面和移动端都能使用
以及和Infinite content provider彼此绑定的core-list
有意思的是

Chinese: 
一旦你开始感觉你的应用初见起色
有模有样的时候
你就会开始想着更好地打造它
比如说看到此情此景  我就在想
也许给工具栏再加些CSS
或者是往list里添加些内容
这样仿佛就和Inbox
差不多了耶
所有的部件确切的说都是相同的
我们仅仅只是微微调节了一下它们的外观
换换颜色  增加一点儿内容
但是我们却获得了完全不一样的体验
而且core-list支持自适应高度
所以这就这意味着
我们不必过分的苛求相同大小
我们可以试试卡片式风格
而且如果我们这样做的话
体验就会有点儿像Google plus
再一次  我们的外观没有发生根本变化
依旧有一个core-toolbar和paper-icon-button
以及paper-menu-button还有header-panel和core-panel 最后还有core-list
所以说我们的外观保持了原样

English: 
to do once your application
has reached the state where you
feel like it's kind of
shaped up a little bit
is to think about ways
that you could change it.
And if I look at this
and I just imagine
perhaps applying a little
CSS to that toolbar
and perhaps adding a little
bit more content to the list,
then I'm really not
that far from something
that looks a lot
like Inbox, right.
All the parts remain
the exact same,
we're just tweaking slightly the
appearance of them-- changing
some colors, adding a
little bit more content--
but we've now got a very
different experience.
And because the core list
supports variable height
content-- meaning that
our rows don't all
have to be the exact
same fixed size--
we can think about throwing
cards inside of here.
And if we do that, then we have
an experience that looks kind
of like G+.
And again, none of my
markup actually changed.
I still have a core-toolbar, I
still have paper-icon-button,
still have paper-menu-button,
header-panel, core-panel,
and core-list.
So my markup remained
the exact same.

Chinese: 
唯一发生变化的  就是放在应用里面的
那些精彩纷呈的内容
我想  这就是composition的力量
当我们有一个架构优良的移动端SDK的时候
我们能开发出给人以不同体验的非凡应用
仅仅通过适当的将模块进行组合
或者是微微调节一下
我觉得这很不得了
好  让我们回到刚才的联系人应用
我们已经得到了一个基本的页面
但是我还没有向你展示如何从一个状态移动到
另一个状态  这对很多人来说是个难点
他们开始构建组件并感到非常兴奋
然后他们把这些组件整合到一个页面里
然后他们会想该如何从一个状态
过渡到了一个状态  就是说该如何做转换呢
这是我们正在解决的问题之一
但是我觉得我们已经弄出来了
一些非常酷的东西
这是我之前向你们展示过的我认为很棒的element
我在它上面放了一个演示用的图案
虽然这只是个小实验
但它真的非常赞让我忍不住晒一晒
这是一个叫做core-animated-pages的元素

English: 
The only thing that
changed was the content
that I'm placing inside of
it, which is pretty cool.
Now in my mind, this is
the power of composition.
When we have a mobile SDK
that's full of these really
good generic building blocks,
we can build vastly different
experiences just by arranging
them differently and tweaking
them slightly.
I think that's huge.
So let's go back to our
contacts app for a second.
We've got the basic pages
kind of figured out,
but I haven't really shown
you how to move from one state
to the next, and this is a
dilemma for a lot of folks.
They start building components,
they get really excited,
they throw them
together on a page,
and then they're like,
how do I go from point A
to point B. Basically,
how do I do transitions?
And this is one of those
areas where we're still
working on it, but
I think we've got
some really cool
stuff in the pipeline.
One of the elements that I've
shown before which I think
is really awesome-- I put this
little experimental badge on it
because it also is a
little experimental--
but it's so freaking
cool I like to show it.
It's this element called
core-animated-pages,

English: 
which gives you a pluggable
system for transitioning
of one state of your
application to the next.
And basically, the
way this works is I
put some sections inside
of my core animated pages.
I configure its
selected attribute
to tell it which section should
be displaying at the time,
and I give it a transitions
property and I tell it--
or sorry, transitions
attribute to tell it
which transitions
I would like it
to play as it moves from
one state to the next.
And with basically
just that I've wired up
this is really cool
system for animating
through different states
in my application.
So inside of my app, my markup
kind of looks like this.
I've got a whole bunch of markup
that makes up every single page
and it's all kind of
composed together.
And so the way that
I'm going to transition
from one state to the next is
actually take all this markup
and turn each section of my
application into a custom tag.
Keep all that markup,
make an element out of it.
Then I start nesting
those elements
inside of core-animated-pages.
So I start with
my contacts page.
I drop in an info page for
when you click on a contact

Chinese: 
它提供了一个可组合的系统
用于从应用的一个状态转换到另一个状态
它的基本使用方式是把一些section元素
放到core-animated-pages元素中
我配置了它的selected属性
好告诉它一开始应该显示哪一个section
我还给它加了一个transitions属性
transitions属性是
用来声明从一个状态到另一个状态
要做什么样的转换
就像这样  我把他们装好了
这真是非常赞的系统
在我应用中的不同状态之间实现了动画效果
这样在我的应用中标签看起来就是这个样子的
我得到了构建每个页面的一大堆标签
所有这些组装到了一起
那么我现在开始做状态转换
就是移除所有这些标签
然后把应用中的每个section变成一个自定义标签
保留所有标签  创建一个它的元素
接着我开始把所有这些自定义元素嵌入到
core-animated-pages元素中
我从contacts-page开始
当你点击联系人的时候放入一个info-page

English: 
and you actually can
see their profile.
So I created a little
custom transition here
called fade scale.
It's on my info page
as an attribute.
It's also in the
transitions attribute
for core-animated-pages.
So now when you click
on a contact, which
is going to animate up,
so you're adding there
and then it goes away.
And again, for the page
where I add a user,
it's basically the same thing.
I nest that element
inside of here.
I give it a transition.
I add that transition to
animated-pages transitions
attribute.
I click on my floating
action button now, pops up.
I can add a new user if
I want and it goes away.
Now, another tip that I
want to share with you
is something that I came
across as I was building this.
Core animated pages
does this thing
where if an element
is not displaying,
it's going to make it display
none, which can totally
screw it up if it's trying
to figure out its height
or do anything like that.
So this magical event here
called core animated pages
transition prepare,
which is the longest
this event name in the
history of the world.
But this event
does magical things

Chinese: 
你就可以看到他们的详细信息了
所以我在这里创建了一个
叫做fade-scale的转换
它作为info-page的一个属性出现
同时它也用作core-animated-pages的
transition属性
现在当你点击一个联系人时
动画就出现了  如果你返回
它就消失了
接下来对于添加用户的页面
基本上也是一样的
我在这里嵌入那个元素
给它加上一个转换属性
在animated-pages的transition属性中也加上
现在我点击浮动按钮  就会弹出
我就可以添加新用户或者返回
现在我想要和大家分享另一个技巧
是我在构建这个的时候偶然想到的
Core animated pages做了这么一件事
如果一个元素当前没有被显示
它将会被设置为 display none
这时如果要计算它的高度或类似的事情
就有麻烦了
所以这里有个叫做
史上最长事件名
但是这个事件可厉害了

Chinese: 
因为它是在你的元素从display none
到display block的时候触发的
这意味着你可以用它来做所有
你需要确认测量到
的正确高度和类似的事情
我知道你们看到这个的时候
会觉得这都什么鬼
我也觉得不够好
这是我们团队
已经意识到的问题之一
我们正在想办法来改善它
这样你就不必做这些自我欺骗的事情了
但再一次  我提请大家注意
如果你在跟着看这个视频
或者事后想要自己尝试和实现这些
你知道应该如何去做了
现在我有了这个网站的所有section
它们有动画效果  跑起来特帅
但它们仅仅是个动画效果
我们并没有真正地改变状态
我们还有另一个要点路由没说
这经常出现
开发者总是喜欢问在Polymer中如何实现路由
这里Polymer和Webfluenz并没有提供实际的方法
我们不会告诉你具体如何做
并不要求你必须怎么做

English: 
because it basically fires the
moment that your element goes
from being display none
to being display block.
And that means that you
can then do all the work
that you need to do to make
sure that things are measured
and have the right height
and everything like that.
Again, this is one of the things
that I'm sure if you see this,
you're like dude, that
feels like a wart,
and I totally agree.
I think you're right.
And this is one of
the things that I
know the team is
aware of and we're
going to work on to see if we
can actually smooth this out
for people so you don't have to
do all that finagling yourself.
But again, I wanted to
make you aware of it
so if you're following along
with this video or something
afterwards, you want to try and
implement this stuff yourself,
you know how to do it.
So at this point, I have all the
sections of my site together.
They animate, they
do really cool stuff,
but really that's
just animation.
We're not really changing
the state, per se.
We're missing the other half of
the puzzle, which is routing,
and this comes up a lot.
Developers are always like,
how do I do routing in Polymer?
And Polymer and Webfluenz don't
really have an opinion here.
We're not going to
tell you specifically
you have to do routing this way.

Chinese: 
事实上这上面有两种处理方式
你可以用JavaScript命令式指定
或者你可以用元素声明式地指定
我将给你展示这两种方法
然后你可以决定你喜欢哪种方式
如果你想用命令式路由
就像这样
就像看上去一样简单
使用一些路由库处理路由改变
这里我用的是flatiron库
所以当匹配了一条路由   我告诉
core-animated-pages改变它当前选择的页面
这种方式非常直接
用JavaScript方式指定路由有一个好处
你可以进行细致入微的控制
 如果路由里有参数的话
可以很容易的进行匹配
或者是
获取更多的数据
给页面传递参数
就像这样
参数一进来就做出响应
还有些有意思的事
非常的酷
在我演示时并没有用到
我想这是一个好主意
未来也许会
应用的更加广泛
这就是lazy loading import

English: 
There's really two ways
that you can go about this.
You can do it
imperatively in JavaScript
or you can do it
declaratively with element.
And so I'm going to show
you both approaches,
and you can decide
which you prefer.
So if you're going
the imperative route,
looks something like this.
It's really as simple
as just listening
for a route change using
some sort of routing library.
Here, I'm using flat
iron director library,
so when I hear a route match, I
tell core-animated-pages, hey,
change whichever page
is currently selected.
It's pretty straightforward.
Now, one of the nice things
about routing in JavaScript
is it gives you pretty fine
grained control if you want it.
So if there's
parameters in my route,
I can catch those when
the route matches.
I can go fetch more
data if I need to
and feed that to the
page, or I can just
pass those parameters
to the page itself,
be like, here you go, here's
the parameter that's coming in,
and change.
So some interesting stuff there.
One thing that is pretty cool,
which I wasn't actually using
my contacts as I
experimented with it.
I think it's a really cool idea.
It's something
that we're probably
going to be using a
lot more in the future
is this notion of
lazy loading imports.

English: 
So actually, let's say
you've got part of your site
that's four or five
pages deep, someone
doesn't need all of those
components right away.
There's this
mechanism in Polymer
called Polymer
Import which you can
use to just sort of
dynamically import things.
So you can add that
to your router.
You can say, hey, when
that route matches,
that far away route, let's
import some of that new stuff,
maybe throw a loading
screen up during that time.
And when it's ready, Polymer
Import gives us a call back
and we can change that page.
So that's the JavaScript
way of doing it.
There are also projects out
there which do this in markup
with elements.
In particular, there's
this really cool one
called app-router
by Erik Ringsmuth.
It allows you to
handle URL changes
and update the views
in your application.
It handles hashchange URLs,
as well as HTMLs history API.
So you get either
flavor that you prefer.
The other cool thing is that
it actually already supports
core-animated pages and
doing lazy importing
with Polymer import.
But it does all that
under the hood for you
so you don't have
to do it yourself.
So again, two options.
It really depends
on which flavor

Chinese: 
我们假设
页面有四到五层
这时候用户不需要后面看不到的页面
在Polymer里
有一个叫Polymer Import的组件
用以实现动态加载
把它加在路由上
当路由匹配时
就加载一些新的内容
期间你可以在这放个加载界面什么的
当一切准备就绪
Polymer会给一个回调来更新页面
这就是用JavaScript式
你也可以通过
元素声明式地指定路由
这里有一个由Erik Ringsmuth开发
叫做app router的神奇东西
它能帮你处理URL变化
更新应用视图
监测URL的hash变化以及Html的历史API
这样就又有一个可选的方案啦
还有一个超棒的事情是
它早已支持core-animate-pags和Polymer import中的lazy importing元素
在后台就帮你打理好了一切
根本不用你亲自动手
再一次  两种选择
挑一个你喜欢的

Chinese: 
我倒是建议你两个都试一试
选一个表现最好的
在这一环节  我们把所有的组件都缝合到了一起
为应用添加了很多有趣的动作
它看起来棒极了
现在是时候优化性能了
对不起  放错幻灯片了
让我们开始吧
我喜欢这个表情
我们搞不定Polymer的地方
通常是路由文件的大小
你之前八成听到过
Polymer太臃肿
等等之类的话
我们可以通过很多方法来进行优化
首先就是从x-gif的缔造者
Glen Maddern大神那里搞来的
最牛的custom element
谢谢
如果你还没感受过x-gif
那么应该去花时间去看一看了
所以一个有效的方法
就是有选择地加载polyfill
你不必在每个平台上都加载polyfills
这是一些支持polyfill的平台

English: 
you prefer, but definitely
try both out and see
what you like in
your application.
So this one, I feel like I have
my application pretty sewn up.
It does all sorts of really
interesting behaviors.
I'm pretty stoked
with the way it looks,
and now it's time to
focus on performance.
Sorry, that's the wrong
slide-- performance.
There we go.
I love that lady's face.
One of the areas that people
run afoul with Polymer
often is the route file size.
You'll even hear this.
People will be like,
Polymer's too big.
It's just bloated, whatever.
And there's some ways that
you can mitigate this.
First is this thing that I
stole from Glen Maddern, who
is the creator of x-gif, which
is the most important custom
element ever made.
Yeah.
Thank you.
If you haven't seen x-gif
you should take some time
and spend it with x-gif.
So one really quick
win that you can get
is just conditionally
loading the polyfills.
You don't have to load the
polyfills on every platform.
There are platforms
that support them.

Chinese: 
Chrome  Opera  还有Android上的Chrome
Firefox也将很快提供支持
所以我们要做的
仅仅是去核实每一个页面在不同标准下
能否都能得以正常工作
可以的话就继续下一步
否则我们就加载polyfill
这就是能为你节省流量的高招
请务必有选择地加载内容
这是其一
还有件事
你需要打开你的开发者工具
实时监视着每一个页面
这里我打开我那个
引以为豪的联系人应用
点击上面的网络面板
一共有109个请求  有点儿多啊
并且共加载了943KB
而且我这还是没有加载图片
仅仅是一些代码
啊噢  玩脱啦
让我们看看这109个请求都有啥
这里面到底发生了什么

English: 
Chrome supports it, Opera
supports it, Chrome for Android
supports it, and hopefully
very soon Firefox.
So all we're doing
here's is just
checking to see if the different
standards are implemented
on the page.
If they are, we just
move right along.
If they're not, then
we load the polyfills.
So this is an easy
way to save yourself
quite a bit of kilobytes.
Just conditionally load stuff.
That's one trick.
And the other thing
you've got to do
is you've got to actually
pop open the dev tools
and you got to make sure that
you're inspecting your page.
So I looked at the
contacts app after I
built it and was
very proud of it.
I popped open the
network panel there
and I saw that I was making
109 requests-- which is a lot--
and I'm loading 943
kilobytes of stuff.
Now, keep in mind, I
have excluded the images
from this network panel,
so that's just my code.
Holy crap, that's a lot.
I recognize that 109
requests for some of you
might be concerning.
But what's going on
there is under the hood,

Chinese: 
关键就在于插入的那些element
这些元素具有依赖性
它们再引入它们的依赖  如此循环
它们就像一棵树一样
在应用里越长越大
为了解决这个问题  我们造了一个叫Vulcanize的工具
Vulcanize是一个
把你所有的import都串在一起的工具模块
将所有的JavaScript和CSS
都压制到一个文件里
这样应用仅需加载一个文件就可以了
你可以通过nodejs获取这个模块
如果你不喜欢用命令行来操作
你也可以通过构建工具Grunt和Gulp
获取它
而对于刚才的这个联系人应用  我用的是Grunt
仅需设置一次  然后放手不管就可以
简化工作  节省时间
这太棒了
现在  经过vulcanize化之后
重新把它推送到server上
应用请求只有3个  效果显著

English: 
I'm importing elements.
Those elements
have dependencies.
They're importing
their dependencies,
and so on and so on.
It's basically this
whole tree that's
growing out of my application.
And so to mitigate
this, we created
a tool called Vulcanize.
And Vulcanize is a module
which will actually
take all of your imports,
concatenate them together,
smoosh them all together,
take all your JavaScript
and your CSS, mash
it all into one file,
and allow you to
just load that one
thing into your application.
Now, it is available
as a node module,
but if you are not so stoked
about doing everything
on the command line, it's
also available in a Grunt
task and a Gulp task.
And for the contacts app,
I just used the Grunt task.
I set it up once and I just
never thought about it again.
It just runs every
time I'm about to push
to production, which is cool.
Now, after I
Vulcanize and I make
sure to put my stuff on a server
that supports [INAUDIBLE],
my application is
now three requests,
which is a significant change.

Chinese: 
而且把文件加载也降低到了114KB  太棒啦 
这里边包含了所有的应用代码
所有的JavaScript以及CSS
以及所有的HTML
我们把它降到了114K
这个数字 在Polymer0.8版本中 
还可以变得更小  更简洁  酷毙了
至此  我们最后要做的
就是准备要将其打包
发布出来
但是别忘了确保它能够脱机使用
老生常谈  如果你的移动应用不提供离线支持的话
怎能谈得上算是移动应用
今天我们讨论了不少跟Service Worker有关的东西
我还是想再说说
因为它实在是酷的要冒烟儿了
我所做的就是把Service Worker添加到应用里面
简单粗暴
看看Service Worker是否存在
存在的话就安上
还有件重要的事要说说
在我安装Service Worker时碰到的
务必要确保使用root scope
这样才能在应用顶层捕捉到全部请求
如果你把ServiceWorker嵌套在子目录里面

English: 
And I've got it down
to 114 kilobytes, which
is pretty nice.
Now, this is all the code
for my entire application.
This is all the
JavaScript, all the CSS,
all the HTML for my
entire application.
So I've got it down to
114 K, and this number
gets actually even
smaller, much smaller,
in Polymer 0.8, which is cool.
Now, the last thing
we've got to do,
we've got our app to
the point where we're
ready to put it up there,
share it with the world,
but we've got to make sure
we're thinking about offline.
Because again, if your
app doesn't work offline,
you really don't have
a mobile experience.
And I know that we've talked
a lot about ServiceWorker
today, so I will talk about
it again here because it's so
freaking awesome and
I'm so excited about it.
What I did was I added service
worker to this application.
Pretty straightforward.
I just checked to see
if ServiceWorker exists.
If it does, I install it.
Important thing to note
here is that as I'm
installing my
ServiceWorker, I've
got to make sure that I'm using
the root scope so that I can
catch any request at sort of
the top level of my application.
If you nest your ServiceWorker
inside of a subdirectory

Chinese: 
或者其他类似的地方
Service Worker只能捕捉到当前Scope的请求
这糟透了
尽可能的把它放在更高的层级
在这个联系人应用里面  在启动的时候
就尽可能的进行缓存
你会注意到我在缓存所有element里面
vulcanize化的bundle
所以UI才能像丝一般顺滑
我也缓存了不少来自data Service的初始请求
所以你看到联系人填充了列表
我做的另外一件事
就是当用户来回滚动时
动态缓存每一个
放在Amazon S3服务器上的图像
不管你通过采用avatar头像
还是从Amazon S3服务器获取的方式
所有的一切  都只是为了获取那个头像
将其通过Service Worker缓存  让Service Worker充当服务端
这样用户使用时就是从Service Worker本地获取相关资源
现在  我们在Chrome Canary版
提供了Service Worker的相关支持  开始运行我们的应用
我所要做的
就是先快速的滑到最底部

English: 
or something like
that, then it's
only going to have access to
the request in that scope, which
sort of sucks.
You want to put it
high up if you can.
Inside my application,
as soon as we boot up,
I just try and cache
as much stuff as I can.
You'll notice that I'm caching
the vulcanized bundle of all
of my elements.
So my UI is just like
instantly available.
I'm also caching the initial
response from my data service
so that there are contacts
to populate my list there.
And then the other
thing that I did
was as the user is
scrolling around,
I'm dynamically caching
any sort of image
that has a host
name from S3.amazon.
So as you pass through
an avatar image
and call this S3
response method.
And really, all it's doing
is it's fetching that image,
it's caching it, and then
serving up for people.
So as user kind of
uses my app, it just
consumes things for them.
Now, if we pop
this open in Canary
and we've got Service
Worker running,
we started running our app.
And what I'm doing
here is at first,
I'm just racing to the
bottom of my application.

English: 
And right now, there's no
Service Worker in play,
and so what it's doing
is loading all 300
of my contact images at once
and just hammering the crap out
of the network.
And you'll see
it's like, oh God,
why are you doing this to me.
And it finally all
starts to load in.
Now let's refresh
it and see what
happens when
ServiceWorker's in play.
Let's turn our Wi-Fi
off, refresh the page.
You'll see here
over in the column
that our assets are now
coming from ServiceWorker.
So I race to the bottom
of my application.
All those things are just
coming in immediately.
There's no wait on those
assets, which is really cool.
[APPLAUSE]
So, wrap up.
What did we learn?
For structuring
your application,
for structuring your UI, you've
got the core and the paper
elements.
So you can compose
those together
to make a really awesome
mobile experience.
From moving from one state of
your application to the next,
you've got core-animated-pages,
and you've also

Chinese: 
注意看  Service Worker并没有开启
现在正在从网络上一次性加载
所有的300个联系人头像
需要一些些等待
你可能会说  哦  上帝
为毛这样对我
现在差不多加载完了
现在让我们刷新一下下
看看Service Worker运行会出现什么
关掉Wifi  刷新页面
看Network这一栏
我们所有的资源都来自Service Worker的缓存
再一次滑到最底部
立等可现有木有
没有丝毫的延迟  太棒了
掌声
好  基本齐活儿
我们从中学到了什么呢
为了构建你的应用
为了构建你的UI  
你学会了使用core和paper elements
所以你才能把这些合成到一起
只为创作出最佳的移动应用体验
为了让应用的一个状态过渡到另外一个状态
你学会了如何运用core-animated-pages

Chinese: 
学会了如何用命令式和声明式指定路由
二者随你爱好  任选其一
出于性能的考虑  有选择的加载polyfill
最重要的是vulcanize化所有的一切
使用Vulcanize尽可能的将其打包
能为你省很多事
另外  还应该考虑研究延迟加载
这也是我们一直试图弄明白的事情之一
什么是合适的模式
什么才是合适的UI
我想在未来
我们会看到更多生动的例子
尤其是在Polymer世界
最后  关于应用的离线支持  Service Worker会为你保驾护航
用不同的浏览器去载入它
即使是现在还不尽完善  也尽情地尝试吧
载入不同的浏览器  放入你的App
这感觉棒极啦
如果你仍对这款联系人应用意犹未尽的话
你可以在Github上找到它
它依旧会有Bug  为了让其变得更加完善
所以请不吝指教  提交bug report  尽情的pull requests
如果你想了解更多关于Polymer
或者你对这一切都充满激情
正如今天下午Matt所说
我们在世界各地都有举办Polymer活动
我们称之为Polytechnics

English: 
got imperative or
declarative routing.
Kind of depends on how
you like to do that.
For performance,
conditional polyfills.
And most importantly,
vulcanize all the things.
Use Vulcanize to bundle up
as much as you possibly can.
It'll save you a lot.
Also, consider
exploring lazy loading.
It's one of those
things that we're still
trying to figure out what's
the right pattern, what's
the right UX there.
But it's something
that I think we'll
be seeing a lot
more in the future,
especially in the
world of Polymer.
Lastly, for offline,
ServiceWorker's got your back.
So as that starts to land
in the various browsers--
I mean, even today,
experiment with it.
As it starts to land in various
browsers, put it in your app.
It's going to be really awesome.
If you want to play around
with this contacts app,
it's available up
on the GitHubs.
It totally has a lot
of bugs, so please
file bug reports, but even
better, submit pull requests.
If you want to learn
more about Polymer
and you're just
excited by everything
you've seen this afternoon,
as Matt mentioned,
we're running Polymer
events all over the world.
We call these Polytechnics.
I see some of you
wearing the shirts, which

English: 
means you are cool.
If you go to
itshackademic.com, you
can find a Polytechnic near you.
If you want to
participate in one,
maybe you want to run
your own, whatever,
all the material is up there.
If you set one up,
please let me know.
Tweet about it, whatever.
It's freaking awesome, so you
should all go check it out.
Most importantly,
polymer-project.org.
As you've all been sitting
here, we've actually secretly
been updating the website.
So there's kind of a
new experience there.
It's just a slight-- it's
just a nicer coat of paint.
It's not a full blown
reboot of the site,
but now it's a lot easier
to find the content
that you're looking for.
The getting started experience
is a lot easier if you just
want to get up and
running with Polymer,
so definitely
check out the site,
go through some
of the tutorials.
And I'm looking forward to
seeing all the really cool
stuff that you guys
build, so thanks.
[APPLAUSE]

Chinese: 
我看见你们当中有穿Polymer的衬衫  这非常的酷
你可以登陆itshackademic.com  找到离你最近的Polytech
如果你想加入其中
亦或是想自己举办一个  无论如何
都是触手可及
若你自己已经举办了一个  烦请让我知道
我好帮你宣传一番  等等
这非常的棒  你们都该去看一看
当然  别忘了Polymer-project.org
每时每刻
我们都在秘密更新 
在那里你将会有一个全新的体验
删繁就简
至臻至美
而所有一切
都触手可得
如果你想要入门Polymer
这非常的简单
欢迎来到明天世界  赶快到polymer网站看一看相关教程吧
并且  我也期待大家所创造出的非凡作品
再一次  感谢大家
掌声
