UNPKG

extjs-gpl

Version:

GPL licensed version of Sencha Ext JS

489 lines (373 loc) 17.8 kB
describe("Ext.dom.Query", function(){ var body = Ext.getBody().dom, useQuerySelectorAll = false, defs = [ '<div id="a:b" class="myclass">abc</div>', // test for conflict with pseudo class '<div id="c:last-child" class="myotherclass and-another-class">def</div>', // another conflict test '<div id="abc:" specialAttr="jkl\\\\tasdf">ghi</div>', '<div id="nn" class="cls:hover">jkl\\tasdf</div>', '<div id="12345">mno:pqr</div>', '<div id="--abc" customAttr="12345678">pqr</div>', '<div id="\\nn" customAttr="myval:ue\t">stu</div>', '<div id="n\\nn" customAttr="my\\tvalue">vwx</div>', '<div id="oddClass" class="#odd-class-name"></div>', '<div id="\nn">yz</div>', ('<div id=":id">' + '<span id=":only-child-span">some more text</span>' + '<div id="n6e">asdf</div>' + '<div id="n6g">asdf</div>' + '</div>'), ('<span id="myspan" class="myclass isSpan">' + '<span id="AAA" class="beginning">some</span>' + '<span id="BBB" class="ending">text</span>' + '</span>') ], content = defs.join(''), elem, targetSpan; function doQuery(query, element) { return useQuerySelectorAll ? elem.querySelectorAll(query) : Ext.dom.Query.jsSelect(query, element); } beforeEach(function(){ elem = document.createElement('div'); elem.innerHTML = content; elem.id = 'elemNode'; body.appendChild(elem); targetSpan = doQuery("#myspan", elem)[0]; }); afterEach(function(){ if(elem) { body.removeChild(elem); elem = targetSpan = null; } }); describe("selectValue", function() { it("should return defaultValue if nothing is found", function() { var result = Ext.dom.Query.selectValue("testing", document, "empty"); expect(result).toBe('empty'); }); }); describe("jsSelect", function(){ it("should throw error for an invalid query", function(){ try { var found = Ext.dom.Query("$#@$%", elem); expect(false).toBe(true); } catch (ex) { } }); describe("Standard CSS Selectors", function(){ it("should locate elements by id", function(){ var found = doQuery("#nn", elem), len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[3]); found = doQuery("span > span#BBB", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(targetSpan.childNodes[1]); found = doQuery("span + span#BBB", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(targetSpan.childNodes[1]); if(useQuerySelectorAll) { found = doQuery("#\\31 2345 + div", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[5]); } else { // technically, our regexes will match this // but shouldn't, as the first character isn't // supposed to be a number found = doQuery("#12345 + div", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[5]); } }); it("should locate elements by class", function(){ var found = doQuery(".myclass", elem), len = found.length; expect(len).toBe(2); expect(found[0]).toBe(elem.childNodes[0]); expect(found[1]).toBe(targetSpan); found = doQuery(" .isSpan", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(targetSpan); found = doQuery(".isSpan .ending", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(targetSpan.childNodes[1]); found = doQuery(".isSpan span.ending", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(targetSpan.childNodes[1]); }); it("should find elements by pseudo class", function(){ var found = doQuery(":last-child", elem), len = found.length; expect(len).toBe(3); expect(found[1]).toBe(targetSpan); expect(found[2]).toBe(targetSpan.childNodes[1]); found = doQuery(":first-child", elem); len = found.length; expect(len).toBe(3); expect(found[0]).toBe(elem.childNodes[0]); found = doQuery("#myspan :first-child", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(targetSpan.childNodes[0]); found = doQuery("span:last-child", elem); len = found.length; expect(len).toBe(2); expect(found[0]).toBe(targetSpan); found = doQuery("span :last-child", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(targetSpan.childNodes[1]); // :contains unsupported by some implementations of // querySelectorAll if (!useQuerySelectorAll) { found = doQuery('div:contains(abc)', elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[0]); } }); it("should find elements by attribute value", function(){ var found = doQuery('div[customAttr="12345678"]', elem), len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[5]); found = doQuery('div[customAttr]', elem), len = found.length; expect(len).toBe(3); expect(found[0]).toBe(elem.childNodes[5]); expect(found[1]).toBe(elem.childNodes[6]); expect(found[2]).toBe(elem.childNodes[7]); }); }); describe("CSS Escape Sequences", function(){ it("should handle escapes sequences for IDs", function(){ var found = doQuery("#\\00006en", elem), len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[3]); found = doQuery("#\\006e\\00036g", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[10].childNodes[2]); found = doQuery("#\\006e\\00036 e", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[10].childNodes[1]); found = doQuery("#\\6e \\6e ", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[3]); found = doQuery("#\\6e\\6e ", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[3]); // two spaces found = doQuery("#\\6e \\6e ", elem); len = found.length; expect(len).toBe(0); found = doQuery("#\\6e \\6e", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[3]); found = doQuery("#\\--abc ", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[5]); found = doQuery("#\\\\nn", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[6]); found = doQuery("#n\\\\nn", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[7]); found = doQuery("#a\\00003ab", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[0]); found = doQuery("#a\\:b", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[0]); found = doQuery("#a\\3a b", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[0]); found = doQuery("#c\\:last-child", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[1]); found = doQuery("#\\nn", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toEqual(elem.childNodes[3]); found = doQuery("div#a\\:b + div", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[1]); found = doQuery("div#abc\\3a + div", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[3]); // test another standard expression to make sure we can switch // back to non-escaped mode cleanly found = doQuery("#nn", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toEqual(elem.childNodes[3]); found = doQuery("div + div#\\--abc", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[5]); }); it("should handle escape sequences for class names", function(){ var found = doQuery("div.\\#odd-class-name", elem), len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[8]); found = doQuery(".\\#odd-class-name", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[8]); found = doQuery(".cls\\3a hover", elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[3]); }); it("should handle escape sequences for psuedos", function(){ var found = doQuery('#\\:id :first-child', elem), len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[10].childNodes[0]); // :contains unsupported by some implementations of // querySelectorAll if (!useQuerySelectorAll) { found = doQuery('div:contains(mno\\:pqr)', elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[4]); found = doQuery('div:contains(jkl\\\\\\tasdf)', elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[3]); } }); it("should handle escape sequences for attributes", function(){ var found, len; if (Ext.isFF3_6) { // ff 3.6 doesn allow \t in attribute values found = doQuery('div[customAttr="myval\\3a ue"]', elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[6]); found = doQuery('div[customAttr="myval:ue"]', elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[6]); found = doQuery('div[customAttr="myval\\:ue"]', elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[6]); } else { found = doQuery('div[customAttr="myval\\3a ue\t"]', elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[6]); found = doQuery('div[customAttr="myval:ue\t"]', elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[6]); found = doQuery('div[customAttr="myval\\:ue\t"]', elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[6]); } found = doQuery('div[customAttr="my\\\\tvalue"]', elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[7]); found = doQuery('div[specialAttr="jkl\\\\\\\\tasdf"]', elem); len = found.length; expect(len).toBe(1); expect(found[0]).toBe(elem.childNodes[2]); }); }); describe("XML", function() { describe("selecting elements with namespace prefixes", function() { var doc; beforeEach(function() { var xml = [ '<a>', '<x:b xmlns:x="xns">x1</x:b>', '<y:b xmlns:y="yns">y1</y:b>', '<x:b xmlns:x="xns">x2</x:b>', '<y:b xmlns:y="yns">y2</y:b>', '</a>' ].join(''); if (typeof DOMParser != 'undefined') { doc = (new DOMParser()).parseFromString(xml, "application/xml"); } else { // IE doesn't have DOMParser, but fortunately, there is an ActiveX for XML doc = new ActiveXObject("Microsoft.XMLDOM"); doc.async = false; doc.loadXML(xml); } }); it("should select elements with namespace prefixes using the '|' namespace selector", function() { var xResult = doQuery('x|b', doc), yResult = doQuery('y|b', doc); expect(xResult.length).toBe(2); expect(yResult.length).toBe(2); expect(xResult[0].firstChild.nodeValue).toBe('x1'); expect(xResult[1].firstChild.nodeValue).toBe('x2'); expect(yResult[0].firstChild.nodeValue).toBe('y1'); expect(yResult[1].firstChild.nodeValue).toBe('y2'); }); it("should select elements with namespace prefixes using the undocumented escaped colon method", function() { var xResult = doQuery('x\\:b', doc), yResult = doQuery('y\\:b', doc); expect(xResult.length).toBe(2); expect(yResult.length).toBe(2); expect(xResult[0].firstChild.nodeValue).toBe('x1'); expect(xResult[1].firstChild.nodeValue).toBe('x2'); expect(yResult[0].firstChild.nodeValue).toBe('y1'); expect(yResult[1].firstChild.nodeValue).toBe('y2'); }); }); describe("selecting attributes with non-word characters", function() { var doc; beforeEach(function() { var xml = [ '<a>', '<b att.name-part="x1">x1</b>', '</a>' ].join(''); if (typeof DOMParser != 'undefined') { doc = (new DOMParser()).parseFromString(xml, "application/xml"); } else { // IE doesn't have DOMParser, but fortunately, there is an ActiveX for XML doc = new ActiveXObject("Microsoft.XMLDOM"); doc.async = false; doc.loadXML(xml); } }); it("should select attributes non-word characters '.' and '-'", function() { var result = doQuery('b @att.name-part', doc); expect(result.length).toBe(1); expect(result[0].firstChild.nodeValue).toBe('x1'); }); }); }); }); });