Search

1/31/2008

Web Bug Track: bug 263 - beware of DoubleClick in IE

Web Bug Track: bug 263 - beware of DoubleClick in IE
double click的event fire順序
mousedown mouseup click mousedown mouseup click doubleclick
IE的順序
mousedown mouseup click mousedown mouseup click doubleclick

1/29/2008

dokuwiki

Sidebar Installation and Configuration Instructions [j:insites]
Zenzire | mmClean
wiki:syntax [DokuWiki]
http://tatewake.com/wiki/projects:monobook_for_dokuwiki
要先安裝 Display Wiki Page for DokuWiki plugin才能顯示navigation bar, edit wiki:navigation即可編輯內容

<?php if (file_exists(DOKU_PLUGIN.'displaywikipage/code.php')) include_once(DOKU_PLUGIN.'displaywikipage/code.php'); ?>

1/27/2008

Efficient JavaScript - Opera Developer Community

Efficient JavaScript - Opera Developer Community
Avoid using eval or the Function constructor

The eval function is especially bad, as the contents of the string passed to eval cannot be known in advance. Since the code is interpreted in the context of the call to eval this means that the compiler cannot optimise the surrounding context, and the browser is left to interpret much of the surrounding code at runtime. This adds an aditional performance impact.

Don't use try-catch-finally inside performance-critical functions
Avoid using global variables
To begin with, if code inside a function or another scope references that variable, the script engine has to step up through each scope in turn until it reaches the global scope. A variable in the local scope will be found more quickly.

Primitive operations can be faster than function calls
A.push('foo');A[A.length] = 'foo'; 來得慢,
因為A.push是一個 function call

Pass functions, not strings, to setTimeout() and setInterval()
The setTimeout() and setInterval() methods are very closely related to eval. If they are passed a string, then after the specified delay, that string will be evaluated in exactly the same way as with eval, including the associated performance impact.

DOM - Repaint and reflow
Repaint - also known as redraw - is what happens whenever something is made visible when it was not previously visible, or vice versa, without altering the layout of the document. An example would be when adding an outline to an element, changing the background color, or changing the visibility style.
A reflow is a more significant change. This will happen whenever the DOM tree is manipulated, whenever a style is changed that affects the layout, whenever the className property of an element is changed, or whenever the browser window size is changed. The engine must then reflow the relevant element to work out where the various parts of it should now be displayed. Its children will also be reflowed to take the new layout of their parent into account. Elements that appear after the element in the DOM will also be reflowed to calculate their new layout, as they may have been moved by the initial reflows. Ancestor elements will also reflow, to account for the changes in size of their children. Finally, everything is repainted.
Reflows are very expensive in terms of performance, and is one of the main causes of slow DOM scripts, especially on devices with low processing power, such as phones. In many cases, they are equivalent to laying out the entire page again.

Taking measurements - since asking for offsetWidth forced the element to reflow in order to answer you question (because it had a pending change to style).
As stated earlier, the browser may cache several changes for you, and reflow only once when those changes have all been made. However, note that taking measurements of the element will force it to reflow, so that the measurements will be correct. The changes may or may not not be visibly repainted, but the reflow itself still has to happen behind the scenes.

This effect is created when measurements are taken using properties like offsetWidth, or using methods like getComputedStyle. Even if the numbers are not used, simply using either of these while the browser is still caching changes, will be enough to trigger the hidden reflow. If these measurements are taken repeatedly, you should consider taking them just once, and storing the result, which can then be used later.

批踢踢實業坊 - 看板 標 題: 十年一覺程設夢

標 題: 十年一覺程設夢 - ASUS EeePC 事業處軟體第 5 部的頭,整篇看起來很像是 CIH 反串,講了蠻多秘辛的。
我對”十年一覺程設夢”的看法
via: 我對”十年一覺程設夢”的看法

1/25/2008

Dia for Windows

Dia for Windows

Dia is a program to draw structured diagrams. This website only provides the Dia for Windows version while the Dia Project Page provides all other information.

Google web history

Google 網頁記錄 - Google is keep tracking of ur every single search and how many times u click sponsors' link.

有了 [網頁記錄] 功能,您將能夠:

* 檢視和管理您的網頁活動。
您曾在網路上看到一個很棒的網站,但現在卻找不到了? 從現在開始,您可以輕鬆找到瀏覽過的網站。 有了 [網頁記錄],您就可以檢視並搜尋您所造訪網頁的全文,包括 Google 搜尋、網頁、圖片、影片和新聞報導。您也可以隨時管理您的網頁活動並將項目從網頁記錄中移除。

* 取得與您最相關的搜尋結果。
[網頁記錄] 可根據您在 Google 上搜尋的內容以及您曾造訪的網站,來協助提供更多個人化搜尋結果。 一開始您也許無法發覺到這對您的搜尋結果有什麼重大影響,但是在您使用 [網頁記錄] 一段時間後,您的搜尋結果就會不斷改進。

* 追蹤您網頁活動中有趣的趨勢。
您經常造訪哪些網站? 您在早上 10 點到下午 2 點之間進行了幾次搜尋? [網頁記錄] 可以提供您這些問題的答案,以及您網頁活動上的有趣趨勢。

1/24/2008

HTML 5

HTML 5
HTML 5 differences from HTML 4
John Resig - HTML5 Shiv
一開始 IE 對不認識的 HTML tags 是沒辦法 style 的


<html>
<head>
<style>blah { color: red; }</style>
</head>
<body>
<blah>Hello!</blah>
</body>
</html>

不過只要小小的一個 document.createElement("blah") 就可以了, 這樣的好處我們可以讓 IE 處理一些無法 recognized 的 HTML tag.

<html>
<head>
<style>blah { color: red; }</style>
<script>document.createElement("blah")</script>
</head>
<body>
<blah>Hello!</blah>
</body>
</html>

New Twist on Date Pickers

Ajaxian » New Twist on Date Pickers
Ajaxorized » Introducing: The sliding date-picker

Demo

1/22/2008

Nifty Corners Cube - freedom to round

Nifty Corners Cube - freedom to round
http://www.html.it/articoli/niftycube/niftycube.js
http://www.html.it/articoli/niftycube/niftyCorners.css
nifty cube layout with same height
Mix two colors:


