bitbucket上提交代码后用户名不显示链接问题

一个不痛不痒的问题,就是在bitbucket上提交代码到代码仓库,总是不会在我的用户名上显示出链接来,简单搜索一下,没找到中文的信息,搜英文的,倒是很快找到这个 issue : https://bitbucket.org/site/master/issue/3394/user-aliasing-commit-user-not-showing-up

原来很简单,他必须要在用户名里设置邮件才可以,
以 username <email@example.com> 这样的形式设置用户名才可以。
编辑~/.hgrc
找到其中用户名的字段,改成如下的形式即可

[ui]
username = Shawphy <email@example.com>

即可

Node.js 的简易web服务器

网上关于Node.js的介绍已经铺天盖地了,但我就没找到一个简单的web服务器给我做测试用。
实际上Node.js只需要一个exe文件和一个js文件就可以搭建服务器了,用来随便测试页面之类的用起来比nginx还方便。所以我就随手写了一个简单的。只可用于http服务,没有更多功能的js文件。

用起来很简单:
1,先去 http://nodejs.org/下载最新的Node.js可执行的exe文件。比如: http://nodejs.org/dist/latest/node.exe
2,把下面的代码保存为一个 server.js 文件,把它跟刚才下载到的 node.exe 文件放在一起。
3,把server.js文件拖到node.exe文件上就OK了

就这三步之后,整个目录下的文件都可以通过 http://127.0.0.1:8080/ 来访问了,测试用起来非常方便。

其他系统下也如法炮制,官网上也有下载mac和linux的版本。

var http = require("http"),
	url  = require("url"),
	path = require("path"),
	fs   = require("fs");

http.createServer(function (req, res) {
	var pathname=__dirname+url.parse(req.url).pathname;
	if (path.extname(pathname)=="") {
		pathname+="/";
	}
	if (pathname.charAt(pathname.length-1)=="/"){
		pathname+="index.html";
	}

	fs.exists(pathname,function(exists){
		if(exists){
			switch(path.extname(pathname)){
				case ".html":
					res.writeHead(200, {"Content-Type": "text/html"});
					break;
				case ".js":
					res.writeHead(200, {"Content-Type": "text/javascript"});
					break;
				case ".css":
					res.writeHead(200, {"Content-Type": "text/css"});
					break;
				case ".gif":
					res.writeHead(200, {"Content-Type": "image/gif"});
					break;
				case ".jpg":
					res.writeHead(200, {"Content-Type": "image/jpeg"});
					break;
				case ".png":
					res.writeHead(200, {"Content-Type": "image/png"});
					break;
				default:
					res.writeHead(200, {"Content-Type": "application/octet-stream"});
			}

			fs.readFile(pathname,function (err,data){
				res.end(data);
			});
		} else {
			res.writeHead(404, {"Content-Type": "text/html"});
			res.end("<h1>404 Not Found</h1>");
		}
	});

}).listen(8080, "127.0.0.1");

console.log("Server running at http://127.0.0.1:8080/");

Lorem ipsum 是什么?顺便推荐一款假文生成器MoreText

今天在测试Coda还有VIM snipMate都看到了一段 Lorem ipsum 。好长的一串,看都看不懂的文字:

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

一次遇到也就算了,一天之内在不同地方遇到两次,可见是有缘分了。简单一查,原来这是印刷设计排版上用于测试效果的一段无意义的文字,难怪我完全看不懂了。维基上是这样说的:

Lorem ipsum是指一篇常用于排版设计领域的拉丁文文章,主要的目的为测试文章或文字在不同字型、版型下看起来的效果。
Lorem ipsum从西元15世纪开始就被广泛地使用在西方的印刷、设计领域中,在电脑排版盛行之后,这段被传统印刷产业使用几百年的无意义文字又再度流行。由于这段文字以“Lorem ipsum”起头,并且常被用于标题的测试中,所以一般称为Lorem ipsum,简称为Lipsum。

