source: Dev/trunk/src/client/dojo/tests/parser/parser.html @ 485

Last change on this file since 485 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 41.7 KB
Line 
1<!DOCTYPE html>
2<html>
3        <head>
4                <title>Parser Unit Test</title>
5                <style type="text/css">
6                        @import "../../resources/dojo.css";
7                </style>
8                <script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug:true, async:true"></script>
9                <script type="text/javascript">
10                var MyNonDojoClass = function() {};
11                MyNonDojoClass.extend = function(){
12                        var args = arguments;
13                        return function() {
14                                this.expectedClass = true;
15                                this.params = args;
16                        };
17                };
18
19                require([
20                        "require", "dojo/_base/array", "dojo/aspect", "dojo/_base/declare",
21                        "dojo/dom", "dojo/dom-attr", "dojo/dom-construct", "dojo/_base/lang", "dojo/on", "dojo/parser",
22                        "dojo/_base/window", "dojo/date/stamp", "dojo/Stateful", "dojo/Evented",
23                        "doh", "dojo/tests/resources/AMDWidget", "dojo/tests/resources/AMDMixin", "dojo/domReady!"
24                ], function(require, array, aspect, declare, dom, domAttr, domConstruct, lang, on, parser, win, dstamp,
25                                                Stateful, Evented, doh, AMDWidget, AMDMixin){
26
27                        declare("tests.parser.Widget", null, {
28                                constructor: function(args, node){
29                                        this.params = args;
30                                }
31                        });
32
33                        declare("tests.parser.Class1", null, {
34                                constructor: function(args, node){
35                                        this.params = args;
36                                        lang.mixin(this, args);
37                                },
38                                preambleTestProp: 1,
39                                preamble: function(){
40                                        this.preambleTestProp++;
41                                },
42                                intProp: 1,
43                                callCount: 0, // for connect testing
44                                callInc: function(){ this.callCount++; },
45                                callCount2: 0, // for assignment testing
46                                strProp1: "original1",
47                                strProp2: "original2",
48                                arrProp: [],
49                                arrProp2: ["foo"],
50                                boolProp1: false,
51                                boolProp2: true,
52                                boolProp3: false,
53                                boolProp4: true,
54                                dateProp1: dstamp.fromISOString('2007-01-01'),
55                                dateProp2: dstamp.fromISOString('2007-01-01'),
56                                dateProp3: dstamp.fromISOString('2007-01-01'),
57                                funcProp: function(){},
58                                funcProp2: function(){},
59                                funcProp3: function(){},
60                                onclick: function(){ this.prototypeOnclick=true; }
61                                // FIXME: have to test dates!!
62                                // FIXME: need to test the args property!!
63                        });
64
65                        declare("tests.parser.Class2", null, {
66                                constructor: function(){
67                                        this.fromMarkup = false;
68                                },
69                                fromMarkup: false,
70                                markupFactory: function(args, node, classCtor){
71                                        var i = new tests.parser.Class2();
72                                        i.fromMarkup = true;
73                                        return i;
74                                }
75                        });
76
77                        declare("tests.parser.Class3", tests.parser.Class2, {
78                                fromMarkup: false,
79                                markupFactory: function(args, node, classCtor){
80                                        var i = new classCtor();
81                                        i.classCtor = classCtor;
82                                        i.params = args;
83                                        return i;
84                                }
85                        });
86
87                        declare("tests.parser.InputClass", null, {
88                                constructor: function(args, node){
89                                        this.params = args;
90                                        lang.mixin(this, args);
91                                },
92
93                                // these attributes are special in HTML, they don't have a value specified
94                                disabled: false,
95                                readonly: false,
96                                checked: false,
97
98                                // other attributes native to HTML
99                                value: "default value",
100                                title: "default title",
101                                tabIndex: "0",          // special because mixed case
102
103                                // custom widget attributes that don't match a native HTML attributes
104                                custom1: 123,
105                                custom2: 456
106                        });
107
108                        // Test that dir, lang, etc. attributes can be inherited from ancestor node
109                        declare("tests.parser.BidiClass", tests.parser.Widget, {
110                                constructor: function(args, node){ lang.mixin(this, args); },
111                                dir: "",
112                                lang: "",
113                                textdir: "",
114                                name: ""
115                        });
116
117                        // For testing that parser recurses correctly, except when the prototype has a
118                        // stopParser flag
119                        declare("tests.parser.NormalContainer", null, {
120                                constructor: function(args, node){ lang.mixin(this, args); }
121                        });
122                        declare("tests.parser.ShieldedContainer", null, {
123                                constructor: function(args, node){ lang.mixin(this, args); },
124
125                                // flag to tell parser not to instantiate nodes inside of me
126                                stopParser: true
127                        });
128
129                        declare("tests.parser.HTML5Props", null, {
130                                constructor: function(args, node){ lang.mixin(this, args); },
131                                simple:false,
132                                a:2,
133                                b:null, c:null, d: null, e:null, f:null,
134                                afn: function(){
135                                        return this.a * 2;
136                                }
137                        });
138
139                        // not on .prototype:
140                        tests.parser.HTML5Props._aDefaultObj = {
141                                a:1, b:2, simple:true
142                        };
143
144                        declare("tests.parser.HTML5withMethod", null, {
145                                constructor: function(args, node){ lang.mixin(this, args); },
146                                baseValue: 10,
147                                someMethod: function(a, b){
148                                        return this.baseValue;
149                                },
150                                diffMethod: function(a){
151                                        this._ran = true;
152                                }
153                        });
154
155                        declare("tests.parser.StatefulClass", [Evented, Stateful], {
156                                strProp1: "",
157                                objProp1: {},
158                                boolProp1: false,
159                                prototypeOnclick: false,
160                                onclick: function() {this.prototypeOnclick=true;}
161                        });
162
163                        declare("tests.parser.MethodClass", null, {
164                                method1ran: false,
165                                method1after: false,
166                                method2ran: false,
167                                method2before: false,
168                                method2after: false,
169                                method3result: "",
170                                method4ran: false,
171                                method4after: false,
172                                method1: function() { this.method1ran = true },
173                                method2: function() { this.method2ran = true },
174                                method3: function(result) { this.method3result = result; },
175                                method4: function() { this.method4ran = true }
176                        });
177
178                        declare("tests.parser.ClassForMixins", null, {
179                                classDone: true
180                        });
181
182                        declare("tests.parser.Mixin1", null, {
183                                mixin1Done: true
184                        });
185
186                        declare("tests.parser.Mixin2", null, {
187                                mixin2Done: true
188                        });
189
190                        deepTestProp = {
191                                blah: {
192                                        thinger: 1
193                                }
194                        };
195
196                        tests.parser.FormClass = declare(tests.parser.Widget, {
197                                encType: ""
198                        });
199
200                        doh.register("basic tests", [
201                                function parse(){
202                                        // Running the parser here so that failures appear in test log
203                                        parser.parse(dom.byId("main"));
204                                },
205                                function testDataDojoId(t){
206                                        t.is("object", typeof obj);
207                                },
208                                function testJsId(t){
209                                        // Back-compat test, remove for 2.0
210                                        t.is("object", typeof obj3);
211                                },
212                                // Attribute parsing tests
213                                function testStrProp(t){
214                                        // normal string parameter
215                                        t.t(typeof obj.strProp1 == "string", "obj.strProp1 is string");
216                                        t.is("text", obj.strProp1);
217
218                                        // make sure that you override a string value like "foo" to a blank value
219                                        t.t(typeof obj.strProp2 == "string", "obj.strProp2 is string");
220                                        t.is("", obj.strProp2);
221                                },
222                                function testIntProp(t){
223                                        t.is("number", (typeof obj.intProp));
224                                        t.is(5, obj.intProp);
225                                },
226                                function testArrProp(t){
227                                        t.is(3, obj.arrProp.length);
228                                        t.is(3, obj.arrProp[1].length);
229                                        t.is(["foo", "bar", "baz"], obj.arrProp);
230
231                                        // make sure empty arrays are possible
232                                        t.is([], obj.arrProp2);
233                                },
234                                function testBoolProp(t){
235                                        // make sure that both true and false get read correctly,
236                                        // and that unspecified attributes' values don't change
237
238                                        // boolProp1 specified at true
239                                        t.is("boolean", (typeof obj.boolProp1));
240                                        t.t(obj.boolProp1);
241
242                                        // boolProp2 specified as false
243                                        t.is("boolean", (typeof obj.boolProp2));
244                                        t.f(obj.boolProp2);
245
246                                        // boolProp3 not specified (prototype says false)
247                                        t.is("boolean", (typeof obj.boolProp3));
248                                        t.f(obj.boolProp3);
249
250                                        // boolProp4 not specified (prototype says true)
251                                        t.is("boolean", (typeof obj.boolProp4));
252                                        t.t(obj.boolProp4);
253                                },
254                                function testDateProp(t){
255                                        // dateProp1 specified as 2006-1-1
256                                        t.is("2006-01-01", dstamp.toISOString(obj.dateProp1, {selector: 'date'}));
257
258                                        // dateProp2="", should map to NaN (a blank value on DateTextBox)
259                                        t.t(isNaN(obj.dateProp2));
260
261                                        // dateProp3="now", should map to current date
262                                        t.is(dstamp.toISOString(new Date(), {selector: 'date'}),
263                                                dstamp.toISOString(obj.dateProp3, {selector: 'date'}));
264                                },
265                                function testUnwantedParams(t){
266                                        // Make sure that parser doesn't pass any unwanted parameters to
267                                        // widget constructor, especially "toString" or "constructor".
268                                        // Make exception for dir/lang which parser gleans from document itself.
269                                        for(var param in obj.params){
270                                                doh.t(array.indexOf(
271                                                        ["strProp1", "strProp2",
272                                                                "intProp",
273                                                                "arrProp", "arrProp2",
274                                                                "boolProp1", "boolProp2",
275                                                                "dateProp1", "dateProp2", "dateProp3",
276                                                                "funcProp2", "funcProp3",
277                                                                "preamble",
278                                                                "callInc1", "callInc2", "dir", "lang", "textDir"],
279                                                        param) >= 0, param);
280                                        }
281                                },
282                                function testDisabledFlag(t){
283                                        t.is("boolean", typeof disabledObj.disabled, "typeof disabled");
284                                        t.t(disabledObj.disabled, "disabled");
285                                        t.f(disabledObj.checked, "checked");
286                                },
287                                function testCheckedFlag(t){
288                                        t.is("boolean", typeof checkedObj.checked, "typeof checked");
289                                        t.f(checkedObj.disabled, "disabled");
290                                        t.t(checkedObj.checked, "checked");
291                                },
292                                function testFunctionProp(t){
293                                        // make sure that unspecified functions (even with common names)
294                                        // don't get overridden (bug #3074)
295                                        obj.onclick();
296                                        t.t(obj.prototypeOnclick, "prototypeOnClick");
297
298                                        // funcProp2="foo"
299                                        obj.funcProp2();
300                                        t.t(obj.fooCalled, "fooCalled");
301
302                                        // funcProp3="this.func3Called=true;"
303                                        obj.funcProp3();
304                                        t.t(obj.func3Called, "func3Called");
305                                },
306
307                                // test script tags inside innerHTML of source node
308                                "t.is(4, obj.preambleTestProp);",
309                                "t.is(deepTestProp, obj.deepProp);",
310                                function testConnect(t){
311                                        obj.callInc();
312                                        t.is(2, obj.callCount);
313                                },
314                                function testFunctionAssignment(t){
315                                        obj.callInc2();
316                                        t.is(1, obj.callCount2);
317                                },
318                                function testSubNodeParse(t){
319                                        t.f(lang.exists("obj2"), "exists before parse");
320                                        var toParse = dom.byId("toParse");
321                                        parser.parse(toParse.parentNode);
322                                        t.t(lang.exists("obj2"), "exists after parse");
323                                        t.is("tests.parser.Class1", obj2.declaredClass);
324                                },
325                                function testMarkupFactory(t){
326                                        t.t(lang.exists("obj3"), "obj3 exists");
327                                        t.t(obj3.fromMarkup);
328                                },
329                                function testMarkupFactoryClass(t){
330                                        t.t(lang.exists("obj4"), "obj4 exists");
331                                        t.is(obj4.classCtor, tests.parser.Class3);
332                                        t.t(obj4 instanceof tests.parser.Class3);
333                                        t.t(obj4 instanceof tests.parser.Class2);
334                                },
335                                function testnostart(t){
336
337                                        var started = false;
338                                        declare("SampleThinger", null, {
339                                                startup: function(){
340                                                        started = true;
341                                                }
342                                        });
343
344                                        domConstruct.create("div", { dojoType:"SampleThinger" }, "parsertest");
345                                        parser.parse("parsertest", { noStart:true });
346
347                                        t.f(started, "first started check");
348
349                                        domConstruct.empty("parsertest");
350
351                                        started = false;
352
353                                        domConstruct.create("div", { dojoType:"SampleThinger" }, "parsertest");
354                                        parser.parse({ noStart:true, rootNode:"parsertest" });
355
356                                        t.f(started, "second started check");
357                                },
358
359                                // test the various iterations of parser test
360                                function rootTest(t){
361
362                                        var tmp = aspect.after(dojo, "query", function(sel, root){
363                                                t.is("parsertest2", root);
364                                        });
365
366                                        parser.parse("parsertest2");
367                                        parser.parse({ rootNode: "parsertest2" });
368                                        parser.parse("parsertest2", { noStart:true });
369
370                                        tmp.remove();
371                                },
372
373                                // Test that when BorderContainer etc. extends _Widget,
374                                // parser is aware of the new parameters added (to _Widget
375                                // and all of it's subclasses)
376                                function cacheRefresh(t){
377                                        // Add new node to be parsed, referencing a widget that the parser has already
378                                        // dealt with (and thus cached)
379                                        var wrapper = domConstruct.place("<div><div dojoType='tests.parser.Class3' newParam=12345>hi</div></div>", win.body(), "last");
380
381                                        // Modify Class3's superclass widget to have new parameter (thus Class3 inherits it)
382                                        lang.extend(tests.parser.Class2, {
383                                                newParam: 0
384                                        });
385
386                                        // Run the parser and see if it reads in newParam
387                                        var widgets = parser.parse({rootNode: wrapper});
388                                        doh.is(1, widgets.length, "parsed newly inserted parserTest widget");
389                                        doh.is(12345, widgets[0].params.newParam, "new parameter parsed");
390                                },
391
392                                // Test that parser recurses correctly, except when there's a stopParser flag not to
393                                function recurse(){
394                                        doh.t(container1, "normal container created");
395                                        doh.t(container1.incr, "script tag works too");
396                                        doh.t(window.contained1, "child widget also created");
397                                        doh.t(window.contained2, "child widget 2 also created");
398
399                                        doh.t(container2, "shielded container created");
400                                        doh.t(container2.incr, "script tag works too");
401                                        doh.f(window.contained3, "child widget not created");
402                                        doh.f(window.contained4, "child widget 2 not created");
403                                },
404
405                                function simpleHTML5(){
406                                        doh.is("object", typeof html5simple, "data-dojo-id export");
407                                        doh.is("object", typeof html5simple2, "data-dojo-id export");
408
409                                        doh.t(html5simple.simple, "default respecified in props=''");
410                                        doh.f(html5simple2.simple, "default overridden by props=''");
411
412                                        // test data-dojo-props="simple:false, a:1, b:'two', c:[1,2,3], d:function(){ return this; }, e:{ f:'g' }"
413                                        var it = html5simple2;
414                                        doh.is(1, it.a, "number in param");
415                                        doh.is("two", it.b, "string in param");
416                                        doh.t(it.c instanceof Array, "array in param");
417                                        doh.is(3, it.c.length, "array sanity");
418                                        doh.is("g", it.e.f, "nested object with string");
419
420                                        // test the function
421                                        doh.is(it, it.d(), "simple 'return this' function");
422
423                                },
424
425                                function html5inherited(){
426                                        doh.is("object", typeof html5simple3);
427                                        var val = html5simple3.afn();
428                                        doh.is(html5simple3.a * 2, val, "afn() overrides default but calls inherited")
429                                },
430
431                                function html5withMethod(){
432                                        // testing data-dojo-event and data-dojo-args support for dojo/method and dojo/connect
433                                        doh.is("object", typeof htmldojomethod);
434                                        doh.t(htmldojomethod._methodRan, "plain dojo/method ran");
435
436                                        var x = htmldojomethod.someMethod(2, 2);
437                                        doh.is(14, x, "overridden dojo/method");
438
439                                        htmldojomethod.diffMethod(2);
440                                        doh.t(htmldojomethod._ran, "ensures original was called first");
441                                        doh.is(2, htmldojomethod._fromvalue, "ensures connected was executed in scope");
442                                },
443
444                                function testOnWatch(){
445                                        // testing script-type dojo/watch and dojo/on
446                                        doh.is("object", typeof objOnWatch);
447                                        objOnWatch.set("strProp1","newValue1");
448                                        doh.is("newValue1", objOnWatch.arrProp.newValue, "ensures watch executed");
449
450                                        objOnWatch.onclick();
451                                        doh.t(objOnWatch.prototypeOnclick, "ensures original was called");
452                                        doh.t(objOnWatch.boolProp1, "ensure on executed in scope");
453                                },
454
455                                function testOn2(){
456                                        // testing script-type dojo/on, when script comes after another element
457                                        parser.parse("on");
458                                        doh.t("on_form" in window, "widget created");
459                                        on_form.emit("click");
460                                        doh.t(on_form.clicked, "on callback fired");
461                                },
462
463                                function testAspect(){
464                                        // testing script-type dojo/aspect
465                                        doh.is("object", typeof objAspect);
466                                        doh.f(objAspect.method1ran, "ensures method unfired");
467                                        doh.f(objAspect.method2ran, "ensures method unfired");
468                                        doh.is(objAspect.method3result, "", "ensures method unfired");
469                                        doh.f(objAspect.method4ran, "ensures method unfired");
470
471                                        objAspect.method1();
472                                        objAspect.method2();
473                                        objAspect.method3("something");
474                                        objAspect.method4();
475
476                                        doh.t(objAspect.method1ran, "method fired");
477                                        doh.t(objAspect.method1after, "after advice fired");
478                                        doh.t(objAspect.method2ran, "method fired");
479                                        doh.t(objAspect.method2before, "around before advice fired");
480                                        doh.t(objAspect.method2after, "around after advice fired");
481                                        doh.is(objAspect.method3result, "before", "before argument passed");
482                                        doh.t(objAspect.method4ran, "method fired");
483                                        doh.t(objAspect.method4after, "after advice fired");
484                                },
485
486                                function testMID(){
487                                        // testing specifying data-dojo-type as mid
488                                        doh.is("object", typeof objAMDWidget);
489                                        doh.is("Value1", objAMDWidget.params.value, "ensure object was properly parsed using MID");
490                                }
491                        ]);
492
493                        doh.register("BIDI", [
494                                // Test that dir=rtl or dir=ltr setting trickles down from root node
495                                function dirAttr(){
496                                        parser.parse("dirSection1");
497                                        parser.parse("dirSection2");
498                                        doh.is("rtl", setRtl.dir, "direct setting of dir=rtl works");
499                                        doh.is("rtl", inheritRtl.dir, "inherited rtl works");
500                                        doh.is("ltr", inheritLtr.dir, "inherited ltr works (closest ancestor wins)");
501                                        doh.is("rtl", inheritRtl2.dir, "inherited rtl works, from grandparent");
502                                        doh.is("ltr", setLtr.dir, "direct setting of dir=ltr overrides inherited RTL");
503                                },
504                                function langAttr(){
505                                        parser.parse("langSection");
506                                        doh.f(lang in noLang.params, "no lang");
507                                        doh.is("it_it", inheritedLang.lang, "inherited lang works");
508                                        doh.is("en_us", specifiedLang.lang,"direct setting of lang overrides inherited");
509                                },
510                                function textdirAttr(){
511                                        parser.parse("textDirSection");
512                                        doh.f("textDir" in noTextdir.params, "no textdir");
513                                        doh.is("rtl", inheritedTextdir.textDir, "inherited textdir works");
514                                        doh.is("ltr", specifiedTextdir.textDir,"direct setting of textdir overrides inherited");
515                                },
516                                {
517                                        // Test that calling parser.parse(nodeX) will inherit dir/lang/etc. settings
518                                        // even from <html>
519                                        name: "inheritance from HTML",
520                                        setUp: function(){
521                                                domAttr.set(win.doc.documentElement, {dir: "rtl", lang: "ja-jp", "data-dojo-textdir": "auto"});
522                                                parser.parse("bidiInheritanceFromHtml");
523                                        },
524                                        runTest: function(){
525                                                doh.is("rtl", inheritedFromHtml.params.dir, "dir");
526                                                doh.is("ja-jp", inheritedFromHtml.params.lang, "lang");
527                                                doh.is("auto", inheritedFromHtml.params.textDir, "textDir");
528                                        },
529                                        tearDown: function(){
530                                                array.forEach(["dir", "lang", "data-dojo-textdir"], function(attr){
531                                                        win.doc.documentElement.removeAttribute(attr);
532                                                });
533                                        }
534                                }
535                        ]);
536
537                        doh.register("IE attribute detection", [
538                                function input1(){
539                                        var widgets = parser.instantiate([dom.byId("ieInput1")]);
540                                        var params = widgets[0].params;
541
542                                        doh.is("checkbox", params.type, "type");
543                                        doh.t(params.disabled, "disabled");
544                                        doh.t(params.checked, "checked");
545                                        doh.t(params.readonly, "readonly");
546                                        doh.is("bar", params.foo, "foo");
547                                        doh.is("zaz", params.bar, "bar");
548                                        doh.is("escaped\"dq", params.bob, "bob");
549                                        doh.is("escaped\'sq", params.frank, "frank");
550                                        //doh.f("value" in params, "value not specified");      // fails in IE8, thinks value=="on"
551                                },
552                                function input2(){
553                                        var widgets = parser.instantiate([dom.byId("ieInput2")]);
554                                        var params = widgets[0].params;
555
556                                        doh.f("type" in params, "type");
557                                        doh.f("name" in params, "name");
558                                        doh.f("value" in params, "value");
559                                        doh.f("data-dojo-type" in params, "data-dojo-type");
560                                        doh.f("data-dojo-props" in params, "data-dojo-props");
561                                        doh.is("hi", params.foo, "foo");
562                                        doh.f("value" in params, "value not specified");
563                                },
564                                function input3(){
565                                        var widgets = parser.instantiate([dom.byId("ieInput3")]);
566                                        var params = widgets[0].params;
567
568                                        doh.is("password", params.type, "type");
569                                        doh.is("test", params.name, "name");
570                                        doh.is("123", params.value, "value");
571                                        doh.is("myClass", params["class"], "class");
572                                        doh.is("display:block", params["style"].replace(/[ ;]/g, "").toLowerCase(), "style");
573                                        doh.is("3", params.tabIndex, "tabIndex");
574                                },
575                                function textarea(){
576                                        var widgets = parser.instantiate([dom.byId("ieTextarea")]);
577                                        var params = widgets[0].params;
578
579                                        doh.is("attrVal", params.value, "value");
580                                },
581                                function button1(){
582                                        var widgets = parser.instantiate([dom.byId("ieButton1")]);
583                                        var params = widgets[0].params;
584                                        doh.t(params.checked, "checked");
585                                        doh.is("button1val", params.value, "value");
586                                },
587                                function button2(){
588                                        var widgets = parser.instantiate([dom.byId("ieButton2")]);
589                                        var params = widgets[0].params;
590                                        doh.f("checked" in params, "checked");
591                                        doh.f("value" in params, "value");
592                                },
593                                function button3(){
594                                        var widgets = parser.instantiate([dom.byId("ieButton3")]);
595                                        var params = widgets[0].params;
596                                        doh.t(params.checked, "checked");
597                                },
598                                function button4(){
599                                        var widgets = parser.instantiate([dom.byId("ieButton4")]);
600                                        var params = widgets[0].params;
601                                        doh.f("checked" in params);
602                                },
603                                function form1(){
604                                        var widgets = parser.instantiate([dom.byId("ieForm1")]);
605                                        var params = widgets[0].params;
606
607                                        doh.is("foo", params.encType, "encType is specified");
608                                },
609                                function form2(){
610                                        var widgets = parser.instantiate([dom.byId("ieForm2")]);
611                                        var params = widgets[0].params;
612
613                                        doh.f("encType" in params, "encType not specified")
614                                },
615                                function li(){
616                                        var widgets = parser.instantiate([dom.byId("li")]);
617                                        var params = widgets[0].params;
618                                        doh.is("home", params.value);
619
620                                }
621                        ]);
622
623                        doh.register("mixed attribute specification", function mixed(){
624                                parser.parse(dom.byId("mixedContainer"));
625                                doh.is("object", typeof mixedObj, "widget created");
626                                doh.is("mixedValue", mixedObj.value, "native attribute");
627                                doh.is(999, mixedObj.custom1, "data-dojo-props attribute");
628                                doh.is("custom title", mixedObj.title, "data-dojo-props overrides native");
629                        });
630
631                        doh.register("functions", function onclick(){
632                                // Create objects referenced from markup inside of "functions" div
633                                declare("tests.parser.Button", null, {
634                                        onClick: function(){
635                                                console.log("prototype click");
636                                        },
637                                        constructor: function(args, node){
638                                                lang.mixin(this, args);
639                                                this.domNode = node;
640                                                aspect.after(this.domNode, "onclick", lang.hitch(this, "onClick"));
641                                        }
642                                });
643                                buttonClicked = function(){
644                                        console.log("markup click");
645                                };      // markup says onClick="buttonClicked"
646
647                                // Parse markup inside "functions" div
648                                parser.parse("functions");
649
650                                // Should have created an instance called "button" where button.onClick == buttonClicked
651                                doh.is("object", typeof button, "widget created");
652                                doh.is("function", typeof button.onClick, "created as function");
653                                doh.t(buttonClicked == button.onClick, "points to specified function");
654                        });
655
656                        doh.register("parser.instantiate()", function instantiate1() {
657                                var nodes = [dom.byId("objId1"),dom.byId("objId2"),dom.byId("contId1"),dom.byId("objId3")];
658                                parser.instantiate(nodes);
659                                doh.is("object", typeof objI1, "widget 1 created");
660                                doh.is("object", typeof objI2, "widget 2 created");
661                                doh.t(contI1, "container created");
662                                doh.is("object", typeof objI3, "child widget 3 created");
663                                doh.f(window.objI4, "child widget 4 not created");
664                        });
665
666                        doh.register("parser.construct()", function construct1() {
667                                var nodes = [dom.byId("objC1"),dom.byId("objC2")];
668
669                                parser.construct(tests.parser.Class1, dom.byId("objC1"));
670                                doh.is("object", typeof objC1, "widget 1 created");
671                                doh.is(5, objC1.intProp, "objC1.intProp");
672
673                                parser.construct(tests.parser.Class1, dom.byId("objC2"));
674                                doh.is("object", typeof objC2, "widget 2 created");
675                                doh.is(5, objC2.intProp, "objC2.intProp");
676                        });
677
678                        doh.register("data-dojo-mixins support", function mixins() {
679                                parser.parse("mixins");
680                                doh.t(resultMixins1, "object using data-dojo-mixins created from an already parsed type");
681                                doh.t(resultMixins1.mixin1Done, "mixin1 correctly mixed in");
682                                doh.t(resultMixins1.mixin2Done, "mixin2 correctly mixed in");
683                                doh.t(resultMixins1.amdMixinDone, "amd mixin correctly mixed in");
684                                doh.t(resultMixins2, "object using data-dojo-mixins created from a non parsed type");
685                                doh.t(resultMixins2.classDone, "class correctly created");
686                                doh.t(resultMixins2.mixin1Done, "mixin1 correctly mixed in");
687                                doh.t(resultMixins2.mixin2Done, "mixin2 correctly mixed in");
688                                doh.t(resultMixins2.amdMixinDone, "amd mixin correctly mixed in");
689                                doh.t(resultNonDojoMixin.expectedClass, "correct class is returned for composeJS mixin");
690                                doh.is(resultNonDojoMixin.params.length, 2, "correct # of params were passed to compose JS");
691                                doh.is(resultNonDojoMixin.params[0], tests.parser.Mixin1, "correct param 1");
692                                doh.is(resultNonDojoMixin.params[1], tests.parser.Mixin2, "correct param 2");
693                        });
694
695                        // For any special issues with behavioral widgets (as opposed to Templated)
696                        doh.register("behavioral", [
697                                function doubleConnect(){
698                                        // Class used in "behavioral" <div>
699                                        Behavioral1 = declare(null, {
700                                                constructor: function(params, node){
701                                                        on(node, "click", lang.hitch(this, "onClick"));
702                                                        if(typeof params.onClick != "function"){
703                                                                throw new Error("onClick not passed to constructor");
704                                                        }
705                                                        lang.mixin(this, params);
706                                                },
707                                                onClick: function(){
708                                                        console.log("original onnClick handler")
709                                                },
710                                                foo: ""
711                                        });
712
713                                        parser.parse("behavioral");
714
715                                        // Setup global accessed by Behavioral1.onclick handler
716                                        behavioralClickCounter = 0;
717
718                                        // Trigger click event, and make sure that handler was only called once.
719                                        on.emit(dom.byId("bh1"), "click", {bubbles: true, cancelable: true});
720
721                                        doh.is(1, behavioralClickCounter, "one click event processed");
722
723                                        doh.is("bar", dom.byId("bh1").getAttribute("foo"), "foo attribute not removed from widget DOMNode");
724                                }
725                        ]);
726
727                        doh.register("script type=dojo/require support", function declarativeRequire(){
728                                var td = new doh.Deferred();
729
730                                parser.parse("declarativeRequire").then(td.getTestCallback(function(){
731                                        doh.is(typeof dr1, "object", "object using MID mapped to return var");
732                                        doh.is(dr1.params.foo, "bar", "parameters set on instantiation");
733                                        doh.is(typeof dr2, "object", "object using MID mapped to return var");
734                                        doh.is(dr2.params.foo, "bar", "parameters set on instantiation");
735                                        doh.is(typeof dr3, "object", "object using fully required");
736                                        doh.is(dr3.params.foo, "bar", "parameters set on instantiation");
737                                        doh.is(dr4.params.foo, 2, "module loaded and executed");
738                                        doh.is(dr5.method1(1), 3, "declarative script has access to parser scope");
739                                }));
740
741                                return td;
742                        });
743
744                        doh.register("context require support", function contextRequire(){
745                                var td = new doh.Deferred();
746
747                                parser.parse("contextRequire", {
748                                        contextRequire: require
749                                }).then(td.getTestCallback(function(){
750                                        doh.is(typeof cr1, "object", "object using relative MID mapped to return var");
751                                        doh.is(cr1.params.foo, "bar", "parameters set on instantiation");
752                                        doh.is(typeof cr2, "object", "object using relative MID mapped to return var");
753                                        doh.is(cr2.params.foo, "bar", "parameters set on instantiation");
754                                        doh.is(typeof cr3, "object", "object using relative MID mapped to return var");
755                                        doh.is(cr3.params.foo, "bar", "parameters set on instantiation");
756                                        doh.is(typeof cr4, "object", "object using relative MID mapped to return var");
757                                        doh.is(cr4.params.foo, "bar", "parameters set on instantiation");
758                                }));
759
760                                return td;
761                        });
762
763                        doh.register("promise error handling support", [
764                                function asyncError(){
765                                        var td = new doh.Deferred();
766
767                                        parser.parse("errorHandling").then(td.getTestErrback(function(){
768                                                throw new Error("shouldn't get here");
769                                        }), td.getTestCallback(function(e){
770                                                doh.is(typeof e, "object", "error object returned");
771                                        }));
772
773                                        return td;
774                                },
775                                function missingCtor(){
776                                        var td = new doh.Deferred();
777
778                                        parser.parse("missingCtor").then(td.getTestErrback(function(){
779                                                throw new Error("shouldn't get here");
780                                        }), td.getTestCallback(function(e){
781                                                doh.is(typeof e, "object", "error object returned");
782                                                doh.is(e.toString(), "Error: Unable to resolve constructor for: 'some.type'", "proper error value returned");
783                                        }));
784
785                                        return td;
786                                }
787                        ]);
788
789                        doh.run();
790                });
791                </script>
792        </head>
793        <body>
794                <h1>Parser Unit Test</h1>
795
796                <div id=main>
797                        <script>
798                                function foo(){ this.fooCalled=true; }
799                        </script>
800                        <div dojoType="tests.parser.Class1" data-dojo-id="obj"
801                                 strProp1="text" strProp2=""
802                                 intProp="5"
803                                 arrProp="foo, bar, baz"
804                                 arrProp2=""
805                                 boolProp1="true" boolProp2="false"
806                                 dateProp1="2006-01-01" dateProp2="" dateProp3="now"
807                                 funcProp2="foo" funcProp3="this.func3Called=true;"
808                        >
809                                <script type="dojo/method" data-dojo-event="preamble">
810                                        this.preambleTestProp = 3;
811                                </script>
812                                <script type="dojo/method">
813                                        // this should be run immediately
814                                        this.deepProp = deepTestProp;
815                                </script>
816                                <script type="dojo/connect" data-dojo-event="callInc">
817                                        this.callCount++;
818                                </script>
819                                <script type="dojo/method" data-dojo-event="callInc2">
820                                        this.callCount2++;
821                                </script>
822                        </div>
823                        <div dojoType="tests.parser.Class2" jsId="obj3">
824                        </div>
825                        <div dojoType="tests.parser.Class3" data-dojo-id="obj4">
826                        </div>
827                        <input dojoType="tests.parser.InputClass" data-dojo-id="checkedObj" checked type="checkbox">
828                        <button dojoType="tests.parser.InputClass" data-dojo-id="disabledObj" disabled>hi</button>
829
830                        <div id="parsertest"></div>
831                        <div id="parsertest2"></div>
832
833                        <!-- section for testing parser recursion -->
834                        <div>
835                                <div dojoType="tests.parser.NormalContainer" data-dojo-id="container1">
836                                        <!-- this script tag should get passed as param to NormalContainer constructor -->
837                                        <script type="dojo/method" data-dojo-event="incr" data-dojo-args="x">
838                                                return x+1;
839                                        </script>
840
841                                        <!-- and these contained widgets should get instantiated -->
842                                        <div dojoType="tests.parser.Class1" data-dojo-id="contained1"></div>
843                                        <div>
844                                                <div dojoType="tests.parser.Class1" data-dojo-id="contained2"></div>
845                                        </div>
846                                </div>
847                        </div>
848
849                        <div>
850                                <div dojoType="tests.parser.ShieldedContainer" data-dojo-id="container2">
851                                        <!-- this script tag should get passed as param to ShieldedContainer constructor -->
852                                        <script type="dojo/method" data-dojo-event="incr" data-dojo-args="x">
853                                                return x+1;
854                                        </script>
855
856                                        <!-- but these contained widgets should *not* get instantiated -->
857                                        <div dojoType="tests.parser.Class1" data-dojo-id="contained3"></div>
858                                        <div>
859                                                <div dojoType="tests.parser.Class1" data-dojo-id="contained4"></div>
860                                        </div>
861                                </div>
862                        </div>
863
864                        <!-- tests for new data-dojo-type / data-dojo-props syntax -->
865                        <div>
866                                <div data-dojo-id="html5simple" data-dojo-type="tests.parser.HTML5Props" data-dojo-props="simple:true"></div>
867                                <div data-dojo-id="html5simple2" data-dojo-type="tests.parser.HTML5Props"
868                                         data-dojo-props="simple:false, a:1, b:'two', c:[1,2,3], d:function(){ return this; }, e:{ f:'g' }"
869                                ></div>
870                                <!-- note needing to use a named inherited lookup because we're just mixing in -->
871                                <div data-dojo-id="html5simple3" data-dojo-type="tests.parser.HTML5Props"
872                                         data-dojo-props="afn: function(){ return this.inherited('afn', arguments); }"
873                                ></div>
874
875                                <!-- not used for tests, but thinking out loud: what about a named-resource prop, via getObject -->
876                                <div data-dojo-id="html5fromobjectns" data-dojo-type="tests.parser.HTML5Props"
877                                         data-dojo-obj="tests.parser.HTML5Props._aDefaultObj"
878                                ></div>
879                                <div data-dojo-id="html5fromobjectns2" data-dojo-type="tests.parser.HTML5Props"
880                                         data-dojo-obj="tests.parser.HTML5Props._aDefaultObj" data-dojo-props="simple:false"
881                                ></div>
882
883                        </div>
884
885                        <div>
886                                <div data-dojo-id="htmldojomethod" data-dojo-type="tests.parser.HTML5withMethod">
887                                        <p>Some random markup</p>
888                                        <script type="dojo/method" data-dojo-event="someMethod" data-dojo-args="a, b">
889                                                return this.baseValue + a + b;
890                                        </script>
891                                        <script type="dojo/connect" data-dojo-event="diffMethod" data-dojo-args="a">
892                                                console.log("diffMethod connect, this is ", this);
893                                                this._fromvalue = a;
894                                        </script>
895                                        <script type="dojo/method">
896                                                this._methodRan = true;
897                                        </script>
898                                        <div data-dojo-id="objAspect" data-dojo-type="tests.parser.MethodClass">
899                                                <script type="dojo/aspect" data-dojo-method="method1" data-dojo-advice="after">
900                                                        if(this.method1ran){
901                                                                this.method1after = true;
902                                                        }
903                                                </script>
904                                                <script type="dojo/aspect" data-dojo-method="method2" data-dojo-advice="around" data-dojo-args="origFn">
905                                                        return function(){
906                                                                if(!this.method2ran){
907                                                                        this.method2before = true;
908                                                                }
909                                                                origFn.call(this);
910                                                                if(this.method2ran){
911                                                                        this.method2after = true;
912                                                                }
913                                                        };
914                                                </script>
915                                                <script type="dojo/aspect" data-dojo-method="method3" data-dojo-advice="before" data-dojo-args="result">
916                                                        if(result == "something"){
917                                                                return ["before"];
918                                                        }
919                                                </script>
920                                                <script type="dojo/aspect" data-dojo-method="method4">
921                                                        if(this.method4ran){
922                                                                this.method4after = true;
923                                                        }
924                                                </script>
925                                        </div>
926                                </div>
927                        </div>
928
929                        <!-- section for testing dojo/on and dojo/watch scripts -->
930                        <div>
931                                <div data-dojo-id="objOnWatch" data-dojo-type="tests.parser.StatefulClass">
932                                        <script type="dojo/watch" data-dojo-prop="strProp1" data-dojo-args="prop,oldValue,newValue">
933                                                this.set("arrProp",{prop: prop, oldValue: oldValue, newValue: newValue});
934                                        </script>
935                                        <script type="dojo/on" data-dojo-event="click" data-dojo-args="e">
936                                                console.log("diffMethod on, this is ",this);
937                                                this.set("boolProp1",true);
938                                        </script>
939                                </div>
940                        </div>
941
942                        <!-- section for testing mid syntax for data-dojo-type -->
943                        <div>
944                                <div data-dojo-id="objAMDWidget" data-dojo-type="dojo/tests/resources/AMDWidget" data-dojo-props="value: 'Value1'"></div>
945                        </div>
946                </div> <!-- end of <div id=main> -->
947
948                <!-- more dojo/on tests -->
949                <div id="on">
950                        <form action="/SomeUrl" data-dojo-type="tests.parser.StatefulClass" data-dojo-id="on_form">
951                                <input data-dojo-type="tests.parser.InputClass" name="ACheckBox" />
952                                <script type="dojo/on" data-dojo-event="click">
953                                        this.clicked = true;
954                                </script>
955                        </form>
956                </div>
957
958                <!-- section for testing parse on a subnode -->
959                <div>
960                        <div data-dojo-type="tests.parser.Class1" data-dojo-id="obj2" id="toParse">
961                        </div>
962                </div>
963
964                <!-- section for testing that dir, lang attribute trickles down from ancestor -->
965                <div id="dirSection1">
966                        <div dojoType="tests.parser.BidiClass" data-dojo-id="setRtl" dir="rtl" name="RTL setting"></div>
967                        <div dojoType="tests.parser.BidiClass" data-dojo-id="noDir" name="dir not inherited or set"></div>
968                </div>
969                <div id="dirSection2" dir="rtl">
970                        <div dojoType="tests.parser.BidiClass" data-dojo-id="inheritRtl" name="inherited RTL from parent"></div>
971                        <div dir="ltr">
972                                <div dojoType="tests.parser.BidiClass" data-dojo-id="inheritLtr" name="inherited LTR from parent"></div>
973                        </div>
974                        <div>
975                                <div dojoType="tests.parser.BidiClass" data-dojo-id="inheritRtl2" name="inherited RTL from grandparent"></div>
976                        </div>
977                        <div dojoType="tests.parser.BidiClass" data-dojo-id="setLtr" dir="ltr" name="LTR setting overrides inherited RTL"></div>
978                </div>
979                <div id="langSection">
980                        <div dojoType="tests.parser.BidiClass" data-dojo-id="noLang" name="shouldn't get lang"></div>
981                        <div lang="it_it">
982                                <div dojoType="tests.parser.BidiClass" data-dojo-id="inheritedLang" name="inherited lang from parent"></div>
983                                <div dojoType="tests.parser.BidiClass" data-dojo-id="specifiedLang" lang="en_us" name="specified lang overrides parent"></div>
984                        </div>
985                </div>
986                <div id="textDirSection">
987                        <div dojoType="tests.parser.BidiClass" data-dojo-id="noTextdir" name="shouldn't get textdir"></div>
988                        <div data-dojo-textdir="rtl">
989                                <div dojoType="tests.parser.BidiClass" data-dojo-id="inheritedTextdir" name="inherited textdir from parent"></div>
990                                <div dojoType="tests.parser.BidiClass" data-dojo-id="specifiedTextdir" data-dojo-textdir="ltr" name="specified textdir overrides parent"></div>
991                        </div>
992                </div>
993                <div id="bidiInheritanceFromHtml">
994                        <div dojoType="tests.parser.BidiClass" data-dojo-id="inheritedFromHtml" name="should get dir/lang/textDir from HTML tag"></div>
995                </div>
996
997                <!-- tests that we can parse parameters correctly on IE6/7, not getting tripped up by escaped quotes etc. -->
998                <div id=ie>
999                        <input id="ieInput1" data-dojo-type="tests.parser.InputClass"
1000                                   type=checkbox disabled foo = 'bar' readonly bar=zaz bob='escaped"dq' frank="escaped'sq" checked />
1001                        <input id="ieInput2" data-dojo-type="tests.parser.InputClass"
1002                                   fakeout1="type=submit" fakeout2="name='test'" fakeout3="value='123'" data-dojo-props="foo: 'hi'"/>
1003                        <input id="ieInput3" data-dojo-type="tests.parser.InputClass"
1004                                   type=password name="test" value="123" class="myClass" style="display:block" tabindex="3"/>
1005                        <textarea id="ieTextarea" data-dojo-type="tests.parser.InputClass" value="attrVal">contentVal</textarea>
1006                        <button id="ieButton1" data-dojo-type="tests.parser.InputClass" checked value="button1val">
1007                                checked ToggleButton as button
1008                        </button>
1009                        <button id="ieButton2" data-dojo-type="tests.parser.InputClass">
1010                                unchecked ToggleButton as button
1011                        </button>
1012                        <div id="ieButton3" data-dojo-type="tests.parser.InputClass" checked>
1013                                checked ToggleButton as div
1014                        </div>
1015                        <div id="ieButton4" data-dojo-type="tests.parser.InputClass">
1016                                unchecked ToggleButton as div
1017                        </div>
1018                        <form id="ieForm1" data-dojo-type="tests.parser.FormClass" encType="foo"></form>
1019                        <form id="ieForm2" data-dojo-type="tests.parser.FormClass"></form>
1020                        <ul dojoType="tests.parser.Widget" class="nav">
1021                                <li id="li" dojoType="tests.parser.Widget" value="home">Home</li>
1022                                <li dojoType="tests.parser.Widget" value="contact">Contact</li>
1023                                <li dojoType="tests.parser.Widget" value="group">Group</li>
1024                                <li dojoType="tests.parser.Widget" value="campaign">Campaign</li>
1025                        </ul>
1026                </div>
1027
1028                <!-- tests for when parameters are specified both natively and in data-dojo-props. -->
1029                <div id="mixedContainer">
1030                        <input data-dojo-type="tests.parser.InputClass" data-dojo-id="mixedObj"
1031                                   value="mixedValue" title="native title" data-dojo-props="custom1: 999, title: 'custom title'">
1032                </div>
1033
1034                <!-- tests for function names native to HTML, specifically an issue on IE<8 -->
1035                <div id="functions">
1036                        <button dojoType="tests.parser.Button" onClick="buttonClicked" data-dojo-id="button">Click me</button>
1037                </div>
1038
1039                <!-- section for testing parser.instantiate() -->
1040                <div id="instantiate1">
1041                        <div dojoType="tests.parser.Class1" data-dojo-id="objI1" id="objId1"
1042                                 strProp1="text" strProp2=""
1043                                 intProp="5"
1044                                 arrProp="foo, bar, baz"
1045                                 arrProp2=""
1046                                 boolProp1="true" boolProp2="false"
1047                                 dateProp1="2006-01-01" dateProp2="" dateProp3="now"
1048                                 funcProp2="foo" funcProp3="this.func3Called=true;"
1049                        >
1050                        </div>
1051                        <div data-dojo-type="tests.parser.Class1" data-dojo-id="objI2" id="objId2"
1052                                 data-dojo-props="
1053                                        strProp1:'text',
1054                                        strProp2:'',
1055                                        intProp:5,
1056                                        arrProp:['foo', 'bar', 'baz'],
1057                                        arrProp2:[],
1058                                        boolProp1:true,
1059                                        boolProp2:'false',
1060                                        dateProp1:'2006-01-01',
1061                                        dateProp2:'',
1062                                        dateProp3:'now',
1063                                        funcProp2:foo,
1064                                        funcProp3:'this.func3Called=true;'"
1065                        >
1066                        </div>
1067                        <div dojoType="tests.parser.NormalContainer" data-dojo-id="contI1" id ="contId1">
1068                                <div dojoType="tests.parser.Class1" data-dojo-id="objI3" id="objId3"></div>
1069                                <div dojoType="tests.parser.Class1" data-dojo-id="objI4" id="objId4"></div>
1070                        </div>
1071                </div>
1072
1073                <!-- section for testing parser.construct() -->
1074                <div id="construct1">
1075                        <div data-dojo-id="objC1" id="objC1"
1076                                 strProp1="text" strProp2=""
1077                                 intProp="5"
1078                                 arrProp="foo, bar, baz"
1079                                 arrProp2=""
1080                                 boolProp1="true" boolProp2="false"
1081                                 dateProp1="2006-01-01" dateProp2="" dateProp3="now"
1082                                 funcProp2="foo" funcProp3="this.func3Called=true;"
1083                        >
1084                        </div>
1085                        <div data-dojo-id="objC2" id="objC2"
1086                                 data-dojo-props="
1087                                        strProp1:'text',
1088                                        strProp2:'',
1089                                        intProp:5,
1090                                        arrProp:['foo', 'bar', 'baz'],
1091                                        arrProp2:[],
1092                                        boolProp1:true,
1093                                        boolProp2:'false',
1094                                        dateProp1:'2006-01-01',
1095                                        dateProp2:'',
1096                                        dateProp3:'now',
1097                                        funcProp2:foo,
1098                                        funcProp3:'this.func3Called=true;'"
1099                        >
1100                        </div>
1101                </div>
1102
1103                <!-- tests for data-dojo-mixins -->
1104                <div id="mixins">
1105                        <div data-dojo-type="tests.parser.Class1" data-dojo-mixins="tests.parser.Mixin1,tests.parser.Mixin2,dojo/tests/resources/AMDMixin"
1106                                 data-dojo-id="resultMixins1"></div>
1107                        <div data-dojo-type="tests.parser.ClassForMixins" data-dojo-mixins="tests.parser.Mixin1, tests.parser.Mixin2, dojo/tests/resources/AMDMixin"
1108                                 data-dojo-id="resultMixins2"></div>
1109                        <div data-dojo-type="MyNonDojoClass" data-dojo-mixins="tests.parser.Mixin1, tests.parser.Mixin2"
1110                                 data-dojo-id="resultNonDojoMixin"></div>
1111                </div>
1112
1113                <!-- tests for behavioral widgets -->
1114                <div id="behavioral">
1115                        <div data-dojo-type="Behavioral1" onClick="behavioralClickCounter++;" id="bh1" foo="bar">click me</div>
1116                </div>
1117               
1118                <!-- tests for declarative require -->
1119                <div id="declarativeRequire">
1120                        <script type="dojo/require">
1121                                AMDWidget: "dojo/tests/resources/AMDWidget",
1122                                AMDWidget2: "dojo/tests/resources/AMDWidget2"
1123                        </script>
1124                        <div data-dojo-id="dr1" data-dojo-type="AMDWidget" data-dojo-props="foo: 'bar'"></div>
1125                        <div data-dojo-id="dr2" data-dojo-type="AMDWidget2" data-dojo-props="foo: 'bar'"></div>
1126                        <script type="dojo/require">
1127                                AMDWidget3: "dojo/tests/resources/AMDWidget3"
1128                        </script>
1129                        <div data-dojo-id="dr3" data-dojo-type="dojo/tests/resources/AMDWidget3" data-dojo-props="foo: 'bar'"></div>
1130                        <script type="dojo/require">
1131                                amdmodule: "dojo/tests/resources/amdmodule"
1132                        </script>
1133                        <div data-dojo-id="dr4" data-dojo-type="AMDWidget" data-dojo-props="foo: amdmodule(1)"></div>
1134                        <div data-dojo-id="dr5" data-dojo-type="AMDWidget2">
1135                        <script type="dojo/aspect" data-dojo-advice="before" data-dojo-method="method1" data-dojo-args="value">
1136                                return [amdmodule(value)];
1137                        </script>
1138                        </div>
1139                </div>
1140
1141                <!-- tests for context require -->
1142                <!-- The relative MIDs, because they are "up", the loader thinks they are not necessarily modules, in the
1143                                real world, they would most likely be in sibling paths and the need for the .js would not be
1144                                necessary -->
1145                <div id="contextRequire">
1146                        <script type="dojo/require">
1147                                "context.AMDWidget": "../resources/AMDWidget.js",
1148                                "context.AMDWidget2": "../resources/AMDWidget2.js"
1149                        </script>
1150                        <div data-dojo-id="cr1" data-dojo-type="context.AMDWidget" data-dojo-props="foo: 'bar'"></div>
1151                        <div data-dojo-id="cr2" data-dojo-type="context.AMDWidget2" data-dojo-props="foo: 'bar'"></div>
1152                        <div data-dojo-id="cr3" data-dojo-type="../resources/AMDWidget.js" data-dojo-props="foo: 'bar'"></div>
1153                        <div data-dojo-id="cr4" data-dojo-type="../resources/AMDWidget3.js" data-dojo-props="foo: 'bar'"></div>
1154                </div>
1155               
1156                <!-- tests for promise error handling -->
1157                <div id="errorHandling">
1158                        <div data-dojo-type="dojo/tests/resources/AMDWidget" data-dojo-props="foo: bar"></div>
1159                </div>
1160                <div id="missingCtor">
1161                        <div data-dojo-type="some.type"></div>
1162                </div>
1163        </body>
1164</html>
Note: See TracBrowser for help on using the repository browser.