ゼロと無限の間に

フリーでオープンソースなJavaScriptとかPHPとか。

ユーザ用ツール

サイト用ツール


サイドバー

何かありましたら、メールで連絡いただくか、ブログのどこかにコメント入れてくださいね ^_^

Menu

ゼロと無限の間に

はじめに

作った主なサイト

作った主な便利ツール(無料)

ログ (Blog)

javascript:prometheus

Titanium Mobileに神の火を! - Prometheus.js

コメントと更新履歴はPrometheus Archive - ゼロと無限の間のログでどうぞ。

iPhoneアプリもAndroidアプリもJavaScriptで作れてしまうTitanium Mobile。便利なのだがその構成は良くも悪くもきちんと体系だっている。(JavaやYUIを連想させる?)

そこで、もう少しだけ手軽にTitamium Mobileを使えるように、Titaniumをラップするライブラリを作ってみた。その名も、Prometheus.js

ライセンス

MITライセンス

使用例

UIを生成する

全てのUIを、本家Titaniumよりちょっと短いコードで生成できる

// Titaniumの場合
var win = Ti.UI.createWindow();
 
// Prometheus.jsの場合
var win = Pr.window();

UI生成時のパラメータはTitaniumと同様に渡すことができる

var label = Pr.label({text:"ラベルだよ", fontWeight:"bold"});

ラベルとボタンは、パラメータが表示文字列のみなら、それを文字列として渡すことができる

Hashにしない分、ちょっと短くて済む

// Titaniumの場合
var label = Ti.UI.createLabel({text:"ラベルだよ"});
 
// Prometheus.jsの場合
var label = Pr.label("ラベルだよ");

ボタンやダイアログは、第2匹数としてonclickのイベントハンドラーを渡すことができる

// Titaniumの場合
var button = Ti.UI.creatButton({title:"押してみる?"});
button.addEventListener("click", function() { alert("押しちゃったね"); });
 
// Prometheus.jsの場合
var button = Pr.button("押してみる?", function() { alert("押しちゃったね"); });

Viewは第2匹数としてView上に載せるUIを渡すことができる

var view = Pr.view({}, Pr.label("viewに載るよ"));
 
// 複数の場合は配列で渡す
var view = Pr.view({}, [Pr.label("ラベル1"), Pr.label("ラベル2")]);

パラメータの共通の初期値を指定できる

見た目のデザイン等を後から一括して変えたい時に便利

// ラベルは全て太字にする場合
Pr.params.label.fontWeight = "bold";

この後にPrometheus.jsで生成したlabelは全てfontWeightがboldになる

また、いくつかのUIはデフォルトで使いやすいように初期値が設定されている

これらを合わせると、Titaniumに比べてこれぐらいコードが短くなる

// Titaniumの場合
var win = Ti.UI.createWindow({backgroundColor:"#000", layout:"vertical"});
var view = Ti.UI.createView({layout:"horizontal"});
win.add(view);
view.add(Ti.UI.createLabel({text:"ラベル1", fontWeight:"bold"}));
view.add(Ti.UI.createLabel({text:"ラベル2", fontWeight:"bold"}));
var button = Ti.UI.createButton({title:"ボタン"});
button.addEventListener("click", function() {
    Ti.UI.createAlertDialog(message:"こんにちはこんにちは!", buttonNames:["OK"]).show();
});
win.add(button);
 
