Roar for mootools 1.4

早在天下大势还处在分久必合的时候,那时候mootools还有不少简单实用的小库,比如我今天搜索”mootools notification”就找到这个08年的库叫做Roar。不过遗憾的是从那以后,这个库就再也没有更新过了。

Mootools本身也沉寂了很久,这个项目恐怕也要思考自己未来的发展方向了。今年9月Mootools迈进了1.4,API上有一些变化。现在的下载页也能看到with/without backward compatibility的版本分开下载。为了用上Roar,我尝试了这两个版本发现都不能使用。最后downgrade到1.2可以确定Roar本身在当时是没有什么问题。

这么多年对mootools痴心不改,所以顺手维护了一下Roar,现在可以在1.4 without compatibility的发布下运行了。主要是几个小修改,大多是一些多年deprecated函数被正式删除:

  • Type常量,原先的String.type,Object.type现在统一到一个Type对象下,变成Type.isString和Type.isObject
  • $empty 常量被删除了,现在直接用function()或Function.from()代替
  • $pick 方法被Array.pick取代,参数现在也必须接受数组类型了
  • $merge 方法被Object.merge取代
  • $type 被typeOf取代
  • 函数对象的create方法被删除了,现在可以用函数对象的bind方法替代
  • Browser.Engine 被删除了,需要用其他Browser的API替代

修改后的Roar,放在这个gist里,测试过可以在firefox和chromium上健康使用。IE没有做测试。这个08年的库,眼看四年过去了,用起来依然不错。

作为mootools的铁杆,我还是会一直专一地坚守下去的。(于是,我也已经变成了多年前那些我眼中为旧事物顽抗到底的老家伙了)

Using Google closure library with ClojureScript

Google closure library is shipped with ClojureScript, and could be compiled with ClojureScript into a minimized javascript file. So closure library is doubtlessly the first candidate when you are considering to use an external Javascript library in your cljs browser application.

However, different from clojure’s interoperability with Java, ClojureScript has its own characteristics when you are interoperating with JavaScript and JavaScript based libraries.

Clojure types are not fully compatible with JavaScript types
In ClojureScript, you can never treat a Clojure map as a JavaScript object although they have similar characteristics. You have to do some conversion before passing a clojure map to javascript functions. Matthew Gilliard made a sample of such conversion.

JavaScript package is not Clojure namespace
This could be a common mistake for ClojureScript newbie. Actually, JavaScript doesn’t have concept of “Package” or “Namespace”. Many JavaScript libraries(dojo, Google Closure) made enhancement on this. ClojureScript also takes advantage of this mechanism. So before you start to coding with closure, you may browse closure library API document, and find a module called goog.net which includes lots of types. Then you write this:

(ns myjs
  (:require [goog.net :as gnet]))

But compiler shows you “ERROR: JSC_MISSING_PROVIDE_ERROR. required “goog.net” namespace never
provided at … “. This is not a PATH issue. The root cause is that closure module has a lower granularity than Clojure ones. Types are often contained in their own modules. You can find closure source code in clojurescript/closure/library/closure. Modules are declare with goog.provide function. Thus, you should require this name instead of the logical module name.

(ns myjs
  (:require [goog.net.XhrIo :as gxhr]))

In addition, ClojureScript does not support ‘use’.

Just use full name for JavaScript class
For functions contains in some module, you can refer it with the clojure way:

(ns myjs
  (:require [goog.dom :as dom]))
(dom/$ "element-id")

But for classes, just use the full name and ignore the module alias.

(ns myjs
  (:require [goog.net.XhrIo :as gxhr]))
(def xhr (goog.net.XhrIo.))

These are basic tips before you start using Closure with ClojureScript. Leveraging on Google’s closure library, you can create cross-browser JavaScript application with Clojure easily.

HeatCanvas support for Leaflet

Leaflet is a light weight web mapping library developed by Cloudmade. Leaflet is designed for compatibility with both desktop browser and mobile browser.

