Saturday, March 22, 2008

google gears on firefox2

Problem: the latest google gears version 0.3.11.0 can't install on firefox2.0.0.12.
Resolution: download google gears 0.3.2.0 version from neyric's blog , install it and restart firefox, google gears works.

Google AJAX Language API - Basic Scripting HTTP Request


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google AJAX Language API - Basic Translation</title>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">

google.load("language", "1");

function initialize() {
google.language.translate("Hello world", "en", "zh-CN", function(result) {
if (!result.error) {
var container = document.getElementById("translation");
container.innerHTML = result.translation;
}
});

var text = "简体中文测试";
google.language.detect(text, function(result) {
if (!result.error) {
var language = 'unknown';
for (l in google.language.Languages) {
if (google.language.Languages[l] == result.language) {
language = l;
break;
}
}
var container = document.getElementById("detection");
container.innerHTML = text + " is: " + language + "";
}
});
}
google.setOnLoadCallback(initialize);

</script>
</head>
<body>
<div id="translation"></div>
<div id="detection"></div>
</body>
</html>

Google get response and execute response text through scripting http request. Scripting HTTP Request step:
  • First add an dynamic "script" node after head, even if document source have not head tag, javascript will still run right. If add "script" node to document.body node, javascript may be error because javascript can't get body element.
  • Then set this "script" node "src" to get google translate service, and it will return a javascript statement, and when "script" loaded, it will be executed auto.
  • At last, Delete this "script" node.
Here is an simple example:
1. javascript file - "getTextWithScript.js";

var getTextWithScript = function(callback) {
// Create a new script element and add it to the document.
var head=document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.type="text/javascript";
script.charset="utf-8";
head.appendChild(script);

// Get a unique function name.
var funcname = "func" + getTextWithScript.counter++;

// Define a function with that name, using this function as a
// convenient namespace. The script generated on the server
// invokes this function.
getTextWithScript[funcname] = function() {
// Pass the text to the callback function
callback(Array.prototype.slice.call(arguments));

// Clean up the script tag and the generated function.
script.onload = null;
head.removeChild(script);
delete script;
delete getTextWithScript[funcname];
}

// Encode the URL we want to fetch and the name of the function
// as arguments to the jsquoter.php server-side script. Set the src
// property of the script tag to fetch the URL.
script.src = "jsquoter.php" + "?func=" + encodeURIComponent("getTextWithScript." + funcname);
}

// We use this to generate unique function callback names in case there
// is more than one request pending at a time.
getTextWithScript.counter = 0;

2. server process request file - "jsquoter.php";

<?php
// Tell the browser that we're sending a script
header("Content-Type: text/javascript");
// Get arguments from the URL
$func = $_GET["func"];
// process
echo "$func('test', 'from', 'php', 'file');";
?>

3. test file - "getTextWithScript.html":

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Scripting HTTP</title>
<script type="text/javascript" src="getTextWithScript.js"></script>
<script type="text/javascript">
function callback(){
document.getElementById('main').innerHTML = arguments[0].join(" ");
}
getTextWithScript(callback);
</script>
</head>
<body>
<div id="main"></div>
</body>
</html>

test file will get result: "test from php file"

Simple JavaScript Inheritance

John Resig published a great article on his blog, which brought out a smiple javascript inheritance resolution:

