|
1 |
| -# Polymer 0.8 Preview |
2 |
| - |
3 |
| -Authors interested in learning the core concepts in 0.8 may be interested in our [primer](https://github.com/Polymer/polymer/blob/0.8-preview/PRIMER.md). |
4 |
| - |
5 |
| -## From The Ground Up |
6 |
| - |
7 |
| -Let us begin this tale with a short stroll through the layers that Polymer is |
8 |
| -built upon, and some of the rationale of how we got there. |
9 |
| - |
10 |
| -### Raw Custom Elements |
11 |
| - |
12 |
| -Custom Elements are a powerful emerging web standard that allows developers to create their own elements by attaching a class to a tag-name. |
13 |
| - |
14 |
| -#### document.registerElement |
15 |
| - |
16 |
| -The native API is very simple, it looks something like this: |
17 |
| - |
18 |
| -```js |
19 |
| -document.registerElement(<name String>, {prototype: Object[, extends: String]}); |
20 |
| -``` |
21 |
| - |
22 |
| -#### Typical Boilerplate |
23 |
| - |
24 |
| -There is a little bit of work one has to do to set up the class with the right prototypes and so on to construct a Custom Element. Here is an typical example (using ES5 syntax): |
25 |
| - |
26 |
| -```js |
27 |
| -var ctor = function() { |
28 |
| - return document.createElement('x-custom'); |
29 |
| -}; |
30 |
| -ctor.prototype = Object.create(HTMLElement.prototype); |
31 |
| -ctor.prototype.constructor = ctor; |
32 |
| -ctor.prototype.createdCallback = function() { |
33 |
| - this.innerHTML = 'Hello World, I am a <b>Custom Element!</b>'; |
34 |
| -} |
35 |
| -document.registerElement('x-custom', ctor); |
36 |
| -``` |
37 |
| - |
38 |
| -### Reluctant Polymer() Abstraction |
39 |
| - |
40 |
| -By principle, Polymer team tries to avoid abstracting DOM APIs, especially new ones. But in this case we finally decided the ergonomic benefit was worth it. By wrapping `registerElement` in our own function, we can reduce the above boilerplate to: |
41 |
| - |
42 |
| -```js |
43 |
| -var ctor = Polymer({ |
44 |
| - is: 'x-custom', |
45 |
| - created: function() { |
46 |
| - this.innerHTML = 'Hello World, I am a <b>Custom Element!</b>'; |
47 |
| - } |
48 |
| -}); |
49 |
| -``` |
50 |
| - |
51 |
| -### Polymer() Does a Bit More |
52 |
| - |
53 |
| -You might notice the `Polymer()` invocation defines `created` instead of `createdCallback`. This is a feature of `Polymer.Base`, a tiny prototype that `Polymer()` adds to your prototype chain as it's handling the boilerplate above. `Polymer.Base` hooks the standard Custom Element lifecycle callbacks to provide helper implementations. The hooks in turn call shorter-named lifecycle methods on your prototype. |
54 |
| - |
55 |
| -- `created` instead of `createdCallback` |
56 |
| -- `attached` instead of `attachedCallback` |
57 |
| -- `detached` instead of `detachedCallback` |
58 |
| -- `attributeChanged` instead of `attributeChangedCallback` |
59 |
| - |
60 |
| -You can always fallback to using the low-level methods if you wish (iow, you could simply implement `createdCallback` in your prototype). |
61 |
| - |
62 |
| -`Polymer.Base` also implements `registerCallback` on your prototype. `Polymer()` calls `registerCallback` which allows `Polymer.Base` to supply a layering system for Polymer abstractions so that no element needs to pay for features it doesn't use. |
63 |
| - |
64 |
| -## Features |
65 |
| - |
66 |
| -By default, the default Polymer distribution include several features. Although `Polymer.Base` itself is tiny, if you examine `Polymer.Base` you will probably see several methods that have been plugged-in to that prototype by feature definitions. The next few sections will explain these features and why we include them in the default set. Keep in mind that it's entirely possible to construct custom feature sets, or even use a trivial, featureless form of `Polymer()`. |
67 |
| - |
68 |
| -### Feature: _property-config_ |
69 |
| - |
70 |
| -The first feature implements support for the `properties` property. By placing a object-valued `properties` property on your prototype, let's you define various aspects of your custom-elements public API. |
71 |
| - |
72 |
| -By itself, the `properties` feature **doesn't do anything**. It only provides API for asking questions about these special properties (see [link to docs] for details). |
73 |
| - |
74 |
| -```js |
75 |
| -Polymer({ |
76 |
| - |
77 |
| - is: 'x-custom', |
78 |
| - |
79 |
| - properties: { |
80 |
| - user: String, |
81 |
| - isHappy: Boolean, |
82 |
| - count: { |
83 |
| - type: Number, |
84 |
| - readOnly: true, |
85 |
| - notify: true |
86 |
| - } |
87 |
| - }, |
88 |
| - |
89 |
| - created: function() { |
90 |
| - this.innerHTML = 'Hello World, I am a <b>Custom Element!</b>'; |
91 |
| - } |
92 |
| - |
93 |
| -}); |
94 |
| -``` |
95 |
| - |
96 |
| -Remember that the fields assigned to `count`, such as `readOnly` and `notify` don't do anything by themselves, it requires other features to give them life. |
97 |
| - |
98 |
| -### Feature: _attributes_ |
99 |
| - |
100 |
| -Many custom elements want to support configuration using HTML attributes. Custom Elements provides the `attributeChanged` callback gives us the raw API for this ability, but then we have to deal with initialization and type conversion (attributes are always strings). Here is an example of a custom element that supports a `user` attribute using the raw API. |
101 |
| - |
102 |
| -```js |
103 |
| - Polymer({ |
104 |
| - |
105 |
| - is: 'x-custom', |
106 |
| - |
107 |
| - created: function() { |
108 |
| - // handle any initial value |
109 |
| - this.attributeChanged('user'); |
110 |
| - // render |
111 |
| - this.innerHTML = 'Hello World, my user is ' + (this.user || 'nobody') + '.'; |
112 |
| - }, |
113 |
| - |
114 |
| - attributeChanged: function(name) { |
115 |
| - switch(name) { |
116 |
| - case 'user': |
117 |
| - // pretty easy since user is a String, for other types |
118 |
| - // we have to do more work |
119 |
| - if (this.hasAttribute('user')) { |
120 |
| - this.user = this.getAttribute('user'); |
121 |
| - } |
122 |
| - break; |
123 |
| - } |
124 |
| - } |
125 |
| - |
126 |
| - }); |
127 |
| -``` |
128 |
| - |
129 |
| -Although it's relatively simple, having to write this code becomes annoying when working with multiple attributes or non-String types. It's also not very DRY. |
130 |
| - |
131 |
| -Instead, Polymer's `attributes` feature handles this work for you (using the `properties` feature data). If an attribute is set that matches a property listed in the `properties` object, the value is captured into the matching property. Strings are automatically converted to the specified type. |
132 |
| - |
133 |
| -The type system includes support for Object values expressed as JSON, or Date objects expressed as any Date-parsable string representation. Boolean properties are mapped to Boolean attributes, in other words, if the attribute exists at all, its value is true, regardless of its string-value (and the value is only false if the attribute does not exist). |
134 |
| - |
135 |
| -Here is the equivalent of the above code, taking advantage of the `attributes` feature. |
136 |
| - |
137 |
| -```html |
138 |
| -<script> |
139 |
| -
|
140 |
| - Polymer({ |
141 |
| -
|
142 |
| - is: 'x-custom', |
143 |
| -
|
144 |
| - properties: { |
145 |
| - user: String |
146 |
| - }, |
147 |
| -
|
148 |
| - created: function() { |
149 |
| - // render |
150 |
| - this.innerHTML = 'Hello World, my user is ' + (this.user || 'nobody') + '.'; |
151 |
| - } |
152 |
| -
|
153 |
| - }); |
154 |
| -
|
155 |
| -</script> |
156 |
| - |
157 |
| -<x-custom user="Scott"></x-custom> |
158 |
| -``` |
159 |
| - |
160 |
| -### [ToDoc] attributes:hostAttributes |
161 |
| - |
162 |
| -### Feature: _template_ |
163 |
| - |
164 |
| -HTML templates are an emerging web standard that we like to consider part of the Web Components family. Templates are a great way to provide archetypal DOM content for your custom element, and this is where the `template` feature comes in. |
165 |
| - |
166 |
| -As usual, we started by writing basic template support by hand. It generally looks something like this: |
167 |
| - |
168 |
| -```html |
169 |
| -<template> |
170 |
| - |
171 |
| - Hello World from x-custom! |
172 |
| - |
173 |
| - </template> |
174 |
| - |
175 |
| -<script> |
176 |
| -
|
177 |
| - Polymer({ |
178 |
| -
|
179 |
| - is: 'x-custom', |
180 |
| -
|
181 |
| - created: function() { |
182 |
| - var template = <find the template somehow>; |
183 |
| - var instance = document.importNode(template.content, true); |
184 |
| - this.appendChild(instance); |
185 |
| - } |
186 |
| -
|
187 |
| - }); |
188 |
| -
|
189 |
| -</script> |
190 |
| -``` |
191 |
| - |
192 |
| -Again, it's simple, but it's a common pattern, so the `template` feature does it automatically. By default it looks for a template as the first element before the script, so our code can look like this: |
193 |
| - |
194 |
| -```html |
195 |
| -<template> |
196 |
| - |
197 |
| - Hello World from x-custom! |
198 |
| - |
199 |
| -</template> |
200 |
| - |
201 |
| -<script> |
202 |
| -
|
203 |
| - Polymer({ |
204 |
| -
|
205 |
| - is: 'x-custom' |
206 |
| -
|
207 |
| - }); |
208 |
| -
|
209 |
| -</script> |
210 |
| -``` |
211 |
| - |
212 |
| -### Feature: _annotations_ |
213 |
| - |
214 |
| -Most elements need to customize the DOM instanced from a template. For this reason, it's handy to encode markers into your template to indicate special nodes, attributes, or text. Polymer calls these markers _annotations_. The `annotations` feature scans the template (once per element, at registration time) and builds a data-structure into the prototype that identifies markers it finds in the DOM (see [link to docs] for details). Normally you do not need to work with this data directly, Polymer does it for you. |
215 |
| - |
216 |
| -### Feature: _annotations-nodes_ |
217 |
| - |
218 |
| -Traditionally, modifying DOM is done by querying for elements to manipulate. Here is an example: |
219 |
| - |
220 |
| -```html |
221 |
| -<template> |
222 |
| - |
223 |
| - Hello World from <span id="name"></span>! |
224 |
| - |
225 |
| -</template> |
226 |
| - |
227 |
| -<script> |
228 |
| -
|
229 |
| - Polymer({ |
230 |
| -
|
231 |
| - is: 'x-custom', |
232 |
| -
|
233 |
| - created: function() { |
234 |
| - this.querySelector("#name").textContent = this.name; |
235 |
| - } |
236 |
| -
|
237 |
| - }); |
238 |
| -
|
239 |
| -</script> |
240 |
| -``` |
241 |
| - |
242 |
| -This example is very simple. But in real projects, repeating queries is inefficient, so query results are often stored (memoized). Also, as DOM composition becomes more tricky, crafting correct queries can be difficult. For these reasons, automatically capturing nodes makes a good feature. |
243 |
| - |
244 |
| -The `annotations-nodes` feature builds a map of instance nodes by `id` in `this.$` (using the `annotations` feature data). Here is how the `annotations-nodes` feature simplifies the above example. |
245 |
| - |
246 |
| -```html |
247 |
| -<template> |
248 |
| - |
249 |
| - Hello World from <span id="name"></span>! |
250 |
| - |
251 |
| -</template> |
252 |
| - |
253 |
| -<script> |
254 |
| -
|
255 |
| - Polymer({ |
256 |
| -
|
257 |
| - is: 'x-custom', |
258 |
| -
|
259 |
| - created: function() { |
260 |
| - this.$.name.textContent = this.name; |
261 |
| - } |
262 |
| -
|
263 |
| - }); |
264 |
| -
|
265 |
| -</script> |
266 |
| -``` |
267 |
| - |
268 |
| -### Feature: _annotations-events_ |
269 |
| - |
270 |
| -Most elements also need to listen for events. The standard DOM method `addEventListener` provides the low-level support: |
271 |
| - |
272 |
| -```html |
273 |
| -<template> |
274 |
| - |
275 |
| - <button id="button">Kick Me</button> |
276 |
| - |
277 |
| -</template> |
278 |
| - |
279 |
| -<script> |
280 |
| -
|
281 |
| - Polymer({ |
282 |
| -
|
283 |
| - is: 'x-custom', |
284 |
| -
|
285 |
| - created: function() { |
286 |
| - this.$.button.addEventListener('click', function() { |
287 |
| - alert('Ow!'); |
288 |
| - }); |
289 |
| - } |
290 |
| -
|
291 |
| - }); |
292 |
| -
|
293 |
| -</script> |
294 |
| -``` |
295 |
| - |
296 |
| -Again, this is pretty simple, but it's so common that it's worth making even simpler. The `annotations-events` feature supports declaring event listeners directly in our template. |
297 |
| - |
298 |
| -Declaring listeners in the template is convenient, and also helps us decouple view from behavior. |
299 |
| - |
300 |
| -```html |
301 |
| -<template> |
302 |
| - |
303 |
| - <button on-click="kickAction">Kick Me</button> |
304 |
| - |
305 |
| -</template> |
306 |
| - |
307 |
| -<script> |
308 |
| -
|
309 |
| - Polymer({ |
310 |
| -
|
311 |
| - is: 'x-custom', |
312 |
| -
|
313 |
| - kickAction: function() { |
314 |
| - alert('Ow!'); |
315 |
| - } |
316 |
| -
|
317 |
| - }); |
318 |
| -
|
319 |
| -</script> |
320 |
| -``` |
321 |
| - |
322 |
| -Notice that the `kickAction` method doesn't know anything about `button`. If we decided that kicking should be performed by a key-press, or a menu-item, the element code doesn't need to know. We can change the UI however we want. Also notice that by attaching the event declaratively, we have removed the need to give the button an id. |
323 |
| - |
324 |
| -### [ToDoc] events feature |
325 |
| - |
326 |
| -### [ToDoc] keys feature |
327 |
| - |
328 |
| -### [ToDoc] content feature |
329 |
| - |
330 |
| - |
| 1 | +# Polymer |
| 2 | + |
| 3 | +[](http://build.chromium.org/p/client.polymer/waterfall) |
| 4 | + |
| 5 | +## Brief Overview |
| 6 | + |
| 7 | +For more detailed info goto [http://polymer-project.org/](http://polymer-project.org/). |
| 8 | + |
| 9 | +Polymer is a new type of library for the web, designed to leverage the existing browser infrastructure to provide the encapsulation and extendability currently only available in JS libraries. |
| 10 | + |
| 11 | +Polymer is based on a set of future technologies, including [Shadow DOM](http://w3c.github.io/webcomponents/spec/shadow/), [Custom Elements](http://w3c.github.io/webcomponents/spec/custom/) and Model Driven Views. Currently these technologies are implemented as polyfills or shims, but as browsers adopt these features natively, the platform code that drives Polymer evacipates, leaving only the value-adds. |
| 12 | + |
| 13 | +## Tools & Testing |
| 14 | + |
| 15 | +For running tests or building minified files, consult the [tooling information](https://www.polymer-project.org/resources/tooling-strategy.html). |
| 16 | + |
| 17 | +## Releases |
| 18 | + |
| 19 | +[Release (tagged) versions](https://github.com/Polymer/polymer/releases) of Polymer include concatenated and minified sources for your convenience. |
| 20 | + |
| 21 | +[](https://github.com/igrigorik/ga-beacon) |
0 commit comments