function rgb2hex(value){
var hex="",v,h,i;
var regexp=/([0-9]+)[, ]+([0-9]+)[, ]+([0-9]+)/;
var h=regexp.exec(value);
for(i=1;i<4;i++){
v=parseInt(h[i]).toString(16);
if(v.length==1) hex+="0"+v;
else hex+=v;
}
return("#"+hex);
}
function Mix(c1,c2){
var i,step1,step2,x,y,r=new Array(3);
if(c1.length==4)step1=1;
else step1=2;
if(c2.length==4) step2=1;
else step2=2;
for(i=0;i<3;i++){
x=parseInt(c1.substr(1+step1*i,step1),16);
if(step1==1) x=16*x+x;
y=parseInt(c2.substr(1+step2*i,step2),16);
if(step2==1) y=16*y+y;
r[i]=Math.floor((x*50+y*50)/100);
r[i]=r[i].toString(16);
if(r[i].length==1) r[i]="0"+r[i];
}
return("#"+r[0]+r[1]+r[2]);
}
// console.log(Mix('#333333', '#ffffff'));
// output: #999999

niftycorner, nifty corner, niftycube, nifty cube

scrolltop & onscroll

IE的onscroll event listener必須在window上,FF則上window/document皆可,所以


YUE.on(window, 'scroll', hScroll);

scrollTop 如果是在 quirk mode 是取 document.body.scrollTop 的值,如果不是 quirk mode 則是取 document.documentElement.scrollTop 的值。
// code from YUI image loader
var scrollTop = (document.compatMode != 'CSS1Compat') ? document.body.scrollTop : document.documentElement.scrollTop;
var scrollLeft = (document.compatMode != 'CSS1Compat') ? document.body.scrollLeft : document.documentElement.scrollLeft;


// code from YUI Dom
/**
* Returns the top scroll value of the document
* @method getDocumentScrollTop
* @param {HTMLDocument} document (optional) The document to get the scroll value of
* @return {Int} The amount that the document is scrolled to the top
*/
getDocumentScrollTop: function(doc) {
doc = doc || document;
return Math.max(doc.documentElement.scrollTop, doc.body.scrollTop);
},

Youtube 右邊的 Related Videos 有一個效果是,使用者捲軸捲下去之後才會開始 loading,也就是他只會 load 看得到的部分,看不到的部分等到 scroll 才 load,藉此節省頻寬,上面是錯的, Youtube 的作法是 onscroll event 一 fire 就會把 Related Videos 裡面的圖片全部 load 進來,不管看不看得到。onscroll 這個 event 居然<PPK on JavaScript> <JavaScript: The Definitive Guide, Fifth Edition> 都沒有提到。同樣的技巧可以透過 Yahoo! UI Library: ImageLoader達成,原理就是 event 發生時動態給 img src。以下是個例子:
http://chunghe.googlecode.com/svn/trunk/experiment/image.lazy.loader.by.scroll/onscroll.event.image.lazyloader.htm

不過只有這樣是不夠的,因為動態生出來的 image 會導致 scroll bar 長度的改變而會有點遲滯,所以我們要先設定 img 的 height & width
http://chunghe.googlecode.com/svn/trunk/experiment/image.lazy.loader.by.scroll/onscroll.event.image.lazyloader.fixed.htm

null & undefined

The undefined value is returned in three cases:
* If you declared a variable but did not assign a value to it.
* If you access an undefined property of an object (and in JavaScript you can see anything you like as a property of an object).
* If you have defined a function argument, but no value is passed to it. (See 5I for arguments.)


0 || 100 // 0
1 || 100 // 1


document.getElementById('nosuchid') // return null
typeof (document.getElementById('nosuchid')) // object, 'cause typeof null == 'obejct'
null||'test' // test

firebug中如果沒有印出任何值,那就是'undefined'
access an undefined property of an object

var foo = {'bar':'bar'};
foo.tttt // nothing happen, it's 'undefined'
foo.bar||'else' // 'bar'

window.ttttt // nothing happen, it's 'undefined'
window.tttt||'else' // 'else'
typeof window.tttt // 'undefined'
typeof window.tttt == 'undefined' //true
typeof window.tttt === 'undefined' //true

declare a variable but not assign value to it:

var tttt;
tttt // nothing happen, it's 'undefined'
alert(tttt) // undefined
typeof tttt // 'undefined'
alert(typeof tttt) // undefined

not declare at all

tttt // error: tttt is not defined
tttt == 'undefined' // error: tttt is not defined
tttt||'test' // error: tttt is not defined
typeof tttt // 'undefined'
typeof tttt == 'undefined' //true
typeof tttt === 'undefined' //true

HttpWatch: An HTTP Viewer and HTTP Sniffer for IE 6 & 7

HttpWatch: An HTTP Viewer and HTTP Sniffer for IE 6 & 7
HttpWatch is an HTTP viewer and debugger that integrates
with Internet Explorer to provide seamless HTTP and HTTPS
monitoring without leaving the browser window.

101 CSS Techniques Of All Time

101 CSS Techniques Of All Time- Part 1

One of the somewhat frustrating properties of CSS is the fact that elements only stretch vertically as far as they need to. So how can we make all columns appear to be the same height? Several techniques was introduced to solve this issue.

* Faux Columns- The simple secret is to use a vertically tiled background image to create the illusion of colored columns.
* Equal Height Columns - revisited- A method to make all columns appear to be the same height but without the need for faux column style background images.

* Equal height boxes with CSS- The trick is to use the CSS properties display:table, display:table-row and display:table-cell to make containers (in this case div elements) behave like table cells.

101 CSS Techniques Of All Time- Part2
47+ Excellent Ajax CSS Forms
Niceforms 1.0 :: badboy.media.design
niceforms

YouTube - Can World's Strongest Dad


Strongest Dad in the World [From Sports Illustrated, By Rick Reilly] Eighty-five times he's pushed his disabled son, Rick, 26.2 miles in marathons. Eight times he's not only pushed him 26.2 miles in a wheelchair but also towed him 2.4 miles in a dinghy while swimming and pedaled him 112 miles in a seat on the handlebars--all in the same day.

1/21/2008


Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Mauris ultrices. Donec feugiat tellus a urna. Etiam ac nibh. Suspendisse euismod, justo et sodales auctor, arcu massa scelerisque metus, a tincidunt neque ante consequat nunc. Donec suscipit nonummy ante. Donec consectetuer. Cras vitae eros non mauris ullamcorper sollicitudin. Aenean sagittis, justo sed pulvinar condimentum, pede enim placerat nulla, et porttitor erat risus a lectus. Nunc vel odio. Pellentesque tristique metus a justo. Aenean ultricies. Etiam sagittis imperdiet urna. Nulla facilisi. Nulla facilisi.

