<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>O3noBLOG</title>
<link>http://blog.othree.net/</link>
<description></description>
<copyright>Copyright 2010</copyright>
<lastBuildDate>2010-02-28 21:14</lastBuildDate>
<generator>http://www.movabletype.org/?v=4.3-en</generator>
<docs>http://blogs.law.harvard.edu/tech/rss</docs> 


<item>
<title>vimrc 的 onload</title>
<description><![CDATA[<p>vimrc 會比任何 plugin 都還要先執行，所以如果有什麼工作是想要在 plugin 讀完後才做的，就不能直接寫在 vimrc 裡面，以我的例子，我想要在某些 plugin 有安裝，該 plugin 的命令確實存在的話，才去另外做這些命令的 mapping ，例如：</p>



<pre><code>if exists(&quot;:Align&quot;)
    com! -bang -range -nargs=* A &lt;line1&gt;,&lt;line2&gt;call Align#Align(&lt;bang&gt;0,&lt;q-args&gt;)
endif</code></pre>



<p>這段程式直接放在 vimrc 裡面的話， if 判斷都不會成立，所以我的作法是丟到 function 裡面，然後放到 <a href="http://vimdoc.sourceforge.net/htmldoc/autocmd.html#VimEnter">VimEnter</a> 這個 auto command 的事件執行：</p>



<pre><code>function AfterStart ()

&quot; plugin commands
if exists(&quot;:Align&quot;)
    com! -bang -range -nargs=* A &lt;line1&gt;,&lt;line2&gt;call Align#Align(&lt;bang&gt;0,&lt;q-args&gt;)
endif

endfunction
autocmd VimEnter * :call AfterStart()
</code></pre>]]></description>
<link>http://blog.othree.net/log/2010/02/28/vimrc-onload/</link>
<guid>http://blog.othree.net/log/2010/02/28/vimrc-onload/</guid>
<category>vim</category>
<pubDate>2010-02-28 21:14</pubDate>
</item>

<item>
<title>jQuery() in 1.4 </title>
<description><![CDATA[<p><a href="http://www.jquery.com">jQuery 1.4</a> 有個改變應該很少有人注意到，我也是最近剛好有需求才發現，就是直接執行 jQuery 不傳任何參數：</p>



<pre><code>jQuery();</code></pre>



<p>結果會傳回一個 <a href="http://api.jquery.com/jQuery/#returning-empty-set">空的 jQuery set</a> ，不過這在 1.4 以前的版本會傳回 <a href="http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-core.html#i-Document">document</a> ，這樣的修改我覺得是比較好的，因為以前完全沒辦法產生空的 jQuery set，如果要自己做 jQuery set 會比較方便，除了把要的 <span class="caps">DOM </span>節點抓好放陣列丟給 jQuery 外還多了個建立空的 jQuery set 後一個一個把要的節點丟進去的方法，另一個優點是這樣確保 jQuery function 傳回來的物件是同樣的類型。</p>]]></description>
<link>http://blog.othree.net/log/2010/02/12/jquery-function-in-14/</link>
<guid>http://blog.othree.net/log/2010/02/12/jquery-function-in-14/</guid>
<category>script</category>
<pubDate>2010-02-12 21:12</pubDate>
</item>

<item>
<title>WAI-ARIA</title>
<description><![CDATA[<p><a href="http://www.w3.org/WAI/intro/aria.php"><span class="caps">WAI</span>-ARIA</a> 全名是 Accessible Rich Internet Applications Suite，是 <a href="http://www.w3.org/WAI/"><span class="caps">WAI</span></a> 正在制定中的規範之一，對象是網路應用程式，像是 gmail、各種 <span class="caps">CMS </span>等，它在WAI 制定的各種規範中，是唯一縮寫名稱用 <span class="caps">WAI</span>- 開頭的，一直很好奇為什麼，前幾天寫信去問也得到了答覆：</p>

<blockquote>Short answer: Because the acronym <span class="caps">ARIA </span>is used for other things, we use <span class="caps">WAI</span>-ARIA.</blockquote>

<p>結果和 J長輩 猜的一樣是因為 <a href="http://www.ariacompany.net/index2.htm">A</a> <a href="http://www.aria-soft.com/">R</a> <a href="http://en.wikipedia.org/wiki/Aria">I</a> <a href="http://www.google.com/search?q=aria">A</a>  太常見了，所以加上 <span class="caps">WAI</span>- 。</p>]]></description>
<link>http://blog.othree.net/log/2010/02/09/wai-aria/</link>
<guid>http://blog.othree.net/log/2010/02/09/wai-aria/</guid>
<category>web</category>
<pubDate>2010-02-09 23:35</pubDate>
</item>

