3/31/2007

My javascript addEvent

1 comments

In the end of 2005 several web programming gurus, Peter-Paul Koch (ppk), Dean Edward and Scott Andrew LePera host a "javascript recoding contest" in which they asked participants to submit their code for adding and removing events in javascript. A template page was designed to test the code. The winner was John Resig, whose original code is here. The final code was slightly modified version:

function addEvent( obj, type, fn )
{
if (obj.addEventListener)
obj.addEventListener( type, fn, false );
else if (obj.attachEvent)
{
obj["e"+type+fn] = fn;
obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
obj.attachEvent( "on"+type, obj[type+fn] );
}
}
function removeEvent( obj, type, fn )
{
if (obj.removeEventListener)
obj.removeEventListener( type, fn, false );
else if (obj.detachEvent)
{
obj.detachEvent( "on"+type, obj[type+fn] );
obj[type+fn] = null;
obj["e"+type+fn] = null;
}
}

I personally don't feel comfortable with these code. First of all, as one of the comments mentioned (#2 Posted by Tino Zijdel on 18 October 2005) that in cases of multiple-eventhandlers in IE, the eventhandler added last will be executed first:

... since this is for IE a wrapper around attachEvent, the execution order of the events is different ('random' according to Microsofts documentation, but LIFO in practice against FIFO using the W3C event model)

A simple test reveals this problem:

function init(){
var btn=document.createElement('input')
btn.value = 'Click me'
btn.type = 'button'
document.body.appendChild( btn )
addEvent( btn, "click", function(){alert("#1")} )
addEvent( btn, "click", function(){alert("#2")} )
}

Run the init() function as the onload eventhandler (<body onload="init()">) and load with browser. Firefox alerts "#1" then "#2". But IE alerts "#2" first then "#1", which is not what it should be.

Another part making me uncomfortable is that it uses the entire function content as the key name of a hash:

   obj["e"+type+fn] = fn;
obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }

Although none obvioiusly problem is mentioned or discussed, it could result in extremely long and complex key name, which, IMHO, is not what a hash is supposed to be.

I therefore came up with my own version:

function addEvent( obj, type, fn ) 
{
obj.eventHooks = obj.eventHooks || {} // set .eventHooks for obj if not exists
var evs = obj.eventHooks[type] || [] // set .eventHooks[type] if not exists
obj.eventHooks[type] = evs.concat( fn.concat? fn:[fn]) // this allows for multiple fns added
obj['on'+type] = function (e) // like addEvent(obj,"click",[f1,f2])
{
for (var i=0;i<this.eventHooks[type].length;i++)
{
this.tmp = this.eventHooks[type][i] // attach to the obj such that the this
this.tmp(e) // inside the function points to the obj correctly
this.tmp = undefined
}
}
obj = null
}
function removeEvent( obj, type, fn )
{
if (obj.eventHooks && obj.eventHooks[type])
{
var evs = obj.eventHooks[type]
for (var i=0; i<evs.length;i++)
{
if (evs[i]==fn)
{
obj.eventHooks[type] = evs.slice(0,i).concat(evs.slice(i+1))
break
}
}
}
obj = null
}

Unlike most addEvent inventions, in which either addEventListener or attachEvent is used, the above code simply stores eventhandlers into a buffer that has the following structure:

  obj.eventHooks = { click    : [f1, f2]
, keyup : []
, mouseover: [f3]
....
}

For each event, say, click, a function is assigned to the .onclick. This function carries out the following steps:
  1. Check if obj.eventHooks exists. If not, create one
  2. Check if obj.eventHooks.click exists. If not, create one
  3. Loop through each functions in obj.eventHooks.click
  4. For each function, attaches it to obj as a temporary obj.tmp, then executes obj.tmp(e). This makes sure that any this keyword inside that function point to the obj correctly.
A test page, using the contest template, is here. I am sure that there will be some downside along with this code, but at least at this moment it seems to solve the problems came with the winning code.

