• R/O
  • HTTP
  • SSH
  • HTTPS

clientJs: コミット

クライアント側 js 開発用


コミットメタ情報

リビジョン3c54df5e0d4f20eb32cfd73480cbc9ae8358ebbf (tree)
日時2016-01-05 11:04:45
作者itozyun <itozyun@user...>
コミッターitozyun

ログメッセージ

Version 0.6.205, bug fixes X.Net.Form, update X.HTMLAudio for iOS7+.

変更サマリ

差分

--- a/0.6.x/js/06_net/00_XNet.js
+++ b/0.6.x/js/06_net/00_XNet.js
@@ -22,9 +22,10 @@
2222 * <h4>必須プロパティ</h4>
2323 * <dl>
2424 * <dt>url<dd>URL
25- * <dt>type<dd>'xhr', 'jsonp', 'image', 'img'
25+ * <dt>type<dd>'xhr', 'jsonp', 'form', 'image', 'img'
2626 * <dt>xhr<dd>URL { url : 'hoge', type : 'xhr' } の省略形
2727 * <dt>jsonp<dd>URL { url : 'hoge', type : 'jsonp' } の省略形
28+ * <dt>form<dd>URL { url : 'hoge', type : 'form' } の省略形
2829 * <dt>image, img<dd>URL { url : 'hoge', type : 'image' } の省略形
2930 * </dl>
3031 * <h4>XHR 用プロパティ</h4>
@@ -50,14 +51,16 @@
5051 * <dt>params<dd>url パラメータを object で渡すことが出来る。
5152 * <dt>callbackName<dd>callback(json) コールバック名が固定されている際に指定。または &callback=hoge 以外の名前でコールバックを指定する場合に params と callbackName に書いておく。url パラメータに callback が無く、callbackName もない場合、フレームワーク内で自動で設定される
5253 * <dt>charset<dd>ページと異なるjsonpを読み込む場合に指定 'EUC-JP', 'Shift-JIS' 等 script タグの charset に入る。https://code.google.com/p/ajaxzip3/issues/detail?id=5
53- * <dt>useFireWall<dd>異なるドメインに jsonp を読み込んだ後、xdomain iframe 通信を使ってデータを受け取る。不正なコードの実行を防ぐことが出来る、未実装
54+ * <dt>useFireWall<dd>異なるドメインに jsonp を読み込んだ後、xdomain iframe 通信を使ってデータを受け取る。不正なコードの実行を防ぐことが出来る(はず)、未実装
5455 * </dl>
5556 *
5657 * <h4>Form 用プロパティ</h4>
5758 * <dl>
58- * <dt>params<dd>url パラメータを object で渡すことが出来る。
5959 * <dt>method<dd>'GET' or 'POST'
60- * <dt>target<dd>'_self', '_parent', '_top' の場合、ページから離脱する。target を指定せず同一ドメインの場合 response に body.innerHTML が返る。
60+ * <dt>params<dd>パラメータ object は input タグの name & value に展開される。object を入れ子にすることはできない。
61+ * <dt>target<dd>'_self', '_parent', '_top' の場合、ページから離脱する。target を指定せず同一ドメインの場合 response に body.innerHTML が返る。TODO X.Window
62+ * <dt>timeout<dd>ms タイムアウト時間、省略可能
63+ * <dt>charset<dd>未実装
6164 * </dl>
6265 *
6366 * @alias X.Net
@@ -155,8 +158,8 @@ X[ 'Net' ] = X_EventDispatcher[ 'inherits' ](
155158 opt[ 'auth' ] = auth; // auth は deep copy されるとまずい
156159 };
157160
158- // params を url に追加
159- if( opt[ 'params' ] ){
161+ // params を url に追加 但し form は除く
162+ if( opt[ 'params' ] && type !== X_NET_TYPE_FORM ){
160163 url = X_URL_create( url, opt[ 'params' ] );
161164 delete opt[ 'params' ];
162165 };
--- a/0.6.x/js/06_net/02_XNetJSONP.js
+++ b/0.6.x/js/06_net/02_XNetJSONP.js
@@ -68,7 +68,6 @@ X_TEMP.X_JSONP_params = {
6868 load : function( option ){
6969 //createURL
7070 var url = option[ 'url' ],
71- params = option[ 'params' ],
7271 callback = option[ 'callbackName' ],
7372 charset = option[ 'charset' ],
7473 json2Path = window.RegExp ? 'js/libs/json2.js' : 'js/libs/json2_regfree.js',
@@ -79,9 +78,7 @@ X_TEMP.X_JSONP_params = {
7978 if( !X_URL_isSameProtocol( url ) ){
8079 return X_JSONP[ 'asyncDispatch' ]( X_EVENT_ERROR );
8180 };
82-
83- url = X_URL_create( url, params );
84-
81+
8582 if( !callback && !( callback = X_URL_paramToObj( url.split( '?' )[ 1 ] )[ 'callback' ] ) ){
8683 url += '&callback=cb';
8784 callback = 'cb';
--- a/0.6.x/js/06_net/03_XNetForm.js
+++ b/0.6.x/js/06_net/03_XNetForm.js
@@ -1,6 +1,8 @@
11 //{+netform"<form>によるGETとPOST"(動的に生成したフォームによるGETとPOST。)[+net,+ninjaiframe]
22
3-var X_FormSender_errorTimerID, X_FormSender_onloadCount = 0;
3+var X_FormSender_errorTimerID,
4+ X_FormSender_isLeave,
5+ X_FormSender_onloadCount = 0;
46
57 X_TEMP.X_FormSender_init = function(){
68 X_FormSender = X_Class_override( X_NinjaIframe(), X_TEMP.X_FormSender_params );
@@ -13,7 +15,7 @@ X_TEMP.X_FormSender_init = function(){
1315
1416 /*
1517 * form 構築時に "><script> といった文字列の挿入を禁止するために " を エスケープする
16- * TODO 改行文字を消す
18+ * TODO 改行文字を消す escape?
1719 */
1820 function X_FormSender_escapeQuote( str ){
1921
@@ -21,28 +23,29 @@ function X_FormSender_escapeQuote( str ){
2123 };
2224
2325 X_TEMP.X_FormSender_params = {
24-
26+
2527 _busy : false,
2628 _canceled : false,
2729
28- timeout : 1000,
29- isJump : false, // ページを離脱するか?
30-
3130 load : function( option ){
3231 //createURL
33- var params = option[ 'params' ] || {},
34- target = option[ 'target' ],
32+ var params = option[ 'params' ] || {},
33+ target = option[ 'target' ],
34+ timeout = option[ 'timeout' ],
35+ // http://search.web-sun.com/zatu/charset.html
36+ // charset = option[ 'charset' ],
3537 html, k;
3638
3739 target = target === '_self' ? '_parent' : target === '_blank' ? '_self' : target || '_self',
3840 html = [
41+ // <meta http-equiv="Content-Type" content="text/html; charset=euc-jp">
3942 '<form method="', X_FormSender_escapeQuote( option[ 'method' ] || 'GET' ),
4043 '" action="', X_FormSender_escapeQuote( option[ 'url' ] || '' ),
4144 '" target="', X_FormSender_escapeQuote( target ),
4245 '">' ];
4346
44- if( target === '_top' || target === '_parent' ) X_FormSender.isJump = true;
45- if( 0 <= option[ 'timeout' ] ) X_FormSender.timeout = option[ 'timeout' ];
47+ X_FormSender_isLeave = target === '_top' || target === '_parent';
48+
4649
4750 for( k in params ){
4851 // TODO 使用すべきでない name
@@ -51,11 +54,15 @@ X_TEMP.X_FormSender_params = {
5154 };
5255
5356 html.push( '</form><script>document.forms[0].submit();</script>' );
54-
57+
5558 X_FormSender
5659 [ 'refresh' ]( html.join( '' ) )
5760 [ 'listen' ]( [ 'ninjaload', 'ninjaerror' ], X_FormSender_iframeListener );
58-
61+
62+ if( 0 < timeout ){
63+ X_FormSender_errorTimerID = X_FormSender[ 'asyncDispatch' ]( timeout, { type : X_EVENT_ERROR, 'timeout' : true } );
64+ };
65+
5966 X_FormSender._busy = true;
6067 },
6168
@@ -66,8 +73,9 @@ X_TEMP.X_FormSender_params = {
6673
6774 reset : function(){
6875 X_FormSender._busy = X_FormSender._canceled = false;
69- X_FormSender[ 'unlisten' ]( [ 'ninjaload', 'ninjaerror' ], X_FormSender_iframeListener );
70- X_FormSender[ 'refresh' ]( '' );
76+ X_FormSender
77+ [ 'unlisten' ]( [ 'ninjaload', 'ninjaerror' ], X_FormSender_iframeListener )
78+ [ 'refresh' ]( '' );
7179 X_FormSender_errorTimerID && X_Timer_remove( X_FormSender_errorTimerID );
7280 X_FormSender_errorTimerID = X_FormSender_onloadCount = 0;
7381 }
@@ -78,18 +86,13 @@ function X_FormSender_iframeListener( e ){
7886
7987 switch( e.type ){
8088 case 'ninjaload' :
81- if( X_FormSender.isJump ){
89+ if( X_FormSender_isLeave ){
8290 return;
8391 };
8492
8593 if( ++X_FormSender_onloadCount === 1 ){
86- X_FormSender_errorTimerID = X_FormSender[ 'asyncDispatch' ]( X_FormSender.timeout, { type : X_EVENT_ERROR, 'timeout' : true } );
87-
88- // TODO レスポンスの html にアクセスしたい場合
89- // TODO samedomain or xiframe-sender
90-
9194 idoc = this[ '_rawObject' ].contentDocument || this._iwin.document,
92-
95+
9396 X_FormSender[ 'asyncDispatch' ]( { type : X_EVENT_SUCCESS, response : idoc && idoc.body ? idoc.body.innerHTML : '' } );
9497 };
9598 break;
--- a/0.6.x/js/07_audio/01_XWebAudio.js
+++ b/0.6.x/js/07_audio/01_XWebAudio.js
@@ -79,7 +79,9 @@ if( X_Audio_constructor ){
7979
8080
8181 var X_WebAudio_context = // 4s 以下ではない iPad 2G または iPad mini 1G 以下ではない, iPod touch 4G 以下ではない
82- !X_UA[ 'iPhone_4s' ] && !X_UA[ 'iPad_2Mini1' ] && !X_UA[ 'iPod_4' ] &&
82+ !X_UA[ 'iPhone_4s' ] && !X_UA[ 'iPad_2Mini1' ] && !X_UA[ 'iPod_4' ] &&
83+ // iOS7 以上で HTML Audio が鳴らない問題を見ていくよ
84+ // !X_UA[ 'iOS' ] &&
8385 // Android2 + Gecko で WebAudio が極めて不安定
8486 !( X_UA[ 'Fennec' ] && X_UA[ 'Android' ] < 3 ) &&
8587 // AOSP でも WebAudio を不完全に実装するものがある, touch の有無も不明のため一律に切ってしまう
@@ -166,7 +168,7 @@ if( X_WebAudio_context ){
166168 _onDecodeSuccess : function( buffer ){
167169 this.onDecodeSuccess && this._onDecodeComplete();
168170
169- if ( !buffer ) {
171+ if( !buffer ){
170172 this.errorState = 2;
171173 this[ 'asyncDispatch' ]( X_EVENT_COMPLETE );
172174 return;
@@ -198,6 +200,7 @@ if( X_WebAudio_context ){
198200 unregister : function( webAudio ){
199201 var list = this.webAudioList,
200202 i = list.indexOf( webAudio );
203+
201204 if( 0 < i ){
202205 list.splice( i, 1 );
203206 if( !list.length ){
@@ -289,7 +292,6 @@ if( X_WebAudio_context ){
289292
290293 if ( !buffer ) {
291294 this.error = loader.errorState;
292-
293295 this.disatcher[ 'dispatch' ]({
294296 type : X_EVENT_ERROR,
295297 error : loader.errorState,
--- a/0.6.x/js/07_audio/02_XHTMLAudio.js
+++ b/0.6.x/js/07_audio/02_XHTMLAudio.js
@@ -39,8 +39,9 @@
3939
4040 var
4141 X_HTMLAudio,
42-
43- // ended が発生しない timeupdate 内で play() を呼ぶ (未検証) 不具合確認は iOS4,6
42+ // iOS7.1, 8.3 で確認.seeking -> seeked の間の currentTime の値が全くあてにならないので無視する。
43+ X_HTMLAudio_seekingFixIOS = 7 <= X_UA[ 'iOS' ],
44+ // ended が発生しない timeupdate 内で play() を呼ぶ (未検証) 不具合確認は iOS4,6 iOS7.1,8.3ではpause->ended起きてる 但し iOS7.1 でも 6 と同じ症状になることがある
4445 X_HTMLAudio_endedFixIOS = X_UA[ 'iOS' ] < 7,
4546 // Android 2.3.5 で ended 時に audio.src='';audio.src=src;audio.load() を実施。 2.3.4 でも問題なし。
4647 X_HTMLAudio_endedFixAOSP2 = X_UA[ 'AOSP' ] < 3,
@@ -59,17 +60,21 @@ var
5960 * win opera12 volume, mute の変更が2度目以降できない
6061 */
6162 X_HTMLAudio_volumeEnabled = !( X_UA[ 'WinPhone' ] && X_UA[ 'IE9' ] ) && !X_UA[ 'Opera' ],
62- // Gecko PC + Android でseek時に再生がしばしば止まる問題の修正
63+ // Gecko PC + Android でseek時に再生がしばしば止まる問題の修正、iOS8でも確認
6364 X_HTMLAudio_needPlayForSeek = X_UA[ 'iOS' ] || X_UA[ 'Gecko' ],
6465 //
6566 X_HTMLAudio_pauseFix = 12 <= X_UA[ 'Opera' ] && 0 < ' XP XPSP2 2003|XP64'.indexOf( X_UA[ 'Windows' ] ), // XP + Opera12 のみ?
6667
6768 X_HTMLAudio_need1stTouch = X_UA[ 'iOS' ] || 4.2 <= X_UA[ 'AOSP' ] || X_UA[ 'ChromeWV' ] || X_UA[ 'WinPhone' ] || ( X_UA[ 'Blink' ] && X_UA[ 'Android' ] ),
6869
69- X_HTMLAudio_playTrigger = ( X_UA[ 'WinPhone' ] && X_UA[ 'IE9' ] ) ? 'canplay' : X_UA[ 'iOS' ] ? 'suspend' : X_UA[ 'Blink' ] < 32 ? 'stalled' : 'canplaythrough',
70+ X_HTMLAudio_playTrigger = ( X_UA[ 'WinPhone' ] && X_UA[ 'IE9' ] ) ? 'canplay' :
71+ X_UA[ 'iOS' ] < 8 ? 'suspend' : // iOS7.x以下
72+ X_UA[ 'iOS' ] ? 'loadedmetadata' : // iOS8以上は
73+ X_UA[ 'Blink' ] < 32 ? 'stalled' : 'canplaythrough',
7074
71- X_HTMLAudio_durationFix = X_UA[ 'iOS' ] || X_UA[ 'ChromeWV' ] || ( X_UA[ 'WinPhone' ] && X_UA[ 'IE9' ] ) ||
72- ( X_UA[ 'Windows' ] && 12 <= X_UA[ 'Opera' ] ) || ( X_UA[ 'Blink' ] < 36 && X_UA[ 'Android' ] ),
75+ X_HTMLAudio_durationFix = // iOS8.1(シュミレータでは不要)
76+ X_UA[ 'iOS' ] < 8 || X_UA[ 'ChromeWV' ] || ( X_UA[ 'WinPhone' ] && X_UA[ 'IE9' ] ) ||
77+ ( X_UA[ 'Windows' ] && 12 <= X_UA[ 'Opera' ] ) || ( X_UA[ 'Blink' ] < 36 && X_UA[ 'Android' ] ),
7378
7479 X_HTMLAudio_shortPlayFix = X_UA[ 'AOSP' ],
7580
@@ -109,6 +114,8 @@ if( X_Audio_constructor ){
109114
110115 _endedFixON : false,
111116
117+ _seekingFixON : false,
118+
112119 'Constructor' : function( disatcher, source, option ){
113120 var raw;
114121
@@ -146,7 +153,8 @@ if( X_Audio_constructor ){
146153 //'loadstart', 'load',
147154 'progress', //'error',
148155 // 'suspend', 'abort', 'emptied', 'stalled',
149- // 'play', 'pause', 'seeked', 'ratechange', 'volumechange',
156+ // 'play', 'pause', 'ratechange', 'volumechange',
157+ 'seeked',
150158 'loadedmetadata', 'loadeddata', 'canplay', 'canplaythrough',
151159 'playing', 'waiting', 'seeking',
152160 'durationchange', 'timeupdate', 'ended' ] );
@@ -161,7 +169,7 @@ if( X_Audio_constructor ){
161169 'durationchange', 'timeupdate', 'ended' ], this.onDebug );
162170
163171 if( X_HTMLAudio_endedFixAOSP2 || X_HTMLAudio_endedFixAOSP4 ){
164- raw.loop = true; // loop を使えば ended で止まること回避できるかも 但し ended イベントが起きなくなる
172+ raw.loop = true; // loop を使えば ended で止まること回避できる 但し ended イベントが起きなくなる
165173 };
166174
167175 if( X_HTMLAudio_need1stTouch ){
@@ -252,6 +260,9 @@ if( X_Audio_constructor ){
252260
253261 // TODO firefox で 短い音声でtimeupdate, ended が発火しない <- 最後の音に無音部分を追加する
254262 case 'timeupdate' : // 通常の再生が行われ現在の再生位置の変化が起こった場合に発生
263+ if( this._seekingFixON ){
264+ eventType = X_EVENT_MEDIA_SEEKING;
265+ } else
255266 if( this._durationFixPhase === 8 ){
256267 this._durationFixPhase = 0;
257268 this._readyState |= 1;
@@ -271,9 +282,13 @@ if( X_Audio_constructor ){
271282 end = X_Audio_getEndTime( this ) + this._shortPlayFixTime;
272283 //console.log( now + ' / ' + end );
273284 if( ( 0 + end <= 0 + now ) || // 0+ なぜか iem9 で必要,,,
274- ( now < this._lastCurrentTime ) ){ // loop した場合
285+ ( now < this._lastCurrentTime && now < 2000 ) ){
286+ //( ( X_HTMLAudio_endedFixAOSP2 || X_HTMLAudio_endedFixAOSP4 ) && ( now < this._lastCurrentTime && now < 1000 ) ) ){
287+ // loop して0付近に戻った場合
288+ // iOS8.4 ではこのタイミングで now が last より 0.1秒後退している場合がある
289+ // iOS7.1 ではもっと小さい場合がある,,,
275290 if( this.autoLoop ){
276- console.log( '☆★☆ 曲の最後に到達 @timeupdate now-end:' + ( now - end ) );
291+ console.log( '☆★☆ 曲の最後に到達 @timeupdate now-end:' + ( now - end ) + ' now:' + now + ' last:' + this._lastCurrentTime );
277292 ended = true;
278293 //if( X_HTMLAudio_endedFixIOS ) actualEnded = true;
279294 } else {
@@ -310,16 +325,20 @@ if( X_Audio_constructor ){
310325 eventType = !this._durationFixPhase && !this._endedFixON ? X_EVENT_MEDIA_PLAYING : X_EVENT_MEDIA_WAITING;
311326 //case 'play' : // 再生が開始された。play()メソッドからの復帰後に発生する場合に発生
312327 //case 'pause' : // 再生が一時停止された。pauseメソッドからの復帰後に発生する場合に発生
313- //case 'seeked' :
314328 //case 'ratechange' : // defaultPlaybackRate属性とplaybackRate属性のどちらかが更新された場合に発生
315329 //case 'volumechange' : // volume属性とmuted属性のどちらかが変化した場合に発生
316330 break;
317331
332+ case 'seeked' :
333+ if( this._seekingFixON ) this._seekingFixON = false;
334+ break;
335+
318336 case 'waiting' : // 次のフレームが利用不可のため再生を停止したが、そのフレームがやがて利用可能になると想定している場合に発生
319337 eventType = X_EVENT_MEDIA_WAITING;
320338 break;
321339 case 'seeking' : // シークがtrueに変化し、イベントを発生させるのに十分な時間がシーク操作にかかっている場合に発生
322340 eventType = X_EVENT_MEDIA_SEEKING;
341+ if( X_HTMLAudio_seekingFixIOS ) this._seekingFixON = true;
323342 break;
324343 };
325344
旧リポジトリブラウザで表示