于是根据维基页面上,找到了两款中文的假文生成器。但遗憾的是都是繁体中文的,没有简体的。我只推荐这款MoreText,因为虽然他生成的是没有意义的假文,但每句话看起来都还像是一句句子,而不是随意的汉字堆砌的句子而已。因为他可以选择语料库!有赖和、徐志摩、Twitter和苹果日报!所以他的这个看起来效果还真不错呢!如果你在设计产品的时候需要大量文本填充的话,不妨试试吧!我随便贴一段:

鬧熱到了,借著拜年的名目,奉行正朔,實在可憐可恨,雖受過欺負,使人們沒有年歲的感覺,死鴨子的嘴吧,街上看鬧熱的人,波湧似的,和狺狺的狗吠,和他們一拚!街上看鬧熱的人,驟然受到光的刺激,現在不高興了,地方領導人。接連鬥過兩三晚,是抱著滿腹的憤氣,先先後後,在冷風中戰慄著,且新正閒著的時候,孩子們得到指示,看看又要到了。這回在奔走的人,走過了一段里程,勞動總說是神聖之事,怎地所說的一週會不同?一陣吶喊的聲浪,蹧躂人!所謂風家也者,他倆的來歷有些不明,凶惡的他們忍相虐待,甲總不平地罵。

看吧,每句话都像是一句话,但就是看不明白他们的意思。其实用Google Translate随便翻译一段英文,也能达到差不多的效果吧。

Be Pro

我的博客很少有转载的文章,今天难得转一篇,因为文中我也客串了一把,呵呵,并且文中的观点非常认同,所以转载过来,供大家探讨。原文地址:糖伴西红柿的Be Pro

=======================================

最近再次仔细把《HTML5设计原理》重新过了一遍,比起上次粗粗的浏览,收获更多,这篇文章没有任何关于 HTML5 标签、api 的使用的详细解释,而是对其背后的设计原理做了详细说明。这是 HTML5 一切纷繁表象背后的真义,值得每个前端工作者多次阅读。

下午和小飞 @shawphy 讨论一些问题的时候,说到了中文书写里的“的、得、地”地区别。据说现在已经把这三个 de 统一,不做区分了。想想也是,虽然我受教育的时候是区分三者使用的,但是我也一直没弄清楚它们之间的区别。因为最近的一些书写要求,还想趁过年期间回去请教下俺那当了一辈子语文教师的爹来着。

小飞说:“有一种观点认为,语言是活的,随着人们的使用而变化的。如果大部分人都不分了,那也就不要再分了。感觉着就像是HTML5一样。HTML5 很宽容,比如关于属性引号。按理需要有引号,但现在有没有都无所谓了。”

这就不得不提到 HTML5 设计原理其中的一条:“发送时要保守;接收时要开放。” HTML5 以包容的心接受开发者书写的文档,这些文档发送到同样敞开胸怀的浏览器,以使得那些不够标准的文档也可以渲染出来。

与之相对的是已经死去的 XHTML2 ,(呃,突然发现 XHTML 。。。2。想起郭德纲的一句玩笑:“CCTV。。。2,多大的勇气,谁好意思承认这个,人家还写上了。”)XHTML2 是绝对的理想派,要求严格使用 XML 的错误处理模型,也就是遇到一个错误就会停止解析。这对文档书写着的要求得多高啊。当然最为开发者,我们应该遵从最佳实践,尽量保证文档格式的正确。但是谁也不能保证 100% 的正确性,作为开放的互联网,对错误零容忍,导致浏览器无法渲染确实不是那么回事。

尤其是技术就像数码产品,越来越先进,但是价格(门槛)越来越低。我之前有私心,眼看国内一些人对技术的滥用,导致的网上的虚假信息、垃圾信息泛滥,甚至一度希望一些技术应该保有一定的门槛。但是后来想明白了,互联网本身就是开放到,技术生来也应该是服务每一个人的,至于怎么使用,那就要看人自己的选择了。

遵从伯斯塔尔法则(Postel’s Law)的 HTML5 在于完美理想话的 XHTML2 的角力中胜利了。或者应该说是人性再一次取得了胜利,人人追求完美,但是最后还得面对现实。

我们应该看到伯斯塔尔法则其实是同时对发送者和接收者有要求的,”接收时要开放“是对标准和浏览器的要求,而”发送时保守“则是对文档作者的要求。

