为使用旧的HTML5 Notification API的网站提供一个兼容层,使得可以使用Firefox所支持的新版API来弹出通知。

关闭华为C8950D的低电提示

这手机有个不爽的设定,就是在电量29%的时候会弹出个提示,问是否要开启省电模式。更不爽的是,这个提示会打断当前的进程,导致录像中断。

把几个可疑的/system/app下的apk弄出来研究了下,发现相关代码是在SystemUI里,懒得改动代码,试了一个偷懒的方法,发现比较靠谱有用:

ROM Toolbox Pro的App Manager找到System UI,使用Advanced Freeze,把Receivers里的Power Saving Mode和Services里的PowerSavingService都disable掉,然后Force Stop一下就好了。

也许不用ROM Toolbox Pro也可以,大家自行寻找具有类似功能的软件吧。

Tags: Android 技术

请把饼图做好

科研中学到的东西,虽然大部分和实际生活关系不大,但正确地制作图表却是少数几个比较实用的技能。

我们来看小众软件的我最喜爱的《快速启动工具》。里面有张饼图:

这一看就是不懂作图的人做的。为什么这么说?因为这图存在非常多的问题。我们先来看一张比较正确的(Google随便找的):

大家可能已经发现问题了。小众软件的图虽然用颜色标识了,但因为项目太多,颜色区分度并不是很好,而且左右的对应程度并不好。尤其是我想看那几个占有率较小的项目时,左右对应是一件非常痛苦的事情。而下面这个图就非常清晰明了,把项目名称直接标在图饼里面,即使项目数多于小众软件的图,但依然清晰明了。更为重要的是,小众软件的图,是在无意识中歧视了色盲色弱患者,使得这群人根本无法解读图表的含义。

当然这个的原因是因为作图软件默认设置的问题。Excel 2013中的饼图样式,只有很少几个会默认添加项目名称到饼图分块中,而大部分人更是不知道原来分块标签的格式还可以自定义。

做好一个饼图,虽然不难,但意识的缺失却是非常常见的。

Tags: Excel chart

jQuery事件处理的小坑

在给Twitter写UserScript,不想用MutationObserver,因为总觉得这个东西会很影响性能。而Twitter的UI框架Flight又是事件驱动的,因此想到利用Twitter自己的UI事件来hook进去。

但无论怎么addEventListener,都无法捕获信息,读了源代码,确定有个自定义事件是从里面的li冒泡到外面的div,但是在中间的DOM节点就是截获不到事件。被迫利用Chrome开发者工具的单步运行,一点点看它自身的事件机制,发现其使用的jQuery在事件处理上是重新发明了一套轮子。

具体而言,$.on不仅仅是addEventListener这么简单,它同时把相关处理用$.data保存起来(关于DOM节点的数据都存在$.data中)。当$.event.trigger的时候,并没有利用DOM3开始支持的CustomEvent,而是js生成了bubble path其中包含从window、document到target节点的所有DOM元素,然后挨个触发相应的jQuery handler和native handler。最后利用DOMNode.click()触发默认行为。

问题就在这最后一步的行为比较有迷惑性,因为从一个沙盒中$.trigger(“click”)的时候,能激活另外一个沙盒里对应的行为,而两者的事件处理并不是共享的($.data不同)。原因在于DOMNode.click原生方法(显示为native code)会触发click事件,而这个click事件是会正常冒泡的。但对于自定义事件,不存在对应的原生方法触发事件冒泡,因此整个trigger和on就在该沙盒内的jQuery对象内部完成,不对外广播事件。

因此要hook进来,必须向该沙盒注入代码调用该沙盒的jQuery对象,从而参与到其内部的事件处理机制,并向外广播。

小心GreaseMonkey里的window

这是写Twitter RT脚本的时候发现的。

之前采用了这样一种性能优化方式:

(function(window){
  var Array = window.Array;
})(window);

然后在Firefox中却提示Array is undefined,很莫名。用console.log把window打印出来才发现里面所有大写开头的变量全部不存在。不知道是怎么回事。想起来Twitter的页面代码全部是用this.Array来代替window.Array的,估计也是避免类似的情况。

只好放弃了这种优化来保证Firefox兼容性。

