【项目总结】Leetcode刷题插件项目总结



  • LeetCode Extension for Chrome

    作者:Xiakun Lu
    下载:Chrome Web Store
    源码:https://github.com/binarylu/leetcode-ext

    1 概述

    1.1 简介

    LeetCode Extension是一个用于leetcode刷题的chrome插件。项目最初的想法来自于自己在刷题过程中觉得leetcode在有些地方做得不是特别好,于是就有了写个插件改善leetcode刷题体验的想法。

    1.2 功能

    1. 显示各个题目分类的完成进度情况
    2. 隐藏题目难度和通过率
    3. 点击“run code”或“submit solution”按钮后,disable 10秒,防止提交过于频繁
    4. 提交代码时,同步代码到github

    1.3 使用到的技术

    0_1469825623155_l2.png img

    服务器端
    服务器端使用NodeJS + PhantomJS来实现一个简单的爬虫,抓取题目的分类信息。
    NodeJS只是用来返回题目分类信息的json文件,也可以用Apache和Nginx直接返回json文件。
    PhantomJS是是一个基于 WebKit 的服务器端 JavaScript API,用来执行网页中的js渲染网页。

    客户端
    客户端即为chrome插件,主要使用了Chrome API和Github API。其中Chrome API使用JavaScript调用,Github API通过HTTPS调用。

    2 实现过程

    2.1 服务器端

    服务器端主要实现一个简单的爬虫,生成一个json文件,记录每个题目的分类信息,leetcode题目更新速度不快,这个爬虫一天跑一次即可。客户端请求题目分类信息时,返回该json文件内容即可。
    源码中的render.js负责渲染网页,用于被爬虫调用,输入题目分类的url,如:https://leetcode.com/tag/array/,返回一个json数组,数组内容为题目标题。
    crawler.js是爬虫部分,打开刷题页面,读取所有分类的url,依次创建子进程调用render.js来处理这些url,最后将分类信息汇总,生成json文件。

    踩过的坑:
    PhantomJS在mac上运行OK,在CentOS上运行需要安装fontconfig-devel库。
    JQuery是为客户端JavaScript开发的,不能直接支持nodejs上跑,需要安装jsdom来提供JQuery需要的环境,之后便可正常运行jquery。

    2.2 Chrome 插件开发

    Chrome插件最核心的文件就是mainfest.json这个配置文件,其他的都是js和html代码,还有图标文件。

    manifest.json格式简介:
    manifest.json官方文档:https://developer.chrome.com/extensions/manifest
    本项目的manifest.json:https://github.com/binarylu/leetcode-ext/blob/master/leetcode-ext/manifest.json

    name: 插件名称
    version: 版本,用于在chrome商店发布时候做版本检测,两次提交版本一样就会被拒绝上传。
    description: 项目介绍,在chrome插件管理页面和chrome商店显示插件的介绍信息。
    browser_action: 在这个key下设置插件在地址栏右侧图标的一些行为,如图标、鼠标悬停时的title、点击图标后的弹窗。
    permission: 权限设置,插件的一些行为需要相应的权限,只有在用户安装插件时授权了这些权限,才能实现相应功能。
    options_ui: 插件的选项页面,在这个key下填写选项页面的html文件名称。注:现在网上很多chrome插件开发教程还使用options_page,这个选项在chrome 40之后就被options_ui替代,chrome将来不再支持options_page。chrome_style设置为true之后,选项页面就不再是先开一个标签页的形式,而是在chrome插件管理页面以小弹窗的形式出现。
    content_scripts: 比较核心的选项,用来告诉chrome不同的页面使用哪个js来处理。

    踩过的坑:
    保存选项页面里的选项值时,不能使用html5的local storage,因为选项页面和插件代码在不同的域下,不能读对方的local storage。使用chrome提供的api chrome.sync.storage,sync表示同步选项到用户的Google账户,这样用户在另外一台电脑上登录chrome后,这些选项也会同步下来。对应的是chrome.local.storage,只保存在本地。
    API的url(包括github api和题目分类信息的json文件的url)要放到manifest.json里的permission里,这样才不会出现跨域的问题。
    点击地址栏右侧的插件图标,出现的弹窗的html文件中a标签会失效,只能使用chrome提供的API chrome.tabs.create在页面中打开链接。

    读取leetcode中的代码遇到的问题:

    leetcode中的代码编辑器支持语法高亮等编辑器高级功能,这些功能原生的html元素都不支持,leetcode使用的是ACE这个js插件实现的。需要使用js中ace的对象才能读到代码。

    在chrome插件代码中,插件的js代码和网页的js代码是在两个相互独立的环境下运行的,相当于插件的js代码运行在一个沙盒中,这样插件的js代码就获取不到ace对象,只能通过js注入的办法,将读取代码的js代码注入到页面的html中,这样,这段代码就运行在页面的js环境中了。使用这段代码在页面中创建一个隐藏的textarea元素,在点击提交代码的按钮时,将代码保存在这个textarea中,然后插件代码去读这个textarea的value就可获取到代码了。

    踩过的坑:
    用jquery将js代码注入到页面html中,这段js代码依然无法获取到ace对象,使用js原生的dom操作函数即可实现,可参考本项目源码此处的实现,leetcode-github.js

    2.3 如何发布

    如果想自己尝试开发chrome插件,可以下载本项目的源码,leetcode-ext文件夹中即为插件的源码,源码中以leetcode-开头的文件就是这个项目各个功能的实现文件,为简单起见,manifest.json文件中的content_scripts只保留

    {
    “matches”: [“https://leetcode.com/*”],
    “js”: [“jquery.js”, “leetcode-hidden.js”]
    },

    然后打开chrome插件管理页面chrome://extension,在最上面勾选developer mode。 这里提供了两种本地安装的方法:

    1. 点击load unpacked extension,然后选中源码中leetcode-ext文件夹,即可把源码加载到chrome中,此方法适合调试代码,代码修改完后,点击页面中这个插件下的reload即可将最近代码加载到chrome。
    2. 点击Pack extension打包,生成一个crx文件,然后再把这个文件拖动到chrome中即可加载,此方法适合朋友间分享插件。

    如果想在chrome商店中发布,只需将leetcode-ext文件夹压缩成zip文件,然后再chrome商店右上角设置菜单里打开Developer Dashboard,按照指示依次上传zip文件,填写信息即可,这里压缩文件、源码文件夹名称都无所谓,插件名称决定于manifest.json文件中的配置信息。

    3 未来计划

    未来计划实现以下功能:

    • 显示更详细的进度统计信息,如各个难度的完成情况,各个公司分类的完成情况
    • 显示公司分类下的题目
    • 显示locked题目内容
    • 支持隐藏locked题目,并且不对这些题目进行统计
    • 使用GitHub OAuth登录
    • 支持导出功能,将已在leetcode上提交的代码一次导出到github中

    Reference

    官方文档:

    参考博客:

    h- ttp://blog.iderzheng.com/introduction-to-chrome-extension-development/


登录后回复
 

与 BitTiger Community 的连接断开,我们正在尝试重连,请耐心等待