OSDN Git Service

4f7ab2aff5f9f674893917b954ca16c741d366b2
[pettanr/clientJs.git] / 0.6.x / js / 05_util / 04_XXML.js
1 /*\r
2  * XMLWrapper_find 周りの オリジナルコードに関する情報\r
3  *  Original code by pettanR team\r
4  *  - http://sourceforge.jp/projects/pettanr/scm/git/clientJs/blobs/master/0.6.x/js/01_dom/18_XDomQuery.js\r
5  *  and\r
6  *  Original code by ofk ( kQuery, ksk )\r
7  *  - http://d.hatena.ne.jp/ofk/comment/20090106/1231258010\r
8  *  - http://d.hatena.ne.jp/ofk/20090111/1231668170\r
9  * \r
10  * TODO X.Class で作り、kill を強要する\r
11  */\r
12 \r
13 X[ 'XML' ] = XMLWrapper;\r
14 \r
15 /**\r
16  * XML 探索用のラッパークラスです\r
17  * @alias X.XML\r
18  * @class XML 探索用のラッパークラスです\r
19  * @constructor\r
20  * @param {xml}\r
21  */\r
22 function XMLWrapper( xml ){\r
23         this._rawXML = xml;\r
24 };\r
25 \r
26 XMLWrapper.prototype.length    = 1;\r
27 XMLWrapper.prototype[ 'has' ]  = XMLWrapper_has;\r
28 XMLWrapper.prototype[ 'get' ]  = XMLWrapper_get;\r
29 XMLWrapper.prototype[ 'val' ]  = XMLWrapper_val;\r
30 XMLWrapper.prototype[ 'find' ] = XMLWrapper_find;\r
31 \r
32 function XMLWrapper_has( queryString ){\r
33         return !!this.find( queryString ).length;\r
34 };\r
35 \r
36 function XMLWrapper_get( index ){\r
37         if( this.length === 1 ) return this;\r
38         if( this.length === 0 ) return null;\r
39         // 一度発行した XMLWrapper は控えて置いて再発行する。\r
40         if( this._wraps && this._wraps[ index ] ) return this._wraps[ index ];\r
41         if( !this._wraps ) this._wraps = [];\r
42         return this[ index ] ?\r
43                 ( this._wraps[ index ] = new XMLWrapper( this[ index ] ) ) :\r
44                 null;\r
45 };\r
46 \r
47 function XMLWrapper_val( queryString, type ){\r
48         var attr_textContent = X_UA[ 'IE' ] < 9 || X_UA[ 'Opera' ] ? 'innerText' : X_UA[ 'IE9' ] ? 'text' : 'textContent',\r
49                 wrapper, xml, v;\r
50         \r
51         switch( queryString ){\r
52                 case 'number' :\r
53                 case 'int' :\r
54                 case 'boolean' :\r
55                 case 'string' :\r
56                 case undefined :\r
57                         type = queryString;\r
58                         queryString = undefined;\r
59         };\r
60                 \r
61         wrapper = queryString ? this.find( queryString ) : this;\r
62         xml     = wrapper.length === 1 ? wrapper._rawXML : wrapper[ 0 ];\r
63 \r
64         if( !xml ){\r
65                 switch( type ){\r
66                         case 'number' :\r
67                         case 'int' :\r
68                                 return NaN;\r
69                         case 'boolean' :\r
70                                 return false;\r
71                         case 'string' :\r
72                                 return '';\r
73                         default :\r
74                                 return null;\r
75                 };\r
76         };\r
77         \r
78         v = xml.nodeType === 1 ? xml.innerText || xml.text || xml.textContent : xml.nodeValue;\r
79         //xml.toStrign()\r
80         switch( type ){\r
81                 case 'number' :\r
82                         return parseFloat( v );\r
83                 case 'int' :\r
84                         return parseInt( v );\r
85                 case 'boolean' :\r
86                         return v && v !== '0' && v !== 'false' && v !== 'null' && v !== 'undefined' && v !== 'NaN';\r
87                 //case 'string' :\r
88                 //default :     \r
89         };\r
90         return v || '';\r
91 };\r
92 \r
93         function XMLWrapper_find( queryString ){\r
94 \r
95                 var scope     = this.constructor === XMLListWrapper ? this : [ this._rawXML ],\r
96                         parents   = scope, // 探索元の親要素 xmlList の場合あり\r
97                         ARY_PUSH  = Array.prototype.push,\r
98                         ret       = [], // 結果要素\r
99                         isXML     = true,\r
100                         isMulti   = 1 < scope.length,// 要素をマージする必要がある\r
101                         isStart   = true,\r
102                         _         = ' ',\r
103                         isAll, isNot, hasRoot,\r
104                         l, i, n, parsed,\r
105                         xmlList, // 一時保存用\r
106                         merge, // 要素がコメントノードで汚染されている場合使う\r
107                         combinator, selector, name, tagName,\r
108                         uid, tmp, xml, filter, key, op, val, toLower, useName,\r
109             links, className, attr, flag;\r
110 \r
111                 // 文字列以外は空で返す\r
112                 if( !X_Type_isString( queryString ) ) return XMLListWrapper_0;\r
113                 \r
114                 xmlList = [];\r
115                 \r
116                 // 以下、パースと探索\r
117                 for( ; queryString.length; ){\r
118                         //console.log( 'queryString[' + queryString + ']' );\r
119                         \r
120                         // 初期化処理\r
121                         if( !parsed ){\r
122                                 parsed = X_Node_Selector__parse( queryString );\r
123                                 \r
124                                 if( X_Type_isNumber( parsed ) ){\r
125                                         // error\r
126                                         return XMLListWrapper_0;\r
127                                 };\r
128                                 \r
129                                 queryString = queryString.substr( parsed[ 0 ] );\r
130                                 parsed      = parsed[ 1 ];\r
131                                 \r
132                                 if( parsed === 5 ){\r
133                                         isMulti = true;\r
134                                         parents = scope;\r
135                                         xmlList && xmlList.length && ARY_PUSH.apply( ret, xmlList );\r
136                                         parsed  = null;\r
137                                         xmlList = [];\r
138                                         isStart = true;\r
139                                         continue;\r
140                                 };\r
141                         };\r
142                         \r
143                         combinator  = parsed[ 0 ];\r
144                         selector    = parsed[ 1 ];\r
145                         name        = parsed[ 2 ];\r
146                         tagName     = selector === 1 ? name : '*';\r
147                         isAll       = tagName === '*';\r
148         \r
149                         if( !isStart ){\r
150                                 if( !xmlList.length ){\r
151                                         parsed = null;\r
152                                         continue;                                       \r
153                                 } else\r
154                                 if( combinator !== 0 ){\r
155                                         parents = xmlList;\r
156                                         xmlList = [];\r
157                                         //console.log( 'cobinator !== 0 ' + parents.length + ' : ' + xmlList.length );\r
158                                 };\r
159                         };\r
160                         \r
161                         i = 0;\r
162                         l = parents.length;\r
163                         n = -1; \r
164                         isMulti = isMulti || 1 < l;\r
165                         \r
166                         console.log( 'combinator ' + combinator );\r
167         \r
168                         switch( combinator ){\r
169                                 // > TagName|*\r
170                                 case 2 :\r
171                                         for( ; i < l; ++i ){\r
172                                                 for( xml = parents[ i ].firstChild; xml; xml = xml.nextSibling ){\r
173                                                         if( xml.nodeType === 1 && ( isAll || tagName === xml.tagName ) ) xmlList[ ++n ] = xml;\r
174                                                 };                              \r
175                                         };\r
176                                         break;\r
177                                 // + TagName|*\r
178                                 case 3 :\r
179                                         for( ; i < l; ++i ){\r
180                                                 for( xml = parents[ i ].nextSibling; xml; xml = xml.nextSibling ){\r
181                                                         if( xml.nodeType === 1 ){\r
182                                                                 if( isAll || tagName === xml.tagName ) xmlList[ ++n ] = xml;\r
183                                                                 break;                                                          \r
184                                                         };\r
185                                                 };                                                              \r
186                                         };\r
187                                         break;\r
188                                 // ~ TagName|*\r
189                                 case 4 :\r
190                                         merge = [];\r
191                                         for( ; i < l; ++i ){\r
192                                                 for( xml = parents[ i ].nextSibling; xml; xml = xml.nextSibling ){\r
193                                                         if( xml.nodeType === 1 && ( isAll || tagName === xml.tagName ) ){\r
194                                                                 if( merge.indexOf( xml ) !== -1 ){\r
195                                                                         break;\r
196                                                                 } else {\r
197                                                                         merge[ merge.length ] = xml;\r
198                                                                         xmlList[ ++n ] = xml;\r
199                                                                 };\r
200                                                         };                                                                      \r
201                                                 };                                                              \r
202                                         };\r
203                                         break;\r
204 \r
205                                 // @ 属性ノード\r
206                                 case 6 :\r
207                                         selector = 0;\r
208                                         tagName  = '*';\r
209                                         for( ; i < l; ++i ){\r
210                                                 if( xml = parents[ i ].getAttributeNode( name ) ){\r
211                                                         xmlList[ ++n ] = xml;\r
212                                                 };\r
213                                         };\r
214                                         break;\r
215                                 default :\r
216                                         if( combinator === 1 || ( isStart && selector < 7 ) ){\r
217                                                 console.log( l + ' > ' + xmlList.length + ' tag:' + tagName );\r
218                                                 for( ; i < l; ++i ){\r
219                                                         xml = parents[ i ];\r
220                                                         xml.childNodes && xml.childNodes.length && XMLWrapper_fetchElements( xmlList, xml, isAll ? null : tagName );\r
221                                                 };\r
222                                                 console.log( l + ' >> ' + xmlList.length + ' tag:' + tagName );\r
223                                         };\r
224                         };\r
225                         \r
226                         isStart = false;\r
227                         \r
228                         //alert( 'pre-selector:' + ( xmlList && xmlList.length ) )\r
229                         \r
230                         switch( selector ){\r
231                                 // #, ID\r
232                                 case 2 :\r
233                                         filter = [ 'id', 1, name ]; break;\r
234                                 // ., class\r
235                                 case 3 :\r
236                                         filter = [ 'class', 3 /*'~='*/, name ]; break;\r
237                                 // :, 擬似クラス\r
238                                 case 4 :\r
239                                         if( !( filter = XMLWrapper_filter[ name ] ) ){\r
240                                                 return XMLListWrapper_0;;\r
241                                         };\r
242                                         break;\r
243                                 // [] 属性\r
244                                 case 5 :\r
245                                         filter = [ name, parsed[ 3 ], parsed[ 4 ] ]; break;\r
246                                 // :not\r
247                                 case 6 :\r
248                                         isNot  = true;\r
249                                         parsed = parsed[ 2 ];\r
250                                         name   = parsed[ 2 ];\r
251                                         switch( parsed[ 1 ] ) {\r
252                                                 case 1 :\r
253                                                         filter = [ 'tag', 1, name ]; break;\r
254                                                 // #, ID\r
255                                                 case 2 :\r
256                                                         filter = [ 'id', 1, name ]; break;\r
257                                                 // ., class\r
258                                                 case 3 :\r
259                                                         filter = [ 'class', 3, name ]; break;\r
260                                                 // :, 擬似クラス\r
261                                                 case 4 :\r
262                                                         if( !( filter = X_Node_Selector__filter[ name ] ) ){\r
263                                                                 return [];\r
264                                                         };\r
265                                                         break;\r
266                                                 // [] 属性\r
267                                                 case 5 :\r
268                                                         filter = [ name, parsed[ 3 ], parsed[ 4 ] ]; break;\r
269                                         };\r
270                                         break;\r
271                                 // scope\r
272                                 case 7 :\r
273                                         xmlList = scope; break;\r
274                                 /* root\r
275                                 case 8 :\r
276                                         hasRoot = true;\r
277                                         xmlList = [ HTML ]; break;\r
278                                 // link\r
279                                 case 9 :\r
280                                         if( links = document.links ){\r
281                                                 for( xmlList = [], i = links.length; i; ){\r
282                                                         xmlList[ --i ] = new Node( links[ i ] );\r
283                                                 };\r
284                                         } else {\r
285                                                 // area[href],a[href]\r
286                                         }; */\r
287                         };\r
288                         \r
289                         if( filter && xmlList.length ){\r
290                                 // filter.mが関数の場合\r
291                                 if( filter.m ){\r
292                                         xmlList = filter.m(\r
293                                                 {\r
294                                                         not : isNot,\r
295                                                         xml : isXML\r
296                                                 },\r
297                                                 xmlList,\r
298                                                 parsed[ 3 ], parsed[ 4 ]\r
299                                         );\r
300                                 } else\r
301                                 // filterが関数の場合\r
302                                 if( X_Type_isFunction( filter ) ){\r
303                                         tmp = [];\r
304                                         for( i = 0, n = -1; xml = xmlList[ i ]; ++i ){\r
305                                                 if( ( !!filter( xml ) ) ^ isNot ) tmp[ ++n ] = xml;     \r
306                                         };\r
307                                         xmlList = tmp;\r
308                                 } else {\r
309                                 // 属性セレクター                        \r
310                                         tmp = [];\r
311                                         key = filter[ 0 ];\r
312                                         op  = filter[ 1 ];\r
313                                         val = filter[ 2 ];\r
314 \r
315                                         // 通常\r
316                                                 if( op === 3 ) val = _ + val + _;\r
317 \r
318                                                 for( i = 0, n = -1, l = xmlList.length; i < l; ++i ){\r
319                                                         xml  = xmlList[ i ];\r
320                                                         attr = xml.getAttribute( key, 2 );\r
321                                                         flag = attr != null;// && ( !useName || attr !== '' );\r
322                                                         if( flag && op ){\r
323                                                                 //if( toLower ) attr = attr.toLowerCase();\r
324                                                                 \r
325                                                                 switch( op ){\r
326                                                                         case 1: // =\r
327                                                                                 flag = attr === val;\r
328                                                                                 break;\r
329                                                                         case 2: // !=\r
330                                                                                 flag = attr !== val;\r
331                                                                                 break;\r
332                                                                         case 3: // ~=\r
333                                                                                 flag = ( _ + attr + _ ).indexOf( val ) !== -1;\r
334                                                                                 break;\r
335                                                                         case 4: // ^=\r
336                                                                                 flag = attr.indexOf( val ) === 0;\r
337                                                                                 break;\r
338                                                                         case 5: // $=\r
339                                                                                 flag = attr.lastIndexOf( val ) + val.length === attr.length;\r
340                                                                                 break;\r
341                                                                         case 6: // *=\r
342                                                                                 flag = attr.indexOf( val ) !== -1;\r
343                                                                                 break;\r
344                                                                         case 7: // |=\r
345                                                                                 flag = attr === val || attr.substring( 0, val.length + 1 ) === val + '-';\r
346                                                                                 break;\r
347                                                                 };\r
348                                                         };\r
349                                                         if( !!flag ^ isNot ) tmp[ ++n ] = xml;\r
350                                                 //};\r
351                                         };\r
352                                         xmlList = tmp;\r
353                                 };\r
354                         };\r
355                         filter  = null;\r
356                         isNot   = false;\r
357                         parsed  = null;\r
358                         \r
359                         //console.log( '//end :' + ( xmlList && xmlList.length ) );\r
360                 };\r
361                 //console.log( 'multi:' + ( xmlList && xmlList.length ) );\r
362                 \r
363                 // tree 順に並び替え、同一要素の排除\r
364                 if( isMulti ){\r
365                         xmlList && xmlList.length && ARY_PUSH.apply( ret, xmlList );\r
366                         l = ret.length;\r
367                         if( l === 0 ) return XMLListWrapper_0;\r
368                         if( l === 1 ) return new XMLWrapper( ret[ 0 ] );\r
369                         \r
370                         xmlList = [];\r
371                         //merge   = [];\r
372                         for( i = 0, n = -1; i < l; ++i ){\r
373                                 //alert( 'multi:' + i )\r
374                                 xml = ret[ i ];\r
375                                 if( xmlList.indexOf( xml ) === -1 ){\r
376                                         //merge[ merge.length ] = xml;\r
377                                         xmlList[ ++n ] = xml;\r
378                                 };\r
379                         };\r
380                         XMLWrapper_sortElementOrder( ret = [], xmlList, this._rawXML.childNodes );\r
381                         \r
382                         // @\r
383                         for( i = 0, l = xmlList.length; i < l; ++i ){\r
384                                 if( ret.indexOf( xml = xmlList[ i ] ) === -1 ){\r
385                                         ret[ ret.length ] = xml;\r
386                                 };\r
387                         };\r
388                         \r
389                         xmlList = ret;\r
390                 };\r
391 \r
392                 return xmlList.length === 1 ? new XMLWrapper( xmlList[ 0 ] ) : new XMLListWrapper( xmlList );\r
393         };\r
394 \r
395         function XMLWrapper_sortElementOrder( newList, list, xmlList ){\r
396                 var l = xmlList.length,\r
397                         i = 0,\r
398                         j, child, _xmlList;\r
399                 for( ; i < l; ++i ){\r
400                         child = xmlList[ i ];\r
401                         //if( child.nodeType !== 1 ) continue;\r
402                         //console.log( child.tagName );\r
403                         if( ( j = list.indexOf( child ) ) !== -1 ){\r
404                                 newList[ newList.length ] = child;\r
405                                 list.splice( j, 1 );\r
406                                 if( list.length === 1 ){\r
407                                         newList[ newList.length ] = list[ 0 ];\r
408                                         list.length = 0;\r
409                                         return true;\r
410                                 };\r
411                                 if( list.length === 0 ) return true;\r
412                         };\r
413                         if( ( _xmlList = child.childNodes ) && XMLWrapper_sortElementOrder( newList, list, _xmlList ) ){\r
414                                 return true;\r
415                         };\r
416                 };\r
417         };\r
418         \r
419         function XMLWrapper_fetchElements( list, parent, tag ){\r
420                 var xmlList = parent.childNodes,\r
421                         l      = xmlList.length,\r
422                         i      = 0,\r
423                         child;\r
424                 for( ; i < l; ++i ){\r
425                         child = xmlList[ i ];\r
426                         if( child.nodeType === 1 ){\r
427                                 ( !tag || child.tagName === tag ) && ( list[ list.length ] = child );\r
428                                 //console.log( parent.tagName + ' > ' + child.tagName + ' == ' + tag+ ' l:' + list.length );\r
429                                 child.childNodes && child.childNodes.length && XMLWrapper_fetchElements( list, child, tag );\r
430                         };\r
431                 };\r
432         };\r
433 \r
434         function XMLWrapper_funcSelectorChild( type, flag_all, flags, xmlList ){\r
435                 var res      = [],\r
436                         flag_not = flags.not,\r
437                         i = 0, n = -1, xnode, node,\r
438                         tagName, tmp;\r
439                 for( ; xnode = xmlList[ i ]; ++i ){\r
440                         tagName = flag_all || xnode.tagName;\r
441                         tmp     = null;\r
442                         if( /* tmp === null && */ type <= 0 ){\r
443                                 for( node = xnode.previousSibling; node; node = node.previousSibling ){\r
444                                         if( node.nodeType === 1 && ( flag_all || tagName === node.tagName ) ){\r
445                                                 tmp = false;\r
446                                                 break;\r
447                                         };\r
448                                 };\r
449                         };\r
450                         if( tmp === null && 0 <= type ){\r
451                                 for( node = xnode.nextSibling; node; node = node.nextSibling ){\r
452                                         if( node.nodeType === 1 && ( flag_all || tagName === node.tagName ) ){\r
453                                                 tmp = false;\r
454                                                 break;\r
455                                         };              \r
456                                 };                                              \r
457                         };\r
458                         if( tmp === null ) tmp = true;\r
459                         if( tmp ^ flag_not ) res[ ++n ] = xnode;\r
460                 };\r
461                 return res;\r
462         };\r
463         function XMLWrapper_funcSelectorNth( pointer, sibling, flag_all, flags, xmlList, a, b ){\r
464                 var res      = [],\r
465                         checked  = {},\r
466                         flag_not = flags.not,\r
467                         i = 0, n = -1, uid,\r
468                         c, xnode, tmp, node, tagName;\r
469                 for( ; xnode = xmlList[ i ]; ++i ){\r
470                         uid = xnode._uid;\r
471                         tmp = checked[ uid ];\r
472                         if( tmp === void 0 ){\r
473                                 for( c = 0, node = xnode.parentNode[ pointer ], tagName = flag_all || xnode.tagName; node; node = node[ sibling ] ){\r
474                                         if( node.nodeType === 1 && ( flag_all || tagName === node.tagName ) ){\r
475                                                 ++c;\r
476                                                 checked[ node._uid ] = a === 0 ? c === b : (c - b) % a === 0 && (c - b) / a >= 0;\r
477                                         };                                                      \r
478                                 };\r
479                                 tmp = checked[ uid ];\r
480                         };\r
481                         if( tmp ^ flag_not ) res[ ++n ] = xnode;\r
482                 };\r
483                 return res;\r
484         };\r
485         /*\r
486         function XMLWrapper_funcSelectorProp( prop, flag, flags, xmlList ){\r
487                 var res = [],\r
488                         flag_not = flag ? flags.not : !flags.not,\r
489                         i = 0, n = -1, xnode;\r
490                 for( ; xnode = xmlList[ i ]; ++i ){\r
491                         if( xnode.getAttributeNode( prop ) ^ flag_not ) res[ ++n ] = xnode;\r
492                 };\r
493                 return res;\r
494         }; */\r
495 \r
496 var XMLWrapper_filter = {\r
497         'first-child' : {\r
498                 m : function( flags, xmlList ){ return XMLWrapper_funcSelectorChild( -1, true, flags, xmlList ); }\r
499         },\r
500         'last-child' : {\r
501                 m : function( flags, xmlList ){ return XMLWrapper_funcSelectorChild( 1, true, flags, xmlList ); }\r
502         },\r
503         'only-child' : {\r
504                 m : function( flags, xmlList ){ return XMLWrapper_funcSelectorChild( 0, true, flags, xmlList ); }\r
505         },\r
506         'first-of-type' : {\r
507                 m : function( flags, xmlList ){ return XMLWrapper_funcSelectorChild( -1, false, flags, xmlList ); }\r
508         },\r
509         'last-of-type' : {\r
510                 m : function( flags, xmlList ){ return XMLWrapper_funcSelectorChild( 1, false, flags, xmlList ); }\r
511         },\r
512         'only-of-type' : {\r
513                 m : function( flags, xmlList ){ return XMLWrapper_funcSelectorChild( 0, false, flags, xmlList ); }\r
514         },\r
515         'nth-child' : {\r
516                 m : function( flags, xmlList, a, b ){ return XMLWrapper_funcSelectorNth( 'firstChild', 'nextSibling', true, flags, xmlList, a, b ); }\r
517         },\r
518         'nth-last-child' : {\r
519                 m : function( flags, xmlList, a, b ){ return XMLWrapper_funcSelectorNth( 'lastChild', 'previousSibling', true, flags, xmlList, a, b ); }\r
520         },\r
521         'nth-of-type' : {\r
522                 m : function( flags, xmlList, a, b ){ return XMLWrapper_funcSelectorNth( 'firstChild', 'nextSibling', false, flags, xmlList, a, b ); }\r
523         },\r
524         'nth-last-of-type' : {\r
525                 m : function( flags, xmlList, a, b ){ return XMLWrapper_funcSelectorNth( 'lastChild', 'previousSibling', false, flags, xmlList, a, b ); }\r
526         },\r
527         'empty' : {\r
528                 m : function( flags, xmlList ){\r
529                         var res = [],\r
530                                 flag_not = flags.not,\r
531                                 i = 0, n = -1, xnode, tmp, node;\r
532                         for( ; xnode = xmlList[i]; ++i ){\r
533                                 tmp = true;\r
534                                 for( node = xnode.firstChild; node; node = node.nextSibling ){\r
535                                         if( node.nodeType === 1 || ( node.nodeType === 3 && node._text ) ){\r
536                                                 tmp = false;\r
537                                                 break;\r
538                                         };                              \r
539                                 };\r
540                                 if( tmp ^ flag_not ) res[ ++n ] = xnode;\r
541                         };\r
542                         return res;\r
543                 }\r
544         },\r
545         'contains' : {\r
546                 m : function( flags, xmlList, arg ){\r
547                         var res = [],\r
548                                 flag_not = flags.not,\r
549                                 i = 0, n = -1, xnode, text = '';\r
550 \r
551                         for( ; xnode = xmlList[ i ]; ++i ){\r
552                                 switch( xnode.nodeType ){\r
553                                         case 1 :\r
554                                                 text = xml.nodeType === 1 ? xml.innerText || xml.text || xml.textContent : xml.nodeValue;\r
555                                                 break;\r
556                                         //case 2 :\r
557                                         case 3 :\r
558                                                 text = xnode.nodeValue;\r
559                                                 break;\r
560                                 };\r
561                                 console.log( text + ' ' + arg );\r
562                                 if ( ( -1 < text.indexOf( arg ) ) ^ flag_not ) res[ ++n ] = xnode;                                              \r
563                         };\r
564                         return res;\r
565                 }\r
566         }\r
567 };\r
568 \r
569 function XMLListWrapper( xmlList ){\r
570         var i = 0, l = xmlList ? xmlList.length : 0;\r
571         for( ; i < l; ++i ){\r
572                 this[ i ] = xmlList[ i ];\r
573         };\r
574         this.length = l;\r
575 };\r
576 \r
577 var XMLListWrapper_0 = new XMLListWrapper();\r
578 \r
579 XMLListWrapper.prototype.length    = 0;\r
580 XMLListWrapper.prototype._wraps    = null;\r
581 XMLListWrapper.prototype[ 'has' ]  = XMLWrapper_has;\r
582 XMLListWrapper.prototype[ 'get' ]  = XMLWrapper_get;\r
583 XMLListWrapper.prototype[ 'val' ]  = XMLWrapper_val;\r
584 XMLListWrapper.prototype[ 'find' ] = XMLWrapper_find;\r