<item>
<title>JavaScript 的一些效率問題</title>
<description><![CDATA[<p>前幾天在測試 <a href="http://api.jquery.com/each/">each</a> 和 for 迴圈的效率時，意外的一直得到 each 效率比較好的奇怪現象，搞了兩天才找到原因。</p>

<p>each 這種方法效率會比 for 迴圈還要低主要是因為它是把要做的事情用 function 傳進去，多了一個 function call 和一層 function scope，要對變數作存取時會多了到不同層 scope 尋找的差，所以理論上它會比 for 迴圈還要慢。除此之外，DOM 本身就很慢了，當然 <a href="http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-536297177"><span class="caps">DOM</span> NodeList</a> 的操作和存取也不會快到哪去，所以像 <a href="http://sizzlejs.com/">Sizzle</a> 引擎就會把 <span class="caps">DOM</span> NodeList 轉成陣列再傳回來，而我測試 each 和 for 兩者的效率時，也就是這個部分產生了非預想的結果，根據測試結果 Google V8 和 Firefox 3.6 的 Tracemonkey 這兩個會編譯 JS 的引擎，第二次對同樣內容的 <span class="caps">DOM </span>collection 轉陣列的動作時會比第一次還要快，而且大約是兩倍快，測試的基準是第一次用 <a href="http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#method-getElementsByTagName">getElementsByTagName</a> 抓 &lt;span&gt; ，第二次用 jQuery，內部也是一樣用 getElementsByTagName ，並且小修改過 <span class="caps">DOM </span>結構後再做一樣的事情也是會比第一次還快，並且，不管是用 <a href="https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Array/Slice">slice</a> 還是 for 迴圈一個元素一個元素推到陣列裡面都沒差很多，一開始因為測試都是對同樣的標籤作處理，結果先測的方法就佔了劣勢，就像是美食漫畫一樣，先上菜的都會輸一樣，不過我對編譯器的怎樣做最佳化的方法不熟，所以這兩個引擎是怎麼辦到的就不清楚了。</p>

<p>除了這點之外，還有一些不算小發現的小發現，第一個就是 Firefox 3.6 還是好慢，詳細數據我忘了，不過和 V8、Safari 比起來差距還是不小，然後就是 IE 超．級．慢！！第二是 each 真的比較慢，不過在現在 JS 引擎普遍暴力的情況下差距其實不明顯（不過 NodeList 和陣列的差距還是有）。第三是前面已經講過的 Sizzle 回傳的是陣列而不是 NodeList ，雖然實際上想要自己組合 NodeList 似乎也是不可能的。最後是 jQeury 可以用 <code>$(&quot;span&quot;)[0]</code> 這種寫法來直接存取 <span class="caps">DOM </span>節點，不過它並不是陣列，要轉成純陣列可以用 <code>$(&quot;span&quot;).get()</code> ，只是測試過後發現沒有比較快，因為還要重新轉一次陣列，這裡損失的時間也不會比直接存取來的少。</p>]]></description>
<link>http://blog.othree.net/log/2010/01/25/javascript-performance-tips/</link>
<guid>http://blog.othree.net/log/2010/01/25/javascript-performance-tips/</guid>
<category>script</category>
<pubDate>2010-01-25 18:56</pubDate>
</item>

<item>
<title>為什麼有  這個標籤</title>
<description><![CDATA[<p><a href="http://diveintomark.org/">dive into mark</a> 在去年11月有一篇文章 <a href="http://diveintomark.org/archives/2009/11/02/why-do-we-have-an-img-element">Why do we have an <span class="caps">IMG </span>element?</a> ，裡面翻出了很多當初 <span class="caps">HTML </span>剛起步時的討論，當時就在針對網頁上的媒體內容要怎樣放進去作了不少爭論，過程有興趣的可以自己去看，結果還是先下手為強，先做出來的贏， mark 歸納出的幾點結論中有一點蠻有趣的：「HTML一直都是瀏覽器製造者、標準制定者、網頁製造者和其他想參與其中的人所討論而得的，而多數成功的標準都是 <strong>retro-specs</strong> （實作、制定標準同時，甚至先實作），有些人認為標準應該保持純潔，不要受到瀏覽器製造者或網頁製造者的影響，這完全是錯誤的。」HTML 5 也是一個 retro-specs ，新功能都是跟著網路的變化所產生，像是 <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd">拖拉 <span class="caps">API</span></a>  、 <a href="http://dev.w3.org/html5/webstorage/">近端儲存系統</a> 等，最近還多了 <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/commands.html#devices">device 標籤</a> 和 <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/commands.html#stream">stream <span class="caps">API</span></a> ，這些都是現在大家需要的功能，而目前只能用其他方法弄起來，像是拖拉要去算位置、範圍，近端儲存要裝像 Google Gears 的外掛，要抓 webcam 畫面或是撥影片則要用 Flash 或是 Java，未來這些功能都會變成瀏覽器原生支援，甚至用顯示卡 <a href="http://www.khronos.org/webgl/">加速畫 3D 圖形</a> 都不是問題。</p>

<p>另外可以拿來作反例的我覺得是 <a href="http://www.w3.org/XML/Schema"><span class="caps">XML</span> Schema</a> ，整個複雜過頭，還有難解的用詞，據之前修課時的老師說是語言學家制定的，結果造成沒有工具很難寫，就算寫了沒驗證過我看也不敢拿來用。</p>]]></description>
<link>http://blog.othree.net/log/2010/01/17/why-do-we-have-an-img-element/</link>
<guid>http://blog.othree.net/log/2010/01/17/why-do-we-have-an-img-element/</guid>
<category>css-html</category>
<pubDate>2010-01-17 09:29</pubDate>
</item>