3/20/2007

Javascript string replacing function

0 comments

In python there's a very convinient string replacing function that comes with every string. The following example show how it works:

To construct a string:   "firstname:Runsun, lastname:Pan, project:wysiwyc"

firstname='Runsun'
lastname ='Pan'
project ='wysiwyc'
s= 'firstname:<b>%s</b>, lastname:<b>%s</b>, project:<b>%s</b>'%(firstname, lastname, project)

The symbol % attaching to the end of a string is a function to insert a series of strings (firstname, lastname, project) into the original string. This not only makes it easier to read but also easier to type, as compared to:

'firstname:<b>'+ firstname +'</b>, lastname:<b>'+ lastname+ '</b>, project:<b>'+ project + '</b>'

In javascript you don't have that luxury. I came up with a tiny function that does just that:

function ___(s)
{
var ss = arguments[0].split('___')
var out= [ss[0]]
for (var i=1;i<ss.length;i++){
out.push(arguments[i])
out.push(ss[i])
}
return out.join('')
}

So now you can do this:

s= ___('firstname:<b>___</b>, lastname:<b>___</b>, project:<b>___</b>',firstname, lastname, project)

I found that this syntax is actually better than its python cousin, because the symbol "___" implies that there's something to be filled, just like what we used to do when filling up a form with a pen.

It would look even more clear if we attach this "___()" function to the string prototype:

String.prototype._= function()
{

var ss = this.valueOf().split('___')
var out= [ss.shift()]
for (var i=0;i<ss.length;i++){
out.push(arguments[i])
out.push(ss[i])
}
return out.join('')
}

which allows this:

s= 'firstname:<b>___</b>, lastname:<b>___</b>, project:<b>___</b>'._(firstname, lastname, project)

Some other uses of this function:

Example-1:

alert('myArray=[___]'._(myArray))

Example-2:

tag = '<___ style="___">___</___>'
DIV = tag._('div','___','___','div')
SPAN = tag._('span','___','___','span')
adiv = DIV._("border:1px dashed blue; color:blue", "div example")
aspan= SPAN._("color:red;background-color:yellow", "span example")

The 2nd example gives:

div example
span example

Replace with a data in a hash


The above ___() function is already very helpful. But the original python % has one other feature:

data= {'fname':'Runsun'
,'lname':'Pan'
,'proj' :'wysiwyc'}
s= 'firstname:<b>%(fname)s</b>, lastname:<b>%(lname)s</b>, project:<b>%(proj)s</b>'%(data)

By inserting a (fname) into %s, you allow the data be in hash form. Now lets put this feature into the ___() function.

Stand-alone ___() function:

function ___(s)
{
var isObj=false
try {
isObj = arguments[1].constructor.toString().split('(')[0].split(' ')[1]=='Object'
}catch(e) {}

if (isObj)
{
var args = arguments[1]
for (var k in args) { s=s.split( '_'+k+'_').join( args[k] ) }
return s

}else{

var ss = arguments[0].split('___')
var out= [ss[0]]
for (var i=1;i<ss.length;i++){
out.push(arguments[i])
out.push(ss[i])
}
return out.join("")
}
}

Attached to string prototype:

String.prototype._= function()
{
var ss= this.valueOf()
var isObj=false
try {
isObj = arguments[0].constructor.toString().split('(')[0].split(' ')[1]=='Object'
}catch(e) {}

if (isObj)
{
var args = arguments[0]
for (var k in args) { ss=ss.split( '_'+k+'_').join( args[k] ) }
return ss

}else{

var ss = ss.split('___')
var out= [ss.shift()]
for (var i=0;i<ss.length;i++){
out.push(arguments[i])
out.push(ss[i])
}
return out.join("")
}
}

Now we can do this in javascript:

