OSDN Git Service

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