+/*\r
+ * XMLWrapper_find 周りの オリジナルコードに関する情報\r
+ * Original code by pettanR team\r
+ * - http://sourceforge.jp/projects/pettanr/scm/git/clientJs/blobs/master/0.6.x/js/01_dom/18_XDomQuery.js\r
+ * and\r
+ * Original code by ofk ( kQuery, ksk )\r
+ * - http://d.hatena.ne.jp/ofk/comment/20090106/1231258010\r
+ * - http://d.hatena.ne.jp/ofk/20090111/1231668170\r
+ */\r
+\r
+X[ 'XML' ] = XMLWrapper;\r
+\r
+function XMLWrapper( xml ){\r
+ this._rawXML = xml;\r
+};\r
+\r
+XMLWrapper.prototype.length = 1;\r
+XMLWrapper.prototype.has = XMLWrapper_has;\r
+XMLWrapper.prototype.get = XMLWrapper_get;\r
+XMLWrapper.prototype.val = XMLWrapper_val;\r
+XMLWrapper.prototype.find = XMLWrapper_find;\r
+\r
+function XMLWrapper_has( queryString ){\r
+ return !!this.find( queryString ).length;\r
+};\r
+\r
+function XMLWrapper_get( index ){\r
+ if( this.length === 1 ) return this;\r
+ if( this.length === 0 ) return null;\r
+ // 一度発行した XMLWrapper は控えて置いて再発行する。\r
+ if( this._wraps && this._wraps[ index ] ) return this._wraps[ index ];\r
+ if( !this._wraps ) this._wraps = [];\r
+ return this[ index ] ?\r
+ ( this._wraps[ index ] = new XMLWrapper( this[ index ] ) ) :\r
+ null;\r
+};\r
+\r
+function XMLWrapper_val( queryString, type ){\r
+ var attr_textContent = X.UA.IE < 9 || X.UA.Opera ? 'innerText' : X.UA.IE9 ? 'text' : 'textContent',\r
+ wrapper, xml, v;\r
+ \r
+ switch( queryString ){\r
+ case 'number' :\r
+ case 'int' :\r
+ case 'boolean' :\r
+ case 'string' :\r
+ case undefined :\r
+ type = queryString;\r
+ queryString = undefined;\r
+ };\r
+ \r
+ wrapper = queryString ? this.find( queryString ) : this;\r
+ xml = wrapper.length === 1 ? wrapper._rawXML : wrapper[ 0 ];\r
+\r
+ if( !xml ){\r
+ switch( type ){\r
+ case 'number' :\r
+ case 'int' :\r
+ return NaN;\r
+ case 'boolean' :\r
+ return false;\r
+ case 'string' :\r
+ return '';\r
+ default :\r
+ return null;\r
+ };\r
+ };\r
+ \r
+ v = xml.nodeType === 1 ? xml.innerText || xml.text || xml.textContent : xml.nodeValue;\r
+ //xml.toStrign()\r
+ switch( type ){\r
+ case 'number' :\r
+ return parseFloat( v );\r
+ case 'int' :\r
+ return parseInt( v );\r
+ case 'boolean' :\r
+ return v && v !== '0' && v !== 'false' && v !== 'null' && v !== 'undefined' && v !== 'NaN';\r
+ //case 'string' :\r
+ //default : \r
+ };\r
+ return v || '';\r
+};\r
+\r
+ function XMLWrapper_find( queryString ){\r
+\r
+ var scope = this.constructor === XMLListWrapper ? this : [ this._rawXML ],\r
+ parents = scope, // 探索元の親要素 xmlList の場合あり\r
+ ARY_PUSH = Array.prototype.push,\r
+ ret = [], // 結果要素\r
+ isXML = true,\r
+ isMulti = 1 < scope.length,// 要素をマージする必要がある\r
+ isStart = true,\r
+ _ = ' ',\r
+ isAll, isNot, hasRoot,\r
+ l, i, n, parsed,\r
+ xmlList, // 一時保存用\r
+ merge, // 要素がコメントノードで汚染されている場合使う\r
+ combinator, selector, name, tagName,\r
+ uid, tmp, xml, filter, key, op, val, toLower, useName,\r
+ links, className, attr, flag;\r
+\r
+ // 文字列以外は空で返す\r
+ if( !X_Type_isString( queryString ) ) return XMLListWrapper_0;\r
+ \r
+ xmlList = [];\r
+ \r
+ // 以下、パースと探索\r
+ for( ; queryString.length; ){\r
+ //console.log( 'queryString[' + queryString + ']' );\r
+ \r
+ // 初期化処理\r
+ if( !parsed ){\r
+ parsed = X_Node_Selector__parse( queryString );\r
+ \r
+ if( X_Type_isNumber( parsed ) ){\r
+ // error\r
+ return XMLListWrapper_0;\r
+ };\r
+ \r
+ queryString = queryString.substr( parsed[ 0 ] );\r
+ parsed = parsed[ 1 ];\r
+ \r
+ if( parsed === 5 ){\r
+ isMulti = true;\r
+ parents = scope;\r
+ xmlList && xmlList.length && ARY_PUSH.apply( ret, xmlList );\r
+ parsed = null;\r
+ xmlList = [];\r
+ isStart = true;\r
+ continue;\r
+ };\r
+ };\r
+ \r
+ combinator = parsed[ 0 ];\r
+ selector = parsed[ 1 ];\r
+ name = parsed[ 2 ];\r
+ tagName = selector === 1 ? name : '*';\r
+ isAll = tagName === '*';\r
+ \r
+ if( !isStart ){\r
+ if( !xmlList.length ){\r
+ parsed = null;\r
+ continue; \r
+ } else\r
+ if( combinator !== 0 ){\r
+ parents = xmlList;\r
+ xmlList = [];\r
+ //console.log( 'cobinator !== 0 ' + parents.length + ' : ' + xmlList.length );\r
+ };\r
+ };\r
+ \r
+ i = 0;\r
+ l = parents.length;\r
+ n = -1; \r
+ isMulti = isMulti || 1 < l;\r
+ \r
+ console.log( 'combinator ' + combinator );\r
+ \r
+ switch( combinator ){\r
+ // > TagName|*\r
+ case 2 :\r
+ for( ; i < l; ++i ){\r
+ for( xml = parents[ i ].firstChild; xml; xml = xml.nextSibling ){\r
+ if( xml.nodeType === 1 && ( isAll || tagName === xml.tagName ) ) xmlList[ ++n ] = xml;\r
+ }; \r
+ };\r
+ break;\r
+ // + TagName|*\r
+ case 3 :\r
+ for( ; i < l; ++i ){\r
+ for( xml = parents[ i ].nextSibling; xml; xml = xml.nextSibling ){\r
+ if( xml.nodeType === 1 ){\r
+ if( isAll || tagName === xml.tagName ) xmlList[ ++n ] = xml;\r
+ break; \r
+ };\r
+ }; \r
+ };\r
+ break;\r
+ // ~ TagName|*\r
+ case 4 :\r
+ merge = [];\r
+ for( ; i < l; ++i ){\r
+ for( xml = parents[ i ].nextSibling; xml; xml = xml.nextSibling ){\r
+ if( xml.nodeType === 1 && ( isAll || tagName === xml.tagName ) ){\r
+ if( merge.indexOf( xml ) !== -1 ){\r
+ break;\r
+ } else {\r
+ merge[ merge.length ] = xml;\r
+ xmlList[ ++n ] = xml;\r
+ };\r
+ }; \r
+ }; \r
+ };\r
+ break;\r
+\r
+ // @ 属性ノード\r
+ case 6 :\r
+ selector = 0;\r
+ tagName = '*';\r
+ for( ; i < l; ++i ){\r
+ if( xml = parents[ i ].getAttributeNode( name ) ){\r
+ xmlList[ ++n ] = xml;\r
+ };\r
+ };\r
+ break;\r
+ default :\r
+ if( combinator === 1 || ( isStart && selector < 7 ) ){\r
+ console.log( l + ' > ' + xmlList.length + ' tag:' + tagName );\r
+ for( ; i < l; ++i ){\r
+ xml = parents[ i ];\r
+ xml.childNodes && xml.childNodes.length && XMLWrapper_fetchElements( xmlList, xml, isAll ? null : tagName );\r
+ };\r
+ console.log( l + ' >> ' + xmlList.length + ' tag:' + tagName );\r
+ };\r
+ };\r
+ \r
+ isStart = false;\r
+ \r
+ //alert( 'pre-selector:' + ( xmlList && xmlList.length ) )\r
+ \r
+ switch( selector ){\r
+ // #, ID\r
+ case 2 :\r
+ filter = [ 'id', 1, name ]; break;\r
+ // ., class\r
+ case 3 :\r
+ filter = [ 'class', 3 /*'~='*/, name ]; break;\r
+ // :, 擬似クラス\r
+ case 4 :\r
+ if( !( filter = XMLWrapper_filter[ name ] ) ){\r
+ return XMLListWrapper_0;;\r
+ };\r
+ break;\r
+ // [] 属性\r
+ case 5 :\r
+ filter = [ name, parsed[ 3 ], parsed[ 4 ] ]; break;\r
+ // :not\r
+ case 6 :\r
+ isNot = true;\r
+ parsed = parsed[ 2 ];\r
+ name = parsed[ 2 ];\r
+ switch( parsed[ 1 ] ) {\r
+ case 1 :\r
+ filter = [ 'tag', 1, name ]; break;\r
+ // #, ID\r
+ case 2 :\r
+ filter = [ 'id', 1, name ]; break;\r
+ // ., class\r
+ case 3 :\r
+ filter = [ 'class', 3, name ]; break;\r
+ // :, 擬似クラス\r
+ case 4 :\r
+ if( !( filter = X_Node_Selector__filter[ name ] ) ){\r
+ return [];\r
+ };\r
+ break;\r
+ // [] 属性\r
+ case 5 :\r
+ filter = [ name, parsed[ 3 ], parsed[ 4 ] ]; break;\r
+ };\r
+ break;\r
+ // scope\r
+ case 7 :\r
+ xmlList = scope; break;\r
+ /* root\r
+ case 8 :\r
+ hasRoot = true;\r
+ xmlList = [ HTML ]; break;\r
+ // link\r
+ case 9 :\r
+ if( links = document.links ){\r
+ for( xmlList = [], i = links.length; i; ){\r
+ xmlList[ --i ] = new Node( links[ i ] );\r
+ };\r
+ } else {\r
+ // area[href],a[href]\r
+ }; */\r
+ };\r
+ \r
+ if( filter && xmlList.length ){\r
+ // filter.mが関数の場合\r
+ if( filter.m ){\r
+ xmlList = filter.m(\r
+ {\r
+ not : isNot,\r
+ xml : isXML\r
+ },\r
+ xmlList,\r
+ parsed[ 3 ], parsed[ 4 ]\r
+ );\r
+ } else\r
+ // filterが関数の場合\r
+ if( X_Type_isFunction( filter ) ){\r
+ tmp = [];\r
+ for( i = 0, n = -1; xml = xmlList[ i ]; ++i ){\r
+ if( ( !!filter( xml ) ) ^ isNot ) tmp[ ++n ] = xml; \r
+ };\r
+ xmlList = tmp;\r
+ } else {\r
+ // 属性セレクター \r
+ tmp = [];\r
+ key = filter[ 0 ];\r
+ op = filter[ 1 ];\r
+ val = filter[ 2 ];\r
+\r
+ // 通常\r
+ if( op === 3 ) val = _ + val + _;\r
+\r
+ for( i = 0, n = -1, l = xmlList.length; i < l; ++i ){\r
+ xml = xmlList[ i ];\r
+ attr = elem.getAttribute( key, 2 );\r
+ flag = attr != null;// && ( !useName || attr !== '' );\r
+ if( flag && op ){\r
+ //if( toLower ) attr = attr.toLowerCase();\r
+ \r
+ switch( op ){\r
+ case 1: // =\r
+ flag = attr === val;\r
+ break;\r
+ case 2: // !=\r
+ flag = attr !== val;\r
+ break;\r
+ case 3: // ~=\r
+ flag = ( _ + attr + _ ).indexOf( val ) !== -1;\r
+ break;\r
+ case 4: // ^=\r
+ flag = attr.indexOf( val ) === 0;\r
+ break;\r
+ case 5: // $=\r
+ flag = attr.lastIndexOf( val ) + val.length === attr.length;\r
+ break;\r
+ case 6: // *=\r
+ flag = attr.indexOf( val ) !== -1;\r
+ break;\r
+ case 7: // |=\r
+ flag = attr === val || attr.substring( 0, val.length + 1 ) === val + '-';\r
+ break;\r
+ };\r
+ };\r
+ if( !!flag ^ isNot ) tmp[ ++n ] = xml;\r
+ //};\r
+ };\r
+ xmlList = tmp;\r
+ };\r
+ };\r
+ filter = null;\r
+ isNot = false;\r
+ parsed = null;\r
+ \r
+ //console.log( '//end :' + ( xmlList && xmlList.length ) );\r
+ };\r
+ //console.log( 'multi:' + ( xmlList && xmlList.length ) );\r
+ \r
+ // tree 順に並び替え、同一要素の排除\r
+ if( isMulti ){\r
+ xmlList && xmlList.length && ARY_PUSH.apply( ret, xmlList );\r
+ l = ret.length;\r
+ if( l === 0 ) return XMLListWrapper_0;\r
+ if( l === 1 ) return new XMLWrapper( ret[ 0 ] );\r
+ \r
+ xmlList = [];\r
+ //merge = [];\r
+ for( i = 0, n = -1; i < l; ++i ){\r
+ //alert( 'multi:' + i )\r
+ xml = ret[ i ];\r
+ if( xmlList.indexOf( xml ) === -1 ){\r
+ //merge[ merge.length ] = xml;\r
+ xmlList[ ++n ] = xml;\r
+ };\r
+ };\r
+ XMLWrapper_sortElementOrder( ret = [], xmlList, this._rawXML.childNodes );\r
+ \r
+ // @\r
+ for( i = 0, l = xmlList.length; i < l; ++i ){\r
+ if( ret.indexOf( xml = xmlList[ i ] ) === -1 ){\r
+ ret[ ret.length ] = xml;\r
+ };\r
+ };\r
+ \r
+ xmlList = ret;\r
+ };\r
+\r
+ return xmlList.length === 1 ? new XMLWrapper( xmlList[ 0 ] ) : new XMLListWrapper( xmlList );\r
+ };\r
+\r
+ function XMLWrapper_sortElementOrder( newList, list, xmlList ){\r
+ var l = xmlList.length,\r
+ i = 0,\r
+ j, child, _xmlList;\r
+ for( ; i < l; ++i ){\r
+ child = xmlList[ i ];\r
+ //if( child.nodeType !== 1 ) continue;\r
+ //console.log( child.tagName );\r
+ if( ( j = list.indexOf( child ) ) !== -1 ){\r
+ newList[ newList.length ] = child;\r
+ list.splice( j, 1 );\r
+ if( list.length === 1 ){\r
+ newList[ newList.length ] = list[ 0 ];\r
+ list.length = 0;\r
+ return true;\r
+ };\r
+ if( list.length === 0 ) return true;\r
+ };\r
+ if( ( _xmlList = child.childNodes ) && XMLWrapper_sortElementOrder( newList, list, _xmlList ) ){\r
+ return true;\r
+ };\r
+ };\r
+ };\r
+ \r
+ function XMLWrapper_fetchElements( list, parent, tag ){\r
+ var xmlList = parent.childNodes,\r
+ l = xmlList.length,\r
+ i = 0,\r
+ child;\r
+ for( ; i < l; ++i ){\r
+ child = xmlList[ i ];\r
+ if( child.nodeType === 1 ){\r
+ ( !tag || child.tagName === tag ) && ( list[ list.length ] = child );\r
+ //console.log( parent.tagName + ' > ' + child.tagName + ' == ' + tag+ ' l:' + list.length );\r
+ child.childNodes && child.childNodes.length && XMLWrapper_fetchElements( list, child, tag );\r
+ };\r
+ };\r
+ };\r
+\r
+ function XMLWrapper_funcSelectorChild( type, flag_all, flags, xmlList ){\r
+ var res = [],\r
+ flag_not = flags.not,\r
+ i = 0, n = -1, xnode, node,\r
+ tagName, tmp;\r
+ for( ; xnode = xmlList[ i ]; ++i ){\r
+ tagName = flag_all || xnode.tagName;\r
+ tmp = null;\r
+ if( /* tmp === null && */ type <= 0 ){\r
+ for( node = xnode.previousSibling; node; node = node.previousSibling ){\r
+ if( node.nodeType === 1 && ( flag_all || tagName === node.tagName ) ){\r
+ tmp = false;\r
+ break;\r
+ };\r
+ };\r
+ };\r
+ if( tmp === null && 0 <= type ){\r
+ for( node = xnode.nextSibling; node; node = node.nextSibling ){\r
+ if( node.nodeType === 1 && ( flag_all || tagName === node.tagName ) ){\r
+ tmp = false;\r
+ break;\r
+ }; \r
+ }; \r
+ };\r
+ if( tmp === null ) tmp = true;\r
+ if( tmp ^ flag_not ) res[ ++n ] = xnode;\r
+ };\r
+ return res;\r
+ };\r
+ function XMLWrapper_funcSelectorNth( pointer, sibling, flag_all, flags, xmlList, a, b ){\r
+ var res = [],\r
+ checked = {},\r
+ flag_not = flags.not,\r
+ i = 0, n = -1, uid,\r
+ c, xnode, tmp, node, tagName;\r
+ for( ; xnode = xmlList[ i ]; ++i ){\r
+ uid = xnode._uid;\r
+ tmp = checked[ uid ];\r
+ if( tmp === void 0 ){\r
+ for( c = 0, node = xnode.parentNode[ pointer ], tagName = flag_all || xnode.tagName; node; node = node[ sibling ] ){\r
+ if( node.nodeType === 1 && ( flag_all || tagName === node.tagName ) ){\r
+ ++c;\r
+ checked[ node._uid ] = a === 0 ? c === b : (c - b) % a === 0 && (c - b) / a >= 0;\r
+ }; \r
+ };\r
+ tmp = checked[ uid ];\r
+ };\r
+ if( tmp ^ flag_not ) res[ ++n ] = xnode;\r
+ };\r
+ return res;\r
+ };\r
+ function XMLWrapper_funcSelectorProp( prop, flag, flags, xmlList ){\r
+ var res = [],\r
+ flag_not = flag ? flags.not : !flags.not,\r
+ i = 0, n = -1, xnode;\r
+ for( ; xnode = xmlList[ i ]; ++i ){\r
+ if( xnode.getAttributeNode( prop ) ^ flag_not ) res[ ++n ] = xnode;\r
+ };\r
+ return res;\r
+ };\r
+\r
+var XMLWrapper_filter = {\r
+ 'first-child' : {\r
+ m : function( flags, xmlList ){ return XMLWrapper_funcSelectorChild( -1, true, flags, xmlList ); }\r
+ },\r
+ 'last-child' : {\r
+ m : function( flags, xmlList ){ return XMLWrapper_funcSelectorChild( 1, true, flags, xmlList ); }\r
+ },\r
+ 'only-child' : {\r
+ m : function( flags, xmlList ){ return XMLWrapper_funcSelectorChild( 0, true, flags, xmlList ); }\r
+ },\r
+ 'first-of-type' : {\r
+ m : function( flags, xmlList ){ return XMLWrapper_funcSelectorChild( -1, false, flags, xmlList ); }\r
+ },\r
+ 'last-of-type' : {\r
+ m : function( flags, xmlList ){ return XMLWrapper_funcSelectorChild( 1, false, flags, xmlList ); }\r
+ },\r
+ 'only-of-type' : {\r
+ m : function( flags, xmlList ){ return XMLWrapper_funcSelectorChild( 0, false, flags, xmlList ); }\r
+ },\r
+ 'nth-child' : {\r
+ m : function( flags, xmlList, a, b ){ return XMLWrapper_funcSelectorNth( 'firstChild', 'nextSibling', true, flags, xmlList, a, b ); }\r
+ },\r
+ 'nth-last-child' : {\r
+ m : function( flags, xmlList, a, b ){ return XMLWrapper_funcSelectorNth( 'lastChild', 'previousSibling', true, flags, xmlList, a, b ); }\r
+ },\r
+ 'nth-of-type' : {\r
+ m : function( flags, xmlList, a, b ){ return XMLWrapper_funcSelectorNth( 'firstChild', 'nextSibling', false, flags, xmlList, a, b ); }\r
+ },\r
+ 'nth-last-of-type' : {\r
+ m : function( flags, xmlList, a, b ){ return XMLWrapper_funcSelectorNth( 'lastChild', 'previousSibling', false, flags, xmlList, a, b ); }\r
+ },\r
+ empty : {\r
+ m : function( flags, xmlList ){\r
+ var res = [],\r
+ flag_not = flags.not,\r
+ i = 0, n = -1, xnode, tmp, node;\r
+ for( ; xnode = xmlList[i]; ++i ){\r
+ tmp = true;\r
+ for( node = xnode.firstChild; node; node = node.nextSibling ){\r
+ if( node.nodeType === 1 || ( node.nodeType === 3 && node._text ) ){\r
+ tmp = false;\r
+ break;\r
+ }; \r
+ };\r
+ if( tmp ^ flag_not ) res[ ++n ] = xnode;\r
+ };\r
+ return res;\r
+ }\r
+ },\r
+ contains : {\r
+ m : function( flags, xmlList, arg ){\r
+ var res = [],\r
+ flag_not = flags.not,\r
+ i = 0, n = -1, xnode, text = '',\r
+ // kquery\r
+ attr_textContent = X_UA[ 'IE' ] < 9 || X_UA[ 'Opera' ] ? 'innerText' : X_UA[ 'IE9' ] ? 'text' : 'textContent';\r
+ for( ; xnode = xmlList[ i ]; ++i ){\r
+ switch( xnode.nodeType ){\r
+ case 1 :\r
+ text = xml.nodeType === 1 ? xml.innerText || xml.text || xml.textContent : xml.nodeValue;// xnode[ attr_textContent ];\r
+ break;\r
+ case 2 :\r
+ case 3 :\r
+ text = xnode.nodeValue;\r
+ break;\r
+ };\r
+ console.log( text + ' ' + arg );\r
+ if ( ( -1 < text.indexOf( arg ) ) ^ flag_not ) res[ ++n ] = xnode; \r
+ };\r
+ return res;\r
+ }\r
+ }\r
+};\r
+\r
+function XMLListWrapper( xmlList ){\r
+ var i = 0, l = xmlList ? xmlList.length : 0;\r
+ for( ; i < l; ++i ){\r
+ this[ i ] = xmlList[ i ];\r
+ };\r
+ this.length = l;\r
+};\r
+\r
+var XMLListWrapper_0 = new XMLListWrapper();\r
+\r
+XMLListWrapper.prototype.length = 0;\r
+XMLListWrapper.prototype._wraps = null;\r
+XMLListWrapper.prototype.has = XMLWrapper_has;\r
+XMLListWrapper.prototype.get = XMLWrapper_get;\r
+XMLListWrapper.prototype.val = XMLWrapper_val;\r
+XMLListWrapper.prototype.find = XMLWrapper_find;\r