HeatCanvas-Leaflet extension enables heat map on Leaflet. You can create heat map layer and add it to Leatlet map:

var heatmap = new L.TileLayer.HeatCanvas("Heat Canvas", map, {},
                        {'step':0.3, 'degree':HeatCanvas.QUAD, 'opacity':0.7});
heatmap.pushData(32.1104, 118.0852, 14);
//push more data ...
map.addLayer(heatmap);

You can find live demo on:
http://sunng87.github.com/heatcanvas/leaflet.html
Mobile browser is also supported. (Tested on Firefox Android and default Android browser)

Find more about HeatCanvas on github page.

Leaflet is still buggy for extension. There is a latlng-pixel coordinate conversion issue in low zoom level, affects this demo. Hope it could be fixed soon.

ngeohash: node module for geohash algorithm

ngeohash是一个geohash的javascript实现,之所以叫做ngeohash是因为到了Publish的时候才发现已经有geohash这个module了。这么令人沮丧的事就不多说了。

安装
npm install ngeohash

使用
var geohash = require(‘ngeohash’);
sys.puts(geohash.encode(32.1717, 118.2342));

详细
访问github的相关页面:https://github.com/sunng87/node-geohash

Update on HeatCanvas and gefr

HeatCanvas的百度地图扩展

感谢@lbt05姐的无私贡献,现在HeatCanvas又增加了百度地图API支持。你可以在你的百度地图中使用heat map了。详情可以参考@lbt05姐撰写的文档,而这里是一个简单的live demo。此外,@lbt05姐还贡献了GoogleMap扩展的patch,帮助我解决了地图拖动后Canvas无法覆盖viewport的bug。再次感谢@lbt05姐。

百度地图支持已经汇入主干,可以在github找到它。

Gefr新增 Jetty WSGI Bridge

昨天为gefr新增了Jetty服务器的支持,这样你可以将自己的Python WSGI程序运行在成熟的Jetty服务器上。性能是大家关心的因素,下面是在我的本机(32位CentOS,双核2.8GHz,4G内存)上一个粗略的测试结果:

100并发,20000请求:

Server Software: gefr-jetty/0.3dev
Server Hostname: localhost
Server Port: 8088

Document Path: /
Document Length: 19 bytes

Concurrency Level: 100
Time taken for tests: 3.120827 seconds
Complete requests: 20000
Failed requests: 0
Write errors: 0
Total transferred: 2584515 bytes
HTML transferred: 380665 bytes
Requests per second: 6408.56 [#/sec] (mean)
Time per request: 15.604 [ms] (mean)
Time per request: 0.156 [ms] (mean, across all concurrent requests)
Transfer rate: 808.44 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 4 114.1 0 3000
Processing: 0 7 18.5 5 1776
Waiting: 0 6 18.5 4 1776
Total: 0 12 115.8 6 3015

Percentage of the requests served within a certain time (ms)
50% 6
66% 7
75% 8
80% 8
90% 10
95% 13
98% 70
99% 74
100% 3015 (longest request)

如果打开KeepAlive,吞吐量可以达到10000以上:

Server Software: gefr-jetty/0.3dev
Server Hostname: localhost
Server Port: 8088

Document Path: /
Document Length: 19 bytes

Concurrency Level: 100
Time taken for tests: 1.749189 seconds
Complete requests: 20000
Failed requests: 0
Write errors: 0
Keep-Alive requests: 20000
Total transferred: 3062142 bytes
HTML transferred: 380266 bytes
Requests per second: 11433.87 [#/sec] (mean)
Time per request: 8.746 [ms] (mean)
Time per request: 0.087 [ms] (mean, across all concurrent requests)
Transfer rate: 1709.36 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.8 0 23
Processing: 0 8 8.0 6 85
Waiting: 0 8 8.0 6 85
Total: 0 8 8.1 6 85

Percentage of the requests served within a certain time (ms)
50% 6
66% 7
75% 8
80% 9
90% 11
95% 20
98% 41
99% 43
100% 85 (longest request)

你可以根据gefr的文档安装它。