预备知识: 不知什么时候开始,我发现一个问题: 似乎失效了,单击以后剪贴板没有改变。于是很长一段时间都用在ed2K的链接上点右键复制链接地址的方法来应付。这样需要下载的链接很多时简直不堪重负,甚至开Maxthon来应急。 今天早上精神比较好,打算在吃早餐的过程彻底解决一下。 首先,重点怀疑对象是扩展和插件。我的Firefox里装有54个扩展和9个插件,而且不定时会进行插件的各种参数设置。所以无法从时间上定位具体装了哪个插件以后出现该现象。说到这里,停下来BS一些不负责任的客服: 客户:我这里的系统出现了xxx现象,请问怎么解决? 客服mm:请问您的系统是什么时候开始出现该现象的? 客户:大约是上周。。。也有可能是上上周。 客服mm:请问您上上周对电脑做过什么操作? 客户:~!@¥%@¥#&%!@#¥#~~@¥!#~...记不得了。 客服mm:您再好好回忆一下,您当时对电脑做过什么操作,好吗? 客户:对。。对不起,上上周的事我实在想不起来了。 客服mm:哦,那么这样我无法帮助您。还有什么我可以帮助您?如果不需要帮助,请稍候对我的服务进行评价。 客户: ~@!$~!$~@~@$$@~@$~~@$~!~@~#@~~~#$%^&^!~ @#$%^%*&^~ 这种客服各行各业都是,不会分析问题,避重就轻,制造障碍,想办法打发客户。 好了,BS完毕,我们继续分析。既然无法从时间上定位哪个扩展造成影响,那么我们从空间上来。一共有54个扩展,我们先禁掉前27个,如果现象消失,说明这27个插件中有某个在作怪。否则说明问题可能存在于后27个。然后再对可能存在问题的27个进行迭代分析。实际上最多需要 [log2(54)]+1 次即可定位到出问题的扩展所在。 OK,二分法很简单。写这篇文章的主要目的在于启发一个调试技巧:分块注释。比如说我们发现接手了一个程序有诸多内存泄漏,而根本不可能追述代码是谁写的、什么时候写的。这时候最好的办法就是分块注释,从程序入口点开始,在合适的构造函数处把后面的操作分块注释。在不影响程序编译的情况下,尽量按二分法注释代码。很多同行们看着代码大片大片地变绿会有些心虚,实际上动动手,你会发现比想象的简单。 ;-) 在Firefox中禁用、启用扩展是需要重启程序的。在重复劳动量很大的时候,千万不要用鼠标,因为使用鼠标容易造成疲劳。我们尽量用键盘。观察一下,在插件管理器中,按↓跳到下一个插件,按ALT + D是禁用(&D),按ALT + E是启用(&E)。所以我们只要右手放在↓键,左手放在ALT+D或E,就能一阵噼里啪啦地完成这项工作,很high。 ;-) 经过一番噼里啪啦,我找到是MediaWrap在作怪。最后再分别禁用一次、启用一次,确认现象消失一次、出现一次,那么MediaWrap确实是元凶。 打开MediaWrap,里面也有不少复选选项,继续套用二分法,发现是和"检查 EMBED 标签媒体"和"自动播放Flash"这两个选项在作怪,勾上就挂了。 好,现在从源码角度剖析。先拖拽反选 按钮。我习惯多选一点,把相邻的也选一点点,某些情况下可以避免遗漏。然后右键,查看选中部分的源码。观察到有关的代码片段为: <input 这时候运用"Web Developer Toolbar"扩展的Information -> View JavaScrip功能。这里我不选用FireBug的原因是WDT的JS查看功能能够把所有引用到的JS组合到一个新窗口中,而FireBug会开N个新窗口,查找起来就麻烦了。这里找到copy()函数的定义: http://statics.verycd.com/javascripts/group.js.r8407 第485行 function copy(str) { ed2kcopy += a[i].value; ed2kcopy += "\r\n"; } } VeryCD.events.copy(ed2kcopy); } 在FireBug中定位到这个函数,我们在VeryCD.events.copy(ed2kcopy);下断点,之后可以说一切尽在掌握中。这里引用了函数"VeryCD.events.copy",单步来到 http://statics.verycd.com/javascripts/global.js.r8589 第156行 VeryCD.events.copy = function(text2copy) { { window.clipboardData.setData("Text", text2copy)return } { { flash_el = $(arguments[1]) } } { } flash_el.innerHTML = '<embed src= + / g, "%2B") + '" width="0" height="0" type="application\/x -shockwave-flash"><\/embed>' } 从上一段代码可以看出,VeryCD http://statics.verycd.com http://statics.verycd.com/images/clipboard.swf 嘿,这里用了个Flash // Action script... // [Action in Frame 1] System.useCodepage = true; if (clipboard.length) { System.setClipboard(clipboard); } // end if 哈哈,这下基本上清楚了:我在Firefox的Mediawrap插件中,VeryCD网站的右键复制功能是利用运行一个Flash。Flash的第一帧有个ActionScript,作用是写入剪贴板。当我勾选了MediaWrap中的"非ActiveX控件-检查EMBED标签的媒体",同时反选"自动播放Flash"的时候,这个ActionScript得不到执行。应该是显示一个"播放"的图标,等待用户点击。但是这个Flash的尺寸是0("width="0" height="0"),根本不可见,所以一直处在等待用户点击的状态,所以复制剪贴板无效。 自动播放Flash 勾选 反选 检查EMBED标签的媒体 勾选 可用 不可用 反选 可用 可用 至于"检查EMBED标签的媒体"做了什么,没有文档资料,我也不太清楚,如果知道的朋友请告诉我一声?如果找到原因,我将更新本文。
value="复制选中的链接"
class="button"
onclick="copy('EM47b82f9be4a8e')"
type="button">
var a = document.getElementsByName(str);
var n = a.length;
var ed2kcopy = "";
for (var i = 0; i < n; i++) {
if(a[i].checked) {
//copyToClipboard(ed2kcopy);
if (window.clipboardData)
var flash_el = null
if (arguments.length == 2)
if (typeof $(arguments[1]) == "object")
if (!flash_el)
var div_holder = document.createElement('div')div_holder.id =
"flash-copier"document.body.appendChild(div_holder)flash_el = $(
"flash-copier")
"' + VeryCD.config.root.statics + '\/images\/clipboard.swf" FlashVars=
"clipboard=' + encodeURIComponent(text2copy).replace( / \
2008年2月22日星期五
用二分法快速定位bug
订阅:
博文评论 (Atom)


没有评论:
发表评论