Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 <!DOCTYPE html>
3 <html>
5 <head>
6 <meta charset="utf8">
7 <title></title>
9 <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
10 <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
11 </head>
13 <div id="root">
14 <span template='{"type":"textContent","path":"title"}'></span>
15 <span template='{"type":"attribute","name":"title","path":"title"}'></span>
16 <span template='{"type":"localizedContent","paths":["foo2.foo_l10n","foo2.bar_l10n"],"property":"foo2"}'></span>
17 <div template-for='{"path":"mop","childSelector":"#template-for"}'></div>
18 <div template-loop='{"arrayPath":"foo1.bar1","childSelector":"#template-loop"}'></div>
19 </div>
21 <div id="ref0">
22 <span template='{"type":"textContent","path":"title"}'>ttt</span>
23 <span title="ttt" template='{"type":"attribute","name":"title","path":"title"}'></span>
24 <span template='{"type":"localizedContent","paths":["foo2.foo_l10n","foo2.bar_l10n"],"property":"foo2"}'>foo2:foo_l10n/bar_l10n</span>
25 <div template-for='{"path":"mop","childSelector":"#template-for"}'><span template='{"type":"textContent","path":"name","rootPath":"mop"}'>meh</span></div>
26 <div template-loop='{"arrayPath":"foo1.bar1","childSelector":"#template-loop"}'>
27 <div>
28 <span template='{"type":"textContent","path":"idx","rootPath":"foo1.bar1.0"}'>xx0</span>
29 <span template='{"type":"textContent","path":"a","rootPath":"foo1.bar1.0"}'>a</span>
30 <span template='{"type":"textContent","path":"b","rootPath":"foo1.bar1.0"}'>b</span>
31 </div>
32 <div>
33 <span template='{"type":"textContent","path":"idx","rootPath":"foo1.bar1.1"}'>xx1</span>
34 <span template='{"type":"textContent","path":"a","rootPath":"foo1.bar1.1"}'>a</span>
35 <span template='{"type":"textContent","path":"b","rootPath":"foo1.bar1.1"}'>b</span>
36 </div>
37 </div>
38 </div>
41 <div id="ref1">
42 <span template='{"type":"textContent","path":"title"}'>xxx</span>
43 <span title="xxx" template='{"type":"attribute","name":"title","path":"title"}'></span>
44 <span template='{"type":"localizedContent","paths":["foo2.foo_l10n","foo2.bar_l10n"],"property":"foo2"}'>foo2:foo2_l10n/bar_l10n</span>
45 <div template-for='{"path":"mop","childSelector":"#template-for"}'><span template='{"type":"textContent","path":"name","rootPath":"mop"}'>meh2</span></div>
46 <div template-loop='{"arrayPath":"foo1.bar1","childSelector":"#template-loop"}'>
47 <div>
48 <span template='{"type":"textContent","path":"idx","rootPath":"foo1.bar1.0"}'>xx0</span>
49 <span template='{"type":"textContent","path":"a","rootPath":"foo1.bar1.0"}'>a</span>
50 <span template='{"type":"textContent","path":"b","rootPath":"foo1.bar1.0"}'>b</span>
51 </div>
52 <div>
53 <span template='{"type":"textContent","path":"idx","rootPath":"foo1.bar1.1"}'>xx1</span>
54 <span template='{"type":"textContent","path":"a","rootPath":"foo1.bar1.1"}'>a</span>
55 <span template='{"type":"textContent","path":"b","rootPath":"foo1.bar1.1"}'>b</span>
56 </div>
57 </div>
58 </div>
60 <div id="ref2">
61 <span template='{"type":"textContent","path":"title"}'>xxx</span>
62 <span title="xxx" template='{"type":"attribute","name":"title","path":"title"}'></span>
63 <span template='{"type":"localizedContent","paths":["foo2.foo_l10n","foo2.bar_l10n"],"property":"foo2"}'>foo2:yyy/zzz</span>
64 <div template-for='{"path":"","childSelector":"#template-for"}'></div>
65 <div template-loop='{"arrayPath":"foo1.bar1","childSelector":"#template-loop"}'>
66 <div>
67 <span template='{"type":"textContent","path":"idx","rootPath":"foo1.bar1.0"}'>xx0</span>
68 <span template='{"type":"textContent","path":"a","rootPath":"foo1.bar1.0"}'>a</span>
69 <span template='{"type":"textContent","path":"b","rootPath":"foo1.bar1.0"}'>b</span>
70 </div>
71 <div>
72 <span template='{"type":"textContent","path":"idx","rootPath":"foo1.bar1.1"}'>xx1</span>
73 <span template='{"type":"textContent","path":"a","rootPath":"foo1.bar1.1"}'>a</span>
74 <span template='{"type":"textContent","path":"b","rootPath":"foo1.bar1.1"}'>b</span>
75 </div>
76 </div>
77 </div>
79 <div id="ref3">
80 <span template='{"type":"textContent","path":"title"}'>xxx</span>
81 <span title="xxx" template='{"type":"attribute","name":"title","path":"title"}'></span>
82 <span template='{"type":"localizedContent","paths":["foo2.foo_l10n","foo2.bar_l10n"],"property":"foo2"}'>foo2:yyy/zzz</span>
83 <div template-for='{"path":"","childSelector":"#template-for"}'></div>
84 <div template-loop='{"arrayPath":"foo1.bar1","childSelector":"#template-loop"}'>
85 <div>
86 <span template='{"type":"textContent","path":"idx","rootPath":"foo1.bar1.0"}'>xx0</span>
87 <span template='{"type":"textContent","path":"a","rootPath":"foo1.bar1.0"}'>a</span>
88 <span template='{"type":"textContent","path":"b","rootPath":"foo1.bar1.0"}'>b</span>
89 </div>
90 <div>
91 <span template='{"type":"textContent","path":"idx","rootPath":"foo1.bar1.1"}'>xx1</span>
92 <span template='{"type":"textContent","path":"a","rootPath":"foo1.bar1.1"}'>a</span>
93 <span template='{"type":"textContent","path":"b","rootPath":"foo1.bar1.1"}'>b</span>
94 </div>
95 <div>
96 <span template='{"type":"textContent","path":"idx","rootPath":"foo1.bar1.2"}'>xx2</span>
97 <span template='{"type":"textContent","path":"a","rootPath":"foo1.bar1.2"}'>a</span>
98 <span template='{"type":"textContent","path":"b","rootPath":"foo1.bar1.2"}'>b</span>
99 </div>
100 <div>
101 <span template='{"type":"textContent","path":"idx","rootPath":"foo1.bar1.3"}'>xx3</span>
102 <span template='{"type":"textContent","path":"a","rootPath":"foo1.bar1.3"}'>a</span>
103 <span template='{"type":"textContent","path":"b","rootPath":"foo1.bar1.3"}'>b</span>
104 </div>
105 <div>
106 <span template='{"type":"textContent","path":"idx","rootPath":"foo1.bar1.4"}'>xx4</span>
107 <span template='{"type":"textContent","path":"a","rootPath":"foo1.bar1.4"}'>a</span>
108 <span template='{"type":"textContent","path":"b","rootPath":"foo1.bar1.4"}'>b</span>
109 </div>
110 </div>
111 </div>
113 <div id="ref4">
114 <span template='{"type":"textContent","path":"title"}'>xxx</span>
115 <span title="xxx" template='{"type":"attribute","name":"title","path":"title"}'></span>
116 <span template='{"type":"localizedContent","paths":["foo2.foo_l10n","foo2.bar_l10n"],"property":"foo2"}'>foo2:yyy/zzz</span>
117 <div template-for='{"path":"","childSelector":"#template-for"}'></div>
118 <div template-loop='{"arrayPath":"foo1.bar1","childSelector":"#template-loop"}'>
119 <div>
120 <span template='{"type":"textContent","path":"idx","rootPath":"foo1.bar1.0"}'>xx0</span>
121 <span template='{"type":"textContent","path":"a","rootPath":"foo1.bar1.0"}'>a</span>
122 <span template='{"type":"textContent","path":"b","rootPath":"foo1.bar1.0"}'>b</span>
123 </div>
124 <div>
125 <span template='{"type":"textContent","path":"idx","rootPath":"foo1.bar1.1"}'>xx1</span>
126 <span template='{"type":"textContent","path":"a","rootPath":"foo1.bar1.1"}'>a</span>
127 <span template='{"type":"textContent","path":"b","rootPath":"foo1.bar1.1"}'>b</span>
128 </div>
129 <div>
130 <span template='{"type":"textContent","path":"idx","rootPath":"foo1.bar1.2"}'>xx2</span>
131 <span template='{"type":"textContent","path":"a","rootPath":"foo1.bar1.2"}'>a</span>
132 <span template='{"type":"textContent","path":"b","rootPath":"foo1.bar1.2"}'>b</span>
133 </div>
134 <div>
135 <span template='{"type":"textContent","path":"idx","rootPath":"foo1.bar1.3"}'>xx3</span>
136 <span template='{"type":"textContent","path":"a","rootPath":"foo1.bar1.3"}'>a</span>
137 <span template='{"type":"textContent","path":"b","rootPath":"foo1.bar1.3"}'>b</span>
138 </div>
139 </div>
140 </div>
144 <template id="template-loop">
145 <div>
146 <span template='{"type":"textContent","path":"idx"}'></span>
147 <span template='{"type":"textContent","path":"a"}'></span>
148 <span template='{"type":"textContent","path":"b"}'></span>
149 </div>
150 </template>
152 <template id="template-for">
153 <span template='{"type":"textContent","path":"name"}'></span>
154 </template>
156 <script type="application/javascript;version=1.8" src="chrome://browser/content/devtools/app-manager/template.js"></script>
157 <script type="application/javascript;version=1.8">
158 SimpleTest.waitForExplicitFinish();
160 const Cu = Components.utils;
161 Cu.import("resource:///modules/devtools/gDevTools.jsm");
162 const {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
163 const {require} = devtools;
164 const ObservableObject = require("devtools/shared/observable-object");
166 let data = {
167 title: "ttt",
168 mop: {
169 name: "meh",
170 },
171 foo1: {
172 bar1: [
173 {idx: "xx0", a: "a", b: "b"},
174 {idx: "xx1", a: "a", b: "b"},
175 ],
176 },
177 foo2: {
178 foo_l10n: "foo_l10n",
179 bar_l10n: "bar_l10n"
180 },
181 };
183 let store = new ObservableObject(data);
185 let changes = [
186 {
187 exec: function() {},
188 reference: document.querySelector("#ref0")
189 },
190 {
191 exec: function() {
192 store.object.title = "xxx";
193 store.object.foo2.foo_l10n = "foo2_l10n";
194 store.object.mop.name = "meh2";
195 },
196 reference: document.querySelector("#ref1")
197 },
198 {
199 exec: function() {
200 store.object.foo2 = {
201 foo_l10n: "yyy",
202 bar_l10n: "zzz",
203 }
204 let forElt = document.querySelector("#root > [template-for]");
205 forElt.setAttribute("template-for", '{"path":"","childSelector":"#template-for"}');
206 t._processFor(forElt);
207 },
208 reference: document.querySelector("#ref2")
209 },
210 {
211 exec: function() {
212 let items = [];
213 for (let i = 2; i < 5; i++) {
214 items.push({idx: "xx" + i, a: "a", b: "b"});
215 }
217 store.object.foo1.bar1 = store.object.foo1.bar1.concat(items);
218 },
219 reference: document.querySelector("#ref3")
220 },
221 {
222 exec: function() {
223 store.object.foo1.bar1.pop();
224 },
225 reference: document.querySelector("#ref4")
226 },
227 ];
229 function compare(node1, node2) {
230 let text1 = node1.innerHTML;
231 let text2 = node2.innerHTML;
232 text1 = text1.replace(/\n/g,"");
233 text2 = text2.replace(/\n/g,"");
234 text1 = text1.replace(/\s+/g,"");
235 text2 = text2.replace(/\s+/g,"");
236 return text1 == text2;
237 }
240 let root = document.querySelector("#root");
242 let t = new Template(root, store, (prop, args) => {
243 return prop + ":" + args.join("/");
244 });
246 t.start();
248 for (let i = 0; i < changes.length; i++) {
249 let change = changes[i];
250 change.exec();
251 ok(compare(change.reference, root), "Content " + i + " looks good.");
252 }
253 SimpleTest.finish();
255 </script>
256 </html>