Update: 浪费了早上宝贵的一个多小时,逐行排查,终于发现真正的原因。

用了GM_addStyle后,好像运行环境变了,于是Array和Math就都从window对象里消失了。

给GreaseMonkey提了个issue,也不知道会不会修好。

Update2: 这个问题应该不会修正,根据MDN对Global对象的描述,并没有提到可以通过window对象访问,而是要在全局作用域的时候访问this才行。

The global object itself can be accessed by this in the global scope.

把测试脚本改了一下,果然是正常的。熟读文档才是王道。

去掉Chrome 27之后的主页上的Google页面

自从用上硬又黑的导航条后,Google的脑残驱动工作方式越来越强了。从Chrome 27开始,居然默认在新建标签页里加了个Google主页。搜索栏地址栏合一是你Chrome提倡的,现在又直接内嵌个Google搜索框……

image

而且下面展示的,将证明这不是为了推广品牌,而是实实在在的脑残!

发现这个设计后,自然要想办法去掉,用开发者工具可以看到这个页面的一些信息,于是用关键字去搜了下,发现相关内容都在chrome.dll这个文件里,尝试了几种修改,都去不掉。柳暗花明,想到里面有好多判断是不是Google搜索的代码,于是尝试着把设置里一直用的Google搜索换成Bing,然后换完,就发现开着的另一个新建标签页自己刷新成了Google页面,再新建一个标签,恢复正常了!!!!

image

但是我前面文章也吐槽过了,目前Google搜索是最好用的,谁有bing才去用Bing。

但既然可以用Bing,应该其它自定义的搜索引擎都可以,在搜索里先把默认的Google删掉,再找个可以修改的搜索引擎,按截图中修改,其中搜索串用https://www.google.com/search?q=%s

image

设为默认。现在既可以去掉恶心页面,又可以继续用Google了

Update: 28.0.1495.0 canary 无法通过上述方法绕过,会检测搜索引擎字串里是否包含Google的网址,包含的话,就依旧显示恶心的搜索框。不过Canary版本变化很快,不排除过一段时间再次变化的可能。

Update: 刚发现,可以彻底恢复成Chrome26之前的样式。打开about:flags,把Enable Instant extended API这项设为disabled然后relaunch就好了。当然我个人因为不喜欢新建标签页上有App所以还是喜欢新版一点

Tags: 技术 Chrome

上下文

在微博上看到这条

如果有一天,你11岁的女儿在放学的路上失踪了。你疯狂的找,后来在一家妓院找到,已经被轮奸、殴打、虐待。即便这样,你得以死相逼,警察才管;你得去长沙百余次、去北京23次上访,绝食、下跪,历经六年,被数次刑拘、劳教,像狗一样乞求正义,才走完司法程序。最后,有人问你:你为什么给政府添乱?

想到最近的又风风火火的朱令案。太多的人关注事件容易受到洗脑般的操控。

电影Case 39中描述的是一对父母想方设法要杀死自己的女儿,被社工救出来,最后却发现女孩是个恶魔,杀死她周围所有人的故事。

电影虽然拍的不咋样,但却努力揭示了事件上下文的重要性。电影中父母杀女的情节,如果像电影女主角那样孤立地看待,会觉得父母没有人性。但结合全片情节,却是女主角无知。

再例如,如果一个人A在意外中杀死另一个人B,是否要负责任呢?如果A是超人,和毁灭地球的外星人打斗中,余波杀死了很多人,那超人是否又该被审判?审判后又来了新的外星人,而超人因为之前的审判已经不愿意再拯救人类,那之前的审判,又是否是盲目的正义?请不要笑,这正是DC超级英雄漫画中,正义联盟最终分裂的原因。

再回到朱令案中,不管真相如何嫌疑人是谁,如果我们把孙维换成她们寝室中另外一个叫王维的人,而把孙维替换为室友,所有的指控是否仍然能成立?再假如先描述一大段朱令在校内的骄横行为,再把这件事不起眼的拿出来,不断强调其中朱令无理的行为和她家的背景而不提王维家的背景,又会有多少人对朱令还有好感?当然这些都是假设,真相已经不可知了。

所以公正地看待一件事情是非常困难的,真正的正义几乎不存在。

