1 | <!DOCTYPE html> |
---|
2 | <html> |
---|
3 | <head> |
---|
4 | <meta http-equiv="Content-type" content="text/html; charset=utf-8"> |
---|
5 | <title>_Templated tests</title> |
---|
6 | <script type="text/javascript" src="../../dojo/dojo.js" |
---|
7 | data-dojo-config="isDebug: true"></script> |
---|
8 | <script type="text/javascript"> |
---|
9 | require([ |
---|
10 | "doh/runner", |
---|
11 | "dojo/_base/array", "dojo/_base/declare", "dojo/dom", "dojo/query", |
---|
12 | "dijit/_WidgetBase", "dijit/_TemplatedMixin", "dijit/_WidgetsInTemplateMixin", "dijit/layout/LayoutContainer", |
---|
13 | "dojo/domReady!" |
---|
14 | ], function(doh, array, declare, dom, query, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin){ |
---|
15 | |
---|
16 | function getOuterHTML(/*DomNode*/ node){ |
---|
17 | var wrapper = document.createElement("div"); |
---|
18 | wrapper.appendChild(node); |
---|
19 | return wrapper.innerHTML.toLowerCase(); // IE prints <BUTTON> rather than <button>; normalize it. |
---|
20 | } |
---|
21 | |
---|
22 | // Template with no variables (should be cached as a DOM tree) |
---|
23 | declare("SimpleTemplate", [_WidgetBase, _TemplatedMixin], { |
---|
24 | id: "test1", |
---|
25 | _setIdAttr: null, // override _Widget to not copy id to domNode |
---|
26 | |
---|
27 | templateString: "<button type='button'><span>hello < world</span></button>" |
---|
28 | }); |
---|
29 | |
---|
30 | // Template with variables |
---|
31 | declare("VariableTemplate", [_WidgetBase, _TemplatedMixin], { |
---|
32 | id: "test2", |
---|
33 | _setIdAttr: null, // override _Widget to not copy id to domNode |
---|
34 | |
---|
35 | num: 5, |
---|
36 | bool: false, |
---|
37 | text: "hello <\"' world", |
---|
38 | |
---|
39 | templateString: "<button><span num=\"${num}\" value=\"${bool}\">${text}</span></button>" |
---|
40 | }); |
---|
41 | |
---|
42 | // Template with ! variables (for literal substitution) |
---|
43 | declare("ExclamationVariableTemplate", [_WidgetBase, _TemplatedMixin], { |
---|
44 | markup: "<span>hello world</span>", |
---|
45 | |
---|
46 | templateString: "<div>${!markup}</div>" |
---|
47 | }); |
---|
48 | |
---|
49 | // Template that starts with special node (has to be constructed inside a <tbody>) |
---|
50 | declare("TableRowTemplate", [_WidgetBase, _TemplatedMixin], { |
---|
51 | id: "test3", |
---|
52 | _setIdAttr: null, // override _Widget to not copy id to domNode |
---|
53 | text: "bar", |
---|
54 | |
---|
55 | templateString: "<tr><td>${text}</td></tr>" |
---|
56 | }); |
---|
57 | |
---|
58 | // Illegal substitution variable name |
---|
59 | declare("IllegalSubstitution", [_WidgetBase, _TemplatedMixin], { |
---|
60 | templateString: "<tr><td>${fake}</td></tr>" |
---|
61 | }); |
---|
62 | |
---|
63 | // data-dojo-attach-point |
---|
64 | declare("AttachPoint", [_WidgetBase, _TemplatedMixin], { |
---|
65 | templateString: "<div style='border: 1px solid red'>" + |
---|
66 | "<button data-dojo-attach-point='buttonNode,focusNode'>hi</button>" + |
---|
67 | '<span><input data-dojo-attach-point="inputNode" value="input"/></span>' + |
---|
68 | "<span data-dojo-attach-point='containerNode'></span>" + |
---|
69 | "</div>" |
---|
70 | }); |
---|
71 | |
---|
72 | // data-dojo-attach-event |
---|
73 | declare("AttachEvent", [_WidgetBase, _TemplatedMixin], { |
---|
74 | click: function(){ |
---|
75 | this.clickCalled = true; |
---|
76 | }, |
---|
77 | onfocus: function(){ |
---|
78 | this.focusCalled = true; |
---|
79 | }, |
---|
80 | focus2: function(){ |
---|
81 | this.focus2Called = true; |
---|
82 | }, |
---|
83 | templateString: "<table style='border: 1px solid blue'><tr>" + |
---|
84 | "<td><button type='button' data-dojo-attach-point='left' data-dojo-attach-event='onclick: click, onfocus'>left</button></td>" + |
---|
85 | "<td><button type='button' data-dojo-attach-point='right' data-dojo-attach-event='onclick: click, onfocus: focus2'>right</button></td>" + |
---|
86 | "</tr></table>" |
---|
87 | }); |
---|
88 | |
---|
89 | var testW; |
---|
90 | |
---|
91 | doh.register("_TemplatedMixin", [ |
---|
92 | function simple(t){ |
---|
93 | var widget = new SimpleTemplate(); |
---|
94 | var wrapper = dom.byId("simpleWrapper"); |
---|
95 | wrapper.appendChild(widget.domNode); |
---|
96 | |
---|
97 | // Different browsers have different orders for type=button and widgetid=... so simplify |
---|
98 | // by just removing the type=button. |
---|
99 | t.is('<button widgetid=\"test1\"><span>hello < world</span></button>', wrapper.innerHTML.toLowerCase().replace(/ type="?button"?/, "")); |
---|
100 | }, |
---|
101 | |
---|
102 | function variables(t){ |
---|
103 | var widget = new VariableTemplate(); |
---|
104 | var span = widget.domNode.getElementsByTagName("span")[0]; |
---|
105 | var text = span.innerHTML; |
---|
106 | t.is("5", span.getAttribute("num")); |
---|
107 | t.is("false", span.getAttribute("value")); |
---|
108 | t.is("hello <\"' world", text); |
---|
109 | }, |
---|
110 | function variables2(t){ |
---|
111 | var widget = new VariableTemplate({id: "myid", num: -5, bool: true, text: ""}); |
---|
112 | var span = widget.domNode.getElementsByTagName("span")[0]; |
---|
113 | var text = span.innerHTML; |
---|
114 | t.is("-5", span.getAttribute("num")); |
---|
115 | t.is("true", span.getAttribute("value")); |
---|
116 | t.is("", text); |
---|
117 | }, |
---|
118 | function variablesWithExclamation(t){ |
---|
119 | var widget = new ExclamationVariableTemplate(); |
---|
120 | |
---|
121 | // ExclamationVariableTemplate should create markup like |
---|
122 | // <div><span>hello world</span></div> |
---|
123 | // The <span> comes from the ${!markup} variable. |
---|
124 | var span = query("> *", widget.domNode); |
---|
125 | t.is(1, span.length, "dom node has one child"); |
---|
126 | t.is("SPAN", span[0].nodeName.toUpperCase(), "which is a span"); |
---|
127 | t.is("hello world", span[0].innerHTML, "and the text is set correctly too"); |
---|
128 | }, |
---|
129 | |
---|
130 | function table(t){ |
---|
131 | var widget = new TableRowTemplate({text: "hello"}); |
---|
132 | var wrapper = dom.byId("trWrapper"); |
---|
133 | wrapper.appendChild(widget.domNode); |
---|
134 | var actual = wrapper.innerHTML.toLowerCase().replace(/\r/g, "").replace(/\n/g, ""); |
---|
135 | t.is('<tr widgetid="test3"><td>hello</td></tr>', actual); |
---|
136 | }, |
---|
137 | function illegal(t){ |
---|
138 | var hadException = false; |
---|
139 | try{ |
---|
140 | var widget = new IllegalSubstitution(); |
---|
141 | }catch(e){ |
---|
142 | console.log(e); |
---|
143 | hadException = true; |
---|
144 | } |
---|
145 | t.t(hadException); |
---|
146 | }, |
---|
147 | function attachPoint(t){ |
---|
148 | var widget = new AttachPoint(); |
---|
149 | var wrapper = dom.byId("attachPointWrapper"); |
---|
150 | wrapper.appendChild(widget.domNode); |
---|
151 | t.is(widget.containerNode.tagName.toLowerCase(), "span"); |
---|
152 | t.is(widget.buttonNode.tagName.toLowerCase(), "button"); |
---|
153 | t.is(widget.focusNode.tagName.toLowerCase(), "button"); |
---|
154 | t.is(widget.inputNode.tagName.toLowerCase(), "input"); |
---|
155 | }, |
---|
156 | function attachEvent(t){ |
---|
157 | var deferred = new doh.Deferred(); |
---|
158 | var widget = new AttachEvent(); |
---|
159 | var wrapper = dom.byId("attachEventWrapper"); |
---|
160 | wrapper.appendChild(widget.domNode); |
---|
161 | widget.left.focus(); |
---|
162 | widget.right.focus(); |
---|
163 | setTimeout(deferred.getTestCallback(function(){ |
---|
164 | t.t(widget.focusCalled, "left focused"); |
---|
165 | t.t(widget.focus2Called, "right focused"); |
---|
166 | }), 50); |
---|
167 | return deferred; |
---|
168 | }, |
---|
169 | |
---|
170 | function widgetsInTemplateLifecycle(t){ |
---|
171 | |
---|
172 | var result = [], expected = [1, 1, 0, 2, 2, 3]; |
---|
173 | |
---|
174 | // widgetsInTemplateLifecycle |
---|
175 | declare("SubThing", _WidgetBase, { |
---|
176 | postCreate: function(){ |
---|
177 | this.inherited(arguments); |
---|
178 | result.push(1); |
---|
179 | }, |
---|
180 | startup: function(){ |
---|
181 | this.inherited(arguments); |
---|
182 | result.push(2); |
---|
183 | } |
---|
184 | }); |
---|
185 | |
---|
186 | declare("ParentThing", [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], { |
---|
187 | templateString: "<div>" + |
---|
188 | "<span data-dojo-type='SubThing'>a</span>" + |
---|
189 | "<div data-dojo-type='dijit/layout/LayoutContainer'>" + |
---|
190 | "<span data-dojo-type='SubThing' data-dojo-props='region: \"center\"'>b</span>" + |
---|
191 | "</div>" + |
---|
192 | "</div>", |
---|
193 | postCreate: function(){ |
---|
194 | // children postcreate (x2) called before this postCreate |
---|
195 | this.inherited(arguments); |
---|
196 | result.push(0); |
---|
197 | }, |
---|
198 | startup: function(){ |
---|
199 | // then children startup (x2) then our startup |
---|
200 | // (we can call inherited after push(), and change the order) |
---|
201 | this.inherited(arguments); |
---|
202 | result.push(3); |
---|
203 | } |
---|
204 | }); |
---|
205 | |
---|
206 | new ParentThing().startup(); |
---|
207 | |
---|
208 | t.is(expected.length, result.length); |
---|
209 | array.forEach(expected, function(r){ |
---|
210 | t.is(r, result.shift()); |
---|
211 | }); |
---|
212 | |
---|
213 | }, |
---|
214 | |
---|
215 | // Test IE problem having "length" as data-dojo-attach-point name |
---|
216 | function length(){ |
---|
217 | var MyWidget = declare([_WidgetBase, _TemplatedMixin], { |
---|
218 | name: "", |
---|
219 | templateString: "<div>" + |
---|
220 | "<input data-dojo-attach-point='focusNode' name='${name}'>" + |
---|
221 | "<span data-dojo-attach-point='spanNode'>" + |
---|
222 | "</div>" |
---|
223 | }); |
---|
224 | var widget = new MyWidget({name: "length"}); |
---|
225 | doh.isNot(undefined, widget.focusNode, "focusNode"); |
---|
226 | doh.isNot(undefined, widget.spanNode, "spanNode"); |
---|
227 | } |
---|
228 | ]); |
---|
229 | |
---|
230 | // This is more of a test of _WidgetBase, but putting here for convenience |
---|
231 | // since it tests the case when srcNodeRef is swapped for a widget's template |
---|
232 | doh.register("srcNodeRef", [ |
---|
233 | function replaceMe(){ |
---|
234 | var prev = dom.byId("replaceMe").previousSibling; |
---|
235 | |
---|
236 | // This should swap out the <span id="replaceMe"> w/the widget |
---|
237 | var widget = new SimpleTemplate({}, "replaceMe"); |
---|
238 | |
---|
239 | // Make sure the swap occurred |
---|
240 | doh.is(widget.domNode, prev.nextSibling, "swapped"); |
---|
241 | doh.is(null, dom.byId("replaceMe"), "original node removed"); |
---|
242 | |
---|
243 | // For garbage collection widget.srcNodeRef should also be cleared |
---|
244 | doh.is(null, widget.srcNodeRef, "srcNodeRef cleared"); |
---|
245 | } |
---|
246 | ]); |
---|
247 | |
---|
248 | doh.register("_rendered", [ |
---|
249 | function preRendered(){ |
---|
250 | // Testing for when a widget's template is expanded on the server, so _rendered:true is passed |
---|
251 | // as a parameter to the widget constructor. |
---|
252 | var MyWidget = declare([_WidgetBase, _TemplatedMixin], { |
---|
253 | declaredClass: "MyWidget", |
---|
254 | templateString: "<input>" // shouldn't be used, just listing a template for testing purposes |
---|
255 | }); |
---|
256 | var widget = new MyWidget({ |
---|
257 | _rendered: true // flag to not do template insertion |
---|
258 | }, dom.byId("prerendered")); |
---|
259 | doh.t(widget.heading, "heading attach point setup"); |
---|
260 | doh.is("h2", widget.heading.tagName.toLowerCase()); |
---|
261 | } |
---|
262 | ]); |
---|
263 | |
---|
264 | doh.run(); |
---|
265 | }); |
---|
266 | </script> |
---|
267 | </head> |
---|
268 | <body> |
---|
269 | <h1>_TemplatedMixin test</h1> |
---|
270 | |
---|
271 | <div id="simpleWrapper"></div> |
---|
272 | <table> |
---|
273 | <tbody id="trWrapper"></tbody> |
---|
274 | </table> |
---|
275 | <div id="attachPointWrapper"></div> |
---|
276 | <div id="attachEventWrapper"></div> |
---|
277 | <span id="replaceMe"></span> |
---|
278 | |
---|
279 | <!-- test for _rendered=true flag --> |
---|
280 | <div id="prerendered"> |
---|
281 | <h2 data-dojo-attach-point="heading">hi</h2> |
---|
282 | </div> |
---|
283 | </body> |
---|
284 | </html> |
---|