Suspendisse tristique fringilla diam. Proin vel urna. Morbi vitae urna. Aliquam quam. Sed pretium. Curabitur congue odio. Sed condimentum neque eu nisl. Maecenas venenatis. Morbi tristique. Vivamus ut nisl sed magna malesuada scelerisque. Vestibulum non ipsum ac tellus dictum lobortis. Cras eleifend semper magna. Integer in lectus sit amet neque luctus consequat. Morbi sollicitudin ipsum et est.

Aliquam condimentum pharetra massa. Phasellus aliquam. Cras ut purus. Nam eget orci eu neque cursus aliquet. In pede leo, faucibus vitae, lacinia non, porta eget, ipsum. Sed at lectus. Sed risus metus, luctus vel, lacinia sit amet, euismod sed, pede. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus est orci, dictum et, fringilla eget, posuere sit amet, elit. Pellentesque ultrices sem sed tellus. Sed odio lorem, dictum nec, sollicitudin vel, posuere vitae, urna. Cras venenatis. Nullam lacus magna, dignissim sed, iaculis eget, porttitor vel, dui. Aliquam vehicula orci vitae pede. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Praesent rhoncus, justo sit amet mollis blandit, lectus justo dapibus risus, sit amet auctor odio orci eget quam. Mauris blandit convallis massa.

1/20/2008

JavaScript file I/O

http://www.tiddlywiki.com/


function saveFile(fileUrl, content) {
var r = null;
if ((r == null) || (r == false)) r = mozillaSaveFile(fileUrl, content);
if ((r == null) || (r == false)) r = ieSaveFile(fileUrl, content);
if ((r == null) || (r == false)) r = javaSaveFile(fileUrl, content);
return (r);
}
function loadFile(fileUrl) {
var r = null;
if ((r == null) || (r == false)) r = mozillaLoadFile(fileUrl);
if ((r == null) || (r == false)) r = ieLoadFile(fileUrl);
if ((r == null) || (r == false)) r = javaLoadFile(fileUrl);
return (r);
} // Returns null if it can't do it, false if there's an error, true if it saved OK
function ieSaveFile(filePath, content) {
try {
var fso = new ActiveXObject("Scripting.FileSystemObject");
} catch(e) { //alert("Exception while attempting to save\n\n" + e.toString());
return (null);
}
var file = fso.OpenTextFile(filePath, 2, -1, 0);
file.Write(content);
file.Close();
return (true);
} // Returns null if it can't do it, false if there's an error, or a string of the content if successful
function ieLoadFile(filePath) {
try {
var fso = new ActiveXObject("Scripting.FileSystemObject");
var file = fso.OpenTextFile(filePath, 1);
var content = file.ReadAll();
file.Close();
} catch(e) { //alert("Exception while attempting to load\n\n" + e.toString());
return (null);
}
return (content);
} // Returns null if it can't do it, false if there's an error, true if it saved OK
function mozillaSaveFile(filePath, content) {
if (window.Components) try {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
file.initWithPath(filePath);
if (!file.exists()) file.create(0, 0664);
var out = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
out.init(file, 0x20 | 0x02, 00004, null);
out.write(content, content.length);
out.flush();
out.close();
return (true);
} catch(e) { //alert("Exception while attempting to save\n\n" + e);
return (false);
}
return (null);
} // Returns null if it can't do it, false if there's an error, or a string of the content if successful
function mozillaLoadFile(filePath) {
if (window.Components) try {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
file.initWithPath(filePath);
if (!file.exists()) return (null);
var inputStream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
inputStream.init(file, 0x01, 00004, null);
var sInputStream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
sInputStream.init(inputStream);
return (sInputStream.read(sInputStream.available()));
} catch(e) { //alert("Exception while attempting to load\n\n" + e);
return (false);
}
return (null);
}
function javaUrlToFilename(url) {
var f = "//localhost";
if (url.indexOf(f) == 0) return url.substring(f.length);
var i = url.indexOf(":");
if (i & gt; 0) return url.substring(i - 1);
return url;
}
function javaSaveFile(filePath, content) {
try {
if (document.applets["TiddlySaver"]) return document.applets["TiddlySaver"].saveFile(javaUrlToFilename(filePath), "UTF-8", content);
} catch(e) {}
try {
var s = new java.io.PrintStream(new java.io.FileOutputStream(javaUrlToFilename(filePath)));
s.print(content);
s.close();
} catch(e) {
return null;
}
return true;
}
function javaLoadFile(filePath) {
try {
if (document.applets["TiddlySaver"]) return String(document.applets["TiddlySaver"].loadFile(javaUrlToFilename(filePath), "UTF-8"));
} catch(e) {}
var content = [];
try {
var r = new java.io.BufferedReader(new java.io.FileReader(javaUrlToFilename(filePath)));
var line;
while ((lie = r.readLine()) != null) content.push(new String(line));
r.close();
} catch(e) {
return null;
}
return content.join("\n");
} // UTF-8 encoding rules:
// 0x0000 - 0x007F: 0xxxxxxx
// 0x0080 - 0x07FF: 110xxxxx 10xxxxxx
// 0x0800 - 0xFFFF: 1110xxxx 10xxxxxx 10xxxxxx
function convertUTF8ToUnicode(u) {
if (window.netscape == undefined) return manualConvertUTF8ToUnicode(u);
else return mozConvertUTF8ToUnicode(u);
}
function manualConvertUTF8ToUnicode(utf) {
var uni = utf;
var src = 0;
var dst = 0;
var b1, b2, b3;
var c;
while (src & lt; utf.length) {
b1 = utf.charCodeAt(src++);
if (b1 & lt; 0x80) dst++;
else if (b1 & lt; 0xE0) {
b2 = utf.charCodeAt(src++);
c = String.fromCharCode(((b1 & amp; 0x1F) & lt; & lt; 6) | (b2 & amp; 0x3F));
uni = uni.substring(0, dst++).concat(c, utf.substr(src));
} else {
b2 = utf.charCodeAt(src++);
b3 = utf.charCodeAt(src++);
c = String.fromCharCode(((b1 & amp; 0xF) & lt; & lt; 12) | ((b2 & amp; 0x3F) & lt; & lt; 6) | (b3 & amp; 0x3F));
uni = uni.substring(0, dst++).concat(c, utf.substr(src));
}
}
return (uni);
}
function manualConvertUTF8ToUnicode(u) {
try {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
converter.charset = "UTF-8";
} catch(e) {
return manualConvertUTF8ToUnicode(u);
} // fallback
var s = converter.ConvertToUnicode(u);
var fin = converter.Finish();
return (fin.length & gt; 0) ? s + fin: s;
}
function convertUnicodeToUTF8(s) {
if (window.netscape == undefined) return manualConvertUnicodeToUTF8(s);
else return mozConvertUnicodeToUTF8(s);
}
function manualConvertUnicodeToUTF8(s) {
var re = /[^\u0000-\u007F]/g;
return s.replace(re,
function($0) {
return ("&#" + $0.charCodeAt(0).toString() + ";");
})
}
function mozConvertUnicodeToUTF8(s) {
try {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
converter.charset = "UTF-8";
} catch(e) {
return manualConvertUnicodeToUTF8(s);
} // fallback
var u = converter.ConvertFromUnicode(s);
var fin = converter.Finish();
if (fin.length & gt; 0) return u + fin;
else return u;
}

