OSDN Git Service

Version 0.6.208, bug fixes.
[pettanr/clientJs.git] / 0.6.x / js / 05_util / 04_XXML.js
index 6ef1908..39859ce 100644 (file)
@@ -1,36 +1,77 @@
 /*\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
+ *  - https://osdn.jp/projects/pettanr/scm/git/clientJs/blobs/master/0.6.x/js/02_dom/08_XNodeSelector.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
+ * TODO X.Class で作り、kill を強要する\r
  */\r
-\r
 X[ 'XML' ] = XMLWrapper;\r
 \r
 /**\r
- * XML 探索用のラッパークラスです\r
+ * XML ツリーを探索して読み出す用のラッパークラスです.XML を操作する機能はありません、あしからず…\r
  * @alias X.XML\r
  * @class XML 探索用のラッパークラスです\r
  * @constructor\r
- * @param {xml}\r
+ * @param {XMLElement}\r
  */\r
 function XMLWrapper( xml ){\r
-       this._rawXML = xml;\r
+       if( xml ){\r
+               this._rawXML = xml;\r
+               this.tagName = xml.tagName;\r
+       };\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
+ * tagName または nodeName\r
+ * @alias X.XML.prototype.tagName\r
+ * @type {string}\r
+ */\r
+XMLWrapper.prototype.tagName     = '';\r
+/**\r
+ * ラップした xml の数 常に1または0, XMLList の場合2以上\r
+ * @alias X.XML.prototype.length\r
+ * @type {Number}\r
+ */\r
+XMLWrapper.prototype.length      = 1;\r
+XMLWrapper.prototype[ 'parent' ] = XMLWrapper_parent;\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
+/**\r
+ * 親要素を返す、ルート要素の場合 null を返す\r
+ * @alias X.XML.prototype.parent\r
+ * @return {X.XML} 親要素\r
+ */\r
+function XMLWrapper_parent(){\r
+       if( this.length === 1 ) return this._rawXML && this._rawXML.parentNode ? new XMLWrapper( this._rawXML.parentNode ) : null;\r
+       if( this.length === 0 ) return null;\r
+       \r
+       return this[ 0 ].parentNode ? ( new XMLWrapper( this[ 0 ].parentNode ) ) : null;\r
+};\r
 \r
+/**\r
+ * セレクターにヒットした要素数を返す\r
+ * @alias X.XML.prototype.has\r
+ * @param {string} queryString XML セレクター文字列\r
+ * @return {number}\r
+ */\r
 function XMLWrapper_has( queryString ){\r
        return !!this.find( queryString ).length;\r
 };\r
 \r
+/**\r
+ * <p>X.XML では常に自信を返す\r
+ * <p>X.XMLList ではラップした xml 群から index のものを返す\r
+ * @alias X.XML.prototype.get\r
+ * @param {number} index\r
+ * @return {X.XML} X.XML では自身、X.XMLList では index の X.XML\r
+ */\r
 function XMLWrapper_get( index ){\r
        if( this.length === 1 ) return this;\r
        if( this.length === 0 ) return null;\r
@@ -42,8 +83,15 @@ function XMLWrapper_get( index ){
                null;\r
 };\r
 \r
+/**\r
+ * セレクターにヒットした要素の内容を指定されたデータ型で返す。複数要素にヒットした場合、0番目の要素の内容を使用する。\r
+ * @alias X.XML.prototype.val\r
+ * @param {string} queryString XML セレクター文字列\r
+ * @param {string} type 'number','int','boolean','string'\r
+ * @return {boolean|number|string} 内容を型変換した値\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
+       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
@@ -53,7 +101,7 @@ function XMLWrapper_val( queryString, type ){
                case 'string' :\r
                case undefined :\r
                        type = queryString;\r
-                       queryString = undefined;\r
+                       queryString = 0;\r
        };\r
                \r
        wrapper = queryString ? this.find( queryString ) : this;\r
@@ -79,15 +127,21 @@ function XMLWrapper_val( queryString, type ){
                case 'number' :\r
                        return parseFloat( v );\r
                case 'int' :\r
-                       return parseInt( v );\r
+                       return parseFloat( v ) | 0;\r
                case 'boolean' :\r
-                       return v && v !== '0' && v !== 'false' && v !== 'null' && v !== 'undefined' && v !== 'NaN';\r
+                       return !!X_String_parse( v );\r
                //case 'string' :\r
                //default :     \r
        };\r
        return v || '';\r
 };\r
 \r
+/**\r
+ * セレクターにヒットした要素を返す。0~1個の要素がヒットした場合は X.XML を、それ以上の場合は X.XMLList を返す。\r
+ * @alias X.XML.prototype.find\r
+ * @param {string} queryString セレクター文字列\r
+ * @return {X.XML|X.XMLList} \r
+ */\r
        function XMLWrapper_find( queryString ){\r
 \r
                var scope     = this.constructor === XMLListWrapper ? this : [ this._rawXML ],\r
@@ -161,7 +215,7 @@ function XMLWrapper_val( queryString, type ){
                        n = -1; \r
                        isMulti = isMulti || 1 < l;\r
                        \r
-                       console.log( 'combinator ' + combinator );\r
+                       //console.log( 'combinator ' + combinator );\r
        \r
                        switch( combinator ){\r
                                // > TagName|*\r
@@ -212,12 +266,12 @@ function XMLWrapper_val( queryString, type ){
                                        break;\r
                                default :\r
                                        if( combinator === 1 || ( isStart && selector < 7 ) ){\r
-                                               console.log( l + ' > ' + xmlList.length + ' tag:' + tagName );\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
+                                               //console.log( l + ' >> ' + xmlList.length + ' tag:' + tagName );\r
                                        };\r
                        };\r
                        \r
@@ -235,7 +289,7 @@ function XMLWrapper_val( queryString, type ){
                                // :, 擬似クラス\r
                                case 4 :\r
                                        if( !( filter = XMLWrapper_filter[ name ] ) ){\r
-                                               return XMLListWrapper_0;;\r
+                                               return XMLListWrapper_0;\r
                                        };\r
                                        break;\r
                                // [] 属性\r
@@ -257,7 +311,7 @@ function XMLWrapper_val( queryString, type ){
                                                        filter = [ 'class', 3, name ]; break;\r
                                                // :, 擬似クラス\r
                                                case 4 :\r
-                                                       if( !( filter = X_Node_Selector__filter[ name ] ) ){\r
+                                                       if( !( filter = XMLWrapper_filter[ name ] ) ){\r
                                                                return [];\r
                                                        };\r
                                                        break;\r
@@ -315,7 +369,7 @@ function XMLWrapper_val( queryString, type ){
 \r
                                                for( i = 0, n = -1, l = xmlList.length; i < l; ++i ){\r
                                                        xml  = xmlList[ i ];\r
-                                                       attr = elem.getAttribute( key, 2 );\r
+                                                       attr = xml.getAttribute( key, 2 );\r
                                                        flag = attr != null;// && ( !useName || attr !== '' );\r
                                                        if( flag && op ){\r
                                                                //if( toLower ) attr = attr.toLowerCase();\r
@@ -432,13 +486,13 @@ function XMLWrapper_val( queryString, type ){
        function XMLWrapper_funcSelectorChild( type, flag_all, flags, xmlList ){\r
                var res      = [],\r
                        flag_not = flags.not,\r
-                       i = 0, n = -1, xnode, node,\r
+                       i = 0, n = -1, xml, node,\r
                        tagName, tmp;\r
-               for( ; xnode = xmlList[ i ]; ++i ){\r
-                       tagName = flag_all || xnode.tagName;\r
+               for( ; xml = xmlList[ i ]; ++i ){\r
+                       tagName = flag_all || xml.tagName;\r
                        tmp     = null;\r
                        if( /* tmp === null && */ type <= 0 ){\r
-                               for( node = xnode.previousSibling; node; node = node.previousSibling ){\r
+                               for( node = xml.previousSibling; node; node = node.previousSibling ){\r
                                        if( node.nodeType === 1 && ( flag_all || tagName === node.tagName ) ){\r
                                                tmp = false;\r
                                                break;\r
@@ -446,7 +500,7 @@ function XMLWrapper_val( queryString, type ){
                                };\r
                        };\r
                        if( tmp === null && 0 <= type ){\r
-                               for( node = xnode.nextSibling; node; node = node.nextSibling ){\r
+                               for( node = xml.nextSibling; node; node = node.nextSibling ){\r
                                        if( node.nodeType === 1 && ( flag_all || tagName === node.tagName ) ){\r
                                                tmp = false;\r
                                                break;\r
@@ -454,41 +508,45 @@ function XMLWrapper_val( queryString, type ){
                                };                                              \r
                        };\r
                        if( tmp === null ) tmp = true;\r
-                       if( tmp ^ flag_not ) res[ ++n ] = xnode;\r
+                       if( tmp ^ flag_not ) res[ ++n ] = xml;\r
                };\r
                return res;\r
        };\r
        function XMLWrapper_funcSelectorNth( pointer, sibling, flag_all, flags, xmlList, a, b ){\r
-               var res      = [],\r
+               var uids     = X_Array_copy( xmlList ),\r
+                       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
+                       i = 0, n = -1,\r
+                       c, xml, tmp, node, tagName, uid;\r
+\r
+               for( ; xml = xmlList[ i ]; ++i ){\r
+                       tmp = checked[ i ];\r
+                       if( tmp === undefined ){\r
+                               for( c = 0, node = xml.parentNode[ pointer ], tagName = flag_all || xml.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
+                                               uid = uids.indexOf( node );\r
+                                               if( uid === -1 ) uids[ uid = uids.length ] = node;\r
+                                               checked[ uid ] = a === 0 ? c === b : (c - b) % a === 0 && (c - b) / a >= 0;\r
+                                       };\r
                                };\r
-                               tmp = checked[ uid ];\r
+                               tmp = checked[ i ];\r
                        };\r
-                       if( tmp ^ flag_not ) res[ ++n ] = xnode;\r
+                       if( tmp ^ flag_not ) res[ ++n ] = xml;\r
                };\r
                return res;\r
        };\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
+                       i = 0, n = -1, xml;\r
+               for( ; xml = xmlList[ i ]; ++i ){\r
+                       if( xml.getAttributeNode( prop ) ^ flag_not ) res[ ++n ] = xml;\r
                };\r
                return res;\r
-       };\r
+       }; */\r
 \r
 var XMLWrapper_filter = {\r
        'first-child' : {\r
@@ -521,49 +579,54 @@ var XMLWrapper_filter = {
        '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
+       '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
+                               i = 0, n = -1, xml, tmp, node;\r
+                       for( ; xml = 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
+                               for( node = xml.firstChild; node; node = node.nextSibling ){\r
+                                       if( node.nodeType === 1 || ( node.nodeType === 3 && node.nodeValue ) ){\r
                                                tmp = false;\r
                                                break;\r
                                        };                              \r
                                };\r
-                               if( tmp ^ flag_not ) res[ ++n ] = xnode;\r
+                               if( tmp ^ flag_not ) res[ ++n ] = xml;\r
                        };\r
                        return res;\r
                }\r
        },\r
-       contains : {\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
+                               i = 0, n = -1, xml, text = '';\r
+\r
+                       for( ; xml = xmlList[ i ]; ++i ){\r
+                               switch( xml.nodeType ){\r
                                        case 1 :\r
-                                               text = xml.nodeType === 1 ? xml.innerText || xml.text || xml.textContent : xml.nodeValue;// xnode[ attr_textContent ];\r
+                                               text = xml.innerText || xml.text || xml.textContent;\r
                                                break;\r
-                                       case 2 :\r
+                                       //case 2 :\r
                                        case 3 :\r
-                                               text = xnode.nodeValue;\r
+                                               text = xml.nodeValue;\r
                                                break;\r
                                };\r
-                               console.log( text + ' ' + arg );\r
-                               if ( ( -1 < text.indexOf( arg ) ) ^ flag_not ) res[ ++n ] = xnode;                                              \r
+                               if ( ( -1 < text.indexOf( arg ) ) ^ flag_not ) res[ ++n ] = xml;                \r
                        };\r
                        return res;\r
                }\r
        }\r
 };\r
 \r
+/**\r
+ * XML配列を扱う XML 探索用のラッパークラスです\r
+ * @alias X.XMLList\r
+ * @class XMLList XML配列を扱う XML 探索用のラッパークラスです\r
+ * @constructor\r
+ * @extends {X.XML}\r
+ */\r
 function XMLListWrapper( xmlList ){\r
        var i = 0, l = xmlList ? xmlList.length : 0;\r
        for( ; i < l; ++i ){\r
@@ -574,9 +637,10 @@ function XMLListWrapper( xmlList ){
 \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
+XMLListWrapper.prototype.length      = 0;\r
+XMLListWrapper.prototype._wraps      = null;\r
+XMLListWrapper.prototype[ 'parent' ] = XMLWrapper_parent;\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