リビジョン | 604668ba9efa027d4bc77fd8020d6b6be55d03e1 (tree) |
---|---|
日時 | 2016-11-28 14:21:24 |
作者 | itozyun <itozyun@user...> |
コミッター | itozyun |
Version 0.6.222, Fix the bug of X.TextRange.
add ExecuteAtEnd and FocusUtility.
@@ -3,6 +3,8 @@ var X_Event_Rename = {}, | ||
3 | 3 | X_Event_RenameTo = {}, |
4 | 4 | |
5 | 5 | // TODO IFRAMEload, SCRIPTload, LINKload raw.readyState !== 'complete' && raw.readyState !== 'loaded' && this.dispatch( 'load' ) |
6 | + | |
7 | + | |
6 | 8 | X_Event_proxy = { |
7 | 9 | |
8 | 10 | 'IFRAMEload' : function( eventDispatcher ){ |
@@ -13,9 +15,11 @@ var X_Event_Rename = {}, | ||
13 | 15 | var raw = this[ '_rawObject' ]; |
14 | 16 | |
15 | 17 | return ( raw.readyState === 'complete' || raw.readyState === 'loaded' ) ? |
16 | - this[ 'dispatch' ]( 'load' ) : X_CALLBACK_PREVENT_DEFAULT | X_CALLBACK_STOP_PROPAGATION; | |
18 | + X_EventDispatcher_actualHandleEvent( 'load' ) : X_CALLBACK_PREVENT_DEFAULT | X_CALLBACK_STOP_PROPAGATION; | |
17 | 19 | }, |
18 | 20 | |
21 | + // TODO focusin focusout | |
22 | + | |
19 | 23 | // X_UA[ 'Opera' ] |
20 | 24 | 'contextmenu' : function( eventDispatcher ){ |
21 | 25 | eventDispatcher[ 'listen' ]( 'mousedown', contextmenu_proxy ); |
@@ -734,7 +734,8 @@ function X_EventDispatcher_actualRemoveEvent( that, type, raw, list, skip ){ | ||
734 | 734 | |
735 | 735 | // TODO ブラウザからの呼び出しの最後に登録された関数を呼び出す機能(例えば画面の更新) |
736 | 736 | var X_EventDispatcher_CURRENT_EVENTS = []; |
737 | -var X_EventDispatcher_ignoreActualEvent = ''; | |
737 | +var X_EventDispatcher_ignoreActualEvent; | |
738 | +var X_EventDispatcher_rawEvent; | |
738 | 739 | |
739 | 740 | // handleEvent を拡張可能にするために、クロージャに移動した |
740 | 741 | // Is this in regard to the Safari 1.x preventDefault bug on click/dblclick? |
@@ -746,36 +747,48 @@ var X_EventDispatcher_actualHandleEvent = | ||
746 | 747 | elm = this[ '_rawObject' ], |
747 | 748 | ev, ret; |
748 | 749 | |
749 | - /* if( e.type === X_EventDispatcher_ignoreActualEvent ){ | |
750 | + if( X_EventDispatcher_ignoreActualEvent ){ | |
750 | 751 | e.cancelBubble = true; |
751 | 752 | return; |
752 | - }; */ | |
753 | + }; | |
753 | 754 | |
754 | - ev = new X_DomEvent( e, this, elm ); | |
755 | + X_EventDispatcher_rawEvent = e; | |
755 | 756 | |
757 | + ev = new X_DomEvent( e, this, elm ); | |
758 | + | |
756 | 759 | X_EventDispatcher_CURRENT_EVENTS[ X_EventDispatcher_CURRENT_EVENTS.length ] = ev; |
757 | 760 | |
758 | 761 | ret = this[ 'dispatch' ]( ev ); |
759 | 762 | |
763 | + if( X_EventDispatcher_rawEvent === e ) X_EventDispatcher_rawEvent = null; | |
764 | + | |
760 | 765 | --X_EventDispatcher_CURRENT_EVENTS.length; |
761 | 766 | |
762 | 767 | if( ret & X_CALLBACK_STOP_PROPAGATION ){ |
763 | 768 | e.cancelBubble = true; |
764 | 769 | }; |
770 | + | |
771 | + if( !X_EventDispatcher_CURRENT_EVENTS.length ) ExecuteAtEnd_onEnd(); | |
772 | + | |
765 | 773 | if( ret & X_CALLBACK_PREVENT_DEFAULT ){ |
766 | - this[ '_tag' ] === 'A' && elm.blur(); | |
774 | + X_EventDispatcher_ignoreActualEvent = true; | |
775 | + this[ '_tag' ] === 'A' && elm.blur(); // おかしくない?? | |
776 | + X_EventDispatcher_ignoreActualEvent = false; | |
767 | 777 | return e.returnValue = false; |
768 | 778 | }; |
769 | 779 | }) : |
770 | 780 | //X_UA_EVENT.W3C || X_UA_EVENT.DOM0 |
771 | 781 | (function( e ){ |
772 | 782 | var ret = X_CALLBACK_NONE, |
783 | + elm = this[ '_rawObject' ], | |
773 | 784 | ev, i, l; |
774 | 785 | |
775 | - /* if( e.type === X_EventDispatcher_ignoreActualEvent ){ | |
786 | + if( X_EventDispatcher_ignoreActualEvent ){ | |
776 | 787 | e.stopPropagation(); |
777 | 788 | return; |
778 | - }; */ | |
789 | + }; | |
790 | + | |
791 | + X_EventDispatcher_rawEvent = e; | |
779 | 792 | |
780 | 793 | ev = new X_DomEvent( e, this ); |
781 | 794 | X_EventDispatcher_CURRENT_EVENTS[ X_EventDispatcher_CURRENT_EVENTS.length ] = ev; |
@@ -795,13 +808,20 @@ var X_EventDispatcher_actualHandleEvent = | ||
795 | 808 | ret = this[ 'dispatch' ]( ev ); |
796 | 809 | }; |
797 | 810 | |
811 | + if( X_EventDispatcher_rawEvent === e ) X_EventDispatcher_rawEvent = null; | |
812 | + | |
798 | 813 | --X_EventDispatcher_CURRENT_EVENTS.length; |
799 | 814 | |
815 | + if( !X_EventDispatcher_CURRENT_EVENTS.length ) ExecuteAtEnd_onEnd(); | |
816 | + | |
800 | 817 | if( ret & X_CALLBACK_STOP_PROPAGATION ){ |
801 | 818 | e.stopPropagation(); |
802 | 819 | }; |
803 | 820 | if( ret & X_CALLBACK_PREVENT_DEFAULT ){ |
804 | - this[ '_tag' ] === 'A' && this[ '_rawObject' ].blur(); | |
821 | + X_EventDispatcher_ignoreActualEvent = true; | |
822 | + this[ '_tag' ] === 'A' && elm.blur(); | |
823 | + X_EventDispatcher_ignoreActualEvent = false; | |
824 | + | |
805 | 825 | e.preventDefault(); |
806 | 826 | if( X_UA[ 'WebKit' ] < 525.13 ){ // Safari3- |
807 | 827 | if( e.type === 'click' || e.type === 'dbclick' ){ |
@@ -362,6 +362,8 @@ function X_Timer_onTimeout(){ | ||
362 | 362 | X_Timer_removal = null; |
363 | 363 | }; |
364 | 364 | X_Timer_update(); |
365 | + | |
366 | + ExecuteAtEnd_onEnd(); | |
365 | 367 | }; |
366 | 368 | |
367 | 369 | function X_Timer_update(){ |
@@ -453,6 +455,8 @@ function X_Timer_onEnterFrame( time ){ | ||
453 | 455 | }; |
454 | 456 | X_Timer_removal = null; |
455 | 457 | }; |
458 | + | |
459 | + ExecuteAtEnd_onEnd(); | |
456 | 460 | }; |
457 | 461 | |
458 | 462 | console.log( 'X.Core.Timer' ); |
@@ -0,0 +1,17 @@ | ||
1 | + | |
2 | +var ExecuteAtEnd_CALLBACKS = []; | |
3 | + | |
4 | +function ExecuteAtEnd_add( func ){ | |
5 | + ExecuteAtEnd_CALLBACKS[ ExecuteAtEnd_CALLBACKS.length ] = func; | |
6 | +}; | |
7 | + | |
8 | +function ExecuteAtEnd_onEnd(){ | |
9 | + var i = -1, func; | |
10 | + | |
11 | + if( !ExecuteAtEnd_CALLBACKS.length ) return; | |
12 | + | |
13 | + while( func = ExecuteAtEnd_CALLBACKS[ ++i ] ){ | |
14 | + func(); | |
15 | + }; | |
16 | + ExecuteAtEnd_CALLBACKS.length = 0; | |
17 | +}; |
@@ -0,0 +1,53 @@ | ||
1 | + | |
2 | + | |
3 | +var FocusUtility_lastElmFocused; | |
4 | +var FocusUtility_docActiveElmSupport = X_UA[ 'IE' ] || document.activeElement !== undefined; | |
5 | +var FocusUtility_fixActiveElm; | |
6 | + | |
7 | +// http://www.codingforums.com/javascript-programming/19503-determining-focus-ns6-ie6-context-sensitive-help.html | |
8 | +// https://developer.mozilla.org/ja/docs/Web/API/Document/activeElement | |
9 | +// IE 4+, Chrome 2+, Safari 4+, Firefox 3+ Opera 9.6+ | |
10 | + | |
11 | +function FocusUtility_getFocusedElement(){ | |
12 | + return FocusUtility_fixActiveElm || | |
13 | + ( | |
14 | + X_Script_gte15 ? | |
15 | + X_Script_try( X_Object_find, [ document, 'activeElement' ] ) : | |
16 | + // ieは iframe 内で focus がない場合に activeElement に触ると エラーになる | |
17 | + // VBS 経由で activeElement に触り安全確認する | |
18 | + ( window[ 'vbs_testAE' ]() && document.activeElement ) | |
19 | + ); | |
20 | +}; | |
21 | + | |
22 | +/* | |
23 | + * 通常の focus は xnode.call('focus') を使う. | |
24 | + * フレームワーク内部で API の実行のために一時的に focus を当てたい場合に使う.focus の復帰は自動で行われる | |
25 | + */ | |
26 | +function FocusUtility_setTemporarilyFocus( elm ){ | |
27 | + var elmActive = FocusUtility_getFocusedElement(); | |
28 | + | |
29 | + if( elmActive !== elm ){ | |
30 | + X_EventDispatcher_ignoreActualEvent = true; // ignoreAllEvent focus, blur | |
31 | + elm.focus(); | |
32 | + X_EventDispatcher_ignoreActualEvent = false; | |
33 | + if( !FocusUtility_lastElmFocused ){ | |
34 | + FocusUtility_lastElmFocused = elmActive; | |
35 | + // ie5(IE11のエミュレーション) でしばしば空なんですけど... | |
36 | + elmActive && ExecuteAtEnd_add( FocusUtility_restoreFocus ); | |
37 | + }; | |
38 | + }; | |
39 | +}; | |
40 | + | |
41 | +// こっそり復帰 | |
42 | +function FocusUtility_restoreFocus(){ | |
43 | + var elmActive = FocusUtility_getFocusedElement(), | |
44 | + elm = FocusUtility_lastElmFocused; | |
45 | + | |
46 | + if( elmActive !== elm ){ | |
47 | + X_EventDispatcher_ignoreActualEvent = true; | |
48 | + elm.focus(); | |
49 | + X_EventDispatcher_ignoreActualEvent = false; | |
50 | + }; | |
51 | + FocusUtility_lastElmFocused = null; | |
52 | +}; | |
53 | + |
@@ -1,6 +1,6 @@ | ||
1 | 1 | |
2 | 2 | var X_ViewPort_readyState, |
3 | - X_ViewPort_active = ( window.parent === window ) || !window.parent, // parent は frameに読み込まれた場合のieのerror回避 | |
3 | + X_ViewPort_active = ( window.parent === window ) || !window.parent, // parent は frameに読み込まれた場合のieのerror回避 | |
4 | 4 | X_ViewPort_activeTimerID, |
5 | 5 | X_ViewPort_rootElement, |
6 | 6 | X_ViewPort_lock, |
@@ -35,11 +35,11 @@ X_ViewPort = X_Class_override( | ||
35 | 35 | { |
36 | 36 | |
37 | 37 | 'handleEvent' : function( e ){ |
38 | - var href, i, name, active = false, xnode; | |
38 | + var href, i, name, active = false, elm, xnode; | |
39 | 39 | |
40 | 40 | switch( e.type ){ |
41 | 41 | case 'beforeunload' : |
42 | - // ie では a href='javascript' な要素でも beforeunload が起こる | |
42 | + // ie では a href='javascript' な要素でも beforeunload が起こる | |
43 | 43 | href = e.target && e.target[ 'attr' ] && e.target[ 'attr' ]( 'href' ); |
44 | 44 | if( X_Type_isString( href ) && !href.toLowerCase().indexOf( 'javascript:' ) ) return X_CALLBACK_PREVENT_DEFAULT | X_CALLBACK_STOP_PROPAGATION; |
45 | 45 |
@@ -74,12 +74,8 @@ X_ViewPort = X_Class_override( | ||
74 | 74 | |
75 | 75 | case 'blur' : |
76 | 76 | case 'focusout' : |
77 | - if( ( 5.5 < X_UA[ 'IE' ] && X_UA[ 'IE' ] < 9 ) | |
78 | - || | |
79 | - // TODO ie5... activeElement に障るとエラーになるため VBS 経由で activeElement に触り安全確認する(未確認) | |
80 | - ( 5 <= X_UA[ 'IE' ] && X_UA[ 'IE' ] < 5.5 && !window[ 'vbs_testAE' ]() ) | |
81 | - ){ | |
82 | - xnode = X_Node_getXNode( document.activeElement ); | |
77 | + if( X_UA[ 'IE' ] < 9 && ( elm = FocusUtility_getFocusedElement() ) ){ | |
78 | + xnode = X_Node_getXNode( elm ); | |
83 | 79 | if( xnode ){ |
84 | 80 | xnode[ 'listenOnce' ]( [ 'focus', 'blur' ], X_ViewPort_detectFocusForIE ); |
85 | 81 | //break; |
@@ -111,18 +107,18 @@ X_ViewPort = X_Class_override( | ||
111 | 107 | |
112 | 108 | function X_ViewPort_detectFocusForIE( e ){ |
113 | 109 | //console.log( 'iefix! ' + e.type + ':' + this.attr( 'tag' ) + ' isActive?:' + ( this[ '_rawObject' ] === document.activeElement ) ); |
114 | - var elmActive = X_Script_try( X_Object_find, [ document, 'activeElement' ] ); | |
110 | + var elmActive = FocusUtility_getFocusedElement(); | |
115 | 111 | X_ViewPort_active = e.type === 'focus'; |
116 | 112 | |
117 | 113 | |
118 | 114 | if( elmActive && this[ '_rawObject' ] !== elmActive ){ |
119 | 115 | this[ 'unlisten' ]( X_ViewPort_active ? 'blur' : 'focus', X_ViewPort_detectFocusForIE ); |
120 | - console.log( '>>>>>> activeElement 取得 不一致 ' + this._tag ); | |
116 | + console.log( '>>>>>> activeElement 取得 不一致 ' + this._tag ); | |
121 | 117 | } else |
122 | 118 | if( !elmActive ){ |
123 | - console.log( '******** activeElement 取得のエラー' ); | |
119 | + //console.log( '******** activeElement 取得のエラー' ); | |
124 | 120 | } else if( elmActive ){ |
125 | - console.log( '>>>>>> activeElement 取得' ); | |
121 | + //console.log( '>>>>>> activeElement 取得' ); | |
126 | 122 | }; |
127 | 123 | |
128 | 124 | if( X_ViewPort_activeTimerID ){ |
@@ -370,7 +366,7 @@ X[ 'ViewPort' ] = { | ||
370 | 366 | * http://sssslide.com/www.slideshare.net/hiroakiwakamatsu/ss-12718639 |
371 | 367 | * |
372 | 368 | * |
373 | - * getBoundingClientRect で fontsize の調査 | |
369 | + * getBoundingClientRect で fontsize の調査 | |
374 | 370 | */ |
375 | 371 | var X_ViewPort_resize = |
376 | 372 | // iOS もループで回す,,,iOS3.1.3, iOS6 で確認 |
@@ -508,7 +504,7 @@ X[ 'ViewPort' ] = { | ||
508 | 504 | |
509 | 505 | X_ViewPort_vScrollbarSize = w; |
510 | 506 | X_ViewPort_hScrollbarSize = h; |
511 | - if( h <= 0 ){ // ie6, ie11, firefox で 負の値が返る | |
507 | + if( h <= 0 ){ // ie6, ie11, firefox で 負の値が返る | |
512 | 508 | console.log( 'invalid hScrollbarSize: ' + h ); |
513 | 509 | X_ViewPort_hScrollbarSize = w; |
514 | 510 | }; |
@@ -538,16 +534,17 @@ X[ 'ViewPort' ] = { | ||
538 | 534 | //ブラウザの戻るボタンで戻ったときに呼ばれるイベントとかキャッシュとかそこらへんのこと |
539 | 535 | //http://d.hatena.ne.jp/koumiya/20080916/1221580149 |
540 | 536 | |
541 | - if( document[ 'webkitHidden' ] !== undefined ){ | |
542 | - X_ViewPort_document[ 'listen' ]( 'webkitvisibilitychange', X_ViewPort ); | |
543 | - } else | |
544 | 537 | if( document[ 'hidden' ] !== undefined ){// iOS 7+ |
545 | 538 | X_ViewPort_document[ 'listen' ]( 'visibilitychange', X_ViewPort ); |
546 | 539 | } else |
540 | + if( document[ 'webkitHidden' ] !== undefined ){ | |
541 | + X_ViewPort_document[ 'listen' ]( 'webkitvisibilitychange', X_ViewPort ); | |
542 | + } else | |
547 | 543 | if( document[ 'msHidden' ] !== undefined ){ |
548 | 544 | X_ViewPort_document[ 'listen' ]( 'msvisibilitychange', X_ViewPort ); |
549 | 545 | } else |
550 | 546 | if( document[ 'mozHidden' ] !== undefined ){ |
547 | + // TODO Firefox + Android2 でブラウザにフォーカスが戻ったことが判らない... | |
551 | 548 | X_ViewPort_document[ 'listen' ]( 'mozvisibilitychange', X_ViewPort ); |
552 | 549 | }; |
553 | 550 |
@@ -560,11 +557,21 @@ X[ 'ViewPort' ] = { | ||
560 | 557 | X_ViewPort_document[ 'listen' ]( [ 'focusin', 'focusout' ], X_ViewPort ); |
561 | 558 | }; |
562 | 559 | |
560 | + // TODO activeElement が無い対策 | |
561 | + if( !FocusUtility_docActiveElmSupport ){ | |
562 | + X_ViewPort[ 'listen' ]( 'focus', X_ViewPort_fixActiveElm ); | |
563 | + }; | |
564 | + | |
563 | 565 | X_ViewPort[ 'listen' ]( [ 'focus', 'blur' ] ); |
564 | 566 | |
565 | 567 | return X_CALLBACK_UN_LISTEN; |
566 | 568 | }; |
567 | 569 | |
570 | + function X_ViewPort_fixActiveElm( e ){ | |
571 | + // textNode を修正して elm にする処理は EventDisptcher に入っている | |
572 | + FocusUtility_fixActiveElm = e.target[ '_rawObject' ]; | |
573 | + }; | |
574 | + | |
568 | 575 | function X_ViewPort_getWindowSize(){ |
569 | 576 | return X_UA[ 'IE' ] ? // Opera10.1 では ズーム時に表示領域のサイズが取れない! |
570 | 577 | [ X_ViewPort_rootElement.clientWidth, X_ViewPort_rootElement.clientHeight ] : |
@@ -1425,7 +1425,7 @@ function X_Node_startUpdate( time ){ | ||
1425 | 1425 | // 強制的に再描画を起こす, 但し activeElement からフォーカスが外れるため復帰する |
1426 | 1426 | // IE5mode win10 で 確認 |
1427 | 1427 | if( X_UA[ 'IE5' ] ){ |
1428 | - active = document.activeElement; | |
1428 | + active = FocusUtility_getFocusedElement(); | |
1429 | 1429 | X_elmBody.style.visibility = 'hidden'; |
1430 | 1430 | }; |
1431 | 1431 |
@@ -1438,7 +1438,7 @@ function X_Node_startUpdate( time ){ | ||
1438 | 1438 | |
1439 | 1439 | if( X_UA[ 'IE5' ] ){ |
1440 | 1440 | X_elmBody.style.visibility = ''; |
1441 | - active && active.parentNode && active.focus(); | |
1441 | + active && active.parentNode && FocusUtility_setTemporarilyFocus( active ); | |
1442 | 1442 | }; |
1443 | 1443 | |
1444 | 1444 | if( X_Node_updateReservedByReleaseGPU ){ |
@@ -1530,7 +1530,7 @@ var X_Node__commitUpdate = | ||
1530 | 1530 | if( !that[ '_tag' ] ){ |
1531 | 1531 | that[ '_flags' ] &= X_Node_BitMask_RESET_DIRTY; |
1532 | 1532 | if( X_UA[ 'IE' ] < 8 ){ |
1533 | - // \n -> \r\n に変換しないと pre タグで開業されない win10ie7(ie11 emu) で確認 | |
1533 | + // \n -> \r\n に変換しないと pre タグで改行されない win10ie7(ie11 emu) で確認 | |
1534 | 1534 | elm = document.createTextNode( X_String_chrReferanceTo( that[ '_text' ] ).split( '\n' ).join( X_String_CRLF ) ); |
1535 | 1535 | } else { |
1536 | 1536 | elm = document.createTextNode( X_String_chrReferanceTo( that[ '_text' ] ) ); |
@@ -1811,7 +1811,7 @@ var X_Node__updateRawNode = | ||
1811 | 1811 | // textNode |
1812 | 1812 | if( !that[ '_tag' ] ){ |
1813 | 1813 | if( X_UA[ 'IE' ] < 8 ){ |
1814 | - // \n -> \r\n に変換しないと pre タグで開業されない win10ie7(ie11 emu) で確認 | |
1814 | + // \n -> \r\n に変換しないと pre タグで改行されない win10ie7(ie11 emu) で確認 | |
1815 | 1815 | elm.data = X_String_chrReferanceTo( that[ '_text' ] ).split( '\n' ).join( X_String_CRLF ); |
1816 | 1816 | } else { |
1817 | 1817 | elm.data = X_String_chrReferanceTo( that[ '_text' ] ); |
@@ -18,8 +18,8 @@ | ||
18 | 18 | */ |
19 | 19 | |
20 | 20 | var X_TextRange_range, |
21 | - X_TextRange_range2, | |
22 | - X_TextRange_isW3C = !document.selection || 10 <= X_UA[ 'IE' ]; | |
21 | + X_TextRange_selection, | |
22 | + X_TextRange_isW3C = !document.selection || 9 <= X_UA[ 'IE' ] || X_UA[ 'Edge' ]; | |
23 | 23 | |
24 | 24 | /** |
25 | 25 | * ユーザーによって選択されたテキストへの参照や文字の座標の取得 |
@@ -34,25 +34,26 @@ var X_TextRange = X_Class_create( | ||
34 | 34 | |
35 | 35 | /** @lends X.TextRange.prototype */ |
36 | 36 | { |
37 | - xnode : null, | |
38 | - createFrom : '', | |
39 | - v1 : 0, | |
40 | - v2 : 0, | |
37 | + 'xnode' : null, | |
38 | + 'by' : '', | |
39 | + 'v1' : 0, | |
40 | + 'v2' : 0, | |
41 | 41 | |
42 | 42 | 'Constructor' : function( xnode, arg2, arg3, arg4 ){ |
43 | 43 | if( !X_TextRange_range ){ |
44 | 44 | X_TextRange_range = X_TextRange_isW3C ? document.createRange() : X_elmBody.createTextRange(); |
45 | - if( !X_TextRange_isW3C ) X_TextRange_range2 = X_elmBody.createTextRange(); | |
46 | 45 | }; |
47 | 46 | |
48 | 47 | this.xnode = xnode; |
49 | 48 | |
50 | 49 | switch( arg2 ){ |
51 | 50 | case 'selection' : |
52 | - //break; | |
51 | + if( !X_TextRange_selection ){ | |
52 | + X_TextRange_selection = X_TextRange_isW3C ? window.getSelection() : document.selection.createRange; | |
53 | + }; | |
53 | 54 | case 'point' : |
54 | 55 | case 'char' : |
55 | - this.createFrom = arg2; | |
56 | + this[ 'by' ] = arg2; | |
56 | 57 | break; |
57 | 58 | default : |
58 | 59 | arg4 = arg3; |
@@ -60,8 +61,8 @@ var X_TextRange = X_Class_create( | ||
60 | 61 | }; |
61 | 62 | |
62 | 63 | if( arg2 !== 'selection' ){ |
63 | - this.v1 = arg3 || 0; | |
64 | - this.v2 = arg4 || 0; | |
64 | + this[ 'v1' ] = arg3 || 0; | |
65 | + this[ 'v2' ] = arg4 || 0; | |
65 | 66 | } else { |
66 | 67 | this[ 'getOffset' ](); |
67 | 68 | }; |
@@ -98,13 +99,15 @@ function X_TextRange_collectTextNodes( elm, ary ){ | ||
98 | 99 | }; |
99 | 100 | }; |
100 | 101 | |
101 | -function X_TextRange_getRawRange( tr, createFrom ){ | |
102 | +function X_TextRange_getRawRange( tr ){ | |
102 | 103 | var xnode = tr.xnode, |
103 | 104 | // |
104 | - range = 10 <= X_UA[ 'IE' ] /* || X_UA[ 'iOS' ] */ ? document.createRange() : | |
105 | - 8 <= X_UA[ 'IE' ] ? X_elmBody.createTextRange() : X_TextRange_range, | |
106 | - elm, selection, isPoint, | |
107 | - texts, i, offset, j, l, x, y, rect; | |
105 | + range = //10 <= X_UA[ 'IE' ] /* || X_UA[ 'iOS' ] */ ? document.createRange() : | |
106 | + //8 <= X_UA[ 'IE' ] ? X_elmBody.createTextRange() : | |
107 | + X_TextRange_range, | |
108 | + selection = X_TextRange_selection, | |
109 | + elm, isPoint, | |
110 | + texts, i, offset, j, l, x, y, rect, top, btm, left; | |
108 | 111 | |
109 | 112 | if( xnode[ '_flags' ] & X_NodeFlags_IN_TREE ){ |
110 | 113 |
@@ -112,24 +115,24 @@ function X_TextRange_getRawRange( tr, createFrom ){ | ||
112 | 115 | |
113 | 116 | elm = xnode[ '_rawObject' ]; |
114 | 117 | |
115 | - switch( createFrom || tr.createFrom ){ | |
118 | + switch( tr[ 'by' ] ){ | |
116 | 119 | case 'selection' : |
117 | 120 | if( X_TextRange_isW3C ){ |
118 | - selection = window.getSelection(); | |
121 | + //selection = window.getSelection(); | |
119 | 122 | |
120 | 123 | if( selection.getRangeAt ){ |
121 | 124 | return selection.rangeCount && selection.getRangeAt( 0 ); |
122 | 125 | }; |
123 | 126 | // http://d.hatena.ne.jp/dayflower/20080423/1208941641 |
124 | 127 | // for Safari 1.3 |
125 | - range = document.createRange(); | |
128 | + //range = document.createRange(); | |
126 | 129 | range.setStart( selection.anchorNode, selection.anchorOffset ); |
127 | 130 | range.setEnd( selection.focusNode, selection.focusOffset ); |
128 | 131 | return range; |
129 | 132 | } else { |
130 | 133 | switch( document.selection.type ){ |
131 | 134 | case 'text' : |
132 | - return document.selection.createRange(); | |
135 | + return selection(); | |
133 | 136 | case 'Control' : |
134 | 137 | // TODO |
135 | 138 | case 'none' : |
@@ -138,57 +141,100 @@ function X_TextRange_getRawRange( tr, createFrom ){ | ||
138 | 141 | break; |
139 | 142 | |
140 | 143 | case 'point' : |
141 | - isPoint = true; | |
142 | - case 'char' : | |
143 | 144 | if( X_TextRange_isW3C ){ |
144 | 145 | // textarea で異なる |
146 | + // TextNode をフラットな配列に回収 | |
147 | + X_TextRange_collectTextNodes( elm, texts = [] ); | |
148 | + | |
149 | + x = tr[ 'v1' ]; | |
150 | + y = tr[ 'v2' ]; | |
151 | + | |
152 | + for( i = offset = 0; text = texts[ i ]; ++i ){ | |
153 | + range.selectNodeContents( text ); // selectNodeContents は TextNode のみ?? Firefox | |
154 | + l = text.data.length; | |
145 | 155 | |
146 | - if( isPoint ){ | |
147 | - // TextNode をフラットな配列に回収 | |
148 | - X_TextRange_collectTextNodes( elm, texts = [] ); | |
149 | - | |
150 | - for( i = offset = 0; text = texts[ i ]; ++i ){ | |
151 | - range.selectNodeContents( text ); // selectNodeContents は TextNode のみ?? Firefox | |
152 | - l = text.data.length; | |
153 | - | |
154 | - for( j = 0, x = tr.v1, y = tr.v2; j < l; ++j ){ | |
155 | - if( range ){ | |
156 | - range.setStart( text, j ); | |
157 | - range.setEnd( text, j + 1 ); | |
158 | - rect = range.getBoundingClientRect(); | |
159 | - }; | |
160 | - if( rect.left <= x && x <= rect.right && rect.top <= y && y <= rect.bottom ){ | |
161 | - return { | |
162 | - 'hitRange' : range, | |
163 | - 'rect' : rect, | |
164 | - 'offset' : offset, | |
165 | - 'text' : text | |
166 | - }; | |
167 | - }; | |
168 | - }; | |
169 | - offset += l; | |
170 | - }; | |
171 | - range = null; | |
172 | - } else { | |
173 | - // 未チェック! | |
174 | - range.setEnd( elm, l < tr.v2 ? l : tr.v2 ); | |
175 | - range.setStart( elm, tr.v1 ); | |
176 | - return { 'hitRange' : range }; | |
156 | + for( j = 0; j < l; ++j ){ | |
157 | + if( X_UA[ 'IE' ] || X_UA[ 'Edge' ] ){ | |
158 | + // 改行の直前の文字を選択すると rect が巨大になってしまう | |
159 | + range.setEnd( text, j ); | |
160 | + range.setStart( text, j ); | |
161 | + rect = range.getBoundingClientRect(); | |
162 | + top = rect.top; | |
163 | + btm = rect.bottom; | |
164 | + left = rect.left; | |
165 | + range.setEnd( text, j + 1 ); | |
166 | + rect = range.getBoundingClientRect(); | |
167 | + | |
168 | + if( rect.left < left ){ | |
169 | + //console.log( '= ', text.data.charAt( j ), ' x:', x, ' y:', y, ' top:', top | 0, ' left:', left | 0, ' bottom:', btm | 0, ' right:', rect.right | 0 ); | |
170 | + if( left <= x && x <= rect.right && top <= y && y <= btm ){ | |
171 | + return { | |
172 | + 'hitRange' : range, // TODO startContainer, endContainer | |
173 | + 'rect' : rect, | |
174 | + 'offset' : offset, | |
175 | + 'text' : text // TODO xtext じゃないの? | |
176 | + }; | |
177 | + }; | |
178 | + continue; | |
179 | + }; | |
180 | + } else { | |
181 | + range.setEnd( text, j + 1 ); | |
182 | + range.setStart( text, j ); | |
183 | + rect = range.getBoundingClientRect(); | |
184 | + }; | |
185 | + | |
186 | + //console.log( text.data.charAt( j ), ' x:', x, ' y:', y, ' top:', rect.top | 0, ' left:', rect.left | 0, ' bottom:', rect.bottom | 0, ' right:', rect.right | 0 ); | |
187 | + if( rect.left <= x && x <= rect.right && rect.top <= y && y <= rect.bottom ){ | |
188 | + return { | |
189 | + 'hitRange' : range, // TODO startContainer, endContainer | |
190 | + 'rect' : rect, | |
191 | + 'offset' : offset, | |
192 | + 'text' : text // TODO xtext じゃないの? | |
193 | + }; | |
194 | + }; | |
195 | + }; | |
196 | + offset += l; | |
177 | 197 | }; |
198 | + range = null; | |
178 | 199 | } else { |
179 | - // !save && ( text = text.split( '\r\n' ).join( '\n' ) ); textarea用 | |
180 | - if( isPoint ){ | |
181 | - // ie11 の ie10モード で moveToPoint がないといわれる. よって isW3C:false で動作するのは ie9 以下 | |
182 | - range.moveToPoint( tr.v1, tr.v2 ); | |
183 | - if( !range.duplicate().expand( 'character' ) ) range = null; | |
200 | + // ie11 の ie10モード で moveToPoint がないといわれる. よって isW3C:false で動作するのは ie9 以下 | |
201 | + // 行の最後の文字の端をクリックすると次の行の文字が選択されてしまう ie8, ie7 | |
202 | + // 選択を移動して補正する https://msdn.microsoft.com/ja-jp/library/ms535872(v=vs.85).aspx | |
203 | + range.moveToPoint( x = tr[ 'v1' ], y = tr[ 'v2' ] ); | |
204 | + | |
205 | + // if( range.parentElement() !== elm || elm.contains( range.parentElement() ) ){ | |
206 | + | |
207 | + if( range.expand( 'character' ) ){ | |
208 | + left = range.boundingLeft; | |
209 | + top = range.boundingTop; | |
210 | + if( x < left || left + range.boundingWidth < x || y < top || top + range.boundingHeight < y ){ | |
211 | + range.moveStart( 'character', -1 ); | |
212 | + range.moveEnd( 'character', -1 ); | |
213 | + left = range.boundingLeft; | |
214 | + top = range.boundingTop; | |
215 | + if( x < left || left + range.boundingWidth < x || y < top || top + range.boundingHeight < y ){ | |
216 | + range = null; | |
217 | + }; | |
218 | + }; | |
184 | 219 | } else { |
185 | - range.moveToElementText( elm ); | |
186 | - //range.collapse( true ); | |
187 | - range.moveEnd( 'character', l < tr.v2 ? l : tr.v2 ); | |
188 | - range.moveStart( 'character', tr.v1 ); | |
220 | + range = null; | |
189 | 221 | }; |
190 | 222 | }; |
191 | 223 | return range; |
224 | + | |
225 | + case 'char' : | |
226 | + if( X_TextRange_isW3C ){ | |
227 | + // 未チェック! | |
228 | + range.setEnd( elm, l < tr[ 'v2' ] ? l : tr[ 'v2' ] ); | |
229 | + range.setStart( elm, tr[ 'v1' ] ); | |
230 | + return { 'hitRange' : range }; | |
231 | + } else { | |
232 | + range.moveToElementText( elm ); | |
233 | + //range.collapse( true ); | |
234 | + range.moveEnd( 'character', l < tr[ 'v2' ] ? l : tr[ 'v2' ] ); | |
235 | + range.moveStart( 'character', tr[ 'v1' ] ); | |
236 | + }; | |
237 | + return range; | |
192 | 238 | }; |
193 | 239 | }; |
194 | 240 | }; |
@@ -255,13 +301,13 @@ function X_TextRange_getOffset(){ | ||
255 | 301 | if( X_UA[ 'IE' ] < 12 ){ |
256 | 302 | l = elm.value.length; |
257 | 303 | ret = { |
258 | - 'from' : this.v1 = elm.selectionStart < l ? elm.selectionStart : l, | |
259 | - 'to' : this.v2 = elm.selectionEnd < l ? elm.selectionEnd : l | |
304 | + 'from' : this[ 'v1' ] = elm.selectionStart < l ? elm.selectionStart : l, | |
305 | + 'to' : this[ 'v2' ] = elm.selectionEnd < l ? elm.selectionEnd : l | |
260 | 306 | }; |
261 | 307 | } else { |
262 | 308 | ret = { |
263 | - 'from' : this.v1 = elm.selectionStart, | |
264 | - 'to' : this.v2 = elm.selectionEnd | |
309 | + 'from' : this[ 'v1' ] = elm.selectionStart, | |
310 | + 'to' : this[ 'v2' ] = elm.selectionEnd | |
265 | 311 | }; |
266 | 312 | }; |
267 | 313 | }; |
@@ -272,17 +318,18 @@ function X_TextRange_getOffset(){ | ||
272 | 318 | range = result.hitRange; |
273 | 319 | ret = { |
274 | 320 | 'offset' : result.offset, |
275 | - 'from' : this.v1 = range.startOffset, | |
276 | - 'to' : this.v2 = range.endOffset, | |
321 | + 'from' : this[ 'v1' ] = range.startOffset, | |
322 | + 'to' : this[ 'v2' ] = range.endOffset, | |
277 | 323 | 'text' : X_Node_getXNode( result.text ) |
278 | 324 | }; |
279 | 325 | // range.detach && range.detach(); |
280 | 326 | } else { |
281 | 327 | // http://www.studio-freesky.net/programming/javascript/3/ |
282 | 328 | |
283 | - range = X_TextRange_range2; | |
329 | + range = X_TextRange_range.duplicate(); | |
284 | 330 | range.moveToElementText( xnode[ '_rawObject' ] ); |
285 | 331 | range.setEndPoint( 'EndToStart', result ); |
332 | + //range.text && range.moveEnd( 'character', -1 ); | |
286 | 333 | from = range.text.length; |
287 | 334 | |
288 | 335 | X_TextRange_collectXTexts( xnode, xtexts = [] ); |
@@ -298,8 +345,8 @@ function X_TextRange_getOffset(){ | ||
298 | 345 | |
299 | 346 | ret = { |
300 | 347 | 'offset' : n, // elm の何個目の node か? |
301 | - 'from' : this.v1 = from - n, | |
302 | - 'to' : this.v2 = from - n + result.text.length, | |
348 | + 'from' : this[ 'v1' ] = from - n, | |
349 | + 'to' : this[ 'v2' ] = from - n + result.text.length, | |
303 | 350 | 'text' : xtext |
304 | 351 | }; |
305 | 352 | }; |
@@ -319,9 +366,9 @@ function X_TextRange_text( v ){ | ||
319 | 366 | elm = xnode[ '_rawObject' ]; |
320 | 367 | val = X_UA[ 'IE' ] < 9 ? X_Node_Attr_getValueForIE( elm ) : elm.value; |
321 | 368 | |
322 | - if( this.createFrom === 'char' ){ | |
369 | + if( this[ 'by' ] === 'char' ){ | |
323 | 370 | xnode.attr( { |
324 | - 'value' : val.substr( 0, this.v1 ) + v + val.substr( this.v2 ) | |
371 | + 'value' : val.substr( 0, this[ 'v1' ] ) + v + val.substr( this[ 'v2' ] ) | |
325 | 372 | } ); |
326 | 373 | } else { |
327 | 374 | offset = this[ 'getOffset' ](); |
@@ -330,7 +377,7 @@ function X_TextRange_text( v ){ | ||
330 | 377 | to = offset[ 'to' ]; |
331 | 378 | |
332 | 379 | if( X_UA[ 'IE' ] < 9 ){ |
333 | - range = document.selection.createRange(); | |
380 | + range = X_TextRange_selection(); | |
334 | 381 | // TODO check textarea |
335 | 382 | range.text = v; |
336 | 383 | // ここには range.text がいない https://msdn.microsoft.com/ja-jp/library/cc427934.aspx |
@@ -358,18 +405,18 @@ function X_TextRange_move( from, to ){ | ||
358 | 405 | len, range; |
359 | 406 | |
360 | 407 | if( 0 <= from ){ |
361 | - this.v1 = from; | |
408 | + this[ 'v1' ] = from; | |
362 | 409 | } else { |
363 | - this.v1 = this.v1 + from; | |
364 | - this.v1 < 0 && ( this.v1 = 0 ); | |
410 | + this[ 'v1' ] = this[ 'v1' ] + from; | |
411 | + this[ 'v1' ] < 0 && ( this[ 'v1' ] = 0 ); | |
365 | 412 | }; |
366 | 413 | |
367 | 414 | if( X_Type_isNumber( to ) ){ |
368 | 415 | if( 0 <= to ){ |
369 | - this.v2 = to; | |
416 | + this[ 'v2' ] = to; | |
370 | 417 | } else { |
371 | - this.v2 = this.v2 + to; | |
372 | - this.v2 < this.v1 && ( this.v2 = this.v1 ); | |
418 | + this[ 'v2' ] = this[ 'v2' ] + to; | |
419 | + this[ 'v2' ] < this[ 'v1' ] && ( this[ 'v2' ] = this[ 'v1' ] ); | |
373 | 420 | }; |
374 | 421 | }; |
375 | 422 |
@@ -380,24 +427,22 @@ function X_TextRange_move( from, to ){ | ||
380 | 427 | len = ( X_UA[ 'IE' ] < 9 ? X_Node_Attr_getValueForIE( elm ) : elm.value ).length; |
381 | 428 | |
382 | 429 | if( X_UA[ 'Opera' ] ){ |
383 | - X_EventDispatcher_ignoreActualEvent = 'focus'; | |
384 | - elm.focus(); // Operaの為(IEでは無くても大丈夫) | |
385 | - X_EventDispatcher_ignoreActualEvent = ''; | |
430 | + FocusUtility_setTemporarilyFocus( elm ); | |
386 | 431 | }; |
387 | 432 | |
388 | 433 | range = elm.createTextRange(); |
389 | 434 | |
390 | - if( this.v1 === this.v2 && this.v1 === 0 ){ | |
435 | + if( this[ 'v1' ] === this[ 'v2' ] && this[ 'v1' ] === 0 ){ | |
391 | 436 | range.collapse( true ); // 先頭に移動 |
392 | 437 | } else { |
393 | - if( this.v1 !== this.v2 || this.v1 < len ){ | |
438 | + if( this[ 'v1' ] !== this[ 'v2' ] || this[ 'v1' ] < len ){ | |
394 | 439 | range.collapse(); // おまじない? |
395 | 440 | |
396 | - if( this.v1 === this.v2 ){ | |
397 | - range.move( 'character', this.v1 ); | |
441 | + if( this[ 'v1' ] === this[ 'v2' ] ){ | |
442 | + range.move( 'character', this[ 'v1' ] ); | |
398 | 443 | } else { |
399 | - range.moveEnd( 'character', this.v2 ); | |
400 | - range.moveStart( 'character', this.v1 ); | |
444 | + range.moveEnd( 'character', this[ 'v2' ] ); | |
445 | + range.moveStart( 'character', this[ 'v1' ] ); | |
401 | 446 | }; |
402 | 447 | } else { |
403 | 448 | range.collapse( false ); // 末美に移動 |
@@ -406,7 +451,7 @@ function X_TextRange_move( from, to ){ | ||
406 | 451 | range.select(); |
407 | 452 | |
408 | 453 | } else if( elm.setSelectionRange ){ |
409 | - elm.setSelectionRange( this.v1, this.v2 ); | |
454 | + elm.setSelectionRange( this[ 'v1' ], this[ 'v2' ] ); | |
410 | 455 | }; |
411 | 456 | }; |
412 | 457 | }; |
@@ -422,15 +467,13 @@ function X_TextRange_select( v ){ | ||
422 | 467 | // https://web.archive.org/web/20090904183807/http://www.dedestruct.com/cursorPosition.html |
423 | 468 | function cursorPosition( textarea ){ |
424 | 469 | |
425 | - var selection_range = document.selection.createRange().duplicate(); | |
470 | + var selection_range = X_TextRange_selection().duplicate(); | |
426 | 471 | |
427 | 472 | |
428 | 473 | if (selection_range.parentElement() !== textarea) { |
429 | 474 | // TODO 正しくはカーソル位置・選択範囲の復帰 |
430 | 475 | |
431 | - X_EventDispatcher_ignoreActualEvent = 'focus'; | |
432 | - textarea.focus(); | |
433 | - X_EventDispatcher_ignoreActualEvent = ''; | |
476 | + FocusUtility_setTemporarilyFocus( textarea ); | |
434 | 477 | |
435 | 478 | // BODY要素のテキスト範囲を作成する |
436 | 479 | selection_range = X_elmBody.createTextRange(); |
@@ -523,8 +566,8 @@ function X_TextRange_select( v ){ | ||
523 | 566 | var startPoint = untrimmed_before_text.split( '\r' ).join( '' ).length; |
524 | 567 | // alert(startPoint); |
525 | 568 | return { |
526 | - 'from' : this.v1 = startPoint, | |
527 | - 'to' : this.v2 = startPoint + untrimmed_selection_text.split( '\r' ).join( '' ).length | |
569 | + 'from' : this[ 'v1' ] = startPoint, | |
570 | + 'to' : this[ 'v2' ] = startPoint + untrimmed_selection_text.split( '\r' ).join( '' ).length | |
528 | 571 | }; |
529 | 572 | //} |
530 | 573 | } |
@@ -4,10 +4,6 @@ | ||
4 | 4 | * keydown について。Firefox では押している間中リスナの関数が実行される |
5 | 5 | * デフォルトイベントの制御・抑止 (opera)keypress を用いる。 |
6 | 6 | * |
7 | - * キーイベント処理の工夫 | |
8 | - * http://www.keynavi.net/ja/tipsj/kfunc.html | |
9 | - * keydown/up時にピリオドが文字化け (IE4-6) IE4+では「keypress」でキーコードを処理する 但しCtrlやALTが押されている場合は逆にkeydownで処理する必要があります | |
10 | - * | |
11 | 7 | * |
12 | 8 | * keydown をトリガーにイベントを発火するもの |
13 | 9 | * 1. テンキーの 0~9 keyCode:96-105 |
@@ -25,8 +21,8 @@ var X_KB_SPECIALS = eval( // IE5- 対策 | ||
25 | 21 | "'33':'PAGE_UP','34':'PAGE_DOWN','35':'END','36':'HOME','37':'CSR_L','38':'CSR_U','39':'CSR_R','40':'CSR_D'," + |
26 | 22 | "'44':'PRT_SCRN','45':'INS','46':'DEL'," + |
27 | 23 | "'91':'LWIN','92':'RWIN','93':'APP'," + |
28 | - "'96':48,'97':49,'98':50,'99':51,'100':52,'101':53,'102':54,'103':55,'104':56,'105':57,'106':42,'107':43,'109':45," + | |
29 | - "'111':47,'112':'F1','113':'F2','114':'F3','115':'F4','116':'F5','117':'F6','118':'F7','119':'F8','120':'F9','121':'F10','122':'F11','123':'F12'," + | |
24 | + "'96':48,'97':49,'98':50,'99':51,'100':52,'101':53,'102':54,'103':55,'104':56,'105':57,'106':42,'107':43,'109':45,'110':46,'111':47," + | |
25 | + "'112':'F1','113':'F2','114':'F3','115':'F4','116':'F5','117':'F6','118':'F7','119':'F8','120':'F9','121':'F10','122':'F11','123':'F12'," + | |
30 | 26 | "'144':'NUM_LOCK','145':'SCROLL_LOCK','208':'CAPS_LOCK','240':'CAPS_LOCK','242':'K/H','243':'H/Z','244':'H/Z'})" ), |
31 | 27 | X_KB_DOWN_KEYS = {}, |
32 | 28 | X_KB_CANCELED = {}, |
@@ -34,6 +30,8 @@ var X_KB_SPECIALS = eval( // IE5- 対策 | ||
34 | 30 | X_KB_lastKeyCode = 0, |
35 | 31 | X_KB_TRANSFOEM = {}, |
36 | 32 | |
33 | + // TODO keyevent のためには input 等にフォーカスが必要 -> iOS | |
34 | + | |
37 | 35 | X_kbManager = |
38 | 36 | X_Class_override( |
39 | 37 | X_EventDispatcher(), |
@@ -42,14 +40,16 @@ var X_KB_SPECIALS = eval( // IE5- 対策 | ||
42 | 40 | var keyCode = e.keyCode, // keyCode says something about the actual keyboard key the user pressed |
43 | 41 | chrCode = e.charCode, // while charCode gives the ASCII value of the resulting character |
44 | 42 | cb = X_CALLBACK_NONE, |
45 | - special, _keyCode; | |
43 | + special; | |
46 | 44 | |
47 | - console.log( e.type + ' > keyCode:' + keyCode + ' chrCode:' + chrCode ); | |
45 | + // console.log( e.type + ' > keyCode:' + keyCode + ' chrCode:' + chrCode ); | |
48 | 46 | |
49 | 47 | switch( e.type ){ |
50 | 48 | case 'keydown' : |
51 | 49 | if( X_KB_DOWN_KEYS[ keyCode ] ){ |
52 | 50 | // 既に押されている、メタキー[shift,ctrl,alt]の変化はある? |
51 | + console.log( ' doen -- ' ); | |
52 | + | |
53 | 53 | return X_KB_CANCELED[ keyCode ] ? X_CALLBACK_PREVENT_DEFAULT : cb; |
54 | 54 | } else |
55 | 55 | if( special = X_KB_SPECIALS[ keyCode ] ){ |
@@ -87,13 +87,32 @@ var X_KB_SPECIALS = eval( // IE5- 対策 | ||
87 | 87 | }; */ |
88 | 88 | } else { |
89 | 89 | X_KB_lastKeyCode = keyCode; |
90 | - }; | |
90 | + | |
91 | + if( e.ctrlKey || e.altKey || e.metaKey ){ | |
92 | + cb = this[ 'dispatch' ]( { | |
93 | + type : 'keydown', | |
94 | + keyCode : 0, | |
95 | + charCode : chrCode, | |
96 | + 'keyName' : '', | |
97 | + 'is10key' : false, | |
98 | + shiftKey : !!X_KB_DOWN_KEYS[ 16 ], | |
99 | + ctrlKey : !!X_KB_DOWN_KEYS[ 17 ], | |
100 | + altKey : !!X_KB_DOWN_KEYS[ 18 ], | |
101 | + metaKey : !!X_KB_DOWN_KEYS[ 224 ] | |
102 | + } ); | |
103 | + | |
104 | + if( cb & X_CALLBACK_PREVENT_DEFAULT ){ | |
105 | + X_KB_CANCELED[ keyCode ] = true; | |
106 | + }; | |
107 | + }; | |
108 | + console.log( ' keydown[' + keyCode + ']' + String.fromCharCode( chrCode ) + chrCode ); | |
109 | + }; | |
91 | 110 | return cb; |
92 | 111 | |
93 | 112 | case 'keypress' : |
94 | 113 | // keydown 側で発火しているものは再び発火しない |
95 | - | |
96 | 114 | if( X_KB_DOWN_KEYS[ chrCode ] ){ |
115 | + // TODO keypress | |
97 | 116 | return X_KB_CANCELED[ chrCode ] ? X_CALLBACK_PREVENT_DEFAULT : cb; |
98 | 117 | } else |
99 | 118 | if( keyCode === 32 ){ |
@@ -117,6 +136,8 @@ var X_KB_SPECIALS = eval( // IE5- 対策 | ||
117 | 136 | X_KB_lastIs10Key = false; |
118 | 137 | |
119 | 138 | console.log( X_KB_lastKeyCode + 'keypress : chrCode:' + chrCode + ' down:' + X_KB_DOWN_KEYS[ chrCode ] + ( X_KB_CANCELED[ chrCode ] ? ' Cancel!' : '' ) ); |
139 | + } else { | |
140 | + console.log( '>> keypress : chrCode:' + chrCode + ' down:' + X_KB_DOWN_KEYS[ chrCode ] + ( X_KB_CANCELED[ chrCode ] ? ' Cancel!' : '' ) ); | |
120 | 141 | }; |
121 | 142 | return cb; |
122 | 143 |
@@ -156,7 +177,7 @@ var X_KB_SPECIALS = eval( // IE5- 対策 | ||
156 | 177 | chrCode = 0; |
157 | 178 | }; |
158 | 179 | |
159 | - console.log( keyCode + ' keyup ' + chrCode ); | |
180 | + //console.log( keyCode + ' keyup ' + chrCode ); | |
160 | 181 | |
161 | 182 | cb |= this[ 'dispatch' ]( { |
162 | 183 | type : 'keyup', |
@@ -24,6 +24,8 @@ document.write( [ | ||
24 | 24 | 'js/01_core/14_XEvent.js', |
25 | 25 | 'js/01_core/15_XEventDispatcher.js', |
26 | 26 | 'js/01_core/16_XTimer.js', |
27 | + 'js/01_core/17_ExecuteAtEnd.js', | |
28 | + 'js/01_core/18_FocusUtility.js', | |
27 | 29 | |
28 | 30 | 'js/01_core/20_XSystem.js', |
29 | 31 | 'js/01_core/21_XViewPort.js', |