PHP debugger

Tsung's Blog | 大量檢查 PHP 程式是否有 Syntax Error

要檢查 PHP 程式是否有 Syntax Error 的命令, 就是於 command line 使用:

php -l filename.php

註: -l Syntax check only (lint)

Xdebug - Debugger and Profiler Tool for PHP
The Xdebug extension helps you debugging your script by providing a lot of valuable debug information. The debug information that Xdebug can provide includes the following:

* stack traces and function traces in error messages with:
o full parameter display for user defined functions
o function name, file name and line indications
o support for member functions
* memory allocation
* protection for infinite recursions

Xdebug also provides:

* profiling information for PHP scripts
* code coverage analysis
* capabilities to debug your scripts interactively with a debug client

TiddlyWiki

TiddlyWiki - a reusable non-linear personal web notebook
TiddlyWiki Templates
TiddlyWiki - Allwiki

TiddlyWiki是個非常小巧酷炫的wiki引擎,全部程式只是一個一百多K的HTML頁面。TiddlyWiki用CSS+HTML+javascript寫成,可以在多種瀏覽器上瀏覽,而對於使用來說只可以在本地機器上使用,而且只可以Firefox和IE6.0以上的版本搭配WIN_XP_SP_TW的系統上使用。

TiddlyWiki頁面所有元素都能都訂製,能方便地修改頁面結構和CSS表現形式.它不需要任何伺服器端的腳本支持,你要你的電腦有有瀏覽器就能運行.非常適合放在U盤裡到處帶著走的個人做記事本。

Removing the script tags

/<script[^>]*>[\S\s]*?<\/script[^>]*>/ig

[^>] 指的是除了>的任何字元
[\S\s]是所有 unicode 字元的集合

[...] Any one character between the brackets.
[^...] Any one character not between the brackets.
. Any character except newline or another Unicode line terminator.
\w Any ASCII word character. Equivalent to [a-zA-Z0-9_].
\W Any character that is not an ASCII word character. Equivalent to
[^a-zA-Z0-9_].
\s Any Unicode whitespace character.
\S Any character that is not Unicode whitespace. Note that \w and \S are not the
same thing.
\d Any ASCII digit. Equivalent to [0-9].
\D Any character other than an ASCII digit. Equivalent to [^0-9].

Facebook Releases Open Source JavaScript Library

Facebook Releases Open Source JavaScript Library - ReadWriteWeb
FBJS/Animation - Facebook Developers Wiki
Facebook Developers | Facebook Animation

1/18/2008

Understanding CSS z-index

Understanding CSS z-index - MDC - 很詳細的有關 z-index 的文章, z-index絕對不是高的就在上面這麼簡單.

Understanding CSS z-index:Stacking without z-index - MDC

在沒有 z-index 的情況下
1) 分成兩個 group: positioned element (div #1, div #2, div #3, div #4), non-positioned element: (div #5)
2) non-positioned element 先 render, 並且出現在 positioned element的下面
3) render positioned element,先出現在 HTML hierarchy 的在最下面,後出現的往上疊。
Understanding CSS z-index:Stacking and float - MDC

1. Background and borders of the root element
2. Descendant blocks in the normal flow, in order of appearance (in HTML)
3. Floating blocks
4. Descendant positioned elements, in order of appearance (in HTML)
Understanding CSS z-index:The stacking context - MDC

* Positioning and assigning a z-index value to an HTML element creates a stacking context.
* Stacking contexts can be contained in other stacking contexts, and together create a hierarchy of stacking contexts.
* Each stacking context is completly [sic] independent from its siblings: only descendant elements are considered when stacking is processed.
* Each stacking context is self-contained: after the element’s contents are stacked, the whole element is considered in the stacking order of the parent stacking context.

這個說法最簡單清楚
An easy way to figure out the rendering order of stacked elements along the Z axis is to think of it as a "version number" of sorts, where child elements are minor version numbers underneath their parent's major version numbers. This way we can easily see how an element with a z-index of 1 (DIV #5) is stacked above an element with a z-index of 2 (DIV #2), and how an element with a z-index of 6 (DIV #4) is stacked below an element with a z-index of 5 (DIV #1). In our example (sorted according to the final rendering order):
* Root
o DIV #2 - z-index is 2
o DIV #3 - z-index is 4
+ DIV #5 - z-index is 1, stacked under an element with a z-index of 4, which results in a rendering order of 4.1
+ DIV #6 - z-index is 3, stacked under an element with a z-index of 4, which
+ DIV #4 - z-index is 6, stacked under an element with a z-index of 4, which results in a rendering order of 4.6
o DIV #1 - z-index is 5

1/16/2008

Nine Javascript Gotchas

Nine Javascript Gotchas
Realazy » JavaScript的9个陷阱及评点


<input type="button" value="Gotcha!" id="MyButton" >
<script>
var MyObject = function () {
this.alertMessage = "Javascript rules";
this.ClickHandler = function() {
alert(this.alertMessage );
}
}();
document.getElementById("theText").onclick = MyObject.ClickHandler
</script>

If you call MyObject.OnClick(); you will get a popup saying "Javascript rules".
However, if you click on the button "MyButton", the popup will say "undefined"

<input type="button" value="Gotcha!" id="theText" >
<script>
var MyObject = function () {
var self = this;
this.alertMessage = "Javascript rules";
this.OnClick = function() {
alert(self.value);
}
}();
document.getElementById("theText").onclick = MyObject.OnClick
</script>

Release : jQuery 1.2.2

Julien Lecomte’s Blog » Gzip Your Minified JavaScript Files - 用 YUI compressor + Gzip 才是正途,用 Packer 做出來的 file size 雖然比較小,不過 Gzip 之後 YUI compressor 才是贏家,Packer 還要另外負擔 unpack 的 overhead , 作者提供了一個 PHP version 的 Gzip