回到“的 得 地”这个问题。小飞问:”这些坚持 三个 de 不同的人,是不是就好像坚持 xhtml2 的人呢?“ 我认为不然,这些人是选择了发送时保守的“开发者”。不区分这三个 de 的人,如果是普通人,自然无可厚非,但是作为职业的作家,如果无法区分这三者,就算不上好的作家。

同样的产品,不同的工艺就决定了价值的不一样。A货再能以假乱真,也不能和真品等价。同样,作为一名职业的前端工程师,在职业的道路上,我们的选择决定了输出的产品的质量,产品质量反过来也决定了我们自身的价值。

啰哩巴嗦的说了这么多,其实是希望各位前端工程师(其实也可以延伸至各个行业的从业者)能更加专业些,在发送时更加”保守“些。Be pro,这也是 2011 我对自己的要求。

Eric Meyer又更新reset css了

前几天Eric Meyer又思考了一下reset.css的问题,于是有所更新,具体为何要这样做,请看原文Reset Revisited。注意最开始的那句

NOTE: WORK IN PROGRESS
USE WITH CAUTION AND TEST WITH ABANDON

使用需谨慎!


/* http://meyerweb.com/eric/tools/css/reset/
v2.0b1 | 201101
NOTE: WORK IN PROGRESS
USE WITH CAUTION AND TEST WITH ABANDON */

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, figcaption, figure,
footer, header, hgroup, menu, nav, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: ”;
content: none;
}

/* remember to define visible focus styles!
:focus {
outline: ?????;
} */

/* remember to highlight inserts somehow! */
ins {
text-decoration: none;
}
del {
text-decoration: line-through;
}

table {
border-collapse: collapse;
border-spacing: 0;
}

前端开发中需要用到的变换矩阵

想写写关于矩阵变换的博文已经想了很久了,今天看到 winter 写的一篇博客CSS3:transform与transition背后的数学原理,于是就促成了本文。注意,下面的演示内容需要现代浏览器支持。比如Chrome/Firefox/Opera。阅读器中无法看到演示。

矩阵是线性代数中的内容,在计算机图形学中就拿来做矩阵变换。在以前,对于前端工作来说,几乎用不到矩阵变换。然而,随着浏览器的进步,HTML5和CSS3的普及,对于前端可以操作的东西越来越多,于是,矩阵变换也出现在视野当中了。

矩阵变换,听起来是一个挺高级的东西,其实本质上只不过是把一系列简单的数学运算给包装一下,赋予一个比较华丽和高深的外表而已。如果你之前没有接触过矩阵运算,也不用慌,跳过下面矩阵公式,直接看每条后面的黑体字公式即可。这些公式仅仅涉及高中水平的加减运算和三角函数而已。除了最开始的时候我会搬出那个矩阵,之后的讨论我会避开矩阵的公式,直接用容易理解的方式阐述问题。

最早浏览器中支持的矩阵变换可能是在SVG的标准中。之后跟图形带点边的CSS 3以及HTML5的Canvas中也有了矩阵变换,当然强大的Flash以及Flex中也有变换矩阵。他们的基本原理都是一样的。目前2D的矩阵变换已经有不少浏览器支持了,而3D的变换还需时日。

说了半天矩阵变换,其实本质上来说,一个元素渲染后就可以得到一张位图,然后对这个位图上每一点进行变换,就可以得到新的一张位图,从而产生平移、缩放、旋转,切变以及镜像反射等效果了。

基本公式

目前不论是SVG也好,CSS 3也好,还是Canvas,2D的矩阵变换都提供了6个参数a b c d e f,其使用基本公式是这样的:

其中,x和y是元素最开始的坐标,x’ 和y’则是通过矩阵变换后得到新的坐标。
通过中间的那个3×3的变换矩阵,对原先的坐标施加变换,就能得到新的坐标了。

注意!a b c d e f几个参数的排列方式,是竖着排的,网上有不少文章排列方向有误。

根据矩阵乘法的运算法则,上面的矩阵式子可以化成下面的两个式子

x’=ax+cy+e
y’=bx+dy+f

