OLD | NEW |
(Empty) | |
| 1 <!-- |
| 2 @license |
| 3 Copyright (c) 2014 The Polymer Project Authors. All rights reserved. |
| 4 This code may only be used under the BSD style license found at http://polymer.g
ithub.io/LICENSE.txt |
| 5 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt |
| 6 The complete set of contributors may be found at http://polymer.github.io/CONTRI
BUTORS.txt |
| 7 Code distributed by Google as part of the polymer project is also |
| 8 subject to an additional IP rights grant found at http://polymer.github.io/PATEN
TS.txt |
| 9 --> |
| 10 |
| 11 <!-- employ 'Annotations' module --> |
| 12 |
| 13 <link rel="import" href="../lib/annotations/annotations.html"> |
| 14 <link rel="import" href="../lib/resolve-url.html"> |
| 15 <script> |
| 16 |
| 17 /** |
| 18 * Scans a template to produce an annotation object that stores expression |
| 19 * metadata along with information to associate the metadata with nodes in an |
| 20 * instance. |
| 21 * |
| 22 * Elements with `id` in the template are noted and marshaled into an |
| 23 * the `$` hash in an instance. |
| 24 * |
| 25 * Example |
| 26 * |
| 27 * <template> |
| 28 * <div id="foo"></div> |
| 29 * </template> |
| 30 * <script> |
| 31 * Polymer({ |
| 32 * task: function() { |
| 33 * this.$.foo.style.color = 'red'; |
| 34 * } |
| 35 * }); |
| 36 * </script> |
| 37 * |
| 38 * Other expressions that are noted include: |
| 39 * |
| 40 * Double-mustache annotations in text content. The annotation must be the only |
| 41 * content in the tag, compound expressions are not (currently) supported. |
| 42 * |
| 43 * <[tag]>{{path.to.host.property}}<[tag]> |
| 44 * |
| 45 * Double-mustache annotations in an attribute. |
| 46 * |
| 47 * <[tag] someAttribute="{{path.to.host.property}}"><[tag]> |
| 48 * |
| 49 * Only immediate host properties can automatically trigger side-effects. |
| 50 * Setting `host.path` in the example above triggers the binding, setting |
| 51 * `host.path.to.host.property` does not. |
| 52 * |
| 53 * `on-` style event declarations. |
| 54 * |
| 55 * <[tag] on-<event-name>="{{hostMethodName}}"><[tag]> |
| 56 * |
| 57 * Note: **the `annotations` feature does not actually implement the behaviors |
| 58 * associated with these expressions, it only captures the data**. |
| 59 * |
| 60 * Other optional features contain actual data implementations. |
| 61 * |
| 62 * @class standard feature: annotations |
| 63 */ |
| 64 |
| 65 /* |
| 66 |
| 67 Scans a template to produce an annotation map that stores expression metadata |
| 68 and information that associates the metadata to nodes in a template instance. |
| 69 |
| 70 Supported annotations are: |
| 71 |
| 72 * id attributes |
| 73 * binding annotations in text nodes |
| 74 * double-mustache expressions: {{expression}} |
| 75 * double-bracket expressions: [[expression]] |
| 76 * binding annotations in attributes |
| 77 * attribute-bind expressions: name="{{expression}} || [[expression]]" |
| 78 * property-bind expressions: name*="{{expression}} || [[expression]]" |
| 79 * property-bind expressions: name:="expression" |
| 80 * event annotations |
| 81 * event delegation directives: on-<eventName>="expression" |
| 82 |
| 83 Generated data-structure: |
| 84 |
| 85 [ |
| 86 { |
| 87 id: '<id>', |
| 88 events: [ |
| 89 { |
| 90 mode: ['auto'|''], |
| 91 name: '<name>' |
| 92 value: '<expression>' |
| 93 }, ... |
| 94 ], |
| 95 bindings: [ |
| 96 { |
| 97 kind: ['text'|'attribute'|'property'], |
| 98 mode: ['auto'|''], |
| 99 name: '<name>' |
| 100 value: '<expression>' |
| 101 }, ... |
| 102 ], |
| 103 // TODO(sjmiles): confusingly, this is annotation-parent, not node-parent |
| 104 parent: <reference to parent annotation>, |
| 105 index: <integer index in parent's childNodes collection> |
| 106 }, |
| 107 ... |
| 108 ] |
| 109 |
| 110 TODO(sjmiles): this module should produce either syntactic metadata |
| 111 (e.g. double-mustache, double-bracket, star-attr), or semantic metadata |
| 112 (e.g. manual-bind, auto-bind, property-bind). Right now it's half and half. |
| 113 |
| 114 */ |
| 115 |
| 116 Polymer.Base._addFeature({ |
| 117 |
| 118 // registration-time |
| 119 |
| 120 _prepAnnotations: function() { |
| 121 if (!this._template) { |
| 122 this._notes = []; |
| 123 } else { |
| 124 // TODO(sorvell): ad hoc method of plugging behavior into Annotations |
| 125 Polymer.Annotations.prepElement = this._prepElement.bind(this); |
| 126 this._notes = Polymer.Annotations.parseAnnotations(this._template); |
| 127 Polymer.Annotations.prepElement = null; |
| 128 } |
| 129 }, |
| 130 |
| 131 _prepElement: function(element) { |
| 132 Polymer.ResolveUrl.resolveAttrs(element, this._template.ownerDocument); |
| 133 }, |
| 134 |
| 135 // instance-time |
| 136 |
| 137 findAnnotatedNode: Polymer.Annotations.findAnnotatedNode, |
| 138 |
| 139 // marshal all teh things |
| 140 _marshalAnnotationReferences: function() { |
| 141 if (this._template) { |
| 142 this._marshalIdNodes(); |
| 143 this._marshalAnnotatedNodes(); |
| 144 this._marshalAnnotatedListeners(); |
| 145 } |
| 146 }, |
| 147 |
| 148 // push configuration references at configure time |
| 149 _configureAnnotationReferences: function() { |
| 150 this._configureTemplateContent(); |
| 151 }, |
| 152 |
| 153 // nested template contents have been stored prototypically to avoid |
| 154 // unnecessary duplication, here we put references to the |
| 155 // indirected contents onto the nested template instances |
| 156 _configureTemplateContent: function() { |
| 157 this._notes.forEach(function(note) { |
| 158 if (note.templateContent) { |
| 159 var template = this.findAnnotatedNode(this.root, note); |
| 160 template._content = note.templateContent; |
| 161 } |
| 162 }, this); |
| 163 }, |
| 164 |
| 165 // construct `$` map (from id annotations) |
| 166 _marshalIdNodes: function() { |
| 167 this.$ = {}; |
| 168 this._notes.forEach(function(a) { |
| 169 if (a.id) { |
| 170 this.$[a.id] = this.findAnnotatedNode(this.root, a); |
| 171 } |
| 172 }, this); |
| 173 }, |
| 174 |
| 175 // concretize `_nodes` map (from anonymous annotations) |
| 176 _marshalAnnotatedNodes: function() { |
| 177 if (this._nodes) { |
| 178 this._nodes = this._nodes.map(function(a) { |
| 179 return this.findAnnotatedNode(this.root, a); |
| 180 }, this); |
| 181 } |
| 182 }, |
| 183 |
| 184 // install event listeners (from event annotations) |
| 185 _marshalAnnotatedListeners: function() { |
| 186 this._notes.forEach(function(a) { |
| 187 if (a.events && a.events.length) { |
| 188 var node = this.findAnnotatedNode(this.root, a); |
| 189 a.events.forEach(function(e) { |
| 190 this.listen(node, e.name, e.value); |
| 191 }, this); |
| 192 } |
| 193 }, this); |
| 194 } |
| 195 |
| 196 }); |
| 197 |
| 198 </script> |
OLD | NEW |