
长久以来我对很多浏览器扩展都是不满意的,这次重写 Stylus
理想中的 User CSS loader 应该符合以下条件
1 . CSS 应该是外置的,这样才能满足
1). 方便用顺手的编辑器改写
2). 使用预处理器
3). 同时给多个浏览器使用
4). 避免浏览器崩溃毁数据
2 . CSS 应该是自匹配的,不需要额外编写规则。把 v2ex.com.css 放在硬盘上,立即对网站生效,删除后立即失效 
3 . CSS 模块化,163.com.css 先加载,news.163.com.css 后加载,规则叠加,互不引用 
4 . CSS 应该有简单的地址查询能力
>> www.bilibili.com.css /* 只对 B 站文章页面生效 */ html[location*="/read/cv"] { ...some code } /* 只对 B 站视频页面生效 */ html[location*="/video/av"] { ...some code } 按照这个标准,写了个简易版
Tampermonkey UserJS
// ==UserScript== // @name outboard user css loader // @author autoxbc // @version 1.0 // @match *://*/* // @run-at document-start // @require https://wzrd.in/standalone/tldjs // ==/UserScript== if(location.hostname) { const root = document.documentElement ; root.setAttribute('location', location ); let domain = tldjs.getDomain(location); const domains = [ domain ]; const subs = tldjs.getSubdomain(location).split('.').filter( e => e ).reverse(); subs.forEach( sub => domains.push( domain = sub + '.' + domain ) ); domains.forEach( async domain => { const link = Object.assign( document.createElement('link') , { rel:'stylesheet', href:`https://localhost/styles/${ domain }.css`, } ); root.append(link); const { ok } = await fetch( link.href , { mode:'cors', cache:'no-cache', } ); if(!ok) link.remove(); } ); } tld.js 的 standalone 版本地址是 tld.js 作者 oncletom 给出的,比较安全
https://github.com/oncletom/tld.js/issues/37
注意:
既然是外置式,需要准备一个文件服务器来传递数据,这里用 node.js + http-server
http-server 启动参数
http-server -a localhost --cors --ssl --cert cert.pem --key key.pem CORS 标志使得这里不使用特权方法 GM_xmlhttpRequest 也能跨域;
启用 SSL 避免了浏览器的混合内容安全策略错误,需要给文件服务器添加自签名证书,OpenSSL 或者 LibreSSL 或者在线生成;
这里也没有使用 GM_addStyle,GM_addStyle 会把 CSS 内嵌,不利于调试;现在这样更容易区分代码来自那个文件

事实上,在我自己的系统里,不止 User CSS 外置,这个加载器也用 Tampermonkey 的 @require 外置了,所有浏览器都可以同时对接这个加载器,即 EaaS -- Extensions as a Service
有人喜欢 Chrome,有人喜欢 Firefox,如果他们都用外置式的扩展,会不会更有趣?