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

Side by Side Diff: pkg/mdv/test/binding_syntax_test.dart

Issue 19663011: Custom Syntax's are now enabled via template.bindingDelegate = (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: restore @Experimental Created 7 years, 5 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/mdv/lib/src/template_iterator.dart ('k') | pkg/mdv/test/element_bindings_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library binding_syntax_test; 5 library binding_syntax_test;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 import 'dart:html'; 9 import 'dart:html';
10 import 'package:mdv/mdv.dart' as mdv; 10 import 'package:mdv/mdv.dart' as mdv;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 div.innerHtml = s; 45 div.innerHtml = s;
46 testDiv.append(div); 46 testDiv.append(div);
47 47
48 for (var node in div.queryAll('*')) { 48 for (var node in div.queryAll('*')) {
49 if (node.isTemplate) TemplateElement.decorate(node); 49 if (node.isTemplate) TemplateElement.decorate(node);
50 } 50 }
51 51
52 return div; 52 return div;
53 } 53 }
54 54
55 recursivelySetTemplateModel(element, model) {
56 for (var node in element.queryAll('*')) {
57 if (node.isTemplate) node.model = model;
58 }
59 }
60
61 observeTest('Registration', () { 55 observeTest('Registration', () {
62 var model = fooModel('bar'); 56 var model = fooModel('bar');
63 57
64 var testSyntax = new TestBindingSyntax(); 58 var testSyntax = new TestBindingSyntax();
65 TemplateElement.syntax['Test'] = testSyntax; 59 var div = createTestHtml('<template bind>{{ foo }}'
66 try { 60 '<template bind>{{ foo }}</template></template>');
67 var div = createTestHtml( 61 recursivelySetTemplateModel(div, model, testSyntax);
68 '<template bind syntax="Test">{{ foo }}' + 62 performMicrotaskCheckpoint();
69 '<template bind>{{ foo }}</template></template>'); 63 expect(div.nodes.length, 4);
70 recursivelySetTemplateModel(div, model); 64 expect(div.nodes.last.text, 'bar');
71 performMicrotaskCheckpoint(); 65 expect(div.nodes[2].tagName, 'TEMPLATE');
72 expect(div.nodes.length, 4);
73 expect(div.nodes.last.text, 'bar');
74 expect(div.nodes[2].tagName, 'TEMPLATE');
75 expect(div.nodes[2].attributes['syntax'], 'Test');
76 66
77 expect(testSyntax.log, [ 67 expect(testSyntax.log, [
78 [model, '', 'bind', 'TEMPLATE'], 68 [model, '', 'bind', 'TEMPLATE'],
79 [model, 'foo', 'text', null], 69 [model, 'foo', 'text', null],
80 [model, '', 'bind', 'TEMPLATE'], 70 [model, '', 'bind', 'TEMPLATE'],
81 [model, 'foo', 'text', null], 71 [model, 'foo', 'text', null],
82 ]); 72 ]);
83 } finally {
84 TemplateElement.syntax.remove('Test');
85 }
86 }); 73 });
87 74
88 observeTest('getInstanceModel', () { 75 observeTest('getInstanceModel', () {
89 var model = toObservable([fooModel(1), fooModel(2), fooModel(3)]); 76 var model = toObservable([fooModel(1), fooModel(2), fooModel(3)]);
90 77
91 var testSyntax = new TestModelSyntax(); 78 var testSyntax = new TestModelSyntax();
92 testSyntax.altModels.addAll([fooModel('a'), fooModel('b'), fooModel('c')]); 79 testSyntax.altModels.addAll([fooModel('a'), fooModel('b'), fooModel('c')]);
93 80
94 TemplateElement.syntax['Test'] = testSyntax; 81 var div = createTestHtml('<template repeat>{{ foo }}</template>');
95 try {
96 82
97 var div = createTestHtml( 83 var template = div.nodes[0];
98 '<template repeat syntax="Test">' + 84 recursivelySetTemplateModel(div, model, testSyntax);
99 '{{ foo }}</template>'); 85 performMicrotaskCheckpoint();
100 86
101 var template = div.nodes[0]; 87 expect(div.nodes.length, 4);
102 recursivelySetTemplateModel(div, model); 88 expect(div.nodes[0].tagName, 'TEMPLATE');
103 performMicrotaskCheckpoint(); 89 expect(div.nodes[1].text, 'a');
90 expect(div.nodes[2].text, 'b');
91 expect(div.nodes[3].text, 'c');
104 92
105 expect(div.nodes.length, 4); 93 expect(testSyntax.log, [
106 expect(div.nodes[0].tagName, 'TEMPLATE'); 94 [template, model[0]],
107 expect(div.nodes[1].text, 'a'); 95 [template, model[1]],
108 expect(div.nodes[2].text, 'b'); 96 [template, model[2]],
109 expect(div.nodes[3].text, 'c'); 97 ]);
110
111 expect(testSyntax.log, [
112 [template, model[0]],
113 [template, model[1]],
114 [template, model[2]],
115 ]);
116
117 } finally {
118 TemplateElement.syntax.remove('Test');
119 }
120 }); 98 });
121 99
122 observeTest('Basic', () { 100 observeTest('Basic', () {
123 var model = fooModel(2, 4); 101 var model = fooModel(2, 4);
124
125 TemplateElement.syntax['2x'] = new TimesTwoSyntax();
126
127 var div = createTestHtml( 102 var div = createTestHtml(
128 '<template bind syntax="2x">' 103 '<template bind syntax="2x">'
129 '{{ foo }} + {{ 2x: bar }} + {{ 4x: bar }}</template>'); 104 '{{ foo }} + {{ 2x: bar }} + {{ 4x: bar }}</template>');
130 recursivelySetTemplateModel(div, model); 105 recursivelySetTemplateModel(div, model, new TimesTwoSyntax());
131 performMicrotaskCheckpoint(); 106 performMicrotaskCheckpoint();
132 expect(div.nodes.length, 2); 107 expect(div.nodes.length, 2);
133 expect(div.nodes.last.text, '2 + 8 + '); 108 expect(div.nodes.last.text, '2 + 8 + ');
134 109
135 model.foo = 4; 110 model.foo = 4;
136 model.bar = 8; 111 model.bar = 8;
137 performMicrotaskCheckpoint(); 112 performMicrotaskCheckpoint();
138 expect(div.nodes.last.text, '4 + 16 + '); 113 expect(div.nodes.last.text, '4 + 16 + ');
139
140 TemplateElement.syntax.remove('2x');
141 });
142
143 observeTest('Different Sub-Template Syntax', () {
144 var model = fooModel('bar');
145
146 TemplateElement.syntax['Test'] = new TestBindingSyntax();
147 TemplateElement.syntax['Test2'] = new TestBindingSyntax();
148
149 var div = createTestHtml(
150 '<template bind syntax="Test">{{ foo }}'
151 '<template bind syntax="Test2">{{ foo }}</template></template>');
152 recursivelySetTemplateModel(div, model);
153 performMicrotaskCheckpoint();
154 expect(div.nodes.length, 4);
155 expect(div.nodes.last.text, 'bar');
156 expect(div.nodes[2].tagName, 'TEMPLATE');
157 expect(div.nodes[2].attributes['syntax'], 'Test2');
158
159 var testLog = TemplateElement.syntax['Test'].log;
160 var test2Log = TemplateElement.syntax['Test2'].log;
161
162 expect(testLog, [
163 [model, '', 'bind', 'TEMPLATE'],
164 [model, 'foo', 'text', null],
165 [model, '', 'bind', 'TEMPLATE']
166 ]);
167
168 expect(test2Log, [[model, 'foo', 'text', null]]);
169
170 TemplateElement.syntax.remove('Test');
171 TemplateElement.syntax.remove('Test2');
172 }); 114 });
173 } 115 }
174 116
175 // TODO(jmesserly): mocks would be cleaner here. 117 // TODO(jmesserly): mocks would be cleaner here.
176 118
177 class TestBindingSyntax extends CustomBindingSyntax { 119 class TestBindingSyntax extends BindingDelegate {
178 var log = []; 120 var log = [];
179 121
180 getBinding(model, String path, String name, Node node) { 122 getBinding(model, String path, String name, Node node) {
181 log.add([model, path, name, node is Element ? node.tagName : null]); 123 log.add([model, path, name, node is Element ? node.tagName : null]);
182 } 124 }
183 } 125 }
184 126
185 class TestModelSyntax extends CustomBindingSyntax { 127 class TestModelSyntax extends BindingDelegate {
186 var log = []; 128 var log = [];
187 var altModels = new ListQueue(); 129 var altModels = new ListQueue();
188 130
189 getInstanceModel(template, model) { 131 getInstanceModel(template, model) {
190 log.add([template, model]); 132 log.add([template, model]);
191 return altModels.removeFirst(); 133 return altModels.removeFirst();
192 } 134 }
193 } 135 }
194 136
195 // Note: this isn't a very smart whitespace handler. A smarter one would only 137 // Note: this isn't a very smart whitespace handler. A smarter one would only
196 // trim indentation, not all whitespace. 138 // trim indentation, not all whitespace.
197 // See "trimOrCompact" in the web_ui Pub package. 139 // See "trimOrCompact" in the web_ui Pub package.
198 class WhitespaceRemover extends CustomBindingSyntax { 140 class WhitespaceRemover extends BindingDelegate {
199 int trimmed = 0; 141 int trimmed = 0;
200 int removed = 0; 142 int removed = 0;
201 143
202 DocumentFragment getInstanceFragment(Element template) { 144 DocumentFragment getInstanceFragment(Element template) {
203 var instance = template.createInstance(); 145 var instance = template.createInstance();
204 var walker = new TreeWalker(instance, NodeFilter.SHOW_TEXT); 146 var walker = new TreeWalker(instance, NodeFilter.SHOW_TEXT);
205 147
206 var toRemove = []; 148 var toRemove = [];
207 while (walker.nextNode() != null) { 149 while (walker.nextNode() != null) {
208 var node = walker.currentNode; 150 var node = walker.currentNode;
209 var text = node.text.replaceAll('\n', '').trim(); 151 var text = node.text.replaceAll('\n', '').trim();
210 if (text.length != node.text.length) { 152 if (text.length != node.text.length) {
211 if (text.length == 0) { 153 if (text.length == 0) {
212 toRemove.add(node); 154 toRemove.add(node);
213 } else { 155 } else {
214 trimmed++; 156 trimmed++;
215 node.text = text; 157 node.text = text;
216 } 158 }
217 } 159 }
218 } 160 }
219 161
220 for (var node in toRemove) node.remove(); 162 for (var node in toRemove) node.remove();
221 removed += toRemove.length; 163 removed += toRemove.length;
222 164
223 return instance; 165 return instance;
224 } 166 }
225 } 167 }
226 168
227 class TimesTwoSyntax extends CustomBindingSyntax { 169 class TimesTwoSyntax extends BindingDelegate {
228 getBinding(model, path, name, node) { 170 getBinding(model, path, name, node) {
229 path = path.trim(); 171 path = path.trim();
230 if (!path.startsWith('2x:')) return null; 172 if (!path.startsWith('2x:')) return null;
231 173
232 path = path.substring(3); 174 path = path.substring(3);
233 return new CompoundBinding((values) => values['value'] * 2) 175 return new CompoundBinding((values) => values['value'] * 2)
234 ..bind('value', model, path); 176 ..bind('value', model, path);
235 } 177 }
236 } 178 }
OLDNEW
« no previous file with comments | « pkg/mdv/lib/src/template_iterator.dart ('k') | pkg/mdv/test/element_bindings_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698