<item>
<title>Perl Style RegExp for Vim</title>
<description><![CDATA[<p>今天下午在尋找能讓 Vim 的 Regular Expression 變得好看一點的方法，因為實在太多斜線了，當然直接就把目標鎖定在 perl 的語法，一開始找到一個 <a href="http://vim.wikia.com/wiki/Perl_compatible_regular_expressions">vim tip</a> 有建議用 <a href="http://vimdoc.sourceforge.net/htmldoc/if_perl.html#:perldo">perldo</a> ，不過編譯時要把 <a href="http://vimdoc.sourceforge.net/htmldoc/various.html#+perl">+perl</a> 弄起來，使用上也不是很好用，而且不能搜尋，只能做取代，雖然 <a href="http://tech.groups.yahoo.com/group/vim/message/49561">有人寫了 function</a> 來搜尋，不過實際測試之後離方便使用還有些距離。 <a href="http://c9s.blogspot.com/">c9s</a> 還有建議我用 <a href="http://vimdoc.sourceforge.net/htmldoc/pattern.html#/\v">very magic</a> 看看，結果還是不夠滿意，後來換成找日本那邊，終於找到 <a href="http://www.vector.co.jp/soft/unix/writing/se265654.html">eregex.vim</a> 這個 plugin ，他的作法是把 perl/ruby 的 regexp 語法用 function 轉成 vim 的 regexp 語法，所以問題少很多，預設會把 S（大寫S）替換成用 perl/ruby 的 regexp 語法來搜尋搜尋取代的指令，使用方法和原來 s（小寫S）的都一樣，另外單純搜尋的部分有 :M/ 這個命令，也可以 map 到原來的 / 上：</p>



<pre><code>nnoremap / :M/</code></pre>



<p>使用上就和原來幾乎完全一樣了，超棒的～</p>

<p>順帶一提， <a href="http://www.ubuntu.com/">Ubuntu</a> 上要編譯出 +perl 的功能要 <a href="http://www.tfug.org/pipermail/tfug/2006-May/011262.html">確定一下 libperl.so 在不在</a> ，像我的系統就只有 libperl.so.5.8，還要自己做個鏈結。</p>]]></description>
<link>http://blog.othree.net/log/2010/01/08/perl-style-regexp-for-vim/</link>
<guid>http://blog.othree.net/log/2010/01/08/perl-style-regexp-for-vim/</guid>
<category>vim</category>
<pubDate>2010-01-08 01:41</pubDate>
</item>

