You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
617 lines
22 KiB
617 lines
22 KiB
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/> |
|
<title>WidgetsInTemplateMixin.js</title> |
|
|
|
<style type="text/css"> |
|
/* Make our tests stand out as easily identifiable content */ |
|
.testcontainer { |
|
border: 10px yellow; |
|
border-style: dashed; |
|
padding: 1em; |
|
margin: 1em; |
|
} |
|
.testcontainer > p { |
|
padding: 0 1em; |
|
font-weight: bold; |
|
} |
|
</style> |
|
|
|
<script type="text/javascript" src="boilerplate.js"></script> |
|
<script type="text/javascript"> |
|
require([ |
|
"doh", "dojo/_base/array", "dojo/_base/declare", "dojo/_base/window", "dojo/dom", "dojo/dom-geometry", |
|
"dojo/html", "dojo/on", "dojo/query", "dojo/parser", |
|
"dijit/registry", "dijit/_WidgetBase", "dijit/_Widget", |
|
"dijit/_AttachMixin", "dijit/_TemplatedMixin", "dijit/_WidgetsInTemplateMixin", |
|
"dijit/form/Button", "dijit/form/CheckBox", "dijit/form/TextBox", |
|
"dijit/ProgressBar", "dijit/_Container", "dijit/_Contained", |
|
"dijit/layout/ContentPane", "dijit/layout/_LayoutWidget", "dijit/layout/LayoutContainer", |
|
"dijit/tests/resources/TestContextRequireWidget", |
|
"dojo/domReady!" |
|
], function(doh, array, declare, win, dom, domGeom, html, on, query, parser, |
|
registry, _WidgetBase, _Widget, _AttachMixin, _TemplatedMixin, _WidgetsInTemplateMixin, |
|
Button, CheckBox, TextBox, ProgressBar, _Container, _Contained, _LayoutWidget, LayoutContainer){ |
|
|
|
declare('Test1Widget', [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], { |
|
templateString: dom.byId('Test1Template').value, |
|
onClick: function(e){ |
|
if(e.target){ |
|
alert('onClick widgetId='+e.target.id); |
|
}else{ |
|
if(e._counter == undefined){ |
|
e._counter = 1; |
|
}else{ |
|
e._counter++; |
|
} |
|
} |
|
} |
|
}); |
|
|
|
declare('Test3Widget', [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], { |
|
templateString: dom.byId('Test3Template').value |
|
}); |
|
|
|
declare('TestLayoutWidget', _LayoutWidget, { |
|
startup: function(){ |
|
if(this._started){ |
|
this._doubleStarted = true; |
|
} |
|
this.inherited(arguments); |
|
}, |
|
destroy: function(){ |
|
if(this._destroyed){ |
|
this._doubleDestroyed = true; |
|
} |
|
this.inherited(arguments); |
|
this._destroyed = true; |
|
} |
|
}); |
|
|
|
declare('TestCtnrWidget', [_WidgetBase, _Container], { |
|
startup: function(){ |
|
if(this._started){ |
|
this._doubleStarted = true; |
|
} |
|
this.inherited(arguments); |
|
}, |
|
destroy: function(){ |
|
if(this._destroyed){ |
|
this._doubleDestroyed = true; |
|
} |
|
this.inherited(arguments); |
|
this._destroyed = true; |
|
} |
|
}); |
|
|
|
declare('TestCtndWidget', [_WidgetBase, _Contained], { |
|
startup: function(){ |
|
if(this._started){ |
|
this._doubleStarted = true; |
|
} |
|
this.inherited(arguments); |
|
}, |
|
destroy: function(){ |
|
if(this._destroyed){ |
|
this._doubleDestroyed = true; |
|
} |
|
this.inherited(arguments); |
|
this._destroyed = true; |
|
} |
|
}); |
|
|
|
declare('TestNonCtnrWidget', [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], { |
|
templateString: "<div data-dojo-attach-point=containerNode></div>", |
|
startup: function(){ |
|
if(this._started){ |
|
this._doubleStarted = true; |
|
} |
|
this.inherited(arguments); |
|
}, |
|
destroy: function(){ |
|
if(this._destroyed){ |
|
this._doubleDestroyed = true; |
|
} |
|
this.inherited(arguments); |
|
this._destroyed = true; |
|
} |
|
}); |
|
|
|
declare('TestStubWidget', _WidgetBase, { |
|
startup: function(){ |
|
if(this._started){ |
|
this._doubleStarted = true; |
|
} |
|
this.inherited(arguments); |
|
}, |
|
destroy: function(){ |
|
if(this._destroyed){ |
|
this._doubleDestroyed = true; |
|
} |
|
this.inherited(arguments); |
|
this._destroyed = true; |
|
} |
|
}); |
|
|
|
declare('Test5Widget', |
|
[_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], |
|
{ |
|
templateString: dom.byId('Test5Template').value, |
|
startup: function(){ |
|
if(this._started){ |
|
this._doubleStarted = true; |
|
} |
|
this.inherited(arguments); |
|
}, |
|
destroy: function(){ |
|
if(this._destroyed){ |
|
this._doubleDestroyed = true; |
|
} |
|
this.inherited(arguments); |
|
this._destroyed = true; |
|
} |
|
}); |
|
|
|
declare('Test6Widget', [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], { |
|
templateString: dom.byId('Test6Template').value, |
|
clickCount: 0, |
|
handleClick: function(){ |
|
this.clickCount++; |
|
} |
|
}); |
|
|
|
declare("Missing", [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], { |
|
templateString: '<div>' + |
|
'<div data-dojo-type="dijit/layout/ContentPane">' + |
|
'<div data-dojo-type="dijit/form/Button" data-dojo-props="id: \'missingButtonId\'" ' + |
|
'data-dojo-attach-point="missingButton">Missing...</div>' + |
|
'</div>' + |
|
'</div>' |
|
}); |
|
|
|
function getTest5WidgetsInTemplate(testW){ |
|
// summary: |
|
// Returns all the widgets in the template for a Test5Widget |
|
return [ |
|
testW, |
|
testW.layout, |
|
testW.layChild1, |
|
testW.layChild2, |
|
testW.container, |
|
testW.contained1, |
|
testW.contained2, |
|
testW.nonContainer, |
|
testW.nonContained1, |
|
testW.nonContained2, |
|
testW.threeLevel, |
|
testW.secondLevel, |
|
testW.bottomLevel, |
|
testW.anotherThree, |
|
testW.anotherSecond, |
|
testW.anotherBottom, |
|
testW.stub1 |
|
]; |
|
} |
|
|
|
function validateTest5Widget(/*Test5Widget*/ testW, /*Boolean*/ started){ |
|
// Check that testW widget, and all the widgets in it's template, got started, but not double-started |
|
array.forEach(getTest5WidgetsInTemplate(testW), function(w){ |
|
if(started){ |
|
doh.t(w._started, w + " should be started"); |
|
}else{ |
|
doh.f(w._started, w + " should not be started"); |
|
} |
|
doh.is(undefined, w._doubleStarted, "w._doubleStarted: " + w); |
|
}); |
|
} |
|
|
|
function validateTest5WidgetDestroy(t, testW){ |
|
var savedWidgets = getTest5WidgetsInTemplate(testW); |
|
testW.destroy(); |
|
array.forEach(savedWidgets, function(w, idx){ |
|
doh.t(w._destroyed, "w._destroyed: " + w); |
|
doh.is(undefined, w._doubleDestroyed, "w._doubleDestroyed: " + w); |
|
}); |
|
} |
|
|
|
doh.register("_AttachMixin-widgetInTemplate", [ |
|
function createAttachWidgetsCombo() { |
|
/*** TEST _AttachMixin combined with _WidgetsInTemplateMixin ***/ |
|
var AttachWidgetsCombo = declare([ _WidgetBase, _AttachMixin, _WidgetsInTemplateMixin ], { |
|
|
|
postCreate: function() { |
|
html.set(this.heading, "Amazing things will happen if you click this button!!!"); |
|
}, |
|
_buttonClicked: function(e) { |
|
html.set(this.heading, "Well that was boring. " + |
|
"My attach point button thinks it is a " + (this.mybutton.isInstanceOf(Button) ? 'dijit/form/Button':'Gruffalo')); |
|
} |
|
}); |
|
|
|
var myawc = new AttachWidgetsCombo({}, dom.byId('attachMeThree')); |
|
|
|
doh.t(myawc.heading, "heading"); |
|
doh.t(myawc.mybutton, "mybutton"); |
|
doh.is("Amazing things will happen if you click this button!!!", myawc.heading.innerHTML, "Initial value"); |
|
|
|
// Simulate clicking the button. Don't use click() because it's not supported on a <span> |
|
// in Android < 4.4. |
|
on.emit(myawc.mybutton.focusNode, "click", { |
|
bubbles: true, |
|
cancelable: true |
|
}); |
|
|
|
doh.is("Well that was boring. My attach point button thinks it is a dijit/form/Button", myawc.heading.innerHTML, "Post-op value"); |
|
}, |
|
|
|
function containerNode(){ |
|
// Test that widgets inside of containerNode aren't parsed by _WidgetsInTemplateMixin |
|
|
|
declare("OuterWidget", [ _WidgetBase, _AttachMixin, _WidgetsInTemplateMixin ], { |
|
// Prevent the main parser call from hitting my supporting widgets. |
|
// But this also stops the parser from hitting anything inside my containerNode, so I need |
|
// to do a recursive parse() like ContentPane does (or just extend ContentPane) |
|
stopParser: true, |
|
|
|
postCreate: function(){ |
|
doh.is(0, this.getChildren().length, "contained widget not created yet"); |
|
parser.parse(this.containerNode); |
|
} |
|
}); |
|
declare("SupportingWidget", _WidgetBase); |
|
declare("ContainedWidget", _WidgetBase); |
|
parser.parse(dom.byId("containerNode")); |
|
|
|
doh.t("outerWidget" in window, "outer widget created"); |
|
doh.t(outerWidget.supportingWidget, "supporting widget instantiated"); |
|
doh.f(outerWidget.containedWidget, "contained widget not instantiated by _WidgetsInTemplateMixin parse call"); |
|
|
|
doh.is(1, outerWidget.getChildren().length, "contained widget created too"); |
|
} |
|
]); |
|
|
|
doh.register("_Templated-widgetsInTemplate", [ |
|
function parse(){ |
|
parser.parse("templateTests"); |
|
}, |
|
{ |
|
name: "data-dojo-attach-point", |
|
runTest: function(t){ |
|
var testW = registry.byId("test1Widget"); |
|
doh.t(testW, "test1Widget was instantiated"); |
|
doh.t(testW.normalNode, "normalNode"); |
|
doh.f(isNaN(testW.normalNode.nodeType), "normalNode.nodeType"); |
|
doh.t(testW.buttonWidget instanceof Button, "buttonWidget is Button"); |
|
doh.t(testW.checkboxWidget instanceof CheckBox, "checkboxWidget is CheckBox"); |
|
doh.t(testW.progressBarWidget instanceof ProgressBar, "progressBarWidget is ProgressBar"); |
|
} |
|
}, |
|
{ |
|
name: "data-dojo-attach-event", |
|
runTest: function(t){ |
|
var testW = registry.byId("test1Widget"); |
|
testW.buttonWidget._counter=0; |
|
testW.buttonWidget.onClick(testW.buttonWidget); |
|
testW.checkboxWidget._counter=0; |
|
testW.checkboxWidget.onClick(testW.checkboxWidget); |
|
testW.progressBarWidget._counter=0; |
|
testW.progressBarWidget.onChange(testW.progressBarWidget); |
|
doh.is(1,testW.buttonWidget._counter, "buttonWidget._counter"); |
|
doh.is(1,testW.checkboxWidget._counter, "checkboxWidget._counter"); |
|
doh.is(1,testW.progressBarWidget._counter, "progressBarWidget._counter"); |
|
} |
|
}, |
|
{ |
|
name: "data-dojo-attach-event strange name", |
|
runTest: function(t){ |
|
// This is for testing data-dojo-attach-event to attach to a method in the widget, |
|
// rather than using _WidgetBase.on(...). Remove for 2.0. |
|
var SubWidget = declare("SubWidget", _WidgetBase, { |
|
f: function(){ |
|
// just for attaching to |
|
} |
|
}); |
|
var MainWidget = declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], { |
|
templateString: |
|
'<div>' + |
|
'<div data-dojo-type="SubWidget" data-dojo-attach-point="sw" ' + |
|
' data-dojo-attach-event="f: g">' + |
|
'</div>', |
|
g: function(){ |
|
this.gWasCalled = true; |
|
} |
|
}); |
|
var mw = new MainWidget(); |
|
doh.t(mw.sw, "attach-point exists"); |
|
mw.sw.f(); |
|
doh.t(mw.gWasCalled, "attach-event worked"); |
|
} |
|
}, |
|
{ |
|
// Test that getDescendants () |
|
// finds direct descendants but skips widgetsInTemplates |
|
// and also nested widgets (if direct==true) |
|
name: "getChildren", |
|
runTest: function(t){ |
|
var testW = registry.byId("test3Widget"); |
|
|
|
/*** performance tests |
|
var start = new Date(); |
|
for(var i=0; i<1000; i++) |
|
testW.getChildren(); |
|
console.log("*** time for getChildren(): " + (new Date()-start)); |
|
var start = new Date(); |
|
for(var i=0; i<1000; i++) |
|
testW.getDescendants(); |
|
console.log("*** time for getDescendants(false): " + (new Date()-start)); |
|
***/ |
|
var chil = testW.getChildren(); |
|
doh.is(5, chil.length, "number of direct descendants"); |
|
doh.is(chil[0].id, "3.1"); |
|
doh.is(chil[1].id, "3.2"); |
|
doh.is(chil[2].id, "3.3"); |
|
doh.is(chil[3].id, "3.4"); |
|
doh.is(chil[4].id, "3.5"); |
|
|
|
// remove this test for 2.0 |
|
var desc = testW.getDescendants(); |
|
doh.is(7, desc.length, "number of descendants (including nested ones)"); |
|
doh.is(desc[0].id, "3.1"); |
|
doh.is(desc[1].id, "3.2"); |
|
doh.is(desc[2].id, "3.3"); |
|
doh.is(desc[3].id, "3.nested"); |
|
doh.is(desc[4].id, "3.nested2"); |
|
doh.is(desc[5].id, "3.4"); |
|
doh.is(desc[6].id, "3.5"); |
|
} |
|
}, |
|
{ |
|
// Check that declarative widget with other widgets in template is correctly started |
|
name: "declarative widget with many child widgets", |
|
runTest: function(t){ |
|
validateTest5Widget(registry.byId("test5Widget"), true); |
|
} |
|
}, |
|
{ |
|
// Check that programmatic widget with other widgets in template is correctly started |
|
name: "programmatic widget with many child widgets", |
|
runTest: function(t){ |
|
// Create widget. Widgets in template should not be started yet. |
|
test5WidgetProgrammatic = new Test5Widget(); |
|
validateTest5Widget(test5WidgetProgrammatic, false); |
|
|
|
// Place widget in DOM and startup. Widgets in template should now be started. |
|
test5WidgetProgrammatic.placeAt("test5Widget", "after"); |
|
test5WidgetProgrammatic.startup(); |
|
validateTest5Widget(test5WidgetProgrammatic, true); |
|
} |
|
}, |
|
{ |
|
// Check that destroying our declarative widget works correctly |
|
name: "declarative widget destruction", |
|
runTest: function(t){ |
|
validateTest5WidgetDestroy(t, registry.byId("test5Widget")); |
|
} |
|
}, |
|
{ |
|
// Check that destroying our programmatic widget works correctly |
|
name: "programmatic widget destruction", |
|
runTest: function(t){ |
|
validateTest5WidgetDestroy(t, test5WidgetProgrammatic); |
|
} |
|
}, |
|
{ |
|
// Test that data-dojo-attach-point inside of a ContentPane (inside of a template) works |
|
name: "ContentPane", |
|
runTest: function(){ |
|
var testW = registry.byId("missing"); |
|
doh.t(testW, "widget was created"); |
|
doh.t(testW.missingButton, "data-dojo-attach-point created"); |
|
doh.is("dijit.form.Button", testW.missingButton.declaredClass, "and it's to a widget"); |
|
doh.t(registry.byId("missingButtonId"), "nested widget also registered by id"); |
|
} |
|
}, |
|
{ |
|
// Test that data-dojo-attach-event bindings work with widgets in template, when |
|
// binding to dijit/_Widget methods |
|
name: "_Widget Deferred Connect methods", |
|
runTest: function(){ |
|
var test6Widget = registry.byId("test6Widget"); |
|
doh.t(test6Widget.clickCount === 0, "click count was initially zero"); |
|
// Issue a 'click' event directly on the interior input of the TextBox |
|
test6Widget.textbox.textbox.click(); |
|
doh.t(test6Widget.clickCount === 1, "click count incremented properly"); |
|
} |
|
}, |
|
|
|
function widgetsInTemplateLifecycle(t){ |
|
|
|
var result = [], expected = [1, 1, 0, 2, 2, 3]; |
|
|
|
// widgetsInTemplateLifecycle |
|
declare("SubThing", _WidgetBase, { |
|
postCreate: function(){ |
|
this.inherited(arguments); |
|
result.push(1); |
|
}, |
|
startup: function(){ |
|
this.inherited(arguments); |
|
result.push(2); |
|
} |
|
}); |
|
|
|
declare("ParentThing", [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], { |
|
templateString: "<div>" + |
|
"<span data-dojo-type='SubThing'>a</span>" + |
|
"<div data-dojo-type='dijit/layout/LayoutContainer'>" + |
|
"<span data-dojo-type='SubThing' data-dojo-props='region: \"center\"'>b</span>" + |
|
"</div>" + |
|
"</div>", |
|
postCreate: function(){ |
|
// children postcreate (x2) called before this postCreate |
|
this.inherited(arguments); |
|
result.push(0); |
|
}, |
|
startup: function(){ |
|
// then children startup (x2) then our startup |
|
// (we can call inherited after push(), and change the order) |
|
this.inherited(arguments); |
|
result.push(3); |
|
} |
|
}); |
|
|
|
new ParentThing().startup(); |
|
|
|
t.is(expected.length, result.length); |
|
array.forEach(expected, function(r){ |
|
t.is(r, result.shift()); |
|
}); |
|
|
|
} |
|
]); |
|
|
|
// Test that "this" referenced from data-dojo-props can refer to the hosting widget |
|
doh.register("data-dojo-props this", function(){ |
|
var host = declare([dijit._WidgetBase, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], { |
|
obj: {hello: "world"}, |
|
templateString: |
|
"<div>" + |
|
"<div data-dojo-type='dijit/_WidgetBase' data-dojo-props='hostObj: this.obj'" + |
|
" data-dojo-attach-point='subWidget'></div>" + |
|
"</div>" |
|
}); |
|
|
|
var hostWidget = new host(), |
|
subWidget = hostWidget && hostWidget.subWidget; |
|
doh.isNot(undefined, hostWidget, "created host widget"); |
|
doh.isNot(undefined, subWidget, "created sub widget"); |
|
doh.isNot(undefined, subWidget.hostObj, "sub widget got hostObj defined"); |
|
doh.is("world", subWidget.hostObj.hello, "object is correct") |
|
}); |
|
|
|
// Test that a context require can be passed to the parser |
|
doh.register("context require", function(){ |
|
var cw = registry.byId("testContextWidget"); |
|
doh.is(typeof cw.fooNode, "object", "button created"); |
|
doh.is(cw.fooNode.fooNode.innerHTML, "TestWidget", "sub widget contains right properties"); |
|
}); |
|
|
|
doh.run(); |
|
}); |
|
</script> |
|
</head> |
|
<body> |
|
<h1>WidgetsInTemplateMixin</h1> |
|
|
|
<!-- Tests for _WidgetsInTemplateMixin combined with _AttachMixin --> |
|
<div class="testcontainer"> |
|
<p>This test shows that a _AttachMixin dijit with _WidgetsInTemplate properly attaches widgets from the template.<br> |
|
<div id="attachMeThree"> |
|
<h2 data-dojo-attach-point='heading'></h2> |
|
<button data-dojo-type='dijit/form/Button' |
|
data-dojo-attach-point='mybutton' |
|
data-dojo-attach-event='click: _buttonClicked'>A button</button> |
|
</div> |
|
</div> |
|
|
|
<!-- Test that widgets inside containerNode aren't parsed by _WidgetsInTemplateMixin--> |
|
<div id="containerNode" class="testcontainer"> |
|
<p>This tests that nodes inside of data-dojo-attach-point="containerNode" are ignored<br> |
|
<div data-dojo-id="outerWidget" data-dojo-type="OuterWidget"> |
|
<h2 data-dojo-attach-point="heading">heading</h2> |
|
<div data-dojo-type="SupportingWidget" data-dojo-attach-point="supportingWidget">supporting widget</div> |
|
<div data-dojo-attach-point="containerNode"> |
|
<span data-dojo-type="ContainedWidget" data-dojo-attach-point="containedWidget">contained widget</span> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<!-- Tests for _WidgetsInTemplateMixin combined with _TemplatedMixin --> |
|
<div id="templateTests"> |
|
<textarea id="Test1Template" style="display:none;"> |
|
<div> |
|
<div data-dojo-attach-point="normalNode">normal node</div> |
|
<button data-dojo-attach-point="buttonWidget" data-dojo-attach-event="click:onClick" data-dojo-type="dijit/form/Button">button #1</button> |
|
<div data-dojo-attach-point="checkboxWidget" data-dojo-attach-event="click:onClick" data-dojo-type="dijit/form/CheckBox"></div> checkbox #1 |
|
<div data-dojo-attach-point="progressBarWidget" data-dojo-attach-event="change:onClick" |
|
data-dojo-type="dijit/ProgressBar" data-dojo-props='value: 20, maximum: 200, style: "width:400px;"'></div> |
|
</div> |
|
</textarea> |
|
|
|
<div data-dojo-type="Test1Widget" data-dojo-props="id: 'test1Widget'"></div> |
|
|
|
|
|
<textarea id="Test3Template" style="display:none;"> |
|
<div> |
|
<div data-dojo-attach-point="checkboxWidget" data-dojo-type="dijit/form/CheckBox"></div> checkbox #3 |
|
<div data-dojo-attach-point="containerNode"></div> |
|
</div> |
|
</textarea> |
|
|
|
<div data-dojo-type="Test3Widget" data-dojo-props="id: 'test3Widget'"> |
|
<span>hello world</span> |
|
<b style="border: 1px solid blue;">this is my |
|
<button data-dojo-type="dijit/form/Button" data-dojo-props="id: '3.1'">first button</button> |
|
</b> |
|
<button data-dojo-type="dijit/form/Button" data-dojo-props="id: '3.2'">another button</button> |
|
<i>and some more</i> |
|
<div style="border: 1px solid red;"> |
|
<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="style: {border: '1px solid gray'}, id: '3.3'"> |
|
<button data-dojo-type="dijit/form/Button" data-dojo-props="id: '3.nested'">a nested button</button> |
|
<button data-dojo-type="dijit/form/Button" data-dojo-props="id: '3.nested2'">another nested button</button> |
|
</div> |
|
<button data-dojo-type="dijit/form/Button" data-dojo-props="id: '3.4'">yet another button</button> |
|
<button data-dojo-type="dijit/form/Button" data-dojo-props="id: '3.5'">yet yet another button</button> |
|
</div> |
|
</div> |
|
|
|
<!-- Test templated widget containing container and nested widgets in template --> |
|
<textarea id="Test5Template" style="display:none;"> |
|
<div> |
|
<div data-dojo-type="TestLayoutWidget" data-dojo-attach-point="layout"> |
|
<div data-dojo-type="TestCtndWidget" data-dojo-attach-point="layChild1"></div> |
|
<div data-dojo-type="TestCtndWidget" data-dojo-attach-point="layChild2"></div> |
|
</div> |
|
<div data-dojo-type="TestCtnrWidget" data-dojo-attach-point="container"> |
|
<div data-dojo-type="TestCtndWidget" data-dojo-attach-point="contained1"></div> |
|
<div data-dojo-type="TestCtndWidget" data-dojo-attach-point="contained2"></div> |
|
</div> |
|
<div data-dojo-type="TestStubWidget" data-dojo-attach-point="stub1"></div> |
|
<div data-dojo-type="TestNonCtnrWidget" data-dojo-attach-point="nonContainer"> |
|
<div data-dojo-type="TestStubWidget" data-dojo-attach-point="nonContained1"></div> |
|
<div data-dojo-type="TestStubWidget" data-dojo-attach-point="nonContained2"></div> |
|
</div> |
|
<div data-dojo-type="TestCtnrWidget" data-dojo-attach-point="threeLevel"> |
|
<div data-dojo-type="TestNonCtnrWidget" data-dojo-attach-point="secondLevel"> |
|
<div data-dojo-type="TestStubWidget" data-dojo-attach-point="bottomLevel"></div> |
|
</div> |
|
</div> |
|
<div data-dojo-type="TestNonCtnrWidget" data-dojo-attach-point="anotherThree"> |
|
<div data-dojo-type="TestCtnrWidget" data-dojo-attach-point="anotherSecond"> |
|
<div data-dojo-type="TestCtndWidget" data-dojo-attach-point="anotherBottom"></div> |
|
</div> |
|
</div> |
|
</div> |
|
</textarea> |
|
|
|
<div data-dojo-type="Test5Widget" data-dojo-props="id: 'test5Widget'"></div> |
|
|
|
<div data-dojo-type="Missing" data-dojo-props="id: 'missing'"></div> |
|
|
|
<!-- Test templated widget containing relative MIDs for data-dojo-type --> |
|
<div data-dojo-type="dijit/tests/resources/TestContextRequireWidget" data-dojo-props="id: 'testContextWidget'"></div> |
|
|
|
<!-- Test templated widget for back-compat with inherited onClick etc events when using widgets in template --> |
|
<textarea id="Test6Template" style="display:none;"> |
|
<div> |
|
<div data-dojo-type="dijit/form/TextBox" data-dojo-attach-point="textbox" data-dojo-attach-event="onClick: handleClick"></div> |
|
</div> |
|
</textarea> |
|
|
|
<div data-dojo-type="Test6Widget" data-dojo-props="id: 'test6Widget'"></div> |
|
|
|
</div> |
|
|
|
</body> |
|
</html>
|
|
|