OSDN Git Service

Version 0.6.118, fix X.Audio.Sprite & etc.
[pettanr/clientJs.git] / 0.6.x / js / 02_dom / 02_XNode.js
1 var \r
2         X_Node_Dirty = {\r
3                 CLEAN            :  0,\r
4                 CHILD_IS_DIRTY   :  1,\r
5                 ID               :  2, // width, height, x, y\r
6                 CONTENT          :  4, // width, height, x, y textNode の内容\r
7                 CLASSNAME        :  8, // X_Node_CSS_getCharSize, width, height, x, y\r
8                 ATTR             : 16, // X_Node_CSS_getCharSize, width, height, x, y\r
9                 CSS              : 32, // X_Node_CSS_getCharSize, width, height, x, y\r
10                 IE_FILTER        : X_UA.IE < 9 && !X_UA.MacIE ? 64 : 0,\r
11                 UNKNOWN_TAG_FIX  : 128,\r
12                 IE4_TEXTNODE_FIX : 256\r
13         },\r
14         \r
15         X_Node_State = {\r
16                 DESTROYED          : 0,\r
17                 EXIST              : 1, // XNODE_EXIDT, ELEMENT_EXIST\r
18                 BELONG_TREE        : 2, // HAS_PARENT, HAS_PARENT_ACTUAL, BELONG_TREE, BELONG_TREE_ACTUAL\r
19                 DISPLAY_NONE       : 4, // VISIVILITY_HIDDEN(opacity0), DISPALY_NONE\r
20                 DISPLAY_BLOCK      : 8, // remove\r
21                 DISPLAY_INLINE     : 16,// remove\r
22                 POSITION_ABSOLUTE  : 32,\r
23                 OVERFLOW_HIDDEN    : 64,\r
24                 HAS_WIDTH_LENGTH   : 128,\r
25                 HAS_WIDTH_PERCENT  : 256,\r
26                 HAS_HEIGHT_LENGTH  : 512,\r
27                 HAS_HEIGHT_PERCENT : 1024,\r
28                 IE4_ONLY_TEXT      : 2048,\r
29                 IE5_DISPLAY_NONE_FIX : !X_UA.MacIE && X_UA.IE5 ? 4096 : 0 // filterがかかっていると不可? MacIE5.2- は ?\r
30         },\r
31         \r
32         X_Node_TYPE = {\r
33                 XNODE       : 1,\r
34                 RAW_HTML    : 2,\r
35                 RAW_TEXT    : 3,\r
36                 HTML_STRING : 4,\r
37                 STRING      : 5,\r
38                 //DOC_FRAG    : 6,\r
39                 XNODE_LIST  : 7,\r
40                 WINDOW      : 8,\r
41                 DOCUMENT    : 9,\r
42                 IMAGE       : 10\r
43         },\r
44         \r
45         X_Node_strictElmCreation = !X_UA.MacIE && X_UA.IE5678,// && !X_UA.MacIE;\r
46         \r
47         X_Node_useDocumentFragment = document.createDocumentFragment && ( !X_UA.IE || 5.5 <= X_UA.IE ) && document.createDocumentFragment(),\r
48         \r
49         X_Node_newByTag      = false,\r
50         \r
51         X_Node_newByText     = false,\r
52         \r
53         X_Node_outerXNode    = null,\r
54         \r
55         X_Node_updateTimerID = 0,\r
56 /*\r
57  * Node( rawElement | rawTextnode | htmlString | textString )\r
58  */     \r
59         Node = X.Node = X.EventDispatcher.inherits(\r
60         'XDomNode',\r
61         X.Class.POOL_OBJECT,\r
62         {\r
63                 _uid       : 0,\r
64                 _state     : 0,\r
65                 _dirty     : 0,\r
66                 \r
67                 _isNew     : false, // state にまとめる\r
68                 \r
69                 _rawObject : null,\r
70                 _rect      : null, // \r
71                 \r
72                 _root      : null, // xnode が文書ツリーに属しているか?はこれを見る -> state\r
73                 parent     : null, // remove された枝も親子構造は維持している。\r
74                 _xnodes    : null,\r
75         \r
76                 _xnodeType : 0,\r
77                 _tag       : null,\r
78                 _text      : null,\r
79                 _id        : null,\r
80                 _className : '',\r
81 \r
82                 _attrs     : null, // see X_Node_Attr\r
83                 _newAttrs  : null,\r
84                 _attrText  : '', // X_Node_Attr_objToAttrText が必要な場合は false が入っている\r
85                 \r
86                 _css       : null, // see X_Node_CSS\r
87                 _cssText   : null,\r
88                 \r
89                 _fontSize  : 0,\r
90                 \r
91                 _anime     : null,\r
92                 \r
93         /*\r
94          * TODO Node の継承ができない!\r
95          */\r
96                 Constructor : function( v ){\r
97                         var css, xnodes, xnode, parent, uid = X_Node_CHASHE.length;\r
98                         \r
99                         if( X_Node_newByTag ){\r
100                                 X_Node_newByTag = false;\r
101                                 this._tag       = v.toUpperCase();\r
102                                 this._xnodeType = 1;\r
103                                 this._state     = X_Node_State.DISPLAY_INLINE; // TODO\r
104                                 arguments[ 1 ] && this.attr( arguments[ 1 ] );\r
105                                 css = arguments[ 2 ];\r
106                                 css && this[ X.Type.isString( css ) ? 'cssText' : 'css' ]( css );\r
107                         } else\r
108                         if( X_Node_newByText ){\r
109                                 X_Node_newByText = false;\r
110                                 this._text       = v;\r
111                                 this._xnodeType  = 3;\r
112                                 this._state      = X_Node_State.DISPLAY_INLINE;\r
113                         } else {\r
114                                 if( 1 < arguments.length ) return new X_NodeList( arguments );\r
115                                 if( X.Type.isArray( v ) && v.length ) return new X_NodeList( v );\r
116 \r
117                                 switch( X_Node_getType( v ) ){\r
118                                         case X_Node_TYPE.XNODE :\r
119                                         case X_Node_TYPE.XNODE_LIST :\r
120                                                 return v;\r
121                                         case X_Node_TYPE.RAW_HTML :\r
122                                                 if( xnode = X_Node_getXNode( v ) ) return xnode;\r
123                                                 // v.parentNode || v.parentElement : dom1 || dom0\r
124                                                 this.parent     = ( parent = v.parentNode || v.parentElement ) && parent.tagName /* ie7- */ && X_Node_getXNode( parent );\r
125                                                 if( this.parent && this.parent._root ) this._root = this.parent._root;\r
126                                                 this._rawObject = v;\r
127                                                 this._xnodeType = 1;\r
128                                                 this._state     = X_Node_State.DISPLAY_BLOCK; // TODO\r
129                                                 this._tag       = v.tagName.toUpperCase();\r
130                                                 this._id        = v.id;\r
131                                                 this._className = v.className;\r
132                                                 this.cssText( v.style.cssText );\r
133                                                 // X_Node_Dirty.CSS を落とす\r
134                                                 this._dirty = 0;\r
135                                                 // TODO attr の回収は不可能、、、\r
136                                                 if( X_UA_DOM.IE4 ){\r
137                                                         v.setAttribute( 'UID', '' + uid );\r
138                                                 } else {\r
139                                                         v.UID = uid;\r
140                                                 };\r
141                                                 // childNodes...\r
142                                                 break;\r
143                                         case X_Node_TYPE.RAW_TEXT :\r
144                                                 if( xnode = X_Node_getXNode( v ) ) return xnode;\r
145                                                 this.parent     = X_Node_getXNode( v.parentNode );\r
146                                                 if( this.parent && this.parent._root ) this._root = this.parent._root;\r
147                                                 this._rawObject = v;\r
148                                                 this._xnodeType = 3;\r
149                                                 this._state     = X_Node_State.DISPLAY_INLINE;\r
150                                                 this._text      = v.data;\r
151                                                 v.UID = uid;\r
152                                                 break;\r
153                                         case X_Node_TYPE.HTML_STRING :\r
154                                         case X_Node_TYPE.STRING :\r
155                                                 if( xnodes = X_HtmlParser_parse( v, true ) && 1 < xnodes.length ) return new X_NodeList( xnodes );\r
156                                                 if( xnodes.length ) return xnodes[ 0 ];\r
157                                                 return X_Node_none;\r
158                                         /*\r
159                                         case X_Node_TYPE.IMAGE :\r
160                                                 if( xnode = X_Node_getXNode( v ) ) return xnode;\r
161                                                 this._rawObject = v;\r
162                                                 this._xnodeType = 4;\r
163                                                 v.UID           = uid;\r
164                                                 this._state     = X_Node_State.EXIST;\r
165                                                 break; */\r
166                                         default :\r
167                                                 if( X_Node_none ) return X_Node_none;\r
168                                                 return;\r
169                                 };\r
170                         };\r
171                         \r
172                         X_Node_CHASHE[ this._uid = uid ] = this;\r
173                 },\r
174                 \r
175                 create         : X_Node_create,\r
176                 \r
177                 createAt       : X_Node_createAt,\r
178                 \r
179                 createText     : X_Node_createText,\r
180                 \r
181                 createTextAt   : X_Node_createTextAt,\r
182                 \r
183                 clone          : X_Node_clone,\r
184                 \r
185                 append         : X_Node_append,\r
186                 \r
187                 appendAt       : X_Node_appendAt,\r
188                 \r
189                 appendTo       : X_Node_appendTo,\r
190                 \r
191                 appendToRoot   : X_Node_appendToRoot,\r
192                 \r
193                 before         : X_Node_before, // remove\r
194                 \r
195                 prevNode       : X_Node_before, // -> prev\r
196                 \r
197                 after          : X_Node_after, // remove\r
198                 \r
199                 nextNode       : X_Node_after, // -> next\r
200                 \r
201                 replace        : X_Node_replace, // remove\r
202                 \r
203                 swap           : X_Node_replace,\r
204                 \r
205                 remove         : X_Node_remove,\r
206                 \r
207                 empty          : X_Node_empty,\r
208                 \r
209                 destroy        : X_Node_destroy, // -> kill && kill event\r
210                 \r
211                 contains       : X_Node_contains,\r
212                 \r
213                 getChildAt     : X_Node_getChildAt,\r
214                 \r
215                 numChildren    : X_Node_length,\r
216                 \r
217                 firstChild     : X_Node_firstChild,\r
218                 \r
219                 lastChild      : X_Node_lastChild,\r
220                 \r
221                 getOrder       : X_Node_getOrder,\r
222                 \r
223                 className      : X_Node_className,\r
224                 addClass       : X_Node_addClass,\r
225                 removeClass    : X_Node_removeClass,\r
226                 toggleClass    : X_Node_toggleClass,\r
227                 hasClass       : X_Node_hasClass,\r
228                 \r
229                 html           : X_Node_html,\r
230                 text           : X_Node_text,\r
231                 call           : X_Node_call,\r
232                 each           : X_Node_each\r
233                 \r
234         }\r
235 );\r
236 \r
237 function X_Node_getType( v ){\r
238         if( v === '' ) return X_Node_TYPE.STRING;\r
239         if( !v ) return 0;\r
240         if( v === window ) return X_Node_TYPE.WINDOW;\r
241         if( v === document ) return X_Node_TYPE.DOCUMENT;\r
242         if( v.constructor === Node ) return X_Node_TYPE.XNODE;\r
243         if( v.constructor === X_NodeList ) return X_Node_TYPE.XNODE_LIST;\r
244         if( X.Type.isHTMLElement( v ) ) return X_Node_TYPE.RAW_HTML;\r
245         if( v.nodeType === 3 ) return X_Node_TYPE.RAW_TEXT;\r
246         //if( X.Type.isImage( v ) ) return X_Node_TYPE.IMAGE;\r
247         if( X.Type.isString( v ) ){\r
248                 return '<' === v.charAt( 0 ) && v.charAt( v.length - 1 ) === '>' ? X_Node_TYPE.HTML_STRING : X_Node_TYPE.STRING;\r
249         };\r
250         //if( v.nodeType === 11 ) return X_Node_TYPE.DOC_FRAG;\r
251         return 0;\r
252 };\r
253 function X_Node_getXNode( v ){\r
254         var uid, i, chashe, xnode;\r
255         switch( X_Node_getType( v ) ){\r
256                 case X_Node_TYPE.XNODE :\r
257                 case X_Node_TYPE.XNODE_LIST :\r
258                         return v;\r
259                 case X_Node_TYPE.RAW_HTML :\r
260                 //case X_Node_TYPE.IMAGE :\r
261                         // fake TextNode too.\r
262                         if( X_UA_DOM.IE4 ){\r
263                                 uid = v.getAttribute( 'UID' );\r
264                                 return uid && X_Node_CHASHE[ uid ];\r
265                         };\r
266                         return v.UID && X_Node_CHASHE[ v.UID ];\r
267                 case X_Node_TYPE.WINDOW :\r
268                         return X_ViewPort;\r
269                 case X_Node_TYPE.DOCUMENT :\r
270                         return X_ViewPort_document;\r
271                 case X_Node_TYPE.RAW_TEXT :\r
272                         if( v.UID ) return X_Node_CHASHE[ v.UID ];\r
273                         for( chashe = X_Node_CHASHE, i = chashe.length; i; ){\r
274                                 if( ( xnode = X_Node_CHASHE[ --i ] ) && ( xnode._rawObject === v ) ) return xnode;\r
275                         };\r
276         };\r
277 };\r
278 \r
279 function X_Node_getRoot( xnode ){\r
280         return X_ViewPort_document;\r
281         //return X_Node_body._rawObject.documentElement ? node : node.ownerDocument || node.document;\r
282 };\r
283         // XMLかどうかを判別する\r
284 var X_Node_isXmlDocument =\r
285                 X_UA_DOM.IE4 ?\r
286                         X.emptyFunction :\r
287                         (function( root ){\r
288                                 if( X.Type.isBoolean( root.isXML ) ) return root.isXML;\r
289                                 return root.isXML = root._rawObject.createElement( 'p' ).tagName !== root._rawObject.createElement( 'P' ).tagName;\r
290                         }),\r
291         X_Node_CHASHE     = [],\r
292         X_Node_none  = X_Node_CHASHE[ 0 ] = new Node(),\r
293         X_Node_html, // = X_Node_CHASHE[ 1 ] <html>\r
294         X_Node_head, // = X_Node_CHASHE[ 2 ] <head>\r
295         X_Node_body, // = X_Node_CHASHE[ 3 ] <body>\r
296         X_Node_systemNode, // = X_Node_CHASHE[ ? ]\r
297         X_Node_fontSizeNode,\r
298         X_Node_reserveRemoval = [];\r
299 \r
300 \r
301 var X_Node__ie4getRawNode = X_UA_DOM.IE4 && function ( that ){\r
302                 var elm = that._rawObject;\r
303                 return elm ||\r
304                         ( ( elm = document.all[ 'ie4uid' + that._uid ] ) && ( that._rawObject = elm ) ) ||\r
305                         ( that._id && ( elm = document.all[ that._id ] ) ) && ( that._rawObject = elm );\r
306         };\r
307 \r
308 \r
309 /* --------------------------------------\r
310  *  Create\r
311  */\r
312 function X_Node_create( tag, opt_attrs, opt_css ){\r
313         var xnode;\r
314         if( this._xnodeType !== 1 ) return;\r
315         if( !this._xnodes ) this._xnodes = [];\r
316         \r
317         xnode = X_Doc_create( tag, opt_attrs, opt_css );\r
318         \r
319         xnode.parent = this;\r
320         this._xnodes[ this._xnodes.length ] = xnode;\r
321         this._root && X_Node_reserveUpdate();\r
322         return xnode;\r
323 };\r
324 function X_Node_createAt( index, tag, opt_attrs, opt_css ){\r
325         var xnode = X_Doc_create( tag, opt_attrs, opt_css );\r
326         this.appendAt( index, xnode );\r
327         return xnode;\r
328 };\r
329 \r
330 /* --------------------------------------\r
331  *  CreateText\r
332  */\r
333 function X_Node_createText( text ){\r
334         var xnode;\r
335         if( this._xnodeType !== 1 ) return;\r
336         if( !this._xnodes ) this._xnodes = [];\r
337         \r
338         X_Node_newByText = true;\r
339         xnode = new Node( text );\r
340         xnode.parent = this;\r
341         \r
342         this._root && X_Node_reserveUpdate();\r
343         this._xnodes[ this._xnodes.length ] = xnode;\r
344         return xnode;\r
345 };\r
346 function X_Node_createTextAt( index, text ){\r
347         var xtext = X_Doc_createText( text );\r
348         this.appendAt( index, xtext );\r
349         return xtext;\r
350 };\r
351 \r
352 /* --------------------------------------\r
353  *  Clone\r
354  * http://d.hatena.ne.jp/think49/20110724/1311472811\r
355  * http://d.hatena.ne.jp/uupaa/20100508/1273299874\r
356  */\r
357 function X_Node_clone( opt_clone_children ){\r
358         var xnode, xnodes, i, l;\r
359         switch( this._xnodeType ){\r
360                 case 1 :\r
361                         X_Node_newByTag = true;\r
362                         xnode = new Node( this._tag, X_Object_clone( this._attrs ), X_Object_clone( this._css ) )\r
363                                 .attr( { 'id' : this._id } )\r
364                                 .className( this._className );\r
365                         if( opt_clone_children && ( xnodes = this._xnodes ) && ( l = xnodes.length ) ){\r
366                                 for( i = 0; i < l; ++i ){\r
367                                         xnode.append( xnodes[ i ].clone( true ) );\r
368                                 };\r
369                         };\r
370                         return xnode;\r
371                 case 3 :\r
372                         X_Node_newByText = true;\r
373                         xnode = new Node( this._text );\r
374                         return xnode;\r
375                 \r
376                 //case 0 :\r
377                 //case 2 :\r
378         };\r
379         return this;\r
380 };\r
381 \r
382 /* --------------------------------------\r
383  *  Add\r
384  * Node\r
385  * HtmlElement の場合は内部使用専用 そのため event の破棄等しない\r
386  */\r
387 function X_Node_append( v ){\r
388         var i, l, xnodes, frg;\r
389         if( this._xnodeType !== 1 ) return;\r
390         \r
391         if( 1 < ( l = arguments.length ) ){\r
392                 for( i = 0; i < l; ++i ){\r
393                         this.append( arguments[ i ] );\r
394                 };\r
395                 return this;\r
396         };\r
397         \r
398         if( !( xnodes = this._xnodes ) ) this._xnodes = xnodes = [];\r
399         \r
400         switch( X_Node_getType( v ) ){\r
401                 case X_Node_TYPE.RAW_HTML :\r
402                 case X_Node_TYPE.RAW_TEXT :\r
403                         v = new Node( v );\r
404                         break;\r
405                 case X_Node_TYPE.HTML_STRING :\r
406                 case X_Node_TYPE.STRING :\r
407                         return this.append.apply( this, X_HtmlParser_parse( v, true ) );\r
408                 case X_Node_TYPE.XNODE :\r
409                         if( v._xnodeType !== 1 && v._xnodeType !== 3 ) return this;\r
410                         // 親の xnodes から v を消す\r
411                         if( v.parent ){\r
412                                 //if( X_UA_DOM.W3C ){\r
413                                 //      v.parent._xnodes.splice( v.parent._xnodes.indexOf( v ), 1 );\r
414                                 //} else\r
415                                 //if( X_UA_DOM.IE4 ){\r
416                                         v.remove();\r
417                                 //} else {\r
418                                         \r
419                                 //};\r
420                         };// else\r
421                         //if( ( i = X_Node_reserveRemoval.indexOf( v ) ) !== -1 ){\r
422                         //      if( !this._state ) alert( 'xnode already destroyed!' );\r
423                         //      X_Node_reserveRemoval.splice( i, 1 );\r
424                         //};\r
425                         break;\r
426                 default :\r
427                         return this;\r
428         };\r
429 \r
430         v.parent = this;\r
431         xnodes[ xnodes.length ] = v;\r
432         this._root && X_Node_reserveUpdate();\r
433         return this;\r
434 };\r
435 \r
436 \r
437 function X_Node_appendAt( start, v ){\r
438         var xnodes, l, i;\r
439         \r
440         if( this._xnodeType !== 1 ) return this;\r
441         \r
442         l = arguments.length;\r
443         if( !( xnodes = this._xnodes ) ) xnodes = this._xnodes = [];\r
444         \r
445         if( xnodes.length <= start ){\r
446                 if( l === 2 ) return this.append( v );\r
447                 for( i = 1; i < l; ++i ){\r
448                         this.append( arguments[ i ] );\r
449                 };\r
450                 return this;\r
451         };\r
452         if( start < 0 ) start = 0;\r
453         if( 2 < l ){\r
454                 for( ; l; ){\r
455                         this.appendAt( start, arguments[ --l ] );\r
456                 };\r
457                 return this;\r
458         };\r
459 \r
460         switch( X_Node_getType( v ) ){\r
461                 case X_Node_TYPE.RAW_HTML :\r
462                 case X_Node_TYPE.RAW_TEXT :\r
463                         v = new Node( v );\r
464                         break;\r
465                 case X_Node_TYPE.HTML_STRING :\r
466                 case X_Node_TYPE.STRING :\r
467                         v = X_HtmlParser_parse( v, true );\r
468                         for( i = v.length; i; ){\r
469                                 this.appendAt( start, v[ --i ] );\r
470                         };\r
471                         return this;\r
472                 case X_Node_TYPE.XNODE :\r
473                         if( v._xnodeType !== 1 && v._xnodeType !== 3 ) return this;\r
474                         // 親の xnodes から v を消す\r
475                         if( v.parent ){\r
476                                 //if( X_UA_DOM.W3C ){\r
477                                 //      v.parent._xnodes.splice( v.parent._xnodes.indexOf( v ), 1 );\r
478                                 //} else\r
479                                 //if( X_UA_DOM.IE4 ){\r
480                                         v.remove();\r
481                                 //} else {\r
482                                         \r
483                                 //};\r
484                         };// else\r
485                         //if( ( i = X_Node_reserveRemoval.indexOf( v ) ) !== -1 ){\r
486                         //      if( !this._state ) alert( 'xnode already destroyed!' );\r
487                         //      X_Node_reserveRemoval.splice( i, 1 );\r
488                         //};\r
489                         break;\r
490                 default :\r
491                         return this;\r
492         };\r
493 \r
494         v.parent = this;\r
495         this._xnodes.splice( start, 0, v );\r
496         this._root && X_Node_reserveUpdate();\r
497         return this;\r
498 };\r
499 \r
500 function X_Node_appendTo( parent, opt_index ){\r
501         switch( X_Node_getType( parent ) ){\r
502                 case X_Node_TYPE.RAW_HTML :\r
503                         parent = new Node( parent );\r
504                         break;\r
505                 case X_Node_TYPE.HTML_STRING :\r
506                         parent = X_HtmlParser_parse( parent, true );\r
507                         parent = parent[ 0 ] || parent;\r
508                 case X_Node_TYPE.XNODE :\r
509                         break;\r
510                 default :\r
511                         return this;\r
512         };\r
513         opt_index === undefined ? parent.append( this ) : parent.appendAt( opt_index, this );\r
514         return this;\r
515 };\r
516 \r
517 function X_Node_appendToRoot( opt_index ){\r
518         opt_index === undefined ? X_Node_body.append( this ) : X_Node_body.appendAt( opt_index, this );\r
519         return this;\r
520 };\r
521 \r
522 /* --------------------------------------\r
523  *  Before , After, Replace\r
524  */\r
525 function X_Node_before( v ){\r
526         var parent = this.parent, xnodes, i, l, start;\r
527         \r
528         // getter\r
529         if( v === undefined ){\r
530                 if( !parent ) return;\r
531                 xnodes = parent._xnodes;\r
532                 i      = xnodes.indexOf( this );\r
533                 return 0 < i ? xnodes[ i - 1 ] : v;\r
534         };\r
535         \r
536         if( !parent ) return this;\r
537         \r
538         l = arguments.length;\r
539         start = this.getOrder();\r
540         if( 1 < l ){\r
541                 for( ; l; ){\r
542                         parent.appendAt( start, arguments[ --l ] );\r
543                 };\r
544                 return this;\r
545         };\r
546         parent.appendAt( start, v );\r
547         return this;\r
548 };\r
549 \r
550 function X_Node_after( v ){\r
551         var parent = this.parent, xnodes, i, l, start;\r
552         \r
553         // getter\r
554         if( v === undefined ){\r
555                 if( !parent ) return;\r
556                 xnodes = parent._xnodes;\r
557                 i      = xnodes.indexOf( this );\r
558                 return ++i < xnodes.length ? xnodes[ i ] : v;\r
559         };\r
560         \r
561         if( !parent ) return this;\r
562         \r
563         l = arguments.length;\r
564         start = this.getOrder() + 1;\r
565         if( parent._xnodes.length <= start ){\r
566                 if( 1 < l ){\r
567                         for( i = 0; i < l; ++i ){\r
568                                 parent.append( arguments[ i ] );\r
569                         };\r
570                         return this;\r
571                 };\r
572                 parent.append( v );\r
573                 return this;\r
574         };\r
575         if( 1 < l ){\r
576                 for( ; l; ){\r
577                         parent.appendAt( start, arguments[ --l ] );\r
578                 };\r
579                 return this;\r
580         };\r
581         parent.appendAt( start, v );\r
582         return this;\r
583 };\r
584 \r
585 function X_Node_replace( v ){\r
586         if( !this.parent ) return this;\r
587         return arguments.length === 1 ? this.before( v ).remove() : this.before.apply( this, arguments ).remove();\r
588 };\r
589 \r
590 /* --------------------------------------\r
591  *  Remove\r
592  */\r
593 function X_Node_remove(){\r
594         var parent = this.parent;\r
595         \r
596         if( !parent ) return this;\r
597 \r
598         parent._xnodes.splice( parent._xnodes.indexOf( this ), 1 );\r
599         if( this._root ){\r
600                 X_Node_reserveRemoval[ X_Node_reserveRemoval.length ] = this;\r
601                 X_Node_reserveUpdate();\r
602         };\r
603         delete this.parent;\r
604         delete this._root;\r
605         return this;\r
606 };\r
607 \r
608 function X_Node_empty(){\r
609         var xnodes = this._xnodes, i;\r
610         if( xnodes && ( i = xnodes.length ) ){\r
611                 for( ; i; ){\r
612                         xnodes[ --i ].destroy();\r
613                 };\r
614                 xnodes.length = 0;\r
615         };\r
616         return this;\r
617 };\r
618 \r
619 /* --------------------------------------\r
620  *  destory\r
621  */\r
622 // Node._destroyChildFlag = false; // TODO\r
623 \r
624 function X_Node_destroy( isChild ){\r
625         var xnodes = this._xnodes, i, elm;\r
626         \r
627         if( !this._state ) return;\r
628         \r
629         elm = this._rawObject || X_UA_DOM.IE4 && X_Node__ie4getRawNode( this );\r
630         \r
631         if( xnodes && ( i = xnodes.length ) ){\r
632                 //for( ; i; ){\r
633                 //      xnodes[ --i ].destroy( true );\r
634                 //};\r
635         };\r
636         elm && this._listeners && this.unlisten(); // イベントの退避\r
637 \r
638         delete X_Node_CHASHE[ this._uid ];\r
639         delete this._state;\r
640         \r
641         if( this._root ){\r
642                 !isChild && this.remove();\r
643         } else {\r
644                 this.parent && this.parent._xnodes.splice( this.parent._xnodes.indexOf( this ), 1 );\r
645                 elm && !isChild && X_Node__actualRemove( this );\r
646                 this.kill();\r
647         };\r
648 };\r
649 \r
650 \r
651 \r
652 /* --------------------------------------\r
653  *  contains\r
654  */\r
655 function X_Node_contains( v ){\r
656         var elm, type, xnodes, i;\r
657         if( !v || this._xnodeType !== 1 ) return false;\r
658         // contains ie4+\r
659         if( ( elm = this._rawObject || X_UA_DOM.IE4 && X_Node__ie4getRawNode( this ) ) && document.contains && ( type = X_Node_getType( v ) ) && ( type === X_Node_TYPE.RAW_HTML || type === X_Node_TYPE.RAW_TEXT ) ){\r
660                 return elm.contains( v );       \r
661         };\r
662         //if( document.compareDocumentPosition ){\r
663         //      \r
664         //};\r
665         xnodes = this._xnodes;\r
666         if( !xnodes || !xnodes.length ) return false;\r
667         if( xnodes.indexOf( v ) !== -1 ) return true; // fast\r
668         if( elm === v.parentNode ) return false;\r
669         for( i = xnodes.length; i; ){\r
670                 if( xnodes[ --i ].contains( v ) ) return true;\r
671         };\r
672         return false;\r
673 };\r
674 \r
675 /* --------------------------------------\r
676  *  getChild\r
677  */\r
678 function X_Node_getChildAt( i ){\r
679         var xnodes = this._xnodeType === 1 && this._xnodes;\r
680         return xnodes && 0 <= i && i < xnodes.length && xnodes[ i ];\r
681 };\r
682 \r
683 function X_Node_length(){\r
684         var xnodes = this._xnodes;\r
685         return xnodes ? xnodes.length : 0;\r
686 };\r
687 \r
688 /* --------------------------------------\r
689  *  firstChild, lastChild\r
690  */\r
691 function X_Node_firstChild(){\r
692         return this.getChildAt( 0 );\r
693 };\r
694 function X_Node_lastChild(){\r
695         return this.getChildAt( this._xnodes.length - 1 );\r
696 };\r
697 \r
698 /* --------------------------------------\r
699  *  getOrder\r
700  */\r
701 function X_Node_getOrder(){\r
702         var parent = this.parent;\r
703         if( !parent ) return -1;\r
704         return parent._xnodes.indexOf( this );\r
705 };\r
706 \r
707 /* --------------------------------------\r
708  *  className, addClass, removeClass, hasClass\r
709  */\r
710 function X_Node_className( v ){\r
711         var node, _, __;\r
712         // getter\r
713         if( v === undefined ) return this._className;\r
714         \r
715         // setter\r
716         if( this._className === v ) return this;\r
717         if( !v || typeof v !== 'string' ){\r
718                 delete this._className;\r
719         } else {\r
720                 // cleanup\r
721                 _  = ' ';\r
722                 __ = '  ';\r
723                 while( v.indexOf( __ ) !== -1 ){ v = v.split( __ ).join( _ ); };\r
724                 v.charAt( 0 ) === _ && ( v = v.substr( 1 ) );\r
725                 v.lastIndexOf( _ ) === 0 && ( v = v.substr( 0, v.length - 1 ) );\r
726                 \r
727                 if( this._className === v ) return this;\r
728                 v ? ( this._className = v ) : delete this._className;\r
729         };\r
730         this._dirty |= X_Node_Dirty.CLASSNAME;\r
731         this._root && X_Node_reserveUpdate();\r
732         return this;\r
733 };\r
734 function X_Node_addClass( v ){\r
735         var names = v.split( ' ' ),\r
736                 i     = names.length,\r
737                 name;\r
738         v = '';\r
739         for( ; i; ){\r
740                 name = names[ --i ];\r
741                 if( !name ) continue;\r
742                 !this.hasClass( name ) && ( v += ( v ? ' ' : '' ) + name );\r
743         };\r
744         return v ? this.className( this._className + ( this._className ? ' ' : '' ) + v ) : this;\r
745 };\r
746 function X_Node_removeClass( v ){\r
747         var _          = ' ',\r
748                 className  = this._className,\r
749                 names      = v.split( _ ),\r
750                 classNames, i, f, j;\r
751         if( !className ) return this;\r
752         for( classNames = className.split( _ ), i = classNames.length; i; ){\r
753                 className = classNames[ --i ];\r
754                 for( j = names.length; j; ){\r
755                         if( className === names[ --j ] ){\r
756                                 classNames.splice( i, 1 );\r
757                                 names.splice( j, 1 );\r
758                                 f = true;\r
759                                 break;\r
760                         };\r
761                 };\r
762         };\r
763         return f ? this.className( classNames.join( _ ) ) : this;\r
764 };\r
765 function X_Node_toggleClass( v, opt_toggle ){\r
766         var names, i, name;\r
767         if( opt_toggle !== undefined ){\r
768                 return !!opt_toggle ? this.addClass( v ) : this.removeClass( v );       \r
769         };\r
770         names = v.split( ' ' );\r
771         for( i = names.length; i; ){\r
772                 name = names[ --i ];\r
773                 this.hasClass( name ) ? this.removeClass( name ) : this.addClass( name );\r
774         };\r
775         return this;\r
776 };\r
777 function X_Node_hasClass( v ){\r
778         var _ = ' ',\r
779                 className = this._className,\r
780                 i, name;\r
781         if( className === v ) return true;\r
782         if( !className ) return false;\r
783         \r
784         className = _ + className + _;\r
785         if( className.indexOf( _ + v + _ ) !== -1 ) return true; // lucky hit\r
786         \r
787         for( v = v.split( _ ), i = v.length; i; ){\r
788                 name = v[ --i ];\r
789                 if( name === '' ) continue;\r
790                 if( className.indexOf( _ + name + _ ) === -1 ) return false;\r
791         };\r
792         return true;\r
793 };\r
794 \r
795 /* --------------------------------------\r
796  *  html, text\r
797  */\r
798 \r
799 function X_Node_html( html ){\r
800         var _ = '', q = '"', xnodes, n, i, l;\r
801         // setter\r
802         if( html !== undefined ){ // String 以外に Number や false null なども許可\r
803                 if( this._xnodeType === 3 ) return this.text( html );\r
804                 return html ? this.empty().append.apply( this, X_HtmlParser_parse( html, true ) ) : this.empty();\r
805         };\r
806         \r
807         // getter\r
808         if( this._xnodeType === 3 ){\r
809                 return this._text;\r
810         };\r
811         \r
812         if( this._dirty & X_Node_Dirty.CSS && !( this._cssText = X_Node_CSS_objToCssText( this ) ) ){\r
813                 delete this._cssText;\r
814         };\r
815         html = !X_Node_outerXNode ? [] : [\r
816                 '<', this._tag,\r
817                 this._id ? ' id="' + this._id + q : _,\r
818                 this._className ? ' class="' + this._className + q : _,\r
819                 this._attrText === false ? ( this._attrText = X_Node_Attr_objToAttrText( this._attrs ) ) : this._attrText,\r
820                 this._cssText ? ' style="' + this._cssText + q : _,\r
821         '>' ];\r
822         \r
823         n = html.length;\r
824         if( ( xnodes = this._xnodes ) && ( l = xnodes.length ) ){\r
825                 if( !X_Node_outerXNode ) X_Node_outerXNode = this;\r
826                 for( i = 0; i < l; ++i ){\r
827                         html[ n ] = xnodes[ i ].html();\r
828                         ++n;\r
829                 };\r
830                 if( X_Node_outerXNode === this )  X_Node_outerXNode = null;\r
831         };\r
832         !X_Node_outerXNode || X_Dom_DTD_EMPTY[ this._tag ] || ( html[ n ] = '<\/' + this._tag + '>' );\r
833         return html.join( _ );\r
834 };\r
835 \r
836 /*\r
837  * null が来たら '', 数値等が来たら文字烈化\r
838  */\r
839 function X_Node_text( text ){\r
840         var xnodes, texts, i, l;\r
841         // setter\r
842         if( text !== undefined ){\r
843                 if( text === null ) text = '';\r
844                 text += '';\r
845                 \r
846                 if( this._xnodeType === 3 ){\r
847                         if( this._text !== text ){\r
848                                 text ? ( this._text = text ) : delete this.text;\r
849                                 this._root && X_Node_reserveUpdate();\r
850                                 this._dirty |= X_Node_Dirty.CONTENT;\r
851                         };\r
852                         return this;\r
853                 };\r
854                 if( !text ) return this.empty();\r
855                 if( ( xnodes = this._xnodes ) && xnodes.length === 1 && xnodes[ 0 ]._xnodeType === 3 ){\r
856                         xnodes[ 0 ].text( text );\r
857                         return this;\r
858                 };\r
859                 this.empty().createText( text );\r
860                 return this;\r
861         };\r
862         // getter\r
863         if( this._xnodeType === 1 ){\r
864                 if( ( xnodes = this._xnodes ) && ( l = xnodes.length ) ){\r
865                         for( texts = [], i = 0; i < l; ++i ){\r
866                                 texts[ i ] = xnodes[ i ].text();\r
867                         };\r
868                         return texts.join( '' );\r
869                 };\r
870                 return '';\r
871         };\r
872         return this._text;\r
873 };\r
874 \r
875 /*\r
876  * HTML要素に対して name の関数を実行しその戻り値を返す。関数に渡す引数も任意に設定できる。\r
877  */\r
878 function X_Node_call( name /*, opt_args... */ ){\r
879         var l = arguments.length - 1,\r
880                 raw, func, args, params, i;\r
881                 \r
882         X_Node_updateTimerID && X_Node_startUpdate();\r
883         \r
884         raw  = this._rawObject || X_UA_DOM.IE4 && X_Node__ie4getRawNode( this );\r
885         if( !raw ) return;\r
886         \r
887         func = raw[ name ];\r
888         if( X.Type.isFunction( func ) ){\r
889                 if( l ){\r
890                         args = X_Object_cloneArray( arguments );\r
891                         args.shift();\r
892                         return func.apply( raw, args );\r
893                 };\r
894                 return raw[ name ]();           \r
895         } else\r
896         if( X.Type.isUnknown( func ) ){\r
897                 // typeof func === unknown に対策\r
898                 // http://la.ma.la/blog/diary_200509031529.htm          \r
899                 if( l ){\r
900                         args = X_Object_cloneArray( arguments );\r
901                         args.shift();\r
902                         \r
903                 params = [];\r
904                 for( i = 0; i < l; ++i ){\r
905                         params[ i ] = '_' + i;\r
906                 };\r
907                 params = params.join( ',' );\r
908                 return Function(\r
909                         params,\r
910                     [ 'return this.', name, '(', params, ')' ].join( '' )\r
911                 ).apply( raw, args );\r
912                 };\r
913                 return raw[ name ]();\r
914         };\r
915 };\r
916 \r
917 /*\r
918  * xnode を this として関数を実行する。 NodeList.each と動作を合わせてあるため関数の戻り値は破棄される。\r
919  * 関数に渡す引数も任意に設定できる。\r
920  */\r
921 function X_Node_each( func /*, opt_args */ ){\r
922         var args;\r
923         if( 1 < arguments.length ){\r
924                 args = X_Object_cloneArray( arguments );\r
925                 args[ 0 ] = 0;          \r
926                 func.apply( this, args );\r
927         } else {\r
928                 func.call( this, 0 );\r
929         };\r
930         return this;\r
931 };\r
932 \r
933 \r
934 /* --------------------------------------\r
935  *  Async commit update\r
936  * \r
937  * state:\r
938  *  0 : no_rawObject\r
939  *  1 : no_parent\r
940  *  2 : no_root\r
941  *  3 : dirty\r
942  *  4 : clean\r
943  * \r
944  * remove :\r
945  * root._reserveRemoval = [] に追加。commitUpdate で remove して state は not_added\r
946  * add :\r
947  * root._reserveRemoval にいたら消す, new_parent._xnodes に挿入 steta は not_added にして commitUpdate を待つ\r
948  */\r
949         \r
950 function X_Node_reserveUpdate(){\r
951         if( !X_Node_updateTimerID ) X_Node_updateTimerID = X.Timer.requestFrame( X_Node_startUpdate );\r
952 };\r
953 \r
954 function X_Node_startUpdate( time ){\r
955         var removal, i, xnode, tmp;\r
956         \r
957         if( !X_Node_updateTimerID || X_ViewPort_readyState < X_TEMP.SYSTEM_EVENT_INIT ){\r
958                 return;\r
959         };\r
960 \r
961         X.Timer.cancelFrame( X_Node_updateTimerID );\r
962         X_Node_updateTimerID = 0;\r
963 \r
964         if( time ){\r
965                 // X.Timer 経由でないと発火しない このイベントでサイズを取ると無限ループに\r
966                 X_System._listeners && X_System._listeners[ X.Event.BEFORE_UPDATE ] && X_System.dispatch( X.Event.BEFORE_UPDATE );\r
967         };\r
968 \r
969         removal = X_Node_reserveRemoval;\r
970         \r
971         //tmp = X_Node_body._rawObject.style.visibility;\r
972         //this._rawObject.style.visibility = 'hidden';\r
973 \r
974         //console.log( '_actualRemove().' );\r
975 \r
976         if( i = removal.length ){\r
977                 for( ; i; ){\r
978                         xnode = removal[ --i ];\r
979                         X_Node__actualRemove( xnode );\r
980                         !X_Node_body._state && xnode.kill();\r
981                 };\r
982                 removal.length = 0;\r
983         };\r
984 \r
985         //console.log( 'start _startUpdate().' );\r
986 \r
987         /* X_Node_html._dirty ? */ X_Node__commitUpdate( X_Node_html ); /* : X_Node__commitUpdate( X_Node_body ); */;\r
988         \r
989         //console.log( 'end of _startUpdate().' );\r
990         \r
991         if( time ){\r
992                 // X.Timer 経由でないと発火しない このイベントでサイズを取ると無限ループに\r
993                 X_System._listeners && X_System._listeners[ X.Event.UPDATED ] && X_System.dispatch( X.Event.UPDATED );  \r
994         };\r
995         \r
996         X_ViewPort._listeners && X_ViewPort._listeners[ X.Event.AFTER_UPDATE ] && X_ViewPort.asyncDispatch( X.Event.AFTER_UPDATE );\r
997         //this._rawObject.style.visibility = tmp;\r
998 };\r
999 \r
1000 var X_Node__commitUpdate =\r
1001         X_UA_DOM.W3C ?\r
1002                 ( function( that, parentElement, nextElement ){\r
1003                         var elm = that._rawObject,\r
1004                                 xnodes, l, i, frg, next, k, v;\r
1005 \r
1006                         if( that._state & X_Node_State.IE5_DISPLAY_NONE_FIX ){\r
1007                                 //alert( that._tag + ' ' + !!elm );\r
1008                                 // filter の効いている要素だけdisplay:none が無視される模様。filter を切ればよい?\r
1009                                 // 親が、display:none の場合は?\r
1010                                 elm && elm.parentNode && X_Node__actualRemove( that );\r
1011                                 return nextElement;\r
1012                         };\r
1013 \r
1014                         if( !elm || ( parentElement && elm.parentNode !== parentElement ) || ( nextElement && elm.nextSibling !== nextElement ) ){\r
1015                                 nextElement ?\r
1016                                         parentElement.insertBefore( X_Node__actualCreate( that ), nextElement ) :\r
1017                                         parentElement.appendChild( X_Node__actualCreate( that ) );\r
1018                                 X_Node__afterActualCreate( that );\r
1019 \r
1020                                 return elm || that._rawObject;\r
1021                         } else\r
1022                         if( ( xnodes = that._xnodes ) && ( l = xnodes.length ) ) {\r
1023                                 \r
1024                                 /*if( elm.childNodes.length !== l && ( frg = X_Node_useDocumentFragment ) ){\r
1025                                         for( i = 0; i < l; ++i ){\r
1026                                                 frg.appendChild( X_Node__actualCreate( xnodes[ i ], true ) );\r
1027                                         };\r
1028                                         elm.appendChild( frg );\r
1029                                 } else {*/\r
1030                                         for( ; l; ){\r
1031                                                 next = X_Node__commitUpdate( xnodes[ --l ], elm, next );\r
1032                                         };\r
1033                                 //};\r
1034                         };\r
1035 \r
1036                         delete that._fontSize;\r
1037                         that._dirty && X_Node__updateRawNode( that, elm );\r
1038                         if( that._state & X_Node_State.IE5_DISPLAY_NONE_FIX ){\r
1039                                 return nextElement;\r
1040                         };\r
1041                         return elm;\r
1042                 }) :\r
1043         X_UA_DOM.IE4 ? \r
1044                 ( function( that, parentElement, prevElement ){\r
1045                         var elm    = that._rawObject || X_Node__ie4getRawNode( that ),\r
1046                                 xnodes, l, i, html, text, prev;\r
1047 \r
1048                         if( !elm ){\r
1049                                 prevElement ?\r
1050                                         prevElement.insertAdjacentHTML( 'AfterEnd', X_Node__actualCreate( that ) ) :\r
1051                                         parentElement.insertAdjacentHTML( 'AfterBegin', X_Node__actualCreate( that ) );\r
1052                                 X_Node__afterActualCreate( that );\r
1053                                 return that._rawObject || X_Node__ie4getRawNode( that );\r
1054                         };\r
1055                         \r
1056                         xnodes = that._xnodes;\r
1057                         l      = xnodes ? xnodes.length : 0;\r
1058                         \r
1059                         if( that._dirty & X_Node_Dirty.IE4_TEXTNODE_FIX || ( that._state & X_Node_State.IE4_ONLY_TEXT && ( l !== 1 || xnodes[ 0 ]._xnodeType !== 3 ) ) ){ // 1 < l && elm.children.length === 0\r
1060                                 html = [];\r
1061                                 for( i = 0; i < l; ++i ){\r
1062                                         html[ i ] = X_Node__actualCreate( xnodes[ i ] );\r
1063                                 };\r
1064                                 elm.innerHTML = html.join( '' );\r
1065                                 for( i = 0; i < l; ++i ){\r
1066                                         X_Node__afterActualCreate( xnodes[ i ] );\r
1067                                 };\r
1068                                 that._state &= ~X_Node_State.IE4_ONLY_TEXT;\r
1069                         } else\r
1070                         if( that._state & X_Node_State.IE4_ONLY_TEXT ){ // textNode が swap した場合の検出は、_root で行う\r
1071                                 text = xnodes[ 0 ];\r
1072                                 if( text._dirty || !text._root ){\r
1073                                         elm.innerHTML = text._text;\r
1074                                         delete text._dirty;\r
1075                                         text._root = that._root;                                        \r
1076                                 };\r
1077                         } else\r
1078                         if( l ){\r
1079                                 for( i = 0; i < l; ++i ){\r
1080                                         prev = X_Node__commitUpdate( xnodes[ i ], elm, prev );\r
1081                                 };\r
1082                         };\r
1083                         \r
1084                         delete that._fontSize;\r
1085                         that._dirty && X_Node__updateRawNode( that, elm );\r
1086                         return elm;\r
1087                 }) :\r
1088                 (function(){});\r
1089 \r
1090 var X_Node__updateRawNode =\r
1091         X_UA_DOM.W3C ?\r
1092                 ( function( that, elm ){\r
1093                         var attrs, rename, k, v;\r
1094 \r
1095                         // textNode\r
1096                         if( that._dirty & X_Node_Dirty.CONTENT ){\r
1097                                 elm.data = X_String_chrReferanceTo( that._text );\r
1098                                 delete that._dirty;\r
1099                                 return;\r
1100                         };\r
1101                         // id\r
1102                         if( that._dirty & X_Node_Dirty.ID ){\r
1103                                 that._id ? ( elm.id = that._id ) : ( elm.id && elm.removeAttribute( 'id' ) );           \r
1104                         };\r
1105                         // className\r
1106                         if( that._dirty & X_Node_Dirty.CLASSNAME ){\r
1107                                 that._className ? ( elm.className = that._className ) : ( elm.className && elm.removeAttribute( X_UA.IE5678 ? 'className' : 'class' ) ); // className は ie7-?                         \r
1108 \r
1109                                 // ie5 only\r
1110                                 if( X_Node_State.IE5_DISPLAY_NONE_FIX && elm.currentStyle.display === 'none' ){\r
1111                                         X_Node__actualRemove( that );\r
1112                                         that._state |= X_Node_State.IE5_DISPLAY_NONE_FIX;\r
1113                                         return;\r
1114                                 };\r
1115                         };\r
1116                         \r
1117                         // style\r
1118                         // TODO display:none の場合、更新をスキップ\r
1119                         if( that._dirty & X_Node_Dirty.CSS ){\r
1120                                 if( that._cssText !== null || ( that._cssText = X_Node_CSS_objToCssText( that ) ) ){\r
1121                                         X_UA.Opera78 || X_UA.NN6 ?\r
1122                                                 elm.setAttribute( 'style', that._cssText ) : // opera8用\r
1123                                                 ( elm.style.cssText = that._cssText );\r
1124                                 } else {\r
1125                                         elm.style.cssText = ''; // IE5.5以下 Safari3.2 で必要\r
1126                                         elm.removeAttribute( 'style' );\r
1127                                         delete that._cssText;\r
1128                                 };\r
1129                         };\r
1130                         \r
1131                         if( that._dirty & X_Node_Dirty.IE_FILTER ){\r
1132                                 elm.style.filter = X_Node_CSS_objToIEFilterText( that );;\r
1133                         };\r
1134                         \r
1135                         // attr\r
1136                         // TODO display:none の場合、更新をスキップ\r
1137                         if( that._dirty & X_Node_Dirty.ATTR && ( attrs = that._newAttrs || that._attrs ) ){\r
1138                                 rename = X_Node_Attr_renameForDOM;\r
1139                                 for( k in attrs ){\r
1140                                         if( !X_UA.MacIE && ( X_UA.IE5 || X_UA.IE55 ) ){ // IETester 5.5 ではエラーが出なかった.MultipulIE5.5 ではエラーが出たので\r
1141                                                 if( that._tag === 'TEXTAREA' && k === 'value' ){\r
1142                                                         elm.firstChild ?\r
1143                                                                 ( elm.firstChild.data = attrs[ k ] ) :\r
1144                                                                 elm.appendChild( document.createTextNode( attrs[ k ] ) );\r
1145                                                         continue;\r
1146                                                 };\r
1147                                         };\r
1148                                         // TODO IE では input, なぜか buttonも、type の変更が出来ない、object も 同値で置き換えようとしても不可\r
1149                                         ( v = attrs[ k ] ) === undefined ?\r
1150                                                 elm.removeAttribute( rename[ k ] || k ) :\r
1151                                                 ( elm[ rename[ k ] || k ] = X_Node_Attr_noValue[ k ] ? k : v );                         \r
1152 \r
1153                                 };\r
1154                                 delete that._newAttrs;\r
1155                         };\r
1156                         \r
1157                         delete that._dirty;\r
1158                 }) :\r
1159         X_UA_DOM.IE4 ? \r
1160                 ( function( that, elm ){\r
1161                         var attrs, rename, k, v;\r
1162 \r
1163                         // fake textNode\r
1164                         if( that._dirty & X_Node_Dirty.CONTENT ){\r
1165                                 elm.innerText = that._text;\r
1166                                 delete that._dirty;\r
1167                                 return;\r
1168                         };\r
1169                         \r
1170                 /*\r
1171                  * http://www.tohoho-web.com/js/element.htm\r
1172                  * title、className、id、lang、language には setAttribute でなく、element.id で直接読み書きできる\r
1173                  */     \r
1174                         // id\r
1175                         if( that._dirty & X_Node_Dirty.CONTENT ) elm.setAttribute( 'id', that._id || ( 'ie4uid' + xnode._uid ) );\r
1176 \r
1177                         // className\r
1178                         if( that._dirty & X_Node_Dirty.CLASSNAME ){\r
1179                                 that._className ? ( elm.className = that._className ) : elm.removeAttribute( 'class' );\r
1180                         };\r
1181                         // style\r
1182                         if( that._dirty & X_Node_Dirty.CSS ){\r
1183                                 if( that._cssText !== null || ( that._cssText = X_Node_CSS_objToCssText( that ) ) ){\r
1184                                         elm.style.cssText = that._cssText;\r
1185                                 } else {\r
1186                                         elm.style.cssText = '';\r
1187                                         elm.removeAttribute( 'style' );\r
1188                                         delete that._cssText;\r
1189                                 };\r
1190                         };\r
1191                         \r
1192                         if( that._dirty & X_Node_Dirty.IE_FILTER ){\r
1193                                 that._rawObject.style.filter = X_Node_CSS_objToIEFilterText( that );;\r
1194                         };\r
1195                         \r
1196                         // attr\r
1197                         if( that._dirty & X_Node_Dirty.ATTR && ( attrs = that._newAttrs || that._attrs ) ){\r
1198                                 rename = X_Node_Attr_renameForDOM;\r
1199                                 for( k in attrs ){\r
1200                                         ( v = attrs[ k ] ) === undefined ?\r
1201                                                 elm.removeAttribute( rename[ k ] || k ) :\r
1202                                         //that._tag === 'TEXTAREA' && k === 'value' ?\r
1203                                         //      ( elm.innerText = v ) :\r
1204                                                 elm.setAttribute( rename[ k ] || k, X_Node_Attr_noValue[ k ] ? k : v );\r
1205                                 };\r
1206                                 delete that._newAttrs;\r
1207                         };\r
1208                         \r
1209                         delete that._dirty;\r
1210                 }) :\r
1211                 (function(){});\r
1212 \r
1213 /* --------------------------------------\r
1214  *  Create\r
1215  * \r
1216  * http://d.hatena.ne.jp/uupaa/20080718/1216362040\r
1217  * DOM Rangeが使える環境(Firefox2+,Opera9+,Safari3+)なら、innerHTMLいらずで、ガーって書けます。\r
1218  * return document.createRange().createContextualFragment("<div><select><option></option></select></div>");\r
1219  * insertAdjacentHTML\r
1220  * \r
1221  * ie7 以下では iframe の frameborder や、input name は、createElement 後に setAttribute しても無視される\r
1222  * \r
1223  * fragument がある場合 children も足して\r
1224  * Mozilla: 1.0+, IE: 5.5+, Netscape: 2.0+, Safari: 1.0+, Opera: 7.0+\r
1225  * ie6 大丈夫?fragment の場合リークしないか?チェックが必要\r
1226  * http://msdn.microsoft.com/ja-jp/library/bb250448%28v=vs.85%29.aspx\r
1227  * \r
1228  * document.createElement of ie4 is only for OPTION & IMAGE.\r
1229  */\r
1230 var X_Node__actualCreate =\r
1231         X_UA_DOM.W3C ? (function( that, isChild ){\r
1232                 var elm = that._rawObject,\r
1233                         xnodes, frg, i, l;\r
1234                 \r
1235                 if( that._xnodeType === 3 ){\r
1236                         if( elm ) return elm;\r
1237                         delete that._dirty;\r
1238                         return that._rawObject = document.createTextNode( X_String_chrReferanceTo( that._text ) );\r
1239                 };\r
1240                 \r
1241                 if( !elm ){\r
1242                         if( that._dirty & X_Node_Dirty.CSS && !( that._cssText = X_Node_CSS_objToCssText( that ) ) ){\r
1243                                 delete that._cssText;\r
1244                         };\r
1245                         that._isNew = true;\r
1246                         that._rawObject = elm =\r
1247                                 X_Node_strictElmCreation ?\r
1248                                         document.createElement( [\r
1249                                                 '<', that._tag,\r
1250                                                         ' UID="', that._uid, '"',\r
1251                                                         that._id ? ' id="' + that._id + '"' : '',\r
1252                                                         that._className ? ' class="' + that._className + '"' : '',\r
1253                                                         that._attrText === false ? ( that._attrText = X_Node_Attr_objToAttrText( that._attrs ) ) : that._attrText,\r
1254                                                         that._cssText ? ' style="' + that._cssText + '"' : '',\r
1255                                                 '>' ].join( '' ) ) :\r
1256                                         document.createElement( that._tag );\r
1257                 };\r
1258                 if( X_Node_useDocumentFragment ){\r
1259                         if( ( xnodes = that._xnodes ) && ( l = xnodes.length ) ){\r
1260                                 !isChild && ( frg = X_Node_useDocumentFragment ).appendChild( elm );\r
1261                                 for( i = 0; i < l; ++i ){\r
1262                                         elm.appendChild( X_Node__actualCreate( xnodes[ i ], true ) );\r
1263                                 };\r
1264                                 return frg || elm;\r
1265                         };\r
1266                 };\r
1267                 \r
1268                 return elm;\r
1269         }) :\r
1270         X_UA_DOM.IE4 ? (function( that, isChild ){\r
1271                 var uid = that._uid,\r
1272                         html, xnodes, n, i, l;\r
1273                 \r
1274                 if( that._xnodeType === 3 ){\r
1275                         html = [ '<FONT id=ie4uid', uid, ' UID="', uid, '">', that._text, '</FONT>' ];// fake textNode\r
1276                         delete that._rawObject;\r
1277                 } else {\r
1278                         if( that._rawObject && !isChild ) X_Node__actualRemove( that, true );\r
1279                         \r
1280                         if( that._dirty & X_Node_Dirty.CSS && !( that._cssText = X_Node_CSS_objToCssText( that ) ) ){\r
1281                                 delete that._cssText;\r
1282                         };\r
1283                         \r
1284                         html = [\r
1285                                 '<', that._tag, ' id=', ( that._id || ( 'ie4uid' + uid ) ), ' UID="', uid, '"',\r
1286                                 that._className ? ' class="' + that._className + '"' : '',\r
1287                                 that._attrText === false ? ( that._attrText = X_Node_Attr_objToAttrText( that._attrs ) ) : that._attrText,\r
1288                                 that._cssText ? ' style="' + that._cssText + '"' : '',\r
1289                         '>' ];\r
1290                         \r
1291                         n = html.length;\r
1292                         if( ( xnodes = that._xnodes ) && ( l = xnodes.length ) ){\r
1293                                 if( l === 1 && xnodes[ 0 ]._xnodeType === 3 ){\r
1294                                         // only textnode\r
1295                                         html[ n ] = xnodes[ 0 ]._text;\r
1296                                         ++n;\r
1297                                         that._state |= X_Node_State.IE4_ONLY_TEXT;\r
1298                                 } else {\r
1299                                         for( i = 0; i < l; ++i ){\r
1300                                                 html[ n ] = X_Node__actualCreate( xnodes[ i ], true );\r
1301                                                 ++n;\r
1302                                         };                                      \r
1303                                 };\r
1304                         };\r
1305                         X_Dom_DTD_EMPTY[ that._tag ] || ( html[ n ] = '<\/' + that._tag + '>' );\r
1306                         \r
1307                         delete that._newAttrs;\r
1308                 };\r
1309                 \r
1310                 return html.join( '' );\r
1311         }) :\r
1312         (function(){});\r
1313 \r
1314 var X_Node__afterActualCreate =\r
1315         X_UA_DOM.W3C ? (function( that ){\r
1316                 var elm = that._rawObject, xnodes, l, attrs, k, i;\r
1317 \r
1318                 that._root  = that.parent._root;\r
1319                 \r
1320                 if( that._xnodeType === 3 ){\r
1321                         that._dirty && X_Node__updateRawNode( that, elm );\r
1322                         return that;\r
1323                 };\r
1324                         \r
1325                 xnodes = that._xnodes;\r
1326                 l      = xnodes && xnodes.length;\r
1327                 \r
1328                 if( that._isNew ){\r
1329                         if( !X_Node_useDocumentFragment && l ){// docFrg が使えない場合、doc 追加後に子を追加\r
1330                                 for( i = 0; i < l; ++i ){\r
1331                                         elm.appendChild( X_Node__actualCreate( xnodes[ i ], true ) );\r
1332                                 };\r
1333                         };\r
1334                         if( X_Node_strictElmCreation ){\r
1335                                 if( that._dirty & X_Node_Dirty.IE_FILTER ){\r
1336                                         elm.style.filter = X_Node_CSS_objToIEFilterText( that );;\r
1337                                 };\r
1338                                 delete that._dirty;\r
1339                         } else {\r
1340                                 elm.UID = that._uid;\r
1341                                 that._newAttrs = that._attrs;\r
1342                                 that._dirty = X_Node_Dirty.ID | X_Node_Dirty.CLASSNAME | X_Node_Dirty.CSS | X_Node_Dirty.ATTR | X_Node_Dirty.IE_FILTER;\r
1343                                 X_Node__updateRawNode( that, elm );\r
1344                         };\r
1345                         \r
1346                         delete that._isNew;\r
1347                 } else {\r
1348                         that._dirty && X_Node__updateRawNode( that, elm );\r
1349                 };\r
1350                 \r
1351                 for( i = 0; i < l; ++i ){\r
1352                         X_Node__afterActualCreate( xnodes[ i ] );\r
1353                 };\r
1354                 // src の onload があるので先ではないか?\r
1355                 // TODO ie の str から要素を作る場合、srcだけ イベント設定後ではないか?\r
1356                 X_EventDispatcher_toggleAllEvents( that, true );// イベントの復帰\r
1357         }) :\r
1358         X_UA_DOM.IE4 ? (function( that ){\r
1359                 var xnodes, i;\r
1360                 that._root = that.parent._root;\r
1361                 \r
1362                 if( that._xnodeType !== 1 ) return that;\r
1363                 \r
1364                 if( ( xnodes = that._xnodes ) && ( i = xnodes.length ) ){\r
1365                         for( ; i; ){\r
1366                                 X_Node__afterActualCreate( xnodes[ --i ] );\r
1367                         };\r
1368                 };\r
1369                 // textarea への value の適用はここで\r
1370                 if( that._dirty & X_Node_Dirty.IE_FILTER ){\r
1371                         X_Node__ie4getRawNode( that ).style.filter = X_Node_CSS_objToIEFilterText( that );;\r
1372                 };\r
1373                 delete that._dirty;\r
1374                 X_EventDispatcher_toggleAllEvents( that, true );// イベントの復帰\r
1375         }) :\r
1376         (function(){});\r
1377 \r
1378 var X_Node__actualRemove =\r
1379         X_UA_DOM.W3C ?\r
1380                 ( function( that, isChild ){\r
1381                         var xnodes = that._xnodes,\r
1382                                 elm    = that._rawObject,\r
1383                                 child, i, l;\r
1384                         if( xnodes && ( l = xnodes.length ) ){\r
1385                                 for( i = 0; i < l; ++i ){\r
1386                                         child = xnodes[ i ];\r
1387                                         child._xnodeType === 1 && X_Node__actualRemove( child, true );\r
1388                                 };\r
1389                         };\r
1390 \r
1391                         if( !elm ) return;\r
1392                         that._listeners && X_EventDispatcher_toggleAllEvents( that, false );// イベントの退避\r
1393                         if( !X_UA.MacIE ){\r
1394                                 // elm.parentNode.tagName for ie7 -> that.state & BELONG_TREE_ACTUAL\r
1395                                 !isChild && elm.parentNode && elm.parentNode.tagName && elm.parentNode.removeChild( elm );\r
1396                         } else {\r
1397                                 !isChild && elm.parentNode && elm.parentNode.tagName && X_TEMP._fixed_remove( elm, that );\r
1398                         };\r
1399                 }) :\r
1400         X_UA_DOM.IE4 ?\r
1401                 ( function( that, isChild ){\r
1402                         var xnodes = that._xnodes,\r
1403                                 elm    = that._rawObject || X_Node__ie4getRawNode( that ),\r
1404                                 i, l, xnode;\r
1405                         if( xnodes && ( l = xnodes.length ) ){\r
1406                                 for( i = 0; i < l; ++i ){\r
1407                                         X_Node__actualRemove( xnodes[ i ], true );\r
1408                                 };\r
1409                         };\r
1410 \r
1411                         if( !elm ) return;\r
1412                         that._listeners && X_EventDispatcher_toggleAllEvents( that, false );// イベントの退避\r
1413                         \r
1414                         if( X_Node_Attr_HAS_VALUE[ that._tag ] && ( !that._newAttrs || !X_Object_inObject( 'value', that._newAttrs ) ) ){\r
1415                                 that._attrs.value = elm.value;\r
1416                         };\r
1417                         elm.removeAttribute( 'id' ); // ?\r
1418                         //document.all[ that._id || ( 'ie4uid' + that._uid ) ] = null; // MacIE5 でエラー\r
1419                         if( !isChild ) elm.outerHTML = '';\r
1420                         delete that._rawObject;\r
1421                 }) :\r
1422                 (function(){});\r
1423 \r
1424 X_ViewPort.listenOnce( X.Event.UNLOAD, X_Node__actualRemove, [ X_Node_html, true ] );\r
1425 \r