X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=0.6.x%2Fjs%2F02_dom%2F05_XNodeAttr.js;h=3f9a059e5367cf95f8af9f8fc9af359e2828832a;hb=6c4c72f7e862c9f950bfb3562adda24c39498abd;hp=8b1237ad843b2462e9a14b4d39c0ccd0de98adfe;hpb=dc5a75639232882249108b4f708916e9690e42b3;p=pettanr%2FclientJs.git diff --git a/0.6.x/js/02_dom/05_XNodeAttr.js b/0.6.x/js/02_dom/05_XNodeAttr.js index 8b1237a..3f9a059 100644 --- a/0.6.x/js/02_dom/05_XNodeAttr.js +++ b/0.6.x/js/02_dom/05_XNodeAttr.js @@ -1,88 +1,146 @@ var X_Node_Attr_noValue = { - checked : 1, - compact : 1, - declare : 1, - defer : 1, - disabled : 1, - ismap : 1, - multiple : 1, - nohref : 1, - noresize : 1, - noshade : 1, - nowrap : 1, - readonly : 1, - selected : 1 + 'checked' : 1, + 'compact' : 1, + 'declare' : 1, + 'defer' : 1, + 'disabled' : 1, + 'ismap' : 1, + 'multiple' : 1, + 'nohref' : 1, + 'noresize' : 1, + 'noshade' : 1, + 'nowrap' : 1, + 'readonly' : 1, + 'selected' : 1 }, X_Node_Attr_renameForDOM = { - 'class' : 'className', - accesskey : 'accessKey', - 'accept-charset' : 'acceptCharset', - bgcolor : 'bgColor', - cellpadding : 'cellPadding', - cellspacing : 'cellSpacing', - 'char' : 'ch', - charoff : 'chOff', - codebase : 'codeBase', - codetype : 'codeType', - colspan : 'colSpan', - datetime : 'dateTime', - 'for' : 'htmlFor', - frameborder : 'frameBorder', - 'http-equiv' : 'httpEquiv', - ismap : 'isMap', - longdesc : 'longDesc', - maxlength : 'maxLength', - nohref : 'noHref', - readonly : 'readOnly', - rowspan : 'rowSpan', - tabindex : 'tabIndex', - usemap : 'useMap', - valuetype : 'valueType', - checked : 'defaultChecked' + 'class' : 'className', + 'accesskey' : 'accessKey', + 'accept-charset' : 'acceptCharset', + 'bgcolor' : 'bgColor', + 'cellpadding' : 'cellPadding', + 'cellspacing' : 'cellSpacing', + 'char' : 'ch', + 'charoff' : 'chOff', + 'codebase' : 'codeBase', + 'codetype' : 'codeType', + 'colspan' : 'colSpan', + 'datetime' : 'dateTime', + 'for' : 'htmlFor', + 'frameborder' : 'frameBorder', + 'http-equiv' : 'httpEquiv', + 'ismap' : 'isMap', + 'longdesc' : 'longDesc', + 'maxlength' : 'maxLength', + 'nohref' : 'noHref', + 'readonly' : 'readOnly', + 'rowspan' : 'rowSpan', + 'tabindex' : 'tabIndex', + 'usemap' : 'useMap', + 'valuetype' : 'valueType', + 'checked' : 'defaultChecked' }, X_Node_Attr_HAS_VALUE = { - INPUT : true, - TEXTAREA : true, - SELECT : true, - BUTTON : true, - OBJECT : true, - PARAM : true // FlashVars が flash 側から書き換えられるケースがある?? + 'INPUT' : true, + 'TEXTAREA' : true, + 'SELECT' : true, + 'BUTTON' : true, + 'OBJECT' : true, + 'PARAM' : true // FlashVars が flash 側から書き換えられるケースがある?? }, // の場合、value の値はユーザーで変えることはない // はユーザーによって常に変更される HTML5 ではこれにさらにいろいろ加わる X_Node_Attr_STATIC_VALUE_TYPES = { - button : true, - hidden : true, - submit : true, - reset : true, - radio : true, - checkbox : true + 'button' : true, + 'hidden' : true, + 'submit' : true, + 'reset' : true, + 'radio' : true, + 'checkbox' : true +}, + +// 自由な内容が入るため、参照文字への変換が必要 +X_Node_Attr_toChrReferance = { + 'value' : true, + 'title' : true, + 'alt' : true }, X_Node_Attr_renameForTag = {}; // http://nanto.asablo.jp/blog/2005/10/29/123294 // checked -> defaultChecked // 動的に生成した input 要素を文書ツリーに挿入する前に設定した checked 属性は反映されず、defaultChecked だと反映される - // 先頭にスペース -function X_Node_Attr_objToAttrText( obj ){ - var noValue = X_Node_Attr_noValue, - attrs = [ '' ], n = 0, k, v; - if( !obj ) return ''; // Opera7 - for( k in obj ){ - //if( X_EMPTY_OBJECT[ k ] ) continue; - v = obj[ k ]; - if( k === 'value' ){ - v = v.split( '"' ).join( '"' ).split( '>' ).join( '>' ).split( '<' ).join( '<' ); + // ロードイベントを拾うために、要素生成時にネットワーク関連の属性を設定しない。 + // -> src (img, iframe, ), link の href, + // +function X_Node_Attr_objToAttrText( that, skipNetworkForElmCreation ){ + var obj = that[ '_attrs' ], + noValue = X_Node_Attr_noValue, + attrs = [ '' ], // 先頭にスペース + plain = X_EMPTY_OBJECT, + n = 0, k, check; + + if( skipNetworkForElmCreation ){ + delete that[ '_newAttrs' ]; + // このあとで _newAttr にネットワーク系の属性を控える, attrText には加えない + } else { + that[ '_flags' ] &= ~X_Node_State.OLD_ATTRTEXT; + // 完全な attrText + }; + + if( !obj ){ // Opera7 + delete that[ '_attrText' ]; + return ''; + }; + + for( k in obj ){ + if( plain[ k ] ) continue; + + if( skipNetworkForElmCreation ){ + check = false; + switch( that[ '_tag' ] + k ){ + case 'PARAMvalue' : + check = obj[ 'name' ] !== 'movie'; + case 'INPUTsrc' : + check = check || ( obj[ 'type' ] !== 'image' ); + case 'LINKhref' : + check = check || ( obj[ 'rel' ] !== 'stylesheet' ); + + if( !check ) break; + + case 'IMGsrc' : + case 'IFRAMEsrc' : + case 'FRAMEsrc' : + case 'SCRIPTsrc' : + case 'EMBEDsrc' : + case 'OBJECTdata' : + case 'BGSOUNDsrc' : + case 'APPLETcode' : + //case 'AUDIOsrc' : + //case 'VIDEOsrc' : + if( !that[ '_newAttrs' ] ) that[ '_newAttrs' ] = {}; + that[ '_newAttrs' ][ k ] = obj[ k ]; + continue; }; - attrs[ ++n ] = noValue[ k ] ? k : [ k, '="', v, '"' ].join( '' ); }; - return 0 < n ? attrs.join( ' ' ) : ''; + + attrs[ ++n ] = noValue[ k ] ? k : [ + k, '="', + X_Node_Attr_toChrReferance[ k ] ? X_String_toChrReferance( obj[ k ] ) : obj[ k ], + '"' ].join( '' ); + }; + + if( 0 < n ){ + return that[ '_attrText' ] = attrs.join( ' ' ); + }; + delete that[ '_attrText' ]; + return ''; }; (function( renameForDOM, renameForTag ){ - var k, i; + var k; for( k in renameForDOM ){ //if( X_EMPTY_OBJECT[ k ] ) continue; renameForTag[ renameForDOM[ k ] ] = k; @@ -98,32 +156,32 @@ function X_Node_Attr_objToAttrText( obj ){ * className, onclick等 はここで設定しない * */ -Node.prototype.attr = function( nameOrObj /* v */ ){ - var attrs = this._attrs, newAttrs, f, k, elm, v; +Node.prototype[ 'attr' ] = function( nameOrObj /* v */ ){ + var attrs = this[ '_attrs' ], newAttrs, f, k, elm, v; - if( this._xnodeType !== 1 ) return this; + if( !this[ '_tag' ] ) return this; - if( nameOrObj && X.Type.isObject( nameOrObj ) ){ - attrs || ( attrs = this._attrs = {} ); - newAttrs = this._newAttrs || ( this._newAttrs = {} ); + if( nameOrObj && X_Type_isObject( nameOrObj ) ){ + attrs || ( attrs = this[ '_attrs' ] = {} ); + newAttrs = this[ '_newAttrs' ] || ( this[ '_newAttrs' ] = {} ); for( k in nameOrObj ){ //if( X_EMPTY_OBJECT[ k ] ) continue; if( X_Node_Attr_setAttr( this, attrs, newAttrs, k, nameOrObj[ k ] ) === true ) f = true; }; if( f ){ - this._attrText = false; - this._dirty |= X_Node_Dirty.ATTR; - this._root && X_Node_reserveUpdate(); + delete this[ '_attrText' ]; + this[ '_flags' ] |= X_Node_State.DIRTY_ATTR | X_Node_State.OLD_ATTRTEXT; + this[ '_flags' ] & X_Node_State.IN_TREE && X_Node_reserveUpdate(); }; return this; } else if( 1 < arguments.length ){ // setter - if( X_Node_Attr_setAttr( this, attrs || ( this._attrs = {} ), this._newAttrs || ( this._newAttrs = {} ), nameOrObj, arguments[ 1 ] ) === true ){ - this._attrText = false; - this._dirty |= X_Node_Dirty.ATTR; - this._root && X_Node_reserveUpdate(); + if( X_Node_Attr_setAttr( this, attrs || ( this[ '_attrs' ] = {} ), this[ '_newAttrs' ] || ( this[ '_newAttrs' ] = {} ), nameOrObj, arguments[ 1 ] ) === true ){ + delete this[ '_attrText' ]; + this[ '_flags' ] |= X_Node_State.DIRTY_ATTR | X_Node_State.OLD_ATTRTEXT; + this[ '_flags' ] & X_Node_State.IN_TREE && X_Node_reserveUpdate(); }; return this; } else @@ -131,41 +189,40 @@ Node.prototype.attr = function( nameOrObj /* v */ ){ // getter switch( nameOrObj ){ case 'id' : - return this._id; + return this[ '_id' ]; case 'class' : case 'className' : - return this._className; + return this[ '_className' ]; case 'tag' : case 'tagName' : - return this._tag; + return this[ '_tag' ]; case 'style' : case 'cssText' : - return this.cssText(); - case 'text' : - return this.text(); - case 'html' : - case 'innerHTML' : - return this.html(); - case 'outerHTML' : - X_Node_outerXNode = this; - v = this.html(); - X_Node_outerXNode = null; - return v; + return this[ 'cssText' ](); + case 'src' : // src は遷移して変化する, name も? + if( this[ '_tag' ] !== 'IFRAME' ) break; + if( this[ '_newAttrs' ] && X_Object_inObject( nameOrObj, this[ '_newAttrs' ] ) ) return this[ '_newAttrs' ][ nameOrObj ]; + if( elm = X_UA_DOM.IE4 ? this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) : this[ '_rawObject' ] ){ + if( !attrs ) attrs = this[ '_attrs' ] = {}; + return attrs[ nameOrObj ] = elm[ nameOrObj ]; // getAttribute( nameOrObj )? + }; + break; + case 'selected' : // kquery.js : safariのバグ対策 // if ($.browser.safari && key === "selected" && tmp) tmp.selectedIndex; // 親ノードの selectedIndex の getter を呼んでおくと値が正しくなる、ということ?( by itozyun ) - if( X_UA.WebKit ) this._rawObject.parentNode && this._rawObject.parentNode.selectedIndex; + if( X_UA[ 'WebKit' ] ) this[ '_rawObject' ].parentNode && this[ '_rawObject' ].parentNode.selectedIndex; case 'value' : - if( this._tag === 'INPUT' && X_Node_Attr_STATIC_VALUE_TYPES[ attrs[ 'type' ] ] ) break; + if( this[ '_tag' ] === 'INPUT' && X_Node_Attr_STATIC_VALUE_TYPES[ attrs[ 'type' ] ] ) break; case 'checked' : case 'disabled' : case 'selectedIndex' : - if( X_Node_Attr_HAS_VALUE[ this._tag ] ){ - if( this._newAttrs && X_Object_inObject( nameOrObj, this._newAttrs ) ) return this._newAttrs[ nameOrObj ]; - if( elm = X_UA_DOM.IE4 ? this._rawObject || X_Node__ie4getRawNode( this ) : this._rawObject ){ - if( !attrs ) attrs = this._attrs = {}; + if( X_Node_Attr_HAS_VALUE[ this[ '_tag' ] ] ){ + if( this[ '_newAttrs' ] && X_Object_inObject( nameOrObj, this[ '_newAttrs' ] ) ) return this[ '_newAttrs' ][ nameOrObj ]; + if( elm = X_UA_DOM.IE4 ? this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) : this[ '_rawObject' ] ){ + if( !attrs ) attrs = this[ '_attrs' ] = {}; return attrs[ nameOrObj ] = elm[ nameOrObj ]; // getAttribute( nameOrObj )? }; }; @@ -182,24 +239,24 @@ function X_Node_Attr_setAttr( that, attrs, newAttrs, name, v ){ case 'tagName' : return; case 'id' : - v = ( v !== 'ie4uid' + that._uid ) ? v : undefined; + v = ( v !== 'ie4uid' + that[ '_uid' ] ) ? v : undefined; // TODO unique の check - if( v !== that._id ){ - that._id = v; - that._dirty |= X_Node_Dirty.ID; - that._root && X_Node_reserveUpdate(); + if( v !== that[ '_id' ] ){ + that[ '_id' ] = v; + that[ '_flags' ] |= X_Node_State.DIRTY_ID; + that[ '_flags' ] & X_Node_State.IN_TREE && X_Node_reserveUpdate(); }; return; case 'class' : case 'className' : - return that.className( v ); + return that[ 'className' ]( v ); case 'style' : case 'cssText' : - return that.cssText( v ); + return that[ 'cssText' ]( v ); case 'text' : - return that.text( v ); + return that[ 'text' ]( v ); case 'html' : - return that.html( v ); + return that[ 'html' ]( v ); }; // debug if( name.indexOf( 'on' ) === 0 ){ @@ -212,7 +269,7 @@ function X_Node_Attr_setAttr( that, attrs, newAttrs, name, v ){ if( v == null ){ newAttrs[ name ] = undefined; - if( attrs.hasOwnProperty( name ) ) delete attrs[ name ]; + if( X_Object_inObject( name, attrs ) ) delete attrs[ name ]; } else { newAttrs[ name ] = attrs[ name ] = v; };