<item>
<title>Screen 下 Vim F1~F4 沒辦法正常 map</title>
<description><![CDATA[<p>剛剛遇到的問題，好像是我的環境才會，不過如果有遇到的話就把下面這段 code 加到 vimrc 裡面吧，記得放在 map 前。</p>



<pre><code>&quot; Screen fix
if &amp;term =~ '^screen'
    set t_k1=^[[11~
    set t_k2=^[[12~
    set t_k3=^[[13~
    set t_k4=^[[14~
endif
</code></pre>]]></description>
<link>http://blog.othree.net/log/2010/01/07/screen_vim_f1f4_map/</link>
<guid>http://blog.othree.net/log/2010/01/07/screen_vim_f1f4_map/</guid>
<category>vim</category>
<pubDate>2010-01-07 22:41</pubDate>
</item>

<item>
<title>用 :wq 送出 BBS 文章</title>
<description><![CDATA[<p>因為在 <span class="caps">BBS </span>想要用 :wq 發文章的次數不算少，剛剛就用 expect 弄起來了，只要加一行到 interact 裡面就可以：</p>



<pre><code>\033:wq\r { send \030; send &quot;\r&quot; }</code></pre>



<p>實際操作是要 &lt;ESC&gt; :wq &lt;ENTER&gt; ，會直接把文章發表，如果不想跳過發文前的確認選單，那就把最後的 \r 拿掉。</p>]]></description>
<link>http://blog.othree.net/log/2010/01/07/wq-post-bbs-article/</link>
<guid>http://blog.othree.net/log/2010/01/07/wq-post-bbs-article/</guid>
<category>unix</category>
<pubDate>2010-01-07 20:25</pubDate>
</item>

<item>
<title>在 screen windows 裡開一個比較小的 terminal</title>
<description><![CDATA[<p>這真是超特殊的需求，不過今天還是弄出來了，花不少間走錯方向就是，會有這樣的需求是因為我同時要掛 <span class="caps">BBS </span>和 <span class="caps">IRC</span>，BBS 的標準視窗大小是 80*24，但是這個大小對於 <span class="caps">IRC </span>來說又太小了，好在現在很多 <span class="caps">BBS </span>系統已經已經支援大於 80*24 的終端機了，但是有一個 <a href="http://www.gamer.com.tw/">bahamut</a> 自從商業化後 <span class="caps">BBS </span>系統就完全沒改進，不支援就算了，終端機大小只要不對，看文章往下卷頁時就會有錯誤排版產生，最常見就是按 <strong>下</strong> ，本來應該是整個畫面移動一行，結果會變成只有最後一行被取代，而我現在是使用 100*35 的大小，本來是一直把這問題放著，不過今天總算解決了，其實解法很簡單，就是 screen 裡面再開一個 screen，用不同的設定檔案，裡面要拿來上 bahamut 那個的設定檔加上：</p>



<pre><code>width -d 80 24</code></pre>



<p>重點在那個 <a href="http://www.gnu.org/software/screen/manual/screen.html#Window-Size">-d</a> 參數，本來一直在終端機的設定上跑來跑去，不是說沒辦法改大小，就是內部的終端機改大小會影響到外面的，版面就整個亂掉，不過 -d 是只改 display 的大小，不是終端機大小，本來的話是會所有的 screen 一起改，但是因為用兩層的關係，所以外面的不會受到影響。</p>]]></description>
<link>http://blog.othree.net/log/2010/01/05/_screen_windows_terminal/</link>
<guid>http://blog.othree.net/log/2010/01/05/_screen_windows_terminal/</guid>
<category>unix</category>
<pubDate>2010-01-05 21:18</pubDate>
</item>

<item>
<title>新年快樂</title>
<description><![CDATA[<p><strong>新年快樂！</strong></p>

<p>今年因為腳包著石膏，所以三天假期都沒出門，31號回到家後就等著看 <a href="http://www9.nhk.or.jp/kouhaku/">紅白</a> ，這是我第一次有從一開始就看到啊，話說我每年12/31都會想著明年一定要裝 <a href="http://www.nhk.or.jp/bs/"><span class="caps">BSD</span></a> ，然後一年一年一直過去....，算了，等電視升級時在一起好了。今年紅白有 <a href="http://www.mizukinana.jp/">水樹奈奈</a> 登場，對我來說算是比較有特別意義，到不是特別迷她，而是史上第一位聲優登上紅白，總覺得要見證一下，加上今年是第 60 屆，感覺就是不能錯過～～</p>

<p>話說這三天我竟然沒有很墮落的睡覺看動畫，第一天整理了 irc logs，把部落格內的文章又掃過一次，檢查有沒有圖片連結錯誤，然後重新編譯了我機器上的 <a href="http://www.vim.org/">vim</a> ，之前忘了 patch ，加上沒把 <a href="http://vimdoc.sourceforge.net/htmldoc/various.html#+gettext">gettext</a> 功能弄上，所以介面一直是中文的，另外就是搞定了 <a href="http://www.tcsh.org/Welcome">tcsh</a> 的 Home,、End、PageUp 等案件的功能，因為和 <a href="http://www.gnu.org/software/bash/">bash</a> 用 inputrc 的設定不一樣，一直到這天才找到設定方法， bash 下的 inputrc 是這樣寫：</p>



<pre><code>&quot;\e[1~&quot;: beginning-of-line
&quot;\e[2~&quot;: yank
&quot;\e[3~&quot;: delete-char
&quot;\e[4~&quot;: end-of-line
&quot;\e[5~&quot;: history-search-backward
&quot;\e[6~&quot;: history-search-forward</code></pre>



<p>tcsh 則是寫在 cshrc 裡面：</p>



<pre><code>bindkey &quot;\e[1~&quot; beginning-of-line
bindkey &quot;\e[2~&quot; overwrite-mode
bindkey &quot;\e[3~&quot; delete-char
bindkey &quot;\e[4~&quot; end-of-line
bindkey &quot;\e[5~&quot; history-search-backward
bindkey &quot;\e[6~&quot; history-search-forward</code></pre>



<p>第三天玩的 zsh 也和 tcsh 一樣。</p>

<p>第二天都在看 javascript 的 <a href="http://www.nczonline.net/blog/tag/javascript/">文章</a> 和 <a href="http://www.designfollow.com/javascript/17-hours-of-javascript-from-the-masters/">影片</a> ，其中有一篇 <a href="http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/">Rendering: repaint, reflow/relayout, restyle</a> 蠻不錯的，介紹了 render tree 的概念，是以前沒接觸過的，另外還看了不少 performance 相關的文章，希望 Nicolas 的 <a href="http://www.amazon.com/dp/059680279X">High Performance JavaScript</a> 能快點出。</p>

<p>第三天早上則是弄拖了很久的 <a href="http://jedi.org/p4/Opera/pub/">Opera 三太子</a> Mac 版，因為這部份動力不大所以一直都沒什麼動，不過這次算是蠻有進度的，幾乎大部分的設定都有套上去了，該改的檔案要放哪也大概都確定了，應該過陣子會有個測試版吧，接著因為噗浪上 <a href="http://www.zsh.org/">zsh</a> 正夯，所以我也玩起來了，zsh 是真的厲害不少，自動完成的功能，git 後面的指令也會自動完成，還會列出參考，cd 可以直接切換父層目錄，例如要從 「 <code>xx/2.1/blah/blah/blah</code> 」 跑到 「 <code>xx/2.2/blah/blah/blah</code> 」 只要輸入 cd 2.1 2.2 就可以了，另外我發現他除了 <a href="http://zsh.sourceforge.net/Doc/Release/Parameters.html#IDX248"><span class="caps">PROMPT</span></a> 可以設定外，還有一個 <a href="http://zsh.sourceforge.net/Doc/Release/Parameters.html#IDX264"><span class="caps">RPROMPT</span></a> ，是會放在最右邊的，而且指令打太長時還會自動消失，不過因為在 freebsd 下設定顏色的方法找很久才找到，所以整個幾乎下午剩下的時間都在弄，我的 zsh 現在變這樣了。</p>

<p><a href="http://www.flickr.com/photos/othree/4240326365/" title="Flickr 上 othree 的 zsh"><img src="http://farm3.static.flickr.com/2531/4240326365_3ca467f0c9_o.png" width="498" height="216" alt="zsh" /></a></p>

<p>最後就是今天晚上開始用 <a href="https://github.com/">github</a> 備份我的 <a href="http://github.com/othree/rc">rc 檔</a> 了，現在比較整齊的只有 zshrc 吧XD。</p>

<p>至於動畫，不知道為什麼把 <a href="http://zh.wikipedia.org/wiki/%E5%A4%A7%E9%81%8B%E5%8B%95%E6%9C%83">大運動會</a> <span class="caps">OVA </span>版重看一遍了，其實 TV 版也在重看，只是 <span class="caps">OVA </span>比較好看，TV 最後面太超展開了，所以越看越慢，日本年假期間都沒新動畫啊&gt;&lt;。</p>]]></description>
<link>http://blog.othree.net/log/2010/01/03/happy-2010/</link>
<guid>http://blog.othree.net/log/2010/01/03/happy-2010/</guid>
<category>diary</category>
<pubDate>2010-01-03 22:45</pubDate>
</item>

<item>
<title>簡單的 javascript 自動單元測試</title>
<description><![CDATA[<p>前幾天弄完 <a href="http://github.com/hallettj/jslint.vim"><span class="caps">JSL</span>int.vim</a> 後，就對 server side javascript 產生了一些興趣，還抓了 <a href="http://code.google.com/p/v8/">v8 引擎</a> 來用，於是就想到之前想弄很久的自動單元測試，想說要跑 <a href="http://docs.jquery.com/QUnit">QUnit</a> ，不過 QUnit 雖然獨立於 jQuery 了，但還是要在瀏覽器環境下才能執行，純 javascript engine 還少了 <span class="caps">DOM </span>和 <span class="caps">BOM</span>，就是說它需要 document, window 這些物件，找了一下發現 John Resig 有弄 <a href="http://ejohn.org/blog/bringing-the-browser-to-the-server/">env.js</a> 這個專案，就是要在 js shell 裡面做出瀏覽器的環境，不過問題是目前只能跑在 <a href="http://www.mozilla.org/rhino/">Rhino</a> 下，因為他是 java based ，可以在 javascript 裡面寫 Java ，所以可以做很多壞事，但是其他的 js shell 沒辦法這樣跑， John Resig 好像有想要 port 成 python + v8 的版本，不過不知道有沒有成功，因為也 <a href="http://groups.google.com/group/envjs/browse_thread/thread/132617236878676b#">沒放出</a> 。</p>]]><![CDATA[<p>剛好最近有點紅的 <a href="http://nodejs.org/">node.js</a> ，似乎可以拿來做一樣的事情（要做 http request、開檔案、DOM），於是也調查了一下，結果缺少了重要的 <span class="caps">DOM </span>，這樣也跑不起 Qunit，傷心難過之餘只好把方向改成尋找簡單的 JavaScript Unit Test Framework，希望能找到不會存取到 <span class="caps">BOM </span>和 <span class="caps">DOM </span>的版本，結果找到 <a href="http://github.com/jeresig/env-js/blob/master/test/testrunner.js">這個</a> ，雖然沒完全符合需求，不過裡面要改的地方很少，所以改了一下就拿來用了（還不知道授權所以不敢丟出來），把幾個要用到 jQuery, <span class="caps">DOM </span>的地方註解掉，還有 log 改成有錯誤才輸出，然後 ~/.vimrc 加上：</p>



<pre><code>function Jsunit ()
    let ut = 'unit.test.js'
    let fn = expand('&lt;afile&gt;:t')
    if fn != ut
        let cwd = expand('&lt;afile&gt;:p:h')
        if filereadable(cwd.'/unit.test.js')
            let has_error = 0
            let cmd = 'js '. ut
            let output = system(cmd)
            for error in split(output, &quot;\n&quot;)
                let has_error = 1
                caddexpr expand(&quot;%&quot;) . fn . &quot;:0:0:&quot; . error
            endfor
            if has_error == 1
                copen
            else
                echo 'Unit  : All OK.'
            endif
        endif
    endif
endfunction

autocmd FileWritePost,BufWritePost *.js :call Jsunit()
</code></pre>



<p>存檔的時候會自動找 unit.test.js ，如果存在的話就會執行它，unit.test.js 裡面長得像這樣：</p>



<pre><code>load('testrunner.js');
load('lib.js');

test('all', function () {
    ok(libFunc(true) == 530, 'send true');
    isObj(libFunc(false), {a:'1'}, 'send false');
});
</code></pre>



<p>不過這個 testrunner 不能做任何和 html 文件、瀏覽器有關的測試，只能做很核心部份的測試。</p>]]></description>
<link>http://blog.othree.net/log/2009/12/31/basic-javascript-auto-unit-test/</link>
<guid>http://blog.othree.net/log/2009/12/31/basic-javascript-auto-unit-test/</guid>
<category>vim</category>
<pubDate>2009-12-31 10:18</pubDate>
</item>

<item>
<title>closure-compiler on OSX</title>
<description><![CDATA[<p>Google 的 <a href="http://code.google.com/intl/en/closure/compiler/">Closure Cmpiler</a> 要 Java 1.6 ，蘋果雖然有提供 1.6 的 <a href="http://www.apple.com/downloads/macosx/apple/application_updates/javaformacosx105update1.html">更新</a> ，不過在終端機下直接打 java 還是 1.5 版，至於 1.6 版則是放在</p>



<pre><code>/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Commands/java</code></pre>



<p>如果要跑 closure-compiler 建立shell script 時 java 執行檔要改用這個。</p>]]></description>
<link>http://blog.othree.net/log/2009/12/29/closure-compiler-osx/</link>
<guid>http://blog.othree.net/log/2009/12/29/closure-compiler-osx/</guid>
<category>unix</category>
<pubDate>2009-12-29 23:16</pubDate>
</item>

<item>
<title>var foo = foo || {};</title>
<description><![CDATA[<pre><code>foo = foo || {};</code></pre>



<p>這樣的寫法大家一定不陌生，如果 ab 有值的話就繼續用，不然就讓他成為空物件。通常會用到的地方有兩種，函式設定參數預設值，或是跨檔案的公用函式庫，這種時候會把變數放在 global scope 下，也就是全域變數，要宣告全域變數的話不用 var，直接變數名稱就可以了，就像上面那段 code，不過實際上，這樣寫是會出錯的，沒寫 var 的話，第二個 foo 會跑出 foo 尚未定義的錯誤，所以寫成標題那樣是比較沒問題的，不過有時候，程式碼會全部包在一個 function scope 裡面，避免安全的問題，但是在這個 scope 裡面用 var 宣告變數的話，變數又不會是全域的，這時其實加上 window 就可以了：</p>



<pre><code>(function () {
foo = window.foo || {};
})();</code></pre>



<p>也可以用 if 判斷：</p>



<pre><code>(function () {
if (! window.foo ) { window.foo = {} }
})();</code></pre>



<p>最後我還發現一件趣事，大家可以猜猜看下面的 code 會不會有錯誤：</p>



<pre><code>(function () {
foo = undefined;
foo = foo || {};
})()</code></pre>]]></description>
<link>http://blog.othree.net/log/2009/12/29/foo-eq-foo-or-default/</link>
<guid>http://blog.othree.net/log/2009/12/29/foo-eq-foo-or-default/</guid>
<category>script</category>
<pubDate>2009-12-29 12:42</pubDate>
</item>

<item>
<title>spidermonkey 的 UTF-8 支援</title>
<description><![CDATA[<p><a href="http://www.jslint.com/"><span class="caps">JSL</span>int</a> 其實是用 javascript 寫的 javascript 語法檢查工具， <a href="http://github.com/hallettj/jslint.vim">jslint.vim</a> 並沒有把它轉成 vim script ，而是呼叫 JS 引擎來跑 <span class="caps">JSL</span>int ，最好找的 JS 引擎就是 mozilla 的 <a href="http://www.mozilla.org/js/spidermonkey/">spidermonkey</a> ，很多 linux 有包好的套件，FreeBSD 也有 <a href="http://www.freebsd.org/cgi/cvsweb.cgi/ports/lang/spidermonkey/">port</a> ，不過實際上用的時候發現有個問題，就是不支援 <span class="caps">UTF</span>-8 字串，結果就是在 <span class="caps">JSL</span>int 的字元檢查時會把一些中文當成不安全字元，例如：「下」。</p>

<p>其實要 spidermonkey 支援 <span class="caps">UTF</span>-8 字串也不難，FreeBSD 的話在裝 port 時加個參數就可以了，OSX 的話把 <a href="http://www.macports.org/">MacPorts</a> 更新到新版的再裝就可以了，Linux 的話就沒辦法用套件安裝，要自己抓來編， 1.7 的話要去修改 Makefile 讓 <span class="caps">CFLAGS </span>加上 "-DJS_C_STRINGS_ARE_UTF8" 這個參數，或是參考 <a href="http://www.mongodb.org/display/DOCS/Building+Spider+Monkey">mongoDB</a> 的作法，如果是 1.8 版的話有內建支援，不用修改 makefile，但是以後要執行的 js 檔案裡面都要先呼叫 <a href="https://developer.mozilla.org/En/SpiderMonkey/JSAPI_Reference/JS_CStringsAreUTF8">JS_CStringsAreUTF8</a> 這個函式，以 jslint.vim 來說就要加到 ~/.vim/plugin/jslint/runjslint.js 這個檔案。</p>

<p>其實要解決 <span class="caps">UTF</span>-8 問題還有其他方法，就是換其他的 JS 引擎，像是 <a href="http://code.google.com/p/v8/">Google V8</a> ， 要用 V8 的話 <a href="http://code.google.com/apis/v8/build.html">編譯</a> 時要編 developer shell ，產生的執行檔檔名叫 <strong>d8</strong> ，弄個鏈結讓 <strong>js</strong> 這個指令可以執行就可以了，V8 直接支援 <span class="caps">UTF</span>-8 ，弄起來就可以用了，不用再去改其他東西，理論上速度應該也比較快吧，JSLint 都跑很快，無從比較XD。</p>]]></description>
<link>http://blog.othree.net/log/2009/12/27/spidermonkey-utf-8/</link>
<guid>http://blog.othree.net/log/2009/12/27/spidermonkey-utf-8/</guid>
<category>unix</category>
<pubDate>2009-12-27 16:01</pubDate>
</item>

<item>
<title>javascript on vim</title>
<description><![CDATA[<p>因為現在主要都是在寫 javascript 為主，所以這兩天調整 <a href="http://www.vim.org">Vim</a> 主要目標都是為了 javascript，這篇整理一下使用的 plugin 和相關設定，不過在開始前，請先把 Vim 升級到 7.2，套件沒有的話自己編譯也可以。</p>

<h4>syntax/indent</h4>

<p>Vim 雖然有內建支援 javascript 的縮排和語法標籤，不過另外都有人維護比較完整的版本，而且不只一種，我沒詳細比較，只是挑看起來比較有在維護的：</p>


<ul>
<li><a href="http://www.vim.org/scripts/script.php?script_id=1491">JavaScript syntax : Better JavaScrirpt syntax support</a></li>
<li><a href="http://www.vim.org/scripts/script.php?script_id=1840">Javascript Indentation : Indentation for Javascript</a></li>
</ul>



<p>照說明把檔案放到正確的位置即可，另外雖然有 <a href="http://www.vim.org/scripts/script.php?script_id=2416">jQuery 的 syntax</a> ，不過我安裝後發現會和 <a href="http://www.vim.org/scripts/script.php?script_id=1218">The <span class="caps">NERD</span> Commenter</a> 衝突，而且看一下內容覺得也沒做的很好，就沒用了。縮排的部份也有人是用外部程式來處理，詳細可以 <a href="http://groups.google.com/group/vim-taiwan">vim-taiwan</a> 上的 <a href="http://groups.google.com/group/vim-taiwan/browse_thread/thread/a371c30000e3138e">討論</a> ，我目前是還沒覺得有需求。</p>]]><![CDATA[<h4>自動完成</h4>

<p>這部份就比較麻煩了，在自動完成我使用了 <a href="http://www.vim.org/scripts/script.php?script_id=2540">snipMate</a> （ <a href="http://blog.othree.net/log/2008/03/23/auto-complete-on-vim/">以前</a> 用 <a href="http://www.vim.org/scripts/script.php?script_id=1318">snippetsEmu</a> ，不過都沒更新了，而且內建的 snippets 少很多），還有 <a href="http://www.vim.org/scripts/script.php?script_id=1879">autocomplpop</a> ，兩者安裝都很簡單，就解到 .vim 目錄下，或是用 c9s 大大寫的 <a href="http://github.com/c9s/Vimana">Vimana</a> ，snipMate 別忘了先 <a href="http://groups.google.com/group/vim-taiwan/browse_thread/thread/55c11ab0438dfeb9">hack 一下</a> 讓它支援 autocomplpop ，autocomplpop 雖然新版已經有幫不少檔案格式設定好預設的行為了，包括 html 和 css，但是卻不包含 javascript，所以還要自己設定一下，在 vimrc 裡面加上以下的設定：</p>



<pre><code>let g:acp_enableAtStartup = 1
let g:acp_completeOption = '.,w,b,u,t,i,k'
let g:acp_behaviorSnipmateLength = 1
let g:acp_behaviorKeywordCommand = &quot;\&lt;C-n&gt;&quot;

let jsbehavs = { 'javascript': [] }
    call add(jsbehavs.javascript, {
        \   'command'      : &quot;\&lt;C-x&gt;\&lt;C-u&gt;&quot;,
        \   'completefunc' : 'acp#completeSnipmate',
        \   'meets'        : 'acp#meetsForSnipmate',
        \   'onPopupClose' : 'acp#onPopupCloseSnipmate',
        \   'repeat'       : 0,
    \})
    call add(jsbehavs.javascript, {
        \   'command' : g:acp_behaviorKeywordCommand,
        \   'meets'   : 'acp#meetsForKeyword',
        \   'repeat'  : 0,
        \ })
    call add(jsbehavs.javascript, {
        \    'command'  : &quot;\&lt;C-x&gt;\&lt;C-o&gt;&quot;,
        \    'meets'   : 'acp#meetsForKeyword',
        \    'repeat'   : 0,
    \})

let g:acp_behavior = {}
call extend(g:acp_behavior, jsbehavs, 'keep')
</code></pre>



<p>這樣編輯 javascript 時應該就會做正確的跑出自動完成的候選選項，包括 snipMate、關鍵字自動完成、和 omni 自動完成（好像有翻成全補完的），順便提一下，Vim 7.2 大部分檔案格式不用去設定 omnifunc ，幾乎都會指到自己的預設函式，不過 html 卻沒有，還要自己加下面這行到 vimrc ：</p>



<pre><code>autocmd FileType html set omnifunc=htmlcomplete#CompleteTags</code></pre>



<p>而且最好依照我 <a href="http://blog.othree.net/log/2009/12/25/bug-of-html-complete/">上一篇的建議</a> 修改一下。</p>

<h4>code 檢查</h4>

<p>再來是設定讓 <a href="http://www.jslint.com/">jslint</a> 檢查 javascript 程式碼，用的是 <a href="http://github.com/hallettj/jslint.vim">jslint.vim</a> ，要記得先安裝 <a href="http://www.mozilla.org/js/spidermonkey/">spidermonkey</a> ，然後照說明把檔案移動到 ~/.vim 裡面，這樣就可以執行 :JSLint 來檢查程式碼了，不過一開始一定會發現它對所有的全域變數都發出錯誤訊息，這時可以加上一些設定參數放到 ~/.jslintrc ，我的設定檔內容（其實就是 jslint.vim 提供的範例）：</p>



<pre><code>/*jslint browser: true*/
/*global jQuery $ */
</code></pre>



<p>第一行是說這些 code 是網路用的，用瀏覽器來執行，所以在這種環境下會出現的全域變數就不會被當成錯誤，第二行則是你自己定義會使用到的全域變數，這個範例是加上了 jQuery 的兩個全域變數，這些設定也可以加在 js 檔案裡面，其他的設定參數請看 <a href="http://www.jslint.com/lint.html">官方說明</a> 。不過每次都要執行 :JSLint 也是蠻麻煩的，所以可以設一下快速鍵，另外也可以設定存檔時自動檢查：</p>



<pre><code>map &lt;F12&gt; :JSLintLight&lt;CR&gt;
map &lt;F11&gt; :JSLint&lt;CR&gt;

autocmd FileWritePost,BufWritePost *.js :JSLint</code></pre>



<h4>壓縮</h4>

<p>最後就是壓縮了， <a href="http://blog.othree.net/log/2009/09/08/vim-js-yuicompressor/">以前有寫過個 function</a> ，因應 <a href="http://code.google.com/p/closure-compiler/">closure-compiler</a> 的出現和建議，現在有作些修改：</p>



<pre><code>function Yuic ()
    let cwd = expand('&lt;afile&gt;:p:h')
    let nam = expand('&lt;afile&gt;:t:r')
    let ext = expand('&lt;afile&gt;:e')
    if -1 == match(nam, &quot;[\._]src$&quot;)
        let minfname = nam.&quot;.min.&quot;.ext
    else
        let minfname = substitute(nam, &quot;[\._]src$&quot;, &quot;&quot;, &quot;g&quot;).&quot;.&quot;.ext
    endif
    if filewritable(cwd.'/'.minfname)
        if ext == 'js' &amp;&amp; executable('closure-compiler')
            cal system( 'closure-compiler --js '.cwd.'/'.nam.'.'.ext.' &gt; '.cwd.'/'.minfname.' &amp;')
        elseif executable('yuicompressor')
            cal system( 'yuicompressor '.cwd.'/'.nam.'.'.ext.' &gt; '.cwd.'/'.minfname.' &amp;')
        endif
    endif
endfunction

autocmd FileWritePost,BufWritePost *.js :call Yuic()
autocmd FileWritePost,BufWritePost *.css :call Yuic()
</code></pre>



<p>至於怎麼裝 <a href="http://developer.yahoo.com/yui/compressor/">yuicompressor</a> 和 <a href="http://code.google.com/p/closure-compiler/">closure-compiler</a> 就因系統而異了。</p>

<h4>其他</h4>

<p>其他還有兩個不是針對 javascript 的 plugin ，不過寫程式時蠻有用的，分別是 <a href="http://www.vim.org/scripts/script.php?script_id=1218">The <span class="caps">NERD</span> Commenter</a> 和 <a href="http://www.vim.org/scripts/script.php?script_id=294">Align</a> ，The <span class="caps">NERD</span> Commenter 是快速註解用，Align 則是對齊用，例如一連串的變數初值指定，可以用 :Align = 來把等號左右兩邊的程式碼對齊，美觀不少。</p>]]></description>
<link>http://blog.othree.net/log/2009/12/26/javascript-on-vim/</link>
<guid>http://blog.othree.net/log/2009/12/26/javascript-on-vim/</guid>
<category>vim</category>
<pubDate>2009-12-26 20:10</pubDate>
</item>


</channel>
</rss>