顯示具有 JavaScript 標籤的文章。 顯示所有文章
顯示具有 JavaScript 標籤的文章。 顯示所有文章

2013年9月12日 星期四

LiveScript do keyword

LiveScript 眾多的語法糖衣中, do 算是被附加最多功能的 keyword . 所以整理一下目前已知的用法備忘。

1. execute

如同 do 字面的意思,就是執行。後面可以跟的是 Function or Array .

do Function

如:

# anonymous function
do ->
  x = 5

# named function
a = ->
  x = 5
do a

# declare named function and execute it
do function f
  x = 5

會產生出

// anonymous function
(function(){
  var x;
  return x = 5;
})();

// named function
var a;
a = function(){
  var x;
  return x = 5;
};
a();

// declare named function and execute it
function f(){
  var x;
  return x = 5;
} f();

由上列可知 do 非常聰明,它能依 anonymous 或是 named Function 決定產生出的 javascript 語法。

而 do 後面跟一個 anonymous 非常方便,很適合使用來將一段程式碼包起來,將變數變成區域變數(local scope variables),好處就是避免變數外漏(expose variables).

do Array

如果 do 後面跟著是 Array , 而 Array 內的元素是可呼叫(callable), 則 do 會執行 Array 內每一個元素。

如:

do [a, b, c]
a(), b(), c();

2. omit parentheses

LiveScript Coding Style 建議我們能省略 parentheses (),就量省略。所以我們可以利用 do 來做到。

implicit object

如:

func do
  a: 1
  b: 2

會產生

func({
  a: 1,
  b: 2
});

list

如:

func do
  a
  b

# 經常使用在 callback, error_callback
func do
  (data) ->
    x = 1
  (err) ->
    x = -1

會產生

func(a, b);

// 經常使用在 callback, error_callback
func(function(data){
  var x;
  return x = 1;
}, function(err){
  var x;
  return x = -1;
});

3. Backcalls

由於 LiveScript backcalls ,省略了內縮,讓 async callback 程式碼較容易閱讀,也因為省略內縮,如果你某段 code 要在 backcall 後執行就無法做到,這時需要利用 do 。

如官方範例:

do
  data <-! $.get 'ajaxtest'
  $ '.result' .html data
  processed <-! $.get 'ajaxprocess', data
  $ '.result' .append processed

alert 'hi'

產生:

$.get('ajaxtest', function(data){
  $('.result').html(data);
  $.get('ajaxprocess', data, function(processed){
    $('.result').append(processed);
  });
});
alert('hi');

4. Do while loop

相容 javascript 的 do-while 迴圈語法

如:

i = 0
do
  i++
while i<5

產生:

i = 0
do
  i++
while i<5

5. code block

沒什麼特別作用,如同你在 javascript 中的 {} . 如:

do
  x = 1
  x = 2

do 
  x = 3

產生:

var x;
x = 1;
x = 2;
x = 3;

Written with StackEdit.

2013年7月15日 星期一

LiveScript - tax-free javascript

由 clkao 在 CUSCOP 2012 介紹的 "LiveScript - tax-free JavaScript" , 我到了 2013 的 HDM 聚會,才經由他介紹才知道,一看真是驚為天人,真是才疏學淺。

對於正在使用 JavaScript 或 CoffeeScript 為解決方案的朋友,可以考慮試試 LiveScript http://livescript.net/ .

由於目前使用者相對於 CoffeeScript 算少,所以很多工具尚很欠缺,請有志青年一起捲起袖子來開發。

目前阿土伯進行的是 LiveScript JetBrains IDEs(IntelliJ , PHPStorm, WebStorm, RubyMine, PyCharm) 的支援。
Source Code hosting 在 Github https://github.com/racklin/livescript-idea .


clkao 精彩的 LiveScript - tax-free Javascript 簡報:

2008年8月18日 星期一

GREUtils 1.1 in trunk

GREUtils 1.1 已經 update 到 http://greutils.googlecode.com/svn/trunk 中, 有興趣參考 Source Code 或使用, 請利用 svn checkout .

