Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(802)

Unified Diff: src/site/docs/tutorials/polymer/index.markdown

Issue 24269013: first draft of polymer element tutorial (Closed) Base URL: https://github.com/dart-lang/dartlang.org.git@master
Patch Set: resolving some xx's Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/site/docs/tutorials/polymer/images/template-code.png ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.
+
+![Polymer element encapsulates its contents](images/dev-tools-dom.png)
+
+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
+
+![The connections between Dart and HTML](images/connections.png)
+
+##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:
+
+ ![Sample pubspec file with polymer dependency](images/sample-pubspec.png)
+
+* 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 &lt;head&gt; 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.
+
+ ![Include the Polymer bootstrap script](images/bootstrap-script.png)
+
+* Each Dart file that uses Polymer features
+needs to import the Polymer library:
+
+ ![Import the Polymer library](images/polymer-library.png)
+
+##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`.
+
+![Instantiate a Polymer element with a custom tag](images/polymer-element-instantiation.png)
+
+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 &lt;html&gt;, &lt;head&gt;, or &lt;body&gt; tags.
+
+To define a Polymer element,
+use the &lt;polymer-element&gt; 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 &lt;polymer-element&gt; 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> &lt;template&gt; </dt>
+ <dd>
+ Describes the element's structure&mdash;its user interface.
+ The template comprises any valid HTML code within the &lt;template&gt; 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 &lt;style&gt; 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> &lt;script&gt; </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 template code for the tute-stopwatch element](images/template-code.png)
+
+The tute-stopwatch template uses a &lt;style&gt; 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.
+
+![Two parts to a Polymer element definition](images/polymer-element-definition.png)
+
+This diagram gives an overview of the TuteStopwatch class:
+
+![The script code for the tute-stopwatch element](images/dart-script-code.png)
+
+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`.
+
+![One-way data binding](images/one-way-data-binding.png)
+
+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.
+
+![Declaratively attach a click handler](images/click-handler.png)
+
+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&mdash;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.
+
+![Shadow DOM for tute-stopwatch Polymer element](images/shadow-dom.png)
+
+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
+
+![Scoped CSS styleing](images/css-styling.png)
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 &lt;div&gt; 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>&mdash;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 &lt;content&gt; tag and shadow DOM.
+Aren't you excited?
+
+Wahoo!
+
+Go write some code.
+
+{% endcapture %}
+
+{% include tutorial.html %}
« no previous file with comments | « src/site/docs/tutorials/polymer/images/template-code.png ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698