3 * Node( rawElement | rawTextnode | htmlString | textString )
\r
5 //;(function( window, document, undeifned ){
\r
6 X.Dom.Node = X.EventDispatcher.inherits(
\r
22 _attrs : null, // X.Dom.Attr
\r
24 _attrUpdated : false,
\r
25 _css : null, // X.Dom.Style
\r
29 Constructor : function( v ){
\r
30 var css, xnodes, xnode, parent, uid = Node._chashe.length;
\r
32 if( Node._newByTag ){
\r
33 Node._newByTag = false;
\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
40 if( Node._newByText ){
\r
41 Node._newByText = false;
\r
43 this._xnodeType = 3;
\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
49 switch( Node._getType( v ) ){
\r
50 case Node.IS_XNODE :
\r
51 case Node.IS_XNODE_LIST :
\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
58 this._xnodeType = 1;
\r
59 this._tag = v.tagName;
\r
61 this._className = v.className;
\r
62 this._classText = ' class="' + this._className + '" ';
\r
63 this.cssText( v.style.cssText );
\r
66 if( X.UA.IE && X.UA.IE < 5 ){
\r
67 v.setAttribute( 'UID', '' + uid );
\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
77 this._xnodeType = 3;
\r
78 this._text = v.data;
\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
85 case Node.IS_WINDOW :
\r
86 case Node.IS_DOCUMENT :
\r
87 case Node.IS_IMAGE :
\r
89 this._xnodeType = 2;
\r
92 if( Node.none ) return Node.none;
\r
97 Node._chashe[ this._uid = uid ] = this;
\r
102 var Node = X.Dom.Node;
\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
115 Node._getType = function( v ){
\r
116 if( v === '' ) return Node.IS_STRING;
\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
128 if( v.nodeType === 11 ) return Node.IS_DOC_FRAG;
\r
131 Node._getXNode = function( node ){
\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
138 return node.UID && Node._chashe[ node.UID ];
\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
146 Node.createText = function( text ){
\r
147 Node._newByText = true;
\r
148 return new Node( text );
\r
152 Node.getRoot = function( xnode ){
\r
153 return Node._document;
\r
154 //return xnode.root._rawNode.documentElement ? node : node.ownerDocument || node.document;
\r
157 Node.isXmlDocument =
\r
158 X.UA.IE && X.UA.IE < 5 ?
\r
161 return root._rawNode.createElement( 'p' ).tagName !== root._rawNode.createElement( 'P' ).tagName;
\r
165 /* --------------------------------------
\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
180 elm.insertBefore( child, _child ) :
\r
181 elm.appendChild( child );
\r
182 _child && elm.removeChild( _child );
\r
185 while( ( _child = childNodes[ i ] ) ){
\r
186 elm.removeChild( _child );
\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
200 /* --------------------------------------
\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
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
212 * ie7 以下では iframe の frameborder や、input name は、createElement 後に aetAttribute しても無視される
\r
215 if( !( node = this._rawNode ) ){
\r
216 this._isNew = true;
\r
217 node = this._rawNode = (
\r
219 document.createElement( [
\r
221 ' UID="', this._uid, '"',
\r
222 this._id ? ' id="' + this._id + '"' : '',
\r
224 ( this._attrUpdated ? ( this._attrText = X.Dom.Attr.objToAttrText( this._attrs ) ) : this._attrText ),
\r
226 '>' ].join( '' ) ) :
\r
228 document.createElement( tag ) :
\r
229 document.createTextNode( this._text ) );
\r
230 delete this._attrUpdated;
\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
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
249 if( this._rawNode || this._ie4getRawNode() ){
\r
251 this._beforeRemove();
\r
256 if( !skipContainsDirty && !this._ie4containsDirty() ){
\r
257 return this._htmlText;
\r
261 '<', this._tag, ' id=', ( this._id || ( 'ie4uid' + this._uid ) ),
\r
263 ( this._attrUpdated ? ( this._attrText = X.Dom.Attr.objToAttrText( this._attrs ) ) : this._attrText ),
\r
266 delete this._attrUpdated;
\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
273 html[ html.length ] = '<\/' + this._tag + '>';
\r
274 return html.join( '' );
\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
287 if( _children && !document.createDocumentFragment ){
\r
288 Node._dom1cleanUp( this ); // docFrg が使えない場合、doc 追加後に子を追加
\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
298 node[ p ] = attrs[ p ];
\r
301 node.style.cssText = this._cssText;
\r
303 this._restoreEvent();// イベントの復帰
\r
304 delete this._isNew;
\r
307 * elm.childNodes を this._xnodes にリンクさせる
\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
315 if( eChildren && eChildren.length ){
\r
317 this._xnodes.push.apply( this._xnodes, eChildren );
\r
321 document.all ? (function( parent ){
\r
323 children = this._xnodes,
\r
325 this.parent = parent;
\r
326 delete this._ie4dirty;
\r
328 if( this._xnodeType !== 1 ) return this;
\r
330 delete this._rawNode;
\r
331 delete this._ie4dirtyChildren;
\r
334 for( i = children.length; i; ){
\r
335 children[ --i ]._afterCreate( this );
\r
338 if( elm = this._ie4getRawNode() ){
\r
339 this._restoreEvent();// イベントの復帰
\r
340 elm.setAttribute( 'UID', '' + this._uid );
\r
345 /* --------------------------------------
\r
348 Node.prototype.create = function( tag, opt_attrs, opt_css ){
\r
350 if( this._xnodeType !== 1 ) return;
\r
351 if( !this._xnodes ) this._xnodes = [];
\r
353 elm = this._ie4getRawNode ? this._ie4getRawNode() : this._rawNode;
\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
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
373 Node._newByTag = true;
\r
374 xnode = new Node( tag, opt_attrs, opt_css );
\r
376 xnode.parent = this;
\r
377 this._xnodes[ this._xnodes.length ] = xnode;
\r
381 /* --------------------------------------
\r
384 Node.prototype.createText = function( text ){
\r
386 if( this._xnodeType !== 1 ) return;
\r
387 if( !this._xnodes ) this._xnodes = [];
\r
389 elm = this._ie4getRawNode ? this._ie4getRawNode() : this._rawNode;
\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
396 if( document.all ){
\r
397 elm.insertAdjacentText( 'BeforeEnd', text );
\r
398 Node._newByText = true;
\r
399 xnode = new Node( text );
\r
404 Node._newByText = true;
\r
405 xnode = new Node( text );
\r
407 xnode.parent = this;
\r
408 this._xnodes[ this._xnodes.length ] = xnode;
\r
412 /* --------------------------------------
\r
414 * http://d.hatena.ne.jp/think49/20110724/1311472811
\r
415 * http://d.hatena.ne.jp/uupaa/20100508/1273299874
\r
417 Node.prototype.clone = function( opt_clone_children ){
\r
419 switch( this._xnodeType ){
\r
421 if( X.UA.IE && X.UA.IE < 5 ){
\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
432 if( elm = this.rawNode ){
\r
433 xnode = new Node( elm.cloneNode( !!opt_clone_children ) );
\r
438 Node._newByText = true;
\r
439 xnode = new Node( this._text );
\r
448 /* --------------------------------------
\r
451 * HtmlElement の場合は内部使用専用 そのため event の破棄等しない
\r
453 Node.prototype.append = function( v ){
\r
454 var elm, i, l, children, frg;
\r
455 if( this._xnodeType !== 1 ) return;
\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
467 this._rawNode.appendChild( frg );
\r
470 for( i = 0; i < l; ++i ){
\r
471 this.append( arguments[ i ] );
\r
477 if( !this._xnodes ) this._xnodes = [];
\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
484 if( document.getElementById ){
\r
485 elm.appendChild( v );
\r
487 if( document.all ){
\r
488 elm.insertAdjacentHTML( 'BeforeEnd', v.outerHTML );
\r
489 v = elm.children[ elm.children.length - 1 ];
\r
494 this._xnodes[ this._xnodes.length ] = new Node( v );
\r
496 case Node.IS_HTML_STRING :
\r
497 case Node.IS_STRING :
\r
498 this.append( X.Dom.parse( v, true ) );
\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
505 if( document.getElementById ){
\r
506 elm.appendChild( v._create() );
\r
507 v._afterCreate( this );
\r
509 if( document.all ){
\r
510 elm.insertAdjacentHTML( 'BeforeEnd', v._create() );
\r
511 v._afterCreate( this );
\r
516 this._xnodes[ this._xnodes.length ] = v;
\r
522 Node.prototype.appendAt = function( start, v ){
\r
523 var children, l, elm, i, prev, next;
\r
525 if( this._xnodeType !== 1 ) return this;
\r
527 if( !( children = this._xnodes ) ) children = this._xnodes = [];
\r
529 l = arguments.length;
\r
530 if( children.length <= start ){
\r
531 if( l === 2 ) return this.append( v );
\r
534 v[ l - 2 ] = arguments[ --l ];
\r
536 return this.append.apply( this, v );
\r
538 if( start < 0 ) start = 0;
\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
549 elm.insertBefore( frg, elm.childNodes[ start ] );
\r
553 this.appendAt( start, arguments[ --l ] );
\r
558 if( !this.parent ){
\r
559 children.splice( start, 0, v );
\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
567 if( document.getElementById ){
\r
568 elm.insertBefore( v, elm.childNodes[ start ] );
\r
570 if( document.all ){
\r
572 elm.insertAdjacentHTML( 'AfterBegin', v.outerHTML );
\r
573 v = elm.children[ 0 ];
\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
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
585 this._ie4reserveUpdate( v );// テキストノードの間に入れる場合!
\r
590 children.splice( start, 0, v );
\r
592 children.splice( start, 0, v );
\r
595 case Node.IS_HTML_STRING :
\r
596 case Node.IS_STRING :
\r
597 v = X.Dom.parse( v, true );
\r
599 for( i = v.length; i; ){
\r
600 this.appendAt( start, v[ --i ] );
\r
604 children.push.apply( children, v );
\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
612 if( document.getElementById ){
\r
613 elm.insertBefore( v._create(), elm.childNodes[ start ] );
\r
614 v._afterCreate( this );
\r
616 if( document.all ){
\r
617 this._ie4reserveUpdate( v );
\r
622 children.splice( start, 0, v );
\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
631 opt_index === undefined ? new Node( parent ).append( this ) : new Node( parent ).appendAt( opt_index, this );
\r
636 Node.prototype.appendToRoot = function( opt_index ){
\r
637 opt_index === undefined ? Node.root.append( this ) : Node.root.appendAt( opt_index, this );
\r
641 /* --------------------------------------
\r
642 * Before , After, Replace
\r
644 Node.prototype.before = function( v ){
\r
646 if( this._xnodeType !== 1 || !( parent = this.parent ) ) return this;
\r
647 l = arguments.length;
\r
649 v = [ this.getOrder() ];
\r
651 v[ l ] = arguments[ --l ];
\r
653 parent.appendAt.apply( parent, v );
\r
656 parent.appendAt( this.getOrder(), v );
\r
660 Node.prototype.after = function( v ){
\r
662 if( this._xnodeType !== 1 || !( parent = this.parent ) ) return this;
\r
663 l = arguments.length;
\r
665 v = [ this.getOrder() + 1 ];
\r
667 v[ l ] = arguments[ --l ];
\r
669 parent.appendAt.apply( parent, v );
\r
672 parent.appendAt( this.getOrder() + 1, v );
\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
681 /* --------------------------------------
\r
684 Node.prototype.remove = function(){
\r
685 var parent = this.parent, elm;
\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
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
703 parent._beforeRemove(); //??
\r
704 parent._ie4reserveUpdate();
\r
710 parent._xnodes.splice( parent._xnodes.indexOf( this ), 1 );
\r
711 delete this.parent;
\r
715 Node.prototype._beforeRemove =
\r
716 document.getElementById ?
\r
718 var elm = this._rawNode, children,
\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
731 var elm = this._ie4getRawNode(),
\r
733 if( children = this._xnodes ){
\r
734 for( i = 0, l = children.length; i < l; ++i ){
\r
735 children[ i ]._beforeRemove();
\r
739 this._migrateEvent();// イベントの退避
\r
740 this._htmlText = elm.outerHTML;
\r
741 elm.removeAttribute( 'id' );
\r
745 Node.prototype.empty =
\r
746 document.getElementById ?
\r
748 var elm = this._rawNode, children,
\r
750 if( children = this._xnodes ){
\r
751 for( i = 0, l = children.length; i < l; ++i ){
\r
752 children[ i ].destroy();
\r
754 children.length = 0;
\r
756 if( elm ) elm.innerHTML = '';
\r
761 var elm = this._ie4getRawNode(),
\r
763 if( children = this._xnodes ){
\r
764 for( i = 0, l = children.length; i < l; ++i ){
\r
765 children[ i ].destroy();
\r
767 children.length = 0;
\r
769 if( elm ) elm.innerHTML = '';
\r
774 /* --------------------------------------
\r
777 Node.prototype.destroy = function(){
\r
778 var elm = this._ie4getRawNode ? this._ie4getRawNode() : this._rawNode,
\r
779 children = this._xnodes, i, l;
\r
782 for( i = 0, l = children.length; i < l; ++i ){
\r
783 children[ i ].destroy();
\r
785 children.length = 0;
\r
787 this._xnodeType === 1 && this.unlisten(); // イベントの退避
\r
789 this._xnodeType === 1 && ( elm.innerHTML = '' );
\r
791 // remove() empty()
\r
793 document.getElementById && this.parent._rawNode.removeChild( elm );
\r
795 delete Node._chashe[ this._uid ];
\r
799 /* --------------------------------------
\r
802 if( !document.getElementById && document.all ){
\r
804 Node.prototype._ie4getRawNode = function(){
\r
806 if( elm = this._rawNode ) return elm;
\r
807 if( this._id && ( elm = this._rawNode = document.all[ this._id ] ) ){
\r
810 if( elm = this._rawNode = document.all[ 'ie4uid' + this._uid ] ){
\r
811 if( this._id ) elm.setAttribute( 'id', this._id );
\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
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
832 Node.prototype._ie4commitUpdate = function(){
\r
833 var children = this._xnodes,
\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
844 if( children && ( l = children.length ) ){
\r
845 for( i = 0; i < l; ++i ){
\r
846 html[ html.length ] = children[ i ]._create( true );
\r
849 this._rawNode.innerHTML = html.join( '' );
\r
853 Node.prototype._ie4afterUpdate = function(){
\r
854 var children = this._xnodes,
\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
864 if( children && ( l = children.length ) ){
\r
865 for( i = 0; i < l; ++i ){
\r
866 children[ i ]._afterCreate( this );
\r
869 delete this._ie4dirtyChildren;
\r
872 Node.prototype._ie4containsDirty = function(){
\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
878 if( children[ --i ]._ie4containsDirty() ) return true;
\r
883 /* --------------------------------------
\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
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
905 //if( document.compareDocumentPosition ){
\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
917 /* --------------------------------------
\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
933 /* --------------------------------------
\r
934 * prevNode, nextNode, firstChild, lastChild
\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
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
951 Node.prototype.firstChild = function(){
\r
952 return this.getChildAt( 0 );
\r
954 Node.prototype.lastChild = function(){
\r
955 return this.getChildAt( this._xnodes.length - 1 );
\r
958 /* --------------------------------------
\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
967 /* --------------------------------------
\r
968 * className, addClass, removeClass, hasClass
\r
970 Node.prototype.className = function( v ){
\r
973 if( typeof v !== 'string' ) return this._className;
\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
983 Node.prototype.addClass = function(){
\r
986 Node.prototype.removeClass = function(){
\r
989 Node.prototype.toggleClass = function(){
\r
992 Node.prototype.hasClass = function( className ){
\r
994 _className = this._className, i, name;
\r
995 if( _className === className ) return true;
\r
996 if( !_className ) return false;
\r
998 _className = _ + _className + _;
\r
999 if( _className.indexOf( _ + className + _ ) !== -1 ) return true; // lucky hit
\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
1009 /* --------------------------------------
\r
1012 Node.prototype.html = function( html ){
\r
1014 if( this._xnodeType === 3 ){
\r
1015 this._text = html;
\r
1016 if( this._rawNode ) this._rawNode.data = html;
\r
1019 return this.empty().append.call( this, X.Dom.parse( html, true ) );
\r
1022 return this._rawNode ? this._rawNode.innerHTML : '';
\r
1025 Node.prototype.text = function( text ){
\r
1028 if( this._xnodeType === 3 ){
\r
1029 this._text = text;
\r
1030 if( this._rawNode ) this._rawNode.data = text;
\r
1033 this.empty().createText( text );
\r
1037 if( this._xnodeType === 1 ){
\r
1040 return this._text;
\r
1043 //})( window, document );
\r