我把整个的修改过程和中间出现的bug写在了我的博客上, 有兴趣的可以上博客阅读,
http://blog.2i2j.com, 下面内容转自博客
前面经过两次的修改, 差不多解决了downthemall!在下载的文件名中出现乱码的问题, 但还是有一个问题没有解决,就是在下载过程中“dta管理器”中显示文件名还是乱码的, 虽然说这个问题不大, 等下载完毕后, 关闭dta管理器再重新打开就显示为正确了,可人的追求总是无止境的, 所以虽然问题不大, 可看起来就是不爽。 所以又重新阅读了整体的代码,最后弄明白了这个“dta管理器”中的乱码存在的原因, 然后重新修改了代码, 彻底解决了出现的乱码问题, 包括在log文件中也不会再出现乱码了。
此次修改如果没有出现bug的话应该就是最后一次修改了, 因为从测试来看已经解决了这个根本性的乱码问题。 这个事情就暂告一个段落, 我把中间修改的过程和修改的地方详细的描写一遍, 算是给自己记个笔记, 同时也可以给需要的人一个参考。
首先说说修改乱码的机理, 就是以什么方式修正乱码。 众所周知,乱码的产生是因为本身的编码和显示的编码不是同一个编码从而看起来就成了乱码,由于mozilla中读取字符的方式都是采用iso8859_1编码的, 但实际每个网页的编码都有变化, 这个时候如果都是单字节字符没有任何问题,因为在任何一个编码情况下, 单字节都是同一个编码, 所以都不会读错, 但读到多字节字符的时候, 因为iso8859_1编码是默认单字节的,所以导致无法识别, 从而产生乱码, 我们这里要解决的就是把用iso8859_1编码的读取,仍旧还原成原来网页的编码, 从而可以识别多字节字符,不至于产生乱码, 对这个转换主要就用到了一个函数ConvertToUnicode()。 所有的乱码修改的地方都贯穿了这个函数。
下面就来说说我修改乱码的思路, 我修改乱码是这样的一个思路, 既然乱码是因为多字节字符引起的,而多字节字符在相应的网页编码下都能良好的工作,那我们就用ConvertToUnicode()这个函数把由于iso8859_1编码读取的字符还原到原始网页编码的字符那就ok了,可从哪里得到网页的编码呢? 这里我就用了下载页面的编码来作为参考, 也就是用了下载中经常说到了refer页面(即参考页面)的编码。所以在这个修改的乱码中有一点注意, 如果本次下载没有refer页面, 那就不会用ConvertToUnicode()进行编码转换,从而如果出现多字节字符, 还是会出现乱码。 这个没有办法, 因为我实在不能知道这个编码是什么的。
介绍完了思路, 下面就说说我修改的地方, 本次修改总共涉及到了一下几个文件, dta.jar/content/dmoverlay.js, dta.jar/content/menu.js, dta.jar/content/dta/overlayfunction.js, dta.jar/content/dta/internalfunction.js 和 dta.jar/content/dta/down.js ,下面我一个一个说明修改的部分。
1、dta.jar/content/dmoverlay.js
这个文件是用来获取下载的文件, 所有的参数都是从这个文件生成然后传入其他文件然后进行下载过程的, 我们在这里要做的就是换取refer页面的编码, 我用了这个语句。
if(this.referrer != “”)
this.description = dialog.mLauncher.source.originCharset;
else
this.description =”"
这个语句就是用来判断refer是否为空, 如果有refer, 那把description设置成为该网页的编码,注意我在修改代码的时候没有增加相应的参数, 而是用了description作为编码传递的参数,这个description本来是作为一个注释用的。 后面都是这个方式实现的。 因为我觉得注释不是很重要, 而且也几乎没有用到,而增加参数这个工程量太大,所以就采用了这个方法。
在这个文件中还修改了一处地方, 这个地方的修改跟下载文件名的乱码没有关系, 这个部分是用来在下载对话框中显示dta一键下载,并在下面显示下载的路径, 这个下载路径中如果有多字节字符就会出现乱码, 这个地方修改后就可以编码这个问题, 不会再出现乱码, 具体的代码是:
var converter = Components.classes[”@mozilla.org/intl/scriptableunicodeconverter”]
.createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
converter.charset = ‘UTF-8′;
dir = converter.ConvertToUnicode(dir);
dmoverlay.js文件大的修改就这两点, 最后修改的一点是参数传递, 原版的downthemall在传递是将description直接用“”进行传递的, 我这里就用了description, 代码如下(注释掉的就是原始代码):
//DTA_AddingFunctions.saveSingleLink(turbo, this.url, this.referrer, “”);
DTA_AddingFunctions.saveSingleLink(turbo, this.url, this.referrer, this.description);
×××××××××××××××××××××××××××××××××××××××××××××
2、dta.jar/content/menu.js
这个文件是在右键下载菜单下载文件时的入口点, 上面的dmoverylay.js是弹出下载框的入口点,所以第一次(2007-03-16修改版)的时候我没有考虑到这里, 因为我不习惯用右键下载, 从而在某些朋友使用的时候出现了问题。这个是右键菜单和批量下载的入口点, 所以这里修改的地方跟dmoverlay.js差不多, 就是获取网页的编码, 然后传递编码。代码如下(具体修改的位置请直接看文件, 所有的修改处都以//start modified by hongfengye开始到//end modified by hongfengye结束):
document.commandDispatcher.focusedWindow.document.URL ? document.commandDispatcher.focusedWindow.document.characterSet : “”
3、dta.jar/content/dta/overlayfunction.js
这个文件里面要改的地方有一个是涉及到log文件中的乱码的, log文件出现乱码的原因同上, 这个代码是从原版中抄袭的, downthemall!还涉及到 一个文件, dta_history.xml, 这个文件是用来放下载的文件的信息的, 这个文件没有乱码,但log文件却是有乱码的, 原因就在于这个dta_history.xml做了乱码处理, 而log文件没有,我就把dta_history.xml中的编码转换部分抄过来了, 代码如下:
var converter = Components.classes[”@mozilla.org/intl/saveascharset;1″]
.createInstance(Components.interfaces.nsISaveAsCharset);
converter.Init(’utf-8′, 1, 0);
text = converter.Convert(text);
另外还修改了两处地方, 但不知道这两个地方的代码是干吗用的, 但还是修改了, 怕到时候出现bug。 这两个地方就是var dragObserverTdTa 和 var dragObserverdTa , 这两处中涉及到了一个function - DTA_AddingFunctions.saveSingleLink , 所以在里面也传递了一个description参数。但我不知道这两个var是干吗的, 我也没有测试出来, 先暂时放放。(突然想到, 这个可能是拖放到“dta管理器”中的时候运行的函数。
4、dta.jar/content/dta/internalfunction.js
这个文件中有一个最重要的函数, 就是getUsablefileName(), 这个函数就是用来获取文件名的,所有的文件名乱码在这里修改是最彻底的, 只要这里获取的时候不是乱码就不会是乱码了。 所以我修改了这个函数,但因为这个函数中间没有办法得到网页编码, 所以编码必须从外部传递过来, 所以我就把函数加两个一个参数传递, 把编码从外部传递到函数内部。修改这个函数可以免去修改其他多处地方, 这是一个优点。 具体修改后的代码如下(原代码请参考原始版本):
getUsableFileName : function(tochar) {
var t = this.trim().removeArguments().removeFinalBackSlash().split(”/”);
//return t[t.length-1].removeBadChars().replace(/[\\/]/g, “”).trim();
var tt = t[t.length-1].removeBadChars().replace(/[\\/]/g, “”).trim();
//start modified by hongfengye at 2007-03-21
if(tochar !=”"){
var allcharset = new Array(
‘GB2312′,
‘X-GBK’,
‘GB18030′,
‘HZ-GB-2312′,
‘UTF-8′,
‘ISO-2022-CN’,
‘ISO-2022-JP’,
‘ISO-2022-KR’,
‘BIG5′,
‘BIG5-HKSCS’,
‘EUC-JP’,
‘EUC-KR’,
‘ARMSCII-8′,
‘GEOSTD8′,
‘ISO-8859-1′,
‘ISO-8859-10′,
‘ISO-8859-11′,
‘ISO-8859-12′,
‘ISO-8859-13′,
‘ISO-8859-14′,
‘ISO-8859-15′,
‘ISO-8859-16′,
‘ISO-8859-2′,
‘ISO-8859-3′,
‘ISO-8859-4′,
‘ISO-8859-5′,
‘ISO-8859-6′,
‘ISO-8859-6-E’,
‘ISO-8859-6-I’,
‘ISO-8859-7′,
‘ISO-8859-8′,
‘ISO-8859-8-E’,
‘ISO-8859-8-I’,
‘ISO-8859-9′,
‘ISO-IR-111′,
‘IBM850′,
‘IBM852′,
‘IBM855′,
‘IBM857′,
‘IBM862′,
‘IBM864′,
‘IBM864I’,
‘IBM866′,
‘KOI8-R’,
‘KOI8-U’,
‘SHIFT_JIS’,
‘T.61-8BIT’,
‘TIS-620′,
‘US-ASCII’,
‘UTF-16′,
‘UTF-16BE’,
‘UTF-16LE’,
‘UTF-32BE’,
‘UTF-32LE’,
‘UTF-7′,
‘VIQR’,
‘VISCII’,
‘WINDOWS-1250′,
‘WINDOWS-1251′,
‘WINDOWS-1252′,
‘WINDOWS-1253′,
‘WINDOWS-1254′,
‘WINDOWS-1255′,
‘WINDOWS-1256′,
‘WINDOWS-1257′,
‘WINDOWS-1258′,
‘WINDOWS-874′,
‘WINDOWS-936′,
‘X-EUC-TW’,
‘X-IMAP4-MODIFIED-UTF7′,
‘X-JOHAB’,
‘X-MAC-ARABIC’,
‘X-MAC-CE’,
‘X-MAC-CROATIAN’,
‘X-MAC-CYRILLIC’,
‘X-MAC-GREEK’,
‘X-MAC-HEBREW’,
‘X-MAC-ICELANDIC’,
‘X-MAC-ROMAN’,
‘X-MAC-ROMANIAN’,
‘X-MAC-TURKISH’,
‘X-MAC-UKRAINIAN’,
‘X-OBSOLETED-EUC-JP’,
‘X-OBSOLETED-ISO-2022-JP’,
‘X-OBSOLETED-SHIFT_JIS’,
‘X-U-ESCAPED’,
‘X-USER-DEFINED’,
‘X-VIET-TCVN5712′,
‘X-VIET-VNI’,
‘X-VIET-VPS’,
‘X-WINDOWS-949′
);
for(var i=0; i<allcharset.length; i++){
if(tochar.toUpperCase() == allcharset[i]){
var converter = Components.classes[”@mozilla.org/intl/scriptableunicodeconverter”]
.createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
converter.charset = tochar;
tt = converter.ConvertToUnicode(tt);
break;
}
}
}
return tt;
//end modified
},
然后将涉及到getUsablefileName()的地方, 都将这个函数改成了参数传递, 主要有down.js 和 internalfunction.js, 这里就不一一罗列了!
5、dta.jar/content/dta/down.js
这个文件里面主要修改的部分就是我上面说的将getUsableFileName()改成了传递参数(参数就是编码),但有一处是改动较大的, 就是原版本来在visitHeader函数中使用了getUsableFileName(),在这个地方无法将编码参数传递过来, 一直是我所困扰的, 后来看到代码的赋值并不在这里,所以将这里的getUsableFileName()函数取消, 将该函数移动到赋值之前, 即这里:
d.fileName = d.destinationName = visitor.fileName + (visitor.fileName.lastIndexOf(’.') == -1 && d.url.getExtension() ? ‘.’ + d.url.getExtension() : ”);
将getUsableFileName()函数插入这个语句之前, 这样就解决了在header中改变文件名而不能修正乱码的麻烦。 至此也就彻底解决乱码问题
关于downthemall!乱码修正问题,经过几天的努力终于告一个段落。这是我对firefox扩展的第一个修改, 也是第一次尝试, 通过这次的作业,我也学到了很多以前从来都不知道的东西, 学到的最多的就是关于xpcom这个东西, 虽然我到现在也没有弄清楚是什么东西,但还是用这个东西做了点事情。
希望下次还有机会可以再锻炼锻炼, 也希望能多跟高手学习学习, 这次多亏了有greasemonkey的修改作者sunwan, 有了它写的这个convertToUnicode才有了这个修改版的诞生。
最后, 修改版的下载地址在这里http://blog.2i2j.com/downthemall.xpi