也就是说,别看上面有那么一大坨的东西,本质上就是上面这两条简简单单的公式而已。之后的讨论中,我将围绕着上面的两行来讨论,而不再涉及矩阵的内容了。

平移

原始位置
平移120px, 50px后

如果调用时提供参数matrix(1,0,0,1,tx,ty),即a=d=1,b=c=0,那么上面的式子就简化成

x’ = 1x+0y+tx = x+tx
y’ = 0x+1y+ty = y+ty

很容易看到,这里就是在原先x,y的基础上进行平移,变成x+tx,y+ty点而已。非常简单。如果数学上讲,tx和ty就好比是Δx和Δy。

x’ = x+Δx
y’ = y+Δy

CSS 3中的transform: translate(tx, ty);就等价于transform: matrix(1,0,0,1,tx,ty);注意,使用matrix的时候不需要单位,默认是px,而translate需要单位,可以是px、em之类的单位。

缩放和拉伸

原始大小
长宽放大1.5倍

如果调用时提供参数matrix(Sx,0,0,Sy,0,0),即a或d不等于1,比如a=Sx,d=Sy而b=c=e=f=0,于是公式简化成

x’ = Sx*x+0y+0 = Sx*x
y’ = 0x+Sy*y+0 = Sy*y

可以想到,这个操作,实际上是让x的坐标扩大Sx倍,而y的坐标扩大Sy倍。
这主要是用来让元素进行缩放效果的。如果Sx和Sy大于1,则是放大,而Sx和Sy小于1,就是缩小了,如果等于1,那就是保持原状了。并且,由于x方向和y方向是相互独立的,所以可以一个方向放大,另一个方向缩小。
上面的那个例子中,我设置的m和n都是0.5,于是图形长宽就各缩小了一半。另外,值得注意的是,他是以元素的中心作为缩放的基点的,而不是左上角。
CSS 3中的transform: scale(Sx, Sy);就等价于transform: matrix(Sx,0,0,Sy,0,0);

旋转

原始方向
旋转37°

这里用到的就相对高级一些了,需要使用三角函数的一些知识了
如果调用时提供参数matrix(cosθ,sinθ,-sinθ,cosθ,0,0)

x’ = x*cosθ-y*sinθ+0 = x*cosθ-y*sinθ
y’ = x*sinθ+y*cosθ+0 = x*sinθ+y*cosθ

由于计算机图形学中,通常向右为x轴正方向,向下为y轴正方向,所以这里的θ表示元素绕坐标原点顺时针旋转的角度。而这里的原点不是元素的左上角,而是元素的中心点。
上面的例子中,我把一个div顺时针旋转了37°,cos37°=0.8,sin37°=0.6,所以提供的矩阵的参数就是 matrix(0.8,0.6,-0.6,0.8,0,0)
CSS 3中,transform:rotate(37deg)就等价于我上面的那个变换了。注意CSS 3中的角度必须带单位 deg。好处是不用自己算sin和cos值了。

切变

x方向倾斜45°

切变,就是把一个元素往某一个方向倾斜一定的角度。传入的参数应当是matrix(1,tan(θy),tan(θx),1,0,0)

x’ = x+y*tan(θx)+0 = x+y*tan(θx)
y’ = x*tan(θy)+y+0 = x*tan(θy)+y

这里的θx和θy分别代表往x正方向和往y正方向倾斜的角度,两者是相互独立的。上面的例子中,我把元素往x方向倾斜了45°,因此他的tan(θx)=1
CSS 3中的transform: skew(θx, θy);就等价于transform: matrix(tan(θx),0,0,tan(θy),0,0); 如果使用skew的话,直接使用角度即可,但必须带单位deg,比如上面的例子用矩阵的话写成transform: matrix(1,0,1,1,0,0);等价于 transform: skew(45deg, 0);

镜像反射

镜像对称
镜像对称

