From: itozyun Date: Wed, 22 Oct 2014 12:47:17 +0000 (+0900) Subject: Version 0.6.107, cleanup X.NodeCSS, fix X.Node.Event for touch, add unescape for... X-Git-Url: http://git.osdn.jp/view?p=pettanr%2FclientJs.git;a=commitdiff_plain;h=57e35f063b4a70fcec59db6ec7366b43f41f0ba4 Version 0.6.107, cleanup X.NodeCSS, fix X.Node.Event for touch, add unescape for IE8-JSON, fix X.EventDispatcher for iOS-webkitTransitionEnd. --- diff --git a/0.6.x/js/01_core/01_X.js b/0.6.x/js/01_core/01_X.js index 2685af2..7655eee 100644 --- a/0.6.x/js/01_core/01_X.js +++ b/0.6.x/js/01_core/01_X.js @@ -10,10 +10,14 @@ if( !window['console'] || ( window.parent && window.parent.log ) ) } }; var undefined, + X_EMPTY_OBJECT = {}, X_TEMP = { onSystemReady : [] }, X_shortcutFunction, X_shortcutContext; +/** + * @namespace ライブラリは X という名前空間を使用します。X( func ) で X.ViewPort.listenOnce(X.Event.XDOM_READY, func)、 X('#mydiv') として X.Doc.find('#mydiv') のショートハンドになります。 + */ function X( v ){ if( X.Type.isFunction( v ) ){ X.ViewPort.listenOnce( X.Event.XDOM_READY, v ); diff --git a/0.6.x/js/01_core/10_XCallback.js b/0.6.x/js/01_core/10_XCallback.js index bf00497..4dad3ff 100644 --- a/0.6.x/js/01_core/10_XCallback.js +++ b/0.6.x/js/01_core/10_XCallback.js @@ -32,11 +32,6 @@ var listener; */ var callbackHash; -/* - * - * @typedef {(funciton|{ _ : function, same : function, kill : function, a : (Array|undefined) })} - */ -var functionHash; X.Callback = { NONE : X_Callback_NONE, @@ -64,7 +59,7 @@ function X_Callback_create( thisObject, opt_callback, opt_args /* [ listener || _obj.s = obj.s; _obj._ = X_Callback_proxyCallback; } else { - ret = X_Closure_actualClosure( obj ); + ret = X_Callback_actualClosure( obj ); obj._ = X_Callback_proxyCallback; }; X_Callback_LIVE_LIST[ X_Callback_LIVE_LIST.length ] = ret; @@ -113,7 +108,7 @@ function X_Callback_classifyCallbackArgs( arg1, arg2, arg3, alt_context ){ return ( obj.x || obj.s ) ? obj : arg1; }; -function X_Closure_actualClosure( obj ){ +function X_Callback_actualClosure( obj ){ return function(){ if( arguments[ 0 ] === X_Closure_COMMAND_BACK ) return obj; if( arguments[ 0 ] !== X_Closure_COMMAND_DROP ) return obj._( obj, arguments ); @@ -189,14 +184,6 @@ function X_Callback_correct( f ){ return false; }; - -// sys -X_TEMP.X_Callback_onSystemReady = function( sys ){ - delete X_TEMP.X_Callback_onSystemReady; - sys.monitor( X_Callback_monitor ); - sys.gc( X_Callback_gc ); -}; - function X_Callback_monitor(){ return { 'Callback:Live' : X_Callback_LIVE_LIST.length, @@ -207,7 +194,10 @@ function X_Callback_gc(){ X_Callback_POOL_LIST.length = 0; // ? }; -X_TEMP.onSystemReady.push( X_TEMP.X_Callback_onSystemReady ); +X_TEMP.onSystemReady.push( function( sys ){ + sys.monitor( X_Callback_monitor ); + sys.gc( X_Callback_gc ); +}); console.log( 'X.Core.Callback' ); diff --git a/0.6.x/js/01_core/11_XClass.js b/0.6.x/js/01_core/11_XClass.js index 0379861..5222ea8 100644 --- a/0.6.x/js/01_core/11_XClass.js +++ b/0.6.x/js/01_core/11_XClass.js @@ -2,7 +2,7 @@ * Class を定義し システムの管理下に置く. * 全てのクラスと pool が有効の場合インスタンスへの参照が保持される. * 1. X.Class.create( opt_settings, opt_name, opt_privateClass, opt_props ) でクラスを登録. - * 2. コンストラクタ となるメソッドは、Constructor : function( arg ){ ... }, に書く. + * 2. コンストラクタ となるメソッドは、opt_props 内の Constructor : function( arg ){ ... }, に書く. * 3. 通常通り new で インスタンス生成 * 4. kill() でオブジェクトをクリーンして削除、pool が有効の場合は pool される. * 5. pool が有効の場合、new で pool されたインスタンスが返される. @@ -22,12 +22,19 @@ var X_Class_CLASS_LIST = [], X_Class_killPrivateFlag = false, X_Class_traits = null, X_Class_useObjectCreate = false, // !!Object.create, http://jsperf.com/prototype-vs-object-create-perf - X_Class_use_proto_ = !!X.emptyFunction.prototype.__proto__; + X_Class_use_proto_ = !!X.emptyFunction.prototype.__proto__, -/* - * X.Class.create で作られたクラスのインスタンスが共通で備えるメソッド - */ -var X_Class_CommonProps = { +/** + * X.Class.create で定義されたクラスのインスタンスが共通で備えるメソッド を格納 + * + * @class + */ +X_Class_CommonProps = + +{ + /* + * インスタンスの破棄。 + */ kill : function(){ var instance = this, klass = X_Class_getClass( instance ), @@ -104,14 +111,27 @@ var X_Class_CommonProps = { // ------------------------------------------------------------------------- // // --- interface ----------------------------------------------------------- // // ------------------------------------------------------------------------- // + +/** @namespace */ X.Class = { - + /** + * インスタンスは破棄時(this.kill())に回収され、次回の new MyClass() 時に再利用されます。 + * @memberof X.Class */ POOL_OBJECT : 1, + + /** + * 定義するクラスは抽象クラスになります。new AbstractClass() とするとエラーになります。 + * @memberof X.Class */ ABSTRACT : 2, + + + /** @memberof X.Class */ FINAL : 4, + /** @memberof X.Class */ SUPER_ACCESS : 8, + /** @memberof X.Class */ PRIVATE_DATA : 16, - + /** @memberof X.Class */ SINGLETON : 32, // 未実装 create : function( /* displayName, classSetting, opt_PrivateClass, props */ ){ @@ -173,7 +193,7 @@ X.Class = { classDef.Constructor = props.Constructor; }; - klass = X_Closure_actualClosure( hash = { _ : X_Class_actualConstructor } ); // TODO hash = classDef + klass = X_Callback_actualClosure( hash = { _ : X_Class_actualConstructor } ); // TODO hash = classDef hash.c = klass; klass.superClassOf = X_Class_superClassOf; klass.subClassOf = X_Class_subClassOf; diff --git a/0.6.x/js/01_core/12_XEvent.js b/0.6.x/js/01_core/12_XEvent.js index 36e8130..61250b1 100644 --- a/0.6.x/js/01_core/12_XEvent.js +++ b/0.6.x/js/01_core/12_XEvent.js @@ -5,9 +5,9 @@ var X_Event_last = 0, X_Event_toPointer = !X_UA_HID.POINTER && ( X_UA_HID.TOUCH ? { - touchdown : 'pointerdown', + touchstart : 'pointerdown', mousedown : 'pointerdown', - touchup : 'pointerup', + touchend : 'pointerup', mouseup : 'pointerup', touchmove : 'pointermove', mousemove : 'pointermove', @@ -55,19 +55,22 @@ X.Event = { // in_page_jump // on_screen_keyboard_show // on_screen_keyboard_hide -// X.Event.BEFORE_UPDATE = ++X_Event_last; // このイベントで要素のサイズを取得すると無限ループに! - AFTER_UPDATE : 21, -// hash_change - BEFORE_UNLOAD : 22, - UNLOAD : 23, + BEFORE_UPDATE : 21,// このイベントで要素のサイズを取得すると無限ループに! + UPDATED : 22, + AFTER_UPDATE : 23, + + HASH_CHANGED : 24, + + BEFORE_UNLOAD : 25, + UNLOAD : 26, - BACKEND_READY : 24, - BACKEND_NOT_FOUND : 25, - BACKEND_RESEARCH : 26, - BACKEND_CHANGED : 27 + BACKEND_READY : 27, + BACKEND_NOT_FOUND : 28, + BACKEND_RESEARCH : 29, + BACKEND_CHANGED : 30 }; -X_Event_last = 27; +X_Event_last = 29; X_TEMP.onSystemReady.push( function(){ diff --git a/0.6.x/js/01_core/13_XEventDispatcher.js b/0.6.x/js/01_core/13_XEventDispatcher.js index 7ff83b3..1aaadc5 100644 --- a/0.6.x/js/01_core/13_XEventDispatcher.js +++ b/0.6.x/js/01_core/13_XEventDispatcher.js @@ -1,4 +1,8 @@ /** + * + */ + +/** * X.EventDispatcher * * 1. as3 の EventDispatcher ライクなクラス。そのまま使ったり、継承したり。コールバック中にイベントを追加したら?削除したら?にも対処している。 @@ -32,30 +36,32 @@ var X_EventDispatcher_once = false, // ------------------------------------------------------------------------- // /** - * イベントターゲット(widnow, document, Image, XHR, Silverlight 等)をラップする場合、通常は new 時に渡します。参照:コンストラクタ実体 {@link X.EventDispatcher.Constructor} - * アプリケーション独自のイベントをやり取りしたいだけ、という場合、イベントターゲットは不要です。 + *

イベントターゲット(widnow, document, Image, XHR, Silverlight 等)をラップする場合、通常は new 時に渡します。 + *

参照:コンストラクタ実体 {@link X.EventDispatcher.Constructor} + *

アプリケーション独自のイベントをやり取りしたい、という場合、イベントターゲットは不要です。 + * * @class * @classdesc EventTarget オブジェクトをラップしたり、アプリケーションで独自に定義したイベントを発信するためのクラスです。 - * listen, unlisten, dispatch という addEventListener, removeEventListener, dispatchEvent に対応する関数を持ちます。 - * さらに listening という as3 の hasEventListener に相当する関数を持ちます。 - * イベントターゲットオブジェクト(widnow, document, HTMLElement, XHR 等)が _rawObject に設定されていた場合に、それらへ実際のイベント登録・解除も行います。 - * このイベントの登録・解除はクロスブラウザで、IE5~8 の独自イベントの差異を吸収し、DOM0 に対しても複数のコールバックを登録することができます。 - * またコールバックに対して、this コンテキストや、追加の引数を指定もできます。 this コンテキストを指定しなかった場合、EventDispatcher インスタンスがコールバックの this になります。 - * unlisten() は、引数を指定しなかった場合、全てのイベントを解除します。ただし、systemListen 経由で登録されたハンドラは解除されません。 + *