// Inspired by base2 and Prototype
(function(){
var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;

// The base Class implementation (does nothing)
this.Class = function(){};

// Create a new Class that inherits from this class
Class.extend = function(prop) {
// "super" is a FutureReservedWord in ECMAScript v3.
var _super = this.prototype;

// Instantiate a base class (but only create the instance,
// don't run the init constructor)
// SubClass may define init() function, "new this()" should prevent init() function to be excuted.
initializing = true;
var prototype = new this();
initializing = false;

// Copy the properties over onto the new prototype
for (var name in prop) {
// Check if we're overwriting an existing function
prototype[name] = typeof prop[name] == "function" &&
typeof _super[name] == "function" && fnTest.test(prop[name]) ?
(function(name, fn){
// return a cloures, which return results of function prop[name](arguments)
return function() {
//save a reference to the old this._super (disregarding if it actually exists)
//and restore it after we're done.
var tmp = this._super;

// Add a new ._super() method that is the same method
// but on the super-class
// fn function body has statement such as "this._super()"
// this._super will be invoked by function fn
this._super = _super[name];

// The method only need to be bound temporarily, so we
// remove it when we're done executing
var ret = fn.apply(this, arguments);
this._super = tmp;

return ret;
};
})(name, prop[name]) :
prop[name];
}

// The dummy SubClass constructor
function SubClass() {
// All construction is actually done in the init method
if ( !initializing && this.init )
this.init.apply(this, arguments);
}

// Populate our constructed prototype object
SubClass.prototype = prototype;

// Enforce the constructor to be what we expect
// else SubClass.constructor is Function
SubClass.constructor = SubClass;

// And make this SubClass extendable
SubClass.extend = arguments.callee;

return SubClass;
};
})();

Example:

var A = Class.extend({
value:"A",
doStuff:function(){
return this.value;
}
});
var B = A.extend({});
var C = B.extend({
doStuff:function(){
return this._super();
}
});
var c = new C;
alert(c.doStuff());

function doc(argument) {
document.write(argument);
}

var Person = Class.extend({
init: function(isDancing){
this.dancing = isDancing;
},
dance: function(){
return this.dancing;
}
});
doc(Person.constructor);

var Ninja = Person.extend({
init: function(){
this._super( false );
},
dance: function(){
// Call the inherited version of dance()
return this._super();
},
swingSword: function(){
return true;
}
});
doc(Ninja.constructor);

var p = new Person(true);
doc(p.dance()); // => true

var n = new Ninja();
doc(n.dance()); // => false
doc(n.swingSword()); // => true

// Should all be true
doc(p instanceof Person && p instanceof Class && n instanceof Ninja && n instanceof Person && n instanceof Class);

Friday, March 21, 2008

difference of function toString() in IE7 and FF2

IE7:
alert(/x/.test(function(){'x';}))
// => true
(function(){'x';}).toString();
// => "(function(){'x';})"

FF2:
alert(/x/.test(function(){'x';}))
// => false
(function(){'x';}).toString();
// => "function () { }"

Thursday, March 20, 2008

hostname not match (OpenSSL::SSL::SSLError)

1. install soap4r
$> gem install soap4r
2. run soap request
driver = SOAP::RPC::Driver.new
driver.wiredump_dev = STDERR if $DEBUG
driver.wiredump_file_base = "soap_result"
......
3.get error as below:


