OSDN Git Service

cd9a1ff8dcc821fa26dfce3c63e246bb11287e03
[pettanr/clientJs.git] / 0.6.x / js / 02_dom / 05_XNodeAttr.js
1 var X_Node_Attr_noValue = {\r
2                 checked  : 1,\r
3                 compact  : 1,\r
4                 declare  : 1,\r
5                 defer    : 1,\r
6                 disabled : 1,\r
7                 ismap    : 1,\r
8                 multiple : 1,\r
9                 nohref   : 1,\r
10                 noresize : 1,\r
11                 noshade  : 1,\r
12                 nowrap   : 1,\r
13                 readonly : 1,\r
14                 selected : 1\r
15 },\r
16 X_Node_Attr_renameForDOM = {\r
17                 'class'          : 'className',\r
18                 accesskey        : 'accessKey',\r
19                 'accept-charset' : 'acceptCharset',\r
20                 bgcolor          : 'bgColor',\r
21                 cellpadding      : 'cellPadding',\r
22                 cellspacing      : 'cellSpacing',\r
23                 'char'           : 'ch',\r
24                 charoff          : 'chOff',\r
25                 codebase         : 'codeBase',\r
26                 codetype         : 'codeType',\r
27                 colspan          : 'colSpan',\r
28                 datetime         : 'dateTime',\r
29                 'for'            : 'htmlFor',\r
30                 frameborder      : 'frameBorder',\r
31                 'http-equiv'     : 'httpEquiv',\r
32                 ismap            : 'isMap',\r
33                 longdesc         : 'longDesc',\r
34                 maxlength        : 'maxLength',\r
35                 nohref           : 'noHref',\r
36                 readonly         : 'readOnly',\r
37                 rowspan          : 'rowSpan',\r
38                 tabindex         : 'tabIndex',\r
39                 usemap           : 'useMap',\r
40                 valuetype        : 'valueType',\r
41                 checked          : 'defaultChecked'\r
42 },\r
43 \r
44 X_Node_Attr_HAS_VALUE = {\r
45                 INPUT    : true,\r
46                 TEXTAREA : true,\r
47                 SELECT   : true,\r
48                 BUTTON   : true,\r
49                 OBJECT   : true,\r
50                 PARAM    : true // FlashVars が flash 側から書き換えられるケースがある??\r
51 },\r
52 \r
53 // <input type=button,hidden,submit,reset,radio,checkbox> の場合、value の値はユーザーで変えることはない\r
54 // <input type=text,password,file> はユーザーによって常に変更される HTML5 ではこれにさらにいろいろ加わる\r
55 X_Node_Attr_STATIC_VALUE_TYPES = {\r
56         button   : true,\r
57         hidden   : true,\r
58         submit   : true,\r
59         reset    : true,\r
60         radio    : true,\r
61         checkbox : true\r
62 },\r
63 \r
64 X_Node_Attr_renameForTag = {};\r
65         // http://nanto.asablo.jp/blog/2005/10/29/123294\r
66         // checked -> defaultChecked\r
67         // 動的に生成した input 要素を文書ツリーに挿入する前に設定した checked 属性は反映されず、defaultChecked だと反映される\r
68         // ロードイベントを拾うために、要素生成時にネットワーク関連の属性を設定しない。\r
69         //  -> src (img, iframe, ), link の href, <param name="movie" src=>\r
70 function X_Node_Attr_objToAttrText( that, skipNetwork, escape ){ // TODO value の escape " -> &quot;\r
71         var obj     = that._attrs,\r
72                 noValue = X_Node_Attr_noValue,\r
73                 attrs   = [ '' ], // 先頭にスペース\r
74                 plain   = X_EMPTY_OBJECT,\r
75                 n = 0, k, hasNetwork;\r
76 \r
77         that._flags &= ~X_Node_State.OLD_ATTRTEXT;\r
78 \r
79         if( !obj ){ // Opera7\r
80                 delete that._attrText;\r
81                 return '';\r
82         };\r
83         for( k in obj ){\r
84                 if( plain[ k ] ) continue;\r
85                 \r
86                 if( skipNetwork ){\r
87                         switch( k ){\r
88                                 case 'value' :\r
89                                         if( that._tag === 'LINK' && that._attr && that._attr.name === 'movie' ){\r
90                                                 hasNetwork = true;\r
91                                                 continue;\r
92                                         };\r
93                                         break;\r
94                                         \r
95                                 case 'src' :\r
96                                         hasNetwork = true;\r
97                                         continue;\r
98                                         \r
99                                 case 'href' :\r
100                                         if( that._tag === 'LINK' ){\r
101                                                 hasNetwork = true;\r
102                                                 continue;\r
103                                         };\r
104                         };\r
105                 };\r
106 \r
107                 attrs[ ++n ] = noValue[ k ] ? k : [\r
108                         k, '="',\r
109                         k === 'value' ? X_String_toChrReferance( obj[ k ] ) : obj[ k ],\r
110                         '"' ].join( '' );\r
111         };\r
112         \r
113         //if( hasNetwork ) that._flags |= X_Node_State.IE_NETWORK_ATTR\r
114         \r
115         if( 0 < n ){\r
116                 return that._attrText = attrs.join( ' ' );\r
117         };\r
118         delete that._attrText;\r
119         return '';\r
120 };\r
121 \r
122 (function( renameForDOM, renameForTag ){\r
123         var k, i;\r
124         for( k in renameForDOM ){\r
125                 //if( X_EMPTY_OBJECT[ k ] ) continue;\r
126                 renameForTag[ renameForDOM[ k ] ] = k;\r
127         };\r
128 })( X_Node_Attr_renameForDOM, X_Node_Attr_renameForTag );\r
129 \r
130 \r
131 \r
132 /* --------------------------------------\r
133  *  attribute\r
134  * \r
135  * http://nanto.asablo.jp/blog/2005/10/29/123294\r
136  * className, onclick等 はここで設定しない\r
137  * \r
138  */\r
139 Node.prototype.attr = function( nameOrObj /* v */ ){\r
140         var attrs = this._attrs, newAttrs, f, k, elm, v;\r
141         \r
142         if( !this._tag ) return this;\r
143         \r
144         if( nameOrObj && X.Type.isObject( nameOrObj ) ){\r
145                 attrs || ( attrs = this._attrs = {} );\r
146                 newAttrs = this._newAttrs || ( this._newAttrs = {} );\r
147                 \r
148                 for( k in nameOrObj ){\r
149                         //if( X_EMPTY_OBJECT[ k ] ) continue;\r
150                         if( X_Node_Attr_setAttr( this, attrs, newAttrs, k, nameOrObj[ k ] ) === true ) f = true;\r
151                 };\r
152                 if( f ){\r
153                         delete this._attrText;\r
154                         this._flags |= X_Node_State.DIRTY_ATTR | X_Node_State.OLD_ATTRTEXT;\r
155                         this._flags & X_Node_State.IN_TREE && X_Node_reserveUpdate();\r
156                 };\r
157                 return this;\r
158         } else\r
159         if( 1 < arguments.length ){\r
160                 // setter\r
161                 if( X_Node_Attr_setAttr( this, attrs || ( this._attrs = {} ), this._newAttrs || ( this._newAttrs = {} ), nameOrObj, arguments[ 1 ] ) === true ){\r
162                         delete this._attrText;\r
163                         this._flags |= X_Node_State.DIRTY_ATTR | X_Node_State.OLD_ATTRTEXT;\r
164                         this._flags & X_Node_State.IN_TREE && X_Node_reserveUpdate();\r
165                 };\r
166                 return this;\r
167         } else\r
168         if( typeof nameOrObj === 'string' ){\r
169                 // getter\r
170                 switch( nameOrObj ){\r
171                         case 'id' :\r
172                                 return this._id;\r
173                         case 'class' :\r
174                         case 'className' :\r
175                                 return this._className;\r
176                         case 'tag' :\r
177                         case 'tagName' :\r
178                                 return this._tag;\r
179                         case 'style' :\r
180                         case 'cssText' :\r
181                                 return this.cssText();\r
182 \r
183                         case 'src' : // src は遷移して変化する, name も?\r
184                                 if( this._tag !== 'IFRAME' ) break;\r
185                                 if( this._newAttrs && X_Object_inObject( nameOrObj, this._newAttrs ) ) return this._newAttrs[ nameOrObj ];\r
186                                 if( elm = X_UA_DOM.IE4 ? this._rawObject || X_Node__ie4getRawNode( this ) : this._rawObject ){\r
187                                         if( !attrs ) attrs = this._attrs = {};\r
188                                         return attrs[ nameOrObj ] = elm[ nameOrObj ]; // getAttribute( nameOrObj )?\r
189                                 };\r
190                                 break;\r
191                                 \r
192                         case 'selected' :\r
193                                 // kquery.js : safariのバグ対策\r
194                                 // if ($.browser.safari && key === "selected" && tmp) tmp.selectedIndex;\r
195                                 // 親ノードの selectedIndex の getter を呼んでおくと値が正しくなる、ということ?( by itozyun )\r
196                                 if( X_UA.WebKit ) this._rawObject.parentNode && this._rawObject.parentNode.selectedIndex;\r
197                         case 'value' :\r
198                                 if( this._tag === 'INPUT' && X_Node_Attr_STATIC_VALUE_TYPES[ attrs[ 'type' ] ] ) break;\r
199                         case 'checked' :\r
200                         case 'disabled' :                       \r
201                         case 'selectedIndex' :\r
202                                 if( X_Node_Attr_HAS_VALUE[ this._tag ] ){\r
203                                         if( this._newAttrs && X_Object_inObject( nameOrObj, this._newAttrs ) ) return this._newAttrs[ nameOrObj ];\r
204                                         if( elm = X_UA_DOM.IE4 ? this._rawObject || X_Node__ie4getRawNode( this ) : this._rawObject ){\r
205                                                 if( !attrs ) attrs = this._attrs = {};\r
206                                                 return attrs[ nameOrObj ] = elm[ nameOrObj ]; // getAttribute( nameOrObj )?\r
207                                         };\r
208                                 };\r
209                                 break;\r
210                 };\r
211                 return attrs && attrs[ X_Node_Attr_renameForTag[ nameOrObj ] || nameOrObj ];\r
212         };\r
213 };\r
214 function X_Node_Attr_setAttr( that, attrs, newAttrs, name, v ){\r
215         switch( name ){\r
216                 // case 'type' : TODO IE は input, button, object に対して type の再設定が出来ない _state が要素生成済なら不可\r
217                 case 'UID' :\r
218                 case 'tag' :\r
219                 case 'tagName' :\r
220                         return;\r
221                 case 'id' :\r
222                         v = ( v !== 'ie4uid' + that._uid ) ? v : undefined;\r
223                         // TODO unique の check\r
224                         if( v !== that._id ){\r
225                                 that._id = v;\r
226                                 that._flags |= X_Node_State.DIRTY_ID;\r
227                                 that._flags & X_Node_State.IN_TREE && X_Node_reserveUpdate();\r
228                         };\r
229                         return; \r
230                 case 'class' :\r
231                 case 'className' :\r
232                         return that.className( v );\r
233                 case 'style' :\r
234                 case 'cssText' :\r
235                         return that.cssText( v );\r
236                 case 'text' :\r
237                         return that.text( v );\r
238                 case 'html' :\r
239                         return that.html( v );\r
240         };\r
241         // debug\r
242         if( name.indexOf( 'on' ) === 0 ){\r
243                 X.Logger.warn( 'xnode.attr("' + name + '") is wrong, xnode.listen() & xnode.unlisten().' );\r
244                 return;\r
245         };\r
246         \r
247         name = X_Node_Attr_renameForTag[ name ] || name;\r
248         if( attrs[ name ] === v ) return;\r
249         \r
250         if( v == null ){\r
251                 newAttrs[ name ] = undefined;\r
252                 if( X_Object_inObject( name, attrs ) ) delete attrs[ name ];\r
253         } else {\r
254                 newAttrs[ name ] = attrs[ name ] = v;\r
255         };\r
256         return true;\r
257 };\r
258 \r