The conclusion is clear: for optimal performance, gzip your JavaScript code, and stay away from “advanced” JavaScript compression schemes that look attractive on paper, but end up degrading the performance of your site.

Release:jQuery 1.2.2 - jQuery JavaScript Library
.ready() Overhaul
* Internet Explorer document ready drastically improved. We use a new technique inspired by Diego Perini. It allows us to not have to do a document.write() anymore, which is really fantastic.
* All browsers now wait for CSS to be ready, in addition to just the DOM. In reality, it's not just a vanilla document ready anymore - but we found that users, overwhelmingly, needed to wait for document styling to be active (such as knowing if an element is visible, or what its height is). Specifically we've added improvements to Safari and Opera to make this possible.
* $(document).bind("ready", fn); - You can now watch for the document ready event via the traditional .bind() function. Of course, .ready() still works as you would expect it to.

.bind("mouseenter") / .bind("mouseleave")
The functionality that was the core of the .hover() function has been split out into two new cross-browser events: mouseenter and mouseleave. These are different from mouseover and mouseout as those events will fire as you move in and out of child elements (which is generally not desired). For example, the following are both valid and work perfectly in jQuery 1.2.2:


$("li").hover(function(){
$(this).addClass("hover");
}, function(){
$(this).removeClass("hover");
});

$("li").bind("mouseenter", function(){
$(this).addClass("hover");
}).bind("mouseleave", function(){
$(this).removeClass("hover");
});


// Checks if an event happened on an element within another element
// Used in jQuery.event.special.mouseenter and mouseleave handlers
var withinElement = function(event, elem) {
// Check if mouse(over|out) are still within the same parent element
var parent = event.relatedTarget;
// Traverse up the tree
while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; }
// Return true if we actually just moused on to a sub-element
return parent == elem;
};

mouseenter: {
setup: function() {
if ( jQuery.browser.msie ) return false;
jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler);
return true;
},

teardown: function() {
if ( jQuery.browser.msie ) return false;
jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler);
return true;
},

handler: function(event) {
// If we actually just moused on to a sub-element, ignore it
if ( withinElement(event, this) ) return true;
// Execute the right handlers by setting the event type to mouseenter
arguments[0].type = "mouseenter";
return jQuery.event.handle.apply(this, arguments);
}
}

Inserting text in multiple lines : vim online

Tip #194 - Inserting text in multiple lines : vim online
以前是這樣做的,只適合在某些行的最前面或最後加東西
1. 用 shift+v 做 row 的選取。
2. 按 : 此時下面出現 :'<,'>
3. 接著打 s/^/foo/ 在最前面插入 foo,或者 s/$/foo/在最後面插入foo,完成。

這篇提到的方法適合在任意的地方加上東西。
1. 用 ctrl+v 做 block 的選取。
2. 用 A 可以在選取範圍的後面 append,用 I 可以在選取範圍的後面 insert。
3. 打一些東西,不過只會看到現在這一行有改變。
4. 按 Esc,這是最重要的一步,完成。

照理講第3步應該要有一些視覺上的提示才對阿。

1/14/2008

Querying Selected Text

Amazon.com: JavaScript: The Definitive Guide: Books: David Flanagan


function getSelectedText() {
if (window.getSelection) {
// This technique is the most likely to be standardized.
// getSelection() returns a Selection object, which we do not document.
return window.getSelection().toString();
}
else if (document.getSelection) {
// This is an older, simpler technique that returns a string
return document.getSelection();
}
else if (document.selection) {
// This is the IE-specific technique.
// We do not document the IE selection property or TextRange objects.
return document.selection.createRange().text;
}
}

John Resig - Super-Fast Delicious Bookmarklet

(window.getSelection ? window.getSelection() : document.getSelection ?
document.getSelection() : document.selection.createRange().text);

Text Truncation with JavaScript

Text Truncation with JavaScript

* Truncate the text to a length of your choosing
* Do not truncate in the middle of a word (only on a word boundary)
* Keep the page search-engine friendly by publishing the complete non-truncated text
* Add an ellipsis to the end of the truncated text
* Make the ellipsis a link that expands the text to full length. Once expanded it cannot be collapsed again (but that functionality could be added just as easily)
* Assumes that the content is plain text with no markup.


var len = 100;
var p = document.getElementById('truncateMe');
if (p) {
var trunc = p.innerHTML;
if (trunc.length> len) {
/* Truncate the content of the P, then go back to the end of the
previous word to ensure that we don't truncate in the middle of
a word */
trunc = trunc.substring(0, len);
trunc = trunc.replace(/\w+$/, '');
/* Add an ellipses to the end and make it a link that expands
the paragraph back to its original size */
trunc += '<a href="#" ' +
'onclick="this.parentNode.innerHTML=' +
'unescape(\''+escape(p.innerHTML)+'\');return false;">' +
'...<\/a>';
p.innerHTML = trunc;
}
}

onAvailable, onContentReady, onDOMReady, onLoad

YUI Library Examples: Event Utility: Using onAvailable, onContentReady, and onDOMReady

1. onAvailable: onAvailable targets a single element and fires when that element is available (when it responds to document.getElementById()) — but you can't count on the element's children having been loaded at this point.
2. onContentReady: When you care about not just your target element but its children as well, use onContentReady. This method will tell you that your target element and all of its children are present in the DOM.
3. onDOMReady: Some DOM scripting operations cannot be performed safely until the page's entire DOM has loaded. onDOMReady will let you know that the DOM is fully loaded and ready for you to modify via script.

(1) becomes available, (2) its content becomes ready (after all of its 100 children have loaded), (3) the DOM becomes ready, and finally (4) the page loads.


init: function() {

//assign page load handler:
YAHOO.util.Event.on(window, "load", this.fnLoadHandler, "The window.onload event fired. The page and all of its image data, including the large image of Uluru, has completed loading.");

//assign onDOMReady handler:
YAHOO.util.Event.onDOMReady(this.fnHandler, "The onDOMReady event fired. The DOM is now safe to modify via script.");

//assign onContentReady handler:
YAHOO.util.Event.onContentReady("contentContainer", this.fnHandler, "The onContentReady event fired for the element 'contentContainer'. That element and all of its children are present in the DOM.");

//assign onAvailable handler:
YAHOO.util.Event.onAvailable("contentContainer", this.fnHandler, "The onAvailable event fired on the element 'contentContainer'. That element is present in the DOM.");

},

bookmarklet: replaceGtRtAmp