如果一件事情,既没有前因后果,把其中的当事者替换又不影响事情本身的成立,就请当心了,你的“独立思考”有被他人玩弄的可能。

搜索引擎

在Google里搜索“浮士德”

第一条维基百科介绍人物;第二条维基百科介绍悲剧背身;第三条豆瓣读书介绍书本身;第四条豆瓣电影介绍电影;第五条新浪大片继续介绍电影,接下来的是书评、视频等。右边的box也同样按照1人物2书3电影的顺序。第一页提供了足够的信息。

再看百度

前面几条和Google类似,不过把视频结果放到了最上面,必须承认确实更懂中国人,国人搜这个大部分是要看视频。但最下面百度贴吧和百度知道的乱入,也确实证明,除非你是够大的站,否则你的结果只是百度站内搜索结果的补充而已。甚至连《浮士德精神——歌德的晚年》这篇非常有名评论也不存在了。

最后来看Bing的

页面简洁到爆,不过除了第一条维基百科结果和第二条著名评论,其余的几乎就沦落为书商的宝地了。

我的评论已经非常有倾向性了,就不总结什么了。

那天和@shell909090聊天时也提到,Google Now这种东西,只可能由Google做出来。庞大的信息集和现阶段最优化的搜索结果,只要把语音识别的结果直接去搜然后返回第一条结果就可以保证足够的正确率了。这是讯飞语音助手之类永远无法做到的。

交叉编译stunnel

optware里的stunnel以及openssl都太老了,没办法配合我PC上的。决定自己重新编译一个。

直接利用tomato源代码里的OpenSSL,在stunnel目录里

./configure --host=mipsel-linux-uclibc --disable-libwrap --with-threads=pthread --with-ssl=~/tomato/release/src-rt/router/openssl --prefix=/opt

放到路由器上,很不给面子的提示

stunnel: can't load library 'libssp.so.0'

Google一下,一开始走了弯路,想着disable-libssp,然后发现居然要重新编译gcc,工作量太大显然不可能。不死心,因为tomato里其它程序都没这个问题,找了一会,发现一个类似的情况发生在cups上,而且openwrt已经解决了。看了下他们的补丁,发现原来是禁用了CFLAGS的-fstack-protector。

照葫芦画瓢,把stunnel里configure删掉相关部分,重新编译后,stunnel -h没有问题了,但是加载配置文件的时候又提示

undefined symbol FIPS_mode

然后想起configure的时候确实有提示

WARNING: OpenSSL fips header not found

搜了下,没找到什么好办法,这是个符号链接,即使把fips.h真实文件放到了正确的位置依旧如此提示。没辙,只好暴力方法,src/ssl.c中把关于FIPS_mode那一段(用USE_FIPS)包裹住的,全部删掉。其实configure的时候加个—enable-fips=no就可以了

再重新编译,提示不支持压缩,想起配置文件里开了zlib压缩,应该是tomato的openssl里没有编译进zlib,算了,直接删掉配置文件里的相关配置,终于没问题,成功运行。

Tags: 技术 Linux

朱令案

不管是朱令还是孙维都是有背景的人。

这事能确定的只有学校失职、投毒事实和寝室有人参与这三个框而已,其它都是没有证据的臆测。

整个事情前因后果不知道,关键性证据丢失,又牵扯到势力斗争,任何的疑点都只能是个疑点而已。你觉得疑点只是因为整件事情披露的东西太少,俨然演化成电影“罗生门”的状况了。

这件事真相永远不可知,但不能凭着莫须有的各种疑点就定罪。栽赃的可能性被有意无意的忽视、舆论导向的坏处,这件事中都得以体现。

再引用一下米兰达警告

你有权保持沉默,否则你所说的一切,都能够而且将会在法庭上作为指控你的不利证据;审问之前,你有权与律师谈话,得到律师的帮助和建议;你有权请律师在你受审问时在场;如果你希望聘请律师但却雇不起,法庭将为你指定一位律师。

请记住,既然追求法治,就不应该以当事者孙维及其它几个人的沉默作为疑点来进行各种臆测,更不应该以这些臆测进行逻辑推理来认定一个人的犯罪事实。

为什么彭宇案中,法官用逻辑推理定罪受到网民的热烈抨击,而换到朱令案,却又各种热衷于逻辑推理了?