<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <!-- we use a strict-mode DTD to ensure that the box model is the same for these basic tests --> <html> <head> <style type="text/css"> @import "../../resources/dojo.css"; html, body { padding: 0px; margin: 0px; border: 0px; } #sq100 { background-color: black; color: white; position: absolute; left: 100px; top: 100px; width: 100px; height: 100px; border: 0px; padding: 0px; margin: 0px; overflow: hidden; } </style> <title>testing dojo.NodeList</title> <script type="text/javascript" src="../../dojo.js"></script> <script type="text/javascript"> require(["dojo", "doh", "dojo/query", "dojo/on", "dojo/string", "dojo/parser", "dojo/domReady!"], function(dojo, doh, query, listen){ function registerForNodeList(name, query, NodeList){ var tn; var c = dojo.byId("c1"); var t = dojo.byId("t"); var s = dojo.byId("sq100"); var fourElementNL = new NodeList(c, t, c, t); function verify(/*dojo.NodeList*/nl, /*Array*/ids){ for(var i = 0, node; node = nl[i]; i++){ doh.is(ids[i], node.id); } //Make sure lengths are equal. doh.is(ids.length, i); } doh.register(name, [ // constructor tests function ctor(){ var nl = new NodeList(); nl.push(c); doh.is(1, nl.length); }, function ctorArgs(){ var nl = new NodeList(4); nl.push(c); doh.is(5, nl.length); }, function ctorArgs2(){ var nl = new NodeList(c, t); doh.is(2, nl.length); doh.is(c, nl[0]); doh.is(t, nl[1]); }, // iteration and array tests function forEach(){ var lastItem; var nl = new NodeList(c, t); nl.forEach(function(i){ lastItem = i; }); doh.is(t, lastItem); var r = nl.forEach(function(i, idx, arr){ doh.t(arr.constructor == dojo.NodeList); doh.is(2, arr.length); }); doh.t(r.constructor == dojo.NodeList); doh.is(r, nl); }, function indexOf(){ doh.is(0, fourElementNL.indexOf(c)); doh.is(1, fourElementNL.indexOf(t)); doh.is(-1, fourElementNL.indexOf(null)); }, function lastIndexOf(){ doh.is(2, fourElementNL.lastIndexOf(c)); doh.is(3, fourElementNL.lastIndexOf(t)); doh.is(-1, fourElementNL.lastIndexOf(null)); }, function every(){ var ctr = 0; var ret = fourElementNL.every(function(){ ctr++; return true; }); doh.is(4, ctr); doh.t(ret); ctr = 0; var ret = fourElementNL.every(function(){ ctr++; return false; }); doh.is(1, ctr); doh.f(ret); }, function some(){ var ret = fourElementNL.some(function(){ return true; }); doh.t(ret); var ret = fourElementNL.some(function(i){ return (i.id == "t"); }); doh.t(ret); }, function map(){ var ret = fourElementNL.map(function(){ return true; }); doh.is(ret, [true, true, true, true]); verify(ret.end(), ["c1", "t", "c1", "t"]); var cnt = 0; var ret = fourElementNL.map(function(){ return cnt++; }); // doh.is(ret, [0, 1, 2, 3]); doh.t(ret.constructor == dojo.NodeList); // make sure that map() returns a NodeList var sum = 0; fourElementNL.map(function(){ return 2; }).forEach( function(x){ sum += x; } ); doh.is(sum, 8); }, function slice(){ var pnl = new NodeList(t, t, c); doh.is(2, pnl.slice(1).length); doh.is(3, pnl.length); doh.is(c, pnl.slice(-1)[0]); doh.is(2, pnl.slice(-2).length); verify(pnl.slice(1).end(), ["t", "t", "c1"]); }, function splice(){ var pnl = new NodeList(t, t, c); console.debug(pnl.splice(1)); /* doh.is(2, pnl.splice(1).length); doh.is(1, pnl.length); pnl = new NodeList(t, t, c); doh.is(c, pnl.splice(-1)[0]); doh.is(2, pnl.length); pnl = new NodeList(t, t, c); doh.is(2, pnl.splice(-2).length); */ }, function spliceInsert(){ // insert 1 var pnl = new NodeList(t, t, c); pnl.splice(0, 0, c); doh.is(4, pnl.length); doh.is(c, pnl[0]); // insert multiple pnl = new NodeList(t, t, c); pnl.splice(0, 0, c, s); doh.is(5, pnl.length); doh.is(c, pnl[0]); doh.is(s, pnl[1]); doh.is(t, pnl[2]); // insert multiple at offset pnl = new NodeList(t, t, c); pnl.splice(1, 0, c, s); doh.is(5, pnl.length); doh.is(t, pnl[0]); doh.is(c, pnl[1]); doh.is(s, pnl[2]); doh.is(t, pnl[3]); }, function spliceDel(){ // clobbery 1 var pnl = new NodeList(c, t, s); pnl.splice(0, 1); doh.is(2, pnl.length); doh.is(t, pnl[0]); // clobber multiple pnl = new NodeList(c, t, s); pnl.splice(0, 2); doh.is(1, pnl.length); doh.is(s, pnl[0]); // ...at an offset pnl = new NodeList(c, t, s); pnl.splice(1, 1); doh.is(2, pnl.length); doh.is(c, pnl[0]); doh.is(s, pnl[1]); }, function spliceInsertDel(){ // clobbery 1 var pnl = new NodeList(c, t, s); pnl.splice(1, 1, s); doh.is(3, pnl.length); doh.is(new NodeList(c, s, s), pnl); pnl = new NodeList(c, t, s); pnl.splice(1, 2, s); doh.is(2, pnl.length); doh.is(new NodeList(c, s), pnl); }, // sub-search function queryTest(){ var pnl = new NodeList(t); doh.is(c, pnl.query("span")[0]); if(name != "t"){ // this gets messed up by new DOM nodes the second time around doh.is(t, query("body").query(":last-child")[0]); doh.is(c, query("body").query(":last-child")[1]); doh.is(1, pnl.query().length); verify(pnl.query("span").end(), ["t"]); } }, function filter(){ if(name != "t"){ // this gets messed up by new DOM nodes the second time around doh.is(query("body :first-child").filter(":last-child")[0], c); doh.is(1, query("*").filter(function(n){ return (n.nodeName.toLowerCase() == "span"); }).length); var filterObj = { filterFunc: function(n){ return (n.nodeName.toLowerCase() == "span"); } }; doh.is(1, query("*").filter(filterObj.filterFunc).length); doh.is(1, query("*").filter(filterObj.filterFunc, filterObj).length); verify((new NodeList(t)).filter("span").end(), ["t"]); } }, // layout DOM functions function coords(){ var tnl = new NodeList(dojo.byId('sq100')); doh.t(dojo.isArray(tnl)); doh.is(100, tnl.coords()[0].w); doh.is(100, tnl.coords()[0].h); doh.is(100, tnl.position()[0].w); doh.is(100, tnl.position()[0].h); doh.is(document.body.getElementsByTagName("*").length, query("body *").coords().length); doh.is(document.body.getElementsByTagName("*").length, query("body *").position().length); }, function styleGet(){ // test getting var tnl = new NodeList(s); doh.is(1, tnl.style("opacity")[0]); tnl.push(t); dojo.style(t, "opacity", 0.5); doh.is(0.5, tnl.style("opacity").slice(-1)[0]); tnl.style("opacity", 1); }, function styleSet(){ // test setting var tnl = new NodeList(s, t); tnl.style("opacity", 0.5); doh.is(0.5, dojo.style(tnl[0], "opacity")); doh.is(0.5, dojo.style(tnl[1], "opacity")); // reset tnl.style("opacity", 1); }, function style(){ var tnl = new NodeList(s, t); tnl.style("opacity", 1); doh.is(1, tnl.style("opacity")[0]); dojo.style(t, "opacity", 0.5); doh.is(1.0, tnl.style("opacity")[0]); doh.is(0.5, tnl.style("opacity")[1]); // reset things tnl.style("opacity", 1); }, function addRemoveClass(){ var tnl = new NodeList(s, t); tnl.addClass("a"); doh.is("a", s.className); doh.is("a", t.className); tnl.addClass("a b"); doh.is("a b", s.className); doh.is("a b", t.className); tnl.addClass(["a", "c"]); doh.is("a b c", s.className); doh.is("a b c", t.className); tnl.removeClass(); doh.is("", s.className); doh.is("", t.className); tnl.addClass(" a"); doh.is("a", s.className); doh.is("a", t.className); tnl.addClass(" a b "); doh.is("a b", s.className); doh.is("a b", t.className); tnl.addClass(" c b a "); doh.is("a b c", s.className); doh.is("a b c", t.className); tnl.removeClass(" b"); doh.is("a c", s.className); doh.is("a c", t.className); tnl.removeClass("a b "); doh.is("c", s.className); doh.is("c", t.className); tnl.removeClass(["a", "c"]); doh.is("", s.className); doh.is("", t.className); tnl.addClass("a b c"); tnl.replaceClass("d e", "a b"); doh.is("c d e", s.className, "class is c d e after replacing a b with d e"); doh.is("c d e", t.className, "class is c d e after replacing a b with d e"); tnl.replaceClass("f", "d"); doh.is("c e f", s.className, "class is c e f after replacing d with f"); doh.is("c e f", t.className, "class is c e f after replacing d with f"); tnl.replaceClass("d"); doh.is("d", s.className); doh.is("d", t.className); tnl.removeClass(); doh.is("", s.className, "empty class"); doh.is("", t.className, "empty class"); }, function concat(){ if(name != "t"){ // this isn't supported in the new query method var spans = query("span"); var divs = query("div"); var cat = spans.concat(divs); console.debug(cat); doh.t(cat.constructor == dojo.NodeList || cat.constructor == dojo.NodeList); doh.is((divs.length + spans.length), cat.length); verify(cat.end(), ["c1"]); } }, function concat2(){ var spans = query("span"); var divs = query("div"); doh.is(spans.concat([]).constructor, dojo.NodeList); }, function concat3(){ var spans = query("span"); var divs = query("div"); var cat = spans.concat(divs); doh.t(typeof NodeList != "undefined" && cat.constructor === dojo.NodeList || cat.constructor === dojo.NodeList); }, function concat4(){ var res = (new dojo.NodeList()).concat([]); doh.is(0, res.length); }, function place(){ var ih = "<div><span></span></div><span class='thud'><b>blah</b></span>"; var tn = document.createElement("div"); tn.innerHTML = ih; dojo.body().appendChild(tn); var nl = query("b", tn).place(tn, "first"); doh.t(nl.constructor == dojo.NodeList || nl.constructor == dojo.NodeList); doh.is(1, nl.length); doh.is("b", nl[0].nodeName.toLowerCase()); doh.is(tn, nl[0].parentNode); doh.is(tn.firstChild, nl[0]); }, function orphan(){ var ih = "<div><span></span></div><span class='thud'><b>blah</b></span>"; var tn = document.createElement("div"); tn.innerHTML = ih; dojo.body().appendChild(tn); var nl = query("span", tn).orphan(); doh.t(nl.constructor == dojo.NodeList || nl.constructor == dojo.NodeList); doh.is(2, nl.length); doh.is(1, tn.getElementsByTagName("*").length); tn.innerHTML = ih; var nl = query("*", tn).orphan("b"); doh.is(1, nl.length); doh.is("blah", nl[0].innerHTML); }, function adopt(){ var div = query(dojo.create("div")); div.adopt(dojo.create("span")); div.adopt(dojo.create("em"), "first"); doh.is(2, query("*", div[0]).length); doh.is("em", div[0].firstChild.tagName.toLowerCase()); doh.is("span", div[0].lastChild.tagName.toLowerCase()); }, function addContent(){ //text content var tn = document.createElement("div"); var nl = query(tn).addContent("some text content"); doh.is(1, nl[0].childNodes.length); doh.is("some text content", nl[0].firstChild.nodeValue); //move a node var mNode = document.createElement("span"); mNode.id = "addContent1"; mNode.innerHTML = "hello"; dojo.body().appendChild(mNode); doh.t(dojo.byId("addContent1")); nl.addContent(mNode); doh.f(dojo.byId("addContent1")); doh.is("addContent1", nl[0].lastChild.id); //put in multiple content/clone node tn.innerHTML = '<select><option name="second" value="second" selected>second</option></select>'; nl = query("select", tn).addContent('<option name="first" value="first">first</option>', "first"); nl.forEach(function(node){ doh.is("first", node.options[0].value); doh.f(node.options[0].selected); }); //Some divs to use for addContent template actions. var templs = dojo._toDom('<div class="multitemplate"></div><div class="multitemplate"></div>'); dojo.body().appendChild(templs); templs = query(".multitemplate"); //templateFunc test templs.addContent({ template: '<b>[name]</b>', templateFunc: function(str, obj){ return str.replace(/\[name\]/g, obj.name); }, name: "bar" }); var bolds = templs.query("b"); doh.is(2, bolds.length); bolds.forEach(function(node){ doh.is("bar", node.innerHTML); }); //template with dojo.string.substitute used. templs.addContent({ template: "<p>${name}</p>", name: "baz" }); var ps = templs.query("p"); doh.is(2, ps.length); ps.forEach(function(node){ doh.is("baz", node.innerHTML); }); //Try a dojo.declared thing. dojo.declare("dojo.tests.Mini", null, { constructor: function(args, node){ dojo.mixin(this, args); node.innerHTML = this.name; this.domNode = node; }, name: "" }); templs.addContent({ template: '<i dojoType="dojo.tests.Mini" name="cool"></i>', parse: true }); var declaredNodes = templs.query("[dojoType]"); doh.is(2, declaredNodes.length); dojo.forEach(declaredNodes, function(node){ doh.is("cool", node.innerHTML); }); //Get rid of the junk used for template testing. templs.orphan(); }, function connect(){ var ih = "<div><span></span></div><span class='thud'><button>blah</button></span>"; tn = document.createElement("div"); tn.innerHTML = ih; dojo.body().appendChild(tn); var ctr = 0; var nl = query("button", tn).connect("onclick", function(){ ctr++; }); nl[0].click(); doh.is(1, ctr); nl[0].click(); nl[0].click(); doh.is(3, ctr); }, function on(){ var ctr = 0; dojo.body().appendChild(tn); var nl = query("button", tn); var handle = nl.on("click", function(){ ctr++; }); nl[0].click(); doh.is(1, ctr); var inButton = nl[0].appendChild(document.createElement("span")); listen.emit(nl[0], "click", { }); listen.emit(inButton, "click", { bubbles: true }); listen.emit(inButton, "click", { bubbles: false }); doh.is(3, ctr); handle.remove(); listen.emit(nl[0], "click", { }); doh.is(3, ctr); }, function onDelegate(){ var ctr = 0; dojo.body().appendChild(tn); var nl = query(".thud", tn); var bl = query("button", tn); var handle = nl.on("button:click", function(){ doh.is(this, bl[0]); ctr++; }); doh.is(0, ctr); listen.emit(nl[0], "click", { }); listen.emit(bl[0], "click", { bubbles: true }); doh.is(1, ctr); handle.remove(); listen.emit(bl[0], "click", { bubbles: true }); doh.is(1, ctr); // listen and on should behave the same query(tn).on(".thud:click, .thud button:custom", function(){ ctr++; }); listen.emit(bl[0], "click", { bubbles: true }); doh.is(2, ctr); listen.emit(bl[0], "click", { bubbles: false }); doh.is(2, ctr); listen.emit(bl[0], "custom", { bubbles: true }); doh.is(3, ctr); listen.emit(bl[0], "mouseout", { bubbles: true }); doh.is(3, ctr); bl[0].click(); doh.is(4, ctr); }, function at(){ var divs = query("body div"); var at0 = divs.at(0); doh.is(divs[0], at0[0]); if(name != "t"){ // this gets messed up by new DOM nodes the second time around var at1 = divs.at(1,3,5); doh.is(divs[1], at1[0]); doh.is(divs[3], at1[1]); doh.is(divs[5], at1[2]); var at2 = divs.at(3,6,9); doh.is(at2.length, 2); var at3 = divs.at(3,6).at(1); doh.is(divs[6], at3[0]); var ending = divs.at(0).end(); verify([ending[0], ending[1]], ["sq100", "t"]); var at4 = divs.at(-1); doh.is(divs[divs.length - 1], at4[0]); var at5 = divs.at(1, -1); doh.is(at5[0], divs[1]); doh.is(at5[1], divs[divs.length - 1]); } }, function attr(){ var divs = query("div"); var ids = divs.attr("id"); }, function _adaptAsForEach(t){ var passes = false; var count = 0; var i = { setTrue: function(node){ count++; passes = true; } }; dojo.NodeList.prototype.setTrue = dojo.NodeList._adaptAsForEach(i.setTrue, i); var divs = query("div").setTrue(); doh.t(passes); doh.is(count, divs.length); }, function instantiate(){ //Insert some divs to use for test dojo.place('<p id="thinger">Hi</p><p id="thinger2">Hi</p>', dojo.body()); var test = 0; dojo.declare("tests._base.NodeList.some.Thing", null, { foo:"baz", constructor: function(props, node){ dojo.mixin(this, props); doh.is("bar", this.foo, test++); } }); query("#thinger").instantiate(tests._base.NodeList.some.Thing, { foo:"bar" }); query("#thinger2").instantiate("tests._base.NodeList.some.Thing", { foo:"bar" }); doh.is(2, test); //clean up the divs inserted for the test. query("#thinger, #thinger2").orphan(); }, function removeAttr(){ // buildup dojo.place('<p id="attr" title="Foobar">Hi</p>', dojo.body()); var n = query("#attr"); doh.t(dojo.hasAttr(n[0], "title")); var t = n.attr("title"); doh.is(t, "Foobar"); n.removeAttr("title"); t = dojo.hasAttr(n[0], "title"); doh.f(t); // cleanup n.orphan(); } ] ); } registerForNodeList("t-backcompat", dojo.query, function(){ return dojo.NodeList.apply(dojo.NodeList, arguments); }); registerForNodeList("t", query, dojo.NodeList); doh.run(); }); </script> </head> <body> <h1>testing dojo.NodeList</h1> <div id="sq100"> 100px square, abs </div> <div id="t"> <span id="c1">c1</span> </div> </body> </html>