http://chunghe.googlecode.com/svn/trunk/bookmarklet/replaceRtGtAmp/index.htm
這是為 Blooger 專用的,目的是把選取範圍內的<&> encode成 html entities,Firefox only。
對一個 input/textarea f,f.selectionStart 可以取得選取範圍開始的 index,f.selectionEnd 可以取得選取範圍結束的 index,另外修改完 textarea 內容後,Firefox 會 focus 到 textarea 最上面的位置,所以先用 f.scrollTop 把 scrollbar 的位置存下來,最後再設定回去。


<a href="javascript:
var ta = document.getElementById('textarea');
var scrollTop = ta.scrollTop;
var start = ta.selectionStart;
var end = ta.selectionEnd;
var s1 = ta.value.substring(0, start);
var s2 = ta.value.substring(start, end);
var s3 = ta.value.substring(end, ta.value.length);

s2 = s2.replace(/&/g, '&amp;amp;').
replace(/</g, '&amp;lt;').
replace(/>/g, '&amp;gt;');
ta.value =s1+s2+s3;
ta.scrollTop = scrollTop;

void 0;">replaceGtRtAmp</a>

1/13/2008

copy to clipboard

以下的 code 以及 swf 檔都來自 syntaxhighlighter,我把這部分的 code 拔出來放在 http://chunghe.googlecode.com/svn/trunk/project/copy.to.clipboard/
複製到剪貼簿在 IE 下是使用 IE 獨有的window.clipboardData.setData('text', text);,在FF下面沒有對應的方法,所以使用了 flash 來替我們完成。另外比較有趣的是要如何透過 flash 來達成一些原本無法達成的 cross-browser 的動作。
clipboard.swf 的 source code


if (clipboard.length)
{
System.setClipboard(clipboard);
} // end if


function copyToClipboard( text ){

var htmlEncode = function(string) {
return string.replace(/[<&>]/g, function(c) { return {'<': '<', '&': '>', '>': '&'}[c] })
}

var config = {
'swf': 'http://chunghe.googlecode.com/svn/trunk/project/copy.to.clipboard/clipboard.swf'
}

text = htmlEncode(text);
if(window.clipboardData){
window.clipboardData.setData('text', text);
}
else{
if(!document.getElementById('flashcopier')){
flashcopier = document.createElement('div');
flashcopier.id = 'flashcopier';
document.body.appendChild(flashcopier);
}
flashcopier.innerHTML = '<embed src="' + config.swf + '"
FlashVars="clipboard='+encodeURIComponent(text)+'" width="0" height="0" type="application/x-shockwave-flash"></embed>';
}
alert('done');
}

1/11/2008

Acid3

John Resig - Acid 3 Tackles ECMAScript - Acid3 不只是 CSS test suite, 還包括了一堆的 ECMAScript test, source code 相當值得一看。

* Array Elisions - Making sure that stuff like [,,] doesn't have a length and [0,,1] has a length of 3.
* Array Methods - Doing an unshift with multiple arguments .unshift(0, 1, 2), joining with an undefined argument .join(undefined).
* Number Conversion - Banging against .toFixed(), .toExponential(), and .toPrecision() - especially with decimals and negative numbers.
* String Operations - Negative indicies in substr .substr(-7, 3), character access by index "foo"[1] (part of the ECMAScript 4 spec).
* Date - Making sure that certain method calls result in NaN results (like d.setMilliseconds(), with no arguments) and also enforcing +1900 year offsets.
* Unicode in Identifiers - You can't use escaped Unicode in identifiers, for example: eval("test.i\\u002b= 1;"); (that should throw an exception).
* Regular Expressions - /[]/ matches an empty set, /[])]/ should throw an exception, backreferences to non-existent captures, and negative lookaheads /(?!test)(test).exec("test test").
* Enumeration - Make sure that object properties are enumerated in the correct order, make sure that you're able to enumerate properties of certain names (toString, hasOwnProperty, etc.).
* Function Constructors - The user should be able to set custom constructors on the .constructor property, .constructor should not be enumerable, and .prototype.constructor should be deletable.
* Function Expressions - (function test(){ ... })(); You should be able to call the function by name, within the function itself, you can't directly overwrite the function name (only with a function-scoped variable), and 'test' isn't leaked into the parent scope.
* Exception Scope - Variables within the catch(){} should interact with the catch arguments primarily, followed by variables in an outer scope.
* Assignment Expressions - s = a.length = "123"; - a.length has a return value of 123 (the number) which is assigned to 's', rather than the correct result of the string "123".
* Encoding - encodeURI() and encodeURIComponent() must gracefully handle null bytes.

flickr's json format api

JSON一個很大的好處是可以 corss-domain,利用動態產生出來的 script tag 把 remote JSON 給load 進來,for example


var script = document.createElement('script');
script.setAttribute('src', 'http://api.flickr.com/services/rest/?format=json&method=flickr.people.getPublicPhotos&api_key=e8bde2fca0855f7e712e091fd6384bcf&user_id=79311125%40N00&');
script.setAttribute('id', 'json');
script.setAttribute('type', 'text/javascript');
document.documentElement.firstChild.appendChild(script);

通常 JSON load進來之後我們才可以對它進行一些處理,不過要如何知道 JSON 已經 load進來了?根據 石頭閒語:Load and Execute JavaScript on Demand, by createElement - 樂多日誌,我們可以用 script.onload = function(){ code goes here ...},不過似乎 IE 不能用,該篇文章 propose 的方法是每 0.1 秒去檢查變數進來了沒。

今天玩了一下 Flickr 的 JSON format API,發現 Flickr 的解法太聰明了,一個 Flickr API的回傳值看起來像是底下這樣子:

jsonFlickrApi({
"stat" : "fail",
"code" : "97",
"message" : "Missing signature"
})

這個回傳值只做了一件事情,就是呼叫 jsonFlckrApi 這個 function,再把整個資料的 object 丟過去。所有只要我們在頁面有個這樣的function,for example

function jsonFlickrApi(rsp){
console.log(rsp["stat"], rsp["code"], rsp["msg"] )
}

在我們收到 JSON 的回傳值之後,jsonFlickrApi這個 function 會被呼叫起來做動作,簡單,明瞭,免 polling,缺點就只有一個,就是 function 名稱是被定死的,不過這也沒什麼。
update: flickr 可以自己定義 callback function name
Flickr Services
Callback Function

If you just want the raw JSON, with no function wrapper, add the parameter nojsoncallback with a value of 1 to your request.

To define your own callback function name, add the parameter jsoncallback with your desired name as the value.

nojsoncallback=1 -> {...}
jsoncallback=wooYay -> wooYay({...});