GREUtils 是一個 XULRunner / Firefox extensions Javascript Utilities Libraries.
1.0 到 1.1 基本上是全面改寫, GREUtils 1.1 提供以下功能:
  • Object extend function
  • include / include_once specified URL script.
  • XPCOM utilities
  • Charset Convert
  • Preferences Services
  • File IO
  • Dialog utilities (all XPCOM implemented, can use in javascript code modules)
  • Controller and CommandDispatcher? Helper
  • Cryphto Hash Utilities – md5 / sha1 /sha256
  • JSON encode / decode use XPCOM implemented (VERY FASTer then json.org's javascript version)
  • Threading – Native Multi-Threading support
  • JavaScript code modules support

其它改變:
  • GREUtils 1.1 全部改寫了 1.0 的 inline document , 由 ScriptDoc 改成了 jsdoc 格式, 以方便產生出 API Reference.
  • Makefile for linux user , 以方便產生 minified / packed / jsmodues / jsdoc 等 distribution files.
  • singleton support
  • inherits / namespace support (many idea and source from goog javascript libraries).
Project URL: http://code.google.com/p/greutils/

API References: http://greutils.googlecode.com/svn/trunk/jsdoc/index.html

2008年7月4日 星期五

Threading in Firefox 3

Firefox 3 (Gecko 1.9) 新增了許多特色 (詳見 ), 其中一項重要的特色, 便是導入了 Thread Manager 機制.

##CONTINUE##

在 Firefox 3 以前, 我們要讓 Javascript 程式在背景執行, 最簡單的方式便是利用 setTimeout / setInterval 方式:


function backgroundTask() {
// Perform a small amount of work

window.setTimeout(arguments.callee, 100);
}

window.setTimeout(backgroundTask, 100);

以上的方式雖然可以把程式丟到背景執行, 然而, 它依然只是在主執行緒(mainThread)中, 以非同步的方式執行.

Firefox 3 後, 導入了 Thread Manager , 讓我們可以撰寫平台相關的真正多執行緒程式.

要實作多執行緒 Javascript 程式,本身必須是 XPCOM Object, 且實作 nsIRunnable 介面(和 Java Thread 很像不是嗎?).
詳細範例可參考 Thread Manager 和 nsIThreadManager .

Thread Utils:
雖然 Firefox 3 已經大大簡化了多執行緒程式的寫作方式(且很有 Java 風格), 但就 Javascript 來說, 就顯的有些麻煩, 我們要為每一個要執行的程式, 一一實作成 XPCOM Object 也是一件很煩人的事..
阿土伯在 GREUtils Rewriting 計劃中, 為 Threading 做了一些封裝, 讓您可以比較容易且直覺的使用 Firefox 3 所帶來的 Multi-Threading 這份大禮.

有關 Thread 部份的 Code 如下, 已修改過可以獨立運作於 GREUtils 整個專案之外:

/**
* Thread - is simple and easy use Thread Manager APIs libraries for GRE (Gecko Runtime Environment).
* ONLY Work with Firefox 3 or XULRunner 1.9
*
* @public
* @name GREUtils.Thread
* @namespace GREUtils.Thread
*/
var GREUtils = GREUtils || {};

GREUtils.Thread = {

_threadManager: Components.classes["@mozilla.org/thread-manager;1"]
.getService(Components.interfaces.nsIThreadManager),

_mainThread: null,

_workerThread: null,

reportError: function(err){
Components.utils.reportError(err);
}
};


/**
* getThreadManager
*
* @public
* @static
* @function
* @return {Object} nsIThreadManager
*/
GREUtils.Thread.getThreadManager = function(){
return this._threadManager;
};


/**
* getMainThread
*
* @public
* @static
* @function
* @return {Object} nsIThread main thread
*/
GREUtils.Thread.getMainThread = function(){
if (this._mainThread == null) {
this._mainThread = GREUtils.Thread.getThreadManager().mainThread;

// extends magical method to worker thread
// this._workerThread.dispatchMainThread = GREUtils.Thread.dispatchMainThread;
}
return this._mainThread;
};


/**
* dispatchMainThread
*
* @public
* @static
* @function
* @return {Object} nsIThreadManager
* @param {Object} aRunnable
* @param {Object} aType
*/
GREUtils.Thread.dispatchMainThread = function(aRunnable, aType) {
var mainThread = GREUtils.Thread.getMainThread();
var aType = aType || mainThread.DISPATCH_NORMAL;
try {
mainThread.dispatch(aRunnable, aType);
}catch (err) {
GREUtils.Thread.reportError(err);
}
};


/**
* dispatchWorkerThread
*
* @public
* @static
* @function
* @return {Object} nsIThreadManager
* @param {Object} workerThread
* @param {Object} aRunnable
* @param {Object} aType
*/
GREUtils.Thread.dispatchWorkerThread = function(workerThread, aRunnable, aType) {
var aType = aType || workerThread.DISPATCH_NORMAL;
try {
workerThread.dispatch(aRunnable, aType);
}catch (err) {
GREUtils.Thread.reportError(err);
}
};

/**
* getWorkerThread in pool
*
* @public
* @static
* @function
* @return {Object} nsIThread worker thread
*/
GREUtils.Thread.getWorkerThread = function(){
// get presist work thread
// will not create new worker thread
if (this._workerThread == null) {
this._workerThread = GREUtils.Thread.getThreadManager().newThread(0);

// extends magical method to worker thread
// this._workerThread.dispatchMainThread = GREUtils.Thread.dispatchMainThread;
}
return this._workerThread;
};


/**
* createWorkerThread - create new worker thread.
*
* @public
* @static
* @function
* @return {Object} nsIThread worker thread
*/
GREUtils.Thread.createWorkerThread = function(){
// create new worker thread
var worker = GREUtils.Thread.getThreadManager().newThread(0);

// extends magical method to worker thread
//worker.dispatchMainThread = GREUtils.Thread.dispatchMainThread;

return worker;
};


/**
* CallbackRunnableAdapter
*
* @public
* @class
* @param {Object} func
* @param {Object} data
*/
GREUtils.Thread.CallbackRunnableAdapter = function(func, data) {
this._func = func;
this._data = data;
};

GREUtils.Thread.CallbackRunnableAdapter.prototype = {

get func() {
return this._func;
},

set func(func){
this._func = func || null;
},

get data() {
return this._data;
},

set data(data){
this._data = data || null;
},

run: function() {
try {
if (this.func) {
if(this.data) this.func(this.data);
else this.func();
}
} catch (err) {
Components.utils.reportError(err);
}
},

QueryInterface: function(iid) {
if (iid.equals(Components.Interfaces.nsIRunnable) || iid.equals(Components.Interfaces.nsISupports)) {
return this;
}
throw Components.results.NS_ERROR_NO_INTERFACE;
}
};


/**
* WorkerRunnableAdapter
*
* @public
* @class
* @param {Object} func
* @param {Object} callback
* @param {Object} data
*/
GREUtils.Thread.WorkerRunnableAdapter = function(func, callback, data) {
this._func = func;
this._callback = callback;
this._data = data;

if(arguments.length == 2 ) {
this._data = callback;
this._callback = null;
}
};

GREUtils.Thread.WorkerRunnableAdapter.prototype = {

get func() {
return this._func;
},

set func(func){
this._func = func || null;
},

get callback() {
return this._callback;
},

set callback(callback){
this._callback = callback || null;
},

get data() {
return this._data;
},

set data(data){
this._data = data || null;
},

run: function() {
try {
var result = null;
if (this.func) {
if(this.data) result = this.func(this.data);
else result = this.func();
}

if (this.callback) {
GREUtils.Thread.dispatchMainThread(new GREUtils.Thread.CallbackRunnableAdapter(this.callback, result));
}
} catch (err) {
Components.utils.reportError(err);
}

},

QueryInterface: function(iid) {
if (iid.equals(Components.Interfaces.nsIRunnable) || iid.equals(Components.Interfaces.nsISupports)) {
return this;
}
throw Components.results.NS_ERROR_NO_INTERFACE;
}
};


/**
* createWorkerThreadAdapter
*
* @public
* @static
* @function
* @param {Object} workerFunc
* @param {Object} callbackFunc
* @param {Object} data
*/
GREUtils.Thread.createWorkerThreadAdapter = function(workerFunc, callbackFunc, data) {

return new GREUtils.Thread.WorkerRunnableAdapter(workerFunc, callbackFunc, data);
};


使用方式:
利用 GREUtils.Thread.getMainThread() 可以取得主執行緒.
利用 GREUtils.Thread.createWorkerThread() 產生一個新的執行緒.

WorkerThreadAdapter:
則是用以簡化自行撰寫 worker / callback 二個 XPCOM Object, 取而代之的是二個 Function handle 以及要傳入 worker thread 的資料.


var worker = GREUtils.Thread.createWorkerThread();
var execute = GREUtils.Thread.createWorkerThreadAdapter(
/* worker function */
function(data) {
var result = 0;
var i = 0;

while(i <= data) {
result += i;
i++;
}
return result;
},
/* callback function */
function(result) {
alert('sum = ' + result);
},
/* data to worker function */
10000
);

GREUtils.Thread.dispatchWorkerThread(worker, execute);



註1:
Firefox3 的 Thread 由於是以 XPCOM 實作, 所以您只能用於 extension addons 寫作或是 XULRunner 專案中, 如果您需要在一般 Web Application 中使用多執行緒, 可以參考 Google Gears 的 WorkerPool 實作.

註2:
請特別注意 The Thread Manager 那篇的這句重要的警告.
Note: The DOM is not thread safe. You must not access the DOM or user interface from background threads. Doing so will likely crash.
其中要再注意的是, alert() 也是 DOM global scope 哦, 如果您在 background threads 用了 alert(), Firefox 3 也是會當給你看地.


忙裡偷閒寫下本篇, 內容有點雜亂簡單, 但還是希望對大家有幫助.

2008年5月11日 星期日

Processing.js

Processing.js. jQuery 作者 John Resig’s 將 processing.org Java implementation's Processing Language port to JavaScript and Canvas.

而且實測, 在 Firefox 3 執行的很完美, 真是有夠強.

有興趣的可以玩玩 Processing.js 的 Basic Demo.
和 processing.org java 版的 Basic Demo.
只能說..太酷了..

其中有幾樣和 Processing Language 無關的 javascript 實作, 也很值得研究.

  • Types and type casting
  • Classes
  • Method overloading and multiple constructors
  • Inheritance

2008年2月26日 星期二

GRE 開發三: Step by Step 桌面程式快速開發

XULRunner + jQuery + GREUtils = Quick Application Platform.

本篇將利用範例的方式, 一步一步展示如何快速撰寫一個 Windows / Linux / MacOS 上的桌面應用程式, 您會發現利用 XULRunner (Gecko) 寫 Application 是那麼的容易. 這也是前二篇阿土伯專案中選用 XULRunner 而暫時排處 JavaFX 的原因.
基本上和設計 FireFox Extensions 差不多, 但本篇著重在撰寫 standalone application.
##CONTINUE##
XULRunner 安裝:
XULRunner 的官方網址在 http://developer.mozilla.org/en/docs/XULRunner , 而各個 build 好的
binary 可在此 FTP 下載 http://releases.mozilla.org/pub/mozilla.org/xulrunner/releases/1.8.1.3/contrib/
在這邊我們下載 xulrunner-1.8.1.3.en-US.win32-20080128.zip , 然後 解壓到 C:\

下載 GREUtils 範例:
請到 http://code.google.com/p/greutils/ , 下載 helloworld 範例 http://greutils.googlecode.com/files/greutil-helloworld.zip
然後一樣解壓到 C:\

執行 GREUtils 範例:
請開啟 Command Prompt (執行->cmd.exe), 然後鍵入

c:\xulrunner\xulrunner.exe c:\greutil-helloworld\application.ini


執行畫面:
OK~ 您應該可以看到如下的畫面. Linux / MacOS 執行方式及結果應該亦是相同.
應為跨平台亦是 Gecko 的特色之一, 且由於使用 XUL/XHTML/CSS 所以各平台執行結果及承現是一致的.


開發環境:
XULRunner + jQuery + GREUtils 為此範例的主要環境.
XULRunner 開發細節在此不多作解釋, 請見官網文件. 您可以把它想像成 JavaRuntime 之類的環境, Firefox / ThunderBird 便是架構在 XULRunner 之上.

jQuery 我們的老朋友嘍, 所有 javascript 和 XUL/XHTML 的互動, 都是利用它來實現, 也就是您原來在 Web 中所使用的技巧(Ajax/DOM/XHR), 都可以搬到 Application 來用嘍.
這樣您有沒有信心大增, 即使您熟悉的是 Web Programming, 現在不用學 Java / VB / VC .... VX 就可以寫一些(簡單?)的應用程式嘍.

GREUtils 它是阿土伯封裝的一個簡易框架, 讓您可以容易的開發 XULRunner 應用程式.


application.js:
application.js 負責配製 Preferences , Initialize , 期望您在此僅撰寫這二件事, 相關的程式, 請將它寫到 Controller 中.
以下為 initialize 片斷

// init controller
GREUtils.include_once('appController.js', window);
GREUtils.include_once('mainController.js', window);
GREUtils.include_once('charsetController.js', window);
GREUtils.ControllerHelper.appendController(AppController, this);
GREUtils.ControllerHelper.appendController(MainController, this);
GREUtils.ControllerHelper.appendController(CharsetController, this);


xxxController.js:
Controller 提供相關的 action 實作. 由於 GREUtils 封裝了 CommandDispatcher , 所以您只要擴展
GREUtils.ControllerAdapter , 您可以僅實作您的 action commands , 它會自動處理 supportsCommand / isCommandEnabled / doCommand / onEvent 等相關細節.
其中 init 為 Controller initialize function , 它會傳入 Application, 讓您可以在您的 Controller 中處理 Preferences 以及 Application wide function.

jQuery:
您可以在 Controller , 利用 jQuery 處理畫面上的任何元素, 所以相當容易直覺, 就如同您在設計 Web.

charsetCmdConvert1: function() {
jQuery("#charsetList1").each(function(i) {
var cs = this.selectedItem.label;
var input_text = jQuery("#utf8MsgBoxInput").val();
var out = GREUtils.Charset.convertCharset(input_text, 'UTF-8', cs);
jQuery("#utf8MsgBoxoutput").val(out);
});
}


Append DOM Object:
如果您發現您直接利用 jQuery.append 等相關的 DOM 操作, 和您想的不一樣, 別感到驚訝.
因為在 XULRunner 中, XUL 和 HTML 的 Namespace 是不同的.
所以您可以利用 GREUtils.domXULString / GREUtils.domHTMLString 來處理.
如 明確的指定您要加入一個 XUL 的 Label Object:

jQuery("#testContainer").append( GREUtils.domXULString("<label value='test'/>" ));


Debug:
程式執行起來, 會為您 Popup Error Console 供您 Debug, 當然, 您也可以在 AppController.js
中拿掉它... 您更可以自行安裝 FireBug 為您的 Debuger.

其它..:
有關利用 3rd extensions 和提供您的 application add-ons 在下次有機會阿土伯再行解說.
歡迎大家來信/留言討論, 一同成長.

2008年2月25日 星期一

GREUtils 1.0 Release

GREUtils 是一個輔助您在設計 Firefox extensions 或設計 XULRunner 程式的一個工具程式.

  • 封裝了幾個常用的 XPCOM 功能, 讓您可以更方便更直覺的叫用它們.
  • 封裝了 Dialog / Preferences / Sound 等常用 XPCOM.
  • 封裝了 Charset Convert , 您可以利用 Function 進行 charset convert, 如同 php .
  • 亦加入了如同 PHP 的 include / include_once 的特色, 讓您的程式可以更 MVC , 只有在需要的時侯, 引入適當的 javascript 及模組.
  • 封裝了 Controller 和 CommandDispatch , 讓您的程式有一個良好易於寫作的MVC 架構.

今年比較忙, 一直沒有更新 Blog, 包含之前希望提供給大家的 Gecko 開發工具包, 也一直沒有時間整理(阿土伯很早 2007/09 就投到 google code 開放出來了).

還是沒有時間為大家寫完完整的說明及 Sample code, 怕一拖下去沒完沒了,
先放出來讓大家使用, 或請大家幫我寫一下 Sample Code 吧~~ :D

已補上 hello world 的 xulrunne rsample application, 利用了所有 GREUtils 的特性.
您可以把 helloworld application 當成您專案的 blank application 來用.


大家先看 Source code 或 javadoc 理解一下. 希望對您在撰寫 extension / xulrunner 上有幫助.

專案位址: http://code.google.com/p/greutils/

##CONTINUE##

GREUtils is simple and easy use APIs libraries for GRE (Gecko Runtime Environment).

It provides:

  • Object extend function
  • include / include_once specified URL script.
  • XPCOM utilities
  • Charset Convert
  • Preferences Services
  • File IO
  • Dialog utilities
  • Controller and CommandDispatcher? Helper

2007年11月24日 星期六

iGoogle BossKey 暗黑老板鍵小工具

由於 iGoogle 提供的小工具已經非常非常的多元化.. 舉凡股市投資組合, 打電動, 看新聞, 聊天, 看美女圖, 都可以在 iGoogle 中全部搞定... 嘿嘿..
頁面停留在 iGoogle 中, 已不見得是用功好學在努力找資料了... 這時就需要 iGoogle 老板鍵 功能.

這是在 GTDD2007 當天下午分組程式設計時寫的小工具(編號 30), 可能太害羞還是氣氛的關係, 很少人在各組間走動觀摩討論... 所以得票數一票 :( (還是同桌投的..呵呵)
阿土伯把它補完整一點並加上設定、多國語.. 放出來和大家分享..

功能:
  • 隱藏 iGoogle 的畫面
  • 帶入 傳統 Google 搜尋頁面
  • 自動在搜尋欄位中填入設定關鍵字

##CONTINUE##
說明:

暗黑老板鍵小工具說明, 要用情境模式來示範解說.. 大家就了解了.

話說阿土伯上班正努力的用功........... 看盤/看圖/打電動..


這時老板突然走了過來, 看的正精彩,關掉瀏覽器實在太可惜了(等會要重執行).
趕快使用暗黑老板鍵...(F10). 畫面馬上變成:


老板問: 阿土伯你在做什麼...
阿土伯: 報告老板, 我正準備要在 Google 搜尋上查詢有關 google 的相關新聞, 研究 google 的成功模式能不能應用在公司上面.... (呼~~ 要臉不紅氣不喘的回答, 小朋友不要學, 大哥哥是練過的)

OK~~ 大致上軟體就是這麼用的....

設定畫面:



加入您的 iGoogle:
請點取 Add to Google 直接加入您的 iGoogle 中.



原始程式及小工具 URL:
http://racklin.googlepages.com/bosskey.xml

PS.
像這樣的暗黑小工具投到目錄中不知道能不能審核通過..
對不起 kevin, 不小心又弄了一支 html-inline gadget, gtdd2007 當日苦口婆心希望大家寫 html type gadget...

2007年11月13日 星期二

GRE 開發備註二

阿土伯手上專案終於完工了, 並 Release 給客戶以及交付生產線試用了.

看看最後一篇文章, 足足隔了一個多月(手腳變慢了 = =), 各位朋友, 久違了..

近期會整理一下及發表阿土伯在開發 Gecko / XULRunner Application 時, 所開發的一些 Utilities Libraries.

這篇主要介紹及回答為什麼當時阿土伯要用 GRE 而不是 Java RCP(eclipse RCP / netbeans RCP...etc,)

##CONTINUE##

GRE/XULRunner 特色

* Cross Platform -
只要是有 mozilla or firefox 都可以執行您的 Application. 這部份的特色和阿土伯喜愛的 Java 一樣可愛.

* Gecko Rendering Engine -
有了 Gecko Rendering Engine, 可以用大家最熟悉的 HTML 技術來開發富豐的 GUI.
更可以內崁 Flash Object 來開發更炫麗 GUI.
當然, 你要內崁 Java Applet 來開發 GUI 也可以.

* Javascript
使用 Javascript 來開發 Application. 任何您原來在 Web 上開發的技巧都可以直接使用.
再加上豐富大量的 3rd-party Libraries (jQuery / Dojo / YUI) + Firebug 開發效率及入門門檻低.

* XUL / XML / XBL / SOAP
做為 Rich Client Platform , XUL+XBL 配合的讓人讚賞.. 而 XBL 讓您利用 CSS Selector 的方式, 讓 XUL / HTML 可以
binding 到 Content / Properties / Methods / Events / Style .
這部份讓您對於開發 XUL 有很大的彈性.
在部份的應用下, 可以開發類似於 jsp / jsf 的 custom tag .

* XPCOM
透過 XPCOM, 可以讓 javascript 使用原生的方法.
利用 XPCOM 開檔 , 網路連線 , 資料庫操作等.
亦可以自行利用 C++ 或 javascript 實作自己的 XPCOM , 有點像 JNI.


心得
對於一個中/大型的 Application 專案, 建議採用 Java RCP.
對於一個小型的 Application 專案或設計專案 Prototype 時, 這時利用 GRE/XULRunner 是在適合不過的了..
(大專案也行啦.... firefox/thunderbird 就是, 它們可不是小專案呀...)

而且...... 還有一個當初我採用的最大原因....... 懶....
若是利用 Java RCP, 每次換個客戶,換個 UI , 或是加點小功能..工作就會再回到我們手上來...
用了 Gecko.. 現在變成美術設計的事了, 除非 XPCOM / XBL 有問題, 才需要 debug 及維護.
這下子, 原來 "軟體部門" 的專案變成了 "設計部門" 的專案... 這才是太極最高奧義呀~

歡迎大家來信或留言討論...

2007年9月17日 星期一

GRE 開發備註一

整整花了一個星期閉關搞 GRE . 這裡的 GRE 不是指英文的 GRE普通測驗. 而是 Gecko Runtime Environment.

源起:
由於手上一個 CASE 的需求是需要為公司的硬體週邊做一個檢測程式, 而這些週邊含 Serial Port(RS232) / Parallel Port(IEEE 1284) / USB 裝置 / 以及部份數位 TTL信號.
而這些裝置希要提供 Win32 / Linux(趨勢) 上測試通過.
且這支測試程式還有另一個任務, 就是 Open Source C++ 部份的 API 給買裝置回去整合的廠商參考實作.
本來想用 Java + JNI 把它解決掉, 因為要 Release 的廠商多, 每一家要有自己的版本及 Logo, 所以要一家一家改 JForm 有點麻煩, 本來試試 JavaFX 來動態搞, 不熟再加上第二個原因.
廠商的工程師都是使用 C++ , 用 Java+JNI 等於我還是要再寫一份 C++ 的 Sample 給廠商.

最主要的是.....想玩玩 GRE , 於是... 整個架構如下..

XUL/XHTML -> Javascript -> XPConnect -> XPCOM(C++ or Javascript)

##CONTINUE##
所以, 除了最底層的裝置操作用 C++ 實作, 且這部份的 Code 剛好就是要給廠商的 Sample Code.
其它的 GUI 部份及全部的程式流程, 只要在 XUL/XHTML 中寫寫 Javascript , 而 jQuery 部份修改也能操作 XUL ...
所以每個客戶的程式界面要多炫就能有多炫,還可以給個 Flash 單介面和動畫 Splash 呢。

卻被 Win32 平台搞死:
在 Linux 下開發很順利, 整個實作過程和原始概念差不多, 也開發的很愉快..
沒想到原本以為最容易的 Win32 平台, 由於開始想用 GRE 前沒做太多功課, 卻是惡夢的開始.

阿土伯是打算使用 VC++ 2005 express edition 來 make , 怎麼搞就是一堆 error.
後來看到 Windows Build Prerequisites 差點昏倒, 原來 Gecko 1.8 在 VC++ 2005 express 是 NO .. 問題剩下最後一哩路了, 總不改用 "原版A拷 VC6 / VC7.1" 呀~~
查了很多, 日本人寫的這篇還算詳細, 雖然整個 mozilla 還是無法 build 出來, 但 extensions 及 sdk 都還沒問題. 給使用 VC++ 2005 express 的大家參考.


建議參考資料:
XULRunner - 一個可以單獨運作的 gecko 開發包, 如果沒有一定要 embed gecko , 由這個開始會很舒服.
XPCOMViewer - 一個用來 Browse XPCOM 的工具, 您可以看到 Gecko 中一大堆實用的 XPCOM Interface.
XPCOM Strings / XPCOM Array / XPCOM Hashtable - 這也是讓阿土伯最無力的文件之一, 資料有點老舊, 如果你是直接使用 Gecko-SDK 而不是由 seamonkey-src 來 build 你的專案, 你會發現文件中說的 class 在 SDK 中都不存在, 因為 frozen / unfrozen API 的關係. 建議直接花時間看看 SDK 中的 .h 看看有什麼 Class 比較快.
這部份等結案後再來整理...

總之... 忙到爆... 但希望這個工做完.. 以後就能涼到爆....
因為, 不管什麼程式, 都只剩下 XUL/XHTML + Javascript 了.. 這部份要怎麼改都行.

2007年8月27日 星期一

AOP for jQuery

就在寫 jQuery 1.1.4 那篇介紹文的同時, 逛了一下 jQuery plugins , 看到了一個很有意思的專案.
jQuery AOP , 看起來是一個新的專案,作者於 2007/08/17 上傳第一個 release 檔案.

aspect-oriented programming (AOP) 在 Java 中有幾個流行的 AOP 實作, AspectJ , AspectWerkz 和 JBossAOP, 所以有關 AOP 的介紹, 請看上面四個 Link, 不在此重覆說明.

而 jQuery AOP 則是實作了 before / after / around 三個 advice, 雖然名為 jQuery AOP, 其實並未使用到 jQuery 的任何特性及功能, 所以即使您沒有使用 jQuery , 依然可以小改一下 code 來使用哦, 所以一定要堆的啦.

##CONTINUE##
我們可以很容易的利用 javascript 的 Function.apply() 來 hook function 或 object(Blogger Hack Tip#1) , 所以實作起來相當的輕巧, 只有 943 bytes.

舉一個實例:
任何程式語言, 在程式寫作過程中, 我們少不了要 Log , 然而 Log 的動作和程式本身實際的業務邏輯無關, 若是為每一個業務操作的 function / method 前後都加上 Logger.log('message'), 對於程式本身而言.. 太過於難看(bad smell).
所以這時我們可以藉由 Dynamic proxy 或 AOP framework 來改善這個 bad smell.

使用 jQuery AOP 在 javascript 中使用 after / before / around advices 變的很簡單:

例1 對 native object 切入:

jQuery.aop.before( {target: String, method: 'replace'},
function(regex, newString) {
alert("About to replace string '" + this + "' with '" + newString + "' using regEx '" + regex + "'");
}
);
"Hello World".replace("Hello", "Hello jQuery");


例2 對 global function 切入:

function testEcho ( arg) {
alert('testEcho: ' + arg);
}
jQuery.aop.before( {target: window, method: 'testEcho'},
function(arg) {
alert("About to testEcho arguments is " + arg);
}
);


例3 對 instance object 切入:

var TestObj = function (name) {
this.name = name;
};
TestObj.prototype.hello = function (arg) {
alert(this.name + ':' + arg);
};
var rack = new TestObj('rack');
jQuery.aop.before( {target: rack, method: 'hello'},
function(arg) {
alert("before "+ this.name +" say " + arg);
}
);
rack.hello('hello');


其它各位依此類堆.... 有了 jQuery AOP , javascript 也能寫的很優雅嘍.
(都已經 Hook Blogger了, 之前怎麼沒想到順便弄一個 plugin , 唉~~ sense 不足.. 被搶頭香了 :D )

jQuery 1.1.4 Release

jQuery 1.1.4 出來了 , 這將會是 1.1 系列的最後一版, 下一版本會跳到 1.2 了.
雖然被 jaceju 的 [JavaScript] jQuery 推出 1.1.4 版 搶了頭香 :D ,
阿土伯還是介紹一下, 並以一些比較技術部份簡介一下.
##CONTINUE##

Speed Improvements


在三個基本常用的操作上, ID selectors, tag name selectors, 和 each() 迴圈處理上, 速度有大幅的提昇.

Any Name jQuery


jQuery 在前面的版本, 只使用了二個 global variables , 就是 $ 和 jQuery, 現在 1.1.4 後, 您可以將這二個變數也換掉, 並和其它 3rd party 的 Library 整合,果如他在 Google 的演說一樣, (阿土伯這篇有介紹), 這版就加入了, 它帶來了二個好處:

1. 你可以在同一網頁使用不同版本的 jQuery:
這個功能, 或許猛一看, 你會認為為什麼有這樣的需求??
然而, 如果您的 Library 是運用在其它大量 3rd party library 的場合, 這個功能將會是很大的相容性保證.
如:
1. 阿土伯的 Blogger-Ext 它會運用在 blogspot.com 上的, 然而很多網誌作者已自行擴充了很多功能, 也可能使用其它版本的 jQuery, 這時這個功能將能保證不會有相容性問題.

2. 使用 Firefox 的使用者一定知道 Firefox 有很多的 extensions 可以使用, 包含 Greasemonkey 等, extensions 作者可能用到了 jQuery 來設計 js , 如果這時網頁也使用 jQuery, 這時這個功能將保證不會和網頁有相容問題.
2. 您可以將 jQuery 整合進其它 Namespace 中:
同上, 你更能將 jQuery 整進你 Library 的一部份, 一同發表, 這時, 您可以維護一份您自己使用的版本, 即使網頁作者換了別的版本 jQuery, 你的程式也不會發生相容性的問題.

也就是未來版本的 BloggerExt , 阿土伯可以將它整進 BloggerExt.jQuery 或 BloggerExt.$ , 這樣 BloggerExt 將對任何網誌有最大的相容性以及最低的侵入性.

jQuery 在設計之初, 就有良好的設計模式以及未擴充任何 Native Objects , 這時就派上很大的用途.

// With the Dojo Toolkit
dojo.jquery = jQuery.noConflict(true);
dojo.jquery("#elem div").slideDown("slow");
// or with Yahoo UI
YAHOO.query = jQuery.noConflict(true);
YAHOO.query("span.hidden").removeClass("hidden");


.slice()


對於 jQuery 的 objects , 我們可以使用如同標準 Javascript arrays slice() function.
這個 Function 太優了, 它讓 jQuery 操作和 Javascript Array 有一致的操作介面.
所以, 理所當然的 .eq() , .lt() , .gt() 就被捨棄掉了. 因為可以用 .slice() 取代它.

Bug Fixes


53 個 1.1.3.1 版本的問題修正, 詳見 the bug tracker , 相當多的修正, 希望不會太快出現 1.1.4.1 :q

Local Variables:

一樣同他在 Google Tech Talk 上建議的良好習慣, 這版 1.1.4 便是將自己放在

(function(){
// your code
})();

中.

Blogger-ext2 使用方式


所以有使用 Blogger-ext2 的朋友, 只要將

<script type="text/javascript" src="http://blogger-ext2.googlecode.com/files/jquery-1.1.4.pack.js"></script>

即可完成 jQuery 的昇級動作..

2007年8月24日 星期五

John Resig 談 Building a JavaScript Library

( 的發起人) 在 Google Tech Talk 談如何建立一個 JavaScript Library:Building a JavaScript Library,包含影片及投影片。

對於每一位有心學好 Javascript 的 Programmer 都該花點時間看一下, 除了介紹 jQuery 外,包含很多設計 Javascript Library 的實用技巧及觀念, 即使您不是使用 jQuery 也該看一看.
##CONTINUE##
阿土伯對於實作(Implementaion)上的實務技巧簡單筆記:

  • 使用 Local variables / 盡可能使用最少的 Global Variables
    這部份是所有語言都共通的良好習慣, 讓您的程式碼及變數, 作用在最小的 Scope 中.
    或盡可能宣告最少的 Global Variables.
    在 Javascipt 中這個 Wrapper 寫法, 應當成基本程式習慣, 尤其是如果您的 javascript 會和其它大量的 javascript 一起運作時, (如阿土伯寫在 iGoogle 的 html-inline gadget ):

    (function(){
    // your code
    })();

    或

    (function(){
    // your code
    }).call(this);


    (參考: Blogger Hack Tip #2 - Javascript Code Style)
  • Namespacing
    如果一定要讓自己的 Library 使用到 Global Variables 時, 請使用 Namespace.
    如:(Dojo, Yahoo UI, jQuery, BloggerExt)
  • 利用 Namespace 和其它 Library 相容並存或合作.
    這是 Namespacing 的擴展應用, 當您的 Library 僅作用在單一 Namespace 時, 您可以將自己的 Library 掛在別的 Library 下. 如 BloggerExt.proccess(); YamUtils.BloggerExt.proccess();
  • Don't Extend Native Objects
    其中, 這點和阿土伯的理念一拍即合, 也是我在 2007/02 之後的所有專案換到 jQuery 的原因. ( 參考: jQuery: 又一個非常優秀的 JavaScript Framework. )
上述 John Resig 所說的技巧, 也都全部應用在新版本的 jQuery 1.1.4, 請參考這篇 中, 有興趣的朋友可以看看 jQuery source code.

2007年8月23日 星期四

ifunP 推推王點播台 / 推文貼紙 支援 funP.com alpha4 嘍

就在 funP 展開了 alpha4 改版的夏日傳說 , 在 2007.08.22 上線嘍!!
由於 Alpha4 的改版, 阿土伯愛放屁(ifunP)放不出來了..
以及推推王 堆文貼紙加強版 變的不好看(高度不夠, 原 55 現在 69)..
所以都一併更版, 讓阿土伯的小工具也有個美好的夏日傳說...

##CONTINUE##
ifunP 點播台更新版本:
您不需要重新安裝, 由於 iGoogle 會 cache , 應該在 1 - 2 天或更短的時間內即可使用到最新的版本.
當然, 若您等不及, 請先將小工具移除, reload Browser , 再加入一次小工具應該就能直接用到更新的版本.

ifunP 點播台 功能介紹及說明

funP 推文貼紙:
您不需要改版任何語法, 已利用原檔案覆蓋更新..
若您是自行下載至其它位置, 請您再下載回去.
推推王 推文按鈕貼紙 加強版介紹及說明

2007年8月14日 星期二

blogger_ext2.js 0.6.3 / 0.7.2 修正版發表


0.6.3 / 0.7.2 修正版本發表:
主要是阿土伯將大家列給我的已知問題修正, 沒有新的功能加入:

changelog:
* 較新/舊的文章 換頁到第三次後, 表情符號及繼續閱讀功能失效. (fixed)
* 表情符號效能修正, 若該內容無符號則不處理. (fixed)
* registerHook API 修正 (fixed)
- 使用 Hook API 的 plugin 發生換頁問題, 將一併獲得解決.

##CONTINUE##
0.6.3 版 all-in-one script

<script src='http://blogger-ext2.googlecode.com/files/blogger_ext2-0.6.3.pack.js' type='text/javascript'></script>


0.6.3 版 核心 script

<script src='http://blogger-ext2.googlecode.com/files/blogger_ext2-core-0.6.3.pack.js' type='text/javascript'></script>


0.7.2 版 目前在 svn 中, 所以不用改變. 隨時會引用到最新版本.


表情符號修正版

<script src='http://blogger-ext2.googlecode.com/files/plugin_replace_smiley-0.2.pack.js' type='text/javascript'></script>


詳細使用說明:
0.6 版
0.7 版

讓大家久侯了, Sorry and Thanks.

Technorati Tags: , ,

2007年8月13日 星期一

黑米小按鈕 加強版

利用 HEMiDEMi 官方 javascript 改良了一下, 提供一個以 DOM 操作為主的版本.歡迎官方直接引用.

加強了以下三點:
1. 解決在各 Blog 平台上部份網誌會造成畫面一片白的問題.
2. 一顆/多顆 按鈕語法統一.
3. 支援 Blogger-ext2, 在 Blogger 系統中換頁, 小按鈕依然能生效.
##CONTINUE##
解決畫面一片白:
其實這個問題同 "推推王 推文按鈕貼紙" , 加了 黑米小按鈕 貼紙後, 有時畫面會一片白. [出現空白頁]
這在 Blogger 系統最為明顯, 因為 Blogger 系統的 Sidebar, 換頁都是使用 javascript 動態 產生, 所以只要在 onload 前, 黑米小按鈕的 javascript 執行到, 而黑米小按鈕的 javascript 僅利用 document.write 產生一個 iframe.這時的 document 就僅剩下一個 iframe , 所以您會得到一片白.
請大家忘了 document.write 這個 n 年前的遺產吧.. 以 DOM 來提供小工具.

按鈕語法統一:
使用此一加強版, 不再分一個按鈕或多個按鈕, 您只要使用單一的語法即可. 而語法中也看不到 javascript , 只是一個 div 的語法, 您可以輕輕鬆鬆放入 黑米小按鈕.

使用方式:
放在網頁 <head> 位置加入 或 加入 html/javascript 網頁元素:
程式碼:

<script src='http://blogger-ext2.googlecode.com/svn/trunk/3rd/hemidemi_bookmark_button2.js' ></script>


放在按鈕位置的
程式碼:

<div class="hemi_button" style="font-size:0px;">網址</div>

如果不打就直接用貼紙所在頁面的網址.

就是這麼容易, 不管幾顆都是一樣.


如何在 Blogger 系統中使用:
1.範本 => 版面配置 => 修改 HTML => 勾選「展開小裝置範本」 => 在 </head> 前加入

<script src='http://blogger-ext2.googlecode.com/svn/trunk/3rd/hemidemi_bookmark_button2.js' ></script>

2. 找到 <p><data:post.body/><p> 在 <p><data:post.body/><p> 前加入按鈕語法

<div style='float:right; margin-left:10px; font-size:0px;' class="hemi_button"><data:post.url/></div>


如何在天空(yam) 系統中使用:
1.管理者後台 => 功能設定 => 個人資料 => 部落格描述: 中填入

<script src='http://blogger-ext2.googlecode.com/svn/trunk/3rd/hemidemi_bookmark_button2.js' ></script>

2. 在發表網址時, 在 "追加內容" 加入按鈕語法

<div style='float:right; margin-left:10px; font-size:0px;' class="hemi_button"></div>

3. sample.

詳細參數及使用說明可參考 [功能] 黑米小按鈕

PS. 推推王推文按鈕也是存在相同的問題. 請看這裡.

ifunP 推推王點播台 可直接推文嘍

在修改 推推王 推文按鈕貼紙 加強版 之餘, 順便把阿土伯考慮很久的 ifunP 點播台 加上了直接推文功能. 現在大家可以直接在 iGoogle 中利用 ifunP 點播台小工具直接推文嘍.

ifunP 點播台 功能介紹及說明.

希望大家會喜歡.
##CONTINUE##
有圖有真相:



PS. 考慮原因我在 這裡 有 唸到, 我是覺得大家還是要連回 funP 原始網站, 支持原網站才對.
怕加了直接推文會影響 funP 的流量.. 那就不是阿土伯的本意了..
後來想想, 應該影響不大, 大部份的人不會看到 "標題" 就 "推" 下去的, 還是會連回去看才對.

推推王 推文按鈕貼紙 加強版

利用推推王官方 javascript 改良了一下, 提供一個以 DOM 操作為主的版本.歡迎官方直接引用.

加強了以下二點:
1. 解決在各 Blog 平台上部份網誌會造成畫面一片白的問題.
2. 一顆/多顆 按鈕語法統一.
3. 支援 Blogger-ext2, 在 Blogger 系統中換頁, 小按鈕依然能生效.

##CONTINUE##
解決畫面一片白:
由於已有許多網友反應, 加了 推推王 推文按鈕貼紙 後, 有時畫面會一片白.
在Blogger加入推推王按鈕導致不明反白的解法 , 問題2, 問題3
這在 Blogger 系統最為明顯, 因為 Blogger 系統的 Sidebar, 換頁都是使用 javascript 動態 產生, 所以只要在 onload 前, 推推王的 javascript 執行到, 而推推王的 javascript 僅有三行, 也就是利用 document.write 產生一個 iframe.這時的 document 就僅剩下一個 iframe , 所以您會得到一片白.
請大家忘了 document.write 這個 n 年前的遺產吧.. 以 DOM 來提供小工具.

按鈕語法統一:
使用此一加強版, 不再分一個按鈕或多個按鈕, 您只要使用單一的語法即可. 而語法中也看不到 javascript , 只是一個 div 的語法, 您可以輕輕鬆鬆放入 推推王推文按鈕.

使用方式:
放在網頁 <head> 位置加入 或 加入 html/javascript 網頁元素:
程式碼:

<script src='http://blogger-ext2.googlecode.com/svn/trunk/3rd/funp_button2.js' ></script>


放在按鈕位置的
程式碼:

<div class="funp_button" style="font-size:0px;">網址</div>

如果不打就直接用貼紙所在頁面的網址.

就是這麼容易, 不管幾顆都是一樣.


如何在 Blogger 系統中使用:
1.範本 => 版面配置 => 修改 HTML => 勾選「展開小裝置範本」 => 在 </head> 前加入

<script src='http://blogger-ext2.googlecode.com/svn/trunk/3rd/funp_button2.js' ></script>

2. 找到 <p><data:post.body/><p> 在 <p><data:post.body/><p> 前加入按鈕語法

<div style='float:right; margin-left:10px; font-size:0px;' class="funp_button"><data:post.url/></div>

style 說明可參考 funP Button On Blogger

如何在天空(yam) 系統中使用:
1.管理者後台 => 功能設定 => 個人資料 => 部落格描述: 中填入

<script src='http://blogger-ext2.googlecode.com/svn/trunk/3rd/funp_button2.js' ></script>

2. 在發表網址時, 在 "追加內容" 加入按鈕語法

<div style='float:right; margin-left:10px; font-size:0px;' class="funp_button"></div>

3. sample.


PS. 黑米小按鈕也是存在相同的問題. 請看這篇留.

2007年8月8日 星期三

iGoogle Easy Layout 更新~

由於 iGoogle Render Html 於 2007/08/08 做小改版, 導致原 EasyLayout 無法作用, 阿土伯已於第一時間配合改版, 已能相容目前的 iGoogle 了.

阿土伯已上傳更新版本, 所以您無需重裝小工具, 然而由於 iGoogle 會 Cache 小工具, 所以請您耐心等侯, 小工具會於 Cache 失效時, 自動套用新版本.

使用說明, 請見 EasyLayout 簡介.

PS. iGoogle 會對此一部份改版, 是否意味著, 未來 iGoogle 將內建調整欄位的功能.. 樂見其成 :D
PS2. 出現了 c_4 又意味著有四欄的配置?
##CONTINUE##
技術部份:
原 iGoogle Render Html Layout: 所以 EasyLayout 僅需覆寫 CSS Style 重定義 c_1, c_2, c_3 即可.

<div id="c_1" class="yui-u" style="display: block;">
<div id="c_2" class="yui-u" style="display: block;">
<div id="c_3" class="yui-u" style="display: block;">

新 iGoogle Render Html Layout: c_1,c_2,c_3 width 強制出現在 HTML 中, 又取代了 EasyLayout CSS Style , 所以輔以 DOM 方式設定屬性.

<div id="c_1" class="yui-u" style="width: 32%; display: block;">
<div id="c_2" class="yui-u" style="width: 32%; display: block;">
<div id="c_3" class="yui-u" style="width: 32%; display: block;">

2007年7月27日 星期五

iGoogle funP 推推王點播台 小工具

親愛的, 我把 iGoogle 變成 funP 推推王了, 是瘋狂還是有趣....

寫了一個 iGoogle 的 funP 推推王小工具.
小工具的名稱就叫 ifunP 吧... (愛放屁?) :D
它提供了類似 funPaper 點播台的功能, 您可以利用 ifunP 快速的瀏覽推推王上的資訊, 以及被推的次數.
除此之外, 由於我是使用 TabRSS 為核心, 所以, 您可以自行新增訂閱 RSS 到 ifunP.
這下真的和 funP 點播台有點異曲同工之妙了.... :)

當然, 請搭配 EasyLayout 使用, 然後加上天氣, Flickr 相簿小工具, 讓您的版面配置和 funP 推推王很相似唷.

功能:
  • 提供 funP 點播台功能.
  • 可自行新增項目.
  • 可以直接於 iGoogle 中推文. (new)

讓您用 iGoogle 更方便更好用...
##CONTINUE##
小工具畫面:


很像 funP ? 有圖有真相:


原始 funP:


加入您的 iGoogle:
請點取 Add to Google 直接加入您的 iGoogle 中.





原始程式:
http://racklin.googlepages.com/ifunp.xml

L10n:
http://racklin.googlepages.com/ifunp_tw.xml

Technorati Tags: , , ,