1 var X_Node_Attr_noValue = {
\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
24 'charoff' : 'chOff',
\r
25 'codebase' : 'codeBase',
\r
26 'codetype' : 'codeType',
\r
27 'colspan' : 'colSpan',
\r
28 'datetime' : 'dateTime',
\r
30 'frameborder' : 'frameBorder',
\r
31 'http-equiv' : 'httpEquiv',
\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
44 X_Node_Attr_HAS_VALUE = {
\r
50 'PARAM' : true // FlashVars が flash 側から書き換えられるケースがある??
\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
64 // 自由な内容が入るため、参照文字への変換が必要
\r
65 X_Node_Attr_toChrReferance = {
\r
71 X_Node_Attr_renameForTag = {};
\r
72 // http://nanto.asablo.jp/blog/2005/10/29/123294
\r
73 // checked -> defaultChecked
\r
74 // 動的に生成した input 要素を文書ツリーに挿入する前に設定した checked 属性は反映されず、defaultChecked だと反映される
\r
75 // ロードイベントを拾うために、要素生成時にネットワーク関連の属性を設定しない。
\r
76 // -> src (img, iframe, ), link の href, <param name="movie" src=>
\r
78 function X_Node_Attr_objToAttrText( that, skipNetworkForElmCreation ){
\r
79 var obj = that[ '_attrs' ],
\r
80 noValue = X_Node_Attr_noValue,
\r
81 attrs = [ '' ], // 先頭にスペース
\r
82 plain = X_EMPTY_OBJECT,
\r
85 if( skipNetworkForElmCreation ){
\r
86 delete that[ '_newAttrs' ];
\r
87 // このあとで _newAttr にネットワーク系の属性を控える, attrText には加えない
\r
89 that[ '_flags' ] &= ~X_NodeFlags_OLD_ATTRTEXT;
\r
93 if( !obj ){ // Opera7
\r
94 delete that[ '_attrText' ];
\r
99 if( plain[ k ] ) continue;
\r
101 if( skipNetworkForElmCreation ){
\r
103 switch( that[ '_tag' ] + k ){
\r
104 case 'PARAMvalue' :
\r
105 check = obj[ 'name' ] !== 'movie';
\r
107 check = check || ( obj[ 'type' ] !== 'image' );
\r
109 check = check || ( obj[ 'rel' ] !== 'stylesheet' );
\r
111 if( !check ) break;
\r
118 case 'OBJECTdata' :
\r
119 case 'BGSOUNDsrc' :
\r
120 case 'APPLETcode' :
\r
121 //case 'AUDIOsrc' :
\r
122 //case 'VIDEOsrc' :
\r
123 if( !that[ '_newAttrs' ] ) that[ '_newAttrs' ] = {};
\r
124 that[ '_newAttrs' ][ k ] = obj[ k ];
\r
129 attrs[ ++n ] = noValue[ k ] ? k : [
\r
131 X_Node_Attr_toChrReferance[ k ] ? X_String_toChrReferance( obj[ k ] ) : obj[ k ],
\r
136 return that[ '_attrText' ] = attrs.join( ' ' );
\r
138 delete that[ '_attrText' ];
\r
142 (function( renameForDOM, renameForTag ){
\r
144 for( k in renameForDOM ){
\r
145 //if( X_EMPTY_OBJECT[ k ] ) continue;
\r
146 renameForTag[ renameForDOM[ k ] ] = k;
\r
148 })( X_Node_Attr_renameForDOM, X_Node_Attr_renameForTag );
\r
152 * 属性の getter と setter。onclick等はできないので listen, listenOnce を使うこと。http://nanto.asablo.jp/blog/2005/10/29/123294
\r
153 * @alias Node.prototype.attr
\r
154 * @param {string|object} [nameOrObj] 属性名、または追加する属性のハッシュ
\r
155 * @param {string|number} [value=] 属性の値
\r
156 * @return {Node|string|number} getter の場合は値を、setter の場合は自身を返す。(メソッドチェーン)
\r
157 * @example // getter
\r
158 * node.attr( 'tagName' ) === 'DIV';
\r
160 * node.attr( { src : url, width : 100, height : 100 } );
\r
162 * node.attr( 'src', url );
\r
164 function X_Node_attr( nameOrObj /* v */ ){
\r
165 var attrs = this[ '_attrs' ], newAttrs, f, k, elm, v;
\r
167 if( !this[ '_tag' ] ) return this;
\r
169 if( nameOrObj && X_Type_isObject( nameOrObj ) ){
\r
170 attrs || ( attrs = this[ '_attrs' ] = {} );
\r
171 newAttrs = this[ '_newAttrs' ] || ( this[ '_newAttrs' ] = {} );
\r
173 for( k in nameOrObj ){
\r
174 //if( X_EMPTY_OBJECT[ k ] ) continue;
\r
175 if( X_Node_Attr_setAttr( this, attrs, newAttrs, k, nameOrObj[ k ] ) === true ) f = true;
\r
178 delete this[ '_attrText' ];
\r
179 this[ '_flags' ] |= X_NodeFlags_DIRTY_ATTR | X_NodeFlags_OLD_ATTRTEXT;
\r
180 this[ '_flags' ] & X_NodeFlags_IN_TREE && X_Node_reserveUpdate();
\r
184 if( 1 < arguments.length ){
\r
186 if( X_Node_Attr_setAttr( this, attrs || ( this[ '_attrs' ] = {} ), this[ '_newAttrs' ] || ( this[ '_newAttrs' ] = {} ), nameOrObj, arguments[ 1 ] ) === true ){
\r
187 delete this[ '_attrText' ];
\r
188 this[ '_flags' ] |= X_NodeFlags_DIRTY_ATTR | X_NodeFlags_OLD_ATTRTEXT;
\r
189 this[ '_flags' ] & X_NodeFlags_IN_TREE && X_Node_reserveUpdate();
\r
193 if( typeof nameOrObj === 'string' ){
\r
195 switch( nameOrObj ){
\r
197 return this[ '_id' ];
\r
200 return this[ '_className' ];
\r
203 return this[ '_tag' ];
\r
206 return this[ 'cssText' ]();
\r
208 case 'src' : // src は遷移して変化する, name も?
\r
209 if( this[ '_tag' ] !== 'IFRAME' ) break;
\r
210 if( this[ '_newAttrs' ] && X_Object_inObject( nameOrObj, this[ '_newAttrs' ] ) ) return this[ '_newAttrs' ][ nameOrObj ];
\r
211 if( elm = X_UA_DOM.IE4 ? this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) : this[ '_rawObject' ] ){
\r
212 if( !attrs ) attrs = this[ '_attrs' ] = {};
\r
213 return attrs[ nameOrObj ] = elm[ nameOrObj ]; // getAttribute( nameOrObj )?
\r
218 // kquery.js : safariのバグ対策
\r
219 // if ($.browser.safari && key === "selected" && tmp) tmp.selectedIndex;
\r
220 // 親ノードの selectedIndex の getter を呼んでおくと値が正しくなる、ということ?( by itozyun )
\r
221 if( X_UA[ 'WebKit' ] ) this[ '_rawObject' ].parentNode && this[ '_rawObject' ].parentNode.selectedIndex;
\r
223 if( this[ '_tag' ] === 'INPUT' && X_Node_Attr_STATIC_VALUE_TYPES[ attrs[ 'type' ] ] ) break;
\r
226 case 'selectedIndex' :
\r
227 if( X_Node_Attr_HAS_VALUE[ this[ '_tag' ] ] ){
\r
228 if( this[ '_newAttrs' ] && X_Object_inObject( nameOrObj, this[ '_newAttrs' ] ) ) return this[ '_newAttrs' ][ nameOrObj ];
\r
229 if( elm = X_UA_DOM.IE4 ? this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) : this[ '_rawObject' ] ){
\r
230 if( !attrs ) attrs = this[ '_attrs' ] = {};
\r
231 return attrs[ nameOrObj ] = elm[ nameOrObj ]; // getAttribute( nameOrObj )?
\r
236 return attrs && attrs[ X_Node_Attr_renameForTag[ nameOrObj ] || nameOrObj ];
\r
239 function X_Node_Attr_setAttr( that, attrs, newAttrs, name, v ){
\r
243 if( v === 'svg' || v === 'SVG' ){
\r
244 that[ '_flags' ] |= X_NodeFlags_IS_SVG;
\r
246 if( v === 'vml' || v === 'VML' ){
\r
247 that[ '_flags' ] |= X_NodeFlags_IS_VML;
\r
251 // case 'type' : TODO IE は input, button, object に対して type の再設定が出来ない _state が要素生成済なら不可
\r
257 v = ( v !== 'ie4uid' + that[ '_uid' ] ) ? v : undefined;
\r
258 // TODO unique の check
\r
259 if( v !== that[ '_id' ] ){
\r
261 that[ '_flags' ] |= X_NodeFlags_DIRTY_ID;
\r
262 that[ '_flags' ] & X_NodeFlags_IN_TREE && X_Node_reserveUpdate();
\r
267 return that[ 'className' ]( v );
\r
270 return that[ 'cssText' ]( v );
\r
272 return that[ 'text' ]( v );
\r
274 return that[ 'html' ]( v );
\r
277 if( name.indexOf( 'on' ) === 0 ){
\r
278 X.Logger.warn( 'xnode.attr("' + name + '") is wrong, xnode.listen() & xnode.unlisten().' );
\r
282 name = X_Node_Attr_renameForTag[ name ] || name;
\r
283 if( attrs[ name ] === v ) return;
\r
286 newAttrs[ name ] = undefined;
\r
287 if( X_Object_inObject( name, attrs ) ) delete attrs[ name ];
\r
289 newAttrs[ name ] = attrs[ name ] = v;
\r