update: 在FF下,每次都要重新建立一個script tag,如果重複使用同一個script tag,則只會執行第一次而已,IE則是每次都會執行。

1/10/2008

document.getElementById() returns element with name equal to id specified

document.getElementById() returns element with name equal to id specified - 如果頁面上有一個 <div name = "foo">,用document.getElementById('foo')是抓得到的,說IE笨還不算笨!

Access Control for Cross-site Requests

Access Control for Cross-site Requests - 這東西早就該有了阿, 大佬

Firefox 3 implements the W3C Access Control working draft, which gives you the ability to do XMLHttpRequests to other web sites

Cross-Site XMLHttpRequest - MDC
John Resig - Cross-Site XMLHttpRequest

<?php header('Access-Control: allow <*>'); ?>
<b>John Resig</b>


<?xml version="1.0" encoding="UTF-8"?>
<?access-control allow="*"?>
<simple><name>John Resig</name></simple>

1/09/2008

style for printing chm format ebooks


pre {
border-left: 2px solid #222;
color:#222;
background-color: #eee;
font-size:14px;
line-height:140%;
padding:5px 10px;
}
tt {
background-color:#EEEEEE;
color:#333;
font-family:"Courier New",Courier,monospace;
font-size:13px;
}
.docText {
color:#222222;
font-family:'Lucida Grande',Verdana,Geneva,Lucida,Helvetica,sans-serif;
font-size:small;
line-height:140%;
}
.docLink {
color:#003399;
text-decoration:none;
}
.docList {
color:#222;
font-family:'Lucida Grande',Verdana,Geneva,Lucida,Helvetica,sans-serif;
font-size:small;
line-height:140%;
}

Styling an input type="file"

Styling an input type="file" - input type="file"一直是沒辦法 style 的 element, ppk在這篇提到一個解決辦法, 其實就是用一張圖片蓋在 input 上面. anyway, 這邊有人寫了一個 jQuery 的 plugin 來處理: Style File Inputs With jQuery (and CSS), 這邊有 demo

Firebug internals & debug PHP with firePHP

Firebug internals - MDC - 這篇介紹了 Firebug 的構造組成 & how to extend firebug
FirePHP - Extending Firebug < Reference
FirePHP - Firebug Extension for AJAX Development

FirePHP adds a "Server" tab to each request in the Firebug Net and Console panels displaying data from the FirePHP-Data response header.

Leeym’s Blog

Leeym’s Blog - 最新連載 - 矽谷台勞週記 - 在 Y! Tiger Team 的 backend engineer, 台灣人,在 Y! TW待了六年,07年七月轉調 Y! US(應該是),寫了蠻多美國文化以及在 sunnyvale 工作(code review, project, ...)的種種。
獵人頭公司來電 at Leeym’s Blog

我在 Yahoo! 當軟體工程師,拿的是 Blanket L-1B 簽證。

和 H 簽證一樣,L-1A 用於專業經理人,L-1B 用給專業人員。和 H 簽證不同的是,L 簽證適用於公司內轉,你必須在三年之內於一家公司的海外部門待滿一年,然後才能轉調至該公司的美國部門。有聽說 Blanket L-1B 只要待滿半年即可申請轉調,不過我不確定相關規定。

大型的公司大部分用 Blanket L-1B,幾乎申請都會過,提出申請後一個月內就會拿到簽證。比較小型的公司如果用一般的 L-1B 的話,需經過個案審核,會拖得比較久一點。

L-1 不受限於每年四萬五千個的名額限制,所以近年來成為 H-1 的替代方案之一。不過已經有美國國會議員盯上這個議題,不知道之後會不會修改規定。

Foo Hack » Cross Browser Support for inline-block Styling

Foo Hack » Cross Browser Support for inline-block Styling i'll check out for this later

Tracking fingers with the Wii Remote

這是近期看到最有創意的idea了: 利用家家戶戶都有的 Wii 來實做目前還很貴的 multi-touch , 材料簡單, 人人都做得出來, 成果看起來也非常非常的棒, 尤其是最後一個例子,被震撼到了,感覺是看到了 game industry 的未來。

So if you are watching this and you are a Nitendo Wii game developer, I wanna see some games.

Wii sensor bar 其實是 emanate infrared, Wii remote是可以 capture infrared 的 camera, Wii remote 再把捕捉到的訊號用藍芽送回到 Wii 的主機


Reference:
Mr./Ms. Days (MMDays) - 網路, 資訊, 觀察, 生活 » Blog Archive » 利用 Wii Remote 模擬 Multi-touch Screen

YouTube - Keynote - Bill Gates' Last Day - January 6, 2008

1/04/2008

web.Frontend :: 再说 IE6 的背景闪烁 :: January :: 2008

Window to DPO's thoughts: A forensic analysis of the IE6 BackgroundImageCache command identifier

IE would "normally" check with your web server for newer versions of the css background images prior to applyng a css rule, no matter what is the value of the cache option. Make it "Every visit to the page.", "Automatically" or "Never", it does not matter, IE wants to know anyway.

Whats seems to be the problem
Internet Explorer 6 seems to check for a newer version of the background-image css property on links (A tag) every time you move the mouse over a link.

evil.che.lu - No more IE6 background flicker

/*@cc_on @*/
/*@if (@_win32)
try {
document.execCommand('BackgroundImageCache', false, true);
} catch(e) {}
/*@end @*/

How to use CSS for Flickerless Image Replacement - WebReference.com -
web.Frontend :: 再说 IE6 的背景闪烁 :: January :: 2008

web design

» Color


web design styles

web design

code snippet

The window.onload problem (still)

先存下來慢慢看

Peter's Blog - The window.onload problem (still) - 這篇很詳細的解釋了整個經過以及各種不同的嘗試

The YUI YAHOO.util.Event.onContentReady() function solves the problems with onAvailable for some situations. The onContentAvailable() function is similar to onAvailable() but onContentAvailable() declares an element available when it's nextSibling is also found in the DOM. If a nextSibling element is not found then the element is declared available when the window.onload event fires.

Why wait for nextSibling? Suppose in the previous example that we poll the DOM for the unordered list engines element. When this element is found in the DOM it is not necessarily true that all of it's child elements are also in the DOM. The HTML parser may have only parsed the first element in the list and not the rest of the list. If the engines element has a nextSibling existent in the DOM then it is safe to assume that the HTML parser has finished creating the entire list and that all of the list's elements are also available in the DOM. It would take an unreasonably huge amount of paranoia to suspect that browser parsing and DOM construction works any other way.