data= {fname:'Runsun'
,lname:'Pan'
,proj :'wysiwyc'}
s= 'firstname:<b>_fname_</b>, lastname:<b>_lname_</b>, project:<b>_proj_</b>'._(data)

Again, IMO, this looks better than its python cousin does.

UPDATE(7/23/07): See a regular expression version of the same function.

3/15/2007

HTML tablizer

0 comments

Introducing a html tablizer -- an online utilite to make simple html table.

The program has an Input Section and Output Section:


Enter your table data in the Input Section and either hit [Submit] button or simply move the cursor away from the input box. Then the resulting table will be shown immediately in the Demonstration in the Output Section. Also, the corresponding HTML code will be displayed in HTML code for copy and paste.

After the HTML code and the demo result are shown, you can modify the HTML code and see the result immediately:



If the resulting table is too wide:



You can hit the button [demo on top] to bring the table up:



Enjoy tablizer here.

3/11/2007

△ Recovering CHK files

0 comments

I have an old One-Touch external hard drive from Maxtor. It went crazy and generated 10,000 FILE????.CHK files about a year ago. My wife and I were worried about that the entire hard drive has gone unstable so we simply gave up using it. Recently I found some spare time trying to search for some tools to recover those CHK files.

RecognizeImageFiles.py


One of the most important file types to recover is our photos. The first step I tried was to find some python script that can recognize image files by file content but not by file extensions. There is indeed such a nice little script imghdr.py in python repository. I modified it a little to have it specifically useful in CHK image file recovery (RecognizeImageFiles).
Screenshot of RecognizeImageFiles.py execution

It was quite successful and about 500 image files were recovered. But then, what about other types of files? I went online to search for third-party tools.

UnCHK and FileCHK


Surprisingly there isn't too many tools online. The most popular tools seem to be UnCHK (by Eric Phelps) and FileCHK (by Martin Kratz). They seem to be neat and useful. However, UnCHK (version UnCHK3) froze at the very beginning:



and FileCHK gave an error that reads:

Runtime error "9":
Subscript out of range

It's possible that they couldn't recognize my One-Touch in drive F. Whatever, they don't work in my case.

MediaHeal


I then found a MediaHeal from officerecovery. The description reads:

Recovers files from corrupted hard disks. Supported are all common file systems, including NTFS, FAT12, VFAT12, FAT16, and FAT32.

I downloaded the MediaHeal for Hard Drives and gave it a try. Unfortunately, this program only aims at the entire hard drives but doesn't allow users to check folder(s):

MediaHeal doesn't allow you to choose a folder (image shrunk to fit screen)

Much worse, it froze at the very beginning on this screen:

The excution of MediaHeal demo version froze at the very beginning
(image shrunk to fit screen)


RecoverMyFiles


Finally, I found RecoverMyFiles from GetData. According to their website, this program allows users to recover deleted files even after the hard disk is reformatted (I didn't even know that it's possible):

Recover deleted files even if emptied from the Recycle Bin
Recover formatted hard drives, even if you have reinstalled Windows!
Recover your files after a hard disk crash
Get back files after a partitioning error
Recover documents, photos, video music and email.
Recover from hard drive, camera card, USB, Zip, floppy disk or other media

and it's able to recover 200 types of files. I downloaded the trial version and was amazed how efficient it was:

The screenshot of RecoverMyFile excution.

It ran smoothly and took less than 4 minutes to complete checking my 250GB One-Touch. You can check the content of each file to decide what file is valuable. Since this is a trial vresion so it doesn't allow real rescuing. But it already impressed me.

Other links


FILExt.com
http://filext.com/detaillist.php?extdetail=chk&Search=Search

Look for info about a file ext
http://shell.windows.com/fileassoc/0409/xml/redir.asp?Ext=jpg

A list of common file extensions
http://safari.oreilly.com/0596002491/winxpnut-APP-F

OfficeRecovery.com (data recovery software for corrupted files)
http://www.officerecovery.com/mediaheal/index.htm

