UNPKG

dijit

Version:

Dijit provides a complete collection of user interface controls based on Dojo, giving you the power to create web applications that are highly optimized for usability, performance, internationalization, accessibility, but above all deliver an incredible u

725 lines (622 loc) 25.7 kB
<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <title>TabContainer DOH Test</title> <script type="text/javascript" src="../boilerplate.js"></script> <script type="text/javascript"> require([ "doh/runner", "dojo/_base/array", "dojo/aspect", "dojo/dom", "dojo/dom-class", "dojo/dom-geometry", "dojo/json", "dojo/_base/lang", "dojo/parser", "dojo/query", "dijit/focus", "dijit/registry", "dijit/layout/TabContainer", "dijit/layout/ContentPane", "dijit/tests/helpers", "dojo/domReady!" ], function(doh, array, aspect, dom, domClass, domGeom, json, lang, parser, query, focus, registry, TabContainer, ContentPane, helpers){ doh.register("parse", function(){ return parser.parse(); }); doh.register("creationAndDestruction", [ // Test that destroyRecursive removes all supporting widgets, including the list-of-tabs menu // and the close menu. Also test that the second tab doesn't get selected // for a split second as the TabContainer is being destroyed. { name: 'destroyRecursive', runTest: function(t){ var num = registry.length; var cp1 = new ContentPane({title: "test pane 1", closable: true}), cp2 = new ContentPane({title: "test pane 2", href: "doc0.html"}), tc = new TabContainer({ id:"creationAndDestruction", useMenu:true }).placeAt(document.body); var cp2selected = false; cp2.watch("selected", function(){ cp2selected = true; }); tc.addChild(cp1); tc.addChild(cp2); tc.startup(); tc.destroyRecursive(); t.is(registry.length, num, "registry length"); t.f(cp2selected, "second pane wasn't temporarily selected"); } }, // Test that on destroyDescendants(), the second tab doesn't get selected // for a split second as the TabContainer is being destroyed. { name: 'destroyDescendants', runTest: function(t){ var cp1 = new ContentPane({ id: "destroyDescendants_pane1", title: "test pane 1", closable: true }), cp2 = new ContentPane({ id: "destroyDescendants_pane2", title: "test pane 2", href: "doc0.html" }), tc = new TabContainer({ id:"destroyDescendants", useMenu:true }).placeAt(document.body); var cp2selected = false; cp2.watch("selected", function(){ cp2selected = true; }); var downloadStarted = false; cp2.on("downloadstart", function(){ downloadStarted = true; }); tc.addChild(cp1); tc.addChild(cp2); tc.startup(); tc.destroyDescendants(); t.f(cp2selected, "second pane wasn't temporarily selected"); t.f(downloadStarted, "second pane never started downloading"); t.is(undefined, tc._selectedChildWidget, "no selected child widget"); } }, // Check that tab labels for initial tabs are created { name: 'checkTabLabels', runTest: function(t){ var tabLabels = query("#tc1 .tabLabel"); t.is(4, tabLabels.length); } } ]); doh.register("addingTabs", [ // Test that adding a pane creates new tab button { name: 'add new tab', runTest: function(t){ var tc = registry.byId("tc1"); var cp1 = new ContentPane({ id: "newTab1", title: "newTab1", content: "newTab1 content" }); tc.addChild(cp1); var tabLabels = registry.byId("tc1").getChildren(); t.is(5, tabLabels.length, "there are 5 tabs"); } }, // Test that scroll buttons show up when tab buttons overflow { name: 'addTabsOverflowMenu', runTest: function(t){ var tc = registry.byId("tc1"); var cp2 = new ContentPane({ id: "newTab2", title: "newTab2", content: "newTab2 content" }); tc.addChild(cp2); var left = dom.byId("tc1_tablist_leftBtn"); var right = dom.byId("tc1_tablist_rightBtn"); var menu = dom.byId("tc1_tablist_menuBtn"); t.t(left, "verify left scroll button exists"); t.t(right, "verify right scroll button exists"); t.t(menu, "verify dropdown menu button exists"); t.t(helpers.isVisible(left), "left scroll button is displayed"); t.t(helpers.isVisible(right), "right scroll button is displayed"); t.t(helpers.isVisible(menu), "menu button is displayed"); } } ]); doh.register("selectingTabs", [ // Check that tab button is scrolled into view when tab is selected { name: 'isVisible', timeout: 10000, runTest: function(t){ var d = new doh.Deferred(); var tc = registry.byId("tc1"); var cp = registry.byId("newTab1"); tc.selectChild(cp); setTimeout(d.getTestCallback(function(){ var cpLeft = dom.byId("tc1_tablist_leftBtn"); var left = domGeom.position(cpLeft).x + domGeom.position(cpLeft).w; var cpRight = dom.byId("tc1_tablist_rightBtn"); var right = domGeom.position(cpRight).x; var tab = registry.byId("tc1_tablist_newTab1"); var tabLeft = domGeom.position(tab.domNode).x; var tabRight = domGeom.position(tab.domNode).x + domGeom.position(tab.domNode).w; var isTabVisible = ((tabLeft > left) && (tabRight < right)); doh.t(isTabVisible, "verify chosen tab is in viewable area"); }), 1000); return d; } }, function focusOutside(){ // Test what happens when focus is outside the TabContainer and you call selectChild(). // In this case, focus shouldn't be changed. registry.byId("tc1").selectChild("t2"); dom.byId("inputBeforeTc1").focus(); registry.byId("tc1").selectChild("cpTitle"); doh.is("inputBeforeTc1", focus.curNode.id); }, function focusInside(){ // Test what happens when focus is inside tab1 and you call selectChild() to select tab2. // In this case focus should be put on the tab label, so that it isn't in a hidden pane. dom.byId("inputInsideCpTitle").focus(); registry.byId("tc1").selectChild("t2"); doh.is("tc1_tablist_t2", focus.curNode.id); } ]); doh.register("icons", [ { name: "initialIcon", runTest: function(t){ var cp = registry.byId("cp4"); t.is('tab1', innerText(cp.controlButton.containerNode), "tab label"); t.is('plusIcon', cp.controlButton.iconClass, "tab icon"); } }, { name: "changeIcon", runTest: function(t){ var cp = registry.byId("cp4"); cp.set({ "title": "note", "iconClass": "noteIcon" }); t.is('note', innerText(cp.controlButton.containerNode), "the tab's label has changed"); t.is('noteIcon', cp.controlButton.iconClass, "new icon is displayed in tab"); } }, { name: "noTitle", runTest: function(t){ var cp = registry.byId("cp7"); t.f(cp.controlButton.showLabel, "an icon exists, but there is no text label"); } } ]); doh.register("changeTabName", [ { name: 'changeName', runTest: function(t){ var cp = registry.byId('cpTitle'); cp.set('title', 'newTitle'); var title = query("#tc1_tablist_cpTitle")[0]; t.is('newTitle', innerText(title), "the tab's text label has changed"); } } ]); doh.register("deletingTabs", [ // Check that deleting a pane removes the tab button { name: 'deleteTab', runTest: function(t){ var tc1 = registry.byId("tc1"); var cp = registry.byId("cpTitle"); // track resizes to cp, removing it from tc1 shouldn't cause a resize call var cpResizes = 0; aspect.after(cp, "resize", function(){ cpResizes++; }, true); tc1.removeChild(cp); var childPanes = tc1.getChildren(); t.is(5, childPanes.length, "verify there are now only 4 tabs instead of 5"); t.t(cp.domNode, "verify that the deleted tab's content pane still exists on the page"); var label = dom.byId("#tc1_tablist_cpTitle"); t.f(label, "verify that deleted tab's label does not exist"); t.is(0, cpResizes, "no resize"); } }, // Check that scroll buttons disappear when no longer needed { name: 'removedOverflowMenu', runTest: function(t){ var tc = registry.byId("tc3"); var cp = registry.byId('cp10'); tc.removeChild(cp); cp = registry.byId('cp9'); tc.removeChild(cp); cp = registry.byId('cp8'); tc.removeChild(cp); cp = registry.byId('cp7'); tc.removeChild(cp); var left = registry.byId("tc3_tablist_leftBtn").domNode; var right = registry.byId("tc3_tablist_rightBtn").domNode; var menu = registry.byId("tc3_tablist_menuBtn").domNode; t.t(helpers.isHidden(left), "left scroll is hidden"); t.t(helpers.isHidden(right), "right scroll is hidden"); t.t(helpers.isHidden(menu), "menu is hidden"); } } ]); doh.register("closableTabs", [ { name: "closeTab", runTest: function(t){ var cp = registry.byId("cp6"); var cp2 = registry.byId("cp5"); t.t(cp.controlButton.closeButton, "close button is displayed"); t.f(cp2.controlButton.closeButton, "close button is not displayed"); } } ]); doh.register("menu", { name: "menu", runTest: function(t){ var tc1 = registry.byId("tc1"), children = tc1.getChildren(); // add an icon and change the title just for testing that the icon and label appear in the menu children[0].set({ title: "new title", iconClass: "noteIcon" }); var menuBtn = registry.byId("tc1_tablist_menuBtn"); menuBtn.toggleDropDown(); var menu = registry.byId("tc1_menu"); doh.t(helpers.isVisible(menu), "menu exists and is visible"); doh.is(menu.getChildren().length, children.length, "# of menu children"); doh.is("new title", innerText(menu.getChildren()[0].containerNode)); doh.is("noteIcon", menu.getChildren()[0].iconClass); }, tearDown: function(){ var tc1 = registry.byId("tc1"), children = tc1.getChildren(); children[0].set({ title: "old title", iconClass: "" }); var menuBtn = registry.byId("tc1_tablist_menuBtn"); menuBtn.closeDropDown(); } }); doh.register("layoutTests", [ { name: "tabPosition", runTest: function(t){ var tc = registry.byId("tc1"); // top tabs above content var topTabs = dom.byId("tc1_tablist"), topContent = query(".dijitTabPaneWrapper", "tc1")[0], topTabsPos = domGeom.position(topTabs), topContentPos = domGeom.position(topContent); t.t(topTabsPos.y + topTabsPos.h <= topContentPos.y, "top tabs above content " + json.stringify(topTabsPos) + json.stringify(topContentPos)); // left tabs to left of content var leftTabs = dom.byId("leftTabs_tablist"), leftContent = query(".dijitTabPaneWrapper", "leftTabs")[0], leftTabsPos = domGeom.position(leftTabs), leftContentPos = domGeom.position(leftContent); t.t(leftTabsPos.x + Math.floor(leftTabsPos.w) <= leftContentPos.x, "left tabs before content " + json.stringify(leftTabsPos) + json.stringify(leftContentPos)); // right tabs to right of content var rightTabs = dom.byId("rightTabs_tablist"), rightContent = query(".dijitTabPaneWrapper", "rightTabs")[0], rightTabsPos = domGeom.position(rightTabs), rightContentPos = domGeom.position(rightContent); t.t(rightTabsPos.x >= rightContentPos.x + rightContentPos.w, "right tabs after content " + json.stringify(rightTabsPos) + json.stringify(rightContentPos)); // bottom tabs below content var bottomTabs = dom.byId("bottomTabs_tablist"), bottomContent = query(".dijitTabPaneWrapper", "bottomTabs")[0], bottomTabsPos = domGeom.position(bottomTabs), bottomContentPos = domGeom.position(bottomContent); t.t(bottomTabsPos.y >= bottomContentPos.y + bottomContentPos.h, "bottom tabs below content " + json.stringify(bottomTabsPos) + json.stringify(bottomContentPos)); } }, { name: "nested", runTest: function(t){ var parent = registry.byId("tcNestedParent"), child = registry.byId("tcNestedChild"); t.f(parent.nested, "parent TabContainer is not nested"); var children = parent.getChildren(); t.is(2, children.length, "parent TabContainer has multiple children"); t.t(children[1].nested, "second child of parent TabContainer has nested tabs"); t.t(domClass.contains("tcNestedChild_tablist", "dijitTabContainerTabListNested"), "nested CSS applied"); // test that when TabButtons overflow to 2 rows, the content area is reduced parent.selectChild(registry.byId("tcNestedChild")); var content = query(".dijitTabPaneWrapper", "tcNestedChild")[0], height0 = domGeom.position(content).h; var newGrandchildren = []; for(var i=0; i<10; i++){ var gc = new ContentPane({ title: "additional child #" + i, content: "hello world " + i }); newGrandchildren.push(gc); child.addChild(gc); } var height1 = domGeom.position(content).h; doh.t(height1 < height0, "content area size reduced ", height1, height0); // and that size increases back when children are removed array.forEach(newGrandchildren, lang.hitch(child, "removeChild")); var height2 = domGeom.position(content).h; doh.is(height0, height2, "after deleting extra children height restored to original"); // Setting the title of nested TabContainer shouldn't make a tooltip over it doh.f(child.domNode.hasAttribute && child.domNode.hasAttribute("title"), "child.hasAttribute(title) before"); child.set("title", "Nested new title"); doh.f(child.domNode.hasAttribute && child.domNode.hasAttribute("title"), "child.hasAttribute(title) after"); } }, { name: "doLayoutFalse", runTest: function(t){ var tc = registry.byId("tcNoLayout"); var cps = tc.getChildren(); tc.selectChild(cps[0]); var height1 = tc.domNode.offsetHeight; tc.selectChild(cps[1]); var height2 = tc.domNode.offsetHeight; tc.selectChild(cps[2]); var height3 = tc.domNode.offsetHeight; t.t(height1 < height2, "height 1 < height 2" + height1 + " < " + height2); t.t(height2 < height3, "height 2 < height 3" + height2 + " < " + height3); } }, { name: "doLayoutTrue", runTest: function(t){ var tc = registry.byId("tc3"); var cps = tc.getChildren(); tc.selectChild(cps[0]); var height1 = tc.domNode.offsetHeight; tc.selectChild(cps[1]); var height2 = tc.domNode.offsetHeight; tc.selectChild(cps[2]); var height3 = tc.domNode.offsetHeight; t.is(height1, height2); t.is(height2, height3); t.t(height1 > 10, "make sure height measurement is giving something reasonable"); } } ]); var tabId = 1; function addTab(tc){ // summary: // Add a tab to specified TabContainer var cp = new ContentPane({ title: 'Tab' + tabId, content: "Contents of Tab " + tabId++ }); tc.addChild(cp); } doh.register("empty tab container",[ function createEmptyTabContainer(){ var emptyTC = new TabContainer({id:"emptyTC", style:'height:200px;width:500px;'}); document.body.appendChild(emptyTC.domNode); emptyTC.startup(); var children = emptyTC.getChildren(); doh.is(0, children.length); doh.t(helpers.isVisible(emptyTC)); var pos = domGeom.position(emptyTC.domNode); var heightDiff = 200 - pos.h; var widthDiff = 500 - pos.w; doh.t(-0.01 < heightDiff && heightDiff < 0.01); doh.t(-0.01 < widthDiff && widthDiff < 0.01); }, function addTabToEmptyTabContainer(){ var tc = registry.byId("emptyTC"); addTab(tc); var children = tc.getChildren(); doh.is(1, children.length); doh.is("Tab1", children[0].title); doh.is("Contents of Tab 1", tc.selectedChildWidget.domNode.innerHTML); doh.t(helpers.isVisible(tc.tablist.containerNode.childNodes[0])); }, function add2ndTabToEmptyTabContainer(){ var tc = registry.byId("emptyTC"); addTab(tc); tc.selectChild(tc.getChildren()[1]); var children = tc.getChildren(); doh.is(2, children.length); doh.is("Tab2", children[1].title); doh.is("Contents of Tab 2", tc.selectedChildWidget.domNode.innerHTML); doh.t(helpers.isVisible(tc.tablist.containerNode.childNodes[1])); }, function remove2ndTabToEmptyTabContainer(){ var tc = registry.byId("emptyTC"); tc.removeChild(tc.getChildren()[1]); var children = tc.getChildren(); doh.is(1, children.length); doh.is("Tab1", children[0].title); doh.is("Contents of Tab 1", tc.selectedChildWidget.domNode.innerHTML); } ]); doh.register("tab label scrolling", [ function initialScroll(){ // Make sure that tab labels are scrolled so that selected tab visible var tc = registry.byId("scroll"), tcPos = domGeom.position("scroll"); labelPos = domGeom.position("scroll_tablist_nine"); doh.t(tcPos.x < labelPos.x, "tcPos.x (" + tcPos.x + ") < labelPos.x (" + labelPos.x + ")"); doh.t(tcPos.x + tcPos.w > labelPos.x + labelPos.w, "tcPos.x (" + tcPos.x + ") + tcPos.w (" + tcPos.w + ") < labelPos.x " + labelPos.x + " + labelPos.w + (" + labelPos.w + ")"); }, function selectATab(){ // Make sure that tab labels are scrolled so that selected tab visible var d = new doh.Deferred(); var tc = registry.byId("scroll"); tc.selectChild(registry.byId("one")); setTimeout(d.getTestCallback(function(){ var tcPos = domGeom.position("scroll"); labelPos = domGeom.position("scroll_tablist_one"); doh.t(tcPos.x < labelPos.x, "tcPos.x (" + tcPos.x + ") < labelPos.x (" + labelPos.x + ")"); doh.t(tcPos.x + tcPos.w > labelPos.x + labelPos.w, "tcPos.x (" + tcPos.x + ") + tcPos.w (" + tcPos.w + ") < labelPos.x " + labelPos.x + " + labelPos.w + (" + labelPos.w + ")"); }), 500); return d; } ]); doh.run(); }); </script> </head> <body class="claro" role="main"> <h1 class="testTitle">Dijit layout.TabContainer DOH tests</h1> <input id="inputBeforeTc1" value="for focus testing"> <div id="tc1" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width: 300px; height: 100px;","aria-label":"my super label" '> <div id="cpTitle" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"tab1", selected:true'> Lorem ipsum and all around... <input id="inputInsideCpTitle" value="for focus testing"> </div> <div id="t2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"tab2"'> Lorem ipsum and all around - second... </div> <div id="t3" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"tab3", closable:true'> Lorem ipsum and all around - third... </div> <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"tab4", closable:true'> Lorem ipsum and all around - last... </div> </div> <div id="tc3" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width: 300px; height: 100px;" '> <div id="cp4" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"tab1", selected:true, iconClass:"plusIcon"'> Lorem ipsum and all around... </div> <div id="cp5" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"tab2"'> Lorem ipsum and all around - last... <br /> <br /> <br /> Hmmm even more expanding tabs...... </div> <div id="cp6" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"tab3", closable:true'> Lorem ipsum and all around - last... </div> <div id="cp7" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"plus", closable:true, iconClass:"plusIcon", showTitle:false'> Lorem ipsum and all around - last... </div> <div id="cp8" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"tab4", closable:true'> Lorem ipsum and all around - last... </div> <div id="cp9" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"tab5", closable:true'> Lorem ipsum and all around - last... </div> <div id="cp10" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"tab6", closable:true'> Lorem ipsum and all around - last... </div> </div> <div id="tcNestedParent" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width: 400px; height: 300px;" '> <div id="tcNestedChild" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='title:"Tab 1", nested:true '> <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My first inner tab", selected:true'> Lorem ipsum and all around... </div> <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My second inner tab"'> Lorem ipsum and all around - second... </div> <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My last inner tab"'> Lorem ipsum and all around - last... </div> </div> <div data-dojo-type="dijit/layout/TabContainer" data-dojo-props='title:"Tab 2", nested:true'> <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My first inner tab", selected:true'> Lorem ipsum and all around... </div> <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My second inner tab"'> Lorem ipsum and all around - second... </div> <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My last inner tab"'> Lorem ipsum and all around - last... </div> </div> </div> <div id="tcNoLayout" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width: 100%;", doLayout:false'> <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My first tab", selected:true'> Lorem ipsum and all around... </div> <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My second tab", closable:true'> Lorem ipsum and all around - second... <br /> Hmmm expanding tabs...... </div> <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My last tab"'> Lorem ipsum and all around - last... <br /> <br /> <br /> Hmmm even more expanding tabs...... </div> </div> <br /> <div id="leftTabs" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width: 500px; height: 200px;", tabPosition:"left-h"'> <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My first tab", selected:true'> Left tabs </div> <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My second tab", closable:true'> Lorem ipsum and all around - second... </div> <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My last tab"'> Lorem ipsum and all around - last... </div> </div> <br /> <div id="rightTabs" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width: 500px; height: 200px;", tabPosition:"right-h"'> <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My first tab", selected:true'> Right tabs </div> <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My second tab", closable:true'> Lorem ipsum and all around - second... </div> <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My last tab"'> Lorem ipsum and all around - last... </div> </div> <br /> <div id="bottomTabs" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width: 500px; height: 200px;", tabPosition:"bottom"'> <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My first tab", selected:true'> Bottom tabs </div> <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My second tab", closable:true'> Lorem ipsum and all around - second... </div> <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My last tab"'> Lorem ipsum and all around - last... </div> </div> <div id="scroll" data-dojo-type="dijit/layout/TabContainer" data-dojo-id="scroll" style="width: 300px; height:200px;"> <div data-dojo-type="dijit/layout/ContentPane" title="One" data-dojo-id="one" id="one">One</div> <div data-dojo-type="dijit/layout/ContentPane" title="Two" data-dojo-id="two" id="two">Two</div> <div data-dojo-type="dijit/layout/ContentPane" title="Three" data-dojo-id="three" id="three">Three</div> <div data-dojo-type="dijit/layout/ContentPane" title="Four" data-dojo-id="four" id="four">Four</div> <div data-dojo-type="dijit/layout/ContentPane" title="Five" data-dojo-id="five" id="five">Five</div> <div data-dojo-type="dijit/layout/ContentPane" title="Six" data-dojo-id="six" id="six">Six</div> <div data-dojo-type="dijit/layout/ContentPane" title="Seven" data-dojo-id="seven" id="seven">Seven</div> <div data-dojo-type="dijit/layout/ContentPane" title="Eight" data-dojo-id="eight" id="eight">Eight</div> <div data-dojo-type="dijit/layout/ContentPane" selected="true" title="Nine" data-dojo-id="nine" id="nine">Nine</div> </div> </body> </html>