OSDN Git Service

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