3/02/2007

■ 228 六十週年

0 comments

228 整整六十週年了。就如過去一樣,台灣藍綠雙方政治人物與支持者都有一大堆活動與討論。我們看看六十週年的今年,跟過去有什麼不同。

● 法律制裁


去年此時,我寫了一篇有關於 228 責任追究與法律制裁的文章(註一),裡頭提到:

在二次大戰後的「紐倫堡大審」中,有很多納粹的一級戰犯被審判、定罪並處死。但是,有很多德國納粹軍官化名逃亡而逃過審判。西方社會對這些人的做法是:不管你用什麼方式逃到什麼天涯海角,即使化成灰也要把你抓出來將你定罪。

反觀台灣人對二二八事件的態度,恐怕任何一個西方人也會為之傻眼 ── 在那樣一個「系統性屠殺」之後,竟然到今天沒有任何審判與定罪。不但如此,當初有系統殺害台灣菁英的那些劊子手,不但沒有任何人接受任何法律制裁,而且接承該殘暴法統的外來勢力至今還在繼續掌握、享有社會資源,甚至還能囂張地利用新聞的編造與扭曲唱衰台灣、撕裂台灣。

並批判泛綠政客對 228 法律追究的漠視:

為什麼那麼多泛綠人士對二二八事件的探討中,竟也很少很少看到二二八事件法律責任的追究?陳水扁總統本身還是律師出身,為什麼竟不懂得強調二二八的「法律層面」,而一再地落入泛藍「將二二八政治化」的圈套裡?

一年過去了,也許時機也漸漸成熟了,台灣人似乎已經從「要求道歉賠償」醒過來,開始有了法律追訴的聲音。日前,美國228大屠殺遺族代表在總統府受陳總統接見時提出法律制裁的請求(註二註三):

台灣應設特別法庭審理已故總統蔣介石當年下令鎮壓導致數千名台灣人喪生的悲劇。

「我們不要求血債血償,但希望獲得公平正義的處理」,代表王文宏說道。

家屬團共計提出五點訴求,包括對蔣介石與其他幫兇進行缺席審判、將228事件列入教科書、把「中正紀念堂」更名為「台灣忠烈祠」、撤走看守蔣介石陵寢的警衛兵、以及撤銷每年將蔣介石逝世日當作國定假日的做法。

而這項請求也得到陳總統的正面回應。在新成立的228國家紀念館的揭幕儀式中,陳總統公開指稱蔣中正為 228 的元兇,並承諾政府將對 228 的犯行採取法律追溯(註四):

總統說,過去為了內部團結,政府以撫平傷痛取代責任追究,卻讓228成為有受害者卻沒加害者的無頭公案:『更讓部分政治人物有機會基於政治的需要,任意捏造歪曲歷史,不論是早年將228抹紅成由台共所主導的叛亂事件,到近日所謂「官逼民反」的最新詮釋,本質上都是一樣的,都在掩飾,並淡化當時獨裁統治者打壓民主、迫害人權的國際罪行。』

未來政府將透過責任追究和法律追訴等方式,加速還原歷史真相,因為只有這樣才能進一步尋求真正的寬恕與和解。

另外,在泛綠的『與媒體對抗』網站,一個專門探討 228 法律追溯的討論欄已經進行了好一段時間(註五),可見,國人已經漸漸瞭解,「法律制裁」才是解決 228 爭議的唯一方式。這實在是 228 六十週年最令人欣慰的事。

● 官逼民反


同一個時間,幾週前才因貪污罪被起訴的泛藍明星馬英九,再一次地重複去年他發明的「標籤」,指稱 228 屠殺是 『官逼民反』(註六):

國民黨前主席馬英九昨天重申,二二八事件不是族群衝突,是查緝私煙導致「官逼民反」