listen, unlisten, dispatch という addEventListener, removeEventListener, dispatchEvent に対応する関数を持ちます。 + *

また listening という ActionScript3 の hasEventListener に相当する関数を持ちます。 + *

イベントターゲットオブジェクト(widnow, document, HTMLElement, XHR 等)が this._rawObject に設定されていた場合に、それらへ実際のイベント登録・解除も行います。 + *

このイベントの登録・解除はクロスブラウザで、IE5~8 の独自イベントの差異を吸収し、DOM0 に対しても複数のコールバックを登録することができます。 + *

またコールバックに対して、this コンテキストや、追加の引数を指定もできます。 this コンテキストを指定しなかった場合、EventDispatcher インスタンスがコールバックの this になります。 + *

unlisten() は、引数を指定しなかった場合、全てのイベントを解除します。ただし、systemListen 経由で登録されたハンドラは解除されません。 * systemListen, systemUnlisten は、ライブラリ内のコードからしかアクセスできません。 - * @param {object=} opt_rawObject + * + * @augments X_Class_CommonProps + * + * @param {object=} opt_rawObject イベントターゲット(EventTarget) */ X.EventDispatcher = X.Class.create( 'EventDispatcher', - /** @lends {X.EventDispatcher.prototype} */ + /** @lends X.EventDispatcher.prototype */ { - /** - * @namespace - * @memberof X.EventDispatcher - */ + // TODO _rawObjectType EventTarget, XHR, Silverlight, ... /** @@ -84,7 +90,7 @@ X.EventDispatcher = */ '_handleEvent' : null, - /* + /** * dispatch 中に dispatch が呼ばれた際に、そのネストの深さを保存する。 * dispatch() 終了時に _dispatching が 0 の場合に、現在のインスタンスの dispatch がすべて終わったことになる。 * @private @@ -92,7 +98,7 @@ X.EventDispatcher = */ '_dispatching' : 0, // dispatch 中の unlisten で使用 - /* + /** * dispatch 中に listen が呼ばれた場合に、配列のindexがずれることを避けるため、一旦保持する。 * _dispatching が 0 のときに _reserves を使って listen() を呼び出す。 * @private @@ -100,7 +106,7 @@ X.EventDispatcher = */ '_reserves' : null, - /* + /** * dispatch 中に unlisten が呼ばれた場合に、配列のindexがずれることを避けるため、一旦保持する。 * _dispatching が 0 のときに _unlistens を使って unlisten() を呼び出す。 * @private @@ -108,7 +114,7 @@ X.EventDispatcher = */ '_unlistens' : null, - /* + /** * dispatch 中に kill が呼ばれた場合に、X.EventDispatcher インスタンスの削除を dispatch 後にずらすために立てるフラグ。 * @private * @type {boolean} @@ -117,9 +123,9 @@ X.EventDispatcher = /** * X.EventDispatcher のコンストラクタの実体。 - * @constructs + * @@@constructs * @this {X.EventDispatcher} - * @params {object=} opt_rawObject + * @param {object=} opt_rawObject */ Constructor : function( opt_rawObject ){ if( opt_rawObject ){ @@ -135,11 +141,20 @@ X.EventDispatcher = */ dispatch : X_EventDispatcher_dispatch, - /** - * - * @this {X.EventDispatcher} - */ + /** + * @function + */ on : X_EventDispatcher_listen, + + /** + * + * @this {X.EventDispatcher} + * @param {(string|number|Array.<(string,number)>)} type + * @param {(listener|function|Array)=} opt_arg1 + * @param {(function|Array=} opt_arg2 + * @param {Array=} opt_arg3 + * @return {X.EventDispatcher} + */ listen : X_EventDispatcher_listen, /** @@ -162,12 +177,15 @@ X.EventDispatcher = unlisten : X_EventDispatcher_unlisten, /** - * イベントリスナの登録状況を真偽値で返す。戻り値が数値(index)の場合もあるが、これは内部のみで使用。 - * listening() と type を省略した場合、一つでも登録があれば true を返す。 - * listening( type ) と type だけを与えた場合、その type に登録があれば true を返す。 - * type と イベントリスナの組み合わせが登録されているかを調べる場合は、listen 時の thisObject や args(Array) も一致させて渡す必要がある。 + *

イベントリスナの登録状況を真偽値で返す。戻り値が数値(index)の場合もあるが、これは内部のみで使用。 + *

this.listening(); のように type を省略した場合、一つでも登録があれば true を返す。 + *

this.listening( 'myevent' ); と type だけを与えた場合、その type に登録があれば true を返す。 + *

type と イベントリスナの組み合わせが登録されているかを調べる場合は、listen 時の thisObject や args(Array) も一致させて渡す必要がある。 + * + * @example * this.listen( [ 'myevent', 'yourevent' ], this, onMyEvent, args = [ 1, 'a' ] ); * this.listening( 'myevent', this, onMyEvent, args ) === true; + * * @this {X.EventDispatcher} * @return {(number|boolean)} * @param {(string|number)=} opt_type @@ -325,11 +343,12 @@ function X_EventDispatcher_dispatch( e ){ /** * * @this {X.EventDispatcher} - * @return {X.EventDispatcher} + * @memberOf X.EventDispatcher.prototype * @param {(string|number|Array.<(string,number)>)} type * @param {(listener|function|Array)=} opt_arg1 * @param {(function|Array=} opt_arg2 * @param {Array=} opt_arg3 + * @return {X.EventDispatcher} */ function X_EventDispatcher_listen( type, opt_arg1, opt_arg2, opt_arg3 ){ var list = this._listeners, @@ -476,7 +495,7 @@ function X_EventDispatcher_addEvent( that, type, raw, list ){ if( X.Type.isArray( type ) ){ for( i = type.length; i; ){ X_EventDispatcher_systemListen( that, type[ --i ], X.emptyFunction ); - console.log( 'X_EventDispatcher_systemListen ' + type[ i ] ); + console.log( 'events fix > ' + type[ i ] ); }; } else { X_EventDispatcher_actualAddEvent( that, type, raw, list ); @@ -496,9 +515,13 @@ var X_EventDispatcher_actualAddEvent = if( that._isSilverlight ){ list.slcallback = X_Callback_create( that, X_EventDispatcher_sliverLightDispatch, [ type ] ); list.sltoken = raw.AddEventListener( type, list.slcallback ); - } else { + } else { + console.log( 'event > ' + type ); that._handleEvent || ( that._handleEvent = X_Callback_create( that, X_EventDispatcher_actualHandleEvent ) ); - + + if( X.UA.iOS && type === 'webkitTransitionEnd' ){ + raw.addEventListener( type, X_EventDispatcher_iOS3transitionEndDispatch, false ); + } else if( raw.addEventListener ){ raw.addEventListener( type, that._handleEvent, false ); } else { @@ -541,6 +564,16 @@ var X_EventDispatcher_actualAddEvent = }); /* + * iOS の webkitTransitionEnd が連続して起こる場合、 + * コールバックの(that._handleEvent)クロージャ内の実際のコールバック(X_Callback_actualClosure:obj._)が + * 参照できていない問題に遭遇、、、iOS3.1.3 & iOS6.1.5 で確認 + * animation も怪しい、、、 + */ +function X_EventDispatcher_iOS3transitionEndDispatch( e ){ + return X_Node_getXNode( this ).dispatch( X_Event_RenameTo[ e.type ] ); +}; + +/* * Silverlight のイベントの概要 * http://msdn.microsoft.com/ja-jp/library/cc189018%28v=vs.95%29.aspx#the_sender_parameter_and_event_data */ @@ -574,6 +607,9 @@ var X_EventDispatcher_actualRemoveEvent = delete list.sltoken; delete list.slcallback; } else { + if( X.UA.iOS && type === 'webkitTransitionEnd' ){ + raw.removeEventListener( type, X_EventDispatcher_iOS3transitionEndDispatch, false ); + } else if( raw.addEventListener ){ raw.removeEventListener( type, that._handleEvent, false ); } else { @@ -661,7 +697,7 @@ var X_EventDispatcher_actualHandleEvent = var ev = new X.Dom.Event( e, this ), ret = X_Callback_NONE, i, l; - console.log( '>>>>>>>>>> ' + e.type ); + //console.log( '>>>>>>>>>> ' + e.type ); // touch event -> pointer if( X.Type.isArray( ev ) ){ if( ev.length === 0 ){ diff --git a/0.6.x/js/01_core/14_XTimer.js b/0.6.x/js/01_core/14_XTimer.js index 379ed35..be20ccc 100644 --- a/0.6.x/js/01_core/14_XTimer.js +++ b/0.6.x/js/01_core/14_XTimer.js @@ -234,7 +234,7 @@ function X_Timer_onTimeout(){ //console.log( 'fire....' ); if( limit <= X_Timer_now() ){ - console.log( '******* heavy!' ); + //console.log( '******* heavy!' ); // 関数の実行に時間がかかる場合、次のタイミングに heavy = true; }; diff --git a/0.6.x/js/02_dom/02_XNode.js b/0.6.x/js/02_dom/02_XNode.js index 22c8f03..525eb81 100644 --- a/0.6.x/js/02_dom/02_XNode.js +++ b/0.6.x/js/02_dom/02_XNode.js @@ -272,7 +272,7 @@ function X_Node_getXNode( v ){ }; return v.UID && X_Node_CHASHE[ v.UID ]; case X_Node_TYPE.WINDOW : - return X.ViewPort; + return X_ViewPort; case X_Node_TYPE.DOCUMENT : return X_ViewPort_document; case X_Node_TYPE.RAW_TEXT : @@ -833,7 +833,7 @@ function X_Node_html( html ){ return this._text; }; - if( this._dirty & X_Node_Dirty.CSS && !( this._cssText = X_Node_CSS_objToCssText( this._css ) ) ){ + if( this._dirty & X_Node_Dirty.CSS && !( this._cssText = X_Node_CSS_objToCssText( this ) ) ){ delete this._cssText; }; html = !X_Node_outerXNode ? [] : [ @@ -977,7 +977,7 @@ function X_Node_startUpdate(){ // このイベントでサイズを取ると無限ループに - // X_ViewPort._listeners && X_ViewPort._listeners[ X.Event.BEFORE_UPDATE ] && X_ViewPort.dispatch( X.Dom.Event.BEFORE_UPDATE ); + X_System._listeners && X_System._listeners[ X.Event.BEFORE_UPDATE ] && X_System.dispatch( X.Event.BEFORE_UPDATE ); removal = X_Node_reserveRemoval; @@ -1001,6 +1001,8 @@ function X_Node_startUpdate(){ //console.log( 'end of _startUpdate().' ); + X_System._listeners && X_System._listeners[ X.Event.UPDATED ] && X_System.dispatch( X.Event.UPDATED ); + X_ViewPort._listeners && X_ViewPort._listeners[ X.Event.AFTER_UPDATE ] && X_ViewPort.asyncDispatch( X.Event.AFTER_UPDATE ); //this._rawObject.style.visibility = tmp; }; @@ -1125,7 +1127,7 @@ var X_Node__updateRawNode = // style // TODO display:none の場合、更新をスキップ if( that._dirty & X_Node_Dirty.CSS ){ - if( that._cssText !== null || ( that._cssText = X_Node_CSS_objToCssText( that._css ) ) ){ + if( that._cssText !== null || ( that._cssText = X_Node_CSS_objToCssText( that ) ) ){ X_UA.Opera78 || X_UA.NN6 ? elm.setAttribute( 'style', that._cssText ) : // opera8用 ( elm.style.cssText = that._cssText ); @@ -1137,7 +1139,7 @@ var X_Node__updateRawNode = }; if( that._dirty & X_Node_Dirty.IE_FILTER ){ - elm.style.filter = X_Node_CSS_SPECIAL_FIX( that._css ); + elm.style.filter = X_Node_CSS_objToIEFilterText( that );; }; // attr @@ -1188,7 +1190,7 @@ var X_Node__updateRawNode = }; // style if( that._dirty & X_Node_Dirty.CSS ){ - if( that._cssText !== null || ( that._cssText = X_Node_CSS_objToCssText( that._css ) ) ){ + if( that._cssText !== null || ( that._cssText = X_Node_CSS_objToCssText( that ) ) ){ elm.style.cssText = that._cssText; } else { elm.style.cssText = ''; @@ -1198,7 +1200,7 @@ var X_Node__updateRawNode = }; if( that._dirty & X_Node_Dirty.IE_FILTER ){ - that._rawObject.style.filter = X_Node_CSS_SPECIAL_FIX( that._css ); + that._rawObject.style.filter = X_Node_CSS_objToIEFilterText( that );; }; // attr @@ -1247,7 +1249,7 @@ var X_Node__actualCreate = }; if( !elm ){ - if( that._dirty & X_Node_Dirty.CSS && !( that._cssText = X_Node_CSS_objToCssText( that._css ) ) ){ + if( that._dirty & X_Node_Dirty.CSS && !( that._cssText = X_Node_CSS_objToCssText( that ) ) ){ delete that._cssText; }; that._isNew = true; @@ -1285,7 +1287,7 @@ var X_Node__actualCreate = } else { if( that._rawObject && !isChild ) X_Node__actualRemove( that, true ); - if( that._dirty & X_Node_Dirty.CSS && !( that._cssText = X_Node_CSS_objToCssText( that._css ) ) ){ + if( that._dirty & X_Node_Dirty.CSS && !( that._cssText = X_Node_CSS_objToCssText( that ) ) ){ delete that._cssText; }; @@ -1341,7 +1343,7 @@ var X_Node__afterActualCreate = }; if( X_Node_strictElmCreation ){ if( that._dirty & X_Node_Dirty.IE_FILTER ){ - elm.style.filter = X_Node_CSS_SPECIAL_FIX( that._css ); + elm.style.filter = X_Node_CSS_objToIEFilterText( that );; }; delete that._dirty; } else { @@ -1376,7 +1378,7 @@ var X_Node__afterActualCreate = }; // textarea への value の適用はここで if( that._dirty & X_Node_Dirty.IE_FILTER ){ - X_Node__ie4getRawNode( that ).style.filter = X_Node_CSS_SPECIAL_FIX( that._css ); + X_Node__ie4getRawNode( that ).style.filter = X_Node_CSS_objToIEFilterText( that );; }; delete that._dirty; X_EventDispatcher_toggleAllEvents( that, true );// イベントの復帰 diff --git a/0.6.x/js/02_dom/03_XDomEvent.js b/0.6.x/js/02_dom/03_XDomEvent.js index 540ed81..ec27fb1 100644 --- a/0.6.x/js/02_dom/03_XDomEvent.js +++ b/0.6.x/js/02_dom/03_XDomEvent.js @@ -23,13 +23,13 @@ if( !X_UA.IE || 9 <= X_UA.IE ){ var originalType = e.type, type, pointerType, touches, events, - altKey, ctrlKey, metaKey, shiftKey, target, related, + altKey, ctrlKey, metaKey, shiftKey, target, related, force, elm, i, n, time, touch, ev; //this._event = e; this.type = type = X_Event_RenameTo[ originalType ] || originalType; - console.log( 'original : ' + originalType + ' > ' + type ); + //console.log( 'original : ' + originalType + ' > ' + type ); // http://msdn.microsoft.com/ja-jp/library/ie/dn304886%28v=vs.85%29.aspx // ポインター イベントの更新 if( e.pointerType ){ @@ -88,9 +88,11 @@ if( !X_UA.IE || 9 <= X_UA.IE ){ } else if( pointerType = X_Event_toPointer[ originalType ] ){ // Touch or Mouse + //console.log( originalType + ' => ' + pointerType ); /* e.constructor === window.TouchEvent -> e.touches for iOS3.13 */ if( touches = e.changedTouches ){ + //console.log( originalType + ' => ' + pointerType ); if( touches.length === 0 ){ alert( 'e.changedTouches.length === 0' ); }; @@ -102,6 +104,7 @@ if( !X_UA.IE || 9 <= X_UA.IE ){ metaKey = e.metaKey; shiftKey = e.shiftKey; time = X_Timer_now(); + force = originalType === 'touchend' || originalType === 'touchcancel' ? 0 : 0.5; for( i = touches.length; i; ){ touch = touches[ --i ]; target = touch.target; @@ -111,11 +114,11 @@ if( !X_UA.IE || 9 <= X_UA.IE ){ pointerType : 'touch', target : X_Node_getXNode( target.nodeType === 3 ? target.parentNode : target ),// defeat Safari bug // xnodetouch.target, currentTarget : xnode, - relatedTarget : X_Node_getXNode( related.nodeType === 3 ? related.parentNode : related ), // xnode + relatedTarget : related && X_Node_getXNode( related.nodeType === 3 ? related.parentNode : related ), // xnode iOS3 には relatedTarget がない isPrimary : true, hwTimestamp : time, timestamp : time, - buttons : e.button, + button : e.button, buttons : e.buttons || e.button, altKey : altKey, ctrlKey : ctrlKey, @@ -133,7 +136,7 @@ if( !X_UA.IE || 9 <= X_UA.IE ){ radiusX : touch.radiusX || 0, radiusY : touch.radiusY || 0, rotationAngle : touch.rotationAngle || 0, - pressure : touch.force || touch.webkitForce || ( isEnd ? 0 : 0.5 ), + pressure : touch.force || touch.webkitForce || force, width : touch.width || 0, height : touch.height || 0 }; @@ -411,11 +414,11 @@ if( !navigator.pointerEnabled ){ } else if( X_UA_HID.TOUCH ){ // touch のみ(iOS でも脱獄したら?)、 touch と mouse(Android), mouse のみ - X_Event_Rename[ 'pointerdown' ] = [ 'touchdown', 'mousedown' ]; - X_Event_Rename[ 'pointerup' ] = [ 'touchup', 'mouseup' ]; - X_Event_Rename[ 'pointermove' ] = [ 'touchmove', 'mousemove' ]; + X_Event_Rename[ 'pointerdown' ] = [ 'touchstart', 'mousedown' ]; + X_Event_Rename[ 'pointerup' ] = [ 'touchend', 'mouseup' ]; + X_Event_Rename[ 'pointermove' ] = [ 'touchmove', 'mousemove' ]; X_Event_Rename[ 'pointercancel' ] = 'touchcancel'; - // X_Event_Rename[ 'click' ] = [ 'touchdown', 'touchmove', 'touchup' ]; // ループになってしまう!直した!直ってない! + // X_Event_Rename[ 'click' ] = [ 'touchstart', 'touchmove', 'touchend' ]; // ループになってしまう!直した!直ってない! } else { X_Event_Rename[ 'pointerdown' ] = 'mousedown'; X_Event_Rename[ 'pointerup' ] = 'mouseup'; diff --git a/0.6.x/js/02_dom/06_XNodeCSS.js b/0.6.x/js/02_dom/06_XNodeCSS.js index f0f3309..8bb9256 100644 --- a/0.6.x/js/02_dom/06_XNodeCSS.js +++ b/0.6.x/js/02_dom/06_XNodeCSS.js @@ -7,80 +7,56 @@ * * use X.Dom.Event */ -var -X_Node_CSS_Type = { - LENGTH : 1, - PERCENT : 2, - COLOR : 2 < 2, - U_DECIMAL : 2 < 3, - NUMERICAL : 2 < 4, - BOOLEAN : 2 < 5, - QUARTET : 2 < 6, - URL : 2 < 7, - FONT_NAME : 2 < 8, - TIME : 2 < 9, - CONTENT : 2 < 10, - LIST : 2 < 11, - AUTO : 2 < 12, - COMBI : 2 < 13 - }, + +/* font-size -> fontSize */ +function X_Node_CSS_camelize( cssProp ){ + var parts, l, i, parts0, camelized; -X_Node_CSS_UNIT = { - 'px' : 0, - 'em' : 1, - 'cm' : 2, - 'mm' : 3, - 'in' : 4, - '%' : 5, - 'pct' : 5, - 'ms' : 6, - 's' : 7, - '#' : 8, - 'rgb' : 9, - 'rgba' : 10 - }, + if( camelized = X_Node_CSS__DICTIONARY_CAMELIZE[ cssProp ] ) return camelized; + parts = cssProp.split( ' ' ).join( '' ).split( '-' ); + parts0 = parts[ 0 ]; + l = parts.length; + if( l === 1 ) return parts0; + + camelized = cssProp.charAt(0) === '-' + ? parts0.charAt( 0 ).toUpperCase() + parts0.substring( 1 ) + : parts0; + for( i = 1; i < l; ++i ){ + camelized += parts[ i ].charAt( 0 ).toUpperCase() + parts[ i ].substring( 1 ); + }; + return X_Node_CSS__DICTIONARY_CAMELIZE[ cssProp ] = camelized; +}; + +// TODO use X_HTMLParser_CHARS +/* fontSize -> font-size */ +function X_Node_CSS_uncamelize( str ){ + var A = X_Node_CSS_CHAR_CODE_A, + Z = A + 25, + uncamelized, l, chr, code, i; + str = str.split( ' ' ).join( '' ); + if( uncamelized = X_Node_CSS__DICTIONARY_UNCAMELIZE[ str ] ) return uncamelized; + uncamelized = ''; + for( i = 0, l = str.length; i < l; ++i ){ + chr = str.charAt( i ); + code = chr.charCodeAt( 0 ); + uncamelized += ( A <= code && code <= Z ) ? '-' + chr : chr; + }; + return X_Node_CSS__DICTIONARY_UNCAMELIZE[ str ] = uncamelized.toLowerCase(); +}; + +var + +X_node_CSS_getComputedStyle = window.getComputedStyle || document.defaultView && document.defaultView.getComputedStyle, + /* font-size -> fontSize */ X_Node_CSS__DICTIONARY_CAMELIZE = {}, - -X_Node_CSS_camelize = function( cssProp ){ - var parts, l, i, camelized; - - if( camelized = X_Node_CSS__DICTIONARY_CAMELIZE[ cssProp ] ) return camelized; - parts = cssProp.split( ' ' ).join( '' ).split( '-' ); - l = parts.length; - if( l === 1 ) return parts[ 0 ]; - - camelized = cssProp.charAt(0) === '-' - ? parts[ 0 ].charAt( 0 ).toUpperCase() + parts[ 0 ].substring( 1 ) - : parts[ 0 ]; - - for( i = 1; i < l; ++i ){ - camelized += parts[ i ].charAt( 0 ).toUpperCase() + parts[ i ].substring( 1 ); - }; - return X_Node_CSS__DICTIONARY_CAMELIZE[ cssProp ] = camelized; - }, - + /* fontSize -> font-size */ X_Node_CSS_CHAR_CODE_A = 'A'.charCodeAt( 0 ), X_Node_CSS__DICTIONARY_UNCAMELIZE = {}, -X_Node_CSS_uncamelize = function( str ){ - var A = X_Node_CSS_CHAR_CODE_A, - Z = A + 25, - uncamelized, l, chr, code, i; - str = str.split( ' ' ).join( '' ); - if( uncamelized = X_Node_CSS__DICTIONARY_UNCAMELIZE[ str ] ) return uncamelized; - uncamelized = ''; - for( i = 0, l = str.length; i < l; ++i ){ - chr = str.charAt( i ); - code = chr.charCodeAt( 0 ); - uncamelized += ( A <= code && code <= Z ) ? '-' + chr : chr; - }; - return X_Node_CSS__DICTIONARY_UNCAMELIZE[ str ] = uncamelized.toLowerCase(); - }, - /* * CSS における display, position, float プロパティの相互関係 * http://d.hatena.ne.jp/elm200/20080201/1201874740 @@ -109,38 +85,8 @@ _FLOAT_BOX _GRNERAL */ X_Node_CSS_VENDER_PREFIX = {}, - -X_Node_CSS_objToCssText = function( obj ){ - var css = [], - uncamelize = X_Node_CSS_uncamelize, - VENDER_PREFIX = X_Node_CSS_VENDER_PREFIX, - FIX_PROP = X_Node_CSS_SPECIAL_FIX_PROP, - SPECIAL_FIX = X_Node_CSS_SPECIAL_FIX, - n = -1, - p, v, name, sp; - if( !obj ) return ''; // Opera7.5 未満? - for( p in obj ){ - // TODO Object が拡張されていると error... - name = uncamelize( VENDER_PREFIX[ p ] || p ); - if( FIX_PROP[ name ] ){ - sp = true; - } else { - css[ ++n ] = [ name, obj[ p ] ].join( ':' ); - }; - }; - sp && ( css[ ++n ] = 'filter:' + SPECIAL_FIX( obj ) ); - return css.join( ';' ); - }, -X_Node_CSS_IE_FILTER_FIX = - X_UA.IE && X_UA.IE < 9 && !X_UA.MacIE ? - { - opacity : 1, - textShadow : 1 - } : - 9 <= X_UA.IE && X_UA.IE < 10 ? // == 9 - {} : - {}, +X_Node_CSS__CLIP_SEPARATOR = X_UA.IE < 8 ? ' ' : ',', X_Node_CSS__UNIT_RATIO = {}, X_Node_CSS__FONT_SIZE_RATIO = {}, @@ -238,692 +184,259 @@ X_Node_CSS_COLOR = { MISTYROSE : 0xFFE4E1, IVORY : 0xFFFFF0, LEMONCHIFFON : 0xFFFACD - }, +}; -X_Node_CSS_parseColor = function( x ){ - var rgb, r, g, b; - - if( X.Type.isNumber( x ) ){ - return ( 0x0 <= x && x <= 0xFFFFFF ) ? x : undefined; - } else - if( !X.Type.isString( x ) ) return; - - if( X.Type.isNumber( rgb = X_Node_CSS_COLOR[ x.toUpperCase() ] ) && 0x0 <= rgb && rgb <= 0xFFFFFF ){ - return rgb; - } else - if( x.charAt( 0 ) === '#' ){ - switch( x.length ){ - case 7 : - r = parseInt( x.substr( 1, 2 ), 16 ); - g = parseInt( x.substr( 3, 2 ), 16 ); - b = parseInt( x.substr( 5, 2 ), 16 ); - break; - case 4 : - r = parseInt( x.charAt( 1 ) + x.charAt( 1 ), 16 ); - g = parseInt( x.charAt( 2 ) + x.charAt( 2 ), 16 ); - b = parseInt( x.charAt( 3 ) + x.charAt( 3 ), 16 ); - break; - case 2 : - r = g = b = parseInt( x.charAt( 1 ) + x.charAt( 1 ), 16 ); - break; - default : - return; - }; - } else - if( x.indexOf( 'rgb(' ) === 0 ){ - rgb = x.substr( 4 ).split( ',' ); - r = parseFloat( rgb[ 0 ] ); - g = parseFloat( rgb[ 1 ] ); - b = parseFloat( rgb[ 2 ] ); - if( x.indexOf( '%' ) !== -1 ){ - r *= 2.55; - g *= 2.55; - b *= 2.55; - }; - } else - if( x.indexOf( 'rgba(' ) === 0 ){ - rgb = x.substr( 5 ).split( ',' ); - r = parseFloat( rgb[ 0 ] ); - g = parseFloat( rgb[ 1 ] ); - b = parseFloat( rgb[ 2 ] ); - //a = parseFloat( rgb[ 3 ] ); - if( x.indexOf( '%' ) !== -1 ){ - r *= 2.55; - g *= 2.55; - b *= 2.55; - }; - } else { - return undefined; +function X_Node_CSS_parseColor( x ){ + var rgb, r, g, b; + + if( X.Type.isNumber( x ) ){ + return ( 0x0 <= x && x <= 0xFFFFFF ) ? x : undefined; + } else + if( !X.Type.isString( x ) ) return; + + if( X.Type.isNumber( rgb = X_Node_CSS_COLOR[ x.toUpperCase() ] ) && 0x0 <= rgb && rgb <= 0xFFFFFF ){ + return rgb; + } else + if( x.charAt( 0 ) === '#' ){ + switch( x.length ){ + case 7 : + r = parseInt( x.substr( 1, 2 ), 16 ); + g = parseInt( x.substr( 3, 2 ), 16 ); + b = parseInt( x.substr( 5, 2 ), 16 ); + break; + case 4 : + r = parseInt( x.charAt( 1 ) + x.charAt( 1 ), 16 ); + g = parseInt( x.charAt( 2 ) + x.charAt( 2 ), 16 ); + b = parseInt( x.charAt( 3 ) + x.charAt( 3 ), 16 ); + break; + case 2 : + r = g = b = parseInt( x.charAt( 1 ) + x.charAt( 1 ), 16 ); + break; + default : + return; }; - return isFinite( r + b + g ) ? ( r << 16 ) + ( g << 8 ) + b : undefined; - }, + } else + if( x.indexOf( 'rgb(' ) === 0 ){ + rgb = x.substr( 4 ).split( ',' ); + r = parseFloat( rgb[ 0 ] ); + g = parseFloat( rgb[ 1 ] ); + b = parseFloat( rgb[ 2 ] ); + if( x.indexOf( '%' ) !== -1 ){ + r *= 2.55; + g *= 2.55; + b *= 2.55; + }; + } else + if( x.indexOf( 'rgba(' ) === 0 ){ + rgb = x.substr( 5 ).split( ',' ); + r = parseFloat( rgb[ 0 ] ); + g = parseFloat( rgb[ 1 ] ); + b = parseFloat( rgb[ 2 ] ); + //a = parseFloat( rgb[ 3 ] ); + if( x.indexOf( '%' ) !== -1 ){ + r *= 2.55; + g *= 2.55; + b *= 2.55; + }; + } else { + return undefined; + }; + return isFinite( r + b + g ) ? ( r << 16 ) + ( g << 8 ) + b : undefined; +}; + +function X_Node_CSS_objToCssText( that ){ + var obj = that._css, + plain = X_EMPTY_OBJECT, + css = [], + n = -1, + p, v, specialFix, filterFix; + + if( !obj ) return ''; // Opera7.5 未満? + + for( p in obj ){ + v = obj[ p ]; -X_Node_CSS_PARAMS = ( function(){ - var ret = {}; - register( ret.percent = {}, - 'marginBottom,marginLeft,marginRight,marginTop,paddingBottom,paddingLeft,paddingRight,paddingTop,fontSize,textIndent' - ); - register( ret.offset = {}, - 'height,width,bottom,left,right,top' - ); - register( ret.size = {}, - 'borderBottomWidth,borderLeftWidth,borderRightWidth,borderTopWidth,letterSpacing,wordSpacing' - ); - register( ret.color = {}, - 'backgroundColor,borderBottomColor,borderLeftColor,borderRightColor,borderTopColor,color' - ); - register( ret.region = {}, - 'margin,padding,borderWidth,borderColor' - ); - register( ret.special = {}, - 'clip,backgroundPosition,backgroundPositionX,backgroundPositionY,opacity,lineHeight,zIndex' - ); - register( ret.unit = {}, 'px,cm,mm,in,pt,pc,em,%' ); + // object の拡張に備えて plain なオブジェクトを用意し、そのメンバーと一致するものは処理の対象外。 + if( plain[ p ] === v ) continue; - register( ret.margin = {}, 'marginBottom,marginLeft,marginRight,marginTop,paddingBottom' ); - register( ret.padding = {}, 'paddingBottom,paddingLeft,paddingRight,paddingTop' ); - register( ret.borderWidth = {}, 'borderBottomWidth,borderLeftWidth,borderRightWidth,borderTopWidth' ); - register( ret.borderColor = {}, 'borderBottomColor,borderLeftColor,borderRightColor,borderTopColor' ); + p = X_Node_CSS_uncamelize( X_Node_CSS_VENDER_PREFIX[ p ] || p ); - function register( obj, params ){ - params = params.split( ',' ); - for( var i = params.length; i; ) obj[ params[ --i ] ] = true; + if( specialFix = X_Node_CSS_SPECIAL_FIX_PROP[ p ] ){ + css[ ++n ] = p + ':' + specialFix( v ); + + } else + if( X_Node_CSS_FILTER_FIX_PROPS && X_Node_CSS_FILTER_FIX_PROPS[ p ] ){ + ( filterFix || ( filterFix = {} ) )[ p ] = v; + + } else { + css[ ++n ] = p + ':' + v; }; - return ret; - })(), + }; -X_Node_CSS__CLIP_SEPARATOR = X_UA.IE && X_UA.IE < 8 ? ' ' : ',', + filterFix && ( css[ ++n ] = 'filter:' + X_Node_CSS_objToIEFilterText( that, filterFix ) ); - /* - * - */ -X_Node_CSS_Property = X.Class.create( - 'Property', - X.Class.POOL_OBJECT, + return css.join( ';' ); +}; + +var +X_Node_CSS_FILTER_FIX_PROPS = + X_UA.ActiveX && X_UA.IE < 9 && !X_UA.MacIE ? { - Constructor : function( name, value, unit, xnode ){ - this.name = name; - this.value = value; - this.unit = unit; - this.xnode = xnode; - }, - name : '', - value : 0, - unit : '', - xnode : null, - equal : function( prop ){ - if( this.unit === prop.unit ){ - return this.value === prop.value; - }; - return Math.abs( this.toPx() - prop.toPx() ) < 1; - }, - convert: function( prop ){ - var u = prop.unit, v; - if( this.unit === u ) return; - this.value = v = this.toPx(); - this.unit = u; - // % - // bgpX, bgpY の場合 X.Util.Image.getActualDimension( backgroundImage url を使用 ) - if( u !== 'px' ){ - this.value = - u === 'em' ? - v / X_Node_CSS_getCharSize( this.xnode ) : - v / ( X_Node_CSS__UNIT_RATIO[ u ] || 1 ); - }; - }, - setValue: function( v ){ - this.value = v; - }, - getValue: function(){ - return this.value; - }, - getOffset: function( prop ){ - return prop.value - this.value; - }, - getUnit: function(){ - return this.unit; - }, - getValueText: function(){ - return this.value === 0 ? '0' : this.value + this.unit; - }, - toPx: function(){ - var v = this.value, u = this.unit; - return - u === 'px' ? - v : - ( u === 'em' || ( u === '' && this.name === 'lineHeight' ) ) ? - v * X_Node_CSS_getCharSize( this.xnode ) : - // u === '%' - v / ( X_Node_CSS__UNIT_RATIO[ u ] || 1 ); - }, - isValid: function(){ - var p = X_Node_CSS_PARAMS, - n = this.name, - v = this.value, - u = this.unit, - z = u !== '' ? true : v === 0; - if( p.percent[ n ] === true ) return z; - if( p.offset[ n ] === true ) return z; - if( p.size[ n ] === true ) return z && u !== '%'; - if( p.special[ n ] === true ){ - if( n === 'lineHeight' ) return true; - if( n === 'opacity' ) return 0 <= v && v <= 1 && u === ''; - if( n === 'zIndex' ) return u === ''; - }; - return false; - } - } - ), - - /** - * backgroundPosition, clip - */ -X_Node_CSS_PropertyGroup = X.Class.create( - 'PropertyGroup', - X.Class.POOL_OBJECT, + opacity : 2, + boxShadow : 3, + textShadow : 4 + } : + X_UA.ActiveX && X_UA.IE9 ? // == 9 { - Constructor : function( name ){ - this.name = name; - this.props = []; - for( var i = 1, l = arguments.length; i> 16; - g = ( rgb & 0xff00 ) >> 8; - b = ( rgb & 0xff ); - } else - if( x.charAt( 0 ) === '#' ){ - if( x.length === 7 ){ - r = parseInt( x.charAt( 1 ) + x.charAt( 2 ), 16 ); - g = parseInt( x.charAt( 3 ) + x.charAt( 4 ), 16 ); - b = parseInt( x.charAt( 5 ) + x.charAt( 6 ), 16 ); - } else - if( x.length === 4 ){ - r = parseInt( x.charAt( 1 ) + x.charAt( 1 ), 16 ); - g = parseInt( x.charAt( 2 ) + x.charAt( 2 ), 16 ); - b = parseInt( x.charAt( 3 ) + x.charAt( 3 ), 16 ); + textShadow : 4 + } : + null; + +function X_Node_CSS_objToIEFilterText( that, opt_css ){ + var obj = opt_css || that._css, + test = X_Node_CSS_FILTER_FIX_PROPS, + filters = [], + n = -1, + p, id, v, num, ary, params, i, l, dir, + afterUpdate, impossible; + for( p in obj ){ + if( !( id = test[ p ] ) ) continue; + v = obj[ p ]; + + switch( id ){ + case 1 : //'filter' : + filters[ ++n ] = v; + break; + case 2 : //'opacity' : + filters[ ++n ] = 'alpha(opacity=' + ( v * 100 | 0 ) +')'; + break; + case 3 : //'boxShadow' : + // TODO カンマ区切りの複数指定 + // box-shadow: 10px 10px 10px 10px rgba(0,0,0,0.4) inset; + // スペース区切りで、水平方向の距離 垂直方向の距離 ぼかし距離 広がり距離 影の色 insetキーワードを指定する。 ぼかし距離 広がり距離 影の色 insetキーワードは省略可 + // https://developer.mozilla.org/ja/docs/Web/CSS/box-shadow + // に絶対値は不可? 省略した場合は、文字の色が使われる(webkit以外) + // shadow(color=#cccccc, strength=10, direction=135); + ary = v.split( ' ' ); + params = [ 0, 0, 0, 0 ]; // offset-x, offset-y, blur-radius, spread-radius + for( i = 0, l = ary.length; i < l; ++i ){ + v = ary[ i ]; + num = i < 4 && parsetFloat( v ); + + if( num === num ){ + vu = X_Node_CSS__splitValueAndUnit( v ); + v = vu[ 0 ]; + u = vu[ 1 ]; + if( v ){ + if( _v = X_Node_CSS__UNIT_RATIO[ u ] ){ + params[ i ] = v / _v; + } else { + switch( u ){ + case 'px' : + params[ i ] = v; + break; + case 'em' : + if( X_Node_updateTimerID ){ + afterUpdate = true; + } else { + params[ i ] = X_Node_CSS_getCharSize( that ) * v; + }; + default : + params[ i ] = 0; + break; + }; + }; + } else { + params[ i ] = 0; + }; } else - if( x.length === 2 ){ - r = parseInt( x.charAt( 1 ) + x.charAt( 1 ), 16 ); - g = parseInt( x.charAt( 1 ) + x.charAt( 1 ), 16 ); - b = parseInt( x.charAt( 1 ) + x.charAt( 1 ), 16 ); + if( v.charAt( 0 ) === '#' || v.indexOf( 'rgb' ) === 0 || X_Node_CSS_COLOR[ v.toUpperCase() ] ){ + v = X_Node_CSS_parseColor( v ); + if( 0 <= v && v < 0x100000 ){ + color = '00000' + v.toString( 16 ); + color = '#' + color.substr( color.length - 6 ); + } else + if( v ){ + color = '#' + v.toString( 16 ); + }; + } else + if( v === 'inset' ){ + impossible = true; + } else { + // unknown }; - } else - if( x.indexOf( 'rgb(' ) === 0 ){ - rgb = x.substr( 4 ).split( ',' ); - r = parseFloat( rgb[ 0 ] ); - g = parseFloat( rgb[ 1 ] ); - b = parseFloat( rgb[ 2 ] ); - if( x.indexOf( '%' ) !== -1 ) pct = true; - } else - if( x.indexOf( 'rgba(' ) === 0 ){ - rgb = x.substr( 5 ).split( ',' ); - r = parseFloat( rgb[ 0 ] ); - g = parseFloat( rgb[ 1 ] ); - b = parseFloat( rgb[ 2 ] ); - a = parseFloat( rgb[ 3 ] ); - if( x.indexOf( '%' ) !== -1 ) pct = true; - } else { - r = 255; - g = 255; - b = 255; }; - - this.name = name; - this.r = r; - this.g = g; - this.b = b; - this.a = a; - this.pct = pct; - }, - name : '', - r : 0, - g : 0, - b : 0, - a : 0, - pct : false, - equal : function( prop ){ - if( this.pct === prop.pct ){ - return this.r === prop.r && this.g === prop.g && this.b === prop.b; - }; - var rgb = this._toPct(), - _rgb = prop._toPct(), - i = rgb.length; - for( ; i; ){ - --i; - if( Math.abs( rgb[ i ] - _rgb[ i ] ) > 1 ) return false; + if( impossible || !color ){ + break; }; - return true; - }, - convert : function( prop ){ - var u = prop.pct, x; - if( this.pct === u ) return; - x = u === true ? 100 / 255 : 2.55; - this.r *= x; - this.g *= x; - this.b *= x; - this.pct = u; - }, - setValue : function( rgb ){ - this.r = rgb[ 0 ]; - this.g = rgb[ 1 ]; - this.b = rgb[ 2 ]; - }, - getValue : function(){ - return [ this.r, this.g, this.b ]; - }, - getOffset : function( prop ){ - return [ prop.r - this.r, prop.g - this.g, prop.b - this.b ]; - }, - getUnit : function(){ - return this.pct === true ? '%' : ''; - }, - getValueText : function(){ - if( this.pct === true ){ - return [ 'rgb(', this.r, '%,', this.g, '%,', this.b, '%)' ].join( '' ); + if( afterUpdate ){ + // AFTER_UPDATE 時に 再計算 + X_ViewPort.listenOnce( X_Event.AFTER_UPDATE, that, X_Node_CSS_onAfterUpdateForIEFilterFix ); + break; }; - var round = Math.round; - - var rgb = '00000' + ( ( round( this.r ) << 16 ) + ( round( this.g ) << 8 ) + round( this.b ) ).toString( 16 ); - return '#' + rgb.substr( rgb.length - 6 ); - }, - _toPct : function(){ - if( this.pct === true ) return [ this.r, this.g, this.b ]; - return [ this.r / 2.55, this.g / 2.55, this.b / 2.55 ]; - }, - isValid : function( t ){ - var isFinite = window.isFinite; - if( !isFinite( this.r ) || !isFinite( this.g ) || !isFinite( this.b ) ) return false; - if( 0 > this.r || 0 > this.g || 0 > this.b ) return false; - if( this.pct === true ) return this.r <= 100 && this.g <= 100 && this.b <= 100; - return this.r <= 255 && this.g <= 255 && this.b <= 255; - } - } - ); - -function X_Node_CSS__getProperty( xnode, css, unit, p ){ - - var me = X_Node_CSS__getProperty, - PARAMS = X_Node_CSS_PARAMS, - PropertyGroup = X_Node_CSS_PropertyGroup, - Property = X_Node_CSS_Property, - ColorProperty = X_Node_CSS_ColorProperty, - name, width; - - if( PARAMS.special[ p ] === true || PARAMS.region[ p ] === true ){ - switch( p ){ - case 'clip' : - // rect(...) クリップします。, は上端からの、 , は左端からのオフセットで指定します。Internet Explorer 4~7 では、カンマの代わりにスペースで区切る必要があります。 - // position:absolute または position:fixed を適用した要素に対してのみ有効です。 - var top = me( p + 'Top' ), - right = me( p + 'Right' ), - bottom = me( p + 'Bottom' ), - left = me( p + 'Left' ), - ret = new PropertyGroup( p, top, right, bottom, left ), - all; - if( ret.isValid() === true ) return ret; - ret.kill(); - all = css[ p ].split( '(' )[ 1 ].split( ')' )[ 0 ].split( X_Node_CSS__CLIP_SEPARATOR ); - return - new PropertyGroup( - p, - new Property( p + 'Top', all[ 0 ], 'px', xnode ), - new Property( p + 'Right', all[ 1 ], 'px', xnode ), - new Property( p + 'Bottom', all[ 2 ], 'px', xnode ), - new Property( p + 'Left', all[ 3 ], 'px', xnode ) - ); - - case 'margin' : - case 'padding' : - name = p; - width = ''; - case 'borderWidth' : - var props = '$1Top$2,$1Right$2,$1Bottom$2,$1Left$2'.split( '$1' ).join( name || 'border' ).split( '$2' ).join( width || 'Width' ).split( ',' ), - top = me( props[ 0 ] ), - right = me( props[ 1 ] ), - bottom = me( props[ 2 ] ), - left = me( props[ 3 ] ), - ret = new PropertyGroup( p, top, right, bottom, left ), - all, _0, _1, _2, _3, vu, v, u; - if( ret.isValid() === true ) return ret; - ret.kill(); - all = css[ p ].split( ' ' ); - _0 = all[ 0 ]; - _1 = all[ 1 ]; - _2 = all[ 2 ]; - _3 = all[ 3 ]; - vu = X_Node_CSS__splitValueAndUnit( _0 ); - v = vu[ 0 ]; - u = vu[ 1 ]; - switch( all.length ){ - case 1 : - top = new Property( props[ 0 ], v, u, xnode ); - right = new Property( props[ 1 ], v, u, xnode ); - bottom = new Property( props[ 2 ], v, u, xnode ); - left = new Property( props[ 3 ], v, u, xnode ); - break; - case 2 : - top = new Property( props[ 0 ], v, u, xnode ); - bottom = new Property( props[ 2 ], v, u, xnode ); - vu = X_Node_CSS__splitValueAndUnit( _1 ); - v = vu[ 0 ]; - u = vu[ 1 ]; - right = new Property( props[ 1 ], v, u, xnode ); - left = new Property( props[ 3 ], v, u, xnode ); - break; - case 3 : - top = new Property( props[ 0 ], v, u, xnode ); - vu = X_Node_CSS__splitValueAndUnit( _1 ); - v = vu[ 0 ]; - u = vu[ 1 ]; - right = new Property( props[ 1 ], v, u, xnode ); - left = new Property( props[ 3 ], v, u, xnode ); - vu = X_Node_CSS__splitValueAndUnit( _2 ); - v = vu[ 0 ]; - u = vu[ 1 ]; - bottom = new Property( props[ 2 ], v, u, xnode ); - break; - case 4 : - top = new Property( props[ 0 ], v, u, xnode ); - vu = X_Node_CSS__splitValueAndUnit( _1 ); - v = vu[ 0 ]; - u = vu[ 1 ]; - right = new Property( props[ 1 ], v, u, xnode ); - vu = X_Node_CSS__splitValueAndUnit( _2 ); - v = vu[ 0 ]; - u = vu[ 1 ]; - bottom = new Property( props[ 2 ], v,u, xnode ); - vu = X_Node_CSS__splitValueAndUnit( _3 ); - v = vu[ 0 ]; - u = vu[ 1 ]; - left = new Property( props[ 3 ], v, u, xnode ); - break; - }; - return new PropertyGroup( p, top, right, bottom, left ); - - case 'borderColor' : - var props = 'borderTopColor,borderRightColor,borderBottomColor,borderLeftColor'.split( ',' ), - top = me( props[ 0 ] ), - right = me( props[ 1 ] ), - bottom = me( props[ 2 ] ), - left = me( props[ 3 ] ), - ret = new PropertyGroup( p, top, right, bottom, left ), - all, _0, _1; - if( ret.isValid() === true ) return ret; - ret.kill(); - all = css[ p ].split( ' ' ); - _0 = all[ 0 ]; - _1 = all[ 1 ]; - switch( all.length ){ - case 1 : - top = new ColorProperty( props[ 0 ], _0 ); - right = new ColorProperty( props[ 1 ], _0 ); - bottom = new ColorProperty( props[ 2 ], _0 ); - left = new ColorProperty( props[ 3 ], _0 ); - break; - case 2 : - top = new ColorProperty( props[ 0 ], _0 ); - right = new ColorProperty( props[ 1 ], _1 ); - bottom = new ColorProperty( props[ 2 ], _0 ); - left = new ColorProperty( props[ 3 ], _1 ); - break; - case 3 : - top = new ColorProperty( props[ 0 ], _0 ); - right = new ColorProperty( props[ 1 ], _1 ); - bottom = new ColorProperty( props[ 2 ], all[ 2 ] ); - left = new ColorProperty( props[ 3 ], _1 ); - break; - case 4 : - top = new ColorProperty( props[ 0 ], _0 ); - right = new ColorProperty( props[ 1 ], _1 ); - bottom = new ColorProperty( props[ 2 ], all[ 2 ] ); - left = new ColorProperty( props[ 3 ], all[ 3 ] ); - break; - }; - return new PropertyGroup( p, top, right, bottom, left ); - - case 'backgroundPosition' : - var x = me( p + 'X' ), - y = me( p + 'Y' ), - ret = new PropertyGroup( p, x, y ), - xy; - if( ret.isValid() === true ) return ret; - ret.kill(); - xy = css[ p ].split( ' ' ); - x = X_Node_CSS__splitValueAndUnit( xy[ 0 ] ); - y = X_Node_CSS__splitValueAndUnit( xy[ 1 ] ); - return - new PropertyGroup( - p, - new Property( p + 'X', x[ 0 ], x[ 1 ], xnode ), - new Property( p + 'Y', y[ 0 ], y[ 1 ], xnode ) - ); - }; - // opacity, zindex, lineHeight - vu = X_Node_CSS__splitValueAndUnit( css[ p ] ); - return new Property( p, vu[ 0 ], vu[ 1 ], xnode ); - }; - var x = css[ p ], e, v, u; - /* - if( PARAMS.offset[ p ] === true ){ - return new Property( p, vu[ 0 ], vu[ 1 ], xnode ); - - e = this.elm; - if( p === 'width' ) v = e.offsetWidth; - if( p === 'height' ) v = e.offsetHeight; - if( p === 'top' ) v = e.offsetTop; - if( p === 'bottom' ) v = e.offsetBottom; - if( p === 'left' ) v = e.offsetLeft; - if( p === 'right' ) v = e.offsetRight; - u = _getUnit( x, p ); - // alert( p + X_Node_CSS__Util.pxTo( v, u ) + u ) - return new Property( p, X_Node_CSS__Util.pxTo( v, u ), u, xnode ); - }; */ - if( p === 'fontSize' && ( v = X_Node_CSS__FONT_SIZE_RATIO[ x ] ) ){ // xx-small 等 - return new Property( p, v, 'px', xnode ); - }; - if( PARAMS.offset[ p ] || PARAMS.percent[ p ] || PARAMS.size[ p ] ){ - vu = X_Node_CSS__splitValueAndUnit( x ); - return new Property( p, vu[ 0 ], vu[ 1 ], xnode ); + dir = Math.atan2( params[ 1 ] + params[ 3 ], params[ 0 ] + params[ 3 ] ) * 180 / Math.PI + 90; + dir += dir < 0 ? 360 : 0; + filters[ ++n ] = 'shadow(color=' + color + ',strength=' + params[ 3 ] + ',direction=' + ( dir | 0 ) + ')'; + break; + case 4 : //'textShadow' : + //text-shadow: 5px 5px 2px blue; 水平方向の距離 垂直方向の距離 影のぼかし半径 影の色 none + //glow(Color=yellow,Strength=10); + //どうやらCSSのbackgroundプロパティと同時に使えないようです。 s + break; + case 5 : //'backgroundImage' : + // }; - - if( PARAMS.color[ p ] ) return new ColorProperty( p, x ); }; - -function X_Node_CSS__splitValueAndUnit( v ){ - var num, _num, u; - if( X.Type.isNumber( v ) ) return [ v || 0, '' ]; - if( isNaN( num = parseFloat( v ) ) ) return [ 0, '' ]; - _num = '' + num; - if( _num.indexOf( '0.' ) === 0 ) _num = _num.slice( 1 ); - u = v.substr( v.indexOf( _num ) + _num.length ); - return [ num, X_Node_CSS_UNIT[ u ] ? u : 'px' ]; + return filters.join( ' ' ); +}; + +function X_Node_CSS_onAfterUpdateForIEFilterFix(){ + if( this._root ){ // 要素があり、要素がツリーに属している + this._dirty |= X_Node_Dirty.IE_FILTER; + X_Node_reserveUpdate(); }; +}; + -var X_Node_CSS__GET_VALUE_WITH_UNIT = { - borderWidth : X_Node_CSS_Type.QUARTET | X_Node_CSS_Type.LENGTH, - //borderStyle : X_Node_CSS_Type.QUARTET, - borderRadius : X_Node_CSS_Type.QUARTET | X_Node_CSS_Type.LENGTH, - margin : X_Node_CSS_Type.QUARTET | X_Node_CSS_Type.LENGTH | X_Node_CSS_Type.PERCENT, - padding : X_Node_CSS_Type.QUARTET | X_Node_CSS_Type.LENGTH | X_Node_CSS_Type.PERCENT, - clip : X_Node_CSS_Type.QUARTET | X_Node_CSS_Type.LENGTH | X_Node_CSS_Type.PERCENT, - - backgroundColor : X_Node_CSS_Type.COLOR, - backgroundPosition : X_Node_CSS_Type.COMBI, - - // boxShadow - - fontSize : X_Node_CSS_Type.LENGTH, - lineHeight : X_Node_CSS_Type.LENGTH | X_Node_CSS_Type.PERCENT | X_Node_CSS_Type.NUMERICAL, - textIndent : X_Node_CSS_Type.LENGTH, - letterSpacing : X_Node_CSS_Type.LENGTH, - wordSpacing : X_Node_CSS_Type.LENGTH, /* - textShadowColor : X_Node_CSS_Type.COLOR, - textShadowOffsetX : X_Node_CSS_Type.LENGTH, - textShadowOffsetY : X_Node_CSS_Type.LENGTH, - textShadowBlur : X_Node_CSS_Type.LENGTH, */ - - width : X_Node_CSS_Type.LENGTH | X_Node_CSS_Type.PERCENT, - height : X_Node_CSS_Type.LENGTH | X_Node_CSS_Type.PERCENT, - - left : X_Node_CSS_Type.LENGTH | X_Node_CSS_Type.PERCENT, - top : X_Node_CSS_Type.LENGTH | X_Node_CSS_Type.PERCENT, - bottom : X_Node_CSS_Type.LENGTH | X_Node_CSS_Type.PERCENT, - right : X_Node_CSS_Type.LENGTH | X_Node_CSS_Type.PERCENT, + * http://css-eblog.com/ie-css-problems/rgba-pe.html + * ie67 では rgb() は background-color で反応しない、、、 + */ - // table - borderSpacing : X_Node_CSS_Type.LENGTH +var +X_Node_CSS_UNIT = { + 'px' : 0, + 'em' : 1, + // ex, rem, vh, vw, vmin, vmax + 'cm' : 2, + 'mm' : 3, + 'in' : 4, + // pt, pc, mozmm + '%' : 5, + 'pct' : 5, + 'ms' : 6, + 's' : 7, + '#' : 8, + 'rgb' : 9, + 'rgba' : 10 }; - -var X_Node_CSS_SPECIAL_FIX = - // ~IE8 - X_UA.IE && X_UA.IE < 9 && !X_UA.MacIE? - (function( obj ){ - var test = X_Node_CSS_SPECIAL_FIX_PROP, - filters = [], - n = -1, - p, id, v, dir; - for( p in obj ){ - if( !( id = test[ p ] ) ) continue; - v = obj[ p ]; - switch( id ){ - case 1 : //'filter' : - filters[ ++n ] = v; - break; - case 2 : //'opacity' : - filters[ ++n ] = 'alpha(opacity=' + v * 100 +')'; - break; - case 3 : //'boxShadow' : - // box-shadow: 10px 10px 10px 10px rgba(0,0,0,0.4) inset; - // スペース区切りで、水平方向の距離 垂直方向の距離 ぼかし距離 広がり距離 影の色 insetキーワードを指定する。 ぼかし距離 広がり距離 影の色 insetキーワードは省略可 - // shadow(color=#cccccc, strength=10, direction=135); - v = X_Node_CSS__getProperty( this, css, 'px', 'boxShadow' ); - dir = Math.atan2( v[ 1 ], v[ 0 ] ) * 180 / Math.PI + 90; - dir += dir < 0 ? 360 : 0; - filters[ ++n ] = 'shadow(color=' + v[ 4 ] + ',strength=' + v[ 3 ] + ',direction=' + dir + ')'; - break; - case 4 : //'textShadow' : - //text-shadow: 5px 5px 2px blue; 水平方向の距離 垂直方向の距離 影のぼかし半径 影の色 none - //glow(Color=yellow,Strength=10); - //どうやらCSSのbackgroundプロパティと同時に使えないようです。 - - - break; - case 5 : //'backgroundImage' : - // - }; - }; - return filters.join( ' ' ); - }) : - // IE9 textShadow に filter を使用 - X_UA.IE && 9 <= X_UA.IE && X_UA.IE < 10 ? - (function( obj ){ - var test = X_Node_CSS_SPECIAL_FIX_PROP, - filters = [], p, id, v; - for( p in obj ){ - if( !( id = test[ p ] ) ) continue; - v = obj[ p ]; - switch( id ){ - case 1 : //'filter' : - filters[ filters.length ] = v; - break; - }; - }; - if( filters ) return filters.join( ' ' ); - }) : +/* + * .2, -.1 といったケースに対処 + * + */ +function X_Node_CSS__splitValueAndUnit( v ){ + var num, _num, u; + if( X.Type.isNumber( v ) ) return [ v || 0, '' ]; + num = parseFloat( v ); + if( num !== num ) return [ 0, '' ]; + _num = '' + num; + if( 0 < num && num < 1 && v.charAt( 0 ) === '.' ) _num = _num.slice( 1 ); + if( -1 < num && num < 0 && v.charAt( 1 ) === '.' ) _num = '-.' + _num.substr( 2 ); + u = v.substr( v.indexOf( _num ) + _num.length ); + return [ num, X_Node_CSS_UNIT[ u ] ? u : 'px' ]; +}; + /* (function( obj ){ var test = X_Node_CSS_SPECIAL_FIX_PROP, ret = [], p, id, v, bgpX, bgpY, clipT, clipB, clipL, clipR; @@ -937,16 +450,16 @@ var X_Node_CSS_SPECIAL_FIX = case 2 : //'backgroundPositionY' : bgpY = v; break; - case 3 : //'backgroundPositionX' : + case 3 : //'clipTop' : clipT = v; break; - case 4 : //'backgroundPositionX' : + case 4 : //'clipBottom' : clipB = v; break; - case 5 : //'backgroundPositionX' : + case 5 : //'clipLeft' : clipL = v; break; - case 6 : //'backgroundPositionX' : + case 6 : //'clipRight' : clipR = v; break; }; @@ -956,7 +469,7 @@ var X_Node_CSS_SPECIAL_FIX = ret[ ret.length ] = 'clip:rect('; }; return ret.join( ';' ); - }); + }); */ @@ -968,17 +481,20 @@ var X_Node_CSS_SPECIAL_FIX = // name, value setter Node.prototype.css = function( nameOrObj /* orUnitID, valuOrUnitOrName */ ){ - var args = arguments, - css = this._css, + var plain = X_EMPTY_OBJECT, + args = arguments, + css = this._css, p, name, v, camelize, unit, ieFix; if( this._xnodeType !== 1 ) return this; // setter:object if( X.Type.isObject( nameOrObj ) ){ if( !css ) css = this._css = {}; camelize = X_Node_CSS_camelize; - ieFix = X_Node_CSS_IE_FILTER_FIX; + ieFix = X_Node_CSS_FILTER_FIX_PROPS; for( p in nameOrObj ){ - if( ieFix[ p ] ){ + if( plain[ p ] === nameOrObj[ p ] ) continue; + + if( ieFix && ieFix[ p ] ){ this._dirty |= X_Node_Dirty.IE_FILTER; }; v = nameOrObj[ p ]; @@ -994,38 +510,28 @@ Node.prototype.css = function( nameOrObj /* orUnitID, valuOrUnitOrName */ ){ return this; } else if( 1 < args.length ){ - if( !X_Node_CSS_UNIT[ nameOrObj ] ){ // setter name, value - if( !css ) css = this._css = {}; - name = X_Node_CSS_camelize( nameOrObj ); - v = args[ 1 ]; - if( css[ name ] === v ) return this; - if( X_Node_CSS_IE_FILTER_FIX[ name ] ){ - this._dirty |= X_Node_Dirty.IE_FILTER; - }; - if( !v && v !== 0 ){ - delete css[ name ]; - } else { - css[ name ] = v; - }; - delete this._cssText; - this._dirty |= X_Node_Dirty.CSS; - if( name === 'display' ){ - v === 'none' ? ( this._state |= X_Node_State.IE5_DISPLAY_NONE_FIX ) : ( this._state &= ~X_Node_State.IE5_DISPLAY_NONE_FIX ); - v === 'none' ? ( this._state |= X_Node_State.DISPLAY_NONE ) : ( this._state &= ~X_Node_State.DISPLAY_NONE ); - }; - // parent でなく this._root! でなくて this._state & in tree - this.parent && X_Node_reserveUpdate(); - return this; + if( !css ) css = this._css = {}; + name = X_Node_CSS_camelize( nameOrObj ); + v = args[ 1 ]; + if( css[ name ] === v ) return this; + if( X_Node_CSS_FILTER_FIX_PROPS && X_Node_CSS_FILTER_FIX_PROPS[ name ] ){ + this._dirty |= X_Node_Dirty.IE_FILTER; + }; + if( !v && v !== 0 ){ + delete css[ name ]; + } else { + css[ name ] = v; + }; + delete this._cssText; + this._dirty |= X_Node_Dirty.CSS; + if( name === 'display' ){ + v === 'none' ? ( this._state |= X_Node_State.IE5_DISPLAY_NONE_FIX ) : ( this._state &= ~X_Node_State.IE5_DISPLAY_NONE_FIX ); + v === 'none' ? ( this._state |= X_Node_State.DISPLAY_NONE ) : ( this._state &= ~X_Node_State.DISPLAY_NONE ); }; -// getter unit -// unit 付の値取得は fontSize と 画像サイズが確定していないと正確に取れない。内部のみにする? - if( !css ) return; - if( !X_Node_CSS__GET_VALUE_WITH_UNIT[ name = X_Node_CSS_camelize( args[ 1 ] ) ] ) return null; - p = X_Node_CSS__getProperty( this, css, nameOrObj, name ); - v = p.pxTo( nameOrObj ); - p.kill(); - return v; + // parent でなく this._root! でなくて this._state & in tree + this.parent && X_Node_reserveUpdate(); + return this; }; // getter if( !css ) return; @@ -1056,7 +562,7 @@ Node.prototype.cssText = function( v ){ return this.css( obj ); }; // getter - if( this._dirty & X_Node_Dirty.CSS && !( this._cssText = X_Node_CSS_objToCssText( this._css ) ) ){ + if( this._dirty & X_Node_Dirty.CSS && !( this._cssText = X_Node_CSS_objToCssText( this ) ) ){ delete this._cssText; }; return this._cssText; @@ -1066,23 +572,18 @@ Node.prototype.cssText = function( v ){ * ここでは HTMLElement のチ1ェックは行わない! * TODO * body に css attr がセットされた場合には X_ViewPort_baseFontSize をクリア + * class, id, attr() の変更があった場合は、変更の適用の後、charSize を取得 + * css の場合は、計算で求めることが可能、content は影響しない + * :hover, #target, が絡む場合、正しく扱えない */ var X_Node_CSS_getCharSize = - window.getComputedStyle ? - (function( that ){ - X_Node_updateTimerID && X_Node_startUpdate(); - if( that === X_Node_body && X_ViewPort_baseFontSize ) return X_ViewPort_baseFontSize; - if( that._fontSize ) return that._fontSize; - return that._fontSize = parseFloat( getComputedStyle( that._rawObject, null ).fontSize ); - }) : - - document.defaultView && document.defaultView.getComputedStyle ? + X_node_CSS_getComputedStyle ? (function( that ){ X_Node_updateTimerID && X_Node_startUpdate(); if( that === X_Node_body && X_ViewPort_baseFontSize ) return X_ViewPort_baseFontSize; if( that._fontSize ) return that._fontSize; - return that._fontSize = parseFloat( document.defaultView.getComputedStyle( that._rawObject, null ).fontSize ); + return that._fontSize = parseFloat( X_node_CSS_getComputedStyle( that._rawObject, null ).fontSize ); }) : 5.5 <= X_UA.IE ? @@ -1167,29 +668,46 @@ X_Node_CSS_getCharSize = }) : 0; +var X_Node_CSS_Support = {}, + + X_Node_CSS_SPECIAL_FIX_PROP = { + + transitionDuration : X_UA.Android && !X_UA.Chrome && function( v ){ // bad Android + return parseFloat( v ) === 0 ? '0.001s' : v; + } + + //webkit boxShadow が省略された場合。transparent になるのを color に + //webkit boxShadow が border-radius をはみ出す, background-image に グラデーションのないグラデーション指定 + // http://melty.koume.in/android-bug-boxshadow-radius/ + + }; X.CSS = { VENDER_PREFIX : X_Node_CSS_VENDER_PREFIX, + // iscroll で使用 + uncamelize : X_Node_CSS_uncamelize, - parseColor : X_Node_CSS_parseColor, - - uncamelize : X_Node_CSS_uncamelize + Support : X_Node_CSS_Support }; +/* + * backgroundPositionX : testStyle.backgroundPositionX === undefined ? 3 : 0, + backgroundPosiitonY : testStyle.backgroundPositionX === undefined ? 3 : 0, + clipTop : testStyle.clipTop === undefined && testStyle[ 'clip-top' ] === undefined ? 3 : 0, + clipBottom : testStyle.clipTop === undefined && testStyle[ 'clip-top' ] === undefined ? 4 : 0, + clipLeft : testStyle.clipTop === undefined && testStyle[ 'clip-top' ] === undefined ? 5 : 0, + clipRight : testStyle.clipTop === undefined && testStyle[ 'clip-top' ] === undefined ? 6 : 0 + */ - -var X_Node_CSS_Support, X_Node_CSS_SPECIAL_FIX_PROP; - -( function(){ +(function(){ var testStyle = X_UA.IE4 ? {} : ( document.documentElement || document.createElement( 'div' ) ).style, temp = testStyle.cssText, - prefix = X_Node_CSS_VENDER_PREFIX, vendors = 'webkit,Webkit,Moz,moz,Ms,ms,O,o,khtml,Khtml'.split( ',' ), searches = ( - 'opacity,boxSizing,' + + 'opacity,boxSizing,boxShadow,' + 'transform,transformOrigin,perspective,' + - 'transisiton,transitionDelay,transitionProperty,transitionDuration,transitionTimingFunction,' + + 'transisiton,transitionDelay,transitionProperty,transitionDuration,transitionTimingFunction,backfaceVisibility,willChange,' + 'userSelect,touchSelect,touchAction,touchCallout,contentZooming,userDrag,tapHighlightColor' ).split( ',' ), vendor, i, search, prop, j, v; @@ -1203,48 +721,51 @@ var X_Node_CSS_Support, X_Node_CSS_SPECIAL_FIX_PROP; if( testStyle[ v + prop ] !== undefined ){ if( v === 'ms' ) v = 'Ms';// for ie9 if( v === 'o' ) v = 'O';//for opera12 - prefix[ search ] = v + prop; + X_Node_CSS_VENDER_PREFIX[ search ] = v + prop; break; }; }; } else { - prefix[ search ] = prop; + X_Node_CSS_VENDER_PREFIX[ search ] = prop; }; }; testStyle.cssText = 'background:rgba(0,0,0,0.5)'; + X_Node_CSS_Support[ 'rgba' ] = !!testStyle.background; - X.CSS.Support = X_Node_CSS_Support = { - rgba : !!testStyle.background + /* + * chrome 1+, ff3.5(1.9.1), ie9+, opera10.5+, Safari3+(522) + */ + if( prop = X_Node_CSS_VENDER_PREFIX[ 'boxShadow' ] ){ + + testStyle.cssText = X_Node_CSS_uncamelize( prop ) + ':0 0'; + X_Node_CSS_Support[ 'boxShadow' ] = !!testStyle[ prop ]; + + /* + * chrome 4+, ff3.5(1.9.1), ie9+, opera10.5+, Safari5+(533) + */ + testStyle.cssText = X_Node_CSS_uncamelize( prop ) + ':0 0, 0 0'; + X_Node_CSS_Support[ 'boxShadowMulti' ] = !!testStyle[ prop ]; + + /* + * https://developer.mozilla.org/ja/docs/Web/CSS/box-shadow + * この値を用いる場合には、spread-radius を省略出来ません。box-shadow が効かないケースに遭遇した時はこの事を思い出して下さい。 + * chrome 4+, ff3.5(1.9.1), ie9+, opera10.5+, Safari5+(533) + * + * http://unformedbuilding.com/articles/considerations-when-using-the-box-shadow/ + * box-shadow:inset と border-radius を指定しているときの Google Chrome の表示 + * このバグは Windows と Linux で発生するようです。 + * Windows 版 Chrome 10.0.648.127 で修正されているのを確認しました。 + */ + testStyle.cssText = X_Node_CSS_uncamelize( prop ) + ':0 0 inset'; + X_Node_CSS_Support[ 'boxShadowInset' ] = testStyle[ prop ] && testStyle[ prop ].indexOf( 'inset' ) !== -1; + }; + testStyle.cssText = temp; - - X_Node_CSS_SPECIAL_FIX_PROP = - // ~IE8 - X_UA.IE < 9 && !X_UA.MacIE ? - { - filter : 1, - opacity : 2//, uinode ChromeNode で行う - //boxShadow : 3, - //textShadow : 4, - //backgroundImage : 5 - } : - // IE9 - 9 <= X_UA.IE && X_UA.IE < 10 ? - { - filter : 1//, - //textShadow : 1 - } : - { - backgroundPositionX : testStyle.backgroundPositionX === undefined ? 3 : 0, - backgroundPosiitonY : testStyle.backgroundPositionX === undefined ? 3 : 0, - clipTop : testStyle.clipTop === undefined && testStyle[ 'clip-top' ] === undefined ? 3 : 0, - clipBottom : testStyle.clipTop === undefined && testStyle[ 'clip-top' ] === undefined ? 4 : 0, - clipLeft : testStyle.clipTop === undefined && testStyle[ 'clip-top' ] === undefined ? 5 : 0, - clipRight : testStyle.clipTop === undefined && testStyle[ 'clip-top' ] === undefined ? 6 : 0 - }; -} )(); + +})(); X_ViewPort.listenOnce( X_TEMP.SYSTEM_EVENT_INIT, function(){ var xnode = X_Node_systemNode, @@ -1267,5 +788,5 @@ X_ViewPort.listenOnce( X_TEMP.SYSTEM_EVENT_INIT, function(){ }; xnode.cssText( '' ).empty(); -} ); +}); diff --git a/0.6.x/js/06_net/02_XNetJSONP.js b/0.6.x/js/06_net/02_XNetJSONP.js index 806396c..45cfec5 100644 --- a/0.6.x/js/06_net/02_XNetJSONP.js +++ b/0.6.x/js/06_net/02_XNetJSONP.js @@ -26,9 +26,9 @@ X.Net.JSONP = { X_NET_JSONPWrapper._busy = false; X_NET_JSONPWrapper - .asyncDispatch( 0, { + .asyncDispatch( { type : jsonString ? X.Event.SUCCESS : X.Event.ERROR, - data : jsonString //eval( jsonString ) + data : jsonString //window.JSON ? JSON.parse( jsonString ) : eval( jsonString ) } ); console.log( 'ms : ' + time + ' speed : ' + ( ( jsonString.length + ( opt_json2FileSize || 0 ) ) / time * 1000 ) + ' バイト/秒.' ); @@ -52,15 +52,13 @@ function X_NET_JSONP_loadScriptInNinjaIframe( url ){ // TODO ' 化 恐らくアンチウイルスソフトが反応しないための対策 // TODO postMessage の利用 - // numonLoad - if( X_UA.Opera ){ html = [ ( window[ 'JSON' ] ? '' : '' ), '', '', '' @@ -69,6 +67,9 @@ function X_NET_JSONP_loadScriptInNinjaIframe( url ){ } else if( X_UA.IE8 ){ html = [ + // JavaScriptでunicode文字列をunescapeする + // http://perutago.seesaa.net/article/202801583.html + // http://blog.livedoor.jp/dankogai/archives/51503830.html // Ajax - IE8にもJSON入ってます。使えるとは限らないけど // Compatibility mode (別名Quirks mode) では、JSONオブジェクトは無効になります。iframeもだめです @@ -76,7 +77,7 @@ function X_NET_JSONP_loadScriptInNinjaIframe( url ){ '' diff --git a/0.6.x/js/20_ui/06_AbstractUINode.js b/0.6.x/js/20_ui/06_AbstractUINode.js index f3b9c1f..4c6e210 100644 --- a/0.6.x/js/20_ui/06_AbstractUINode.js +++ b/0.6.x/js/20_ui/06_AbstractUINode.js @@ -144,7 +144,7 @@ X.UI._AbstractUINode = X.EventDispatcher.inherits( if( v.indexOf( ' ' ) !== -1 ){ v = v.split( ' ' ); } else - if( color && X.Type.isNumber( _v = X.CSS.parseColor( v ) ) ){ + if( color && X.Type.isNumber( _v = X_Node_CSS_objToIEFilterText( v ) ) ){ v = _v; } else { // bad