OSDN Git Service

Version 0.6.17, X.Dom.Query work a little.
[pettanr/clientJs.git] / 0.6.x / js / dom / 11_XDomNode.js
1 \r
2 /*\r
3  * Node( rawElement | rawTextnode | htmlString | textString )\r
4  */\r
5 //;(function( window, document, undeifned ){\r
6 X.Dom.Node = X.EventDispatcher.inherits(\r
7         'XDomNode',\r
8         X.Class.POOL_OBJECT,\r
9         {\r
10                 _uid       : 0,\r
11                 _rawNode   : null,              \r
12                 parent     : null,              \r
13                 _xnodes    : null,\r
14         \r
15                 _xnodeType : 0,\r
16                 _tag       : null,\r
17                 _text      : null,\r
18                 _id        : null,\r
19                 _className : '',\r
20                 _classText : ' ',\r
21 \r
22                 _attrs     : null, // X.Dom.Attr\r
23                 _attrText  : '',\r
24                 _attrUpdated : false,\r
25                 _css       : null, // X.Dom.Style\r
26                 _cssText   : '',\r
27                 _styleText : '',\r
28                 \r
29                 Constructor : function( v ){\r
30                         var css, xnodes, xnode, parent, uid = Node._chashe.length;\r
31                         \r
32                         if( Node._newByTag ){\r
33                                 Node._newByTag  = false;\r
34                                 this._tag       = v;\r
35                                 this._xnodeType = 1;\r
36                                 arguments[ 1 ] && this.attr( arguments[ 1 ] );\r
37                                 css = arguments[ 2 ];\r
38                                 css && this[ X.Type.isString( css ) ? 'cssText' : 'css' ]( css );\r
39                         } else\r
40                         if( Node._newByText ){\r
41                                 Node._newByText = false;\r
42                                 this._text      = v;\r
43                                 this._xnodeType = 3;\r
44                         } else {\r
45                                 if( 1 < arguments.length ) return new X.Dom.NodeList( arguments );\r
46                                 if( X.Type.isArray( v ) && v.length ) return new X.Dom.NodeList( v );\r
47                                 if( !this || this.append !== Node.prototype.append ) return new Node( v );\r
48                 \r
49                                 switch( Node._getType( v ) ){\r
50                                         case Node.IS_XNODE :\r
51                                         case Node.IS_XNODE_LIST :\r
52                                                 return v;\r
53                                         case Node.IS_RAW_HTML :\r
54                                                 if( xnode = Node._getXNode( v ) ) return xnode;\r
55                                                 // v.parentNode || v.parentElement : dom1 || dom0\r
56                                                 this.parent     = v !== document.body && ( parent = v.parentNode || v.parentElement ) && parent.tagName /* ie7- */ && Node._getXNode( parent );\r
57                                                 this._rawNode   = v;\r
58                                                 this._xnodeType = 1;\r
59                                                 this._tag       = v.tagName;\r
60                                                 this._id        = v.id;\r
61                                                 this._className = v.className;\r
62                                                 this._classText = ' class="' + this._className + '" ';\r
63                                                 this.cssText( v.style.cssText );\r
64                                                 // attr\r
65                                                 \r
66                                                 if( X.UA.IE && X.UA.IE < 5 ){\r
67                                                         v.setAttribute( 'UID', '' + uid );\r
68                                                 } else {\r
69                                                         v.UID = uid;\r
70                                                 };\r
71                                                 // childNodes...\r
72                                                 break;\r
73                                         case Node.IS_RAW_TEXT :\r
74                                                 if( xnode = Node._getXNode( v ) ) return xnode;\r
75                                                 this.parent     = Node._getXNode( v.parentNode );\r
76                                                 this._rawNode   = v;\r
77                                                 this._xnodeType = 3;\r
78                                                 this._text      = v.data;\r
79                                                 break;\r
80                                         case Node.IS_HTML_STRING :\r
81                                         case Node.IS_STRING :\r
82                                                 if( xnodes = X.Dom.parse( v, true ) && 1 < xnodes.length ) return new X.Dom.NodeList( xnodes );\r
83                                                 if( xnodes.length ) return xnodes[ 0 ];\r
84                                                 return Node.none;\r
85                                         case Node.IS_WINDOW :\r
86                                         case Node.IS_DOCUMENT :\r
87                                         case Node.IS_IMAGE :\r
88                                                 this._rawNode   = v;\r
89                                                 this._xnodeType = 2;\r
90                                                 break;\r
91                                         default :\r
92                                                 if( Node.none ) return Node.none;\r
93                                                 return;\r
94                                 };\r
95                         };\r
96                         \r
97                         Node._chashe[ this._uid = uid ] = this;\r
98                 }\r
99         }\r
100 );\r
101 \r
102 var Node = X.Dom.Node;\r
103 \r
104 Node.IS_XNODE       = 1;\r
105 Node.IS_RAW_HTML    = 2;\r
106 Node.IS_RAW_TEXT    = 3;\r
107 Node.IS_HTML_STRING = 4;\r
108 Node.IS_STRING      = 5;\r
109 Node.IS_DOC_FRAG    = 6;\r
110 Node.IS_XNODE_LIST  = 7;\r
111 Node.IS_WINDOW      = 8;\r
112 Node.IS_DOCUMENT    = 9;\r
113 Node.IS_IMAGE       = 10;\r
114 \r
115 Node._getType = function( v ){\r
116         if( v === '' ) return Node.IS_STRING;\r
117         if( !v ) return 0;\r
118         if( v === window ) return Node.IS_WINDOW;\r
119         if( v === document ) return Node.IS_DOCUMENT;\r
120         if( v.constructor === window.Image ) return Node.IS_IMAGE;\r
121         if( v.constructor === Node ) return Node.IS_XNODE;\r
122         if( v.constructor === X.Dom.NodeList ) return Node.IS_XNODE_LIST;\r
123         if( v.tagName ) return Node.IS_RAW_HTML;\r
124         if( v.nodeType === 3 ) return Node.IS_RAW_TEXT;\r
125         if( typeof v === 'string' ){\r
126                 return '<' === v.charAt( 0 ) && v.charAt( v.length - 1 ) === '>' ? Node.IS_HTML_STRING : Node.IS_STRING;\r
127         };\r
128         if( v.nodeType === 11 ) return Node.IS_DOC_FRAG;\r
129         return 0;\r
130 };\r
131 Node._getXNode = function( node ){\r
132         var uid;\r
133         if( !node ) return;\r
134         if( X.UA.IE && X.UA.IE < 5 ){\r
135                 uid = node.getAttribute( 'UID' );\r
136                 return uid && Node._chashe[ uid ];\r
137         };\r
138         return node.UID && Node._chashe[ node.UID ];\r
139 };\r
140 \r
141 \r
142 Node.create = function( tag, opt_attr, opt_css ){\r
143         Node._newByTag = true;\r
144         return new Node( tag, opt_attr, opt_css );\r
145 };\r
146 Node.createText = function( text ){\r
147         Node._newByText = true;\r
148         return new Node( text );\r
149 };\r
150 \r
151 \r
152 Node.getRoot = function( xnode ){\r
153         return Node._document;\r
154         //return xnode.root._rawNode.documentElement ? node : node.ownerDocument || node.document;\r
155 };\r
156         // XMLかどうかを判別する\r
157 Node.isXmlDocument =\r
158         X.UA.IE && X.UA.IE < 5 ?\r
159                 X.emptyFunction :\r
160                 (function( root ){\r
161                         return root._rawNode.createElement( 'p' ).tagName !== root._rawNode.createElement( 'P' ).tagName;\r
162                 });\r
163 \r
164 \r
165 /* --------------------------------------\r
166  *  Dom Core 1\r
167  */\r
168 if( document.getElementById ){\r
169         Node._dom1cleanUp = function( xnode ){\r
170                 var elm      = xnode._rawNode,\r
171                         children = xnode._xnodes,\r
172                         childNodes, i, l, child, _child;\r
173                 if( elm && children && ( childNodes = elm.childNodes ) ){\r
174                         for( i = 0, l = children.length; i < l; ++i ){\r
175                                 child = children[ i ];\r
176                                 if( child.constructor === Node ) child = child._create( true );\r
177                                 if( typeof child === 'string'  ) child = document.createTextNode( child );\r
178                                 if( ( _child = childNodes[ i ] ) !== child ){\r
179                                         _child ?\r
180                                                 elm.insertBefore( child, _child ) :\r
181                                                 elm.appendChild( child );\r
182                                         _child && elm.removeChild( _child );\r
183                                 };\r
184                         };\r
185                         while( ( _child = childNodes[ i ] ) ){\r
186                                 elm.removeChild( _child );\r
187                         };\r
188                 };\r
189         };      \r
190 };\r
191 \r
192 Node._chashe     = [];\r
193 Node.none        = Node._chashe[ 0 ] = new Node();\r
194 Node._window     = new Node( window ); // Node._chashe[ 1 ]\r
195 Node._document   = new Node( document ); // Node._chashe[ 2 ]\r
196 Node._html       = null; // Node._chashe[ 3 ]\r
197 Node.root        = null;// = Node._chashe[ 4 ] body\r
198 Node._systemNode = null;// = Node._chashe[ ? ]\r
199 \r
200 /* --------------------------------------\r
201  *  Create\r
202  */\r
203 Node.prototype._create =\r
204         // document.createElement of ie4 is only for OPTION & IMAGE.\r
205         document.getElementById ? (function( isChild ){\r
206                 var tag = this._tag, node, frg;\r
207 /*\r
208  * http://d.hatena.ne.jp/uupaa/20080718/1216362040\r
209  * DOM Rangeが使える環境(Firefox2+,Opera9+,Safari3+)なら、innerHTMLいらずで、ガーって書けます。\r
210  * return document.createRange().createContextualFragment("<div><select><option></option></select></div>");\r
211  * \r
212  * ie7 以下では iframe の frameborder や、input name は、createElement 後に aetAttribute しても無視される\r
213  */\r
214 \r
215                 if( !( node = this._rawNode ) ){\r
216                         this._isNew = true;\r
217                         node = this._rawNode = (\r
218                                 tag && X.UA.IE ?\r
219                                         document.createElement( [\r
220                                                 '<', this._tag,\r
221                                                         ' UID="', this._uid, '"',\r
222                                                         this._id ? ' id="' + this._id + '"' : '',\r
223                                                         this._classText,\r
224                                                         ( this._attrUpdated ? ( this._attrText = X.Dom.Attr.objToAttrText( this._attrs ) ) : this._attrText ),\r
225                                                         this._styleText,\r
226                                                 '>' ].join( '' ) ) :\r
227                                 tag ?\r
228                                         document.createElement( tag ) :\r
229                                         document.createTextNode( this._text ) );\r
230                         delete this._attrUpdated;\r
231                 };\r
232                 // fragument がある場合 children も足して\r
233                 // Mozilla: 1.0+, IE: 6.0+, Netscape: 2.0+, Safari: 1.0+, Opera: 7.0+\r
234                 if( !isChild && document.createDocumentFragment ){\r
235                         if( node.nodeType === 1 ){\r
236                                 frg = document.createDocumentFragment();\r
237                                 frg.appendChild( node );\r
238                                 Node._dom1cleanUp( this );\r
239                                 return frg;\r
240                         };\r
241                 };\r
242                 \r
243                 return node;\r
244         }) :\r
245         document.all ? (function( skipRemove, skipContainsDirty ){\r
246                 var html, attrs, attr, children, i, l, child, toName, noValue, name;\r
247                 if( this._xnodeType !== 1 ) return this._text;\r
248                 \r
249                 if( this._rawNode || this._ie4getRawNode() ){\r
250                         if( skipRemove ){\r
251                                 this._beforeRemove();\r
252                         } else {\r
253                                 // 追加する前に要素を抜く\r
254                                 this.remove();          \r
255                         };\r
256                         if( !skipContainsDirty && !this._ie4containsDirty() ){\r
257                                 return this._htmlText;\r
258                         };\r
259                 };\r
260                 html = [\r
261                         '<', this._tag, ' id=', ( this._id || ( 'ie4uid' + this._uid ) ),\r
262                         this._classText,\r
263                         ( this._attrUpdated ? ( this._attrText = X.Dom.Attr.objToAttrText( this._attrs ) ) : this._attrText ),\r
264                         this._styleText,\r
265                 '>' ];\r
266                 delete this._attrUpdated;\r
267                 \r
268                 if( ( children = this._xnodes ) && ( l = children.length ) ){\r
269                         for( i = 0; i < l; ++i ){\r
270                                 html[ html.length ] = children[ i ]._create( true, true );\r
271                         };\r
272                 };\r
273                 html[ html.length ] = '<\/' + this._tag + '>';\r
274                 return html.join( '' );\r
275         }) :\r
276         (function(){});\r
277 \r
278 Node.prototype._afterCreate =\r
279         ( document.getElementById ) ? (function( parent ){\r
280                 var _children = this._xnodes,\r
281                         node      = this._rawNode,\r
282                         eChildren = node && node.nodeType === 1 && node.childNodes,\r
283                         attrs, p, _child, i, l;\r
284                 this.parent = parent;\r
285                 if( this._xnodeType !== 1 ) return this;\r
286                 if( this._isNew ){\r
287                         if( _children && !document.createDocumentFragment ){\r
288                                 Node._dom1cleanUp( this ); // docFrg が使えない場合、doc 追加後に子を追加\r
289                         };\r
290                         if( !X.UA.IE ){\r
291                                 node.UID       = this._uid;\r
292                                 if( this._id ) node.id = this._id;\r
293                                 if( this._className ) node.className = this._className;\r
294                                 // ie では createElement に <div class=...> HTML 文字列を渡すことができる\r
295                                 // 動的に生成した iframe に後から frameborder 等を設定しても無視される ie7\r
296                                 if( attrs = this._attrs ){\r
297                                         for( p in attrs ){\r
298                                                 node[ p ] = attrs[ p ];\r
299                                         };\r
300                                 };\r
301                                 node.style.cssText = this._cssText;                             \r
302                         };\r
303                         this._restoreEvent();// イベントの復帰\r
304                         delete this._isNew;\r
305                 };\r
306                 /*\r
307                  * elm.childNodes を this._xnodes にリンクさせる\r
308                  */\r
309                 if( _children ){\r
310                         for( i = 0, l = _children.length; i < l; ++i ){\r
311                                 _child = _children[ i ];\r
312                                 _child.constructor === Node ? _child._afterCreate( this ) : ( _children[ i ] = eChildren[ i ] );\r
313                         };\r
314                 } else\r
315                 if( eChildren && eChildren.length ){\r
316                         this._xnodes = [];\r
317                         this._xnodes.push.apply( this._xnodes, eChildren );\r
318                 };\r
319                 return this;\r
320         }) :\r
321         document.all ? (function( parent ){\r
322                 var elm,\r
323                         children = this._xnodes,\r
324                         child, i, l;\r
325                 this.parent = parent;\r
326                 delete this._ie4dirty;\r
327                 \r
328                 if( this._xnodeType !== 1 ) return this;\r
329 \r
330                 delete this._rawNode;\r
331                 delete this._ie4dirtyChildren;\r
332                 \r
333                 if( children ){\r
334                         for( i = children.length; i; ){\r
335                                 children[ --i ]._afterCreate( this );\r
336                         };\r
337                 };\r
338                 if( elm = this._ie4getRawNode() ){\r
339                         this._restoreEvent();// イベントの復帰\r
340                         elm.setAttribute( 'UID', '' + this._uid );\r
341                 };\r
342         }) :\r
343         (function(){});\r
344 \r
345 /* --------------------------------------\r
346  *  Create\r
347  */\r
348 Node.prototype.create = function( tag, opt_attrs, opt_css ){\r
349         var elm, xnode;\r
350         if( this._xnodeType !== 1 ) return;\r
351         if( !this._xnodes ) this._xnodes = [];\r
352         \r
353         elm = this._ie4getRawNode ? this._ie4getRawNode() : this._rawNode;\r
354         \r
355         if( elm && !Node.skipCreate ){\r
356                 if( document.getElementById ){\r
357                         // ie では iframe の frameborder が無視されるので、<iframe class=> を渡す\r
358                         elm.appendChild( document.createElement( tag ) );\r
359                         xnode = new Node( elm.lastChild );\r
360                         opt_attrs && xnode.attr( opt_attrs );\r
361                         opt_css   && xnode[ X.Type.isString( opt_css ) ? 'cssText' : 'css' ]( opt_css );\r
362                 } else\r
363                 if( document.all ){\r
364                         Node._newByTag = true;\r
365                         xnode = new Node( tag, opt_attrs, opt_css );\r
366                         // opt_attrs && xnode.attr( opt_attrs );\r
367                         elm.insertAdjacentHTML( 'BeforeEnd', xnode._create() );\r
368                         xnode._rawNode = elm.children[ elm.children.length - 1 ];\r
369                 } else {\r
370                         \r
371                 };\r
372         } else {\r
373                 Node._newByTag = true;\r
374                 xnode = new Node( tag, opt_attrs, opt_css );\r
375         };\r
376         xnode.parent = this;\r
377         this._xnodes[ this._xnodes.length ] = xnode;\r
378         return xnode;\r
379 };\r
380 \r
381 /* --------------------------------------\r
382  *  CreateText\r
383  */\r
384 Node.prototype.createText = function( text ){\r
385         var elm, xnode;\r
386         if( this._xnodeType !== 1 ) return;\r
387         if( !this._xnodes ) this._xnodes = [];\r
388         \r
389         elm = this._ie4getRawNode ? this._ie4getRawNode() : this._rawNode;\r
390         \r
391         if( elm && !Node.skipCreate ){\r
392                 if( document.createTextNode ){\r
393                         elm.appendChild( document.createTextNode( text ) );\r
394                         xnode = new Node( elm.lastChild );\r
395                 } else\r
396                 if( document.all ){\r
397                         elm.insertAdjacentText( 'BeforeEnd', text );\r
398                         Node._newByText = true;\r
399                         xnode = new Node( text );\r
400                 } else {\r
401                         \r
402                 };\r
403         } else {\r
404                 Node._newByText = true;\r
405                 xnode = new Node( text );\r
406         };\r
407         xnode.parent = this;\r
408         this._xnodes[ this._xnodes.length ] = xnode;\r
409         return xnode;\r
410 };\r
411 \r
412 /* --------------------------------------\r
413  *  Clone\r
414  * http://d.hatena.ne.jp/think49/20110724/1311472811\r
415  * http://d.hatena.ne.jp/uupaa/20100508/1273299874\r
416  */\r
417 Node.prototype.clone = function( opt_clone_children ){\r
418         var xnode, elm;\r
419         switch( this._xnodeType ){\r
420                 case 1 :\r
421                         if( X.UA.IE && X.UA.IE < 5 ){\r
422                                 \r
423                         } else\r
424                         if( X.UA.IE && 5 <= X.UA.IE && X.UA.IE < 10 ){\r
425                                 Node._newByTag = true;\r
426                                 xnode = new Node( this._tag, this._attrs, this._css );\r
427                                 xnode.className( this.className() );\r
428                                 if( opt_clone_children ){\r
429                                         \r
430                                 };\r
431                         } else\r
432                         if( elm = this.rawNode ){\r
433                                 xnode = new Node( elm.cloneNode( !!opt_clone_children ) );\r
434                         };\r
435 \r
436                         return xnode;\r
437                 case 3 :\r
438                         Node._newByText = true;\r
439                         xnode = new Node( this._text );\r
440                         return xnode;\r
441                 \r
442                 //case 0 :\r
443                 //case 2 :\r
444         };\r
445         return this;\r
446 };\r
447 \r
448 /* --------------------------------------\r
449  *  Add\r
450  * Node\r
451  * HtmlElement の場合は内部使用専用 そのため event の破棄等しない\r
452  */\r
453 Node.prototype.append = function( v ){\r
454         var elm, i, l, children, frg;\r
455         if( this._xnodeType !== 1 ) return;\r
456         \r
457         if( 1 < ( l = arguments.length ) ){\r
458                 if( document.createDocumentFragment && this._rawNode ){\r
459                         frg = document.createDocumentFragment();\r
460                         for( i = 0; i < l; ++i ){\r
461                                 v = arguments[ i ];\r
462                                 v = v.constructor === Node ? v : new Node( v );\r
463                                 frg.appendChild( v._create() );\r
464                                 this._xnodes[ this._xnodes.length ] = v;\r
465                                 v._afterCreate( this );\r
466                         };\r
467                         this._rawNode.appendChild( frg );\r
468                         return this;\r
469                 } else {\r
470                         for( i = 0; i < l; ++i ){\r
471                                 this.append( arguments[ i ] );\r
472                         };\r
473                 };\r
474                 return this;\r
475         };\r
476         \r
477         if( !this._xnodes ) this._xnodes = [];\r
478         \r
479         elm = this._ie4getRawNode ? this._ie4getRawNode() : this._rawNode;\r
480         switch( Node._getType( v ) ){\r
481                 case Node.IS_RAW_HTML :\r
482                 case Node.IS_RAW_TEXT :\r
483                         if( elm ){\r
484                                 if( document.getElementById ){\r
485                                         elm.appendChild( v );\r
486                                 } else\r
487                                 if( document.all ){\r
488                                         elm.insertAdjacentHTML( 'BeforeEnd', v.outerHTML );\r
489                                         v = elm.children[ elm.children.length - 1 ];\r
490                                 } else {\r
491                                         \r
492                                 };\r
493                         };\r
494                         this._xnodes[ this._xnodes.length ] = new Node( v );\r
495                         break;\r
496                 case Node.IS_HTML_STRING :\r
497                 case Node.IS_STRING :\r
498                         this.append( X.Dom.parse( v, true ) );\r
499                         break;\r
500                 case Node.IS_XNODE :\r
501                         if( v === Node.none ) return this;\r
502                         // 親の xnodes から v を消す\r
503                         v.parent && ( i = v.parent._xnodes.indexOf( v ) ) !== -1 && v.parent._xnodes.splice( i, 1 );\r
504                         if( elm ){\r
505                                 if( document.getElementById ){\r
506                                         elm.appendChild( v._create() );\r
507                                         v._afterCreate( this );\r
508                                 } else\r
509                                 if( document.all ){\r
510                                         elm.insertAdjacentHTML( 'BeforeEnd', v._create() );\r
511                                         v._afterCreate( this );\r
512                                 } else {\r
513                                         \r
514                                 };\r
515                         };\r
516                         this._xnodes[ this._xnodes.length ] = v;\r
517         };\r
518         return this;\r
519 };\r
520 \r
521 \r
522 Node.prototype.appendAt = function( start, v ){\r
523         var children, l, elm, i, prev, next;\r
524         \r
525         if( this._xnodeType !== 1 ) return this;\r
526         \r
527         if( !( children = this._xnodes ) ) children = this._xnodes = [];\r
528         \r
529         l = arguments.length;\r
530         if( children.length <= start ){\r
531                 if( l === 2 ) return this.append( v );\r
532                 v = [];\r
533                 for( ; 1 < l; ){\r
534                         v[ l - 2 ] = arguments[ --l ];\r
535                 };\r
536                 return this.append.apply( this, v );\r
537         };\r
538         if( start < 0 ) start = 0;\r
539         if( 2 < l ){\r
540                 if( document.createDocumentFragment && ( elm = this._rawNode ) ){\r
541                         var frg = document.createDocumentFragment();\r
542                         for( i = 0; i < l; ++i ){\r
543                                 v = arguments[ i ];\r
544                                 v = v.constructor === Node ? v : new Node( v );\r
545                                 frg.appendChild( v._create() );\r
546                                 children.splice( start + i, 0, v );\r
547                                 v._afterCreate( this );\r
548                         };\r
549                         elm.insertBefore( frg, elm.childNodes[ start ] );\r
550                         return this;\r
551                 };\r
552                 for( ; l; ){\r
553                         this.appendAt( start, arguments[ --l ] );\r
554                 };\r
555                 return this;\r
556         };\r
557         \r
558         if( !this.parent ){\r
559                 children.splice( start, 0, v );\r
560                 return this;\r
561         };\r
562         elm = this._ie4getRawNode ? this._ie4getRawNode() : this._rawNode;\r
563         switch( Node._getType( v ) ){\r
564                 case Node.IS_RAW_HTML :\r
565                 case Node.IS_RAW_TEXT :\r
566                         if( elm ){\r
567                                 if( document.getElementById ){\r
568                                         elm.insertBefore( v, elm.childNodes[ start ] );\r
569                                 } else\r
570                                 if( document.all ){\r
571                                         if( start === 0 ){\r
572                                                 elm.insertAdjacentHTML( 'AfterBegin', v.outerHTML );\r
573                                                 v = elm.children[ 0 ];\r
574                                         } else\r
575                                         if( ( next = children[ start ] ) && typeof next !== 'string' && next._xnodeType !== 3 &&\r
576                                                 ( next = ( next._ie4getRawNode ? next._ie4getRawNode() : next ) ) ){\r
577                                                 next.insertAdjacentHTML( 'BeforeBegin', v.outerHTML );\r
578                                                 v = elm.children[ ( Array.prototype.indexOf.call( elm.children, next ) ) - 1 ];\r
579                                         } else\r
580                                         if( 0 < start && ( prev = children[ start - 1 ] ) && typeof prev !== 'string' && prev._xnodeType !== 3 &&\r
581                                                 ( prev = ( prev._ie4getRawNode ? prev._ie4getRawNode() : prev ) ) ){\r
582                                                 prev.insertAdjacentHTML( 'AfterEnd', v.outerHTML );\r
583                                                 v = elm.children[ ( Array.prototype.indexOf.call( elm.children, prev ) ) + 1 ];\r
584                                         } else {\r
585                                                 this._ie4reserveUpdate( v );// テキストノードの間に入れる場合!\r
586                                         };\r
587                                 } else {\r
588                                         \r
589                                 };\r
590                                 children.splice( start, 0, v );\r
591                         } else {\r
592                                 children.splice( start, 0, v );\r
593                         };\r
594                         break;\r
595                 case Node.IS_HTML_STRING :\r
596                 case Node.IS_STRING :\r
597                         v = X.Dom.parse( v, true );\r
598                         if( elm ){\r
599                                 for( i = v.length; i; ){\r
600                                         this.appendAt( start, v[ --i ] );\r
601                                 };\r
602                         } else\r
603                         if( v.length ){\r
604                                 children.push.apply( children, v );\r
605                         };\r
606                         break;\r
607                 case Node.IS_XNODE :\r
608                         if( v === Node.none ) return this;\r
609                         // 親の xnodes から v を消す\r
610                         v.parent && ( i = v.parent._xnodes.indexOf( v ) ) !== -1 && v.parent._xnodes.splice( i, 1 );\r
611                         if( elm ){\r
612                                 if( document.getElementById ){\r
613                                         elm.insertBefore( v._create(), elm.childNodes[ start ] );\r
614                                         v._afterCreate( this );\r
615                                 } else\r
616                                 if( document.all ){\r
617                                         this._ie4reserveUpdate( v );\r
618                                 } else {\r
619                                         \r
620                                 };\r
621                         };\r
622                         children.splice( start, 0, v );\r
623         };\r
624         return this;\r
625 };\r
626 \r
627 Node.prototype.appendTo = function( parent, opt_index ){\r
628         if( parent.constructor === Node ){\r
629                 opt_index === undefined ? parent.append( this ) : parent.appendAt( opt_index, this );\r
630         } else {\r
631                 opt_index === undefined ? new Node( parent ).append( this ) : new Node( parent ).appendAt( opt_index, this );\r
632         };\r
633         return this;\r
634 };\r
635 \r
636 Node.prototype.appendToRoot = function( opt_index ){\r
637         opt_index === undefined ? Node.root.append( this ) : Node.root.appendAt( opt_index, this );\r
638         return this;\r
639 };\r
640 \r
641 /* --------------------------------------\r
642  *  Before , After, Replace\r
643  */\r
644 Node.prototype.before = function( v ){\r
645         var parent, l;\r
646         if( this._xnodeType !== 1 || !( parent = this.parent ) ) return this;\r
647         l = arguments.length;\r
648         if( 1 < l ){\r
649                 v = [ this.getOrder() ];\r
650                 for( ; l; ){\r
651                         v[ l ] = arguments[ --l ];\r
652                 };\r
653                 parent.appendAt.apply( parent, v );\r
654                 return this;\r
655         };\r
656         parent.appendAt( this.getOrder(), v );\r
657         return this;\r
658 };\r
659 \r
660 Node.prototype.after = function( v ){\r
661         var parent, l;\r
662         if( this._xnodeType !== 1 || !( parent = this.parent ) ) return this;\r
663         l = arguments.length;\r
664         if( 1 < l ){\r
665                 v = [ this.getOrder() + 1 ];\r
666                 for( ; l; ){\r
667                         v[ l ] = arguments[ --l ];\r
668                 };\r
669                 parent.appendAt.apply( parent, v );\r
670                 return this;\r
671         };\r
672         parent.appendAt( this.getOrder() + 1, v );\r
673         return this;\r
674 };\r
675 \r
676 Node.prototype.replace = function( v ){\r
677         if( !this.parent ) return this;\r
678         return arguments.length === 1 ? this.before( v ).remove() : this.before.apply( this, arguments ).remove();\r
679 };\r
680 \r
681 /* --------------------------------------\r
682  *  Remove\r
683  */\r
684 Node.prototype.remove = function(){\r
685         var parent = this.parent, elm;\r
686                 \r
687         if( !parent ) return this;\r
688         if( document.getElementById ){\r
689                 if( this._rawNode ){\r
690                         this._xnodeType === 1 && this._beforeRemove();\r
691                         parent._rawNode.removeChild( this._rawNode );\r
692                 };\r
693         } else\r
694         if( document.all ){\r
695                 delete this._ie4dirty;\r
696                 delete this._ie4dirtyChildren;\r
697                 if( this._xnodeType === 1 ){\r
698                         this._beforeRemove();\r
699                         if( elm = this._ie4getRawNode() ){\r
700                                 elm.outerHTML = '';\r
701                         };\r
702                 } else {\r
703                         parent._beforeRemove(); //??\r
704                         parent._ie4reserveUpdate();\r
705                 };\r
706         } else {\r
707                 \r
708         };\r
709 \r
710         parent._xnodes.splice( parent._xnodes.indexOf( this ), 1 );\r
711         delete this.parent;\r
712         return this;\r
713 };\r
714 \r
715 Node.prototype._beforeRemove = \r
716         document.getElementById ?\r
717                 ( function(){\r
718                         var elm = this._rawNode, children,\r
719                                 child, i, l;\r
720                         if( !elm ) return;\r
721                         this._migrateEvent();// イベントの退避\r
722                         if( children = this._xnodes ){\r
723                                 for( i = 0, l = children.length; i < l; ++i ){\r
724                                         child = children[ i ];\r
725                                         child._xnodeType === 1 && child._beforeRemove();\r
726                                 };\r
727                         };\r
728                 }) :\r
729         document.all ? \r
730                 ( function(){\r
731                         var elm = this._ie4getRawNode(),\r
732                                 children, i, l;\r
733                         if( children = this._xnodes ){\r
734                                 for( i = 0, l = children.length; i < l; ++i ){\r
735                                         children[ i ]._beforeRemove();\r
736                                 };      \r
737                         };\r
738                         if( !elm ) return;\r
739                         this._migrateEvent();// イベントの退避\r
740                         this._htmlText = elm.outerHTML;\r
741                         elm.removeAttribute( 'id' );\r
742                 }) :\r
743                 (function(){});\r
744 \r
745 Node.prototype.empty =\r
746         document.getElementById ?\r
747                 ( function(){\r
748                         var elm = this._rawNode, children,\r
749                                 child, i, l;\r
750                         if( children = this._xnodes ){\r
751                                 for( i = 0, l = children.length; i < l; ++i ){\r
752                                         children[ i ].destroy();\r
753                                 };\r
754                                 children.length = 0;\r
755                         };\r
756                         if( elm ) elm.innerHTML = '';\r
757                         return this;\r
758                 }) :\r
759         document.all ? \r
760                 ( function(){\r
761                         var elm = this._ie4getRawNode(),\r
762                                 children, i, l;\r
763                         if( children = this._xnodes ){\r
764                                 for( i = 0, l = children.length; i < l; ++i ){\r
765                                         children[ i ].destroy();\r
766                                 };\r
767                                 children.length = 0;\r
768                         };\r
769                         if( elm ) elm.innerHTML = '';\r
770                         return this;\r
771                 }) :\r
772                 (function(){});\r
773 \r
774 /* --------------------------------------\r
775  *  destory\r
776  */\r
777 Node.prototype.destroy = function(){\r
778         var elm = this._ie4getRawNode ? this._ie4getRawNode() : this._rawNode,\r
779                 children = this._xnodes, i, l;\r
780         \r
781         if( children ){\r
782                 for( i = 0, l = children.length; i < l; ++i ){\r
783                         children[ i ].destroy();\r
784                 };\r
785                 children.length = 0;\r
786         };\r
787         this._xnodeType === 1 && this.unlisten(); // イベントの退避\r
788         if( elm ){\r
789                 this._xnodeType === 1 && ( elm.innerHTML = '' );\r
790                 // stop()\r
791                 // remove() empty()\r
792                 \r
793                 document.getElementById && this.parent._rawNode.removeChild( elm );\r
794         };\r
795         delete Node._chashe[ this._uid ];\r
796         this.kill();\r
797 };\r
798 \r
799 /* --------------------------------------\r
800  *  for ie4\r
801  */\r
802 if( !document.getElementById && document.all ){\r
803 \r
804         Node.prototype._ie4getRawNode = function(){\r
805                 var elm, uid;\r
806                 if( elm = this._rawNode ) return elm;\r
807                 if( this._id && ( elm = this._rawNode = document.all[ this._id ] ) ){\r
808                         return elm;\r
809                 };\r
810                 if( elm = this._rawNode = document.all[ 'ie4uid' + this._uid ] ){\r
811                         if( this._id ) elm.setAttribute( 'id', this._id );\r
812                         return elm;\r
813                 };\r
814         };\r
815         \r
816         Node.prototype._ie4reserveUpdate = function( child ){\r
817                 var root = Node.root;\r
818                 child && ( child._ie4dirty = true );\r
819                 this._ie4dirtyChildren = true;\r
820                 if( root._ie4reserved === true ) return;\r
821                 root._ie4reserved = true;\r
822                 X.Timer.once( 1, root, root._ie4startUpdate );\r
823         };\r
824         \r
825         Node.prototype._ie4startUpdate = function(){\r
826                 if( this._ie4reserved !== true ) return;\r
827                 delete this._ie4reserved;\r
828                 if( !this._xnodes ) return;\r
829                 this._ie4commitUpdate()._ie4afterUpdate();\r
830         };\r
831         \r
832         Node.prototype._ie4commitUpdate = function(){\r
833                 var children = this._xnodes,\r
834                         i, l, html;\r
835                 if( !this._ie4dirtyChildren ){\r
836                         if( children && ( l = children.length ) ){\r
837                                 for( i = 0; i < l; ++i ){\r
838                                         children[ i ]._ie4commitUpdate();\r
839                                 };                              \r
840                         };\r
841                         return this;\r
842                 };\r
843                 html = [];\r
844                 if( children && ( l = children.length ) ){\r
845                         for( i = 0; i < l; ++i ){\r
846                                 html[ html.length ] = children[ i ]._create( true );\r
847                         };      \r
848                 };\r
849                 this._rawNode.innerHTML = html.join( '' );\r
850                 return this;\r
851         };\r
852         \r
853         Node.prototype._ie4afterUpdate = function(){\r
854                 var children = this._xnodes,\r
855                         i, l;\r
856                 if( !this._ie4dirtyChildren ){\r
857                         if( children && ( l = children.length ) ){\r
858                                 for( i = 0; i < l; ++i ){\r
859                                         children[ i ]._ie4afterUpdate();\r
860                                 };                              \r
861                         };\r
862                         return this;\r
863                 };\r
864                 if( children && ( l = children.length ) ){\r
865                         for( i = 0; i < l; ++i ){\r
866                                 children[ i ]._afterCreate( this );\r
867                         };      \r
868                 };\r
869                 delete this._ie4dirtyChildren;\r
870         };\r
871         \r
872         Node.prototype._ie4containsDirty = function(){\r
873                 var children, i;\r
874                 if( this._xnodeType !== 1 ) return;\r
875                 if( this._ie4dirtyChildren || this._ie4dirty ) return true;\r
876                 if( !( children = this._xnodes ) || !( i = children.length ) ) return;\r
877                 for( ; i; ){\r
878                         if( children[ --i ]._ie4containsDirty() ) return true;\r
879                 };\r
880         };\r
881 };\r
882 \r
883 /* --------------------------------------\r
884  *  contains\r
885  */\r
886 Node.prototype.contains = function( v ){\r
887         var node, children, i;\r
888         if( !v || !this.parent || this._xnodeType !== -1 ) return false;\r
889         // contains ie4+\r
890         if( document.contains ){\r
891                 node = this._ie4getRawNode ? this._ie4getRawNode() : this._rawNode;\r
892                 switch( Node._getType( v ) ){\r
893                         case Node.IS_RAW_HTML :\r
894                         case Node.IS_RAW_TEXT :\r
895                                 return node.contains( v );\r
896                         case Node.IS_XNODE :\r
897                                 if( v.parent === this ) return true;\r
898                                 v = v._ie4getRawNode ? v._ie4getRawNode() : v._rawNode;\r
899                                 if( node && v ) return node.contains( v );\r
900                                 break;\r
901                         default :\r
902                                 return false;\r
903                 };              \r
904         };\r
905         //if( document.compareDocumentPosition ){\r
906         //      \r
907         //};\r
908         children = this._xnodes;\r
909         if( children.indexOf( v ) !== -1 ) return true;\r
910         if( ( node = this._rawNode ) && node === v.parentNode ) return false;\r
911         for( i = children.length; i; ){\r
912                 if( children[ --i ].contains( v ) ) return true;\r
913         };\r
914         return false;\r
915 };\r
916 \r
917 /* --------------------------------------\r
918  *  getChild\r
919  */\r
920 Node.prototype.getChildAt = function( index ){\r
921         var children = this._xnodes,\r
922                 elm, childNodes, child, xnode;\r
923         if( this._xnodeType !== 1 || index < 0 ) return;\r
924         if( children.length <= index ) return;\r
925         child = children[ index ];\r
926         if( child.constructor === Node ) return child;\r
927         xnode = new Node( child );\r
928         xnode.parent = this;\r
929         return children[ index ] = xnode;\r
930 };\r
931 \r
932 \r
933 /* --------------------------------------\r
934  *  prevNode, nextNode, firstChild, lastChild\r
935  */\r
936 \r
937 Node.prototype.prevNode = function(){\r
938         var parent = this.parent, children, index;\r
939         if( !parent ) return;\r
940         children = parent._xnodes;\r
941         index = children.indexOf( this );\r
942         if( 0 < index ) return children[ index - 1 ];\r
943 };\r
944 Node.prototype.nextNode = function(){\r
945         var parent = this.parent, children, index;\r
946         if( !parent ) return;\r
947         children = parent._xnodes;\r
948         index    = children.indexOf( this );\r
949         if( index !== -1 && index + 1 < children.length ) return children[ index + 1 ];\r
950 };\r
951 Node.prototype.firstChild = function(){\r
952         return this.getChildAt( 0 );\r
953 };\r
954 Node.prototype.lastChild = function(){\r
955         return this.getChildAt( this._xnodes.length - 1 );\r
956 };\r
957 \r
958 /* --------------------------------------\r
959  *  getOrder\r
960  */\r
961 Node.prototype.getOrder = function(){\r
962         var parent = this.parent;\r
963         if( !parent ) return -1;\r
964         return parent._xnodes.indexOf( this );\r
965 };\r
966 \r
967 /* --------------------------------------\r
968  *  className, addClass, removeClass, hasClass\r
969  */\r
970 Node.prototype.className = function( v ){\r
971         var node;\r
972         // getter\r
973         if(  typeof v !== 'string' ) return this._className;\r
974         // setter\r
975         if( this._className === v ) return this;\r
976         if( !v ) delete this._className;\r
977         node = this._ie4getRawNode ? this._ie4getRawNode() : this._rawNode;\r
978         if( node ) node.className = v;\r
979         this._className = v;\r
980         this._classText = ' class="' + v + '" ';\r
981         return this;\r
982 };\r
983 Node.prototype.addClass = function(){\r
984         \r
985 };\r
986 Node.prototype.removeClass = function(){\r
987         \r
988 };\r
989 Node.prototype.toggleClass = function(){\r
990         \r
991 };\r
992 Node.prototype.hasClass = function( className ){\r
993         var _ = ' ',\r
994                 _className = this._className, i, name;\r
995         if( _className === className ) return true;\r
996         if( !_className ) return false;\r
997         \r
998         _className = _ + _className + _;\r
999         if( _className.indexOf( _ + className + _ ) !== -1 ) return true; // lucky hit\r
1000         \r
1001         for( className = className.split( _ ), i = className.length; i; ){\r
1002                 name = className[ --i ];\r
1003                 if( name === '' ) continue;\r
1004                 if( _className.indexOf( _ + name + _ ) === -1 ) return false;\r
1005         };\r
1006         return true;\r
1007 };\r
1008 \r
1009 /* --------------------------------------\r
1010  *  html, text\r
1011  */\r
1012 Node.prototype.html = function( html ){\r
1013         if( html ){\r
1014                 if( this._xnodeType === 3 ){\r
1015                         this._text = html;\r
1016                         if( this._rawNode ) this._rawNode.data = html;\r
1017                         return this;\r
1018                 };\r
1019                 return this.empty().append.call( this, X.Dom.parse( html, true ) );\r
1020         };\r
1021         // if dirty\r
1022         return this._rawNode ? this._rawNode.innerHTML : '';\r
1023 };\r
1024 \r
1025 Node.prototype.text = function( text ){\r
1026         // setter\r
1027         if( text ){\r
1028                 if( this._xnodeType === 3 ){\r
1029                         this._text = text;\r
1030                         if( this._rawNode ) this._rawNode.data = text;\r
1031                         return this;\r
1032                 };\r
1033                 this.empty().createText( text );\r
1034                 return this;    \r
1035         };\r
1036         // getter\r
1037         if( this._xnodeType === 1 ){\r
1038                 //\r
1039         };\r
1040         return this._text;\r
1041 };\r
1042 \r
1043 //})( window, document );\r
1044 \r
1045 \r