window.onload: another solution to get it going
window.onload(), DOMContentLoaded, onDocumentReady and document.readystate
window.onload: continued attempt
Dean Edwards's demo and soruce code:
function init() {
// quit if this function has already been called
if (arguments.callee.done) return;

// flag this function so we don't do the same thing twice
arguments.callee.done = true;

// kill the timer
if (_timer) {
clearInterval(_timer);
_timer = null;
}

// create the "page loaded" message
var text = document.createTextNode("Page loaded!");
var message = document.getElementById("message");
message.appendChild(text);
};

/* for Mozilla */
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", init, false);
}

/* for Internet Explorer */
/*@cc_on @*/
/*@if (@_win32)
document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
var script = document.getElementById("__ie_onload");
script.onreadystatechange = function() {
if (this.readyState == "complete") {
init(); // call the onload handler
}
};
/*@end @*/

/* for Safari */
if (/WebKit/i.test(navigator.userAgent)) { // sniff
var _timer = setInterval(function() {
if (/loaded|complete/.test(document.readyState)) {
init(); // call the onload handler
}
}, 10);
}

/* for other browsers */
window.onload = init;

以下是prototype用到的code
(function() {
/* Support for the DOMContentLoaded event is based on work by Dan Webb,
Matthias Miller, Dean Edwards and John Resig. */

var timer, fired = false;

function fireContentLoadedEvent() {
if (fired) return;
if (timer) window.clearInterval(timer);
document.fire("dom:loaded");
fired = true;
}

if (document.addEventListener) {
if (Prototype.Browser.WebKit) {
timer = window.setInterval(function() {
if (/loaded|complete/.test(document.readyState))
fireContentLoadedEvent();
}, 0);

Event.observe(window, "load", fireContentLoadedEvent);

} else {
document.addEventListener("DOMContentLoaded",
fireContentLoadedEvent, false);
}

} else {
document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>");
$("__onDOMContentLoaded").onreadystatechange = function() {
if (this.readyState == "complete") {
this.onreadystatechange = null;
fireContentLoadedEvent();
}
};
}
})();

http://livepipe.net/scripts/code_highlighter.js 用到的code

function asap(fn) {
asap.done ? setTimeout(fn, 0) : asap.waiting.push(fn);
}
asap.waiting = [];
asap.done = 0;
asap.ready = function() {
// (note: deliberately avoids using 'this')
if (!asap.done++) {
asap.timer && clearInterval(asap.timer);
var funcs = asap.waiting;
for (var i = 0, l = funcs.length; i < l; i++) {
setTimeout(funcs[i], 0);
}
}
}
// IE
/*@cc_on@if(@_win32)document.write('<script defer onreadystatechange="readyState==\'complete\'&&asap.ready()" src=//:></script>')@end@*/
// Moz/Op
document.addEventListener && document.addEventListener('DOMContentLoaded', asap.ready, false);
// Safari
asap.timer = navigator.userAgent.match(/WebKit|KHTML/i) && setInterval(function() { document.readyState.match(/loaded|complete/i) && asap.ready() }, 10);
// Fallback
window.onload = asap.ready;

//asap('Syntax.init()');

Update: YUI 的 YAHOO.util.Event.onDOMReady 可以達到一樣的效果.
Update: prototype的寫法

document.observe('dom:loaded', function(){alert('hello')})

DOM加载事件的终极解决方案 - dexter_yy - JavaEye技术网站

1/02/2008

Google gears - ImageManipulationAPI

Google gears - Wiki, source code, 目前有下面三個 design doc

This is a module to give Javascript a way to resize, crop and compose images together on the client side. This will allow, for example, images to be resized into a web-friendly format before being uploaded to a photo album. Another use is for composition of images together as an efficient alternative to server-side composition or CSS layering. Yet another use is for basic photo editing - a user can edit a photo with instantly applied changes before uploading it to the server.

This module will be implemented as a wrapper around libGD. This is the smallest of the popular image libraries which does all of the below. If this turns out to still be too big, we can consider writing the image manipulation code ourselves, or using browser specific image libraries.

[Reference]
http://almaer.com/blog/gears-future-apis-image-manipulation-api
Ajaxian » Google Gears Future APIs

JavaScript: It's Just Not Validation!

JavaScript: It's Just Not Validation! [JavaScript & AJAX Tutorials]

The term "JavaScript validation" is a somewhat misleading one for describing the process of assisting the users to fill forms out correctly. In fact, the back-end code performs the validation -- JavaScript merely provides assistance. But when the validation and assistance don't come from the same source, they do nothing but confuse people.
Strictly speaking JavaScript validation isn't validation -- it's input assistance. Anyone can bypass JavaScript; it's an aid, not a gate. It simply helps to give your users the confidence to hit that big submit button.
Finally, back-end validation is required. JavaScript assistance is nice.

John Resig - Bug Fixes in JavaScript 2

John Resig - Bug Fixes in JavaScript 2
arguments is now a 'real array'
arguments is now a 'real array', as opposed to an array-like object, with the following distinctions:

  • arguments.toString() behaves like an object's .toString(), rather than an array's.
  • If you manipulate the .length property its contents aren't deleted (if the length is reduced), nor are new items added (if the length is increased).
This means that you can now do simple things like:
arguments.slice(1);

Whereas, previously, you would have to do:
Array.prototype.slice.call( arguments, 1 );

this propagation
If you now define a function inside another, its this is bound to the this of the outer function, as opposed to the global object (e.g. window).
This makes the following code possible:
function User(name){
this.name = name;

function test(){
alert(this.name);
}

test();
}

Whereas, previously, you would've had to have used a closure to store a reference to this and retrieve it within test(). The resulting code would have looked something like this:
function User(name){
var self = this;
this.name = name;

function test(){
alert(self.name);
}

test();
}

Trailing Commas
When initialising an object, trailing commas are ignored (some implementations already support this).
var obj = {
a: 1,
b: 2,
};


It's now being made expressly clear that a trailing comma in an array initialisation does not create an extra undefined entry at the end of the array. JScript currently gets this implementation detail wrong, even though it was specified in ECMAScript 3. The correct result is as follows:
[a, b,].length
>> 2 (not 3)


Single-Character Substrings
You can now get single characters out of a string by using [index], instead of the .charAt(index) method. This way was already widely implemented.
'string'[0]
>> 's'

for .. in order
When looping through the properties of an object the order in which they were returned was left up to the implementation - now it's required that the properties be returned in the order in which they were created. The final result would allow for the following, intuitive, result:
var obj = {1: 2, p: 'hi', '_':'under'};
for ( var i in obj )
alert(i);
>> alert('1')
>> alert('p')
>> alert('_')