镜像反射就是指元素对某一条直线做镜像对称。最基本的情况是可以对经过原点的某条直线进行反射。定义(ux,uy)为直线方向的单位向量。也就是说,如果直线方程是y=kx,那么ux=1/sqrt(1+k^2),uy=k/sqrt(1+k^2)
那么对这种镜像反射变化时传入的参数应当是
matrix(2*ux^2-1,2*ux*uy,2*ux*uy,2*uy^2-1,0,0)
于是最终的方程

x’ = (2*ux^2-1)*x+2*ux*uy*y
y’ = 2*ux*uy*x+(2*uy^2-1)*y

上面的例子中,就是对y=2x这条直线进行的镜像对称。CSS 3中目前没有简化的规则与之对应。

至于如何对一条不过原点的线对称,则需要设置原点所在的坐标了。由于默认情况下,原点坐标是这个元素的中心,如果改变了原点的坐标,就可以改变对称的直线,当然也可以改变前面所有效果的呈现方式,CSS 3中使用transform-origin方法修改坐标原点的位置。

最后,如果你想要玩的更High点,买本计算机图形学的书来看是不可避免的,这篇文章也仅仅是个皮毛而已。希望对你有所帮助。

扩展阅读

前端观察,你需要知道的CSS3 动画技术
维基百科中关于矩阵变换的条目
理解矩阵(1)
理解矩阵(2)
理解矩阵(3)
w3 文档,关于坐标系以及矩阵变换属性
w3 文档,SVG中的3D变换矩阵
w3 文档,CSS 3中的3D变换矩阵,基本跟上一条的差不多

CSS通用元素选择器的都市流言

本文尚未有测试数据支持,以下结论仅是根据现有情况的一种解释。

关于 * 这个选择器,一直有个疑惑,到底是否影响效率。在先前的观念中,这由于要匹配所有的元素,让每一个元素都带上这个属性,所以会影响页面的效率。但近来的思考,觉得这应该不会影响效率。为此还特地写过一篇博文,里边提到了这点:真的还需要reset.css么?

而这篇文章中我打算着重阐述为何 * 这个选择器不会影响效率。

上周六去参加了 web标准化交流会,席间 winter 从浏览器(webkit)的角度分享了关于页面渲染的过程。其PPT也可以在前面的链接中下载到。

其中一个很重要的过程是,当页面载入过程中,CSS 和 HTML 是并行下载的。并且通常CSS是在HEAD中引入的,并且体积不如HTML大,所以CSS会先下载完。下载的过程中浏览器就已经开始对CSS中的规则进行索引,也就是已经确定哪一个元素呈现的样式是如何的了。同时,浏览器根据HTML构建出的DOM树,其中的每一个元素会直接去CSS规则索引中去比对,构建出渲染树。这个过程都是并行的,并且CSS规则是进行了索引的,因此速度非常的快速。

那么我们看看CSS规则的来源主要有2个,一是浏览器内置的元素样式,Firefox 3.x版是放在目录下的res文件夹内,4.0版和Chrome中没找到(这里是我的主观臆断不太可靠,大家自行辨别),另一个就是页面提供的。根据查看 放在 res 文件夹下的 CSS 文件就可以得知,就是是什么样式都不写,已经为每一个HTML元素设定好了基本样式了。

那么看看我们所忌讳的事情,不用*{margin:0;padding:0},而是使用

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
margin: 0;
padding: 0;
}

看看这一大坨东西啊,难道不是跟上面的 * 选择器一个用途么?对每个元素(至少是常用元素),添加样式。其实作用是一样的,并且就算没有这一坨,浏览器内置样式也在对每个元素设置样式。之后 HTML 文件中的每一个元素,可以很容易找到自己应当呈现的样式了。

那么,对于之后添加的,会不会有性能影响呢?也不会,由于CSS规则已经确定并索引了,所以今后增加的元素也不过就是简单比对一下而已,不会多走一步的。

所以,由此得出结论,只要有需要,大胆的使用 * 吧,他不会给你从性能上增加额外的麻烦。

最后补两个前端优化小知识:
1,由于CSS规则和HTML是并行载入的,因此把CSS放在HEAD中是非常有必要的。
2,少使用 :last-child 。因为这个选择器无法索引起来,必须等DOM构件完,才能知道他是不是父元素中最后的那个 元素。这种就非常慢了,慎用。