OSDN Git Service

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