まめしみ

やったことを淡々と書く

Archive for 10月, 2011

jQueryMobile(1.0rc2)でkeepNativeが復活


 

以前書いた「jQueryMobile(1.0b2)のスタイルを無効化する」でkeepNativeが使えなくなった話をしましたが「1.0rc2」で復活してるようです。

 

「1.0b2」から何度かバージョンが上がって「1.0rc2」がリリースされました。Change logをさら〜っと見てたらこんなの見つけました!

Allow users to define keepnative on page elements – Change allows for more flexibility

 

commit log探ってポイントを抜粋してみました。

 

定義してるとこ

$.widget( "mobile.page", $.mobile.widget, {
	options: {
		theme: "c",
		domCache: false,
		keepNativeDefault: ":jqmData(role='none'), :jqmData(role='nojs')"
	},

	_create: function() {

		this._trigger( "beforecreate" );

		this.element
			.attr( "tabindex", "0" )
			.addClass( "ui-page ui-body-" + this.options.theme );
	},

	keepNativeSelector: function() {
		var options = this.options,
			keepNativeDefined = options.keepNative && $.trim(options.keepNative);

		if( keepNativeDefined && options.keepNative !== options.keepNativeDefault ){
			return [options.keepNative, options.keepNativeDefault].join(", ");
		}

		return options.keepNativeDefault;
	}
});

 

実際に使ってるとこ

(function( $, undefined ) {

$.widget( "mobile.widget", {
	// decorate the parent _createWidget to trigger `widgetinit` for users
	// who wish to do post post `widgetcreate` alterations/additions
	//
	// TODO create a pull request for jquery ui to trigger this event
	// in the original _createWidget
	_createWidget: function() {
		$.Widget.prototype._createWidget.apply( this, arguments );
		this._trigger( 'init' );
	},

	_getCreateOptions: function() {

		var elem = this.element,
			options = {};

		$.each( this.options, function( option ) {

			var value = elem.jqmData( option.replace( /[A-Z]/g, function( c ) {
							return "-" + c.toLowerCase();
						})
					);

			if ( value !== undefined ) {
				options[ option ] = value;
			}
		});

		return options;
	},

	enhanceWithin: function( target ) {
		// TODO remove dependency on the page widget for the keepNative.
		// Currently the keepNative value is defined on the page prototype so
		// the method is as well
		var page = $(target).data( "page" ),
			keepNative = page && page.keepNativeSelector();

		$( this.options.initSelector, target ).not( keepNative || "" )[ this.widgetName ]();
	}
});

 

enhanceWithinで各widgetの初期化が実行されます。その時点でkeepNativeで指定したセレクタは除外してます。
enhanceWithinが呼ばれないwidget(listviewなど)には意味が無いです。
data-role=”listview”指定してる時点で無効にする事はないので問題ないでしょう。

 

試したところ1.0b2以前のようにclass指定での一括除外もできました。
※この記述はjQueryMobileの読み込みより先に

$(document).bind("mobileinit", function(){
  $.mobile.page.prototype.options.keepNative = ".data-role-none, .data-role-none *";
});

TODOに今のとこ同じだからprototypeで定義するよ!的なこと書いてあるのでまた変更されるかもしれませんが、、、


 

jQueryMobile(1.0b2)でフォーカスの装飾が残る問題がありました。
inputがページ上部にあると発生することがあります。

 

ソース解析したので原因まとめてみます。

フォーカスの装飾はcssのclass「ui-focus」で定義されています。
そしてfocusイベントでaddClass、blurイベントでremoveClassされます。
読み込み時にfocusさせclassが追加されますが実際にはfocusがちゃんとあたっていません。
そのため別の場所にfocusが移動してもblurイベントが起きずclassが残るようです。
jQueryMobileのバグともブラウザの仕様の問題とも解釈できる内容ですね。

 
1.0rc1では解消されていました。(もっと以前に解消されてるかも)
可能であればjQueryMobileのバージョンをあげてしまうのが手っ取り早いと思います。

既に公開中だとバージョンあげるのも怖いので対応方法を。
まずは該当部分の抜粋。

1.0b2

#2144行目
//define first selector to receive focus when a page is shown
focusable = "[tabindex],a,button:visible,select:visible,input",

#2192行目
//direct focus to the page title, or otherwise first focusable element
function reFocus( page ) {
    var lastClicked = page.jqmData( "lastClicked" );

    if( lastClicked && lastClicked.length ) {
        lastClicked.focus();
    }
    else {
        var pageTitle = page.find( ".ui-title:eq(0)" );

        if( pageTitle.length ) {
            pageTitle.focus();
        }
        else{
            page.find( focusable ).eq( 0 ).focus();
        }
    }
}

 

1.0rc1

#2223行目
//define first selector to receive focus when a page is shown
focusable = "[tabindex],a,button:visible,select:visible,input",

#2282行目
//direct focus to the page title, or otherwise first focusable element
function reFocus( page ) {
	var pageTitle = page.find( ".ui-title:eq(0)" );

	if( pageTitle.length ) {
		pageTitle.focus();
	}
	else{
		page.focus();
	}
}


セレクタ「focusable」で最初に見つけたものにフォーカスを当ててます。
これがよろしくないので、1.0rc1と同様に「page.focus();」にすればいいと思います。
ソースを弄るのを避けたい場合、「page.find( focusable ).eq( 0 )」がinputにならないように調整して対応することもできます。

 
1.0rc1でfocusableの定義残ってますがここ以外では使用されていません。消し忘れ?


 

cakephp2.0を試そうと思ったらDB接続にPDOを使っていた。
拡張モジュールpdo_pgsqlを追加したときのメモ。
この環境では複数バージョンのphpをインストールしています。

 

ポイント

  • 追加したいバージョンのphpのphpizeを実行
  • configureのオプション「–with-php-config」で追加するバージョンのphp-configを指定
#インストール時に使用したphpディレクトリ内のpdo_pgsqlに移動
#残ってなければ再度ダウンロード
cd ~/parts/php-5.3.8/ext/pdo_pgsql

#phpize実行
/usr/local/php-5.3.8/bin/phpize

#「--with-php-config」を指定してconfigure
#「--with-pdo-pgsql」は適宜変更すること
./configure
--with-php-config=/usr/local/php-5.3.8/bin/php-config /
--with-pdo-pgsql=/usr/local/lib/postgresql83

make
sudo make install

 

php.iniを編集してrestart。

sudo vi /usr/local/php-5.3.8/lib/php.ini
===================================
extension_dir = "/usr/local/php-5.3.8/lib/php/extensions/no-debug-non-zts-20090626/"
extension=pdo_pgsql.so
===================================

sudo apachectl restart

#確認(pdo_pgsqlがあればOK)
/usr/local/php-5.3.8/bin/php -m