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 %} |