google wave邀请8枚
要的请留言,先到先得。
translate
把上面的链接拖到工具栏就可以了。
google docs
使用方法:把上面的链接拖到你的工具栏里,碰到有相关文件超链接的网页时,点击工具栏的google docs按钮,那些链接地址就会变成相应的google docs链接。
BTW:写完才发现谷奥已经发过一个了,白费好多功夫;对付wordpress的自动私货又发不少时间。
从windows自带计算器,到网络上的应用,以及惠普发布的经典计算器 iPhone 应用,都走的是模拟传统计算器界面的路子,但这真的好吗?
传统计算器之所以用小屏幕,很大的原因是节省成本,但在计算机上(以及现代手机上),我们已经有了大屏幕,为什么还要守着原来的操作方式不变呢?
所以我作了这个在线计算器,和传统界面相比,有如下优势:
可以直接写长表达式,比如(8+5)*(4-7);
可以定义变量:x=3,y=x+4
以前的输入完全可见
一些函数:sin,cos...
目前还只是一个原型,一些基本的功能还没有:进制,精度...
javascript中有值类型和引用类型之分,对象是引用类型,其它类型都是值类型;值类型的值是直接存储在变量中,而引用类型和变量是分开存储的,变量实际是对象的引用,或者说变量的值是对象的地址,因而对象的赋值实际只复制地址:
var a = {v:1}
var b = a
b.v = 2
a.v == 2 //true,a和b引用着同一个对象
a = {v:1}//现在a引用着另一个对象
b.v = 2
a.v == 2 //false
在传递函数参数,对象也是只传递引用,因此我们可以用函数参数改变外部对象的属性,但不能用函数参数改变外部对象的引用:
var a = {v:1}
function set(a){
a.v = 2//全局变量a也改变了
a = {v:1}//对全局变量a无影响
}
set(a)
a.v == 2 //true
和c/c++不同,javascript的引用只会指向对象,而不是变量。因为简单的赋值就可以改变引用的对象,所以称为弱引用。
象javascript这样变量不和类型绑定,可以随意改变的,称为动态类型;而c/c++那样的就是静态类型。静态类型的变量在声明时就确定了类型,因此可以编译时类型检查,相对更安全,但灵活性就不足;动态类型的变量无类型,也可以看作是对类型的一种抽象,也就是一种泛型机制。
如果一种语言的类型之间的可以隐式转换,特别是不安全的类型转换,那么就被称为弱类型,反之就是强类型。
javascript中可以通过字面量直接创建对象,比如:
var c = {r:3,
pi:3.14,
area:function(){return this.pi*this.r*this.r}
}
创建多个同类对象时可以通过构造函数:
var circle = function (r){
this.r = r
this.pi = 3.14
this.area = function(){return this.pi*this.r*this.r}
}
var c = new circle(3)
var c2 = new circle(8)
c,c2被称为circle类型的实例。
javascript中的对象可以在运行时增加和删除属性:
c.x=3
delete c.r
上面的例子中,circle每次实例化都会创建相同的pi,area,原型(prototype)可以重用相同的属性:
var circle = function (r){
this.r = r
}
circle.prototype = {
pi:3.14,
area:function(){return this.pi*this.r*this.r}
}
var c = new circle(3)
关于原型:
javascript用原型链实现继承:
var p_circle = function (r,x,y){
circle.call(this,r)
this.x = x
this.y = y
}
p_circle.prototype = new circle(1)
p_circle.prototype.constructor = circle
delete p_circle.prototype.r
可以看到,javascript的继承方式有一定缺陷,我们要继承的是prototype,却必须要执行一次new操作,然后用delete来删除多余的属性,constructor也要手动设置。
在javascript中,函数和属性几乎没有区别,把函数赋值给对象的属性,就成了方法,把方法赋值给全局变量,就是函数。而this是完全动态的,指向调用属性的对象:
var set_a = function (a) {
this.a = a
}
var a = {}
a.set = set_a
a.set('w')
alert(a.a)//w
a.o = {set:set_a}
a.o.set(3)
alert(a.o.a)//3
var r = [2]
set_a.call(r,10)
alert(r.a)//10
在构造函数中,情况更复杂:this事实是个临时对象,当return返回一个对象时,返回的对象是构造出的值,没有return语句时,this就是构造出的值。
可以用instanceof来检查对象的类型:
var a = {}
a instanceof Object//任何对象都是Object
var f = function () {}
f instanceof Function//f是 Function
Array instanceof Function//Array也是 Function
Object instanceof Function//连Object都是 Function
Function instanceof Object// Function又是Object
instanceof会检查整个原型链,要知道具体的构造函数,可以用constructor,但我们已经知道,这个是可以改变的:
Object.constructor == Function
Function.constructor == Function
编译自mdc
下载文件
下载一个文件, 创建一个 nsIWebBrowserPersist 的实例并调用它的 saveURI() 方法, 传递给它一个下载的URL和代表本地文件名/路径的 nsIFile 实例。
// create a persist
var persist = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"].
createInstance(Components.interfaces.nsIWebBrowserPersist);
// with persist flags if desired See nsIWebBrowserPersist page for more PERSIST_FLAGS.
const nsIWBP = Components.interfaces.nsIWebBrowserPersist;
const flags = nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
persist.persistFlags = flags | nsIWBP.PERSIST_FLAGS_FROM_CACHE;
// do the save
persist.saveURI(uriToFile, null, null, null, "", nsIFile);
用自定义progress listener下载二进制文件:
var persist = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
.createInstance(Components.interfaces.nsIWebBrowserPersist);
var file = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
file.initWithPath("C:\\a\\path\\file.bin"); // 下载目的地
var obj_URI = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService)
.newURI(aURLToDownload, null, null);
persist.progressListener = {
onProgressChange: function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress) {
var percentComplete = (aCurTotalProgress/aMaxTotalProgress)*100;
var ele = document.getElementById("progress_element");
ele.innerHTML = percentComplete +"%";
},
onStateChange: function(aWebProgress, aRequest, aStatus, aMessage) {
// do something
}
}
persist.saveURI(obj_URI, null, null, null, "", file);
在调用nsIWebBrowserPersist.saveURI()前, 你需要设置 nsIWebBrowserPersist 实例的progressListener属性为 nsIAuthPrompt对象 。通常, nsIAuthPrompt 会期待显示一个提示框让用户输入认证信息, 但你可以直接返回用户名和密码而不提示用户. 如果你想打开一个登陆提示框,你能调用window watcher的 getNewAuthPrompter()方法。
TODO: 此代码需要测试
var persist = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"].
createInstance(Components.interfaces.nsIWebBrowserPersist);
var hardCodedUserName = "ericjung";
var hardCodedPassword = "foobar";
persist.progressListener = {
// implements nsIAuthPrompt
prompt: function(dialogTitle, text, passwordRealm, savePassword, defaultText, result) {
result.value = hardCodedPassword;
return true;
},
promptPassword: function(dialogTitle, text, passwordRealm, savePassword, pwd) {
pwd.value = hardCodedPassword;
return true;
},
promptUsernameAndPassword: function(dialogTitle, text, passwordRealm, savePassword, user, pwd) {
user.value = hardCodedUserName;
pwd.value = hardCodedPassword;
return true;
}
};
persist.saveURI(urlToFile, null, null, null, "", nsFileInstance);
从一个URL下载图片的简单函数。
// 接受一个URL,返回文件
// 如果文件没找到(404错误)返回empty.
//试试 .jpg, .ico, .gif (甚至 .html).
function GetImageFromURL(url) {
var ioserv = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var channel = ioserv.newChannel(url, 0, null);
var stream = channel.open();
if (channel instanceof Components.interfaces.nsIHttpChannel && channel.responseStatus != 200) {
return "";
}
var bstream = Components.classes["@mozilla.org/binaryinputstream;1"]
.createInstance(Components.interfaces.nsIBinaryInputStream);
bstream.setInputStream(stream);
var size = 0;
var file_data = "";
while(size = bstream.available()) {
file_data += bstream.readBytes(size);
}
return file_data;
}
Sample download observer for Firefox 2 Download manager.
// ******************************
// DownloadObserver
// ******************************
function sampleDownload_init(){
//**** Add download observer
var observerService = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
observerService.addObserver(sampleDownloadObserver, "dl-start", false);
observerService.addObserver(sampleDownloadObserver, "dl-done", false);
observerService.addObserver(sampleDownloadObserver, "dl-cancel", false);
observerService.addObserver(sampleDownloadObserver, "dl-failed", false);
window.addEventListener("unload", function() {
observerService.removeObserver(sampleDownloadObserver, "dl-start");
observerService.removeObserver(sampleDownloadObserver, "dl-done");
observerService.removeObserver(sampleDownloadObserver, "dl-cancel");
observerService.removeObserver(sampleDownloadObserver, "dl-failed");
}, false);
}
var sampleDownloadObserver = {
observe: function (subject, topic, state) {
var oDownload = subject.QueryInterface(Components.interfaces.nsIDownload);
//**** Get Download file object
var oFile = null;
try{
oFile = oDownload.targetFile; // New firefox 0.9+
} catch (e){
oFile = oDownload.target; // Old firefox 0.8
}
//**** Download Start
if (topic == "dl-start"){
alert('Start download to - '+oFile.path);
}
//**** Download Cancel
if(topic == "dl-cancel"){
alert('Canceled download to - '+oFile.path);
}
//**** Download Failed
else if(topic == "dl-failed"){
alert('Failed download to - '+oFile.path);
}
//**** Download Successs
else if(topic == "dl-done"){
alert('Done download to - '+oFile.path);
}
}
}
window.addEventListener("load", sampleDownload_init, false);
本文编译自https://developer.mozilla.org/en/Code_snippets/File_I%2f%2fO。
存取文件需要xpcom组件 nsIFile 或其扩展 nsILocalFile。
var file = Components.classes["@mozilla.org/file/local;1"].
createInstance(Components.interfaces.nsILocalFile);
file.initWithPath("/home");
NOTE: 传递给initWithPath()的路径应该是“原生”格式 (e.g. "C:\\Windows"). 如果要用file:// URIs来初始化,见 nsIIOService .
NOTE: 如果文件不存在,initWithPath() / initWithFile()不抛任何异常. 需要文件存在的方法被执行时会抛出异常, e.g. isDirectory(), moveTo(), etc.
// 得到profile目录
var file = Components.classes["@mozilla.org/file/directory_service;1"].
getService(Components.interfaces.nsIProperties).
get("ProfD", Components.interfaces.nsIFile);
// NOTE: "file" nsIFile的实例对象. 如果要得到文件系统路径,用file.path
可以放在 "ProfD" 位置的字符串:
| String | Meaning |
|---|---|
| ProfD | profile directory |
| DefProfRt | user (e.g., /root/.mozilla) |
| UChrm | %profile%/chrome |
| DefRt | %installation%/defaults |
| PrfDef | %installation%/defaults/pref |
| ProfDefNoLoc | %installation%/defaults/profile |
| APlugns | %installation%/plugins |
| AChrom | %installation%/chrome |
| ComsD | %installation%/components |
| CurProcD | installation (usually) |
| Home | OS root (e.g., /root) |
| TmpD | OS tmp (e.g., /tmp) |
| ProfLD | Local Settings on windows; where the network cache and fastload files are stored |
| resource:app | application directory in a XULRunner app |
| Desk | Desktop directory (e.g. ~/Desktop on Linux, C:\Documents and Settings\username\Desktop on Windows) |
| Progs | User start menu programs directory (e.g., C:\Documents and Settings\username\Start Menu\Programs) |
其它可用的字符串去查源代码: xpcom/io/nsAppDirectoryServiceDefs.h , xpcom/io/nsDirectoryServiceDefs.h .
//install.rdf中扩展的ID
var MY_ID = "myextension@my.name";
var em = Components.classes["@mozilla.org/extensions/manager;1"].
getService(Components.interfaces.nsIExtensionManager);
// the path may use forward slash ("/") as the delimiter
//返回扩展install.rdf的nsIFile对象
var file = em.getInstallLocation(MY_ID).getItemFile(MY_ID, "install.rdf");
var filestring = file.path;
var root = Components.classes["@mozilla.org/file/local;1"].
createInstance(Components.interfaces.nsILocalFile);
root.initWithPath("\\\\.");
var drivesEnum = root.directoryEntries, drives = [];
while (drivesEnum.hasMoreElements()) {
drives.push(drivesEnum.getNext().
QueryInterface(Components.interfaces.nsILocalFile).path);
}
创建一个文件夹,用 nsIFile.create():
var file = Components.classes["@mozilla.org/file/directory_service;1"].
getService(Components.interfaces.nsIProperties).
get("ProfD", Components.interfaces.nsIFile);
file.append("DIR");
if( !file.exists() || !file.isDirectory() ) { // if it doesn't exist, create
file.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0777);
}
在Profile文件夹创建目录"DIR". 更多信息参见 nsIFile.create reference.
用nsIFile.createUnique():
var file = Components.classes["@mozilla.org/file/directory_service;1"].
getService(Components.interfaces.nsIProperties).
get("TmpD", Components.interfaces.nsIFile);
file.append("suggestedName.tmp");
file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666);
// do whatever you need to the created file
alert(file.path);
The file picker component (nsIFilePicker) 可以用来打开标准的打开/保存对话框. 返回用户指定的文件 nsIFile.
你能用nsIFile.path得到特定平台的路径字符串, e.g. "C:\Windows\System32" or "/usr/share".
得到一个文件的URL,用 nsIIOService#newFileURI():
// file is nsIFile
var ios = Components.classes["@mozilla.org/network/io-service;1"].
getService(Components.interfaces.nsIIOService);
var URL = ios.newFileURI(file);
// URL是nsIURI;得到字符串, "file://...", 用URL.spec
从 'file://' URL得到nsIFile,用 nsIFileURL:
var file = URL.QueryInterface(Components.interfaces.nsIFileURL).file;
// file is now a nsIFile
从file://, http://, chrome://, resource:// 和其它 URLs直接载入, 用 XMLHttpRequest 或 nsIChannel (example).
Also note that generally you don't need to use nsIFile::path. Use nsIFile directly wherever possible. An example below shows how you should save a path in user prefs.
下面2个片段展示了存储文件路径到用户preferences的正确方式 (more about preferences in Mozilla):
// |file| is nsILocalFile
// 1. 写路径到prefs
var prefs = Components.classes["@mozilla.org/preferences-service;1"].
getService(Components.interfaces.nsIPrefService).
getBranch("extensions.myext.");
prefs.setComplexValue("filename", Components.interfaces.nsILocalFile, file);
// 2. 从 prefs读路径
var file = prefs.getComplexValue("filename", Components.interfaces.nsILocalFile);
储存对上表中列出的文件夹的相对路径,例如到profile的相对路径,用下面的代码。
// 1. Write to prefs
var relFile = Components.classes["@mozilla.org/pref-relativefile;1"].
createInstance(Components.interfaces.nsIRelativeFilePref);
relFile.relativeToKey = "ProfD"; // or any other string listed above
relFile.file = file; // |file| is nsILocalFile
prefs.setComplexValue("filename",
Components.interfaces.nsIRelativeFilePref, relFile);
// 2. Read from prefs
var value = prefs.getComplexValue("filename",
Components.interfaces.nsIRelativeFilePref);
// |value.file| is the file.
假定文件是到某些目录(e.g.: a user profile directory)的nsIFile点 , 你能用file.append("myfile.txt")制作那个目录的 myfile.txt文件点。
下面的片段制作给定目录的“子文件”/子目录nsIFiles数组。你可以用nsIFile.isDirectory() and nsIFile.isFile()来分辨文件和文件夹。
// file is the given directory (nsIFile)
var entries = file.directoryEntries;
var array = [];
while(entries.hasMoreElements())
{
var entry = entries.getNext();
entry.QueryInterface(Components.interfaces.nsIFile);
array.push(entry);
}
// |file| is nsIFile
var data = "";
var fstream = Components.classes["@mozilla.org/network/file-input-stream;1"].
createInstance(Components.interfaces.nsIFileInputStream);
var cstream = Components.classes["@mozilla.org/intl/converter-input-stream;1"].
createInstance(Components.interfaces.nsIConverterInputStream);
fstream.init(file, -1, 0, 0);
cstream.init(fstream, "UTF-8", 0, 0); // you can use another encoding here if you wish
let (str = {}) {
cstream.readString(-1, str); // read the whole file and put it in str.value
data = str.value;
}
cstream.close(); // this closes fstream
alert(data);
NOTE: 下面的简单代码不操纵非ASCII字符。 如何读其它的字符编码见Reading textual data 。
// open an input stream from file
var istream = Components.classes["@mozilla.org/network/file-input-stream;1"].
createInstance(Components.interfaces.nsIFileInputStream);
istream.init(file, 0x01, 0444, 0);
istream.QueryInterface(Components.interfaces.nsILineInputStream);
// read lines into array
var line = {}, lines = [], hasmore;
do {
hasmore = istream.readLine(line);
lines.push(line.value);
} while(hasmore);
istream.close();
// do something with read data
alert(lines);
这允许读文件时不死锁UI线程。
var appInfo=Components.classes["@mozilla.org/xre/app-info;1"]
.getService(Components.interfaces.nsIXULAppInfo);
var isOnBranch = appInfo.platformVersion.indexOf("1.8") == 0;
var ios=Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var fileURI=ios.newFileURI(file);
var channel = ios.newChannelFromURI(fileURI);
var observer = {
onStreamComplete : function(aLoader, aContext, aStatus, aLength, aResult)
{
alert(aResult);
}
};
var sl = Components.classes["@mozilla.org/network/stream-loader;1"].
createInstance(Components.interfaces.nsIStreamLoader);
if (isOnBranch) {
sl.init(channel, observer, null);
} else {
sl.init(observer);
channel.asyncOpen(sl, channel);
}
得到一个PNG文件的数据:
var ios = Components.classes["@mozilla.org/network/io-service;1"].
getService(Components.interfaces.nsIIOService);
var url = ios.newURI(aFileURL, null, null);
if (!url || !url.schemeIs("file")) throw "Expected a file URL.";
var pngFile = url.QueryInterface(Components.interfaces.nsIFileURL).file;
var istream = Components.classes["@mozilla.org/network/file-input-stream;1"].
createInstance(Components.interfaces.nsIFileInputStream);
istream.init(pngFile, -1, -1, false);
var bstream = Components.classes["@mozilla.org/binaryinputstream;1"].
createInstance(Components.interfaces.nsIBinaryInputStream);
bstream.setInputStream(istream);
var bytes = bstream.readBytes(bstream.available());
// file is nsIFile, data is a string
var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"].
createInstance(Components.interfaces.nsIFileOutputStream);
// use 0x02 | 0x10 to open file for appending.
foStream.init(file, 0x02 | 0x08 | 0x20, 0666, 0);
// write, create, truncate
// In a c file operation, we have no need to set file mode with or operation,
// directly using "r" or "w" usually.
// 如果你确信数据中永远不会有非ASCII数据,你也可以直接执行foStream.writeData
var converter = Components.classes["@mozilla.org/intl/converter-output-stream;1"].
createInstance(Components.interfaces.nsIConverterOutputStream);
converter.init(foStream, "UTF-8", 0, 0);
converter.writeString(data);
converter.close(); // this closes foStream
NOTE: nsIFileOutputStream::init()函数中的状态标志文档在 PR_Open. 更多信息参见 nsprpub/pr/include/prio.h
写PNG数据到一个文件
// pngBinary 已经存在
var aFile = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
aFile.initWithPath( "/tmp/mypicture.png" );
aFile.createUnique( Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 600);
var stream = Components.classes["@mozilla.org/network/safe-file-output-stream;1"].
createInstance(Components.interfaces.nsIFileOutputStream);
stream.init(aFile, 0x04 | 0x08 | 0x20, 0600, 0); // write, create, truncate
stream.write(pngBinary, pngBinary.length);
if (stream instanceof Components.interfaces.nsISafeOutputStream) {
stream.finish();
} else {
stream.close();
}
扩展开发最共同的问题之一是如何后台执行到工作地点的这段路,有闲置的电影公司、昂贵到有些浪费的首饰铺、酒店以及豪华像酒店的住宅区、成年人的游乐场与难得长时间操作。如果不小心会在操作完成前挂起应用。 这儿有几个技巧.
用setTimeout来计划任务
后台执行工作最容易和安全的方法是分割成小片段来执行。 For example:
这个函数预定每100毫秒执行。 假定函数每次执行很短时间应用会继续响应。 Once the function has completed whatever work it is performing it should just return early rather than reschedule the execution.
在主线程排队任务
不用setTimeout把任务放到主线程的简单方法,是创建一个简单的可运行对象并用 Thread Manager附加。这里有个函数可以用来替代 setTimeout:
因为这个函数跑在主线程,它可能使UI无响应。解除这个限制,你需要一个真正的线程来创建后台任务。
创建一个真正的线程
用真正的线程更容易出错。 尤其是牵涉DOM和许多其它组件时有许多陷阱.可能导致整个应用崩溃或挂起。
这里展示了一个简单的对象,其run方法被创建的后台线程调用。线程安全的更多内容见 Thread Manager 文档。
等待一个后台任务完成