Chromium Code Reviews| Index: src/site/docs/tutorials/polymer/index.markdown |
| diff --git a/src/site/docs/tutorials/polymer/index.markdown b/src/site/docs/tutorials/polymer/index.markdown |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..c44d97d704659ea79b8ee2e0da9ce6704c88d028 |
| --- /dev/null |
| +++ b/src/site/docs/tutorials/polymer/index.markdown |
| @@ -0,0 +1,487 @@ |
| +--- |
| +layout: default |
| +title: "Polymer Elements" |
| +description: "Use Polymer elements to encapsulate and share custom DOM elements." |
| +has-permalinks: true |
| +tutorial: |
| + id: polymer-intro |
| +next: fetchdata |
| +next-title: "Fetch Data Dynamically" |
| +prev: custom-elements |
| +prev-title: "Define a Custom DOM Tag" |
|
ericbidelman
2013/09/24 18:18:42
"Define a Custom HTML Element"
mem
2013/10/01 16:05:31
Done.
|
| +--- |
| + |
| +{% capture whats_the_point %} |
| + |
| +* Polymer.dart is the next evolution of Web UI. |
| +* Everything in Polymer.dart is an element. |
| +* Polymer elements provide semantically meaningful encapsulation. |
| +* Use Polymer.dart to build custom tags. |
| +* Bind Dart data to HTML elements. |
| +* Declaratively bind event handlers to elements. |
| + |
| +{% endcapture %} |
| + |
| +{% capture sample_links %} |
| + |
| +<p> |
| +Get the source code for the samples featured in this target:</p> |
| + |
| +<ul> |
| + <li> |
| + <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/target06-polymer/stopwatch" |
| + target="_blank">stopwatch</a> |
| + </li> |
| +</ul> |
| + |
| +{% endcapture %} |
| + |
| +{% capture content %} |
| + |
| +<div class="tute-target-title"> |
| +<h1>{{page.title}}</h1> |
| +<h3>Create new HTML tags with Polymer elements</h3> |
| +</div> |
| + |
| +Polymer elements are one feature of the |
| +<a href="http://www.polymer-project.org/">Polymer</a> project, |
| +whose primary aim is to help manage the complexity |
|
sethladd
2013/09/20 23:18:36
This sounds like we're speaking for polymer projec
Jennifer Messerly
2013/09/24 02:36:39
borrow some language from "Guiding principals" on
mem
2013/10/01 16:05:31
I got this language from their website.
Changed it
|
| +of building web applications. |
| +<a href="http://www.dartlang.org/polymer-dart/">Polymer.dart</a> |
| +is the Dart implementation of Polymer. |
| + |
| +A Polymer element is a customized element you can define yourself, |
| +encapsulating appearance and/or behavior within semantically meaningful DOM tags. |
|
ericbidelman
2013/09/24 18:18:42
DOM tags -> HTML elements
mem
2013/10/01 16:05:31
Done.
|
| + |
| +* [An example](#an-example) |
| +* [Installing Polymer.dart](#getting-polymer-dart) |
| +* [Including Polymer.dart in your application](#bootstrap) |
| +* [Instantiating a Polymer element](#instantiating) |
| +* [Defining a Polymer element](#define-element) |
| +* [Providing a template for the Polymer element](#providing-a-template) |
| +* [Providing a script for the Polymer element](#providing-a-script) |
| +* [Overiding life-cycle methods](#life-cycle-methods) |
| +* [Embedding live data on the page](#one-way-data-binding) |
| +* [Setting up event handlers declaratively](#event-handlers) |
| +* [Querying the shadow DOM](#in-the-shadows) |
| +* [Styling a Polymer element](#scoped-css) |
| +* [Other resources](#other-resources) |
| + |
| +##An example |
| + |
| +In the example running below, |
|
ericbidelman
2013/09/24 18:18:42
is a custom element, implemented using Polymer.
mem
2013/10/01 16:05:31
Done.
|
| +the area within the black rectangle is implemented by a Polymer element, |
|
sethladd
2013/09/20 23:18:36
there are two black rectangles
mem
2013/10/01 16:05:31
Done.
|
| + |
| +<strong>Try it!</strong> |
|
Jennifer Messerly
2013/09/24 02:36:39
FYI -- the example didn't work for me, but it work
mem
2013/10/01 16:05:31
The link here is actually the Web UI version of th
|
| +Start and stop the stopwatch. |
| +Reset the stopwatch to 00:00 using the **Reset** button. |
| + |
| +<iframe class="running-app-frame" |
| + style="height:175px;width:202px;" |
| + src="http://dart-lang.github.com/dart-tutorials-samples/web/target06/stopwatch/web/out/stopwatch.html"> |
| +</iframe> |
| + |
| +To place this Polymer element on an HTML page, you write: |
|
sethladd
2013/09/20 23:18:36
you also need to import it
mem
2013/10/01 16:05:31
Done.
|
| + |
| +{% prettify html %} |
| +<tute-stopwatch></tute-stopwatch> |
| +{% endprettify %} |
| + |
| +The counting text, the three buttons along with their actions, |
| +and the style are all contained within the Polymer element. |
| +The definition of the Polymer element encapsulates and |
| +hides the implementation details, |
| +which as the user of the element, you care nothing about. |
| + |
| +When you use tools to inspect the element, |
| +you see just the Polymer element's begin and end tag. |
| +The contents of the Polymer element are hidden in the *shadow DOM*. |
|
sethladd
2013/09/20 23:18:36
define shadow dom here, or omit because you don't
mem
2013/10/01 16:05:31
Done.
|
| + |
| + |
| + |
| +With Polymer elements, developers can easily create elements |
| +with semantically meaningful tags that are easy to share, |
| +re-use, and read. |
| + |
| +###Overview of the example files |
| + |
| +Three primary source files implement the stopwatch example: |
| + |
| +<dl> |
| + <dt> |
| + <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/target06-polymer/stopwatch/web/index.html" target="_blank">index.html</a> |
| + </dt> |
| + <dd> |
| + The primary HTML file for the app. |
| + Includes the Polymer bootstrap script and instantiates the Polymer element. |
| + </dd> |
| + <dt> |
| + <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/target06-polymer/stopwatch/web/tute_stopwatch.html" target="_blank">tute_stopwatch.html</a> |
| + </dt> |
| + <dd> |
| + The HTML code that defines the Polymer element. |
| + </dd> |
| + <dt> |
| + <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/target06-polymer/stopwatch/web/tute_stopwatch.dart" target="_blank">tute_stopwatch.dart</a> |
| + </dt> |
| + <dd> |
| + The Dart class that implements the Polymer element. |
| + </dd> |
| +</dl> |
| + |
| +The following diagram shows the structure of the example |
| +app and its use of Polymer elements. |
|
ericbidelman
2013/09/24 18:18:42
There's a lot mentions of "Polymer elements", but
mem
2013/10/01 16:05:31
Changed Polymer elements -> custom elements everyw
|
| + |
| + |
| + |
| +##Installing Polymer.dart {#getting-polymer-dart} |
| + |
| +To use the features provided by Polymer.dart, |
| +you need to install the polymer package. |
| +If you are unfamiliar with installing packages, |
| +refer to |
| +<a href="/docs/tutorials/shared-pkgs/">Install Shared Packages</a>, |
| +which describes the process in detail. |
| + |
| +In brief, to install the polymer package: |
| + |
| +* In the application's `pubspec.yaml` file, |
| +add the package to the list of dependencies |
| +by adding the package name, `polymer`, to the list. |
| +YAML is whitespace-sensitive |
| +so take care to indent the package name as shown: |
| + |
| +  |
| + |
| +* If you are using Dart Editor, |
| +when you save pubspec.yaml |
| +the editor automatically runs `pub install`. |
| +If you are using command line tools, |
| +you can run it with the command `pub install`. |
| +The installation process |
| +recursively installs the polymer.dart package |
| +and all the packages that it depends on. |
| + |
| +##Including Polymer.dart in your application {#bootstrap} |
| + |
| +To use Polymer.dart features, such as Polymer elements, |
| +you need to include Polymer in both |
| +the HTML side and in the Dart side of your app. |
| + |
| +* In the primary HTML file for your app, |
| +you must include `packages/polymer/boot.js` |
| +in the <head> section. |
| +When using this script, |
| +you do not need to include a top-level `main()` function, |
| +although you may. |
| +**Note:** Use this script in lieu of `packages/browser/dart.js`. |
|
sethladd
2013/09/20 23:18:36
concerned that in lieu will be difficult for non-e
mem
2013/10/01 16:05:31
Done.
|
| + |
| +  |
| + |
| +* Each Dart file that uses Polymer features |
| +needs to import the Polymer library: |
| + |
| +  |
| + |
| +##Instantiating a Polymer element {#instantiating} |
| + |
| +To create an instance of the Polymer element, |
| +use the name of the Polymer element just as you would any normal HTML tag. |
| +In this example, the tag name is `tute-stopwatch`. |
| + |
| + |
| + |
| +Using best practices, |
| +the Polymer element definition is in a separate file. |
| +Use `link` to import the HTML definition file as shown. |
|
ericbidelman
2013/09/24 18:18:42
`link[rel="import"]` to be clear
mem
2013/10/01 16:05:31
Done.
|
| + |
| +##Defining a Polymer element {#define-element} |
| + |
| +The definition for the tute-stopwatch element is |
|
ericbidelman
2013/09/24 18:18:42
<tute-stopwatch>
mem
2013/10/01 16:05:31
Done.
|
| +in `tute-stopwatch.html`. |
|
sethladd
2013/09/20 23:18:36
use underscore instead of dash
mem
2013/10/01 16:05:31
Done.
|
| +A Polymer element definition should be in its own |
| +source file so that it can be included by other files. |
| +An HTML file that contains a Polymer element definition |
| +does not need <html>, <head>, or <body> tags. |
| + |
| +To define a Polymer element, |
| +use the <polymer-element> tag and provide a name. |
| + |
| +{% prettify html %} |
| +<polymer-element name="tute-stopwatch"> |
| + ... |
| +</polymer-element> |
| +{% endprettify %} |
| + |
| +A Polymer element name must have at least one hyphen (`-`). |
| +We advise using an identifiable prefix to |
| +avoid naming conflicts with elements shared by others |
| +and to help identify the project from which the element originates. |
| +For example, for tutorial polymer elements, we use the prefix `tute`. |
| + |
| +Within the <polymer-element> tag, |
| +you can provide a template (appearance) and a script (behavior). |
| +UI widgets, like our stopwatch example, |
| +typically have both a template and a script. |
| +But neither is required. |
| +A polymer element with a script and no template is purely functional, |
| +for example a [xx]. |
|
ericbidelman
2013/09/24 18:18:42
are these placeholders?
mem
2013/10/01 16:05:31
Yes they are. Was hoping for a suggestion!
On 201
|
| +A polymer element with a template and no script is purely visual, |
| +for example a [xx]. |
| + |
| +{% prettify html %} |
| +<polymer-element name="tute-stopwatch"> |
| + <template> |
| + ... |
| + </template> |
| + <script type="application/dart" src="tute_stopwatch.dart"> |
| + </script> |
| +</polymer-element> |
| +{% endprettify %} |
| + |
| +<dl> |
| + <dt> <template> </dt> |
| + <dd> |
| + Describes the element's structure—its user interface. |
| + The template comprises any valid HTML code within the <template> tag. |
|
ericbidelman
2013/09/24 18:18:42
It's important to note here that Polymer takes the
mem
2013/10/01 16:05:31
Reworded. Avoided using the term shadow root here.
|
| + The template is rendered when a Polymer element is instantiated. |
| + The template can also include scoped CSS styles within a <style> tag. |
|
ericbidelman
2013/09/24 18:18:42
FYI, the styles are scoped by default.
mem
2013/10/01 16:05:31
Done.
|
| + </dd> |
| + |
| + <dt> <script> </dt> |
| + <dd markdown="1"> Specifies a Dart script. |
| + For Polymer elements, the Dart script is a Dart class |
|
ericbidelman
2013/09/24 18:18:42
Can Polymer.dart do inline <script>?
mem
2013/10/01 16:05:31
Yes. But our tools don't give good info when editi
|
| + that implements the behavior of the element. |
| + The class typically overrides some |
| + life-cycle methods and provides event handlers |
| + that join the UI with its programmatic behavior. |
| + In this example, the script is in the `tute_stopwatch.dart` file. |
| + </dd> |
| +</dl> |
| + |
| +##Providing a template for the Polymer element {#providing-a-template} |
| + |
| +Here's the template code for the tute-stopwatch element: |
| + |
| + |
| + |
| +The tute-stopwatch template uses a <style> tag, which is optional. |
| +These styles are scoped; they affect only |
| +the appearance of the Polymer element and the elements it contains. |
| +More about scoped CSS in [Styling a Polymer element](#scoped-css). |
|
ericbidelman
2013/09/24 18:18:42
Suggset you also link to this article: http://www.
mem
2013/10/01 16:05:31
Done.
|
| + |
| +The rest of the code within the template tag |
|
ericbidelman
2013/09/24 18:18:42
<template>
mem
2013/10/01 16:05:31
Done.
|
| +is normal HTML with two exceptions: |
| + |
| +* {% raw %}`{{counter}}`{% endraw %}--a Polymer syntax for |
|
ericbidelman
2013/09/24 18:18:42
"a mustache for data binding"
mem
2013/10/01 16:05:31
Included reference to mustaches, but worded it dif
|
| +[embedding live data on the page](#one-way-data-binding). |
| + |
| +* `on-click`--a Polymer element attribute that lets you |
|
ericbidelman
2013/09/24 18:18:42
"a Polymer element attribute" -> a Polymer `on-*`d
mem
2013/10/01 16:05:31
Done.
|
| +[declaratively attach a mouse click handler](#event-handlers) |
| +to UI elements, such as buttons. |
| +Polymer has other attributes for other event types, such as `on-change`. |
| + |
| +Let's take a look at the structure of the Dart code |
| +before we get into the details of data binding, event handlers, |
| +and scoped CSS. |
| + |
| +##Providing a script for the Polymer element {#providing-a-script} |
| + |
| +When you define a Polymer element in HTML, |
| +you give it a name using the `name` attribute. |
| +On the Dart side, a class implements the behavior of the Polymer element. |
| +You associate the Dart class with the Polymer element using the `@CustomTag` |
| +annotation and the name of the Polymer element. |
| + |
| + |
| + |
| +This diagram gives an overview of the TuteStopwatch class: |
| + |
| + |
| + |
| +Any Dart class that backs a Polymer element must subclass PolymerElement. |
| +For now, if you want to use data binding, |
| +the class must also use ObservableMixin. |
|
Jennifer Messerly
2013/09/24 02:36:39
this will be fixed soon! this week or next. I've a
|
| + |
| +[xx: more about PolymerElement] |
| + |
| +[xx: more about ObservableMixin] |
| + |
| +The class may override one of several [life-cycle methods](#life-cycle-methods) |
| +such as the inserted() method you see overridden here. |
| + |
| +The `start()` method is an event handler for the **Start** button. |
| +The event handler is declaratively connected to the button. |
| +Refer to [Setting up event handlers declaratively](#event-handlers) to see how. |
| + |
| +##Overriding life-cycle methods {#life-cycle-methods} |
| + |
| +The stopwatch example overrides the inserted() method |
| +to initialize the app. |
| +The app needs a reference to each of the three buttons |
| +so that it can enable and disable the buttons |
| +as appropriate for the state of the app. |
| +You'll notice that it gets the buttons by |
| +[querying its shadow DOM](#in-the-shadows). |
|
ericbidelman
2013/09/24 18:18:42
Do you guys have http://www.polymer-project.org/po
Jennifer Messerly
2013/09/24 18:30:06
not yet. This change is landing soon: https://code
|
| + |
| +{% prettify dart %} |
| +void inserted() { |
| + super.inserted(); |
| + startButton = getShadowRoot("tute-stopwatch").query('#startbutton'); |
| + stopButton = getShadowRoot("tute-stopwatch").query('#stopbutton'); |
| + resetButton = getShadowRoot("tute-stopwatch").query('#resetbutton'); |
| + |
| + stopButton.disabled = true; |
| + resetButton.disabled = true; |
| +} |
| +{% endprettify %} |
| + |
| +The inserted() method is one of four Polymer element life-cycle methods: |
|
ericbidelman
2013/09/24 18:18:42
FYI: the lifecycle methods have been renamed. See
Jennifer Messerly
2013/09/24 18:30:06
yup. We'll have to fix this once a few of our code
|
| + |
| +* created(): called when an instance of a Polymer element is created. |
| + |
| +* inserted(): called when an instance of a Polymer element is |
| +inserted into the DOM. |
| + |
| +* removed(): called when an instance of a Polymer element is |
| +removed from the DOM. |
| + |
| +* attributeChanged(): called when an attribute, such as `class`, |
| +of an instance of the Polymer element is added, changed, or removed. |
| + |
| +You can override any of these life-cycle methods. |
| +The overriding method |
| +*must* call the super class methods first. |
| + |
| +##Embedding live data on the page {#one-way-data-binding} |
|
ericbidelman
2013/09/24 18:18:42
I think the title is misleading. "Using two-way da
mem
2013/10/01 16:05:31
Done.
|
| + |
| +In HTML definition of a Polymer element, |
| +use double curly brackets to embed Dart data into your webpage. |
| +In Dart use the `@observable` annotation in the Dart code |
| +to mark the embedded data. |
| +Here, the data is a string called `counter`. |
| + |
| + |
| + |
| +The stopwatch element uses a periodic Timer to fire an event every second. |
|
Jennifer Messerly
2013/09/24 02:36:39
link to API docs for Timer?
mem
2013/10/01 16:05:31
Done.
|
| +When the Timer fires, it calls the `updateTImer` callback function, |
|
sethladd
2013/09/20 23:18:36
typo
mem
2013/10/01 16:05:31
Done.
|
| +which modifies the `counter` string. |
| +Polymer takes care of update the bound area on the HTML page. |
| + |
| +This type of binding is called _one-way data binding_ |
| +because the data can change only on the Dart side. |
| +Polymer also supports two-way data binding |
| +in which the data can be changed on the HTML side, |
| +for example with an input element, |
| +and it changes the value in the Dart code. |
| + |
| +You can use expressions within the double curly brackets. |
| +<a href="http://pub.dartlang.org/packages/polymer_expressions">Polymer expressions</a> |
| +provide the default syntax. Examples of allowable expressions include: |
| + |
| +* {% raw %} `{{myObject.aProperty}}` {% endraw %}--property access |
| +* {% raw %} `{{!empty}}` {% endraw %}--operators, like the logical not operator |
| +* {% raw %} `{{myList[3]}}` {% endraw %}--list indexing |
| +* {% raw %} `{{myFunction()}}` {% endraw %}--function calls |
|
sethladd
2013/09/20 23:18:36
let's not mention function calls here. not a great
Jennifer Messerly
2013/09/24 02:36:39
mention filters? that's a good time to include fun
mem
2013/10/01 16:05:31
changed the name to make it look like a filter. Do
|
| + |
| +##Setting up event handlers declaratively {#event-handlers} |
| + |
| +This example has three buttons, each |
| +with an event handler that is written in Dart, |
| +but attached to the button declaratively from HTML. |
| + |
| + |
| + |
| +In HTML, use the `on-click` attribute |
| +to attach a mouse click handler to an HTML element. |
| +The value of the attribute is the name of a method |
| +in the class that implements the Polymer element. |
| +When the user clicks the button the named method is called |
| +with three parameters: |
| + |
| +* the |
| +<a href="https://api.dartlang.org/dart_html/Event.html" target="_blank">Event</a> |
| +object contains information about the event, |
| +such as its type, and when it occurred. |
| + |
| +* detail [xx] has some vague use I'm uncertain of. |
|
sethladd
2013/09/20 23:18:36
an object can be attached to the event. it's the "
mem
2013/10/01 16:05:31
Done.
|
| + |
| +* the <a href="https://api.dartlang.org/dart_html/Node.html" target="_blank">Node</a>, |
| +which fired the event—the **Start** button in this case. |
| + |
| +You can attach event handlers for other kinds of events. |
| +For example, you can use `on-change` to handle events for input text elements |
| +when the text changes. |
| + |
| +##Querying the Shadow DOM {#in-the-shadows} |
|
sethladd
2013/09/20 23:18:36
I'd like to delay talking about or mentioning shad
mem
2013/10/01 16:05:31
I've got all the shadow dom stuff isolated here in
|
| + |
| +Hey! Remember we mentioned the shadow DOM earlier. |
| +Now we get to bring it out of the shadows. |
| + |
| +The Shadow DOM is key to encapsulation. |
| +The DOM tree for a Polymer element is in the shadows, |
| +hidden from outside of the Polymer element |
| +(unless the Polymer element chooses to reveal them). |
|
ericbidelman
2013/09/24 18:18:42
Not sure what you mean here. Shadow roots are disc
mem
2013/10/01 16:05:31
Done.
|
| + |
| + |
| + |
| +You can programmatically get items from the shadow DOM |
|
ericbidelman
2013/09/24 18:18:42
Be consistent with "Shadow DOM" capitalization.
mem
2013/10/01 16:05:31
Done.
|
| +by querying a Polymer element's shadow root. |
| + |
| +{% prettify dart %} |
| +startButton = getShadowRoot("tute-stopwatch").query('#startbutton'); |
| +stopButton = getShadowRoot("tute-stopwatch").query('#stopbutton'); |
| +resetButton = getShadowRoot("tute-stopwatch").query('#resetbutton'); |
| +{% endprettify %} |
| + |
| +Call `getShadowRoot` with the name of the Polymer element. |
| +The getShadowRoot function returns the shadow root element |
|
ericbidelman
2013/09/24 18:18:42
`getShadowRoot`
mem
2013/10/01 16:05:31
Done.
|
| +for 'this' instance of the element named. |
|
ericbidelman
2013/09/24 18:18:42
`this`
mem
2013/10/01 16:05:31
Done.
|
| +Then use `query` with a CSS selector to get the element(s) of interest. |
| + |
| +Note that this code uses query to get each button by id. |
| +By querying the shadow root object rather than the DOM, |
| +you are guaranteed to get the objects from within the Polymer element, |
| +not from anywhere else on the page. |
| + |
| +##Styling a Polymer element {#scoped-css} |
| + |
| +You can optionally include CSS styles for your Polymer element |
| +which apply only to the contents of the Polymer element. |
|
ericbidelman
2013/09/24 18:18:42
You can also style the element directly using `@ho
mem
2013/10/01 16:05:31
I couldn't get this to work.
On 2013/09/24 18:18:
mem
2013/10/03 17:01:54
Got it done now.
Adjusted the example and text.
On
|
| + |
| + |
|
Jennifer Messerly
2013/09/24 02:36:39
"Scoped CSS styling"?
mem
2013/10/01 16:05:31
Done.
|
| + |
| +The CSS here provide a style for the ID `stopwatch_container`, |
| +which identifies the primary <div> element within the stopwatch template. |
| +The styles within the template apply only to the template. |
| +So any CSS selectors within the template need only be unique within the template. |
| +You don't need to worry about naming conflicts on the page. |
| + |
| +##Other resources |
| + |
| +Use these other resources to learn more about Polymer.dart: |
| + |
| +* We converted all tutorial examples that previously used Web UI |
| +to use Polymer instead. |
| +Check out the |
| +<a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web">github repo</a> |
| +to find the source code for all of the Polymer examples. |
| + |
| +* Learn more about |
| +<a href="http://www.dartlang.org/polymer-dart/">Polymer.dart</a>—the |
| +Dart port of the Polymer project. |
| + |
| +* Check out the Polymer project website at |
| +<a href="http://www.polymer-project.org/">polymer-project.org</a>. |
| + |
| +* The next target is going to talk about other nifty polymer.dart features like |
| +two-way data binding, xtag, and the <content> tag and shadow DOM. |
| +Aren't you excited? |
| + |
| +Wahoo! |
| + |
| +Go write some code. |
| + |
| +{% endcapture %} |
| + |
| +{% include tutorial.html %} |