// Prometheus.jsの場合
var win = Pr.win();
Pr.params.label.fontWeight = "bold";
win.add(Pr.view({}, [Pr.label("ラベル1"), Pr.label("ラベル2")]);
win.add(Pr.button("ボタン", function() {
    pr.alertDialog(message:"こんにちはこんにちは!").show();
}));

DBにアクセスする

ローカルのSQLiteに簡単にアクセスできる
DatabaseやResultsetのclose()もしてくれるので楽ちん

var db = Pr.db("dbName");
 
// テーブル生成(該当のテーブルが既にある場合は無視される)
db.table("people(id INTEGER, name TEXT, email TEXT)");
 
// SELECT(パラメータは、取得列、テーブル名、取得条件、その他)
var rows = db.select("id, name", "people", { name: "Taro", email: "taro@example.com" }, "ORDER BY id");
// 戻り値はResultsetオブジェクトではなく配列なので扱いやすい
for (var i = 0; i < rows; i++) {
    var id = rows[i]["id"];
}
 
// INSERT(パラメータは、テーブル名、登録データ。戻り値は(あれば)連番のキー値)
var id = db.insert("poeple", { id: 1, name: "Taro" });
 
// UPDATE(パラメータは、テーブル名、更新値、更新条件。戻り値は更新レコード数)
var count = db.update("people", { name: "Jiro", email: "jiro@example.com" }, { id: 2, name: "Taro" });
 
// DELETE(パラメータは、テーブル名、削除条件。戻り値は削除レコード数)
var count = db.remove("people", { id: 2, name: "Taro" });
// メソッド名が"delete"でないので注意!
 
// その他のSQLを実行したい場合はTi.Database#execute()と同様に
var results = db.execute(sql, params);
while(rows.isValidRow()){
    var something = rows.field(0);
    // 略
    rows.next();
}
// この場合は勝手にclose()してくれないので注意
results.close();

HTTPで通信する

Ti.Network.createHTTPClientによる一連の処理のショートカット

Pr.http("POST", "http://www.example.com/", {q:"hoge"}, function(json) {
    // サーバからのレスポンスのJSONをHash化したものが渡される
});

JSONにしたくない場合は、第6引数で“TEXT”を指定すればよい

ディスプレイのサイズを取得する

var w = Pr.width();
var h = Pr.height();

ソースコード

Promethus.jsを使いたい場合は(ダウンロードできるファイルを用意してないので)下記のソースコードをコピーして使ってください

/**
 * Prometheus.js - The library for Titanium Mobile
 *
 * @see       http://0-oo.net/sbox/javascript/prometheus
 * @version   0.2.0
 * @copyright 2012 dgbadmin@gmail.com
 * @license   http://0-oo.net/pryn/MIT_license.txt (The MIT license)
 *
 * See also the references of Titanium Mobile
 * @see http://tidocs.com/mobile/latest/
 * @see http://code.google.com/p/titanium-mobile-doc-ja/wiki/toc
 */
 
var Prometheus = {};
var Pr = Prometheus;
 
Ti.UI.setBackgroundColor('#000');
 
 
/*************************************************
 * The wrapper object of Ti.Database
 ************************************************/
/**
 * Get a wrapper of a database
 * @param	String	dbName
 * @return	Object
 */
Pr.db = function(dbName) {
	var wrapper = {dbName:dbName, db:null};
 
	/**
	 * Execute SQL (It is the wrapper of Ti.Database.execute())
	 * @param	String	sql
	 * @param	Object	(Optional) value(s) of place holder(s)
	 * @return	Object	Ti.Database.Resultset or something Ti.Database.execute() returns
	 */
	wrapper.execute = function() {
		if (!this.db) {
			this.db = Ti.Database.open(this.dbName);
			this.db.execute.apply = Function.prototype.apply;
		}
 
		return this.db.execute.apply(this.db, arguments);
	};
	/**
	 * Close the database
	 */
	wrapper.close = function() {
		this.db.close();
		this.db = null;
	};
	/**
	 * Create a table, if it does not exist
	 * @param	String	sql	SQL to create a table
	 */
	wrapper.table = function(sql) {
		this.execute('CREATE TABLE IF NOT EXISTS ' + sql);
		this.close();
	};
	/**
	 * Select columns
	 * @param	String	columns	Columns to select
	 * @param	String	from	Name of a table
	 * @param	Hash	where	(Optional) Conditions to select
	 * @param	String	ohters	(Optional) SQL after WHERE
	 * @return	Array	Results
	 */
	wrapper.select = function(columns, from, where, others) {
		var params = this._where(where || {});
		params[0] = "SELECT " + columns + " FROM " + from + params[0] + " " + (others || "");
		var arr = this.rows2arr(this.execute.apply(this, params));
		this.close();
		return arr;
	};
	/**
	 * Insert a row
	 * @param	String	table	Name of a table
	 * @param	Hash	values	Values to insert
	 * @return	Number	ID of the last inserted row
	 */
	wrapper.insert = function(table, values) {
		var cols = [];
		var vals = [];
		var params = [""];
 
		for (var col in values) {
			cols.push(col);
			vals.push("?");
			params.push(values[col]);
		}
 
		params[0] = "INSERT INTO " + table + "(" + cols.join(",") + ") VALUES(" + vals.join(",") + ")";
		this.execute.apply(this, params);
		var rowId = this.db.lastInsertRowId;
		this.close();
		return rowId;
	};
	/**
	 * Update colulmns
	 * @param	String	table	Name of a table
	 * @param	Hash	set	Values to update
	 * @param	Hash	where	(Optional) Conditions to update
	 * @return	Number	the number of the updated rows
	 */
	wrapper.update = function(table, set, where) {
		var sets = [];
		var params = [""];
 
		for (var col in set) {
			sets.push(col + " = ?");
			params.push(set[col]);
		}
 
		var cond = this._where(where || {});
		params[0] = "UPDATE " + table + " SET " + sets.join(",") + cond.shift();
		this.execute.apply(this, params.concat(cond));
		var affected = this.db.rowsAffected;
		this.close();
		return affected;
	};
	/**
	 * Delete rows
	 * @param	String	table	Name of a table
	 * @param	Hash	where	(Optional) Conditions to delete
	 * @return	Number	The number of the deleted rows
	 */
	wrapper.remove = function(table, where) {
		var params = this._where(where || {});
		params[0] = "DELETE FROM " + table + params[0];
		this.execute.apply(this, params);
		var affected = this.db.rowsAffected;
		this.close();
		return affected;
	};
	/**
	 * Build a SQL of "WHERE"
	 * @param	Hash	hash
	 * @return	Array	SQL and values of placeholders 
	 */
	wrapper._where = function(hash) {
		var sql = [];
		var arr = [""];
 
		for (var key in hash) {
			sql.push(key + " = ?");
			arr.push(hash[key]);
		}
 
		if (sql.length) {
			arr[0] = " WHERE " + sql.join(" AND ");
		}
 
		return arr;
	};
	/**
	 * Convert a Ti.Database.Resultset to an array
	 */
	wrapper.rows2arr = function(rows) {
		var arr = [];
 
		while(rows.isValidRow()){
			var row = {}
 
			for (var i = 0, cnt = rows.fieldCount; i < cnt; i++) {
				row[rows.fieldName(i)] = rows.field(i);
			}
 
			arr.push(row);
		    rows.next();
		}
 
		rows.close();
		return arr;
	};
 
	return wrapper;
};
 
/*************************************************
 * The utility functions
 ************************************************/
/**
 * Send a HTTP request and get a response
 * @param	String	httpMethod	"GET" or "POST"
 * @param	String	url
 * @param	Hash	params
 * @param	Function	onload
 * @param	Function	onerror	(Optioanl)
 * @param	String	format	(Optioanl) "TEXT" or "JSON"(default)
 */
Pr.http = function(httpMethod, url, params, onload, onerror, format) {
	var http = Ti.Network.createHTTPClient({
		onload: function() {
			var res;
 
			switch (format) {
				case "TEXT":
				    res = this.responseText;
				default:
				    res = JSON.parse(this.responseText);
			}
 
			onload(res);
		},
		onerror: onerror || function(error){
			Pr.alertDialog({title:"Error", message:error}).show();
		}
	});
	http.open(httpMethod, url);
	http.send(params || {});
};
/**
 * Get width of the display
 * @return Number
 */
Pr.width = function() {
	return Ti.Platform.displayCaps.platformWidth;
};
/**
 * Get height of the display
 * @return Number
 */
Pr.height = function() {
	return Ti.Platform.displayCaps.platformHeight;
};
/**
 * Merge hashes
 * @param	Hash	data1
 * @param	Hash	data2
 * @return	Hash
 */
Pr.merge = function(data1, data2) {
	var dst = {};
 
	if (data1) {
		for (var i in data1) {
			dst[i] = data1[i];
		}
	}
 
	if (data2) {
		for (var j in data2) {
			dst[j] = data2[j];
		}
	}
 
	return dst;
};
/**
 * Add a click listener
 * @param	Object	obj
 * @param	Function	onclick
 * @return	Object
 */
Pr.clickable = function(obj, onclick) {
	if (onclick) {
		obj.addEventListener("click", onclick);
	}
 
	return obj;
};
 
/*************************************************
 * The default parameters of UIs
 ************************************************/
Pr.params = {
	ui2DMatrix: {},	// With the prefix "ui"
	ui3DMatrix: {},	// With the prefix "ui"
	activityIndicator:{},
	alertDialog:{buttonNames:["OK"]},
	animation:{},
	button:{},
	buttonBar:{},
	coverFlowView:{},
	dashboardItem:{},
	dashboardView:{},
	emailDialog:{},
	imageView:{},
	label:{},
	optionDialog:{},
	picker:{},
	pickerColumn:{},
	pickerRow:{},
	progressBar:{},
	scrollView:{},
	scrollableView:{},
	searchBar:{},
	slider:{},
	uiSwitch:{},	// With the prefix "ui"
	tab:{},
	tabGroup:{},
	tabbedBar:{},
	tableView:{},
	tableViewRow:{},
	tableViewSection:{},
	textArea:{},
	textField:{passwordMask:false},
	toolbar:{},
	view:{layout:"horizontal"},	// "vertical" or "horizontal" or false
	webView:{backgroundColor:"#000"},
	window:{backgroundColor:"#000", layout:"vertical"}
};
 
/*************************************************
 * The creaters of UIs
 ************************************************/
/**
 * Create a 2dMatrix
 * @param	Hash	params
 * @return	Object
 */
Pr.ui2DMatrix = function(params) {
	return Ti.UI.create2DMatrix(Pr.merge(Pr.params.ui2DMatrix, params));
};
/**
 * Create a ui3DMatrix
 * @param	Hash	params
 * @return	Object
 */
Pr.ui3DMatrix = function(params) {
	return Ti.UI.create3DMatrix(Pr.merge(Pr.params.ui3DMatrix, params));
};
/**
 * Create an activityIndicator
 * @param	Hash	params
 * @return	Object
 */
Pr.activityIndicator = function(params) {
	return Ti.UI.createActivityIndicator(Pr.merge(Pr.params.activityIndicator, params));
};
/**
 * Create an alertDialog
 * @param	Hash	params
 * @param	Function	onclick	(Optional)
 * @return	Object
 */
Pr.alertDialog = function(params, onclick) {
	return Pr.clickable(Ti.UI.createAlertDialog(Pr.merge(Pr.params.alertDialog, params)), onclick);
};
/**
 * Create an animation
 * @param	Hash	params
 * @return	Object
 */
Pr.animation = function(params) {
	return Ti.UI.createAnimation(Pr.merge(Pr.params.animation, params));
};
/**
 * Create a button
 * @param	Hash	params
 * @param	Function	onclick	(Optional)
 * @return	Object
 */
Pr.button = function(params, onclick) {
	if (typeof(params) == "string") {
		params = {title:params};
	}
 
	return Pr.clickable(Ti.UI.createButton(Pr.merge(Pr.params.button, params)), onclick);
};
/**
 * Create a buttonBar
 * @param	Hash	params
 * @return	Object
 */
Pr.buttonBar = function(params) {
	return Ti.UI.createButtonBar(Pr.merge(Pr.params.buttonBar, params));
};
/**
 * Create a coverFlowView
 * @param	Hash	params
 * @return	Object
 */
Pr.coverFlowView = function(params) {
	return Ti.UI.createCoverFlowView(Pr.merge(Pr.params.coverFlowView, params));
};
/**
 * Create a dashboardItem
 * @param	Hash	params
 * @return	Object
 */
Pr.dashboardItem = function(params) {
	return Ti.UI.createDashboardItem(Pr.merge(Pr.params.dashboardItem, params));
};
/**
 * Create a dashboardView
 * @param	Hash	params
 * @return	Object
 */
Pr.dashboardView = function(params) {
	return Ti.UI.createDashboardView(Pr.merge(Pr.params.dashboardView, params));
};
/**
 * Create an emailDialog
 * @param	Hash	params
 * @return	Object
 */
Pr.emailDialog = function(params) {
	return Ti.UI.createEmailDialog(Pr.merge(Pr.params.emailDialog, params));
};
/**
 * Create an imageView
 * @param	Hash	params
 * @return	Object
 */
Pr.imageView = function(params) {
	return Ti.UI.createImageView(Pr.merge(Pr.params.imageView, params));
};
/**
 * Create a label
 * @param	Hash	params
 * @return	Object
 */
Pr.label = function(params) {
	if (typeof(params) == "string") {
		params = {text:params};
	}
 
	return Ti.UI.createLabel(Pr.merge(Pr.params.label, params));
};
/**
 * Create a optionDialog
 * @param	Hash	params
 * @param	Function	onclick	(Optional)
 * @return	Object
 */
Pr.optionDialog = function(params, onclick) {
	return Pr.clickable(Ti.UI.createOptionDialog(Pr.merge(Pr.params.optionDialog, params)), onclick);
};
/**
 * Create a picker
 * @param	Hash	params
 * @return	Object
 */
Pr.picker = function(params) {
	return Ti.UI.createPicker(Pr.merge(Pr.params.picker, params));
};
/**
 * Create a pickerColumn
 * @param	Hash	params
 * @return	Object
 */
Pr.pickerColumn = function(params) {
	return Ti.UI.createPickerColumn(Pr.merge(Pr.params.pickerColumn, params));
};
/**
 * Create a pickerRow
 * @param	Hash	params
 * @return	Object
 */
Pr.pickerRow = function(params) {
	return Ti.UI.createPickerRow(Pr.merge(Pr.params.pickerRow, params));
};
/**
 * Create a progressBar
 * @param	Hash	params
 * @return	Object
 */
Pr.progressBar = function(params) {
	return Ti.UI.createProgressBar(Pr.merge(Pr.params.progressBar, params));
};
/**
 * Create a scrollView
 * @param	Hash	params
 * @return	Object
 */
Pr.scrollView = function(params) {
	return Ti.UI.createScrollView(Pr.merge(Pr.params.scrollView, params));
};
/**
 * Create a scrollableView
 * @param	Hash	params
 * @return	Object
 */
Pr.scrollableView = function(params) {
	return Ti.UI.createScrollableView(Pr.merge(Pr.params.scrollableView, params));
};
/**
 * Create a searchBar
 * @param	Hash	params
 * @return	Object
 */
Pr.searchBar = function(params) {
	return Ti.UI.createSearchBar(Pr.merge(Pr.params.searchBar, params));
};
/**
 * Create a slider
 * @param	Hash	params
 * @return	Object
 */
Pr.slider = function(params) {
	return Ti.UI.createSlider(Pr.merge(Pr.params.slider, params));
};
/**
 * Create a uiSwitch
 * @param	Hash	params
 * @return	Object
 */
Pr.uiSwitch = function(params) {
	return Ti.UI.createSwitch(Pr.merge(Pr.params.uiSwitch, params));
};
/**
 * Create a tab
 * @param	Hash	params
 * @return	Object
 */
Pr.tab = function(params) {
	return Ti.UI.createTab(Pr.merge(Pr.params.tab, params));
};
/**
 * Create a tabGroup
 * @param	Hash	params
 * @return	Object
 */
Pr.tabGroup = function(params) {
	return Ti.UI.createTabGroup(Pr.merge(Pr.params.tabGroup, params));
};
/**
 * Create a tabbedBar
 * @param	Hash	params
 * @return	Object
 */
Pr.tabbedBar = function(params) {
	return Ti.UI.createTabbedBar(Pr.merge(Pr.params.tabbedBar, params));
};
/**
 * Create a tableView
 * @param	Hash	params
 * @return	Object
 */
Pr.tableView = function(params) {
	return Ti.UI.createTableView(Pr.merge(Pr.params.tableView, params));
};
/**
 * Create a tableViewRow
 * @param	Hash	params
 * @return	Object
 */
Pr.tableViewRow = function(params) {
	return Ti.UI.createTableViewRow(Pr.merge(Pr.params.tableViewRow, params));
};
/**
 * Create a tableViewSection
 * @param	Hash	params
 * @return	Object
 */
Pr.tableViewSection = function(params) {
	return Ti.UI.createTableViewSection(Pr.merge(Pr.params.tableViewSection, params));
};
/**
 * Create a textArea
 * @param	Hash	params
 * @return	Object
 */
Pr.textArea = function(params) {
	return Ti.UI.createTextArea(Pr.merge(Pr.params.textArea, params));
};
/**
 * Create a textField
 * @param	Hash	params
 * @return	Object
 */
Pr.textField = function(params) {
	return Ti.UI.createTextField(Pr.merge(Pr.params.textField, params));
};
/**
 * Create a toolbar
 * @param	Hash	params
 * @return	Object
 */
Pr.toolbar = function(params) {
	return Ti.UI.createToolbar(Pr.merge(Pr.params.toolbar, params));
};
/**
 * Create a view
 * @param	Hash	params
 * @param	Object or Array	children	(Optional) Children of a webView
 * @return	Object
 */
Pr.view = function(params, children) {
	var view = Ti.UI.createView(Pr.merge(Pr.params.view, params));
 
	if (children) {
		if (children instanceof Array) {
			for (var i = 0; i < children.length; i++) {
				view.add(children[i]);
			}
		} else {
			view.add(children);
		}
	}
 
	return view;
};
/**
 * Create a webView
 * @param	Hash	params
 * @return	Object
 */
Pr.webView = function(params) {
	return Ti.UI.createWebView(Pr.merge(Pr.params.webView, params));
};
/**
 * Create a window
 * @param	Hash	params
 * @return	Object
 */
Pr.window = function(params) {
	return Ti.UI.createWindow(Pr.merge(Pr.params.window, params));
};
javascript/prometheus.txt · 最終更新: 2012/04/16 21:45 by dgbadmin