C:/ruby/lib/ruby/1.8/openssl/ssl.rb:91:in `post_connection_check': hostname not match (OpenSSL::SSL::SSLError)
from C:/ruby/lib/ruby/gems/1.8/gems/httpclient-2.1.2/lib/httpclient.rb:1052:in `post_connection_check'
from C:/ruby/lib/ruby/gems/1.8/gems/httpclient-2.1.2/lib/httpclient.rb:1467:in `connect'
from C:/ruby/lib/ruby/1.8/timeout.rb:56:in `timeout'
from C:/ruby/lib/ruby/1.8/timeout.rb:76:in `timeout'
from C:/ruby/lib/ruby/gems/1.8/gems/httpclient-2.1.2/lib/httpclient.rb:1454:in `connect'
from C:/ruby/lib/ruby/gems/1.8/gems/httpclient-2.1.2/lib/httpclient.rb:1311:in `query'
from C:/ruby/lib/ruby/gems/1.8/gems/httpclient-2.1.2/lib/httpclient.rb:932:in `query'
from C:/ruby/lib/ruby/gems/1.8/gems/httpclient-2.1.2/lib/httpclient.rb:2131:in `do_get_block'
... 7 levels...
from C:/ruby/lib/ruby/gems/1.8/gems/soap4r-1.5.8/lib/soap/rpc/proxy.rb:143:in `call'
from C:/ruby/lib/ruby/gems/1.8/gems/soap4r-1.5.8/lib/soap/rpc/driver.rb:181:in `call'

4. google this problem and get resolution as below:
driver.options['protocol.http.ssl_config.verify_mode'] = OpenSSL::SSL::VERIFY_NONE
or
driver.options['protocol.http.ssl_config.verify_mode'] = 0
or
driver.options['protocol.http.ssl_config.verify_mode'] = ""
or
driver.options['protocol.http.ssl_config.verify_mode'] = OpenSSL::SSL::VERIFY_PEER
driver.options['protocol.http.ssl_config.ca_file'] = '/etc/ssl/certs/certification_authority.crt'
driver.options['protocol.http.ssl_config.client_cert'] = '/etc/ssl/certs/client.cert'
driver.options['protocol.http.ssl_config.client_key'] = '/etc/ssl/certs/client.key'

Reference: http://www.fngtps.com/2007/03/openssl-ssl-sslerror-with-soap4r-and-the-rubyforge-gem

Wednesday, March 19, 2008

Javascript on property href of link

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<html>
<head>
<title>JavaScript Test</title>
</head>

<body>
<a href="http://www.test.com/Javascript/">test a href when it be clicked will load another web page and then location to its original destination url.</a><br />
<a href="http://www.test.com/Javascript/" onclick="return false;">test a href which property value of onclick return false</a><br />
<a href="javascript:void(0);">test a href with value:"javascript: void(0);"</a>
<script type="text/javascript">
var a = document.getElementsByTagName('a')[0];
var h = a.href;
a.href = "#"; // a.href = "javascript: void(0);"
//a.target = "_self";
a.onclick = function(){
var img = new Image(1,1);
img.src = "http://www.google.com/images/firefox/sprite.png" + (new Date).getTime();
f = function(){setTimeout("window.location = h", 1000);};
img.onload=f;
img.onerror=f;
return false;
};
</script>
</body>
</html>

PHP5 get http response body using CURL library

get response body of specified web page using php5, such as google homepage.

<?php
ob_start();

$ch = curl_init("http://www.google.com/");
curl_exec($ch);
curl_close($ch);
$retrievedhtml = ob_get_contents();
ob_end_clean();
// ob_end_flush();

echo $retrievedhtml;
?>

Tuesday, March 18, 2008

[rails api]filter_parameter_logging API usage

Class ActionController::Base

filter_parameter_logging(*filter_words) {|key, value| ...}
Replace sensitive paramater data from the request log. Filters paramaters that have any of the arguments as a substring. Looks in all subhashes of the param hash for keys to filter. If a block is given, each key and value of the paramater hash and all subhashes is passed to it, the value or key can be replaced using String#replace or similar method.

Examples:

filter_parameter_logging
=> Does nothing, just slows the logging process down

filter_parameter_logging :password
=> replaces the value to all keys matching /password/i with "[FILTERED]"

filter_parameter_logging :foo, "bar"
=> replaces the value to all keys matching /foo|bar/i with "[FILTERED]"

filter_parameter_logging { |k,v| v.reverse! if k =~ /secret/i }
=> reverses the value to all keys matching /secret/i

filter_parameter_logging(:foo, "bar") { |k,v| v.reverse! if k =~ /secret/i }
=> reverses the value to all keys matching /secret/i, and
replaces the value to all keys matching /foo|bar/i with "[FILTERED]"

Sunday, March 16, 2008

Modify hosts file to access blogspot.com

72.14.219.190 yourblogname.blogspot.com
add this line to /etc/hosts or C:\windows\system32\drivers\etc\hosts file end.

首先,在任意目录( 比如C:\)下面,建立一个proxy.pac文件(文本文件,用notepad来写即可)
在该文件中,写入以下内容:

function FindProxyForURL(url, host)
{
if ( dnsDomainIs(host, ".blogspot.com")){
return "PROXY 72.14.219.190:80";
}
if(dnsDomainIs(host, ".wikipedia.org")){
return "PROXY 66.230.200.101:80";
}
if(dnsDomainIs(host, ".wordpress.com")){
return "PROXY 72.232.101.41:80";
}
if(dnsDomainIs(host, ".livejournal.com")){
return "PROXY 204.9.177.19:80";
}
}

在Firefox中,Tools->Options->Advanced->Network->Settings,在Automatic proxy configuration URL中,填入file:///C:/proxy.pac
按Reload按钮,然后重启Firefox

Reference:
http://www.kompakar.com.cn/kukoo/?p=189

Enable terminal colorized output and print out chinese character

$> man ls
.....


-G Enable colorized output. This option is equivalent to defining
CLICOLOR in the environment. (See below.)
-w Force raw printing of non-printable characters. This is the
default when output is not to a terminal.

If you want terminal can display chinese character and colorized output, you should add a line to ~/.bashrc or ~/.profile or ~/.bash_profile:
alias ls='ls -wG'
or:
alias ll='ls -lawG'

Saturday, March 15, 2008

GeoIP libarary install for apache2 and ruby

1. Download the C API from http://www.maxmind.com/download/geoip/api/c/
2. Do the following to build and install GeoIP:
{{{
    ./configure
    make
    make check
    sudo make install
}}}
3. Download the ruby API from http://www.maxmind.com/download/geoip/api/ruby/
4. Do the following to build and install GeoIP ruby:
{{{
    ruby extconf.rb --with-geoip-include=/usr/local/include
    make
    sudo make install
}}}
5. Install mod_geoip
{{{
    sudo apxs -i -a -L/usr/local/lib -I/usr/local/include -lGeoIP -c mod_geoip.c
}}}
6. place
{{{
<IfModule mod_geoip.c>
    GeoIPEnable On
    GeoIPDBFile /usr/local/share/GeoIP/GeoIP.dat
LoadModule geoip_module /usr/lib/httpd/modules/mod_geoip.so
</IfModule>
}}}
inside your httpd.conf file.
If mod_geoip doesn't work, try taking the LoadModule geoip_module line outside the block.
If you get a "libGeoIP.so.1: cannot open shared object file: No such file or directory" error, add /usr/local/lib to /etc/ld.so.conf then run
/sbin/ldconfig /etc/ld.so.conf
7. mod_geoip can't install on Mac OSX because some unknown problem.
8. GeoIp ruby module install on Mac OSX is also some problem, but can install follow instruction of INSTALL
9. ruby example:


require 'net/geoip'

# access_type # Net::GeoIP::TYPE_DISK and Net::GeoIP::TYPE_RAM
#
g = Net::GeoIP.new(Net::GeoIP::TYPE_DISK)
# g = Net::GeoIP.open(db_filename[, access_type])


puts g.country_code_by_addr('220.181.37.55')
puts g.country_code_by_name('www.baidu.com')
puts g.country_code3_by_addr('220.181.37.55')
puts g.country_code3_by_name('www.baidu.com')
puts g.country_name_by_addr('220.181.37.55')
puts g.country_name_by_name('www.baidu.com')
puts g.country_id_by_addr('220.181.37.55')
puts g.country_id_by_name('www.baidu.com')
# >> CN
# >> CN
# >> CHN
# >> CHN
# >> China
# >> China
# >> 48
# >> 48

# puts g.region_by_addr('220.181.37.55') # Invalid database type GeoIP Country Edition, expected GeoIP Region Edition, Rev 1
# puts g.region_by_name('www.baidu.com') # Invalid database type GeoIP Country Edition, expected GeoIP Region Edition, Rev 1

# g.database_info() # Misc database info
# g.update_database(your_key_here[,debug]) # Updates your database

Reference:
1. http://www.maxmind.com/download/geoip/api/ruby/INSTALL
2. http://rubyforge.org/scm/?group_id=947
3. http://www.maxmind.com/app/ruby
4. http://www.howtoforge.com/mod-geoip-apache2-debian-etch
5. http://www.maxmind.com/app/mod_geoip

Get parameter using php and compress queryString using javascript

在php中如果从一个form提交一个数组给php页面的时候,一般在form中就将对应的变量写为: name="arr[]", 这样就可以在接收页面直接用php取到$arr = $_POST["arr"];取到这个数组,如果用get方法传送的query String是这样子的话: ?arr=1&arr=2&arr=3 时, php则在用$_GET["arr"]获得arr时则会只得到最后赋值的3,这是php处理query String的方法。
对于SERVER一端还是会正常收到这个请求的query String: ?arr=1&arr=2&arr=3,仍可以用server端的脚本语言重新对参数进行分析,也可以用javascript在client端分析query String。
javascript compress query string:


function compress(data){
var q = {}, ret = "";
data.replace(/([^=&]+)=([^&]*)/g, function(m, key, value){
q[key] = (q[key] ? q[key] + "," : "") + value;
});
for ( var key in q )
ret = (ret ? ret + "&" : "") + key + "=" + q[key];
return ret;
}

or:

function compress(data) {
data = data.replace(/([^&=]+=)([^&]*)(.*?)&\1([^&]*)/g, "$1$2,$4$3");
return /([^&=]+=).*?&\1/.test(data) ? compress(data) : data;
}

Reference:
Jone Resig's Blog

Axis configure error

copy axis webapp to tomcat webapp and visit:
http://localhost:8080/axis/happyaxis.jsp
Axis Happiness Page
Examining webapp configuration

.....

Found JAXP implementation ( javax.xml.parsers.SAXParserFactory ) at an unknown location

Error: could not find class javax.activation.DataHandler from file activation.jar
Axis will not work.
See http://java.sun.com/products/javabeans/glasgow/jaf.html

solution: put activation.jar and mailapi.jar under the common\lib of the Tomcat. Other locations do not work.
By the way, Axis optional component XML security jar xmlsec.jar should put under the same place, tomcat/common/lib, if axis has not found it.

Thursday, March 13, 2008

Create your own apple startupitems

$> mkdir Tomcat
$> cd Tomcat
$> cp /System/Library/StartupItems/Apache/Apache ./Tomcat
$> cp /System/Library/StartupItems/Apache/StartupParameters.plist .
$> vi StartupParameters.plist


{
Description = "Tomcat servlet engine";
Provides = ("Servlet Engine");
Requires = ("DirectoryServices");
Uses = ("NFS");
OrderPreference = "None";
}

$> vi Tomcat

#!/bin/sh

##
# Tomcat Servlet Engine
##

. /etc/rc.common

StartService ()
{
ConsoleMessage "Starting Tomcat"
/usr/local/jakarta-tomcat-4.1.18/bin/startup.sh
}

StopService ()
{
ConsoleMessage "Stopping Tomcat"
/usr/local/jakarta-tomcat-4.1.18/bin/shutdown.sh
}

RestartService ()
{
ConsoleMessage "Restarting Tomcat"
/usr/local/jakarta-tomcat-4.1.18/bin/shutdown.sh
/usr/local/jakarta-tomcat-4.1.18/bin/startup.sh
}

JAVA_HOME=/Library/Java/Home; export JAVA_HOME
RunService "$1"

$> mv Tomcat /Library/StartupItems/

reboot and accept the chmod of Tomcat, reboot again.

Reference:
http://www.oreilly.com/pub/a/mac/2003/10/21/startup.html

Open openssl module for PHP5 in windows

Warning: SoapClient::SoapClient() [function.SoapClient-SoapClient]: I/O warning : failed to load external entity "http://localhost:9090/test?wsdl" in test.php on line 13

google了一下,是因为PHP的openssl模块没有打开。
修改php.ini文件,去掉extension=php_openssl.dll前面的注释。
将PHP安装目录下的libeay32.dll 拷贝一份到system32目录下,重启Apache即可。
如果不行可以把ssleay32.dll也拷过去重启。
完成后可以在phpinfo()中看到类似消息如下:
openssl
OpenSSL support enabled
OpenSSL Version OpenSSL 0.9.8e 23 Feb 2007

Redirect STDOUT in Ruby

若想对标准输入、输出、错误输出等进行重定向(redirect)时,可以使用IO#reopen:
STDOUT.reopen("/tmp/foo", "a+")
不建议使用: $stdout = File.open("/tmp/foo", "a+"), 这还有个输出缓存的过程,需要用IO#sync(IO#fsync)或者是IO#flush才会将输入写入log中。


Reference:
http://www.ruby-lang.org.cn/forums/archiver/tid-39.html

Tuesday, March 11, 2008

Relationship of Object and Kernel

# Object mixes in the Kernel module, making the built-in kernel functions globally accessible. The instance methods of Object are defined by the Kernel module.


p Kernel.instance_methods(false).length # 42 # Object instance methods
p Kernel.methods(false).length # 65 # Kernel module methods
p Module.instance_methods(false).length # 34 # Module instance methods, Kernel module is instance of Module class.
p Kernel.methods.length # 134

kernel_instance_methods = Kernel.instance_methods(false)
kernel_module_methods = Kernel.methods(false)
module_instance_methods = Module.instance_methods(false)

kernel_methods = [] # 134

Kernel Module include module methods(such as puts/p/gsub...) and module instance methods(such as __id__/__send__/id/send/object_id...), Object class has not defined instance methods, its instance methods are mixed in from Kernel module.

Kernel.methods include three group methods: object instance methods and Kernel module methods and instance methods of class Module.
class A
def self.method1
self.name
end
end
p A.method1
# A
p A.methods(false)
# ["method1"]

Thursday, March 06, 2008

IE8 Developer tools

实现了许多firebug的功能,如CSS、CSS BOX、DOM查看、javascript调试、断点等

Wednesday, March 05, 2008

CSS inline-box and auto margin

line-height只对内联元素有效,对于块元素设置其实是作用在其内部的内联元素上。
水平七属性中margin-left、margin-right、width的值可以设置为auto,其他四个属性不能设置为auto。
水平七属性相加的值总是等于其父元素的width值。
margin的值可以取负值,padding和width不能取负值。
一行中,不同内联元素的内联框位置并不一定相同,根据line-hight、font-size计算,并受vertical-align影响。以下公式在vertical-align基于baseline的计算方法:
内联框的上边框位置:font-size - (font-size - line-height) / 2
内联框的下边框位置:font-size + (font-size - line-height) / 2
行间距等于该行中所有内联元素的内联框(inline-box)的最高位置减最低位置。

Tuesday, March 04, 2008

IE bug: id and name in getElementById function


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title> Test id and name property in IE7 </title>
</head>
<body>
<input name="t1"/> Input tag with name t1, IE7 will alert "INPUT"<br />
<a name="t1">Anchor t1, if remove input element, IE7 will alert "A"</a><br />
<div id="t1">div tag with id t1</div>

<script type="text/javascript">
alert(document.getElementById('t1').tagName);
</script>
</body>
</html>

Opera has the same problem.

Monday, March 03, 2008

margin 和内联元素(inline elements)的关系

当将margin应用于内联元素时,margin的上下边距将不会影响到行高[产生的margin是存在的,不过因其是透明的故不能看得到],左右边距则会影响内联元素的左右间距。如果将一个将粗的border应用于内联元素上时,行高也不会发生变化,border将会覆盖其他元素的显示。
能够改变全文本的行间距的CSS属性只有:
1、line-height
2、font-size
3、vertical-align

Saturday, March 01, 2008

关于CSS中的position和float的二点说明

1、当float的元素的margin为负值时,其周边元素内容可能会覆盖到float元素上面。当float元素宽度大于容器宽度并margin为负值时,会使得float元素在容器二边都超出。
2、position: absolute的元素的一系列上级元素如果具有position:absolute/relative/fixed属性时,会根据其上级元素进行绝对定位。如果其上级元素没有position属性,则根据整个html文档定位。