Changeset 7883
- Timestamp:
- 03/31/07 18:52:28 (22 months ago)
- Location:
- dojo/trunk
- Files:
-
- 2 modified
-
tests/_base/query.html (modified) (2 diffs)
-
_base/query.js (modified) (18 diffs)
Legend:
- Unmodified
- Added
- Removed
-
dojo/trunk/tests/_base/query.html
r7845 r7883 5 5 <script type="text/javascript"> 6 6 dojo.require("tests.runner"); 7 // dojo.require("dojo.query");8 7 dojo.addOnLoad(function(){ 9 /*10 tests.register("thinger", function blah(t){11 t.assertTrue(true);12 });13 tests.register("thinger", function blah2(t){14 t.assertTrue(false);15 });16 */17 8 tests.register("t", 18 9 [ 10 "tests.assertEqual(4, (dojo.query('h3')).length);", 19 11 "tests.assertEqual(4, (dojo.query('#t h3')).length);", 20 "tests.assertEqual(3, (dojo.query('#t > h3')).length);" 12 "tests.assertEqual(1, (dojo.query('#t div > h3')).length);", 13 "tests.assertEqual(3, (dojo.query('#t > h3')).length);", 14 "tests.assertEqual(2, (dojo.query('.foo, .bar')).length);", 15 "tests.assertEqual(2, (dojo.query('.foo')).length);", 16 "tests.assertEqual(2, (dojo.query('.baz')).length);", 17 "tests.assertEqual(1, (dojo.query('span.baz')).length);", 18 // FIXME: need to support [foo="foo bar"]. We're incorrectly tokenizing! 19 "tests.assertEqual(2, (dojo.query('[foo~=\"bar\"]')).length);", 20 "tests.assertEqual(3, (dojo.query('[foo]')).length);", 21 "tests.assertEqual(1, (dojo.query('[foo$=\"thud\"]')).length);", 22 "tests.assertEqual(1, (dojo.query('[foo|=\"bar\"]')).length);", 23 "tests.assertEqual(1, (dojo.query('[foo|=\"bar-baz\"]')).length);", 24 "tests.assertEqual(0, (dojo.query('[foo|=\"baz\"]')).length);", 25 "tests.assertEqual(dojo.byId('_foo'), dojo.query('.foo:nth-child(2)')[0]);" 21 26 ] 22 27 ); … … 28 33 <h1>testing dojo.query()</h1> 29 34 <div id="t"> 30 <h3> 31 <h4>h4</h4> 35 <h3>h3 <span>span</span> endh3 </h3> 36 <!-- comment to throw things off --> 37 <div class="foo bar" id="_foo"> 32 38 <h3>h3</h3> 33 </h3> 39 <span id="foo"></span> 40 <span></span> 41 </div> 34 42 <h3>h3</h3> 35 <h3>h3</h3> 43 <h3 class="baz">h3</h3> 44 <span class="foobar baz foo"></span> 45 <span foo="bar"></span> 46 <span foo="baz bar thud"></span> 47 <!-- FIXME: should foo="bar-baz-thud" match? [foo$=thud] ??? --> 48 <span foo="bar-baz-thudish"></span> 36 49 </div> 37 50 </body> -
dojo/trunk/_base/query.js
r7698 r7883 54 54 }, 55 55 { 56 key: "~=", 57 match: function(attr, value){ 58 return "[contains(concat(' ',@"+attr+",' '), ' "+ value +" ')]"; 59 } 60 }, 61 { 56 62 key: "^=", 57 63 match: function(attr, value){ … … 85 91 } 86 92 ]; 93 94 var strip = function(val){ 95 var re = /^\s+|\s+$/g; 96 return val.replace(re, ""); // string 97 } 87 98 88 99 var handleAttrs = function( attrList, … … 112 123 value = value.substring(1, value.length-1); 113 124 } 114 matcher = ta.match( attr, value);125 matcher = ta.match(strip(attr), strip(value)); 115 126 break; 116 127 } … … 138 149 var buildPath = function(query){ 139 150 var xpath = ""; 140 var qparts = query.split(" "); 151 var qparts = query.split(" "); // FIXME: this break on span[thinger = foo] 141 152 while(qparts.length){ 142 153 var tqp = qparts.shift(); 143 154 var prefix; 155 // FIXME: need to add support for ~ and + 144 156 if(tqp == ">"){ 145 157 prefix = "/"; 158 // prefix = "/child::node()"; 146 159 tqp = qparts.shift(); 147 160 }else{ 148 161 prefix = "//"; 149 } 162 // prefix = "/descendant::node()" 163 } 164 150 165 // get the tag name (if any) 151 166 var tagName = getTagName(tqp); … … 156 171 var id = getId(tqp); 157 172 if(id.length){ 158 xpath += "[@id='"+id+"'] ";173 xpath += "[@id='"+id+"'][1]"; 159 174 } 160 175 … … 182 197 // FIXME: need to implement pseudo-class checks!! 183 198 }; 184 // dojo.debug(xpath);185 199 return xpath; 186 200 }; … … 196 210 // FIXME: don't need to memoize. The closure scope handles it for us. 197 211 var xpath = buildPath(path); 212 // console.debug(xpath); 198 213 199 214 var tf = function(){ 200 215 // XPath query strings are memoized. 201 216 var ret = []; 202 var xpathResult = doc.evaluate(xpath, parent, null, 203 // XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null); 204 XPathResult.ANY_TYPE, null); 217 try{ 218 var xpathResult = doc.evaluate(xpath, parent, null, 219 // XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null); 220 XPathResult.ANY_TYPE, null); 221 }catch(e){ 222 console.debug("failure in exprssion:", xpath, "under:", parent); 223 console.debug(e); 224 } 205 225 var result = xpathResult.iterateNext(); 206 226 while(result){ … … 628 648 var ncount = pi(condition); 629 649 return function(elem){ 630 // removeChaffNodes(elem.parentNode); 631 return (elem.parentNode.childNodes[ncount-1] === elem); 650 return (getNodeIndex(elem) == ncount); 632 651 } 633 652 } … … 661 680 } 662 681 682 var matcher; 683 663 684 // if there's a class in our query, generate a match function for it 664 685 var className = getClassName(query); … … 674 695 return re.test(elem.className); 675 696 }); 676 677 } 678 // [ "#", ".", "[", ":" ]; 679 var defaultGetter = (d.isIE) ? 680 function(cond){ 681 return function(elem){ 682 return elem[cond]; 683 } 684 } : function(cond){ 685 return function(elem){ 686 return elem.hasAttribute(cond); 687 } 688 }; 689 handleAttrs(attrs, query, defaultGetter, 690 function(tmatcher){ 691 ff = agree(ff, tmatcher); 692 } 693 ); 694 695 var matcher; 697 } 698 696 699 if(i[3]>= 0){ 697 700 // NOTE: we count on the pseudo name being at the end 701 // FIXME: this is clearly a bug!!! 698 702 var pseudoName = query.substr(i[3]+1); 699 703 var condition = ""; … … 723 727 } 724 728 } 729 730 // [ "#", ".", "[", ":" ]; 731 var defaultGetter = (d.isIE) ? 732 function(cond){ 733 return function(elem){ 734 return elem[cond]; 735 } 736 } : function(cond){ 737 return function(elem){ 738 return elem.hasAttribute(cond); 739 } 740 }; 741 handleAttrs(attrs, query, defaultGetter, 742 function(tmatcher){ 743 ff = agree(ff, tmatcher); 744 } 745 ); 725 746 if(!ff){ 726 747 ff = function(){ return true; }; … … 768 789 var tn = getTagName(query); 769 790 770 /*771 if(-1 != i[3]){772 var pseudoName = (0 <= i[3]) ? query.substr(i[3]+1) : "";773 switch(pseudoName){774 case "first":775 retFunc = function(root){776 // for(var x=0, te; te = tret[x]; x++){777 var te, x=0, tret = root.getElementsByTagName(tn);778 while(te=tret[x++]){779 if(filterFunc(te)){780 return [ te ];781 }782 }783 return [];784 }785 break;786 case "last":787 retFunc = function(root){788 var tret = root.getElementsByTagName(tn);789 var te, x=tret.length-1;790 while(te=tret[x--]){791 if(filterFunc(te)){792 return [ te ];793 }794 }795 return [];796 }797 break;798 default:799 retFunc = function(root){800 var ret = [];801 var te, x=0, tret = root.getElementsByTagName(tn);802 while(te=tret[x++]){803 if(filterFunc(te)){804 ret[ret.length] = te;805 // ret.push(te);806 }807 }808 return ret;809 }810 break;811 }812 }else813 */814 791 if(isTagOnly(query)){ 815 792 // it's just a plain-ol elements-by-tag-name query from the root … … 851 828 852 829 var sqf = function(root){ 853 var qparts = query.split(" "); 854 830 var qparts = query.split(" "); // FIXME: this is an inaccurate tokenizer! 831 832 /* 855 833 // FIXME: need to make root popping more explicit and cache it somehow 856 834 … … 868 846 partIndex++; 869 847 } 848 // console.debug(qparts[partIndex], root); 870 849 if(qparts.length == partIndex){ 871 850 return [ root ]; … … 884 863 // foo.bar span[blah="thonk"] div div span code.example 885 864 // in short, we need to move the look-ahead logic into _filterDown() 865 // console.debug(qparts[partIndex]); 886 866 if( isTagOnly(qparts[partIndex]) && 887 867 (qparts[partIndex+1] != ">") … … 914 894 } 915 895 }else{ 896 // console.debug(qparts); 916 897 candidates = getElementsFunc(qparts.shift())(root); 917 898 } 899 */ 900 var candidates = getElementsFunc(qparts.shift())(root); 918 901 return filterDown(candidates, qparts); 919 902 } … … 960 943 return getXPathFunc(query); 961 944 } 962 // return getXPathFunc(query);963 } 964 945 } 946 947 // fallthrough 965 948 return getStepQueryFunc(query); 966 949 } : getStepQueryFunc 967 950 ); 968 // FIXME:disable XPath for testing and tuning the DOM path951 // uncomment to disable XPath for testing and tuning the DOM path 969 952 // _getQueryFunc = getStepQueryFunc; 953 // uncomment to disable DOM queries for testing and tuning XPath 954 // _getQueryFunc = getXPathFunc; 970 955 971 956 var getQueryFunc = function(query){ … … 1008 993 */ 1009 994 995 // FIXME: 996 // Dean's new Base2 uses a system whereby queries themselves note if 997 // they'll need duplicate filtering. We need to get on that plan!! 998 1010 999 var _zipIdx = 0; 1011 1000 var _zip = function(arr){ 1012 1001 var ret = new d.NodeList(); 1013 1002 if(!arr){ return ret; } 1014 ret.push(arr[0]); 1003 if(arr[0]){ 1004 ret.push(arr[0]); 1005 } 1015 1006 if(arr.length < 2){ return ret; } 1016 1007 _zipIdx++;