OSDN Git Service

Version 0.6.176, add X.Script.
[pettanr/clientJs.git] / 0.6.x / js / 01_core / 21_XViewPort.js
index b4f53b8..7c29e7d 100644 (file)
@@ -1,6 +1,6 @@
 
 var X_ViewPort_readyState,
-       X_ViewPort_active = !!window.parent || !!document.activeElement, // parent は frameに読み込まれた場合のieのerror回避
+       X_ViewPort_active = ( window.parent === window ) || !window.parent, // parent は frameに読み込まれた場合のieのerror回避
        X_ViewPort_activeTimerID,
        X_ViewPort_rootElement,
        X_ViewPort_lock,
@@ -35,7 +35,7 @@ X_ViewPort = X_Class_override(
        {
 
                'handleEvent' : function( e ){
-                       var href, i, name, active = false;
+                       var href, i, name, active = false, xnode;
                        
                        switch( e.type ){
                                case 'beforeunload' :
@@ -57,30 +57,47 @@ X_ViewPort = X_Class_override(
                                        break;
 
                                case 'visibilitychange' :
-                                       X_ViewPort[ 'dispatch' ]( ( X_ViewPort_active = document[ 'hidden' ] ) ? X_EVENT_VIEW_DEACTIVATE : X_EVENT_VIEW_ACTIVATE );
+                                       console.log( e.type + ':' + document[ 'hidden' ] );
+                                       X_ViewPort[ 'dispatch' ]( ( X_ViewPort_active = !document[ 'hidden' ] ) ? X_EVENT_VIEW_ACTIVATE : X_EVENT_VIEW_DEACTIVATE );
+                                       break;
+                               case 'msvisibilitychange' :
+                                       console.log( e.type + ':' + document[ 'msHidden' ] );
+                                       X_ViewPort[ 'dispatch' ]( ( X_ViewPort_active = !document[ 'msHidden' ] ) ? X_EVENT_VIEW_ACTIVATE : X_EVENT_VIEW_DEACTIVATE );
                                        break;
                                case 'mozvisibilitychange' :
-                                       X_ViewPort[ 'dispatch' ]( ( X_ViewPort_active = document[ 'mozHidden' ] ) ? X_EVENT_VIEW_DEACTIVATE : X_EVENT_VIEW_ACTIVATE );
+                                       console.log( e.type + ':' + document[ 'mozHidden' ] );
+                                       X_ViewPort[ 'dispatch' ]( ( X_ViewPort_active = !document[ 'mozHidden' ] ) ? X_EVENT_VIEW_ACTIVATE : X_EVENT_VIEW_DEACTIVATE );
                                        break;
                                case 'webkitvisibilitychange' :
-                                       X_ViewPort[ 'dispatch' ]( ( X_ViewPort_active = document[ 'webkitHidden' ] ) ? X_EVENT_VIEW_DEACTIVATE : X_EVENT_VIEW_ACTIVATE );
+                                       console.log( e.type + ':' + document[ 'webkitHidden' ] );
+                                       X_ViewPort[ 'dispatch' ]( ( X_ViewPort_active = !document[ 'webkitHidden' ] ) ? X_EVENT_VIEW_ACTIVATE : X_EVENT_VIEW_DEACTIVATE );
                                        break;
-
        
                                case 'blur' :
                                case 'focusout' :
-                               case 'pagehide' :                               
+                                       if( 5 < X_UA[ 'IE' ] && X_UA[ 'IE' ] < 9 ){
+                                               xnode = X_Node_getXNode( document.activeElement );
+                                               if( xnode ){
+                                                       xnode[ 'listenOnce' ]( [ 'focus', 'blur' ], X_ViewPort_detectFocusForIE );
+                                                       //break;
+                                               };
+                                               if( X_ViewPort_activeTimerID ){
+                                                       X_ViewPort_activeTimerID = X_Timer_remove( X_ViewPort_activeTimerID );
+                                               };
+                                               X_ViewPort_activeTimerID = X_Timer_once( 16, X_ViewPort_changeFocus );
+                                               return X_CALLBACK_PREVENT_DEFAULT | X_CALLBACK_STOP_PROPAGATION;
+                                       };
+                                       // 他の要素のfocusout がバブルアップしてきたもの
+                                       if( e.target !== X_ViewPort_document ) break;
+                               case 'pagehide' :               
                                        active = true;
                                case 'focus' :
-                               case 'focusin' :
                                case 'pageshow' :
+                               case 'focusin' :
                                        if( X_ViewPort_active === active ){
                                                X_ViewPort_active = !active;
-                                               if( X_ViewPort_activeTimerID ){
-                                                       X_ViewPort_activeTimerID = X_Timer_remove( X_ViewPort_activeTimerID );
-                                               } else {
-                                                       X_ViewPort_activeTimerID = X_Timer_once( 1, X_ViewPort_changeFocus );
-                                               };
+                                               console.log( e.type + ':' + X_ViewPort_active );
+                                               X_ViewPort[ 'dispatch' ]( active ? X_EVENT_VIEW_DEACTIVATE : X_EVENT_VIEW_ACTIVATE );
                                        };
                                        break;
                        };
@@ -89,6 +106,30 @@ X_ViewPort = X_Class_override(
        }
 );
 
+function X_ViewPort_detectFocusForIE( e ){
+       //console.log( 'iefix! ' + e.type + ':' + this.attr( 'tag' ) + ' isActive?:' + ( this[ '_rawObject' ] === document.activeElement ) );
+       var elmActive = X_Script_try( X_Object_find, [ document, 'activeElement' ] );
+       X_ViewPort_active = e.type === 'focus';
+       
+       
+       if( elmActive && this[ '_rawObject' ] !== elmActive ){
+               this[ 'unlisten' ]( X_ViewPort_active ? 'blur' : 'focus', X_ViewPort_detectFocusForIE );
+               console.log( '>>>>>> activeElement 取得 不一致 ' + this._tag );
+       } else
+       if( !elmActive ){
+               console.log( '******** activeElement 取得のエラー' );
+       } else if( elmActive ){
+               console.log( '>>>>>> activeElement 取得' );
+       };
+
+       if( X_ViewPort_activeTimerID ){
+               X_Timer_remove( X_ViewPort_activeTimerID );
+       };
+       X_ViewPort_activeTimerID = X_Timer_once( 16, X_ViewPort_changeFocus );
+       
+       return X_CALLBACK_PREVENT_DEFAULT | X_CALLBACK_STOP_PROPAGATION;
+};
+
 function X_ViewPort_changeFocus(){
        X_ViewPort[ 'dispatch' ]( X_ViewPort_active ? X_EVENT_VIEW_ACTIVATE : X_EVENT_VIEW_DEACTIVATE );
        X_ViewPort_activeTimerID = 0;
@@ -106,14 +147,24 @@ X[ 'ViewPort' ] = {
         * @alias X.ViewPort.listen
         */
        'listen' : function( type, arg1, arg2, arg3 ){
+               var f;
+               
                if( type <= X_ViewPort_readyState ){
                        /*
                         * X_EVENT_XDOM_READY 以後に listen した場合の対策
                         */
                        X_ViewPort[ 'asyncDispatch' ]( type );
                };
-               // ie8-では keydown -> documentへ
-               type && arg1 && X_ViewPort[ 'listen' ]( type, arg1, arg2, arg3 );
+               
+               f = X_Closure_classifyCallbackArgs( arg1, arg2, arg3 );
+               if( !f.cbKind ){
+                       X_ViewPort[ 'listen' ]( type, this, arg1 );
+               } else
+               if( f.cbKind === X_CLOSURE_FUNC_ONLY ){
+                       X_ViewPort[ 'listen' ]( type, this, f.func, f.supplement );
+               } else {
+                       X_ViewPort[ 'listen' ]( type, arg1, arg2, arg3 );
+               };
                return X[ 'ViewPort' ];
        },
        
@@ -122,13 +173,24 @@ X[ 'ViewPort' ] = {
         * @alias X.ViewPort.listenOnce
         */
        'listenOnce' : function( type, arg1, arg2, arg3 ){
+               var f;
+               
                if( type <= X_ViewPort_readyState ){
                        /*
                         * X.Event.XDOM_READY 以後に listen した場合の対策
                         */
                        X_ViewPort[ 'asyncDispatch' ]( type );
                };
-               type && arg1 && X_ViewPort[ 'listenOnce' ]( type, arg1, arg2, arg3 );
+               
+               f = X_Closure_classifyCallbackArgs( arg1, arg2, arg3 );
+               if( !f.cbKind ){
+                       X_ViewPort[ 'listenOnce' ]( type, this, arg1 );
+               } else
+               if( f.cbKind === X_CLOSURE_FUNC_ONLY ){
+                       X_ViewPort[ 'listenOnce' ]( type, this, f.func, f.supplement );
+               } else {
+                       X_ViewPort[ 'listenOnce' ]( type, arg1, arg2, arg3 );
+               };
                return X[ 'ViewPort' ];
        },
        
@@ -137,7 +199,16 @@ X[ 'ViewPort' ] = {
         * @alias X.ViewPort.unlisten
         */
        'unlisten' : function( type, arg1, arg2, arg3 ){
-               type && arg1 && X_ViewPort[ 'unlisten' ]( type, arg1, arg2, arg3 );
+               var f = X_Closure_classifyCallbackArgs( arg1, arg2, arg3 );
+               
+               if( !f.cbKind ){
+                       X_ViewPort[ 'unlisten' ]( type, this, arg1 );
+               } else
+               if( f.cbKind === X_CLOSURE_FUNC_ONLY ){
+                       X_ViewPort[ 'unlisten' ]( type, this, f.func, f.supplement );
+               } else {
+                       X_ViewPort[ 'unlisten' ]( type, arg1, arg2, arg3 );
+               };
                return X[ 'ViewPort' ];
        },
        
@@ -146,6 +217,14 @@ X[ 'ViewPort' ] = {
         * @alias X.ViewPort.listening
         */
        'listening' : function( type, arg1, arg2, arg3 ){
+               var f = X_Closure_classifyCallbackArgs( arg1, arg2, arg3 );
+               
+               if( !f.cbKind ){
+                       return X_ViewPort[ 'listening' ]( type, this, arg1 );
+               } else
+               if( f.cbKind === X_CLOSURE_FUNC_ONLY ){
+                       return X_ViewPort[ 'listening' ]( type, this, f.func, f.supplement );
+               };
                return X_ViewPort[ 'listening' ]( type, arg1, arg2, arg3 );
        },
 
@@ -180,8 +259,8 @@ X[ 'ViewPort' ] = {
 //(((t = document.documentElement) || (t = document.body.parentNode)) && typeof t.ScrollLeft == 'number' ? t : document.body).ScrollLeft;
 //(((t = document.documentElement) || (t = document.body.parentNode)) && typeof t.ScrollTop == 'number' ? t : document.body).ScrollTop
        
+       // TODO X.Doc へ
        /**
-        * 
         * @alias X.ViewPort.getDocumentSize
         */
        'getDocumentSize' : function(){
@@ -241,6 +320,22 @@ X[ 'ViewPort' ] = {
                        return X_ViewPort_baseFontSize = X_Node_fontSizeNode[ '_rawObject' ].offsetHeight;
                };
                return X_ViewPort_baseFontSize;
+       },
+       
+       /**
+        * キーボードイベントを受け付ける
+        * @alias X.ViewPort.isActive
+        */
+       'isActive' : function(){
+               return X_ViewPort_active;
+       },
+       
+       /**
+        * 可視である。iframe 内のhtmlも
+        * @alias X.ViewPort.isVisible
+        */
+       'isVisible' : function(){
+               return X_ViewPort_active;
        }
        
 };
@@ -448,24 +543,36 @@ X[ 'ViewPort' ] = {
 //ブラウザの戻るボタンで戻ったときに呼ばれるイベントとかキャッシュとかそこらへんのこと
 //http://d.hatena.ne.jp/koumiya/20080916/1221580149
 
+console.log( '------------------->' );
+
+                       if( document[ 'webkitHidden' ] !== undefined ){
+                               console.log( '--> has webkitvisibilitychange' );
+                               X_EventDispatcher_systemListen( X_ViewPort_document, 'webkitvisibilitychange', X_ViewPort );
+                       } else
                        if( document[ 'hidden' ] !== undefined ){// iOS 7+
+                               console.log( '--> has visibilitychange' );
                                X_EventDispatcher_systemListen( X_ViewPort_document, 'visibilitychange', X_ViewPort );
+                               document.onvisibilitychange = function(){ console.log( '!!!!!!!!!!!!!!!!' ) };
+                       } else
+                       if( document[ 'msHidden' ] !== undefined ){
+                               X_EventDispatcher_systemListen( X_ViewPort_document, 'msvisibilitychange', X_ViewPort );
                        } else
                        if( document[ 'mozHidden' ] !== undefined ){
                                X_EventDispatcher_systemListen( X_ViewPort_document, 'mozvisibilitychange', X_ViewPort );
-                       } else
-                       if( document[ 'webkitHidden' ] !== undefined ){
-                               X_EventDispatcher_systemListen( X_ViewPort_document, 'webkitvisibilitychange', X_ViewPort );
-                       } else
-                       if( X_UA[ 'iOS' ] && window[ 'onpageshow' ] !== undefined ){
+                       };
+                       
+                       if( window[ 'onpageshow' ] !== undefined ){
+                               console.log( '-------------------> pageshow, pagehide' );
                                X_EventDispatcher_systemListen( X_ViewPort, [ 'pageshow', 'pagehide' ] );
-                       } else
+                       };
+                       
                        if( document[ 'onfocusin' ] !== undefined ){
+                               console.log( '-------------------> focusin, focusout' );
                                // https://github.com/ai/visibilityjs/blob/master/lib/visibility.fallback.js
                                X_EventDispatcher_systemListen( X_ViewPort_document, [ 'focusin', 'focusout' ], X_ViewPort );
-                       } else {
-                               X_EventDispatcher_systemListen( X_ViewPort, [ 'focus', 'blur' ] );
                        };
+                       
+                       X_EventDispatcher_systemListen( X_ViewPort, [ 'focus', 'blur' ] );
 
                        return X_CALLBACK_UN_LISTEN;
                };
@@ -494,21 +601,21 @@ console.log( 'X.Dom dom:w3c=' + X_UA_DOM.W3C + ' ev:w3c=' + X_UA_EVENT.W3C );
 if( X_UA_EVENT.W3C ){
        X_ViewPort_document[ 'listenOnce' ]( 'DOMContentLoaded', X_TEMP.onDomContentLoaded );
 } else
-if( 6 <= X_UA[ 'IE' ] && X[ 'inHead' ] ){
+if( 6 <= X_UA[ 'IE' ] && X[ 'inHead' ] && !X_UA[ 'ieExeComError' ] ){ // standalone の除外 ->  && !X_UA[ 'ieExeComError' ]
        // if this script in Head
-       //document.write( '<script id="__ie_onload" defer src="javascript:void(0)"></script>' );
-       //X_TEMP._script = document.getElementById( '__ie_onload' );
+       //document.write( '<script id=__ieonload defer src=javascript:void(0)></script>' );
+       //X_TEMP._script = document.getElementById( '__ieonload' );
        
        // 上のコードはスタンドアローン版ie6でエラー
-    X_TEMP._script = document.createElement( '<script id="__ie_onload" defer src="javascript:void(0)"></script>' ) ;
-    document.getElementsByTagName("head")[ 0 ].appendChild( X_TEMP._script );
+    X_TEMP._script = document.createElement( '<script id=__ieonload defer src=javascript:void(0)></script>' ) ;
+    document.getElementsByTagName( 'head' )[ 0 ].appendChild( X_TEMP._script );
     
        X_TEMP._script.onreadystatechange = function(){
                var s = X_TEMP._script;
                if( s && s.readyState === 'complete' ){
                        s.onreadystatechange = X_emptyFunction;
                        s.onreadystatechange = null;
-                       s.parentNode.removeChild( s );
+                       s.removeNode( true );
                        delete X_TEMP._script;
                        X_TEMP.onDomContentLoaded && X_TEMP.onDomContentLoaded();
                };