我在去年的文章裡,已經強烈批判了馬英九這種言論是在替 228 的元兇脫罪,並污衊在 228 中犧牲的台灣人:

通常,在這種官民對抗的事件上,如果你是站在人民的一邊,你會以「起義」或「革命」來形容該事件。只有站在官方或者「同情官方」的立場,才會說那是「造反」。

很顯然,馬英九雖然表面上將責任歸在官方,看起來好像是站在人民的立場講話,但是,這句話的前提卻是「人民造反」,也就是他其實完全是站在官方的立場來看待二二八。利用這句精巧包裝的政治語言,馬英九在事件的歸屬上,很巧妙地將當年台灣人為了活下去而做的掙扎定了「造反」的罪,而那些為了爭民主而犧牲的台灣人,就這樣被馬英九的陰招鎖成「暴民」。

今年,阿扁總統也在公開場合做了同樣的批判(註七):

陳水扁總統上午反駁表示,將「228事件」定位為所謂的「官逼民反」或「警民衝突」,這是為過去的獨裁者粉飾太平,完全是以施暴者與加害者的史觀來詮釋歷史,這是絕大多數台灣人民不能夠接受與理解的。

顯然,馬英九欲以「官逼民反」將 228 事件定位為「人民造反」的陰謀,已經被國人所識破。

● 日本是 228 元兇?


還有更離譜的事。前幾日中研院幾個院士發表了一篇完全背離歷史事實的文章,指稱日本與美國才是 228 的元凶,企圖將 228 的責任歸屬轉嫁到日本與美國(註八):

中央研究院院士黃彰健、研究員朱宏源、民間史學學者武之璋戚嘉林27日上午聯合發表研究新發現。他們發現,日本人蓄意放棄對糧食配給管制,造成光復後台灣糧食大災難是228事件的原兇;美國人則為自身利益,企圖掌控、佔據台灣,屬於幫兇。228事件,其實是「民逼官反」。


雲林228紀念碑
啊??? 蓄意放棄對糧食配給管制,造成光復後台灣糧食大災難,所以是228事件的原兇?

首先,日本人已經要撤離台灣,已經沒有對台灣的控制權,即使他們沒放棄,也不可能有權力去維持該管制,何來「蓄意放棄」之說?

甚且,「沒有糧食管制」造成糧食大災難而導致 228?228 這種涉及整個社會的屠殺事件的原因複雜,怎可能因為單一的「沒有糧食管制」而死那麼多人?這種荒謬的邏輯,這幾個所謂的大學者竟然說得出口?

最後,殺人不眨眼的大魔頭與中國軍隊屠殺台灣人無罪,「已無權力管制台灣」的日本人反倒成為元兇?

這幾個飽讀「屍書」的學者,試圖利用學者身份替屠殺者粉飾罪惡,真是令人可悲。

可喜的是,這幾個無恥的蛋頭學者昧著良心所羅織的偽證,並沒有得到廣大讀者的支持。在該報導所附的討論區裡,絕大部分讀者的回應是在罵這些學者(註九)。舉幾個例子:

2007-02-27 14:18
systemzero:狗黨拿了多少錢給他們這些老頭捏造假歷史
當時基隆港屠殺 可是國民政府軍隊直接用機槍對岸上無辜人民掃射
此事豈可推給美日兩國!!!
2007-02-27 14:23
juliebarbie:如此「學者」!講痟話!
扯太遠啦!
日本人要離台了,當然要解除糧食管制,讓台灣人吃自己的糧食,難道還要繼續把糧食運往日本。
不過,據了解,終戰(「光復」)後台灣糧食大量運往中國去餵「豬」,支應國共內戰所需。
2007-02-27 15:45
haghland1:我在中研院~我也覺得很奇怪
他們雖然是中研院院士,可是是因為自己的興趣與政治傾向去進行自己的研究,他們憑什麼代表中研院發言呢?就我所知,中研院研究人員跟他們意見相左的人,大有人在,為什麼這些人的聲音不被重視?
而且,拿槍殺人的人沒罪?那請問納粹大屠殺的受害者,是不是要怪當年把希特勒給甩了的女性,才讓希特勒變得有偏激傾向?這些所謂學者,真的是讓自己的意識形態掌控一切了!
2007-02-27 16:52
hongshan:錯了!元兇是蒙古人,幫兇是英國人
按照所謂「中央研究院院士黃彰健、研究員朱宏源、民間史學學者武之璋、戚嘉林」等視野獨到鑽家的邏輯,那我們也可以衍論228元兇是蒙古人,因為元朝時蒙古人渡海東征未果,所以才有後來『日本人蓄意放棄對糧食配給管制』造成228民心動盪。而幫兇當然是英國人,因為他們當年放任北美獨立,所以才有後來的『美國人則為自身利益,企圖掌控、佔據台灣』。
當然,我們也可以按照這個邏輯推論其實元兇是亞當,而幫兇是夏娃。
2007-02-27 17:12
allweiout:是壓是壓/ 幕後大元兇 倒底是誰
一直往前推,全部都有責任,共產黨,滿清,發明槍的人。
繼續愚弄人民壓~幹的好,水喔。記住這些名字!
中央研究院院士黃彰健、研究員朱宏源、民間史學學者武之璋、戚嘉林。

這些回應似乎顯示出:這年頭要以學者之名為中國人在 228 事件中屠殺台灣人的劣跡脫罪的努力,已然不能得逞了。

● 可期待的未來


幾週前,陳總統曾說過,現在距離 2008 總統大選還有一段時間,依照台灣意識的發展速度,到了 2008 選總統投票時,台灣人覺醒的程度,將使得那些「支持統一」的候選人完全沒有機會被選上。日前,國民黨的立法院院長王金平也說過類似的話 (註十):

二00八大選時的外省籍問題,將非常嚴重 ... 台灣族群的主體議意識已經發酵了,看看正名問題發酵了沒?中南部已經強烈反映不會投給外省人了

以最近台灣政府大刀闊斧的正名運動,以及民間將 228 事件由「政治層面」回歸到「法治層面」的舉動,似乎顯示,局勢是在台灣人這邊,2008 總統大選,不管親中的泛藍泛橘泛紅抬出什麼人選,以逆著台灣意識的姿態,要贏得政權恐怕很難了。

● 參考資料



註一:被遺忘的法律制裁
http://aztecpassage.blogspot.com/2006/02/blog-post.html

註二:台灣人籲審判已故總統蔣介石屠殺罪
http://www.anti-media.tw/phpBB/post_468620.html#468620

註三:Taiwanese demand trial of late president Chiang for massacre
http://news.monstersandcritics.com/asiapacific/news/article_1269827.php/Taiwanese_demand_trial_of_late_president_Chiang_for_massacre

註四:扁:轉型正義新階段 追訴元兇
http://news.yam.com/bcc/politics/200702/20070228984357.html

註五:從艾斯曼案(The Eichman Case)來探討228集體大屠殺罪責如何追究
http://www.anti-media.tw/phpBB/topic_15469.html

註六:馬:228事件是官逼民反
http://news.chinatimes.com/2007Cti/2007Cti-News/2007Cti-News-Content/0,4521,110501+112007022500006,00.html

註七:馬稱228「官逼民反」 扁反駁
http://news.yam.com/udn/politics/200702/20070226978869.html

註八:228事件60週年/中研院:日本是元兇 美國是幫兇
http://news.yam.com/ettoday/politics/200702/20070227981228.html

註九:「228事件60週年/中研院:日本是元兇 美國是幫兇」討論區
http://forum.news.yam.com/disingle.php?newsid=20070227981228

註十:王金平:2008大選 外省籍問題將非常嚴重
http://udn.com/NEWS/NATIONAL/NATS5/3744920.shtml