因工作需要,会不时的在USTCOJ上产看程序源代码。查看源代码的流程通常是这样的:
1,根据指定题号、账号,或许相关的RunID。
2,登录http://acm.ustc.edu.cn/admin1/,进入http://acm.ustc.edu.cn/admin1/judge.php页面。
3,在如下所示的输入框中输入RunID号,点击View按钮查看代码。
(图片一)
采用这种方式查看源代码是相当痛苦的,因为judge.php是通过POST方式传递RunID值的,也就是说,每次查看源码的时候,都需要返回上述页面,然后输入ID号,再点击View按钮查看代码。
此外,在http://acm.ustc.edu.cn/ustcoj/status.php页面,其中的RunID是纯文本形式的,如下图所示:
(图片二)
现在,我想要做的工作又两个:
1,编写一个php脚本,实现查看源码的功能,而且该php文件通过GET方式来获取RunID参数,从而可以方便的通过URL访问到源码。当然,该PHP脚本还应该具备访问权限控制。
2,编写一个Chrome插件,将图片二中所示的RunID一列的文字更改为指向类似http://acm.ustc.edu.cn/admin1/viewsource.php?id=78651的超文本。之所以不在服务器端修改对应的php脚本(如status.php)。是因为对于一般用户而言,该RunID就只应该是一个纯文本字段。采用插件的形式,既能保证需要用到它的人看到超链接,又能保证不破坏原有代码。
该脚本的第4行判断用户是否已经登录,若未登录(及对应的SESSION字段为空),则显示登录框。第10~14行则表示在用户登录的情况下,通过GET获取id的值。并将代码展示出来。
脚本17~21行则执行登录操作。后面的23~134是对应的三个函数的定义。由于login及showSource函数中需要查询数据库,其中admin.php脚本包含了数据库的连接等初始化操作。
主要参考了以下两个链接:
http://www.cnblogs.com/igrl/archive/2010/09/28/1837236.html
http://kodango.com/content-scritps-develop-in-google-chrome
此外,还参考了“中科大图书馆豆瓣插件”。在此感谢相关作者。
编写完插件进行调试的时候,还遇到了Could not load extension from . The ‘manifest_version’ key must be present and set to 2错误。搜索到一些链接,通过添加“manifest_version”: 2 解决了该问题。链接:http://www.viphper.com/?p=423
好的,接下来该上操作步骤了。首先,新建了文件夹UstcOjSourceView。并准备了一个128×128的icon图标。代码如下图所示:
其中manifest.json文件内容如下:
{ "name" : "UstcOjSourceView", "version" : "1.0", "manifest_version" : 2, "description" : "将UstcOj页面表格中的Runid更改为超文本链接", "content_scripts" : [ { "js" : ["Runidlinked.js"], "matches" : ["http://acm.ustc.edu.cn/ustcoj/*" ], "run_at" : "document_end" } ] }
该json文件中content_scripts的含义如下:当访问以http://acm.ustc.edu.cn/ustcoj/开头的URL的时候,在文档加载结束之后,运行Runidlinked.js文件。
String.prototype.blanklink = function(str) { url = this.link(str); offset = url.indexOf('">'); url = url.substring(0, offset) + '" target="_blank">' + url.substring(offset+2); return url; } document.getElementsByClassName = function(className) { var elem = this.getElementsByTagName('td'); var result = []; for (i in elem) { if (className == elem[i].className) result.push(elem[i]); } return result; }; function getURL(text) { url = "http://acm.ustc.edu.cn/admin1/viewsource.php?id="; url += text; return text.blanklink(url); } function change() { var divs = document.getElementsByClassName('table_runid'); for(i in divs) { text = divs[i].innerText; divs[i].innerHTML = getURL(text); } } change();特别需要留意的,是最后一行代码change();因为在它之前都只是函数定义,而只有这一行代码,才是整个功能实现的关键。
上述JS脚本总体而言还是比较简单的,其中getElementsByClassName是为了获取页面中的<td class="table_runid">,因为这些节点,就是呈现RunID内容的HTML。而其中blanklink,则是为字符串对象添加一个blanklink方法,该方法的功能,是为了将超链接指向新的窗口。
总的就是这样。